diff options
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r-- | src/ui/inputwidget.c | 68 |
1 files changed, 20 insertions, 48 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index b51b3985..29003ad5 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -747,7 +747,13 @@ static size_t indexForRelativeX_InputWidget_(const iInputWidget *d, int x, const | |||
747 | 747 | ||
748 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir) { | 748 | static iBool moveCursorByLine_InputWidget_(iInputWidget *d, int dir) { |
749 | const iInputLine *line = line_InputWidget_(d, d->cursorLine); | 749 | const iInputLine *line = line_InputWidget_(d, d->cursorLine); |
750 | int xPos = measureN_Text(d->font, cstr_String(&line->text), d->cursor - line->offset).advance.x; | 750 | int xPos1 = maxWidth_TextMetrics(measureN_Text(d->font, |
751 | cstr_String(&line->text), | ||
752 | d->cursor - line->offset)); | ||
753 | int xPos2 = maxWidth_TextMetrics(measureN_Text(d->font, | ||
754 | cstr_String(&line->text), | ||
755 | iMin(d->cursor + 1 - line->offset, line->len))); | ||
756 | const int xPos = (xPos1 + xPos2) / 2; | ||
751 | size_t newCursor = iInvalidPos; | 757 | size_t newCursor = iInvalidPos; |
752 | const size_t numLines = size_Array(&d->lines); | 758 | const size_t numLines = size_Array(&d->lines); |
753 | if (dir < 0 && d->cursorLine > 0) { | 759 | if (dir < 0 && d->cursorLine > 0) { |
@@ -861,32 +867,6 @@ static size_t skipWord_InputWidget_(const iInputWidget *d, size_t pos, int dir) | |||
861 | return pos; | 867 | return pos; |
862 | } | 868 | } |
863 | 869 | ||
864 | #if 0 | ||
865 | static iInt2 textOrigin_InputWidget_(const iInputWidget *d) { //}, const char *visText) { | ||
866 | // const iWidget *w = constAs_Widget(d); | ||
867 | iRect bounds = contentBounds_InputWidget_(d);/* adjusted_Rect(bounds_Widget(w), | ||
868 | addX_I2(padding_(), d->leftPadding), | ||
869 | neg_I2(addX_I2(padding_(), d->rightPadding)));*/ | ||
870 | // const iInt2 emSize = advance_Text(d->font, "M"); | ||
871 | // const int textWidth = advance_Text(d->font, visText).x; | ||
872 | // const int cursorX = advanceN_Text(d->font, visText, d->cursor).x; | ||
873 | // int xOff = 0; | ||
874 | // shrink_Rect(&bounds, init_I2(gap_UI * (flags_Widget(w) & tight_WidgetFlag ? 1 : 2), 0)); | ||
875 | /* if (d->maxLen == 0) { | ||
876 | if (textWidth > width_Rect(bounds) - emSize.x) { | ||
877 | xOff = width_Rect(bounds) - emSize.x - textWidth; | ||
878 | } | ||
879 | if (cursorX + xOff < width_Rect(bounds) / 2) { | ||
880 | xOff = width_Rect(bounds) / 2 - cursorX; | ||
881 | } | ||
882 | xOff = iMin(xOff, 0); | ||
883 | }*/ | ||
884 | // const int yOff = 0.3f * lineHeight_Text(d->font); // (height_Rect(bounds) - lineHeight_Text(d->font)) / 2; | ||
885 | // return addY_I2(topLeft_Rect(bounds), yOff); | ||
886 | |||
887 | } | ||
888 | #endif | ||
889 | |||
890 | static size_t coordIndex_InputWidget_(const iInputWidget *d, iInt2 coord) { | 870 | static size_t coordIndex_InputWidget_(const iInputWidget *d, iInt2 coord) { |
891 | const iInt2 pos = sub_I2(coord, contentBounds_InputWidget_(d).pos); | 871 | const iInt2 pos = sub_I2(coord, contentBounds_InputWidget_(d).pos); |
892 | const size_t lineNumber = iMin(iMax(0, pos.y) / lineHeight_Text(d->font), | 872 | const size_t lineNumber = iMin(iMax(0, pos.y) / lineHeight_Text(d->font), |
@@ -1342,17 +1322,6 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1342 | return processEvent_Widget(w, ev); | 1322 | return processEvent_Widget(w, ev); |
1343 | } | 1323 | } |
1344 | 1324 | ||
1345 | #if 0 | ||
1346 | static iBool isWhite_(const iString *str) { | ||
1347 | iConstForEach(String, i, str) { | ||
1348 | if (!isSpace_Char(i.value)) { | ||
1349 | return iFalse; | ||
1350 | } | ||
1351 | } | ||
1352 | return iTrue; | ||
1353 | } | ||
1354 | #endif | ||
1355 | |||
1356 | static void draw_InputWidget_(const iInputWidget *d) { | 1325 | static void draw_InputWidget_(const iInputWidget *d) { |
1357 | const iWidget *w = constAs_Widget(d); | 1326 | const iWidget *w = constAs_Widget(d); |
1358 | iRect bounds = adjusted_Rect(bounds_InputWidget_(d), padding_(), neg_I2(padding_())); | 1327 | iRect bounds = adjusted_Rect(bounds_InputWidget_(d), padding_(), neg_I2(padding_())); |
@@ -1400,14 +1369,12 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1400 | /* Draw the selected range. */ | 1369 | /* Draw the selected range. */ |
1401 | const iRanges mark = mark_InputWidget_(d); | 1370 | const iRanges mark = mark_InputWidget_(d); |
1402 | if (mark.start < lineRange.end && mark.end > lineRange.start) { | 1371 | if (mark.start < lineRange.end && mark.end > lineRange.start) { |
1403 | const int m1 = measureN_Text(d->font, | 1372 | const int m1 = maxWidth_TextMetrics(measureN_Text(d->font, |
1404 | cstr_String(&line->text), | 1373 | cstr_String(&line->text), |
1405 | iMax(lineRange.start, mark.start) - line->offset) | 1374 | iMax(lineRange.start, mark.start) - line->offset)); |
1406 | .advance.x; | 1375 | const int m2 = maxWidth_TextMetrics(measureN_Text(d->font, |
1407 | const int m2 = measureN_Text(d->font, | ||
1408 | cstr_String(&line->text), | 1376 | cstr_String(&line->text), |
1409 | iMin(lineRange.end, mark.end) - line->offset) | 1377 | iMin(lineRange.end, mark.end) - line->offset)); |
1410 | .advance.x; | ||
1411 | fillRect_Paint(&p, | 1378 | fillRect_Paint(&p, |
1412 | (iRect){ addX_I2(drawPos, iMin(m1, m2)), | 1379 | (iRect){ addX_I2(drawPos, iMin(m1, m2)), |
1413 | init_I2(iMax(gap_UI / 3, iAbs(m2 - m1)), | 1380 | init_I2(iMax(gap_UI / 3, iAbs(m2 - m1)), |
@@ -1446,15 +1413,20 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1446 | } | 1413 | } |
1447 | const iInputLine *curLine = line_InputWidget_(d, d->cursorLine); | 1414 | const iInputLine *curLine = line_InputWidget_(d, d->cursorLine); |
1448 | const iString * text = &curLine->text; | 1415 | const iString * text = &curLine->text; |
1449 | /* The `gap_UI` offsets below are a hack. They are used because for some reason the | 1416 | /* The bounds include visible characters, while advance includes whitespace as well. |
1450 | cursor rect and the glyph inside don't quite position like during `run_Text_()`. */ | 1417 | Normally only the advance is needed, but if the cursor is at a newline, the advance |
1451 | const int prefixSize = measureN_Text(d->font, cstr_String(text), d->cursor - curLine->offset).advance.x; | 1418 | will have reset back to zero. */ |
1419 | const int prefixSize = maxWidth_TextMetrics(measureN_Text(d->font, | ||
1420 | cstr_String(text), | ||
1421 | d->cursor - curLine->offset)); | ||
1452 | const iInt2 curPos = addX_I2(addY_I2(contentBounds.pos, lineHeight_Text(d->font) * d->cursorLine), | 1422 | const iInt2 curPos = addX_I2(addY_I2(contentBounds.pos, lineHeight_Text(d->font) * d->cursorLine), |
1453 | prefixSize + | 1423 | prefixSize + |
1454 | (d->mode == insert_InputMode ? -curSize.x / 2 : 0)); | 1424 | (d->mode == insert_InputMode ? -curSize.x / 2 : 0)); |
1455 | const iRect curRect = { curPos, curSize }; | 1425 | const iRect curRect = { curPos, curSize }; |
1456 | fillRect_Paint(&p, curRect, uiInputCursor_ColorId); | 1426 | fillRect_Paint(&p, curRect, uiInputCursor_ColorId); |
1457 | if (d->mode == overwrite_InputMode) { | 1427 | if (d->mode == overwrite_InputMode) { |
1428 | /* The `gap_UI` offsets below are a hack. They are used because for some reason the | ||
1429 | cursor rect and the glyph inside don't quite position like during `run_Text_()`. */ | ||
1458 | draw_Text(d->font, | 1430 | draw_Text(d->font, |
1459 | addX_I2(curPos, iMin(1, gap_UI / 8)), | 1431 | addX_I2(curPos, iMin(1, gap_UI / 8)), |
1460 | uiInputCursorText_ColorId, | 1432 | uiInputCursorText_ColorId, |