List widget now supports multiple columns, each cell can have an icon and or text.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13216 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
2d0d407d7f
commit
de6cc44b2a
@ -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
|
||||
|
@ -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<s32> 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<s32>(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<s32> 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<s32>* clipRect = 0;
|
||||
|
||||
// draw background
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
|
||||
// draw items
|
||||
|
||||
core::rect<s32> 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<s32> 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;i<Items.size(); ++i)
|
||||
{
|
||||
core::stringc label("text");
|
||||
label += i;
|
||||
out->addString(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; i<count; ++i)
|
||||
{
|
||||
core::stringc label("text");
|
||||
ListItem item;
|
||||
|
||||
label += i;
|
||||
item.text = in->getAttributeAsStringW(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
|
||||
|
||||
|
@ -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<s32> 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
|
754
src/guiengine/widgets/CGUISTKListBox.cpp
Normal file
754
src/guiengine/widgets/CGUISTKListBox.cpp
Normal file
@ -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<s32> 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<s32>(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<s32> 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<s32>* clipRect = 0;
|
||||
|
||||
// draw background
|
||||
core::rect<s32> frameRect(AbsoluteRect);
|
||||
|
||||
// draw items
|
||||
|
||||
core::rect<s32> 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<s32> 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
|
||||
|
||||
|
196
src/guiengine/widgets/CGUISTKListBox.h
Normal file
196
src/guiengine/widgets/CGUISTKListBox.h
Normal file
@ -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 <string>
|
||||
|
||||
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<s32> 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
|
@ -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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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<CGUISTKListBox>();
|
||||
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<ListCell> * 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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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<CGUISTKListBox>();
|
||||
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<IGUIListBox>();
|
||||
const CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
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<IGUIListBox>();
|
||||
CGUISTKListBox* list = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
// 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<IGUIListBox>()->getSelected();
|
||||
return getIrrlichtElement<CGUISTKListBox>()->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<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
// 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<IGUIListBox>()->getItemCount();
|
||||
assert((int)m_items.size() == count);
|
||||
const int count = getIrrlichtElement<CGUISTKListBox>()->getItemCount();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -314,7 +341,6 @@ int ListWidget::getItemCount() const
|
||||
void ListWidget::elementRemoved()
|
||||
{
|
||||
Widget::elementRemoved();
|
||||
m_items.clear();
|
||||
|
||||
for (int n=0; n<m_header_elements.size(); n++)
|
||||
{
|
||||
@ -327,26 +353,12 @@ void ListWidget::elementRemoved()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int ListWidget::getItemID(const std::string internalName) const
|
||||
{
|
||||
const int count = m_items.size();
|
||||
|
||||
for (int i=0; i<count; i++)
|
||||
{
|
||||
if (m_items[i].m_internal_name == internalName) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ListWidget::markItemRed(const int id, bool red)
|
||||
{
|
||||
// May only be called AFTER this widget has been add()ed
|
||||
assert(m_element != NULL);
|
||||
|
||||
IGUIListBox* irritem = getIrrlichtElement<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
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<IGUIListBox>();
|
||||
CGUISTKListBox* irritem = getIrrlichtElement<CGUISTKListBox>();
|
||||
|
||||
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<CGUISTKListBox>();
|
||||
assert(list != NULL);
|
||||
return list->getRowByInternalName(internalName);
|
||||
}
|
||||
|
@ -22,12 +22,14 @@
|
||||
|
||||
#include <irrString.h>
|
||||
|
||||
#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
|
||||
@ -49,21 +51,12 @@ namespace GUIEngine
|
||||
{
|
||||
friend class Skin;
|
||||
|
||||
|
||||
/** \brief whether this list has icons */
|
||||
bool m_use_icons;
|
||||
|
||||
/** \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<ListCell> * 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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
|
||||
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 &&
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user