diff options
author | Simon Howard | 2009-01-30 23:53:47 +0000 |
---|---|---|
committer | Simon Howard | 2009-01-30 23:53:47 +0000 |
commit | 39b7cb7bb2e14169af5dc07c7d429fc939200639 (patch) | |
tree | 3dec16991e926a3eeb448d22e156acec85b0347d | |
parent | a6be65e608b72b3e08ea66278e3972864c085495 (diff) | |
download | chocolate-doom-39b7cb7bb2e14169af5dc07c7d429fc939200639.tar.gz chocolate-doom-39b7cb7bb2e14169af5dc07c7d429fc939200639.tar.bz2 chocolate-doom-39b7cb7bb2e14169af5dc07c7d429fc939200639.zip |
Fix layout of widgets within scroll panes. Scroll scroll panes in
response to keyboard events.
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1440
-rw-r--r-- | textscreen/examples/guitest.c | 31 | ||||
-rw-r--r-- | textscreen/txt_scrollpane.c | 122 | ||||
-rw-r--r-- | textscreen/txt_table.c | 26 | ||||
-rw-r--r-- | textscreen/txt_table.h | 3 |
4 files changed, 173 insertions, 9 deletions
diff --git a/textscreen/examples/guitest.c b/textscreen/examples/guitest.c index 893974df..792e38cc 100644 --- a/textscreen/examples/guitest.c +++ b/textscreen/examples/guitest.c @@ -82,6 +82,7 @@ void SetupWindow(void) TXT_AddWidget(window, toplabel); TXT_SetWidgetAlign(toplabel, TXT_HORIZ_CENTER); + //TXT_AddWidget(window, TXT_NewScrollPane(15, 4, table)); TXT_AddWidget(window, table); for (i=0; i<5; ++i) @@ -174,6 +175,35 @@ void Window2(void) TXT_AddWidget(window, scrollpane); } +void ScrollingMenu(void) +{ + txt_window_t *window; + txt_button_t *button; + txt_table_t *table; + + window = TXT_NewWindow("Scrollable menu"); + + table = TXT_NewTable(1); + + TXT_AddWidgets(table, + TXT_NewButton("Configure display"), + TXT_NewButton("Configure joystick"), + TXT_NewButton("Configure keyboard"), + TXT_NewButton("Configure mouse"), + TXT_NewButton("Configure sound"), + TXT_NewStrut(0, 1), + button = TXT_NewButton("Save Parameters and launch DOOM"), + TXT_NewStrut(0, 1), + TXT_NewButton("Start a network game"), + TXT_NewButton("Join a network game"), + TXT_NewButton("Multiplayer configuration"), + NULL); + + TXT_SignalConnect(button, "pressed", PwnBox, NULL); + + TXT_AddWidget(window, TXT_NewScrollPane(0, 6, table)); +} + int main(int argc, char *argv[]) { if (!TXT_Init()) @@ -184,6 +214,7 @@ int main(int argc, char *argv[]) TXT_SetDesktopTitle("Not Chocolate Doom Setup"); + ScrollingMenu(); Window2(); SetupWindow(); diff --git a/textscreen/txt_scrollpane.c b/textscreen/txt_scrollpane.c index cfed6a3e..e9989f19 100644 --- a/textscreen/txt_scrollpane.c +++ b/textscreen/txt_scrollpane.c @@ -29,6 +29,9 @@ #include "txt_gui.h" #include "txt_io.h" #include "txt_main.h" +#include "txt_table.h" + +#include "doomkeys.h" #define SCROLLBAR_VERTICAL (1 << 0) #define SCROLLBAR_HORIZONTAL (1 << 1) @@ -214,18 +217,120 @@ static void TXT_ScrollPaneDestructor(TXT_UNCAST_ARG(scrollpane)) } } +// Hack for tables - when browsing a table inside a scroll pane, +// automatically scroll the window to show the newly-selected +// item. + +static void ShowSelectedWidget(txt_scrollpane_t *scrollpane) +{ + txt_widget_t *selected; + + selected = TXT_GetSelectedWidget(scrollpane->child); + + // Scroll up or down? + + if (selected->y <= scrollpane->widget.y) + { + scrollpane->y -= scrollpane->widget.y - selected->y; + } + else if (selected->y + selected->h > + scrollpane->widget.y + scrollpane->h) + { + scrollpane->y += (selected->y + selected->h) + - (scrollpane->widget.y + scrollpane->h); + } + + // Scroll left or right? + + if (selected->x <= scrollpane->widget.x) + { + scrollpane->x -= scrollpane->widget.x - selected->x; + } + else if (selected->x + selected->w > + scrollpane->widget.x + scrollpane->w) + { + scrollpane->x += (selected->x + selected->w) + - (scrollpane->widget.x + scrollpane->w); + } +} + +// Interpret arrow key presses as scroll commands + +static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key) +{ + switch (key) + { + case KEY_UPARROW: + if (scrollpane->y > 0) + { + --scrollpane->y; + return 1; + } + break; + + case KEY_DOWNARROW: + if (scrollpane->y < FullHeight(scrollpane) - scrollpane->h) + { + ++scrollpane->y; + return 1; + } + break; + + case KEY_LEFTARROW: + if (scrollpane->x > 0) + { + --scrollpane->x; + return 1; + } + break; + + case KEY_RIGHTARROW: + if (scrollpane->x < FullWidth(scrollpane) - scrollpane->w) + { + ++scrollpane->x; + return 1; + } + break; + + default: + break; + } + + return 0; +} + static int TXT_ScrollPaneKeyPress(TXT_UNCAST_ARG(scrollpane), int key) { TXT_CAST_ARG(txt_scrollpane_t, scrollpane); + int result; + + result = 0; if (scrollpane->child != NULL) { - return TXT_WidgetKeyPress(scrollpane->child, key); - } - else - { - return 0; + result = TXT_WidgetKeyPress(scrollpane->child, key); + + // Gross hack - if we're scrolling in a menu with the keyboard, + // automatically move the scroll pane to show the new + // selected item. + + if (scrollpane->child->widget_class == &txt_table_class + && (key == KEY_UPARROW || key == KEY_DOWNARROW + || key == KEY_LEFTARROW || key == KEY_RIGHTARROW)) + { + ShowSelectedWidget(scrollpane); + } + + // If the child widget didn't use the keypress, we can see + // if it can be interpreted as a scrolling command. + + if (result == 0) + { + result = InterpretScrollKey(scrollpane, key); + } } + + return result; } static void TXT_ScrollPaneMousePress(TXT_UNCAST_ARG(scrollpane), @@ -284,10 +389,7 @@ static void TXT_ScrollPaneMousePress(TXT_UNCAST_ARG(scrollpane), if (scrollpane->child != NULL) { - TXT_WidgetMousePress(scrollpane->child, - x - scrollpane->x, - y - scrollpane->y, - b); + TXT_WidgetMousePress(scrollpane->child, x, y, b); } } @@ -305,6 +407,8 @@ static void TXT_ScrollPaneLayout(TXT_UNCAST_ARG(scrollpane)) { scrollpane->child->x = scrollpane->widget.x - scrollpane->x; scrollpane->child->y = scrollpane->widget.y - scrollpane->y; + + TXT_LayoutWidget(scrollpane->child); } } diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c index 29798906..0d4d1e35 100644 --- a/textscreen/txt_table.c +++ b/textscreen/txt_table.c @@ -674,6 +674,32 @@ txt_table_t *TXT_NewHorizBox(TXT_UNCAST_ARG(first_widget), ...) return result; } +// Get the currently-selected widget in a table, recursively searching +// through sub-tables if necessary. + +txt_widget_t *TXT_GetSelectedWidget(TXT_UNCAST_ARG(table)) +{ + TXT_CAST_ARG(txt_table_t, table); + txt_widget_t *result; + int index; + + index = table->selected_y * table->columns + table->selected_x; + + result = NULL; + + if (index >= 0 && index < table->num_widgets) + { + result = table->widgets[index]; + } + + if (result != NULL && result->widget_class == &txt_table_class) + { + result = TXT_GetSelectedWidget(result); + } + + return result; +} + // Selects a given widget in a table, recursively searching any tables // within this table. Returns 1 if successful, 0 if unsuccessful. diff --git a/textscreen/txt_table.h b/textscreen/txt_table.h index d42e9adb..dee6f4bb 100644 --- a/textscreen/txt_table.h +++ b/textscreen/txt_table.h @@ -46,9 +46,12 @@ struct txt_table_s int selected_y; }; +extern txt_widget_class_t txt_table_class; + txt_table_t *TXT_NewTable(int columns); txt_table_t *TXT_NewHorizBox(TXT_UNCAST_ARG(first_widget), ...); void TXT_InitTable(txt_table_t *table, int columns); +txt_widget_t *TXT_GetSelectedWidget(TXT_UNCAST_ARG(table)); void TXT_AddWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)); void TXT_AddWidgets(TXT_UNCAST_ARG(table), ...); int TXT_SelectWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)); |