summaryrefslogtreecommitdiff
path: root/src/ui/inputwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-07-22 06:57:00 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-07-22 06:57:00 +0300
commit62cf1f7ec604cd408b1aaf59ab2e1f6f87558b3d (patch)
treee8bab680968b4d4a1732fa2f9e311f17d538585a /src/ui/inputwidget.c
parent43cce1b10901bff92d5bd52595ef3b7b4e65ee80 (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.c65
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
348static const iChar sensitiveChar_ = 0x25cf; /* black circle */
349static const char *sensitive_ = "\u25cf"; /* black circle */
350
359static iWrapText wrap_InputWidget_(const iInputWidget *d, int y) { 351static 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
472static const char *sensitive_ = "\u25cf"; /* black circle */ 465#if 0
473
474static iString *visText_InputWidget_(const iInputWidget *d) { 466static 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
490static void clearLines_InputWidget_(iInputWidget *d) { 482static 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
1137iDeclareType(LineMover)
1138
1139struct Impl_LineMover {
1140 iInputWidget *d;
1141 int dir;
1142 int x;
1143};
1144
1145static iBool findXBreaks_LineMover_(iWrapText *wrap, iRangecc wrappedText,
1146 int origin, int advance, iBool isBaseRTL) {
1147 iUnused(isBaseRTL);
1148
1149}
1150
1151static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir, int horiz) { 1129static 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 {