Dialogs and events
MX-Windows Help

 
 

Dialogs and events


 
 

What is a dialog ?

A dialog (of type Dialog) is a list of windows that participate in events handling. The windows of a dialog are the toppest windows that may receive events, even if they are overlapped by other windows; the order in which the windows are installed in a dialog is the reverse of the order that they receive events : last installed window is the first to be checked if any event happened in it. The installation order has nothing to do with the z-order of the windows on the screen, but it is a good practice to install dialog windows in the same order as they are visible on the screen. An application may have more than one dialog : typically a dialog is used for each root window and its window tree; a dialog can contain menu windows entries so as that a popup-menu scheme is realized.
 
 
 

Dialog Manipulation

In order to create a dialog you may use the following function :

    Dialog CreateDialog(Cursor cursor, void (*event_handler)(Dialog, Event *), Window window, ...);
 

If you wish to destroy a dialog you may use the following function :

    void DestroyDialog(Dialog *dialog);

If this function is called within an event handler the dialog will be destroyed after all events of it have been executed. The windows of the dialog are not destroyed; they are just removed from the dialog list just before the list is destroyed.

After a dialog has been created, the following set of functions insert and remove windows into a dialog :

    Bool AddDialogWindow(Dialog dialog, Window window);
    Bool RemoveDialogWindow(Window window);

If the windows of a dialog have been rendered visible then any window that is added in the dialog and has not been drawn it gets rendered, too. If a window is removed from a dialog it is not removed from the screen, though; These functions return TRUE if their action is sucessful. Each window may belong in one dialog only; each window is inserted on top of a dialog.

When all window setup has been implemented then a dialog should be executed. A dialog runs by calling the following function :

    void RunDialog(Dialog *dialog);

This function executes any events at the current mouse position and then returns; the given dialog may be destroyed while the dialog executes so it is needed that you pass a pointer to it; If you would like to continuously run events then you should put the above function into a loop that its execution depends on a exit condition that is set from some of your windows. When a dialog runs for the first time all windows in it get drawn on the screen, if they are previously not drawn.
 
 
 

Available events

Each window has a set of flags that indicate which events the window is selected to process.
There are four classes of events : The following event masks are available :

    WindowExpose                      /* window area is exposed */
    ButtonPress                       /* a button is pressed for the first time */
    ButtonDown                        /* a button is continuously pressed */
    ButtonRelease                     /* a button is released */
    PointerStart                      /* pointer started motion */
    PointerEnter                      /* pointer entered a window */
    PointerMove                       /* pointer moved into a window */
    PointerLeave                      /* pointer left a window */
    PointerStop                       /* pointer stopped moving */
    KeyPress                          /* a key was pressed */

You can select which events the window processes by the following function :

    void SetWindowInput(Window window, int val);

Each class of events corresponds to one of the following event structures :

    typedef struct ExposeEvent {
       int type;                      /* common field to all events */
       int x1;                        /* exposed area - */
       int y1;                        /* coordinates measured from */
       int x2;                        /* screen 0, 0 */
       int y2;
       int count;                     /* how many exposure events are pending */
    } ExposeEvent;
 

    typedef struct ButtonEvent {
       int type;
       int root_x;                    /* mouse position equal to mouse_x, mouse_y */
       int root_y;
       int window_x;                  /* mouse position relative to window */
       int window_y;
       Window pointer_child;          /* child window that the mouse is on */
       int button;                    /* button pressed */
       int clicks;                    /* clicks at the time of the event */
       int time;                      /* time in miliseconds since first button press */
    } ButtonEvent;
 

    typedef struct PointerEvent {
       int type;
       int root_x;                    /* mouse position relative to screen 0, 0 */
       int root_y;
       int window_x;                  /* mouse position relative to window */
       int window_y;
       Window pointer_child;          /* child that the pointer is on */
       Window crossed_child;          /* child that the pointer was on */
    } PointerEvent;
 

    typedef struct KeyEvent {
       int type;
       int keyread;                   /* value returned from readkey() */
    } KeyEvent;

All these events are combined to the following union that is used to pass an event to the window. The type field is the one that shows to which class of event structure should the passed event pointer casted :

    typedef union Event {
       int type;
       ExposeEvent expose;
       ButtonEvent button;
       PointerEvent pointer;
       KeyEvent key;
    } Event;

When a window receives an event it also receives a structure with window information :

    typedef struct WindowInfo {
       Window window;                 /* window handle */
       int x1;                        /* window global position - */
       int y1;                        /* measured from screen 0, 0 */
       int x2;
       int y2;
       int border_width;
       void *extension;               /* extension - used for hook to user data */
    } WindowInfo;

This structure is mainly used for expose events where you may use Allegro functions to draw on the screen.

If you would like to send a user-defined event to a window then you may use the function :

void SendEventToWindow(Window window, Event *event);
 

Example event handler


void example_event_handler(WindowInfo *winfo, Event *event)
{
   ExposeEvent *exp;
   ButtonEvent *btn;
   PointerEvent *ptr;
   KeyEvent *kep;

   switch (event->type) {

      case WindowExpose:
         exp = (ExposeEvent *)event;
         /* use Allegro functions to draw either in the exposure rectangle
            which is the current screen clipping or
            the window info rectangle; please DO NOT UNCLIP SCREEN if
            you would like windowing to be maintained */
         break;

      case ButtonPress:
         btn = (ButtonEvent *)event;
         /* do action on button press */
         break;

      case PointerEnter:
         ptr = (PointerEvent *)event;
         /* do action when the pointer enters the window */
         break;

      case KeyPress:
         kep = (KeyEvent *)event;
         /* do action on key press */
         break;

   }
}
 

Events propagation

Each window has a set of flags (exactly like the event selection flags) that control which events are passed to its children. Events happen in a top to bottom fashion : firstly events are reported into the toppest dialog window that the mouse pointer is in; if the pointer is also in a child window then the event is propagated to that child if its parent allows it; this scheme goes on until there is no descentant window under the mouse or a window does not allow propagation. This trick makes a window able to catch events before its children so as that it can act accordingly.

The following function selects the events that the window chooses to propagate :

    void SetWindowPropagation(Window window, int val);
 
 
 

Changing click threshold

When a mouse button is released then an internal click counter is increased and an internal timer is reset and starts counting from the beggining; when it reaches a certain threshold the click counter is reset; this threshold is set with the following function :

    void SetClickThreshold(int msecs);

go to top
go to start page