20. Paleta nástrojů
  1. Řada aplikací bývá také vybavena paletou nástrojů. Paleta nástrojů obvykle obsahuje určitý počet tlačítek, která můžeme stisknout myší a které spouští příkazy nebo přepínají volby. Paleta nástrojů může také někdy obsahovat komponentu ComboBox, editační ovladač nebo jiný ovládací prvek. Poslední generace palet nástrojů mohou být přemisťovány po ploše okna nebo mohou být umístěny úplně mimo jako samostatné okno s polem tlačítek. Aplikace může také obsahovat stavový řádek, který má obvykle jednu nebo více ploch s textovým popisem současného stavu programu. Může zde být plocha pro souřadnice, pro zobrazení aktivního písma nebo pro zobrazení nápovědy, chybového hlášení atd. Pro vytvoření palety nástrojů nebo stavového řádku můžeme použít komponentu Panel a do ní můžeme přidat tlačítka nebo další panely. Panel můžeme považovat za nástroj pro rozdělení uživatelské plochy na různé části a pro seskupení dalších komponent. Panel může mít vlastní text, ale většinou se tato možnost nevyužívá. Panely ale často vytvářejí trojrozměrné zobrazení (pomocí vlastností BevelInner a BevelOuter) a zlepšují tak vzhled aplikace. Panel obvykle umisťujeme na určitou plochu formuláře a měníme hodnotu jeho vlastnosti Align. U typické palety nástrojů použijeme hodnotu alTop a u stavového řádku použijeme alBottom. Panel může využívat vlastnosti Hint a ShowHints k zobrazování bublinkové nápovědy.

  2. V následující aplikaci se pokusíme vytvořit typický panel nástrojů. Panel umístíme na horní okraj formuláře a na něj vložíme několik komponent SpeedButton. Začneme s vývojem nové aplikace. Na formulář umístíme komponentu Panel a nastavíme její vlastnost Align na alTop. Na formulář dále umístíme komponentu Label, u které nastavíme vlastnosti: Align na alClient, AutoSize na false, Caption na Text, na kterém budeme ukazovat vliv tlačítek na paletě komponent, ParentFont na false a WordWrap na true. U formuláře nastavíme vlastnost ActiveControl na Panel1. Na panel budeme postupně přidávat komponenty SpeedButton podle následujícího obrázku (symboly tlačítek se pokusíme najít v knihovně obrázků nebo je nakreslíme; rozměry 17 x 17). Symboly obrázků lze také stáhnout - stažení obrázků.
    Jestliže přidáme SpeedButton můžeme jednoduše napsat jeho obsluhu události OnClick (implicitní událost). V našem programu k prvnímu tlačítku přiřadíme příkaz:
    MessageBeep($FFFF);
    Dále přidáme skupinu tlačítek, která budou fungovat jako přepínací tlačítka. U všech nastavíme hodnotu GroupIndex na stejnou hodnotu (v našem případě na 1). V naši aplikaci budou tři a budeme jimi ovládat zarovnávání textu. Jedno z těchto tlačítek by mělo být vybráno (nastavíme jeho vlastnost Down na true; v našem případě to bude tlačítko označující zarovnávání textu doleva). Obsluhy stisku těchto tlačítek budou obdobné. Pro tlačítko zarovnávání vlevo bude použit příkaz:
    Label1->Alignment = taLeftJustify;
    Vytvořte obsluhy pro stisk dalších dvou tlačítek. Další tři tlačítka budou určovat styl použitého textu. Může jich být stisknuto několik (nebo i žádné). Pro všechna nastavíme GroupIndex na stejnou hodnotu (v našem případě na 2) a AllowAllUp na true. Pro všechna tři tlačítka zde bude stejná obsluha OnClick a bude tvořena příkazy:
    TFontStyles X;
    if (SpeedButton5->Down) X << fsBold;
    if (SpeedButton6->Down) X << fsItalic;
    if (SpeedButton7->Down) X << fsUnderline;
    Label1->Font->Style = X;
    Poslední tlačítko může zůstat stisknuté. To dosáhneme tím, že jeho hodnotu GroupIndex nastavíme na jinou hodnotu než mají ostatní tlačítka (např. na 3) a AllowAllUp na true. Obsluha OnClick tohoto tlačítka bude tvořena příkazy:
    if (SpeedButton8->Down) Label1->Font->Size = 24;
    else Label1->Font->Size = 12;
    Aplikace je hotova a můžeme ji vyzkoušet.
  3. Naše aplikace z předchozího zadání má standardní chování. Každý SpeedButton může využívat i více různých bitových map bez toho, aby je bylo nutno měnit ručně. Je to obdoba BitBtn z aplikace vytvořené podle zadání 7 z kapitoly Formuláře II (tlačítko Pal). V následujícím rozšíření předchozí aplikace si také ukážeme jak některá tlačítka palety nástrojů zakázat. Do předchozí aplikace přidáme tuto nabídku:
  4. Soubor Paleta nástrojů Nápověda
    Konec Viditelná O aplikaci
    Zakázat zvuk
    Zakázat styly
    Zakázat velikost
    Vlastnost Checked u prvku nabídky Viditelná nastavíme na true. Můžeme začít s vytvářením obsluh jednotlivých voleb. Volba Viditelná bude obsloužena příkazy:
    Panel1->Visible = ! Panel1->Visible;
    Viditeln1->Checked = ! Viditeln1->Checked;
    Obdobně pro volbu Zakázat zvuk negujeme hodnotu dvou vlastností (SpeedButton1->Enabled a Zakzatzvuk->Checked). U volby Zakázat styly musíme povolit nebo zakázat všechna tři tlačítka stylů. Vytvořte zbývající obsluhy sami.
    Normálně Builder používá pro SpeedButton tři verze bitových map: normální, zakázané a stisknuté. Pro poslední tlačítko použijeme vlastní verzi symbolů (72 x 17) - soubor tohoto obrázku (big4.bmp) jsme stáhli v předchozím zadání s ostatními obrázky.
    Poslední stav je zůstaň stisknutý. Aplikaci můžeme vyzkoušet. Je zde ale jeden nedostatek. Jestliže máme stisknuté některé z tlačítek stylů a tlačítka stylů zakážeme a opět povolíme, pak stisknuté tlačítko je překresleno jako uvolněné. Problém je v přechodu mezi stavy zakázáno a stisknuto. Problém můžeme vyřešit vynucením obnovení symbolu tlačítka jeho uvolněním a stisknutím, např.
    SpeedButton5->Down = false;
    SpeedButton5->Down = true;
  5. Další prvek, který se na paletách nástrojů používá je bublinková nápověda. Její používání zajistíme změnou některých vlastností. U komponenty Panel nastavíme vlastnost ShowHint na true a ParentShowHint na false. U jednotlivých tlačítek nastavíme vlastnosti Hint. Např. u posledního tlačítka použijeme text Zvětšit. Volbu textů ostatních bublinkových nápověd proveďte sami. U posledního tlačítka by bylo vhodné měnit text nápovědy podle stavu tlačítka. Změníme tedy obsluhu stisku tohoto tlačítka:

  6. if (SpeedButton8->Down){
      Label1->Font->Size = 24;
      SpeedButton8->Hint = "Zmenšit";}
    else {
      Label1->Font->Size = 12;
      SpeedButton8->Hint = "Zvětšit";}
    Při přidávání nápovědy není třeba téměř žádné kódování. Kód je zapotřebí pouze u nápověd závislých na kontextu.
  7. Do palety nástrojů můžeme přidat i další ovladače. Ukážeme si to v dalším rozšíření předchozí aplikace. Zde nejprve zrušíme poslední SpeedButton, obsluhu stisku tohoto tlačítka a volbu v nabídce. Na panel přidáme komponentu ComboBox a budeme s ní provádět volbu použitého písma. Vlevo od této komponenty přidáme komponentu Label s textem Písmo: a nastavíme její vlastnost Hint na Vyber písmo. U komponenty ComboBox nastavíme vlastnosti: Hint na Vyber písmo a Style na csDropDownList. Pro formulář musíme vytvořit obsluhu události OnCreate, ve které do kombinovaného ovladače vložíme seznam dostupných písem:

  8. ComboBox1->Items = Screen->Fonts;
    ComboBox1->ItemIndex = ComboBox1->Items->IndexOf(Label1->Font->Name);
    Dále musíme vytvořit obsluhu OnChange kombinovaného ovladače. Bude tvořena příkazem:
    Label1->Font->Name = ComboBox1->Items->Strings[ComboBox1->ItemIndex];
    To je vše, co se týká této komponenty. Pro komponentu Panel přidáme ještě místní nabídku:
    Skrýt paletu nástrojů
    ---------------------
    Zakázat zvuk
    Zakázat styly
    Pro panel musíme tedy nastavit PopupMenu na PopupMenu1, pro nabídku vytvořit obsluhu OnPopup (překopírujeme označení prvků hlavní nabídky do místní nabídky) s příkazy:
    Zakzatzvuk2->Checked = Zakzatzvuk1->Checked;
    Zakzatstyly2->Checked = Zakzatstyly1->Checked;
    Zbytek potřebných věcí pro používání místní nabídky dokončete sami.
  9. Některé aplikace umožňují přemisťování palety nástrojů. Vyjdeme z předposlední aplikace s paletou nástrojů (ještě před použitím kombinovaného ovladače) a změníme ji tak, že panel nástrojů budeme moci přetáhnout myší na některý jiný okraj formuláře. U komponenty Panel změníme vlastnost DragMode na dmAutomatic. V naši aplikaci využijeme standardní výčtový typ TAlign a k deklaraci třídy formuláře přidáme tyto soukromé položky a metody:

  10. TAlign PozicePalety;
    int SirePanelu;
    TAlign ZiskejPoziciPalety(int X, int y);
    void OtocPaletu(void);
    V jednotce formuláře deklarujeme také konstantu určující šířku okraje formuláře, kde je akceptováno tažení:
    const int SireOkraje = 20;
    Metoda ZiskejPoziciPalety vrací novou pozici palety na základě předaných souřadnic. Tato metoda vypadá takto:
    TAlign TForm1::ZiskejPoziciPalety(int X, int Y){
      if (X < SireOkraje) return alLeft;
      if (Y < SireOkraje) return alTop;
      if (X > ClientWidth - SireOkraje) return alRight;
      if (Y > ClientHeight - SireOkraje) return alBottom;
      return alNone;
    }
    Metoda OtocPaletu provede změnu z vodorovné na svislou paletu nebo naopak. Provádí se zde pouze záměna vlastností Top a Left:
    void TForm1::OtocPaletu(void){
      for (int I = 0; I < Panel1->ControlCount; I++){
        int X = Panel1->Controls[I]->Top;
        int Y = Panel1->Controls[I]->Left;
        Panel1->Controls[I]->Top = Y;
        Panel1->Controls[I]->Left = X;
      }
    }
    Obsluha OnCreate formuláře je tvořena příkazy:
    PozicePalety = alTop;
    SirePanelu = Panel1->Height;
    Nyní již zbývá vytvořit obsluhy událostí OnDragOver a OnDragDrop pro komponentu Label. Obsluha OnDragOver je tvořena příkazem:
    if(ZiskejPoziciPalety(X+Label1->Left,Y+Label1->Top)==alNone)Accept=false;
    else Accept = true;
    a obsluha OnDragDrop příkazy:
    TAlign PP;
    PP = ZiskejPoziciPalety(X+Label1->Left,Y+Label1->Top);
    Panel1->Align = PP;
    if ((((PP == alTop) || (PP == alBottom)) &&
       ((PozicePalety == alLeft) || (PozicePalety == alRight))) ||
       (((PP == alLeft) || (PP == alRight)) &&
       ((PozicePalety == alTop) || (PozicePalety == alBottom))))
         OtocPaletu();
    PozicePalety = PP;
    Nyní již aplikaci můžeme vyzkoušet.
  11. V další aplikaci si ukážeme, jak na stavovém řádku zobrazovat nápovědu k nabídce. Začneme s vývojem nové aplikace. V této aplikaci vytvoříme nabídku (nezáleží na jejím obsahu). Do vlastností Hint jednotlivých prvků nabídky přiřadíme texty, které budeme chtít zobrazovat na stavovém řádku. Dále musíme napsat obsluhu události OnHint u aplikace. Tuto obsluhu musíme do formuláře přidat ručně a potom např. v obsluze OnCreate formuláře ji přiřadit OnHint objektu aplikace. Do deklarace třídy formuláře přidáme veřejnou metodu:

  12. void __fastcall ShowHint(TObject *Sender);
    a v obsluze OnCreate formuláře bude příkaz:
    Application->OnHint = ShowHint;
    Na formulář přidáme komponentu Panel a nastavíme pro ní tyto vlastnosti: Align na alBottom, Alignment na taLeftJustify a BevelInner na bvLowered. Zbývá ještě vytvořit metodu ShowHint:
    void __fastcall TForm1::ShowHint(TObject *Sender){
      Panel1->Caption = Application->Hint;
    }
    Nyní již můžeme vyzkoušet zobrazování nápovědy k nabídce na stavovém řádku.
20. Paleta nástrojů