C dla każdego (cz. 18.)
Gadżety (6)
Tak, to już na pewno ostatnia część o gadżetach! Do omówienia pozostała nam jeszcze obsługa
gadżetów z klawiatury.
W funkcji obsluzokno(), gdy nastąpi zdarzenie klasy IDCMP_VANILLAKEY, wywołujemy funkcję
obsluzklaw().
W funkcji obsluzklaw() przeglądamy tablicę "tabnewgad" w poszukiwaniu gadżetu, którego skrót z
klawiatury odpowiadałby wciśniętemu klawiszowi. Skrót z klawiatury odpowiadałby
wciśniętemu klawiszowi. Skrót z klawiatury dla gadżetu poznajemy zaglądając do pola "ngGadget_Text".
Przy użyciu standardowej funkcji strchr() uzyskujemy lokalizację znaku podkreślenia w nazwie,
sam skrót z klawiatury jest zaś literą występującą po tym znaku.
Jeżeli odnajdziemy własciwy gadżet, to wywołujemy odpowiadającą jego typowi funkcję z tablicy
"tabklawfunc". Tablica ta zawiera wskaźniki na funkcje obsługujące skróty z klawiatury dla
poszczególnych typów gadżetów.
Wskaźniki na funkcje umieściliśmy w tej tablicy w taki sposób, aby ich indeksy były równe rodzajom
gadżetów, jakie dane funkcje obsługują. A więc jeżeli np. LISTWIEV_KIND ma wartość, to wskaźnik,
obsługujący skrót z klawiatury dla gadżetu-listy funkcji listwievklawfunc(), znajduje się w
elemencie tablicy o indeksie 4. bardzo ułatwia to wywoływanie właściwej dla danego gadżetu funkcji.
Korzystając z tablicy "tabgadtypes" usykujemy informacje o typie gadżetu, znając go i korzystając z
"tablawfunc" możemy wywołać właściwą funkcję.
Zadaniem funkcji z tablicy "tabklawfunc" jest zmiana stanu gadżetu po naciśnięciu klawisza. W
wypadku, gdy użytkownik używa myszki, stan gadżetu zmienia się automatycznie (zajmuje się tym
biblioteka GadTools). Np. gdy użytkownik kliknie na którejś pozycji w gadżecie-liście, nasz program
dostaje informacje: "użytkownik kliknął na gadżet, obecnie zaznaczona pozycja to ..." W wypadku
użycia klawiatury to na nas spada obowiązek obsługi zdarzenia, tym właśnie zajmują się funkcje z
"tablawfunc". Niektóre typy gadżetów nie muszą być zdefiniowane. Np. kliknięcie myszą na
gadżecie-przycisku nie zmienia w żaden sposób jego stanu, tak więc nie trzeba się nim przejmować
przy obsłudze klawiatury"
Omówimy pokrótce, co robią poszczególne funkcje:
checkboxklawfunc() - używana dla gadżetów CHECKBOX_KIND. W zależności od bieżącego stanu gadżetu
(opisanego w polu "Flags" przez flagę GFLG_SELECTED) funkcja "zafajeczkowuje" lub "odfajeczkowuje"
gadżet.
integerstringklawfunc() - używana dla gadżetów INETEGER_KIND i STRING_KIND. Wywołuje funkcje z
biblioteki Intuition:
BOOL ActivateGadget(struct Gadget *gadgets, struct Window *window, struct Requester *requester);
Funkcja ta powoduje uaktywnienie gadżetu.
listwievklawfunc() - używana dla gadżetów LISTWIEV_KIND. W wypadku wpisania z klawiatury małej
litery powoduje ona zaznaczenie kolejnej pozycji, a w wypadku wpisania litery z wciśniętym
klawiszem [Shift] zaznaczenie poprzedniej pozycji. Jeżeli użytkownik chciałby wyjść "poza granice"
gadżetu, należy jego żądanie zignorować. osobnego rozpatrzenia wymaga wypadek, gdy żadna pozycja nie
jest zaznaczona - możliwy jest wtedy tylko ruch "w dół".
sliderklawfunc() - używana dla gadżetów SLIDER_KIND. Zachowuje się analogicznie do poprzedniej, nie
wyamaga jednak rozpatrywania przypadku "żadna nie jest zaznaczona", jako że gadżet-suwak zawsze coś
przekazuje.
mxklawfunc(), cycleklawfunc(), paletteklawfunc() - używane dla gadżetów MX_KIND, CYCLE_KIND,
PALETTE_KIND. Podobnie jak poprzednich wypadkach, w zależności od tego czy wpisano literę z
[Shiftem], czy bez, powodują zaznaczenie poprzedniej, bądź kolejnej pozycji. Jednak przy tych
gadżetach zaznaczenie powinno być zapętlone. Jeżeli np. bieżąca pozycja jest ostatnią i użytkownik
chce zaznaczyć kolejną, to należy zaznaczyć pozycję pierwszą, i na odwrót.
Po wywołaniu funkcji z "tabklawfunc" wywoływana jest specyficzna dla danego gadżetu funkcja
odnotowana w polu "UserData" gadżetu. Funkcje te omówiliśmy w poprzedniej części. Zauważcie, że nie
robimy tego dla gadżetów INTEGER_KIND i STRING_KIND. W wypadku tych gadżetów użycie skrótu z
klawiatury powoduje jedynie uaktywnienie gadżetu. Zmiana jego stanu dokonuje się dopiero wtedy, gdy
gadżet jest już aktywny i coś zostanie z klawiatury wpisane.
Pozostała nam do omówienia jeszcze jedna funkcja - wylaczonygad(). Informuje ona czy gadżet jest
wyłączony (za mgiełką), czy nie. Użycie skrótu z klawiatury jest obslugiwane tylko wtedy, gdy gadżet
jest włączony. Można to zasadniczo sprawdzić na dwa sposoby. Pierwszym jest sprawdzenie czy w polu
"Flags" gadżetu jest ustawiona flaga GFLG_DISABLED. Zaglądanie do flag gadżetu podłączonego do
okna nie jest jednak sposobem eleganckim. OS 3.0 oferuje nam w tym celu funkcję biblioteki GadTools:
LONG GT_GetGadgetAttrsA(struct Gadget *gad, struct Window *win, struct Requester *req, struct
TagItem *taglist);
LONG GT_GetGadgetAttrs(struct Gadget *gad, struct Window *win, struct Requester *req, struct
Tag tag1, ...);
Funkcja ta umożliwia pobieranie informacji o poszczególnych atrybutach gadżetu. Parametry są niemal
analogiczne z tymi w GT_SetGadgetAttrsA(). Należy podać tagi atrybutów, jakie chcemy uzyskać, oraz
adresy zmiennych, do których mają zostać zapisane wyniki. Tu uwaga: nawet jeżeli GT_SetGadgetAttrsA
akceptuje parametr typu "char" lub "word", funkcja GT_GetGadgetAttrsA wymaga zmiennej typu "long".
Funkcja ta zwraca liczbę atrybutów, które zostały poprawnie obsłużone.
Jeżeli nasz program jest uruchomiony pod OS 3.0 lub nowszym, to wywołujemy funkcję
GT_GetGadgetAttrsaA() z tagiem "GA_DISABLED". W przeciwnym razie po prostu zaglądamy do pola
"Flags" gadżetu.
To by było wszystko jeżeli chodzi o gadżety.
Wypadałoby jeszcze skorygować małą pomyłkę: w przdstawionej pierwszej części listingu, w napisie
opisującym wersję programu pojawił się rok 95, a powinien być oczywiście 96.