From 978ddf539803405ab8fed17e21014ee1ae69fac8 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 18 May 2006 18:48:24 +0000 Subject: Initial working text-mode GUI framework. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 480 --- textscreen/Makefile.am | 7 ++ textscreen/guitest.c | 88 ++++++++++++++++++++ textscreen/txt_button.c | 69 ++++++++++++++++ textscreen/txt_button.h | 42 ++++++++++ textscreen/txt_io.c | 8 +- textscreen/txt_io.h | 3 +- textscreen/txt_separator.c | 89 +++++++++++++++++++++ textscreen/txt_separator.h | 44 ++++++++++ textscreen/txt_widget.c | 19 +++++ textscreen/txt_widget.h | 55 +++++++++++++ textscreen/txt_window.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ textscreen/txt_window.h | 60 ++++++++++++++ 12 files changed, 677 insertions(+), 2 deletions(-) create mode 100644 textscreen/guitest.c create mode 100644 textscreen/txt_button.c create mode 100644 textscreen/txt_button.h create mode 100644 textscreen/txt_separator.c create mode 100644 textscreen/txt_separator.h create mode 100644 textscreen/txt_widget.c create mode 100644 textscreen/txt_widget.h create mode 100644 textscreen/txt_window.c create mode 100644 textscreen/txt_window.h diff --git a/textscreen/Makefile.am b/textscreen/Makefile.am index 8894f0f4..2c7903f1 100644 --- a/textscreen/Makefile.am +++ b/textscreen/Makefile.am @@ -2,11 +2,18 @@ AM_CFLAGS = @SDL_CFLAGS@ noinst_LIBRARIES=libtextscreen.a +bin_PROGRAMS=guitest libtextscreen_a_SOURCES = \ txt_gui.c txt_gui.h \ txt_io.c txt_io.h \ txt_main.c txt_main.h \ + txt_button.c txt_button.h \ + txt_separator.c txt_separator.h\ + txt_widget.c txt_widget.h \ + txt_window.c txt_window.h \ txt_font.h +guitest_LDADD = @SDL_LIBS@ libtextscreen.a +guitest_SOURCES = guitest.c diff --git a/textscreen/guitest.c b/textscreen/guitest.c new file mode 100644 index 00000000..afa0a45a --- /dev/null +++ b/textscreen/guitest.c @@ -0,0 +1,88 @@ +#include + + +#include "txt_main.h" + +#include "txt_button.h" +#include "txt_separator.h" +#include "txt_window.h" + +txt_window_t *firstwin; + +void SetupWindow(void) +{ + txt_window_t *window; + char buf[100]; + int i; + + window = TXT_NewWindow("Window test", 40, 12); + + strcpy(buf, "This is a button label: "); + + { + txt_separator_t *sep; + sep = TXT_NewSeparator("Main Section"); + TXT_AddWidget(window, &sep->widget); + } + + for (i=0; i<8; ++i) + { + txt_button_t *button; + + button = TXT_NewButton(buf); + strcat(buf, "a"); + TXT_AddWidget(window, &button->widget); + + if (i == 4) + { + txt_separator_t *sep; + + sep = TXT_NewSeparator("Section"); + TXT_AddWidget(window, &sep->widget); + } + + if (i == 6) + { + txt_separator_t *sep; + + sep = TXT_NewSeparator(NULL); + TXT_AddWidget(window, &sep->widget); + } + } + + firstwin = window; +} + +void Window2(void) +{ + txt_window_t *window; + int i; + + window = TXT_NewWindow("Another test", 30, 7); + + for (i=0; i<5; ++i) + { + txt_button_t *button; + + button = TXT_NewButton("hello there blah blah blah blah"); + TXT_AddWidget(window, &button->widget); + } +} + +int main() +{ + TXT_Init(); + + Window2(); + SetupWindow(); + + for (;;) + { + firstwin->selected = (firstwin->selected + 1) % firstwin->num_widgets; + + TXT_DrawAllWindows(); + + } +} + + diff --git a/textscreen/txt_button.c b/textscreen/txt_button.c new file mode 100644 index 00000000..93af5297 --- /dev/null +++ b/textscreen/txt_button.c @@ -0,0 +1,69 @@ + +#include + +#include "txt_button.h" +#include "txt_io.h" +#include "txt_main.h" +#include "txt_widget.h" +#include "txt_window.h" + +static int TXT_ButtonSizeCalc(txt_widget_t *widget) +{ + txt_button_t *button = (txt_button_t *) widget; + + // Minimum width is the string length + two spaces for padding + + return strlen(button->label) + 2; +} + +static void TXT_ButtonDrawer(txt_widget_t *widget, int w, int selected) +{ + txt_button_t *button = (txt_button_t *) widget; + int i; + + TXT_BGColor(TXT_COLOR_BLUE, 0); + TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); + TXT_PutChar(' '); + + if (selected) + { + TXT_BGColor(TXT_COLOR_GREY, 0); + } + + for (i=0; ilabel); ++i) + { + TXT_PutChar(button->label[i]); + } + + for (i=strlen(button->label); i < w-2; ++i) + { + TXT_PutChar(' '); + } +} + +static void TXT_ButtonDestructor(txt_widget_t *widget) +{ + txt_button_t *button = (txt_button_t *) widget; + + free(button->label); +} + +txt_widget_class_t txt_button_class = +{ + TXT_ButtonSizeCalc, + TXT_ButtonDrawer, + TXT_ButtonDestructor, +}; + +txt_button_t *TXT_NewButton(char *label) +{ + txt_button_t *button; + + button = malloc(sizeof(txt_button_t)); + + button->widget.widget_class = &txt_button_class; + button->label = strdup(label); + + return button; +} + diff --git a/textscreen/txt_button.h b/textscreen/txt_button.h new file mode 100644 index 00000000..f48c6bff --- /dev/null +++ b/textscreen/txt_button.h @@ -0,0 +1,42 @@ +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +#ifndef TXT_BUTTON_H +#define TXT_BUTTON_H + +typedef struct txt_button_s txt_button_t; + +#include "txt_widget.h" + +struct txt_button_s +{ + txt_widget_t widget; + char *label; +}; + +txt_button_t *TXT_NewButton(char *label); + +#endif /* #ifndef TXT_BUTTON_H */ + + diff --git a/textscreen/txt_io.c b/textscreen/txt_io.c index e0fdae43..b1a5f31f 100644 --- a/textscreen/txt_io.c +++ b/textscreen/txt_io.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: txt_io.c 292 2006-01-14 00:10:54Z fraggle $ +// $Id: txt_io.c 480 2006-05-18 18:48:24Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -232,6 +232,12 @@ void TXT_GotoXY(int x, int y) cur_y = y; } +void TXT_GetXY(int *x, int *y) +{ + *x = cur_x; + *y = cur_y; +} + void TXT_FGColor(txt_color_t color) { fgcolor = color; diff --git a/textscreen/txt_io.h b/textscreen/txt_io.h index 7ea31706..a3d69ce4 100644 --- a/textscreen/txt_io.h +++ b/textscreen/txt_io.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: txt_io.h 291 2006-01-13 23:56:00Z fraggle $ +// $Id: txt_io.h 480 2006-05-18 18:48:24Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -47,6 +47,7 @@ void TXT_PutChar(int c); void TXT_Puts(char *s); void TXT_GotoXY(int x, int y); +void TXT_GetXY(int *x, int *y); void TXT_FGColor(txt_color_t color); void TXT_BGColor(int color, int blinking); void TXT_ClearScreen(void); diff --git a/textscreen/txt_separator.c b/textscreen/txt_separator.c new file mode 100644 index 00000000..7555547c --- /dev/null +++ b/textscreen/txt_separator.c @@ -0,0 +1,89 @@ + +#include + +#include "txt_separator.h" +#include "txt_io.h" +#include "txt_main.h" +#include "txt_widget.h" +#include "txt_window.h" + +static int TXT_SeparatorSizeCalc(txt_widget_t *widget) +{ + txt_separator_t *separator = (txt_separator_t *) widget; + + if (separator->label != NULL) + { + // Minimum width is the string length + two spaces for padding + + return strlen(separator->label) + 2; + } + else + { + return 0; + } +} + +static void TXT_SeparatorDrawer(txt_widget_t *widget, int w, int selected) +{ + txt_separator_t *separator = (txt_separator_t *) widget; + int i; + int x, y; + + TXT_GetXY(&x, &y); + + // Draw separator. Go back one character and draw two extra + // to overlap the window borders. + + TXT_DrawSeparator(x-1, y, w + 2); + + if (separator->label != NULL) + { + TXT_GotoXY(x, y); + + TXT_BGColor(TXT_COLOR_BLUE, 0); + TXT_FGColor(TXT_COLOR_BRIGHT_GREEN); + TXT_PutChar(' '); + + for (i=0; ilabel); ++i) + { + TXT_PutChar(separator->label[i]); + } + + TXT_PutChar(' '); + } +} + +static void TXT_SeparatorDestructor(txt_widget_t *widget) +{ + txt_separator_t *separator = (txt_separator_t *) widget; + + free(separator->label); +} + +txt_widget_class_t txt_separator_class = +{ + TXT_SeparatorSizeCalc, + TXT_SeparatorDrawer, + TXT_SeparatorDestructor, +}; + +txt_separator_t *TXT_NewSeparator(char *label) +{ + txt_separator_t *separator; + + separator = malloc(sizeof(txt_separator_t)); + + separator->widget.widget_class = &txt_separator_class; + + if (label != NULL) + { + separator->label = strdup(label); + } + else + { + separator->label = NULL; + } + + return separator; +} + diff --git a/textscreen/txt_separator.h b/textscreen/txt_separator.h new file mode 100644 index 00000000..a36e393b --- /dev/null +++ b/textscreen/txt_separator.h @@ -0,0 +1,44 @@ +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +#ifndef TXT_SEPARATOR_H +#define TXT_SEPARATOR_H + +typedef struct txt_separator_s txt_separator_t; + +#include "txt_widget.h" + +struct txt_separator_s +{ + txt_widget_t widget; + char *label; +}; + +extern txt_widget_class_t txt_separator_class; + +txt_separator_t *TXT_NewSeparator(char *label); + +#endif /* #ifndef TXT_SEPARATOR_H */ + + diff --git a/textscreen/txt_widget.c b/textscreen/txt_widget.c new file mode 100644 index 00000000..b0576a26 --- /dev/null +++ b/textscreen/txt_widget.c @@ -0,0 +1,19 @@ + +#include "txt_widget.h" + +int TXT_WidgetWidth(txt_widget_t *widget) +{ + return widget->widget_class->size_calc(widget); +} + +void TXT_DrawWidget(txt_widget_t *widget, int w, int selected) +{ + widget->widget_class->drawer(widget, w, selected); +} + +void TXT_DestroyWidget(txt_widget_t *widget) +{ + widget->widget_class->destructor(widget); +} + + diff --git a/textscreen/txt_widget.h b/textscreen/txt_widget.h new file mode 100644 index 00000000..a8d78bfc --- /dev/null +++ b/textscreen/txt_widget.h @@ -0,0 +1,55 @@ +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +// Base GUI "widget" class that all widgets inherit from. + +#ifndef TXT_WIDGET_H +#define TXT_WIDGET_H + +typedef struct txt_widget_class_s txt_widget_class_t; +typedef struct txt_widget_s txt_widget_t; + +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); + +struct txt_widget_class_s +{ + TxtWidgetSizeCalc size_calc; + TxtWidgetDrawer drawer; + TxtWidgetDestroy destructor; +}; + +struct txt_widget_s +{ + txt_widget_class_t *widget_class; +}; + +int TXT_WidgetWidth(txt_widget_t *widget); +void TXT_DrawWidget(txt_widget_t *widget, int w, int selected); +void TXT_DestroyWidget(txt_widget_t *widget); + +#endif /* #ifndef TXT_WIDGET_H */ + + diff --git a/textscreen/txt_window.c b/textscreen/txt_window.c new file mode 100644 index 00000000..b50da9b4 --- /dev/null +++ b/textscreen/txt_window.c @@ -0,0 +1,195 @@ +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +#include +#include + +#include "txt_gui.h" +#include "txt_separator.h" +#include "txt_window.h" + +#define MAXWINDOWS 128 + +static txt_window_t *all_windows[MAXWINDOWS]; +static int num_windows = 0; + +static void AddWindow(txt_window_t *win) +{ + all_windows[num_windows] = win; + ++num_windows; +} + +static void RemoveWindow(txt_window_t *win) +{ + int from, to; + + for (from=0, to=0; fromtitle = strdup(title); + win->x = x; + win->y = y; + win->widgets = NULL; + win->num_widgets = 0; + win->selected = 0; + + AddWindow(win); + + return win; +} + +void TXT_CloseWindow(txt_window_t *window) +{ + int i; + + // Free all widgets + + for (i=0; inum_widgets; ++i) + { + TXT_DestroyWidget(window->widgets[i]); + } + + // Free window resources + + free(window->widgets); + free(window->title); + free(window); + + RemoveWindow(window); +} + +static void TXT_WindowSize(txt_window_t *window, int *w, int *h) +{ + int max_width; + int i; + int ww; + + max_width = 10; + + for (i=0; inum_widgets; ++i) + { + ww = TXT_WidgetWidth(window->widgets[i]); + + if (ww > max_width) + max_width = ww; + } + + *w = max_width; + *h = window->num_widgets; +} + +static void DrawWindow(txt_window_t *window) +{ + int widgets_w, widgets_h; + int window_w, window_h; + int x, y; + int window_x, window_y; + int i; + + TXT_WindowSize(window, &widgets_w, &widgets_h); + + // Actual window size after padding + + window_w = widgets_w + 2; + window_h = widgets_h + 5; + + // 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); + + // Draw the window + + TXT_DrawWindow(window->title, window_x, window_y, window_w, window_h); + + // Draw all widgets + + for (i=0; inum_widgets; ++i) + { + TXT_GotoXY(window_x + 1, window_y + 2 + i); + TXT_DrawWidget(window->widgets[i], widgets_w, i == window->selected); + } + + // Separator for action area + + TXT_DrawSeparator(window_x, window_y + 2 + window->num_widgets, window_w); +} + +void TXT_DrawAllWindows(void) +{ + int i; + + TXT_DrawDesktop("Not Chocolate Doom setup"); + + for (i=0; inum_widgets == 0) + { + // This is the first widget added. + // + // The first widget in a window should always be a separator. + // If we are not adding a separator now, add one in first. + + if (widget->widget_class != &txt_separator_class) + { + txt_separator_t *separator; + + separator = TXT_NewSeparator(NULL); + + window->widgets = malloc(sizeof(txt_widget_t *)); + window->widgets[0] = &separator->widget; + window->num_widgets = 1; + } + } + + window->widgets = realloc(window->widgets, + sizeof(txt_widget_t *) * (window->num_widgets + 1)); + window->widgets[window->num_widgets] = widget; + ++window->num_widgets; +} + diff --git a/textscreen/txt_window.h b/textscreen/txt_window.h new file mode 100644 index 00000000..51610f47 --- /dev/null +++ b/textscreen/txt_window.h @@ -0,0 +1,60 @@ +// 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 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + +#ifndef TXT_WINDOW_H +#define TXT_WINDOW_H + +typedef struct txt_window_s txt_window_t; + +#include "txt_widget.h" + +struct txt_window_s +{ + // Window title + + char *title; + + // Screen coordinates of the centerpoint of the window + + int x, y; + + // Widgets in this window + + txt_widget_t **widgets; + int num_widgets; + + // Index of the current selected widget. + + int selected; +}; + +txt_window_t *TXT_NewWindow(char *title, int x, int y); +void TXT_CloseWindow(txt_window_t *window); +void TXT_AddWidget(txt_window_t *window, txt_widget_t *widget); + +void TXT_DrawAllWindows(void); + +#endif /* #ifndef TXT_WINDOW_T */ + + -- cgit v1.2.3