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:
parent
a6be65e608
commit
39b7cb7bb2
4 changed files with 173 additions and 9 deletions
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in a new issue