1 //
2 // Copyright(C) 2005-2014 Simon Howard
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14
15 #include <stdlib.h>
16 #include <string.h>
17
18 #include "doomkeys.h"
19 #include "m_misc.h"
20
21 #include "txt_keyinput.h"
22 #include "txt_gui.h"
23 #include "txt_io.h"
24 #include "txt_label.h"
25 #include "txt_utf8.h"
26 #include "txt_window.h"
27
28 #define KEY_INPUT_WIDTH 8
29
KeyPressCallback(txt_window_t * window,int key,TXT_UNCAST_ARG (key_input))30 static int KeyPressCallback(txt_window_t *window, int key,
31 TXT_UNCAST_ARG(key_input))
32 {
33 TXT_CAST_ARG(txt_key_input_t, key_input);
34
35 if (key != KEY_ESCAPE)
36 {
37 // Got the key press. Save to the variable and close the window.
38
39 *key_input->variable = key;
40
41 if (key_input->check_conflicts)
42 {
43 TXT_EmitSignal(key_input, "set");
44 }
45
46 TXT_CloseWindow(window);
47
48 // Return to normal input mode now that we have the key.
49 TXT_SetInputMode(TXT_INPUT_NORMAL);
50
51 return 1;
52 }
53 else
54 {
55 return 0;
56 }
57 }
58
ReleaseGrab(TXT_UNCAST_ARG (window),TXT_UNCAST_ARG (unused))59 static void ReleaseGrab(TXT_UNCAST_ARG(window), TXT_UNCAST_ARG(unused))
60 {
61 // SDL2-TODO: Needed?
62 // SDL_WM_GrabInput(SDL_GRAB_OFF);
63 }
64
OpenPromptWindow(txt_key_input_t * key_input)65 static void OpenPromptWindow(txt_key_input_t *key_input)
66 {
67 txt_window_t *window;
68
69 // Silently update when the shift button is held down.
70
71 key_input->check_conflicts = !TXT_GetModifierState(TXT_MOD_SHIFT);
72
73 window = TXT_MessageBox(NULL, "Press the new key...");
74
75 TXT_SetKeyListener(window, KeyPressCallback, key_input);
76
77 // Switch to raw input mode while we're grabbing the key.
78 TXT_SetInputMode(TXT_INPUT_RAW);
79
80 // Grab input while reading the key. On Windows Mobile
81 // handheld devices, the hardware keypresses are only
82 // detected when input is grabbed.
83
84 // SDL2-TODO: Needed?
85 //SDL_WM_GrabInput(SDL_GRAB_ON);
86 TXT_SignalConnect(window, "closed", ReleaseGrab, NULL);
87 }
88
TXT_KeyInputSizeCalc(TXT_UNCAST_ARG (key_input))89 static void TXT_KeyInputSizeCalc(TXT_UNCAST_ARG(key_input))
90 {
91 TXT_CAST_ARG(txt_key_input_t, key_input);
92
93 // All keyinputs are the same size.
94
95 key_input->widget.w = KEY_INPUT_WIDTH;
96 key_input->widget.h = 1;
97 }
98
99
TXT_KeyInputDrawer(TXT_UNCAST_ARG (key_input))100 static void TXT_KeyInputDrawer(TXT_UNCAST_ARG(key_input))
101 {
102 TXT_CAST_ARG(txt_key_input_t, key_input);
103 char buf[20];
104 int i;
105
106 if (*key_input->variable == 0)
107 {
108 M_StringCopy(buf, "(none)", sizeof(buf));
109 }
110 else
111 {
112 TXT_GetKeyDescription(*key_input->variable, buf, sizeof(buf));
113 }
114
115 TXT_SetWidgetBG(key_input);
116 TXT_FGColor(TXT_COLOR_BRIGHT_WHITE);
117
118 TXT_DrawString(buf);
119
120 for (i = TXT_UTF8_Strlen(buf); i < KEY_INPUT_WIDTH; ++i)
121 {
122 TXT_DrawString(" ");
123 }
124 }
125
TXT_KeyInputDestructor(TXT_UNCAST_ARG (key_input))126 static void TXT_KeyInputDestructor(TXT_UNCAST_ARG(key_input))
127 {
128 }
129
TXT_KeyInputKeyPress(TXT_UNCAST_ARG (key_input),int key)130 static int TXT_KeyInputKeyPress(TXT_UNCAST_ARG(key_input), int key)
131 {
132 TXT_CAST_ARG(txt_key_input_t, key_input);
133
134 if (key == KEY_ENTER)
135 {
136 // Open a window to prompt for the new key press
137
138 OpenPromptWindow(key_input);
139
140 return 1;
141 }
142
143 if (key == KEY_BACKSPACE || key == KEY_DEL)
144 {
145 *key_input->variable = 0;
146 }
147
148 return 0;
149 }
150
TXT_KeyInputMousePress(TXT_UNCAST_ARG (widget),int x,int y,int b)151 static void TXT_KeyInputMousePress(TXT_UNCAST_ARG(widget), int x, int y, int b)
152 {
153 TXT_CAST_ARG(txt_key_input_t, widget);
154
155 // Clicking is like pressing enter
156
157 if (b == TXT_MOUSE_LEFT)
158 {
159 TXT_KeyInputKeyPress(widget, KEY_ENTER);
160 }
161 }
162
163 txt_widget_class_t txt_key_input_class =
164 {
165 TXT_AlwaysSelectable,
166 TXT_KeyInputSizeCalc,
167 TXT_KeyInputDrawer,
168 TXT_KeyInputKeyPress,
169 TXT_KeyInputDestructor,
170 TXT_KeyInputMousePress,
171 NULL,
172 };
173
TXT_NewKeyInput(int * variable)174 txt_key_input_t *TXT_NewKeyInput(int *variable)
175 {
176 txt_key_input_t *key_input;
177
178 key_input = malloc(sizeof(txt_key_input_t));
179
180 TXT_InitWidget(key_input, &txt_key_input_class);
181 key_input->variable = variable;
182
183 return key_input;
184 }
185
186