Fix Textbox width limiting content length

This commit is contained in:
Tamás Bálint Misius 2023-12-15 22:27:12 +01:00
parent 7083f67979
commit 151bc4c9cd
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
5 changed files with 77 additions and 52 deletions

View File

@ -97,7 +97,8 @@ void Label::OnMouseClick(int x, int y, unsigned button)
else
{
selecting = true;
selectionIndex0 = textWrapper.Point2Index(x - textPosition.X, y - textPosition.Y);
auto tp = textPosition - Vec2{ scrollX, 0 };
selectionIndex0 = textWrapper.Point2Index(x - tp.X, y - tp.Y);
selectionIndexL = selectionIndex0;
selectionIndexH = selectionIndex0;
@ -143,7 +144,8 @@ void Label::OnMouseMoved(int localx, int localy, int dx, int dy)
{
if (selecting)
{
selectionIndex1 = textWrapper.Point2Index(localx - textPosition.X, localy - textPosition.Y);
auto tp = textPosition - Vec2{ scrollX, 0 };
selectionIndex1 = textWrapper.Point2Index(localx - tp.X, localy - tp.Y);
if (selectionIndex1.raw_index < selectionIndex0.raw_index)
{
selectionIndexL = selectionIndex1;
@ -160,6 +162,10 @@ void Label::OnMouseMoved(int localx, int localy, int dx, int dy)
void Label::Tick(float dt)
{
if (multiline)
{
scrollX = 0;
}
if (!this->IsFocused() && (HasSelection() || selecting))
{
ClearSelection();
@ -244,13 +250,16 @@ void Label::Draw(const Point& screenPos)
int selectionYH;
int selectionLineH = displayTextWrapper.Index2Point(indexH, selectionXH, selectionYH);
auto clip = RectSized(screenPos + Vec2{ 1, 1 }, Size - Vec2{ 2, 2 }) & g->GetClipRect();
g->SwapClipRect(clip);
auto tp = textPosition - Vec2{ scrollX, 0 };
if (HasSelection())
{
if (selectionLineH == selectionLineL)
{
g->DrawFilledRect(
RectSized(
screenPos + textPosition + Vec2{ selectionXL - 1, selectionYL - 2 },
screenPos + tp + Vec2{ selectionXL - 1, selectionYL - 2 },
Vec2{ selectionXH - selectionXL + 1, FONT_H }
),
0xFFFFFF_rgb
@ -260,7 +269,7 @@ void Label::Draw(const Point& screenPos)
{
g->DrawFilledRect(
RectSized(
screenPos + textPosition + Vec2{ selectionXL - 1, selectionYL - 2 },
screenPos + tp + Vec2{ selectionXL - 1, selectionYL - 2 },
Vec2{ textSize.X - selectionXL + 1, FONT_H }
),
0xFFFFFF_rgb
@ -269,7 +278,7 @@ void Label::Draw(const Point& screenPos)
{
g->DrawFilledRect(
RectSized(
screenPos + textPosition + Vec2{ -1, selectionYL - 2 + i * FONT_H },
screenPos + tp + Vec2{ -1, selectionYL - 2 + i * FONT_H },
Vec2{ textSize.X + 1, FONT_H }
),
0xFFFFFF_rgb
@ -277,18 +286,18 @@ void Label::Draw(const Point& screenPos)
}
g->DrawFilledRect(
RectSized(
screenPos + textPosition + Vec2{ -1, selectionYH - 2 },
screenPos + tp + Vec2{ -1, selectionYH - 2 },
Vec2{ selectionXH + 1, FONT_H }
),
0xFFFFFF_rgb
);
}
}
g->BlendText(
screenPos + textPosition,
screenPos + tp,
displayTextWithSelection,
textColour.NoAlpha().WithAlpha(255)
);
g->SwapClipRect(clip);
}

View File

@ -35,6 +35,7 @@ namespace ui
int getLowerSelectionBound();
int getHigherSelectionBound();
int scrollX = 0;
void copySelection();
public:

View File

@ -27,10 +27,17 @@ namespace ui
int word_begins_at = -1; // this is a pointer into records; we're not currently in a word
int word_width = 0;
int lines = 1;
int lines = 0;
int char_width;
int clear_count = 0;
wrappedWidth = 0;
auto resetLine = [&]() {
wrappedWidth = std::max(wrappedWidth, line_width);
line_width = 0;
lines += 1;
};
auto wrap_if_needed = [&](int width_to_consider) -> bool {
if (do_wrapping && width_to_consider + char_width > max_width)
{
@ -42,8 +49,7 @@ namespace ui
true, // signal the end of the line to the clickmap generator
true // allow record to eat the following space
});
line_width = 0;
lines += 1;
resetLine();
return true;
}
return false;
@ -98,8 +104,7 @@ namespace ui
true, // signal the end of the line to the clickmap generator
false
});
lines += 1;
line_width = 0;
resetLine();
word_begins_at = -1; // reset word state
++clear_count;
break;
@ -206,6 +211,7 @@ namespace ui
wrapped_text.append(1, record.character);
}
resetLine();
clear_text_size = clear_count;
wrapped_lines = lines;
return lines;

View File

@ -27,6 +27,7 @@ namespace ui
Index index;
};
int wrapped_lines;
int wrappedWidth;
std::vector<clickmap_region> regions;
public:
@ -54,5 +55,10 @@ namespace ui
{
return Index{ raw_text_size, (int)wrapped_text.size(), clear_text_size };
}
int WrappedWidth() const
{
return wrappedWidth;
}
};
}

View File

@ -190,33 +190,10 @@ void Textbox::pasteIntoSelection()
cursor = getLowerSelectionBound();
}
int regionWidth = Size.X;
if (Appearance.icon)
regionWidth -= 13;
regionWidth -= Appearance.Margin.Left;
regionWidth -= Appearance.Margin.Right;
if (limit != String::npos)
{
newText = newText.Substr(0, limit-backingText.length());
}
if (!multiline && Graphics::TextSize(backingText + newText).X - 1 > regionWidth)
{
int pLimit = regionWidth - (Graphics::TextSize(backingText).X - 1);
int pWidth = 0;
auto it = newText.begin();
while (it != newText.end())
{
auto w = Graphics::CharWidth(*it);
if (pWidth + w > pLimit)
{
break;
}
pWidth += w;
++it;
}
newText = String(newText.begin(), it);
}
backingText.Insert(cursor, newText);
cursor = cursor+newText.length();
@ -273,9 +250,10 @@ bool Textbox::StringValid(String text)
void Textbox::Tick(float dt)
{
Label::Tick(dt);
auto tp = textPosition - Vec2{ scrollX, 0 };
if (GetParentWindow() && Visible && Enabled && IsFocused())
{
ui::Engine::Ref().TextInputRect(GetScreenPos() + textPosition + inputRectPosition - Point(1, 3), Point(Size.X - textPosition.X - inputRectPosition.X, FONT_H + 2));
ui::Engine::Ref().TextInputRect(GetScreenPos() + tp + inputRectPosition - Point(1, 3), Point(Size.X - tp.X - inputRectPosition.X, FONT_H + 2));
}
if (!IsFocused())
{
@ -288,6 +266,32 @@ void Textbox::Tick(float dt)
//OnVKeyPress(keyDown, characterDown, false, false, false);
repeatTime = Platform::GetTime()+30;
}
if (!multiline)
{
int regionWidth = Size.X;
if (Appearance.icon)
{
regionWidth -= 13;
}
regionWidth -= Appearance.Margin.Left;
regionWidth -= Appearance.Margin.Right;
if (scrollX > displayTextWrapper.WrappedWidth() - regionWidth)
{
scrollX = displayTextWrapper.WrappedWidth() - regionWidth;
}
if (scrollX < cursorPositionX - regionWidth)
{
scrollX = cursorPositionX - regionWidth;
}
if (scrollX > cursorPositionX)
{
scrollX = cursorPositionX;
}
if (scrollX < 0)
{
scrollX = 0;
}
}
}
void Textbox::OnKeyRelease(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt)
@ -483,12 +487,7 @@ void Textbox::InsertText(String text)
cursor = getLowerSelectionBound();
}
int regionWidth = Size.X;
if (Appearance.icon)
regionWidth -= 13;
regionWidth -= Appearance.Margin.Left;
regionWidth -= Appearance.Margin.Right;
if ((limit==String::npos || backingText.length() < limit) && (Graphics::TextSize(backingText + text).X - 1 <= regionWidth || multiline))
if (limit==String::npos || backingText.length() < limit)
{
if (cursor == (int)backingText.length())
{
@ -576,7 +575,8 @@ void Textbox::OnMouseClick(int x, int y, unsigned button)
{
StopTextEditing();
mouseDown = true;
auto index = textWrapper.Point2Index(x-textPosition.X, y-textPosition.Y);
auto tp = textPosition - Vec2{ scrollX, 0 };
auto index = textWrapper.Point2Index(x-tp.X, y-tp.Y);
cursor = index.raw_index;
resetCursorPosition();
}
@ -593,7 +593,8 @@ void Textbox::OnMouseMoved(int localx, int localy, int dx, int dy)
{
if(mouseDown)
{
auto index = textWrapper.Point2Index(localx-textPosition.X, localy-textPosition.Y);
auto tp = textPosition - Vec2{ scrollX, 0 };
auto index = textWrapper.Point2Index(localx-tp.X, localy-tp.Y);
cursor = index.raw_index;
resetCursorPosition();
}
@ -611,24 +612,26 @@ void Textbox::Draw(const Point& screenPos)
Label::Draw(screenPos);
Graphics * g = GetGraphics();
auto clip = RectSized(screenPos + Vec2{ 1, 1 }, Size - Vec2{ 2, 2 }) & g->GetClipRect();
g->SwapClipRect(clip);
auto tp = textPosition - Vec2{ scrollX, 0 };
if(IsFocused())
{
if(border)
g->DrawRect(RectSized(screenPos, Size), 0xFFFFFF_rgb);
g->DrawLine(
screenPos + textPosition + Vec2{ cursorPositionX, cursorPositionY-2 },
screenPos + textPosition + Vec2{ cursorPositionX, cursorPositionY+9 },
screenPos + tp + Vec2{ cursorPositionX, cursorPositionY-2 },
screenPos + tp + Vec2{ cursorPositionX, cursorPositionY+9 },
0xFFFFFF_rgb);
}
else
{
if(!text.length())
{
g->BlendText(screenPos + textPosition, placeHolder, textColour.NoAlpha().WithAlpha(170));
g->BlendText(screenPos + tp, placeHolder, textColour.NoAlpha().WithAlpha(170));
}
if(border)
g->DrawRect(RectSized(screenPos, Size), 0xA0A0A0_rgb);
}
if(Appearance.icon)
g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon);
g->SwapClipRect(clip);
if(border)
g->DrawRect(RectSized(screenPos, Size), IsFocused() ? 0xFFFFFF_rgb : 0xA0A0A0_rgb);
}