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.