Improved spinner (#3374)
* Add spinner arrow focus with keyboard * Improve keyboard navigation for spinners * Only display active arrow if spinner is focused
This commit is contained in:
parent
64595a7b18
commit
41a3a1056e
@ -30,6 +30,7 @@
|
||||
#include "guiengine/widget.hpp"
|
||||
#include "guiengine/widgets/list_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "modes/demo_world.hpp"
|
||||
#include "modes/world.hpp"
|
||||
@ -488,6 +489,16 @@ void EventHandler::navigate(const NavigationDirection nav, const int playerID)
|
||||
sendEventToUser(ribbon, ribbon->m_properties[PROP_ID], playerID);
|
||||
}
|
||||
}
|
||||
|
||||
// For spinners, select the most intuitive button
|
||||
// based on where the navigation came from
|
||||
// Right if coming from right by a left press
|
||||
// Left for all other directions
|
||||
if (closest_widget->getType() == WTYPE_SPINNER)
|
||||
{
|
||||
SpinnerWidget* spinner = dynamic_cast<SpinnerWidget*>(closest_widget);
|
||||
spinner->setSelectedButton(nav == NAV_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -724,6 +735,7 @@ EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int
|
||||
|
||||
Widget* parent = w->m_event_handler;
|
||||
|
||||
//FIXME : sendEventToUser do the same screen keyboard and modal dialog checks, so they are done twice
|
||||
if (ScreenKeyboard::isActive())
|
||||
{
|
||||
if (ScreenKeyboard::getCurrent()->processEvent(w->m_properties[PROP_ID]) == EVENT_BLOCK)
|
||||
@ -743,6 +755,13 @@ EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int
|
||||
|
||||
//Log::info("EventHandler", "Widget activated: %s", w->m_properties[PROP_ID].c_str());
|
||||
|
||||
// For spinners, also trigger activation
|
||||
if (w->getType() == WTYPE_SPINNER)
|
||||
{
|
||||
SpinnerWidget* spinner = dynamic_cast<SpinnerWidget*>(w);
|
||||
spinner->activateSelectedButton();
|
||||
}
|
||||
|
||||
if (w->m_event_handler != NULL)
|
||||
{
|
||||
/* Find all parents. Stop looping if a widget event handler's is itself, to not fall
|
||||
|
@ -1410,20 +1410,29 @@ void Skin::drawSpinnerBody(const core::recti &rect, Widget* widget,
|
||||
void Skin::drawSpinnerChild(const core::recti &rect, Widget* widget,
|
||||
const bool pressed, bool focused)
|
||||
{
|
||||
if (!widget->isVisible()) return;
|
||||
if (!widget->isVisible() || widget->m_deactivated) return;
|
||||
|
||||
if (!widget->m_deactivated && pressed)
|
||||
int areas = 0;
|
||||
bool right;
|
||||
|
||||
if (widget->m_properties[PROP_ID] == "left")
|
||||
{
|
||||
Widget* spinner = widget->m_event_handler;
|
||||
int areas = 0;
|
||||
areas = BoxRenderParams::LEFT;
|
||||
right = false;
|
||||
}
|
||||
else if (widget->m_properties[PROP_ID] == "right")
|
||||
{
|
||||
areas = BoxRenderParams::RIGHT;
|
||||
right = true;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (widget->m_properties[PROP_ID] == "left")
|
||||
areas = BoxRenderParams::LEFT;
|
||||
else if (widget->m_properties[PROP_ID] == "right")
|
||||
areas = BoxRenderParams::RIGHT;
|
||||
else
|
||||
return;
|
||||
SpinnerWidget* spinner = dynamic_cast<SpinnerWidget*>(widget->m_event_handler);
|
||||
bool spinner_focused = spinner->isFocusedForPlayer(PLAYER_ID_GAME_MASTER);
|
||||
|
||||
if (pressed || (spinner->isRightButtonSelected() == right && spinner_focused))
|
||||
{
|
||||
core::recti rect2(spinner->m_x, spinner->m_y,
|
||||
spinner->m_x + spinner->m_w,
|
||||
spinner->m_y + spinner->m_h );
|
||||
@ -1434,7 +1443,7 @@ void Skin::drawSpinnerChild(const core::recti &rect, Widget* widget,
|
||||
widget->m_deactivated);
|
||||
}
|
||||
|
||||
}
|
||||
} // drawSpinnerChild
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/**
|
||||
|
@ -49,6 +49,7 @@ SpinnerWidget::SpinnerWidget(const bool gauge) : Widget(WTYPE_SPINNER)
|
||||
m_spinner_widget_player_id=-1;
|
||||
m_min = 0;
|
||||
m_max = 999;
|
||||
m_right_selected = false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -230,45 +231,65 @@ void SpinnerWidget::move(const int x, const int y, const int w, const int h)
|
||||
|
||||
EventPropagation SpinnerWidget::rightPressed(const int playerID)
|
||||
{
|
||||
//Log::info("SpinnerWidget", "Right pressed");
|
||||
|
||||
// if widget is deactivated, do nothing
|
||||
if (m_deactivated) return EVENT_BLOCK;
|
||||
|
||||
//Log::info("SpinnerWidget", "Right pressed");
|
||||
if (m_value+1 <= m_max)
|
||||
{
|
||||
setValue(m_value+1);
|
||||
}
|
||||
else if (m_wrap_around)
|
||||
{
|
||||
setValue(m_min);
|
||||
}
|
||||
|
||||
//GUIEngine::transmitEvent( this, m_properties[PROP_ID], playerID );
|
||||
// if right arrow is selected, let event handler move to next widget
|
||||
if (m_right_selected)
|
||||
return EVENT_BLOCK;
|
||||
else
|
||||
setSelectedButton(/* right*/ true);
|
||||
|
||||
return EVENT_LET;
|
||||
}
|
||||
} // rightPressed
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
EventPropagation SpinnerWidget::leftPressed(const int playerID)
|
||||
{
|
||||
//Log::info("SpinnerWidget", "Left pressed");
|
||||
|
||||
// if widget is deactivated, do nothing
|
||||
if (m_deactivated) return EVENT_BLOCK;
|
||||
|
||||
//Log::info("SpinnerWidget", "Left pressed");
|
||||
if (m_value-1 >= m_min)
|
||||
{
|
||||
setValue(m_value-1);
|
||||
}
|
||||
else if (m_wrap_around)
|
||||
{
|
||||
setValue(m_max);
|
||||
}
|
||||
|
||||
//GUIEngine::transmitEvent( this, m_properties[PROP_ID], playerID );
|
||||
// if right arrow is selected, select left arrow
|
||||
if (m_right_selected)
|
||||
setSelectedButton(/* right*/ false);
|
||||
// if left arrow is selected, let navigation move to next widget
|
||||
else
|
||||
return EVENT_BLOCK;
|
||||
|
||||
return EVENT_LET;
|
||||
}
|
||||
} // leftPressed
|
||||
|
||||
void SpinnerWidget::activateSelectedButton()
|
||||
{
|
||||
if (m_right_selected)
|
||||
{
|
||||
if (m_value+1 <= m_max)
|
||||
{
|
||||
setValue(m_value+1);
|
||||
}
|
||||
else if (m_wrap_around)
|
||||
{
|
||||
setValue(m_min);
|
||||
}
|
||||
}
|
||||
else // left button active
|
||||
{
|
||||
if (m_value-1 >= m_min)
|
||||
{
|
||||
setValue(m_value-1);
|
||||
}
|
||||
else if (m_wrap_around)
|
||||
{
|
||||
setValue(m_max);
|
||||
}
|
||||
}
|
||||
} // activateSelectedButton
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@ -283,11 +304,13 @@ EventPropagation SpinnerWidget::transmitEvent(Widget* w,
|
||||
|
||||
if (originator == "left")
|
||||
{
|
||||
leftPressed(playerID);
|
||||
m_right_selected = false;
|
||||
activateSelectedButton();
|
||||
}
|
||||
else if (originator == "right")
|
||||
{
|
||||
rightPressed(playerID);
|
||||
m_right_selected = true;
|
||||
activateSelectedButton();
|
||||
}
|
||||
else if (originator == "spinnerbody" || originator == m_properties[PROP_ID])
|
||||
{
|
||||
|
@ -76,6 +76,9 @@ namespace GUIEngine
|
||||
/** \brief Whether to wrap back to the first value when going "beyond" the last value */
|
||||
bool m_wrap_around;
|
||||
|
||||
/** \brief Whether the right or left arrow is the currently selected one */
|
||||
bool m_right_selected;
|
||||
|
||||
/** \brief Keeps track of the custom text in spinner (a text which isn't related to a value)
|
||||
* to remember it and set it back (example : when we deactivate the widget)
|
||||
*/
|
||||
@ -124,6 +127,11 @@ namespace GUIEngine
|
||||
int getSpinnerWidgetPlayerID() {return m_spinner_widget_player_id; }
|
||||
void unsetUseBackgroundColor() {m_use_background_color=false; }
|
||||
|
||||
void activateSelectedButton();
|
||||
void setSelectedButton(bool right) {m_right_selected = right; }
|
||||
bool isRightButtonSelected() {return m_right_selected; }
|
||||
|
||||
|
||||
|
||||
|
||||
void setListener(ISpinnerConfirmListener* listener) { m_listener = listener; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user