summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--textscreen/txt_button.c11
-rw-r--r--textscreen/txt_checkbox.c11
-rw-r--r--textscreen/txt_gui.c49
-rw-r--r--textscreen/txt_inputbox.c11
-rw-r--r--textscreen/txt_label.c11
-rw-r--r--textscreen/txt_main.c10
-rw-r--r--textscreen/txt_main.h6
-rw-r--r--textscreen/txt_radiobutton.c11
-rw-r--r--textscreen/txt_separator.c13
-rw-r--r--textscreen/txt_strut.c8
-rw-r--r--textscreen/txt_table.c150
-rw-r--r--textscreen/txt_widget.c33
-rw-r--r--textscreen/txt_widget.h20
-rw-r--r--textscreen/txt_window.c209
-rw-r--r--textscreen/txt_window.h5
-rw-r--r--textscreen/txt_window_action.c9
16 files changed, 404 insertions, 163 deletions
diff --git a/textscreen/txt_button.c b/textscreen/txt_button.c
index 53021a75..8b8e704b 100644
--- a/textscreen/txt_button.c
+++ b/textscreen/txt_button.c
@@ -9,20 +9,23 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_ButtonSizeCalc(TXT_UNCAST_ARG(button), int *w, int *h)
+static void TXT_ButtonSizeCalc(TXT_UNCAST_ARG(button))
{
TXT_CAST_ARG(txt_button_t, button);
// Minimum width is the string length + two spaces for padding
- *w = strlen(button->label) + 2;
- *h = 1;
+ button->widget.w = strlen(button->label) + 2;
+ button->widget.h = 1;
}
-static void TXT_ButtonDrawer(TXT_UNCAST_ARG(button), int w, int selected)
+static void TXT_ButtonDrawer(TXT_UNCAST_ARG(button), int selected)
{
TXT_CAST_ARG(txt_button_t, button);
int i;
+ int w;
+
+ w = button->widget.w;
TXT_BGColor(TXT_COLOR_BLUE, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
diff --git a/textscreen/txt_checkbox.c b/textscreen/txt_checkbox.c
index 4419c4b3..d32a240c 100644
--- a/textscreen/txt_checkbox.c
+++ b/textscreen/txt_checkbox.c
@@ -9,20 +9,23 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_CheckBoxSizeCalc(TXT_UNCAST_ARG(checkbox), int *w, int *h)
+static void TXT_CheckBoxSizeCalc(TXT_UNCAST_ARG(checkbox))
{
TXT_CAST_ARG(txt_checkbox_t, checkbox);
// Minimum width is the string length + two spaces for padding
- *w = strlen(checkbox->label) + 6;
- *h = 1;
+ checkbox->widget.w = strlen(checkbox->label) + 6;
+ checkbox->widget.h = 1;
}
-static void TXT_CheckBoxDrawer(TXT_UNCAST_ARG(checkbox), int w, int selected)
+static void TXT_CheckBoxDrawer(TXT_UNCAST_ARG(checkbox), int selected)
{
TXT_CAST_ARG(txt_checkbox_t, checkbox);
int i;
+ int w;
+
+ w = checkbox->widget.w;
TXT_BGColor(TXT_COLOR_BLUE, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
diff --git a/textscreen/txt_gui.c b/textscreen/txt_gui.c
index 2c58cb9f..9de66627 100644
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: txt_gui.c 487 2006-05-20 15:45:36Z fraggle $
+// $Id: txt_gui.c 547 2006-06-02 19:29:24Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@@ -140,7 +140,7 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h)
// draw a box around the title.
by = y1 == y ? 0 :
- y1 == y + 2 ? 2 :
+ y1 == y + 2 && title != NULL ? 2 :
y1 == y + h - 1 ? 3 : 1;
for (x1=x; x1<x+w; ++x1)
@@ -158,17 +158,20 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h)
// Draw the title
- TXT_GotoXY(x + 1, y + 1);
- TXT_BGColor(TXT_COLOR_GREY, 0);
- TXT_FGColor(TXT_COLOR_BLUE);
-
- for (x1=0; x1<w-2; ++x1)
+ if (title != NULL)
{
- TXT_DrawString(" ");
- }
+ TXT_GotoXY(x + 1, y + 1);
+ TXT_BGColor(TXT_COLOR_GREY, 0);
+ TXT_FGColor(TXT_COLOR_BLUE);
- TXT_GotoXY(x + (w - strlen(title)) / 2, y + 1);
- TXT_DrawString(title);
+ for (x1=0; x1<w-2; ++x1)
+ {
+ TXT_DrawString(" ");
+ }
+
+ TXT_GotoXY(x + (w - strlen(title)) / 2, y + 1);
+ TXT_DrawString(title);
+ }
// Draw the window's shadow.
@@ -178,8 +181,11 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h)
void TXT_DrawSeparator(int x, int y, int w)
{
+ unsigned char *data;
int x1;
- int c;
+ int b;
+
+ data = TXT_GetScreenData();
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
TXT_BGColor(TXT_COLOR_BLUE, 0);
@@ -189,18 +195,29 @@ void TXT_DrawSeparator(int x, int y, int w)
return;
}
+ data += (y * TXT_SCREEN_W + x) * 2;
+
for (x1=x; x1<x+w; ++x1)
{
TXT_GotoXY(x1, y);
- c = x1 == x ? borders[2][0] :
- x1 == x + w - 1 ? borders[2][3] :
- borders[2][1];
+ b = x1 == x ? 0 :
+ x1 == x + w - 1 ? 3 :
+ 1;
if (VALID_X(x1))
{
- TXT_PutChar(c);
+ // Read the current value from the screen
+ // Check that it matches what the window should look like if
+ // there is no separator, then apply the separator
+
+ if (*data == borders[1][b])
+ {
+ TXT_PutChar(borders[2][b]);
+ }
}
+
+ data += 2;
}
}
diff --git a/textscreen/txt_inputbox.c b/textscreen/txt_inputbox.c
index 11029e4b..cb7bf4fa 100644
--- a/textscreen/txt_inputbox.c
+++ b/textscreen/txt_inputbox.c
@@ -12,21 +12,24 @@
static void SetBufferFromValue(txt_inputbox_t *inputbox);
-static void TXT_InputBoxSizeCalc(TXT_UNCAST_ARG(inputbox), int *w, int *h)
+static void TXT_InputBoxSizeCalc(TXT_UNCAST_ARG(inputbox))
{
TXT_CAST_ARG(txt_inputbox_t, inputbox);
// Enough space for the box + cursor
- *w = inputbox->size + 1;
- *h = 1;
+ inputbox->widget.w = inputbox->size + 1;
+ inputbox->widget.h = 1;
}
-static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox), int w, int selected)
+static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox), int selected)
{
TXT_CAST_ARG(txt_inputbox_t, inputbox);
int i;
int chars;
+ int w;
+
+ w = inputbox->widget.w;
// Select the background colour based on whether we are currently
// editing, and if not, whether the widget is selected.
diff --git a/textscreen/txt_label.c b/textscreen/txt_label.c
index f92eba82..cff3bb69 100644
--- a/textscreen/txt_label.c
+++ b/textscreen/txt_label.c
@@ -7,20 +7,23 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_LabelSizeCalc(TXT_UNCAST_ARG(label), int *w, int *h)
+static void TXT_LabelSizeCalc(TXT_UNCAST_ARG(label))
{
TXT_CAST_ARG(txt_label_t, label);
- *w = label->w;
- *h = label->h;
+ label->widget.w = label->w;
+ label->widget.h = label->h;
}
-static void TXT_LabelDrawer(TXT_UNCAST_ARG(label), int w, int selected)
+static void TXT_LabelDrawer(TXT_UNCAST_ARG(label), int selected)
{
TXT_CAST_ARG(txt_label_t, label);
int x, y;
int origin_x, origin_y;
int align_indent;
+ int w;
+
+ w = label->widget.w;
TXT_BGColor(label->bgcolor, 0);
TXT_FGColor(label->fgcolor);
diff --git a/textscreen/txt_main.c b/textscreen/txt_main.c
index ad766c61..9e9f4231 100644
--- a/textscreen/txt_main.c
+++ b/textscreen/txt_main.c
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: txt_main.c 533 2006-05-26 19:15:05Z fraggle $
+// $Id: txt_main.c 547 2006-06-02 19:29:24Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@@ -185,6 +185,14 @@ void TXT_UpdateScreen(void)
TXT_UpdateScreenArea(0, 0, TXT_SCREEN_W, TXT_SCREEN_H);
}
+void TXT_GetMousePosition(int *x, int *y)
+{
+ SDL_GetMouseState(x, y);
+
+ *x /= CHAR_W;
+ *y /= CHAR_H;
+}
+
//
// Translates the SDL key
//
diff --git a/textscreen/txt_main.h b/textscreen/txt_main.h
index 5a4b8a1c..43c5475b 100644
--- a/textscreen/txt_main.h
+++ b/textscreen/txt_main.h
@@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
-// $Id: txt_main.h 513 2006-05-23 00:04:27Z fraggle $
+// $Id: txt_main.h 547 2006-06-02 19:29:24Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@@ -101,5 +101,9 @@ int TXT_GetChar(void);
void TXT_GetKeyDescription(int key, char *buf);
+// Retrieve the current position of the mouse
+
+void TXT_GetMouseState(int *x, int *y);
+
#endif /* #ifndef TXT_MAIN_H */
diff --git a/textscreen/txt_radiobutton.c b/textscreen/txt_radiobutton.c
index e221896e..d5f694f7 100644
--- a/textscreen/txt_radiobutton.c
+++ b/textscreen/txt_radiobutton.c
@@ -9,20 +9,23 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_RadioButtonSizeCalc(TXT_UNCAST_ARG(radiobutton), int *w, int *h)
+static void TXT_RadioButtonSizeCalc(TXT_UNCAST_ARG(radiobutton))
{
TXT_CAST_ARG(txt_radiobutton_t, radiobutton);
// Minimum width is the string length + two spaces for padding
- *w = strlen(radiobutton->label) + 6;
- *h = 1;
+ radiobutton->widget.w = strlen(radiobutton->label) + 6;
+ radiobutton->widget.h = 1;
}
-static void TXT_RadioButtonDrawer(TXT_UNCAST_ARG(radiobutton), int w, int selected)
+static void TXT_RadioButtonDrawer(TXT_UNCAST_ARG(radiobutton), int selected)
{
TXT_CAST_ARG(txt_radiobutton_t, radiobutton);
int i;
+ int w;
+
+ w = radiobutton->widget.w;
TXT_BGColor(TXT_COLOR_BLUE, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
diff --git a/textscreen/txt_separator.c b/textscreen/txt_separator.c
index 3258c400..1cba708e 100644
--- a/textscreen/txt_separator.c
+++ b/textscreen/txt_separator.c
@@ -7,7 +7,7 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator), int *w, int *h)
+static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator))
{
TXT_CAST_ARG(txt_separator_t, separator);
@@ -15,21 +15,24 @@ static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator), int *w, int *h)
{
// Minimum width is the string length + two spaces for padding
- *w = strlen(separator->label) + 2;
+ separator->widget.w = strlen(separator->label) + 2;
}
else
{
- *w = 0;
+ separator->widget.w = 0;
}
- *h = 1;
+ separator->widget.h = 1;
}
-static void TXT_SeparatorDrawer(TXT_UNCAST_ARG(separator), int w, int selected)
+static void TXT_SeparatorDrawer(TXT_UNCAST_ARG(separator), int selected)
{
TXT_CAST_ARG(txt_separator_t, separator);
int i;
int x, y;
+ int w;
+
+ w = separator->widget.w;
TXT_GetXY(&x, &y);
diff --git a/textscreen/txt_strut.c b/textscreen/txt_strut.c
index 0d827b5a..0a0b402b 100644
--- a/textscreen/txt_strut.c
+++ b/textscreen/txt_strut.c
@@ -9,17 +9,17 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_StrutSizeCalc(TXT_UNCAST_ARG(strut), int *w, int *h)
+static void TXT_StrutSizeCalc(TXT_UNCAST_ARG(strut))
{
TXT_CAST_ARG(txt_strut_t, strut);
// Minimum width is the string length + two spaces for padding
- *w = strut->width;
- *h = strut->height;
+ strut->widget.w = strut->width;
+ strut->widget.h = strut->height;
}
-static void TXT_StrutDrawer(TXT_UNCAST_ARG(strut), int w, int selected)
+static void TXT_StrutDrawer(TXT_UNCAST_ARG(strut), int selected)
{
// Nothing is drawn for a strut.
}
diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c
index e410d4df..86aea997 100644
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -65,7 +65,6 @@ static void CalcRowColSizes(txt_table_t *table,
int table_height;
int x, y;
int rows;
- int ww, wh;
txt_widget_t *widget;
rows = TableRows(table);
@@ -83,27 +82,21 @@ static void CalcRowColSizes(txt_table_t *table,
widget = table->widgets[y * table->columns + x];
+ // NULL represents an empty spacer
+
if (widget != NULL)
{
- TXT_CalcWidgetSize(widget, &ww, &wh);
- }
- else
- {
- // Empty spacer if widget is NULL
-
- ww = 0;
- wh = 0;
+ TXT_CalcWidgetSize(widget);
+ if (widget->h > row_heights[y])
+ row_heights[y] = widget->h;
+ if (widget->w > col_widths[x])
+ col_widths[x] = widget->w;
}
-
- if (wh > row_heights[y])
- row_heights[y] = wh;
- if (ww > col_widths[x])
- col_widths[x] = ww;
}
}
}
-static void TXT_CalcTableSize(TXT_UNCAST_ARG(table), int *w, int *h)
+static void TXT_CalcTableSize(TXT_UNCAST_ARG(table))
{
TXT_CAST_ARG(txt_table_t, table);
int *column_widths;
@@ -118,18 +111,18 @@ static void TXT_CalcTableSize(TXT_UNCAST_ARG(table), int *w, int *h)
CalcRowColSizes(table, row_heights, column_widths);
- *w = 0;
+ table->widget.w = 0;
for (x=0; x<table->columns; ++x)
{
- *w += column_widths[x];
+ table->widget.w += column_widths[x];
}
- *h = 0;
+ table->widget.h = 0;
for (y=0; y<rows; ++y)
{
- *h += row_heights[y];
+ table->widget.h += row_heights[y];
}
free(row_heights);
@@ -354,68 +347,64 @@ static void CheckValidSelection(txt_table_t *table)
}
}
-static void DrawCell(txt_table_t *table, int x, int y,
- int draw_x, int draw_y, int w, int selected)
+static void LayoutCell(txt_table_t *table, int x, int y, int col_width,
+ int draw_x, int draw_y)
{
txt_widget_t *widget;
- int cw, ch;
widget = table->widgets[y * table->columns + x];
+ // Adjust x position based on alignment property
+
switch (widget->align)
{
case TXT_HORIZ_LEFT:
+ widget->w = col_width;
break;
case TXT_HORIZ_CENTER:
- TXT_CalcWidgetSize(widget, &cw, &ch);
+ TXT_CalcWidgetSize(widget);
// Separators are always drawn left-aligned.
if (widget->widget_class != &txt_separator_class)
{
- draw_x += (w - cw) / 2;
- w = cw;
+ draw_x += (col_width - widget->w) / 2;
}
break;
case TXT_HORIZ_RIGHT:
- TXT_CalcWidgetSize(widget, &cw, &ch);
+ TXT_CalcWidgetSize(widget);
if (widget->widget_class != &txt_separator_class)
{
- draw_x += w - cw;
- w = cw;
+ draw_x += col_width - widget->w;
}
break;
}
- TXT_GotoXY(draw_x, draw_y);
+ // Set the position for this widget
+
+ widget->x = draw_x;
+ widget->y = draw_y;
+
+ // Recursively lay out any widgets contained in the widget
- TXT_DrawWidget(widget, w, selected && x == table->selected_x
- && y == table->selected_y);
+ TXT_LayoutWidget(widget);
}
-static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected)
+static void TXT_TableLayout(TXT_UNCAST_ARG(table))
{
TXT_CAST_ARG(txt_table_t, table);
int *column_widths;
int *row_heights;
- int origin_x, origin_y;
int draw_x, draw_y;
int x, y;
int i;
int rows;
- // Check the table's current selection points at something valid before
- // drawing.
-
- CheckValidSelection(table);
-
- TXT_GetXY(&origin_x, &origin_y);
-
// Work out the column widths and row heights
rows = TableRows(table);
@@ -431,16 +420,16 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected)
if (table->columns == 1)
{
- column_widths[0] = w;
+ column_widths[0] = table->widget.w;
}
// Draw all cells
- draw_y = origin_y;
+ draw_y = table->widget.y;
for (y=0; y<rows; ++y)
{
- draw_x = origin_x;
+ draw_x = table->widget.x;
for (x=0; x<table->columns; ++x)
{
@@ -451,8 +440,8 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected)
if (table->widgets[i] != NULL)
{
- DrawCell(table, x, y, draw_x, draw_y,
- column_widths[x], selected);
+ LayoutCell(table, x, y, column_widths[x],
+ draw_x, draw_y);
}
draw_x += column_widths[x];
@@ -464,6 +453,75 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected)
free(row_heights);
free(column_widths);
}
+
+static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int selected)
+{
+ TXT_CAST_ARG(txt_table_t, table);
+ txt_widget_t *widget;
+ int selected_cell;
+ int i;
+
+ // Check the table's current selection points at something valid before
+ // drawing.
+
+ CheckValidSelection(table);
+
+ // Find the index of the currently-selected widget.
+
+ selected_cell = table->selected_y * table->columns + table->selected_x;
+
+ // Draw all cells
+
+ for (i=0; i<table->num_widgets; ++i)
+ {
+ widget = table->widgets[i];
+
+ if (widget != NULL)
+ {
+ TXT_GotoXY(widget->x, widget->y);
+ TXT_DrawWidget(widget, selected && i == selected_cell);
+ }
+ }
+}
+
+// Responds to mouse presses
+
+static void TXT_TableMousePress(TXT_UNCAST_ARG(table), int x, int y, int b)
+{
+ TXT_CAST_ARG(txt_table_t, table);
+ txt_widget_t *widget;
+ int i;
+
+ for (i=0; i<table->num_widgets; ++i)
+ {
+ widget = table->widgets[i];
+
+ // NULL widgets are spacers
+
+ if (widget != NULL)
+ {
+ if (x >= widget->x && x < widget->x + widget->w
+ && y >= widget->y && y < widget->y + widget->h)
+ {
+ // This is the widget that was clicked!
+
+ // Select the cell if the widget is selectable
+
+ if (widget->selectable)
+ {
+ table->selected_x = i % table->columns;
+ table->selected_y = i / table->columns;
+ }
+
+ // Propagate click
+
+ TXT_WidgetMousePress(widget, x, y, b);
+
+ break;
+ }
+ }
+ }
+}
txt_widget_class_t txt_table_class =
{
@@ -471,6 +529,8 @@ txt_widget_class_t txt_table_class =
TXT_TableDrawer,
TXT_TableKeyPress,
TXT_TableDestructor,
+ TXT_TableMousePress,
+ TXT_TableLayout,
};
void TXT_InitTable(txt_table_t *table, int columns)
diff --git a/textscreen/txt_widget.c b/textscreen/txt_widget.c
index 8411ac5b..3ca92c9a 100644
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -112,18 +112,24 @@ void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name)
}
}
-void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget), int *w, int *h)
+void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget))
{
TXT_CAST_ARG(txt_widget_t, widget);
- return widget->widget_class->size_calc(widget, w, h);
+ widget->widget_class->size_calc(widget);
}
-void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int w, int selected)
+void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int selected)
{
TXT_CAST_ARG(txt_widget_t, widget);
- widget->widget_class->drawer(widget, w, selected);
+ // For convenience...
+
+ TXT_GotoXY(widget->x, widget->y);
+
+ // Call drawer method
+
+ widget->widget_class->drawer(widget, selected);
}
void TXT_DestroyWidget(TXT_UNCAST_ARG(widget))
@@ -154,4 +160,23 @@ void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align)
widget->align = horiz_align;
}
+void TXT_WidgetMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b)
+{
+ TXT_CAST_ARG(txt_widget_t, widget);
+
+ if (widget->widget_class->mouse_press != NULL)
+ {
+ widget->widget_class->mouse_press(widget, x, y, b);
+ }
+}
+
+void TXT_LayoutWidget(TXT_UNCAST_ARG(widget))
+{
+ TXT_CAST_ARG(txt_widget_t, widget);
+
+ if (widget->widget_class->layout != NULL)
+ {
+ widget->widget_class->layout(widget);
+ }
+}
diff --git a/textscreen/txt_widget.h b/textscreen/txt_widget.h
index 46fd3745..ee18fd14 100644
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -48,11 +48,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_UNCAST_ARG(widget), int *w, int *h);
-typedef void (*TxtWidgetDrawer)(TXT_UNCAST_ARG(widget), int w, int selected);
+typedef void (*TxtWidgetSizeCalc)(TXT_UNCAST_ARG(widget));
+typedef void (*TxtWidgetDrawer)(TXT_UNCAST_ARG(widget), int selected);
typedef void (*TxtWidgetDestroy)(TXT_UNCAST_ARG(widget));
typedef int (*TxtWidgetKeyPress)(TXT_UNCAST_ARG(widget), int key);
typedef void (*TxtWidgetSignalFunc)(TXT_UNCAST_ARG(widget), void *user_data);
+typedef void (*TxtMousePressFunc)(TXT_UNCAST_ARG(widget), int x, int y, int b);
+typedef void (*TxtWidgetLayoutFunc)(TXT_UNCAST_ARG(widget));
struct txt_widget_class_s
{
@@ -60,6 +62,8 @@ struct txt_widget_class_s
TxtWidgetDrawer drawer;
TxtWidgetKeyPress key_press;
TxtWidgetDestroy destructor;
+ TxtMousePressFunc mouse_press;
+ TxtWidgetLayoutFunc layout;
};
struct txt_widget_s
@@ -69,17 +73,25 @@ struct txt_widget_s
int selectable;
int visible;
txt_horiz_align_t align;
+
+ // These are set automatically when the window is drawn and should
+ // not be set manually.
+
+ int x, y;
+ int w, h;
};
void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class);
-void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget), int *w, int *h);
-void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int w, int selected);
+void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget));
+void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int selected);
void TXT_SignalConnect(TXT_UNCAST_ARG(widget), char *signal_name,
TxtWidgetSignalFunc func, void *user_data);
void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name);
int TXT_WidgetKeyPress(TXT_UNCAST_ARG(widget), int key);
+void TXT_WidgetMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b);
void TXT_DestroyWidget(TXT_UNCAST_ARG(widget));
void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align);
+void TXT_LayoutWidget(TXT_UNCAST_ARG(widget));
#endif /* #ifndef TXT_WIDGET_H */
diff --git a/textscreen/txt_window.c b/textscreen/txt_window.c
index 9c1f0257..f04b8c68 100644
--- a/textscreen/txt_window.c
+++ b/textscreen/txt_window.c
@@ -1,11 +1,3 @@
-// Emacs style mode select -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// $Id$
-//
-// Copyright(C) 1993-1996 Id Software, Inc.
-// Copyright(C) 2006 Simon Howard
-//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
@@ -64,7 +56,15 @@ txt_window_t *TXT_NewWindow(char *title)
TXT_InitTable(&win->table, 1);
- win->title = strdup(title);
+ if (title == NULL)
+ {
+ win->title = NULL;
+ }
+ else
+ {
+ win->title = strdup(title);
+ }
+
win->x = TXT_SCREEN_W / 2;
win->y = TXT_SCREEN_H / 2;
win->horiz_align = TXT_HORIZ_CENTER;
@@ -111,73 +111,92 @@ void TXT_CloseWindow(txt_window_t *window)
TXT_RemoveDesktopWindow(window);
}
-static void CalcWindowPosition(txt_window_t *window,
- int *x, int *y,
- int w, int h)
+static void CalcWindowPosition(txt_window_t *window)
{
switch (window->horiz_align)
{
case TXT_HORIZ_LEFT:
- *x = window->x;
+ window->window_x = window->x;
break;
case TXT_HORIZ_CENTER:
- *x = window->x - (w / 2);
+ window->window_x = window->x - (window->window_w / 2);
break;
case TXT_HORIZ_RIGHT:
- *x = window->x - (w - 1);
+ window->window_x = window->x - (window->window_w - 1);
break;
}
switch (window->vert_align)
{
case TXT_VERT_TOP:
- *y = window->y;
+ window->window_y = window->y;
break;
case TXT_VERT_CENTER:
- *y = window->y - (h / 2);
+ window->window_y = window->y - (window->window_h / 2);
break;
case TXT_VERT_BOTTOM:
- *y = window->y - (h - 1);
+ window->window_y = window->y - (window->window_h - 1);
break;
}
}
-static void DrawActionArea(txt_window_t *window,
- int window_x, int window_y,
- int window_w, int window_h)
+static void LayoutActionArea(txt_window_t *window)
{
- int ww, wh;
+ txt_widget_t *widget;
- // Draw the left action
+ // Left action
if (window->actions[TXT_HORIZ_LEFT] != NULL)
{
- TXT_GotoXY(window_x + 2, window_y + window_h - 2);
- TXT_DrawWidget(window->actions[TXT_HORIZ_LEFT], 0, 0);
+ widget = (txt_widget_t *) window->actions[TXT_HORIZ_LEFT];
+
+ TXT_CalcWidgetSize(widget);
+
+ widget->x = window->window_x + 2;
+ widget->y = window->window_y + window->window_h - 2;
}
// Draw the center action
if (window->actions[TXT_HORIZ_CENTER] != NULL)
{
- TXT_CalcWidgetSize(window->actions[TXT_HORIZ_CENTER], &ww, &wh);
- TXT_GotoXY(window_x + (window_w - ww - 2) / 2, window_y + window_h - 2);
- TXT_DrawWidget(window->actions[TXT_HORIZ_CENTER], 0, 0);
+ widget = (txt_widget_t *) window->actions[TXT_HORIZ_CENTER];
+
+ TXT_CalcWidgetSize(widget);
+
+ widget->x = window->window_x + (window->window_w - widget->w - 2) / 2;
+ widget->y = window->window_y + window->window_h - 2;
}
// Draw the right action
if (window->actions[TXT_HORIZ_RIGHT] != NULL)
{
- TXT_CalcWidgetSize(window->actions[TXT_HORIZ_RIGHT], &ww, &wh);
- TXT_GotoXY(window_x + window_w - 2 - ww, window_y + window_h - 2);
- TXT_DrawWidget(window->actions[TXT_HORIZ_RIGHT], 0, 0);
+ widget = (txt_widget_t *) window->actions[TXT_HORIZ_RIGHT];
+
+ TXT_CalcWidgetSize(widget);
+
+ widget->x = window->window_x + window->window_w - 2 - widget->w;
+ widget->y = window->window_y + window->window_h - 2;
}
}
-static int CalcActionAreaWidth(txt_window_t *window, int *widgets_w)
+static void DrawActionArea(txt_window_t *window)
{
- int ww, wh;
+ int i;
+
+ for (i=0; i<3; ++i)
+ {
+ if (window->actions[i] != NULL)
+ {
+ TXT_DrawWidget(window->actions[i], 0);
+ }
+ }
+}
+
+static int ActionAreaWidth(txt_window_t *window)
+{
+ txt_widget_t *widget;
int w;
int i;
@@ -188,57 +207,99 @@ static int CalcActionAreaWidth(txt_window_t *window, int *widgets_w)
for (i=0; i<3; ++i)
{
- if (window->actions[i] != NULL)
+ widget = (txt_widget_t *) window->actions[i];
+
+ if (widget != NULL)
{
- TXT_CalcWidgetSize(window->actions[i], &ww, &wh);
- w += ww + 1;
+ TXT_CalcWidgetSize(widget);
+ w += widget->w + 1;
}
}
- // If this is larger than the window size, adjust the window to fit.
-
- if (w > *widgets_w)
- *widgets_w = w;
+ return w;
}
-void TXT_DrawWindow(txt_window_t *window)
+// Sets size and position of all widgets in a window
+
+void TXT_LayoutWindow(txt_window_t *window)
{
- int widgets_w, widgets_h;
- int window_w, window_h;
- int x, y;
- int window_x, window_y;
- int i;
- int ww, wh;
+ txt_widget_t *widgets = (txt_widget_t *) window;
+ int widgets_w;
+ int actionarea_w;
+
+ // Calculate size of table
+
+ TXT_CalcWidgetSize(window);
+
+ // Calculate the size of the action area
+
+ actionarea_w = ActionAreaWidth(window);
- TXT_CalcWidgetSize(window, &widgets_w, &widgets_h);
- CalcActionAreaWidth(window, &widgets_w);
+ // Which one is larger?
+
+ widgets_w = widgets->w;
+
+ if (actionarea_w > widgets_w)
+ widgets_w = actionarea_w;
- // Actual window size after padding
+ // Set the window size based on widgets_w
+
+ window->window_w = widgets_w + 2;
+ window->window_h = widgets->h + 3;
- window_w = widgets_w + 2;
- window_h = widgets_h + 5;
+ // If the window has a title, add an extra two lines
+
+ if (window->title != NULL)
+ {
+ window->window_h += 2;
+ }
// Use the x,y position as the centerpoint and find the location to
// draw the window.
- CalcWindowPosition(window, &window_x, &window_y, window_w, window_h);
+ CalcWindowPosition(window);
+
+ // Set the table size and position
+
+ widgets->w = widgets_w;
+ // widgets->h (already set)
+ widgets->x = window->window_x + 1;
+ widgets->y = window->window_y + window->window_h - widgets->h - 3;
+ // Layout the table and action area
+
+ LayoutActionArea(window);
+ TXT_LayoutWidget(widgets);
+}
+
+void TXT_DrawWindow(txt_window_t *window)
+{
+ txt_widget_t *widgets;
+ int x, y;
+ int i;
+ int ww, wh;
+
+ TXT_LayoutWindow(window);
+
// Draw the window
- TXT_DrawWindowFrame(window->title, window_x, window_y, window_w, window_h);
+ TXT_DrawWindowFrame(window->title,
+ window->window_x, window->window_y,
+ window->window_w, window->window_h);
// Draw all widgets
- TXT_GotoXY(window_x + 1, window_y + 2);
- TXT_DrawWidget(window, widgets_w, 1);
+ TXT_DrawWidget(window, 1);
// Separator for action area
- TXT_DrawSeparator(window_x, window_y + 2 + widgets_h, window_w);
+ widgets = (txt_widget_t *) window;
+
+ TXT_DrawSeparator(window->window_x, widgets->y + widgets->h, widgets->w);
// Action area at the window bottom
- DrawActionArea(window, window_x, window_y, window_w, window_h);
+ DrawActionArea(window);
}
void TXT_SetWindowPosition(txt_window_t *window,
@@ -252,9 +313,41 @@ void TXT_SetWindowPosition(txt_window_t *window,
window->y = y;
}
+static void MouseButtonPress(txt_window_t *window, int b)
+{
+ int x, y;
+ txt_widget_t *widgets;
+
+ // Lay out the window, set positions and sizes of all widgets
+
+ TXT_LayoutWindow(window);
+
+ // Get the current mouse position
+
+ TXT_GetMousePosition(&x, &y);
+
+ // Is it within the table range?
+
+ widgets = (txt_widget_t *) window;
+
+ if (x >= widgets->x && x < widgets->x + widgets->w
+ && y >= widgets->y && y < widgets->y + widgets->h)
+ {
+ TXT_WidgetMousePress(window, x, y, b);
+ }
+}
+
void TXT_WindowKeyPress(txt_window_t *window, int c)
{
int i;
+
+ // Is this a mouse button ?
+
+ if (c == TXT_MOUSE_LEFT)
+ {
+ MouseButtonPress(window, c);
+ return;
+ }
// Send to the currently selected widget first
diff --git a/textscreen/txt_window.h b/textscreen/txt_window.h
index 583c76ef..5e01a16d 100644
--- a/textscreen/txt_window.h
+++ b/textscreen/txt_window.h
@@ -50,6 +50,11 @@ struct txt_window_s
// Actions that appear in the box at the bottom of the window
txt_window_action_t *actions[3];
+
+ // These are set automatically when the window is drawn
+
+ int window_x, window_y;
+ int window_w, window_h;
};
txt_window_t *TXT_NewWindow(char *title);
diff --git a/textscreen/txt_window_action.c b/textscreen/txt_window_action.c
index 2cffb8a6..d7b82f68 100644
--- a/textscreen/txt_window_action.c
+++ b/textscreen/txt_window_action.c
@@ -9,8 +9,7 @@
#include "txt_main.h"
#include "txt_window.h"
-static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action),
- int *w, int *h)
+static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action))
{
TXT_CAST_ARG(txt_window_action_t, action);
char buf[10];
@@ -19,11 +18,11 @@ static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action),
// Minimum width is the string length + two spaces for padding
- *w = strlen(action->label) + strlen(buf) + 1;
- *h = 1;
+ action->widget.w = strlen(action->label) + strlen(buf) + 1;
+ action->widget.h = 1;
}
-static void TXT_WindowActionDrawer(TXT_UNCAST_ARG(action), int w, int selected)
+static void TXT_WindowActionDrawer(TXT_UNCAST_ARG(action), int selected)
{
TXT_CAST_ARG(txt_window_action_t, action);
int i;