Gadtools.library (cz. 1.) ------------------------- TRÓJWYMIAROWE GADÛETY Zapewnie wielokrotnie widziaîeô w programach îadne trójwymiarowe gadûety. Sâ one utworzone za pomocâ wprowadzonej w systemie 2.0 biblioteki gadtools. Moûliwoôci tej biblioteki sâ ogromne. Wystarczy przejrzeê programy w katalogu preferences. Wiëkszoôê istniejâcych tam gadûetów zostaîa utworzona za jej pomocâ. Sebastian Koîodziejczyk Na poczâtku uwaga dotyczâca zamieszczonych przykîadów. Prawie wszystkie sâ przeznaczone dla KickPascala. Dla innych pascali program oraz includy mogâ wymagaê niewielkich przeróbek. Piszâcy w C i asemblerze nie powinni mieê kîopotów z wykorzystaniem tej biblioteki po zapoznaniu sië z podanymi informacjami. Instrukcje opisane sâ w nastëpujâcy sposób: wynik:=instrukcja(parametr); typ typ -- typy wyniku i parametrów d0 rejestr -- rejestry, w których podajemy parametry Przedrostek P_ przy typie (dla Pascala) oznacza, ûe jest to wskaúnik. Np. typ P_XXX jest to wskaúnik do XXX. Przez rejestry procesora, oczywiôcie, nie moûemy przekazaê caîych struktur tylko wskaúniki do nich. W dalszej czëôci przy opisach funkcji sîowo "wskaúnik" jest pomijane. Przed utworzeniem gadûetów gadtools musi otrzymaê informacjë o ekranie, na którym znajduje sië okno. Do tego celu sîuûy funkcja GetVisualInfo. Zwraca ona strukturë VisualInfo zawierajâcâ niezbëdne informacje. Struktura ta jest przeznaczona wyîâcznie dla gadtools i jej zawartoôê nie jest udostëpniona programiôcie (inkludy nie zawierajâ jej opisu). Zmiennâ, zawierajâcâ wskaúnik do tej struktury, definiujemy po prostu jako Ptr (APTR). Format instrukcji: VisualInfo:=GetVisualInfo(Screen, TagList); Ptr p_Screen p_TagList d0 a0 a1 Screen -- struktura Screen, o której informacjë chcemy uzyskaê. Moûe to byê wskaúnik otrzymany z OpenScreen lub wskaúnik do ekranu Workbencha. TagList -- tag list. Poniewaû nie istniejâ jeszcze ûadne tagi dla tej funkcji, wiëc podajemy Nil. Wynik: VisualInfo -- struktura VisualInfo lub Nil, jeûeli wystâpiî bîâd. Gdy VisualInfo nie jest nam juû potrzebna, zwalniamy zajmowanâ przez niâ pamiëê za pomocâ procedury FreeVisualInfo. Format instrukcji: FreeVisualInfo(VisualInfo); Ptr a0 VisualInfo -- struktura VisualInfo uzyskana z GetVisualInfo. Wiëkszoôê programów (szczególnie maîych) otwiera okna na ekranie Workbencha. Jak wiëc uzyskaê wskaúnik do struktury Screen dla tego ekranu? Jednâ z moûliwoôci jest uûycie funkcji OpenWorkbench (z intuition.library). Otwiera ona ekran Workbencha zwracajâc przy okazji potrzebny nam wskaúnik. Uwaga! W inkludach ta funkcja moûe byê zadeklarowana jako procedura (nie zwraca ûadnej wartoôci), np.: (dla KickPascala). -210: procedure OpenWorkBench; naleûy wtedy zmieniê powyûszâ linië na: -210: function OpenWorkBench:p_Screen; Przykîadowe uûycie: program przyklad; {$incl 'libraries/gadtools.h' } var VI:p_VisualInfo; WBScreen:p_Screen begin { otwieramy biblioteki } OpenLib (IntBase,'intuition.library',0); OpenLib (GTBase,'gadtools.library',0); WBScreen:=OpenWorkBench; { otwieramy i otrzymujemy strukturë screen Workbench'a } VI:=GetVisualInfo(WBScreen); { mamy VisualInfo } { ....... } { kod programu } { ....... } FreeVisualInfo(VI); { zwalniamy VisualInfo } { zamykamy biblioteki } CloseLib (GTBase); CloseLib (IntBase); end. Powyûsza metoda ma wadë. W czasie pomiëdzy wywoîaniem OpenWorkbench, a GetVisualInfo inny program moûe zamknâê ekran Workbencha. Jeûeli mamy inkludy w wersji 36. lub wyûszej (dotyczy to chyba tylko piszâcych w C, E itp.), moûemy skorzystaê z innej, znacznie lepszej, metody: Od wersji 36. w bibliotece intuition.library istnieje funkcja LockPubScreen. Zabezpiecza ona public screen o podanej nazwie przed zamkniëciem (do czasu uûycia UnlockPubScreen), zwracajâc structurë Screen dla tego ekranu. Wykorzystanie tej funkcji czyni nie tylko program caîkowicie odpornym na dziaîanie innych programów (w zakresie zamykania ekranów), ale równieû pozwala otworzyê okno na dowolnym public screenie. Przykîad (tym razem dla C z wymienionych wyûej powodów): struct Screen PrgScreen; struct VisualInfo *VI; PrgScreen=LockPubScreen("Workbench"); if (PrgScreen!=NULL) { VI=GetVisualInfo(PrgScreen) /* .... */ /* Otwarcie okna */ UnlockPubScreen(NULL,PrgScreen); /* ... */ FreeVisualInfo(VI); } Jak moûna wywnioskowaê z przykîadu funkcji LockPubScreen, jako argument podajemy nazwë public screena, który chcemy zabezpieczyê przed zamkniëciem. W wypadku ekranu Workbencha bëdzie to, jak w przykîadzie, "Workbench" bâdú NULL (polecam raczej to drugie). Funkcja zwraca structurë Screen danego ekranu lub NULL, jeûeli na tym ekranie otworzenie wîasnego okna jest niemoûliwe. Zabezpieczenie ekranu przed zamkniëciem jest konieczne do czasu otwarcia wîasnego okna na nim (z tâ chwilâ zamkniëcie ekranu jest niemoûliwe aû do zamkniëcia okna). Po otwarciu okna moûna wiëc wywoîaê procedurë UnlockPubScreen, która zezwoli na ewentualne zamkniëcie ekranu po zakoïczeniu pracy naszego programu. Jako argumenty podajemy nazwë ekranu (w przykîadzie NULL) lub jego strukturë Screen (tak jak w przykîadzie). Jeûeli jako oba argumenty podamy NULL, procedura nie zadziaîa. Nastëpnym krokiem, po uzyskaniu VisualInfo, bëdzie wywoîanie funkcji CreateContext. Tworzy ona miejsce, w którym gadtools przechowuje informacje o gadûetach. Format instrukcji: gad:=CreateContext(glist); P_gadûet (P_)P_gadûet d0 a0 glist -- wskaúnik do zmiennej, która bëdzie wskazywaîa poczâtek listy gadûetów. Funkcja ustawia zmiennâ GList tak, ûe wskazuje na Contextgadûet -- niewidoczny gadûet, w którym gadtools bëdzie gromadziîa dane o swoich gadûetach. Jest on pierwszym gadûetem (nastëpne bëdâ doîâczane do niego), wiëc zmiennâ të bëdziemy traktowaê jako wskaúnik listy naszych gadûetów. Wykorzystamy jâ przy otwieraniu okna. Wynik: gad -- context_gadûet lub jeûeli wystâpiî bîâd -- Nil. W praktyce wyglâda to tak: var gad,glist:p_gadget; NW:NewWindow; begin { ....... } Gad:=CreateContext(^glist); if gad<>nil then begin { tutaj tworzymy inne gadûety (wskaúnikiem do pierwszego gadûetu jest glist) } NW.Firstgadget:=glist; { ....... } end; end. Przystëpujemy teraz do tworzenia gadûetów. Do tego celu sîuûy funkcja Creategadûet. Gad:=Creategadget(rodzaj, poprzedni, Newgadget, TagList); p_gadget long P_gadûet P_Newgadget P_TagList d0 d0 a0 a1 a2 Rodzaj -- typ gadûetu, jaki chcemy utworzyê. Poprzedni -- wskaúnik do poprzedniego gadûetu. Przy pierwszym wywoîaniu bëdzie to GList (z funkcji CreateContext). Newgadget -- struktura opisujâca gadûet. TagList -- wskaúnik do taglistu. Na razie Nil. Wynik: gad -- utworzony gadûet lub Nil, jeûeli wystâpiî bîâd. Struktura Newgadûet Newgadûet=Record gng_LeftEdge,gng_TopEdge:Word; { pozyjca X,Y gadûetu } gng_Width,gng_Height:Word; { szerokoôê, wysokoôê } gng_gadgetText:Str; { nazwa gadûetu (zakoïczona zerem) } gng_TextAttr:p_TextAttr; { wskaúnik do struktury TextAttr opisujâcej czcionkë, jeûeli standardowa -- Nil } gng_gadgetID:Word; { identyfikator gadûetu, bëdzie póúniej wpisany do gadûet.gadûetid } gng_Flags:Long; { flagi decydujâce o sposobie wyôwietlania tekstu w gadûecie } gng_VisualInfo:Ptr; { wskaúnik do struktury VisualInfo otrzymanej przez GetVisualInfo } gng_UserData:Ptr; { wskaúnik do danych uûytkownika, bëdzie póúniej wpisany do gadûet.userdata } End; Uwaga! Mimo ûe jest to moûliwe, nie polecam wpisywania w pole gng_TextAttr Nil. W wypadku zmiany standardowej czcionki w preferencjach na wiëkszâ (np. z Topaz 8 na 11) gadûety nie bëdâ dopasowane do jej rozmiarów. Najprostszym wyjôciem jest ustawienie tego pola na strukturë TextAttr, zawierajâcâ opis czcionki, np. topaz 8. Flagi dotyczâce sposobu wyôwietlania tekstu: PLACETEXT_LEFT -- tekst po lewej stronie PLACETEXT_RIGHT -- po prawej PLACETEXT_ABOVE -- ponad gadûetem PLACETEXT_BELOW -- pod gadûetem PLACETEXT_IN -- w gadûecie Jeûeli nie zostanie podana ûadna z nich, gadtools przyjmie wartoôê standardowâ dla danego typu gadûetu. NG_HIGHLABEL -- "podôwietlenie" tekstu Przykîadowe uûycie Creategadget: var OKNewgadget:Newgadget; OKgadget:p_gadget; begin { ........ } OKNewgadget:=Newgadget(10,30,30,12,' OK! ',Nil,1,0,VI,Nil); OKgadget:=Creategadget(BUTTON_KIND,GList,^OKNewgadûet,Nil); { ........ } end. Po zamkniëciu okna naleûy zwolniê pamiëê zajmowanâ przez gadûety. W tym celu wywoîujemy procedurë Freegadûets. Zwalnia ona pamiëê zajëtâ przez CreateContext oraz Creategadûet. Format instrukcji: Freegadgets (GList); P_gadget a0 GList -- lista gadûetów Procedura ta powinna byê wywoîana przed FreeVisualInfo. Na poczâtek zajmijmy sië najprostszym gadûetem -- BUTTON_KIND. Jest on najczëôciej spotykanym gadûetem -- "OK" , "Use" , "Save" itp. Wystarczy ustawiê pozycjë, rozmiary i nazwë gadûetu. Dodatkowo za pomocâ tagów moûna ustawiê: GT_Underscore -- symbol, jaki poprzedza podkreôlonâ literë w nazwie gadûetu. Na przykîad jeûeli w "Cancel" chcemy podkreôliê "C", wtedy w tagu podajemy np. '_', a w nazwie "_Cancel". Uwaga -- dziaîa od wersji 37. biblioteki. GA_Disabled -- jeûeli podamy TRUE (wartoôê róûnâ od 0), gadûet zostanie wyîâczony. Zostanie pokryty "siateczkâ" i nie bëdzie moûna go wybraê. Domyôlnie FALSE. GA_Immediate -- jeûeli podamy TRUE, bëdziemy otrzymywaê message, gdy tylko gadûet zostanie naciôniëty. Domyôlnie FALSE. Uwaga! Dziaîa od wersji 39.! Przy odbieraniu messages z okna, w którym sâ gadûety gadtools, funkcje GetMsg i ReplyMsg naleûy zastâpiê funkcjami GetIMsg i ReplyIMsg (skîadnia taka sama, zmieniono tylko typy parametrów -- zamiast p_Message od razu p_IntuiMessage). W wypadku BUTTON_KIND otrzymujemy tylko IDCMP_gadûETUP (dla systemu 1.3 gadûETUP) oraz, od wersji 39., gdy zostanie ustawiony tag GA_Immediate, IDCMP_gadûETDOWN (gadûETDOWN). Naleûy pamiëtaê jeszcze o paru rzeczach: -- Do ustalonych przez nas flag IDCMP naleûy dodaê (or) xxxIDCMP, gdzie xxx jest typem gadûetu, jakiego uûywamy, np. BUTTONIDCMP, LISTVIEWIDCMP, MXIDCMP. -- Po utworzeniu gadûetów i otwarciu okna naleûy wywoîaê procedurë GT_RefreshWindow. Format instrukcji: GT_RefreshWindow (window, requester); p_Window p_Requester a0 a1 Window -- struktura window okna zawierajâcego gadûety gadtools. Requester -- na razie nie uûywany. Zawsze Nil! Jeûeli najpierw otwieramy okno, potem dodajâc gadûety za pomocâ AddGList, naleûy wywoîaê RefreshGList (z intuition.library), a póúniej GT_RefreshWindow. To tyle w tym odcinku. Za miesiâc przedstawië m.in. listing w KickPascalu, przedstawiajâcy przykîad uûycia biblioteki gadtools.library.