diff --git a/SDK/include/NDK/Canvas.hpp b/SDK/include/NDK/Canvas.hpp index 1b0fbda4f..26cc36cbd 100644 --- a/SDK/include/NDK/Canvas.hpp +++ b/SDK/include/NDK/Canvas.hpp @@ -31,6 +31,9 @@ namespace Ndk Canvas& operator=(const Canvas&) = delete; Canvas& operator=(Canvas&&) = delete; + NazaraSignal(OnUnhandledKeyPressed, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/); + NazaraSignal(OnUnhandledKeyReleased, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/); + protected: inline void ClearKeyboardOwner(std::size_t canvasIndex); diff --git a/SDK/src/NDK/Canvas.cpp b/SDK/src/NDK/Canvas.cpp index aced59e4e..f6d27ad15 100644 --- a/SDK/src/NDK/Canvas.cpp +++ b/SDK/src/NDK/Canvas.cpp @@ -150,7 +150,7 @@ namespace Ndk } } - void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) + void Canvas::OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event) { if (m_keyboardOwner != InvalidCanvasIndex) { @@ -204,12 +204,16 @@ namespace Ndk } } } + + OnUnhandledKeyPressed(eventHandler, event); } - void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event) + void Canvas::OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event) { if (m_keyboardOwner != InvalidCanvasIndex) m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event); + + OnUnhandledKeyReleased(eventHandler, event); } void Canvas::OnEventTextEntered(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::TextEvent& event) diff --git a/SDK/src/NDK/Widgets/TextAreaWidget.cpp b/SDK/src/NDK/Widgets/TextAreaWidget.cpp index 3ab119a0a..e823e54e8 100644 --- a/SDK/src/NDK/Widgets/TextAreaWidget.cpp +++ b/SDK/src/NDK/Widgets/TextAreaWidget.cpp @@ -243,6 +243,39 @@ namespace Ndk { switch (key.code) { + case Nz::Keyboard::Backspace: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyBackspace(this, &ignoreDefaultAction); + + std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin); + std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd); + + if (ignoreDefaultAction || cursorGlyphEnd == 0) + return true; + + // When a text is selected, delete key does the same as delete and leave the character behind it + if (HasSelection()) + EraseSelection(); + else + { + Nz::String newText; + + if (cursorGlyphBegin > 1) + newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin - 1) - 1)); + + if (cursorGlyphEnd < m_text.GetLength()) + newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd))); + + // Move cursor before setting text (to prevent SetText to move our cursor) + MoveCursor(-1); + + SetText(newText); + } + + return true; + } + case Nz::Keyboard::Delete: { if (HasSelection()) @@ -335,6 +368,24 @@ namespace Ndk return true; } + case Nz::Keyboard::Return: + { + bool ignoreDefaultAction = false; + OnTextAreaKeyReturn(this, &ignoreDefaultAction); + + if (ignoreDefaultAction) + return true; + + if (!m_multiLineEnabled) + break; + + if (HasSelection()) + EraseSelection(); + + Write(Nz::String('\n')); + return true;; + } + case Nz::Keyboard::Right: { bool ignoreDefaultAction = false; @@ -442,8 +493,10 @@ namespace Ndk } default: - return false; + break; } + + return false; } void TextAreaWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/) @@ -494,68 +547,13 @@ namespace Ndk if (m_readOnly) return; - switch (character) - { - case '\b': - { - bool ignoreDefaultAction = false; - OnTextAreaKeyBackspace(this, &ignoreDefaultAction); + if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control || (m_characterFilter && !m_characterFilter(character))) + return; - std::size_t cursorGlyphBegin = GetGlyphIndex(m_cursorPositionBegin); - std::size_t cursorGlyphEnd = GetGlyphIndex(m_cursorPositionEnd); + if (HasSelection()) + EraseSelection(); - if (ignoreDefaultAction || cursorGlyphEnd == 0) - break; - - // When a text is selected, delete key does the same as delete and leave the character behind it - if (HasSelection()) - EraseSelection(); - else - { - Nz::String newText; - - if (cursorGlyphBegin > 1) - newText.Append(m_text.SubString(0, m_text.GetCharacterPosition(cursorGlyphBegin - 1) - 1)); - - if (cursorGlyphEnd < m_text.GetLength()) - newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyphEnd))); - - // Move cursor before setting text (to prevent SetText to move our cursor) - MoveCursor(-1); - - SetText(newText); - } - break; - } - - case '\r': - case '\n': - { - bool ignoreDefaultAction = false; - OnTextAreaKeyReturn(this, &ignoreDefaultAction); - - if (ignoreDefaultAction || !m_multiLineEnabled) - break; - - if (HasSelection()) - EraseSelection(); - - Write(Nz::String('\n')); - break; - } - - default: - { - if (Nz::Unicode::GetCategory(character) == Nz::Unicode::Category_Other_Control || (m_characterFilter && !m_characterFilter(character))) - break; - - if (HasSelection()) - EraseSelection(); - - Write(Nz::String::Unicode(character)); - break; - } - } + Write(Nz::String::Unicode(character)); } void TextAreaWidget::RefreshCursor()