Implement keyboard sorting list widget
This commit is contained in:
parent
5f32b81ab8
commit
1d384961dd
@ -509,7 +509,7 @@ void EventHandler::navigate(const NavigationDirection nav, const int playerID)
|
|||||||
{
|
{
|
||||||
ListWidget* list = (ListWidget*) closest_widget;
|
ListWidget* list = (ListWidget*) closest_widget;
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
list->setSelectionID(nav == NAV_UP ? list->getItemCount() - 1 : 0);
|
list->focusHeader(nav);
|
||||||
}
|
}
|
||||||
// Similar exception for vertical tabs, only apply when entering with down/up
|
// Similar exception for vertical tabs, only apply when entering with down/up
|
||||||
if (closest_widget->m_type == GUIEngine::WTYPE_RIBBON && (nav == NAV_UP || nav == NAV_DOWN))
|
if (closest_widget->m_type == GUIEngine::WTYPE_RIBBON && (nav == NAV_UP || nav == NAV_DOWN))
|
||||||
|
@ -1822,20 +1822,20 @@ void Skin::drawListHeader(const irr::core::rect< irr::s32 > &rect,
|
|||||||
Widget* widget)
|
Widget* widget)
|
||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
|
ListWidget* list = static_cast<ListWidget*>(widget->m_event_handler);
|
||||||
bool isSelected =
|
bool isSelected =
|
||||||
(((ListWidget*)widget->m_event_handler)->m_selected_column == widget &&
|
(list->m_selected_column == widget && list->m_choosing_header);
|
||||||
((ListWidget*)widget->m_event_handler)->m_sort_default == false);
|
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(widget, rect,
|
drawBoxFromStretchableTexture(widget, rect,
|
||||||
(isSelected ? SkinConfig::m_render_params["list_header::down"]
|
(isSelected ? SkinConfig::m_render_params["list_header::down"]
|
||||||
: SkinConfig::m_render_params["list_header::neutral"]),
|
: SkinConfig::m_render_params["list_header::neutral"]),
|
||||||
false, NULL /* clip */);
|
false, NULL /* clip */);
|
||||||
|
|
||||||
if (isSelected)
|
if (list->m_selected_column == widget && !list->m_sort_default)
|
||||||
{
|
{
|
||||||
/** \brief img sets the icon for the column according to sort order **/
|
/** \brief img sets the icon for the column according to sort order **/
|
||||||
ITexture* img;
|
ITexture* img;
|
||||||
if (((ListWidget*)widget->m_event_handler)->m_sort_desc)
|
if (list->m_sort_desc)
|
||||||
img =
|
img =
|
||||||
SkinConfig::m_render_params["list_sort_down::neutral"].getImage();
|
SkinConfig::m_render_params["list_sort_down::neutral"].getImage();
|
||||||
else
|
else
|
||||||
|
@ -47,6 +47,7 @@ ListWidget::ListWidget() : Widget(WTYPE_LIST)
|
|||||||
m_sort_col = 0;
|
m_sort_col = 0;
|
||||||
m_sortable = true;
|
m_sortable = true;
|
||||||
m_header_created = false;
|
m_header_created = false;
|
||||||
|
m_choosing_header = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -360,6 +361,9 @@ irr::core::stringw ListWidget::getSelectionLabel(const int cell) const
|
|||||||
|
|
||||||
void ListWidget::selectItemWithLabel(const irr::core::stringw& name)
|
void ListWidget::selectItemWithLabel(const irr::core::stringw& name)
|
||||||
{
|
{
|
||||||
|
// Disable focusing header for choosing
|
||||||
|
m_choosing_header = false;
|
||||||
|
|
||||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||||
assert(list != NULL);
|
assert(list != NULL);
|
||||||
return list->setSelectedByCellText( name.c_str() );
|
return list->setSelectedByCellText( name.c_str() );
|
||||||
@ -393,6 +397,9 @@ void ListWidget::setSelectionID(const int index)
|
|||||||
// May only be called AFTER this widget has been add()ed
|
// May only be called AFTER this widget has been add()ed
|
||||||
assert(m_element != NULL);
|
assert(m_element != NULL);
|
||||||
|
|
||||||
|
// Disable focusing header for choosing
|
||||||
|
m_choosing_header = false;
|
||||||
|
|
||||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||||
|
|
||||||
// auto-scroll to item when selecting something, don't auto-scroll when selecting nothing
|
// auto-scroll to item when selecting something, don't auto-scroll when selecting nothing
|
||||||
@ -527,7 +534,7 @@ EventPropagation ListWidget::transmitEvent(Widget* w,
|
|||||||
|
|
||||||
m_sort_col = originator[(m_properties[PROP_ID] + "_column_").size()] - '0';
|
m_sort_col = originator[(m_properties[PROP_ID] + "_column_").size()] - '0';
|
||||||
m_selected_column = m_header_elements.get(m_sort_col);
|
m_selected_column = m_header_elements.get(m_sort_col);
|
||||||
|
m_choosing_header = true;
|
||||||
/** \brief Allows sort icon to change depending on sort order **/
|
/** \brief Allows sort icon to change depending on sort order **/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -560,6 +567,57 @@ EventPropagation ListWidget::downPressed(const int playerID)
|
|||||||
return moveToNextItem(/*reverse*/ false);
|
return moveToNextItem(/*reverse*/ false);
|
||||||
} // downPressed
|
} // downPressed
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
EventPropagation ListWidget::leftPressed(const int playerID)
|
||||||
|
{
|
||||||
|
if (m_deactivated || !m_choosing_header)
|
||||||
|
return EVENT_BLOCK;
|
||||||
|
|
||||||
|
m_sort_col--;
|
||||||
|
repairSortCol();
|
||||||
|
m_sort_default = true;
|
||||||
|
m_selected_column = m_header_elements.get(m_sort_col);
|
||||||
|
m_selected_column->setFocusForPlayer(0);
|
||||||
|
|
||||||
|
return EVENT_LET;
|
||||||
|
} // upPressed
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
EventPropagation ListWidget::rightPressed(const int playerID)
|
||||||
|
{
|
||||||
|
if (m_deactivated || !m_choosing_header)
|
||||||
|
return EVENT_BLOCK;
|
||||||
|
|
||||||
|
m_sort_col++;
|
||||||
|
repairSortCol();
|
||||||
|
m_sort_default = true;
|
||||||
|
m_selected_column = m_header_elements.get(m_sort_col);
|
||||||
|
m_selected_column->setFocusForPlayer(0);
|
||||||
|
|
||||||
|
return EVENT_LET;
|
||||||
|
} // downPressed
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ListWidget::focusHeader(const NavigationDirection nav)
|
||||||
|
{
|
||||||
|
if (m_header.empty() || getItemCount() == 0)
|
||||||
|
{
|
||||||
|
setSelectionID(nav == NAV_UP ? getItemCount() - 1 : 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
repairSortCol();
|
||||||
|
m_selected_column = m_header_elements.get(m_sort_col);
|
||||||
|
m_selected_column->setFocusForPlayer(0);
|
||||||
|
m_choosing_header = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
EventPropagation ListWidget::moveToNextItem(const bool reverse)
|
EventPropagation ListWidget::moveToNextItem(const bool reverse)
|
||||||
{
|
{
|
||||||
// if widget is deactivated, do nothing
|
// if widget is deactivated, do nothing
|
||||||
@ -570,6 +628,11 @@ EventPropagation ListWidget::moveToNextItem(const bool reverse)
|
|||||||
|
|
||||||
if (stay_within_list)
|
if (stay_within_list)
|
||||||
{
|
{
|
||||||
|
if (m_choosing_header)
|
||||||
|
{
|
||||||
|
m_choosing_header = false;
|
||||||
|
setFocusForPlayer(0);
|
||||||
|
}
|
||||||
if (reverse)
|
if (reverse)
|
||||||
setSelectionID(getSelectionID() - 1);
|
setSelectionID(getSelectionID() - 1);
|
||||||
else
|
else
|
||||||
@ -578,6 +641,17 @@ EventPropagation ListWidget::moveToNextItem(const bool reverse)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (reverse && !m_choosing_header &&
|
||||||
|
m_sort_col < (int)m_header_elements.size())
|
||||||
|
{
|
||||||
|
// Up pressed
|
||||||
|
repairSortCol();
|
||||||
|
m_selected_column = m_header_elements.get(m_sort_col);
|
||||||
|
m_selected_column->setFocusForPlayer(0);
|
||||||
|
setSelectionID(-1); // select nothing
|
||||||
|
m_choosing_header = true;
|
||||||
|
return EVENT_LET;
|
||||||
|
}
|
||||||
setSelectionID(-1); // select nothing
|
setSelectionID(-1); // select nothing
|
||||||
}
|
}
|
||||||
return EVENT_BLOCK;
|
return EVENT_BLOCK;
|
||||||
|
@ -69,6 +69,8 @@ namespace GUIEngine
|
|||||||
/** index of column*/
|
/** index of column*/
|
||||||
int m_sort_col;
|
int m_sort_col;
|
||||||
|
|
||||||
|
bool m_choosing_header;
|
||||||
|
|
||||||
struct Column
|
struct Column
|
||||||
{
|
{
|
||||||
irr::core::stringw m_text;
|
irr::core::stringw m_text;
|
||||||
@ -96,6 +98,16 @@ namespace GUIEngine
|
|||||||
|
|
||||||
bool m_header_created;
|
bool m_header_created;
|
||||||
|
|
||||||
|
void repairSortCol()
|
||||||
|
{
|
||||||
|
// Exclude scrollbar
|
||||||
|
int max_size = (int)m_header_elements.size() - 1;
|
||||||
|
if (m_sort_col < 0)
|
||||||
|
m_sort_col = max_size - 1;
|
||||||
|
else if (m_sort_col >= max_size)
|
||||||
|
m_sort_col = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef irr::gui::CGUISTKListBox::ListItem ListItem;
|
typedef irr::gui::CGUISTKListBox::ListItem ListItem;
|
||||||
typedef ListItem::ListCell ListCell;
|
typedef ListItem::ListCell ListCell;
|
||||||
@ -266,6 +278,12 @@ namespace GUIEngine
|
|||||||
/** \brief implementing method from base class Widget */
|
/** \brief implementing method from base class Widget */
|
||||||
virtual EventPropagation downPressed(const int playerID);
|
virtual EventPropagation downPressed(const int playerID);
|
||||||
|
|
||||||
|
/** \brief implementing method from base class Widget */
|
||||||
|
virtual EventPropagation leftPressed(const int playerID);
|
||||||
|
|
||||||
|
/** \brief implementing method from base class Widget */
|
||||||
|
virtual EventPropagation rightPressed(const int playerID);
|
||||||
|
|
||||||
/** \brief implement common core parts of upPressed and downPressed */
|
/** \brief implement common core parts of upPressed and downPressed */
|
||||||
EventPropagation moveToNextItem(const bool down);
|
EventPropagation moveToNextItem(const bool down);
|
||||||
|
|
||||||
@ -282,6 +300,8 @@ namespace GUIEngine
|
|||||||
void addColumn(irr::video::ITexture* tex, int proportion=1) { m_header.push_back( Column(tex, proportion) ); }
|
void addColumn(irr::video::ITexture* tex, int proportion=1) { m_header.push_back( Column(tex, proportion) ); }
|
||||||
|
|
||||||
void setSortable(bool sortable) { m_sortable = sortable; }
|
void setSortable(bool sortable) { m_sortable = sortable; }
|
||||||
|
void focusHeader(const NavigationDirection nav);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user