diff options
-rw-r--r-- | textscreen/txt_button.c | 11 | ||||
-rw-r--r-- | textscreen/txt_checkbox.c | 11 | ||||
-rw-r--r-- | textscreen/txt_gui.c | 49 | ||||
-rw-r--r-- | textscreen/txt_inputbox.c | 11 | ||||
-rw-r--r-- | textscreen/txt_label.c | 11 | ||||
-rw-r--r-- | textscreen/txt_main.c | 10 | ||||
-rw-r--r-- | textscreen/txt_main.h | 6 | ||||
-rw-r--r-- | textscreen/txt_radiobutton.c | 11 | ||||
-rw-r--r-- | textscreen/txt_separator.c | 13 | ||||
-rw-r--r-- | textscreen/txt_strut.c | 8 | ||||
-rw-r--r-- | textscreen/txt_table.c | 150 | ||||
-rw-r--r-- | textscreen/txt_widget.c | 33 | ||||
-rw-r--r-- | textscreen/txt_widget.h | 20 | ||||
-rw-r--r-- | textscreen/txt_window.c | 209 | ||||
-rw-r--r-- | textscreen/txt_window.h | 5 | ||||
-rw-r--r-- | textscreen/txt_window_action.c | 9 |
16 files changed, 404 insertions, 163 deletions
diff --git a/textscreen/txt_button.c b/textscreen/txt_button.c index 53021a75..8b8e704b 100644 --- a/textscreen/txt_button.c +++ b/textscreen/txt_button.c @@ -9,20 +9,23 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_ButtonSizeCalc(TXT_UNCAST_ARG(button), int *w, int *h) +static void TXT_ButtonSizeCalc(TXT_UNCAST_ARG(button)) { TXT_CAST_ARG(txt_button_t, button); // Minimum width is the string length + two spaces for padding - *w = strlen(button->label) + 2; - *h = 1; + button->widget.w = strlen(button->label) + 2; + button->widget.h = 1; } -static void TXT_ButtonDrawer(TXT_UNCAST_ARG(button), int w, int selected) +static void TXT_ButtonDrawer(TXT_UNCAST_ARG(button), int selected) { TXT_CAST_ARG(txt_button_t, button); int i; + int w; + + w = button->widget.w; TXT_BGColor(TXT_COLOR_BLUE, 0); TXT_FGColor(TXT_COLOR_BRIGHT_WHITE); diff --git a/textscreen/txt_checkbox.c b/textscreen/txt_checkbox.c index 4419c4b3..d32a240c 100644 --- a/textscreen/txt_checkbox.c +++ b/textscreen/txt_checkbox.c @@ -9,20 +9,23 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_CheckBoxSizeCalc(TXT_UNCAST_ARG(checkbox), int *w, int *h) +static void TXT_CheckBoxSizeCalc(TXT_UNCAST_ARG(checkbox)) { TXT_CAST_ARG(txt_checkbox_t, checkbox); // Minimum width is the string length + two spaces for padding - *w = strlen(checkbox->label) + 6; - *h = 1; + checkbox->widget.w = strlen(checkbox->label) + 6; + checkbox->widget.h = 1; } -static void TXT_CheckBoxDrawer(TXT_UNCAST_ARG(checkbox), int w, int selected) +static void TXT_CheckBoxDrawer(TXT_UNCAST_ARG(checkbox), int selected) { TXT_CAST_ARG(txt_checkbox_t, checkbox); int i; + int w; + + w = checkbox->widget.w; TXT_BGColor(TXT_COLOR_BLUE, 0); TXT_FGColor(TXT_COLOR_BRIGHT_CYAN); diff --git a/textscreen/txt_gui.c b/textscreen/txt_gui.c index 2c58cb9f..9de66627 100644 --- a/textscreen/txt_gui.c +++ b/textscreen/txt_gui.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: txt_gui.c 487 2006-05-20 15:45:36Z fraggle $ +// $Id: txt_gui.c 547 2006-06-02 19:29:24Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -140,7 +140,7 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h) // draw a box around the title. by = y1 == y ? 0 : - y1 == y + 2 ? 2 : + y1 == y + 2 && title != NULL ? 2 : y1 == y + h - 1 ? 3 : 1; for (x1=x; x1<x+w; ++x1) @@ -158,17 +158,20 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h) // Draw the title - TXT_GotoXY(x + 1, y + 1); - TXT_BGColor(TXT_COLOR_GREY, 0); - TXT_FGColor(TXT_COLOR_BLUE); - - for (x1=0; x1<w-2; ++x1) + if (title != NULL) { - TXT_DrawString(" "); - } + TXT_GotoXY(x + 1, y + 1); + TXT_BGColor(TXT_COLOR_GREY, 0); + TXT_FGColor(TXT_COLOR_BLUE); - TXT_GotoXY(x + (w - strlen(title)) / 2, y + 1); - TXT_DrawString(title); + for (x1=0; x1<w-2; ++x1) + { + TXT_DrawString(" "); + } + + TXT_GotoXY(x + (w - strlen(title)) / 2, y + 1); + TXT_DrawString(title); + } // Draw the window's shadow. @@ -178,8 +181,11 @@ void TXT_DrawWindowFrame(char *title, int x, int y, int w, int h) void TXT_DrawSeparator(int x, int y, int w) { + unsigned char *data; int x1; - int c; + int b; + + data = TXT_GetScreenData(); TXT_FGColor(TXT_COLOR_BRIGHT_CYAN); TXT_BGColor(TXT_COLOR_BLUE, 0); @@ -189,18 +195,29 @@ void TXT_DrawSeparator(int x, int y, int w) return; } + data += (y * TXT_SCREEN_W + x) * 2; + for (x1=x; x1<x+w; ++x1) { TXT_GotoXY(x1, y); - c = x1 == x ? borders[2][0] : - x1 == x + w - 1 ? borders[2][3] : - borders[2][1]; + b = x1 == x ? 0 : + x1 == x + w - 1 ? 3 : + 1; if (VALID_X(x1)) { - TXT_PutChar(c); + // Read the current value from the screen + // Check that it matches what the window should look like if + // there is no separator, then apply the separator + + if (*data == borders[1][b]) + { + TXT_PutChar(borders[2][b]); + } } + + data += 2; } } diff --git a/textscreen/txt_inputbox.c b/textscreen/txt_inputbox.c index 11029e4b..cb7bf4fa 100644 --- a/textscreen/txt_inputbox.c +++ b/textscreen/txt_inputbox.c @@ -12,21 +12,24 @@ static void SetBufferFromValue(txt_inputbox_t *inputbox); -static void TXT_InputBoxSizeCalc(TXT_UNCAST_ARG(inputbox), int *w, int *h) +static void TXT_InputBoxSizeCalc(TXT_UNCAST_ARG(inputbox)) { TXT_CAST_ARG(txt_inputbox_t, inputbox); // Enough space for the box + cursor - *w = inputbox->size + 1; - *h = 1; + inputbox->widget.w = inputbox->size + 1; + inputbox->widget.h = 1; } -static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox), int w, int selected) +static void TXT_InputBoxDrawer(TXT_UNCAST_ARG(inputbox), int selected) { TXT_CAST_ARG(txt_inputbox_t, inputbox); int i; int chars; + int w; + + w = inputbox->widget.w; // Select the background colour based on whether we are currently // editing, and if not, whether the widget is selected. diff --git a/textscreen/txt_label.c b/textscreen/txt_label.c index f92eba82..cff3bb69 100644 --- a/textscreen/txt_label.c +++ b/textscreen/txt_label.c @@ -7,20 +7,23 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_LabelSizeCalc(TXT_UNCAST_ARG(label), int *w, int *h) +static void TXT_LabelSizeCalc(TXT_UNCAST_ARG(label)) { TXT_CAST_ARG(txt_label_t, label); - *w = label->w; - *h = label->h; + label->widget.w = label->w; + label->widget.h = label->h; } -static void TXT_LabelDrawer(TXT_UNCAST_ARG(label), int w, int selected) +static void TXT_LabelDrawer(TXT_UNCAST_ARG(label), int selected) { TXT_CAST_ARG(txt_label_t, label); int x, y; int origin_x, origin_y; int align_indent; + int w; + + w = label->widget.w; TXT_BGColor(label->bgcolor, 0); TXT_FGColor(label->fgcolor); diff --git a/textscreen/txt_main.c b/textscreen/txt_main.c index ad766c61..9e9f4231 100644 --- a/textscreen/txt_main.c +++ b/textscreen/txt_main.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: txt_main.c 533 2006-05-26 19:15:05Z fraggle $ +// $Id: txt_main.c 547 2006-06-02 19:29:24Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -185,6 +185,14 @@ void TXT_UpdateScreen(void) TXT_UpdateScreenArea(0, 0, TXT_SCREEN_W, TXT_SCREEN_H); } +void TXT_GetMousePosition(int *x, int *y) +{ + SDL_GetMouseState(x, y); + + *x /= CHAR_W; + *y /= CHAR_H; +} + // // Translates the SDL key // diff --git a/textscreen/txt_main.h b/textscreen/txt_main.h index 5a4b8a1c..43c5475b 100644 --- a/textscreen/txt_main.h +++ b/textscreen/txt_main.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: txt_main.h 513 2006-05-23 00:04:27Z fraggle $ +// $Id: txt_main.h 547 2006-06-02 19:29:24Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -101,5 +101,9 @@ int TXT_GetChar(void); void TXT_GetKeyDescription(int key, char *buf); +// Retrieve the current position of the mouse + +void TXT_GetMouseState(int *x, int *y); + #endif /* #ifndef TXT_MAIN_H */ diff --git a/textscreen/txt_radiobutton.c b/textscreen/txt_radiobutton.c index e221896e..d5f694f7 100644 --- a/textscreen/txt_radiobutton.c +++ b/textscreen/txt_radiobutton.c @@ -9,20 +9,23 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_RadioButtonSizeCalc(TXT_UNCAST_ARG(radiobutton), int *w, int *h) +static void TXT_RadioButtonSizeCalc(TXT_UNCAST_ARG(radiobutton)) { TXT_CAST_ARG(txt_radiobutton_t, radiobutton); // Minimum width is the string length + two spaces for padding - *w = strlen(radiobutton->label) + 6; - *h = 1; + radiobutton->widget.w = strlen(radiobutton->label) + 6; + radiobutton->widget.h = 1; } -static void TXT_RadioButtonDrawer(TXT_UNCAST_ARG(radiobutton), int w, int selected) +static void TXT_RadioButtonDrawer(TXT_UNCAST_ARG(radiobutton), int selected) { TXT_CAST_ARG(txt_radiobutton_t, radiobutton); int i; + int w; + + w = radiobutton->widget.w; TXT_BGColor(TXT_COLOR_BLUE, 0); TXT_FGColor(TXT_COLOR_BRIGHT_CYAN); diff --git a/textscreen/txt_separator.c b/textscreen/txt_separator.c index 3258c400..1cba708e 100644 --- a/textscreen/txt_separator.c +++ b/textscreen/txt_separator.c @@ -7,7 +7,7 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator), int *w, int *h) +static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator)) { TXT_CAST_ARG(txt_separator_t, separator); @@ -15,21 +15,24 @@ static void TXT_SeparatorSizeCalc(TXT_UNCAST_ARG(separator), int *w, int *h) { // Minimum width is the string length + two spaces for padding - *w = strlen(separator->label) + 2; + separator->widget.w = strlen(separator->label) + 2; } else { - *w = 0; + separator->widget.w = 0; } - *h = 1; + separator->widget.h = 1; } -static void TXT_SeparatorDrawer(TXT_UNCAST_ARG(separator), int w, int selected) +static void TXT_SeparatorDrawer(TXT_UNCAST_ARG(separator), int selected) { TXT_CAST_ARG(txt_separator_t, separator); int i; int x, y; + int w; + + w = separator->widget.w; TXT_GetXY(&x, &y); diff --git a/textscreen/txt_strut.c b/textscreen/txt_strut.c index 0d827b5a..0a0b402b 100644 --- a/textscreen/txt_strut.c +++ b/textscreen/txt_strut.c @@ -9,17 +9,17 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_StrutSizeCalc(TXT_UNCAST_ARG(strut), int *w, int *h) +static void TXT_StrutSizeCalc(TXT_UNCAST_ARG(strut)) { TXT_CAST_ARG(txt_strut_t, strut); // Minimum width is the string length + two spaces for padding - *w = strut->width; - *h = strut->height; + strut->widget.w = strut->width; + strut->widget.h = strut->height; } -static void TXT_StrutDrawer(TXT_UNCAST_ARG(strut), int w, int selected) +static void TXT_StrutDrawer(TXT_UNCAST_ARG(strut), int selected) { // Nothing is drawn for a strut. } diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c index e410d4df..86aea997 100644 --- a/textscreen/txt_table.c +++ b/textscreen/txt_table.c @@ -65,7 +65,6 @@ static void CalcRowColSizes(txt_table_t *table, int table_height; int x, y; int rows; - int ww, wh; txt_widget_t *widget; rows = TableRows(table); @@ -83,27 +82,21 @@ static void CalcRowColSizes(txt_table_t *table, widget = table->widgets[y * table->columns + x]; + // NULL represents an empty spacer + if (widget != NULL) { - TXT_CalcWidgetSize(widget, &ww, &wh); - } - else - { - // Empty spacer if widget is NULL - - ww = 0; - wh = 0; + TXT_CalcWidgetSize(widget); + if (widget->h > row_heights[y]) + row_heights[y] = widget->h; + if (widget->w > col_widths[x]) + col_widths[x] = widget->w; } - - if (wh > row_heights[y]) - row_heights[y] = wh; - if (ww > col_widths[x]) - col_widths[x] = ww; } } } -static void TXT_CalcTableSize(TXT_UNCAST_ARG(table), int *w, int *h) +static void TXT_CalcTableSize(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); int *column_widths; @@ -118,18 +111,18 @@ static void TXT_CalcTableSize(TXT_UNCAST_ARG(table), int *w, int *h) CalcRowColSizes(table, row_heights, column_widths); - *w = 0; + table->widget.w = 0; for (x=0; x<table->columns; ++x) { - *w += column_widths[x]; + table->widget.w += column_widths[x]; } - *h = 0; + table->widget.h = 0; for (y=0; y<rows; ++y) { - *h += row_heights[y]; + table->widget.h += row_heights[y]; } free(row_heights); @@ -354,68 +347,64 @@ static void CheckValidSelection(txt_table_t *table) } } -static void DrawCell(txt_table_t *table, int x, int y, - int draw_x, int draw_y, int w, int selected) +static void LayoutCell(txt_table_t *table, int x, int y, int col_width, + int draw_x, int draw_y) { txt_widget_t *widget; - int cw, ch; widget = table->widgets[y * table->columns + x]; + // Adjust x position based on alignment property + switch (widget->align) { case TXT_HORIZ_LEFT: + widget->w = col_width; break; case TXT_HORIZ_CENTER: - TXT_CalcWidgetSize(widget, &cw, &ch); + TXT_CalcWidgetSize(widget); // Separators are always drawn left-aligned. if (widget->widget_class != &txt_separator_class) { - draw_x += (w - cw) / 2; - w = cw; + draw_x += (col_width - widget->w) / 2; } break; case TXT_HORIZ_RIGHT: - TXT_CalcWidgetSize(widget, &cw, &ch); + TXT_CalcWidgetSize(widget); if (widget->widget_class != &txt_separator_class) { - draw_x += w - cw; - w = cw; + draw_x += col_width - widget->w; } break; } - TXT_GotoXY(draw_x, draw_y); + // Set the position for this widget + + widget->x = draw_x; + widget->y = draw_y; + + // Recursively lay out any widgets contained in the widget - TXT_DrawWidget(widget, w, selected && x == table->selected_x - && y == table->selected_y); + TXT_LayoutWidget(widget); } -static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected) +static void TXT_TableLayout(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); 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 - // drawing. - - CheckValidSelection(table); - - TXT_GetXY(&origin_x, &origin_y); - // Work out the column widths and row heights rows = TableRows(table); @@ -431,16 +420,16 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected) if (table->columns == 1) { - column_widths[0] = w; + column_widths[0] = table->widget.w; } // Draw all cells - draw_y = origin_y; + draw_y = table->widget.y; for (y=0; y<rows; ++y) { - draw_x = origin_x; + draw_x = table->widget.x; for (x=0; x<table->columns; ++x) { @@ -451,8 +440,8 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected) if (table->widgets[i] != NULL) { - DrawCell(table, x, y, draw_x, draw_y, - column_widths[x], selected); + LayoutCell(table, x, y, column_widths[x], + draw_x, draw_y); } draw_x += column_widths[x]; @@ -464,6 +453,75 @@ static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int w, int selected) free(row_heights); free(column_widths); } + +static void TXT_TableDrawer(TXT_UNCAST_ARG(table), int selected) +{ + TXT_CAST_ARG(txt_table_t, table); + txt_widget_t *widget; + int selected_cell; + int i; + + // Check the table's current selection points at something valid before + // drawing. + + CheckValidSelection(table); + + // Find the index of the currently-selected widget. + + selected_cell = table->selected_y * table->columns + table->selected_x; + + // Draw all cells + + for (i=0; i<table->num_widgets; ++i) + { + widget = table->widgets[i]; + + if (widget != NULL) + { + TXT_GotoXY(widget->x, widget->y); + TXT_DrawWidget(widget, selected && i == selected_cell); + } + } +} + +// Responds to mouse presses + +static void TXT_TableMousePress(TXT_UNCAST_ARG(table), int x, int y, int b) +{ + TXT_CAST_ARG(txt_table_t, table); + txt_widget_t *widget; + int i; + + for (i=0; i<table->num_widgets; ++i) + { + widget = table->widgets[i]; + + // NULL widgets are spacers + + if (widget != NULL) + { + if (x >= widget->x && x < widget->x + widget->w + && y >= widget->y && y < widget->y + widget->h) + { + // This is the widget that was clicked! + + // Select the cell if the widget is selectable + + if (widget->selectable) + { + table->selected_x = i % table->columns; + table->selected_y = i / table->columns; + } + + // Propagate click + + TXT_WidgetMousePress(widget, x, y, b); + + break; + } + } + } +} txt_widget_class_t txt_table_class = { @@ -471,6 +529,8 @@ txt_widget_class_t txt_table_class = TXT_TableDrawer, TXT_TableKeyPress, TXT_TableDestructor, + TXT_TableMousePress, + TXT_TableLayout, }; void TXT_InitTable(txt_table_t *table, int columns) diff --git a/textscreen/txt_widget.c b/textscreen/txt_widget.c index 8411ac5b..3ca92c9a 100644 --- a/textscreen/txt_widget.c +++ b/textscreen/txt_widget.c @@ -112,18 +112,24 @@ void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name) } } -void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget), int *w, int *h) +void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget)) { TXT_CAST_ARG(txt_widget_t, widget); - return widget->widget_class->size_calc(widget, w, h); + widget->widget_class->size_calc(widget); } -void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int w, int selected) +void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int selected) { TXT_CAST_ARG(txt_widget_t, widget); - widget->widget_class->drawer(widget, w, selected); + // For convenience... + + TXT_GotoXY(widget->x, widget->y); + + // Call drawer method + + widget->widget_class->drawer(widget, selected); } void TXT_DestroyWidget(TXT_UNCAST_ARG(widget)) @@ -154,4 +160,23 @@ void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align) widget->align = horiz_align; } +void TXT_WidgetMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b) +{ + TXT_CAST_ARG(txt_widget_t, widget); + + if (widget->widget_class->mouse_press != NULL) + { + widget->widget_class->mouse_press(widget, x, y, b); + } +} + +void TXT_LayoutWidget(TXT_UNCAST_ARG(widget)) +{ + TXT_CAST_ARG(txt_widget_t, widget); + + if (widget->widget_class->layout != NULL) + { + widget->widget_class->layout(widget); + } +} diff --git a/textscreen/txt_widget.h b/textscreen/txt_widget.h index 46fd3745..ee18fd14 100644 --- a/textscreen/txt_widget.h +++ b/textscreen/txt_widget.h @@ -48,11 +48,13 @@ 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; -typedef void (*TxtWidgetSizeCalc)(TXT_UNCAST_ARG(widget), int *w, int *h); -typedef void (*TxtWidgetDrawer)(TXT_UNCAST_ARG(widget), int w, int selected); +typedef void (*TxtWidgetSizeCalc)(TXT_UNCAST_ARG(widget)); +typedef void (*TxtWidgetDrawer)(TXT_UNCAST_ARG(widget), int selected); typedef void (*TxtWidgetDestroy)(TXT_UNCAST_ARG(widget)); typedef int (*TxtWidgetKeyPress)(TXT_UNCAST_ARG(widget), int key); typedef void (*TxtWidgetSignalFunc)(TXT_UNCAST_ARG(widget), void *user_data); +typedef void (*TxtMousePressFunc)(TXT_UNCAST_ARG(widget), int x, int y, int b); +typedef void (*TxtWidgetLayoutFunc)(TXT_UNCAST_ARG(widget)); struct txt_widget_class_s { @@ -60,6 +62,8 @@ struct txt_widget_class_s TxtWidgetDrawer drawer; TxtWidgetKeyPress key_press; TxtWidgetDestroy destructor; + TxtMousePressFunc mouse_press; + TxtWidgetLayoutFunc layout; }; struct txt_widget_s @@ -69,17 +73,25 @@ struct txt_widget_s int selectable; int visible; txt_horiz_align_t align; + + // These are set automatically when the window is drawn and should + // not be set manually. + + int x, y; + int w, h; }; void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class); -void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget), int *w, int *h); -void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int w, int selected); +void TXT_CalcWidgetSize(TXT_UNCAST_ARG(widget)); +void TXT_DrawWidget(TXT_UNCAST_ARG(widget), int selected); void TXT_SignalConnect(TXT_UNCAST_ARG(widget), char *signal_name, TxtWidgetSignalFunc func, void *user_data); void TXT_EmitSignal(TXT_UNCAST_ARG(widget), char *signal_name); int TXT_WidgetKeyPress(TXT_UNCAST_ARG(widget), int key); +void TXT_WidgetMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b); void TXT_DestroyWidget(TXT_UNCAST_ARG(widget)); void TXT_SetWidgetAlign(TXT_UNCAST_ARG(widget), txt_horiz_align_t horiz_align); +void TXT_LayoutWidget(TXT_UNCAST_ARG(widget)); #endif /* #ifndef TXT_WIDGET_H */ diff --git a/textscreen/txt_window.c b/textscreen/txt_window.c index 9c1f0257..f04b8c68 100644 --- a/textscreen/txt_window.c +++ b/textscreen/txt_window.c @@ -1,11 +1,3 @@ -// 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 @@ -64,7 +56,15 @@ txt_window_t *TXT_NewWindow(char *title) TXT_InitTable(&win->table, 1); - win->title = strdup(title); + if (title == NULL) + { + win->title = NULL; + } + else + { + win->title = strdup(title); + } + win->x = TXT_SCREEN_W / 2; win->y = TXT_SCREEN_H / 2; win->horiz_align = TXT_HORIZ_CENTER; @@ -111,73 +111,92 @@ void TXT_CloseWindow(txt_window_t *window) TXT_RemoveDesktopWindow(window); } -static void CalcWindowPosition(txt_window_t *window, - int *x, int *y, - int w, int h) +static void CalcWindowPosition(txt_window_t *window) { switch (window->horiz_align) { case TXT_HORIZ_LEFT: - *x = window->x; + window->window_x = window->x; break; case TXT_HORIZ_CENTER: - *x = window->x - (w / 2); + window->window_x = window->x - (window->window_w / 2); break; case TXT_HORIZ_RIGHT: - *x = window->x - (w - 1); + window->window_x = window->x - (window->window_w - 1); break; } switch (window->vert_align) { case TXT_VERT_TOP: - *y = window->y; + window->window_y = window->y; break; case TXT_VERT_CENTER: - *y = window->y - (h / 2); + window->window_y = window->y - (window->window_h / 2); break; case TXT_VERT_BOTTOM: - *y = window->y - (h - 1); + window->window_y = window->y - (window->window_h - 1); break; } } -static void DrawActionArea(txt_window_t *window, - int window_x, int window_y, - int window_w, int window_h) +static void LayoutActionArea(txt_window_t *window) { - int ww, wh; + txt_widget_t *widget; - // Draw the left action + // Left action if (window->actions[TXT_HORIZ_LEFT] != NULL) { - TXT_GotoXY(window_x + 2, window_y + window_h - 2); - TXT_DrawWidget(window->actions[TXT_HORIZ_LEFT], 0, 0); + widget = (txt_widget_t *) window->actions[TXT_HORIZ_LEFT]; + + TXT_CalcWidgetSize(widget); + + widget->x = window->window_x + 2; + widget->y = window->window_y + window->window_h - 2; } // Draw the center action if (window->actions[TXT_HORIZ_CENTER] != NULL) { - TXT_CalcWidgetSize(window->actions[TXT_HORIZ_CENTER], &ww, &wh); - TXT_GotoXY(window_x + (window_w - ww - 2) / 2, window_y + window_h - 2); - TXT_DrawWidget(window->actions[TXT_HORIZ_CENTER], 0, 0); + widget = (txt_widget_t *) window->actions[TXT_HORIZ_CENTER]; + + TXT_CalcWidgetSize(widget); + + widget->x = window->window_x + (window->window_w - widget->w - 2) / 2; + widget->y = window->window_y + window->window_h - 2; } // Draw the right action if (window->actions[TXT_HORIZ_RIGHT] != NULL) { - TXT_CalcWidgetSize(window->actions[TXT_HORIZ_RIGHT], &ww, &wh); - TXT_GotoXY(window_x + window_w - 2 - ww, window_y + window_h - 2); - TXT_DrawWidget(window->actions[TXT_HORIZ_RIGHT], 0, 0); + widget = (txt_widget_t *) window->actions[TXT_HORIZ_RIGHT]; + + TXT_CalcWidgetSize(widget); + + widget->x = window->window_x + window->window_w - 2 - widget->w; + widget->y = window->window_y + window->window_h - 2; } } -static int CalcActionAreaWidth(txt_window_t *window, int *widgets_w) +static void DrawActionArea(txt_window_t *window) { - int ww, wh; + int i; + + for (i=0; i<3; ++i) + { + if (window->actions[i] != NULL) + { + TXT_DrawWidget(window->actions[i], 0); + } + } +} + +static int ActionAreaWidth(txt_window_t *window) +{ + txt_widget_t *widget; int w; int i; @@ -188,57 +207,99 @@ static int CalcActionAreaWidth(txt_window_t *window, int *widgets_w) for (i=0; i<3; ++i) { - if (window->actions[i] != NULL) + widget = (txt_widget_t *) window->actions[i]; + + if (widget != NULL) { - TXT_CalcWidgetSize(window->actions[i], &ww, &wh); - w += ww + 1; + TXT_CalcWidgetSize(widget); + w += widget->w + 1; } } - // If this is larger than the window size, adjust the window to fit. - - if (w > *widgets_w) - *widgets_w = w; + return w; } -void TXT_DrawWindow(txt_window_t *window) +// Sets size and position of all widgets in a window + +void TXT_LayoutWindow(txt_window_t *window) { - int widgets_w, widgets_h; - int window_w, window_h; - int x, y; - int window_x, window_y; - int i; - int ww, wh; + txt_widget_t *widgets = (txt_widget_t *) window; + int widgets_w; + int actionarea_w; + + // Calculate size of table + + TXT_CalcWidgetSize(window); + + // Calculate the size of the action area + + actionarea_w = ActionAreaWidth(window); - TXT_CalcWidgetSize(window, &widgets_w, &widgets_h); - CalcActionAreaWidth(window, &widgets_w); + // Which one is larger? + + widgets_w = widgets->w; + + if (actionarea_w > widgets_w) + widgets_w = actionarea_w; - // Actual window size after padding + // Set the window size based on widgets_w + + window->window_w = widgets_w + 2; + window->window_h = widgets->h + 3; - window_w = widgets_w + 2; - window_h = widgets_h + 5; + // If the window has a title, add an extra two lines + + if (window->title != NULL) + { + window->window_h += 2; + } // Use the x,y position as the centerpoint and find the location to // draw the window. - CalcWindowPosition(window, &window_x, &window_y, window_w, window_h); + CalcWindowPosition(window); + + // Set the table size and position + + widgets->w = widgets_w; + // widgets->h (already set) + widgets->x = window->window_x + 1; + widgets->y = window->window_y + window->window_h - widgets->h - 3; + // Layout the table and action area + + LayoutActionArea(window); + TXT_LayoutWidget(widgets); +} + +void TXT_DrawWindow(txt_window_t *window) +{ + txt_widget_t *widgets; + int x, y; + int i; + int ww, wh; + + TXT_LayoutWindow(window); + // Draw the window - TXT_DrawWindowFrame(window->title, window_x, window_y, window_w, window_h); + TXT_DrawWindowFrame(window->title, + window->window_x, window->window_y, + window->window_w, window->window_h); // Draw all widgets - TXT_GotoXY(window_x + 1, window_y + 2); - TXT_DrawWidget(window, widgets_w, 1); + TXT_DrawWidget(window, 1); // Separator for action area - TXT_DrawSeparator(window_x, window_y + 2 + widgets_h, window_w); + widgets = (txt_widget_t *) window; + + TXT_DrawSeparator(window->window_x, widgets->y + widgets->h, widgets->w); // Action area at the window bottom - DrawActionArea(window, window_x, window_y, window_w, window_h); + DrawActionArea(window); } void TXT_SetWindowPosition(txt_window_t *window, @@ -252,9 +313,41 @@ void TXT_SetWindowPosition(txt_window_t *window, window->y = y; } +static void MouseButtonPress(txt_window_t *window, int b) +{ + int x, y; + txt_widget_t *widgets; + + // Lay out the window, set positions and sizes of all widgets + + TXT_LayoutWindow(window); + + // Get the current mouse position + + TXT_GetMousePosition(&x, &y); + + // Is it within the table range? + + widgets = (txt_widget_t *) window; + + if (x >= widgets->x && x < widgets->x + widgets->w + && y >= widgets->y && y < widgets->y + widgets->h) + { + TXT_WidgetMousePress(window, x, y, b); + } +} + void TXT_WindowKeyPress(txt_window_t *window, int c) { int i; + + // Is this a mouse button ? + + if (c == TXT_MOUSE_LEFT) + { + MouseButtonPress(window, c); + return; + } // Send to the currently selected widget first diff --git a/textscreen/txt_window.h b/textscreen/txt_window.h index 583c76ef..5e01a16d 100644 --- a/textscreen/txt_window.h +++ b/textscreen/txt_window.h @@ -50,6 +50,11 @@ struct txt_window_s // Actions that appear in the box at the bottom of the window txt_window_action_t *actions[3]; + + // These are set automatically when the window is drawn + + int window_x, window_y; + int window_w, window_h; }; txt_window_t *TXT_NewWindow(char *title); diff --git a/textscreen/txt_window_action.c b/textscreen/txt_window_action.c index 2cffb8a6..d7b82f68 100644 --- a/textscreen/txt_window_action.c +++ b/textscreen/txt_window_action.c @@ -9,8 +9,7 @@ #include "txt_main.h" #include "txt_window.h" -static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action), - int *w, int *h) +static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action)) { TXT_CAST_ARG(txt_window_action_t, action); char buf[10]; @@ -19,11 +18,11 @@ static void TXT_WindowActionSizeCalc(TXT_UNCAST_ARG(action), // Minimum width is the string length + two spaces for padding - *w = strlen(action->label) + strlen(buf) + 1; - *h = 1; + action->widget.w = strlen(action->label) + strlen(buf) + 1; + action->widget.h = 1; } -static void TXT_WindowActionDrawer(TXT_UNCAST_ARG(action), int w, int selected) +static void TXT_WindowActionDrawer(TXT_UNCAST_ARG(action), int selected) { TXT_CAST_ARG(txt_window_action_t, action); int i; |