shithub: choc

Download patch

ref: 9ba105fa4ee6e68c1bbea9568a36b31fc47cf24c
parent: 47287b653271d94cb0fa49833db621a048df2ca1
author: Simon Howard <fraggle@gmail.com>
date: Sat May 20 20:07:11 EDT 2006

Always select a valid widget in a table before drawing the table.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 497

--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -123,57 +123,6 @@
     free(column_widths);
 }
 
-static void TXT_TableDrawer(txt_widget_t *widget, int w, int selected)
-{
-    txt_table_t *table = (txt_table_t *) widget;
-    int *column_widths;
-    int *row_heights;
-    int origin_x, origin_y;
-    int draw_x, draw_y;
-    int x, y;
-    int rows;
-
-    TXT_GetXY(&origin_x, &origin_y);
-
-    // Work out the column widths and row heights
-
-    rows = TableRows(table);
-
-    column_widths = malloc(sizeof(int) * table->columns);
-    row_heights = malloc(sizeof(int) * rows);
-
-    CalcRowColSizes(table, row_heights, column_widths);
-
-    // Draw all cells
-    
-    draw_y = origin_y;
-    
-    for (y=0; y<rows; ++y)
-    {
-        draw_x = origin_x;
-
-        for (x=0; x<table->columns; ++x)
-        {
-            if (y * table->columns + x >= table->num_widgets)
-                break;
-
-            TXT_GotoXY(draw_x, draw_y);
-
-            TXT_DrawWidget(table->widgets[y * table->columns + x],
-                           column_widths[x],
-                           selected && x == table->selected_x
-                                    && y == table->selected_y);
-
-            draw_x += column_widths[x];
-        }
-
-        draw_y += row_heights[y];
-    }
-
-    free(row_heights);
-    free(column_widths);
-}
-
 void TXT_AddWidget(void *uncast_table, void *uncast_widget)
 {
     txt_widget_t *widget;
@@ -212,8 +161,22 @@
     ++table->num_widgets;
 }
 
-#define SELECTABLE_WIDGET(w) ((w)->selectable && (w)->visible)
+static int SelectableWidget(txt_table_t *table, int x, int y)
+{
+    txt_widget_t *widget;
+    int i;
 
+    i = y * table->columns + x;
+
+    if (i >= 0 && i < table->num_widgets)
+    {
+        widget = table->widgets[i];
+        return widget->selectable && widget->visible;
+    }
+
+    return 0;
+}
+
 // Tries to locate a selectable widget in the given row, returning
 // the column number of the first column available or -1 if none are 
 // available in the given row.
@@ -229,10 +192,7 @@
     {
         // Search to the right
 
-        i = table->columns * row + start_col + x;
-
-        if (i >= 0 && i < table->num_widgets
-         && SELECTABLE_WIDGET(table->widgets[i]))
+        if (SelectableWidget(table, start_col + x, row))
         {
             return start_col + x;
         }
@@ -239,10 +199,7 @@
 
         // Search to the left
 
-        i = table->columns * row + start_col - x;
-
-        if (i >= 0 && i < table->num_widgets
-         && SELECTABLE_WIDGET(table->widgets[i]))
+        if (SelectableWidget(table, start_col - x, row))
         {
             return start_col - x;
         }
@@ -326,10 +283,7 @@
 
         for (new_x = table->selected_x - 1; new_x >= 0; --new_x)
         {
-            i = table->selected_y * table->columns + new_x;
-            
-            if (i >= 0 && i < table->num_widgets
-             && SELECTABLE_WIDGET(table->widgets[i]))
+            if (SelectableWidget(table, new_x, table->selected_y))
             {
                 // Found a selectable widget!
 
@@ -349,10 +303,7 @@
 
         for (new_x = table->selected_x + 1; new_x < table->columns; ++new_x)
         {
-            i = table->selected_y * table->columns + new_x;
-            
-            if (i >= 0 && i < table->num_widgets
-             && SELECTABLE_WIDGET(table->widgets[i]))
+            if (SelectableWidget(table, new_x, table->selected_y))
             {
                 // Found a selectable widget!
 
@@ -364,6 +315,87 @@
     }
 
     return 0;
+}
+
+// Check the currently selected widget in the table is valid.
+
+static void CheckValidSelection(txt_table_t *table)
+{
+    int rows;
+    int new_x, new_y;
+
+    rows = TableRows(table);
+
+    for (new_y = table->selected_y; new_y < rows; ++new_y)
+    {
+        new_x = FindSelectableColumn(table, new_y, table->selected_x);
+
+        if (new_x >= 0)
+        {
+            // Found a selectable column.
+
+            table->selected_x = new_x;
+            table->selected_y = new_y;
+
+            break;
+        }
+    }
+}
+
+static void TXT_TableDrawer(txt_widget_t *widget, int w, int selected)
+{
+    txt_table_t *table = (txt_table_t *) widget;
+    int *column_widths;
+    int *row_heights;
+    int origin_x, origin_y;
+    int draw_x, draw_y;
+    int x, y;
+    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);
+
+    column_widths = malloc(sizeof(int) * table->columns);
+    row_heights = malloc(sizeof(int) * rows);
+
+    CalcRowColSizes(table, row_heights, column_widths);
+
+    // Draw all cells
+    
+    draw_y = origin_y;
+    
+    for (y=0; y<rows; ++y)
+    {
+        draw_x = origin_x;
+
+        for (x=0; x<table->columns; ++x)
+        {
+            if (y * table->columns + x >= table->num_widgets)
+                break;
+
+            TXT_GotoXY(draw_x, draw_y);
+
+            TXT_DrawWidget(table->widgets[y * table->columns + x],
+                           column_widths[x],
+                           selected && x == table->selected_x
+                                    && y == table->selected_y);
+
+            draw_x += column_widths[x];
+        }
+
+        draw_y += row_heights[y];
+    }
+
+    free(row_heights);
+    free(column_widths);
 }
 
 txt_widget_class_t txt_table_class =