Programmation événementielle et composants dinterface (« widgets »)

Preview:

Citation preview

Programmation événementielle et composants d’interface (« widgets »)

Logiciel traditionnel,sans interface utilisateur

{

Lire les entrées d’un fichier

Effectuer des calculs

Écrire les sorties dans un fichier

}

… avec interface utilisateur minimale

{

Lire les entrées du clavier

Effectuer des calculs

Écrire les sorties sur l’écran

}

… dans une boucleRépéter {

Afficher l’invite de commandes

Lire la commande

Exécuter la commande

Écrire les sorties sur l’écran

}

Logiciel événementiel(« event-driven program»)

Répéter {

Attendre un événement

Traiter l’événement

}

Logiciel événementielpour une interface graphique

Afficher l’interface (fenêtre(s), etc.)Répéter { Attendre un événement d’entrée e switch(e.type) { case KEY_PRESS: ... case MOUSE_BUTTON: ... case MOUSE_MOTION: ... } Si nécessaire, mettre à jour l’affichage}

Boucle d’événements

Logiciel traditionnel:• Le logiciel « a le contrôle ».• Le logiciel peut prendre le temps nécessaire pour

traiter les entrées. L’utilisateur doit attendre.• Les entrées sont limitées

aux chaînes de caractères.Logiciel graphique interactif:• L’utilisateur doit (avoir l’impression de)

« avoir le contrôle ».• Le logiciel doit traiter chaque événement assez

rapidement pour répondre en temps réel.• L’utilisateur peut générer différents événements

à tout moment.

Structure, ou classe, d’événement

Event {

unsigned long int timestamp;

int type; // KEY_PRESS, MOUSE_...

int x, y;

int key;

boolean flag...

...

}

Sortes d’événements (1)

• KEY_DOWN ou …_PRESS (touche appuyée),KEY_UP ou …_RELEASE (touche relâchée),KEY_TYPED (synonyme pour DOWN + UP)– Attributs:

temps,caractère ASCII (‘a’, ‘b’, ‘c’, …),touche de clavier (F1, F2, PageUp, Esc, …),s’il s’agit d’une auto-répétition ou non,coordonnées (x, y) de la souris,état des touches de modification (Ctrl, Shift, etc.)

Sortes d’événements (2)• MOUSE_DOWN ou …_PRESS (bouton appuyé),

MOUSE_UP ou …_RELEASE (bouton relâché),MOUSE_CLICK (synonyme pour DOWN + UP)MOUSE_DOUBLE_CLICK,MOUSE_MOTION ou …_MOVEMENT (mouvement),MOUSE_DRAG (glissement)

– Attributs: temps,bouton (1-5) (gauche, droit, milieu, …),coordonnées (x, y),état de tous les boutons (utile pour les combinaisons),état des touches de modification (Ctrl, Shift, etc.)

– Taux d’échantillonnage de la position dépend habituellement de la charge CPU

Autres sortes d’événements?

Autres sortes d’événements?

Sortes d’événements (3)

• RESIZE (redimensionnement),MAXIMIZE, MINIMIZE– Attributs: temps,

nouvelles dimensions (width, height)

• WINDOW_CLOSE– Permet au logiciel de sauvegarder ses données,

faire le ménage, etc.

Autres sortes d’événements?

Sortes d’événements (4)

• MOUSE_ENTER (souris entre dans la fenêtre),MOUSE_LEAVE ou …_EXIT (souris sort de la fenêtre)

– Attributs: semblable à ceux des autres événements de souris

• REDRAW ou EXPOSE ou PAINT (demande de redessiner)

– Peut être généré par un redimensionnement,un mouvement d’une autre fenêtre,ou par une demande du client même

– Attributs:rectangle(s) à redessiner (x, y, width, height),c.-à-d. les rectangles endommagés (« damaged »)

Rectangles endommagés

Boucle d’événementsen C avec Xlib (UNIX/X11)

XEvent event;

ouvrir une fenêtre

while (!quit) {

XNextEvent(..., &event); // attend le prochain événement

switch (event.type) {

case Expose: ... // redessiner

case ConfigureNotify: ... // redimensionnement

case ButtonPress: ... // bouton de souris

case ButtonRelease: ... // bouton de souris

case MotionNotify: ... // mouvement de souris

case KeyPress: // touche de clavier

switch (XLookupKeysym(&event.xkey, ...)) {

case XK_F1: ... // afficher de l’aide

case XK_Escape: quit=true; break;

}

break;

}

}

Boucle d’événements Xlib – comment travailler en même tempswhile (!quit) {

while (0 == XEventsQueued(...)) {

// Peut avancer une animation, simulation, des calculs, etc.

faireUnPeuDeTravail();

usleep(100000); // dormir une fraction de seconde

}

XNextEvent(..., &event);

switch (event.type) {

case ...

}

}

Optionnel

Une autre façon de faire du travaille en même temps:utiliser des événements spéciaux …

Sortes d’événements (5)

• TIMER ou TIMEOUT (un délai de temps expiré),IDLE (le CPU est libre)– Envoyés au client sur demande seulement– Permettent de faire un peu de travail en attendant

d’autres événements– Les « timeouts » peuvent être envoyés de façon

périodique (exemple: pour une animation),ou seulement une fois (ex: pour retarder une action)

Exemples d’actions retardées

Affichage d’une infobulle Ouverture d’un sous-menu

Traitement d’événementsen C avec GLUT (OpenGL)

void drawHandler() {

... // redessiner

}

void reshapeHandler( int width, int height ) {

... // redimensionnement

}

void mouseHandler( int button,int state,int x,int y ) {

// boutons de souris

if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) ...

}

void passiveMotionHandler( int x, int y ) {

... // mouvement de souris

}

void motionHandler( int x, int y ) {

... // glissement de souris

}

void keyboardHandler( unsigned char key, int x, int y ) {

... // touches normales

}

void specialKeyHandler( int key, int x, int y ) {

... // touches spéciales

}

int main( ... ) {

glutInit...

glutCreateWindow( "My Window" );

glutDisplayFunc( drawHandler );

glutReshapeFunc( reshapeHandler );

glutMouseFunc( mouseHandler );

...

glutMainLoop();

}

• Ces sous-routines s’appellent des « event handlers » (traiteurs d’événements)ou « callbacks »

• Où est la boucle d’événements?

Classes d’événements,architecture orientée objets

Event

KeyEventMouseEvent

MouseButtonEvent MouseMotionEvent

• Les informations décrivant les événements peuvent être encodées dans une structure (exemple: Xlib), une ou plusieurs classes (ex: Java), ou de simples paramètres (ex: GLUT).

• Ces informations peuvent être traitées par une seule sous-routine, ou par plusieurs sous-routines selon le type d’événement. (Ces sous-routines s’appellent « event handlers » (traiteurs d’événements), ou « callbacks », ou sont des méthodes d’objets « event listeners » (écouters d’événements))

• La boucle d’événements peut être située dans le code du client (ex: Xlib), ou à l’extérieur (dans une librarie ou « framework »; ex: GLUT).

Quelques exemples en Java …

Quelques éléments desinterfaces graphiques

Les fenêtres

Les fenêtres

Curseurs standards de X11

Les curseurs de souris (ou pointeurs)

Curseur de souris, ou pointeur

« hotspot »

Les curseurs de texte (« caret »)

Les widgets

Les boutons

Les boutons

Les boutons

Les cases à cocher (« checkbox »)

Pour des choix binaires et indépendants

Les boutons radio

Pour des choix mutuellement exclusifs

Les infobulles (« tooltips »)

Barre de défilementou glisseur

(« scrollbar » ou « slider »)

Défileur (« thumb » ou « slider »)

Barre de défilementcontextuelle (« popup slider »)

Barre de progrès

Les champs

• Champs de texte• Champs numériques

– Avec « spinner »– Avec unités– Avec barre de défilement

Les menus

item ou commande (« menu item »)

Barre de menus

Menu déroulant (« Pull-down menu »)

Menu contextuel(« popup menu » ou « context-sensitive menu »)

C’est quoi la différence entre « popup » et « context-sensitive » ?

Les menus d’options(« option menus »)

Affichage de sous-menus

Les ellipses …

Menus détachés ou menus flottants (« Tear-off menus »)

Liste déroulante(« Pick list » ou « Scrolling list »)

Menu divisé (« Split menu »)

Menu divisé (« Split menu »)

Les cadres

Les onglets

Les onglets

Des onglets hiérarchiques ?

Les séparateurs

Un bouton + menu

Créateur de tables

Les palettes de boutons

Les barres d’outils

Des boîtes de dialogue

2 sortes de boîtes de dialogue

• Modale (« modal »)– Oblige l’utilisateur de compléter son interaction

avec la boîte avant de retourner à la fenêtre principale

• Non-modale (« modeless »)– Plusieurs boîtes non-modales peuvent être

ouvertes en même temps dans une même application

Les tableaux

« tree list »

« tree list »

Cadres défilables (« scrolling area »)

Sélecteur de couleur (« color picker »)

Sélecteur de couleur (« color picker »)

Observations

• Widgets simples vs widgets composés• Widgets composés:

– Un enfant vs plusieurs enfants

– Contenu fixe vs contenu variable

Observations (2)Certains widgets aident à gérer l’espace• Onglets, menus, barres de défilement, …

L’exemple de SimpleDraw.java …

class Stroke ArrayList< Point2D > points = …; AlignedRectangle2D getBoundingRectangle() draw()class Drawing ArrayList< Stroke > strokes = …; AlignedRectangle2D getBoundingRectangle() draw()class MyCanvas RadialMenuWidget radialMenu = …; paintComponent() mousePressed() mouseReleased() mouseMoved() mouseDragged()class SimpleDraw actionPerformed() createUI() main()

class CustomWidget pressEvent() releaseEvent() moveEvent() dragEvent() draw()

class RadialMenuWidget …

RadialMenuWidget.java

SimpleDraw.javaCustomWidget.java

JMenuBar menuBar

JMenu("File")

JMenu("View")

JMenu("Help")

JMenuItem("Clear")

JMenuItem(“Quit")

JFrame frame

Container toolPanel MyCanvas canvas

JRadioButton(…)

JButton("Delete Selection")

JButton("Frame Selection")

… …

RadialMenuWidget