Add support for 'modeless' windows - windows that will allow events to be passed on to the underlying window. Intended for the editor
This commit is contained in:
parent
5f87108ba4
commit
3121fb4990
|
@ -3,6 +3,7 @@ D1X-Rebirth Changelog
|
|||
20111009
|
||||
--------
|
||||
main/render.c: Initialise dyn_light using memset, fixing a warning
|
||||
arch/include/event.h, arch/include/window.h, arch/sdl/event.c, arch/sdl/window.c, include/ui.h, ui/dialog.c, ui/file.c, ui/keypress.c, ui/menu.c, ui/message.c, ui/popup.c: Add support for 'modeless' windows - windows that will allow events to be passed on to the underlying window. Intended for the editor
|
||||
|
||||
20110927
|
||||
--------
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef enum event_type
|
|||
|
||||
EVENT_MOUSE_BUTTON_DOWN,
|
||||
EVENT_MOUSE_BUTTON_UP,
|
||||
EVENT_MOUSE_DOUBLE_CLICKED, // editor only for now
|
||||
EVENT_MOUSE_DOUBLE_CLICKED,
|
||||
EVENT_MOUSE_MOVED,
|
||||
|
||||
EVENT_KEY_COMMAND,
|
||||
|
@ -47,7 +47,7 @@ void event_flush();
|
|||
void set_default_handler(int (*handler)(d_event *event));
|
||||
int call_default_handler(d_event *event);
|
||||
|
||||
// Send an event to the front window as first priority, then the default handler
|
||||
// Send an event to the front window as first priority, then to the windows behind if it's not modal (editor), then the default handler
|
||||
void event_send(d_event *event);
|
||||
|
||||
// Sends input, idle and draw events to event handlers
|
||||
|
|
|
@ -29,6 +29,8 @@ extern void window_set_visible(window *wind, int visible);
|
|||
extern int window_is_visible(window *wind);
|
||||
extern grs_canvas *window_get_canvas(window *wind);
|
||||
extern int window_send_event(window *wind, d_event *event);
|
||||
extern void window_set_modal(window *wind, int modal);
|
||||
extern int window_is_modal(window *wind);
|
||||
|
||||
#define WINDOW_SEND_EVENT(w, e) \
|
||||
do { \
|
||||
|
|
|
@ -124,13 +124,18 @@ int call_default_handler(d_event *event)
|
|||
void event_send(d_event *event)
|
||||
{
|
||||
window *wind;
|
||||
int handled = 0;
|
||||
|
||||
if ((wind = window_get_front()))
|
||||
{
|
||||
if (!window_send_event(wind, event))
|
||||
call_default_handler(event);
|
||||
}
|
||||
else
|
||||
for (wind = window_get_front(); wind != NULL && !handled; wind = window_get_prev(wind))
|
||||
if (window_is_visible(wind))
|
||||
{
|
||||
handled = window_send_event(wind, event);
|
||||
|
||||
if (window_is_modal(wind))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
call_default_handler(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ struct window
|
|||
grs_canvas w_canv; // the window's canvas to draw to
|
||||
int (*w_callback)(window *wind, d_event *event, void *data); // the event handler
|
||||
int w_visible; // whether it's visible
|
||||
int w_modal; // modal = accept all user input exclusively
|
||||
void *data; // whatever the user wants (eg menu data for 'newmenu' menus)
|
||||
struct window *prev; // the previous window in the doubly linked list
|
||||
struct window *next; // the next window in the doubly linked list
|
||||
|
@ -41,6 +42,7 @@ window *window_create(grs_canvas *src, int x, int y, int w, int h, int (*event_c
|
|||
gr_init_sub_canvas(&wind->w_canv, src, x, y, w, h);
|
||||
wind->w_callback = event_callback;
|
||||
wind->w_visible = 1; // default to visible
|
||||
wind->w_modal = 1; // default to modal
|
||||
wind->data = data;
|
||||
|
||||
if (FirstWindow == NULL)
|
||||
|
@ -194,3 +196,13 @@ int window_send_event(window *wind, d_event *event)
|
|||
{
|
||||
return wind->w_callback(wind, event, wind->data);
|
||||
}
|
||||
|
||||
void window_set_modal(window *wind, int modal)
|
||||
{
|
||||
wind->w_modal = modal;
|
||||
}
|
||||
|
||||
int window_is_modal(window *wind)
|
||||
{
|
||||
return wind->w_modal;
|
||||
}
|
||||
|
|
23
include/ui.h
23
include/ui.h
|
@ -186,12 +186,18 @@ typedef struct {
|
|||
int moved;
|
||||
} UI_GADGET_LISTBOX;
|
||||
|
||||
enum dialog_flags
|
||||
{
|
||||
DF_BORDER = 1,
|
||||
DF_FILLED = 2,
|
||||
DF_SAVE_BG = 4,
|
||||
DF_DIALOG = (4+2+1),
|
||||
DF_MODAL = 8 // modal = accept all user input exclusively
|
||||
};
|
||||
|
||||
typedef struct _ui_window {
|
||||
struct window *wind;
|
||||
int (*callback)(struct _ui_window *, struct d_event *, void *);
|
||||
short x, y;
|
||||
short width, height;
|
||||
short text_x, text_y;
|
||||
grs_canvas * canvas;
|
||||
grs_canvas * oldcanvas;
|
||||
grs_bitmap * background;
|
||||
|
@ -200,6 +206,10 @@ typedef struct _ui_window {
|
|||
struct _ui_window * next;
|
||||
struct _ui_window * prev;
|
||||
void *userdata;
|
||||
short x, y;
|
||||
short width, height;
|
||||
short text_x, text_y;
|
||||
enum dialog_flags flags;
|
||||
} UI_DIALOG;
|
||||
|
||||
typedef struct {
|
||||
|
@ -270,12 +280,7 @@ extern int ui_mouse_motion_process(struct d_event *event);
|
|||
extern void ui_mouse_hide();
|
||||
extern void ui_mouse_show();
|
||||
|
||||
#define DF_BORDER 1
|
||||
#define DF_FILLED 2
|
||||
#define DF_SAVE_BG 4
|
||||
#define DF_DIALOG (4+2+1)
|
||||
|
||||
extern UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, int flags, int (*callback)(UI_DIALOG *, struct d_event *, void *), void *userdata );
|
||||
extern UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, enum dialog_flags flags, int (*callback)(UI_DIALOG *, struct d_event *, void *), void *userdata );
|
||||
extern void ui_close_dialog( UI_DIALOG * dlg );
|
||||
|
||||
extern UI_GADGET * ui_gadget_add( UI_DIALOG * dlg, short kind, short x1, short y1, short x2, short y2 );
|
||||
|
|
|
@ -257,7 +257,7 @@ int ui_dialog_handler(window *wind, d_event *event, UI_DIALOG *dlg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, int flags, int (*callback)(UI_DIALOG *, d_event *, void *), void *userdata )
|
||||
UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, enum dialog_flags flags, int (*callback)(UI_DIALOG *, d_event *, void *), void *userdata )
|
||||
{
|
||||
UI_DIALOG *dlg;
|
||||
int sw, sh, req_w, req_h;
|
||||
|
@ -277,6 +277,8 @@ UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, int flags, int
|
|||
|
||||
req_w = w;
|
||||
req_h = h;
|
||||
|
||||
dlg->flags = flags;
|
||||
|
||||
if (flags & DF_BORDER)
|
||||
{
|
||||
|
@ -332,6 +334,9 @@ UI_DIALOG * ui_create_dialog( short x, short y, short w, short h, int flags, int
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!(flags & DF_MODAL))
|
||||
window_set_modal(dlg->wind, 0); // make this window modeless, allowing events to propogate through the window stack
|
||||
|
||||
if (flags & DF_FILLED)
|
||||
ui_draw_box_out( 0, 0, req_w-1, req_h-1 );
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ int ui_get_filename( char * filename, char * Filespec, char * message )
|
|||
Spaces[i] = ' ';
|
||||
Spaces[34] = 0;
|
||||
|
||||
dlg = ui_create_dialog( 200, 100, 400, 370, DF_DIALOG, NULL, NULL );
|
||||
dlg = ui_create_dialog( 200, 100, 400, 370, DF_DIALOG | DF_MODAL, NULL, NULL );
|
||||
|
||||
ui_dprintf_at( dlg, 10, 5, message );
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ int GetKeyCode(char * text)
|
|||
|
||||
text = text;
|
||||
|
||||
dlg = ui_create_dialog( 200, 200, 400, 200, DF_DIALOG, NULL, NULL );
|
||||
dlg = ui_create_dialog( 200, 200, 400, 200, DF_DIALOG | DF_MODAL, NULL, NULL );
|
||||
|
||||
DoneButton = ui_add_gadget_button( dlg, 170, 165, 60, 25, "Ok", NULL );
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ int MenuX( int x, int y, int NumButtons, char * text[] )
|
|||
y = h - height;
|
||||
}
|
||||
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_FILLED | DF_SAVE_BG, NULL, NULL );
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_FILLED | DF_SAVE_BG | DF_MODAL, NULL, NULL );
|
||||
|
||||
x = MENU_BORDER+3;
|
||||
y = MENU_BORDER+3;
|
||||
|
|
|
@ -116,7 +116,7 @@ int MessageBoxN( short xc, short yc, int NumButtons, char * text, char * Button[
|
|||
y = h - height;
|
||||
}
|
||||
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_DIALOG, NULL, NULL );
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_DIALOG | DF_MODAL, NULL, NULL );
|
||||
|
||||
//ui_draw_line_in( MESSAGEBOX_BORDER, MESSAGEBOX_BORDER, width-MESSAGEBOX_BORDER, height-MESSAGEBOX_BORDER );
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ int PopupMenu( int NumButtons, char * text[] )
|
|||
Mouse.y = y + (MENU_BORDER+3) + button_height/2;
|
||||
}
|
||||
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_DIALOG, NULL, NULL );
|
||||
dlg = ui_create_dialog( x, y, width, height, DF_DIALOG | DF_MODAL, NULL, NULL );
|
||||
|
||||
//mouse_set_pos(Mouse.x, Mouse.y);
|
||||
|
||||
|
|
Loading…
Reference in a new issue