summaryrefslogtreecommitdiff
path: root/textscreen
diff options
context:
space:
mode:
authorSimon Howard2006-06-02 19:29:24 +0000
committerSimon Howard2006-06-02 19:29:24 +0000
commit517af9477b7269564f3ba8c0ccc6ef53c78a7abb (patch)
tree1d60d219a7c71b90330baee90acf06a05670fb0f /textscreen
parentb3e5170bbba1c3048da86a5291cd45524abfeac2 (diff)
downloadchocolate-doom-517af9477b7269564f3ba8c0ccc6ef53c78a7abb.tar.gz
chocolate-doom-517af9477b7269564f3ba8c0ccc6ef53c78a7abb.tar.bz2
chocolate-doom-517af9477b7269564f3ba8c0ccc6ef53c78a7abb.zip
textscreen: Rejig how the entire drawing process works. Add a recursive
layout method that assigns the position and size of widgets for the whole window before drawing. Add another method that responds to mouse button presses. Allow windows to have no title bar by specifying NULL as the title. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 547
Diffstat (limited to 'textscreen')
-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;