Widgets/TextAreaWidget: Add support for double/triple click selection
This commit is contained in:
parent
e73489e958
commit
86071eae88
|
|
@ -94,6 +94,7 @@ namespace Nz
|
|||
virtual void HandleIndentation(bool add) = 0;
|
||||
virtual void HandleSelectionIndentation(bool add) = 0;
|
||||
virtual void HandleWordCursorMove(bool left) = 0;
|
||||
virtual void HandleWordSelection(const Vector2ui& position) = 0;
|
||||
|
||||
bool IsFocusable() const override;
|
||||
void Layout() override;
|
||||
|
|
@ -102,8 +103,10 @@ namespace Nz
|
|||
void OnFocusReceived() override;
|
||||
bool OnKeyPressed(const WindowEvent::KeyEvent& key) override;
|
||||
void OnKeyReleased(const WindowEvent::KeyEvent& key) override;
|
||||
void OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button button) override;
|
||||
void OnMouseButtonRelease(int /*x*/, int /*y*/, Mouse::Button button) override;
|
||||
void OnMouseButtonDoublePress(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseButtonPress(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseButtonRelease(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseButtonTriplePress(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseEnter() override;
|
||||
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
||||
void OnTextEntered(char32_t character, bool repeated) override;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Nz
|
|||
{
|
||||
const AbstractTextDrawer& textDrawer = GetTextDrawer();
|
||||
|
||||
glyphIndex = std::min(glyphIndex, GetTextDrawer().GetGlyphCount());
|
||||
glyphIndex = std::min(glyphIndex, textDrawer.GetGlyphCount());
|
||||
|
||||
std::size_t lineCount = textDrawer.GetLineCount();
|
||||
std::size_t line = 0U;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ namespace Nz
|
|||
void HandleIndentation(bool add) override;
|
||||
void HandleSelectionIndentation(bool add) override;
|
||||
void HandleWordCursorMove(bool left) override;
|
||||
void HandleWordSelection(const Vector2ui& position) override;
|
||||
|
||||
void PasteFromClipboard(const Vector2ui& targetPosition) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -397,6 +397,23 @@ namespace Nz
|
|||
{
|
||||
}
|
||||
|
||||
void AbstractTextAreaWidget::OnMouseButtonDoublePress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
{
|
||||
// Shift double click is handled as single click
|
||||
if (Keyboard::IsKeyPressed(Keyboard::VKey::LShift) || Keyboard::IsKeyPressed(Keyboard::VKey::RShift))
|
||||
return OnMouseButtonPress(x, y, button);
|
||||
|
||||
SetFocus();
|
||||
|
||||
Vector2ui hoveredGlyph = GetHoveredGlyph(float(x), float(y));
|
||||
HandleWordSelection(hoveredGlyph);
|
||||
|
||||
m_isMouseButtonDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractTextAreaWidget::OnMouseButtonPress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
|
|
@ -424,6 +441,23 @@ namespace Nz
|
|||
m_isMouseButtonDown = false;
|
||||
}
|
||||
|
||||
void AbstractTextAreaWidget::OnMouseButtonTriplePress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
{
|
||||
// Shift triple click is handled as single click
|
||||
if (Keyboard::IsKeyPressed(Keyboard::VKey::LShift) || Keyboard::IsKeyPressed(Keyboard::VKey::RShift))
|
||||
return OnMouseButtonPress(x, y, button);
|
||||
|
||||
SetFocus();
|
||||
|
||||
Vector2ui hoveredGlyph = GetHoveredGlyph(float(x), float(y));
|
||||
SetSelection(Vector2ui(0, hoveredGlyph.y), Vector2ui(std::numeric_limits<unsigned int>::max(), hoveredGlyph.y));
|
||||
|
||||
m_isMouseButtonDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractTextAreaWidget::OnMouseEnter()
|
||||
{
|
||||
if (!Mouse::IsButtonPressed(Mouse::Left))
|
||||
|
|
|
|||
|
|
@ -171,14 +171,22 @@ namespace Nz
|
|||
|
||||
void RichTextAreaWidget::HandleIndentation(bool add)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::HandleSelectionIndentation(bool add)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::HandleWordCursorMove(bool left)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::HandleWordSelection(const Vector2ui& position)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void RichTextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,25 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool IsSpace(char32_t character)
|
||||
{
|
||||
switch (character)
|
||||
{
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\v':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return Unicode::GetCategory(character) & Unicode::Category_Separator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextAreaWidget::TextAreaWidget(BaseWidget* parent) :
|
||||
AbstractTextAreaWidget(parent)
|
||||
{
|
||||
|
|
@ -188,7 +207,7 @@ namespace Nz
|
|||
if (index == 0)
|
||||
return;
|
||||
|
||||
std::size_t spaceIndex = m_text.rfind(' ', index - 2);
|
||||
std::size_t spaceIndex = m_text.rfind(' ', index - 1);
|
||||
std::size_t endlIndex = m_text.rfind('\n', index - 1);
|
||||
|
||||
if ((spaceIndex > endlIndex || endlIndex == std::string::npos) && spaceIndex != std::string::npos)
|
||||
|
|
@ -228,6 +247,32 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void TextAreaWidget::HandleWordSelection(const Vector2ui& position)
|
||||
{
|
||||
std::size_t index = GetGlyphIndex(m_cursorPositionEnd);
|
||||
|
||||
// FIXME: Handle Unicode properly
|
||||
std::size_t startIndex = index;
|
||||
for (std::string::reverse_iterator it { m_text.begin() + index }; it != m_text.rend(); ++it)
|
||||
{
|
||||
if (IsSpace(*it))
|
||||
break;
|
||||
|
||||
--startIndex;
|
||||
}
|
||||
|
||||
std::size_t endIndex = index;
|
||||
for (auto it = m_text.begin() + index; it != m_text.end(); ++it)
|
||||
{
|
||||
if (IsSpace(*it))
|
||||
break;
|
||||
|
||||
++endIndex;
|
||||
}
|
||||
|
||||
SetSelection(GetCursorPosition(GetCharacterPosition(m_text, startIndex)), GetCursorPosition(GetCharacterPosition(m_text, endIndex)));
|
||||
}
|
||||
|
||||
void TextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||
{
|
||||
std::size_t glyphCount = ComputeCharacterCount(m_text);
|
||||
|
|
|
|||
Loading…
Reference in New Issue