Sdk/Canvas: Implement tab/shift-tab to switch to next/previous widget
This commit is contained in:
parent
4116984f9f
commit
377dd992b9
|
|
@ -44,6 +44,8 @@ Nazara Development Kit:
|
||||||
- Add Entity::Disable method, which is a shortcut to Enable(false)
|
- Add Entity::Disable method, which is a shortcut to Enable(false)
|
||||||
- Add BaseWidget::HasFocus
|
- Add BaseWidget::HasFocus
|
||||||
- Fix TextAreaWidget cursor sometimes showing up in readonly mode
|
- Fix TextAreaWidget cursor sometimes showing up in readonly mode
|
||||||
|
- ⚠️ BaseWidget::OnKeyPressed now returns a boolean to indicate if it should block default action (such as tab to switch to the previous/next widget)
|
||||||
|
- Pressing tab/shift-tab will now move to the next/previous widget able to be focused on
|
||||||
|
|
||||||
# 0.4:
|
# 0.4:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,10 @@ namespace Ndk
|
||||||
virtual void Layout();
|
virtual void Layout();
|
||||||
void InvalidateNode() override;
|
void InvalidateNode() override;
|
||||||
|
|
||||||
|
virtual bool IsFocusable() const;
|
||||||
virtual void OnFocusLost();
|
virtual void OnFocusLost();
|
||||||
virtual void OnFocusReceived();
|
virtual void OnFocusReceived();
|
||||||
virtual void OnKeyPressed(const Nz::WindowEvent::KeyEvent& key);
|
virtual bool OnKeyPressed(const Nz::WindowEvent::KeyEvent& key);
|
||||||
virtual void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key);
|
virtual void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key);
|
||||||
virtual void OnMouseEnter();
|
virtual void OnMouseEnter();
|
||||||
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
|
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Ndk
|
||||||
bool IsFocusable() const override;
|
bool IsFocusable() const override;
|
||||||
void OnFocusLost() override;
|
void OnFocusLost() override;
|
||||||
void OnFocusReceived() override;
|
void OnFocusReceived() override;
|
||||||
void OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) override;
|
bool OnKeyPressed(const Nz::WindowEvent::KeyEvent& key) override;
|
||||||
void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key) override;
|
void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key) override;
|
||||||
void OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button button) override;
|
void OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button button) override;
|
||||||
void OnTextEntered(char32_t character, bool repeated) override;
|
void OnTextEntered(char32_t character, bool repeated) override;
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,11 @@ namespace Ndk
|
||||||
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
|
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseWidget::IsFocusable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseWidget::OnFocusLost()
|
void BaseWidget::OnFocusLost()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -197,8 +202,9 @@ namespace Ndk
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& /*key*/)
|
bool BaseWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/)
|
void BaseWidget::OnKeyReleased(const Nz::WindowEvent::KeyEvent& /*key*/)
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,57 @@ 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)
|
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||||
m_widgetEntries[m_keyboardOwner].widget->OnKeyPressed(event);
|
{
|
||||||
|
if (m_widgetEntries[m_keyboardOwner].widget->OnKeyPressed(event))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.code == Nz::Keyboard::Tab)
|
||||||
|
{
|
||||||
|
if (!event.shift)
|
||||||
|
{
|
||||||
|
// Forward
|
||||||
|
for (std::size_t i = m_keyboardOwner + 1; i < m_widgetEntries.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_widgetEntries[i].widget->IsFocusable())
|
||||||
|
{
|
||||||
|
SetKeyboardOwner(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_keyboardOwner; ++i)
|
||||||
|
{
|
||||||
|
if (m_widgetEntries[i].widget->IsFocusable())
|
||||||
|
{
|
||||||
|
SetKeyboardOwner(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Backward
|
||||||
|
for (decltype(m_widgetEntries)::reverse_iterator rit{ m_widgetEntries.begin() + m_keyboardOwner }; rit != m_widgetEntries.rend(); ++rit)
|
||||||
|
{
|
||||||
|
if (rit->widget->IsFocusable())
|
||||||
|
{
|
||||||
|
SetKeyboardOwner(std::distance(m_widgetEntries.begin(), rit.base()) - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(m_widgetEntries)::reverse_iterator rend { m_widgetEntries.begin() + m_keyboardOwner };
|
||||||
|
for (auto rit = m_widgetEntries.rbegin(); rit != rend; ++rit)
|
||||||
|
{
|
||||||
|
if (rit->widget->IsFocusable())
|
||||||
|
{
|
||||||
|
SetKeyboardOwner(std::distance(m_widgetEntries.begin(), rit.base()) - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
void Canvas::OnEventKeyReleased(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
|
||||||
|
|
|
||||||
|
|
@ -134,9 +134,14 @@ namespace Ndk
|
||||||
RefreshCursor();
|
RefreshCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextAreaWidget::IsFocusable() const
|
||||||
|
{
|
||||||
|
return !m_readOnly;
|
||||||
|
}
|
||||||
|
|
||||||
void TextAreaWidget::OnFocusLost()
|
void TextAreaWidget::OnFocusLost()
|
||||||
{
|
{
|
||||||
m_cursorEntity->Enable(false);
|
m_cursorEntity->Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextAreaWidget::OnFocusReceived()
|
void TextAreaWidget::OnFocusReceived()
|
||||||
|
|
@ -145,7 +150,7 @@ namespace Ndk
|
||||||
m_cursorEntity->Enable(true);
|
m_cursorEntity->Enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
|
bool TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
|
||||||
{
|
{
|
||||||
switch (key.code)
|
switch (key.code)
|
||||||
{
|
{
|
||||||
|
|
@ -155,7 +160,7 @@ namespace Ndk
|
||||||
|
|
||||||
std::size_t textLength = m_text.GetLength();
|
std::size_t textLength = m_text.GetLength();
|
||||||
if (cursorGlyph > textLength)
|
if (cursorGlyph > textLength)
|
||||||
break;
|
return true;
|
||||||
|
|
||||||
Nz::String newText;
|
Nz::String newText;
|
||||||
if (cursorGlyph > 0)
|
if (cursorGlyph > 0)
|
||||||
|
|
@ -165,7 +170,7 @@ namespace Ndk
|
||||||
newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph + 1)));
|
newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph + 1)));
|
||||||
|
|
||||||
SetText(newText);
|
SetText(newText);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::Keyboard::Down:
|
case Nz::Keyboard::Down:
|
||||||
|
|
@ -174,10 +179,10 @@ namespace Ndk
|
||||||
OnTextAreaKeyDown(this, &ignoreDefaultAction);
|
OnTextAreaKeyDown(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
if (ignoreDefaultAction)
|
if (ignoreDefaultAction)
|
||||||
break;
|
return true;
|
||||||
|
|
||||||
MoveCursor({0, 1});
|
MoveCursor({0, 1});
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::Keyboard::Left:
|
case Nz::Keyboard::Left:
|
||||||
|
|
@ -186,10 +191,10 @@ namespace Ndk
|
||||||
OnTextAreaKeyLeft(this, &ignoreDefaultAction);
|
OnTextAreaKeyLeft(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
if (ignoreDefaultAction)
|
if (ignoreDefaultAction)
|
||||||
break;
|
return true;
|
||||||
|
|
||||||
MoveCursor(-1);
|
MoveCursor(-1);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::Keyboard::Right:
|
case Nz::Keyboard::Right:
|
||||||
|
|
@ -198,10 +203,10 @@ namespace Ndk
|
||||||
OnTextAreaKeyRight(this, &ignoreDefaultAction);
|
OnTextAreaKeyRight(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
if (ignoreDefaultAction)
|
if (ignoreDefaultAction)
|
||||||
break;
|
return true;
|
||||||
|
|
||||||
MoveCursor(1);
|
MoveCursor(1);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Nz::Keyboard::Up:
|
case Nz::Keyboard::Up:
|
||||||
|
|
@ -210,14 +215,14 @@ namespace Ndk
|
||||||
OnTextAreaKeyUp(this, &ignoreDefaultAction);
|
OnTextAreaKeyUp(this, &ignoreDefaultAction);
|
||||||
|
|
||||||
if (ignoreDefaultAction)
|
if (ignoreDefaultAction)
|
||||||
break;
|
return true;
|
||||||
|
|
||||||
MoveCursor({0, -1});
|
MoveCursor({0, -1});
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue