diff --git a/sources.cmake b/sources.cmake index a57995969..c9f8454a7 100644 --- a/sources.cmake +++ b/sources.cmake @@ -63,7 +63,7 @@ src/guiengine/widget.cpp src/guiengine/widgets/bubble_widget.cpp src/guiengine/widgets/button_widget.cpp src/guiengine/widgets/CGUIEditBox.cpp -src/guiengine/widgets/CGUIListBox.cpp +src/guiengine/widgets/CGUISTKListBox.cpp src/guiengine/widgets/check_box_widget.cpp src/guiengine/widgets/dynamic_ribbon_widget.cpp src/guiengine/widgets/icon_button_widget.cpp diff --git a/src/guiengine/widgets/CGUIListBox.cpp b/src/guiengine/widgets/CGUIListBox.cpp deleted file mode 100644 index 253ddb850..000000000 --- a/src/guiengine/widgets/CGUIListBox.cpp +++ /dev/null @@ -1,909 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "guiengine/widgets/CGUIListBox.h" - -#include "IGUISkin.h" -#include "IGUIEnvironment.h" -#include "IVideoDriver.h" -#include "IGUIFont.h" -#include "IGUISpriteBank.h" -#include "CGUIScrollBar.h" -#include "os.h" - -namespace irr -{ -namespace gui -{ - -//! constructor -CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, - s32 id, core::rect rectangle, bool clip, - bool drawBack, bool moveOverSelect) -: IGUIListBox(environment, parent, id, rectangle), Selected(-1), - ItemHeight(0),ItemHeightOverride(0), - TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), - ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack), - MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true) -{ - #ifdef _DEBUG - setDebugName("CGUIListBox"); - #endif - - IGUISkin* skin = Environment->getSkin(); - const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE); - - ScrollBar = new CGUIScrollBar(false, Environment, this, -1, - core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), - !clip); - ScrollBar->setSubElement(true); - ScrollBar->setTabStop(false); - ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); - ScrollBar->setVisible(false); - ScrollBar->setPos(0); - - setNotClipped(!clip); - - // this element can be tabbed to - setTabStop(true); - setTabOrder(-1); - - updateAbsolutePosition(); -} - - -//! destructor -CGUIListBox::~CGUIListBox() -{ - if (ScrollBar) - ScrollBar->drop(); - - if (Font) - Font->drop(); - - if (IconBank) - IconBank->drop(); -} - - -//! returns amount of list items -u32 CGUIListBox::getItemCount() const -{ - return Items.size(); -} - - -//! returns string of a list item. the may be a value from 0 to itemCount-1 -const wchar_t* CGUIListBox::getListItem(u32 id) const -{ - if (id>=Items.size()) - return 0; - - return Items[id].text.c_str(); -} - - -//! Returns the icon of an item -s32 CGUIListBox::getIcon(u32 id) const -{ - if (id>=Items.size()) - return -1; - - return Items[id].icon; -} - - -//! adds a list item, returns id of item -u32 CGUIListBox::addItem(const wchar_t* text) -{ - return addItem(text, -1); -} - - -//! adds a list item, returns id of item -void CGUIListBox::removeItem(u32 id) -{ - if (id >= Items.size()) - return; - - if ((u32)Selected==id) - { - Selected = -1; - } - else if ((u32)Selected > id) - { - Selected -= 1; - selectTime = os::Timer::getTime(); - } - - Items.erase(id); - - recalculateItemHeight(); -} - - -s32 CGUIListBox::getItemAt(s32 xpos, s32 ypos) const -{ - if ( xpos < AbsoluteRect.UpperLeftCorner.X || xpos >= AbsoluteRect.LowerRightCorner.X - || ypos < AbsoluteRect.UpperLeftCorner.Y || ypos >= AbsoluteRect.LowerRightCorner.Y - ) - return -1; - - if ( ItemHeight == 0 ) - return -1; - - s32 item = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; - if ( item < 0 || item >= (s32)Items.size()) - return -1; - - return item; -} - -//! clears the list -void CGUIListBox::clear() -{ - Items.clear(); - ItemsIconWidth = 0; - Selected = -1; - - if (ScrollBar) - ScrollBar->setPos(0); - - recalculateItemHeight(); -} - - -void CGUIListBox::recalculateItemHeight() -{ - IGUISkin* skin = Environment->getSkin(); - - if (Font != skin->getFont()) - { - if (Font) - Font->drop(); - - Font = skin->getFont(); - if ( 0 == ItemHeightOverride ) - ItemHeight = 0; - - if (Font) - { - if ( 0 == ItemHeightOverride ) - ItemHeight = Font->getDimension(L"A").Height + 4; - - Font->grab(); - } - } - - TotalItemHeight = ItemHeight * Items.size(); - ScrollBar->setMax( core::max_(0, TotalItemHeight - AbsoluteRect.getHeight()) ); - s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1; - ScrollBar->setSmallStep ( minItemHeight ); - ScrollBar->setLargeStep ( 2*minItemHeight ); - - if ( TotalItemHeight <= AbsoluteRect.getHeight() ) - ScrollBar->setVisible(false); - else - ScrollBar->setVisible(true); -} - - -//! returns id of selected item. returns -1 if no item is selected. -s32 CGUIListBox::getSelected() const -{ - return Selected; -} - - -//! sets the selected item. Set this to -1 if no item should be selected -void CGUIListBox::setSelected(s32 id) -{ - if ((u32)id>=Items.size()) - Selected = -1; - else - Selected = id; - - selectTime = os::Timer::getTime(); - - recalculateScrollPos(); -} - -//! sets the selected item. Set this to -1 if no item should be selected -void CGUIListBox::setSelected(const wchar_t *item) -{ - s32 index = -1; - - if ( item ) - { - for ( index = 0; index < (s32) Items.size(); ++index ) - { - if ( Items[index].text == item ) - break; - } - } - setSelected ( index ); -} - -//! called if an event happened. -bool CGUIListBox::OnEvent(const SEvent& event) -{ - if (isEnabled()) - { - switch(event.EventType) - { - case EET_KEY_INPUT_EVENT: - if (event.KeyInput.PressedDown && - (event.KeyInput.Key == KEY_DOWN || - event.KeyInput.Key == KEY_UP || - event.KeyInput.Key == KEY_HOME || - event.KeyInput.Key == KEY_END || - event.KeyInput.Key == KEY_NEXT || - event.KeyInput.Key == KEY_PRIOR ) ) - { - s32 oldSelected = Selected; - switch (event.KeyInput.Key) - { - case KEY_DOWN: - Selected += 1; - break; - case KEY_UP: - Selected -= 1; - break; - case KEY_HOME: - Selected = 0; - break; - case KEY_END: - Selected = (s32)Items.size()-1; - break; - case KEY_NEXT: - Selected += AbsoluteRect.getHeight() / ItemHeight; - break; - case KEY_PRIOR: - Selected -= AbsoluteRect.getHeight() / ItemHeight; - break; - default: - break; - } - if (Selected >= (s32)Items.size()) - Selected = Items.size() - 1; - else - if (Selected<0) - Selected = 0; - - recalculateScrollPos(); - - // post the news - - if (oldSelected != Selected && Parent && !Selecting && !MoveOverSelect) - { - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = 0; - e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; - Parent->OnEvent(e); - } - - return true; - } - else - if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) ) - { - if (Parent) - { - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = 0; - e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN; - Parent->OnEvent(e); - } - return true; - } - else if (event.KeyInput.PressedDown && event.KeyInput.Char) - { - // change selection based on text as it is typed. - u32 now = os::Timer::getTime(); - - if (now - LastKeyTime < 500) - { - // add to key buffer if it isn't a key repeat - if (!(KeyBuffer.size() == 1 && KeyBuffer[0] == event.KeyInput.Char)) - { - KeyBuffer += L" "; - KeyBuffer[KeyBuffer.size()-1] = event.KeyInput.Char; - } - } - else - { - KeyBuffer = L" "; - KeyBuffer[0] = event.KeyInput.Char; - } - LastKeyTime = now; - - // find the selected item, starting at the current selection - s32 start = Selected; - // dont change selection if the key buffer matches the current item - if (Selected > -1 && KeyBuffer.size() > 1) - { - if (Items[Selected].text.size() >= KeyBuffer.size() && - KeyBuffer.equals_ignore_case(Items[Selected].text.subString(0,KeyBuffer.size()))) - return true; - } - - s32 current; - for (current = start+1; current < (s32)Items.size(); ++current) - { - if (Items[current].text.size() >= KeyBuffer.size()) - { - if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) - { - if (Parent && Selected != current && !Selecting && !MoveOverSelect) - { - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = 0; - e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; - Parent->OnEvent(e); - } - setSelected(current); - return true; - } - } - } - for (current = 0; current <= start; ++current) - { - if (Items[current].text.size() >= KeyBuffer.size()) - { - if (KeyBuffer.equals_ignore_case(Items[current].text.subString(0,KeyBuffer.size()))) - { - if (Parent && Selected != current && !Selecting && !MoveOverSelect) - { - Selected = current; - SEvent e; - e.EventType = EET_GUI_EVENT; - e.GUIEvent.Caller = this; - e.GUIEvent.Element = 0; - e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; - Parent->OnEvent(e); - } - setSelected(current); - return true; - } - } - } - - return true; - } - break; - - case EET_GUI_EVENT: - switch(event.GUIEvent.EventType) - { - case gui::EGET_SCROLL_BAR_CHANGED: - if (event.GUIEvent.Caller == ScrollBar) - return true; - break; - case gui::EGET_ELEMENT_FOCUS_LOST: - { - if (event.GUIEvent.Caller == this) - Selecting = false; - break; - } - - default: - break; - } - break; - - case EET_MOUSE_INPUT_EVENT: - { - core::position2d p(event.MouseInput.X, event.MouseInput.Y); - - switch(event.MouseInput.Event) - { - case EMIE_MOUSE_WHEEL: - ScrollBar->setPos(ScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-ItemHeight/2); - return true; - - case EMIE_LMOUSE_PRESSED_DOWN: - { - Selecting = true; - return true; - } - - case EMIE_LMOUSE_LEFT_UP: - { - Selecting = false; - - if (isPointInside(p)) - selectNew(event.MouseInput.Y); - - return true; - } - - case EMIE_MOUSE_MOVED: - if (Selecting || MoveOverSelect) - { - if (isPointInside(p)) - { - selectNew(event.MouseInput.Y, true); - return true; - } - } - default: - break; - } - } - break; - case EET_LOG_TEXT_EVENT: - case EET_USER_EVENT: - case EET_JOYSTICK_INPUT_EVENT: - case EGUIET_FORCE_32_BIT: - break; - } - } - - return IGUIElement::OnEvent(event); -} - - -void CGUIListBox::selectNew(s32 ypos, bool onlyHover) -{ - u32 now = os::Timer::getTime(); - s32 oldSelected = Selected; - - Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); - if (Selected<0 && !Items.empty()) - Selected = 0; - - recalculateScrollPos(); - - gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; - selectTime = now; - // post the news - if (Parent && !onlyHover) - { - SEvent event; - event.EventType = EET_GUI_EVENT; - event.GUIEvent.Caller = this; - event.GUIEvent.Element = 0; - event.GUIEvent.EventType = eventType; - Parent->OnEvent(event); - } -} - - -//! Update the position and size of the listbox, and update the scrollbar -void CGUIListBox::updateAbsolutePosition() -{ - IGUIElement::updateAbsolutePosition(); - - recalculateItemHeight(); -} - - -//! draws the element and its children -void CGUIListBox::draw() -{ - if (!IsVisible) - return; - - recalculateItemHeight(); // if the font changed - - IGUISkin* skin = Environment->getSkin(); - - core::rect* clipRect = 0; - - // draw background - core::rect frameRect(AbsoluteRect); - - // draw items - - core::rect clientClip(AbsoluteRect); - clientClip.UpperLeftCorner.Y += 1; - clientClip.UpperLeftCorner.X += 1; - if (ScrollBar->isVisible()) - clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); - clientClip.LowerRightCorner.Y -= 1; - clientClip.clipAgainst(AbsoluteClippingRect); - - skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, - DrawBack, frameRect, &clientClip); - - if (clipRect) - clientClip.clipAgainst(*clipRect); - - frameRect = AbsoluteRect; - frameRect.UpperLeftCorner.X += 1; - if (ScrollBar->isVisible()) - frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); - - frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; - - frameRect.UpperLeftCorner.Y -= ScrollBar->getPos(); - frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); - - bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); - - for (s32 i=0; i<(s32)Items.size(); ++i) - { - if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && - frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) - { - if (i == Selected && hl) - skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); - - core::rect textRect = frameRect; - textRect.UpperLeftCorner.X += 3; - - if (Font) - { - if (IconBank && (Items[i].icon > -1)) - { - core::position2di iconPos = textRect.UpperLeftCorner; - iconPos.Y += textRect.getHeight() / 2; - iconPos.X += ItemsIconWidth/2; - - if ( i==Selected && hl ) - { - IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, - hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? - getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), - selectTime, os::Timer::getTime(), false, true); - } - else - { - IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, - hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), - 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); - } - } - - textRect.UpperLeftCorner.X += ItemsIconWidth+3; - - if ( i==Selected && hl ) - { - Font->draw(Items[i].text.c_str(), textRect, - hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? - getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT), - false, true, &clientClip); - } - else - { - Font->draw(Items[i].text.c_str(), textRect, - hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT), - false, true, &clientClip); - } - - textRect.UpperLeftCorner.X -= ItemsIconWidth+3; - } - } - - frameRect.UpperLeftCorner.Y += ItemHeight; - frameRect.LowerRightCorner.Y += ItemHeight; - } - - IGUIElement::draw(); -} - - -//! adds an list item with an icon -u32 CGUIListBox::addItem(const wchar_t* text, s32 icon) -{ - ListItem i; - i.text = text; - i.icon = icon; - - Items.push_back(i); - recalculateItemHeight(); - recalculateItemWidth(icon); - - return Items.size() - 1; -} - - -void CGUIListBox::setSpriteBank(IGUISpriteBank* bank) -{ - if ( bank == IconBank ) - return; - if (IconBank) - IconBank->drop(); - - IconBank = bank; - if (IconBank) - IconBank->grab(); -} - - -void CGUIListBox::recalculateScrollPos() -{ - if (!AutoScroll) - return; - - const s32 selPos = (Selected == -1 ? TotalItemHeight : Selected * ItemHeight) - ScrollBar->getPos(); - - if (selPos < 0) - { - ScrollBar->setPos(ScrollBar->getPos() + selPos); - } - else - if (selPos > AbsoluteRect.getHeight() - ItemHeight) - { - ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight); - } -} - - -void CGUIListBox::setAutoScrollEnabled(bool scroll) -{ - AutoScroll = scroll; -} - - -bool CGUIListBox::isAutoScrollEnabled() const -{ - _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; - return AutoScroll; -} - - -bool CGUIListBox::getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const -{ - switch ( colorType ) - { - case EGUI_LBC_TEXT: - useColorLabel = "UseColText"; - colorLabel = "ColText"; - break; - case EGUI_LBC_TEXT_HIGHLIGHT: - useColorLabel = "UseColTextHl"; - colorLabel = "ColTextHl"; - break; - case EGUI_LBC_ICON: - useColorLabel = "UseColIcon"; - colorLabel = "ColIcon"; - break; - case EGUI_LBC_ICON_HIGHLIGHT: - useColorLabel = "UseColIconHl"; - colorLabel = "ColIconHl"; - break; - default: - return false; - } - return true; -} - - -//! Writes attributes of the element. -void CGUIListBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const -{ - IGUIListBox::serializeAttributes(out,options); - - // todo: out->addString ("IconBank", IconBank->getName?); - out->addBool ("DrawBack", DrawBack); - out->addBool ("MoveOverSelect", MoveOverSelect); - out->addBool ("AutoScroll", AutoScroll); - - out->addInt("ItemCount", Items.size()); - for (u32 i=0;iaddString(label.c_str(), Items[i].text.c_str() ); - - for ( s32 c=0; c < (s32)EGUI_LBC_COUNT; ++c ) - { - core::stringc useColorLabel, colorLabel; - if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) - return; - label = useColorLabel; label += i; - if ( Items[i].OverrideColors[c].Use ) - { - out->addBool(label.c_str(), true ); - label = colorLabel; label += i; - out->addColor(label.c_str(), Items[i].OverrideColors[c].Color); - } - else - { - out->addBool(label.c_str(), false ); - } - } - } -} - - -//! Reads attributes of the element -void CGUIListBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) -{ - clear(); - - DrawBack = in->getAttributeAsBool("DrawBack"); - MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); - AutoScroll = in->getAttributeAsBool("AutoScroll"); - - IGUIListBox::deserializeAttributes(in,options); - - const s32 count = in->getAttributeAsInt("ItemCount"); - for (s32 i=0; igetAttributeAsStringW(label.c_str()); - - addItem(item.text.c_str(), item.icon); - - for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) - { - core::stringc useColorLabel, colorLabel; - if ( !getSerializationLabels((EGUI_LISTBOX_COLOR)c, useColorLabel, colorLabel) ) - return; - label = useColorLabel; label += i; - Items[i].OverrideColors[c].Use = in->getAttributeAsBool(label.c_str()); - if ( Items[i].OverrideColors[c].Use ) - { - label = colorLabel; label += i; - Items[i].OverrideColors[c].Color = in->getAttributeAsColor(label.c_str()); - } - } - } -} - - -void CGUIListBox::recalculateItemWidth(s32 icon) -{ - if (IconBank && icon > -1 && - IconBank->getSprites().size() > (u32)icon && - IconBank->getSprites()[(u32)icon].Frames.size()) - { - u32 rno = IconBank->getSprites()[(u32)icon].Frames[0].rectNumber; - if (IconBank->getPositions().size() > rno) - { - const s32 w = IconBank->getPositions()[rno].getWidth(); - if (w > ItemsIconWidth) - ItemsIconWidth = w; - } - } -} - - -void CGUIListBox::setItem(u32 index, const wchar_t* text, s32 icon) -{ - if ( index >= Items.size() ) - return; - - Items[index].text = text; - Items[index].icon = icon; - - recalculateItemHeight(); - recalculateItemWidth(icon); -} - - -//! Insert the item at the given index -//! Return the index on success or -1 on failure. -s32 CGUIListBox::insertItem(u32 index, const wchar_t* text, s32 icon) -{ - ListItem i; - i.text = text; - i.icon = icon; - - Items.insert(i, index); - recalculateItemHeight(); - recalculateItemWidth(icon); - - return index; -} - - -void CGUIListBox::swapItems(u32 index1, u32 index2) -{ - if ( index1 >= Items.size() || index2 >= Items.size() ) - return; - - ListItem dummmy = Items[index1]; - Items[index1] = Items[index2]; - Items[index2] = dummmy; -} - - -void CGUIListBox::setItemOverrideColor(u32 index, video::SColor color) -{ - for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) - { - Items[index].OverrideColors[c].Use = true; - Items[index].OverrideColors[c].Color = color; - } -} - - -void CGUIListBox::setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) -{ - if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) - return; - - Items[index].OverrideColors[colorType].Use = true; - Items[index].OverrideColors[colorType].Color = color; -} - - -void CGUIListBox::clearItemOverrideColor(u32 index) -{ - for (u32 c=0; c < (u32)EGUI_LBC_COUNT; ++c ) - { - Items[index].OverrideColors[c].Use = false; - } -} - - -void CGUIListBox::clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) -{ - if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) - return; - - Items[index].OverrideColors[colorType].Use = false; -} - - -bool CGUIListBox::hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const -{ - if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) - return false; - - return Items[index].OverrideColors[colorType].Use; -} - - -video::SColor CGUIListBox::getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const -{ - if ( (u32)index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) - return video::SColor(); - - return Items[index].OverrideColors[colorType].Color; -} - - -video::SColor CGUIListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const -{ - IGUISkin* skin = Environment->getSkin(); - if ( !skin ) - return video::SColor(); - - switch ( colorType ) - { - case EGUI_LBC_TEXT: - return skin->getColor(EGDC_BUTTON_TEXT); - case EGUI_LBC_TEXT_HIGHLIGHT: - return skin->getColor(EGDC_HIGH_LIGHT_TEXT); - case EGUI_LBC_ICON: - return skin->getColor(EGDC_ICON); - case EGUI_LBC_ICON_HIGHLIGHT: - return skin->getColor(EGDC_ICON_HIGH_LIGHT); - default: - return video::SColor(); - } -} - -//! set global itemHeight -void CGUIListBox::setItemHeight( s32 height ) -{ - ItemHeight = height; - ItemHeightOverride = 1; -} - - -//! Sets whether to draw the background -void CGUIListBox::setDrawBackground(bool draw) -{ - DrawBack = draw; -} - - -} // end namespace gui -} // end namespace irr - - diff --git a/src/guiengine/widgets/CGUIListBox.h b/src/guiengine/widgets/CGUIListBox.h deleted file mode 100644 index 7f6d21278..000000000 --- a/src/guiengine/widgets/CGUIListBox.h +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef HEADER_CGUILISTBOX_HPP -#define HEADER_CGUILISTBOX_HPP - -#include "IrrCompileConfig.h" - -#include "IGUIListBox.h" -#include "irrArray.h" - -namespace irr -{ -namespace gui -{ - - class IGUIFont; - class IGUIScrollBar; - - class CGUIListBox : public IGUIListBox - { - public: - //! constructor - CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent, - s32 id, core::rect rectangle, bool clip=true, - bool drawBack=false, bool moveOverSelect=false); - - //! destructor - virtual ~CGUIListBox(); - - //! returns amount of list items - virtual u32 getItemCount() const; - - //! returns string of a list item. the id may be a value from 0 to itemCount-1 - virtual const wchar_t* getListItem(u32 id) const; - - //! adds an list item, returns id of item - virtual u32 addItem(const wchar_t* text); - - //! clears the list - virtual void clear(); - - //! returns id of selected item. returns -1 if no item is selected. - virtual s32 getSelected() const; - - //! sets the selected item. Set this to -1 if no item should be selected - virtual void setSelected(s32 id); - - //! sets the selected item. Set this to -1 if no item should be selected - virtual void setSelected(const wchar_t *item); - - //! called if an event happened. - virtual bool OnEvent(const SEvent& event); - - //! draws the element and its children - virtual void draw(); - - //! adds an list item with an icon - //! \param text Text of list entry - //! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon - //! \return - //! returns the id of the new created item - virtual u32 addItem(const wchar_t* text, s32 icon); - - //! Returns the icon of an item - virtual s32 getIcon(u32 id) const; - - //! removes an item from the list - virtual void removeItem(u32 id); - - //! get the the id of the item at the given absolute coordinates - virtual s32 getItemAt(s32 xpos, s32 ypos) const; - - //! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of - //! the built-in-font by default. A sprite can be displayed in front of every list item. - //! An icon is an index within the icon sprite bank. Several default icons are available in the - //! skin through getIcon - virtual void setSpriteBank(IGUISpriteBank* bank); - - //! set whether the listbox should scroll to newly selected items - virtual void setAutoScrollEnabled(bool scroll); - - //! returns true if automatic scrolling is enabled, false if not. - virtual bool isAutoScrollEnabled() const; - - //! Update the position and size of the listbox, and update the scrollbar - virtual void updateAbsolutePosition(); - - //! Writes attributes of the element. - virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const; - - //! Reads attributes of the element - virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options); - - //! set all item colors at given index to color - virtual void setItemOverrideColor(u32 index, video::SColor color); - - //! set all item colors of specified type at given index to color - virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color); - - //! clear all item colors at index - virtual void clearItemOverrideColor(u32 index); - - //! clear item color at index for given colortype - virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType); - - //! has the item at index its color overwritten? - virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; - - //! return the overwrite color at given item index. - virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; - - //! return the default color which is used for the given colorType - virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const; - - //! set the item at the given index - virtual void setItem(u32 index, const wchar_t* text, s32 icon); - - //! Insert the item at the given index - //! Return the index on success or -1 on failure. - virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon); - - //! Swap the items at the given indices - virtual void swapItems(u32 index1, u32 index2); - - //! set global itemHeight - virtual void setItemHeight( s32 height ); - - //! Sets whether to draw the background - virtual void setDrawBackground(bool draw); - - - private: - - struct ListItem - { - ListItem() : icon(-1) - {} - - core::stringw text; - s32 icon; - - // A multicolor extension - struct ListItemOverrideColor - { - ListItemOverrideColor() : Use(false) {} - bool Use; - video::SColor Color; - }; - ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]; - }; - - void recalculateItemHeight(); - void selectNew(s32 ypos, bool onlyHover=false); - void recalculateScrollPos(); - - // extracted that function to avoid copy&paste code - void recalculateItemWidth(s32 icon); - - // get labels used for serialization - bool getSerializationLabels(EGUI_LISTBOX_COLOR colorType, core::stringc & useColorLabel, core::stringc & colorLabel) const; - - core::array< ListItem > Items; - s32 Selected; - s32 ItemHeight; - s32 ItemHeightOverride; - s32 TotalItemHeight; - s32 ItemsIconWidth; - gui::IGUIFont* Font; - gui::IGUISpriteBank* IconBank; - gui::IGUIScrollBar* ScrollBar; - u32 selectTime; - u32 LastKeyTime; - core::stringw KeyBuffer; - bool Selecting; - bool DrawBack; - bool MoveOverSelect; - bool AutoScroll; - bool HighlightWhenNotFocused; - }; - - -} // end namespace gui -} // end namespace irr - -#endif diff --git a/src/guiengine/widgets/CGUISTKListBox.cpp b/src/guiengine/widgets/CGUISTKListBox.cpp new file mode 100644 index 000000000..a3ca8a543 --- /dev/null +++ b/src/guiengine/widgets/CGUISTKListBox.cpp @@ -0,0 +1,754 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// 2013 Glenn De Jonghe +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#include "guiengine/widgets/CGUISTKListBox.h" + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IVideoDriver.h" +#include "IGUIFont.h" +#include "IGUISpriteBank.h" +#include "CGUIScrollBar.h" +#include "os.h" + +namespace irr +{ +namespace gui +{ + +//! constructor +CGUISTKListBox::CGUISTKListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip, + bool drawBack, bool moveOverSelect) +: IGUIElement(EGUIET_LIST_BOX, environment, parent, id, rectangle), Selected(-1), + ItemHeight(0),ItemHeightOverride(0), + TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), + ScrollBar(0), selectTime(0), LastKeyTime(0), Selecting(false), DrawBack(drawBack), + MoveOverSelect(moveOverSelect), AutoScroll(true), HighlightWhenNotFocused(true) +{ + #ifdef _DEBUG + setDebugName("CGUISTKListBox"); + #endif + + IGUISkin* skin = Environment->getSkin(); + const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE); + + ScrollBar = new CGUIScrollBar(false, Environment, this, -1, + core::rect(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()), + !clip); + ScrollBar->setSubElement(true); + ScrollBar->setTabStop(false); + ScrollBar->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); + ScrollBar->setVisible(false); + ScrollBar->setPos(0); + + setNotClipped(!clip); + + // this element can be tabbed to + setTabStop(true); + setTabOrder(-1); + + updateAbsolutePosition(); +} + + +//! destructor +CGUISTKListBox::~CGUISTKListBox() +{ + if (ScrollBar) + ScrollBar->drop(); + + if (Font) + Font->drop(); + + if (IconBank) + IconBank->drop(); +} + + +//! returns amount of list items +u32 CGUISTKListBox::getItemCount() const +{ + return Items.size(); +} + + + +const wchar_t* CGUISTKListBox::getCellText(u32 row_num, u32 col_num) const +{ + if ( row_num >= Items.size() ) + return 0; + if ( col_num >= Items[row_num].m_contents.size() ) + return 0; + return Items[row_num].m_contents[col_num].m_text.c_str(); +} + +CGUISTKListBox::ListItem CGUISTKListBox::getItem(u32 id) const +{ + return Items[id]; +} + + +//! Returns the icon of an item +s32 CGUISTKListBox::getIcon(u32 row_num, u32 col_num) const +{ + if ( row_num >= Items.size() ) + return -1; + if ( col_num >= Items[row_num].m_contents.size() ) + return -1; + return Items[row_num].m_contents[col_num].m_icon; +} + +void CGUISTKListBox::removeItem(u32 id) +{ + if (id >= Items.size()) + return; + + if ((u32)Selected==id) + { + Selected = -1; + } + else if ((u32)Selected > id) + { + Selected -= 1; + selectTime = os::Timer::getTime(); + } + + Items.erase(id); + + recalculateItemHeight(); +} + + +s32 CGUISTKListBox::getItemAt(s32 xpos, s32 ypos) const +{ + if ( xpos < AbsoluteRect.UpperLeftCorner.X || xpos >= AbsoluteRect.LowerRightCorner.X + || ypos < AbsoluteRect.UpperLeftCorner.Y || ypos >= AbsoluteRect.LowerRightCorner.Y + ) + return -1; + + if ( ItemHeight == 0 ) + return -1; + + s32 item = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; + if ( item < 0 || item >= (s32)Items.size()) + return -1; + + return item; +} + +//! clears the list +void CGUISTKListBox::clear() +{ + Items.clear(); + ItemsIconWidth = 0; + Selected = -1; + + if (ScrollBar) + ScrollBar->setPos(0); + + recalculateItemHeight(); +} + + +void CGUISTKListBox::recalculateItemHeight() +{ + IGUISkin* skin = Environment->getSkin(); + + if (Font != skin->getFont()) + { + if (Font) + Font->drop(); + + Font = skin->getFont(); + if ( 0 == ItemHeightOverride ) + ItemHeight = 0; + + if (Font) + { + if ( 0 == ItemHeightOverride ) + ItemHeight = Font->getDimension(L"A").Height + 4; + + Font->grab(); + } + } + + TotalItemHeight = ItemHeight * Items.size(); + ScrollBar->setMax( core::max_(0, TotalItemHeight - AbsoluteRect.getHeight()) ); + s32 minItemHeight = ItemHeight > 0 ? ItemHeight : 1; + ScrollBar->setSmallStep ( minItemHeight ); + ScrollBar->setLargeStep ( 2*minItemHeight ); + + if ( TotalItemHeight <= AbsoluteRect.getHeight() ) + ScrollBar->setVisible(false); + else + ScrollBar->setVisible(true); +} + + +//! returns id of selected item. returns -1 if no item is selected. +s32 CGUISTKListBox::getSelected() const +{ + return Selected; +} + + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUISTKListBox::setSelected(s32 id) +{ + if ((u32)id>=Items.size()) + Selected = -1; + else + Selected = id; + + selectTime = os::Timer::getTime(); + + recalculateScrollPos(); +} + +s32 CGUISTKListBox::getRowByCellText(const wchar_t * text) +{ + s32 row_index = -1; + s32 col_index = -1; + if (text) + { + for ( row_index = 0; row_index < (s32) Items.size(); ++row_index ) + { + for ( col_index = 0; col_index < (s32) Items[row_index].m_contents.size(); ++col_index ) + { + if ( Items[row_index].m_contents[col_index].m_text == text ) return row_index; + } + } + } + return -1; +} + +//! sets the selected item. Set this to -1 if no item should be selected +void CGUISTKListBox::setSelectedByCellText(const wchar_t * text) +{ + setSelected(getRowByCellText(text)); +} + +s32 CGUISTKListBox::getRowByInternalName(const std::string & text) const +{ + s32 row_index = -1; + if (text != "") + { + for ( row_index = 0; row_index < (s32) Items.size(); ++row_index ) + { + if (Items[row_index].m_internal_name == text) return row_index; + } + } + return -1; +} + +//! called if an event happened. +bool CGUISTKListBox::OnEvent(const SEvent& event) +{ + if (isEnabled()) + { + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + if (event.KeyInput.PressedDown && + (event.KeyInput.Key == KEY_DOWN || + event.KeyInput.Key == KEY_UP || + event.KeyInput.Key == KEY_HOME || + event.KeyInput.Key == KEY_END || + event.KeyInput.Key == KEY_NEXT || + event.KeyInput.Key == KEY_PRIOR ) ) + { + s32 oldSelected = Selected; + switch (event.KeyInput.Key) + { + case KEY_DOWN: + Selected += 1; + break; + case KEY_UP: + Selected -= 1; + break; + case KEY_HOME: + Selected = 0; + break; + case KEY_END: + Selected = (s32)Items.size()-1; + break; + case KEY_NEXT: + Selected += AbsoluteRect.getHeight() / ItemHeight; + break; + case KEY_PRIOR: + Selected -= AbsoluteRect.getHeight() / ItemHeight; + break; + default: + break; + } + if (Selected >= (s32)Items.size()) + Selected = Items.size() - 1; + else + if (Selected<0) + Selected = 0; + + recalculateScrollPos(); + + // post the news + + if (oldSelected != Selected && Parent && !Selecting && !MoveOverSelect) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_CHANGED; + Parent->OnEvent(e); + } + + return true; + } + else + if (!event.KeyInput.PressedDown && ( event.KeyInput.Key == KEY_RETURN || event.KeyInput.Key == KEY_SPACE ) ) + { + if (Parent) + { + SEvent e; + e.EventType = EET_GUI_EVENT; + e.GUIEvent.Caller = this; + e.GUIEvent.Element = 0; + e.GUIEvent.EventType = EGET_LISTBOX_SELECTED_AGAIN; + Parent->OnEvent(e); + } + return true; + } + break; + + case EET_GUI_EVENT: + switch(event.GUIEvent.EventType) + { + case gui::EGET_SCROLL_BAR_CHANGED: + if (event.GUIEvent.Caller == ScrollBar) + return true; + break; + case gui::EGET_ELEMENT_FOCUS_LOST: + { + if (event.GUIEvent.Caller == this) + Selecting = false; + break; + } + + default: + break; + } + break; + + case EET_MOUSE_INPUT_EVENT: + { + core::position2d p(event.MouseInput.X, event.MouseInput.Y); + + switch(event.MouseInput.Event) + { + case EMIE_MOUSE_WHEEL: + ScrollBar->setPos(ScrollBar->getPos() + (event.MouseInput.Wheel < 0 ? -1 : 1)*-ItemHeight/2); + return true; + + case EMIE_LMOUSE_PRESSED_DOWN: + { + Selecting = true; + return true; + } + + case EMIE_LMOUSE_LEFT_UP: + { + Selecting = false; + + if (isPointInside(p)) + selectNew(event.MouseInput.Y); + + return true; + } + + case EMIE_MOUSE_MOVED: + if (Selecting || MoveOverSelect) + { + if (isPointInside(p)) + { + selectNew(event.MouseInput.Y, true); + return true; + } + } + default: + break; + } + } + break; + case EET_LOG_TEXT_EVENT: + case EET_USER_EVENT: + case EET_JOYSTICK_INPUT_EVENT: + case EGUIET_FORCE_32_BIT: + break; + } + } + + return IGUIElement::OnEvent(event); +} + + +void CGUISTKListBox::selectNew(s32 ypos, bool onlyHover) +{ + u32 now = os::Timer::getTime(); + s32 oldSelected = Selected; + + Selected = getItemAt(AbsoluteRect.UpperLeftCorner.X, ypos); + if (Selected<0 && !Items.empty()) + Selected = 0; + + recalculateScrollPos(); + + gui::EGUI_EVENT_TYPE eventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; + selectTime = now; + // post the news + if (Parent && !onlyHover) + { + SEvent event; + event.EventType = EET_GUI_EVENT; + event.GUIEvent.Caller = this; + event.GUIEvent.Element = 0; + event.GUIEvent.EventType = eventType; + Parent->OnEvent(event); + } +} + + +//! Update the position and size of the listbox, and update the scrollbar +void CGUISTKListBox::updateAbsolutePosition() +{ + IGUIElement::updateAbsolutePosition(); + + recalculateItemHeight(); +} + + +//! draws the element and its children +void CGUISTKListBox::draw() +{ + if (!IsVisible) + return; + + recalculateItemHeight(); // if the font changed + + IGUISkin* skin = Environment->getSkin(); + + core::rect* clipRect = 0; + + // draw background + core::rect frameRect(AbsoluteRect); + + // draw items + + core::rect clientClip(AbsoluteRect); + clientClip.UpperLeftCorner.Y += 1; + clientClip.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + clientClip.LowerRightCorner.Y -= 1; + clientClip.clipAgainst(AbsoluteClippingRect); + + skin->draw3DSunkenPane(this, skin->getColor(EGDC_3D_HIGH_LIGHT), true, + DrawBack, frameRect, &clientClip); + + if (clipRect) + clientClip.clipAgainst(*clipRect); + + frameRect = AbsoluteRect; + frameRect.UpperLeftCorner.X += 1; + if (ScrollBar->isVisible()) + frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); + + frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; + + frameRect.UpperLeftCorner.Y -= ScrollBar->getPos(); + frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); + + bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); + + for (s32 i=0; i<(s32)Items.size(); ++i) + { + if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && + frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) + { + if (i == Selected && hl) + skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); + + core::rect textRect = frameRect; + + if (Font) + { + int total_proportion = 0; + for(int x = 0; x < Items[i].m_contents.size(); ++x) + { + total_proportion += Items[i].m_contents[x].m_proportion; + } + int part_size = textRect.getWidth() / total_proportion; + + for(int x = 0; x < Items[i].m_contents.size(); ++x) + { + textRect.LowerRightCorner.X = textRect.UpperLeftCorner.X + + (Items[i].m_contents[x].m_proportion * part_size); + textRect.UpperLeftCorner.X += 3; + + if (IconBank && (Items[i].m_contents[x].m_icon > -1)) + { + core::position2di iconPos = textRect.UpperLeftCorner; + iconPos.Y += textRect.getHeight() / 2; + iconPos.X += ItemsIconWidth/2; + + if ( i==Selected && hl ) + { + IconBank->draw2DSprite( + (u32)Items[i].m_contents[x].m_icon, + iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? + getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), + selectTime, os::Timer::getTime(), false, true); + } + else + { + IconBank->draw2DSprite( + (u32)Items[i].m_contents[x].m_icon, + iconPos, + &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), + 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); + } + } + + textRect.UpperLeftCorner.X += ItemsIconWidth+3; + + if ( i==Selected && hl ) + { + Font->draw( + Items[i].m_contents[x].m_text.c_str(), + textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? + getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT), + false, true, &clientClip); + } + else + { + Font->draw( + Items[i].m_contents[x].m_text.c_str(), + textRect, + hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT), + false, true, &clientClip); + } + //Position back to inital pos + textRect.UpperLeftCorner.X -= ItemsIconWidth+6; + //Calculate new beginning + textRect.UpperLeftCorner.X += Items[i].m_contents[x].m_proportion * part_size; + } + } + } + + frameRect.UpperLeftCorner.Y += ItemHeight; + frameRect.LowerRightCorner.Y += ItemHeight; + } + + IGUIElement::draw(); +} + + +//! adds an list item with an icon +u32 CGUISTKListBox::addItem(const ListItem & item) +{ + Items.push_back(item); + recalculateItemHeight(); + recalculateIconWidth(); + return Items.size() - 1; +} + + +void CGUISTKListBox::setSpriteBank(IGUISpriteBank* bank) +{ + if ( bank == IconBank ) + return; + if (IconBank) + IconBank->drop(); + + IconBank = bank; + if (IconBank) + IconBank->grab(); +} + + +void CGUISTKListBox::recalculateScrollPos() +{ + if (!AutoScroll) + return; + + const s32 selPos = (Selected == -1 ? TotalItemHeight : Selected * ItemHeight) - ScrollBar->getPos(); + + if (selPos < 0) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos); + } + else + if (selPos > AbsoluteRect.getHeight() - ItemHeight) + { + ScrollBar->setPos(ScrollBar->getPos() + selPos - AbsoluteRect.getHeight() + ItemHeight); + } +} + + +void CGUISTKListBox::setAutoScrollEnabled(bool scroll) +{ + AutoScroll = scroll; +} + + +bool CGUISTKListBox::isAutoScrollEnabled() const +{ + _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; + return AutoScroll; +} + +void CGUISTKListBox::recalculateIconWidth() +{ + for(int x = 0; x < Items.getLast().m_contents.size(); ++x) + { + s32 icon = Items.getLast().m_contents[x].m_icon; + if (IconBank && icon > -1 && + IconBank->getSprites().size() > (u32)icon && + IconBank->getSprites()[(u32)icon].Frames.size()) + { + u32 rno = IconBank->getSprites()[(u32)icon].Frames[0].rectNumber; + if (IconBank->getPositions().size() > rno) + { + const s32 w = IconBank->getPositions()[rno].getWidth(); + if (w > ItemsIconWidth) + ItemsIconWidth = w; + } + } + } +} + + +void CGUISTKListBox::setCell(u32 row_num, u32 col_num, const wchar_t* text, s32 icon) +{ + if ( row_num >= Items.size() ) + return; + if ( col_num >= Items[row_num].m_contents.size() ) + return; + Items[row_num].m_contents[col_num].m_text = text; + Items[row_num].m_contents[col_num].m_icon = icon; + + recalculateItemHeight(); + recalculateIconWidth(); +} + +void CGUISTKListBox::swapItems(u32 index1, u32 index2) +{ + if ( index1 >= Items.size() || index2 >= Items.size() ) + return; + + ListItem dummmy = Items[index1]; + Items[index1] = Items[index2]; + Items[index2] = dummmy; +} + + +void CGUISTKListBox::setItemOverrideColor(u32 index, video::SColor color) +{ + for ( u32 c=0; c < EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = true; + Items[index].OverrideColors[c].Color = color; + } +} + + +void CGUISTKListBox::setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = true; + Items[index].OverrideColors[colorType].Color = color; +} + + +void CGUISTKListBox::clearItemOverrideColor(u32 index) +{ + for (u32 c=0; c < (u32)EGUI_LBC_COUNT; ++c ) + { + Items[index].OverrideColors[c].Use = false; + } +} + + +void CGUISTKListBox::clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return; + + Items[index].OverrideColors[colorType].Use = false; +} + + +bool CGUISTKListBox::hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return false; + + return Items[index].OverrideColors[colorType].Use; +} + + +video::SColor CGUISTKListBox::getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const +{ + if ( (u32)index >= Items.size() || colorType < 0 || colorType >= EGUI_LBC_COUNT ) + return video::SColor(); + + return Items[index].OverrideColors[colorType].Color; +} + + +video::SColor CGUISTKListBox::getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const +{ + IGUISkin* skin = Environment->getSkin(); + if ( !skin ) + return video::SColor(); + + switch ( colorType ) + { + case EGUI_LBC_TEXT: + return skin->getColor(EGDC_BUTTON_TEXT); + case EGUI_LBC_TEXT_HIGHLIGHT: + return skin->getColor(EGDC_HIGH_LIGHT_TEXT); + case EGUI_LBC_ICON: + return skin->getColor(EGDC_ICON); + case EGUI_LBC_ICON_HIGHLIGHT: + return skin->getColor(EGDC_ICON_HIGH_LIGHT); + default: + return video::SColor(); + } +} + +//! set global itemHeight +void CGUISTKListBox::setItemHeight( s32 height ) +{ + ItemHeight = height; + ItemHeightOverride = 1; +} + + +//! Sets whether to draw the background +void CGUISTKListBox::setDrawBackground(bool draw) +{ + DrawBack = draw; +} + + +} // end namespace gui +} // end namespace irr + + diff --git a/src/guiengine/widgets/CGUISTKListBox.h b/src/guiengine/widgets/CGUISTKListBox.h new file mode 100644 index 000000000..b8e3fa662 --- /dev/null +++ b/src/guiengine/widgets/CGUISTKListBox.h @@ -0,0 +1,196 @@ +// Copyright (C) 2002-2012 Nikolaus Gebhardt +// 2013 Glenn De Jonghe +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in irrlicht.h + +#ifndef HEADER_CGUISTKListBox_HPP +#define HEADER_CGUISTKListBox_HPP + +#include "IrrCompileConfig.h" + +#include "IGUIListBox.h" +#include "IGUIElement.h" +#include "irrArray.h" +#include + +namespace irr +{ + namespace gui + { + class IGUIFont; + class IGUIScrollBar; + + class CGUISTKListBox : public IGUIElement + { + public: + + struct ListItem + { + + struct ListCell + { + irr::core::stringw m_text; + int m_proportion; + s32 m_icon; + + ListCell(irr::core::stringw text, s32 icon = -1, int proportion = 1) + { + m_text = text; + m_proportion = proportion; + m_icon = icon; + } + }; + + core::array< ListCell > m_contents; + + // Actually only used in list_widget -- still refactoring FIXME + std::string m_internal_name; + int m_current_id; + + // A multicolor extension + struct ListItemOverrideColor + { + ListItemOverrideColor() : Use(false) {} + bool Use; + video::SColor Color; + }; + + ListItemOverrideColor OverrideColors[EGUI_LBC_COUNT]; + }; + + //! constructor + CGUISTKListBox(IGUIEnvironment* environment, IGUIElement* parent, + s32 id, core::rect rectangle, bool clip=true, + bool drawBack=false, bool moveOverSelect=false); + + //! destructor + virtual ~CGUISTKListBox(); + + //! returns amount of list items + virtual u32 getItemCount() const; + + virtual const wchar_t* getCellText(u32 row_num, u32 col_num) const; + + virtual ListItem getItem(u32 id) const; + + //! clears the list + virtual void clear(); + + //! returns id of selected item. returns -1 if no item is selected. + virtual s32 getSelected() const; + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelected(s32 id); + + virtual s32 getRowByCellText(const wchar_t * text); + + //! sets the selected item. Set this to -1 if no item should be selected + virtual void setSelectedByCellText(const wchar_t * text); + + virtual s32 getRowByInternalName(const std::string & text) const; + + //! called if an event happened. + virtual bool OnEvent(const SEvent& event); + + //! draws the element and its children + virtual void draw(); + + //! adds an list item with an icon + //! \param text Text of list entry + //! \param icon Sprite index of the Icon within the current sprite bank. Set it to -1 if you want no icon + //! \return + //! returns the id of the new created item + //virtual u32 addItem(const wchar_t* text, s32 icon); + + virtual u32 addItem(const ListItem & item); + + //! Returns the icon of an item + virtual s32 getIcon(u32 row_num, u32 col_num) const; + + //! removes an item from the list + virtual void removeItem(u32 id); + + //! get the the id of the item at the given absolute coordinates + virtual s32 getItemAt(s32 xpos, s32 ypos) const; + + //! Sets the sprite bank which should be used to draw list icons. This font is set to the sprite bank of + //! the built-in-font by default. A sprite can be displayed in front of every list item. + //! An icon is an index within the icon sprite bank. Several default icons are available in the + //! skin through getIcon + virtual void setSpriteBank(IGUISpriteBank* bank); + + //! set whether the listbox should scroll to newly selected items + virtual void setAutoScrollEnabled(bool scroll); + + //! returns true if automatic scrolling is enabled, false if not. + virtual bool isAutoScrollEnabled() const; + + //! Update the position and size of the listbox, and update the scrollbar + virtual void updateAbsolutePosition(); + + //! set all item colors at given index to color + virtual void setItemOverrideColor(u32 index, video::SColor color); + + //! set all item colors of specified type at given index to color + virtual void setItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType, video::SColor color); + + //! clear all item colors at index + virtual void clearItemOverrideColor(u32 index); + + //! clear item color at index for given colortype + virtual void clearItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType); + + //! has the item at index its color overwritten? + virtual bool hasItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the overwrite color at given item index. + virtual video::SColor getItemOverrideColor(u32 index, EGUI_LISTBOX_COLOR colorType) const; + + //! return the default color which is used for the given colorType + virtual video::SColor getItemDefaultColor(EGUI_LISTBOX_COLOR colorType) const; + + //! set the item at the given index + virtual void setCell(u32 row_num, u32 col_num, const wchar_t* text, s32 icon); + + //! Swap the items at the given indices + virtual void swapItems(u32 index1, u32 index2); + + //! set global itemHeight + virtual void setItemHeight( s32 height ); + + //! Sets whether to draw the background + virtual void setDrawBackground(bool draw); + + private: + + void recalculateItemHeight(); + void selectNew(s32 ypos, bool onlyHover=false); + void recalculateScrollPos(); + + // extracted that function to avoid copy&paste code + void recalculateIconWidth(); + + core::array< ListItem > Items; + s32 Selected; + s32 ItemHeight; + s32 ItemHeightOverride; + s32 TotalItemHeight; + s32 ItemsIconWidth; + gui::IGUIFont* Font; + gui::IGUISpriteBank* IconBank; + gui::IGUIScrollBar* ScrollBar; + u32 selectTime; + u32 LastKeyTime; + core::stringw KeyBuffer; + bool Selecting; + bool DrawBack; + bool MoveOverSelect; + bool AutoScroll; + bool HighlightWhenNotFocused; + }; + + + } // end namespace gui +} // end namespace irr + +#endif diff --git a/src/guiengine/widgets/list_widget.cpp b/src/guiengine/widgets/list_widget.cpp index ba8def7bf..4998ed27d 100644 --- a/src/guiengine/widgets/list_widget.cpp +++ b/src/guiengine/widgets/list_widget.cpp @@ -17,7 +17,6 @@ #include "guiengine/widgets/list_widget.hpp" -#include "guiengine/widgets/CGUIListBox.h" #include "guiengine/CGUISpriteBank.h" #include "guiengine/engine.hpp" #include "io/file_manager.hpp" @@ -53,7 +52,7 @@ void ListWidget::setIcons(STKModifiedSpriteBank* icons, int size) if (m_use_icons) { - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); list->setSpriteBank(m_icons); @@ -94,7 +93,7 @@ void ListWidget::add() IGUISkin * current_skin = GUIEngine::getGUIEnv()->getSkin(); IGUIFont * current_font = GUIEngine::getGUIEnv()->getBuiltInFont(); - IGUIListBox * list_box = new CGUIListBox( + CGUISTKListBox * list_box = new CGUISTKListBox( GUIEngine::getGUIEnv(), m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement(), getNewID(), @@ -173,91 +172,120 @@ void ListWidget::clear() // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); list->clear(); - m_items.clear(); } // ----------------------------------------------------------------------------- -void ListWidget::addItem(const std::string& internalName, - const irr::core::stringw& name, const int icon) +void ListWidget::addItem( const std::string& internal_name, + const irr::core::stringw &name, + const int icon) +{ + // May only be called AFTER this widget has been add()ed + assert(m_element != NULL); + + ListCell cell(name, icon); + ListItem newItem; + newItem.m_internal_name = internal_name; + newItem.m_contents.push_back(cell); + + CGUISTKListBox* list = getIrrlichtElement(); + assert(list != NULL); + + u32 itemID = list->addItem( newItem ); + if (m_use_icons) + { + list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) ); + list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) ); + } + newItem.m_current_id = itemID; +} + +// ----------------------------------------------------------------------------- + +void ListWidget::addItem(const std::string& internal_name, + PtrVector * contents) { // May only be called AFTER this widget has been add()ed assert(m_element != NULL); ListItem newItem; - newItem.m_label = name; - newItem.m_internal_name = internalName; + newItem.m_internal_name = internal_name; + for(int i = 0; i < (int)contents->size(); i++) + { + newItem.m_contents.push_back(*contents->get(i)); + } - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); - if (m_use_icons && icon != -1) + u32 itemID = list->addItem( newItem ); + if (m_use_icons) { - u32 itemID = list->addItem( name.c_str(), icon ); list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON, video::SColor(255,255,255,255) ); list->setItemOverrideColor( itemID, gui::EGUI_LBC_ICON_HIGHLIGHT, video::SColor(255,255,255,255) ); - newItem.m_current_id = itemID; } - else - { - newItem.m_current_id = list->addItem( name.c_str() ); - } - m_items.push_back(newItem); + newItem.m_current_id = itemID; } // ----------------------------------------------------------------------------- - -void ListWidget::renameItem(const int itemID, const irr::core::stringw newName, const int icon) +void ListWidget::renameCell(const int row_index, const int col_index, const irr::core::stringw newName, const int icon) { // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); - m_items[itemID].m_label = newName; - list->setItem(itemID, newName.c_str(), icon); + list->setCell(row_index, col_index, newName.c_str(), icon); - list->setItemOverrideColor( itemID, EGUI_LBC_TEXT , video::SColor(255,0,0,0) ); - list->setItemOverrideColor( itemID, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) ); + list->setItemOverrideColor( row_index, EGUI_LBC_TEXT , video::SColor(255,0,0,0) ); + list->setItemOverrideColor( row_index, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) ); +} + +// ----------------------------------------------------------------------------- +void ListWidget::renameItem(const int row_index, const irr::core::stringw newName, const int icon) +{ + renameCell(row_index, 0, newName, icon); } // ----------------------------------------------------------------------------- std::string ListWidget::getSelectionInternalName() { - if (getSelectionID() == -1) return ""; - return m_items[ getSelectionID() ].m_internal_name; + CGUISTKListBox* list = getIrrlichtElement(); + assert(list != NULL); + if (getSelectionID() == -1 || (getSelectionID() >= (int)list->getItemCount())) + return ""; + return list->getItem(getSelectionID()).m_internal_name; } // ----------------------------------------------------------------------------- - -irr::core::stringw ListWidget::getSelectionLabel() const +irr::core::stringw ListWidget::getSelectionLabel(const int cell) const { - const IGUIListBox* list = getIrrlichtElement(); + const CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); - return list->getListItem( list->getSelected() ); + return list->getCellText( list->getSelected(), cell); } // ----------------------------------------------------------------------------- void ListWidget::selectItemWithLabel(const irr::core::stringw& name) { - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); - return list->setSelected( name.c_str() ); + return list->setSelectedByCellText( name.c_str() ); } // ----------------------------------------------------------------------------- void ListWidget::unfocused(const int playerID, Widget* new_focus) { - IGUIListBox* list = getIrrlichtElement(); + CGUISTKListBox* list = getIrrlichtElement(); // remove selection when leaving list if (list != NULL) list->setSelected(-1); @@ -270,7 +298,7 @@ int ListWidget::getSelectionID() const // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - return getIrrlichtElement()->getSelected(); + return getIrrlichtElement()->getSelected(); } // ----------------------------------------------------------------------------- @@ -280,7 +308,7 @@ void ListWidget::setSelectionID(const int index) // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - IGUIListBox* irritem = getIrrlichtElement(); + CGUISTKListBox* irritem = getIrrlichtElement(); // auto-scroll to item when selecting something, don't auto-scroll when selecting nothing if (index != -1) @@ -303,8 +331,7 @@ int ListWidget::getItemCount() const // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - const int count = getIrrlichtElement()->getItemCount(); - assert((int)m_items.size() == count); + const int count = getIrrlichtElement()->getItemCount(); return count; } @@ -314,7 +341,6 @@ int ListWidget::getItemCount() const void ListWidget::elementRemoved() { Widget::elementRemoved(); - m_items.clear(); for (int n=0; n(); + CGUISTKListBox* irritem = getIrrlichtElement(); if (red) { @@ -367,7 +379,7 @@ void ListWidget::markItemBlue(const int id, bool blue) // May only be called AFTER this widget has been add()ed assert(m_element != NULL); - IGUIListBox* irritem = getIrrlichtElement(); + CGUISTKListBox* irritem = getIrrlichtElement(); if (blue) { @@ -413,3 +425,11 @@ EventPropagation ListWidget::transmitEvent(Widget* w, return EVENT_LET; } + +// ----------------------------------------------------------------------------- +int ListWidget::getItemID(const std::string internalName) const +{ + const CGUISTKListBox* list = getIrrlichtElement(); + assert(list != NULL); + return list->getRowByInternalName(internalName); +} diff --git a/src/guiengine/widgets/list_widget.hpp b/src/guiengine/widgets/list_widget.hpp index 4e1a3191c..657adbac8 100644 --- a/src/guiengine/widgets/list_widget.hpp +++ b/src/guiengine/widgets/list_widget.hpp @@ -22,12 +22,14 @@ #include +#include "guiengine/widgets/CGUISTKListBox.h" #include "guiengine/widget.hpp" #include "guiengine/widgets/button_widget.hpp" #include "utils/leak_check.hpp" #include "utils/ptr_vector.hpp" #include "IGUIElement.h" + namespace irr { namespace gui { class STKModifiedSpriteBank; } } namespace GUIEngine @@ -48,7 +50,6 @@ namespace GUIEngine class ListWidget : public Widget { friend class Skin; - /** \brief whether this list has icons */ bool m_use_icons; @@ -56,14 +57,6 @@ namespace GUIEngine /** \brief if m_use_icons is true, this will contain the icon bank */ irr::gui::STKModifiedSpriteBank* m_icons; - struct ListItem - { - std::string m_internal_name; - irr::core::stringw m_label; - int m_current_id; - }; - std::vector< ListItem > m_items; - PtrVector< ButtonWidget > m_header_elements; ButtonWidget* m_selected_column; @@ -89,6 +82,8 @@ namespace GUIEngine IListWidgetHeaderListener* m_listener; public: + typedef irr::gui::CGUISTKListBox::ListItem ListItem; + typedef ListItem::ListCell ListCell; LEAK_CHECK() @@ -125,8 +120,12 @@ namespace GUIEngine * \param icon ID of the icon within the icon bank. Only used if an icon bank was passed. * \pre may only be called after the widget has been added to the screen with add() */ - void addItem(const std::string& internal_name, - const irr::core::stringw &name, const int icon=-1); + void addItem( const std::string& internal_name, + const irr::core::stringw &name, + const int icon=-1); + + void addItem( const std::string& internal_name, + PtrVector * contents); /** * \brief erases all items in the list @@ -152,7 +151,7 @@ namespace GUIEngine */ std::string getSelectionInternalName(); - irr::core::stringw getSelectionLabel() const; + irr::core::stringw getSelectionLabel(const int cell = 0) const; void selectItemWithLabel(const irr::core::stringw& name); @@ -172,18 +171,23 @@ namespace GUIEngine * \brief rename an item and/or change its icon based on its ID * \pre may only be called after the widget has been added to the screen with add() */ - void renameItem(const int itemID, const irr::core::stringw newName, const int icon=-1); + void renameCell(const int row_num, const int col_num, const irr::core::stringw newName, const int icon=-1); + /** + * renames first cell only + */ + void renameItem(const int row_num, const irr::core::stringw newName, const int icon=-1); + /** * \brief rename an item and/or change its icon based on its internal name * \pre may only be called after the widget has been added to the screen with add() */ - void renameItem(const std::string internalName, const irr::core::stringw newName, + void renameCell(const std::string internalName, const int col_num, const irr::core::stringw newName, const int icon=-1) { const int id = getItemID(internalName); assert(id != -1); - renameItem( id, newName, icon ); + renameCell( id, col_num, newName, icon ); } /** diff --git a/src/states_screens/addons_screen.cpp b/src/states_screens/addons_screen.cpp index b51dbea3f..6130ffc1b 100644 --- a/src/states_screens/addons_screen.cpp +++ b/src/states_screens/addons_screen.cpp @@ -279,10 +279,11 @@ void AddonsScreen::loadList() s = (addon->getName()+L"\t" + core::stringc(addon->getDateAsString().c_str())).c_str(); - gui::IGUIFont* font = GUIEngine::getFont(); + /* gui::IGUIFont* font = GUIEngine::getFont(); // first column is 0.666% of the list's width. // and icon width == icon height. + const unsigned int available_width = (int)(w_list->m_w*0.6666f - m_icon_height); if (font->getDimension(s.c_str()).Width > available_width) @@ -291,7 +292,7 @@ void AddonsScreen::loadList() s.append("..."); } else - { + {*/ if (addon->getDesigner().size() == 0) { s = addon->getName(); @@ -302,7 +303,7 @@ void AddonsScreen::loadList() s = _C("addons", "%s by %s", addon->getName().c_str(), addon->getDesigner().c_str()); } - + /* // check if text is too long to fit if (font->getDimension(s.c_str()).Width > available_width) { @@ -342,10 +343,9 @@ void AddonsScreen::loadList() } // for nlines.size() s = final_string; - } // if - s.append("\t"); - s.append(addon->getDateAsString().c_str()); - } + */ + //} // if + //} // we have no icon for featured+updateme, so if an add-on is updatable // forget about the featured icon @@ -355,7 +355,10 @@ void AddonsScreen::loadList() icon += 2; } - w_list->addItem(addon->getId(), s.c_str(), icon); + PtrVector * row = new PtrVector; + row->push_back(new GUIEngine::ListWidget::ListCell(s.c_str(),icon,2)); + row->push_back(new GUIEngine::ListWidget::ListCell(addon->getDateAsString().c_str(),-1,1)); + w_list->addItem(addon->getId(), row); // Highlight if it's not approved in artists debug mode. if(UserConfigParams::m_artist_debug_mode && @@ -365,16 +368,16 @@ void AddonsScreen::loadList() } } - getWidget("category")->setActivated(); - if(m_type == "kart") - getWidget("category")->select("tab_kart", - PLAYER_ID_GAME_MASTER); - else if(m_type == "track") - getWidget("category")->select("tab_track", - PLAYER_ID_GAME_MASTER); + getWidget("category")->setActivated(); + if(m_type == "kart") + getWidget("category")->select("tab_kart", + PLAYER_ID_GAME_MASTER); + else if(m_type == "track") + getWidget("category")->select("tab_track", + PLAYER_ID_GAME_MASTER); else - getWidget("category")->select("tab_update", - PLAYER_ID_GAME_MASTER); + getWidget("category")->select("tab_update", + PLAYER_ID_GAME_MASTER); } // loadList // ---------------------------------------------------------------------------- @@ -384,7 +387,7 @@ void AddonsScreen::onColumnClicked(int column_id) { case 0: Addon::setSortOrder(Addon::SO_NAME); break; case 1: Addon::setSortOrder(Addon::SO_DATE); break; - default: assert(0); + default: assert(0); break; } // switch /** \brief Toggle the sort order after column click **/ m_sort_desc = !m_sort_desc; @@ -412,9 +415,7 @@ void AddonsScreen::eventCallback(GUIEngine::Widget* widget, w_list->clear(); w_list->addItem("spacer", L""); - w_list->addItem("loading", - _("Please wait while addons are updated"), - m_icon_loading); + w_list->addItem("loading",_("Please wait while addons are updated"), m_icon_loading); } }