10. Editor obrßzk∙ C++ Builderu
  1. Editor obrßzk∙ je vizußlnφ editor. M∙₧eme jej pou₧φt k vytvß°enφ a editaci obrßzk∙, kterΘ chceme pou₧φt v naÜφ aplikaci. K otev°enφ editoru obrßzk∙ zvolφme Tools | Image Editor. Editor obrßzk∙ zobrazφ novΘ okno, kde m∙₧eme vytvß°et, otvφrat a uklßdat r∙znΘ typy soubor∙ obrßzk∙ (ikon, kurzor∙ a bitov²ch map). Okno mß svou vlastnφ nabφdku, paletu barev, paletu nßstroj∙ a dalÜφ palety.

  2. Editor obrßzk∙ m∙₧eme pou₧φt k vytvß°enφ obrßzk∙ pro naÜi aplikaci. Pro vytvo°enφ novΘho obrßzku zvolφme File | New, k otev°enφ existujφcφho obrßzku zvolφme File | Open a pro ulo₧enφ obrßzku zvolφme File | Save nebo File | Save As.
    Editor obrßzk∙ umo₧≥uje provßd∞t tyto Φinnosti: Volby v nabφdce majφ obvykl² v²znam a pou₧φvajφ se b∞₧n²m zp∙sobem. Paleta nßstroj∙ se takΘ pou₧φvß b∞₧n²m zp∙sobem.
    Pokuste se pomocφ Editoru obrßzk∙ nakreslit n∞jak² obrßzek a pou₧ijte jej v n∞jakΘ aplikaci.

  3. Jsou t°i mo₧nosti pou₧itφ grafiky v aplikaci C++ Builderu: m∙₧eme vlo₧it p°edem vytvo°en² obrßzek b∞hem nßvrhu, vytvo°it jej pou₧itφm grafickΘho ovladaΦe p°i nßvrhu nebo jej dynamicky kreslit p°i b∞hu aplikace. V tΘto kapitole se budeme dßle zab²vat kreslenφm za b∞hu aplikace a to bu∩ na formulß° nebo na n∞jakou komponentu. GrafickΘ komponenty VCL zaobalujφ GDI Windows (Graphics Device Interface) a znaΦn∞ usnad≥ujφ p°idßvßnφ grafick²ch mo₧nostφ do naÜich program∙.

  4. Kdy₧ kreslφme v aplikaci C++ Builderu, m∙₧eme kreslit na plßtno (canvas) objektu; je to vhodn∞jÜφ ne₧ kreslit p°φmo na objekt. Plßtno je vlastnost objektu a je to samotn² objekt se sv²mi vlastnφmi vlastnostmi. Hlavnφ v²hodou objektu plßtna je to, ₧e efektivn∞ vyu₧φvß zdroje systΘmu a naÜe programy mohou pou₧φvat stejnΘ metody a to bez ohledu na to, zda manipulujeme s bitov²mi mapami nebo metasoubory. Plßtna jsou dostupnß pouze za b∞hu aplikace a m∙₧eme tedy s nimi pracovat pouze prost°ednictvφm k≤du. Jeliko₧ TCanvas je obal okolo kontextu za°φzenφ Windows, lze takΘ pou₧φvat vÜechny funkce GDI Windows pro plßtno. Vlastnost Handle plßtna je kontext za°φzenφ.
    Objekt plßtna mß p∞t d∙le₧it²ch vlastnostφ: pero pro kreslenφ Φar (Pen), Üt∞tec pro vypl≥ovßnφ tvar∙ (Brush), pφsmo pro zßpis text∙ (Font), souΦasnou pozici pera (PenPos) a pole bod∙ reprezentujφcφch obraz (Pixels). N∞kolik metod objektu plßtna je popsßno v nßsledujφcφ tabulce.
     
    Metoda Popis
    Arc Kreslφ eliptick² oblouk.
    Chord Kreslφ eliptickou ·seΦ.
    CopyRect Kopφruje Φßst obrßzku z jednoho plßtna na jinΘ.
    Draw Zobrazuje specifikovanou grafiku na plßtn∞.
    Ellipse Kreslφ elipsu.
    FillRect Vypl≥uje specifikovan² obdΘlnφk na plßtn∞ souΦasn²m Üt∞tcem.
    FloodFill Zapl≥uje oblast plßtna souΦasn²m Üt∞tcem.
    FrameRect Kreslφ rßmeΦek plßtna.
    LineTo Kreslφ ·seΦku z PenPos do specifikovanΘho bodu a PenPos nastavφ na tento bod. 
    MoveTo Nastavuje PenPos na zadanΘ sou°adnice.
    Pie Kreslφ eliptickou v²seΦ.
    Polygon Propojuje p°edanΘ body ·seΦkami a uzavφrß nakreslen² tvar.
    PolyLine Propojuje p°edanΘ body ·seΦkami.
    Rectangle Kreslφ obdΘlnφk souΦasn²m perem a vypl≥uje jej souΦasn²m Üt∞tcem.
    RoundRect Kreslφ obdΘlnφk se zaoblen²mi rohy.
    StretchDraw Kreslφ grafiku na plßtn∞ tak, aby obrßzek zaplnil specifikovan² obdΘlnφk.
    TextHeight, 
    TextWidth
    Vracφ v²Üku a Üφ°ku °et∞zce zapsanΘho souΦasn²m pφsmem. V²Üka obsahuje i mezeru mezi °ßdky.
    TextOut Zapisuje °et∞zec na plßtno.
    TextRect Zapisuje °et∞zec do obdΘlnφkovΘ oblasti. ╚ßsti textu mimo oblast se nezobrazujφ.

    Kdy₧ pracujeme s grafikou, je nutno si uv∞domit rozdφl mezi kreslenφm a malovßnφm. Rozdφln²m v²znamem t∞chto pojm∙ jsme se ji₧ zab²vali.
    V jist²ch okam₧icφch Windows urΦuje, ₧e objekty zobrazenΘ na obrazovce majφ obnovit sv∙j vzhled. Provßdφ to generovßnφm zprßvy wm_Paint, kterou VCL p°evßdφ na udßlost OnPaint. Kdy₧ pou₧ijeme metodu Refresh, C++ Builder volß obsluhu udßlosti OnPaint objektu. Jak se grafika zobrazuje v naÜφ aplikaci, zßvisφ na zp∙sobu jejφho kreslenφ. Pokud kreslφme p°φmo na plßtno ovladaΦe, pak objekt obrßzku je zobrazovßn bezprost°edn∞. M∙₧eme ale kreslit mimo obrazovku na plßtno TBitmap a obrßzek se zobrazφ a₧ po p°ekopφrovßnφ z plßtna TBitmap na plßtno ovladaΦe.
    C++ Builder pou₧φvß nßsledujφcφ grafickΘ objekty:
     

    Objekt Popis
    Picture Pou₧φvß se k dr₧enφ obrßzku. K p°idßnφ dalÜφch grafick²ch formßt∙, pou₧φvßme metodu Register. Takto lze pou₧φt libovolnΘ soubory obrßzk∙ k zobrazenφ na ovladaΦi.
    Bitmap Grafick² objekt pou₧φvan² k vytvß°enφ, manipulaci (zm∞na m∞°φtka, rotace apod.) a uklßdßnφ obrßzk∙. Vytvß°enφ kopie je rychlΘ, nebo¥ je kopφrovßno madlo a ne obrßzek.
    Clipboard Reprezentuje kontejner pro libovoln² text nebo grafiku, kterou m∙₧eme vyst°ihovat, kopφrovat a vklßdat z nebo do aplikace. 
    Icon Reprezentuje hodnotu zavedenou ze souboru ikony (soubor ICO).
    Metafile Obsahuje grafiku metasouboru.
  5. Vlastnost Pen plßtna °φdφ zp∙sob zobrazovßnφ Φar, vΦetn∞ kreslenφ Φar obrys∙ tvar∙. Kreslenφ rovnΘ Φßry zm∞nφ skupinu bod∙, kterΘ jsou p°φmo mezi dv∞ma body. SamotnΘ pero mß Φty°i vlastnosti, kterΘ m∙₧eme m∞nit: Color, Width, Style a Mode. Hodnoty t∞chto vlastnostφ urΦujφ jak pero zm∞nφ body na Φß°e. Implicitn∞ ka₧dΘ pero zaΦφnß s Φernou barvou, se Üφ°kou 1 bod, plnou Φarou a re₧imem nazvan²m pmCopy, kter² p°episuje body na plßtn∞.

  6. Barvu pera m∙₧eme nastavit p°i b∞hu aplikace zm∞nou vlastnosti Color. Barva pera urΦuje barvu kreslenΘ Φßry. Width je celΘ Φφslo urΦujφcφ Üφ°ku Φßry v bodech. Pokud kreslφme Φßru siln∞jÜφ ne₧ jeden bod, pak Windows v₧dy kreslφ plnΘ Φßry (neuva₧uje se hodnota vlastnosti Style). Style umo₧≥uje pou₧φvat plnou Φßru, teΦkovanou Φßru, Φßrkovanou Φßru apod. Mode slou₧φ k urΦenφ zp∙sobu kombinace barvy pera s p∙vodnφ barvou v poli bod∙.
    Aktußlnφ kreslφcφ pozice (pozice, kde jsme skonΦili s kreslenφm p°edchozφ Φßry) se naz²vß pozice pera. Plßtno uklßdß svoji pozici pera do vlastnosti nazvanΘ PenPos. Pozici pera ovliv≥uje pouze kreslenφ Φar; pro tvary a texty zadßvßme vÜechny po₧adovanΘ sou°adnice. K nastavenφ pozice pera volßme metodu MoveTo plßtna. Nap°. k p°esunu pozice pera do hornφho levΘho rohu plßtna pou₧ijeme nßsledujφcφ k≤d:
    Canvas->MoveTo(0, 0);
    Kreslenφ Φßry metodou LineTo takΘ p°esouvß pozici pera do koncovΘho bodu Φßry.
    Vlastnost Brush plßtna °φdφ zp∙sob vypl≥ovßnφ oblastφ, vΦetn∞ vypl≥ovßnφ tvar∙. Vypl≥ovßnφ oblasti Üt∞tcem zp∙sobφ zm∞nu v∞tÜφho poΦtu urΦen²ch bod∙. èt∞tec mß t°i vlastnosti, kterΘ m∙₧eme m∞nit: Color, Style a Bitmap. Hodnoty t∞chto vlastnostφ urΦujφ zp∙sob vypl≥ovßnφ tvar∙ nebo jin²ch oblastφ plßtna. Implicitn∞ ka₧d² Üt∞tec zaΦφnß bφlou barvou, pln²m stylem a bez vzoru bitovΘ mapy. Barvu Üt∞tce m∙₧eme nastavit pomocφ vlastnosti Color. Style urΦuje vzor pou₧it² k vypln∞nφ tvaru. P°eddefinovanΘ hodnoty tΘto vlastnosti urΦujφ r∙znΘ typy Ürafovßnφ. Bitmap slou₧φ ke specifikaci obrßzku pro Üt∞tec k pou₧itφ jako vzor pro vypl≥ovßnφ tvar∙ a jin²ch oblastφ.
    Ka₧dΘ plßtno mß indexovanou vlastnost nazvanou Pixels, kterß reprezentuje jednotlivΘ barevnΘ body obrßzku na plßtn∞. K vlastnosti Pixels p°istupujeme p°φmo pouze kdy₧ pot°ebujeme zjistit nebo nastavit barvu konkrΘtnφho bodu. Pixels p°edstavuje kreslφcφ plochu plßtna a pero nebo Üt∞tec pracujφ se skupinou bod∙. Pou₧φvßnφ tΘto vlastnosti zpomaluje grafickΘ operace.
  7. Na plßtno m∙₧eme kreslit dva typy Φar: p°φmΘ Φßry a lomenΘ Φßry. P°φmß Φßra je Φßra spojujφcφ dva body. Lomenß Φßra je °et∞zec p°φm²ch Φar, kterΘ na sebe navazujφ. VÜechny Φary kreslφme pomocφ pera. Ke kreslenφ p°φm²ch Φar na plßtn∞ pou₧φvßme metodu LineTo plßtna. LineTo kreslφ Φßru z aktußlnφ pozice pera do bodu urΦujφcφho koncov² bod Φßry. Plßtno kreslφ Φaru pomocφ svΘho pera. Nap°. nßsledujφcφ metoda nakreslφ ·hlop°φΦky formulß°e p°i malovßnφ formulß°e (uvedenΘ p°φkazy tvo°φ obsluhu OnPaint formulß°e):

  8. Canvas->MoveTo(0, 0);
    Canvas->LineTo(ClientWidth, ClientHeight);
    Canvas->MoveTo(0, ClientHeight);
    Canvas->LineTo(ClientWidth, 0);
    Udßlost OnPaint vznikne, kdy₧ Windows zjistφ, ₧e je pot°eba formulß° p°ekreslit. Mimo samostatn²ch Φar, plßtno m∙₧e takΘ kreslit lomenΘ Φßry, co₧ je skupina n∞kolika propojen²ch Φßrov²ch segment∙. Pro kreslenφ lomenΘ Φßry na plßtno, volßme metodu Polyline plßtna. Parametr p°edßvan² metod∞ Polyline je pole bod∙. Tato metoda provede MoveTo do prvnφho bodu a LineTo do ka₧dΘho nßsledujφcφho bodu. Nßsledujφcφ p°φkazy nap°. kreslφ na formulß°i kosoΦtverec:
    POINT body[5];
    body[0] = Point(0, 0);
    body[1] = Point(50, 0);
    body[2] = Point(75, 50);
    body[3] = Point(25, 50);
    body[4] = Point(0, 0);
    Canvas->Polyline(body, 4);
    Druh² parametr metody Polyline je index poslednφho prvku a ne poΦet bod∙.
  9. Plßtna majφ metody pro kreslenφ r∙zn²ch typ∙ tvar∙. Plßtno kreslφ obrys tvaru sv²m perem a vnit°ek tvaru vypl≥uje sv²m Üt∞tcem. Pro kreslenφ obdΘlnφku nebo elipsy na plßtnu, volßme metodu Rectangle nebo Ellipse plßtna a p°edßme sou°adnice ohraniΦujφcφho obdΘlnφku. Metoda Rectangle kreslφ ohraniΦujφcφ obdΘlnφk, Ellipse kreslφ elipsu vlo₧enou do obdΘlnφku. Nßsledujφcφ p°φkazy nap°. kreslφ obdΘlnφk do hornφ levΘ Φtvrtiny formulß°e a pak do stejnΘ oblasti nakreslφ elipsu:

  10. Canvas->Rectangle(0, 0, ClientWidth / 2, ClientHeight / 2);
    Canvas->Ellipse(0, 0, ClientWidth / 2, ClientHeight / 2);
    Pro kreslenφ obdΘlnφk∙ se zaoblen²mi rohy na plßtno, volßme metodu RoundRect plßtna. Prvnφ Φty°i parametry p°edanΘ RoundRect urΦujφ ohraniΦujφcφ obdΘlnφk (stejn∞ jako u Rectangle) a dalÜφ dva parametry urΦujφ zaoblenφ roh∙. Nßsledujφcφ p°φkaz nap°. kreslφ obdΘlnφk se zaoblen²mi rohy do hornφ levΘ Φtvrtiny formulß°e a zaoblenΘ rohy jsou tvo°eny Φtvrtinou kru₧nice o polom∞ru 10 bod∙:
    Canvas->RoundRect(0,0,ClientWidth / 2,ClientHeight / 2, 10, 10);
    Pro kreslenφ mnoho·helnφku na plßtno, volßme metodu Polygon plßtna. Mnoho·helnφk p°ebφrß pole bod∙ jako sv∙j jedin² parametr a tyto body propojuje Φarou nakreslenou perem (spojφ takΘ poslednφ bod s prvnφm k uzav°enφ mnoho·helnφku). Po nakreslenφ Φar je pou₧it Üt∞tec k vypln∞nφ mnoho·helnφku. Nßsleduje p°φklad pou₧itφ (pravo·hl² troj·helnφk):
    POINT body[3];
    body[0] = Point(0, 0);
    body[1] = Point(0, ClientHeight);
    body[2] = Point(ClientWidth,ClientHeight);
    Canvas->Polygon(body,2);
    Mimo kreslenφ Φar a tvar∙, kterΘ jsou zde popsßny, plßtno takΘ poskytuje n∞kterΘ specializovanΘ grafickΘ mo₧nosti, jako eliptick² oblouk, eliptickß v²seΦ apod. M∙₧eme takΘ vypl≥ovat oblasti a kopφrovat obrßzky na jinΘ plßtno. Informace o t∞chto mo₧nostech najdeme v nßpov∞d∞.
    VyzkouÜejte pou₧itφ v²Üe uveden²ch p°φkaz∙.
  11. Dßle se seznßmφme s pou₧φvßnφm udßlostφ myÜi pro kreslenφ. ZaΦneme s v²vojem novΘ aplikace. Vytvo°φme obsluhu udßlosti OnMouseDown formulß°e k nastavenφ aktußlnφ kreslφcφ pozice na sou°adnice, kde u₧ivatel stiskl tlaΦφtko myÜi:

  12. Canvas->MoveTo(X, Y);
    Stisknutφ tlaΦφtka myÜi nynφ nastavφ pozici pera, tj. nastavφ poΦßteΦnφ bod Φßry. Ke kreslenφ Φßry je jeÜt∞ zapot°ebφ bod, kde u₧ivatel tlaΦφtko myÜi uvolnφ. To urΦφme v obsluze udßlosti OnMouseUp. Tato udßlost je obvykle zaslßna objektu, nad kter²m bylo tlaΦφtko myÜi stisknuto. V naÜi aplikaci vytvo°φme obsluhu udßlosti OnMouseUp formulß°e a p°edanΘ sou°adnice pou₧ijeme jako koncov² bod Φßry. Tato obsluha udßlosti bude vypadat takto:
    Canvas->LineTo(X, Y);
    Aplikaci m∙₧eme vyzkouÜet a nakreslit n∞kolik Φar. Udßlost OnMouseMove se p°i pohybu myÜi vyskytuje periodicky. Udßlost je zasφlßna objektu, nad kter²m bylo tlaΦφtko myÜi stisknuto. V naÜem p°φkladu pou₧ijeme udßlost p°emφst∞nφ myÜi pro kreslenφ Φßry podle pohybu myÜi. To dosßhneme pou₧itφm nßsledujφcφ obsluhy udßlosti OnMouseMove formulß°e:
    Canvas->LineTo(X, Y);
    Nynφ jestli₧e spustφme aplikaci, pak pohybem myÜi po formulß°i kreslφme Φßru. Musφme jeÜt∞ zajistit, aby kreslenφ probφhalo pouze p°i stisknutΘm tlaΦφtku. V naÜem p°φkladu, je zapot°ebφ, aby formulß° udr₧oval informaci o tom, zda tlaΦφtko myÜi je stisknuto. K tomuto ·Φelu do deklarace typu formulß°e p°idßme do ve°ejnΘ Φßsti polo₧ku Drawing typu bool a nastavφme jejφ hodnotu p°i stisku tlaΦφtka myÜi. Pozd∞ji budeme pot°ebovat dalÜφ dv∞ polo₧ky, ob∞ typu POINT. Jednß se o polo₧ky Origin a MovePt.
    bool Drawing;
    POINT Origin, MovePt;
    V polo₧ce Drawing budeme udr₧ovat informaci o tom, zda kreslit. P°i stisku tlaΦφtka ji nastavφme na true a p°i jeho uvoln∞nφ na false. V tomto smyslu zm∞nφme ji₧ vytvo°enΘ obsluhy udßlosti. Pro OnMouseDown pou₧ijeme p°φkazy:
    Drawing = true;
    Canvas->MoveTo(X, Y);
    a pro OnMouseUp p°φkazy:
    Canvas->LineTo(X, Y);
    Drawing = false;
    Dßle musφme modifikovat obsluhu udßlosti OnMouseMove tak, aby kreslenφ probφhalo pouze tehdy, kdy₧ Drawing mß hodnotu true:
    if (Drawing) Canvas->LineTo(X, Y);
    Nynφ kreslenφ probφhß pouze mezi stiskem tlaΦφtka a jeho uvoln∞nφm. Poka₧dΘ, p°i p°esunu myÜi, obsluha udßlosti OnMouseMove volß LineTo, kterΘ m∞nφ pozici pera. P°i uvoln∞nφ tlaΦφtka myÜi ji₧ tedy neznßme poΦßteΦnφ bod Φßry. Abychom po skonΦenφ kreslenφ mohli propojit poΦßteΦnφ bod k°ivky s koncov²m a k°ivku tak uzav°φt, pou₧ijeme polo₧ku Origin k ulo₧enφ poΦßteΦnφho bodu k°ivky. Zm∞nφme tedy obsluhy udßlostφ takto: pro OnMouseDown pou₧ijeme:
    Drawing = true;
    Canvas->MoveTo(X, Y);
    Origin = Point(X, Y);
    a pro OnMouseUp:
    Canvas->MoveTo(Origin.X, Origin.Y);
    Canvas->LineTo(X, Y);
    Drawing = false;
    Obsluha udßlosti OnMouseMove je nynφ napsßna tak, ₧e jsou kresleny Φßry z poslednφ pozice myÜi do aktußlnφ pozice. M∙₧eme to zm∞nit tak, aby kreslenΘ Φßry zaΦφnaly v bod∞ stisku tlaΦφtka myÜi:
    if (Drawing){
      Canvas->MoveTo(Origin.X, Origin.Y);
      Canvas->LineTo(X, Y);
    }
    VyzkouÜejte. Pro rozumnou prßci tΘto aplikace bychom pot°ebovali, aby v₧dy p°ed nakreslenφm dalÜφ Φßry byla p°edchozφ Φßra smazßna. Vyu₧ijeme k tomu polo₧ku MovePt, kde bude ulo₧en koncov² bod p°edchozφ nakreslenΘ Φßry. NaÜe obsluhy udßlostφ zm∞nφme takto. Pro OnMouseDown pou₧ijeme:
    Drawing = true;
    Canvas->MoveTo(X, Y);
    Origin = Point(X, Y);
    MovePt = Point(X, Y);
    a pro OnMouseMove:
    if (Drawing) {
      Canvas->Pen->Mode = pmNotXor;
      Canvas->MoveTo(Origin.X, Origin.Y);
      Canvas->LineTo(MovePt.X, MovePt.Y);
      Canvas->MoveTo(Origin.X, Origin.Y);
      Canvas->LineTo(X, Y);
    }
    MovePt = Point(X,Y);
    Canvas->Pen->Mode = pmCopy;
    Nynφ po spuÜt∞nφ aplikace se nßmi kreslenß Φßra pr∙b∞₧n∞ zobrazuje a z∙stane zobrazenß pouze ta, p°i kterΘ jsme uvolnili tlaΦφtko myÜi. Je to dosa₧eno tφm, ₧e p°i zßpisovΘm re₧imu pmNotXor druhΘ zobrazenφ stejnΘ Φßry tuto Φßru sma₧e. Na zßv∞r kreslenφ je op∞t nastaven implicitnφ zßpisov² re₧im pmCopy.
10. Editor obrßzk∙ C++ Builderu