ref: 9f3f6683d929d118b18e21b06a0b729586569e1a
parent: f596cfcd76c8c03c41c0691561c9b3c9c4419393
author: Simon Howard <fraggle@gmail.com>
date: Mon Apr 4 16:07:07 EDT 2011
Change the background color when hovering over widgets. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2320
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,8 @@
match the game default (thanks Alexandre Xavier).
libtextscreen:
+ * The background on GUI controls now lights up when hovering over
+ them, so that it is more obvious what you are selecting.
* It is now possible to type a '+' in input boxes (thanks
Alexandre Xavier).
* It is possible to use the mouse wheel to scroll through scroll
--- a/setup/txt_joybinput.c
+++ b/setup/txt_joybinput.c
@@ -153,15 +153,7 @@
GetJoystickButtonDescription(*joystick_input->variable, buf);
}
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
- else
- {
- TXT_BGColor(TXT_COLOR_BLUE, 0);
- }
-
+ TXT_SetWidgetBG(joystick_input, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(buf);
--- a/setup/txt_keyinput.c
+++ b/setup/txt_keyinput.c
@@ -118,15 +118,7 @@
TXT_GetKeyDescription(*key_input->variable, buf);
}
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
- else
- {
- TXT_BGColor(TXT_COLOR_BLUE, 0);
- }
-
+ TXT_SetWidgetBG(key_input, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(buf);
--- a/setup/txt_mouseinput.c
+++ b/setup/txt_mouseinput.c
@@ -111,15 +111,7 @@
GetMouseButtonDescription(*mouse_input->variable, buf);
}
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
- else
- {
- TXT_BGColor(TXT_COLOR_BLUE, 0);
- }
-
+ TXT_SetWidgetBG(mouse_input, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(buf);
--- a/textscreen/txt_button.c
+++ b/textscreen/txt_button.c
@@ -46,16 +46,12 @@
w = button->widget.w;
- TXT_BGColor(TXT_COLOR_BLUE, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
+ TXT_SetWidgetBG(button, selected);
TXT_DrawString(button->label);
-
+
for (i=strlen(button->label); i < w; ++i)
{
TXT_DrawString(" ");
--- a/textscreen/txt_checkbox.c
+++ b/textscreen/txt_checkbox.c
@@ -48,7 +48,7 @@
w = checkbox->widget.w;
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
TXT_DrawString("(");
@@ -67,11 +67,7 @@
TXT_DrawString(") ");
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
-
+ TXT_SetWidgetBG(checkbox, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(checkbox->label);
--- a/textscreen/txt_desktop.c
+++ b/textscreen/txt_desktop.c
@@ -61,6 +61,16 @@
num_windows = to;
}
+txt_window_t *TXT_GetActiveWindow(void)
+{
+ if (num_windows == 0)
+ {
+ return NULL;
+ }
+
+ return all_windows[num_windows - 1];
+}
+
static void DrawDesktopBackground(const char *title)
{
int i;
--- a/textscreen/txt_desktop.h
+++ b/textscreen/txt_desktop.h
@@ -63,6 +63,15 @@
void TXT_GUIMainLoop(void);
+/**
+ * Get the top window on the desktop that is currently receiving
+ * inputs.
+ *
+ * @return The active window, or NULL if no windows are present.
+ */
+
+txt_window_t *TXT_GetActiveWindow(void);
+
#endif /* #ifndef TXT_DESKTOP_H */
--- a/textscreen/txt_dropdown.c
+++ b/textscreen/txt_dropdown.c
@@ -197,15 +197,7 @@
// Set bg/fg text colors.
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
- else
- {
- TXT_BGColor(TXT_COLOR_BLUE, 0);
- }
-
+ TXT_SetWidgetBG(list, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
// Select a string to draw from the list, if the current value is
--- a/textscreen/txt_gui.c
+++ b/textscreen/txt_gui.c
@@ -131,7 +131,7 @@
int bx, by;
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
for (y1=y; y1<y+h; ++y1)
{
@@ -191,7 +191,7 @@
data = TXT_GetScreenData();
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
if (!VALID_Y(y))
{
--- a/textscreen/txt_gui.h
+++ b/textscreen/txt_gui.h
@@ -27,6 +27,9 @@
#ifndef TXT_GUI_H
#define TXT_GUI_H
+#define TXT_WINDOW_BACKGROUND TXT_COLOR_BLUE
+#define TXT_HOVER_BACKGROUND TXT_COLOR_CYAN
+
void TXT_DrawDesktopBackground(const char *title);
void TXT_DrawWindowFrame(const char *title, int x, int y, int w, int h);
void TXT_DrawSeparator(int x, int y, int w);
@@ -34,6 +37,7 @@
void TXT_DrawHorizScrollbar(int x, int y, int w, int cursor, int range);
void TXT_DrawVertScrollbar(int x, int y, int h, int cursor, int range);
+
void TXT_InitClipArea(void);
void TXT_PushClipArea(int x1, int x2, int y1, int y2);
--- a/textscreen/txt_inputbox.c
+++ b/textscreen/txt_inputbox.c
@@ -60,15 +60,9 @@
{
TXT_BGColor(TXT_COLOR_BLACK, 0);
}
- else if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
else
{
- // Not even selected
-
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_SetWidgetBG(inputbox, selected);
}
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
--- a/textscreen/txt_label.c
+++ b/textscreen/txt_label.c
@@ -176,7 +176,7 @@
// Default colors
- label->bgcolor = TXT_COLOR_BLUE;
+ label->bgcolor = TXT_WINDOW_BACKGROUND;
label->fgcolor = TXT_COLOR_BRIGHT_WHITE;
TXT_SetLabel(label, text);
--- a/textscreen/txt_radiobutton.c
+++ b/textscreen/txt_radiobutton.c
@@ -48,7 +48,7 @@
w = radiobutton->widget.w;
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
TXT_DrawString("(");
@@ -67,11 +67,7 @@
TXT_DrawString(") ");
- if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
-
+ TXT_SetWidgetBG(radiobutton, selected);
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(radiobutton->label);
--- a/textscreen/txt_scrollpane.c
+++ b/textscreen/txt_scrollpane.c
@@ -557,6 +557,10 @@
scrollpane->expand_w = w <= 0;
scrollpane->expand_h = h <= 0;
+ // Set parent pointer for inner widget.
+
+ target->parent = &scrollpane->widget;
+
return scrollpane;
}
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -221,7 +221,7 @@
// Ignore all mouse motion events
- SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
+// SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
// Repeat key presses so we can hold down arrows to scroll down the
// menu, for example. This is what setup.exe does.
@@ -475,6 +475,24 @@
}
}
+static int MouseHasMoved(void)
+{
+ static int last_x = 0, last_y = 0;
+ int x, y;
+
+ TXT_GetMousePosition(&x, &y);
+
+ if (x != last_x || y != last_y)
+ {
+ last_x = x; last_y = y;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
signed int TXT_GetChar(void)
{
SDL_Event ev;
@@ -509,6 +527,12 @@
case SDL_QUIT:
// Quit = escape
return 27;
+
+ case SDL_MOUSEMOTION:
+ if (MouseHasMoved())
+ {
+ return 0;
+ }
default:
break;
--- a/textscreen/txt_separator.c
+++ b/textscreen/txt_separator.c
@@ -65,7 +65,7 @@
{
TXT_GotoXY(x, y);
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
TXT_FGColor(TXT_COLOR_BRIGHT_GREEN);
TXT_DrawString(" ");
TXT_DrawString(separator->label);
--- a/textscreen/txt_spinctrl.c
+++ b/textscreen/txt_spinctrl.c
@@ -149,7 +149,7 @@
unsigned int padding;
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
TXT_DrawString("\x1b ");
@@ -161,13 +161,9 @@
{
TXT_BGColor(TXT_COLOR_BLACK, 0);
}
- else if (selected)
- {
- TXT_BGColor(TXT_COLOR_GREY, 0);
- }
else
{
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_SetWidgetBG(spincontrol, selected);
}
if (!spincontrol->editing)
@@ -195,7 +191,7 @@
}
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
- TXT_BGColor(TXT_COLOR_BLUE, 0);
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
TXT_DrawString(" \x1a");
}
--- a/textscreen/txt_table.c
+++ b/textscreen/txt_table.c
@@ -173,6 +173,10 @@
sizeof(txt_widget_t *) * (table->num_widgets + 1));
table->widgets[table->num_widgets] = widget;
++table->num_widgets;
+
+ // Maintain parent pointer.
+
+ widget->parent = &table->widget;
}
// Add multiple widgets to a table.
--- a/textscreen/txt_widget.c
+++ b/textscreen/txt_widget.c
@@ -24,6 +24,8 @@
#include "txt_io.h"
#include "txt_widget.h"
+#include "txt_gui.h"
+#include "txt_desktop.h"
typedef struct
{
@@ -82,6 +84,7 @@
widget->widget_class = widget_class;
widget->callback_table = TXT_NewCallbackTable();
+ widget->parent = NULL;
// Visible by default.
@@ -234,6 +237,65 @@
else
{
return 0;
+ }
+}
+
+int TXT_ContainsWidget(TXT_UNCAST_ARG(haystack), TXT_UNCAST_ARG(needle))
+{
+ TXT_CAST_ARG(txt_widget_t, haystack);
+ TXT_CAST_ARG(txt_widget_t, needle);
+
+ while (needle != NULL)
+ {
+ if (needle == haystack)
+ {
+ return 1;
+ }
+
+ needle = needle->parent;
+ }
+
+ return 0;
+}
+
+int TXT_HoveringOverWidget(TXT_UNCAST_ARG(widget))
+{
+ TXT_CAST_ARG(txt_widget_t, widget);
+ txt_window_t *active_window;
+ int x, y;
+
+ // We can only be hovering over widgets in the active window.
+
+ active_window = TXT_GetActiveWindow();
+
+ if (active_window == NULL || !TXT_ContainsWidget(active_window, widget))
+ {
+ return 0;
+ }
+
+ // Is the mouse cursor within the bounds of the widget?
+
+ TXT_GetMousePosition(&x, &y);
+
+ return (x >= widget->x && x < widget->x + widget->w
+ && y >= widget->y && y < widget->y + widget->h);
+}
+
+void TXT_SetWidgetBG(TXT_UNCAST_ARG(widget), int selected)
+{
+ TXT_CAST_ARG(txt_widget_t, widget);
+
+ if (selected)
+ {
+ TXT_BGColor(TXT_COLOR_GREY, 0);
+ }
+ else if (TXT_HoveringOverWidget(widget))
+ {
+ TXT_BGColor(TXT_HOVER_BACKGROUND, 0);
+ }
+ else
+ {
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
}
}
--- a/textscreen/txt_widget.h
+++ b/textscreen/txt_widget.h
@@ -102,6 +102,10 @@
int x, y;
unsigned int w, h;
+
+ // Pointer up to parent widget that contains this widget.
+
+ txt_widget_t *parent;
};
void TXT_InitWidget(TXT_UNCAST_ARG(widget), txt_widget_class_t *widget_class);
@@ -146,6 +150,34 @@
int TXT_SelectableWidget(TXT_UNCAST_ARG(widget));
-#endif /* #ifndef TXT_WIDGET_H */
+/**
+ * Query whether the mouse is hovering over the specified widget.
+ *
+ * @param widget The widget.
+ * @return Non-zero if the mouse cursor is over the widget.
+ */
+int TXT_HoveringOverWidget(TXT_UNCAST_ARG(widget));
+
+/**
+ * Set the background to draw the specified widget, depending on
+ * whether it is selected and the mouse is hovering over it.
+ *
+ * @param widget The widget.
+ * @param selected Whether the widget is selected.
+ */
+
+void TXT_SetWidgetBG(TXT_UNCAST_ARG(widget), int selected);
+
+/**
+ * Query whether the specified widget is contained within another
+ * widget.
+ *
+ * @param haystack The widget that might contain needle.
+ * @param needle The widget being queried.
+ */
+
+int TXT_ContainsWidget(TXT_UNCAST_ARG(haystack), TXT_UNCAST_ARG(needle));
+
+#endif /* #ifndef TXT_WIDGET_H */
--- a/textscreen/txt_window.c
+++ b/textscreen/txt_window.c
@@ -40,6 +40,10 @@
}
window->actions[position] = action;
+
+ // Maintain parent pointer.
+
+ action->widget.parent = &window->table.widget;
}
txt_window_t *TXT_NewWindow(char *title)
@@ -158,7 +162,7 @@
TXT_CalcWidgetSize(widget);
- widget->x = window->window_x + 2;
+ widget->x = window->window_x + 1;
widget->y = window->window_y + window->window_h - widget->h - 1;
// Adjust available space:
@@ -175,7 +179,7 @@
TXT_CalcWidgetSize(widget);
- widget->x = window->window_x + window->window_w - 2 - widget->w;
+ widget->x = window->window_x + window->window_w - 1 - widget->w;
widget->y = window->window_y + window->window_h - widget->h - 1;
// Adjust available space:
--- a/textscreen/txt_window_action.c
+++ b/textscreen/txt_window_action.c
@@ -37,9 +37,10 @@
TXT_GetKeyDescription(action->key, buf);
- // Minimum width is the string length + two spaces for padding
+ // Width is label length, plus key description length, plus '='
+ // and two surrounding spaces.
- action->widget.w = strlen(action->label) + strlen(buf) + 1;
+ action->widget.w = strlen(action->label) + strlen(buf) + 3;
action->widget.h = 1;
}
@@ -50,12 +51,24 @@
TXT_GetKeyDescription(action->key, buf);
+ if (TXT_HoveringOverWidget(action))
+ {
+ TXT_BGColor(TXT_COLOR_BLACK, 0);
+ }
+ else
+ {
+ TXT_BGColor(TXT_WINDOW_BACKGROUND, 0);
+ }
+
+ TXT_DrawString(" ");
TXT_FGColor(TXT_COLOR_BRIGHT_GREEN);
TXT_DrawString(buf);
TXT_FGColor(TXT_COLOR_BRIGHT_CYAN);
TXT_DrawString("=");
+
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_DrawString(action->label);
+ TXT_DrawString(" ");
}
static void TXT_WindowActionDestructor(TXT_UNCAST_ARG(action))