summaryrefslogtreecommitdiff
path: root/src/ui/inputwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-09-06 22:45:15 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-09-06 22:45:15 +0300
commita364d9456dfdfd8181904fca6308e9c36eefd10a (patch)
treef355ded227cf52053784b991f5d8441a5502e447 /src/ui/inputwidget.c
parent52a1652536e4e27751ac121009f85113e72afe7d (diff)
LookupWidget: Keyboard focus and cursor
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r--src/ui/inputwidget.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c
index 16db6bf5..8f5a0656 100644
--- a/src/ui/inputwidget.c
+++ b/src/ui/inputwidget.c
@@ -54,6 +54,7 @@ struct Impl_InputWidget {
54 iBool isSensitive; 54 iBool isSensitive;
55 iBool enterPressed; 55 iBool enterPressed;
56 iBool selectAllOnFocus; 56 iBool selectAllOnFocus;
57 iBool notifyEdits;
57 size_t maxLen; 58 size_t maxLen;
58 iArray text; /* iChar[] */ 59 iArray text; /* iChar[] */
59 iArray oldText; /* iChar[] */ 60 iArray oldText; /* iChar[] */
@@ -97,6 +98,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) {
97 d->isSensitive = iFalse; 98 d->isSensitive = iFalse;
98 d->enterPressed = iFalse; 99 d->enterPressed = iFalse;
99 d->selectAllOnFocus = iFalse; 100 d->selectAllOnFocus = iFalse;
101 d->notifyEdits = iFalse;
100 iZap(d->mark); 102 iZap(d->mark);
101 setMaxLen_InputWidget(d, maxLen); 103 setMaxLen_InputWidget(d, maxLen);
102 /* Caller must arrange the width, but the height is fixed. */ 104 /* Caller must arrange the width, but the height is fixed. */
@@ -300,10 +302,20 @@ void setSelectAllOnFocus_InputWidget(iInputWidget *d, iBool selectAllOnFocus) {
300 d->selectAllOnFocus = selectAllOnFocus; 302 d->selectAllOnFocus = selectAllOnFocus;
301} 303}
302 304
305void setNotifyEdits_InputWidget(iInputWidget *d, iBool notifyEdits) {
306 d->notifyEdits = notifyEdits;
307}
308
303static iRanges mark_InputWidget_(const iInputWidget *d) { 309static iRanges mark_InputWidget_(const iInputWidget *d) {
304 return (iRanges){ iMin(d->mark.start, d->mark.end), iMax(d->mark.start, d->mark.end) }; 310 return (iRanges){ iMin(d->mark.start, d->mark.end), iMax(d->mark.start, d->mark.end) };
305} 311}
306 312
313static void contentsWereChanged_InputWidget_(iInputWidget *d) {
314 if (d->notifyEdits) {
315 postCommand_Widget(d, "input.edited id:%s", cstr_String(id_Widget(constAs_Widget(d))));
316 }
317}
318
307static iBool deleteMarked_InputWidget_(iInputWidget *d) { 319static iBool deleteMarked_InputWidget_(iInputWidget *d) {
308 const iRanges m = mark_InputWidget_(d); 320 const iRanges m = mark_InputWidget_(d);
309 if (!isEmpty_Range(&m)) { 321 if (!isEmpty_Range(&m)) {
@@ -481,6 +493,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
481 if (key == 'x') { 493 if (key == 'x') {
482 pushUndo_InputWidget_(d); 494 pushUndo_InputWidget_(d);
483 deleteMarked_InputWidget_(d); 495 deleteMarked_InputWidget_(d);
496 contentsWereChanged_InputWidget_(d);
484 } 497 }
485 } 498 }
486 return iTrue; 499 return iTrue;
@@ -494,11 +507,13 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
494 iConstForEach(String, i, paste) { 507 iConstForEach(String, i, paste) {
495 insertChar_InputWidget_(d, i.value); 508 insertChar_InputWidget_(d, i.value);
496 } 509 }
510 contentsWereChanged_InputWidget_(d);
497 } 511 }
498 return iTrue; 512 return iTrue;
499 case 'z': 513 case 'z':
500 if (popUndo_InputWidget_(d)) { 514 if (popUndo_InputWidget_(d)) {
501 refresh_Widget(w); 515 refresh_Widget(w);
516 contentsWereChanged_InputWidget_(d);
502 } 517 }
503 return iTrue; 518 return iTrue;
504 } 519 }
@@ -518,16 +533,19 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
518 if (!isEmpty_Range(&d->mark)) { 533 if (!isEmpty_Range(&d->mark)) {
519 pushUndo_InputWidget_(d); 534 pushUndo_InputWidget_(d);
520 deleteMarked_InputWidget_(d); 535 deleteMarked_InputWidget_(d);
536 contentsWereChanged_InputWidget_(d);
521 } 537 }
522 else if (mods & KMOD_ALT) { 538 else if (mods & KMOD_ALT) {
523 pushUndo_InputWidget_(d); 539 pushUndo_InputWidget_(d);
524 d->mark.start = d->cursor; 540 d->mark.start = d->cursor;
525 d->mark.end = skipWord_InputWidget_(d, d->cursor, -1); 541 d->mark.end = skipWord_InputWidget_(d, d->cursor, -1);
526 deleteMarked_InputWidget_(d); 542 deleteMarked_InputWidget_(d);
543 contentsWereChanged_InputWidget_(d);
527 } 544 }
528 else if (d->cursor > 0) { 545 else if (d->cursor > 0) {
529 pushUndo_InputWidget_(d); 546 pushUndo_InputWidget_(d);
530 remove_Array(&d->text, --d->cursor); 547 remove_Array(&d->text, --d->cursor);
548 contentsWereChanged_InputWidget_(d);
531 } 549 }
532 showCursor_InputWidget_(d); 550 showCursor_InputWidget_(d);
533 refresh_Widget(w); 551 refresh_Widget(w);
@@ -538,16 +556,19 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
538 if (!isEmpty_Range(&d->mark)) { 556 if (!isEmpty_Range(&d->mark)) {
539 pushUndo_InputWidget_(d); 557 pushUndo_InputWidget_(d);
540 deleteMarked_InputWidget_(d); 558 deleteMarked_InputWidget_(d);
559 contentsWereChanged_InputWidget_(d);
541 } 560 }
542 else if (mods & KMOD_ALT) { 561 else if (mods & KMOD_ALT) {
543 pushUndo_InputWidget_(d); 562 pushUndo_InputWidget_(d);
544 d->mark.start = d->cursor; 563 d->mark.start = d->cursor;
545 d->mark.end = skipWord_InputWidget_(d, d->cursor, +1); 564 d->mark.end = skipWord_InputWidget_(d, d->cursor, +1);
546 deleteMarked_InputWidget_(d); 565 deleteMarked_InputWidget_(d);
566 contentsWereChanged_InputWidget_(d);
547 } 567 }
548 else if (d->cursor < size_Array(&d->text)) { 568 else if (d->cursor < size_Array(&d->text)) {
549 pushUndo_InputWidget_(d); 569 pushUndo_InputWidget_(d);
550 remove_Array(&d->text, d->cursor); 570 remove_Array(&d->text, d->cursor);
571 contentsWereChanged_InputWidget_(d);
551 } 572 }
552 showCursor_InputWidget_(d); 573 showCursor_InputWidget_(d);
553 refresh_Widget(w); 574 refresh_Widget(w);
@@ -557,10 +578,12 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
557 if (!isEmpty_Range(&d->mark)) { 578 if (!isEmpty_Range(&d->mark)) {
558 pushUndo_InputWidget_(d); 579 pushUndo_InputWidget_(d);
559 deleteMarked_InputWidget_(d); 580 deleteMarked_InputWidget_(d);
581 contentsWereChanged_InputWidget_(d);
560 } 582 }
561 else { 583 else {
562 pushUndo_InputWidget_(d); 584 pushUndo_InputWidget_(d);
563 removeN_Array(&d->text, d->cursor, size_Array(&d->text) - d->cursor); 585 removeN_Array(&d->text, d->cursor, size_Array(&d->text) - d->cursor);
586 contentsWereChanged_InputWidget_(d);
564 } 587 }
565 showCursor_InputWidget_(d); 588 showCursor_InputWidget_(d);
566 refresh_Widget(w); 589 refresh_Widget(w);
@@ -612,6 +635,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
612 return iTrue; 635 return iTrue;
613 } 636 }
614 case SDLK_TAB: 637 case SDLK_TAB:
638 case SDLK_DOWN: /* for moving to lookup from url entry */
615 /* Allow focus switching. */ 639 /* Allow focus switching. */
616 return processEvent_Widget(as_Widget(d), ev); 640 return processEvent_Widget(as_Widget(d), ev);
617 } 641 }
@@ -627,6 +651,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) {
627 iConstForEach(String, i, uni) { 651 iConstForEach(String, i, uni) {
628 insertChar_InputWidget_(d, i.value); 652 insertChar_InputWidget_(d, i.value);
629 } 653 }
654 contentsWereChanged_InputWidget_(d);
630 return iTrue; 655 return iTrue;
631 } 656 }
632 return processEvent_Widget(w, ev); 657 return processEvent_Widget(w, ev);
@@ -643,7 +668,6 @@ static iBool isWhite_(const iString *str) {
643 668
644static void draw_InputWidget_(const iInputWidget *d) { 669static void draw_InputWidget_(const iInputWidget *d) {
645 const iWidget *w = constAs_Widget(d); 670 const iWidget *w = constAs_Widget(d);
646 const uint32_t time = frameTime_Window(get_Window());
647 iRect bounds = adjusted_Rect(bounds_Widget(w), padding_(), neg_I2(padding_())); 671 iRect bounds = adjusted_Rect(bounds_Widget(w), padding_(), neg_I2(padding_()));
648 iBool isHint = iFalse; 672 iBool isHint = iFalse;
649 const iBool isFocused = isFocused_Widget(w); 673 const iBool isFocused = isFocused_Widget(w);