|
|
|
|
Példaprogram letöltése
18399 bájt
|
A Delphi komponensei között található egy TTrackBar nevű komponens, amely egy csúszkához hasonlít, amivel különböző értékeket lehet beállítani. Ez bizonyos esetekben nagyon jól használható, de a megjelenését a legtöbb komponenshez hasonlóan nem nagyon tudjuk befolyásolni, mindenképpen a hagyományos Windows-os megjelenést tükrözi. Egy gondosan kialakított grafikus felhasználói felülettel rendelkező programnál nem túl szerencsés ilyen komponensek használata. Ebből a megfontolásból jött létre az ebben a cikkben bemutatandó TSlider komponens is, ami a TTrackBar komponenshez hasonló feladatot lát el, de a felülete egy egyszerű trükkel tetszés szerint változtatható.
A mellékelt példaprogram megnyitása előtt a Slider.pas-ban lévő komponenst telepítenie kell a Delphi alá.
Maga a komponens kevesebbet tud, mint a TTrackBar komponens, de a legtöbb feladatra ugyanúgy megfelel. A trükk, amivel a felületét tetszés szerint alakíthatjuk az, hogy a komponens hátterében bármilyen képet elhelyezhetünk, továbbá a csúszka képét is tetszőlegesen megadhatjuk. Innentől kezdve a lehetőségek korlátlanok, hiszen bármilyen képet felhasználhatunk, de úgy is használható a komponens, ha nem adunk meg semmilyen képet. Ebben az esetben viszont inkább maradjunk a TTrackBar-nál.
A komponens property-jei:
- Picture: a komponens hátterében megjelenő kép. Ha az AutoSize property értéke igaz, akkor a komponens ehhez a képhez igazítja a szélességét és a magasságát, ellenkező esetben ez pont fordítva történik;
- KnobPicture: a csúszka képe. Ennek mindenképpen kisebbnek kell lennie a háttérképnél, hiszen ez lesz az, amit a másik felett mozgathatunk;
- KnobWidth: a csúszka szélessége. Ha az AutoSize property értéke igaz, akkor automatikusan a KnobPicture szélességét adja meg, ellenkező esetben a kép lesz ilyen szélességűre nyújtva;
- KnobHeight: a csúszka magassága. Ugyanaz vonatkozik rá, mint a KnobWidth property-re;
- Max: a maximális érték, amit a csúszkával beállíthatunk. A minimum mindig 1;
- Position: az aktuális pozíció. Ha a maximális érték a komponens szélességéhez viszonyítva túl nagy, akkor nem tudunk pontos értéket beállítani!
- AutoSize: igaz érték esetén a komponens méretét automatikusan a Picture, valamint a csúszka szélességét és magasságát a KnobPicture méretéhez igazítja;
- OnChange: ez az esemény akkor jön létre, amikor a Position property értéke megváltozik.
A komponens elkészítésénél a következő feladatokat kellett megoldani:
- Amikor a felhasználó kattint a csúszkán, és az egérgombot lenyomva tartja miközben elmozgatja az egeret, akkor a csúszkának követnie kell ezt a mozgatást, valamint a Position property értékét folyamatosan ennek megfelelően kell beállítania.
- Ha nem a csúszkára kattint a felhasználó, akkor a csúszkát a kattintásnak megfelelő pozícióba kell helyezni.
- Ha a Position property értékét programból változtatják meg, akkor a csúszka helye ennek megfelelően változik.
A Position property-nek történő értékadás a SetPosition eljárásban történik. Ebben kiszámoljuk az új értéknek megfelelő pozíciót, majd meghívva a SetKnobXPosition eljárást, a csúszkát odahelyezzük.
procedure TSlider.SetPosition;
var
sw: real;
begin
if value<1 then value:=1 else if value>FMax then value:=FMax;
FPosition:=value;
sw:=(Width-FKnobWidth) / FMax;
SetKnobXPosition(Round(int(sw*FPosition)));
invalidate;
end;
A SetKnobXPosition eljárás a csúszkát a paraméterként megadott pozícióba helyezi. A pozíciót pixelben adjuk meg, úgy hogy ez lesz a csúszka bal szélének koordinátája. Mivel ezt az eljárást hívjuk meg akkor is, amikor az egérrel történik a csúszka elmozgatása, ezért a Position property értékét a csúszka pozíciójából ki kell számolni. Végül az eljárás végén generálunk egy OnChange eseményt.
procedure TSlider.SetKnobXPosition;
var sw:real;
begin
if value<0 then
value:=0
else
if value>Width-FKnobWidth then value:=Width-FKnobWidth;
FKnobRect.Left:=value;
sw:=(Width-FKnobWidth) / FMax;
FPosition:=Round(int(FKnobRect.Left / sw)) + 1;
if FPosition>FMax then FPosition:=FMax;
invalidate;
if Assigned(FOnChange) then FOnChange(self);
end;
A MouseDown eljárás akkor fut le, ha a felhasználó valamelyik egérgombot lenyomta a komponensen. Ebben ellenőrizzük, hogy az Enabled porperty értéke igaz-e, és a bal egérgombot nyomták-e le. Ha mindegyik feltétel igaz, akkor megnézzük, hogy a csúszka mellett kattintottak-e, vagy a csúszkán. Ha mellette, akkor az egér X koordinátájából kiszámoljuk a csúszka pozícióját, és a SetKnobXPosition eljárást meghívva oda helyezzük azt. Ha a csúszkán kattintottak, akkor az FMouseDown változó értékét igazra állítjuk, és a MouseX változóba eltároljuk a csúszka és a kattintás X koordinátája közötti távolságot. Ez utóbbit a MouseMove eljárásban fogjuk használni.
procedure TSlider.MouseDown;
begin
inherited;
if (Button=mbLeft) and Enabled then begin
if (X<FKnobRect.Left) or (X>FKnobRect.Right) then begin
SetKnobXPosition(X-FKnobWidth div 2);
MouseX:=FKnobWidth div 2;
FMouseDown:=true;
end else begin
MouseX:=X-FKnobRect.Left;
FMouseDown:=true;
invalidate;
end;
end;
end;
A MouseMove eljárás akkor jön létre, amikor az egeret elmozgatják a komponens felett. Ellenőrizzük, hogy a bal egérgomb van-e lenyomva, illetve a komponens engedélyezve van-e. Ha mindkét feltétel igaz, akkor a SetKnobXPosition függvénnyel beállítjuk a csúszka új pozícióját, felhasználva a MouseX változó értékét is, amit a MouseDown eljárásban kaptunk meg.
procedure TSlider.MouseMove;
begin
inherited;
if (ssLeft in Shift) and Enabled then begin
SetKnobXPosition(X-MouseX);
end;
end;
A komponens kirajzolását, mint mindig, most is a Paint eljárás végzi el, ami automatikusan lefut, amikor a komponens területét újra kell rajzolni.
Természetesen először a komponens hátterét kell megrajzolni. Ha a Picture property-ben meg lett adva egy kép, akkor ellenőrizzük, hogy az AutoSize porperty értéke igaz-e. Ha igaz, akkor a komponens méretét a Picture méretéhez igazítjuk. A kirajzolást a StretchDraw eljárással végezzük el. Ez azért jó, mert ha a komponens mérete nem egyezik meg a Picture méretével, akkor a képet a komponens méretére fogja nyújtani.
Ha nem lett kép megadva a Picture property-ben, akkor egy egyszerű keretet rajzolunk vízszintesen a DrawEdge függvénnyel.
Ha megvan a háttér, akkor jöhet a csúszka kirajzolása. A csúszka pozíciója az FKnobrect változóban van tárolva. A megjelenítés ugyanazon az elven történik, mint a háttéré, azzal a különbséggel, hogy a kirajzolást a TransparentBlt függvénnyel végeztetjük el. Ennek utolsó paramétere egy szín, amely a kirajzolandó kép "átlátszó" színe, tehát ahol a képen ilyen szín van, ott a kép mögötti terület fog látszani. Ennek köszönhető, hogy a csúszka innentől kezdve bármilyen alakú lehet. Az átlátszó szín mindig a csúszka képének bal alsó sarkában lévő pixel színe lesz.
Ha a KnobPicture kép nem lett megadva, akkor egy egyszerű keretet rajzolunk a DrawEdge függvénnyel úgy, hogy az FMouseDown változó értékétől függően benyomott, vagy kiemelkedő keretet rajzolunk. A keret clBtnface színnel lesz kitöltve.
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 339. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|