Add a signals architecture to allow callbacks on GUI events.
Make all widget classes initialise widgets by calling TXT_InitWidget. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 501
This commit is contained in:
parent
d90a63ed26
commit
283f71d0f5
9 changed files with 138 additions and 18 deletions
|
|
@ -22,16 +22,23 @@ int radiobutton_value;
|
|||
txt_window_t *firstwin;
|
||||
int checkbox_value;
|
||||
|
||||
void CloseWindow(txt_widget_t *widget, void *user_data)
|
||||
{
|
||||
TXT_CloseWindow(firstwin);
|
||||
}
|
||||
|
||||
void SetupWindow(void)
|
||||
{
|
||||
txt_window_t *window;
|
||||
txt_table_t *table;
|
||||
txt_table_t *leftpane, *rightpane;
|
||||
txt_button_t *button;
|
||||
char buf[100];
|
||||
int i;
|
||||
|
||||
window = TXT_NewWindow("Window test");
|
||||
|
||||
TXT_AddWidget(window, TXT_NewSeparator("Main section"));
|
||||
table = TXT_NewTable(3);
|
||||
|
||||
TXT_AddWidget(window, TXT_NewLabel(" This is a multiline label.\n"
|
||||
|
|
@ -66,6 +73,11 @@ void SetupWindow(void)
|
|||
TXT_AddWidget(rightpane, TXT_NewRadioButton("Snake", &radiobutton_value,
|
||||
RADIO_VALUE_SNAKE));
|
||||
|
||||
button = TXT_NewButton("Close Window");
|
||||
TXT_AddWidget(window, button);
|
||||
|
||||
TXT_SignalConnect(button, "pressed", CloseWindow, NULL);
|
||||
|
||||
firstwin = window;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "doomkeys.h"
|
||||
|
||||
#include "txt_button.h"
|
||||
#include "txt_io.h"
|
||||
#include "txt_main.h"
|
||||
|
|
@ -44,11 +46,15 @@ static void TXT_ButtonDestructor(txt_widget_t *widget)
|
|||
txt_button_t *button = (txt_button_t *) widget;
|
||||
|
||||
free(button->label);
|
||||
free(button);
|
||||
}
|
||||
|
||||
static int TXT_ButtonKeyPress(txt_widget_t *widget, int key)
|
||||
{
|
||||
if (key == KEY_ENTER)
|
||||
{
|
||||
TXT_EmitSignal(widget, "pressed");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -66,9 +72,7 @@ txt_button_t *TXT_NewButton(char *label)
|
|||
|
||||
button = malloc(sizeof(txt_button_t));
|
||||
|
||||
button->widget.widget_class = &txt_button_class;
|
||||
button->widget.selectable = 1;
|
||||
button->widget.visible = 1;
|
||||
TXT_InitWidget(button, &txt_button_class);
|
||||
button->label = strdup(label);
|
||||
|
||||
return button;
|
||||
|
|
|
|||
|
|
@ -91,9 +91,7 @@ txt_checkbox_t *TXT_NewCheckBox(char *label, int *variable)
|
|||
|
||||
checkbox = malloc(sizeof(txt_checkbox_t));
|
||||
|
||||
checkbox->widget.widget_class = &txt_checkbox_class;
|
||||
checkbox->widget.selectable = 1;
|
||||
checkbox->widget.visible = 1;
|
||||
TXT_InitWidget(checkbox, &txt_checkbox_class);
|
||||
checkbox->label = strdup(label);
|
||||
checkbox->variable = variable;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ static void TXT_LabelDestructor(txt_widget_t *widget)
|
|||
|
||||
free(label->label);
|
||||
free(label->lines);
|
||||
free(label);
|
||||
}
|
||||
|
||||
txt_widget_class_t txt_label_class =
|
||||
|
|
@ -98,9 +97,8 @@ txt_label_t *TXT_NewLabel(char *text)
|
|||
|
||||
label = malloc(sizeof(txt_label_t));
|
||||
|
||||
label->widget.widget_class = &txt_label_class;
|
||||
TXT_InitWidget(label, &txt_label_class);
|
||||
label->widget.selectable = 0;
|
||||
label->widget.visible = 1;
|
||||
label->label = strdup(text);
|
||||
|
||||
TXT_SplitLabel(label);
|
||||
|
|
|
|||
|
|
@ -91,9 +91,7 @@ txt_radiobutton_t *TXT_NewRadioButton(char *label, int *variable, int value)
|
|||
|
||||
radiobutton = malloc(sizeof(txt_radiobutton_t));
|
||||
|
||||
radiobutton->widget.widget_class = &txt_radiobutton_class;
|
||||
radiobutton->widget.selectable = 1;
|
||||
radiobutton->widget.visible = 1;
|
||||
TXT_InitWidget(radiobutton, &txt_radiobutton_class);
|
||||
radiobutton->label = strdup(label);
|
||||
radiobutton->variable = variable;
|
||||
radiobutton->value = value;
|
||||
|
|
|
|||
|
|
@ -71,9 +71,8 @@ txt_separator_t *TXT_NewSeparator(char *label)
|
|||
|
||||
separator = malloc(sizeof(txt_separator_t));
|
||||
|
||||
separator->widget.widget_class = &txt_separator_class;
|
||||
TXT_InitWidget(separator, &txt_separator_class);
|
||||
separator->widget.selectable = 0;
|
||||
separator->widget.visible = 1;
|
||||
|
||||
if (label != NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -408,12 +408,10 @@ txt_widget_class_t txt_table_class =
|
|||
|
||||
void TXT_InitTable(txt_table_t *table, int columns)
|
||||
{
|
||||
TXT_InitWidget(table, &txt_table_class);
|
||||
table->columns = columns;
|
||||
table->widgets = NULL;
|
||||
table->num_widgets = 0;
|
||||
table->widget.widget_class = &txt_table_class;
|
||||
table->widget.visible = 1;
|
||||
table->widget.selectable = 1;
|
||||
table->selected_x = 0;
|
||||
table->selected_y = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,111 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "txt_widget.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *signal_name;
|
||||
TxtWidgetSignalFunc func;
|
||||
void *user_data;
|
||||
} txt_callback_t;
|
||||
|
||||
struct txt_callback_table_s
|
||||
{
|
||||
txt_callback_t *callbacks;
|
||||
int num_callbacks;
|
||||
};
|
||||
|
||||
txt_callback_table_t *TXT_NewCallbackTable(void)
|
||||
{
|
||||
txt_callback_table_t *table;
|
||||
|
||||
table = malloc(sizeof(txt_callback_table_t));
|
||||
table->callbacks = NULL;
|
||||
table->num_callbacks = 0;
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
void TXT_DestroyCallbackTable(txt_callback_table_t *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<table->num_callbacks; ++i)
|
||||
{
|
||||
free(table->callbacks[i].signal_name);
|
||||
}
|
||||
|
||||
free(table->callbacks);
|
||||
free(table);
|
||||
}
|
||||
|
||||
void TXT_InitWidget(void *uncast_widget, txt_widget_class_t *widget_class)
|
||||
{
|
||||
txt_widget_t *widget = (txt_widget_t *) uncast_widget;
|
||||
|
||||
widget->widget_class = widget_class;
|
||||
widget->callback_table = TXT_NewCallbackTable();
|
||||
|
||||
// Default values: visible and selectable
|
||||
|
||||
widget->selectable = 1;
|
||||
widget->visible = 1;
|
||||
}
|
||||
|
||||
void TXT_SignalConnect(txt_widget_t *widget,
|
||||
char *signal_name,
|
||||
TxtWidgetSignalFunc func,
|
||||
void *user_data)
|
||||
{
|
||||
txt_callback_table_t *table;
|
||||
txt_callback_t *callback;
|
||||
int i;
|
||||
|
||||
table = widget->callback_table;
|
||||
|
||||
for (i=0; i<table->num_callbacks; ++i)
|
||||
{
|
||||
if (!strcmp(signal_name, table->callbacks[i].signal_name))
|
||||
{
|
||||
// Replace existing signal
|
||||
|
||||
table->callbacks[i].func = func;
|
||||
table->callbacks[i].user_data = user_data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new callback to the table
|
||||
|
||||
table->callbacks
|
||||
= realloc(table->callbacks,
|
||||
sizeof(txt_callback_t) * (table->num_callbacks + 1));
|
||||
callback = &table->callbacks[table->num_callbacks];
|
||||
++table->num_callbacks;
|
||||
|
||||
callback->signal_name = strdup(signal_name);
|
||||
callback->func = func;
|
||||
callback->user_data = user_data;
|
||||
}
|
||||
|
||||
void TXT_EmitSignal(txt_widget_t *widget, char *signal_name)
|
||||
{
|
||||
txt_callback_table_t *table;
|
||||
int i;
|
||||
|
||||
table = widget->callback_table;
|
||||
|
||||
for (i=0; i<table->num_callbacks; ++i)
|
||||
{
|
||||
if (!strcmp(table->callbacks[i].signal_name, signal_name))
|
||||
{
|
||||
table->callbacks[i].func(widget, table->callbacks[i].user_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TXT_CalcWidgetSize(txt_widget_t *widget, int *w, int *h)
|
||||
{
|
||||
return widget->widget_class->size_calc(widget, w, h);
|
||||
|
|
@ -15,6 +119,8 @@ void TXT_DrawWidget(txt_widget_t *widget, int w, int selected)
|
|||
void TXT_DestroyWidget(txt_widget_t *widget)
|
||||
{
|
||||
widget->widget_class->destructor(widget);
|
||||
TXT_DestroyCallbackTable(widget->callback_table);
|
||||
free(widget);
|
||||
}
|
||||
|
||||
int TXT_WidgetKeyPress(txt_widget_t *widget, int key)
|
||||
|
|
|
|||
|
|
@ -29,11 +29,13 @@
|
|||
|
||||
typedef struct txt_widget_class_s txt_widget_class_t;
|
||||
typedef struct txt_widget_s txt_widget_t;
|
||||
typedef struct txt_callback_table_s txt_callback_table_t;
|
||||
|
||||
typedef void (*TxtWidgetSizeCalc)(txt_widget_t *widget, int *w, int *h);
|
||||
typedef void (*TxtWidgetDrawer)(txt_widget_t *widget, int w, int selected);
|
||||
typedef void (*TxtWidgetDestroy)(txt_widget_t *widget);
|
||||
typedef int (*TxtWidgetKeyPress)(txt_widget_t *widget, int key);
|
||||
typedef void (*TxtWidgetSignalFunc)(txt_widget_t *widget, void *user_data);
|
||||
|
||||
struct txt_widget_class_s
|
||||
{
|
||||
|
|
@ -46,12 +48,17 @@ struct txt_widget_class_s
|
|||
struct txt_widget_s
|
||||
{
|
||||
txt_widget_class_t *widget_class;
|
||||
txt_callback_table_t *callback_table;
|
||||
int selectable;
|
||||
int visible;
|
||||
};
|
||||
|
||||
void TXT_InitWidget(void *widget, txt_widget_class_t *widget_class);
|
||||
void TXT_CalcWidgetSize(txt_widget_t *widget, int *w, int *h);
|
||||
void TXT_DrawWidget(txt_widget_t *widget, int w, int selected);
|
||||
void TXT_SignalConnect(txt_widget_t *widget, char *signal_name,
|
||||
TxtWidgetSignalFunc func, void *user_data);
|
||||
void TXT_EmitSignal(txt_widget_t *widget, char *signal_name);
|
||||
int TXT_WidgetKeyPress(txt_widget_t *widget, int key);
|
||||
void TXT_DestroyWidget(txt_widget_t *widget);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue