Hlavní navigace

Dokončujeme textový editor v Gtkmm

Tomáš Velecký

Tento díl seriálu o Gtkmm vylepšuje nás textový editor nutnými novými widgety. Většina z nich jsou prachobyčejné widgety, nicméně tři z nich ale tvoří hned několik widgetů najednou. Ano, jsou to standardizovaná dialogová okna. Pro rychlou úpravu textu se hodí schránka, která také nezůstane opomenuta.

Doba čtení: 5 minut

Dialog na otevření souboru

Všechna dialogová okna, která něco dělají se soubory nebo složkami, je vlastně jedna a ta samá třída, FileChooserDialog. Hlavní informace, tedy, jaký bude mít dané dialogové okno název a co má dělat, předáváme přímo konstruktoru. Na výběr máme tyto typy:

  • FILE_CHOOSER_AC­TION_OPEN
  • FILE_CHOOSER_AC­TION_SAVE
  • FILE_CHOOSER_AC­TION_SELECT_FOL­DER
  • FILE_CHOOSER_AC­TION_CREATE_FOL­DER

Takto vypadá např. dialog na uložení souboru:

Dále můžeme pomocí metody add_button() přidávat tlačítka. To si buď pojmenujeme sami (typ Glib::ustring), nebo zvolíme jeden z BuiltinStockID. Těch je docela dost, proto je zde nebudu vypisovat, ale pouze na ně odkazuji. K tlačítkům se vždy přiřadí událost (signál), která se vygeneruje, když se na dané tlačítko klikne. Několik událostí už je předdefinovaných a jejich seznam vidíte níže. Lze však zadat jakékoli číslo (typu int), ovšem předchozí možnost je jaksi názornější.

  • RESPONSE_NONE
  • RESPONSE_REJECT
  • RESPONSE_ACCEPT
  • RESPONSE_DELE­TE_EVENT
  • RESPONSE_OK
  • RESPONSE_CANCEL
  • RESPONSE_CLOSE
  • RESPONSE_YES
  • RESPONSE_NO
  • RESPONSE_APPLY
  • RESPONSE_HELP

Abychom se dozvěděli, co uživatel s dialogovým oknem udělal, uložíme si návratovou hodnotu metody run() (ta dialog spouští) a použijeme běžný switch. Asi tak, jak to vidíte níže.

#include <gtkmm.h>

class Okno : public Gtk::Window {
    public:
        Okno();
        void VyberSoubor();

    protected:
        Gtk::VBox ram;
        Gtk::Button tlacitko;
        Gtk::Label cesta;
};

Okno::Okno() {
    tlacitko.set_label("Vyber soubor");
    tlacitko.signal_clicked().connect(sigc::mem_fun(*this, &Okno::VyberSoubor));
    cesta.set_text("Ještě nebyl vybrán žádný soubor.");

    add(ram);
    ram.pack_start(tlacitko);
    ram.pack_end(cesta);
    show_all_children();
}

void Okno::VyberSoubor() {
    Gtk::FileChooserDialog dialog("Výběr souboru", Gtk::FILE_CHOOSER_ACTION_SAVE);
    dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
    dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);

    int odpoved = dialog.run();
    switch(odpoved) {
        case(Gtk::RESPONSE_OK): {
            cesta.set_text(dialog.get_filename());
      break;
    }
    case(Gtk::RESPONSE_CANCEL): {
      break;
    }
    default: {
      break;
    }
  }
}

int main(int argc, char *argv[]) {
    Gtk::Main kit(argc, argv);
    Okno okno;
    Gtk::Main::run(okno);
    return 0;
}

Notebook

Notebook je kontejner, který může mít několik stránek, mezi kterými se dá přepínat.

Vše zaštiťuje třída Gtk::Notebook. Metoda get_current_page() vrátí číslo právě aktivní stránky, page_num() vrátí číslo stránky, ve které se nachází předaný widget. Tato čísla budeme potřebovat při zavírání a aktivování stránek metodami remove_page() a set_current_page(). set_current_page() musíme předat číslo stránky, remove_page() nám dává na výběr mezi číslem stránky a widgetem, který je v ní. get_n_pages() vrací počet stránek v notebooku.

Nakonec to nejdůležitější. O přidání nové stránky se postará append_page(), která požaduje jen widget, který má nová stránka obsahovat. Tuto stránku se také hodí nějak označit. Nejjednodušší je použít metodu set_tab_label_text(widget_v_dané_stránce, označení), jenž je však schopna nastavit pouhý text. Za to set_tab_label(widget_v_dané_stránce, widget_v_popisku) je oprávněna použít k označení stránky jakýkoli widget. V praxi tam tak můžeme vložit kontejner, který bude obsahovat třeba ikonku představující typ souboru, název souboru, hvězdičku, která značí, že byl soubor nějak upraven a křížek, který se postará o zavření stránky („tabu“).

SrolledWindow

Textový editor je od toho, aby se v něm psal text. Většinou dlouh. Někdy dost dlouhý. Aby se v něm uživatel vyznal, byly vynalezeny posuvníky. Těmi „obalíme“ vstupní pole. Jak? Stačí jej vložit do kontejneru ScrolledWindow ( add(Gtk::Widget&)). K základnímu nastavení chování ScrolledWindow slouží metoda set_policy(), kde první argument nastavuje vodorovný, druhý svislý posuvník. I tady máme na výběz z několika možností.

  • Gtk::POLICY_ALWAYS
  • Gtk::POLICY_A­UTOMATIC
  • Gtk::POLICY_NEVER

POLICY_ALWAYS posuvník zobrazí za jakýchkoli okolností, POLICY_NEVER jej nezobrazí vůbec, POLICY_AUTOMATIC jen tehdy, když bude v poli příliš mnoho textu (tzn., že se do tohoto pole nevejde) a pokud metodu set_policy() nepoužijeme vůbec, zobrazí se oba posuvníky i při prázdném vstupním poli.

Schránka

Při práci se schránkou se využívá třídy chytrého ukazatele Glib::RefPtr. Deklarace vypadá nějak takto: Glib::RefPtr<Gtk::Clipboard> schranka;. V konstruktoru hlavního okna našeho editoru bude akorát schranka = Gtk::Clipboard::get();  – tímto získáme ukazatel na schránku. To bylo z přípravy práce se schránkou vše. K samotné práci s textem se většinou použije vždy jeden z těchto tří příkazů:

editacni_pole.get_buffer()->cut_clipboard(schranka, true);
editacni_pole.get_buffer()->copy_clipboard(schranka);
editacni_pole.get_buffer()->paste_clipboard(schranka, true);

Metoda get_buffer() vrací ukazatel na Gtk::TextBuffer, třídu obsahující text obsažený např. v Gtk::TextView.

Stavový řádek

Stavový řádek je většinou ten úzký pruh dole na úplném okraji okna, kde dostáváme základní informace o běhu programu, nějakou nápovědu, případně informace o pozici kurzoru apod.

Práce s ním je velmi jednoduchá. Jedná se o třídu Gtk::Statusbar a nový text do něj dostaneme za použití metody push(), které předáme požadovaný řetězec a „číslo kontextu“ (int). To znamená, že tam můžeme zobrazit nějaký text, ten následně přepsat a až se to bude hodit, zobrazit bez opětovného předávání řetězce ten původní. Řetězec s nějakým „číslem kontextu“ se maže metodou pop(guint context_id).

Ukázkový program

Tentokrát je pro přehlednost ukázkový program rozložen na tři díly. Prvním dílem je třída hlavního okna editoru, dalším metody pro práci se soubory a poslední obsahuje funkci main a několik různých metod.

Pokračování

Příště se pravděpodobně naučíme pracovat s Glade. Mám v plánu podívat se na práci s tiskárnou, popř. na novinky v Gtkmm 3. Další náměty můžete psát do diskuze.

Našli jste v článku chybu?