diff --git a/src/guiengine/widgets/ribbon_grid_widget.cpp b/src/guiengine/widgets/ribbon_grid_widget.cpp index ad0c0b66f..2e20850a5 100644 --- a/src/guiengine/widgets/ribbon_grid_widget.cpp +++ b/src/guiengine/widgets/ribbon_grid_widget.cpp @@ -38,6 +38,7 @@ RibbonGridWidget::RibbonGridWidget(const bool combo, const int max_rows) m_left_widget = NULL; m_right_widget = NULL; m_type = WTYPE_RIBBON_GRID; + m_selected_item = 0; } // ----------------------------------------------------------------------------- @@ -279,19 +280,19 @@ void RibbonGridWidget::registerHoverListener(RibbonGridHoverListener* listener) bool RibbonGridWidget::rightPressed() { RibbonWidget* w = getSelectedRibbon(); - if(w != NULL) + if (w != NULL) { updateLabel(); propagateSelection(); } const int listenerAmount = m_hover_listeners.size(); - for(int n=0; ngetSelectionIDString()); } - if(m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false; + if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false; return true; } @@ -299,36 +300,47 @@ bool RibbonGridWidget::rightPressed() bool RibbonGridWidget::leftPressed() { RibbonWidget* w = getSelectedRibbon(); - if(w != NULL) + if (w != NULL) { updateLabel(); propagateSelection(); } const int listenerAmount = m_hover_listeners.size(); - for(int n=0; ngetSelectionIDString()); } - if(m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false; + if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false; return true; } // ----------------------------------------------------------------------------- bool RibbonGridWidget::transmitEvent(Widget* w, std::string& originator) { - if(originator=="left") + if (originator=="left") { scroll(-1); return false; } - if(originator=="right") + if (originator=="right") { scroll(1); return false; } + // find selection in current ribbon + if (m_combo) + { + RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(); + if (selected_ribbon != NULL) + { + m_selected_item = selected_ribbon->m_selection + m_scroll_offset; + if (m_selected_item >= (int)m_items.size()) m_selected_item -= m_items.size(); + } + } + return true; } // ----------------------------------------------------------------------------- @@ -337,10 +349,10 @@ bool RibbonGridWidget::mouseHovered(Widget* child) updateLabel(); propagateSelection(); - if(getSelectedRibbon() != NULL) + if (getSelectedRibbon() != NULL) { const int listenerAmount = m_hover_listeners.size(); - for(int n=0; ngetSelectionIDString()); } @@ -365,7 +377,7 @@ void RibbonGridWidget::onRowChange(RibbonWidget* row) updateLabel(row); const int listenerAmount = m_hover_listeners.size(); - for(int n=0; ngetSelectionIDString()); } @@ -382,10 +394,19 @@ void RibbonGridWidget::scroll(const int x_delta) const int max_scroll = std::max(m_col_amount, m_needed_cols) - 1; - if(m_scroll_offset < 0) m_scroll_offset = max_scroll; - else if(m_scroll_offset > max_scroll) m_scroll_offset = 0; + if (m_scroll_offset < 0) m_scroll_offset = max_scroll; + else if (m_scroll_offset > max_scroll) m_scroll_offset = 0; updateItemDisplay(); + + // update selection markers in child ribbon + if (m_combo) + { + RibbonWidget* ribbon = m_rows.get(0); // there is a single row when we can select items + int id = m_selected_item - m_scroll_offset; + if (id < 0) id += m_items.size(); + ribbon->setSelection(id); + } } // ----------------------------------------------------------------------------- /** RibbonGridWidget is made of several ribbons; each of them thus has @@ -396,17 +417,23 @@ void RibbonGridWidget::propagateSelection() { // find selection in current ribbon RibbonWidget* selected_ribbon = (RibbonWidget*)getSelectedRibbon(); - if(selected_ribbon == NULL) return; - const int i = selected_ribbon->m_selection; + if (selected_ribbon == NULL) return; + const int relative_selection = selected_ribbon->m_selection; + + if (m_combo) + { + m_selected_item = relative_selection + m_scroll_offset; + if (m_selected_item >= (int)m_items.size()) m_selected_item -= m_items.size(); + } // set same selection in all ribbons const int row_amount = m_rows.size(); - for(int n=0; nm_selection = i; + ribbon->m_selection = relative_selection; ribbon->updateSelection(); } } @@ -414,18 +441,18 @@ void RibbonGridWidget::propagateSelection() // ----------------------------------------------------------------------------- void RibbonGridWidget::updateLabel(RibbonWidget* from_this_ribbon) { - if(!m_has_label) return; + if (!m_has_label) return; RibbonWidget* row = from_this_ribbon ? from_this_ribbon : (RibbonWidget*)getSelectedRibbon(); - if(row == NULL) return; + if (row == NULL) return; std::string selection_id = row->getSelectionIDString(); const int amount = m_items.size(); - for(int n=0; nsetText( stringw(m_items[n].m_user_name.c_str()).c_str() ); return; @@ -435,27 +462,6 @@ void RibbonGridWidget::updateLabel(RibbonWidget* from_this_ribbon) m_label->setText( L"Random" ); } // ----------------------------------------------------------------------------- -void RibbonGridWidget::setSelection(int item_id) -{ - if(m_rows.size() > 1) - { - std::cout << "/!\\ Warning, RibbonGridWidget::setSelection only makes sense on 1-row ribbons (since there can't logically be a selection with more than one row)\n"; - } - - - // scroll so selection is visible - m_scroll_offset = item_id; - updateItemDisplay(); - - // set selection again, because scrolling made it wrong - RibbonWidget* ribbon = m_rows.get(0); - ribbon->setSelection(0); -} -void RibbonGridWidget::setSelection(const std::string& code_name) -{ - assert(false); -} -// ----------------------------------------------------------------------------- void RibbonGridWidget::updateItemDisplay() { // Check if we need to update the number of icons in the ribbon @@ -510,4 +516,31 @@ void RibbonGridWidget::updateItemDisplay() } // next column } // next row } - +// ----------------------------------------------------------------------------- +void RibbonGridWidget::setSelection(int item_id) +{ + if (m_rows.size() > 1) + { + std::cout << "\n/!\\ Warning, RibbonGridWidget::setSelection only makes sense on 1-row ribbons " << + "(since there can't logically be a permanent with more than one row)\n\n"; + return; + } + + m_selected_item = item_id; + if (m_selected_item >= (int)m_items.size()) m_selected_item -= m_items.size(); + + // scroll so selection is visible + m_scroll_offset = m_selected_item; // works because in this case there is a single row + updateItemDisplay(); + + // set selection + RibbonWidget* ribbon = m_rows.get(0); // there is a single row when we can select items + int id = m_selected_item - m_scroll_offset; + if (id < 0) id += m_items.size(); + ribbon->setSelection(id); +} +// ----------------------------------------------------------------------------- +void RibbonGridWidget::setSelection(const std::string& code_name) +{ + assert(false); +} diff --git a/src/guiengine/widgets/ribbon_grid_widget.hpp b/src/guiengine/widgets/ribbon_grid_widget.hpp index 915053d85..c615fec3a 100644 --- a/src/guiengine/widgets/ribbon_grid_widget.hpp +++ b/src/guiengine/widgets/ribbon_grid_widget.hpp @@ -65,8 +65,10 @@ namespace GUIEngine IGUIStaticText* m_label; int m_label_height; + /** Used to keep track of item count changes */ int m_previous_item_count; + /** List of items in the ribbon */ std::vector m_items; /** Width of the scrolling arrows on each side */ @@ -80,7 +82,6 @@ namespace GUIEngine /** Whether this is a "combo" style ribbon grid widget */ bool m_combo; - /* reference pointers only, the actual instances are owned by m_children */ Widget* m_left_widget; Widget* m_right_widget; @@ -88,6 +89,7 @@ namespace GUIEngine RibbonWidget* getSelectedRibbon() const; RibbonWidget* getRowContaining(Widget* w) const; + /** Updates the visible label to match the currently selected item */ void updateLabel(RibbonWidget* from_this_ribbon=NULL); /** Even though the ribbon grid widget looks like a grid, it is really a vertical stack of @@ -96,24 +98,34 @@ namespace GUIEngine another row keeps the same selected column. */ void propagateSelection(); + /** Callback called widget is focused */ void focused(); bool transmitEvent(Widget* w, std::string& originator); + /** Removes all previously added contents icons, and re-adds them (calculating the new amount) */ void setSubElements(); void scroll(const int x_delta); + /** Used for combo ribbons, to contain the ID of the currently selected item */ + int m_selected_item; + public: RibbonGridWidget(const bool combo=false, const int max_rows=4); void registerHoverListener(RibbonGridHoverListener* listener); void add(); + + /** Called when right key is pressed */ bool rightPressed(); + + /** Called when left key is pressed */ bool leftPressed(); void addItem( std::string user_name, std::string code_name, std::string image_file ); + void updateItemDisplay(); bool mouseHovered(Widget* child); diff --git a/src/guiengine/widgets/ribbon_widget.cpp b/src/guiengine/widgets/ribbon_widget.cpp index 53e3e4bd0..9fe774cee 100644 --- a/src/guiengine/widgets/ribbon_widget.cpp +++ b/src/guiengine/widgets/ribbon_widget.cpp @@ -122,21 +122,21 @@ void RibbonWidget::updateSelection() { const int subbuttons_amount = m_children.size(); - for(int i=0; i 0 && m_ribbon_type == RIBBON_TOOLBAR) m_focus = m_children.get(m_selection); + if (subbuttons_amount > 0 && m_ribbon_type == RIBBON_TOOLBAR) m_focus = m_children.get(m_selection); } // ----------------------------------------------------------------------------- bool RibbonWidget::transmitEvent(Widget* w, std::string& originator) { const int subbuttons_amount = m_children.size(); - for(int i=0; i