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
This commit is contained in:
Simon Howard 2006-08-31 18:11:26 +00:00
parent b20f94345c
commit 5e303c43da
2 changed files with 109 additions and 22 deletions

View file

@ -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;
}

View file

@ -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 */