Fix layout of widgets within scroll panes. Scroll scroll panes in

response to keyboard events.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1440
This commit is contained in:
Simon Howard 2009-01-30 23:53:47 +00:00
parent a6be65e608
commit 39b7cb7bb2
4 changed files with 173 additions and 9 deletions

View file

@ -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();

View file

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

View file

@ -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.

View file

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