Salut à tous !
Je me suis récemment mis à gtkmm dans le but de faire un petit éditeur 3D pour un jeu que je programme.
J'aimerai pouvoir contrôler la camera avec la souris sur mon widget 3D intègré, par exemple cliquer-glisser (drag) avec le bouton gauche pour faire tourner la camera.
J'y arrive, mais le problème du drag, c'est que le pointeur se déplace. Or, ce qui m'intéresse principalement c'est un mouvement relatif, et non un mouvement absolu : en gros, j'aimerai que le pointeur reste là où il était quand j'ai commencé à faire tourner ma caméra (tout en restant caché pendant l'opération, c'est plus joli).
J'ai trouvé une astuce, presque parfaite :
- Quand je commence le drag, je garde de côté la position du pointeur :
... puis je le cache :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Gdk::ModifierType mModifier; Glib::RefPtr<Gdk::Display> pDisplay = Gdk::Display::get_default(); pDisplay->get_pointer( iDragStartX, iDragStartY, mModifier );
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 this->get_window()->set_cursor(Gdk::Cursor( Gdk::Display::get_default(), Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, 1, 1), 0, 0 ));- Je récupère le mouvement relatif avec l'event "motion notify".
Je regarde où se trouve le curseur sur l'écran : si il atteint un bord de l'écran, je le repositionne au centre (attention : gdk va générer un event de déplacement de la souris, il ne faut pas en tenir compte, d'une manière où d'une autre ^^) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 int x, y; Gdk::ModifierType mModifier; Glib::RefPtr<Gdk::Display> pDisplay = Gdk::Display::get_default(); pDisplay->get_pointer( x, y, mModifier ); Glib::RefPtr<Gdk::Screen> pScreen = pDisplay->get_default_screen(); if ((x == 0) || (y == 0) || (x == pScreen->get_width()-1) || (y == pScreen->get_height()-1)) { pDisplay->warp_pointer( pScreen, iDragStartX, iDragStartY ); }- Quand j'ai fini mon drag, je repositionne le curseur là où il était au début, puis je le ré-affiche :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Glib::RefPtr<Gdk::Display> pDisplay = Gdk::Display::get_default(); Glib::RefPtr<Gdk::Screen> pScreen = pDisplay->get_default_screen(); pDisplay->warp_pointer( pScreen, iDragStartX, iDragStartY ); this->get_window()->set_cursor();
Le seul soucis (sur Ubuntu en tout cas, pas eu l'occasion de tester sous XP), c'est qu'il y a une certaine latence au niveau du repositionnement du curseur : quand le drag est terminé, le curseur réapparait immédiatement, mais il n'est pas encore repositionné. Il faut attendre une miliseconde ^^ Ça peut paraitre tatillon, mais ça se remarque quand même et ça fait vraiment pas propre.
Y a t-il une fonction (portable si possible) pour forcer l'environnement qui gère le curseur à le repositionner immédiatement (et pas à la prochaine mise à jour, ou je ne sais trop quand) ?
Merci d'avance !
Partager