Modul Curses::UI je objektově-orientovanou nadstavbou pro Curses a umí vytvářet textová uživatelská rozhraní rychleji a lépe, než jsme toho byli schopni dosud.
4.2.2010 18:00 | Jiří Václavík | přečteno 13590×
Curses::UI je objektově orientovaný modul, který poskytuje rozhraní pro práci s Curses. Psaní aplikací pomocí Curses::UI je daleko rychlejší. To především díky tomu, že zde již máme předprogramované komponenty (widgety), ze kterých se programy skládají.
Modul je třeba nainstalovat obvyklým způsobem.
$ cpan Curses::UI
Pro inicializaci Curses::UI módu je třeba začít těmito dvěma řádky. Vytvoříme objekt typu Curses::UI.
use Curses::UI;
$cui = new Curses::UI;
Odteď již můžeme používat nadefinované widgety. Ještě předtím si ale zmiňme alespoň dva parametry konstruktoru. Prvním je -color_support => 1, který zapíná podporu barev. Pak je zde parametr -language (hodnota pro češtinu je czech - to znamená, že se použije překlad v modulu Curses::UI::Language::czech), avšak ten není zmíněn v dokumentaci.
my $cui = new Curses::UI(-color_support => 1);
Abychom předali řízení programu objektu, zavoláme na konci metodu mainloop.
$cui->mainloop;
Dnes si představíme několik widgetů z Curses::UI a příště je použijeme k napsání textového editoru.
Začněme zobrazováním dialogových oken. Díky metodě dialog je zobrazování velmi jednoduché a rychlé - stejně tak jako u všech dalších widgetů, které budou následovat. Existuje několik druhů dialogových oken.
Nejjednodušším použitím je informativní dialog, kterému předáme pouze řetězec.
Chceme-li dialog s otázkou, je třeba definovat několik parametrů. Předně to je -message, což je samotná otázka. Dále jsou to tlačítka a jejich hodnoty. Jako tlačítka lze použít hodnoty yes, no a cancel. Texty tlačítek ale nakonec budou zobrazeny ve vybraném jazyce. Návratovou hodnotou metody dialog je jedna z hodnot parametru -values podle toho, které tlačítko bylo stisknuto.
Tento příklad ilustruje práci s dialogy.
use Curses::UI;
$cui = new Curses::UI;
$souhlas = $cui->dialog(
-title => "dialog",
-message => "Souhlasite?",
-buttons => ["yes", "no"],
-values => [1, 0],
);
$cui->dialog($souhlas ? "Souhlasite" : "Nesouhlasite");
Vytvořili jsme dva dialogy. Na obrázku můžeme vidět, jak bude v takovém případě vypadat program.
Existuje ještě další typ dialogu, který se používá u hlášek pro varování o chybách. Zde ovšem už používáme metodu error.
$cui->error("Neco je spatne");
Nezbytnou součástí většiny složitějších aplikací je menu. Pro něj zde máme definován widget Curses::UI::Menubar. Umí všechny základní vlastnosti menu včetně vytváření submenu.
Pro přidání widgetu se se používá metoda add, která má řadu parametrů. Prvními dvěmi hodnotami jsou ID a jméno widgetu - tedy v případě menu je to Menubar.
Dále můžeme přidat parametry -fg a -bg pro barvu textu a pozadí.
Nejdůležitějším parametrem však je -menu, kterému předáváme složitou datovou strukturu. Nebudeme si ji blíže rozebírat, protože by to mělo být zřejmé z následujícího příkladu.
my @menu = (
{
-label => "Menu1", -submenu => [
{-label => "Polozka", -value => "1"},
{-label => "Submenu", -submenu =>
[
{-label => "Polozka", -value => "2"},
{-label => "Polozka", -value => "3"},
]
},
{-label => "Konec", -value => \&exit_dialog},
]
},
{
-label => "Menu2", -submenu =>[
{-label => "Polozka", -value => "4"},
{-label => "Polozka", -value => "5"},
]
},
);
Nyní přidáme menu widget do aplikace
use Curses::UI;
my $cui = new Curses::UI(-color_support => 1, -language => "czech");
my $menu = $cui->add(
"menu",
"Menubar",
-menu =>\@menu,
-fg => "white",
-bg => "blue"
);
$cui->mainloop;
Jedna z položek vykonává po vybrání podprogram exit_dialog, který musíme dopsat.
sub exit_dialog {
exit if $cui->dialog(
-message => "Konec?",
-title => "konec",
-buttons => ["yes", "no"],
);
}
Po stisku této položky a potvrzení se program ukončí.
Funkcí set_binding můžeme navázat k podprogramům klávesové zkratky. set_binding má tento tvar volání.
$cui->set_binding(\&podprogram, klávesová_zkratka);
Konkrétní příkaz pro svázání zkratky Ctrl-o s voláním podprogramu open_file může vypadat třeba takto.
$cui->set_binding(\&open_file, "\\cO");
Velice často se jako úvodní parametr používají anonymní podprogramy. Následující příkaz sváže stisk tabulátoru s přesunem kurzoru na menu.
$cui->set_binding(sub {$menu->focus();}, "\t");
Metodu focus, která přesune kurzor do příslušného widgetu, lze díky dědičnosti volat i nad většinou ostatních widgetů, které si dnes budeme představovat nebo které naleznete v dokumentaci k Curses::UI.
Mimo menu musí být všechny labely v okně. Pro vytváření dalších widgetů je tedy třeba nejprve vytvořit jim okno.
my $okno = $cui->add("okno1", "Window");
A poté tomuto oknu přiřadíme widget.
my $widget = $okno->add(...);
Pro nápis kamkoliv na obrazovku slouží widget Label, kterému stačí předat text a souřadnice v aktuálním okně.
my $label = $okno->add(
"label", "Label",
-text => "LABEL",
-x => 10,
-y => 5,
-bold => 1,
);
$label->draw;
Dalším widgetem, se kterým se seznámíme, a který budeme ještě potřebovat, je Texteditor, v němž může uživatel editovat text.
my $texteditor = $dalsi_okno->add(
"text", "TextEditor",
-border => 1
);
Aby mohl uživatel vybírat soubory z adresářové struktury, máme zde widget filebrowser. Ten ještě dále můžeme dělit na openfilebrowser a savefilebrowser. Parametrem widgetu filebrowser je cesta, ve které má výběr začínat.
my $file = $cui->filebrowser(
-path => "/"
);
if(defined $file){
$cui->dialog("Vybral jste soubor $file");
}else{
$cui->error("Nevybral jste zadny soubor");
}
Pro zobrazení kalendáře zde je widget Calendar. Parametr -date specifikuje úvodní datum, na které má být kalendář nastaven.
my $kalendar = $okno->add(
"mylabel", "Calendar",
-date => "2010-3-8"
);
Ještě uveďme použití widgetu Radiobuttonbox. Pomocí nich může uživatel vybírat jednu z definovaných voleb. K podobným účelům lze užít též Listbox.
my $radio = $okno->add(
"radio", "Radiobuttonbox",
-values => [1, 2, 3],
-labels => {
1 => "Volba 1",
2 => "Volba 2",
3 => "Volba 3"
}
);
my $volba = $radio->get();
Na závěr si uveďmě widget Progressbar. Ten obvykle uvádí, kolik procent něčeho je hotovo. Příklad progressbaru, který 20 sekund čeká, je zde.
$cui->progress(
-max => 20,
-message => "cekejte 20 sekund",
);
for (0..20) {
$cui->setprogress($_);
sleep 1;
}