summaryrefslogtreecommitdiff
path: root/src/ui/inputwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r--src/ui/inputwidget.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index d31130f5..f1f368b6 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -190,6 +190,7 @@ enum iInputWidgetFlag {
190 enterKeyEnabled_InputWidgetFlag = iBit(10), 190 enterKeyEnabled_InputWidgetFlag = iBit(10),
191 lineBreaksEnabled_InputWidgetFlag= iBit(11), 191 lineBreaksEnabled_InputWidgetFlag= iBit(11),
192 needBackup_InputWidgetFlag = iBit(12), 192 needBackup_InputWidgetFlag = iBit(12),
193 useReturnKeyBehavior_InputWidgetFlag = iBit(13),
193}; 194};
194 195
195/*----------------------------------------------------------------------------------------------*/ 196/*----------------------------------------------------------------------------------------------*/
@@ -566,6 +567,28 @@ static void updateAllLinesAndResizeHeight_InputWidget_(iInputWidget *d) {
566 } 567 }
567} 568}
568 569
570static uint32_t cursorTimer_(uint32_t interval, void *w) {
571 iInputWidget *d = w;
572 if (d->cursorVis > 1) {
573 d->cursorVis--;
574 }
575 else {
576 d->cursorVis ^= 1;
577 }
578 refresh_Widget(w);
579 return interval;
580}
581
582static void startOrStopCursorTimer_InputWidget_(iInputWidget *d, iBool doStart) {
583 if (doStart && !d->timer) {
584 d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d);
585 }
586 else if (!doStart && d->timer) {
587 SDL_RemoveTimer(d->timer);
588 d->timer = 0;
589 }
590}
591
569void init_InputWidget(iInputWidget *d, size_t maxLen) { 592void init_InputWidget(iInputWidget *d, size_t maxLen) {
570 iWidget *w = &d->widget; 593 iWidget *w = &d->widget;
571 init_Widget(w); 594 init_Widget(w);
@@ -588,7 +611,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
588 d->prevCursor = zero_I2(); 611 d->prevCursor = zero_I2();
589 d->lastUpdateWidth = 0; 612 d->lastUpdateWidth = 0;
590 d->inFlags = eatEscape_InputWidgetFlag | enterKeyEnabled_InputWidgetFlag | 613 d->inFlags = eatEscape_InputWidgetFlag | enterKeyEnabled_InputWidgetFlag |
591 lineBreaksEnabled_InputWidgetFlag; 614 lineBreaksEnabled_InputWidgetFlag | useReturnKeyBehavior_InputWidgetFlag;
592 // if (deviceType_App() != desktop_AppDeviceType) { 615 // if (deviceType_App() != desktop_AppDeviceType) {
593 // d->inFlags |= enterKeyInsertsLineFeed_InputWidgetFlag; 616 // d->inFlags |= enterKeyInsertsLineFeed_InputWidgetFlag;
594 // } 617 // }
@@ -627,9 +650,7 @@ void deinit_InputWidget(iInputWidget *d) {
627 delete_TextBuf(d->buffered); 650 delete_TextBuf(d->buffered);
628 clearUndo_InputWidget_(d); 651 clearUndo_InputWidget_(d);
629 deinit_Array(&d->undoStack); 652 deinit_Array(&d->undoStack);
630 if (d->timer) { 653 startOrStopCursorTimer_InputWidget_(d, iFalse);
631 SDL_RemoveTimer(d->timer);
632 }
633 deinit_String(&d->srcHint); 654 deinit_String(&d->srcHint);
634 deinit_String(&d->hint); 655 deinit_String(&d->hint);
635 deinit_String(&d->oldText); 656 deinit_String(&d->oldText);
@@ -740,6 +761,10 @@ void setEnterKeyEnabled_InputWidget(iInputWidget *d, iBool enterKeyEnabled) {
740 iChangeFlags(d->inFlags, enterKeyEnabled_InputWidgetFlag, enterKeyEnabled); 761 iChangeFlags(d->inFlags, enterKeyEnabled_InputWidgetFlag, enterKeyEnabled);
741} 762}
742 763
764void setUseReturnKeyBehavior_InputWidget(iInputWidget *d, iBool useReturnKeyBehavior) {
765 iChangeFlags(d->inFlags, useReturnKeyBehavior_InputWidgetFlag, useReturnKeyBehavior);
766}
767
743void setHint_InputWidget(iInputWidget *d, const char *hintText) { 768void setHint_InputWidget(iInputWidget *d, const char *hintText) {
744 /* Keep original for retranslations. */ 769 /* Keep original for retranslations. */
745 setCStr_String(&d->srcHint, hintText); 770 setCStr_String(&d->srcHint, hintText);
@@ -866,18 +891,6 @@ void setTextCStr_InputWidget(iInputWidget *d, const char *cstr) {
866 delete_String(str); 891 delete_String(str);
867} 892}
868 893
869static uint32_t cursorTimer_(uint32_t interval, void *w) {
870 iInputWidget *d = w;
871 if (d->cursorVis > 1) {
872 d->cursorVis--;
873 }
874 else {
875 d->cursorVis ^= 1;
876 }
877 refresh_Widget(w);
878 return interval;
879}
880
881static size_t cursorToIndex_InputWidget_(const iInputWidget *d, iInt2 pos) { 894static size_t cursorToIndex_InputWidget_(const iInputWidget *d, iInt2 pos) {
882 if (pos.y < 0) { 895 if (pos.y < 0) {
883 return 0; 896 return 0;
@@ -930,7 +943,7 @@ void begin_InputWidget(iInputWidget *d) {
930 setFlags_Widget(w, selected_WidgetFlag, iTrue); 943 setFlags_Widget(w, selected_WidgetFlag, iTrue);
931 showCursor_InputWidget_(d); 944 showCursor_InputWidget_(d);
932 refresh_Widget(w); 945 refresh_Widget(w);
933 d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); 946 startOrStopCursorTimer_InputWidget_(d, iTrue);
934 d->inFlags &= ~enterPressed_InputWidgetFlag; 947 d->inFlags &= ~enterPressed_InputWidgetFlag;
935 if (d->inFlags & selectAllOnFocus_InputWidgetFlag) { 948 if (d->inFlags & selectAllOnFocus_InputWidgetFlag) {
936 d->mark = (iRanges){ 0, lastLine_InputWidget_(d)->range.end }; 949 d->mark = (iRanges){ 0, lastLine_InputWidget_(d)->range.end };
@@ -955,8 +968,7 @@ void end_InputWidget(iInputWidget *d, iBool accept) {
955 splitToLines_(&d->oldText, &d->lines); 968 splitToLines_(&d->oldText, &d->lines);
956 } 969 }
957 d->inFlags |= needUpdateBuffer_InputWidgetFlag; 970 d->inFlags |= needUpdateBuffer_InputWidgetFlag;
958 SDL_RemoveTimer(d->timer); 971 startOrStopCursorTimer_InputWidget_(d, iFalse);
959 d->timer = 0;
960 SDL_StopTextInput(); 972 SDL_StopTextInput();
961 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iFalse); 973 setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iFalse);
962 const char *id = cstr_String(id_Widget(as_Widget(d))); 974 const char *id = cstr_String(id_Widget(as_Widget(d)));
@@ -1383,6 +1395,20 @@ static iBool isArrowUpDownConsumed_InputWidget_(const iInputWidget *d) {
1383 return d->maxWrapLines > 1; 1395 return d->maxWrapLines > 1;
1384} 1396}
1385 1397
1398static iBool checkLineBreakMods_InputWidget_(const iInputWidget *d, int mods) {
1399 if (d->inFlags & useReturnKeyBehavior_InputWidgetFlag) {
1400 return mods == lineBreakKeyMod_ReturnKeyBehavior(prefs_App()->returnKey);
1401 }
1402 return mods == 0;
1403}
1404
1405static iBool checkAcceptMods_InputWidget_(const iInputWidget *d, int mods) {
1406 if (d->inFlags & useReturnKeyBehavior_InputWidgetFlag) {
1407 return mods == acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey);
1408 }
1409 return mods == 0;
1410}
1411
1386static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { 1412static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1387 iWidget *w = as_Widget(d); 1413 iWidget *w = as_Widget(d);
1388 /* Resize according to width immediately. */ 1414 /* Resize according to width immediately. */
@@ -1401,6 +1427,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1401 begin_InputWidget(d); 1427 begin_InputWidget(d);
1402 return iFalse; 1428 return iFalse;
1403 } 1429 }
1430 else if (isEditing_InputWidget_(d) && (isCommand_UserEvent(ev, "window.focus.lost") ||
1431 isCommand_UserEvent(ev, "window.focus.gained"))) {
1432 startOrStopCursorTimer_InputWidget_(d, isCommand_UserEvent(ev, "window.focus.gained"));
1433 d->cursorVis = 1;
1434 refresh_Widget(d);
1435 return iFalse;
1436 }
1404 else if (isCommand_UserEvent(ev, "keyroot.changed")) { 1437 else if (isCommand_UserEvent(ev, "keyroot.changed")) {
1405 d->inFlags |= needUpdateBuffer_InputWidgetFlag; 1438 d->inFlags |= needUpdateBuffer_InputWidgetFlag;
1406 } 1439 }
@@ -1617,7 +1650,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1617 if (~d->inFlags & isSensitive_InputWidgetFlag && 1650 if (~d->inFlags & isSensitive_InputWidgetFlag &&
1618 ~d->inFlags & isUrl_InputWidgetFlag && 1651 ~d->inFlags & isUrl_InputWidgetFlag &&
1619 d->inFlags & lineBreaksEnabled_InputWidgetFlag && d->maxLen == 0) { 1652 d->inFlags & lineBreaksEnabled_InputWidgetFlag && d->maxLen == 0) {
1620 if (mods == lineBreakKeyMod_ReturnKeyBehavior(prefs_App()->returnKey)) { 1653 if (checkLineBreakMods_InputWidget_(d, mods)) {
1621 pushUndo_InputWidget_(d); 1654 pushUndo_InputWidget_(d);
1622 deleteMarked_InputWidget_(d); 1655 deleteMarked_InputWidget_(d);
1623 insertChar_InputWidget_(d, '\n'); 1656 insertChar_InputWidget_(d, '\n');
@@ -1626,7 +1659,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1626 } 1659 }
1627 } 1660 }
1628 if (d->inFlags & enterKeyEnabled_InputWidgetFlag && 1661 if (d->inFlags & enterKeyEnabled_InputWidgetFlag &&
1629 (mods == acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey) || 1662 (checkAcceptMods_InputWidget_(d, mods) ||
1630 (~d->inFlags & lineBreaksEnabled_InputWidgetFlag))) { 1663 (~d->inFlags & lineBreaksEnabled_InputWidgetFlag))) {
1631 d->inFlags |= enterPressed_InputWidgetFlag; 1664 d->inFlags |= enterPressed_InputWidgetFlag;
1632 setFocus_Widget(NULL); 1665 setFocus_Widget(NULL);