Umíme ve Flashi – 29. díl – dynamické XML menu

V dnešním díle vytvoříme dynamické flashové menu, které bude externě konfigurovatelné pomocí XML datového souboru.

Princip menu

Jak již bylo naznačeno v úvodu, celé menu bude konfigurovatelné pomocí externího XML dokumentu. Zde bude přímo vytvořena struktura budoucího menu, kdy jednotlivé elementy budou tvořit položky menu.

Než začneme pracovat ve Flashi, připravíme si XML soubor v tomto tvaru:

<?xml version="1.0"?>
<menus xpoz="10" ypoz ="10" >
<mItem nazev="Menu 1" >
<mItem nazev="Submenu 1-1">
<mItem nazev="Subsubmenu 1-1-1" cil="
">
</mItem>
<mItem nazev="Subsubmenu 1-1-2" cil="
">
</mItem>
</mItem>
<mItem nazev="Submenu 1-2">
<mItem nazev="Subsubmenu 1-2-1" cil="
">
</mItem>
<mItem nazev="Subsubmenu 1-2-2" cil="
">
</mItem>
</mItem>
</mItem>
<mItem nazev="Menu 2">
</mItem>
<mItem nazev="Menu 3">
</mItem>
<mItem nazev="Menu 4">
<mItem nazev="Submenu 4-1">
</mItem>
</mItem>
</menus>

Soubor uložíme v UTF-8 formátu pod názvem „menu_1.xml“. Když se na strukturu dokumentu podíváme podrobněji, nalezneme zde hlavní element „menus“, který nám vymezuje data pro menu. Vlastnosti „xpoz“ a „ypoz“ budou sloužit pro umístění celého menu na scéně.

Pokud se podíváme dále, zjistíme, že se zde vyskytují pouze elementy „mItem“, pomocí kterých přesně definujeme strukturu výsledného menu. Pokud je do elementu vložen další, vytvoří se tím submenu příslušné položky. Každý element má dvě vlastnosti, první („nazev“) určuje text položky menu a druhá volitelná položka určuje url stránky, na kterou se má po kliknutí přejít. (Samozřejmě, že akcí může být po kliknutí mnohem více, nemusí se striktně jednat o odskok na webovou stránku).

Tvorba menu

Nyní se pustíme do tvorby samotného menu. Ze všeho nejdříve musíme provést načtení a zpracování XML dat. Vytvoříme si proto prázdný MC, vložíme jej na scénu a pojmenujeme jej „menu0“. MC otevřeme a do prvního snímku vložíme první část kódu:

sirka_m = 195;
vyska_m = 40;
textData = new XML();
textData.ignoreWhite = true;
textData.load("menu_1.xml");
getSubs = function (node:XML, uroven:Number, mc:MovieClip) {
 z = 0;
 if (mc) {
  sirka = mc._parent._width;
  set("_level0.itemsArray"+(mc.uroven+1), new Array());
 }
 for (var ndSubs:XMLNode = node.firstChild; ndSubs != null; ndSubs=ndSubs.nextSibling) {
  z++;
  if (mc) {
   mc.attachMovie("menuItm", "menuI"+z, z);
   eval("mc.menuI"+z)._x = sirka_m;
   eval("mc.menuI"+z)._y = (z-1)*vyska_m;
   eval("mc.menuI"+z).txt.text = ndSubs.attributes.nazev;
   eval("mc.menuI"+z).targ = ndSubs.attributes.cil;
   eval("mc.menuI"+z).uroven = mc.uroven+1;
   eval("menuI"+z).adr = mc._name;
   if (ndSubs.hasChildNodes()) {
    eval("mc.menuI"+z).nd = ndSubs;
   }
   _level0.uroven = mc.uroven+1;
   eval("_level0.itemsArray"+(mc.uroven+1)).push(eval("mc.menuI"+z));
  } else {
   this.attachMovie("menuItm", "menuI"+z, this.getNextHighestDepth());
   eval("menuI"+z)._x = xpoz;
   eval("menuI"+z)._y = ypoz+(z-1)*vyska_m;
   eval("menuI"+z).txt.text = ndSubs.attributes.nazev;
   eval("menuI"+z).uroven = 1;
   eval("menuI"+z).adr = _name;
   if (ndSubs.hasChildNodes()) {
    eval("menuI"+z).nd = ndSubs;
   }
  }
 }
};

Než začneme zpracovávat XML data, musíme si připravit XML objekt, který dokument převezme. Po vytvoření tohoto objektu (textData) do něj načteme příslušný XML dokument. Ještě než budeme testovat úspěšné načtení dokumentu, připravíme si funkci, pomocí které zpracujeme načtená XML data.

Funkce se jmenuje „getSubs“ a bude sloužit pro vygenerování submenu příslušné položky. Z tohoto důvodu potřebujeme předat funkci několik proměnných, informujících o části XML dokumentu, která náleží zvolené položce menu, dále v jaké úrovni menu se nyní nacházíme a nakonec potřebujeme znát, o jakou položku se jedná.

Po otestování proměnné obsahující adresu MC, ze kterého chceme vytvořit submenu přistoupíme k samotnému rozboru XMl dokumentu. Zjistíme si z předaného XML elementu počet subelementů a z knihovny symbolů přetáhneme MC „menuItm“, který bude tvořit jednotlivé položky submenu (tento MC jsme si ještě nevytvořili).

Generování submenu máme rozdělené na dvě části, kde v druhé části generujeme základní úroveň a v první části generujeme další úrovně submenu.

Abychom mohli snadněji odstraňovat již zobrazené položky submenu, automaticky vytváříme pole, do kterých vkládáme cestu k vytvořeným položkám submenu. V další části pak budeme testovat úroveň, na které se nacházíme a pokud je třeba, vyhledáme příslušné pole adres a vymažeme všechny vytvořené položky submenu.

Pokračujeme dále tímto kódem:

textData.onLoad = function() {
 node1 = textData.firstChild;
 xpoz = new Number(node1.attributes.xpoz);
 ypoz = new Number(node1.attributes.ypoz);
 getSubs(node1, 0);
};
subAction = function (target) {
 if (target.targ != undefined) {
  getURL(target.targ, "_blank");
 }
};
removeSubs = function (target) {
 if (target.uroven<_level0.uroven) {
  dif = _level0.uroven-target.uroven+1;
  for (d=1; d<dif; d++) {
   arr = (eval("_level0.itemsArray"+(target.uroven+d)));
   delete eval("_level0.itemsArray"+(target.uroven+d));
   for (i=0; i<arr.length; i++) {
    unloadMovie(arr[i]);
   }
  }
 }
};

Zde nejdříve zjistíme stav načtení XML dokumentu, pokud je vše v pořádku, vygenerujeme první úroveň menu. Dále si zde připravíme funkci, která se spustí při kliknutí na položku menu. Sem můžeme umístit jakoukoliv akci, my zde máme pro začátek odskok na webovou stránku, jejíž adresu známe z XML dokumentu.

Jako poslední funkci jsme si připravili mazání již vytvořených položek submenu. Jak již bylo řečeno, pokaždé, když generujeme nové submenu, ukládáme do pole cesty k jednotlivým položkám. Při kliknutí na položku submenu pak testujeme úroveň, ve které se nacházíme, pokud je úroveň menší, než úroveň naposled rozbaleného menu, původně otevřené submenu vymažeme.

Položky menu

Nyní už zbývá vytvořit pouze položku menu, kterou při generování menu přetahujeme z knihovny na scénu. Vytvoříme si proto nový MC, do kterého vložíme dynamické textové pole, jehož instanci pojmenujeme „txt“. V tomto poli budeme zobrazovat název položky. Pod textovým polem vytvoříme pozadí, které převedeme na MC. Na takto vytvořený MC vložíme následující akce:

on (press) {
 _root.menu0.removeSubs(this._parent);
}
on (release) {
 if (this._parent.nd) {
  _root.menu0.getSubs(this._parent.nd, this._parent.uroven, this._parent);
 }
 _root.menu0.subAction(this._parent);
}

Zde po kliknutí na položku nejdříve vymažeme případná další otevřená submenu a po uvolnění tlačítky vygenerujeme menu nové.

Ukázku menu si můžete prohlédnout zde. Tato ukázka je exportována pro flashplayer 8. Zdrojové soubory dnešní ukázky si můžete stáhnout zde.

Diskuze (4) Další článek: It`s legal to... kdo stojí za fialovou kampaní

Témata článku: , , , , , , , , , , , , , ,