From 5e303c43dab6c433bc3b59dd34d4672317c5f4e1 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 31 Aug 2006 18:11:26 +0000 Subject: Add window listener functions to allow spying on keys and mouse buttons received by windows. Emit a 'closed' signal when a window is closed. Allow windows to have no action buttons. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 576 --- textscreen/txt_window.c | 111 ++++++++++++++++++++++++++++++++++++++---------- textscreen/txt_window.h | 20 +++++++++ 2 files changed, 109 insertions(+), 22 deletions(-) (limited to 'textscreen') diff --git a/textscreen/txt_window.c b/textscreen/txt_window.c index d9a3abca..2cb9ffc4 100644 --- a/textscreen/txt_window.c +++ b/textscreen/txt_window.c @@ -62,6 +62,8 @@ txt_window_t *TXT_NewWindow(char *title) win->y = TXT_SCREEN_H / 2; win->horiz_align = TXT_HORIZ_CENTER; win->vert_align = TXT_VERT_CENTER; + win->key_listener = NULL; + win->mouse_listener = NULL; TXT_AddWidget(win, TXT_NewSeparator(NULL)); @@ -82,6 +84,8 @@ void TXT_CloseWindow(txt_window_t *window) { int i; + TXT_EmitSignal(window, "closed"); + free(window->title); // Destroy all actions @@ -143,7 +147,7 @@ static void LayoutActionArea(txt_window_t *window) TXT_CalcWidgetSize(widget); widget->x = window->window_x + 2; - widget->y = window->window_y + window->window_h - 2; + widget->y = window->window_y + window->window_h - widget->h - 1; } // Draw the center action @@ -155,7 +159,7 @@ static void LayoutActionArea(txt_window_t *window) TXT_CalcWidgetSize(widget); widget->x = window->window_x + (window->window_w - widget->w - 2) / 2; - widget->y = window->window_y + window->window_h - 2; + widget->y = window->window_y + window->window_h - widget->h - 1; } // Draw the right action @@ -167,7 +171,7 @@ static void LayoutActionArea(txt_window_t *window) TXT_CalcWidgetSize(widget); widget->x = window->window_x + window->window_w - 2 - widget->w; - widget->y = window->window_y + window->window_h - 2; + widget->y = window->window_y + window->window_h - widget->h - 1; } } @@ -184,13 +188,13 @@ static void DrawActionArea(txt_window_t *window) } } -static int ActionAreaWidth(txt_window_t *window) +static void CalcActionAreaSize(txt_window_t *window, int *w, int *h) { txt_widget_t *widget; - int w; int i; - w = 1; + *w = 1; + *h = 0; // Calculate the width of all the action widgets and use this // to create an overall min. width of the action area @@ -202,11 +206,14 @@ static int ActionAreaWidth(txt_window_t *window) if (widget != NULL) { TXT_CalcWidgetSize(widget); - w += widget->w + 1; + *w += widget->w + 1; + + if (widget->h > *h) + { + *h = widget->h; + } } } - - return w; } // Sets size and position of all widgets in a window @@ -215,7 +222,7 @@ void TXT_LayoutWindow(txt_window_t *window) { txt_widget_t *widgets = (txt_widget_t *) window; int widgets_w; - int actionarea_w; + int actionarea_w, actionarea_h; // Calculate size of table @@ -227,7 +234,7 @@ void TXT_LayoutWindow(txt_window_t *window) // Calculate the size of the action area // Make window wide enough to action area - actionarea_w = ActionAreaWidth(window); + CalcActionAreaSize(window, &actionarea_w, &actionarea_h); if (actionarea_w > widgets_w) widgets_w = actionarea_w; @@ -235,7 +242,7 @@ void TXT_LayoutWindow(txt_window_t *window) // Set the window size based on widgets_w window->window_w = widgets_w + 2; - window->window_h = widgets->h + 3; + window->window_h = widgets->h + 1; // If the window has a title, add an extra two lines @@ -244,6 +251,13 @@ void TXT_LayoutWindow(txt_window_t *window) window->window_h += 2; } + // If the window has an action area, add extra lines + + if (actionarea_h > 0) + { + window->window_h += actionarea_h + 1; + } + // Use the x,y position as the centerpoint and find the location to // draw the window. @@ -254,7 +268,12 @@ void TXT_LayoutWindow(txt_window_t *window) widgets->w = widgets_w - 2; // widgets->h (already set) widgets->x = window->window_x + 2; - widgets->y = window->window_y + window->window_h - widgets->h - 3; + widgets->y = window->window_y; + + if (window->title != NULL) + { + widgets->y += 2; + } // Layout the table and action area @@ -281,16 +300,21 @@ void TXT_DrawWindow(txt_window_t *window, int selected) TXT_DrawWidget(window, selected); - // Separator for action area + // Draw an action area, if we have one - widgets = (txt_widget_t *) window; + if (widgets->y + widgets->h < window->window_y + window->window_h - 1) + { + // Separator for action area - TXT_DrawSeparator(window->window_x, widgets->y + widgets->h, - window->window_w); + widgets = (txt_widget_t *) window; - // Action area at the window bottom + TXT_DrawSeparator(window->window_x, widgets->y + widgets->h, + window->window_w); - DrawActionArea(window); + // Action area at the window bottom + + DrawActionArea(window); + } } void TXT_SetWindowPosition(txt_window_t *window, @@ -319,6 +343,20 @@ static void MouseButtonPress(txt_window_t *window, int b) TXT_GetMousePosition(&x, &y); + // Try the mouse button listener + // This happens whether it is in the window range or not + + if (window->mouse_listener != NULL) + { + // Mouse listener can eat button presses + + if (window->mouse_listener(window, x, y, b, + window->mouse_listener_data)) + { + return; + } + } + // Is it within the table range? widgets = (txt_widget_t *) window; @@ -351,13 +389,27 @@ void TXT_WindowKeyPress(txt_window_t *window, int c) // Is this a mouse button ? - if (c == TXT_MOUSE_LEFT) + if (c == TXT_MOUSE_LEFT + || c == TXT_MOUSE_MIDDLE + || c == TXT_MOUSE_RIGHT) { MouseButtonPress(window, c); return; } - - // Send to the currently selected widget first + + // Try the window key spy + + if (window->key_listener != NULL) + { + // key listener can eat keys + + if (window->key_listener(window, c, window->key_listener_data)) + { + return; + } + } + + // Send to the currently selected widget if (TXT_WidgetKeyPress(window, c)) { @@ -376,3 +428,18 @@ void TXT_WindowKeyPress(txt_window_t *window, int c) } } +void TXT_SetKeyListener(txt_window_t *window, TxtWindowKeyPress key_listener, + void *user_data) +{ + window->key_listener = key_listener; + window->key_listener_data = user_data; +} + +void TXT_SetMouseListener(txt_window_t *window, + TxtWindowMousePress mouse_listener, + void *user_data) +{ + window->mouse_listener = mouse_listener; + window->mouse_listener_data = user_data; +} + diff --git a/textscreen/txt_window.h b/textscreen/txt_window.h index 5e01a16d..a71307ae 100644 --- a/textscreen/txt_window.h +++ b/textscreen/txt_window.h @@ -31,6 +31,13 @@ typedef struct txt_window_s txt_window_t; #include "txt_table.h" #include "txt_window_action.h" +// Callback function for window key presses + +typedef int (*TxtWindowKeyPress)(txt_window_t *window, int key, void *user_data); +typedef int (*TxtWindowMousePress)(txt_window_t *window, + int x, int y, int b, + void *user_data); + struct txt_window_s { // Base class: all windows are tables with one column. @@ -51,6 +58,13 @@ struct txt_window_s txt_window_action_t *actions[3]; + // Callback functions to invoke when keys/mouse buttons are pressed + + TxtWindowKeyPress key_listener; + void *key_listener_data; + TxtWindowMousePress mouse_listener; + void *mouse_listener_data; + // These are set automatically when the window is drawn int window_x, window_y; @@ -65,6 +79,12 @@ void TXT_SetWindowPosition(txt_window_t *window, int x, int y); void TXT_SetWindowAction(txt_window_t *window, txt_horiz_align_t position, txt_window_action_t *action); +void TXT_SetKeyListener(txt_window_t *window, + TxtWindowKeyPress key_listener, + void *user_data); +void TXT_SetMouseListener(txt_window_t *window, + TxtWindowMousePress mouse_listener, + void *user_data); #endif /* #ifndef TXT_WINDOW_T */ -- cgit v1.2.3