Extracted the new common base for Screen and ModalDialog out of the temporary location where it was put in previous commit

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5747 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2010-08-16 00:46:17 +00:00
parent 021dea1829
commit 4e48bbd66b
7 changed files with 23 additions and 259 deletions

View File

@ -81,6 +81,8 @@ supertuxkart_SOURCES = \
guiengine/CGUISpriteBank.h \
guiengine/abstract_state_manager.cpp \
guiengine/abstract_state_manager.hpp \
guiengine/abstract_top_level_container.cpp \
guiengine/abstract_top_level_container.hpp \
guiengine/engine.cpp \
guiengine/engine.hpp \
guiengine/event_handler.cpp \

View File

@ -16,6 +16,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/irr_driver.hpp"
#include "guiengine/abstract_top_level_container.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/layout_manager.hpp"
#include "guiengine/scalable_font.hpp"
@ -34,198 +35,6 @@ using namespace video;
using namespace io;
using namespace gui;
void ITopLevelWidgetContainer::addWidgetsRecursively(ptr_vector<Widget>& widgets, Widget* parent)
{
const unsigned short widgets_amount = widgets.size();
// ------- add widgets
for (int n=0; n<widgets_amount; n++)
{
if (widgets[n].getType() == WTYPE_DIV)
{
widgets[n].add(); // Will do nothing, but will maybe reserve an ID
addWidgetsRecursively(widgets[n].m_children, &widgets[n]);
}
else
{
// warn if widget has no dimensions (except for ribbons and icons, where it is normal since it
// adjusts to its contents)
if ((widgets[n].m_w < 1 || widgets[n].m_h < 1) &&
widgets[n].getType() != WTYPE_RIBBON &&
widgets[n].getType() != WTYPE_ICON_BUTTON)
{
std::cerr << "/!\\ Warning /!\\ : widget " << widgets[n].m_properties[PROP_ID].c_str() << " has no dimensions" << std::endl;
}
if (widgets[n].m_x == -1 || widgets[n].m_y == -1)
{
std::cerr << "/!\\ Warning /!\\ : widget " << widgets[n].m_properties[PROP_ID].c_str() << " has no position" << std::endl;
}
widgets[n].add();
}
} // next widget
} // addWidgetsRecursively
// ----------------------------------------------------------------------------
bool isMyChildHelperFunc(const ptr_vector<Widget>* within, const Widget* widget)
{
if (within->size() == 0) return false;
if (within->contains(widget))
{
return true;
}
const int count = within->size();
for (int n=0; n<count; n++)
{
if (isMyChildHelperFunc(&within->getConst(n)->getChildren(), widget))
{
return true;
}
}
return false;
}
bool ITopLevelWidgetContainer::isMyChild(Widget* widget) const
{
return isMyChildHelperFunc(&m_widgets, widget);
}
Widget* ITopLevelWidgetContainer::getWidget(const char* name)
{
return getWidget(name, &m_widgets);
} // getWidget
// -----------------------------------------------------------------------------
Widget* ITopLevelWidgetContainer::getWidget(const int id)
{
return getWidget(id, &m_widgets);
} // getWidget
// -----------------------------------------------------------------------------
Widget* ITopLevelWidgetContainer::getWidget(const char* name, ptr_vector<Widget>* within_vector)
{
const unsigned short widgets_amount = within_vector->size();
for(int n=0; n<widgets_amount; n++)
{
Widget& widget = (*within_vector)[n];
if (widget.m_properties[PROP_ID] == name) return &widget;
if (widget.searchInsideMe() && widget.m_children.size() > 0)
{
Widget* el = getWidget(name, &(widget.m_children));
if(el != NULL) return el;
}
} // next
return NULL;
} // getWidget
// -----------------------------------------------------------------------------
Widget* ITopLevelWidgetContainer::getWidget(const int id, ptr_vector<Widget>* within_vector)
{
const unsigned short widgets_amount = within_vector->size();
for (int n=0; n<widgets_amount; n++)
{
Widget& widget = (*within_vector)[n];
if (widget.m_element != NULL && widget.getIrrlichtElement()->getID() == id) return &widget;
if (widget.searchInsideMe() && widget.getChildren().size() > 0)
{
// std::cout << "widget = <" << widget.m_properties[PROP_ID].c_str()
// << "> widget.m_children.size()=" << widget.m_children.size() << std::endl;
Widget* el = getWidget(id, &(widget.m_children));
if(el != NULL) return el;
}
} // next
return NULL;
} // getWidget
// -----------------------------------------------------------------------------
Widget* ITopLevelWidgetContainer::getFirstWidget(ptr_vector<Widget>* within_vector)
{
if (m_first_widget != NULL) return m_first_widget;
if (within_vector == NULL) within_vector = &m_widgets;
for (int i = 0; i < within_vector->size(); i++)
{
if (!within_vector->get(i)->m_focusable) continue;
// if container, also checks children (FIXME: don't hardcode which types to avoid descending into)
if (within_vector->get(i)->m_children.size() > 0 &&
within_vector->get(i)->getType() != WTYPE_RIBBON &&
within_vector->get(i)->getType() != WTYPE_SPINNER)
{
Widget* w = getFirstWidget(&within_vector->get(i)->m_children);
if (w != NULL) return w;
}
Widget* item = within_vector->get(i);
if (item->getIrrlichtElement() == NULL ||
item->getIrrlichtElement()->getTabOrder() == -1 ||
item->getIrrlichtElement()->getTabOrder() >= 1000 /* non-tabbing items are given such IDs */ ||
!item->m_focusable)
{
continue;
}
return item;
}
return NULL;
} // getFirstWidget
// -----------------------------------------------------------------------------
Widget* ITopLevelWidgetContainer::getLastWidget(ptr_vector<Widget>* within_vector)
{
if (m_last_widget != NULL) return m_last_widget;
if (within_vector == NULL) within_vector = &m_widgets;
for (int i = within_vector->size()-1; i >= 0; i--)
{
if (!within_vector->get(i)->m_focusable) continue;
// if container, also checks children
if (within_vector->get(i)->getChildren().size() > 0 &&
within_vector->get(i)->getType() != WTYPE_RIBBON &&
within_vector->get(i)->getType() != WTYPE_SPINNER)
{
Widget* w = getLastWidget(&within_vector->get(i)->m_children);
if (w != NULL) return w;
}
Widget* item = within_vector->get(i);
if (item->getIrrlichtElement() == NULL ||
item->getIrrlichtElement()->getTabOrder() == -1 ||
item->getIrrlichtElement()->getTabOrder() >= 1000 /* non-tabbing items are given such IDs */ ||
!item->m_focusable)
{
continue;
}
return item;
}
return NULL;
} // getLastWidget
// ----------------------------------------------------------------------------
@ -253,7 +62,7 @@ bool LayoutManager::convertToCoord(std::string& x, int* absolute /* out */, int*
// ----------------------------------------------------------------------------
void LayoutManager::readCoords(Widget* self, ITopLevelWidgetContainer* topLevelContainer, Widget* parent)
void LayoutManager::readCoords(Widget* self, AbstractTopLevelContainer* topLevelContainer, Widget* parent)
{
// determine widget position and size if not already done by sizers
std::string x = self->m_properties[PROP_X];
@ -400,7 +209,7 @@ void LayoutManager::readCoords(Widget* self, ITopLevelWidgetContainer* topLevelC
// ----------------------------------------------------------------------------
void LayoutManager::calculateLayout(ptr_vector<Widget>& widgets, ITopLevelWidgetContainer* topLevelContainer,
void LayoutManager::calculateLayout(ptr_vector<Widget>& widgets, AbstractTopLevelContainer* topLevelContainer,
Widget* parent)
{
const unsigned short widgets_amount = widgets.size();

View File

@ -26,62 +26,7 @@
namespace GUIEngine
{
class Widget;
class ITopLevelWidgetContainer
{
protected:
/** the widgets in this screen */
ptr_vector<Widget, HOLD> m_widgets;
/**
* Screen is generally able to determine its first widget just fine, but in highly complex screens
* (e.g. multiplayer kart selection) you can help it by providing the first widget manually.
*/
Widget* m_first_widget;
/**
* Screen is generally able to determine its last widget just fine, but in highly complex screens
* (e.g. multiplayer kart selection) you can help it by providing the first widget manually.
*/
Widget* m_last_widget;
void addWidgetsRecursively(ptr_vector<Widget>& widgets, Widget* parent=NULL);
public:
virtual ~ITopLevelWidgetContainer() {}
virtual int getWidth() = 0;
virtual int getHeight() = 0;
/** \return an object by name, or NULL if not found */
Widget* getWidget(const char* name);
/** \return an object by irrlicht ID, or NULL if not found */
Widget* getWidget(const int id);
/** \return an object by name, casted to specified type, or NULL if not found/wrong type */
template <typename T> T* getWidget(const char* name)
{
Widget* out = getWidget(name);
T* outCasted = dynamic_cast<T*>( out );
if (out != NULL && outCasted == NULL)
{
fprintf(stderr, "Screen::getWidget : Widget '%s' of type '%s' cannot be casted to "
"requested type '%s'!\n", name, typeid(*out).name(), typeid(T).name());
abort();
}
return outCasted;
}
static Widget* getWidget(const char* name, ptr_vector<Widget>* within_vector);
static Widget* getWidget(const int id, ptr_vector<Widget>* within_vector);
Widget* getFirstWidget(ptr_vector<Widget>* within_vector=NULL);
Widget* getLastWidget(ptr_vector<Widget>* within_vector=NULL);
bool isMyChild(Widget* widget) const;
};
class AbstractTopLevelContainer;
class LayoutManager
{
@ -101,7 +46,7 @@ namespace GUIEngine
* \brief Find a widget's x, y, w and h coords from what is specified in the XML properties.
* Most notably, expands coords relative to parent and percentages.
*/
static void readCoords(Widget* self, ITopLevelWidgetContainer* topLevelContainer, Widget* parent);
static void readCoords(Widget* self, AbstractTopLevelContainer* topLevelContainer, Widget* parent);
/**
* \brief Recursive call that lays out children widget within parent (or screen if none).
@ -109,7 +54,7 @@ namespace GUIEngine
* Manages 'horizontal-row' and 'vertical-row' layouts, along with the proportions
* of the remaining children, as well as absolute sizes and locations.
*/
static void calculateLayout(ptr_vector<Widget>& widgets, ITopLevelWidgetContainer* topLevelContainer,
static void calculateLayout(ptr_vector<Widget>& widgets, AbstractTopLevelContainer* topLevelContainer,
Widget* parent=NULL);
};

View File

@ -20,6 +20,7 @@
#include "irrlicht.h"
#include "utils/ptr_vector.hpp"
#include "guiengine/abstract_top_level_container.hpp"
#include "guiengine/event_handler.hpp"
#include "guiengine/layout_manager.hpp"
#include "guiengine/skin.hpp"
@ -43,7 +44,7 @@ namespace GUIEngine
* need to keep track of instances yourself)
* \ingroup guiengine
*/
class ModalDialog : public SkinWidgetContainer, public ITopLevelWidgetContainer
class ModalDialog : public SkinWidgetContainer, public AbstractTopLevelContainer
{
private:
/** Because C++ doesn't support constructor delegation... */
@ -93,12 +94,12 @@ namespace GUIEngine
virtual void onUpdate(float dt) { }
/**
* \brief Implementing callback from ITopLevelWidgetContainer
* \brief Implementing callback from AbstractTopLevelContainer
*/
virtual int getWidth() { return m_area.getWidth(); }
/**
* \brief Implementing callback from ITopLevelWidgetContainer
* \brief Implementing callback from AbstractTopLevelContainer
*/
virtual int getHeight() { return m_area.getHeight(); }

View File

@ -26,6 +26,7 @@
#include "irrlicht.h"
#include "config/stk_config.hpp"
#include "guiengine/abstract_top_level_container.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/layout_manager.hpp"
#include "guiengine/widget.hpp"
@ -81,7 +82,7 @@ namespace GUIEngine
*
* \ingroup guiengine
*/
class Screen : public ITopLevelWidgetContainer
class Screen : public AbstractTopLevelContainer
{
private:
/** True if the race (if it is running) should be paused when this
@ -250,11 +251,11 @@ namespace GUIEngine
virtual MusicInformation* getMusic() const { return stk_config->m_title_music; }
/**
* \brief Implementing method from ITopLevelWidgetContainer
* \brief Implementing method from AbstractTopLevelContainer
*/
virtual int getWidth();
/**
* \brief Implementing method from ITopLevelWidgetContainer
* \brief Implementing method from AbstractTopLevelContainer
*/
virtual int getHeight();
};

View File

@ -125,7 +125,7 @@ namespace GUIEngine
friend class DynamicRibbonWidget;
friend class LayoutManager;
friend class ModalDialog;
friend class ITopLevelWidgetContainer;
friend class AbstractTopLevelContainer;
/** When true, this widget shall use a bigger and more colourful font */
bool m_title_font;

View File

@ -240,6 +240,7 @@
955DE88310042701006A4F3C /* check_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955DE88110042701006A4F3C /* check_manager.cpp */; };
955DE88C1004273B006A4F3C /* check_structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 955DE8871004273B006A4F3C /* check_structure.cpp */; };
9560368C12187EFB00EB96C4 /* layout_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9560368A12187EFB00EB96C4 /* layout_manager.cpp */; };
956039BA1218C09E00EB96C4 /* abstract_top_level_container.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 956039B81218C09E00EB96C4 /* abstract_top_level_container.cpp */; };
95634EF21126272C009C145D /* gp_info_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95634EF01126272C009C145D /* gp_info_dialog.cpp */; };
956541BB10DD5F0A00C83E99 /* arenas_screen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 956541B910DD5F0A00C83E99 /* arenas_screen.cpp */; };
956541E110DD628C00C83E99 /* add_device_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 956541DF10DD628C00C83E99 /* add_device_dialog.cpp */; };
@ -451,6 +452,8 @@
955DE8881004273B006A4F3C /* check_structure.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = check_structure.hpp; path = ../../tracks/check_structure.hpp; sourceTree = SOURCE_ROOT; };
9560368A12187EFB00EB96C4 /* layout_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = layout_manager.cpp; path = ../../guiengine/layout_manager.cpp; sourceTree = SOURCE_ROOT; };
9560368B12187EFB00EB96C4 /* layout_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = layout_manager.hpp; path = ../../guiengine/layout_manager.hpp; sourceTree = SOURCE_ROOT; };
956039B81218C09E00EB96C4 /* abstract_top_level_container.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = abstract_top_level_container.cpp; path = ../../guiengine/abstract_top_level_container.cpp; sourceTree = SOURCE_ROOT; };
956039B91218C09E00EB96C4 /* abstract_top_level_container.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = abstract_top_level_container.hpp; path = ../../guiengine/abstract_top_level_container.hpp; sourceTree = SOURCE_ROOT; };
95634EF01126272C009C145D /* gp_info_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gp_info_dialog.cpp; path = ../../states_screens/dialogs/gp_info_dialog.cpp; sourceTree = SOURCE_ROOT; };
95634EF11126272C009C145D /* gp_info_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = gp_info_dialog.hpp; path = ../../states_screens/dialogs/gp_info_dialog.hpp; sourceTree = SOURCE_ROOT; };
956541B910DD5F0A00C83E99 /* arenas_screen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arenas_screen.cpp; path = ../../states_screens/arenas_screen.cpp; sourceTree = SOURCE_ROOT; };
@ -1287,6 +1290,8 @@
950D448B118DEE3C006CFC41 /* CGUISpriteBank.h */,
9583319810123B0200C5137E /* abstract_state_manager.cpp */,
9583319710123B0200C5137E /* abstract_state_manager.hpp */,
956039B81218C09E00EB96C4 /* abstract_top_level_container.cpp */,
956039B91218C09E00EB96C4 /* abstract_top_level_container.hpp */,
958330B210122B4A00C5137E /* engine.cpp */,
958330B310122B4A00C5137E /* engine.hpp */,
958330B410122B4A00C5137E /* event_handler.cpp */,
@ -2632,6 +2637,7 @@
9554C4A611F1188000906416 /* race_result_gui.cpp in Sources */,
953F8B2111F7C13C00205E66 /* scalable_font.cpp in Sources */,
9560368C12187EFB00EB96C4 /* layout_manager.cpp in Sources */,
956039BA1218C09E00EB96C4 /* abstract_top_level_container.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};