diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/color.c | 9 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 2 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 140 | ||||
-rw-r--r-- | src/ui/inputwidget.h | 3 | ||||
-rw-r--r-- | src/ui/root.c | 9 | ||||
-rw-r--r-- | src/ui/uploadwidget.c | 2 |
6 files changed, 117 insertions, 48 deletions
diff --git a/src/ui/color.c b/src/ui/color.c index 05ec1f6f..656de6f0 100644 --- a/src/ui/color.c +++ b/src/ui/color.c | |||
@@ -85,6 +85,7 @@ void setThemePalette_Color(enum iColorTheme theme) { | |||
85 | const int accentLo = (prefs->accent == cyan_ColorAccent ? teal_ColorId : brown_ColorId); | 85 | const int accentLo = (prefs->accent == cyan_ColorAccent ? teal_ColorId : brown_ColorId); |
86 | const int altAccentHi = (prefs->accent == cyan_ColorAccent ? orange_ColorId : cyan_ColorId); | 86 | const int altAccentHi = (prefs->accent == cyan_ColorAccent ? orange_ColorId : cyan_ColorId); |
87 | const int altAccentLo = (prefs->accent == cyan_ColorAccent ? brown_ColorId : teal_ColorId); | 87 | const int altAccentLo = (prefs->accent == cyan_ColorAccent ? brown_ColorId : teal_ColorId); |
88 | const iColor altAccentMid = mix_Color(get_Color(altAccentHi), get_Color(altAccentLo), 0.5f); | ||
88 | switch (theme) { | 89 | switch (theme) { |
89 | case pureBlack_ColorTheme: { | 90 | case pureBlack_ColorTheme: { |
90 | copy_(uiBackground_ColorId, black_ColorId); | 91 | copy_(uiBackground_ColorId, black_ColorId); |
@@ -123,7 +124,7 @@ void setThemePalette_Color(enum iColorTheme theme) { | |||
123 | copy_(uiInputTextFocused_ColorId, white_ColorId); | 124 | copy_(uiInputTextFocused_ColorId, white_ColorId); |
124 | copy_(uiInputFrame_ColorId, gray25_ColorId); | 125 | copy_(uiInputFrame_ColorId, gray25_ColorId); |
125 | copy_(uiInputFrameHover_ColorId, accentHi); | 126 | copy_(uiInputFrameHover_ColorId, accentHi); |
126 | copy_(uiInputFrameFocused_ColorId, altAccentHi); | 127 | set_Color(uiInputFrameFocused_ColorId, altAccentMid); |
127 | copy_(uiInputCursor_ColorId, altAccentHi); | 128 | copy_(uiInputCursor_ColorId, altAccentHi); |
128 | copy_(uiInputCursorText_ColorId, black_ColorId); | 129 | copy_(uiInputCursorText_ColorId, black_ColorId); |
129 | copy_(uiHeading_ColorId, accentHi); | 130 | copy_(uiHeading_ColorId, accentHi); |
@@ -171,10 +172,12 @@ void setThemePalette_Color(enum iColorTheme theme) { | |||
171 | mix_Color(get_Color(black_ColorId), get_Color(gray25_ColorId), 0.7f)); | 172 | mix_Color(get_Color(black_ColorId), get_Color(gray25_ColorId), 0.7f)); |
172 | copy_(uiInputBackgroundFocused_ColorId, black_ColorId); | 173 | copy_(uiInputBackgroundFocused_ColorId, black_ColorId); |
173 | copy_(uiInputText_ColorId, gray75_ColorId); | 174 | copy_(uiInputText_ColorId, gray75_ColorId); |
174 | copy_(uiInputTextFocused_ColorId, white_ColorId); | 175 | //copy_(uiInputTextFocused_ColorId, white_ColorId); |
176 | set_Color(uiInputTextFocused_ColorId, mix_Color(get_Color(white_ColorId), | ||
177 | get_Color(altAccentHi), 0.15f)); | ||
175 | copy_(uiInputFrame_ColorId, uiInputBackground_ColorId); | 178 | copy_(uiInputFrame_ColorId, uiInputBackground_ColorId); |
176 | copy_(uiInputFrameHover_ColorId, accentHi); | 179 | copy_(uiInputFrameHover_ColorId, accentHi); |
177 | copy_(uiInputFrameFocused_ColorId, altAccentHi); | 180 | set_Color(uiInputFrameFocused_ColorId, altAccentMid); |
178 | copy_(uiInputCursor_ColorId, altAccentHi); | 181 | copy_(uiInputCursor_ColorId, altAccentHi); |
179 | copy_(uiInputCursorText_ColorId, black_ColorId); | 182 | copy_(uiInputCursorText_ColorId, black_ColorId); |
180 | copy_(uiHeading_ColorId, accentHi); | 183 | copy_(uiHeading_ColorId, accentHi); |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 8de1162f..674b0352 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -493,7 +493,7 @@ static int documentWidth_DocumentWidget_(const iDocumentWidget *d) { | |||
493 | const iPrefs * prefs = prefs_App(); | 493 | const iPrefs * prefs = prefs_App(); |
494 | const int minWidth = 50 * gap_UI; /* lines must fit a word at least */ | 494 | const int minWidth = 50 * gap_UI; /* lines must fit a word at least */ |
495 | const float adjust = iClamp((float) bounds.size.x / gap_UI / 11 - 12, | 495 | const float adjust = iClamp((float) bounds.size.x / gap_UI / 11 - 12, |
496 | -2.0f, 10.0f); /* adapt to width */ | 496 | -1.0f, 10.0f); /* adapt to width */ |
497 | //printf("%f\n", adjust); fflush(stdout); | 497 | //printf("%f\n", adjust); fflush(stdout); |
498 | return iMini(iMax(minWidth, bounds.size.x - gap_UI * (d->pageMargin + adjust) * 2), | 498 | return iMini(iMax(minWidth, bounds.size.x - gap_UI * (d->pageMargin + adjust) * 2), |
499 | fontSize_UI * prefs->lineWidth * prefs->zoomPercent / 100); | 499 | fontSize_UI * prefs->lineWidth * prefs->zoomPercent / 100); |
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 8ed52022..f1f368b6 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
39 | # include "macos.h" | 39 | # include "macos.h" |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static const int refreshInterval_InputWidget_ = 256; | 42 | static const int refreshInterval_InputWidget_ = 512; |
43 | static const size_t maxUndo_InputWidget_ = 64; | 43 | static const size_t maxUndo_InputWidget_ = 64; |
44 | static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */ | 44 | static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */ |
45 | 45 | ||
@@ -188,9 +188,9 @@ enum iInputWidgetFlag { | |||
188 | markWords_InputWidgetFlag = iBit(8), | 188 | markWords_InputWidgetFlag = iBit(8), |
189 | needUpdateBuffer_InputWidgetFlag = iBit(9), | 189 | needUpdateBuffer_InputWidgetFlag = iBit(9), |
190 | enterKeyEnabled_InputWidgetFlag = iBit(10), | 190 | enterKeyEnabled_InputWidgetFlag = iBit(10), |
191 | enterKeyInsertsLineFeed_InputWidgetFlag | 191 | lineBreaksEnabled_InputWidgetFlag= iBit(11), |
192 | = iBit(11), | ||
193 | needBackup_InputWidgetFlag = iBit(12), | 192 | needBackup_InputWidgetFlag = iBit(12), |
193 | useReturnKeyBehavior_InputWidgetFlag = iBit(13), | ||
194 | }; | 194 | }; |
195 | 195 | ||
196 | /*----------------------------------------------------------------------------------------------*/ | 196 | /*----------------------------------------------------------------------------------------------*/ |
@@ -216,6 +216,7 @@ struct Impl_InputWidget { | |||
216 | iArray undoStack; | 216 | iArray undoStack; |
217 | int font; | 217 | int font; |
218 | iClick click; | 218 | iClick click; |
219 | int wheelAccum; | ||
219 | int cursorVis; | 220 | int cursorVis; |
220 | uint32_t timer; | 221 | uint32_t timer; |
221 | iTextBuf * buffered; /* pre-rendered static text */ | 222 | iTextBuf * buffered; /* pre-rendered static text */ |
@@ -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); |
@@ -587,10 +610,11 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
587 | d->cursor = zero_I2(); | 610 | d->cursor = zero_I2(); |
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 | if (deviceType_App() != desktop_AppDeviceType) { | 614 | lineBreaksEnabled_InputWidgetFlag | useReturnKeyBehavior_InputWidgetFlag; |
592 | d->inFlags |= enterKeyInsertsLineFeed_InputWidgetFlag; | 615 | // if (deviceType_App() != desktop_AppDeviceType) { |
593 | } | 616 | // d->inFlags |= enterKeyInsertsLineFeed_InputWidgetFlag; |
617 | // } | ||
594 | iZap(d->mark); | 618 | iZap(d->mark); |
595 | setMaxLen_InputWidget(d, maxLen); | 619 | setMaxLen_InputWidget(d, maxLen); |
596 | d->visWrapLines.start = 0; | 620 | d->visWrapLines.start = 0; |
@@ -600,6 +624,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
600 | splitToLines_(&iStringLiteral(""), &d->lines); | 624 | splitToLines_(&iStringLiteral(""), &d->lines); |
601 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); /* resizes its own height */ | 625 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); /* resizes its own height */ |
602 | init_Click(&d->click, d, SDL_BUTTON_LEFT); | 626 | init_Click(&d->click, d, SDL_BUTTON_LEFT); |
627 | d->wheelAccum = 0; | ||
603 | d->timer = 0; | 628 | d->timer = 0; |
604 | d->cursorVis = 0; | 629 | d->cursorVis = 0; |
605 | d->buffered = NULL; | 630 | d->buffered = NULL; |
@@ -625,9 +650,7 @@ void deinit_InputWidget(iInputWidget *d) { | |||
625 | delete_TextBuf(d->buffered); | 650 | delete_TextBuf(d->buffered); |
626 | clearUndo_InputWidget_(d); | 651 | clearUndo_InputWidget_(d); |
627 | deinit_Array(&d->undoStack); | 652 | deinit_Array(&d->undoStack); |
628 | if (d->timer) { | 653 | startOrStopCursorTimer_InputWidget_(d, iFalse); |
629 | SDL_RemoveTimer(d->timer); | ||
630 | } | ||
631 | deinit_String(&d->srcHint); | 654 | deinit_String(&d->srcHint); |
632 | deinit_String(&d->hint); | 655 | deinit_String(&d->hint); |
633 | deinit_String(&d->oldText); | 656 | deinit_String(&d->oldText); |
@@ -730,14 +753,18 @@ void setValidator_InputWidget(iInputWidget *d, iInputWidgetValidatorFunc validat | |||
730 | d->validatorContext = context; | 753 | d->validatorContext = context; |
731 | } | 754 | } |
732 | 755 | ||
733 | void setEnterInsertsLF_InputWidget(iInputWidget *d, iBool enterInsertsLF) { | 756 | void setLineBreaksEnabled_InputWidget(iInputWidget *d, iBool lineBreaksEnabled) { |
734 | iChangeFlags(d->inFlags, enterKeyInsertsLineFeed_InputWidgetFlag, enterInsertsLF); | 757 | iChangeFlags(d->inFlags, lineBreaksEnabled_InputWidgetFlag, lineBreaksEnabled); |
735 | } | 758 | } |
736 | 759 | ||
737 | void setEnterKeyEnabled_InputWidget(iInputWidget *d, iBool enterKeyEnabled) { | 760 | void setEnterKeyEnabled_InputWidget(iInputWidget *d, iBool enterKeyEnabled) { |
738 | iChangeFlags(d->inFlags, enterKeyEnabled_InputWidgetFlag, enterKeyEnabled); | 761 | iChangeFlags(d->inFlags, enterKeyEnabled_InputWidgetFlag, enterKeyEnabled); |
739 | } | 762 | } |
740 | 763 | ||
764 | void setUseReturnKeyBehavior_InputWidget(iInputWidget *d, iBool useReturnKeyBehavior) { | ||
765 | iChangeFlags(d->inFlags, useReturnKeyBehavior_InputWidgetFlag, useReturnKeyBehavior); | ||
766 | } | ||
767 | |||
741 | void setHint_InputWidget(iInputWidget *d, const char *hintText) { | 768 | void setHint_InputWidget(iInputWidget *d, const char *hintText) { |
742 | /* Keep original for retranslations. */ | 769 | /* Keep original for retranslations. */ |
743 | setCStr_String(&d->srcHint, hintText); | 770 | setCStr_String(&d->srcHint, hintText); |
@@ -864,18 +891,6 @@ void setTextCStr_InputWidget(iInputWidget *d, const char *cstr) { | |||
864 | delete_String(str); | 891 | delete_String(str); |
865 | } | 892 | } |
866 | 893 | ||
867 | static uint32_t cursorTimer_(uint32_t interval, void *w) { | ||
868 | iInputWidget *d = w; | ||
869 | if (d->cursorVis > 1) { | ||
870 | d->cursorVis--; | ||
871 | } | ||
872 | else { | ||
873 | d->cursorVis ^= 1; | ||
874 | } | ||
875 | refresh_Widget(w); | ||
876 | return interval; | ||
877 | } | ||
878 | |||
879 | static size_t cursorToIndex_InputWidget_(const iInputWidget *d, iInt2 pos) { | 894 | static size_t cursorToIndex_InputWidget_(const iInputWidget *d, iInt2 pos) { |
880 | if (pos.y < 0) { | 895 | if (pos.y < 0) { |
881 | return 0; | 896 | return 0; |
@@ -928,7 +943,7 @@ void begin_InputWidget(iInputWidget *d) { | |||
928 | setFlags_Widget(w, selected_WidgetFlag, iTrue); | 943 | setFlags_Widget(w, selected_WidgetFlag, iTrue); |
929 | showCursor_InputWidget_(d); | 944 | showCursor_InputWidget_(d); |
930 | refresh_Widget(w); | 945 | refresh_Widget(w); |
931 | d->timer = SDL_AddTimer(refreshInterval_InputWidget_, cursorTimer_, d); | 946 | startOrStopCursorTimer_InputWidget_(d, iTrue); |
932 | d->inFlags &= ~enterPressed_InputWidgetFlag; | 947 | d->inFlags &= ~enterPressed_InputWidgetFlag; |
933 | if (d->inFlags & selectAllOnFocus_InputWidgetFlag) { | 948 | if (d->inFlags & selectAllOnFocus_InputWidgetFlag) { |
934 | d->mark = (iRanges){ 0, lastLine_InputWidget_(d)->range.end }; | 949 | d->mark = (iRanges){ 0, lastLine_InputWidget_(d)->range.end }; |
@@ -953,8 +968,7 @@ void end_InputWidget(iInputWidget *d, iBool accept) { | |||
953 | splitToLines_(&d->oldText, &d->lines); | 968 | splitToLines_(&d->oldText, &d->lines); |
954 | } | 969 | } |
955 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; | 970 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; |
956 | SDL_RemoveTimer(d->timer); | 971 | startOrStopCursorTimer_InputWidget_(d, iFalse); |
957 | d->timer = 0; | ||
958 | SDL_StopTextInput(); | 972 | SDL_StopTextInput(); |
959 | setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iFalse); | 973 | setFlags_Widget(w, selected_WidgetFlag | keepOnTop_WidgetFlag, iFalse); |
960 | const char *id = cstr_String(id_Widget(as_Widget(d))); | 974 | const char *id = cstr_String(id_Widget(as_Widget(d))); |
@@ -1381,6 +1395,20 @@ static iBool isArrowUpDownConsumed_InputWidget_(const iInputWidget *d) { | |||
1381 | return d->maxWrapLines > 1; | 1395 | return d->maxWrapLines > 1; |
1382 | } | 1396 | } |
1383 | 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 | |||
1384 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | 1412 | static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { |
1385 | iWidget *w = as_Widget(d); | 1413 | iWidget *w = as_Widget(d); |
1386 | /* Resize according to width immediately. */ | 1414 | /* Resize according to width immediately. */ |
@@ -1399,6 +1427,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1399 | begin_InputWidget(d); | 1427 | begin_InputWidget(d); |
1400 | return iFalse; | 1428 | return iFalse; |
1401 | } | 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 | } | ||
1402 | else if (isCommand_UserEvent(ev, "keyroot.changed")) { | 1437 | else if (isCommand_UserEvent(ev, "keyroot.changed")) { |
1403 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; | 1438 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; |
1404 | } | 1439 | } |
@@ -1467,6 +1502,31 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1467 | ? SDL_SYSTEM_CURSOR_IBEAM | 1502 | ? SDL_SYSTEM_CURSOR_IBEAM |
1468 | : SDL_SYSTEM_CURSOR_ARROW); | 1503 | : SDL_SYSTEM_CURSOR_ARROW); |
1469 | } | 1504 | } |
1505 | if (ev->type == SDL_MOUSEWHEEL && contains_Widget(w, coord_MouseWheelEvent(&ev->wheel))) { | ||
1506 | const int lineHeight = lineHeight_Text(d->font); | ||
1507 | if (isPerPixel_MouseWheelEvent(&ev->wheel)) { | ||
1508 | d->wheelAccum -= ev->wheel.y; | ||
1509 | } | ||
1510 | else { | ||
1511 | d->wheelAccum -= ev->wheel.y * 3 * lineHeight; | ||
1512 | } | ||
1513 | int lineDelta = d->wheelAccum / lineHeight; | ||
1514 | if (lineDelta < 0) { | ||
1515 | lineDelta = iMax(lineDelta, -d->visWrapLines.start); | ||
1516 | if (!lineDelta) d->wheelAccum = 0; | ||
1517 | } | ||
1518 | else if (lineDelta > 0) { | ||
1519 | lineDelta = iMin(lineDelta, | ||
1520 | lastLine_InputWidget_(d)->wrapLines.end - d->visWrapLines.end); | ||
1521 | if (!lineDelta) d->wheelAccum = 0; | ||
1522 | } | ||
1523 | d->wheelAccum -= lineDelta * lineHeight; | ||
1524 | d->visWrapLines.start += lineDelta; | ||
1525 | d->visWrapLines.end += lineDelta; | ||
1526 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; | ||
1527 | refresh_Widget(d); | ||
1528 | return iTrue; | ||
1529 | } | ||
1470 | switch (processEvent_Click(&d->click, ev)) { | 1530 | switch (processEvent_Click(&d->click, ev)) { |
1471 | case none_ClickResult: | 1531 | case none_ClickResult: |
1472 | break; | 1532 | break; |
@@ -1497,6 +1557,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1497 | selectAll_InputWidget(d); | 1557 | selectAll_InputWidget(d); |
1498 | } | 1558 | } |
1499 | } | 1559 | } |
1560 | refresh_Widget(d); | ||
1500 | return iTrue; | 1561 | return iTrue; |
1501 | } | 1562 | } |
1502 | case aborted_ClickResult: | 1563 | case aborted_ClickResult: |
@@ -1586,10 +1647,10 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1586 | return iTrue; | 1647 | return iTrue; |
1587 | case SDLK_RETURN: | 1648 | case SDLK_RETURN: |
1588 | case SDLK_KP_ENTER: | 1649 | case SDLK_KP_ENTER: |
1589 | if (~d->inFlags & isSensitive_InputWidgetFlag && d->maxLen == 0) { | 1650 | if (~d->inFlags & isSensitive_InputWidgetFlag && |
1590 | if (mods == lineBreakKeyMod_ReturnKeyBehavior(prefs_App()->returnKey) || | 1651 | ~d->inFlags & isUrl_InputWidgetFlag && |
1591 | (~d->inFlags & isUrl_InputWidgetFlag && | 1652 | d->inFlags & lineBreaksEnabled_InputWidgetFlag && d->maxLen == 0) { |
1592 | d->inFlags & enterKeyInsertsLineFeed_InputWidgetFlag)) { | 1653 | if (checkLineBreakMods_InputWidget_(d, mods)) { |
1593 | pushUndo_InputWidget_(d); | 1654 | pushUndo_InputWidget_(d); |
1594 | deleteMarked_InputWidget_(d); | 1655 | deleteMarked_InputWidget_(d); |
1595 | insertChar_InputWidget_(d, '\n'); | 1656 | insertChar_InputWidget_(d, '\n'); |
@@ -1598,7 +1659,8 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1598 | } | 1659 | } |
1599 | } | 1660 | } |
1600 | if (d->inFlags & enterKeyEnabled_InputWidgetFlag && | 1661 | if (d->inFlags & enterKeyEnabled_InputWidgetFlag && |
1601 | mods == acceptKeyMod_ReturnKeyBehavior(prefs_App()->returnKey)) { | 1662 | (checkAcceptMods_InputWidget_(d, mods) || |
1663 | (~d->inFlags & lineBreaksEnabled_InputWidgetFlag))) { | ||
1602 | d->inFlags |= enterPressed_InputWidgetFlag; | 1664 | d->inFlags |= enterPressed_InputWidgetFlag; |
1603 | setFocus_Widget(NULL); | 1665 | setFocus_Widget(NULL); |
1604 | return iTrue; | 1666 | return iTrue; |
@@ -1700,6 +1762,9 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1700 | case SDLK_a: | 1762 | case SDLK_a: |
1701 | #if defined (iPlatformApple) | 1763 | #if defined (iPlatformApple) |
1702 | if (mods == KMOD_PRIMARY) { | 1764 | if (mods == KMOD_PRIMARY) { |
1765 | #else | ||
1766 | if (mods == (KMOD_PRIMARY | KMOD_SHIFT)) { | ||
1767 | #endif | ||
1703 | selectAll_InputWidget(d); | 1768 | selectAll_InputWidget(d); |
1704 | d->mark.start = 0; | 1769 | d->mark.start = 0; |
1705 | d->mark.end = cursorToIndex_InputWidget_(d, curMax); | 1770 | d->mark.end = cursorToIndex_InputWidget_(d, curMax); |
@@ -1708,7 +1773,6 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1708 | refresh_Widget(w); | 1773 | refresh_Widget(w); |
1709 | return iTrue; | 1774 | return iTrue; |
1710 | } | 1775 | } |
1711 | #endif | ||
1712 | /* fall through for Emacs-style Home/End */ | 1776 | /* fall through for Emacs-style Home/End */ |
1713 | case SDLK_e: | 1777 | case SDLK_e: |
1714 | if (mods == KMOD_CTRL || mods == (KMOD_CTRL | KMOD_SHIFT)) { | 1778 | if (mods == KMOD_CTRL || mods == (KMOD_CTRL | KMOD_SHIFT)) { |
@@ -1889,12 +1953,11 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1889 | wrapText.wrapFunc = NULL; | 1953 | wrapText.wrapFunc = NULL; |
1890 | wrapText.context = NULL; | 1954 | wrapText.context = NULL; |
1891 | } | 1955 | } |
1892 | unsetClip_Paint(&p); | ||
1893 | /* Draw the insertion point. */ | 1956 | /* Draw the insertion point. */ |
1894 | if (isFocused && d->cursorVis) { | 1957 | if (isFocused && d->cursorVis && contains_Range(&visLines, d->cursor.y)) { |
1895 | iInt2 curSize; | 1958 | iInt2 curSize; |
1896 | iRangecc cursorChar = iNullRange; | 1959 | iRangecc cursorChar = iNullRange; |
1897 | int visWrapsAbove = 0; | 1960 | int visWrapsAbove = 0; |
1898 | for (int i = d->cursor.y - 1; i >= visLines.start; i--) { | 1961 | for (int i = d->cursor.y - 1; i >= visLines.start; i--) { |
1899 | const iInputLine *line = constAt_Array(&d->lines, i); | 1962 | const iInputLine *line = constAt_Array(&d->lines, i); |
1900 | visWrapsAbove += numWrapLines_InputLine_(line); | 1963 | visWrapsAbove += numWrapLines_InputLine_(line); |
@@ -1938,6 +2001,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1938 | cursorChar); | 2001 | cursorChar); |
1939 | } | 2002 | } |
1940 | } | 2003 | } |
2004 | unsetClip_Paint(&p); | ||
1941 | drawChildren_Widget(w); | 2005 | drawChildren_Widget(w); |
1942 | } | 2006 | } |
1943 | 2007 | ||
diff --git a/src/ui/inputwidget.h b/src/ui/inputwidget.h index a94291ed..0d327ca6 100644 --- a/src/ui/inputwidget.h +++ b/src/ui/inputwidget.h | |||
@@ -50,8 +50,9 @@ void setFont_InputWidget (iInputWidget *, int fontId); | |||
50 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ | 50 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ |
51 | void setLineLimits_InputWidget (iInputWidget *, int minLines, int maxLines); | 51 | void setLineLimits_InputWidget (iInputWidget *, int minLines, int maxLines); |
52 | void setValidator_InputWidget (iInputWidget *, iInputWidgetValidatorFunc validator, void *context); | 52 | void setValidator_InputWidget (iInputWidget *, iInputWidgetValidatorFunc validator, void *context); |
53 | void setEnterInsertsLF_InputWidget (iInputWidget *, iBool enterInsertsLF); | 53 | void setLineBreaksEnabled_InputWidget(iInputWidget *, iBool lineBreaksEnabled); |
54 | void setEnterKeyEnabled_InputWidget (iInputWidget *, iBool enterKeyEnabled); | 54 | void setEnterKeyEnabled_InputWidget (iInputWidget *, iBool enterKeyEnabled); |
55 | void setUseReturnKeyBehavior_InputWidget(iInputWidget *, iBool useReturnKeyBehavior); | ||
55 | void setBackupFileName_InputWidget (iInputWidget *, const char *fileName); | 56 | void setBackupFileName_InputWidget (iInputWidget *, const char *fileName); |
56 | void begin_InputWidget (iInputWidget *); | 57 | void begin_InputWidget (iInputWidget *); |
57 | void end_InputWidget (iInputWidget *, iBool accept); | 58 | void end_InputWidget (iInputWidget *, iBool accept); |
diff --git a/src/ui/root.c b/src/ui/root.c index 9d92c44e..a8b9f998 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -358,9 +358,9 @@ static iBool handleRootCommands_(iWidget *root, const char *cmd) { | |||
358 | return iTrue; | 358 | return iTrue; |
359 | } | 359 | } |
360 | else if (equal_Command(cmd, "window.focus.lost")) { | 360 | else if (equal_Command(cmd, "window.focus.lost")) { |
361 | #if !defined (iPlatformMobile) /* apps don't share input focus on mobile */ | 361 | //#if !defined (iPlatformMobile) /* apps don't share input focus on mobile */ |
362 | setFocus_Widget(NULL); | 362 | // setFocus_Widget(NULL); |
363 | #endif | 363 | //#endif |
364 | setTextColor_LabelWidget(findWidget_App("winbar.app"), uiAnnotation_ColorId); | 364 | setTextColor_LabelWidget(findWidget_App("winbar.app"), uiAnnotation_ColorId); |
365 | setTextColor_LabelWidget(findWidget_App("winbar.title"), uiAnnotation_ColorId); | 365 | setTextColor_LabelWidget(findWidget_App("winbar.title"), uiAnnotation_ColorId); |
366 | return iFalse; | 366 | return iFalse; |
@@ -1077,6 +1077,7 @@ void createUserInterface_Root(iRoot *d) { | |||
1077 | setSelectAllOnFocus_InputWidget(url, iTrue); | 1077 | setSelectAllOnFocus_InputWidget(url, iTrue); |
1078 | setId_Widget(as_Widget(url), "url"); | 1078 | setId_Widget(as_Widget(url), "url"); |
1079 | setLineLimits_InputWidget(url, 1, 1); /* just one line while not focused */ | 1079 | setLineLimits_InputWidget(url, 1, 1); /* just one line while not focused */ |
1080 | setLineBreaksEnabled_InputWidget(url, iFalse); | ||
1080 | setUrlContent_InputWidget(url, iTrue); | 1081 | setUrlContent_InputWidget(url, iTrue); |
1081 | setNotifyEdits_InputWidget(url, iTrue); | 1082 | setNotifyEdits_InputWidget(url, iTrue); |
1082 | setTextCStr_InputWidget(url, "gemini://"); | 1083 | setTextCStr_InputWidget(url, "gemini://"); |
@@ -1272,7 +1273,7 @@ void createUserInterface_Root(iRoot *d) { | |||
1272 | setHint_InputWidget(input, "${hint.findtext}"); | 1273 | setHint_InputWidget(input, "${hint.findtext}"); |
1273 | setSelectAllOnFocus_InputWidget(input, iTrue); | 1274 | setSelectAllOnFocus_InputWidget(input, iTrue); |
1274 | setEatEscape_InputWidget(input, iFalse); /* unfocus and close with one keypress */ | 1275 | setEatEscape_InputWidget(input, iFalse); /* unfocus and close with one keypress */ |
1275 | setEnterInsertsLF_InputWidget(input, iFalse); | 1276 | setLineBreaksEnabled_InputWidget(input, iFalse); |
1276 | setId_Widget(addChildFlags_Widget(searchBar, iClob(input), expand_WidgetFlag), | 1277 | setId_Widget(addChildFlags_Widget(searchBar, iClob(input), expand_WidgetFlag), |
1277 | "find.input"); | 1278 | "find.input"); |
1278 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget(" \u2b9f ", 'g', KMOD_PRIMARY, "find.next"))); | 1279 | addChild_Widget(searchBar, iClob(newIcon_LabelWidget(" \u2b9f ", 'g', KMOD_PRIMARY, "find.next"))); |
diff --git a/src/ui/uploadwidget.c b/src/ui/uploadwidget.c index 7bfa73bd..57b6b6b7 100644 --- a/src/ui/uploadwidget.c +++ b/src/ui/uploadwidget.c | |||
@@ -116,8 +116,8 @@ void init_UploadWidget(iUploadWidget *d) { | |||
116 | setId_Widget(as_Widget(d->input), "upload.text"); | 116 | setId_Widget(as_Widget(d->input), "upload.text"); |
117 | setFont_InputWidget(d->input, monospace_FontId); | 117 | setFont_InputWidget(d->input, monospace_FontId); |
118 | setLineLimits_InputWidget(d->input, 7, 20); | 118 | setLineLimits_InputWidget(d->input, 7, 20); |
119 | setUseReturnKeyBehavior_InputWidget(d->input, iFalse); /* traditional text editor */ | ||
119 | setHint_InputWidget(d->input, "${hint.upload.text}"); | 120 | setHint_InputWidget(d->input, "${hint.upload.text}"); |
120 | setEnterInsertsLF_InputWidget(d->input, iTrue); | ||
121 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); | 121 | setFixedSize_Widget(as_Widget(d->input), init_I2(120 * gap_UI, -1)); |
122 | addChild_Widget(page, iClob(d->input)); | 122 | addChild_Widget(page, iClob(d->input)); |
123 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); | 123 | appendFramelessTabPage_Widget(tabs, iClob(page), "${heading.upload.text}", '1', 0); |