shithub: choc

Download patch

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"