XUL

Jiří Kosek


Obsah

Když se rozhraní potáhne kůží
XP = Cross Platform
XUL v akci
XBL
Závěrem
Další informace

O tom, že Mozilla je v mnoha ohledech jedinečný projekt a webový prohlížeč asi nikdo nepochybuje, potvrdilo to i získání ceny Produkt roku 2000. Málokdo však už ví, že kompletní uživatelské rozhraní prohlížeče je popsáno ve speciálním jazyce XUL. Díky tomu lze vzhled Mozilly velice snadno měnit a navíc lze jádro Mozilly ve spojení s XUL použít pro vytvoření uživatelského rozhraní ve vlastních programech.

Proč je vlastně v Mozille použit tento poněkud neobvyklý způsob vytváření uživatelského rozhraní? Ve většině jazyků se při tvorbě aplikací používá speciální knihovna, která umožňuje vytvářet dialogová okna, vkládat do nich různé prvky uživatelského rozhraní a komunikovat s nimi. Vývojáři windowsových aplikací nejspíše znají knihovnu MFC, existují i knihovny určené původně pro Linux jako Gtk a Qt. Problém je však v tom, že tyto knihovny podporují jednu a v lepším případě několik málo platforem. Existují verze knihoven Gtk a Qt určené i pro Windows, a existují i další multiplatformní knihovny jako wxWindows. S většími či menšími obtížemi tak lze vyvíjet aplikace, které půjde spustit na několika málo platformách.

Když se však podíváme na stránky projektu Mozilla, zjistíme, že prohlížeč je k dispozici pro opravdu širokou škálu platforem: Windows, MacOS, Linux, AIX, BeOS, OpenVMS, HPUX, FreeBSD, BSD/OS, Solaris, Irix, Tru64 Unix, DG/UX. Těžko bychom hledali nějakou knihovnu, která by umožnila vyvíjet grafické aplikace jednotným způsobem pro všechny tyto platformy.

Když se rozhraní potáhne kůží

Mozilla podporuje opravdu široké spektrum platforem, a tak se její vývojáři museli s problémem přenositelnosti vypořádat vlastními silami. Vytvořili přitom velice flexibilní systém, který přináší i další výhody. Jádrem Mozilly je zobrazovací engine Gecko. Ten umí zobrazovat HTML stránky a podporuje samozřejmě kaskádové styly (CSS) a JavaScript. Kromě HTML umí interpretovat i jazyk XUL (XML User Interface Language), který popisuje prvky uživatelského rozhraní jako menu, okna, vstupní pole, tlačítka apod. Mozilla, kterou vidíme na obrazovce našeho počítače, tedy není nic jiného než jedno okno, ve kterém Gecko zobrazuje uživatelské rozhraní definované pomocí XUL.

Samotný XUL nijak přesně nedefinuje vzhled rozhraní. Barvy, způsob zarovnání, velikost okrajů a obrázky, ze kterých se rozhraní skládá, jsou definovány nezávisle pomocí kaskádových stylů. Souboru kaskádových stylů a obrázků, které definují vzhled určité části aplikace, se říká skin. K jednomu XUL rozhraní můžeme mít několik definic vzhledu – skinů. V současné době se Mozilla distribuuje se třemi skiny – Classic, Modern a Blue (viz obrázek 1).

Obrázek 1. Při použití XUL jsou důsledně odděleny jednotlivé prvky uživatelského rozhraní a jejich vzhled. Vytvoření skinů, které upraví vzhled prohlížeče, je proto poměrně jednoduché. Přídavné skiny lze získat například na adrese http://x.themes.org.

XP = Cross Platform

XUL a kaskádové styly řeší pouze zobrazení uživatelského rozhraní. Každá smysluplná aplikace však musí reagovat na požadavky uživatele. Přímo v XUL lze proto pro jednotlivé události vyvolávané uživatelem definovat kód v JavaScriptu, který se postará o obsluhu události. Samozřejmě, že v JavaScriptu nelze psát nějaké velké a složité aplikace. Mozilla proto obsahuje sadu několika technologií, které umožňují pomocí JavaScriptu vyvolávat nativní kód napsaný v C++ a dalších jazycích.

Všechny technologie, které se používají pro propojení JavaScriptu s nativním kódem, mají v názvu písmena „XP“, které symbolizují přenositelnost mezi platformami. Základem psaní přenositelného binárního kódu je XPCOM (cross-platform component object model). Jedná se obdobu rozhraní COM znamého z Windows. Pokud píšeme nějaký kód například v C++ vytvoříme pro něj XPCOM obálku, která obsahuje rozhraní nezávislé na jazyku a použité platformě. Ostatní komponenty pak mohou snadno využívat služby nabízené tímto objektem. Samotný kód v C++ samozřejmě musíme vždy zkompilovat pro konkrétní platformu, ale způsob vyvolání tohoto kódu je díky XPCOMu stejný na všech systémech.

XPIDL (cross-platform interface definition language) umožňuje popsat rozhraní definovaná jednotlivými objekty. Jeho syntaxe je velice blízká jazyku IDL. Pomocí speciálního kompilátoru pak můžeme z XPIDL automaticky vygenerovat hlavičkové soubory a další potřebné soubory pro snazší vytvoření XPCOM objektů.

O samotné propojení JavaScriptu a objektů XPCOM se stará technologie XPConnect, které umožňuje přímé volání XPCOM objektů z JavaScriptu a naopak. Vzájemné propojení jednotlivých XP-technologií je zachyceno na obrázku 2.

Obrázek 2. XP-architektura

XUL v akci

Jelikož je Mozilla poměrně mladý projekt, byl výběr syntaxe jazyka XUL poměrně jednoduchý – XUL je jazyk založený na XML. Pro jednotlivé prvky uživatelského rozhraní existují odpovídající XML elementy. Chování prvků je pak ovlivňováno pomocí parametrů, které se zapisují jako XML atributy. Vzhled prvků je definován pomocí kaskádového stylu.

K dispozici máme všechny běžné prvky uživatelského rozhraní:

  • okna a dialogová okna;

  • menu, submenu a položky menu;

  • přepínací tlačítka;

  • zaškrtávací tlačítka;

  • lišty nástrojů;

  • textové popisky a obrázky;

  • vstupní textová pole;

  • tlačítka;

  • karty se záložkami;

  • pop-up menu;

  • seznamy a hierarchické (stromové) seznamy;

Kromě těchto standardních prvků můžeme v XULu používat libovolné HTML elementy, které se do dokumentu vkládají pomocí zvláštního jmenného prostoru.

Vzájemné umístění prvků lze ovládat třemi způsoby. První možností je uzavírat skupiny prvků do boxů, které se skládají vedle sebe nebo nad sebe. Tento způsob je velice jednoduchý a pro většinu aplikací s ním bohatě vystačíme. Další možností je použít některý ze zabudovaných layout managerů. Poslední možností je nastavit umístění prvků pomocí kaskádového stylu.

Na ukázce 1 je zdrojový kód jednoduchého aplikačního okna zapsaný v XUL. Je na něm demonstrováno použití některých ovládacích prvků. Propojení kódu s uživatelskými akcemi se děje podobně jako v HTML pomocí událostí. U každého elementu můžeme použít speciální atributy, které odpovídají jednotlivým akcím provedeným uživatelem. Jako hodnotu tohoto atributu pak uvedeme javascriptový kód, který se použije pro obsloužení události. Jednoduché aplikace vystačí pouze s JavaScriptem, ty složitější pak zavolají binární objekty pomocí XPConnectu. Mezi nejpoužívanější událost patří oncommand, která se vyvolává např. výběrem z menu nebo stiskem tlačítka.

Příklad 1. Ukázka okna s nejběžnějšími ovládacími prvky

<?xml version="1.0" encoding="windows-1250"?>                        (1)
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>      (2)
<window id="test-window" title="Ukázkové okénko" align="vertical"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <menubar>                                                          (3)
    <menu id="file-menu" value="File" accesskey="F">
      <menupopup id="file-popup">
        <menuitem value="New" oncommand="alert('Nový soubor')"/>     (4)
        <menuitem value="Open" acceltext="Ctrl+O"/>
        <menuitem value="Save" disabled="true"/>
        <menuseparator/>
        <menuitem value="Exit" accesskey="x"/>
      </menupopup>
    </menu>
    <menu id="edit-menu" value="Edit">
      <menupopup id="edit-popup">
        <menuitem value="Undo"/>
        <menuitem value="Redo"/>
      </menupopup>
    </menu>
  </menubar>
  <tabcontrol>                                                       (5)
    <tabbox>
      <tab value="SWN"/>
      <tab value="Inside"/>
    </tabbox>
    <tabpanel>
      <box align="center" autostretch="never">
        <text value="Počet kusů:"/>
        <textfield value="10" width="30"/>
        <button value="Objednat!"/>
      </box>
      <vbox>                                                         (6)
        <hbox>                                                       (6)
          <text value="Vzkaz:"/>
          <textfield multiline="true" width="250" height="120"/>
        </hbox>
        <hbox align="center">                                        (6)
          <button value="Předplatit!"/>
        </hbox>
      </vbox>
    </tabpanel>
  </tabcontrol>
  <hbox>                                                             (6)
    <vbox>                                                           (6)
      <checkbox value="Hardware"/>                                   (7)
      <checkbox value="Software" checked="true"/>
      <checkbox src="ikona.gif"/>
    </vbox>
    <vbox style="background-color: red">                             (6)
      <radiogroup align="vertical">                                  (8)
        <radio value="6 měsíců"/>
        <radio value="1 rok"/>
        <radio value="5 let"/>
        <radio value="doživotí"/>
      </radiogroup>
    </vbox>
  </hbox>
</window>
1

XUL soubor je XML dokument a začíná proto XML deklarací, která mj. obsahuje i kódování použité dále v dokumentu.

2

Načtení kaskádového stylu, který definuje vzhled pro jednotlivé prvky UI. Načte se styl odpovídající právě aktivnímu skinu v Mozille.

3

Definice menu včetně jednotlivých položek. U každého položky lze pomocí atributů definovat např. klávesovou zkratku a další vlastnosti.

4

Kód uvedený v atributu oncommand se provede při výběru příkazu z menu.

5

Karta se záložkami. Pro každou kartu se definuje zvlášť její název a obsah.

6

Skládáním horizontálních a vertikálních boxů můžeme jednoduše a flexibilně určit vzájemnou pozici ovládacích prvků.

7

Zaškrtávací tlačítka.

8

Skupina přepínacích tlačítek.

Pokud si budeme chtít sami XUL vyzkoušet, stačí definice nějakého okna uložit do souboru s příponou xul. Tento soubor pak můžeme otevřít v Mozille jako běžnou HTML stránku. Místo stránky se nám zobrazí definované okno (viz obrázek 3).

Obrázek 3. XUL dokument natažený přímo v Mozille

Tento způsob práce je dobrý jen pokud si chceme možnosti XULu vyzkoušet. Ve vlastní aplikaci samozřejmě nechceme, aby se zobrazovala jako součást okna prohlížeče. Proto lze při startu Mozilly říci, který XUL soubor má načíst místo souboru s definicí rozhraní prohlížeče. V tomto případě však musí být již XUL soubor zaregistrován mezi ty ostatní. Když se podíváte do podadresáře chrome v instalaci Mozilly zjistíte, že jsou zde XUL soubory pro celý prohlížeč, včetně stylů a obrázků pro jednotlivé skiny.

Pro náš XUL soubor si v tomto adresáři vytvoříme vlastní adresář, např. test/content/test. Do něj umístíme náš XUL soubor (např. test.xul). Do stejného adresáře musíme umístit popisný soubor contents.rdf).

<?xml version="1.0" encoding="windows-1250"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:chrome="http://www.mozilla.org/rdf/chrome#">

  <!-- seznam popisovaných balíčků -->
  <RDF:Seq about="urn:mozilla:package:root">
    <RDF:li resource="urn:mozilla:package:test"/>
  </RDF:Seq>

  <!-- informace o balíčku -->
  <RDF:Description about="urn:mozilla:package:test"
        chrome:displayName="Testovací balíček"
        chrome:author="Jirka Kosek"
        chrome:name="Test">
  </RDF:Description>

</RDF:RDF>

Na konec souboru installed-chrome.txt v adresáři chrome přidáme řádku popisující náš balíček s jedním XUL oknem:

content,install,url,resource:/chrome/test/content/test/

Nyní musíme Mozillu restartovat, aby si přeregistrovala všechny balíčky s XUL soubory. Naši XUL aplikaci pak spustíme pomocí příkazu:

mozilla -chrome chrome://test/content/test.xul

Nastartuje se jádro Mozilly (Gecko), ale nezobrazí se celý prohlížeč, pouze námi definované okno (viz obrázek 4).

Obrázek 4. Samostatně zobrazený XUL dokument už vypadá jako běžné aplikační okno

XBL

V současné podobě lze pomocí jazyků XUL a CSS dosáhnout oddělení definice chování rozhraní od jeho vzhledu. Lze tak poměrně jednoduše vytvářet skiny. Pokud bychom však chtěli, aby skin změnil i způsob ovládání – například jiné reakce na události apod. – museli bychom kompletně změnit příslušný XUL soubor.

Vývojáři Mozilly proto přišli s novým jazykem XBL (Extensible Bindings Language), který umožňuje definovat obsluhu událostí mimo XUL (případně HTML) kód. Základní princip je přitom stejný jako při použití oddělených definic chování (behavior), se kterými přišel už Internet Explorer 5. Kaskádový styl může pro každý element kromě prezentačních vlastností definovat jméno souboru, který obsahuje definice funkcí obsluhujících jednotlivé události. V závislosti na použitém stylu se pak může změnit i chování celé aplikace. Jelikož je v Mozille skin jen sada kaskádových stylů, lze nyní při změně skinu změnit i chování aplikace.

Závěrem

XUL, a vůbec celá architektura Mozilly, je velice zajímavá. V článku jsme se jen lehce dotkli některých možností. I když lze XUL a Gecko použít pro tvorbu aplikací přenositelných mezi platformami, nemyslím si, že by to byl hlavní přínos. Samotné jádro Mozilly, které XUL kód interpretuje zabere v paměti poměrně dost místa, které by jinak mohla využívat aplikace. Při vývoji multiplatformních aplikací je proto asi stále lepší sáhnout po nějaké speciální knihovně, případně po Javě.

Otevřená architektura Mozilly se podle mne využije především při rozšiřování schopností prohlížeče. Možnost tvorby skinů pro aplikaci jako je webový prohlížeč je dnes kvůli jeho cílové uživatelské skupině už nutností. Pomocí XULu však můžeme jednoduše upravit rozhraní Mozilly – přidat okno pro aktuální firemní zprávy, burzovní zpravodajství, pohodlné vyhledávání atd. Z prohlížeče se tak dá velice snadno vytvořit pohodlné prostředí pro vstup do digitálního komunikačního světa. Ne nadarmo je Mozilla pokračovatelem Netscape Communicatoru.

Další informace

http://www.mozilla.org

Stránka se vším, co se týká Mozilly

http://www.mozilla.org/docs/

Vývojářská dokumentace k Mozille

http://www.mozilla.org/xpfe/xulref/

XUL reference

http://www.xulplanet.com/tutorials/

XUL tutoriál

© Jiří Kosek 2002