summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/inputwidget.c65
-rw-r--r--src/ui/text.c22
-rw-r--r--src/ui/text.h1
3 files changed, 38 insertions, 50 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 {
diff --git a/src/ui/text.c b/src/ui/text.c
index 27ed80ab..bbfd71b8 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -795,7 +795,7 @@ struct Impl_AttributedRun {
795 795
796iDeclareType(AttributedText) 796iDeclareType(AttributedText)
797iDeclareTypeConstructionArgs(AttributedText, iRangecc text, size_t maxLen, iFont *font, 797iDeclareTypeConstructionArgs(AttributedText, iRangecc text, size_t maxLen, iFont *font,
798 iColor fgColor, int baseDir) 798 iColor fgColor, int baseDir, iChar overrideChar)
799 799
800struct Impl_AttributedText { 800struct Impl_AttributedText {
801 iRangecc source; /* original source text */ 801 iRangecc source; /* original source text */
@@ -813,8 +813,9 @@ struct Impl_AttributedText {
813}; 813};
814 814
815iDefineTypeConstructionArgs(AttributedText, 815iDefineTypeConstructionArgs(AttributedText,
816 (iRangecc text, size_t maxLen, iFont *font, iColor fgColor, int baseDir), 816 (iRangecc text, size_t maxLen, iFont *font, iColor fgColor,
817 text, maxLen, font, fgColor, baseDir) 817 int baseDir, iChar overrideChar),
818 text, maxLen, font, fgColor, baseDir, overrideChar)
818 819
819static const char *sourcePtr_AttributedText_(const iAttributedText *d, int logicalPos) { 820static const char *sourcePtr_AttributedText_(const iAttributedText *d, int logicalPos) {
820 const int *logToSource = constData_Array(&d->logicalToSourceOffset); 821 const int *logToSource = constData_Array(&d->logicalToSourceOffset);
@@ -859,7 +860,7 @@ static enum iFontId fontId_Text_(const iFont *font) {
859 return (enum iFontId) (font - text_.fonts); 860 return (enum iFontId) (font - text_.fonts);
860} 861}
861 862
862static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir) { 863static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir, iChar overrideChar) {
863 iAssert(isEmpty_Array(&d->runs)); 864 iAssert(isEmpty_Array(&d->runs));
864 size_t length = 0; 865 size_t length = 0;
865 /* Prepare the UTF-32 logical string. */ { 866 /* Prepare the UTF-32 logical string. */ {
@@ -867,6 +868,9 @@ static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir) {
867 iChar u32; 868 iChar u32;
868 int len = decodeBytes_MultibyteChar(ch, d->source.end, &u32); 869 int len = decodeBytes_MultibyteChar(ch, d->source.end, &u32);
869 if (len <= 0) break; 870 if (len <= 0) break;
871 if (overrideChar) {
872 u32 = overrideChar;
873 }
870 pushBack_Array(&d->logical, &u32); 874 pushBack_Array(&d->logical, &u32);
871 length++; 875 length++;
872 if (length == d->maxLen) { 876 if (length == d->maxLen) {
@@ -1025,7 +1029,7 @@ static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir) {
1025} 1029}
1026 1030
1027void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont *font, iColor fgColor, 1031void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont *font, iColor fgColor,
1028 int baseDir) { 1032 int baseDir, iChar overrideChar) {
1029 d->source = text; 1033 d->source = text;
1030 d->maxLen = maxLen ? maxLen : iInvalidSize; 1034 d->maxLen = maxLen ? maxLen : iInvalidSize;
1031 d->font = font; 1035 d->font = font;
@@ -1038,7 +1042,7 @@ void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont
1038 init_Array(&d->logicalToSourceOffset, sizeof(int)); 1042 init_Array(&d->logicalToSourceOffset, sizeof(int));
1039 d->bidiLevels = NULL; 1043 d->bidiLevels = NULL;
1040 d->isBaseRTL = iFalse; 1044 d->isBaseRTL = iFalse;
1041 prepare_AttributedText_(d, baseDir); 1045 prepare_AttributedText_(d, baseDir, overrideChar);
1042} 1046}
1043 1047
1044void deinit_AttributedText(iAttributedText *d) { 1048void deinit_AttributedText(iAttributedText *d) {
@@ -1189,7 +1193,7 @@ static void cacheTextGlyphs_Font_(iFont *d, const iRangecc text) {
1189 iArray glyphIndices; 1193 iArray glyphIndices;
1190 init_Array(&glyphIndices, sizeof(uint32_t)); 1194 init_Array(&glyphIndices, sizeof(uint32_t));
1191 iAttributedText attrText; 1195 iAttributedText attrText;
1192 init_AttributedText(&attrText, text, 0, d, (iColor){}, 0); 1196 init_AttributedText(&attrText, text, 0, d, (iColor){}, 0, 0);
1193 /* We use AttributedText here so the font lookup matches the behavior during text drawing -- 1197 /* We use AttributedText here so the font lookup matches the behavior during text drawing --
1194 glyphs may be selected from a font that's different than `d`. */ 1198 glyphs may be selected from a font that's different than `d`. */
1195 const iChar *logicalText = constData_Array(&attrText.logical); 1199 const iChar *logicalText = constData_Array(&attrText.logical);
@@ -1367,14 +1371,14 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1367 float yCursor = 0.0f; 1371 float yCursor = 0.0f;
1368 float xCursorMax = 0.0f; 1372 float xCursorMax = 0.0f;
1369 const iBool isMonospaced = d->isMonospaced; 1373 const iBool isMonospaced = d->isMonospaced;
1374 iWrapText *wrap = args->wrap;
1370 iAssert(args->text.end >= args->text.start); 1375 iAssert(args->text.end >= args->text.start);
1371 /* Split the text into a number of attributed runs that specify exactly which 1376 /* Split the text into a number of attributed runs that specify exactly which
1372 font is used and other attributes such as color. (HarfBuzz shaping is done 1377 font is used and other attributes such as color. (HarfBuzz shaping is done
1373 with one specific font.) */ 1378 with one specific font.) */
1374 iAttributedText attrText; 1379 iAttributedText attrText;
1375 init_AttributedText(&attrText, args->text, args->maxLen, d, get_Color(args->color), 1380 init_AttributedText(&attrText, args->text, args->maxLen, d, get_Color(args->color),
1376 args->baseDir); 1381 args->baseDir, wrap ? wrap->overrideChar : 0);
1377 iWrapText *wrap = args->wrap;
1378 if (wrap) { 1382 if (wrap) {
1379 wrap->baseDir = attrText.isBaseRTL ? -1 : +1; 1383 wrap->baseDir = attrText.isBaseRTL ? -1 : +1;
1380 /* TODO: Duplicated args? */ 1384 /* TODO: Duplicated args? */
diff --git a/src/ui/text.h b/src/ui/text.h
index 322d2938..71776dca 100644
--- a/src/ui/text.h
+++ b/src/ui/text.h
@@ -211,6 +211,7 @@ struct Impl_WrapText {
211 enum iWrapTextMode mode; 211 enum iWrapTextMode mode;
212 iBool (*wrapFunc)(iWrapText *, iRangecc wrappedText, int origin, int advance, iBool isBaseRTL); 212 iBool (*wrapFunc)(iWrapText *, iRangecc wrappedText, int origin, int advance, iBool isBaseRTL);
213 void * context; 213 void * context;
214 iChar overrideChar; /* use this for all characters instead of the real ones */
214 int baseDir; /* set to +1 for LTR, -1 for RTL */ 215 int baseDir; /* set to +1 for LTR, -1 for RTL */
215 iInt2 hitPoint; /* sets hitChar_out */ 216 iInt2 hitPoint; /* sets hitChar_out */
216 const char *hitChar; /* sets hitAdvance_out */ 217 const char *hitChar; /* sets hitAdvance_out */