2009-04-18 19:00:33 +02:00
|
|
|
/* Copyright (C) 2009 Wildfire Games.
|
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2003-11-06 01:21:45 +01:00
|
|
|
/*
|
|
|
|
GUI util
|
|
|
|
|
|
|
|
--Overview--
|
|
|
|
|
|
|
|
Contains help class GUI<>, which gives us templated
|
|
|
|
parameter to all functions within GUI.
|
|
|
|
|
|
|
|
--More info--
|
|
|
|
|
2003-11-25 03:47:12 +01:00
|
|
|
Check GUI.h
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2007-05-07 18:33:24 +02:00
|
|
|
#ifndef INCLUDED_GUIUTIL
|
|
|
|
#define INCLUDED_GUIUTIL
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
// Includes / Compiler directives
|
|
|
|
//--------------------------------------------------------
|
2004-12-19 00:30:28 +01:00
|
|
|
#include "GUIbase.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/Parser.h"
|
2004-05-29 06:06:50 +02:00
|
|
|
// TODO Gee: New
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/Overlay.h"
|
2006-01-29 19:23:47 +01:00
|
|
|
#include "CGUI.h"
|
|
|
|
#include "CGUISprite.h"
|
|
|
|
#include "IGUIObject.h"
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-24 18:13:37 +01:00
|
|
|
//--------------------------------------------------------
|
|
|
|
// Help Classes/Structs for the GUI
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
2004-05-29 06:06:50 +02:00
|
|
|
class CClientArea;
|
|
|
|
class CGUIString;
|
2012-01-29 21:04:21 +01:00
|
|
|
class CMatrix3D;
|
2003-11-24 18:13:37 +01:00
|
|
|
|
2004-05-29 06:06:50 +02:00
|
|
|
template <typename T>
|
2010-05-30 15:11:32 +02:00
|
|
|
bool __ParseString(const CStrW& Value, T &tOutput);
|
2004-05-29 06:06:50 +02:00
|
|
|
|
2012-02-08 21:43:38 +01:00
|
|
|
// Model-view-projection matrix with (0,0) in top-left of screen
|
2012-01-29 21:04:21 +01:00
|
|
|
CMatrix3D GetDefaultGuiMatrix();
|
2004-09-02 05:02:32 +02:00
|
|
|
|
2003-11-06 01:21:45 +01:00
|
|
|
//--------------------------------------------------------
|
|
|
|
// Forward declarations
|
|
|
|
//--------------------------------------------------------
|
2004-12-15 22:24:46 +01:00
|
|
|
struct SGUIMessage;
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Base class to only the class GUI. This superclass is
|
|
|
|
* kind of a templateless extention of the class GUI.
|
|
|
|
* Used for other functions to friend with, because it
|
2004-10-14 12:09:26 +02:00
|
|
|
* can't friend with GUI since it's templated (at least
|
2003-12-27 08:23:47 +01:00
|
|
|
* not on all compilers we're using).
|
2003-11-18 11:00:57 +01:00
|
|
|
*/
|
2003-11-06 01:21:45 +01:00
|
|
|
class CInternalCGUIAccessorBase
|
|
|
|
{
|
|
|
|
protected:
|
2003-11-18 11:00:57 +01:00
|
|
|
/// Get object pointer
|
2004-06-18 16:07:06 +02:00
|
|
|
static IGUIObject * GetObjectPointer(CGUI &GUIinstance, const CStr& Object);
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/// const version
|
2004-06-18 16:07:06 +02:00
|
|
|
static const IGUIObject * GetObjectPointer(const CGUI &GUIinstance, const CStr& Object);
|
2003-11-25 04:21:11 +01:00
|
|
|
|
|
|
|
/// Wrapper for ResetStates
|
|
|
|
static void QueryResetting(IGUIObject *pObject);
|
2003-12-27 08:23:47 +01:00
|
|
|
|
2011-04-28 22:42:11 +02:00
|
|
|
static void HandleMessage(IGUIObject *pObject, SGUIMessage &message);
|
2003-11-06 01:21:45 +01:00
|
|
|
};
|
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
|
2004-12-09 17:09:58 +01:00
|
|
|
#ifndef NDEBUG
|
2004-09-03 23:25:39 +02:00
|
|
|
// Used to ensure type-safety, sort of
|
|
|
|
template<typename T> void CheckType(const IGUIObject* obj, const CStr& setting);
|
2004-12-09 17:09:58 +01:00
|
|
|
#endif
|
2004-09-03 23:25:39 +02:00
|
|
|
|
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Includes static functions that needs one template
|
|
|
|
* argument.
|
|
|
|
*
|
|
|
|
* int is only to please functions that doesn't even use T
|
|
|
|
* and are only within this class because it's convenient
|
|
|
|
*/
|
2003-11-06 01:21:45 +01:00
|
|
|
template <typename T=int>
|
|
|
|
class GUI : public CInternalCGUIAccessorBase
|
|
|
|
{
|
|
|
|
// Private functions further ahead
|
|
|
|
friend class CGUI;
|
2003-11-24 03:18:41 +01:00
|
|
|
friend class IGUIObject;
|
2003-11-25 04:21:11 +01:00
|
|
|
friend class CInternalCGUIAccessorBase;
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
public:
|
2004-12-17 01:05:37 +01:00
|
|
|
|
|
|
|
// Like GetSetting (below), but doesn't make a copy of the value
|
|
|
|
// (so it can be modified later)
|
2009-09-27 17:04:46 +02:00
|
|
|
static PSRETURN GetSettingPointer(const IGUIObject *pObject, const CStr& Setting, T* &Value);
|
2004-12-17 01:05:37 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Retrieves a setting by name from object pointer
|
|
|
|
*
|
|
|
|
* @param pObject Object pointer
|
|
|
|
* @param Setting Setting by name
|
|
|
|
* @param Value Stores value here, note type T!
|
|
|
|
*/
|
2009-09-27 17:04:46 +02:00
|
|
|
static PSRETURN GetSetting(const IGUIObject *pObject, const CStr& Setting, T &Value);
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
2003-11-25 03:47:12 +01:00
|
|
|
* Sets a value by name using a real datatype as input.
|
|
|
|
*
|
|
|
|
* This is the official way of setting a setting, no other
|
2004-12-15 22:24:46 +01:00
|
|
|
* way should only cautiously be used!
|
2003-11-18 11:00:57 +01:00
|
|
|
*
|
|
|
|
* @param pObject Object pointer
|
|
|
|
* @param Setting Setting by name
|
|
|
|
* @param Value Sets value to this, note type T!
|
2005-02-05 08:25:16 +01:00
|
|
|
* @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
|
2003-11-18 11:00:57 +01:00
|
|
|
*/
|
2009-09-27 17:04:46 +02:00
|
|
|
static PSRETURN SetSetting(IGUIObject *pObject, const CStr& Setting,
|
2005-02-05 08:25:16 +01:00
|
|
|
const T &Value, const bool &SkipMessage=false);
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Retrieves a setting by settings name and object name
|
|
|
|
*
|
2010-07-29 17:55:41 +02:00
|
|
|
* @param GUIinstance GUI Object const ref
|
2003-11-18 11:00:57 +01:00
|
|
|
* @param Object Object name
|
|
|
|
* @param Setting Setting by name
|
|
|
|
* @param Value Stores value here, note type T!
|
|
|
|
*/
|
2009-09-27 17:04:46 +02:00
|
|
|
static PSRETURN GetSetting(
|
2004-06-18 16:07:06 +02:00
|
|
|
const CGUI &GUIinstance, const CStr& Object,
|
|
|
|
const CStr& Setting, T &Value)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
|
|
|
if (!GUIinstance.ObjectExists(Object))
|
2009-09-27 17:04:46 +02:00
|
|
|
return PSRETURN_GUI_NullObjectProvided;
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
// Retrieve pointer and call sibling function
|
2003-11-24 03:18:41 +01:00
|
|
|
const IGUIObject *pObject = GetObjectPointer(GUIinstance, Object);
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
return GetSetting(pObject, Setting, Value);
|
|
|
|
}
|
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Sets a value by setting and object name using a real
|
|
|
|
* datatype as input
|
|
|
|
*
|
2003-11-25 03:47:12 +01:00
|
|
|
* This is just a wrapper so that we can type the object name
|
|
|
|
* and not input the actual pointer.
|
|
|
|
*
|
2010-07-29 17:55:41 +02:00
|
|
|
* @param GUIinstance GUI Object, reference since we'll be changing values
|
2003-11-18 11:00:57 +01:00
|
|
|
* @param Object Object name
|
|
|
|
* @param Setting Setting by name
|
|
|
|
* @param Value Sets value to this, note type T!
|
2010-07-29 17:55:41 +02:00
|
|
|
* @param SkipMessage Does not send a GUIM_SETTINGS_UPDATED if true
|
2003-11-18 11:00:57 +01:00
|
|
|
*/
|
2009-09-27 17:04:46 +02:00
|
|
|
static PSRETURN SetSetting(
|
2004-06-18 16:07:06 +02:00
|
|
|
CGUI &GUIinstance, const CStr& Object,
|
2005-02-05 08:25:16 +01:00
|
|
|
const CStr& Setting, const T &Value,
|
|
|
|
const bool& SkipMessage=false)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
|
|
|
if (!GUIinstance.ObjectExists(Object))
|
2009-09-27 17:04:46 +02:00
|
|
|
return PSRETURN_GUI_NullObjectProvided;
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
// Retrieve pointer and call sibling function
|
|
|
|
|
|
|
|
// Important, we don't want to use this T, we want
|
|
|
|
// to use the standard T, since that will be the
|
|
|
|
// one with the friend relationship
|
2003-11-24 03:18:41 +01:00
|
|
|
IGUIObject *pObject = GetObjectPointer(GUIinstance, Object);
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2005-02-05 08:25:16 +01:00
|
|
|
return SetSetting(pObject, Setting, Value, SkipMessage);
|
2003-11-06 01:21:45 +01:00
|
|
|
}
|
2004-05-29 06:06:50 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This will return the value of the first sprite if it's not null,
|
|
|
|
* if it is null, it will return the value of the second sprite, if
|
|
|
|
* that one is null, then null it is.
|
|
|
|
*
|
|
|
|
* @param prim Primary sprite that should be used
|
|
|
|
* @param sec Secondary sprite if Primary should fail
|
|
|
|
* @return Resulting string
|
|
|
|
*/
|
2009-07-28 18:59:19 +02:00
|
|
|
static const CGUISpriteInstance& FallBackSprite(
|
|
|
|
const CGUISpriteInstance& prim,
|
|
|
|
const CGUISpriteInstance& sec)
|
2004-05-29 06:06:50 +02:00
|
|
|
{
|
2004-12-15 22:24:46 +01:00
|
|
|
return (prim.IsEmpty() ? sec : prim);
|
2004-05-29 06:06:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Same principle as FallBackSprite
|
|
|
|
*
|
|
|
|
* @param prim Primary color that should be used
|
|
|
|
* @param sec Secondary color if Primary should fail
|
|
|
|
* @return Resulting color
|
|
|
|
* @see FallBackSprite
|
|
|
|
*/
|
|
|
|
static CColor FallBackColor(const CColor &prim, const CColor &sec)
|
|
|
|
{
|
|
|
|
// CColor() == null.
|
|
|
|
return ((prim!=CColor())?(prim):(sec));
|
|
|
|
}
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-12-01 08:06:55 +01:00
|
|
|
/**
|
|
|
|
* Sets a value by setting and object name using a real
|
|
|
|
* datatype as input.
|
|
|
|
*
|
2010-01-27 20:20:34 +01:00
|
|
|
* This is just a wrapper for __ParseString() which really
|
2003-12-01 08:06:55 +01:00
|
|
|
* works the magic.
|
|
|
|
*
|
|
|
|
* @param Value The value in string form, like "0 0 100% 100%"
|
|
|
|
* @param tOutput Parsed value of type T
|
|
|
|
* @return True at success.
|
|
|
|
*
|
2010-01-27 20:20:34 +01:00
|
|
|
* @see __ParseString()
|
2003-12-01 08:06:55 +01:00
|
|
|
*/
|
2010-05-30 15:11:32 +02:00
|
|
|
static bool ParseString(const CStrW& Value, T &tOutput)
|
2003-12-01 08:06:55 +01:00
|
|
|
{
|
2004-05-29 06:06:50 +02:00
|
|
|
return __ParseString<T>(Value, tOutput);
|
2003-12-01 08:06:55 +01:00
|
|
|
}
|
|
|
|
|
2010-05-30 15:11:32 +02:00
|
|
|
static bool ParseColor(const CStrW& Value, CColor &tOutput, float DefaultAlpha);
|
2005-01-03 23:23:27 +01:00
|
|
|
|
2003-12-01 08:06:55 +01:00
|
|
|
private:
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
// templated typedef of function pointer
|
2003-11-24 03:18:41 +01:00
|
|
|
typedef void (IGUIObject::*void_Object_pFunction_argT)(const T &arg);
|
|
|
|
typedef void (IGUIObject::*void_Object_pFunction_argRefT)(T &arg);
|
|
|
|
typedef void (IGUIObject::*void_Object_pFunction)();
|
2003-11-06 01:21:45 +01:00
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
2003-11-24 03:18:41 +01:00
|
|
|
* If you want to call a IGUIObject-function
|
2003-11-18 11:00:57 +01:00
|
|
|
* on not just an object, but also on ALL of their children
|
|
|
|
* you want to use this recursion system.
|
|
|
|
* It recurses an object calling a function on itself
|
|
|
|
* and all children (and so forth).
|
|
|
|
*
|
2003-11-24 03:18:41 +01:00
|
|
|
* <b>Restrictions:</b>\n
|
2003-11-18 11:00:57 +01:00
|
|
|
* You can also set restrictions, so that if the recursion
|
|
|
|
* reaches an objects with certain setup, it just doesn't
|
|
|
|
* call the function on the object, nor it's children for
|
|
|
|
* that matter. i.e. it cuts that object off from the
|
|
|
|
* recursion tree. What setups that can cause restrictions
|
|
|
|
* are hardcoded and specific. Check out the defines
|
2003-11-24 03:18:41 +01:00
|
|
|
* GUIRR_* for all different setups.
|
|
|
|
*
|
|
|
|
* Error reports are either logged or thrown out of RecurseObject.
|
|
|
|
* Always use it with try/catch!
|
2003-11-18 11:00:57 +01:00
|
|
|
*
|
2003-11-24 03:18:41 +01:00
|
|
|
* @param RR Recurse Restrictions, set to 0 if no restrictions
|
|
|
|
* @param pObject Top object, this is where the iteration starts
|
2003-11-18 11:00:57 +01:00
|
|
|
* @param pFunc Function to recurse
|
2003-11-24 03:18:41 +01:00
|
|
|
* @param Argument Argument for pFunc of type T
|
2009-09-27 17:04:46 +02:00
|
|
|
* @throws PSERROR Depends on what pFunc might throw. PSERROR is standard.
|
2003-11-24 03:18:41 +01:00
|
|
|
* Itself doesn't throw anything.
|
2003-11-18 11:00:57 +01:00
|
|
|
*/
|
2007-06-17 00:07:40 +02:00
|
|
|
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction_argT pFunc, const T &Argument)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
2003-12-27 07:26:03 +01:00
|
|
|
// TODO Gee: Don't run this for the base object.
|
2003-11-06 01:21:45 +01:00
|
|
|
if (CheckIfRestricted(RR, pObject))
|
|
|
|
return;
|
|
|
|
|
|
|
|
(pObject->*pFunc)(Argument);
|
|
|
|
|
|
|
|
// Iterate children
|
|
|
|
vector_pObjects::iterator it;
|
|
|
|
for (it = pObject->ChildrenItBegin(); it != pObject->ChildrenItEnd(); ++it)
|
|
|
|
{
|
|
|
|
RecurseObject(RR, *it, pFunc, Argument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Argument is reference.
|
|
|
|
*
|
|
|
|
* @see RecurseObject()
|
|
|
|
*/
|
2007-06-17 00:07:40 +02:00
|
|
|
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction_argRefT pFunc, T &Argument)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
|
|
|
if (CheckIfRestricted(RR, pObject))
|
|
|
|
return;
|
|
|
|
|
|
|
|
(pObject->*pFunc)(Argument);
|
|
|
|
|
|
|
|
// Iterate children
|
|
|
|
vector_pObjects::iterator it;
|
|
|
|
for (it = pObject->ChildrenItBegin(); it != pObject->ChildrenItEnd(); ++it)
|
|
|
|
{
|
|
|
|
RecurseObject(RR, *it, pFunc, Argument);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* With no argument.
|
|
|
|
*
|
|
|
|
* @see RecurseObject()
|
|
|
|
*/
|
2007-06-17 00:07:40 +02:00
|
|
|
static void RecurseObject(int RR, IGUIObject *pObject, void_Object_pFunction pFunc)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
|
|
|
if (CheckIfRestricted(RR, pObject))
|
|
|
|
return;
|
|
|
|
|
|
|
|
(pObject->*pFunc)();
|
2003-12-27 07:26:03 +01:00
|
|
|
|
2003-11-06 01:21:45 +01:00
|
|
|
// Iterate children
|
|
|
|
vector_pObjects::iterator it;
|
|
|
|
for (it = pObject->ChildrenItBegin(); it != pObject->ChildrenItEnd(); ++it)
|
|
|
|
{
|
|
|
|
RecurseObject(RR, *it, pFunc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2003-11-18 11:00:57 +01:00
|
|
|
/**
|
|
|
|
* Checks restrictions for the iteration, for instance if
|
|
|
|
* you tell the recursor to avoid all hidden objects, it
|
|
|
|
* will, and this function checks a certain object's
|
|
|
|
* restriction values.
|
|
|
|
*
|
|
|
|
* @param RR What kind of restriction, for instance hidden or disabled
|
|
|
|
* @param pObject Object
|
|
|
|
* @return true if restricted
|
|
|
|
*/
|
2007-06-17 00:07:40 +02:00
|
|
|
static bool CheckIfRestricted(int RR, IGUIObject *pObject)
|
2003-11-06 01:21:45 +01:00
|
|
|
{
|
2010-01-07 20:00:56 +01:00
|
|
|
// Statically initialise some strings, so we don't have to do
|
|
|
|
// lots of allocation every time this function is called
|
|
|
|
static CStr strHidden("hidden");
|
|
|
|
static CStr strEnabled("enabled");
|
|
|
|
static CStr strGhost("ghost");
|
|
|
|
|
2003-11-06 01:21:45 +01:00
|
|
|
if (RR & GUIRR_HIDDEN)
|
|
|
|
{
|
2010-08-06 16:15:08 +02:00
|
|
|
bool hidden = true;
|
2010-01-07 20:00:56 +01:00
|
|
|
GUI<bool>::GetSetting(pObject, strHidden, hidden);
|
2004-05-29 06:06:50 +02:00
|
|
|
|
|
|
|
if (hidden)
|
2003-11-06 01:21:45 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (RR & GUIRR_DISABLED)
|
|
|
|
{
|
2010-08-06 16:15:08 +02:00
|
|
|
bool enabled = false;
|
2010-01-07 20:00:56 +01:00
|
|
|
GUI<bool>::GetSetting(pObject, strEnabled, enabled);
|
2004-05-29 06:06:50 +02:00
|
|
|
|
|
|
|
if (!enabled)
|
2003-11-06 01:21:45 +01:00
|
|
|
return true;
|
|
|
|
}
|
2003-12-27 07:26:03 +01:00
|
|
|
if (RR & GUIRR_GHOST)
|
|
|
|
{
|
2010-08-06 16:15:08 +02:00
|
|
|
bool ghost = true;
|
2010-01-07 20:00:56 +01:00
|
|
|
GUI<bool>::GetSetting(pObject, strGhost, ghost);
|
2004-05-29 06:06:50 +02:00
|
|
|
|
|
|
|
if (ghost)
|
2003-12-27 07:26:03 +01:00
|
|
|
return true;
|
|
|
|
}
|
2003-11-06 01:21:45 +01:00
|
|
|
|
|
|
|
// false means not restricted
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2003-11-24 18:13:37 +01:00
|
|
|
#endif
|