diff options
author | Simon Howard | 2006-08-31 18:12:05 +0000 |
---|---|---|
committer | Simon Howard | 2006-08-31 18:12:05 +0000 |
commit | 2fd49a65afdcadbc09680552142c6f107715ebbc (patch) | |
tree | a267143c8e98927d5192f61e21a3cbd4ed895ff6 | |
parent | fe1a0afdd7acec6705ccf0ada6b51eae9aae2870 (diff) | |
download | chocolate-doom-2fd49a65afdcadbc09680552142c6f107715ebbc.tar.gz chocolate-doom-2fd49a65afdcadbc09680552142c6f107715ebbc.tar.bz2 chocolate-doom-2fd49a65afdcadbc09680552142c6f107715ebbc.zip |
Add dropdown listbox widget
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 578
-rw-r--r-- | textscreen/Makefile.am | 1 | ||||
-rw-r--r-- | textscreen/textscreen.h | 1 | ||||
-rw-r--r-- | textscreen/txt_dropdown.c | 263 | ||||
-rw-r--r-- | textscreen/txt_dropdown.h | 49 |
4 files changed, 314 insertions, 0 deletions
diff --git a/textscreen/Makefile.am b/textscreen/Makefile.am index 899088fb..299e3b9d 100644 --- a/textscreen/Makefile.am +++ b/textscreen/Makefile.am @@ -11,6 +11,7 @@ libtextscreen_a_SOURCES = \ textscreen.h \ txt_checkbox.c txt_checkbox.h \ txt_desktop.c txt_desktop.h \ + txt_dropdown.c txt_dropdown.h \ txt_gui.c txt_gui.h \ txt_inputbox.c txt_inputbox.h \ txt_io.c txt_io.h \ diff --git a/textscreen/textscreen.h b/textscreen/textscreen.h index 06fb6c37..dd4bdd46 100644 --- a/textscreen/textscreen.h +++ b/textscreen/textscreen.h @@ -31,6 +31,7 @@ #include "txt_button.h" #include "txt_checkbox.h" #include "txt_desktop.h" +#include "txt_dropdown.h" #include "txt_inputbox.h" #include "txt_label.h" #include "txt_radiobutton.h" diff --git a/textscreen/txt_dropdown.c b/textscreen/txt_dropdown.c new file mode 100644 index 00000000..84fd3aca --- /dev/null +++ b/textscreen/txt_dropdown.c @@ -0,0 +1,263 @@ + +#include <stdlib.h> +#include <string.h> + +#include "doomkeys.h" + +#include "txt_button.h" +#include "txt_dropdown.h" +#include "txt_io.h" +#include "txt_main.h" +#include "txt_window.h" + +typedef struct +{ + txt_window_t *window; + txt_dropdown_list_t *list; + int item; +} callback_data_t; + +// Check if the selected value for a list is valid + +static int ValidSelection(txt_dropdown_list_t *list) +{ + return *list->variable >= 0 && *list->variable < list->num_values; +} + +// Calculate the Y position for the selector window + +static int SelectorWindowY(txt_dropdown_list_t *list) +{ + if (ValidSelection(list)) + { + return list->widget.y - 1 - *list->variable; + } + else + { + return list->widget.y - 1 - (list->num_values / 2); + } +} + +// Called when a button in the selector window is pressed + +static void ItemSelected(TXT_UNCAST_ARG(button), TXT_UNCAST_ARG(callback_data)) +{ + TXT_CAST_ARG(callback_data_t, callback_data); + + // Set the variable + + *callback_data->list->variable = callback_data->item; + + // Close the window + + TXT_CloseWindow(callback_data->window); +} + +// Free callback data when the window is closed + +static void FreeCallbackData(TXT_UNCAST_ARG(list), + TXT_UNCAST_ARG(callback_data)) +{ + TXT_CAST_ARG(callback_data_t, callback_data); + + free(callback_data); +} + +// Catch presses of escape and close the window. + +static int SelectorWindowListener(txt_window_t *window, int key, void *user_data) +{ + if (key == KEY_ESCAPE) + { + TXT_CloseWindow(window); + return 1; + } + + return 0; +} + +// Open the dropdown list window to select an item + +static void OpenSelectorWindow(txt_dropdown_list_t *list) +{ + txt_window_t *window; + int i; + + // Open a simple window with no title bar or action buttons. + + window = TXT_NewWindow(NULL); + + TXT_SetWindowAction(window, TXT_HORIZ_LEFT, NULL); + TXT_SetWindowAction(window, TXT_HORIZ_CENTER, NULL); + TXT_SetWindowAction(window, TXT_HORIZ_RIGHT, NULL); + + // Position the window so that the currently selected item appears + // over the top of the list widget. + + TXT_SetWindowPosition(window, TXT_HORIZ_LEFT, TXT_VERT_TOP, + list->widget.x - 2, SelectorWindowY(list)); + + // Add a button to the window for each option in the list. + + for (i=0; i<list->num_values; ++i) + { + txt_button_t *button; + callback_data_t *data; + + button = TXT_NewButton(list->values[i]); + + TXT_AddWidget(window, button); + + // Callback struct + + data = malloc(sizeof(callback_data_t)); + data->list = list; + data->window = window; + data->item = i; + + // When the button is pressed, invoke the button press callback + + TXT_SignalConnect(button, "pressed", ItemSelected, data); + + // When the window is closed, free back the callback struct + + TXT_SignalConnect(window, "closed", FreeCallbackData, data); + + // Is this the currently-selected value? If so, select the button + // in the window as the default. + + if (i == *list->variable) + { + TXT_SelectWidget(window, button); + } + } + + // Catch presses of escape in this window and close it. + + TXT_SetKeyListener(window, SelectorWindowListener, NULL); +} + +static int DropdownListWidth(txt_dropdown_list_t *list) +{ + int i; + int result; + + // Find the maximum string width + + result = 0; + + for (i=0; i<list->num_values; ++i) + { + int w = strlen(list->values[i]); + if (w > result) + { + result = w; + } + } + + return result; +} + +static void TXT_DropdownListSizeCalc(TXT_UNCAST_ARG(list)) +{ + TXT_CAST_ARG(txt_dropdown_list_t, list); + + list->widget.w = DropdownListWidth(list); + list->widget.h = 1; +} + +static void TXT_DropdownListDrawer(TXT_UNCAST_ARG(list), int selected) +{ + TXT_CAST_ARG(txt_dropdown_list_t, list); + int i; + char *str; + + // Set bg/fg text colors. + + if (selected) + { + TXT_BGColor(TXT_COLOR_GREY, 0); + } + else + { + TXT_BGColor(TXT_COLOR_BLUE, 0); + } + + TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); + + // Select a string to draw from the list, if the current value is + // in range. Otherwise fall back to a default. + + if (ValidSelection(list)) + { + str = list->values[*list->variable]; + } + else + { + str = "???"; + } + + // Draw the string and fill to the end with spaces + + TXT_DrawString(str); + + for (i=strlen(str); i<list->widget.w; ++i) + { + TXT_DrawString(" "); + } +} + +static void TXT_DropdownListDestructor(TXT_UNCAST_ARG(list)) +{ +} + +static int TXT_DropdownListKeyPress(TXT_UNCAST_ARG(list), int key) +{ + TXT_CAST_ARG(txt_dropdown_list_t, list); + + if (key == KEY_ENTER) + { + OpenSelectorWindow(list); + return 1; + } + + return 0; +} + +static void TXT_DropdownListMousePress(TXT_UNCAST_ARG(list), + int x, int y, int b) +{ + TXT_CAST_ARG(txt_dropdown_list_t, list); + + // Left mouse click does the same as selecting and pressing enter + + if (b == TXT_MOUSE_LEFT) + { + TXT_DropdownListKeyPress(list, KEY_ENTER); + } +} + +txt_widget_class_t txt_dropdown_list_class = +{ + TXT_DropdownListSizeCalc, + TXT_DropdownListDrawer, + TXT_DropdownListKeyPress, + TXT_DropdownListDestructor, + TXT_DropdownListMousePress, +}; + +txt_dropdown_list_t *TXT_NewDropdownList(int *variable, char **values, + int num_values) +{ + txt_dropdown_list_t *list; + + list = malloc(sizeof(txt_dropdown_list_t)); + + TXT_InitWidget(list, &txt_dropdown_list_class); + list->variable = variable; + list->values = values; + list->num_values = num_values; + + return list; +} + diff --git a/textscreen/txt_dropdown.h b/textscreen/txt_dropdown.h new file mode 100644 index 00000000..9539a879 --- /dev/null +++ b/textscreen/txt_dropdown.h @@ -0,0 +1,49 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id$ +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 2006 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +#ifndef TXT_DROPDOWN_H +#define TXT_DROPDOWN_H + +typedef struct txt_dropdown_list_s txt_dropdown_list_t; + +#include "txt_widget.h" + +// +// Drop-down list box. +// + +struct txt_dropdown_list_s +{ + txt_widget_t widget; + int *variable; + char **values; + int num_values; +}; + +txt_dropdown_list_t *TXT_NewDropdownList(int *variable, + char **values, int num_values); + +#endif /* #ifndef TXT_DROPDOWN_H */ + + |