Fix Textbox width limiting content length
This commit is contained in:
parent
7083f67979
commit
151bc4c9cd
@ -97,7 +97,8 @@ void Label::OnMouseClick(int x, int y, unsigned button)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
selecting = true;
|
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;
|
selectionIndexL = selectionIndex0;
|
||||||
selectionIndexH = selectionIndex0;
|
selectionIndexH = selectionIndex0;
|
||||||
|
|
||||||
@ -143,7 +144,8 @@ void Label::OnMouseMoved(int localx, int localy, int dx, int dy)
|
|||||||
{
|
{
|
||||||
if (selecting)
|
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)
|
if (selectionIndex1.raw_index < selectionIndex0.raw_index)
|
||||||
{
|
{
|
||||||
selectionIndexL = selectionIndex1;
|
selectionIndexL = selectionIndex1;
|
||||||
@ -160,6 +162,10 @@ void Label::OnMouseMoved(int localx, int localy, int dx, int dy)
|
|||||||
|
|
||||||
void Label::Tick(float dt)
|
void Label::Tick(float dt)
|
||||||
{
|
{
|
||||||
|
if (multiline)
|
||||||
|
{
|
||||||
|
scrollX = 0;
|
||||||
|
}
|
||||||
if (!this->IsFocused() && (HasSelection() || selecting))
|
if (!this->IsFocused() && (HasSelection() || selecting))
|
||||||
{
|
{
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
@ -244,13 +250,16 @@ void Label::Draw(const Point& screenPos)
|
|||||||
int selectionYH;
|
int selectionYH;
|
||||||
int selectionLineH = displayTextWrapper.Index2Point(indexH, selectionXH, 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 (HasSelection())
|
||||||
{
|
{
|
||||||
if (selectionLineH == selectionLineL)
|
if (selectionLineH == selectionLineL)
|
||||||
{
|
{
|
||||||
g->DrawFilledRect(
|
g->DrawFilledRect(
|
||||||
RectSized(
|
RectSized(
|
||||||
screenPos + textPosition + Vec2{ selectionXL - 1, selectionYL - 2 },
|
screenPos + tp + Vec2{ selectionXL - 1, selectionYL - 2 },
|
||||||
Vec2{ selectionXH - selectionXL + 1, FONT_H }
|
Vec2{ selectionXH - selectionXL + 1, FONT_H }
|
||||||
),
|
),
|
||||||
0xFFFFFF_rgb
|
0xFFFFFF_rgb
|
||||||
@ -260,7 +269,7 @@ void Label::Draw(const Point& screenPos)
|
|||||||
{
|
{
|
||||||
g->DrawFilledRect(
|
g->DrawFilledRect(
|
||||||
RectSized(
|
RectSized(
|
||||||
screenPos + textPosition + Vec2{ selectionXL - 1, selectionYL - 2 },
|
screenPos + tp + Vec2{ selectionXL - 1, selectionYL - 2 },
|
||||||
Vec2{ textSize.X - selectionXL + 1, FONT_H }
|
Vec2{ textSize.X - selectionXL + 1, FONT_H }
|
||||||
),
|
),
|
||||||
0xFFFFFF_rgb
|
0xFFFFFF_rgb
|
||||||
@ -269,7 +278,7 @@ void Label::Draw(const Point& screenPos)
|
|||||||
{
|
{
|
||||||
g->DrawFilledRect(
|
g->DrawFilledRect(
|
||||||
RectSized(
|
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 }
|
Vec2{ textSize.X + 1, FONT_H }
|
||||||
),
|
),
|
||||||
0xFFFFFF_rgb
|
0xFFFFFF_rgb
|
||||||
@ -277,18 +286,18 @@ void Label::Draw(const Point& screenPos)
|
|||||||
}
|
}
|
||||||
g->DrawFilledRect(
|
g->DrawFilledRect(
|
||||||
RectSized(
|
RectSized(
|
||||||
screenPos + textPosition + Vec2{ -1, selectionYH - 2 },
|
screenPos + tp + Vec2{ -1, selectionYH - 2 },
|
||||||
Vec2{ selectionXH + 1, FONT_H }
|
Vec2{ selectionXH + 1, FONT_H }
|
||||||
),
|
),
|
||||||
0xFFFFFF_rgb
|
0xFFFFFF_rgb
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g->BlendText(
|
g->BlendText(
|
||||||
screenPos + textPosition,
|
screenPos + tp,
|
||||||
displayTextWithSelection,
|
displayTextWithSelection,
|
||||||
textColour.NoAlpha().WithAlpha(255)
|
textColour.NoAlpha().WithAlpha(255)
|
||||||
);
|
);
|
||||||
|
g->SwapClipRect(clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ namespace ui
|
|||||||
int getLowerSelectionBound();
|
int getLowerSelectionBound();
|
||||||
int getHigherSelectionBound();
|
int getHigherSelectionBound();
|
||||||
|
|
||||||
|
int scrollX = 0;
|
||||||
|
|
||||||
void copySelection();
|
void copySelection();
|
||||||
public:
|
public:
|
||||||
|
@ -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_begins_at = -1; // this is a pointer into records; we're not currently in a word
|
||||||
int word_width = 0;
|
int word_width = 0;
|
||||||
int lines = 1;
|
int lines = 0;
|
||||||
int char_width;
|
int char_width;
|
||||||
int clear_count = 0;
|
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 {
|
auto wrap_if_needed = [&](int width_to_consider) -> bool {
|
||||||
if (do_wrapping && width_to_consider + char_width > max_width)
|
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, // signal the end of the line to the clickmap generator
|
||||||
true // allow record to eat the following space
|
true // allow record to eat the following space
|
||||||
});
|
});
|
||||||
line_width = 0;
|
resetLine();
|
||||||
lines += 1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -98,8 +104,7 @@ namespace ui
|
|||||||
true, // signal the end of the line to the clickmap generator
|
true, // signal the end of the line to the clickmap generator
|
||||||
false
|
false
|
||||||
});
|
});
|
||||||
lines += 1;
|
resetLine();
|
||||||
line_width = 0;
|
|
||||||
word_begins_at = -1; // reset word state
|
word_begins_at = -1; // reset word state
|
||||||
++clear_count;
|
++clear_count;
|
||||||
break;
|
break;
|
||||||
@ -206,6 +211,7 @@ namespace ui
|
|||||||
wrapped_text.append(1, record.character);
|
wrapped_text.append(1, record.character);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetLine();
|
||||||
clear_text_size = clear_count;
|
clear_text_size = clear_count;
|
||||||
wrapped_lines = lines;
|
wrapped_lines = lines;
|
||||||
return lines;
|
return lines;
|
||||||
|
@ -27,6 +27,7 @@ namespace ui
|
|||||||
Index index;
|
Index index;
|
||||||
};
|
};
|
||||||
int wrapped_lines;
|
int wrapped_lines;
|
||||||
|
int wrappedWidth;
|
||||||
std::vector<clickmap_region> regions;
|
std::vector<clickmap_region> regions;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -54,5 +55,10 @@ namespace ui
|
|||||||
{
|
{
|
||||||
return Index{ raw_text_size, (int)wrapped_text.size(), clear_text_size };
|
return Index{ raw_text_size, (int)wrapped_text.size(), clear_text_size };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WrappedWidth() const
|
||||||
|
{
|
||||||
|
return wrappedWidth;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -190,33 +190,10 @@ void Textbox::pasteIntoSelection()
|
|||||||
cursor = getLowerSelectionBound();
|
cursor = getLowerSelectionBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
int regionWidth = Size.X;
|
|
||||||
if (Appearance.icon)
|
|
||||||
regionWidth -= 13;
|
|
||||||
regionWidth -= Appearance.Margin.Left;
|
|
||||||
regionWidth -= Appearance.Margin.Right;
|
|
||||||
|
|
||||||
if (limit != String::npos)
|
if (limit != String::npos)
|
||||||
{
|
{
|
||||||
newText = newText.Substr(0, limit-backingText.length());
|
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);
|
backingText.Insert(cursor, newText);
|
||||||
cursor = cursor+newText.length();
|
cursor = cursor+newText.length();
|
||||||
@ -273,9 +250,10 @@ bool Textbox::StringValid(String text)
|
|||||||
void Textbox::Tick(float dt)
|
void Textbox::Tick(float dt)
|
||||||
{
|
{
|
||||||
Label::Tick(dt);
|
Label::Tick(dt);
|
||||||
|
auto tp = textPosition - Vec2{ scrollX, 0 };
|
||||||
if (GetParentWindow() && Visible && Enabled && IsFocused())
|
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())
|
if (!IsFocused())
|
||||||
{
|
{
|
||||||
@ -288,6 +266,32 @@ void Textbox::Tick(float dt)
|
|||||||
//OnVKeyPress(keyDown, characterDown, false, false, false);
|
//OnVKeyPress(keyDown, characterDown, false, false, false);
|
||||||
repeatTime = Platform::GetTime()+30;
|
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)
|
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();
|
cursor = getLowerSelectionBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
int regionWidth = Size.X;
|
if (limit==String::npos || backingText.length() < limit)
|
||||||
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 (cursor == (int)backingText.length())
|
if (cursor == (int)backingText.length())
|
||||||
{
|
{
|
||||||
@ -576,7 +575,8 @@ void Textbox::OnMouseClick(int x, int y, unsigned button)
|
|||||||
{
|
{
|
||||||
StopTextEditing();
|
StopTextEditing();
|
||||||
mouseDown = true;
|
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;
|
cursor = index.raw_index;
|
||||||
resetCursorPosition();
|
resetCursorPosition();
|
||||||
}
|
}
|
||||||
@ -593,7 +593,8 @@ void Textbox::OnMouseMoved(int localx, int localy, int dx, int dy)
|
|||||||
{
|
{
|
||||||
if(mouseDown)
|
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;
|
cursor = index.raw_index;
|
||||||
resetCursorPosition();
|
resetCursorPosition();
|
||||||
}
|
}
|
||||||
@ -611,24 +612,26 @@ void Textbox::Draw(const Point& screenPos)
|
|||||||
Label::Draw(screenPos);
|
Label::Draw(screenPos);
|
||||||
|
|
||||||
Graphics * g = GetGraphics();
|
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(IsFocused())
|
||||||
{
|
{
|
||||||
if(border)
|
|
||||||
g->DrawRect(RectSized(screenPos, Size), 0xFFFFFF_rgb);
|
|
||||||
g->DrawLine(
|
g->DrawLine(
|
||||||
screenPos + textPosition + Vec2{ cursorPositionX, cursorPositionY-2 },
|
screenPos + tp + Vec2{ cursorPositionX, cursorPositionY-2 },
|
||||||
screenPos + textPosition + Vec2{ cursorPositionX, cursorPositionY+9 },
|
screenPos + tp + Vec2{ cursorPositionX, cursorPositionY+9 },
|
||||||
0xFFFFFF_rgb);
|
0xFFFFFF_rgb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!text.length())
|
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)
|
if(Appearance.icon)
|
||||||
g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, 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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user