From 1de18c1397bfb069771c02336e47b89e098b6f43 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 23 May 2006 00:07:02 +0000 Subject: Add window action class for action area labels at the bottom of windows. Adjust txt_table_t to expand tables to their maximum width when they only have one column (ensures separators reach the window edges). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 515 --- textscreen/txt_window.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 4 deletions(-) (limited to 'textscreen/txt_window.c') diff --git a/textscreen/txt_window.c b/textscreen/txt_window.c index f993a84e..b66995d7 100644 --- a/textscreen/txt_window.c +++ b/textscreen/txt_window.c @@ -33,8 +33,24 @@ #include "txt_separator.h" #include "txt_window.h" +void TXT_SetWindowAction(txt_window_t *window, + txt_horiz_align_t position, + txt_window_action_t *action) +{ + if (window->actions[position] != NULL) + { + TXT_DestroyWidget(window->actions[position]); + } + + window->actions[position] = action; +} + txt_window_t *TXT_NewWindow(char *title) { + int i; + txt_window_action_t *cancel_action; + txt_window_action_t *accept_action; + txt_window_t *win; win = malloc(sizeof(txt_window_t)); @@ -48,18 +64,41 @@ txt_window_t *TXT_NewWindow(char *title) win->vert_align = TXT_VERT_CENTER; TXT_AddWidget(win, TXT_NewSeparator(NULL)); + + for (i=0; i<3; ++i) + win->actions[i] = NULL; + TXT_AddDesktopWindow(win); + // Default actions + + cancel_action = TXT_NewWindowAction(KEY_ESCAPE, "Abort"); + TXT_SetWindowAction(win, TXT_HORIZ_LEFT, cancel_action); + accept_action = TXT_NewWindowAction(KEY_ENTER, "Accept"); + TXT_SetWindowAction(win, TXT_HORIZ_RIGHT, accept_action); + return win; } void TXT_CloseWindow(txt_window_t *window) { + int i; + free(window->title); + // Destroy all actions + + for (i=0; i<3; ++i) + { + if (window->actions[i] != NULL) + { + TXT_DestroyWidget(window->actions[i]); + } + } + // Destroy table and window - TXT_DestroyWidget((txt_widget_t *) window); + TXT_DestroyWidget(window); TXT_RemoveDesktopWindow(window); } @@ -95,6 +134,65 @@ static void CalcWindowPosition(txt_window_t *window, } } +static void DrawActionArea(txt_window_t *window, + int window_x, int window_y, + int window_w, int window_h) +{ + int ww, wh; + + // Draw the left action + + if (window->actions[TXT_HORIZ_LEFT] != NULL) + { + TXT_GotoXY(window_x + 2, window_y + window_h - 2); + TXT_DrawWidget(window->actions[TXT_HORIZ_LEFT], 0, 0); + } + + // Draw the center action + + if (window->actions[TXT_HORIZ_CENTER] != NULL) + { + TXT_CalcWidgetSize(window->actions[TXT_HORIZ_CENTER], &ww, &wh); + TXT_GotoXY(window_x + (window_w - ww - 2) / 2, window_y + window_h - 2); + TXT_DrawWidget(window->actions[TXT_HORIZ_CENTER], 0, 0); + } + + // Draw the right action + + if (window->actions[TXT_HORIZ_RIGHT] != NULL) + { + TXT_CalcWidgetSize(window->actions[TXT_HORIZ_RIGHT], &ww, &wh); + TXT_GotoXY(window_x + window_w - 2 - ww, window_y + window_h - 2); + TXT_DrawWidget(window->actions[TXT_HORIZ_RIGHT], 0, 0); + } +} + +static int CalcActionAreaWidth(txt_window_t *window, int *widgets_w) +{ + int ww, wh; + int w; + int i; + + w = 1; + + // Calculate the width of all the action widgets and use this + // to create an overall min. width of the action area + + for (i=0; i<3; ++i) + { + if (window->actions[i] != NULL) + { + TXT_CalcWidgetSize(window->actions[i], &ww, &wh); + w += ww + 1; + } + } + + // If this is larger than the window size, adjust the window to fit. + + if (w > *widgets_w) + *widgets_w = w; +} + void TXT_DrawWindow(txt_window_t *window) { int widgets_w, widgets_h; @@ -104,7 +202,8 @@ void TXT_DrawWindow(txt_window_t *window) int i; int ww, wh; - TXT_CalcWidgetSize((txt_widget_t *) window, &widgets_w, &widgets_h); + TXT_CalcWidgetSize(window, &widgets_w, &widgets_h); + CalcActionAreaWidth(window, &widgets_w); // Actual window size after padding @@ -123,11 +222,15 @@ void TXT_DrawWindow(txt_window_t *window) // Draw all widgets TXT_GotoXY(window_x + 1, window_y + 2); - TXT_DrawWidget((txt_widget_t *) window, widgets_w, 1); + TXT_DrawWidget(window, widgets_w, 1); // Separator for action area TXT_DrawSeparator(window_x, window_y + 2 + widgets_h, window_w); + + // Action area at the window bottom + + DrawActionArea(window, window_x, window_y, window_w, window_h); } void TXT_SetWindowPosition(txt_window_t *window, @@ -143,8 +246,24 @@ void TXT_SetWindowPosition(txt_window_t *window, void TXT_WindowKeyPress(txt_window_t *window, int c) { + int i; + // Send to the currently selected widget first - TXT_WidgetKeyPress((txt_widget_t *) window, c); + if (TXT_WidgetKeyPress(window, c)) + { + return; + } + + // Try all of the action buttons + + for (i=0; i<3; ++i) + { + if (window->actions[i] != NULL + && TXT_WidgetKeyPress(window->actions[i], c)) + { + return; + } + } } -- cgit v1.2.3