Sdk/Canvas: Implement tab/shift-tab to switch to next/previous widget

This commit is contained in:
Jérôme Leclercq 2017-11-23 14:48:59 +01:00
parent 4116984f9f
commit 377dd992b9
6 changed files with 81 additions and 17 deletions

View File

@ -44,6 +44,8 @@ Nazara Development Kit:
- Add Entity::Disable method, which is a shortcut to Enable(false)
- Add BaseWidget::HasFocus
- 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:

View File

@ -88,9 +88,10 @@ namespace Ndk
virtual void Layout();
void InvalidateNode() override;
virtual bool IsFocusable() const;
virtual void OnFocusLost();
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 OnMouseEnter();
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);

View File

@ -76,7 +76,7 @@ namespace Ndk
bool IsFocusable() const override;
void OnFocusLost() 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 OnMouseButtonPress(int /*x*/, int /*y*/, Nz::Mouse::Button button) override;
void OnTextEntered(char32_t character, bool repeated) override;

View File

@ -189,6 +189,11 @@ namespace Ndk
m_canvas->NotifyWidgetBoxUpdate(m_canvasIndex);
}
bool BaseWidget::IsFocusable() const
{
return false;
}
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*/)

View File

@ -144,7 +144,57 @@ namespace Ndk
void Canvas::OnEventKeyPressed(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& event)
{
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)

View File

@ -134,9 +134,14 @@ namespace Ndk
RefreshCursor();
}
bool TextAreaWidget::IsFocusable() const
{
return !m_readOnly;
}
void TextAreaWidget::OnFocusLost()
{
m_cursorEntity->Enable(false);
m_cursorEntity->Disable();
}
void TextAreaWidget::OnFocusReceived()
@ -145,7 +150,7 @@ namespace Ndk
m_cursorEntity->Enable(true);
}
void TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
bool TextAreaWidget::OnKeyPressed(const Nz::WindowEvent::KeyEvent& key)
{
switch (key.code)
{
@ -155,7 +160,7 @@ namespace Ndk
std::size_t textLength = m_text.GetLength();
if (cursorGlyph > textLength)
break;
return true;
Nz::String newText;
if (cursorGlyph > 0)
@ -165,7 +170,7 @@ namespace Ndk
newText.Append(m_text.SubString(m_text.GetCharacterPosition(cursorGlyph + 1)));
SetText(newText);
break;
return true;
}
case Nz::Keyboard::Down:
@ -174,10 +179,10 @@ namespace Ndk
OnTextAreaKeyDown(this, &ignoreDefaultAction);
if (ignoreDefaultAction)
break;
return true;
MoveCursor({0, 1});
break;
return true;
}
case Nz::Keyboard::Left:
@ -186,10 +191,10 @@ namespace Ndk
OnTextAreaKeyLeft(this, &ignoreDefaultAction);
if (ignoreDefaultAction)
break;
return true;
MoveCursor(-1);
break;
return true;
}
case Nz::Keyboard::Right:
@ -198,10 +203,10 @@ namespace Ndk
OnTextAreaKeyRight(this, &ignoreDefaultAction);
if (ignoreDefaultAction)
break;
return true;
MoveCursor(1);
break;
return true;
}
case Nz::Keyboard::Up:
@ -210,14 +215,14 @@ namespace Ndk
OnTextAreaKeyUp(this, &ignoreDefaultAction);
if (ignoreDefaultAction)
break;
return true;
MoveCursor({0, -1});
break;
return true;
}
default:
break;
return false;
}
}