Fixed selection handling in combo ribbons. Unfotrunately I broke keyboard navigation to the ribbon in the process.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3919 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
4aaddbba4b
commit
298ad53514
@ -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; n<listenerAmount; n++)
|
||||
for (int n=0; n<listenerAmount; n++)
|
||||
{
|
||||
m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon()->getSelectionIDString());
|
||||
}
|
||||
|
||||
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; n<listenerAmount; n++)
|
||||
for (int n=0; n<listenerAmount; n++)
|
||||
{
|
||||
m_hover_listeners[n].onSelectionChanged(this, w->getSelectionIDString());
|
||||
}
|
||||
|
||||
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; n<listenerAmount; n++)
|
||||
for (int n=0; n<listenerAmount; n++)
|
||||
{
|
||||
m_hover_listeners[n].onSelectionChanged(this, getSelectedRibbon()->getSelectionIDString());
|
||||
}
|
||||
@ -365,7 +377,7 @@ void RibbonGridWidget::onRowChange(RibbonWidget* row)
|
||||
updateLabel(row);
|
||||
|
||||
const int listenerAmount = m_hover_listeners.size();
|
||||
for(int n=0; n<listenerAmount; n++)
|
||||
for (int n=0; n<listenerAmount; n++)
|
||||
{
|
||||
m_hover_listeners[n].onSelectionChanged(this, row->getSelectionIDString());
|
||||
}
|
||||
@ -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; n<row_amount; n++)
|
||||
for (int n=0; n<row_amount; n++)
|
||||
{
|
||||
RibbonWidget* ribbon = m_rows.get(n);
|
||||
if(ribbon != selected_ribbon)
|
||||
if (ribbon != selected_ribbon)
|
||||
{
|
||||
ribbon->m_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; n<amount; n++)
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
if(m_items[n].m_code_name == selection_id)
|
||||
if (m_items[n].m_code_name == selection_id)
|
||||
{
|
||||
m_label->setText( 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);
|
||||
}
|
||||
|
@ -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<ItemDescription> 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);
|
||||
|
@ -122,21 +122,21 @@ void RibbonWidget::updateSelection()
|
||||
{
|
||||
const int subbuttons_amount = m_children.size();
|
||||
|
||||
for(int i=0; i<subbuttons_amount; i++)
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
{
|
||||
m_children[i].m_selected = (i == m_selection);
|
||||
}
|
||||
|
||||
if(subbuttons_amount > 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<subbuttons_amount; i++)
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
{
|
||||
if(m_children[i].m_properties[PROP_ID] == originator)
|
||||
if (m_children[i].m_properties[PROP_ID] == originator)
|
||||
{
|
||||
m_selection = i;
|
||||
break;
|
||||
@ -161,11 +161,11 @@ void RibbonWidget::add()
|
||||
|
||||
// ---- check how much space each child button will take and fit them within available space
|
||||
int total_needed_space = 0;
|
||||
for(int i=0; i<subbuttons_amount; i++)
|
||||
for (int i=0; i<subbuttons_amount; i++)
|
||||
{
|
||||
m_children[i].readCoords(this);
|
||||
|
||||
if(m_children[i].m_type != WTYPE_ICON_BUTTON && m_children[i].m_type != WTYPE_BUTTON)
|
||||
if (m_children[i].m_type != WTYPE_ICON_BUTTON && m_children[i].m_type != WTYPE_BUTTON)
|
||||
{
|
||||
std::cerr << "/!\\ Warning /!\\ : ribbon widgets can only have (icon)button widgets as children " << std::endl;
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user