V adresáři /usr/share/themes nalezneme motivy pro vzhled Gtk2 aplikací. Zde se dají také upravovat implicitní hodnoty pro různá nastavení.
Zkusme stručně nahlédnout, jak témata vlastně fungují.
Témata jsou zapsané v tzv. rc souborech, které mají speciální syntaxi. Jsou uložené zpravidla v adresáři /home/uživatel/.themes/ nebo na veřejném místě v /usr/share/themes/, případně /usr/local/share/themes/.
Nastavení témat pro naší aplikaci
Pro každý widget nastavujeme téma zvlášť. Můžeme ale využít dědičnosti. Na gnome.org najdeme widgetovou hierarchii. Protože všechny widgety dědí od Gtk::Widget, lze snadno nastavit všechny widgety najednou.
Je několik možností, jak téma použít uvnitř naší aplikace. Nejjednodušší je napsat si vlastní rc soubor a uvnitř aplikace ho pomocí Gtk2::Rc nastavit. To se dělá následovně.
Gtk2::Rc->parse("/usr/share/themes/MojeTema/gtk-2.0/gtkrc");
Analogický je následující příkaz.
Gtk2::Rc->parse_string("include "/usr/share/themes/MojeTema/gtk-2.0/gtkrc"");
Parametr příkazu je v tomto případě již psaný v rc syntaxi, přičemž include je příkaz pro načtení rc souboru. Díky parse_string můžeme vkládat rc syntaxi přímo do naší aplikace. Můžeme tedy psát příkazy následujícího typu.
Gtk2::Rc->parse_string(<<EOF);
include '/usr/share/themes/MojeTema/gtk-2.0/gtkrc'
style 'normal' {
font_name ='serif 30'
}
EOF
Vytváření témat
Podívejme se na syntaxi rc souborů. Chceme-li vytvořit téma s názvem MojeTema, pak se bude náš rc jmenovat /usr/share/themes/MojeTema/gtk-2.0/gtkrc.
Na začátku rc souboru může být série include příkazů, které se používají pro načítání nastavení z jiných souborů. Chceme-li téma logicky rozdělit do několika souborů (například soubor /usr/share/themes/MojeTema/gtk-2.0/tlacitka.rc může řešit vzhled tlačítek, soubor /usr/share/themes/MojeTema/gtk-2.0/dialogy.rc může řešit vzhled dialogů apod.), vložíme na začátek gtkrc následující řádky.
include "tlacitka.rc"
include "dialogy.rc"
include "ostatni.rc"
Dále definujeme takzvané styly. Obvykle vytvoříme jeden výchozí styl s názvem default a pak můžeme vytvořit několik dalších.
Styly mohou ovlivňovat buď implicitní nastavení (například velikost rámečku atd.) nebo zde můžeme definovat tzv. enginy.
Styl se vytváří následovně.
style "default" {
#nastavení
}
Vytvořme si na úvod jednoduchý styl. Náš gtkrc soubor bude vypadat takto.
style "default" {
xthickness = 1
ythickness = 1
GtkButton ::child-displacement-x = 6
GtkButton ::child-displacement-y = 2
bg[NORMAL] = "#333"
fg[NORMAL] = "#f0f0f0"
text[NORMAL] = "#0ff"
}
class "GtkWidget" style "default"
Nastavili jsme pro ukázku velikost mezery mezi textem a hranicí widgetu (xthickness, ythickness; používá se na různých místech), hloubku stisku tlačítka (o kolik se posune text na tlačítku při stisku) a barvu pozadí, popředí a textu v normálním stavu. Podívejme se, jak vypadá okno.
Náš tmavý theme
Podívejme se na některá nastavení.
Nejprve si všimněme nastavování implicitních hodnot. My jsme nastavili hodnoty child-displacement-x a child-displacement-y pro GtkButton. Chceme-li nastavit nějakou implicitní hodnotu pro daný widget, je vhodné se podívat do dokumentace, kde je seznam všech možných vlastností, možné hodnoty a vysvětlení, co která hodnota znamená. Tento seznam lze nalézt na live.gnome.org. Jakmile nalezneme vhodnou vlastnost, stačí ji zapsat do stylu v rc souboru ve tvaru JménoWidgetu::vlastnost = hodnota. Poznamenejme jen, že jméno widgetu v rc souborech neobsahuje :: (rc soubory nemají s Perl syntaxí nic společného).
Barvy
Barvy jsou vlastnost, která nás asi bude zajímat nejvíce. Jsou čtyři kategorie barev.
- bg - barva pozadí
- fg - barva popředí
- text - barva textu
- base - barva pozadí pro některé speciální widgety (například TextView, TreeView atd.)
Dále je pět stavů, ve kterých se může widget nacházet.
- NORMAL
- PRELIGHT - přejezd myší
- ACTIVE - pro právě stisknutá tlačítka
- SELECTED - pro vybranou oblast (například označený text)
- INSENSITIVE - neaktivní widgety (například formuláře, jejichž hodnoty nelze měnit)
Barvy nastavujeme vždy pro kategorii a stav. To zapisujeme kategorie[stav]. Tedy konkrétně například bg[NORMAL].
Barvy můžeme zadávat mnoha způsoby.
- přes kód barvy ve tvaru #RGB, #RRGGBB, #RRRGGGBBB, #RRRRGGGGBBBB
- {R, G, B}, kde hodnoty jsou mezi 0 a 1
- symbolickými názvy
- vlastními symbolickými názvy (ty se ve stylu definují příkazem barva["název"] = "#RRGGBB")
- pomocí efektů na změnu barev:
- lighter(barva)
- darker(barva)
- mix(typ, barva1, barva2)
- shade(typ, barva)
- pomocí proměnných
Pokud definujeme barvu pomocí proměnných, pak bychom měli ještě před definici stylů přiřadit do gtk_color_scheme a nastavit tím tak barvy pro celé téma. Hodnota pro gtk_color_scheme je seznamem hodnot, které jsou oddělené znakem nového řádku. Hodnoty jsou tvaru kategorie:barva, tedy například bg_color:#000. Používáme-li Gnome, je vhodné dodržovat následujících 8 kategorií: fg_color, bg_color, base_color, text_color, selected_bg_color, selected_fg_color, tooltip_bg_color, tooltip_fg_color.
Zde je příklad barevného schématu.
gtk_color_scheme = "fg_color:#010\nbg_color:#0f0\nbase_color:#fff\ntext_color:#f0f\n
selected_bg_color:#8ad\nselected_fg_color:#eee\ntooltip_bg_color:#ffb\ntooltip_fg_color:#000"
Barvy se potom zapisují jako @kategorie; například @bg_color.
Použití stylu
Již jsme si napsali jednoduchý styl. Gtk2 ale ještě neví, co s ním má dělat. Musíme nějak specifikovat, jaké styly se mají použít na jakých místech.
Příkazem class je možné asociovat styly jednotlivým prvkům a využít hierarchie widgetů. Podívejme se na následující řádky.
class "GtkButton" style "tlacitka"
class "GtkMenu" style "default"
class "GtkWidget" style "default"
Všechny widgety, které dědí od Gtk2::Button (například Gtk2::ToggleButton, Gtk2::VolumeButton, Gtk2::ColorButton) budou mít styl tlacitka. Všechny widgety dědící od Gtk2::Menu budou mít styl default. Pro všechny widgety, které nemají nastaven styl, jsme nastavili styl default.
Poznamnejme, že lze využít i žolíkových znaků.
Jiný příkaz pro aplikaci stylu je widget_class. Ten využívá vnoření widgetů do sebe. Máme-li v okně tlačítko a v něm nějaký text, jde o vnořené widgety. Vnoření popisku tlačítka v okně tak můžeme zapsat jako GtkWidget.GtkButton.GtkLabel.
Chceme-li tedy nastavit pro widgety uvnitř tlačítek typu Gtk2::Button styl uvnitr_tlacitek, zapíšeme to do souboru gtkrc tímto řádkem.
widget_class "*.GtkButton.*" style "uvnitr_tlacitek"
Kdybychom to chtěli aplikovat i na jiné typy tlačítek (tj. na všechny widgety, které od Gtk2::Button dědí), upravili bychom příkaz do nové podoby.
widget_class "*.<GtkButton>.*" style "uvnitr_tlacitek"
Ještě existuje příkaz widget, kterým nastavujeme vzhled pro konkrétní widget. Všechny widgety mohou mít svá jména, která nastavujeme příkazem set_name.
$widget->set_name("nebezpecne-tlacitko-spusteni-stepne-reakce");
Vzhled pak nastavíme již zmíněným příkazem widget.
widget "nebezpecne-tlacitko*" style "nebezpeci"
Enginy
Enginy umožňují použít uvnitř našeho stylu nějaký existující motiv. Pro inspiraci se můžeme podívat do /usr/share/themes/ (či podobněho adresáře), kde máme motivy uložené.
style "nas-styl" {
engine "thinice" {
#naše úpravy
}
}