unitraxx 2d0d407d7f Small bugfixes in the CGUIListBox
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13214 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2013-07-14 01:01:56 +00:00

416 lines
12 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/CGUIListBox.h"
#include "guiengine/CGUISpriteBank.h"
#include "guiengine/engine.hpp"
#include "io/file_manager.hpp"
#include <IGUIElement.h>
#include <IGUISkin.h>
#include <IGUIEnvironment.h>
#include "IGUIFontBitmap.h"
#include <sstream>
using namespace GUIEngine;
using namespace irr::core;
using namespace irr::gui;
// -----------------------------------------------------------------------------
ListWidget::ListWidget() : Widget(WTYPE_LIST)
{
m_use_icons = false;
m_icons = NULL;
m_listener = NULL;
m_selected_column = NULL;
m_sort_desc = true;
}
// -----------------------------------------------------------------------------
void ListWidget::setIcons(STKModifiedSpriteBank* icons, int size)
{
m_use_icons = (icons != NULL);
m_icons = icons;
if (m_use_icons)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
list->setSpriteBank(m_icons);
// determine needed height
int item_height = 0;
if (size > 0)
{
item_height = size;
}
else
{
const core::array< core::rect<s32> >& rects = m_icons->getPositions();
const int count = rects.size();
for (int n=0; n<count; n++)
{
const int h = rects[n].getHeight();
if (h > item_height) item_height = h;
}
}
if (item_height > 0)
{
list->setItemHeight( item_height );
}
}
}
// -----------------------------------------------------------------------------
void ListWidget::add()
{
const int header_height = GUIEngine::getFontHeight() + 15;
rect<s32> widget_size = (m_header.size() > 0 ? rect<s32>(m_x, m_y + header_height, m_x + m_w, m_y + m_h) :
rect<s32>(m_x, m_y, m_x + m_w, m_y + m_h) );
IGUISkin * current_skin = GUIEngine::getGUIEnv()->getSkin();
IGUIFont * current_font = GUIEngine::getGUIEnv()->getBuiltInFont();
IGUIListBox * list_box = new CGUIListBox(
GUIEngine::getGUIEnv(),
m_parent ? m_parent : GUIEngine::getGUIEnv()->getRootGUIElement(),
getNewID(),
widget_size,
true,
true,
false);
if (current_skin && current_skin->getSpriteBank())
{
list_box->setSpriteBank(current_skin->getSpriteBank());
}
else if (current_font && current_font->getType() == EGFT_BITMAP)
{
list_box->setSpriteBank( ((IGUIFontBitmap*)current_font)->getSpriteBank());
}
list_box->drop();
list_box->setAutoScrollEnabled(false);
m_element = list_box;
m_element->setTabOrder( list_box->getID() );
if (m_header.size() > 0)
{
//const int col_size = m_w / m_header.size();
int proportion_total = 0;
for (unsigned int n=0; n<m_header.size(); n++)
{
proportion_total += m_header[n].m_proportion;
}
int x = m_x;
for (unsigned int n=0; n<m_header.size(); n++)
{
std::ostringstream name;
name << m_properties[PROP_ID];
name << "_column_";
name << n;
ButtonWidget* header = new ButtonWidget();
header->m_reserved_id = getNewNoFocusID();
header->m_y = m_y;
header->m_h = header_height;
header->m_x = x;
header->m_w = (int)(m_w * float(m_header[n].m_proportion)
/float(proportion_total));
x += header->m_w;
header->setText( m_header[n].m_text );
header->m_properties[PROP_ID] = name.str();
header->add();
header->m_event_handler = this;
header->getIrrlichtElement()->setTabStop(false);
m_children.push_back(header);
m_header_elements.push_back(header);
}
m_check_inside_me = true;
}
}
// -----------------------------------------------------------------------------
void ListWidget::clear()
{
// May only be called AFTER this widget has been add()ed
assert(m_element != NULL);
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
list->clear();
m_items.clear();
}
// -----------------------------------------------------------------------------
void ListWidget::addItem(const std::string& internalName,
const irr::core::stringw& name, const int icon)
{
// 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;
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
if (m_use_icons && icon != -1)
{
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)
{
// May only be called AFTER this widget has been add()ed
assert(m_element != NULL);
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
m_items[itemID].m_label = newName;
list->setItem(itemID, 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) );
}
// -----------------------------------------------------------------------------
std::string ListWidget::getSelectionInternalName()
{
if (getSelectionID() == -1) return "";
return m_items[ getSelectionID() ].m_internal_name;
}
// -----------------------------------------------------------------------------
irr::core::stringw ListWidget::getSelectionLabel() const
{
const IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
return list->getListItem( list->getSelected() );
}
// -----------------------------------------------------------------------------
void ListWidget::selectItemWithLabel(const irr::core::stringw& name)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
assert(list != NULL);
return list->setSelected( name.c_str() );
}
// -----------------------------------------------------------------------------
void ListWidget::unfocused(const int playerID, Widget* new_focus)
{
IGUIListBox* list = getIrrlichtElement<IGUIListBox>();
// remove selection when leaving list
if (list != NULL) list->setSelected(-1);
}
// -----------------------------------------------------------------------------
int ListWidget::getSelectionID() const
{
// May only be called AFTER this widget has been add()ed
assert(m_element != NULL);
return getIrrlichtElement<IGUIListBox>()->getSelected();
}
// -----------------------------------------------------------------------------
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>();
// auto-scroll to item when selecting something, don't auto-scroll when selecting nothing
if (index != -1)
{
irritem->setAutoScrollEnabled(true);
}
irritem->setSelected(index);
if (index != -1)
{
irritem->setAutoScrollEnabled(false);
}
}
// -----------------------------------------------------------------------------
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);
return count;
}
// -----------------------------------------------------------------------------
void ListWidget::elementRemoved()
{
Widget::elementRemoved();
m_items.clear();
for (int n=0; n<m_header_elements.size(); n++)
{
m_header_elements[n].elementRemoved();
m_children.remove( m_header_elements.get(n) );
}
m_header_elements.clearAndDeleteAll();
m_selected_column = NULL;
}
// -----------------------------------------------------------------------------
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>();
if (red)
{
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT, video::SColor(255,255,0,0) );
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,0,0) );
}
else
{
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT, video::SColor(255,0,0,0) );
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) );
}
}
// -----------------------------------------------------------------------------
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>();
if (blue)
{
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT, video::SColor(255,0,0,255) );
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,0,0,255) );
}
else
{
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT, video::SColor(255,0,0,0) );
irritem->setItemOverrideColor( id, EGUI_LBC_TEXT_HIGHLIGHT, video::SColor(255,255,255,255) );
}
}
// -----------------------------------------------------------------------------
EventPropagation ListWidget::transmitEvent(Widget* w,
const std::string& originator,
const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
if (originator.find(m_properties[PROP_ID] + "_column_") != std::string::npos)
{
int col = originator[ (m_properties[PROP_ID] + "_column_").size() ] - '0';
m_selected_column = m_header_elements.get(col);
/** \brief Allows sort icon to change depending on sort order **/
m_sort_desc = !m_sort_desc;
/*
for (int n=0; n<m_header_elements.size(); n++)
{
m_header_elements[n].getIrrlichtElement<IGUIButton>()->setPressed(false);
}
m_header_elements[col].getIrrlichtElement<IGUIButton>()->setPressed(true);
*/
if (m_listener) m_listener->onColumnClicked(col);
return EVENT_BLOCK;
}
return EVENT_LET;
}