Widgets in modal dialogs can now be skinned

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3642 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2009-06-24 16:09:59 +00:00
parent 238b401cc2
commit 604c7adeea
6 changed files with 185 additions and 44 deletions

View File

@ -15,16 +15,20 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config/player.hpp"
#include "gui/engine.hpp" #include "gui/engine.hpp"
#include "gui/modaldialog.hpp" #include "gui/modaldialog.hpp"
#include "gui/options_screen.hpp" #include "gui/options_screen.hpp"
#include "gui/state_manager.hpp" #include "gui/state_manager.hpp"
#include "gui/widget.hpp"
#include "network/network_manager.hpp" #include "network/network_manager.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
using namespace irr; using namespace irr;
namespace GUIEngine
{
// global instance of the current dialog if any // global instance of the current dialog if any
static ModalDialog* modalWindow = NULL; static ModalDialog* modalWindow = NULL;
@ -50,6 +54,10 @@ bool ModalDialog::isADialogActive()
{ {
return modalWindow != NULL; return modalWindow != NULL;
} }
ModalDialog* ModalDialog::getCurrent()
{
return modalWindow;
}
void ModalDialog::onEnterPressedInternal() void ModalDialog::onEnterPressedInternal()
{ {
@ -74,11 +82,37 @@ ModalDialog::ModalDialog(const float percentWidth, const float percentHeight)
PressAKeyDialog::PressAKeyDialog(const float w, const float h) : PressAKeyDialog::PressAKeyDialog(const float w, const float h) :
ModalDialog(w, h) ModalDialog(w, h)
{ {
core::rect< s32 > area2(0, 0, m_area.getWidth(), m_area.getHeight()); //core::rect< s32 > area2(0, 0, m_area.getWidth(), m_area.getHeight());
IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Press a key")).c_str(), //IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Press a key")).c_str(),
area2, false /* border */, true /* word wrap */, // area2, false /* border */, true /* word wrap */,
m_irrlicht_window); // m_irrlicht_window);
label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); //label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
LabelWidget* widget = new LabelWidget();
widget->m_type = WTYPE_LABEL;
widget->m_properties[PROP_TEXT] = _("Press a key");
widget->m_properties[PROP_TEXT_ALIGN] = "center";
widget->x = 0;
widget->y = 0;
widget->w = m_area.getWidth();
widget->h = m_area.getHeight()/2;
widget->setParent(m_irrlicht_window);
m_children.push_back(widget);
widget->add();
ButtonWidget* widget2 = new ButtonWidget();
widget2->m_type = WTYPE_BUTTON; // FIXME : shouldn't constructor set type?
widget2->m_properties[PROP_TEXT] = _("Press ESC to cancel"); // TODO : pressing this button should cancel
widget2->x = 15;
widget2->y = m_area.getHeight() - 60;
widget2->w = m_area.getWidth() - 30;
widget2->h = 50;
widget2->setParent(m_irrlicht_window);
m_children.push_back(widget2);
widget2->add();
} }
// ------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------
@ -87,12 +121,27 @@ PressAKeyDialog::PressAKeyDialog(const float w, const float h) :
EnterPlayerNameDialog::EnterPlayerNameDialog(const float w, const float h) : EnterPlayerNameDialog::EnterPlayerNameDialog(const float w, const float h) :
ModalDialog(w, h) ModalDialog(w, h)
{ {
core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_area.getHeight()/2); //core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_area.getHeight()/2);
IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Enter the new player's name")).c_str(), //IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Enter the new player's name")).c_str(),
area_top, false /* border */, true /* word wrap */, // area_top, false /* border */, true /* word wrap */,
m_irrlicht_window); // m_irrlicht_window);
label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); // label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
LabelWidget* widget = new LabelWidget();
widget->m_type = WTYPE_LABEL;
widget->m_properties[PROP_TEXT] = _("Enter the new player's name");
widget->m_properties[PROP_TEXT_ALIGN] = "center";
widget->x = 0;
widget->y = 0;
widget->w = m_area.getWidth();
widget->h = m_area.getHeight()/2;
widget->setParent(m_irrlicht_window);
m_children.push_back(widget);
widget->add();
// ----
IGUIFont* font = GUIEngine::getFont(); IGUIFont* font = GUIEngine::getFont();
const int textHeight = font->getDimension(L"X").Height; const int textHeight = font->getDimension(L"X").Height;
@ -135,21 +184,37 @@ TrackInfoDialog::TrackInfoDialog(const char* trackName, ITexture* screenshot, co
area_left, false /* border */, true /* word wrap */, area_left, false /* border */, true /* word wrap */,
m_irrlicht_window); m_irrlicht_window);
// TODO : preserve aspect ratio // TODO : preserve aspect ratio
core::rect< s32 > area_right(m_area.getWidth()/2, y1, m_area.getWidth(), y2); core::rect< s32 > area_right(m_area.getWidth()/2, y1, m_area.getWidth(), y2);
IGUIImage* screenshotWidget = GUIEngine::getGUIEnv()->addImage( area_right, m_irrlicht_window ); IGUIImage* screenshotWidget = GUIEngine::getGUIEnv()->addImage( area_right, m_irrlicht_window );
screenshotWidget->setImage(screenshot); screenshotWidget->setImage(screenshot);
screenshotWidget->setScaleImage(true); screenshotWidget->setScaleImage(true);
core::rect< s32 > area_bottom(0, y2, m_area.getWidth(), m_area.getHeight());
IGUIStaticText* d = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Number of laps")).c_str(), SpinnerWidget* widget = new SpinnerWidget();
area_bottom, false /* border */, true /* word wrap */, widget->m_type = WTYPE_SPINNER;
m_irrlicht_window); widget->x = 0;
widget->y = y2;
widget->w = m_area.getWidth();
widget->h = m_area.getHeight() - y2;
widget->setParent(m_irrlicht_window);
widget->m_properties[PROP_MIN_VALUE] = "1";
widget->m_properties[PROP_MAX_VALUE] = "99";
m_children.push_back(widget);
widget->add();
widget->setValue(3);
//IGUIStaticText* d = GUIEngine::getGUIEnv()->addStaticText( stringw(_("Number of laps")).c_str(),
// area_bottom, false /* border */, true /* word wrap */,
// m_irrlicht_window);
a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); a->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
b->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); b->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
d->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); //d->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
} }
// ------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------
@ -179,3 +244,25 @@ void TrackInfoDialog::onEnterPressedInternal()
race_manager->startNew(); race_manager->startNew();
} }
PlayerInfoDialog::PlayerInfoDialog(Player* PlayerInfoDialog, const float w, const float h) : ModalDialog(w, h)
{
ButtonWidget* widget = new ButtonWidget();
widget->m_type = WTYPE_BUTTON;
widget->m_properties[PROP_TEXT] = _("Remove");
widget->x = 0;
widget->y = 0;
widget->w = m_area.getWidth();
widget->h = m_area.getHeight();
widget->setParent(m_irrlicht_window);
m_children.push_back(widget);
widget->add();
}
void PlayerInfoDialog::onEnterPressedInternal()
{
}
}

View File

@ -16,7 +16,14 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "irrlicht.h" #include "irrlicht.h"
#include "utils/ptr_vector.hpp"
class Player;
namespace GUIEngine
{
class Widget;
/** /**
* Base class, derive your own. * Base class, derive your own.
* Only once instance at a time (if you create a 2nd the first will be destroyed). * Only once instance at a time (if you create a 2nd the first will be destroyed).
@ -37,10 +44,13 @@ protected:
virtual void onEnterPressedInternal(); virtual void onEnterPressedInternal();
public: public:
ptr_vector<Widget> m_children;
virtual ~ModalDialog(); virtual ~ModalDialog();
static void dismiss(); static void dismiss();
static void onEnterPressed(); static void onEnterPressed();
static ModalDialog* getCurrent();
static bool isADialogActive(); static bool isADialogActive();
}; };
@ -74,3 +84,16 @@ public:
void onEnterPressedInternal(); void onEnterPressedInternal();
}; };
class PlayerInfoDialog : public ModalDialog
{
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
PlayerInfoDialog(Player* PlayerInfoDialog,
const float percentWidth, const float percentHeight);
void onEnterPressedInternal();
};
}

View File

@ -310,12 +310,22 @@ void Screen::elementsWereDeleted(ptr_vector<Widget>* within_vector)
Widget* Screen::getWidget(const char* name) Widget* Screen::getWidget(const char* name)
{ {
return getWidget(name, &m_widgets); return getWidget(name, NULL);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Widget* Screen::getWidget(const char* name, ptr_vector<Widget>* within_vector) Widget* Screen::getWidget(const char* name, ptr_vector<Widget>* within_vector)
{ {
if(within_vector == NULL) within_vector = &m_widgets; if(within_vector == NULL)
{
within_vector = &m_widgets;
// if a modal dialog is shown, search within it too
if(ModalDialog::isADialogActive())
{
Widget* widgetWithinDialog = getWidget(name, &(ModalDialog::getCurrent()->m_children));
if(widgetWithinDialog != NULL) return widgetWithinDialog;
}
}
const unsigned short widgets_amount = within_vector->size(); const unsigned short widgets_amount = within_vector->size();
@ -337,7 +347,18 @@ Widget* Screen::getWidget(const char* name, ptr_vector<Widget>* within_vector)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
Widget* Screen::getWidget(const int id, ptr_vector<Widget>* within_vector) Widget* Screen::getWidget(const int id, ptr_vector<Widget>* within_vector)
{ {
if(within_vector == NULL) within_vector = &m_widgets; if(within_vector == NULL)
{
within_vector = &m_widgets;
// if a modal dialog is shown, search within it too
if(ModalDialog::isADialogActive())
{
Widget* widgetWithinDialog = getWidget(id, &(ModalDialog::getCurrent()->m_children));
if(widgetWithinDialog != NULL) return widgetWithinDialog;
}
}
const unsigned short widgets_amount = within_vector->size(); const unsigned short widgets_amount = within_vector->size();
for(int n=0; n<widgets_amount; n++) for(int n=0; n<widgets_amount; n++)
@ -431,6 +452,7 @@ void Screen::processAction(const int action, const unsigned int value, Input::In
{ {
IGUIElement *el = GUIEngine::getGUIEnv()->getFocus(); IGUIElement *el = GUIEngine::getGUIEnv()->getFocus();
if(el == NULL) break; if(el == NULL) break;
Widget* w = getWidget( el->getID() ); Widget* w = getWidget( el->getID() );
if(w == NULL) break; if(w == NULL) break;

View File

@ -62,6 +62,7 @@ Widget::Widget()
m_selected = false; m_selected = false;
m_event_handler = NULL; m_event_handler = NULL;
m_show_bounding_box = false; m_show_bounding_box = false;
m_parent = NULL;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** /**
@ -231,6 +232,11 @@ void Widget::readCoords(Widget* parent)
} }
void Widget::setParent(IGUIElement* parent)
{
m_parent = parent;
}
#if 0 #if 0
#pragma mark - #pragma mark -
#pragma mark Button Widget #pragma mark Button Widget
@ -240,7 +246,7 @@ void ButtonWidget::add()
{ {
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h); rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
stringw message = m_properties[PROP_TEXT].c_str(); stringw message = m_properties[PROP_TEXT].c_str();
m_element = GUIEngine::getGUIEnv()->addButton(widget_size, NULL, ++id_counter, message.c_str(), L""); m_element = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, message.c_str(), L"");
id = m_element->getID(); id = m_element->getID();
m_element->setTabOrder(id); m_element->setTabOrder(id);
@ -267,7 +273,7 @@ void LabelWidget::add()
else if(m_properties[PROP_TEXT_ALIGN] == "right") align = EGUIA_LOWERRIGHT; else if(m_properties[PROP_TEXT_ALIGN] == "right") align = EGUIA_LOWERRIGHT;
EGUI_ALIGNMENT valign = EGUIA_CENTER ; // TODO - make confiurable through XML file? EGUI_ALIGNMENT valign = EGUIA_CENTER ; // TODO - make confiurable through XML file?
IGUIStaticText* irrwidget = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, word_wrap, NULL, -1); IGUIStaticText* irrwidget = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, word_wrap, m_parent, -1);
m_element = irrwidget; m_element = irrwidget;
irrwidget->setTextAlignment( align, valign ); irrwidget->setTextAlignment( align, valign );
@ -294,7 +300,7 @@ void CheckBoxWidget::add()
stringw message = m_properties[PROP_TEXT].c_str(); stringw message = m_properties[PROP_TEXT].c_str();
//m_element = GUIEngine::getGUIEnv()->addCheckBox(true /* checked */, widget_size, NULL, ++id_counter, message.c_str()); //m_element = GUIEngine::getGUIEnv()->addCheckBox(true /* checked */, widget_size, NULL, ++id_counter, message.c_str());
m_element = GUIEngine::getGUIEnv()->addButton(widget_size, NULL, ++id_counter, L""); m_element = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, L"");
id = m_element->getID(); id = m_element->getID();
m_element->setTabOrder(id); m_element->setTabOrder(id);
m_element->setTabGroup(false); m_element->setTabGroup(false);
@ -334,7 +340,7 @@ void IconButtonWidget::add()
if(clickable) if(clickable)
{ {
widget_size = rect<s32>(x, y, x + w, y + h); widget_size = rect<s32>(x, y, x + w, y + h);
IGUIButton* btn = GUIEngine::getGUIEnv()->addButton(widget_size, NULL, ++id_counter, L""); IGUIButton* btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, L"");
m_element = btn; m_element = btn;
btn->setUseAlphaChannel(true); btn->setUseAlphaChannel(true);
btn->setImage(texture); btn->setImage(texture);
@ -349,7 +355,7 @@ void IconButtonWidget::add()
widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h); widget_size = rect<s32>(x + x_gap/2, y, x + w - x_gap/2, y + h);
IGUIImage* btn = GUIEngine::getGUIEnv()->addImage(widget_size, NULL, ++id_counter_2); IGUIImage* btn = GUIEngine::getGUIEnv()->addImage(widget_size, m_parent, ++id_counter_2);
m_element = btn; m_element = btn;
btn->setUseAlphaChannel(true); btn->setUseAlphaChannel(true);
btn->setImage(texture); btn->setImage(texture);
@ -361,7 +367,7 @@ void IconButtonWidget::add()
if(message.size() > 0) if(message.size() > 0)
{ {
widget_size += position2d<s32>(0, widget_size.getHeight()); widget_size += position2d<s32>(0, widget_size.getHeight());
label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size); label = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size, false, false /* word wrap */, m_parent);
label->setTextAlignment(EGUIA_CENTER, EGUIA_UPPERLEFT); label->setTextAlignment(EGUIA_CENTER, EGUIA_UPPERLEFT);
label->setTabStop(false); label->setTabStop(false);
} }
@ -393,12 +399,8 @@ void IconButtonWidget::add()
void IconButtonWidget::setLabel(std::string new_label) void IconButtonWidget::setLabel(std::string new_label)
{ {
std::cout << "trying to set label " << new_label.c_str() << std::endl;
if(label == NULL) return; if(label == NULL) return;
std::cout << "set label " << new_label.c_str() << std::endl;
label->setText( stringw(new_label.c_str()).c_str() ); label->setText( stringw(new_label.c_str()).c_str() );
} }
@ -529,7 +531,7 @@ void RibbonWidget::add()
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h); rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, NULL, ++id_counter, L""); IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, L"");
m_element = btn; m_element = btn;
const int subbuttons_amount = m_children.size(); const int subbuttons_amount = m_children.size();
@ -733,7 +735,7 @@ void SpinnerWidget::add()
} }
rect<s32> widget_size = rect<s32>(x, y, x + w, y + h); rect<s32> widget_size = rect<s32>(x, y, x + w, y + h);
IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, NULL, ++id_counter, L""); IGUIButton * btn = GUIEngine::getGUIEnv()->addButton(widget_size, m_parent, ++id_counter, L"");
m_element = btn; m_element = btn;
// left arrow // left arrow

View File

@ -86,12 +86,6 @@ namespace GUIEngine
*/ */
bool m_selected; bool m_selected;
/**
* Create and add the irrLicht widget(s) associated with this object.
* Call after Widget was read from XML file and laid out.
*/
virtual void add() {}
/** /**
* called when left/right keys pressed and focus is on widget. * called when left/right keys pressed and focus is on widget.
* Returns 'true' if main event handler should be notified of a change. * Returns 'true' if main event handler should be notified of a change.
@ -124,6 +118,8 @@ namespace GUIEngine
*/ */
Widget* m_event_handler; Widget* m_event_handler;
IGUIElement* m_parent;
static bool convertToCoord(std::string& x, int* absolute, int* percentage); static bool convertToCoord(std::string& x, int* absolute, int* percentage);
public: public:
Widget(); Widget();
@ -131,6 +127,14 @@ namespace GUIEngine
bool m_show_bounding_box; bool m_show_bounding_box;
/**
* Create and add the irrLicht widget(s) associated with this object.
* Call after Widget was read from XML file and laid out.
*/
virtual void add() {}
void setParent(IGUIElement* parent);
/** /**
* If this widget has any children, they go here. Children can be either * If this widget has any children, they go here. Children can be either
* specified in the XML file (e.g. Ribbon or Div children), or can also * specified in the XML file (e.g. Ribbon or Div children), or can also
@ -168,27 +172,29 @@ namespace GUIEngine
class ButtonWidget : public Widget class ButtonWidget : public Widget
{ {
void add();
public: public:
void add();
virtual ~ButtonWidget() {} virtual ~ButtonWidget() {}
void setLabel(const char* label); void setLabel(const char* label);
}; };
class LabelWidget : public Widget class LabelWidget : public Widget
{ {
void add();
public: public:
void add();
virtual ~LabelWidget() {} virtual ~LabelWidget() {}
}; };
class CheckBoxWidget : public Widget class CheckBoxWidget : public Widget
{ {
void add();
bool m_state; bool m_state;
bool transmitEvent(Widget* w, std::string& originator); bool transmitEvent(Widget* w, std::string& originator);
public: public:
CheckBoxWidget(); CheckBoxWidget();
virtual ~CheckBoxWidget() {} virtual ~CheckBoxWidget() {}
void add();
bool getState() const { return m_state; } bool getState() const { return m_state; }
void setState(const bool enabled) { m_state = enabled; } void setState(const bool enabled) { m_state = enabled; }
}; };
@ -204,14 +210,14 @@ namespace GUIEngine
bool transmitEvent(Widget* w, std::string& originator); bool transmitEvent(Widget* w, std::string& originator);
bool rightPressed(); bool rightPressed();
bool leftPressed(); bool leftPressed();
void add();
public: public:
SpinnerWidget(const bool gauge=false); SpinnerWidget(const bool gauge=false);
virtual ~SpinnerWidget() {} virtual ~SpinnerWidget() {}
void setValue(const int new_value); void setValue(const int new_value);
void addLabel(std::string label); void addLabel(std::string label);
void add();
bool isGauge() const { return m_gauge; } bool isGauge() const { return m_gauge; }
int getValue() const { return m_value; } int getValue() const { return m_value; }
int getMax() const { return m_max; } int getMax() const { return m_max; }
@ -221,11 +227,12 @@ namespace GUIEngine
class IconButtonWidget : public Widget class IconButtonWidget : public Widget
{ {
bool clickable; bool clickable;
void add();
IGUIStaticText* label; IGUIStaticText* label;
public: public:
virtual ~IconButtonWidget() {}
IconButtonWidget(const bool clickable=true); IconButtonWidget(const bool clickable=true);
virtual ~IconButtonWidget() {}
void add();
void setLabel(std::string new_label); void setLabel(std::string new_label);
}; };

View File

@ -198,7 +198,7 @@ void InputManager::input(Input::InputType type, int deviceID, int btnID, int axi
else if(btnID == KEY_RIGHT) action = PA_RIGHT; else if(btnID == KEY_RIGHT) action = PA_RIGHT;
else if(btnID == KEY_SPACE) action = PA_FIRE; else if(btnID == KEY_SPACE) action = PA_FIRE;
if(btnID == KEY_RETURN && ModalDialog::isADialogActive()) ModalDialog::onEnterPressed(); if(btnID == KEY_RETURN && GUIEngine::ModalDialog::isADialogActive()) GUIEngine::ModalDialog::onEnterPressed();
if(action != PA_FIRST) if(action != PA_FIRST)
{ {