CL_Image
Budeme-li chtít vytvořit nějaké pěkné GUI, oceníme s největší pravděpodobnodstí možnost začlenit do něj nějaké obrázky. K tomuto účelu slouží právě třída CL_Image, která představuje komponentu reprezentující obrázek.
V GDF budeme chtít nastavovat typické atributy jako poloha a navíc atribut specifický právě pro image, kterým je surface. Tento atribut má podobný význam jako například surface_up u tlačítka. Znamená to, že jeho hodnotou je název nějakého surface z našeho souboru zdrojů.
Podíváte-li se na následující příklad, bude vám už určitě všechno jasné:
<surface name="PodkladovyObrazek" file="../zdroje/obrazky/obr.tga"/>
<image name="Obrazek" x="40" y="120" surface="PodkladovyObrazek"/>
Takto tedy zajistíme, že se v našem GUI vykreslí obrázek uložený v souboru obr.tga a příslušná komponenta, která ho bude reprezentovat, se bude jmenovat Obrazek a bude typu CL_Image.
Mimo GUI reprezentujeme samostatný obrázek v ClanLibu obvykle jako objekt třídy CL_Surface. CL_Image k vnitřní reprezentaci obrázku tuto třídu používá také. Není tedy divu, že umožňuje získat daný obrázek (nebo ho nastavit) jako CL_Surface pomocí následujících metod:
CL_Surface *get_surface() const;
void set_surface(CL_Surface *surface, bool delete_surface = false);
Druhý parametr v druhé metodě říká, jestli se má předchozí CL_Surface* v CL_Image zrušit operátorem delete.
CL_ProgressBar
Progress bary požíváme ke grafickému znázornění průběhu nějakého děje, jako je třeba kopírování souborů, načítání dat, instalace programu a podobně.
Jediným zvláštním atributem, který v GDF nastavujeme pro progress bar, je steps. Udává, z kolika kroků se bude znázorňovaný děj skládat. Tedy například děj o předpokládané době trvání okolo jedné minuty můžeme znázornit progress barem, který má nastaveno steps=„60“, a každou vteřinu pak posunout o jeden dílek. V GDF toto zapíšeme následujícím způsobem:
<progressbar name="pbar" x="10" y="10" width="60" height="20" steps="60" />
Progress bar patří k těm komponentám, na které si v našem programu skoro jistě získáme ukazatel (tj. ukazatel na CL_ProgressBar), jelikož budeme volat minimálně jeho metodu realizující posun. Touto metodou tedy začneme výčet metod poskytovaných třídou CL_ProgressBar:
void increase(int steps = 1);
Jak je vidět, můžeme posunovat o libovolný počet dílků.
void reset();
Asi každého napadne, že po zavolání této metody bude progress bar vypadat, jako bychom dosud nikdy nevolali metodu increase().
void set_progress(int progress);
Touto metodou můžeme přímo nastavit aktuální pozici progress baru, tj. počet kroků, které již máme za sebou.
int get_progress() const; float get_percentage() const;
Zmíněný počet již absolvovaných kroků je samozřejmě možné také zjišťovat, a to pomocí první z posledních dvou uvedených metod. Druhá nám vrací tuto hodnotu vyjádřenou jako procento z celkového počtu kroků.
Počet kroků se dozvíme pomocí poslední metody, kterou nám progress bar nabízí oproti rodičovské třídě CL_Component:
int get_steps() const;
CL_InputBox
Input box umožňuje uživateli zapsat do sebe nějaký textový řetězec. V GDF můžeme provést několik speciálních nastavení. Například je možné zadat textový řetězec, který se v input boxu objeví předvyplněný pomocí atributu text.
Pokud chceme tuto komponenetu využít k zadávání hesla, bude se nám hodit atribut passwordmode s možnými hodnotami true nebo false (defaultní). Zadáme-li true, budou se při psaní místo znaků zobrazovat hvězdičky.
Inbut box je možné zapnout také v módu pouze pro čtení atributem read_only. Jeho hodnotu v takovém případě nastavíme na true, defaultně je nastavena na false.
Nakonec je také možné omezit počet znaků, které bude možno zadat, a to pomocí atributu max_length, který má defaultní hodnotu nastavenu na unlimited, což znamená, že nijak neomezuje počet napsaných znaků.
Nastavení input boxu v GDF může vypadat třeba následovně:
<inputbox name="ibox" x="10" y="10" width="100" height="20" text="pocatecni text" />
Input box je reprezentovaný třídou CL_InputBox, která nám dává k dispozici zejména následující metody:
const std::string &get_text() const; const std::string &get_marked_text() const;
Metoda get_text() vrací celý řetězec zapsaný do inpout boxu jako string, zatímco get_marked_text() vrací pouze jeho označenou část.
void set_text(const std::string &text); void set_text(int number); void set_text(double number); void clear();
Pomocí set_text() tento řetězec můžeme nastavit. Po použití této metody se kurzor přesune na konec zadaného řetězce, který je samozřejmě v případě potřeby ořezán na maximální povolenou délku. Zruší se také případné označení části původního řetězce. Je možné použít i přetížené varianty pro zadání čísel, díky čemuž se nemusíme zabývat převodem čísla na řetězec.
int get_length() const;
Metoda get_length() vrací počet znaků zadaného řetězce.
int get_max_length() const; void set_max_length(int length);
První z metod slouží ke zjištění maximální povolené délky, druhá ji nastavuje.
bool in_password_mode() const; bool is_read_only() const; void set_password_mode(bool enable = true); void set_read_only(bool enable = true);
Nastavit samozřejmě můžeme i módy pro zadávání hesla, resp. mód pouze pro čtení, případně jsme schopni zjistit, zda je daný mód zapnutý.
int get_cursor_position() const; void set_cursor_position(int pos);
Není také problém zjistit nebo nastavit pozici kurzoru.
bool is_edited() const;
Metoda is_edited() vrací true, pokud byl obsah editován.
bool has_marked_text() const;
Jsme schopni zjistit i to, zda je nějaký text označen.
int get_selection_start() const; int get_selection_length() const;
V takovém případě nás může zajímat pozice prvního označeného znaku a délka celé označené části řetězce.
void set_selection(int start, int length); void select_all(); void deselect();
Můžeme pomocí set_selection() označit část řetězce zadané délky (druhý parametr) počínaje znakem na zadané pozici (první parametr), nebo pomocí select_all() označit vše (přesune kurzor nakonec), nebo zrušit případné označení pomocí deselect() (zanechá kurzor na svém místě).
void cut();
Označený text je možné pomocí cut() vyříznout.
void del();
Pomocí del() smažeme znak napravo od kurzoru, nebo smažeme případný označený text, což způsobí přesunutí kurzoru na místo, kde začíná nesmazaná část textu, který byl napravo od mazaného.
void backspace();
Metoda backspace() smaže znak nalevo od kurzoru, nebo smaže celý označený text a přesune kurzor na místo, kde by tento začínal.
void move_cursor(int delta, bool mark = false);
Pomocí move_cursor() posuneme kurzor o zadaný počet znaků (pokud je číslo delta záporné, posunujeme doleva, jinak doprava). Pokud jako druhý parametr předáme true, dojde k označení znaků, přes které se kurzor posouval.
void move_cursor_word(int delta, bool mark = false);
Tato metoda se chová obdobně jako předchozí, s tím rozdílem, že neposouvá po znacích, ale po slovech.
void home(bool mark = false);
Zde máme metodu, která způsobí přesun kurzoru úplně doleva. Podle toho, zda předáme true, nebo false dojde k označení resp. odznačení textu, po němž se kurzor přesouval.
void end(bool mark = false);
Obdobně lze kurzor přesunout zcela doprava.
void set_edited(bool on = true);
Pomocí set_edited() můžeme nastavit příznak, zda byl obsah editován, či ne, což se také děje automaticky. Zde však nejsme povini „mluvit pravdu“.
Použít můžeme i následující signály:
CL_Signal_v1<const std::string &> &sig_changed();
Tento je vyslán kdykoliv, když změníme text v input boxu. Jako parametr předává do funkce, k níž ho připojíme, nový řetězec.
CL_Signal_v0 &sig_return_pressed();
Signál vyslaný, pokud uživatel zmáčkne klavesu return. Na mé klávesnici to je pouze „větší z enterů“.
CL_Signal_v0 &sig_activity();
Signál vyslaný při jakékoliv aktivitě v input boxu, jako je třeba posun kurzoru a podobně.
CL_Signal_v2<char &, bool &> &sig_validate_character();
Tento signál je vyslán pokaždé, když uživatel zadává nějaký znak, avšak ještě předtím, než se zapíše, což nám dává možnost takový znak odmítnout.
Závěr
Seznam komponent, o kterých bych se ještě rád zmínil ve stylu posledních několika článků (včetně toho dnešního), se už konečně krátí. Na příště nám ještě zbývá CL_ListBox a několik komponent podobných message boxu, u nichž není typické nastavování v GDF.