goeiemorgen allemaal (waar is die koffiesmiley als je em nodig hebt)
ik heb een GUI gemaakt voor gebruik in mn toekomstige apps (vooral games), volledig autonoom mbv SDL (dus fullscreen gfx, geen windows grappen). nu begint het z'n voltooiing te naderen en wordt het tijd om manieren te bedenken waarop ik de gui goed kan gebruiken in mn programma's, en dan doel ik vooral op messaging en handling.
hoe ik het nu heb geimplementeerd is denk ik een beetje vaag, gezien de lappen code die ik er voor nodig heb. ik zal proberen uit te leggen hoe het in elkaar steekt in het huidige model (niet mn sterkste punt, uitleggen, zeker niet 's ochtends, dus vraag gerust om opheldering als het niet duidelijk is)
mn voorbeeld-app is een window met daarin een datagrid met leden (van een sportschool in dit geval). de gebruiker moet hier leden kunnen aanklikken en veranderen, leden kunnen toevoegen, etc. in mn main.cpp include ik "leden.hpp" (en daarmee .cpp dus) waarin al dit moois staat. hier een stukje uit leden_init():
so far so good, dit vind ik wel een geslaagde manier om een kadertje op te zetten. maar let op het handler stukje, die 2 regels.. ik heb een base class 'handler' waar ik de 'c_handler_win_leden' van afleid. alles wat gebeurd binnen dat window, dus alle children ervan - de datagrid, maar ook evt andere knoppen die ik ga toevoegen - sturen hun events naar handler_win_leden->message(..); hier de code van de definitie van de afgeleide class:
en de implementatie:
(button_voegtoe_lid is een knop in het win_members window, die roept deze functie dus aan als er op geklikt wordt. *sender is het geheugenadres van de knop, in message.message_int zit bijv een _MSG_CLICKED, maar dat is bij een knop natuurlijk logisch dus daar check ik niet op
)
ik heb de hele 'handler_win_voegtoe_lid' implementatie maar achterwege gelaten, want volgens mij is mn probleem hier al wel duidelijk. het wordt allemaal veel te omvangrijk en onduidelijk. om mn subproblemen op te sommen:
- voor elk window moet ik een handler class afleiden en implementeren
- al die handler objecten van subwindows moeten worden gedelete als het hoofdwindow wordt gesloten, en dat moet ik nu dus dubbel coden (in de 'if _MSG_CLOSE' van de hoofdwindowhandler en in die van de subwindows zelf.. maw het al-dan-niet bestaan van de handler pointers is nogal vaag tijdens runtime
- m'n hele message systeem komt me niet helemaal profi over, alleen ik heb dus geen idee hoe dat bij commerciele GUI's werkt
- zelfde voor het hele handler gebeuren
het liefst zou ik gewoon een 'application' class maken waarvan ik mn 'app_leden' afleid, en waarin ik methoden (zo noemt men functies in classes toch?) kan maken die worden aangeroepen in het toepasselijke geval. dus iets als:
(pseudocode)
maar ik geloof niet dat het mogelijk is om het adres van een methode aan een knop te 'knop->sethandler()'en (of heb ik dat mis? zeg me dat ik het mis heb!
) toen ik het probeerde iig mocht het niet van meneer c++..
mijn vragen samenvattend: hoe wordt zo'n eventhandlersysteem normaliter geimplementeerd? hoe houd ik de code zo minimaal en overzichtelijk mogelijk?
hoop dat het zo een beetje duidelijk is. als m'n vragen n00by overkomen; ik ben nog niet extreem ervaren met c++, vergeef me
alvast bedankt.. happy codin'
bazkie
ik heb een GUI gemaakt voor gebruik in mn toekomstige apps (vooral games), volledig autonoom mbv SDL (dus fullscreen gfx, geen windows grappen). nu begint het z'n voltooiing te naderen en wordt het tijd om manieren te bedenken waarop ik de gui goed kan gebruiken in mn programma's, en dan doel ik vooral op messaging en handling.
hoe ik het nu heb geimplementeerd is denk ik een beetje vaag, gezien de lappen code die ik er voor nodig heb. ik zal proberen uit te leggen hoe het in elkaar steekt in het huidige model (niet mn sterkste punt, uitleggen, zeker niet 's ochtends, dus vraag gerust om opheldering als het niet duidelijk is)
mn voorbeeld-app is een window met daarin een datagrid met leden (van een sportschool in dit geval). de gebruiker moet hier leden kunnen aanklikken en veranderen, leden kunnen toevoegen, etc. in mn main.cpp include ik "leden.hpp" (en daarmee .cpp dus) waarin al dit moois staat. hier een stukje uit leden_init():
C++:
1
2
3
4
5
6
7
8
9
10
11
12
| win_leden = new window(screen, "Leden"); win_leden->setcoords(60, 82, SCREEN_WIDTH - 120, SCREEN_HEIGHT - 142); win_leden->setbgcolor(255, 255, 255); win_leden->setalpha(200); handler_win_leden = new c_handler_win_leden(); win_leden->setmessagehandler(handler_win_leden); datagrid *grid_leden = new datagrid(screen); win_leden->addview(grid_leden); grid_leden->setcoords(0, 0, 0, -22); grid_leden->redraw(); |
so far so good, dit vind ik wel een geslaagde manier om een kadertje op te zetten. maar let op het handler stukje, die 2 regels.. ik heb een base class 'handler' waar ik de 'c_handler_win_leden' van afleid. alles wat gebeurd binnen dat window, dus alle children ervan - de datagrid, maar ook evt andere knoppen die ik ga toevoegen - sturen hun events naar handler_win_leden->message(..); hier de code van de definitie van de afgeleide class:
C++:
1
2
3
4
5
6
| class c_handler_win_leden:public handler { public: c_handler_win_leden() {} virtual ~c_handler_win_leden() {} void handle_message(void *sender, s_message message); }; |
en de implementatie:
(button_voegtoe_lid is een knop in het win_members window, die roept deze functie dus aan als er op geklikt wordt. *sender is het geheugenadres van de knop, in message.message_int zit bijv een _MSG_CLICKED, maar dat is bij een knop natuurlijk logisch dus daar check ik niet op
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| void c_handler_win_leden::handle_message(void *sender, s_message message) { if (sender == button_voegtoe_lid && !win_voegtoe_lid) { win_voegtoe_lid = new window(screen, "Lid toevoegen"); win_voegtoe_lid->setcoords(220, 230, 260, 340); win_voegtoe_lid->setbgcolor(0, 0, 0); win_voegtoe_lid->setalpha(200); handler_win_voegtoe_lid = new c_handler_win_voegtoe_lid(); win_voegtoe_lid->setmessagehandler(handler_win_voegtoe_lid); } else if (sender == button_voegtoe_lid) { // voegtoe lid win already there? win_voegtoe_lid->bringtofront(); win_voegtoe_lid->setfocus(); } if (win_leden && message.message_int == _MSG_CLOSE) { // close children if (win_voegtoe_lid) { delete win_voegtoe_lid; win_voegtoe_lid = NULL; delete handler_win_voegtoe_lid; } delete win_leden; win_leden = NULL; delete this; } } |
ik heb de hele 'handler_win_voegtoe_lid' implementatie maar achterwege gelaten, want volgens mij is mn probleem hier al wel duidelijk. het wordt allemaal veel te omvangrijk en onduidelijk. om mn subproblemen op te sommen:
- voor elk window moet ik een handler class afleiden en implementeren
- al die handler objecten van subwindows moeten worden gedelete als het hoofdwindow wordt gesloten, en dat moet ik nu dus dubbel coden (in de 'if _MSG_CLOSE' van de hoofdwindowhandler en in die van de subwindows zelf.. maw het al-dan-niet bestaan van de handler pointers is nogal vaag tijdens runtime
- m'n hele message systeem komt me niet helemaal profi over, alleen ik heb dus geen idee hoe dat bij commerciele GUI's werkt
- zelfde voor het hele handler gebeuren
het liefst zou ik gewoon een 'application' class maken waarvan ik mn 'app_leden' afleid, en waarin ik methoden (zo noemt men functies in classes toch?) kan maken die worden aangeroepen in het toepasselijke geval. dus iets als:
(pseudocode)
C++:
1
2
3
4
5
| class app_leden : public application { void button_lidtoevoegen_onclick(); void win_leden_onclose(); void win_lidtoevoegen_onclose(); } |
maar ik geloof niet dat het mogelijk is om het adres van een methode aan een knop te 'knop->sethandler()'en (of heb ik dat mis? zeg me dat ik het mis heb!
mijn vragen samenvattend: hoe wordt zo'n eventhandlersysteem normaliter geimplementeerd? hoe houd ik de code zo minimaal en overzichtelijk mogelijk?
hoop dat het zo een beetje duidelijk is. als m'n vragen n00by overkomen; ik ben nog niet extreem ervaren met c++, vergeef me
alvast bedankt.. happy codin'