ref: 165a20cf3e4cc4fbf22ee8754e50a557ad609ad6
parent: ba7589ba46ab1f40fe5816d80c3994e0e1957a29
author: Simon Howard <[email protected]>
date: Fri Sep 22 14:24:53 EDT 2006
Add the ability to type in values for spin controls, like with normal input boxes. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 651
--- a/textscreen/txt_spinctrl.c
+++ b/textscreen/txt_spinctrl.c
@@ -37,35 +37,40 @@
static int IntWidth(int val)
{
- if (val < 0)
- {
- return ((int) log(-val)) + 2;
- }
- else
- {
- return ((int) log(val)) + 1;
- }
+ char buf[15];
+
+ sprintf(buf, "%i", val);
+
+ return strlen(buf);
}
-static void TXT_SpinControlSizeCalc(TXT_UNCAST_ARG(spincontrol))
+// Returns the minimum width of the input box
+
+static int SpinControlWidth(txt_spincontrol_t *spincontrol)
{
- TXT_CAST_ARG(txt_spincontrol_t, spincontrol);
int minw, maxw;
- int w;
minw = IntWidth(spincontrol->min);
maxw = IntWidth(spincontrol->max);
+ // Choose the wider of the two values. Add one so that there is always
+ // space for the cursor when editing.
+
if (minw > maxw)
{
- w = minw;
+ return minw;
}
else
{
- w = maxw;
+ return maxw;
}
+}
- spincontrol->widget.w = w + 4;
+static void TXT_SpinControlSizeCalc(TXT_UNCAST_ARG(spincontrol))
+{
+ TXT_CAST_ARG(txt_spincontrol_t, spincontrol);
+
+ spincontrol->widget.w = SpinControlWidth(spincontrol) + 5;
spincontrol->widget.h = 1;
}
@@ -72,8 +77,9 @@
static void TXT_SpinControlDrawer(TXT_UNCAST_ARG(spincontrol), int selected)
{
TXT_CAST_ARG(txt_spincontrol_t, spincontrol);
- char buf[20];
+ char buf[15];
unsigned int i;
+ unsigned int padding;
TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
TXT_BGColor(TXT_COLOR_BLUE, 0);
@@ -82,8 +88,12 @@
// Choose background color
- if (selected)
+ if (selected && spincontrol->editing)
{
+ TXT_BGColor(TXT_COLOR_BLACK, 0);
+ }
+ else if (selected)
+ {
TXT_BGColor(TXT_COLOR_GREY, 0);
}
else
@@ -91,15 +101,34 @@
TXT_BGColor(TXT_COLOR_BLUE, 0);
}
- sprintf(buf, "%i", *spincontrol->value);
+ if (spincontrol->editing)
+ {
+ strcpy(buf, spincontrol->buffer);
+ }
+ else
+ {
+ sprintf(buf, "%i", *spincontrol->value);
+ }
- for (i=strlen(buf); i<spincontrol->widget.w - 4; ++i)
+ i = 0;
+
+ padding = spincontrol->widget.w - strlen(buf) - 4;
+
+ while (i < padding)
{
TXT_DrawString(" ");
+ ++i;
}
TXT_DrawString(buf);
+ i += strlen(buf);
+ while (i < spincontrol->widget.w - 4)
+ {
+ TXT_DrawString(" ");
+ ++i;
+ }
+
TXT_BGColor(TXT_COLOR_BLUE, 0);
TXT_DrawString(" >");
}
@@ -106,36 +135,100 @@
static void TXT_SpinControlDestructor(TXT_UNCAST_ARG(spincontrol))
{
+ TXT_CAST_ARG(txt_spincontrol_t, spincontrol);
+
+ free(spincontrol->buffer);
}
+static void AddCharacter(txt_spincontrol_t *spincontrol, int key)
+{
+ if (strlen(spincontrol->buffer) < SpinControlWidth(spincontrol))
+ {
+ spincontrol->buffer[strlen(spincontrol->buffer) + 1] = '\0';
+ spincontrol->buffer[strlen(spincontrol->buffer)] = key;
+ }
+}
+
+static void Backspace(txt_spincontrol_t *spincontrol)
+{
+ if (strlen(spincontrol->buffer) > 0)
+ {
+ spincontrol->buffer[strlen(spincontrol->buffer) - 1] = '\0';
+ }
+}
+
+static void EnforceLimits(txt_spincontrol_t *spincontrol)
+{
+ if (*spincontrol->value > spincontrol->max)
+ *spincontrol->value = spincontrol->max;
+ else if (*spincontrol->value < spincontrol->min)
+ *spincontrol->value = spincontrol->min;
+}
+
static int TXT_SpinControlKeyPress(TXT_UNCAST_ARG(spincontrol), int key)
{
TXT_CAST_ARG(txt_spincontrol_t, spincontrol);
- if (key == KEY_LEFTARROW)
+ // Enter to enter edit mode
+
+ if (spincontrol->editing)
{
- --*spincontrol->value;
+ if (key == KEY_ENTER)
+ {
+ *spincontrol->value = atoi(spincontrol->buffer);
+ spincontrol->editing = 0;
+ EnforceLimits(spincontrol);
+ return 1;
+ }
- if (*spincontrol->value < spincontrol->min)
+ if (key == KEY_ESCAPE)
{
- *spincontrol->value = spincontrol->min;
+ // Abort without saving value
+ spincontrol->editing = 0;
+ return 1;
}
- return 1;
+ if (isdigit(key) || key == '-')
+ {
+ AddCharacter(spincontrol, key);
+ return 1;
+ }
+
+ if (key == KEY_BACKSPACE)
+ {
+ Backspace(spincontrol);
+ return 1;
+ }
}
-
- if (key == KEY_RIGHTARROW)
+ else
{
- ++*spincontrol->value;
+ // Non-editing mode
- if (*spincontrol->value > spincontrol->max)
+ if (key == KEY_ENTER)
{
- *spincontrol->value = spincontrol->max;
+ sprintf(spincontrol->buffer, "%i", *spincontrol->value);
+ spincontrol->editing = 1;
+ return 1;
}
+ if (key == KEY_LEFTARROW)
+ {
+ --*spincontrol->value;
- return 1;
+ EnforceLimits(spincontrol);
+
+ return 1;
+ }
+
+ if (key == KEY_RIGHTARROW)
+ {
+ ++*spincontrol->value;
+
+ EnforceLimits(spincontrol);
+
+ return 1;
+ }
}
-
+
return 0;
}
@@ -177,6 +270,9 @@
spincontrol->value = value;
spincontrol->min = min;
spincontrol->max = max;
+ spincontrol->buffer = malloc(15);
+ strcpy(spincontrol->buffer, "");
+ spincontrol->editing = 0;
return spincontrol;
}
--- a/textscreen/txt_spinctrl.h
+++ b/textscreen/txt_spinctrl.h
@@ -31,6 +31,8 @@
txt_widget_t widget;
int min, max;
int *value;
+ int editing;
+ char *buffer;
};
txt_spincontrol_t *TXT_NewSpinControl(int *value, int min, int max);