summaryrefslogtreecommitdiff
path: root/textscreen
diff options
context:
space:
mode:
authorSimon Howard2006-05-22 00:20:48 +0000
committerSimon Howard2006-05-22 00:20:48 +0000
commit283f71d0f500541b6273316120e252b03f22fb03 (patch)
tree7a46a0b56e025a70872f54b5e97d6d7773e5144e /textscreen
parentd90a63ed267516f8d35b4d8399dbcb5e52a1e692 (diff)
downloadchocolate-doom-283f71d0f500541b6273316120e252b03f22fb03.tar.gz
chocolate-doom-283f71d0f500541b6273316120e252b03f22fb03.tar.bz2
chocolate-doom-283f71d0f500541b6273316120e252b03f22fb03.zip
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
Diffstat (limited to 'textscreen')
-rw-r--r--textscreen/guitest.c12
-rw-r--r--textscreen/txt_button.c12
-rw-r--r--textscreen/txt_checkbox.c4
-rw-r--r--textscreen/txt_label.c4
-rw-r--r--textscreen/txt_radiobutton.c4
-rw-r--r--textscreen/txt_separator.c3
-rw-r--r--textscreen/txt_table.c4
-rw-r--r--textscreen/txt_widget.c106
-rw-r--r--textscreen/txt_widget.h7
9 files changed, 138 insertions, 18 deletions
diff --git a/textscreen/guitest.c b/textscreen/guitest.c
index 27e23b00..2f8c3733 100644
--- a/textscreen/guitest.c
+++ b/textscreen/guitest.c
@@ -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;
}
diff --git a/textscreen/txt_button.c b/textscreen/txt_button.c
index b7ae1765..e20f462d 100644
--- a/textscreen/txt_button.c
+++ b/textscreen/txt_button.c
@@ -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;
diff --git a/textscreen/txt_checkbox.c b/textscreen/txt_checkbox.c
index b413874e..f33781c1 100644
--- a/textscreen/txt_checkbox.c
+++ b/textscreen/txt_checkbox.c
@@ -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;
diff --git a/textscreen/txt_label.c b/textscreen/txt_label.c
index 0534f10a..afdf9b01 100644
--- a/textscreen/txt_label.c
+++ b/textscreen/txt_label.c
@@ -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);
diff --git a/textscreen/txt_radiobutton.c b/textscreen/txt_radiobutton.c
index 80911a46..45412f28 100644
--- a/textscreen/txt_radiobutton.c
+++ b/textscreen/txt_radiobutton.c
@@ -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;
diff --git a/textscreen/txt_separator.c b/textscreen/txt_separator.c
index 2013edac..038fa19b 100644
--- a/textscreen/txt_separator.c
+++ b/textscreen/txt_separator.c
@@ -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)
{
diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c
index 5ae9ee62..4e2d1f96 100644
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -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;
}
diff --git a/textscreen/txt_widget.c b/textscreen/txt_widget.c
index c10699b5..d257ee75 100644
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -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)
diff --git a/textscreen/txt_widget.h b/textscreen/txt_widget.h
index d852ccd1..a166791a 100644
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -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);