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 HandleIndentation(bool add) = 0;
|
||||||
virtual void HandleSelectionIndentation(bool add) = 0;
|
virtual void HandleSelectionIndentation(bool add) = 0;
|
||||||
virtual void HandleWordCursorMove(bool left) = 0;
|
virtual void HandleWordCursorMove(bool left) = 0;
|
||||||
|
virtual void HandleWordSelection(const Vector2ui& position) = 0;
|
||||||
|
|
||||||
bool IsFocusable() const override;
|
bool IsFocusable() const override;
|
||||||
void Layout() override;
|
void Layout() override;
|
||||||
|
|
@ -102,8 +103,10 @@ namespace Nz
|
||||||
void OnFocusReceived() override;
|
void OnFocusReceived() override;
|
||||||
bool OnKeyPressed(const WindowEvent::KeyEvent& key) override;
|
bool OnKeyPressed(const WindowEvent::KeyEvent& key) override;
|
||||||
void OnKeyReleased(const WindowEvent::KeyEvent& key) override;
|
void OnKeyReleased(const WindowEvent::KeyEvent& key) override;
|
||||||
void OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button button) override;
|
void OnMouseButtonDoublePress(int x, int y, Mouse::Button button) override;
|
||||||
void OnMouseButtonRelease(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 OnMouseEnter() override;
|
||||||
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
||||||
void OnTextEntered(char32_t character, bool repeated) override;
|
void OnTextEntered(char32_t character, bool repeated) override;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const AbstractTextDrawer& textDrawer = GetTextDrawer();
|
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 lineCount = textDrawer.GetLineCount();
|
||||||
std::size_t line = 0U;
|
std::size_t line = 0U;
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ namespace Nz
|
||||||
void HandleIndentation(bool add) override;
|
void HandleIndentation(bool add) override;
|
||||||
void HandleSelectionIndentation(bool add) override;
|
void HandleSelectionIndentation(bool add) override;
|
||||||
void HandleWordCursorMove(bool left) override;
|
void HandleWordCursorMove(bool left) override;
|
||||||
|
void HandleWordSelection(const Vector2ui& position) override;
|
||||||
|
|
||||||
void PasteFromClipboard(const Vector2ui& targetPosition) 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)
|
void AbstractTextAreaWidget::OnMouseButtonPress(int x, int y, Mouse::Button button)
|
||||||
{
|
{
|
||||||
if (button == Mouse::Left)
|
if (button == Mouse::Left)
|
||||||
|
|
@ -424,6 +441,23 @@ namespace Nz
|
||||||
m_isMouseButtonDown = false;
|
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()
|
void AbstractTextAreaWidget::OnMouseEnter()
|
||||||
{
|
{
|
||||||
if (!Mouse::IsButtonPressed(Mouse::Left))
|
if (!Mouse::IsButtonPressed(Mouse::Left))
|
||||||
|
|
|
||||||
|
|
@ -171,14 +171,22 @@ namespace Nz
|
||||||
|
|
||||||
void RichTextAreaWidget::HandleIndentation(bool add)
|
void RichTextAreaWidget::HandleIndentation(bool add)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichTextAreaWidget::HandleSelectionIndentation(bool add)
|
void RichTextAreaWidget::HandleSelectionIndentation(bool add)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichTextAreaWidget::HandleWordCursorMove(bool left)
|
void RichTextAreaWidget::HandleWordCursorMove(bool left)
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextAreaWidget::HandleWordSelection(const Vector2ui& position)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void RichTextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
void RichTextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,25 @@
|
||||||
|
|
||||||
namespace Nz
|
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) :
|
TextAreaWidget::TextAreaWidget(BaseWidget* parent) :
|
||||||
AbstractTextAreaWidget(parent)
|
AbstractTextAreaWidget(parent)
|
||||||
{
|
{
|
||||||
|
|
@ -188,7 +207,7 @@ namespace Nz
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return;
|
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);
|
std::size_t endlIndex = m_text.rfind('\n', index - 1);
|
||||||
|
|
||||||
if ((spaceIndex > endlIndex || endlIndex == std::string::npos) && spaceIndex != std::string::npos)
|
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)
|
void TextAreaWidget::PasteFromClipboard(const Vector2ui& targetPosition)
|
||||||
{
|
{
|
||||||
std::size_t glyphCount = ComputeCharacterCount(m_text);
|
std::size_t glyphCount = ComputeCharacterCount(m_text);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue