diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-22 06:57:00 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-22 06:57:00 +0300 |
commit | 62cf1f7ec604cd408b1aaf59ab2e1f6f87558b3d (patch) | |
tree | e8bab680968b4d4a1732fa2f9e311f17d538585a /src/ui/inputwidget.c | |
parent | 43cce1b10901bff92d5bd52595ef3b7b4e65ee80 (diff) |
InputWidget: Sensitive input mode
At a low level when measuring/drawing text, replace all characters with an override character.
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r-- | src/ui/inputwidget.c | 65 |
1 files changed, 24 insertions, 41 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 38c93f93..3a774b89 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -178,28 +178,17 @@ struct Impl_InputWidget { | |||
178 | enum iInputMode mode; | 178 | enum iInputMode mode; |
179 | int inFlags; | 179 | int inFlags; |
180 | size_t maxLen; /* characters */ | 180 | size_t maxLen; /* characters */ |
181 | // size_t maxLayoutLines; | ||
182 | // iArray text; /* iChar[] */ | ||
183 | // iArray oldText; /* iChar[] */ | ||
184 | size_t length; /* current length in characters */ | ||
185 | iArray lines; /* iInputLine[] */ | 181 | iArray lines; /* iInputLine[] */ |
186 | //iArray oldLines; /* iInputLine[], for restoring if edits cancelled */ | ||
187 | iString oldText; /* for restoring if edits cancelled */ | 182 | iString oldText; /* for restoring if edits cancelled */ |
188 | int lastUpdateWidth; | 183 | int lastUpdateWidth; |
189 | iString srcHint; | 184 | iString srcHint; |
190 | iString hint; | 185 | iString hint; |
191 | int leftPadding; | 186 | int leftPadding; |
192 | int rightPadding; | 187 | int rightPadding; |
193 | // size_t cursor; /* offset from beginning */ | ||
194 | // size_t lastCursor; | ||
195 | // size_t cursorLine; | ||
196 | iInt2 cursor; /* cursor position: x = byte offset, y = line index */ | 188 | iInt2 cursor; /* cursor position: x = byte offset, y = line index */ |
197 | iInt2 prevCursor; /* previous cursor position */ | 189 | iInt2 prevCursor; /* previous cursor position */ |
198 | // int verticalMoveX; | ||
199 | iRangei visWrapLines; /* which wrap lines are current visible */ | 190 | iRangei visWrapLines; /* which wrap lines are current visible */ |
200 | // int visLineOffsetY; /* vertical offset of first visible line (pixels) */ | ||
201 | int minWrapLines, maxWrapLines; /* min/max number of visible lines allowed */ | 191 | int minWrapLines, maxWrapLines; /* min/max number of visible lines allowed */ |
202 | // int scrollY; /* wrap lines */ | ||
203 | iRanges mark; | 192 | iRanges mark; |
204 | iRanges initialMark; | 193 | iRanges initialMark; |
205 | iArray undoStack; | 194 | iArray undoStack; |
@@ -356,12 +345,16 @@ static int visLineOffsetY_InputWidget_(const iInputWidget *d) { | |||
356 | return (line->wrapLines.start - d->visWrapLines.start) * lineHeight_Text(d->font); | 345 | return (line->wrapLines.start - d->visWrapLines.start) * lineHeight_Text(d->font); |
357 | } | 346 | } |
358 | 347 | ||
348 | static const iChar sensitiveChar_ = 0x25cf; /* black circle */ | ||
349 | static const char *sensitive_ = "\u25cf"; /* black circle */ | ||
350 | |||
359 | static iWrapText wrap_InputWidget_(const iInputWidget *d, int y) { | 351 | static iWrapText wrap_InputWidget_(const iInputWidget *d, int y) { |
360 | return (iWrapText){ | 352 | return (iWrapText){ |
361 | .text = range_String(&line_InputWidget_(d, y)->text), | 353 | .text = range_String(&line_InputWidget_(d, y)->text), |
362 | .maxWidth = width_Rect(contentBounds_InputWidget_(d)), | 354 | .maxWidth = width_Rect(contentBounds_InputWidget_(d)), |
363 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode | 355 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode |
364 | : word_WrapTextMode), | 356 | : word_WrapTextMode), |
357 | .overrideChar = (d->inFlags & isSensitive_InputWidgetFlag ? sensitiveChar_ : 0), | ||
365 | }; | 358 | }; |
366 | } | 359 | } |
367 | 360 | ||
@@ -469,8 +462,7 @@ static size_t length_InputWidget_(const iInputWidget *d) { | |||
469 | return len; | 462 | return len; |
470 | } | 463 | } |
471 | 464 | ||
472 | static const char *sensitive_ = "\u25cf"; /* black circle */ | 465 | #if 0 |
473 | |||
474 | static iString *visText_InputWidget_(const iInputWidget *d) { | 466 | static iString *visText_InputWidget_(const iInputWidget *d) { |
475 | iString *text; | 467 | iString *text; |
476 | if (~d->inFlags & isSensitive_InputWidgetFlag) { | 468 | if (~d->inFlags & isSensitive_InputWidgetFlag) { |
@@ -478,15 +470,15 @@ static iString *visText_InputWidget_(const iInputWidget *d) { | |||
478 | } | 470 | } |
479 | else { | 471 | else { |
480 | text = new_String(); | 472 | text = new_String(); |
481 | iAssert(d->length == length_InputWidget_(d)); | 473 | // iAssert(d->length == length_InputWidget_(d)); |
482 | for (size_t i = 0; i < d->length; i++) { | 474 | const size_t len = length_InputWidget_(d); |
475 | for (size_t i = 0; i < len; i++) { | ||
483 | appendCStr_String(text, sensitive_); | 476 | appendCStr_String(text, sensitive_); |
484 | } | 477 | } |
485 | } | 478 | } |
486 | return text; | 479 | return text; |
487 | } | 480 | } |
488 | 481 | ||
489 | #if 0 | ||
490 | static void clearLines_InputWidget_(iInputWidget *d) { | 482 | static void clearLines_InputWidget_(iInputWidget *d) { |
491 | iForEach(Array, i, &d->lines) { | 483 | iForEach(Array, i, &d->lines) { |
492 | deinit_InputLine(i.value); | 484 | deinit_InputLine(i.value); |
@@ -1134,20 +1126,6 @@ static size_t indexForRelativeX_InputWidget_(const iInputWidget *d, int x, const | |||
1134 | } | 1126 | } |
1135 | #endif | 1127 | #endif |
1136 | 1128 | ||
1137 | iDeclareType(LineMover) | ||
1138 | |||
1139 | struct Impl_LineMover { | ||
1140 | iInputWidget *d; | ||
1141 | int dir; | ||
1142 | int x; | ||
1143 | }; | ||
1144 | |||
1145 | static iBool findXBreaks_LineMover_(iWrapText *wrap, iRangecc wrappedText, | ||
1146 | int origin, int advance, iBool isBaseRTL) { | ||
1147 | iUnused(isBaseRTL); | ||
1148 | |||
1149 | } | ||
1150 | |||
1151 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir, int horiz) { | 1129 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir, int horiz) { |
1152 | const iInputLine *line = cursorLine_InputWidget_(d); | 1130 | const iInputLine *line = cursorLine_InputWidget_(d); |
1153 | iRangecc text = range_String(&line->text); | 1131 | iRangecc text = range_String(&line->text); |
@@ -1400,6 +1378,7 @@ static iInt2 coordCursor_InputWidget_(const iInputWidget *d, iInt2 coord) { | |||
1400 | .maxWidth = width_Rect(bounds), | 1378 | .maxWidth = width_Rect(bounds), |
1401 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode : word_WrapTextMode), | 1379 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode : word_WrapTextMode), |
1402 | .hitPoint = relCoord, | 1380 | .hitPoint = relCoord, |
1381 | .overrideChar = (d->inFlags & isSensitive_InputWidgetFlag ? sensitiveChar_ : 0), | ||
1403 | }; | 1382 | }; |
1404 | const iRangei visLines = visibleLineRange_InputWidget_(d); | 1383 | const iRangei visLines = visibleLineRange_InputWidget_(d); |
1405 | for (size_t y = visLines.start; y < visLines.end; y++) { | 1384 | for (size_t y = visLines.start; y < visLines.end; y++) { |
@@ -1710,14 +1689,15 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1710 | return iTrue; | 1689 | return iTrue; |
1711 | case SDLK_RETURN: | 1690 | case SDLK_RETURN: |
1712 | case SDLK_KP_ENTER: | 1691 | case SDLK_KP_ENTER: |
1713 | if (mods == KMOD_SHIFT || (d->maxLen == 0 && | 1692 | if (~d->inFlags & isSensitive_InputWidgetFlag && d->maxLen == 0) { |
1714 | ~d->inFlags & isUrl_InputWidgetFlag && | 1693 | if (mods == KMOD_SHIFT || (~d->inFlags & isUrl_InputWidgetFlag && |
1715 | d->inFlags & enterKeyInsertsLineFeed_InputWidgetFlag)) { | 1694 | d->inFlags & enterKeyInsertsLineFeed_InputWidgetFlag)) { |
1716 | pushUndo_InputWidget_(d); | 1695 | pushUndo_InputWidget_(d); |
1717 | deleteMarked_InputWidget_(d); | 1696 | deleteMarked_InputWidget_(d); |
1718 | insertChar_InputWidget_(d, '\n'); | 1697 | insertChar_InputWidget_(d, '\n'); |
1719 | contentsWereChanged_InputWidget_(d); | 1698 | contentsWereChanged_InputWidget_(d); |
1720 | return iTrue; | 1699 | return iTrue; |
1700 | } | ||
1721 | } | 1701 | } |
1722 | if (d->inFlags & enterKeyEnabled_InputWidgetFlag) { | 1702 | if (d->inFlags & enterKeyEnabled_InputWidgetFlag) { |
1723 | d->inFlags |= enterPressed_InputWidgetFlag; | 1703 | d->inFlags |= enterPressed_InputWidgetFlag; |
@@ -1973,8 +1953,10 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1973 | : isFocused /*&& !isEmpty_Array(&d->lines)*/ ? uiInputTextFocused_ColorId | 1953 | : isFocused /*&& !isEmpty_Array(&d->lines)*/ ? uiInputTextFocused_ColorId |
1974 | : uiInputText_ColorId; | 1954 | : uiInputText_ColorId; |
1975 | iWrapText wrapText = { | 1955 | iWrapText wrapText = { |
1976 | .maxWidth = width_Rect(contentBounds), | 1956 | .maxWidth = width_Rect(contentBounds), |
1977 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode : word_WrapTextMode) | 1957 | .mode = (d->inFlags & isUrl_InputWidgetFlag ? anyCharacter_WrapTextMode |
1958 | : word_WrapTextMode), | ||
1959 | .overrideChar = (d->inFlags & isSensitive_InputWidgetFlag ? sensitiveChar_ : 0), | ||
1978 | }; | 1960 | }; |
1979 | const iRangei visLines = visibleLineRange_InputWidget_(d); | 1961 | const iRangei visLines = visibleLineRange_InputWidget_(d); |
1980 | const int visLineOffsetY = visLineOffsetY_InputWidget_(d); | 1962 | const int visLineOffsetY = visLineOffsetY_InputWidget_(d); |
@@ -1995,6 +1977,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1995 | .contentBounds = contentBounds, | 1977 | .contentBounds = contentBounds, |
1996 | .mark = mark_InputWidget_(d) | 1978 | .mark = mark_InputWidget_(d) |
1997 | }; | 1979 | }; |
1980 | iAssert(~d->inFlags & isSensitive_InputWidgetFlag || size_Range(&visLines) == 1); | ||
1998 | for (size_t vis = visLines.start; vis < visLines.end; vis++) { | 1981 | for (size_t vis = visLines.start; vis < visLines.end; vis++) { |
1999 | const iInputLine *line = constAt_Array(&d->lines, vis); | 1982 | const iInputLine *line = constAt_Array(&d->lines, vis); |
2000 | wrapText.text = range_String(&line->text); | 1983 | wrapText.text = range_String(&line->text); |
@@ -2061,7 +2044,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
2061 | else { | 2044 | else { |
2062 | cursorChar = range_CStr(" "); | 2045 | cursorChar = range_CStr(" "); |
2063 | } | 2046 | } |
2064 | curSize = addX_I2(measureRange_Text(d->font, ch ? cursorChar : range_CStr("_")).bounds.size, | 2047 | curSize = addX_I2(measureRange_Text(d->font, ch ? cursorChar : range_CStr("0")).bounds.size, |
2065 | iMin(2, gap_UI / 4)); | 2048 | iMin(2, gap_UI / 4)); |
2066 | } | 2049 | } |
2067 | else { | 2050 | else { |