.[ ČeskéHry.cz ].
Probublávání událostí v GUI
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 28. září 2009, 12:56:21    Předmět: Probublávání událostí v GUI Odpovědět s citátem

Ahoj,

snažím se v Direct3D splácat uživatelské rozhraní obsahující tradiční objekty jako je Form, TabControl, Panel, Button, Label, CheckBox, RadioButton, Edit a podobně.

Dostal jsem se ale k problému. Nedaří se mi vymyslet nějaký funkční způsob probublávání zpráv (udáslostí, nebo jak to nazvat) až k určitým objektům, které tuto událost zpracují (tzn. kliknutí myší na určité tlačítko, stisknutí klávesy v editu a podobně...) a stejně tak se mi i nedaří najít nějaký popis toho, jak tohle funguje například ve WINAPI (předpokládám, že to chce hledat jen nějaké správné klíčové slovo, ale prostě jsem nic použitelného nenašel).

Chtěl bych vás proto poprosit o radu, díky...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Matasx



Založen: 17. 08. 2008
Příspěvky: 258

PříspěvekZaslal: 28. září 2009, 14:15:10    Předmět: Odpovědět s citátem

Přesně asi nechápu otázku... ale normálně přes události (events) ne? OnClick, OnDoubleClick ... atp. což jsou vlastně delegáty ke kterým uživatel (programátor) přiřadí vlastní funkce.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 28. září 2009, 14:27:51    Předmět: Odpovědět s citátem

No pokud to budeš chtít udělat super obecně a flexibilně, tak se pěkně zapotíš. Pokud ale budeš dělat hru s normálním GUI, tak si většinou vystačíš s posíláním vstupu z klávesnice aktuálně aktivnímu objektu (focus) a události myši objektu pod myší. Případně si každý objekt zaregistruje, co chce dostávat a pak to budou dostávat všichni zaregistrovaná (a musí si pohlídat, jestli se jich to týká).

Ve WinAPI to funguje víceméně podobně a navíc tam jsou pak extra cesty na ty složitější případy (jako například klávesové zkratky). Nějaký konkrétní článek, který by to shrnoval ti nedám, ale když začneš třeba od dokumentace WM_MOUSEMOVE, třeba se něco dozvíšSmile Dál se můžeš inspirovat event modelem v DOM u HTML, tam je to taky krásně složité Smile
_________________
Mám strach
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Ladis



Založen: 18. 09. 2007
Příspěvky: 1536
Bydliště: u Prahy

PříspěvekZaslal: 28. září 2009, 16:14:04    Předmět: Odpovědět s citátem

Něco podobného jsem si zkusil před mnoha lety, akorát to bylo v SDL + OpenGL. Ovládací prvky maj pořadí pro tabování podle pořadí vytvoření (ale lze bez problému upravit, aby šlo za běhu měnit). V jednu chvíli je jeden control aktivní (zaktivní se tabnutím na něj nebo kliknutím myši). Ten aktivní dostává vstup z klávesnice, vstup z myši dostává ten pod kurzorem myši (každý prvek má obdélníkovou oblast, popisující kde je, stačí je tedy projít od posledního - toho nejvíc nahoře - a testovat, jestli pozice kurzoru patří do něj). Reakce na události mám ukazateli na funkce objektů, takže si přiřadím svoji funkci tomu controlu na vybranou událost, např. tlačítku na kliknutí. Mám tam i takovou vychytávku, že když stiskneš tlačítko, tak se zmáčkne, ale událost stisknutí se zavolá, až když myš pustíš, a můžeš za zmáčknuté myši kurzorem vyjet ven, aby se tlačítko nezmáčklo (přesně jako ve Windows a spol.). Zdrojáky zde - myslím, že zatím to umí jen labely, textboxy a buttony (pro princip stačí, další controly jsou už ve stejném stylu; je tam i binárka (tfoclient.exe), kde můžeš vidět, jak ty frmuláře vypadaj; ještě detail, ten kód je pro celoobrazovkovou hru, takže formuláře tam nazývám obrazovky - screens).
_________________
Award-winning game developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 9. srpen 2011, 11:52:15    Předmět: Odpovědět s citátem

Ahoj,

po delší době jsem se vrátil k návrhu GUI a chtěl bych se zeptat spíše na takovou teoretickou otázku.

Prostudoval jsem si W3C specifikace tohoto problému a nezdá se mi úplně ideální probublávání událostí například u pozicovaných elementů (i když je to jasné a logické).

Probublávání OnClick u nepozicovaných elementů není co řešit - probublávání probíhá tak, že se prostě dostane událost od cíle až ke kořenovému elementu přes svoje předky/potomky (v příkladě Button1 a Button2). Pokud se ale element (Button3) napozicuje tak, že je mimo svého předka a navíc ještě přes jiné elementy, přišlo by mi použitelnější, aby událost probublala přes elementy "pod kurzorem" (v době kliknutí), né přes svoje předky (které jsou v úvedeném příkladu mimo Button3).

Má smysl toto řešit, nebo je návrh W3C nějakou vlastností použitelnější nebo správnější?

Díky za názory


Naposledy upravil Solid.Sn dne 26. červen 2012, 20:56:14, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
tomkis



Založen: 06. 06. 2011
Příspěvky: 33

PříspěvekZaslal: 9. srpen 2011, 18:53:40    Předmět: Odpovědět s citátem

Solid.Sn napsal:
Ahoj,

po delší době jsem se vrátil k návrhu GUI a chtěl bych se zeptat spíše na takovou teoretickou otázku.

Prostudoval jsem si W3C specifikace tohoto problému a nezdá se mi úplně ideální probublávání událostí například u pozicovaných elementů (i když je to jasné a logické).

Probublávání OnClick (viz. příklad http://dev2.exact.cz/events.html) u nepozicovaných elementů není co řešit - probublávání probíhá tak, že se prostě dostane událost od cíle až ke kořenovému elementu přes svoje předky/potomky (v příkladě Button1 a Button2). Pokud se ale element (Button3) napozicuje tak, že je mimo svého předka a navíc ještě přes jiné elementy, přišlo by mi použitelnější, aby událost probublala přes elementy "pod kurzorem" (v době kliknutí), né přes svoje předky (které jsou v úvedeném příkladu mimo Button3).

Má smysl toto řešit, nebo je návrh W3C nějakou vlastností použitelnější nebo správnější?

Díky za názory


Ono ten příklad co jsi poslal je docela logický, protože Javascript operuje víceméně nad HTML nikoliv CSS, přepozicování elementu pomocí CSS a vskutku se tak děje i při pozicováním javascriptem nemění pozici v DOM struktuře.

Jinými slovy, když vypneš CSS tak ten prvek bude stejně probublávat dobře.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 9. srpen 2011, 19:05:17    Předmět: Odpovědět s citátem

tomkis napsal:

Ono ten příklad co jsi poslal je docela logický, protože Javascript operuje víceméně nad HTML nikoliv CSS, přepozicování elementu pomocí CSS a vskutku se tak děje i při pozicováním javascriptem nemění pozici v DOM struktuře.

Jinými slovy, když vypneš CSS tak ten prvek bude stejně probublávat dobře.


Já tomu rozumím, jde mi spíš o to, jestli má smysl to řešit tak jak jsem napsal. Jak se to třeba řeší jinde než v DOM / JavaScriptu?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1558

PříspěvekZaslal: 9. srpen 2011, 19:29:36    Předmět: Odpovědět s citátem

Ja bych pouzil takovy pristup, ze bych posilal zpravy vsem prvkum a zpracoval by si je jen ten, ktery by mel nejvyssi prioritu. Ta by se musela nejak rozumne kazdemu prvku nastavit dopredu (asi nejvyssi tem, ktere jsou v nejvrchnejsi vrstve). Kazdy typ zpravy by mel priority vlastni a napr. nulova (== nejnizsi) priorita by znamenala, ze prvku zprava vubec nedojde (protoze ji neni schopny zpracovat.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 9. srpen 2011, 19:53:54    Předmět: Odpovědět s citátem

Nad tím jsem taky přemýšlel... napadlo mě, rozeslat zprávu všem, ty elementy, které můžou / smí na zprávu reagovat událostí se ke zprávě "přihlásí" s nějakou prioritou a následně bude probublávání probíhat ne stylem od cíle přes předky ke kořenu ale právě od nejvyšší priority z přihlášených elementů k nějnižší.

Zpráva tedy projde všechny elementy (čehož se trochu bojím, v případě, že může jít o stovky/tisíce elementů), při průchodu se vytvoří fronta zájemců a po ukončení průchodu se spustí události na tuto zprávu dle priority postupně u všech přihlášených.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 12. září 2011, 20:42:26    Předmět: Odpovědět s citátem

Implementoval jsem události v GUI velmi podobně jak to popisuje W3C.
Zkouším nyní Drag&Drop a přišel jsem na problém s MouseMove.

Došel jsem ale v obou případech na stejnou věc, jak v JS, tak v mé implementaci (která je s velmi podobná JavaScriptovým událostem) dochází při takto implementovaném Drag&Drop ke stejnému problému.

Pokud kliknete na "titulek okna", spustí se OnMouseDown, která nastaví příznak lock na 1. Pokud tlačítko pustíte OnMouseUp, pak se příznak nastaví na nulu. Je-li příznak lock nastaven na 1, pak se okno při OnMouseMove na titulku okna posunuje na souřadnice dané kurzorem. K chybě dochází v případě, že táhnete kurzorem rychle. Zpráva WM_MOUSEMOVE příjde najednou v době, kdy je kurzor už jakoby mimo titulek okna a tím se zruší příznak a přeruší se táhnutí.

Napadá mě několik způsobů jak toto vyřešit. Například OnMouseMove (V JS na element Body, v mé implementaci na něco podobného Smile ). Ale to mi již příjde jako obcházení tohoto problému špatným způsobem.

Také by to šlo vyřešit tak, že při situaci, kdy dojde k OnMouseDown a následně OnMouseMove na jednom elementu, pak nechat události procházet jen na element, nad kterým bylo tlačítko stlačeno, ale také to není v pořádku a zase se tím znemožní jiné věci.

[b]Pro představu přikládám ukázku http://www.uloz.to/10250048/gui-exe (vypnout se to dá Alt+F4 nebo kliknutím na červené tlačítko v titulku toho, co by mělo být okno Smile )

Děkuji za případné tipy Smile

EDIT:

Zde je funkční způsob (http://www.uloz.to/10251558/gui-exe) řešený tak, že mousemove pohyb odchytává při propagaci události v kořenovém elementu (dejme tomu něco jako plocha) a jelikož se kurzor mimo tento element nedostane (když neberu v úvahu vyjetí z okna), tak to funguje. (Díval jsem se a většinou se to takhle řeší právě i v JS - document nebo body.)

Na druhou stranu, dejme tomu, že budu mít posuvník, nebo nějaký track bar. Pak mi příjde odchytávání mousemove při propagaci události v kořenovém elementu pro tyto komponenty jako nesmysl.


Naposledy upravil Solid.Sn dne 26. červen 2012, 20:56:56, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 13. září 2011, 12:07:58    Předmět: Odpovědět s citátem

Ještě se zkusím zeptat jinak.

Jaký způsob šiření MouseMove události je podle Vás použitelnější / správnější...?

Zkoušel jsem MouseMove na Windows Forms Aplikaci a dopadlo to takto:

Pokud nedojde ke kliknutí na tlačítko, chodí MouseMove zpráva prvku, který je pod kurzorem. Je-li tedy pod kurzorem button, zasílá se zpráva tomuto prvku, je-li pod kurzorem formulář, pak formuláři. Pokud dojde ke stisknutí a podržení tlačítka myši nad prvkem button na formuláři, začnou se zprávy MouseMove zasílat buttonu i když kurzorem z tlačítka odjedete (při stále stisknutém tlačítku na myši).


Viz. http://www.uloz.to/10254994/mousemoveevent-exe

V HTML s JavaScriptem to funguje ale jinak. Zpráva chodí prvku pod kurzorem s vyjímkou, kdy pokud je kurzor nad tlačítkem tak díky probublávání dostane zprávu i body. Pokud dojde ke stisknutí tlačítka myši nad buttonem a následně se vyjede mimo button, pak se zprávy zase zasílají body a né prvku button.


Děkuji


Naposledy upravil Solid.Sn dne 26. červen 2012, 20:57:30, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Ladis



Založen: 18. 09. 2007
Příspěvky: 1536
Bydliště: u Prahy

PříspěvekZaslal: 13. září 2011, 12:26:26    Předmět: Odpovědět s citátem

V normálních aplikacích jsem zvyklý, že se po stisknutí zasílá původnímu prvku. Můžeš tak udělat, že po vyjetí z tlačítka se zruší tlačítku promáčknutí, ale po najetí zpátky se zas promáčkne (jsou tak všechny tlačítka ve Windows apod.). Samozřejmě stejně tak původnímu prvku musíš poslat i uvolnění tlačítka.
_________________
Award-winning game developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Dlaha



Založen: 30. 07. 2007
Příspěvky: 598
Bydliště: Olomouc

PříspěvekZaslal: 13. září 2011, 17:07:55    Předmět: Odpovědět s citátem

Já teď zkouším místo probublávání použít observera.
http://cs.wikipedia.org/wiki/Observer

Mám udělanej singleton, který obsluhuje události. A objekt, který chce přijímat nějaké události, se u tohodle singletonu zaregistruje a už mu události chodí, dokud se zase neodregistruje. A navíc si objekt může vybírat, jaké druhy událostí bude chtít přijímat.
_________________
Other Inside
Greenlitnuto!
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Solid.Sn



Založen: 08. 08. 2009
Příspěvky: 55

PříspěvekZaslal: 18. září 2011, 19:42:20    Předmět: Odpovědět s citátem

Rád bych se ještě zeptal, jakými způsoby se animuje GUI? V JS se animování většinou řeší reakcemi na události s timery. V mém případě mě napadá to nějak zakomponovat do OnRender / Render události / metody, které se vyvolávají při renderování všech jednotlivých prvků uživatelského rozhraní, ale není mi moc jasné jak bych to vyřešil.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mem



Založen: 28. 07. 2007
Příspěvky: 1959
Bydliště: Olomouc

PříspěvekZaslal: 19. září 2011, 11:38:36    Předmět: Odpovědět s citátem

Teď si nejsem přesně jistý, o který mechanismus ti jde. Vyvolat překreslení, tj. nějaké zprávy Invalidate z oblastí? Anebo vůbec počítání a aktualizaci času u jednotlivých prvků, které se mají animovat? Tam bys mohl zaregistrovat každý animovatelný prvek u nějakého providera navěšeného na timer (nebo lépe hlavní loop), který by všem zaregistrovaným prvkům posílal zprávu update a delta čas (teď koukám, že Dlaha psal něco o Observeru, to je nejspíš stejný přístup). Ti by si to vevnitř zpracovali, spočítali, a pokud se má animace změnit, vyvolali by ten Invalidate, nebo se rovnou překreslili. Pokud nechceš tu registraci řešit, tak mít tu vypočtenou deltu public přístupnou a jen vyvolat nějaký refresh všechn prvků v kontejneru (případně rekurzivně)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna