stk-code_catmod/src/guiengine/widget.cpp
hikerstk 7cdca13d7b Fixed all(?) warnings about signed and unsigned comparisons.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14950 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2014-01-07 00:09:19 +00:00

361 lines
9.4 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2013 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/widget.hpp"
#include <iostream>
#include <sstream>
#include <IGUIElement.h>
using namespace irr;
using namespace core;
using namespace video;
using namespace io;
using namespace gui;
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "io/file_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "utils/vs.hpp"
namespace GUIEngine
{
static bool g_is_within_a_text_box = false;
bool isWithinATextBox()
{
return g_is_within_a_text_box;
}
void setWithinATextBox(bool in)
{
g_is_within_a_text_box = in;
}
}
using namespace GUIEngine;
// -----------------------------------------------------------------------------
Widget::Widget(WidgetType type, bool reserve_id)
{
m_magic_number = 0xCAFEC001;
m_x = -1;
m_y = -1;
m_w = -1;
m_h = -1;
m_id = -1;
m_badge_x_shift = 0;
m_element = NULL;
m_title_font = false;
m_type = type;
m_parent = NULL;
m_focusable = true;
m_bottom_bar = false;
m_top_bar = false;
m_event_handler = NULL;
m_reserve_id = reserve_id;
m_show_bounding_box = false;
m_supports_multiplayer = false;
m_is_bounding_box_round = false;
m_has_tooltip = false;
m_is_text_rtl = false;
m_absolute_x = m_absolute_y = m_absolute_w = m_absolute_h = -1;
m_relative_x = m_relative_y = m_relative_w = m_relative_h = -1;
m_absolute_reverse_x = m_absolute_reverse_y = -1;
m_tab_down_root = -1;
m_tab_up_root = -1;
for (unsigned int n=0; n<MAX_PLAYER_COUNT; n++)
{
m_player_focus[n] = false;
m_selected[n] = false;
}
m_reserved_id = -1;
m_deactivated = false;
m_is_visible = true;
m_badges = 0;
// set a default value, derivates can override this as they wish
m_check_inside_me = (m_type == WTYPE_DIV);
}
// -----------------------------------------------------------------------------
Widget::~Widget()
{
assert(m_magic_number == 0xCAFEC001);
// If any player focused this widget, unset that focus
for (unsigned int n=0; n<MAX_PLAYER_COUNT; n++)
{
if (m_player_focus[n])
{
GUIEngine::focusNothingForPlayer(n);
}
}
m_magic_number = 0xDEADBEEF;
}
// -----------------------------------------------------------------------------
void Widget::setText(const wchar_t *s)
{
m_text = s;
if(m_element)
m_element->setText(s);
} // setText
// -----------------------------------------------------------------------------
void Widget::elementRemoved()
{
assert(m_magic_number == 0xCAFEC001);
m_element = NULL;
// If any player focused this widget, unset that focus
for (unsigned int n=0; n<MAX_PLAYER_COUNT; n++)
{
if (m_player_focus[n])
{
GUIEngine::focusNothingForPlayer(n);
}
}
}
// -----------------------------------------------------------------------------
void Widget::setActivated()
{
// even if this one is already active, do it anyway on purpose, maybe the
// children widgets need to be updated
m_deactivated = false;
const int count = m_children.size();
for (int n=0; n<count; n++)
{
m_children[n].setActivated();
}
}
// -----------------------------------------------------------------------------
void Widget::setDeactivated()
{
// even if this one is already inactive, do it anyway on purpose, maybe the
// children widgets need to be updated
m_deactivated = true;
const int count = m_children.size();
for (int n=0; n<count; n++)
{
m_children[n].setDeactivated();
}
}
// -----------------------------------------------------------------------------
bool Widget::deleteChild(const char* id)
{
const int count = m_children.size();
for (int n=0; n<count; n++)
{
if (m_children[n].m_properties[PROP_ID] == id)
{
m_children.erase(n);
return true;
}
}
return false;
}
// -----------------------------------------------------------------------------
namespace GUIEngine
{
// IDs must not start at 0, since it appears their GUI engine hardcodes some ID values
const unsigned int FOCUSABLE_IDS_BASE = 100;
const unsigned int UNFOCUSABLE_IDS_BASE = 1000;
/** Used to assign irrLicht IDs to widgets dynamically */
static unsigned int id_counter = FOCUSABLE_IDS_BASE;
/** for items that can't be reached with keyboard navigation but can be clicked */
static unsigned int id_counter_2 = UNFOCUSABLE_IDS_BASE;
}
int Widget::getNewID()
{
return id_counter++;
}
int Widget::getNewNoFocusID()
{
return id_counter_2++;
}
bool Widget::isFocusableId(const int id)
{
if (id < 0) return false;
if ((unsigned int)id >= UNFOCUSABLE_IDS_BASE) return false;
else return true;
}
// -----------------------------------------------------------------------------
/** When switching to a new screen, this function will be called to reset ID counters
* (so we start again from ID 0, and don't grow to big numbers) */
void Widget::resetIDCounters()
{
id_counter = 100;
id_counter_2 = 1000;
}
// -----------------------------------------------------------------------------
void Widget::add()
{
assert(m_magic_number == 0xCAFEC001);
if (m_reserve_id)
{
m_reserved_id = getNewID();
}
}
// -----------------------------------------------------------------------------
/**
* \param playerID ID of the player you want to set/unset focus for, starting from 0
* Since the code tracks focus from main player, this will most likely be used only
* for additionnal players
*/
void Widget::setFocusForPlayer(const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
// Unset focus flag on previous widget that had focus
if (GUIEngine::getFocusForPlayer(playerID) != NULL)
{
GUIEngine::getFocusForPlayer(playerID)->unfocused(playerID, this);
GUIEngine::getFocusForPlayer(playerID)->m_player_focus[playerID] = false;
}
m_player_focus[playerID] = true;
GUIEngine::Private::g_focus_for_player[playerID] = this;
// Callback
this->focused(playerID);
}
// -----------------------------------------------------------------------------
void Widget::unsetFocusForPlayer(const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
if (m_player_focus[playerID]) this->unfocused(playerID, NULL);
m_player_focus[playerID] = false;
}
// -----------------------------------------------------------------------------
/**
* \param playerID ID of the player you want to set/unset focus for, starting from 0
*/
bool Widget::isFocusedForPlayer(const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
return m_player_focus[playerID];
}
// -----------------------------------------------------------------------------
void Widget::move(const int x, const int y, const int w, const int h)
{
assert(m_magic_number == 0xCAFEC001);
m_x = x;
m_y = y;
m_w = w;
m_h = h;
if (m_element != NULL)
m_element->setRelativePosition( core::rect < s32 > (x, y, x+w, y+h) );
}
// -----------------------------------------------------------------------------
void Widget::setParent(IGUIElement* parent)
{
assert(m_magic_number == 0xCAFEC001);
m_parent = parent;
}
// -----------------------------------------------------------------------------
bool Widget::isVisible() const
{
if (m_element != NULL)
assert(m_element->isVisible() == m_is_visible);
return m_is_visible;
}
// -----------------------------------------------------------------------------
bool Widget::isActivated() const
{
if (isVisible())
return !m_deactivated;
return false;
}
// -----------------------------------------------------------------------------
void Widget::setVisible(bool visible)
{
if (m_element != NULL)
{
m_element->setVisible(visible);
}
m_is_visible = visible;
m_deactivated = !visible;
const int childrenCount = m_children.size();
for (int n=0; n<childrenCount; n++)
{
m_children[n].setVisible(visible);
}
}
// -----------------------------------------------------------------------------
void Widget::moveIrrlichtElement()
{
if (m_element != NULL)
{
m_element->setRelativePosition( irr::core::recti(irr::core::position2di(m_x, m_y),
irr::core::dimension2di(m_w, m_h) ) );
}
}