diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-24 21:05:02 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-24 21:05:02 +0300 |
commit | e32fd4e7796d6e7c5a4803e45bc230378ec4dd0b (patch) | |
tree | 5232331654a977cf4ad1bf06eedc2f8752db6c32 /src/ui/inputwidget.c | |
parent | 0f0b4250ca460d58edb61cc0dd509ba1980c3272 (diff) |
Font update; ANSI color escapes; fixed URL update
Newer version of the Fira fonts, and added a separate UI font (Source Sans Pro).
The text renderer checks for the 4-bit ANSI color escapes for the setting the foreground color.
InputWidget supports paste from clipboard.
The navbar updates the current URL when the page has been loaded.
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r-- | src/ui/inputwidget.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index b73fac9e..22b30616 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include "util.h" | 3 | #include "util.h" |
4 | 4 | ||
5 | #include <the_Foundation/array.h> | 5 | #include <the_Foundation/array.h> |
6 | #include <SDL_clipboard.h> | ||
6 | #include <SDL_timer.h> | 7 | #include <SDL_timer.h> |
7 | 8 | ||
8 | static const int REFRESH_INTERVAL = 256; | 9 | static const int REFRESH_INTERVAL = 256; |
@@ -132,6 +133,23 @@ void end_InputWidget(iInputWidget *d, iBool accept) { | |||
132 | postCommand_Widget(w, "input.ended id:%s arg:%d", id, accept ? 1 : 0); | 133 | postCommand_Widget(w, "input.ended id:%s arg:%d", id, accept ? 1 : 0); |
133 | } | 134 | } |
134 | 135 | ||
136 | static void insertChar_InputWidget_(iInputWidget *d, iChar chr) { | ||
137 | if (d->mode == insert_InputMode) { | ||
138 | insert_Array(&d->text, d->cursor, &chr); | ||
139 | d->cursor++; | ||
140 | } | ||
141 | else if (d->maxLen == 0 || d->cursor < d->maxLen) { | ||
142 | if (d->cursor >= size_Array(&d->text)) { | ||
143 | resize_Array(&d->text, d->cursor + 1); | ||
144 | } | ||
145 | set_Array(&d->text, d->cursor++, &chr); | ||
146 | if (d->maxLen && d->cursor == d->maxLen) { | ||
147 | setFocus_Widget(NULL); | ||
148 | } | ||
149 | } | ||
150 | refresh_Widget(as_Widget(d)); | ||
151 | } | ||
152 | |||
135 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | 153 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { |
136 | iWidget *w = as_Widget(d); | 154 | iWidget *w = as_Widget(d); |
137 | if (isCommand_Widget(w, ev, "focus.gained")) { | 155 | if (isCommand_Widget(w, ev, "focus.gained")) { |
@@ -161,6 +179,20 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
161 | if (ev->type == SDL_KEYDOWN && isFocused_Widget(w)) { | 179 | if (ev->type == SDL_KEYDOWN && isFocused_Widget(w)) { |
162 | const int key = ev->key.keysym.sym; | 180 | const int key = ev->key.keysym.sym; |
163 | const int mods = keyMods_Sym(ev->key.keysym.mod); | 181 | const int mods = keyMods_Sym(ev->key.keysym.mod); |
182 | if (mods == KMOD_PRIMARY) { | ||
183 | switch (key) { | ||
184 | case 'v': | ||
185 | if (SDL_HasClipboardText()) { | ||
186 | char *text = SDL_GetClipboardText(); | ||
187 | iString *paste = collect_String(newCStr_String(text)); | ||
188 | SDL_free(text); | ||
189 | iConstForEach(String, i, paste) { | ||
190 | insertChar_InputWidget_(d, i.value); | ||
191 | } | ||
192 | } | ||
193 | return iTrue; | ||
194 | } | ||
195 | } | ||
164 | switch (key) { | 196 | switch (key) { |
165 | case SDLK_RETURN: | 197 | case SDLK_RETURN: |
166 | case SDLK_KP_ENTER: | 198 | case SDLK_KP_ENTER: |
@@ -237,21 +269,9 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
237 | } | 269 | } |
238 | else if (ev->type == SDL_TEXTINPUT && isFocused_Widget(w)) { | 270 | else if (ev->type == SDL_TEXTINPUT && isFocused_Widget(w)) { |
239 | const iString *uni = collectNewCStr_String(ev->text.text); | 271 | const iString *uni = collectNewCStr_String(ev->text.text); |
240 | const iChar chr = first_String(uni); | 272 | iConstForEach(String, i, uni) { |
241 | if (d->mode == insert_InputMode) { | 273 | insertChar_InputWidget_(d, i.value); |
242 | insert_Array(&d->text, d->cursor, &chr); | ||
243 | d->cursor++; | ||
244 | } | ||
245 | else { | ||
246 | if (d->cursor >= size_Array(&d->text)) { | ||
247 | resize_Array(&d->text, d->cursor + 1); | ||
248 | } | ||
249 | set_Array(&d->text, d->cursor++, &chr); | ||
250 | if (d->maxLen && d->cursor == d->maxLen) { | ||
251 | setFocus_Widget(NULL); | ||
252 | } | ||
253 | } | 274 | } |
254 | refresh_Widget(w); | ||
255 | return iTrue; | 275 | return iTrue; |
256 | } | 276 | } |
257 | return processEvent_Widget(w, ev); | 277 | return processEvent_Widget(w, ev); |
@@ -259,7 +279,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
259 | 279 | ||
260 | static void draw_InputWidget_(const iInputWidget *d) { | 280 | static void draw_InputWidget_(const iInputWidget *d) { |
261 | const uint32_t time = frameTime_Window(get_Window()); | 281 | const uint32_t time = frameTime_Window(get_Window()); |
262 | const iInt2 padding = init_I2(3 * gap_UI, gap_UI); | 282 | const iInt2 padding = init_I2(3 * gap_UI, gap_UI / 2); |
263 | iRect bounds = adjusted_Rect(bounds_Widget(constAs_Widget(d)), padding, neg_I2(padding)); | 283 | iRect bounds = adjusted_Rect(bounds_Widget(constAs_Widget(d)), padding, neg_I2(padding)); |
264 | const iBool isFocused = isFocused_Widget(constAs_Widget(d)); | 284 | const iBool isFocused = isFocused_Widget(constAs_Widget(d)); |
265 | const iBool isHover = isHover_Widget(constAs_Widget(d)) && | 285 | const iBool isHover = isHover_Widget(constAs_Widget(d)) && |
@@ -286,13 +306,19 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
286 | } | 306 | } |
287 | xOff = iMin(xOff, 0); | 307 | xOff = iMin(xOff, 0); |
288 | } | 308 | } |
289 | draw_Text(d->font, addX_I2(topLeft_Rect(bounds), xOff), white_ColorId, cstr_String(&text)); | 309 | const int yOff = (height_Rect(bounds) - lineHeight_Text(d->font)) / 2; |
310 | draw_Text(d->font, | ||
311 | add_I2(topLeft_Rect(bounds), | ||
312 | init_I2(xOff, yOff)), | ||
313 | white_ColorId, | ||
314 | cstr_String(&text)); | ||
290 | clearClip_Paint(&p); | 315 | clearClip_Paint(&p); |
291 | /* Cursor blinking. */ | 316 | /* Cursor blinking. */ |
292 | if (isFocused && (time & 256)) { | 317 | if (isFocused && (time & 256)) { |
293 | const iInt2 prefixSize = advanceN_Text(d->font, cstr_String(&text), d->cursor); | 318 | const iInt2 prefixSize = advanceN_Text(d->font, cstr_String(&text), d->cursor); |
294 | const iInt2 curPos = init_I2(xOff + left_Rect(bounds) + prefixSize.x, top_Rect(bounds)); | 319 | const iInt2 curPos = init_I2(xOff + left_Rect(bounds) + prefixSize.x, |
295 | const iRect curRect = { curPos, addX_I2(emSize, 1) }; | 320 | yOff + top_Rect(bounds)); |
321 | const iRect curRect = { curPos, addX_I2(emSize, 1) }; | ||
296 | iString cur; | 322 | iString cur; |
297 | if (d->cursor < size_Array(&d->text)) { | 323 | if (d->cursor < size_Array(&d->text)) { |
298 | initUnicodeN_String(&cur, constAt_Array(&d->text, d->cursor), 1); | 324 | initUnicodeN_String(&cur, constAt_Array(&d->text, d->cursor), 1); |