// obsluga myszy w ekg // (c) 2006 adam wysocki 1. wstep 2. aktualne bindingi 3. terminologia 4. struktury i typy danych 5. rozpoznawane zdarzenia przyciskow 6. interfejs 7. przyklad uzycia 8. do zrobienia 1. wstep obsluga myszy w ekg jest na razie wstepnym, eksperymentalnym frameworkiem do dalszego obudowania, dzialajacym tylko w interfejsie ncurses. ten plik zawiera opis aktualnych bindingow (czyli obszarow, w ktore mozna kliknac lub na ktorych mozna wykonac gesty) oraz developerski opis, przydatny podczas dodawania obslugi myszy do kolejnych elementow ekg. gdyby cos z niego bylo nie do konca jasne albo dwuznaczne, nalezy napisac na ekg-users (adres znajduje sie na stronie ekg). poprawki mile widziane. jesli nie jestes zainteresowany rozwijaniem obslugi myszy w ekg, a jedynie jej uzywaniem, to rozdzial "aktualne bindingi" jest jedynym, ktory powinienes przeczytac. 2. aktualne bindingi aktualne przyporzadkowania zdarzen myszy. gest to przesuniecie myszy podczas trzymania ktoregos przycisku. jesli nie zostalo okreslone inaczej, gest mozna wykonac trzymajac lewy lub prawy przycisk. lpm to lewy przycisk myszy, ppm - prawy. obszar | zdarzenie | polecenie lub opis ------------------------+-----------------------+------------------- header | klikniecie | /list header | podwojne klikniecie | /find statusbar: zegar | klikniecie | /exec ^date statusbar: uin, nick | klikniecie | /status statusbar: uin, nick | prawe klikniecie | /find statusbar: query | klikniecie | /list $ statusbar: query | prawe klikniecie | /find $ statusbar: more | klikniecie | Page Down statusbar: win/numer | klikniecie | /window list $ statusbar: act/numer | klikniecie | /window list statusbar: act/numer | podwojne klikniecie | /window switch rozmowa | gest w lewo | /window prev rozmowa | gest w prawo | /window next rozmowa | gest w gore | /window last rozmowa | gest w dol z lpm | /window oldest rozmowa | gest w dol z ppm | /window active 3. terminologia - zdarzenie myszy (mouse_event): zmiana wartosci zmiennej mouse, zdarzenie przycisku myszy lub prosba o zwolnienie pamieci ze strukturami. NIE jest tozsame ze zdarzeniem myszy w man mouse z ncurses. wszystkie zdarzenia myszy sa obslugiwane w funkcji mouse_event(). - zdarzenie przycisku myszy (bevent): klikniecie, podwojne klikniecie, potrojne klikniecie, wcisniecie lub puszczenie przycisku. zdarzenia przyciskow myszy sa obslugiwane przez odpowiednio dodane handlery. - gest myszy: jest rozpoznawany, gdy przesuniemy mysz trzymajac ktorys przycisk. gesty stworzone zostaly na podstawie obslugi myszy w irssi (http://wouter.coekaerts.be/site/irssi/mouse) z ta roznica, ze kierunek jest obliczany nastepujaco: - odleglosc_x > 2 * odleglosc_y: kierunek poziomy - odleglosc_y > 2 * odleglosc_x: kierunek pionowy - pozostale: gest nierozpoznany 4. struktury i typy danych - mouse_area_t - opisuje jeden konkretny obszar na ekranie. obszar jest prostokatem zdefiniowanym przez polozenie lewego gornego rogu oraz szerokosc i wysokosc. struktura zawiera takze polozenie prawego dolnego rogu, ustawiane przez funkcje obslugi myszy. obszar moze, ale nie musi, miec taki sam rozmiar jak ktores okno (np. header albo statusbar). oprocz tego kazdy obszar ma swoja nazwe - przydatne do lepszej identyfikacji w oknie debugowania i podczas zmiany rozmiaru okna. - mouse_coords_t - struktura opisujaca koordynaty punktu na ekranie lub w obszarze. zawiera zmienne x (numer kolumny) i y (numer wiersza). lewy gorny rog ma koordynaty 0,0. - mouse_bevent_t - struktura na liscie w mouse_area_t. opisuje zdarzenie przycisku dla obszaru, do ktorego nalezy (wartosc zdarzenia okreslajaca, ze np. zostal podwojnie klikniety ktorys przycisk i wskaznik do handlera mouse_handler_t, ktory obsluzy to zdarzenie). - mouse_handler_t - wywolywane do obslugi zdarzenia. dostaje maske przycisku (mmask_t) i wskaznik do opisu koordynatow (mouse_coords_t). maska przycisku moze sie przydac, gdyby ktos chcial podpiac kilka zdarzen przycisku do jednego handlera (podobnie jak signo w sighandlerach). koordynaty mierzone sa wzgledem poczatku obszaru (a nie ekranu lub okna). handler niczego nie zwraca. 5. rozpoznawane zdarzenia przyciskow jak w man 3ncurses mouse: - BUTTONx_PRESSED: przycisk zostal wcisniety i jest trzymany - BUTTONx_RELEASED: przycisk zostal puszczony - BUTTONx_CLICKED: przycisk zostal klikniety - BUTTONx_DOUBLE_CLICKED: przycisk zostal podwojnie klikniety - BUTTONx_TRIPLE_CLICKED: przycisk zostal potrojnie klikniety x moze przyjmowac wartosci od 1 do 5 (dla NCURSES_MOUSE_VERSION == 1 tylko 4). dla normalnych myszek 1 to lewy, 2 srodkowy a 3 prawy przycisk. oprocz tego, jesli numer zdarzenia jest zORowany z BUTTON_CTRL, BUTTON_SHIFT lub BUTTON_ALT, oznacza to zdarzenie przy wcisnietym ktoryms z tych klawiszy. dodajac button eventy powinno sie pamietac, ze: - niektore terminale maja jakies alternatywne funkcje dla klikniec z ktoryms z klawiszy ctrl, shift lub alt i nie przekazuja takiego klikniecia do programu. - nie kazdy posiada srodkowy przycisk myszki lub emulacje przez wcisniecie obu przyciskow. 6. interfejs - mouse_event() - obsluguje zdarzenia myszy - mouse_bevent_add() - dodaje button event do obszaru - mouse_area_add() - dodaje obszar do listy - mouse_area_find() - znajduje obszar po nazwie - mouse_area_del() - usuwa obszar z listy - mouse_area_move() - przesuwa obszar - mouse_area_resize() - ustawia nowy rozmiar obszaru - mouse_in_area() - sprawdza czy punkt nalezy do obszaru wskazniki, ktore dostaja te funkcje, nie musza byc alokowane - moga wskazywac na obiekty lokalne dla wywolujacej funkcji. mouse_bevent_add() powinno byc wywolywane na lokalnej strukturze, a dopiero po wszystkich mouse_bevent_add() powinno zostac wywolane mouse_area_add(). mouse_area_resize() jest przydatne podczas zmiany rozmiaru okna, np. po dostaniu przez leb sigwinchem albo zmianie wartosci ktorejs zmiennej. 7. przyklad uzycia gdyby ktos chcial bardziej czytelnie, niz w zrodlach ekg, dla hipotetycznego obszaru "test": static void mouse_bevent_test (struct mouse_coords_t *coords, mmask_t bstate) { if (bstate == BUTTON1_CLICKED) { // ... } else if (bstate == BUTTON1_DOUBLE_CLICKED) { // ... } } ...() { struct mouse_area_t a; a.name = "test"; a.start.x = a.start.y = 0; a.size.x = a.size.y = 10; a.bevents = NULL; mouse_bevent_add(&a, BUTTON1_CLICKED, mouse_bevent_test); mouse_bevent_add(&a, BUTTON1_DOUBLE_CLICKED, mouse_bevent_test); mouse_area_add(&a); } nie trzeba sie troszczyc o zwalnianie niczego, mouse_event("destroy") zrobi to sama, jednak trzeba pamietac zeby przed pierwszym mouse_bevent_add() pole bevents bylo rowne NULL. pole name nie musi byc zaalokowane - zostanie zaalokowane przez mouse_area_add(). 8. do zrobienia - mozliwosc oskryptowania myszy w pythonie - mozliwosc bindowania beventow przez uzytkownika (/mouse_bind?) - -a: przypisanie akcji do pary obszar,zdarzenie - -d: usuniecie akcji dla podanej pary obszar,zdarzenie - [-l]: wylistowanie przypisanych akcji - -L: wylistowanie przypisanych oraz domyslnych akcji - konkurs na nazwe dla pary obszar,zdarzenie :) - definicje: - obszar (w nawiasie znaczenie parametru) - current (konkurs na lepsza nazwe dla obszaru current_window :)) - contacts ($1: nick) - header (naglowek jako calosc) - header:query_ip ($1: ip) - header:query_descr ($1: opis) - status (pasek stanu jako calosc) - status:time - status:uin - status:nick - status:more - status:query - status:window - status:act ($1: numer okna) - status:query_ip ($1: ip) - status:query_descr ($1: opis) - zdarzenie (przycisk-czynnosc) - przycisk - left - middle - right - czynnosc - click - double_click - triple_click - gesture_up - gesture_down - gesture_left - gesture_right - roll_up (przycisk ignorowany) - roll_down (przycisk ignorowany) - akcja - wszystkie akcje z /bind - komendy do wykonania (przyjmuja parametry) - moze obsluga masek, a nie tylko wartosci, w mouse_bevent_add()? - beventy dla listy kontaktow i paska stanu (jesli nie zaznaczono inaczej, to klikniecia): - lista: /list - lista: podwojne: /query - rolka: scrollowanie listy (może ogólnie też dla okna rozmowy?) - pasek: query_ip: /exec ^host - pasek: query_descr i inne odnosnie opisu: /list - pamietac o sigwinch i innych mozliwosciach (zmiany wartosci zmiennych, zdarzenia itd.) zmiany obecnosci, polozenia i rozmiaru obszarow. podczas dodawania obszaru do okna warto grepnac zrodla pod katem wystepowania odpowiednich funkcji z ncurses dla tego okna. jesli pozycja w oknie ma znaczenie to trzeba tez pilnowac, zeby opis pozycji poszczegolnych elementow byl aktualizowany // $Id$