diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-23 11:48:06 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-02-23 11:48:06 +0200 |
commit | 78092e44e6ba554c6ed31df5bfa3d7c38d2341d2 (patch) | |
tree | 47301877cf313436dc3617b52c81575fd759abe9 | |
parent | 64b9cea544ecb2c0ae95afae5e84543ac6117f62 (diff) |
Show a search indicator in the URL bar
Indicate to user when entered text will be user for a search engine query.
IssueID #157
-rw-r--r-- | src/app.c | 9 | ||||
-rw-r--r-- | src/ui/inputwidget.c | 14 | ||||
-rw-r--r-- | src/ui/inputwidget.h | 1 | ||||
-rw-r--r-- | src/ui/window.c | 37 |
4 files changed, 56 insertions, 5 deletions
@@ -1355,7 +1355,14 @@ iBool handleCommand_App(const char *cmd) { | |||
1355 | return iTrue; | 1355 | return iTrue; |
1356 | } | 1356 | } |
1357 | else if (equal_Command(cmd, "searchurl")) { | 1357 | else if (equal_Command(cmd, "searchurl")) { |
1358 | setCStr_String(&d->prefs.searchUrl, suffixPtr_Command(cmd, "address")); | 1358 | iString *url = &d->prefs.searchUrl; |
1359 | setCStr_String(url, suffixPtr_Command(cmd, "address")); | ||
1360 | if (startsWith_String(url, "//")) { | ||
1361 | prependCStr_String(url, "gemini:"); | ||
1362 | } | ||
1363 | if (!startsWithCase_String(url, "gemini://")) { | ||
1364 | prependCStr_String(url, "gemini://"); | ||
1365 | } | ||
1359 | return iTrue; | 1366 | return iTrue; |
1360 | } | 1367 | } |
1361 | else if (equal_Command(cmd, "proxy.gemini")) { | 1368 | else if (equal_Command(cmd, "proxy.gemini")) { |
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 25c3e145..58a47610 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -81,6 +81,8 @@ struct Impl_InputWidget { | |||
81 | iArray text; /* iChar[] */ | 81 | iArray text; /* iChar[] */ |
82 | iArray oldText; /* iChar[] */ | 82 | iArray oldText; /* iChar[] */ |
83 | iString hint; | 83 | iString hint; |
84 | int leftPadding; | ||
85 | int rightPadding; | ||
84 | size_t cursor; | 86 | size_t cursor; |
85 | size_t lastCursor; | 87 | size_t lastCursor; |
86 | iRanges mark; | 88 | iRanges mark; |
@@ -114,6 +116,8 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
114 | init_String(&d->hint); | 116 | init_String(&d->hint); |
115 | init_Array(&d->undoStack, sizeof(iInputUndo)); | 117 | init_Array(&d->undoStack, sizeof(iInputUndo)); |
116 | d->font = uiInput_FontId | alwaysVariableFlag_FontId; | 118 | d->font = uiInput_FontId | alwaysVariableFlag_FontId; |
119 | d->leftPadding = 0; | ||
120 | d->rightPadding = 0; | ||
117 | d->cursor = 0; | 121 | d->cursor = 0; |
118 | d->lastCursor = 0; | 122 | d->lastCursor = 0; |
119 | d->inFlags = eatEscape_InputWidgetFlag; | 123 | d->inFlags = eatEscape_InputWidgetFlag; |
@@ -196,6 +200,12 @@ void setHint_InputWidget(iInputWidget *d, const char *hintText) { | |||
196 | setCStr_String(&d->hint, hintText); | 200 | setCStr_String(&d->hint, hintText); |
197 | } | 201 | } |
198 | 202 | ||
203 | void setContentPadding_InputWidget(iInputWidget *d, int left, int right) { | ||
204 | d->leftPadding = left; | ||
205 | d->rightPadding = right; | ||
206 | refresh_Widget(d); | ||
207 | } | ||
208 | |||
199 | static const iChar sensitiveChar_ = 0x25cf; /* black circle */ | 209 | static const iChar sensitiveChar_ = 0x25cf; /* black circle */ |
200 | 210 | ||
201 | static iString *visText_InputWidget_(const iInputWidget *d) { | 211 | static iString *visText_InputWidget_(const iInputWidget *d) { |
@@ -488,7 +498,9 @@ iLocalDef iInt2 padding_(void) { | |||
488 | 498 | ||
489 | static iInt2 textOrigin_InputWidget_(const iInputWidget *d, const char *visText) { | 499 | static iInt2 textOrigin_InputWidget_(const iInputWidget *d, const char *visText) { |
490 | const iWidget *w = constAs_Widget(d); | 500 | const iWidget *w = constAs_Widget(d); |
491 | iRect bounds = adjusted_Rect(bounds_Widget(w), padding_(), neg_I2(padding_())); | 501 | iRect bounds = adjusted_Rect(bounds_Widget(w), |
502 | addX_I2(padding_(), d->leftPadding), | ||
503 | neg_I2(addX_I2(padding_(), d->rightPadding))); | ||
492 | const iInt2 emSize = advance_Text(d->font, "M"); | 504 | const iInt2 emSize = advance_Text(d->font, "M"); |
493 | const int textWidth = advance_Text(d->font, visText).x; | 505 | const int textWidth = advance_Text(d->font, visText).x; |
494 | const int cursorX = advanceN_Text(d->font, visText, d->cursor).x; | 506 | const int cursorX = advanceN_Text(d->font, visText, d->cursor).x; |
diff --git a/src/ui/inputwidget.h b/src/ui/inputwidget.h index 654433ea..3c7b2ffb 100644 --- a/src/ui/inputwidget.h +++ b/src/ui/inputwidget.h | |||
@@ -38,6 +38,7 @@ void setMaxLen_InputWidget (iInputWidget *, size_t maxLen); | |||
38 | void setText_InputWidget (iInputWidget *, const iString *text); | 38 | void setText_InputWidget (iInputWidget *, const iString *text); |
39 | void setTextCStr_InputWidget (iInputWidget *, const char *cstr); | 39 | void setTextCStr_InputWidget (iInputWidget *, const char *cstr); |
40 | void setCursor_InputWidget (iInputWidget *, size_t pos); | 40 | void setCursor_InputWidget (iInputWidget *, size_t pos); |
41 | void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ | ||
41 | void begin_InputWidget (iInputWidget *); | 42 | void begin_InputWidget (iInputWidget *); |
42 | void end_InputWidget (iInputWidget *, iBool accept); | 43 | void end_InputWidget (iInputWidget *, iBool accept); |
43 | void selectAll_InputWidget (iInputWidget *); | 44 | void selectAll_InputWidget (iInputWidget *); |
diff --git a/src/ui/window.c b/src/ui/window.c index 510fe2fe..b545cc10 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -480,6 +480,21 @@ static void dismissPortraitPhoneSidebars_(void) { | |||
480 | } | 480 | } |
481 | } | 481 | } |
482 | 482 | ||
483 | static iBool willPerformSearchQuery_(const iString *userInput) { | ||
484 | const iString *clean = collect_String(trimmed_String(userInput)); | ||
485 | if (isEmpty_String(clean)) { | ||
486 | return iFalse; | ||
487 | } | ||
488 | return !isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(userInput); | ||
489 | } | ||
490 | |||
491 | static void showSearchQueryIndicator_(iBool show) { | ||
492 | iWidget *indicator = findWidget_App("input.indicator.search"); | ||
493 | setFlags_Widget(indicator, hidden_WidgetFlag, !show); | ||
494 | setContentPadding_InputWidget( | ||
495 | (iInputWidget *) parent_Widget(indicator), 0, show ? width_Widget(indicator) : 0); | ||
496 | } | ||
497 | |||
483 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | 498 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { |
484 | if (equal_Command(cmd, "window.resized")) { | 499 | if (equal_Command(cmd, "window.resized")) { |
485 | const iBool isPhone = deviceType_App() == phone_AppDeviceType; | 500 | const iBool isPhone = deviceType_App() == phone_AppDeviceType; |
@@ -534,14 +549,18 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
534 | return iTrue; | 549 | return iTrue; |
535 | } | 550 | } |
536 | else if (equal_Command(cmd, "input.edited")) { | 551 | else if (equal_Command(cmd, "input.edited")) { |
537 | iAnyObject *url = findChild_Widget(navBar, "url"); | 552 | iAnyObject * url = findChild_Widget(navBar, "url"); |
553 | const iString *text = text_InputWidget(url); | ||
554 | const iBool show = willPerformSearchQuery_(text); | ||
555 | showSearchQueryIndicator_(show); | ||
538 | if (pointer_Command(cmd) == url) { | 556 | if (pointer_Command(cmd) == url) { |
539 | submit_LookupWidget(findWidget_App("lookup"), text_InputWidget(url)); | 557 | submit_LookupWidget(findWidget_App("lookup"), text); |
540 | return iTrue; | 558 | return iTrue; |
541 | } | 559 | } |
542 | } | 560 | } |
543 | else if (startsWith_CStr(cmd, "input.ended id:url ")) { | 561 | else if (startsWith_CStr(cmd, "input.ended id:url ")) { |
544 | iInputWidget *url = findChild_Widget(navBar, "url"); | 562 | iInputWidget *url = findChild_Widget(navBar, "url"); |
563 | showSearchQueryIndicator_(iFalse); | ||
545 | if (isEmpty_String(text_InputWidget(url))) { | 564 | if (isEmpty_String(text_InputWidget(url))) { |
546 | /* User entered nothing; restore the current URL. */ | 565 | /* User entered nothing; restore the current URL. */ |
547 | setText_InputWidget(url, url_DocumentWidget(document_App())); | 566 | setText_InputWidget(url, url_DocumentWidget(document_App())); |
@@ -551,7 +570,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
551 | !isFocused_Widget(findWidget_App("lookup"))) { | 570 | !isFocused_Widget(findWidget_App("lookup"))) { |
552 | iString *newUrl = copy_String(text_InputWidget(url)); | 571 | iString *newUrl = copy_String(text_InputWidget(url)); |
553 | trim_String(newUrl); | 572 | trim_String(newUrl); |
554 | if (!isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(newUrl)) { | 573 | if (willPerformSearchQuery_(newUrl)) { |
555 | postCommandf_App("open url:%s", cstr_String(searchQueryUrl_App(newUrl))); | 574 | postCommandf_App("open url:%s", cstr_String(searchQueryUrl_App(newUrl))); |
556 | } | 575 | } |
557 | else { | 576 | else { |
@@ -886,6 +905,18 @@ static void setupUserInterface_Window(iWindow *d) { | |||
886 | iClob(progress), | 905 | iClob(progress), |
887 | moveToParentRightEdge_WidgetFlag); | 906 | moveToParentRightEdge_WidgetFlag); |
888 | } | 907 | } |
908 | /* Feeds refresh indicator is inside the input field. */ { | ||
909 | iLabelWidget *queryInd = | ||
910 | new_LabelWidget(uiTextAction_ColorEscape "\u21d2 Search Query", NULL); | ||
911 | setId_Widget(as_Widget(queryInd), "input.indicator.search"); | ||
912 | setBackgroundColor_Widget(as_Widget(queryInd), uiBackground_ColorId); | ||
913 | setFrameColor_Widget(as_Widget(queryInd), uiTextAction_ColorId); | ||
914 | setAlignVisually_LabelWidget(queryInd, iTrue); | ||
915 | shrink_Rect(&as_Widget(queryInd)->rect, init_I2(0, gap_UI)); | ||
916 | addChildFlags_Widget(as_Widget(url), | ||
917 | iClob(queryInd), | ||
918 | moveToParentRightEdge_WidgetFlag | hidden_WidgetFlag); | ||
919 | } | ||
889 | } | 920 | } |
890 | setId_Widget(addChild_Widget( | 921 | setId_Widget(addChild_Widget( |
891 | navBar, iClob(newIcon_LabelWidget(reloadCStr_, 0, 0, "navigate.reload"))), | 922 | navBar, iClob(newIcon_LabelWidget(reloadCStr_, 0, 0, "navigate.reload"))), |