diff options
-rw-r--r-- | src/ui/inputwidget.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index d583b109..16db6bf5 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -65,6 +65,7 @@ struct Impl_InputWidget { | |||
65 | iArray undoStack; | 65 | iArray undoStack; |
66 | int font; | 66 | int font; |
67 | iClick click; | 67 | iClick click; |
68 | int cursorVis; | ||
68 | uint32_t timer; | 69 | uint32_t timer; |
69 | }; | 70 | }; |
70 | 71 | ||
@@ -77,6 +78,10 @@ static void clearUndo_InputWidget_(iInputWidget *d) { | |||
77 | clear_Array(&d->undoStack); | 78 | clear_Array(&d->undoStack); |
78 | } | 79 | } |
79 | 80 | ||
81 | static void showCursor_InputWidget_(iInputWidget *d) { | ||
82 | d->cursorVis = 2; | ||
83 | } | ||
84 | |||
80 | void init_InputWidget(iInputWidget *d, size_t maxLen) { | 85 | void init_InputWidget(iInputWidget *d, size_t maxLen) { |
81 | iWidget *w = &d->widget; | 86 | iWidget *w = &d->widget; |
82 | init_Widget(w); | 87 | init_Widget(w); |
@@ -85,20 +90,21 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
85 | init_Array(&d->oldText, sizeof(iChar)); | 90 | init_Array(&d->oldText, sizeof(iChar)); |
86 | init_String(&d->hint); | 91 | init_String(&d->hint); |
87 | init_Array(&d->undoStack, sizeof(iInputUndo)); | 92 | init_Array(&d->undoStack, sizeof(iInputUndo)); |
88 | d->font = uiInput_FontId; | 93 | d->font = uiInput_FontId; |
89 | d->cursor = 0; | 94 | d->cursor = 0; |
90 | d->lastCursor = 0; | 95 | d->lastCursor = 0; |
91 | d->isMarking = iFalse; | 96 | d->isMarking = iFalse; |
92 | iZap(d->mark); | ||
93 | d->isSensitive = iFalse; | 97 | d->isSensitive = iFalse; |
94 | d->enterPressed = iFalse; | 98 | d->enterPressed = iFalse; |
95 | d->selectAllOnFocus = iFalse; | 99 | d->selectAllOnFocus = iFalse; |
100 | iZap(d->mark); | ||
96 | setMaxLen_InputWidget(d, maxLen); | 101 | setMaxLen_InputWidget(d, maxLen); |
97 | /* Caller must arrange the width, but the height is fixed. */ | 102 | /* Caller must arrange the width, but the height is fixed. */ |
98 | w->rect.size.y = lineHeight_Text(default_FontId) + 2 * gap_UI; | 103 | w->rect.size.y = lineHeight_Text(default_FontId) + 2 * gap_UI; |
99 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); | 104 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); |
100 | init_Click(&d->click, d, SDL_BUTTON_LEFT); | 105 | init_Click(&d->click, d, SDL_BUTTON_LEFT); |
101 | d->timer = 0; | 106 | d->timer = 0; |
107 | d->cursorVis = 0; | ||
102 | } | 108 | } |
103 | 109 | ||
104 | void deinit_InputWidget(iInputWidget *d) { | 110 | void deinit_InputWidget(iInputWidget *d) { |
@@ -181,8 +187,15 @@ void setTextCStr_InputWidget(iInputWidget *d, const char *cstr) { | |||
181 | delete_String(str); | 187 | delete_String(str); |
182 | } | 188 | } |
183 | 189 | ||
184 | static uint32_t refreshTimer_(uint32_t interval, void *d) { | 190 | static uint32_t cursorTimer_(uint32_t interval, void *w) { |
185 | refresh_Widget(d); | 191 | iInputWidget *d = w; |
192 | if (d->cursorVis > 1) { | ||
193 | d->cursorVis--; | ||
194 | } | ||
195 | else { | ||
196 | d->cursorVis ^= 1; | ||
197 | } | ||
198 | refresh_Widget(w); | ||
186 | return interval; | 199 | return interval; |
187 | } | 200 | } |
188 | 201 | ||
@@ -202,8 +215,9 @@ void begin_InputWidget(iInputWidget *d) { | |||
202 | } | 215 | } |
203 | SDL_StartTextInput(); | 216 | SDL_StartTextInput(); |
204 | setFlags_Widget(w, selected_WidgetFlag, iTrue); | 217 | setFlags_Widget(w, selected_WidgetFlag, iTrue); |
218 | showCursor_InputWidget_(d); | ||
205 | refresh_Widget(w); | 219 | refresh_Widget(w); |
206 | d->timer = SDL_AddTimer(refreshInterval_InputWidget_, refreshTimer_, d); | 220 | d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); |
207 | d->enterPressed = iFalse; | 221 | d->enterPressed = iFalse; |
208 | if (d->selectAllOnFocus) { | 222 | if (d->selectAllOnFocus) { |
209 | d->mark = (iRanges){ 0, size_Array(&d->text) }; | 223 | d->mark = (iRanges){ 0, size_Array(&d->text) }; |
@@ -247,6 +261,7 @@ static void insertChar_InputWidget_(iInputWidget *d, iChar chr) { | |||
247 | setFocus_Widget(NULL); | 261 | setFocus_Widget(NULL); |
248 | } | 262 | } |
249 | } | 263 | } |
264 | showCursor_InputWidget_(d); | ||
250 | refresh_Widget(as_Widget(d)); | 265 | refresh_Widget(as_Widget(d)); |
251 | } | 266 | } |
252 | 267 | ||
@@ -259,6 +274,7 @@ iLocalDef iBool isMarking_(void) { | |||
259 | } | 274 | } |
260 | 275 | ||
261 | void setCursor_InputWidget(iInputWidget *d, size_t pos) { | 276 | void setCursor_InputWidget(iInputWidget *d, size_t pos) { |
277 | showCursor_InputWidget_(d); | ||
262 | if (isEmpty_Array(&d->text)) { | 278 | if (isEmpty_Array(&d->text)) { |
263 | d->cursor = 0; | 279 | d->cursor = 0; |
264 | } | 280 | } |
@@ -435,6 +451,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
435 | case aborted_ClickResult: | 451 | case aborted_ClickResult: |
436 | return iTrue; | 452 | return iTrue; |
437 | case drag_ClickResult: | 453 | case drag_ClickResult: |
454 | showCursor_InputWidget_(d); | ||
438 | d->cursor = coordIndex_InputWidget_(d, pos_Click(&d->click)); | 455 | d->cursor = coordIndex_InputWidget_(d, pos_Click(&d->click)); |
439 | if (!d->isMarking) { | 456 | if (!d->isMarking) { |
440 | d->isMarking = iTrue; | 457 | d->isMarking = iTrue; |
@@ -512,6 +529,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
512 | pushUndo_InputWidget_(d); | 529 | pushUndo_InputWidget_(d); |
513 | remove_Array(&d->text, --d->cursor); | 530 | remove_Array(&d->text, --d->cursor); |
514 | } | 531 | } |
532 | showCursor_InputWidget_(d); | ||
515 | refresh_Widget(w); | 533 | refresh_Widget(w); |
516 | return iTrue; | 534 | return iTrue; |
517 | case SDLK_d: | 535 | case SDLK_d: |
@@ -531,6 +549,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
531 | pushUndo_InputWidget_(d); | 549 | pushUndo_InputWidget_(d); |
532 | remove_Array(&d->text, d->cursor); | 550 | remove_Array(&d->text, d->cursor); |
533 | } | 551 | } |
552 | showCursor_InputWidget_(d); | ||
534 | refresh_Widget(w); | 553 | refresh_Widget(w); |
535 | return iTrue; | 554 | return iTrue; |
536 | case SDLK_k: | 555 | case SDLK_k: |
@@ -543,6 +562,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
543 | pushUndo_InputWidget_(d); | 562 | pushUndo_InputWidget_(d); |
544 | removeN_Array(&d->text, d->cursor, size_Array(&d->text) - d->cursor); | 563 | removeN_Array(&d->text, d->cursor, size_Array(&d->text) - d->cursor); |
545 | } | 564 | } |
565 | showCursor_InputWidget_(d); | ||
546 | refresh_Widget(w); | 566 | refresh_Widget(w); |
547 | return iTrue; | 567 | return iTrue; |
548 | } | 568 | } |
@@ -558,6 +578,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
558 | d->mark.start = 0; | 578 | d->mark.start = 0; |
559 | d->mark.end = curMax; | 579 | d->mark.end = curMax; |
560 | d->cursor = curMax; | 580 | d->cursor = curMax; |
581 | showCursor_InputWidget_(d); | ||
561 | refresh_Widget(w); | 582 | refresh_Widget(w); |
562 | return iTrue; | 583 | return iTrue; |
563 | } | 584 | } |
@@ -662,7 +683,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
662 | cstr_String(text)); | 683 | cstr_String(text)); |
663 | unsetClip_Paint(&p); | 684 | unsetClip_Paint(&p); |
664 | /* Cursor blinking. */ | 685 | /* Cursor blinking. */ |
665 | if (isFocused && (time & 256)) { | 686 | if (isFocused && d->cursorVis) { |
666 | iString cur; | 687 | iString cur; |
667 | if (d->cursor < size_Array(&d->text)) { | 688 | if (d->cursor < size_Array(&d->text)) { |
668 | if (!d->isSensitive) { | 689 | if (!d->isSensitive) { |