summaryrefslogtreecommitdiff
path: root/src/ui/inputwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-07-24 21:05:02 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-07-24 21:05:02 +0300
commite32fd4e7796d6e7c5a4803e45bc230378ec4dd0b (patch)
tree5232331654a977cf4ad1bf06eedc2f8752db6c32 /src/ui/inputwidget.c
parent0f0b4250ca460d58edb61cc0dd509ba1980c3272 (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.c62
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
8static const int REFRESH_INTERVAL = 256; 9static 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
136static 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
135static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { 153static 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
260static void draw_InputWidget_(const iInputWidget *d) { 280static 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);