shithub: choc

Download patch

ref: f761f821f95a3fbf8af1eb645d8ae9412abdc541
parent: c63afd766a9fdb19bc2c3a650f859bbba4699e8f
author: Simon Howard <[email protected]>
date: Sat May 20 11:15:17 EDT 2006

Add selectable and visible properties to widgets. Allow the position of
windows to be set based on position of top/bottom/center,left/right,center
coordinates.

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

--- a/textscreen/guitest.c
+++ b/textscreen/guitest.c
@@ -16,7 +16,7 @@
     char buf[100];
     int i;
     
-    window = TXT_NewWindow("Window test", 40, 12);
+    window = TXT_NewWindow("Window test");
 
     strcpy(buf, "This is a button label: ");
 
@@ -46,7 +46,11 @@
     txt_window_t *window;
     int i;
     
-    window = TXT_NewWindow("Another test", 50, 7);
+    window = TXT_NewWindow("Another test");
+    TXT_SetWindowPosition(window, 
+                          TXT_HORIZ_RIGHT, 
+                          TXT_VERT_TOP, 
+                          TXT_SCREEN_W - 1, 1);
 
     for (i=0; i<5; ++i)
     {
--- a/textscreen/txt_button.c
+++ b/textscreen/txt_button.c
@@ -48,10 +48,15 @@
     free(button->label);
 }
 
+static int TXT_ButtonKeyPress(txt_widget_t *widget, int key)
+{
+}
+
 txt_widget_class_t txt_button_class =
 {
     TXT_ButtonSizeCalc,
     TXT_ButtonDrawer,
+    TXT_ButtonKeyPress,
     TXT_ButtonDestructor,
 };
 
@@ -62,6 +67,8 @@
     button = malloc(sizeof(txt_button_t));
 
     button->widget.widget_class = &txt_button_class;
+    button->widget.selectable = 1;
+    button->widget.visible = 1;
     button->label = strdup(label);
 
     return button;
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -1,7 +1,7 @@
 // Emacs style mode select   -*- C++ -*- 
 //-----------------------------------------------------------------------------
 //
-// $Id: txt_gui.c 483 2006-05-19 19:57:59Z fraggle $
+// $Id: txt_gui.c 486 2006-05-20 15:15:17Z fraggle $
 //
 // Copyright(C) 1993-1996 Id Software, Inc.
 // Copyright(C) 2005 Simon Howard
@@ -104,11 +104,16 @@
 
     for (y1=y; y1<y+h; ++y1)
     {
-        p = screendata + y1 * TXT_SCREEN_W * 2 + x * 2;
+        p = screendata + (y1 * TXT_SCREEN_W + x) * 2;
 
-        for (x1=0; x1<w; ++x1)
+        for (x1=x; x1<x+w; ++x1)
         {
-            p[1] = TXT_COLOR_DARK_GREY;
+            if (x1 >= 0 && x1 < TXT_SCREEN_W
+             && y1 >= 0 && y1 < TXT_SCREEN_H)
+            {
+                p[1] = TXT_COLOR_DARK_GREY;
+            }
+
             p += 2;
         }
     }
--- a/textscreen/txt_separator.c
+++ b/textscreen/txt_separator.c
@@ -64,6 +64,7 @@
 {
     TXT_SeparatorSizeCalc,
     TXT_SeparatorDrawer,
+    NULL,
     TXT_SeparatorDestructor,
 };
 
@@ -74,6 +75,8 @@
     separator = malloc(sizeof(txt_separator_t));
 
     separator->widget.widget_class = &txt_separator_class;
+    separator->widget.selectable = 0;
+    separator->widget.visible = 1;
 
     if (label != NULL)
     {
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 
 #include "txt_widget.h"
 
@@ -14,6 +15,14 @@
 void TXT_DestroyWidget(txt_widget_t *widget)
 {
     widget->widget_class->destructor(widget);
+}
+
+void TXT_WidgetKeyPress(txt_widget_t *widget, int key)
+{
+    if (widget->widget_class->key_press != NULL)
+    {
+        widget->widget_class->key_press(widget, key);
+    }
 }
 
 
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -33,11 +33,13 @@
 typedef int (*TxtWidgetSizeCalc)(txt_widget_t *widget);
 typedef void (*TxtWidgetDrawer)(txt_widget_t *widget, int w, int selected);
 typedef void (*TxtWidgetDestroy)(txt_widget_t *widget);
+typedef int (*TxtWidgetKeyPress)(txt_widget_t *widget, int key);
 
 struct txt_widget_class_s
 {
     TxtWidgetSizeCalc size_calc;
     TxtWidgetDrawer drawer;
+    TxtWidgetKeyPress key_press;
     TxtWidgetDestroy destructor;
 };
 
@@ -44,10 +46,13 @@
 struct txt_widget_s
 {
     txt_widget_class_t *widget_class;
+    int selectable;
+    int visible;
 };
 
 int TXT_WidgetWidth(txt_widget_t *widget);
 void TXT_DrawWidget(txt_widget_t *widget, int w, int selected);
+void TXT_WidgetKeyPress(txt_widget_t *widget, int key);
 void TXT_DestroyWidget(txt_widget_t *widget);
 
 #endif /* #ifndef TXT_WIDGET_H */
--- a/textscreen/txt_window.c
+++ b/textscreen/txt_window.c
@@ -31,7 +31,7 @@
 #include "txt_separator.h"
 #include "txt_window.h"
 
-txt_window_t *TXT_NewWindow(char *title, int x, int y)
+txt_window_t *TXT_NewWindow(char *title)
 {
     txt_window_t *win;
 
@@ -38,8 +38,10 @@
     win = malloc(sizeof(txt_window_t));
 
     win->title = strdup(title);
-    win->x = x;
-    win->y = y;
+    win->x = TXT_SCREEN_W / 2;
+    win->y = TXT_SCREEN_H / 2;
+    win->horiz_align = TXT_HORIZ_CENTER;
+    win->vert_align = TXT_VERT_CENTER;
     win->widgets = NULL;
     win->num_widgets = 0;
     win->selected = 0;
@@ -69,13 +71,16 @@
     TXT_RemoveDesktopWindow(window);
 }
 
-static void TXT_WindowSize(txt_window_t *window, int *w, int *h)
+static void CalcWindowSize(txt_window_t *window, int *w, int *h)
 {
+    txt_widget_t *widget;
     int max_width;
+    int height;
     int i;
     int ww;
 
     max_width = 10;
+    height = 0;
 
     for (i=0; i<window->num_widgets; ++i)
     {
@@ -83,12 +88,48 @@
 
         if (ww > max_width)
             max_width = ww;
+
+        if (window->widgets[i]->visible)
+        {
+            height += 1;
+        }
     }
 
     *w = max_width;
-    *h = window->num_widgets;
+    *h = height;
 }
 
+static void CalcWindowPosition(txt_window_t *window,
+                               int *x, int *y,
+                               int w, int h)
+{
+    switch (window->horiz_align)
+    {
+        case TXT_HORIZ_LEFT:
+            *x = window->x;
+            break;
+        case TXT_HORIZ_CENTER:
+            *x = window->x - (w / 2);
+            break;
+        case TXT_HORIZ_RIGHT:
+            *x = window->x - (w - 1);
+            break;
+    }
+
+    switch (window->vert_align)
+    {
+        case TXT_VERT_TOP:
+            *y = window->y;
+            break;
+        case TXT_VERT_CENTER:
+            *y = window->y - (h / 2);
+            break;
+        case TXT_VERT_BOTTOM:
+            *y = window->y - (h - 1);
+            break;
+    }
+}
+
 void TXT_DrawWindow(txt_window_t *window)
 {
     int widgets_w, widgets_h;
@@ -97,7 +138,7 @@
     int window_x, window_y;
     int i;
     
-    TXT_WindowSize(window, &widgets_w, &widgets_h);
+    CalcWindowSize(window, &widgets_w, &widgets_h);
 
     // Actual window size after padding
 
@@ -107,8 +148,7 @@
     // Use the x,y position as the centerpoint and find the location to 
     // draw the window.
 
-    window_x = window->x - (window_w / 2);
-    window_y = window->y - (window_h / 2);
+    CalcWindowPosition(window, &window_x, &window_y, window_w, window_h);
 
     // Draw the window
 
@@ -116,15 +156,23 @@
 
     // Draw all widgets
 
+    x = window_x + 1;
+    y = window_y + 2;
+
     for (i=0; i<window->num_widgets; ++i)
     {
-        TXT_GotoXY(window_x + 1, window_y + 2 + i);
+        TXT_GotoXY(x, y);
         TXT_DrawWidget(window->widgets[i], widgets_w, i == window->selected);
+
+        if (window->widgets[i]->visible)
+        {
+            y += 1;
+        }
     }
 
     // Separator for action area
 
-    TXT_DrawSeparator(window_x, window_y + 2 + window->num_widgets, window_w);
+    TXT_DrawSeparator(window_x, y, window_w);
 }
 
 void TXT_AddWidget(txt_window_t *window, void *uncast_widget)
@@ -156,5 +204,16 @@
                               sizeof(txt_widget_t *) * (window->num_widgets + 1));
     window->widgets[window->num_widgets] = widget;
     ++window->num_widgets;
+}
+
+void TXT_SetWindowPosition(txt_window_t *window,
+                           txt_horiz_align_t horiz_align,
+                           txt_vert_align_t vert_align,
+                           int x, int y)
+{
+    window->vert_align = vert_align;
+    window->horiz_align = horiz_align;
+    window->x = x;
+    window->y = y;
 }
 
--- a/textscreen/txt_window.h
+++ b/textscreen/txt_window.h
@@ -27,6 +27,20 @@
 
 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" 
 
 struct txt_window_s
@@ -35,8 +49,10 @@
 
     char *title;
 
-    // Screen coordinates of the centerpoint of the window
+    // Screen coordinates of the window
 
+    txt_vert_align_t vert_align;
+    txt_horiz_align_t horiz_align;
     int x, y;
 
     // Widgets in this window
@@ -49,9 +65,13 @@
     int selected;
 };
 
-txt_window_t *TXT_NewWindow(char *title, int x, int y);
+txt_window_t *TXT_NewWindow(char *title);
 void TXT_CloseWindow(txt_window_t *window);
 void TXT_AddWidget(txt_window_t *window, void *widget);
+void TXT_SetWindowPosition(txt_window_t *window, 
+                           txt_horiz_align_t horiz_align,
+                           txt_vert_align_t vert_align,
+                           int x, int y);
 
 #endif /* #ifndef TXT_WINDOW_T */