diff --git a/data/gui/skins/Peach.stkskin b/data/gui/skins/Peach.stkskin index eda064466..b5b9656d1 100644 --- a/data/gui/skins/Peach.stkskin +++ b/data/gui/skins/Peach.stkskin @@ -176,6 +176,9 @@ when the border that intersect at this corner are enabled. + + + &rect, Widget* widget, bool } } +void Skin::drawListHeader(const irr::core::rect< irr::s32 > &rect, Widget* widget) +{ + //ListWidget* list = dynamic_cast(widget); + //assert(list != NULL); + + drawBoxFromStretchableTexture(widget, rect, + SkinConfig::m_render_params["list_header::neutral"], false, NULL /* clip */); + + IGUIButton* btn = widget->getIrrlichtElement(); + if (btn->isPressed()) + { + ITexture* img = SkinConfig::m_render_params["list_sort_up::neutral"].getImage(); + core::rect< s32 > destRect(rect.UpperLeftCorner, + core::dimension2d(rect.getHeight(), rect.getHeight())); + core::rect< s32 > srcRect(core::position2d(0,0), img->getSize()); + irr_driver->getVideoDriver()->draw2DImage(img, destRect, srcRect, NULL, NULL, true /* alpha */); + } + + //GUIEngine::getFont()->draw( list->getHeader(), rect, irr::video::SColor(255,0,0,0) ); //getColor("text") ); +} + /** recursive function to render all sections (recursion allows to easily traverse the tree of children * and sub-children) */ @@ -1520,9 +1541,16 @@ void Skin::process3DPane(IGUIElement *element, const core::rect< s32 > &rect, co { drawIconButton(rect, widget, pressed, focused); } - else if(type == WTYPE_BUTTON) + else if (type == WTYPE_BUTTON) { - drawButton(widget, rect, pressed, focused); + if (widget->m_event_handler != NULL && widget->m_event_handler->getType() == WTYPE_LIST) + { + drawListHeader(rect, widget); + } + else + { + drawButton(widget, rect, pressed, focused); + } } else if(type == WTYPE_PROGRESS) { @@ -1718,7 +1746,19 @@ void Skin::draw3DSunkenPane (IGUIElement *element, video::SColor bgcolor, bool f } else if (type == WTYPE_LIST) { - drawList(rect, widget, focused); + //drawList(rect, widget, focused); + + drawList(core::rect(widget->m_x, widget->m_y, widget->m_x + widget->m_w, widget->m_y + widget->m_h), + widget, focused); + + /* + if (((ListWidget*)widget)->getHeader().size() > 0) + { + drawListHeader(core::rect(widget->m_x, widget->m_y, widget->m_x + widget->m_w, rect.UpperLeftCorner.Y), + widget); + } + */ + } else if (type == WTYPE_BUBBLE) { diff --git a/src/guiengine/skin.hpp b/src/guiengine/skin.hpp index e6e88f780..156ff70ed 100644 --- a/src/guiengine/skin.hpp +++ b/src/guiengine/skin.hpp @@ -265,6 +265,7 @@ namespace GUIEngine void drawGaugeFill(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused); void drawCheckBox(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused); void drawList(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused); + void drawListHeader(const irr::core::rect< irr::s32 > &rect, Widget* widget); void drawListSelection(const irr::core::rect< irr::s32 > &rect, Widget* widget, bool focused, const irr::core::rect< irr::s32 > *clip); void drawIconButton(const irr::core::rect< irr::s32 > &rect, Widget* widget, const bool pressed, bool focused); diff --git a/src/guiengine/widgets/list_widget.cpp b/src/guiengine/widgets/list_widget.cpp index ddbd13f38..7a0b27ec3 100644 --- a/src/guiengine/widgets/list_widget.cpp +++ b/src/guiengine/widgets/list_widget.cpp @@ -23,6 +23,8 @@ #include "guiengine/CGUISpriteBank.h" +#include + using namespace GUIEngine; using namespace irr::core; using namespace irr::gui; @@ -71,13 +73,47 @@ void ListWidget::setIcons(STKModifiedSpriteBank* icons) void ListWidget::add() { - rect widget_size = rect(m_x, m_y, m_x + m_w, m_y + m_h); + const int header_height = GUIEngine::getFontHeight() + 15; + + rect widget_size = (m_header.size() > 0 ? rect(m_x, m_y + header_height, m_x + m_w, m_y + m_h) : + rect(m_x, m_y, m_x + m_w, m_y + m_h) ); IGUIListBox* list = GUIEngine::getGUIEnv()->addListBox (widget_size, m_parent, getNewID()); list->setAutoScrollEnabled(false); m_element = list; m_element->setTabOrder( list->getID() ); + + if (m_header.size() > 0) + { + const int col_size = m_w / m_header.size(); + + for (int n=0; nm_y = m_y; + header->m_h = header_height; + + header->m_x = m_x + col_size*n; + header->m_w = col_size; + + header->setText( m_header[n] ); + header->m_properties[PROP_ID] = name.str(); + + header->add(); + header->m_event_handler = this; + + m_children.push_back(header); + m_header_elements.push_back(header); + } + + m_check_inside_me = true; + } } // ----------------------------------------------------------------------------- @@ -229,6 +265,13 @@ void ListWidget::elementRemoved() { Widget::elementRemoved(); m_items.clear(); + + for (int n=0; n()->setPressed(false); + } + m_header_elements[col].getIrrlichtElement()->setPressed(true); + + return EVENT_BLOCK; + } + + return EVENT_LET; +} diff --git a/src/guiengine/widgets/list_widget.hpp b/src/guiengine/widgets/list_widget.hpp index 7768a64a8..e40fd9a6f 100644 --- a/src/guiengine/widgets/list_widget.hpp +++ b/src/guiengine/widgets/list_widget.hpp @@ -23,6 +23,7 @@ #include #include "guiengine/widget.hpp" +#include "guiengine/widgets/button_widget.hpp" #include "utils/ptr_vector.hpp" namespace irr { namespace gui { class STKModifiedSpriteBank; } } @@ -50,6 +51,11 @@ namespace GUIEngine }; std::vector< ListItem > m_items; + PtrVector< ButtonWidget > m_header_elements; + + /** Leave empty for no header */ + std::vector< irr::core::stringw > m_header; + public: ListWidget(); @@ -161,6 +167,13 @@ namespace GUIEngine assert(id != -1); markItemRed( id, red ); } + + /** Override callback from Widget */ + virtual EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID); + + /** To be called before Widget::add(); columns are persistent across multiple add/remove cycles + */ + void addColumn(irr::core::stringw col) { m_header.push_back( col ); } }; } diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index e6bd28ecc..b9bade500 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -55,6 +55,11 @@ void AddonsScreen::loadedFromFile() m_icon_installed = m_icon_bank->addTextureAsSprite(icon1); m_icon_not_installed = m_icon_bank->addTextureAsSprite(icon2); m_icon_needs_update = m_icon_bank->addTextureAsSprite(icon3); + + GUIEngine::ListWidget* w_list = + getWidget("list_addons"); + w_list->addColumn( L"Add-on name" ); + w_list->addColumn( L"Updated date" ); } // loadedFromFile // ---------------------------------------------------------------------------- @@ -67,12 +72,14 @@ void AddonsScreen::init() if(UserConfigParams::logAddons()) std::cout << "[addons] Using directory <" + file_manager->getAddonsDir() << ">\n"; + GUIEngine::ListWidget* w_list = getWidget("list_addons"); w_list->setIcons(m_icon_bank); - + getWidget("update_status") ->setText(_("Updating the list..."), false); + m_type = "kart"; loadList(); } // init