Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

11. diel - SDĽ - Udalosti myši

Dnes sa bližšie pozrieme na udalosti, ktoré môže vyvolať myš. Myš má dva typy udalostí - posun a stlačenie tlačidla. Najskôr sa pozrieme na stlačenie tlačidla myši, potom na posun a nakoniec aj na koliesko myši. V závere tiež uvediem funkcie, ktoré SDL poskytuje pre editáciu ukazovateľa myši.

SDL_MouseButto­nEvent

SDL_MouseButto­nEvent nám poskytuje informáciu o stlačení tlačidla myši. Opäť uvediem definíciu.

typedef struct SDL_MouseButtonEvent
{
    Uint32 type;
    Uint32 timestamp;
    Uint32 windowID;
    Uint32 which;
    Uint8 button;
    Uint8 state;
    Uint8 clicks;
    Sint32 x;
    Sint32 y;
} SDL_MouseButtonEvent;
  • type je rovnako ako u klávesnice rozdielny pre stlačenie alebo uvoľnenie tlačidla. Môže nadobúdať hodnoty SDL_MOUSEBUTTONDOWN alebo SDL_MOUSEBUTTONUP.
  • which môže obsahovať SDL_TOUCH_MOUSEID alebo ID myši. ID myši nám v aplikácii moc platné nie je, ale SDL_TOUCH_MOUSEID sa generuje vo chvíli, keď je udalosť pôvodne dotyková. Ak zachytávame SDL_TouchFinge­rEvent môžeme udalosť s týmto príznakom ignorovať. V opačnom prípade vidíme, že môžeme s dotykovou obrazovkou pracovať rovnako, ako by užívateľ používal klasickú myš.
  • state je rovnako ako u klávesnice duplicitné informácie. Nadobúda hodnôt SDL_PRESSED a SDL_RELEADED.
  • clicks nám povie, či sa jednalo o jedno kliknutie alebo dvojité (double click), prípadne či používateľ klikol viackrát. Tento atribút je zaradený do SDL až od verzie 2.0.2.
  • Z x a y sa dozvieme, kde užívateľ klikol. Jedná sa o celé číslo udávané v pixeloch a merané relatívne k ľavému hornému rohu okna.

Úmyselne som vynechal najdôležitejšia časť - atribút button. Ten môže nadobúdať jednu z piatich hodnôt a povie nám, ktorého tlačidlá sa udalosť týka. Najčastejšie používané hodnoty sú SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE, SDL_BUTTON_RIGHT pre lacné, prostredný (koliesko) a pravé tlačidlo. Na Windows som zistil, že aj keď nastavíme tlačidla obrátene (voľba "zameniť ľavé a pravé tlačidlo"), bude brať pravé tlačidlo ako ľavé a obrátene, teda tak, ako zodpovedá ich funkcionalite. Pre vývojárov určite dobrá správa.

SDL poskytuje naviac ešte ďalšie dve konštanty, a to SDL_BUTTON_X1 a SDL_BUTTON_X2 pre myši s piatimi tlačidlami (napríklad na boku). Bohužiaľ aktuálne takú myš nevlastným, preto som funkčnosť nemohol overiť.

SDL_MouseMoti­onEvent

SDL_MouseMoti­onEvent informuje o posune myši na obrazovke. Opäť priložím definíciu a popis.

typedef struct SDL_MouseMotionEvent
{
    Uint32 type;
    Uint32 timestamp;
    Uint32 windowID;
    Uint32 which;
    Uint32 state;
    Sint32 x;
    Sint32 y;
    Sint32 xrel;
    Sint32 yrel;
} SDL_MouseMotionEvent;

Atribúty type, timestamp, windowID, which i state sú zhodné s predchádzajúcou udalosťou, preto sa pozrieme iba na charakteristické atribúty pre SDL_MouseMotionEvent. Atribúty x a y sú súradnice, kde myš s pohybom skončila. Tieto súradnice sú relatívne k aktuálnemu oknu. Atribúty xrel a yrel nám udávajú, o koľko sa myš posunula v smere vodorovnom, prípadne horizontálnym.

SDL poskytuje aj dve funkcie, ktoré ukazovateľ myši presunú. Sú nimi SDL_WarpMouse­InWindow a SDL_WarpMouse­Global. Prvá uvedená presunie myš na súradnice relatívna k oknu aplikácie, druhá potom relatívna k obrazovke. Prečo by sme tieto dve funkcie potrebovali? Predstavme si, že programujeme FPS (strieľačku z prvej osoby). Ak by hráč presunul myš ku kraju okna, program by nedostával správy o pohybe myši, pretože by sa myš vlastne nikam nevyvážali, ale zostávala by pri okraji. V takýchto prípadoch budeme najčastejšie po každom pohybe presúvať myš späť na stred obrazovky. Aplikácia tak bude neustále zachytávať pohyby myši. Obe funkcie sami vyvolávajú udalosť SDL_MouseMotionEvent, ktorú budeme musieť z frontu udalostí odstrániť. Teda za predpokladu, že aplikácia nebude udalosť znova potrebovať. Ukážka bude v priloženom programe na konci článku.

V SDL môžeme tiež nariadiť, aby bola myš zachytávaná aj mimo okno. Použijeme na to funkciu SDL_CaptureMouse. Nie je ale doporučené toho využívať príliš často. Na niektorých zariadení táto funkcionalita ani nie je možná. Po nastavení sa môže stať, že ostatné aplikácie prestanú dostávať správy o pohybe myši, pretože pôjdu všetky správy našej aplikácii. Hodnoty súradníc, kde je myš, sú stále stiahnuté k oknu našej aplikácie, to znamená, že môžu nadobúdať aj záporných hodnôt, s čím je potrebné v aplikácii počítať.

SDL_MouseWheelEvent

Nakoniec tu máme SDL_MouseWhee­lEvent, ktorý nám povie informácie o rotácii kolieska myši. V predchádzajúcej verzii SDL bola táto udalosť zaradená pod SDL_MouseButtonEvent s tým, že medzi tlačidlami boli zaradená ešte konštanty SDL_BUTTON_WHEELUP a SDL_BUTTON_WHEELDOWN. V novšej verzii už má koliesko svoju samostatnú udalosť.

typedef struct SDL_MouseWheelEvent
{
    Uint32 type;
    Uint32 timestamp;
    Uint32 windowID;
    Uint32 which;
    Sint32 x;
    Sint32 y;
} SDL_MouseWheelEvent;

Zásadná sú atribúty x a y. Prvý z nich nám povie o horizontálnej rotácii kolieska - teda sprava do ľava. Pre rotáciu doprava bude obsahovať hodnotu kladnú, pre posun doľava hodnotu zápornú. Druhý atribút obsahuje dáta z vertikálnej rotáciu kolieska. Pokiaľ bude užívateľ točiť kolieskom nahor (od seba), bude hodnota záporná, obrátený smer bude generovať hodnoty kladné.

V dokumentácii je uvedený ešte atribút direction, ktorý je tu pravdepodobne kvôli ostatným platformám, konieckoncov rovnako ako atribút x - koľko z nás má na myši koliesko, ktoré možno točiť do všetkých 4 strán? Niektoré platformy môžu mať prevrátenú orientáciu (budú generovať záporné hodnoty tam, kde očakávame kladné). V direction je uložená informácia, ktorá nám to oznámi. Tento atribút je relevantný až od verzie 2.0.4, ktorá nebola v čase písania článku stabilné, preto sa ním ďalej zaoberať nebudeme.

Zmena kurzora

SDL poskytuje viacero funkcií, pomocou ktorých môžeme zmeniť vzhľad kurzora. Tieto funkcie vracia ukazovateľ na SDL_Cursor, ktorý je nutné následne uvoľniť funkcií SDL_FreeCursor. Jediný kurzor, ktorý nie je nutné uvoľniť, je predvolený. Vytvorený kurzor potom aktivujeme funkcií SDL_SetCursor.

Základné funkcie pre vytváranie kurzora je SDL_CreateCursor. Tento kurzor môže byť iba čiernobiely a jeho vytvorenie nie je tak jednoduché, ako u ostatných funkcií, preto funkciu nebudem popisovať. Pre prípadných záujemcov je v dokumentácii SDL uvedený príklad.

Funkciu, ktorú budeme používať častejšie, je SDL_CreateSys­temCursor, ktorá vytvorí jeden z predpripravených kurzorov, ktoré poskytuje operačný systém. Ako parameter prijíma konštantu, ktorá definuje jednotlivé kurzory. Nájdeme tak klasické systémové kurzory ako presýpacie hodiny, ruka (ktorá sa objaví po prejdení na odkaz) a ďalšie. Zoznam je opäť v dokumentácii. Posledná funkcia (a pre nás najzaujímavejšie), je funkcia SDL_CreateColor­Cursor. Kurzor vytvorí z SDL_Surface, ktorú odovzdáme ako parameter. Môžeme nastaviť aj bod, ktorým je aktivačný miesto - miesto, z ktorého sa berie vstup myši. Použijeme na to parametre hot_x a hot_y. Toto miesto teda nemusí byť iba v rohu SDL_Surface, ale môže byť kdekoľvek. Ukážka bude opäť v programe na konci článku.

Kurzor môžeme v aplikácii aj úplne schovať, a to funkciou SDL_ShowCursor. Odovzdáme ak v parametri SDL_ENABLE alebo SDL_DISABLE, kurzor sa zobrazí alebo skryje. Pre zistenie aktuálneho stavu môžeme odovzdať SDL_QUERY a funkcie vráti hodnotu 1, ak sa kurzor zobrazený, v opačnom prípade vráti 0.

Predposledný funkcia je SDL_GetCursor, ktorá vráti aktuálne používaný kurzor, alebo NULL, pokiaľ nie je kurzor na zariadení podporovaný. A konečne posledná je SDL_GetDefaultCur­sor, ktorá vráti predvolený kurzor, ktorý bol systémom nastavený.

Aktuálny stav myši

U myši okrem stlačených tlačidiel môžeme zistiť aj jej aktuálnu pozíciu. Všetky tri funkcie, ktoré SDL poskytuje, vracia ORované hodnoty jednotlivých tlačidiel. Predtým, než konštanty použijeme, na ne musíme aplikovať SDL_BUTTON makro. Funkcia tiež prijímajú dva ukazovatele typu int, v ktorých sa nám vráti aktuálnej pozície myši. Môžeme odovzdať NULL, ak nás súradnice nezaujímajú. Prvou funkciou je SDL_GetMouseS­tate, ktorá uspeje, len ak je myš v okne a vracia súradnice relatívna k tomuto oknu, ďalej je funkcia SDL_GetRelati­veMouseState, ktorá vracia súradnice z celej obrazovky, ale stále relatívna k oknu - súradnice môžu byť aj záporné. Posledná funkcia je SDL_GetGlobal­MouseState, ktorá opäť berie myš z celej obrazovky, ale zároveň sú hodnoty relatívnej k obrazovke - ľavý horný roh má súradnice 0,0. Použitie je ukázané v nasledujúcom kóde.

if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT))
{
    SDL_Log("Levé tlačítko myši bylo stisknuto");
}

Príklad

Ako príklad som zvolil aplikáciu, ktorá si nastaví vlastné ukazovateľ, ktorý nemá aktivačný oblasť v ľavom hornom rohu. Červený štvorec sa potom pohybuje podľa pohybu myši, ktorá sa po prekročení definovanej plochy premiestni späť. Ľavým tlačidlom myši môžeme presunúť štvorec späť do stredu, pravým tlačidlom kurzor skryjeme. Aplikáciu ukončíme kombináciou Alt + F4.

demo - SDĽ

V budúcom dieli zostaneme u udalostí a bližšie sa pozrieme na manipuláciu s frontou udalostí.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 763x (38.19 kB)

 

Predchádzajúci článok
SDĽ - Udalosti klávesnice
Všetky články v sekcii
SDĽ
Preskočiť článok
(neodporúčame)
SDĽ - Všeobecná práca s udalosťami
Článok pre vás napísal Patrik Valkovič
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Věnuji se programování v C++ a C#. Kromě toho také programuji v PHP (Nette) a JavaScriptu (NodeJS).
Aktivity