ref: b3e5170bbba1c3048da86a5291cd45524abfeac2
parent: 64b2890756bc7f48fdf2fd0ef8c25dd8f0fd1c22
author: Simon Howard <fraggle@gmail.com>
date: Mon May 29 17:39:12 EDT 2006
Add ability to make widgets right aligned or centered within tables. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 546
--- a/textscreen/examples/guitest.c
+++ b/textscreen/examples/guitest.c
@@ -68,6 +68,7 @@
txt_button_t *button;
txt_checkbox_t *cheesy_checkbox;
txt_window_action_t *pwn;
+ txt_label_t *toplabel;
char buf[100];
int i;
@@ -76,9 +77,11 @@
TXT_AddWidget(window, TXT_NewSeparator("Main section"));
table = TXT_NewTable(3);
- TXT_AddWidget(window, TXT_NewLabel(" This is a multiline label.\n"
- " A single label object contains \n"
- " all three of these lines.\n"));
+ toplabel = TXT_NewLabel(" This is a multiline label.\n"
+ " A single label object contains \n"
+ " all three of these lines.\n");
+ TXT_AddWidget(window, toplabel);
+ TXT_SetWidgetAlign(toplabel, TXT_HORIZ_CENTER);
TXT_AddWidget(window, table);
@@ -98,6 +101,7 @@
table = TXT_NewTable(2);
TXT_AddWidget(window, table);
+ TXT_SetWidgetAlign(table, TXT_HORIZ_CENTER);
cheesy_checkbox = TXT_NewCheckBox("Cheesy", &cheesy);
TXT_AddWidget(table, cheesy_checkbox);
--- a/textscreen/txt_label.c
+++ b/textscreen/txt_label.c
@@ -20,6 +20,7 @@
TXT_CAST_ARG(txt_label_t, label);
int x, y;
int origin_x, origin_y;
+ int align_indent;
TXT_BGColor(label->bgcolor, 0);
TXT_FGColor(label->fgcolor);
@@ -28,10 +29,41 @@
for (y=0; y<label->h; ++y)
{
+ // Calculate the amount to indent this line due to the align
+ // setting
+
+ switch (label->widget.align)
+ {
+ case TXT_HORIZ_LEFT:
+ align_indent = 0;
+ break;
+ case TXT_HORIZ_CENTER:
+ align_indent = (label->w - strlen(label->lines[y])) / 2;
+ break;
+ case TXT_HORIZ_RIGHT:
+ align_indent = label->w - strlen(label->lines[y]);
+ break;
+ }
+
+ // Draw this line
+
TXT_GotoXY(origin_x, origin_y + y);
+
+ // Gap at the start
+
+ for (x=0; x<align_indent; ++x)
+ {
+ TXT_DrawString(" ");
+ }
+
+ // The string itself
+
TXT_DrawString(label->lines[y]);
+ x += strlen(label->lines[y]);
- for (x=strlen(label->lines[y]); x<w; ++x)
+ // Gap at the end
+
+ for (; x<w; ++x)
{
TXT_DrawString(" ");
}
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -354,15 +354,59 @@
}
}
+static void DrawCell(txt_table_t *table, int x, int y,
+ int draw_x, int draw_y, int w, int selected)
+{
+ txt_widget_t *widget;
+ int cw, ch;
+
+ widget = table->widgets[y * table->columns + x];
+
+ switch (widget->align)
+ {
+ case TXT_HORIZ_LEFT:
+ break;
+
+ case TXT_HORIZ_CENTER:
+ TXT_CalcWidgetSize(widget, &cw, &ch);
+
+ // Separators are always drawn left-aligned.
+
+ if (widget->widget_class != &txt_separator_class)
+ {
+ draw_x += (w - cw) / 2;
+ w = cw;
+ }
+
+ break;
+
+ case TXT_HORIZ_RIGHT:
+ TXT_CalcWidgetSize(widget, &cw, &ch);
+
+ if (widget->widget_class != &txt_separator_class)
+ {
+ draw_x += w - cw;
+ w = cw;
+ }
+
+ break;
+ }
+
+ TXT_GotoXY(draw_x, draw_y);
+
+ TXT_DrawWidget(widget, w, selected && x == table->selected_x
+ && y == table->selected_y);
+}
+
static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected)
{
TXT_CAST_ARG(txt_table_t, table);
- txt_widget_t *widget;
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
@@ -400,18 +444,15 @@
for (x=0; x<table->columns; ++x)
{
- if (y * table->columns + x >= table->num_widgets)
+ i = y * table->columns + x;
+
+ if (i >= table->num_widgets)
break;
- TXT_GotoXY(draw_x, draw_y);
-
- widget = table->widgets[y * table->columns + x];
-
- if (widget != NULL)
+ if (table->widgets[i] != NULL)
{
- TXT_DrawWidget(widget, column_widths[x],
- selected && x == table->selected_x
- && y == table->selected_y);
+ DrawCell(table, x, y, draw_x, draw_y,
+ column_widths[x], selected);
}
draw_x += column_widths[x];
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -51,6 +51,10 @@
widget->selectable = 1;
widget->visible = 1;
+
+ // Align left by default
+
+ widget->align = TXT_HORIZ_LEFT;
}
void TXT_SignalConnect(TXT_UNCAST_ARG(widget),
@@ -141,6 +145,13 @@
}
return 0;
+}
+
+void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align)
+{
+ TXT_CAST_ARG(txt_widget_t, widget);
+
+ widget->align = horiz_align;
}
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -30,6 +30,20 @@
#define TXT_UNCAST_ARG(name) void *uncast_ ## name
#define TXT_CAST_ARG(type, name) type *name = (type *) uncast_ ## name
+typedef enum
+{
+ TXT_VERT_TOP,
+ TXT_VERT_CENTER,
+ TXT_VERT_BOTTOM,
+} txt_vert_align_t;
+
+typedef enum
+{
+ TXT_HORIZ_LEFT,
+ TXT_HORIZ_CENTER,
+ TXT_HORIZ_RIGHT,
+} txt_horiz_align_t;
+
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;
@@ -54,6 +68,7 @@
txt_callback_table_t *callback_table;
int selectable;
int visible;
+ txt_horiz_align_t align;
};
void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class);
@@ -64,6 +79,7 @@
void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name);
int TXT_WidgetKeyPress(TXT_UNCAST_ARG(widget), int key);
void TXT_DestroyWidget(TXT_UNCAST_ARG(widget));
+void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align);
#endif /* #ifndef TXT_WIDGET_H */
--- a/textscreen/txt_window.h
+++ b/textscreen/txt_window.h
@@ -27,20 +27,6 @@
typedef struct txt_window_s txt_window_t;
-typedef enum
-{
- TXT_VERT_TOP,
- TXT_VERT_CENTER,
- TXT_VERT_BOTTOM,
-} txt_vert_align_t;
-
-typedef enum
-{
- TXT_HORIZ_LEFT,
- TXT_HORIZ_CENTER,
- TXT_HORIZ_RIGHT,
-} txt_horiz_align_t;
-
#include "txt_widget.h"
#include "txt_table.h"
#include "txt_window_action.h"