diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-26 14:32:02 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-07-26 14:32:02 +0300 |
commit | deba8cc58be7511ede63d0b6417c739e8e35b176 (patch) | |
tree | 8fd4fa925a5f851c35e558b012bb003131981af7 /src/ui | |
parent | c8a7d28f61ab53d841efe38ddcf34be0db3104d9 (diff) |
Asking the user for input
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/command.c | 8 | ||||
-rw-r--r-- | src/ui/command.h | 5 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 119 | ||||
-rw-r--r-- | src/ui/macos.m | 2 | ||||
-rw-r--r-- | src/ui/util.c | 60 | ||||
-rw-r--r-- | src/ui/util.h | 3 | ||||
-rw-r--r-- | src/ui/window.c | 10 |
7 files changed, 172 insertions, 35 deletions
diff --git a/src/ui/command.c b/src/ui/command.c index 71228784..b79c8bcf 100644 --- a/src/ui/command.c +++ b/src/ui/command.c | |||
@@ -51,7 +51,7 @@ void *pointer_Command(const char *cmd) { | |||
51 | return pointerLabel_Command(cmd, "ptr"); | 51 | return pointerLabel_Command(cmd, "ptr"); |
52 | } | 52 | } |
53 | 53 | ||
54 | const char *valuePtr_Command(const char *cmd, const char *label) { | 54 | const char *suffixPtr_Command(const char *cmd, const char *label) { |
55 | const iString *tok = tokenString_(label); | 55 | const iString *tok = tokenString_(label); |
56 | const char *ptr = strstr(cmd, cstr_String(tok)); | 56 | const char *ptr = strstr(cmd, cstr_String(tok)); |
57 | if (ptr) { | 57 | if (ptr) { |
@@ -60,8 +60,12 @@ const char *valuePtr_Command(const char *cmd, const char *label) { | |||
60 | return NULL; | 60 | return NULL; |
61 | } | 61 | } |
62 | 62 | ||
63 | iString *suffix_Command(const char *cmd, const char *label) { | ||
64 | return newCStr_String(suffixPtr_Command(cmd, label)); | ||
65 | } | ||
66 | |||
63 | const iString *string_Command(const char *cmd, const char *label) { | 67 | const iString *string_Command(const char *cmd, const char *label) { |
64 | iRangecc val = { valuePtr_Command(cmd, label), NULL }; | 68 | iRangecc val = { suffixPtr_Command(cmd, label), NULL }; |
65 | if (val.start) { | 69 | if (val.start) { |
66 | for (val.end = val.start; *val.end && !isspace(*val.end); val.end++) {} | 70 | for (val.end = val.start; *val.end && !isspace(*val.end); val.end++) {} |
67 | return collect_String(newRange_String(val)); | 71 | return collect_String(newRange_String(val)); |
diff --git a/src/ui/command.h b/src/ui/command.h index 84533d77..aed4a0f2 100644 --- a/src/ui/command.h +++ b/src/ui/command.h | |||
@@ -12,5 +12,6 @@ void * pointerLabel_Command (const char *, const char *label); | |||
12 | iInt2 coord_Command (const char *); | 12 | iInt2 coord_Command (const char *); |
13 | iInt2 dir_Command (const char *); | 13 | iInt2 dir_Command (const char *); |
14 | 14 | ||
15 | const iString * string_Command (const char *, const char *label); | 15 | const iString * string_Command (const char *, const char *label); /* space-delimited */ |
16 | const char * valuePtr_Command(const char *, const char *label); | 16 | const char * suffixPtr_Command (const char *, const char *label); /* until end-of-command */ |
17 | iString * suffix_Command (const char *, const char *label); /* until end-of-command */ | ||
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 2a3a2509..9fdadc4c 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -38,6 +38,7 @@ struct Impl_DocumentWidget { | |||
38 | iClick click; | 38 | iClick click; |
39 | iScrollWidget *scroll; | 39 | iScrollWidget *scroll; |
40 | iWidget *menu; | 40 | iWidget *menu; |
41 | // iWidget *userInput; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | iDefineObjectConstruction(DocumentWidget) | 44 | iDefineObjectConstruction(DocumentWidget) |
@@ -64,6 +65,7 @@ void init_DocumentWidget(iDocumentWidget *d) { | |||
64 | { "---", 0, 0, NULL }, | 65 | { "---", 0, 0, NULL }, |
65 | { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" } }, | 66 | { "Reload", 'r', KMOD_PRIMARY, "navigate.reload" } }, |
66 | 4); | 67 | 4); |
68 | // setFlags_Widget(d->userInput, hidden_WidgetFlag | disabled_WidgetFlag, iTrue); | ||
67 | } | 69 | } |
68 | 70 | ||
69 | void deinit_DocumentWidget(iDocumentWidget *d) { | 71 | void deinit_DocumentWidget(iDocumentWidget *d) { |
@@ -139,20 +141,27 @@ static void updateVisible_DocumentWidget_(iDocumentWidget *d) { | |||
139 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); | 141 | render_GmDocument(d->doc, visRange, addVisibleLink_DocumentWidget_, d); |
140 | } | 142 | } |
141 | 143 | ||
142 | static void updateSource_DocumentWidget_(iDocumentWidget *d) { | 144 | static void updateWindowTitle_DocumentWidget_(const iDocumentWidget *d) { |
143 | /* TODO: Do this in the background. However, that requires a text metrics calculator | ||
144 | that does not try to cache the glyph bitmaps. */ | ||
145 | iString str; | ||
146 | initBlock_String(&str, body_GmRequest(d->request)); | ||
147 | setSource_GmDocument(d->doc, &str, documentWidth_DocumentWidget_(d)); | ||
148 | deinit_String(&str); | ||
149 | updateVisible_DocumentWidget_(d); | ||
150 | refresh_Widget(as_Widget(d)); | ||
151 | setTitle_Window(get_Window(), | 145 | setTitle_Window(get_Window(), |
152 | !isEmpty_String(title_GmDocument(d->doc)) ? title_GmDocument(d->doc) | 146 | !isEmpty_String(title_GmDocument(d->doc)) ? title_GmDocument(d->doc) |
153 | : collectNewCStr_String("Lagrange")); | 147 | : collectNewCStr_String("Lagrange")); |
154 | } | 148 | } |
155 | 149 | ||
150 | static void updateSource_DocumentWidget_(iDocumentWidget *d) { | ||
151 | /* TODO: Do this in the background. However, that requires a text metrics calculator | ||
152 | that does not try to cache the glyph bitmaps. */ | ||
153 | if (status_GmRequest(d->request) != input_GmStatusCode && | ||
154 | status_GmRequest(d->request) != sensitiveInput_GmStatusCode) { | ||
155 | iString str; | ||
156 | initBlock_String(&str, body_GmRequest(d->request)); | ||
157 | setSource_GmDocument(d->doc, &str, documentWidth_DocumentWidget_(d)); | ||
158 | updateWindowTitle_DocumentWidget_(d); | ||
159 | updateVisible_DocumentWidget_(d); | ||
160 | refresh_Widget(as_Widget(d)); | ||
161 | deinit_String(&str); | ||
162 | } | ||
163 | } | ||
164 | |||
156 | static void fetch_DocumentWidget_(iDocumentWidget *d) { | 165 | static void fetch_DocumentWidget_(iDocumentWidget *d) { |
157 | /* Forget the previous request. */ | 166 | /* Forget the previous request. */ |
158 | if (d->request) { | 167 | if (d->request) { |
@@ -256,22 +265,80 @@ static const iString *absoluteUrl_DocumentWidget_(const iDocumentWidget *d, cons | |||
256 | return collect_String(absolute); | 265 | return collect_String(absolute); |
257 | } | 266 | } |
258 | 267 | ||
268 | static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode code) { | ||
269 | iWidget *w = as_Widget(d); | ||
270 | iString *src = collectNew_String(); | ||
271 | const iGmError *msg = get_GmError(code); | ||
272 | format_String(src, | ||
273 | "# %lc %s\n%s", | ||
274 | msg->icon ? msg->icon : 0x2327, /* X in a box */ | ||
275 | msg->title, | ||
276 | msg->info); | ||
277 | switch (code) { | ||
278 | case failedToOpenFile_GmStatusCode: | ||
279 | case certificateNotValid_GmStatusCode: | ||
280 | appendFormat_String(src, "\n\n%s", cstr_String(meta_GmRequest(d->request))); | ||
281 | break; | ||
282 | case slowDown_GmStatusCode: | ||
283 | appendFormat_String(src, "\n\nWait %s seconds before your next request.", | ||
284 | cstr_String(meta_GmRequest(d->request))); | ||
285 | break; | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | setSource_GmDocument(d->doc, src, documentWidth_DocumentWidget_(d)); | ||
290 | updateWindowTitle_DocumentWidget_(d); | ||
291 | updateVisible_DocumentWidget_(d); | ||
292 | refresh_Widget(w); | ||
293 | } | ||
294 | |||
259 | static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) { | 295 | static void checkResponseCode_DocumentWidget_(iDocumentWidget *d) { |
260 | if (d->state == fetching_DocumentState) { | 296 | if (d->state == fetching_DocumentState) { |
261 | d->state = receivedPartialResponse_DocumentState; | 297 | d->state = receivedPartialResponse_DocumentState; |
262 | d->scrollY = 0; | 298 | d->scrollY = 0; |
263 | switch (status_GmRequest(d->request)) { | 299 | switch (status_GmRequest(d->request)) { |
300 | case none_GmStatusCode: | ||
301 | case success_GmStatusCode: | ||
302 | break; | ||
303 | case input_GmStatusCode: | ||
304 | case sensitiveInput_GmStatusCode: { | ||
305 | iUrl parts; | ||
306 | init_Url(&parts, d->url); | ||
307 | makeValueInput_Widget( | ||
308 | as_Widget(d), | ||
309 | NULL, | ||
310 | cstrFormat_String(cyan_ColorEscape "%s", | ||
311 | cstr_String(collect_String(newRange_String(parts.host)))), | ||
312 | isEmpty_String(meta_GmRequest(d->request)) | ||
313 | ? cstrFormat_String( | ||
314 | "Please enter input for %s:", | ||
315 | cstr_String(collect_String(newRange_String(parts.path)))) | ||
316 | : cstr_String(meta_GmRequest(d->request)), | ||
317 | orange_ColorEscape "Send \u21d2", | ||
318 | "document.input.submit"); | ||
319 | break; | ||
320 | } | ||
264 | case redirectTemporary_GmStatusCode: | 321 | case redirectTemporary_GmStatusCode: |
265 | case redirectPermanent_GmStatusCode: | 322 | case redirectPermanent_GmStatusCode: |
266 | postCommandf_App("open redirect:1 url:%s", cstr_String(meta_GmRequest(d->request))); | 323 | if (isEmpty_String(meta_GmRequest(d->request))) { |
267 | iReleasePtr(&d->request); | 324 | showErrorPage_DocumentWidget_(d, invalidRedirect_GmStatusCode); |
325 | } | ||
326 | else { | ||
327 | postCommandf_App("open redirect:1 url:%s", cstr_String(meta_GmRequest(d->request))); | ||
328 | iReleasePtr(&d->request); | ||
329 | } | ||
268 | break; | 330 | break; |
269 | default: | 331 | default: |
332 | showErrorPage_DocumentWidget_(d, status_GmRequest(d->request)); | ||
270 | break; | 333 | break; |
271 | } | 334 | } |
272 | } | 335 | } |
273 | } | 336 | } |
274 | 337 | ||
338 | const iString *valueString_Command(const char *cmd, const char *label) { | ||
339 | return collect_String(newCStr_String(suffixPtr_Command(cmd, label))); | ||
340 | } | ||
341 | |||
275 | static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { | 342 | static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *ev) { |
276 | iWidget *w = as_Widget(d); | 343 | iWidget *w = as_Widget(d); |
277 | if (isResize_UserEvent(ev)) { | 344 | if (isResize_UserEvent(ev)) { |
@@ -279,6 +346,25 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
279 | updateVisible_DocumentWidget_(d); | 346 | updateVisible_DocumentWidget_(d); |
280 | refresh_Widget(w); | 347 | refresh_Widget(w); |
281 | } | 348 | } |
349 | else if (isCommand_UserEvent(ev, "document.input.submit")) { | ||
350 | iString *value = collect_String(suffix_Command(command_UserEvent(ev), "value")); | ||
351 | urlEncode_String(value); | ||
352 | iString *url = collect_String(copy_String(d->url)); | ||
353 | const size_t qPos = indexOfCStr_String(url, "?"); | ||
354 | if (qPos != iInvalidPos) { | ||
355 | remove_Block(&url->chars, qPos, iInvalidSize); | ||
356 | } | ||
357 | appendCStr_String(url, "?"); | ||
358 | append_String(url, value); | ||
359 | postCommandf_App("open url:%s", cstr_String(url)); | ||
360 | return iTrue; | ||
361 | } | ||
362 | else if (isCommand_UserEvent(ev, "valueinput.cancelled") && | ||
363 | cmp_String(string_Command(command_UserEvent(ev), "id"), "document.input.submit") == | ||
364 | 0) { | ||
365 | postCommand_App("navigate.back"); | ||
366 | return iTrue; | ||
367 | } | ||
282 | else if (isCommand_Widget(w, ev, "document.request.updated") && | 368 | else if (isCommand_Widget(w, ev, "document.request.updated") && |
283 | pointerLabel_Command(command_UserEvent(ev), "request") == d->request) { | 369 | pointerLabel_Command(command_UserEvent(ev), "request") == d->request) { |
284 | updateSource_DocumentWidget_(d); | 370 | updateSource_DocumentWidget_(d); |
@@ -325,6 +411,17 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
325 | updateVisible_DocumentWidget_(d); | 411 | updateVisible_DocumentWidget_(d); |
326 | refresh_Widget(w); | 412 | refresh_Widget(w); |
327 | return iTrue; | 413 | return iTrue; |
414 | #if 0 | ||
415 | case 't': | ||
416 | if (mods == KMOD_PRIMARY) { | ||
417 | makeValueInput_Widget(get_Window()->root, | ||
418 | NULL, | ||
419 | cyan_ColorEscape "Input Needed", | ||
420 | "Give it!", | ||
421 | "document.input.submit"); | ||
422 | } | ||
423 | return iTrue; | ||
424 | #endif | ||
328 | case SDLK_END: | 425 | case SDLK_END: |
329 | d->scrollY = scrollMax_DocumentWidget_(d); | 426 | d->scrollY = scrollMax_DocumentWidget_(d); |
330 | updateVisible_DocumentWidget_(d); | 427 | updateVisible_DocumentWidget_(d); |
diff --git a/src/ui/macos.m b/src/ui/macos.m index f7c49547..b50fbf38 100644 --- a/src/ui/macos.m +++ b/src/ui/macos.m | |||
@@ -407,7 +407,7 @@ void handleCommand_MacOS(const char *cmd) { | |||
407 | #if 0 | 407 | #if 0 |
408 | if (equal_Command(cmd, "tabs.changed")) { | 408 | if (equal_Command(cmd, "tabs.changed")) { |
409 | MyDelegate *myDel = (MyDelegate *) [[NSApplication sharedApplication] delegate]; | 409 | MyDelegate *myDel = (MyDelegate *) [[NSApplication sharedApplication] delegate]; |
410 | const char *tabId = valuePtr_Command(cmd, "id"); | 410 | const char *tabId = suffixPtr_Command(cmd, "id"); |
411 | if (equal_CStr(tabId, "tracker")) { | 411 | if (equal_CStr(tabId, "tracker")) { |
412 | [myDel setTouchBarVariant:tracker_TouchBarVariant]; | 412 | [myDel setTouchBarVariant:tracker_TouchBarVariant]; |
413 | } | 413 | } |
diff --git a/src/ui/util.c b/src/ui/util.c index c468ba2b..cf75a2b0 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -426,10 +426,8 @@ iWidget *makeSheet_Widget(const char *id) { | |||
426 | setId_Widget(sheet, id); | 426 | setId_Widget(sheet, id); |
427 | setFrameColor_Widget(sheet, black_ColorId); | 427 | setFrameColor_Widget(sheet, black_ColorId); |
428 | setBackgroundColor_Widget(sheet, gray25_ColorId); | 428 | setBackgroundColor_Widget(sheet, gray25_ColorId); |
429 | setFlags_Widget(sheet, | 429 | setFlags_Widget( |
430 | keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | | 430 | sheet, keepOnTop_WidgetFlag | arrangeVertical_WidgetFlag | arrangeHeight_WidgetFlag, iTrue); |
431 | arrangeHeight_WidgetFlag, | ||
432 | iTrue); | ||
433 | const iInt2 rootSize = rootSize_Window(get_Window()); | 431 | const iInt2 rootSize = rootSize_Window(get_Window()); |
434 | setSize_Widget(sheet, init_I2(rootSize.x / 2, 0)); | 432 | setSize_Widget(sheet, init_I2(rootSize.x / 2, 0)); |
435 | setFlags_Widget(sheet, fixedHeight_WidgetFlag, iFalse); | 433 | setFlags_Widget(sheet, fixedHeight_WidgetFlag, iFalse); |
@@ -440,6 +438,7 @@ void centerSheet_Widget(iWidget *sheet) { | |||
440 | arrange_Widget(sheet); | 438 | arrange_Widget(sheet); |
441 | const iInt2 rootSize = rootSize_Window(get_Window()); | 439 | const iInt2 rootSize = rootSize_Window(get_Window()); |
442 | sheet->rect.pos.x = rootSize.x / 2 - sheet->rect.size.x / 2; | 440 | sheet->rect.pos.x = rootSize.x / 2 - sheet->rect.size.x / 2; |
441 | postRefresh_App(); | ||
443 | } | 442 | } |
444 | 443 | ||
445 | void makeFilePath_Widget(iWidget * parent, | 444 | void makeFilePath_Widget(iWidget * parent, |
@@ -479,19 +478,38 @@ static void acceptValueInput_(iWidget *dlg) { | |||
479 | cstr_String(val)); | 478 | cstr_String(val)); |
480 | } | 479 | } |
481 | 480 | ||
481 | static void updateValueInputWidth_(iWidget *dlg) { | ||
482 | const iInt2 rootSize = rootSize_Window(get_Window()); | ||
483 | iWidget * title = findChild_Widget(dlg, "valueinput.title"); | ||
484 | iWidget * prompt = findChild_Widget(dlg, "valueinput.prompt"); | ||
485 | dlg->rect.size.x = iMaxi(iMaxi(rootSize.x / 2, title->rect.size.x), prompt->rect.size.x); | ||
486 | as_Widget(findChild_Widget(dlg, "input"))->rect.size.x = dlg->rect.size.x; | ||
487 | centerSheet_Widget(dlg); | ||
488 | } | ||
489 | |||
482 | iBool valueInputHandler_(iWidget *dlg, const char *cmd) { | 490 | iBool valueInputHandler_(iWidget *dlg, const char *cmd) { |
483 | iWidget *ptr = as_Widget(pointer_Command(cmd)); | 491 | iWidget *ptr = as_Widget(pointer_Command(cmd)); |
492 | if (equal_Command(cmd, "window.resized")) { | ||
493 | if (isVisible_Widget(dlg)) { | ||
494 | updateValueInputWidth_(dlg); | ||
495 | } | ||
496 | return iFalse; | ||
497 | } | ||
484 | if (equal_Command(cmd, "input.ended")) { | 498 | if (equal_Command(cmd, "input.ended")) { |
485 | if (hasParent_Widget(ptr, dlg)) { | 499 | if (hasParent_Widget(ptr, dlg)) { |
486 | if (arg_Command(cmd)) { | 500 | if (arg_Command(cmd)) { |
487 | acceptValueInput_(dlg); | 501 | acceptValueInput_(dlg); |
488 | } | 502 | } |
503 | else { | ||
504 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); | ||
505 | } | ||
489 | destroy_Widget(dlg); | 506 | destroy_Widget(dlg); |
490 | return iTrue; | 507 | return iTrue; |
491 | } | 508 | } |
492 | return iFalse; | 509 | return iFalse; |
493 | } | 510 | } |
494 | else if (equal_Command(cmd, "cancel")) { | 511 | else if (equal_Command(cmd, "cancel")) { |
512 | postCommandf_App("valueinput.cancelled id:%s", cstr_String(id_Widget(dlg))); | ||
495 | destroy_Widget(dlg); | 513 | destroy_Widget(dlg); |
496 | return iTrue; | 514 | return iTrue; |
497 | } | 515 | } |
@@ -504,32 +522,48 @@ iBool valueInputHandler_(iWidget *dlg, const char *cmd) { | |||
504 | } | 522 | } |
505 | 523 | ||
506 | iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, const char *title, | 524 | iWidget *makeValueInput_Widget(iWidget *parent, const iString *initialValue, const char *title, |
507 | const char *prompt, const char *command) { | 525 | const char *prompt, const char *acceptLabel, const char *command) { |
508 | setFocus_Widget(NULL); | 526 | if (parent) { |
509 | processEvents_App(postedEventsOnly_AppEventMode); | 527 | setFocus_Widget(NULL); |
528 | processEvents_App(postedEventsOnly_AppEventMode); | ||
529 | } | ||
510 | iWidget *dlg = makeSheet_Widget(command); | 530 | iWidget *dlg = makeSheet_Widget(command); |
511 | setCommandHandler_Widget(dlg, valueInputHandler_); | 531 | setCommandHandler_Widget(dlg, valueInputHandler_); |
512 | addChild_Widget(parent, iClob(dlg)); | 532 | if (parent) { |
513 | addChild_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL))); | 533 | addChild_Widget(parent, iClob(dlg)); |
514 | addChild_Widget(dlg, iClob(new_LabelWidget(prompt, 0, 0, NULL))); | 534 | } |
535 | setId_Widget(addChild_Widget(dlg, iClob(new_LabelWidget(title, 0, 0, NULL))), "valueinput.title"); | ||
536 | setId_Widget(addChild_Widget(dlg, iClob(new_LabelWidget(prompt, 0, 0, NULL))), "valueinput.prompt"); | ||
515 | iInputWidget *input = addChild_Widget(dlg, iClob(new_InputWidget(0))); | 537 | iInputWidget *input = addChild_Widget(dlg, iClob(new_InputWidget(0))); |
516 | if (initialValue) { | 538 | if (initialValue) { |
517 | setText_InputWidget(input, initialValue); | 539 | setText_InputWidget(input, initialValue); |
518 | } | 540 | } |
519 | setId_Widget(as_Widget(input), "input"); | 541 | setId_Widget(as_Widget(input), "input"); |
520 | as_Widget(input)->rect.size.x = dlg->rect.size.x; | 542 | updateValueInputWidth_(dlg); |
521 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); | 543 | addChild_Widget(dlg, iClob(makePadding_Widget(gap_UI))); |
522 | iWidget *div = new_Widget(); { | 544 | iWidget *div = new_Widget(); { |
523 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); | 545 | setFlags_Widget(div, arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag, iTrue); |
524 | addChild_Widget(div, iClob(new_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel"))); | 546 | addChild_Widget(div, iClob(new_LabelWidget("Cancel", SDLK_ESCAPE, 0, "cancel"))); |
525 | addChild_Widget(div, iClob(new_LabelWidget(cyan_ColorEscape "OK", SDLK_RETURN, 0, "valueinput.accept"))); | 547 | addChild_Widget(div, |
548 | iClob(new_LabelWidget(acceptLabel ? acceptLabel : cyan_ColorEscape "OK", | ||
549 | SDLK_RETURN, | ||
550 | 0, | ||
551 | "valueinput.accept"))); | ||
526 | } | 552 | } |
527 | addChild_Widget(dlg, iClob(div)); | 553 | addChild_Widget(dlg, iClob(div)); |
528 | centerSheet_Widget(dlg); | 554 | centerSheet_Widget(dlg); |
529 | setFocus_Widget(as_Widget(input)); | 555 | if (parent) { |
556 | setFocus_Widget(as_Widget(input)); | ||
557 | } | ||
530 | return dlg; | 558 | return dlg; |
531 | } | 559 | } |
532 | 560 | ||
561 | void updateValueInput_Widget(iWidget *d, const char *title, const char *prompt) { | ||
562 | setTextCStr_LabelWidget(findChild_Widget(d, "valueinput.title"), title); | ||
563 | setTextCStr_LabelWidget(findChild_Widget(d, "valueinput.prompt"), prompt); | ||
564 | updateValueInputWidth_(d); | ||
565 | } | ||
566 | |||
533 | static iBool messageHandler_(iWidget *msg, const char *cmd) { | 567 | static iBool messageHandler_(iWidget *msg, const char *cmd) { |
534 | /* Any command dismisses the sheet. */ | 568 | /* Any command dismisses the sheet. */ |
535 | iUnused(cmd); | 569 | iUnused(cmd); |
diff --git a/src/ui/util.h b/src/ui/util.h index 3181ea3f..a23f84c1 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -111,7 +111,8 @@ void centerSheet_Widget (iWidget *sheet); | |||
111 | void makeFilePath_Widget (iWidget *parent, const iString *initialPath, const char *title, | 111 | void makeFilePath_Widget (iWidget *parent, const iString *initialPath, const char *title, |
112 | const char *acceptLabel, const char *command); | 112 | const char *acceptLabel, const char *command); |
113 | iWidget * makeValueInput_Widget (iWidget *parent, const iString *initialValue, const char *title, | 113 | iWidget * makeValueInput_Widget (iWidget *parent, const iString *initialValue, const char *title, |
114 | const char *prompt, const char *command); | 114 | const char *prompt, const char *acceptLabel, const char *command); |
115 | void updateValueInput_Widget (iWidget *, const char *title, const char *prompt); | ||
115 | void makeMessage_Widget (const char *title, const char *msg); | 116 | void makeMessage_Widget (const char *title, const char *msg); |
116 | iWidget * makeQuestion_Widget (const char *title, const char *msg, | 117 | iWidget * makeQuestion_Widget (const char *title, const char *msg, |
117 | const char *labels[], const char *commands[], size_t count); | 118 | const char *labels[], const char *commands[], size_t count); |
diff --git a/src/ui/window.c b/src/ui/window.c index e9ed8d61..e4ee2799 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -74,8 +74,8 @@ static const iMenuItem editMenuItems[] = { | |||
74 | static const iMenuItem viewMenuItems[] = { | 74 | static const iMenuItem viewMenuItems[] = { |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static const char *reloadCStr_ = "\u25cb"; | 77 | static const char *reloadCStr_ = "\U0001f503"; |
78 | static const char *stopCStr_ = orange_ColorEscape "\u00d7"; | 78 | static const char *stopCStr_ = orange_ColorEscape "\U0001f310"; |
79 | 79 | ||
80 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | 80 | static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { |
81 | if (equal_Command(cmd, "input.ended")) { | 81 | if (equal_Command(cmd, "input.ended")) { |
@@ -87,7 +87,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
87 | } | 87 | } |
88 | else if (equal_Command(cmd, "document.changed")) { | 88 | else if (equal_Command(cmd, "document.changed")) { |
89 | iInputWidget *url = findWidget_App("url"); | 89 | iInputWidget *url = findWidget_App("url"); |
90 | setTextCStr_InputWidget(url, valuePtr_Command(cmd, "url")); | 90 | setTextCStr_InputWidget(url, suffixPtr_Command(cmd, "url")); |
91 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), reloadCStr_); | 91 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), reloadCStr_); |
92 | return iFalse; | 92 | return iFalse; |
93 | } | 93 | } |
@@ -100,7 +100,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
100 | if (isFocused_Widget(as_Widget(url))) { | 100 | if (isFocused_Widget(as_Widget(url))) { |
101 | setFocus_Widget(NULL); | 101 | setFocus_Widget(NULL); |
102 | } | 102 | } |
103 | setTextCStr_InputWidget(url, valuePtr_Command(cmd, "url")); | 103 | setTextCStr_InputWidget(url, suffixPtr_Command(cmd, "url")); |
104 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), stopCStr_); | 104 | updateTextCStr_LabelWidget(findChild_Widget(navBar, "reload"), stopCStr_); |
105 | return iFalse; | 105 | return iFalse; |
106 | } | 106 | } |
@@ -139,7 +139,7 @@ static void setupUserInterface_Window(iWindow *d) { | |||
139 | 139 | ||
140 | addChild_Widget(navBar, iClob(new_LabelWidget(" \u25c4 ", 0, 0, "navigate.back"))); | 140 | addChild_Widget(navBar, iClob(new_LabelWidget(" \u25c4 ", 0, 0, "navigate.back"))); |
141 | addChild_Widget(navBar, iClob(new_LabelWidget(" \u25ba ", 0, 0, "navigate.forward"))); | 141 | addChild_Widget(navBar, iClob(new_LabelWidget(" \u25ba ", 0, 0, "navigate.forward"))); |
142 | addChild_Widget(navBar, iClob(new_LabelWidget("Home", 0, 0, "navigate.home"))); | 142 | addChild_Widget(navBar, iClob(new_LabelWidget("\U0001f3e0", 0, 0, "navigate.home"))); |
143 | iInputWidget *url = new_InputWidget(0); | 143 | iInputWidget *url = new_InputWidget(0); |
144 | setId_Widget(as_Widget(url), "url"); | 144 | setId_Widget(as_Widget(url), "url"); |
145 | setTextCStr_InputWidget(url, "gemini://"); | 145 | setTextCStr_InputWidget(url, "gemini://"); |