C dla każdego (cz. 11.)

Górne menu (2)

W tym odcinku znajdziecie omówienie listingu nr 11.

W elemencie zawierającym opis pozycji "Zwykły" nm_MutualExclude ma wartość 8|16|32, co oznacza wysterowane bity 3, 4 i 5, tak więc wybranie tej pozycji spowoduje wyczyszczenie "fajeczek" w pozycjach "Wytłuszczony", "Kursywa" i "Podkreślony" (bo "Tryb" ma numer 0, BARLABEL 1, "Zwykły" 2 itd). Te trzy ("Wytłuszczony", ...) pozycje mają "nm_MutualExclude" równe 4, ich wybranie powoduje więc wyczyszczenie tylko pozycji "Zwykły" -- mogą więc być jednocześnie zaznaczone, np. "Podkreślony" i "Kursywa".

Jak zapewne wiecie, system umożliwia wybranie więcej niż jednej pozycji na raz -- robi się to klikając kolejno lewym przyciskiem na kilku pozycjach i trzymając równocześnie przez cały czas wciśnięty prawy przycisk. Program nie dostaje jednak w takim wypadku kilku wiadomości IDCMP_MENUPICK: dostaje tylko jedną, a w polu "NextSelect" wybranego "MenuItem" znajduje się numer kolejnej wybranej pozycji bądź MENUNULL, gdy jest to ostatnia wybrana pozycja.

Informacje zapisane w strukturze "NewMenu" w polu "nm_UserData" uzyskuje się ze struktur "Menu" bądˇ "MenuItem" za pomocą makr preprocesora, zdefiniowanych w pliku "libraries/gadtools.h" -- odpowiednio GTMENU_USERDATA() i GTMENUITEM_USERDATA(). W pola "nm_UserData" wstawiliśmy adresy napisów, które wypisywane są na konsoli, gdy użytkownik wybierze daną pozycję/podpozycję. Jest to rozwiązanie dużo bardziej eleganckie i krótsze niż np. użycie instrukcji "switch" do analizowania pola "Code" struktury "IntuiMessage". Wybranie pozycji "Normalny", "Wytłuszczony", "Kursywa" lub "Podkreślony" powoduje wypisanie napisu, zawierającego kody sterujące, które powodują zmianę atrybutów konsoli - są one opisane w dostarczanej wraz z Amigami instrukcji obsługi Workbencha (w rozdziale o drukowaniu), darujemy więc sobie tutaj ich opis.

W listingu wykorzystaliśmy też makro FULLMENUNUM(), zdefiniowane w "intuition/intuition.h". Jest ono przeciwieństwem poznanych wcześniej makr MENUNUM(), ITEMNUM() i SUBNUM(). Oczekuje ono trzech argumentów: numeru menu, pozycji w menu i podpozycji -- koduje podane parametry w taki sam sposób, w jaki zakodowane jest pole "Code".

Listing ukazuje również, w jaki sposób można sprawdzić, czy dana pozycja jest "zafajeczkowana", czy też nie. Sprawdza się to, analizując pole "Flags" w strukturze "MenuItem", opisującej daną pozycjęę (adres tej struktury uzyskujemy za pomocą ItemAddress() i FULLMENUNUM()) -- jest ono niemal dokładnym odpowiednikiem pola "nm_Flags" w strukturze "NewMenu". Należy po prostu sprawdzić, czy wśród flag znajduje się CHECKED.

Aby opis programowania menu uczynię niemal kompletnym, trzeba wspomnieć o jeszcze dwóch, nie użytych przez nas funkcjach:

void OnMenu( struct Window *window, unsigned long menuNumber );
void OffMenu( struct Window *window, unsigned long menuNumber );

Powodują one odpowiednio włączenie bądź wyłączenie (tj. "zamglenie") menu bądź pozycji/podpozycji. To, czy menu albo pozycja/podpozycja jest w danej chwili włączona, można sprawdzić, analizując pole "Flags" struktur "Menu" bądˇ "MenuItem" pod kątem flag odpowiednio "MenuEnabled" lub "ItemEnabled".

W następnej części "odpoczniemy" sobie nieco od graficznego interfejsu użytkownika. Zajmiemy się przydzielaniem pamięci i systemowymi listami. A za dwa miesiące: gadżety.