summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ui/documentwidget.c57
-rw-r--r--src/ui/inputwidget.c25
-rw-r--r--src/ui/inputwidget.h4
-rw-r--r--src/ui/util.c3
4 files changed, 75 insertions, 14 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 4706033a..e138af6f 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1549,6 +1549,43 @@ static void togglePreFold_DocumentWidget_(iDocumentWidget *d, uint16_t preId) {
1549 refresh_Widget(as_Widget(d)); 1549 refresh_Widget(as_Widget(d));
1550} 1550}
1551 1551
1552static iString *makeQueryUrl_DocumentWidget_(const iDocumentWidget *d,
1553 const iString *userEnteredText) {
1554 iString *url = copy_String(d->mod.url);
1555 /* Remove the existing query string. */
1556 const size_t qPos = indexOfCStr_String(url, "?");
1557 if (qPos != iInvalidPos) {
1558 remove_Block(&url->chars, qPos, iInvalidSize);
1559 }
1560 appendCStr_String(url, "?");
1561 append_String(url, collect_String(urlEncode_String(userEnteredText)));
1562 return url;
1563}
1564
1565static void inputQueryValidator_(iInputWidget *input, void *context) {
1566 iDocumentWidget *d = context;
1567 iString *url = makeQueryUrl_DocumentWidget_(d, text_InputWidget(input));
1568 iWidget *dlg = parent_Widget(input);
1569 iLabelWidget *counter = findChild_Widget(dlg, "valueinput.counter");
1570 iAssert(counter);
1571 int avail = 1024 - (int) size_String(url);
1572 setFlags_Widget(findChild_Widget(dlg, "default"), disabled_WidgetFlag, avail < 0);
1573 setEnterKeyEnabled_InputWidget(input, avail >= 0);
1574 int len = length_String(text_InputWidget(input));
1575 if (len > 1024) {
1576 iString *trunc = copy_String(text_InputWidget(input));
1577 truncate_String(trunc, 1024);
1578 setText_InputWidget(input, trunc);
1579 delete_String(trunc);
1580 }
1581 setTextCStr_LabelWidget(counter, format_CStr("%d", avail)); /* Gemini URL maxlen */
1582 setTextColor_LabelWidget(counter,
1583 avail < 0 ? uiTextCaution_ColorId :
1584 avail < 128 ? uiTextStrong_ColorId
1585 : uiTextDim_ColorId);
1586 delete_String(url);
1587}
1588
1552static void checkResponse_DocumentWidget_(iDocumentWidget *d) { 1589static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
1553 if (!d->request) { 1590 if (!d->request) {
1554 return; 1591 return;
@@ -1578,6 +1615,11 @@ static void checkResponse_DocumentWidget_(iDocumentWidget *d) {
1578 : cstr_String(&resp->meta), 1615 : cstr_String(&resp->meta),
1579 uiTextCaution_ColorEscape "${dlg.input.send}", 1616 uiTextCaution_ColorEscape "${dlg.input.send}",
1580 format_CStr("!document.input.submit doc:%p", d)); 1617 format_CStr("!document.input.submit doc:%p", d));
1618 setId_Widget(addChildPosFlags_Widget(findChild_Widget(dlg, "dialogbuttons"),
1619 iClob(new_LabelWidget("", NULL)),
1620 front_WidgetAddPos, frameless_WidgetFlag),
1621 "valueinput.counter");
1622 setValidator_InputWidget(findChild_Widget(dlg, "input"), inputQueryValidator_, d);
1581 setSensitiveContent_InputWidget(findChild_Widget(dlg, "input"), 1623 setSensitiveContent_InputWidget(findChild_Widget(dlg, "input"),
1582 statusCode == sensitiveInput_GmStatusCode); 1624 statusCode == sensitiveInput_GmStatusCode);
1583 if (document_App() != d) { 1625 if (document_App() != d) {
@@ -2209,17 +2251,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
2209 return iTrue; 2251 return iTrue;
2210 } 2252 }
2211 else if (equal_Command(cmd, "document.input.submit") && document_Command(cmd) == d) { 2253 else if (equal_Command(cmd, "document.input.submit") && document_Command(cmd) == d) {
2212 iString *value = suffix_Command(cmd, "value"); 2254 postCommandf_Root(w->root,
2213 set_String(value, collect_String(urlEncode_String(value))); 2255 "open url:%s",
2214 iString *url = collect_String(copy_String(d->mod.url)); 2256 cstrCollect_String(makeQueryUrl_DocumentWidget_
2215 const size_t qPos = indexOfCStr_String(url, "?"); 2257 (d, collect_String(suffix_Command(cmd, "value")))));
2216 if (qPos != iInvalidPos) {
2217 remove_Block(&url->chars, qPos, iInvalidSize);
2218 }
2219 appendCStr_String(url, "?");
2220 append_String(url, value);
2221 postCommandf_Root(w->root, "open url:%s", cstr_String(url));
2222 delete_String(value);
2223 return iTrue; 2258 return iTrue;
2224 } 2259 }
2225 else if (equal_Command(cmd, "valueinput.cancelled") && 2260 else if (equal_Command(cmd, "valueinput.cancelled") &&
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 72f9f706..38d025b9 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -75,6 +75,7 @@ enum iInputWidgetFlag {
75 isMarking_InputWidgetFlag = iBit(7), 75 isMarking_InputWidgetFlag = iBit(7),
76 markWords_InputWidgetFlag = iBit(8), 76 markWords_InputWidgetFlag = iBit(8),
77 needUpdateBuffer_InputWidgetFlag = iBit(9), 77 needUpdateBuffer_InputWidgetFlag = iBit(9),
78 enterKeyEnabled_InputWidgetFlag = iBit(10),
78}; 79};
79 80
80/*----------------------------------------------------------------------------------------------*/ 81/*----------------------------------------------------------------------------------------------*/
@@ -124,6 +125,8 @@ struct Impl_InputWidget {
124 int cursorVis; 125 int cursorVis;
125 uint32_t timer; 126 uint32_t timer;
126 iTextBuf * buffered; 127 iTextBuf * buffered;
128 iInputWidgetValidatorFunc validator;
129 void * validatorContext;
127}; 130};
128 131
129iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen) 132iDefineObjectConstructionArgs(InputWidget, (size_t maxLen), maxLen)
@@ -295,6 +298,8 @@ static void updateLinesAndResize_InputWidget_(iInputWidget *d) {
295void init_InputWidget(iInputWidget *d, size_t maxLen) { 298void init_InputWidget(iInputWidget *d, size_t maxLen) {
296 iWidget *w = &d->widget; 299 iWidget *w = &d->widget;
297 init_Widget(w); 300 init_Widget(w);
301 d->validator = NULL;
302 d->validatorContext = NULL;
298 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue); 303 setFlags_Widget(w, focusable_WidgetFlag | hover_WidgetFlag | touchDrag_WidgetFlag, iTrue);
299#if defined (iPlatformMobile) 304#if defined (iPlatformMobile)
300 setFlags_Widget(w, extraPadding_WidgetFlag, iTrue); 305 setFlags_Widget(w, extraPadding_WidgetFlag, iTrue);
@@ -312,7 +317,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
312 d->lastCursor = 0; 317 d->lastCursor = 0;
313 d->cursorLine = 0; 318 d->cursorLine = 0;
314 d->verticalMoveX = -1; /* TODO: Use this. */ 319 d->verticalMoveX = -1; /* TODO: Use this. */
315 d->inFlags = eatEscape_InputWidgetFlag; 320 d->inFlags = eatEscape_InputWidgetFlag | enterKeyEnabled_InputWidgetFlag;
316 iZap(d->mark); 321 iZap(d->mark);
317 setMaxLen_InputWidget(d, maxLen); 322 setMaxLen_InputWidget(d, maxLen);
318 d->maxLayoutLines = iInvalidSize; 323 d->maxLayoutLines = iInvalidSize;
@@ -423,6 +428,15 @@ void setMaxLayoutLines_InputWidget(iInputWidget *d, size_t maxLayoutLines) {
423 updateMetrics_InputWidget_(d); 428 updateMetrics_InputWidget_(d);
424} 429}
425 430
431void setValidator_InputWidget(iInputWidget *d, iInputWidgetValidatorFunc validator, void *context) {
432 d->validator = validator;
433 d->validatorContext = context;
434}
435
436void setEnterKeyEnabled_InputWidget(iInputWidget *d, iBool enterKeyEnabled) {
437 iChangeFlags(d->inFlags, enterKeyEnabled_InputWidgetFlag, enterKeyEnabled);
438}
439
426void setHint_InputWidget(iInputWidget *d, const char *hintText) { 440void setHint_InputWidget(iInputWidget *d, const char *hintText) {
427 /* Keep original for retranslations. */ 441 /* Keep original for retranslations. */
428 setCStr_String(&d->srcHint, hintText); 442 setCStr_String(&d->srcHint, hintText);
@@ -715,6 +729,9 @@ static iRanges mark_InputWidget_(const iInputWidget *d) {
715} 729}
716 730
717static void contentsWereChanged_InputWidget_(iInputWidget *d) { 731static void contentsWereChanged_InputWidget_(iInputWidget *d) {
732 if (d->validator) {
733 d->validator(d, d->validatorContext); /* this may change the contents */
734 }
718 updateLinesAndResize_InputWidget_(d); 735 updateLinesAndResize_InputWidget_(d);
719 if (d->inFlags & notifyEdits_InputWidgetFlag) { 736 if (d->inFlags & notifyEdits_InputWidgetFlag) {
720 postCommand_Widget(d, "input.edited id:%s", cstr_String(id_Widget(constAs_Widget(d)))); 737 postCommand_Widget(d, "input.edited id:%s", cstr_String(id_Widget(constAs_Widget(d))));
@@ -1068,8 +1085,10 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
1068 contentsWereChanged_InputWidget_(d); 1085 contentsWereChanged_InputWidget_(d);
1069 return iTrue; 1086 return iTrue;
1070 } 1087 }
1071 d->inFlags |= enterPressed_InputWidgetFlag; 1088 if (d->inFlags & enterKeyEnabled_InputWidgetFlag) {
1072 setFocus_Widget(NULL); 1089 d->inFlags |= enterPressed_InputWidgetFlag;
1090 setFocus_Widget(NULL);
1091 }
1073 return iTrue; 1092 return iTrue;
1074 case SDLK_ESCAPE: 1093 case SDLK_ESCAPE:
1075 end_InputWidget(d, iFalse); 1094 end_InputWidget(d, iFalse);
diff --git a/src/ui/inputwidget.h b/src/ui/inputwidget.h
index a632e230..cb32a29c 100644
--- a/src/ui/inputwidget.h
+++ b/src/ui/inputwidget.h
@@ -39,6 +39,8 @@ struct Impl_InputWidgetContentPadding {
39 int right; 39 int right;
40}; 40};
41 41
42typedef void (*iInputWidgetValidatorFunc)(iInputWidget *, void *context);
43
42void setHint_InputWidget (iInputWidget *, const char *hintText); 44void setHint_InputWidget (iInputWidget *, const char *hintText);
43void setMode_InputWidget (iInputWidget *, enum iInputMode mode); 45void setMode_InputWidget (iInputWidget *, enum iInputMode mode);
44void setMaxLen_InputWidget (iInputWidget *, size_t maxLen); 46void setMaxLen_InputWidget (iInputWidget *, size_t maxLen);
@@ -48,6 +50,8 @@ void setFont_InputWidget (iInputWidget *, int fontId);
48void setCursor_InputWidget (iInputWidget *, size_t pos); 50void setCursor_InputWidget (iInputWidget *, size_t pos);
49void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */ 51void setContentPadding_InputWidget (iInputWidget *, int left, int right); /* only affects the text entry */
50void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines); 52void setMaxLayoutLines_InputWidget (iInputWidget *, size_t maxLayoutLines);
53void setValidator_InputWidget (iInputWidget *, iInputWidgetValidatorFunc validator, void *context);
54void setEnterKeyEnabled_InputWidget (iInputWidget *, iBool enterKeyEnabled);
51void begin_InputWidget (iInputWidget *); 55void begin_InputWidget (iInputWidget *);
52void end_InputWidget (iInputWidget *, iBool accept); 56void end_InputWidget (iInputWidget *, iBool accept);
53void selectAll_InputWidget (iInputWidget *); 57void selectAll_InputWidget (iInputWidget *);
diff --git a/src/ui/util.c b/src/ui/util.c
index f20338b5..ece527e1 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1901,6 +1901,9 @@ iWidget *makeDialogButtons_Widget(const iMenuItem *actions, size_t numActions) {
1901 } 1901 }
1902 iLabelWidget *button = 1902 iLabelWidget *button =
1903 addChild_Widget(div, iClob(newKeyMods_LabelWidget(label, key, kmods, cmd))); 1903 addChild_Widget(div, iClob(newKeyMods_LabelWidget(label, key, kmods, cmd)));
1904 if (isDefault) {
1905 setId_Widget(as_Widget(button), "default");
1906 }
1904 setFlags_Widget(as_Widget(button), alignLeft_WidgetFlag | drawKey_WidgetFlag, isDefault); 1907 setFlags_Widget(as_Widget(button), alignLeft_WidgetFlag | drawKey_WidgetFlag, isDefault);
1905 setFont_LabelWidget(button, isDefault ? fonts[1] : fonts[0]); 1908 setFont_LabelWidget(button, isDefault ? fonts[1] : fonts[0]);
1906 } 1909 }