diff options
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r-- | src/ui/inputwidget.c | 75 |
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 | ||
570 | static 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 | |||
582 | static 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 | |||
569 | void init_InputWidget(iInputWidget *d, size_t maxLen) { | 592 | void 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 | ||
764 | void setUseReturnKeyBehavior_InputWidget(iInputWidget *d, iBool useReturnKeyBehavior) { | ||
765 | iChangeFlags(d->inFlags, useReturnKeyBehavior_InputWidgetFlag, useReturnKeyBehavior); | ||
766 | } | ||
767 | |||
743 | void setHint_InputWidget(iInputWidget *d, const char *hintText) { | 768 | void 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 | ||
869 | static 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 | |||
881 | static size_t cursorToIndex_InputWidget_(const iInputWidget *d, iInt2 pos) { | 894 | static 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 | ||
1398 | static 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 | |||
1405 | static 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 | |||
1386 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | 1412 | static 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); |