• Kurs MUI - część 6

20.02.2005 14:41, autor artykułu: Grzegorz Kraszewski
odsłon: 2973, powiększ obrazki, wersja do wydruku,

Tworzenie podstawowych obiektów

Tym razem nieco odpoczniemy sobie od obiektowych zawiłości. Ten odcinek poświęcę prawidłowemu tworzeniu typowych obiektów takich jak przyciski, stringi i tym podobne. Nie będzie to jednak tłumaczenie dokumentacji, większy nacisk położę na wiedzę jaką zdobyłem praktycznie podczas walk z MUI, a więc krótko mówiąc na to, czego w autodokach nie ma. Zatem do rzeczy. Chyba najbardziej popularnym rodzajem gadżetów są

Przyciski

Co ciekawe MUI nie oferuje jakiejś specjalnej klasy do tworzenia przycisków, co może być zaskakujące dla świeżo upieczonego adepta naszej sztuki tajemnej. Wynika to z faktu, że tak naprawdę rolę przycisku może pełnić każdy obiekt (nawet grupa). Przeważnie chodzi nam jednak o zwykły przycisk z napisem, typową ramką i wciskający się. Taki przycisk najprościej stworzyć jako obiekt klasy MUIC_Text. Korzystając z atrybutu MUIA_Text_Contents podajemy napis jaki pojawi się na przycisku. Ponieważ z reguły napis jest wycentrowany, tekst rozpoczynamy kodem centrowania:

MUIA_Text_Contents, "33cKliknij",


Jak już jesteśmy przy napisie - MUI ma w ustawieniach oddzielną czcionkę do przycisków, częstym błędem jest jej nieustawienie (przykład: preferencje do programu VMM). Pamiętajmy więc o tej linijce:

MUIA_Font, MUIV_Font_Button,


Oczywiście przyciski powinny mieć odpowiednie tło:

MUIA_Background, MUII_ButtonBack,


Kolejna sprawa to adekwatna do sytuacji ramka:

MUIA_Frame, MUIV_Frame_Button,


W ten sposób przycisk wygląda już tak jak powinien. Ale wygląd to nie wszystko. Ważną sprawą jest aktywacja z klawiatury. Pierwszy sposób, to umieszczenie przycisku w łańcuchu gadżetów po których można "chodzić" klawiszem TAB. W ten sposób do przycisku będzie można się doTABować, po czym wciskając ENTER wcisnąć jednocześnie przycisk. To osiągamy bardzo łatwo umieszczając tag:

MUIA_CycleChain, TRUE,


Warto zapamiętać, że tag ten należy do klasy MUIC_Area, a więc możemy go stosować do dowolnych gadżetów. Drugi sposób aktywacji to gorące klawisze (hotkeye). Przycisk z gorącym klawiszem ma z reguły podkreśloną literę, której naciśnięcie powoduje zadziałanie przycisku. W MUI osiągamy to dwuetapowo. Po pierwsze podkreślenie litery:

MUIA_Text_HiChar, 'k',


Po drugie reagowanie na klawisz:

MUIA_ControlChar, 'k',


Jest to chyba naturalne, że dla obu tagów podajemy tę samą literę. MUIA_ControlChar możemy zastosować również do dowolnych gadżetów. W przypadku gadżetów nie zawierających w sobie napisów podkreślony znak umieszczamy w etykiecie gadżetu (o której dalej). Nie warto jednak z "oklawiszowywaniem" przesadzać, naturalne jest przypisanie gorących klawiszy przyciskom właśnie oraz np. checkmarkom. Dorabianie hotkeyów do wszystkiego mija się z celem, zwłaszcza że są jeszcze mechanizmy wbudowane w MUI takie jak wspomniany wcześniej TAB. Przy MUIA_CycleChain można sobie nie żałować i podpiąć tu wszystko, czym da się w programie manipulować. Ostatnim wreszcie problemem jest samo wciskanie się przycisków. Przycisk może być jednostanowy (wciska się w momencie wciśnięcia przycisku myszy, powraca do stanu swobodnego po puszczeniu LMB, akcja jest wyzwalana w momencie puszczenia przycisku) lub rzadziej spotykany dwustanowy (po jednum kliknięcu przycisk wciska się i pozostaje wciśnięty aż do następnego kliknięcia). Rodzaj przycisku wybieramy tagiem MUIA_InputMode:

MUIA_InputMode, MUIV_InputMode_RelVerify,


dla przycisku jednostanowego, a

MUIA_InputMode, MUIV_InputMode_Toggle,


dla przycisku dwustanowego. Co za tym idzie inne będą notyfikacje, które ustawimy w celu wykonania działania po wciśnięciu przycisku. Dla przycisku jednostanowego notyfikację ustawić należy na MUIA_Pressed, FALSE, dla dwustanowego MUIA_Selected, TRUE na wciśnięcie i FALSE na wyciśnięcie.

Stringi

To również bardzo szeroko używany rodzaj gadżetów. Pewną niekonsekwencją w MUI jest fakt, że nie musimy tym razem podawać czcionki używanej w gadżecie ani tła (co nie znaczy, że nie można ich zmienić, po prostu standardowa czcionka i tło są ustawiane automatycznie). Wypada natomiast zatroszczyć się o ramkę. Jak łatwo zgadnąć odpowiedni tag będzie miał postać:

MUIA_Frame, MUIV_Frame_String,


Zdecydowanie polecam włączenie stringów w łańcuch klawisza TAB tagiem MUIA_CycleChain. Oprócz tego bardzo wygodne (w przypadku kilku stringów) jest, jeżeli po wciśnięciu ENTER-a w danym stringu automatycznie przechodzimy do następnego. Osiąga się to przez podanie taga:

MUIA_String_AdvanceOnCR, TRUE,


Klasa MUIC_String posiada szereg atrybutów pozwalających na określenie tego, co do gadżetu wpisać można, a czego nie i jak to będzie wyglądało. Przede wszystkim określić można maksymalną długość wpisywanego tekstu:

MUIA_String_MaxLen, 128,


Standardowa wielkość tego parametru wynosi 80. Ale uwaga - wliczany jest również niewidoczny znak o kodzie 0 znajdujący się zawsze na końcu tekstu. Tak więc rzeczywista ilość znaków, jaką może wpisać użytkownik, jest o 1 mniejsza. Czasem z chęcią utrudnilibyśmy użytkownikowi życie i nie pozwolili na wpisanie jakichś znaków do gadżetu, albo z drugiej strony pozwolili na wpisanie tylko określonych przez nas znaków. Na przykład tylko cyfr. MUI daje nam do dyspozycji dwa tagi MUIA_String_Accept i MUIA_String_Reject. W pierwszym możemy podać listę akceptowanych znaków, w drugim listę znaków odrzucanych. I tak gadżet reagujący tylko na cyfry definiuje się następująco:

MUIA_String_Accept, "0123456789",


Z kolei gadżet odrzucający znaki specjalne i wzorce AmigaDOS-u tworzymy tak:

MUIA_String_Reject, "/:[]()*#?|^-~",


Jeżeli chcemy podać w znakach cudzysłów, kodujemy go jako 042 (w C). Oczywiście znaki nie muszą być posortowane według kodów ASCII. Wśród informatyków pracujących w tajnych służbach uznanie znajdzie z pewnością tag MUIA_String_Secret. Powoduje on, że wszystkie wpisywane litery są pokazywane jako gwiazdki, ten tryb niewątpliwie jest przydatny do wpisywania wszelkiego rodzaju haseł. Jednak taki gadżet nie jest zbyt bezpieczny, bo wystarczy wyciąć z niego tekst do clipboardu (AMIGA+C) i wstawić np. do CED-a, aby zobaczyć tekst jawny (!). Tagiem o znaczeniu wyłącznie estetycznym jest MUIA_String_Format pozwalający dosunąć wpisywany tekst do lewej, do prawej, bądź umieścić go na środku. Ostatnim z tagów, które chciałbym opisać jest MUIA_String_Integer. Umożliwia on przekształcenie gadżetu tekstowego w liczbowy. Ustawienie tego taga z jakąś liczbą jako wartością spowoduje zamianę tej liczby na tekst i wstawienie tego tekstu do gadżetu. Pobranie atrybutu pociągnie za sobą próbę konwersji zawartości gażdetu na liczbę i zwrócenie tej liczby. Aby ograniczyć wpisywanie bzdur dobrze jest przy takim gadżecie ograniczyć wpisywane znaki do liczb (i ewentualnie minusa) tagiem MUIA_String_Accept. Gadżet taki obsługuje tylko liczby całkowite z zakresu -2^31 do +2^31 - 1.

Do wstawiania tekstu do gadżetu i odczytywania tego tekstu służy atrybut MUIA_String_Contents. Można również ustawić nań notyfikację. W takim przypadku notyfikacja będzie miała miejsce po każdej zmianie tekstu, a więc po każdym niemal naciśnięciu klawisza (również BACKSPACE, czy DELETE). Nie zawsze o to chodzi, czasem wystarczy notyfikacja w momencie zakończenia wpisywania tekstu. Wtedy notyfikację ustawiamy na MUIA_String_Acknowledge, jest ona wywoływana po wciśnięciu przez użytkownika ENTER-a.

Etykiety gadżetów

Gadżety takie jak string (a właściwie większość gadżetów oprócz przycisków) miewają podpisy, czyli tak zwane etykiety. Etykiety tworzy się jako obiekty klasy MUIC_Text (a więc tej samej, co przyciski). Etykiety nie mają ramki, nie mają też tła, dzięki czemu "dziedziczą" tło po grupie do której należą. Z reguły nie podaje się też czcionki etykiety, przez co używana jest czcionka standardowa. W uzasadnionych przypadkach można ustawić dużą lub małą czcionkę z preferencji (MUIV_Font_Big lub MUIV_Font_Tiny). W celach specjalnych można podać jako czcionkę wskaźnik na strukturę TextFont, ale w typowych programach nie powinno się tego robić (w ten sposób ogranicza się swobodę użytkownika w kształtowaniu wyglądu GUI). Jeżeli etykieta opisuje gadżet mający skrót klawiszowy, włączamy podkreślenie odpowiedniej litery atrybutrem MUIA_Text_HiChar, tak jak to opisałem przy przyciskach.

Teraz słów kilka o rozmieszczaniu etykiet. Z reguły pole zajmowane przez etykietę powinno być tylko takich rozmiarów, ile zajmuje napis. Jeżeli rozciągamy okienko w poziomie, rozmiar pola z etykietą nie powinien się zwiększać. Osiągamy to przez podanie atrybutu

MUIA_Text_SetMax, TRUE,


Rysunek pokazuje różnicę w zachowaniu się grupy złożonej z etykiety i stringa w przypadku użycia lub nie powyższego atrybutu. Jeżeli atrybutu nie ma, pole etykiety i string zajmują po połowie dostępnego miejsca (ewentualnie, jeżeli miejsca jest mało, tak jak na górnym okienku na rys. 1, to tekst dostaje tyle, żeby w całości się zmieścić, a string resztę). Po użyciu MUIA_Text_SetMax rozmiary pola etykiety są stałe, a całą resztę miejsca dostaje string. Jest to bardzo intuicyjne, jeżeli użytkownikowi tekst nie mieści się w stringu, to rozszerza okienko i poszerza się jedynie gadżet tekstowy, a nie jego opis.

MUI

MUI Rysunek ilustruje przy okazji kolejny problem. Jeżeli mamy, tak jak w przykładzie, kilka gadżetów z etykietami, to ładnie by było, gdyby były one ułożone w dwóch eleganckich kolumnach, a więc żeby stringi były tej samej długości. Uważni czytelnicy zapewne zaproponują od razu dwa rozwiązania. Można rozmieścić obiekty w grupach pionowych zamiast poziomych, albo w jednej grupie tablicowej. Oba rozwiązania są dobre, aczkolwiek natkniemy się w obu przypadkach na małe kłopoty, oczywiście do rozwiązania. Zacznijmy od pomysłu z grupami pionowymi. Od razu widać, że etykiety są źle rozmieszczone w pionie. Dlaczego, przecież czcionka jest ta sama? No tak, ale stringi mają przecież ramki, a etykiety nie. Najlepiej by było, gdyby etykiety też miały ramki, ale żeby nie były one rysowane. Niemożliwe? W MUI nie ma rzeczy niemożliwych... Oto rozwiązanie. Gadżetom tekstowym dodajemy:

MUIA_Frame, MUIV_Frame_String,
MUIA_Frame_Phantom_Horiz, TRUE,


MUI Cała sztuka tkwi w drugim atrybucie. Dzięki niemu MUI przy umieszczaniu etykiety zakłada, że ma ona podaną ramkę (dokładniej - zakłada, że obiekt ma poziome części ramki i odstępy w pionie między ramką i zawrtością), ale tej ramki nie rysuje. W efekcie mamy etykiety elegancko rozmieszczone. Niestety pojawił się nowy problem - etykiety nie są wyrównane do prawej, znalazły się bowiem w oddzielnej grupie niż stringi. Winien jest tu - o paradoksie - atrybut MUIA_Text_SetMax. Grupa pionowa jest tak szeroka jak najszerszy jej element (najdłuższy napis). Pozostałe są, jak pisałem w jednym z pierwszych odcinków, centrowane w poziomie. Co zrobić? Potrzebny jest jakiś subtelniejszy mechanizm sterowania szerokością grup. Znakomicie nada się tutaj atrybut MUIA_HorizWeight. Jego działanie ma wpływ na ustalanie szerokości obiektów. Jak pisałem wcześniej, obiekty dostają miejsce według wag ustalanych wyżej wspomnianym atrybutem - im większa waga, tym więcej miejsca. Zastanówmy się teraz co będzie, jeżeli wagę obiektu ustalimy na 0 (nie, nie, MUI się nie zawiesi jeżeli ktoś o tym pomyślał...)? Wtedy obiekt otrzyma możliwie najmniej miejsca, tyle tylko, aby się zmieścił. Podajmy więc ten atrybut grupie z etykietami. W efekcie będzie tak, jakbyśmy podali MUIA_Text_SetMax tylko dla najdłużeszgo napisu, reszta będzie tej samej szerokości i wyrównana do prawej, właśnie tak, jak na rysunku. Oczywiście teraz już nie podajemy MUIA_Text_SetMax.

Podobnie wygląda sprawa z grupą tablicową. Z pozoru może się po jej użyciu wydawać, że użycie "niewidzialnej ramki" MUIA_FramePhantomHoriz jest zbędne. Dzieje się tak dlatego, że obiekty w komórkach tablicy są zawsze centrowane w pionie i w poziomie. Wystarczy jednak w preferencjach MUI ustawić dla ramki stringów różne odstępy między ramką i zawartością na górze i na dole. Wtedy niedoróbka wyjdzie na jaw - etykiety nie będą na jednym poziomie z napisami wewnątrz stringów. Dlatego "poziomego fantoma" trzeba jednak użyć. Poza tym MUIA_HorizWeight, 0 trzeba podać dla każdej etykiety z osobna. Generalnie stosowanie tablicy zamiast grup pionowych daje nam o dwie grupy mniej (a raczej tyle, ile jest kolumn), ale za to więcej jest tagów (bo MUIA_HorizWeight trzeba podać tyle razy, ile jest wierszy). Ja z reguły używam tablicy, ale nie jest to jakaś objawiona prawda, której należy się trzymać, a jedynie kwestia gustu.

MUI

Tutaj znajdziecie kody źródłowe i skompilowane programy do wszystkich przykładów, z których pochodzą rysunki w tekście. Pewnie niektórzy myśleli, że rysuję je np. w Personalu, ale komu to by się chciało ;-). Oprócz tego jest tam większy program ilustrujący omówione dziś zagadnienia, a GUI przez niego tworzone możecie obejrzeć na rysunku powyżej. A w następnych odcinku dowiecie się o tworzeniu checkmarków, gadżetów "radio", gadżetów cyklicznych i może jeszcze o czymś.

    
dodaj komentarz
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem