Přejít k navigační liště

Zdroják » Různé » Flex 4: Drag-and-drop

Flex 4: Drag-and-drop

Články Různé

Technika drag-and-drop (česky „táhni-a-pusť“ nebo „přetahování“) patří k užitečným prvkům, které mohou zvýšit použitelnost vaší aplikace a zpříjemnit její užívání. Je samozřejmé, že možnost drag-and-drop nabízí i Adobe Flex. V článku si ukážeme, jak tuto techniku implementovat.

Drag-and-drop (DnD) můžeme ve Flexu aplikovat téměř na cokoliv. Některé komponenty mají nativní podporu pro drag-and-drop a umí si přímo poradit s přetahovaným objektem (List, TileList…), u jiných je alespoň možnost si podporu přidat dle vlastního uvážení.

Při implementaci DnD rozlišujeme 3 objekty:

  • Drag Initiator (zde táhnutí začíná – tj. toto je objekt, v němž původně ležel tažený objekt)
  • Drag Proxy (tažený objekt – to je ten, na němž uživatel stiskl tlačítko myši a začal jej přetahovat)
  • Drop Target (cíl vhození, tedy objekt – kontejner, nad nímž je tažený objekt puštěn)

Jedna komponenta může být současně Drag Initiator i Drop Target, záleží na tom, jak si logiku nastavíme.

Jednoduchý Drag-and-drop

Pojďme se podívat na základní možnosti techniky DnD u komponenty, která tuto techniku přímo podporuje, totiž u komponenty List. Jediné, co je potřeba nastavit, je dragEnabled="true" a dropEnabled="true". Tím je přetahování pro daný objekt povolené, a to jak „táhnutí odsud“, tak i „pouštění sem“.

Vytvoříme si dva seznamy, kde první je zdroj (má nastaveno dragEnabled) a druhý cíl (má dropEnabled).

<s:List dragEnabled="true" dataProvider="{new ArrayCollection(['Photoshop','Illustrator','Flash'])}" />
<s:List dropEnabled="true" />

Pokud chcete přetahovat více položek najednou, použijte allowMultipleSelection="true".

Celá aplikace bude vypadat následovně:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
        ]]>
    </fx:Script>
    <s:Label x="10" y="10" text="Nabídka"/>
    <s:Label x="168" y="10" text="Košík"/>
    <s:List dragEnabled="true" dropEnabled="true" allowMultipleSelection="true" dataProvider="{new ArrayCollection(['jablka','hrušky','pomeranče'])}" x="10" y="30" width="150" height="200"/>
    <s:List dragEnabled="true" dropEnabled="true" allowMultipleSelection="true" dataProvider="{new ArrayCollection()}" x="168" y="30" width="150" height="200" ></s:List>
</s:Application>

Můžeme si všimnout, že při přetahování položek z jednoho seznamu na druhý se položky kopírují, což nemusí být vždy žádoucí. Pokud chceme, aby se položky nekopírovaly, ale kompletně celé přesouvaly, použijeme vlastnost dragMoveEnabled="true". Slovo „kompletně“ je zde použito záměrně – v seznamu totiž nemusí být jen primitivní stringy, ale celé komplexní objekty a přetahovaná položka tak může nést mnohem víc informací.

Vlastní Drag-and-drop

Při psaní aplikace ve Flexu může nastat situace, kdy bude potřeba (nebo prostě jen výhodnější) udělat Drag-and-drop podle sebe, na vlastních komponentách. K tomu slouží události Drag třídy UIComponent, ze které dědí všechny standardní komponenty.

Při operacích DnD jsou na různých objektech vyvolány tyto události (samosebou ne v tomto pořadí):

  • u původního kontejneru (drag iniciator): dragStart, dragComplete
  • u cílového kontejneru (drag target): dragEnter, dragOver, dragDrop, dragExit

Význam je zřejmý z názvů – dragStart oznamuje začátek tažení, dragComplete je vyvoláno při dokončení celé operace, dragEnter říká, že objekt byl přetažen nad cílový kontejner, dragOver oznamuje, že se objekt pohybuje nad kontejnerem, dragDrop je vyvoláno při puštění objektu a dragExit oznamuje, že uživatel přetáhl objekt z kontejneru ven, aniž by jej pustil.

V dalším příkladu si názorně ukážeme, jak vybrat ze seznamu libovolný počet prvků a přetáhnout je do textového pole (TextArea). K tomu nám postačí dragEnter a dragDrop.

dragEnter potvrdíme či zamítneme příjem přetahovaných položek – DragManager.acceptDragDrop(cílovýObjekt:UIUComponent. Můžeme navíc například změnit kurzor pomocí  DragManager.showFeedback(DragManager.COPY).

dragDrop zase zpracujeme vhozená data. Po celou dobu – i v dragEnter apod. – máte k přetahovaným datům přístup přes event.dragSource, a to konkrétně pomocí metody dataForFormat. My použijeme ještě hasFormat, abychom se ujistili, že se jedná o formát dat, který jsme schopní zpracovat. Tyto formáty se mohou lišit a můžete si zavést i vlastní formát, pokud budete řešit drag-and-drop kompletně ve vlastní režii.

V tuto chvíli nás bude zajímat formát itemsByIndex, který obsahuje položky z komponenty s:List.

Celý příklad tedy bude ve finále vypadat nějak takhle. Všimněte si, že jsme rozšířili nosnou informaci ze Stringu na objekt obsahující dvě položky – nově i cenu. Pomocí labelField nastavíte, který parametr se má vypisovat. Pokud byste chtěli oba, museli byste použít labelFunction nebo vlastní itemRenderer. Pokud vás zajímá, jak se s nimi pracuje, nahlédněte do dokumentace – itemRenderer je podstatně složitější, ale zato má mnohem víc schopností (práci s ním si ukážeme v některém z dalších dílů).

Flex 4 - drag and drop

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.core.IUIComponent;
            import mx.events.DragEvent;
            import mx.managers.DragManager;
            protected function textarea1_dragEnterHandler(event:DragEvent):void
            {
                DragManager.acceptDragDrop(IUIComponent(event.target));
                DragManager.showFeedback(DragManager.COPY);
            }
            protected function txt_dragDropHandler(event:DragEvent):void
            {
                if(event.dragSource.hasFormat("itemsByIndex")){
                    var data:Object = event.dragSource.dataForFormat("itemsByIndex");
                    event.target.text = "";
                    for(var i:Object in data){
                        event.target.text += data[i].nazev+": "+data[i].cena+"n";
                    }
                }
            }
        ]]>
    </fx:Script>
    <s:Label x="10" y="10" text="Nabídka"/>
    <s:Label x="168" y="10" text="Košík"/>
    <s:List dragEnabled="true" allowMultipleSelection="true" labelField="nazev" dataProvider="{new ArrayCollection([{nazev:'jablka',cena:10},{nazev:'hrušky',cena:15},{nazev:'pomeranče',cena:20}])}" x="10" y="30" width="150" height="200"/>
    <s:TextArea x="168" y="30" dragEnter="textarea1_dragEnterHandler(event)" dragDrop="txt_dragDropHandler(event)"/>
</s:Application>

Drag-and-drop plně pod kontrolou

Zatím jsme si ukázali drag-and-drop spojený s List komponentou. DragManager však obsahuje metodu doDrag. která umožňuje pracovat s jakoukoliv komponentou (obrázek, tlačítko, video…). Drag-and-drop si tak můžeme upravit od základu podle našich představ. Přestavme si, že chceme tlačítko, které po stisknutí budeme moci přenést a hodit na textové pole. Viz následující příklad:

Flex 4 - drag and drop

Kód není nijak složitý a podstatné informace jsou z něj patrné.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Script>
        <![CDATA[
            import mx.core.DragSource;
            import mx.core.IUIComponent;
            import mx.events.DragEvent;
            import mx.managers.DragManager;
            protected function textinput1_dragEnterHandler(event:DragEvent):void
            {
                DragManager.acceptDragDrop(IUIComponent(event.target));
            }
            protected function textinput1_dragDropHandler(event:DragEvent):void
            {
                event.target.text = event.dragSource.dataForFormat("mujFormat");
            }
            protected function button1_mouseDownHandler(event:MouseEvent):void
            {
                var src:DragSource = new DragSource();
                src.addData(event.target.label,"mujFormat");
                DragManager.doDrag(IUIComponent(event.target),src,event);
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Button x="10" y="10" label="Tlacitko, ktere nese nejake cool informace" mouseDown="button1_mouseDownHandler(event)"/>
    <s:TextInput x="10" y="77" width="245" dragEnter="textinput1_dragEnterHandler(event)" dragDrop="textinput1_dragDropHandler(event)"/>
</s:Application>

Drag-and-drop v AIRu a File Promise

V AIRu má vývojář k dispozici poměrně příjemnou funkci, a tou je interakce se soubory z file-systému na klientském počítači. Uživatel tedy může do aplikace v AIRu přetáhnout soubor ze správce souborů, který aplikace dokáže nějak zpracovat – např. jej nahraje na server. K dispozici jsou víceméně stejné události, pouze se liší prefixem native

nativeDragComplete, nativeDragDrop, nativeDragEnter, nativeDragExit, nativeDragOver, nativeDragStart, nativeDragUpdate

Tuto funkci doporučuji prozkoumat a odzkoušet si její fungování, hodně AIRových aplikací zjednodušuje práci ze soubory právě pomocí tohoto způsobu přetahování objektů z OS, a lze s ním vymyslet spoustu užitečných věcí – zpracování obrázků, zabalení souborů, konverze, upload na server atp.

V AIR 2.0 můžete navíc nyní z aplikace „vytáhnout“ soubor a přenést ho do file-systému (na plochu, do Průzkumníka, …) – této technice se říká File Promise, což je soubor, který ještě neexistuje, ale vy už ho fyzicky držíte myší „v ruce“. O tom, jakým způsobem s File Promise pracovat, píše např. Piotr Walczyszyn: File Promises with Adobe AIR

Flex 4 - drag and drop
(Autorem ilustračního obrázku je Piotr Walczyszyn)

K tomuto dílu je opět připraven soubor ukázkových aplikací ke stažení: Flex 4 – Drag and Drop

Komentáře

Odebírat
Upozornit na
guest
4 Komentářů
Nejstarší
Nejnovější Most Voted
Gebauer

Flash Builder 4 beta 2 u komponenty <s:List hlásí chybu, nezná vlastnosti dragEnabled a dropEnabled. Podobný příklad http://livedocs.adobe.com/flex/3/html/help.html?content=dragdrop_4.html s mx komponentou funguje. Vypadá to že spark knihovna v betaverzi 2 se nějak liší od verze kterou má autor članku, není totiž k dispozici ani <s:TileGroup> a <s:ComboBox> zmíněný v přechozích článcích seriálu

Jack

Také jsem skoušel a mě nešli ani příklady z 2. tutoriálu

Odysseus: PewDiePie vydal open-source AI workspace, který běží na vašem vlastním hardwaru

AI
Komentáře: 0
Felix Kjellberg, youtuber se 110 miliony odběratelů, strávil rok učením se programovat a fine-tuningem vlastních AI modelů. Výsledkem je Odysseus – bezplatný, open-source workspace pro práci s umělou inteligencí, který neposílá žádná data do cloudu. Projekt má týden, přes 61 000 hvězdiček na GitHubu a znovu otevírá otázku, komu vlastně patří váš digitální kontext.

Když Git už nestačí: jak izolovat databázový stav pro pokusy AI agentů

Gitová větev vývojářům oddělí kód, ale databáze často zůstává společná. U AI agentů je to slabé místo: rychle spouštějí migrace, mění data a zkoušejí víc cest najednou. Databázová větev jim dá vlastní pracovní prostor, jenže tím práce nekončí. Ještě je potřeba řešit citlivá data, oprávnění, životnost větve i zbytek stavu aplikace.

GitHub vyhrál pohodlím. Stejné pohodlí dnes ztěžuje odchod

GitHub kdysi působil jako přesný opak SourceForge: rychlý, přehledný a přirozený. Dnešní projekt na něm ale často nemá jen kód. Má tam issues, pull requesty, CI, balíčky, bezpečnostní pravidla i AI agenty. Lock-in nevzniká tím, že by nešel odnést Git repozitář, ale tím, že se běžný provoz týmu postupně přesune do jedné platformy.