Files
SingularityViewer/indra/llui/llui.h
Siana Gearz 62a7704a4f You shaved 2 minutes off compile time...
... but you are still hungry
2015-09-18 04:29:38 +02:00

608 lines
16 KiB
C++

/**
* @file llui.h
* @brief General static UI services.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLUI_H
#define LL_LLUI_H
#include "llrect.h"
#include "llcontrol.h"
#include "llcoord.h"
#include "v2math.h"
#include "llinitparam.h"
#include "llrender2dutils.h"
#include "llpointer.h"
#include "lluicolor.h"
#include "lluiimage.h"
#include <boost/signals2.hpp>
// for initparam specialization
#include "llfontgl.h"
// LLUIFactory
#include "llsd.h"
class LLHtmlHelp;
class LLUUID;
class LLWindow;
class LLView;
void make_ui_sound(const char* name);
// Used to hide the flashing text cursor when window doesn't have focus.
extern BOOL gShowTextEditCursor;
class LLImageProviderInterface;
typedef void (*LLUIAudioCallback)(const LLUUID& uuid);
class LLUI
{
LOG_CLASS(LLUI);
public:
//
// Methods
//
static void initClass(LLControlGroup* config,
LLControlGroup* account,
LLControlGroup* ignores,
LLControlGroup* colors,
LLImageProviderInterface* image_provider,
LLUIAudioCallback audio_callback = NULL,
const LLVector2 *scale_factor = NULL,
const std::string& language = LLStringUtil::null);
static void cleanupClass();
static void pushMatrix() { LLRender2D::pushMatrix(); }
static void popMatrix() { LLRender2D::popMatrix(); }
static void loadIdentity() { LLRender2D::loadIdentity(); }
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.
// http://www.loc.gov/standards/iso639-2/php/code_list.php
static std::string getLanguage();
//helper functions (should probably move free standing rendering helper functions here)
static LLView* getRootView() { return sRootView; }
static void setRootView(LLView* view) { sRootView = view; }
static std::string locateSkin(const std::string& filename);
static void setMousePositionScreen(S32 x, S32 y);
static void getMousePositionScreen(S32 *x, S32 *y);
static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
{ return LLRender2D::getUIImageByID(image_id, priority); }
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
{ return LLRender2D::getUIImage(name, priority); }
static LLVector2 getWindowSize();
static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
static void screenRectToGL(const LLRect& screen, LLRect *gl);
static void glRectToScreen(const LLRect& gl, LLRect *screen);
// Returns the control group containing the control name, or the default group
static LLControlGroup& getControlControlGroup (const std::string& controlname);
static LLWindow* getWindow() { return sWindow; }
static void setHtmlHelp(LLHtmlHelp* html_help);
//
// Data
//
static LLControlGroup* sConfigGroup;
static LLControlGroup* sAccountGroup;
static LLControlGroup* sIgnoresGroup;
static LLControlGroup* sColorsGroup;
static LLUIAudioCallback sAudioCallback;
static LLWindow* sWindow;
static LLView* sRootView;
static BOOL sShowXUINames;
static LLHtmlHelp* sHtmlHelp;
// *TODO: remove the following when QAR-369 settings clean-up work is in.
// Also remove the call to this method which will then be obsolete.
// Search for QAR-369 below to enable the proper accessing of this feature. -MG
static void setQAMode(BOOL b);
static BOOL sQAMode;
};
// FactoryPolicy is a static class that controls the creation and lookup of UI elements,
// such as floaters.
// The key parameter is used to provide a unique identifier and/or associated construction
// parameters for a given UI instance
//
// Specialize this traits for different types, or provide a class with an identical interface
// in the place of the traits parameter
//
// For example:
//
// template <>
// class FactoryPolicy<MyClass> /* FactoryPolicy specialized for MyClass */
// {
// public:
// static MyClass* findInstance(const LLSD& key = LLSD())
// {
// /* return instance of MyClass associated with key */
// }
//
// static MyClass* createInstance(const LLSD& key = LLSD())
// {
// /* create new instance of MyClass using key for construction parameters */
// }
// }
//
// class MyClass : public LLUIFactory<MyClass>
// {
// /* uses FactoryPolicy<MyClass> by default */
// }
template <class T>
class FactoryPolicy
{
public:
// basic factory methods
static T* findInstance(const LLSD& key); // unimplemented, provide specialiation
static T* createInstance(const LLSD& key); // unimplemented, provide specialiation
};
// VisibilityPolicy controls the visibility of UI elements, such as floaters.
// The key parameter is used to store the unique identifier of a given UI instance
//
// Specialize this traits for different types, or duplicate this interface for specific instances
// (see above)
template <class T>
class VisibilityPolicy
{
public:
// visibility methods
static bool visible(T* instance, const LLSD& key); // unimplemented, provide specialiation
static void show(T* instance, const LLSD& key); // unimplemented, provide specialiation
static void hide(T* instance, const LLSD& key); // unimplemented, provide specialiation
};
// Manages generation of UI elements by LLSD, such that (generally) there is
// a unique instance per distinct LLSD parameter
// Class T is the instance type being managed, and the FACTORY_POLICY and VISIBILITY_POLICY
// classes provide static methods for creating, accessing, showing and hiding the associated
// element T
template <class T, class FACTORY_POLICY = FactoryPolicy<T>, class VISIBILITY_POLICY = VisibilityPolicy<T> >
class LLUIFactory
{
public:
// give names to the template parameters so derived classes can refer to them
// except this doesn't work in gcc
typedef FACTORY_POLICY factory_policy_t;
typedef VISIBILITY_POLICY visibility_policy_t;
LLUIFactory()
{
}
virtual ~LLUIFactory()
{
}
// default show and hide methods
static T* showInstance(const LLSD& key = LLSD())
{
T* instance = getInstance(key);
if (instance != NULL)
{
VISIBILITY_POLICY::show(instance, key);
}
return instance;
}
static void hideInstance(const LLSD& key = LLSD())
{
T* instance = getInstance(key);
if (instance != NULL)
{
VISIBILITY_POLICY::hide(instance, key);
}
}
static void toggleInstance(const LLSD& key = LLSD())
{
if (instanceVisible(key))
{
hideInstance(key);
}
else
{
showInstance(key);
}
}
static bool instanceVisible(const LLSD& key = LLSD())
{
T* instance = FACTORY_POLICY::findInstance(key);
return instance != NULL && VISIBILITY_POLICY::visible(instance, key);
}
static T* getInstance(const LLSD& key = LLSD())
{
T* instance = FACTORY_POLICY::findInstance(key);
if (instance == NULL)
{
instance = FACTORY_POLICY::createInstance(key);
}
return instance;
}
};
// Creates a UI singleton by ignoring the identifying parameter
// and always generating the same instance via the LLUIFactory interface.
// Note that since UI elements can be destroyed by their hierarchy, this singleton
// pattern uses a static pointer to an instance that will be re-created as needed.
//
// Usage Pattern:
//
// class LLFloaterFoo : public LLFloater, public LLUISingleton<LLFloaterFoo>
// {
// friend class LLUISingleton<LLFloaterFoo>;
// private:
// LLFloaterFoo(const LLSD& key);
// };
//
// Note that LLUISingleton takes an option VisibilityPolicy parameter that defines
// how showInstance(), hideInstance(), etc. work.
//
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLUISingleton&oldid=79352
template <class T, class VISIBILITY_POLICY = VisibilityPolicy<T> >
class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>, VISIBILITY_POLICY>
{
protected:
// T must derive from LLUISingleton<T>
LLUISingleton() { sInstance = static_cast<T*>(this); }
~LLUISingleton() { sInstance = NULL; }
public:
static T* findInstance(const LLSD& key = LLSD())
{
return sInstance;
}
static T* createInstance(const LLSD& key = LLSD())
{
if (sInstance == NULL)
{
sInstance = new T(key);
}
return sInstance;
}
private:
static T* sInstance;
};
template <class T, class U> T* LLUISingleton<T,U>::sInstance = NULL;
// Moved LLLocalClipRect to lllocalcliprect.h
class LLCallbackRegistry
{
public:
typedef boost::signals2::signal<void()> callback_signal_t;
void registerCallback(const callback_signal_t::slot_type& slot)
{
mCallbacks.connect(slot);
}
void fireCallbacks()
{
mCallbacks();
}
private:
callback_signal_t mCallbacks;
};
class LLInitClassList :
public LLCallbackRegistry,
public LLSingleton<LLInitClassList>
{
friend class LLSingleton<LLInitClassList>;
private:
LLInitClassList() {}
};
class LLDestroyClassList :
public LLCallbackRegistry,
public LLSingleton<LLDestroyClassList>
{
friend class LLSingleton<LLDestroyClassList>;
private:
LLDestroyClassList() {}
};
template<typename T>
class LLRegisterWith
{
public:
LLRegisterWith(boost::function<void ()> func)
{
T::instance().registerCallback(func);
}
// this avoids a MSVC bug where non-referenced static members are "optimized" away
// even if their constructors have side effects
void reference()
{
#if LL_WINDOWS
S32 dummy;
dummy = 0;
#endif /*LL_WINDOWS*/
}
};
template<typename T>
class LLInitClass
{
public:
LLInitClass() { sRegister.reference(); }
static LLRegisterWith<LLInitClassList> sRegister;
private:
static void initClass()
{
LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL;
}
};
template<typename T>
class LLDestroyClass
{
public:
LLDestroyClass() { sRegister.reference(); }
static LLRegisterWith<LLDestroyClassList> sRegister;
private:
static void destroyClass()
{
LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL;
}
};
template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
template <class T>
class LLUICachedControl : public LLCachedControl<T>
{
public:
// This constructor will declare a control if it doesn't exist in the contol group
LLUICachedControl(const std::string& name,
const T& default_value,
const std::string& comment = "Declared In Code")
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment)
{}
// This constructor will signal an error if the control doesn't exist in the control group
LLUICachedControl(const std::string& name)
: LLCachedControl<T>(LLUI::getControlControlGroup(name), name)
{}
};
template <typename DERIVED>
class LLParamBlock
{
protected:
LLParamBlock() { sBlock = (DERIVED*)this; }
typedef typename boost::add_const<DERIVED>::type Tconst;
template <typename T>
class LLMandatoryParam
{
public:
typedef typename boost::add_const<T>::type T_const;
LLMandatoryParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
LLMandatoryParam(const LLMandatoryParam<T>& other) : mVal(other.mVal) {}
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
operator T() const { return mVal; }
T operator=(T_const set_value) { mVal = set_value; return mVal; }
private:
T mVal;
DERIVED* mBlock;
};
template <typename T>
class LLOptionalParam
{
public:
typedef typename boost::add_const<T>::type T_const;
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
LLOptionalParam() : mBlock(sBlock) {}
LLOptionalParam(const LLOptionalParam<T>& other) : mVal(other.mVal) {}
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
operator T() const { return mVal; }
T operator=(T_const set_value) { mVal = set_value; return mVal; }
private:
T mVal;
DERIVED* mBlock;
};
// specialization that requires initialization for reference types
template <typename T>
class LLOptionalParam <T&>
{
public:
typedef typename boost::add_const<T&>::type T_const;
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
LLOptionalParam(const LLOptionalParam<T&>& other) : mVal(other.mVal) {}
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
operator T&() const { return mVal; }
T& operator=(T_const set_value) { mVal = set_value; return mVal; }
private:
T& mVal;
DERIVED* mBlock;
};
// specialization that initializes pointer params to NULL
template<typename T>
class LLOptionalParam<T*>
{
public:
typedef typename boost::add_const<T*>::type T_const;
LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
LLOptionalParam() : mVal((T*)NULL), mBlock(sBlock) {}
LLOptionalParam(const LLOptionalParam<T*>& other) : mVal(other.mVal) {}
DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
operator T*() const { return mVal; }
T* operator=(T_const set_value) { mVal = set_value; return mVal; }
private:
T* mVal;
DERIVED* mBlock;
};
static DERIVED* sBlock;
};
template <typename T> T* LLParamBlock<T>::sBlock = NULL;
namespace LLInitParam
{
template<>
class ParamValue<LLRect>
: public CustomParamValue<LLRect>
{
typedef CustomParamValue<LLRect> super_t;
public:
Optional<S32> left,
top,
right,
bottom,
width,
height;
ParamValue(const LLRect& value);
void updateValueFromBlock();
void updateBlockFromValue(bool make_block_authoritative);
};
template<>
class ParamValue<LLUIColor>
: public CustomParamValue<LLUIColor>
{
typedef CustomParamValue<LLUIColor> super_t;
public:
Optional<F32> red,
green,
blue,
alpha;
Optional<std::string> control;
ParamValue(const LLUIColor& color);
void updateValueFromBlock();
void updateBlockFromValue(bool make_block_authoritative);
};
template<>
class ParamValue<const LLFontGL*>
: public CustomParamValue<const LLFontGL* >
{
typedef CustomParamValue<const LLFontGL*> super_t;
public:
Optional<std::string> name,
size,
style;
ParamValue(const LLFontGL* value);
void updateValueFromBlock();
void updateBlockFromValue(bool make_block_authoritative);
};
template<>
struct TypeValues<LLFontGL::HAlign> : public TypeValuesHelper<LLFontGL::HAlign>
{
static void declareValues();
};
template<>
struct TypeValues<LLFontGL::VAlign> : public TypeValuesHelper<LLFontGL::VAlign>
{
static void declareValues();
};
template<>
struct TypeValues<LLFontGL::ShadowType> : public TypeValuesHelper<LLFontGL::ShadowType>
{
static void declareValues();
};
template<>
struct ParamCompare<const LLFontGL*, false>
{
static bool equals(const LLFontGL* a, const LLFontGL* b);
};
template<>
class ParamValue<LLCoordGL>
: public CustomParamValue<LLCoordGL>
{
typedef CustomParamValue<LLCoordGL> super_t;
public:
Optional<S32> x,
y;
ParamValue(const LLCoordGL& val);
void updateValueFromBlock();
void updateBlockFromValue(bool make_block_authoritative);
};
}
#endif