Előző számunkban megígértem, hogy készítünk egy szép gombot, mert a karakterátírás eredménye képen a gombunk árnyéka helyett jobb oldalt az egér nyila jelent meg. Lássuk a problémát miről van szó:
 

 
Látható, hogy mi is a hiba ... Mivel - mint ahogy később kiderül - szükség lesz az összes átírható karakterre, hisz szép felhasználói felületet akarunk írni, trükkökhöz kell folyamodnunk. Tudjuk, hogy igazából csak a keretkarakterekkel (ASCII 192-223) kell spórolnunk, hisz csak ezek ismétlik meg a 9. oszlopban a 8 oszlopuk tartalmát. Nos ezen segíthetünk egy karaktert rögtön nyerhetünk !

Ott van a #220-as karakter mely egy téglalap s az alsó fele kitöltött: 
Ugyanakkor van egy hasonló a #223-as karakter mely így néz ki: 
 
Láthatjuk, hogy egyik a másik inverze így az egyiküket átírhatjuk legyen ez a #220-as.

Így ha szükség lenne a #220-as alul kitöltött karakterünkre, akkor nem kell mást tennem a #223-as karakter kiíratásakor, mint az előtér- és háttérszínét fordítva megadni. Az-az tegyük fel, hogy $F1 szín? karaktert akartam kiírni. (Fehér háttér, fekete bet?k. /Ohh fekete - fehér ? PVSK Dália Női Kosárlabda NB I !!! Hmm már megint bajnok lett .../) Tehát ha #223-as karakternek a kívánt színt fordítva adjuk meg, az-az az előtérszín lesz a háttér és fordítva, akkor úgy látjuk, mintha a #220-as karakter lenne kiírva. (Tehát a #223-as színe, pontosabban szín attribútuma legyen $1F.)

Persze nem csak így nyerhetünk karaktert. Amikor még réges - rég írtam ezt a Turbo Vision átírást akkor ippeg, hogy elfogyott az utolsó átírható keretkarakterem is és még volt pár olyan szimbólum ami nem volt még szépen megrajzolva. Ilyen volt, pl. az ablak visszaméretezésére szolgáló restore gomb, az ablak jobb felső csücskében. Úgy terveztem, hogy a Windows-hoz hasonlóan két háromszögecske fogja jelenteni. Ehhez két karakter kellet volna, pláne keretkarakter. Mivel ilyen nem volt kénytelen voltam gondolkodni.

  1. Mi lenne, ha nem keretkarakterrel készíteném el ?
  2. Hát - gondolom - az nem lenne jó, hisz nem érne össze a két karakter, s ronda lenne. (Szóval nem akartam abba a hibába esni, mint a Symantec a Norton Utilities bizonyos programjánál.)
  3. Akkor hogyan lehet szép összeérő karaktert rajzolni keretkarakter nélkül ?
    Huhh, rajzoljuk meg annak a karakternek a negatívját amit látni szeretnénk. Ugye annak, mivel NEM keret karakter a 9. oszlopa üres. Ha ezt invertálom akkor szép teli fehér 9. oszlopot kapok. Glória, hát ez meg lenne !
  4. Lássuk a képet amit kaptunk, ill. amilyet szeretnénk készíteni:
  

Nos, láthatjuk, hogy ilyen szépen kell bele simulnia az ablak fehér fejlécébe a restore-gombnak. Rajzoljuk meg az első karaktert:

Láthatjuk, itt az első része a restore-gombnak és ha ezt invertáljuk akkor szépen beleolvad az ablak fejlécébe, valahogy így:

A 8-9. oszlop pedig teljesen fehér lesz. A 8. azért, mert az eleve üres volt és ezt az üreset invertáltuk, a kilencedik meg ugye mindig üres a NEM keretkarakterek esetében így azt invertálva megint teljesen fehér oszlopot kapunk. A restor-gomb másik fele is hasonlóan megy a negatívot rajzoljuk meg. Mivel invertálgatósdit játszunk még azzal se kell törődnünk, hogy: jaj vajon a nem keretkarakter esetében a 9. oszlop üres marad -e ? Hisz invertáljuk, és a 9. oszlop szép teli (itt fehér) lesz, így bele olvad az ablak fejlécébe.
 
Tehát eme maratoni eszmefuttatásból annyi a konklúzió, hogy nem köll betojni, ha elfogyott a keretkarakter hanem gondolkodjunk inkább. Továbbá, ha olyan karakterre van szükség melynek a teljes 9. oszlopa feltöltött akkor inkább negatívban rajzoljuk meg ahelyett, hogy agyba-főbe csak keretkaraktereket használnánk.
 
Persze ez még korántsem ilyen egyszerű !
 
Az szép és jó, hogy mi ügyesen meg tudtuk rajzolni negatívban a karaktert, csak akkor azt INVERZEN is KELL KIRAJZOLNI. Ezt a Turbo Vision-nek is meg kellene mondani. Persze a ciki ott van hogyha új színben akarunk egy elemet kirajzolni s az a szín még nem létezik az adott palettán akkor új elemet kell létrehozni a kívánt színnel. (Mely persze az applikáció fő palettájára mutat, s ha az applikációnak sincs ilyen színe akkor ott is újat kell létrehozni.)
 
Szóval láthatjátok van probléma elég. De nem vagyok olyan gonosz, hogy elhitessem veletek nincs egyszer?bb megoldás. Mit is mondtunk ? Arról volt szó, hogy az előtér szín lesz a háttérszín, s fordítva.
 
Mivel nekünk nincs villogás (7. attribútum bit) bit-ünk így a karakter szín attribútum byte-jának felső négy bit-jét kell az alsó 4 bit helyére mozgatni, s az alsó 4-et a felső 4- helyére. Valahogy így:
 

 
Ha egy kicsit is gondolkozunk, és a kedves Olvasó olvasta az Assembly rovatomat akkor nagyot sikít, s ezt mondja:
"Hiszen ez egy assembly utasítással megoldható mégpedig a ROR-ral (vagy a ROL-lal)". Nosza neki írjunk egy a byte alsó és felső négy bit-jét megcsereberélő rutint:
 
function  SwapHighAndLowAreaOfByte(BByte: Byte): Byte; Assembler;asm   mov  al, BByte   mov  cl, 4   rol  al, cl end; {és AL-ben van a visszatérési érték /byte típusú/}

Most, hogy meg van minden kellékünk a karakterátírásból eredő piszok (az egér nyila) eltüntetéséhez nem kell mást tennünk, mint a TButton.DrawState() metódusát átírnunk. Persze senki se ijedjen meg, nem az egészet.

Csak annyit kell átírni, ami a #220-as karaktert ill. annak színét írja ki. Szerencsénk van ezt közvetlenül megtehetjük:

for Y := 0 to Size.Y - 2 do {ez a gombot kiíró ciklus, annyiszor fut le ahány sor} begin   MoveChar(B, ' ', Byte(CButton), Size.X); {persze feltöltjük space-szel a button szöveg}   WordRec(B[0]).Hi := CShadow;             {területét. Itt meg megadjuk a szöveg árnyékát}   if Down then {ha a gomb le van nyomva, nincs árnyék}   begin     WordRec(B[1]).Hi := CShadow;     Ch := ' ';     I := 2;   end else   begin     if ShowMarkers then WordRec(B[S]).Hi := Byte(CShadow) {trükkös megoldás, ha kell árnyék}                    else WordRec(B[S]).Hi := SwapHighAndLowAreaOfByte(Byte(CShadow));     if ShowMarkers then Ch := ' ' else {ha mono nincs árnyék}     begin       if Y = 0 then         WordRec(B[S]).Lo := Byte('?') else {#223 invert = #220 jobb szélső átnyék}         WordRec(B[S]).Lo := Byte('?'); {ez a gomb jobb szélén az árnyék, ha több,                                         mint 1 sor vastag a gomb}       Ch := '?'; {az a gomb alsó árnyéka}     end;     I := 1;   end;   if (Y = T) and (Title <> nil) then DrawTitle; {Ha van neve a gombnak tán' írjuk ki}   if ShowMarkers and not Down then {Ha mono-ban vagyok akkor [ ] közé írjuk a gomb szöveget}   begin     WordRec(B[1]).Lo := Byte('[');     WordRec(B[S - 1]).Lo := Byte(']');   end;   WriteLine(0, Y, Size.X, 1, B); {kiírjuk a gomb egy sorát} end;
 
Bekommenteztem a fenti forráskódot, így látható, hogy hol van megoldva a karakter színének invertálása.
 
Így minden eddigi forráskódunkban ki kell cserélni a TButton (ill PButton) objektumokat TPCXButton-ra (ill. PPCXButton-ra), így nem nyíl lesz a gomb szélén.
 
Nos mára ennyit szántam, következő számunkban folytatjuk a Turbo Vision átírás szépségeit. Aki esetleg nem értett volna valamit eMail-ezzen.