System GUI #3 – Zdarzenia

2007-08-14 11:42

Graficzny interfejs może (i powinien) ładnie wyglądać, ale jego najważniejszą cechą jest oczywiście interaktywność. GUI musi przede wszystkim umożliwiać reakcję na poczynania użytkownika, a to jest możliwe przez odpowiednią obsługę zdarzeń.

Informację o tym, że kliknięto gdzieś myszką lub wciśnięto klawisz, pozyskać jest oczywiście bardzo łatwo. W Windows wystarczy w tym celu obsługiwać komunikaty systemowe przychodzące do okna. O wiele większym wyzwaniem jest przetłumaczenie informacji “kliknięto w punkt (458,89) obszaru klienta” na “kliknięto w obrębie kontrolki TextBox o nazwie Text1“. Komunikat należy bowiem przekazać do odpowiedniej kontrolki (-ek) – tej, której on dotyczy.

Jest pewnie wiele sposób na zrealizowanie takiego przekazywania, jednak najbardziej sensowne wydają mi się dwa. Pierwszym z nich jest propagacja zdarzenia na kolejne poziomy drzewa systemu GUI. Kliknięcie jest więc przekazywane do okna i od tej pory cała odpowiedzialność za jego obsłużenie spada na to właśnie okno. Ono sprawdza, czy myszka trafiła w którąś z kontrolek potomnych; jeśli tak, to znów zdarzenie jest przekazywane właśnie do tej kontrolki i okno się już nim nie zajmuje. Proces ten przebiega aż dojdziemy do najniższego możliwego poziomu, czyli kontrolki nie zawierającej już żadnych innych. Tam następuje właściwa obsługa zdarzenia.

Przepływ zdarzeń w systemie GUI - wariant pierwszy

Drugi sposób zakłada, że zdarzenie nie będzie “rozłazić” się po całym drzewie, tylko od razu trafiać do tej właściwej, docelowej kontrolki. Naturalnie nie zawsze da się tak zrobić. W przypadku wciśnięć klawiszy możemy pamiętać, która kontrolka ma tzw. fokus i do niej kierować komunikaty. Natomiast obsługa myszki wymaga wysłania swego rodzaju sondy wgłąb drzewa kontrolek w celu znalezienie tej najmniejszej, w którą trafił kursor (operacja ta jest znana jako hit test).

Przepływ zdarzeń w systemie GUI - wariant drugi

Generalnie zdarzenia z punktu widzenia ich obsługi można podzielić na dwie grupy: na zdarzenia myszki i na… wszystkie inne :) To właśnie te pierwsze przysparzają najwięcej kłopotów. Nie tylko wymagają rekurencyjnego przeszukiwania drzewa kontrolek, ale też mogą mieć globalne konsekwencje, jak np. zmiana fokusu. Zajmowanie się tymi konsekwencjami jest łatwiejsze, gdy wszystko odbywa się “na górze” – na poziomie głównych klas systemu GUI, a nie pojedynczych kontrolek. Jest to jeden z powodów przemawiających za wyborem drugiego sposobu przekazywania informacji o zdarzeniach.

Tags: , , ,
Author: Xion, posted under Programming » 1 comment

Uciążliwe reklamy

2007-08-13 10:08

Dawno, dawno temu, kiedy łącza były wolne a przeglądarki prymitywne, reklamy na stronach WWW miały postać statycznych lub co najwyżej animowanych banerów. Mało kto używał technologii w rodzaju Flash czy ActiveX, wymagających niestandardowych pluginów instalowanych po stronie użytkownika. A jeżeli już się na to decydował, to reklamy wykorzystujące te rozwiązania różniły się od zwykłych głównie stroną estetyczną: jakością i płynnością animacji.

Chciałoby się powiedzieć: stare dobre czasy, bo dawno odeszły już one do przeszłości. Teraz ze świecą można szukać nieflashowych banerów, a na stronach często można spotkać normalne telewizyjne, streamowane spoty reklamowe. Nie byłoby w tym nic niestosownego – w końcu reklamy są nieodłączną częścią każdego medium, a wykorzystanie najnowszych technologii z pewnością zwiększa ich atrakcyjność, a przez to skuteczność.

I wszystko byłoby w porządku, gdyby ich twórcy znali pojęcie umiaru i taktu. Problemem jest bowiem nie to, że dzisiejsze reklamy sieciowe to już nie tylko animacje, ale i filmy z dźwiękiem i muzyką, a nawet interaktywne gry. Sęk w tym, że one bardzo często przeszkadzają, a wręcz uniemożliwiają zapoznanie się z właściwą treścią strony, na której się znajdują.
Dzisiaj na przykład natrafiłem na baner jednego z operatorów komórkowych, wokół którego latały różnokolorowe motylki. Z pewnością wyglądały one efektownie, lecz czy oznacza to, że ich chmara powinna przesuwać się nad czytany przeze mnie tekst? A tak właśnie było, co oczywiście uniemożliwiało przeczytanie czegokolwiek. Rój uspokoił się dopiero wtedy, gdy przewinąłem się z powrotem na początek strony, gdzie widniał baner.

Zazwyczaj jestem przeciwny wszelkim zakazom – zwłaszcza w delikatnym obszarze Internetu – ale tym razem uważam, że ktoś powinien się zająć tą sprawą. Ktoś – czyli na przykład Komisja Europejska, która ostatnio całkiem dobrze spisała się w zakresie obrony praw użytkowników komórek i klientów linii lotniczych. Pół miliarda obywateli UE, z którego większość korzysta z Internetu, na pewno nie miałoby jej za złe wprowadzenie regulacji ograniczających ekspansję uciążliwych reklam.
Nie uważam przy tym, by musiałyby być one szczególnie restrykcyjne. Zasadniczo wystarczyłyby tylko dwa punkty:

  • Reklamy wyświetlane w obrębie strony nie powinny wyświetlać się poza przeznaczonym na nie (w kodzie strony) prostokątem. Wszelkie “wychodzące” banery czy te nieszczęsne motylki powinny być zakazane.
  • Reklamy wyskakujące (popupy i popundery) powinny mieć zawsze widoczny, duży i kontrastowy przycisk X w prawym górnym rogu, przy pomocy którego można zawsze zamknąć reklamę.

Oczywiście można mieć wątpliwości, czy takie prawo nie byłoby trudne do egzekwowania, a przez to martwe. Dotyczyłoby ono jednak głównie dużych portali, czyli zarejestrowanych i powszechnie przedsiębiorstw, na które bez problemu można w razie czego nałożyć kary finansowe.
A co z mniejszymi serwisami? Naturalnie należałoby uniknąć absurdów w rodzaju wlepiania wirtualnych mandatów autorom stron domowych. W ich przypadku karą byłby po prostu spadek liczby odwiedzających i pogorszenie reputacji – czyli mechanizm, który w Internecie działa od zawsze.

Tags: ,
Author: Xion, posted under Internet, Thoughts » 3 comments

Pętle w Pythonie

2007-08-12 12:21

Konstrukcje iteracyjne w C++ mają całkiem spore możliwości. Dotyczy to zwłaszcza instrukcji for, która jest o wiele elastyczniejsza niż w innych językach. Mimo to w dziedzinie pętli C++ ma pewne niedostatki.
Zwykle najbardziej brakuje nam sposobu na przerwanie zagnieżdżonych pętli. W C# czy Javie jest to możliwe za pomocą specjalnych wariantów instrukcji break. Lecz w C++ trzeba to robić albo z wykorzystaniem wyklętej (niezbyt zresztą słusznie) instrukcji goto, albo poprzez zastosowanie zmiennych logicznych. Istnieje też sposób z wykorzystaniem wyjątków, ale można go traktować chyba tylko jako ciekawostkę.

Jest jeszcze jedno usprawnienie mechanizmu pętli, którego C++ nie posiada, ale dla odmiany ten brak nie jest aż tak dolegliwy. Chodzi tu o klauzulę else występującą po pętli. Tę nietypową konstrukcję widziałem jak dotąd tylko w języku Python; wygląda ona następująco:

  1. # sprawdzenie, czy liczba x jest pierwsza
  2. for i in range(2, x):
  3.    if x % i == 0:
  4.       print x, " dzieli się przez ", i
  5.       break
  6. else:
  7.    print x, " jest liczbą pierwszą"

Fraza else odnosi się tutaj do pętli, a nie do instrukcji if. Jest ona wykonywana wtedy, gdy pętla kończy się normalnie, tzn. nie następuje wykonanie instrukcji break. Jak widać oznacza to zwykle, że jakiś rodzaj przeszukiwania dotarł do końca wyznaczonego zakresu bez znalezienia pasującego elementu (w tym przypadku – dzielnika).

Większość języków nie posiada tej dziwnej konstrukcji, bo najczęściej można się bez niej obejść. Przeszukiwanie dokonywane w pętli jest bowiem często zamykane w funkcję, którą można zapisać bez użycia break:
bool IsPrime(unsigned x)
{
for (unsigned i = 2; i < x; ++i) if (x % i == 0) return false; return true; }[/cpp] Pewne “nowoczesne” konstrukcje w nowszych językach programowania nie są więc zawsze lekarstwem na programistyczne bolączki. Czasami są zwykłym zawracaniem głowy.

Tags: ,
Author: Xion, posted under Programming » 3 comments

Rozsupływanie grafów

2007-08-11 13:36

Zawsze lubiłem teorię grafów. Niestety, ta sympatia jest w dużym stopniu nieodwzajemniona, gdyż z obejmującej tę teorię matematyki dyskretnej nie miałem zbyt dobrych ocen :) Mimo to chciałbym dzisiaj polecić pewną grę ściśle związaną z tą dziedziną.

Chodzi o Planarity. Polega ona na tym, by ułożyć wierzchołki danego grafu planarnego tak, by żadne jego krawędzie się nie przecinały. Dla małych grafów jest to oczywiście proste, lecz gdy liczba wierzchołków przekracza kilkanaście, na rysunku zaczyna być już gęsto…

Screen z etapu 3 gry Planarity Screen z etapu 5 gry Planarity

Na forum Warsztatu pojawił się wątek z pytaniem o jakiś systematyczny sposób na odpowiednie ułożenie wierzchołków w tej grze. Z faktu, że o tej pory nie znaleziono tam żadnego pewnego rozwiązania wynika, że to całkiem interesująca gra ;)

Tags: ,
Author: Xion, posted under Games » Comments Off on Rozsupływanie grafów

O pożytkach z komentarzy

2007-08-10 13:35

Kiedy komukolwiek pokazuję fragment napisanego przez siebie kodu, reakcja jest zawsze dość podobna. Można ją streścić jako pytanie: “A dlaczego tu tak zielono?” :)

Faktycznie, dość intensywnie używam komentarzy. Rzeczywiście, nadużywam też stosowania przerw w postaci pustych wierszy. Zgadza się, że dwa wiersze “normalnego” kodu odpowiadają przeciętnie trzem wierszom napisanym przez mnie. Tak, to wszystko prawda. Co mam na swoje usprawiedliwienie?
Otóż… nic :P Wręcz przeciwnie, taki sposób pisania uważam za bardzo pożyteczny, a powodują mną takie oto motywy:


    Logo programu doxygen, jednego z darmowych systemów generujących dokumentację techniczną z kodu
  • Pierwszy jest dość oczywisty: duża ilość komentarzy ułatwia zrozumienie kodu. Ponadto jeżeli nie są to komentarze pisane ot, tak sobie, lecz zgodnie z pewnym powszechnym standardem, mogą zostać wykorzystane do stworzenia dokumentacji technicznej. Na temat takiej dokumentacji można oczywiście powiedzieć mnóstwo złych rzeczy – na czele z jej małą przydatnością dla samego programisty, który dany kod tworzy. Pozwala ona jednak przynajmniej spojrzeć całościowo na daną klasę/moduł/przestrzeń nazw/bibliotekę/program, zwłaszcza jeśli używany program potrafi też rysować ładne schematy :)
  • Poza tym ktoś ładnie powiedział, że komentarze są przydatne, ponieważ są zielone ;] Zdecydowanie lepiej patrzy się na kawałek kodu poprzecinany adnotacjami czy pustymi liniami niż na jednolitą szpaltę wysokości drapacza chmur. Stosowanie separatorów w rodzaju /********/ czy nagłówków opisujących pliki na pewno polepsza czytelność kodu.
    Kiedyś na Warsztacie założyłem sondę na temat zalet komentarzy i wolą większości ten argument został uznany za najważniejszy.
  • Po trzecie kod z komentarzami jest zwyczajnie ładniejszy. Naturalnie nie zdadzą się one na wiele, jeżeli ktoś stosuje nazwy w stylu function1, a klawisza Tab używa tylko w połączeniu z Altem :) Szkoda, że tego rodzaju kod widzi się stanowczo za często ;P
  • I wreszcie jedna sprawa dotycząca nie samych komentarza, lecz ich pisania. Kiedy programuje się z zamiłowania, nierzadko ma się “natchnienie”, które chciałoby się od razu przełożyć na kod. Jakie są tego skutki, nietrudno się domyślić, bo przecież co nagle to po diable ;) Jeżeli jednak wcześniej poświęci się chociaż chwilę na napisanie komentarza do powstającej funkcji/klasy/itp. to skutek jest zwykle lepszy.

Tak więc, Wysoki Sądzie, z powodu swojego rozwlekłego stylu kodowania nie czuję najmniejszych wyrzutów sumienia i nie postanawiam nawet minimalnej poprawy ;P Co więcej, nie będę się krępował przed propagowaniem swoich poglądów na ten temat każdemu, kto będzie miał (nie)przyjemność oglądać napisany przeze mnie kod :)

Tags:
Author: Xion, posted under Programming » 3 comments

Nadmiar interfejsu

2007-08-09 16:40

Projektując klasy i kontrolki systemu GUI, wzoruję się na kilku istniejących rozwiązaniach. Większość wzorców czerpię jednak z Windows Forms, części platformy .NET. Tym, co ostatnio zwróciło w niej moją uwagę, to fakt, że wiele czynności można w niej wykonać na kilka sposób. Mówiąc ściślej, klasy wchodzące w skład WF posiadają często więcej niż jedną składową służącą osiągnięciu tego samego celu.

Przykład? Proszę bardzo. Do zmiany położenia i wymiarów kontrolki wystarczą dokładnie cztery właściwości. Mogą to być: Left (pozycja lewej krawędzi kontrolki), Top (górnej krawędzi), Width i Height. Tyle w zupełności wystarczy. Klasa Windows.Forms.Control ma też jednak inne:

  • Right – pozycja prawej krawędzi
  • Bottom – dolnej krawędzi
  • Location – pozycja lewego górnego rogu
  • Size – wymiary kontrolki
  • Bounds – prostokąt otaczający kontrolkę

Wszystkie je można oczywiście uzyskać z tych czterech, które wymieniłem na początku. Istnieje też rzecz jasna mnóstwo innych kombinacji z innymi właściwościami “pierwotnymi” i “pochodnymi”.

Można mieć jednak wątpliwości, czy istnienie różnych dróg dotarcia do podobnych danych jest konieczne i właściwe. Przy tak bogatym interfejsie (inny przykład: metoda Graphics.DrawImage() ma aż 30 (!) przeciążonych wersji) można bardzo długo zastanawiać się nad tym, którego sposobu mamy użyć w konkretnym przypadku.
To prawda, że interfejs zbyt ubogi jest zwykle o wiele większym problemem. Uważam jednak, że w programowaniu brzytwa Ockhama ma zastosowanie i że dróg prowadzących do tego samego celu nie należy mnożyć ponad potrzebę.

Tags:
Author: Xion, posted under Programming » 1 comment

Minesweeper: The Movie

2007-08-08 22:17

Wszyscy znają tę grę. Jedna z najpopularniejszych, najbardziej rozpowszechnionych i najlepszych produkcji w dziejach komputerowej rozgrywki. Mają prawie każdy i praktycznie każdy w nią grał. O jakiej grze mowa? O windowsowym Saperze, naturalnie :)

  

Dlatego wszystkich fanów z pewnością ucieszy fakt, że oto szykuje się ekranizacja tej niezwykłej produkcji. A już teraz można sobie obejrzeć zapowiadający trailer:

Trailer Minesweeper: The Movie

A teraz nieco poważniej… Większość tzw. śmiesznych filmików jest w rzeczywistości mało zabawna, ale trafiają się też perełki. O tym mogę śmiało powiedzieć, że mnie rozbroił :)

Tags:
Author: Xion, posted under Games » 4 comments
 


© 2022 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.