diff --git a/include/Nazara/Widgets/AbstractTextAreaWidget.hpp b/include/Nazara/Widgets/AbstractTextAreaWidget.hpp index 074476b64..260dd5c9e 100644 --- a/include/Nazara/Widgets/AbstractTextAreaWidget.hpp +++ b/include/Nazara/Widgets/AbstractTextAreaWidget.hpp @@ -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; diff --git a/include/Nazara/Widgets/AbstractTextAreaWidget.inl b/include/Nazara/Widgets/AbstractTextAreaWidget.inl index b35468362..cfe9dd62b 100644 --- a/include/Nazara/Widgets/AbstractTextAreaWidget.inl +++ b/include/Nazara/Widgets/AbstractTextAreaWidget.inl @@ -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; diff --git a/include/Nazara/Widgets/RichTextAreaWidget.hpp b/include/Nazara/Widgets/RichTextAreaWidget.hpp index 158f36168..a46cf6fee 100644 --- a/include/Nazara/Widgets/RichTextAreaWidget.hpp +++ b/include/Nazara/Widgets/RichTextAreaWidget.hpp @@ -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; diff --git a/src/Nazara/Widgets/AbstractTextAreaWidget.cpp b/src/Nazara/Widgets/AbstractTextAreaWidget.cpp index 13c0d38f1..89bf790aa 100644 --- a/src/Nazara/Widgets/AbstractTextAreaWidget.cpp +++ b/src/Nazara/Widgets/AbstractTextAreaWidget.cpp @@ -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::max(), hoveredGlyph.y)); + + m_isMouseButtonDown = true; + } + } + void AbstractTextAreaWidget::OnMouseEnter() { if (!Mouse::IsButtonPressed(Mouse::Left)) diff --git a/src/Nazara/Widgets/RichTextAreaWidget.cpp b/src/Nazara/Widgets/RichTextAreaWidget.cpp index 2ea2dbf78..595346051 100644 --- a/src/Nazara/Widgets/RichTextAreaWidget.cpp +++ b/src/Nazara/Widgets/RichTextAreaWidget.cpp @@ -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) diff --git a/src/Nazara/Widgets/TextAreaWidget.cpp b/src/Nazara/Widgets/TextAreaWidget.cpp index 8c9fa0a66..a19c7d358 100644 --- a/src/Nazara/Widgets/TextAreaWidget.cpp +++ b/src/Nazara/Widgets/TextAreaWidget.cpp @@ -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);