diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index 05fcb967f..999e73ab9 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -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(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(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 diff --git a/src/guiengine/skin.cpp b/src/guiengine/skin.cpp index 8def50b47..c5f971a41 100644 --- a/src/guiengine/skin.cpp +++ b/src/guiengine/skin.cpp @@ -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(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 // ---------------------------------------------------------------------------- /** diff --git a/src/guiengine/widgets/spinner_widget.cpp b/src/guiengine/widgets/spinner_widget.cpp index 4a1c7eefb..a71622472 100644 --- a/src/guiengine/widgets/spinner_widget.cpp +++ b/src/guiengine/widgets/spinner_widget.cpp @@ -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]) { diff --git a/src/guiengine/widgets/spinner_widget.hpp b/src/guiengine/widgets/spinner_widget.hpp index 139089921..71ab7adae 100644 --- a/src/guiengine/widgets/spinner_widget.hpp +++ b/src/guiengine/widgets/spinner_widget.hpp @@ -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; }