Changeset View
Changeset View
Standalone View
Standalone View
source/gui/ObjectBases/IGUIObject.cpp
Show All 37 Lines | |||||
const CStr IGUIObject::EventNameMouseMove = "MouseMove"; | const CStr IGUIObject::EventNameMouseMove = "MouseMove"; | ||||
const CStr IGUIObject::EventNameMouseLeave = "MouseLeave"; | const CStr IGUIObject::EventNameMouseLeave = "MouseLeave"; | ||||
IGUIObject::IGUIObject(CGUI& pGUI) | IGUIObject::IGUIObject(CGUI& pGUI) | ||||
: m_pGUI(pGUI), | : m_pGUI(pGUI), | ||||
m_pParent(), | m_pParent(), | ||||
m_MouseHovering(), | m_MouseHovering(), | ||||
m_LastClickTime(), | m_LastClickTime(), | ||||
m_Enabled(), | m_Enabled(this, "enabled", true), | ||||
m_Hidden(), | m_Hidden(this, "hidden", false), | ||||
m_Size(), | m_Size(this, "size"), | ||||
m_Style(), | m_Style(this, "style"), | ||||
m_Hotkey(), | m_Hotkey(this, "hotkey"), | ||||
m_Z(), | m_Z(this, "z"), | ||||
m_Absolute(), | m_Absolute(this, "absolute", true), | ||||
m_Ghost(), | m_Ghost(this, "ghost", false), | ||||
m_AspectRatio(), | m_AspectRatio(this, "aspectratio"), | ||||
m_Tooltip(), | m_Tooltip(this, "tooltip"), | ||||
m_TooltipStyle() | m_TooltipStyle(this, "tooltip_style") | ||||
{ | { | ||||
RegisterSetting("enabled", m_Enabled); | |||||
RegisterSetting("hidden", m_Hidden); | |||||
RegisterSetting("size", m_Size); | |||||
RegisterSetting("style", m_Style); | |||||
RegisterSetting("hotkey", m_Hotkey); | |||||
RegisterSetting("z", m_Z); | |||||
RegisterSetting("absolute", m_Absolute); | |||||
RegisterSetting("ghost", m_Ghost); | |||||
RegisterSetting("aspectratio", m_AspectRatio); | |||||
RegisterSetting("tooltip", m_Tooltip); | |||||
RegisterSetting("tooltip_style", m_TooltipStyle); | |||||
// Setup important defaults | |||||
// TODO: Should be in the default style? | |||||
SetSetting<bool>("hidden", false, true); | |||||
SetSetting<bool>("ghost", false, true); | |||||
SetSetting<bool>("enabled", true, true); | |||||
SetSetting<bool>("absolute", true, true); | |||||
} | } | ||||
IGUIObject::~IGUIObject() | IGUIObject::~IGUIObject() | ||||
{ | { | ||||
for (const std::pair<const CStr, IGUISetting*>& p : m_Settings) | |||||
delete p.second; | |||||
if (!m_ScriptHandlers.empty()) | if (!m_ScriptHandlers.empty()) | ||||
JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetGeneralJSContext(), Trace, this); | JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetGeneralJSContext(), Trace, this); | ||||
// m_Children is deleted along all other GUI Objects in the CGUI destructor | // m_Children is deleted along all other GUI Objects in the CGUI destructor | ||||
} | } | ||||
void IGUIObject::AddChild(IGUIObject& pChild) | void IGUIObject::AddChild(IGUIObject& pChild) | ||||
{ | { | ||||
pChild.SetParent(this); | pChild.SetParent(this); | ||||
m_Children.push_back(&pChild); | m_Children.push_back(&pChild); | ||||
} | } | ||||
template<typename T> | void IGUIObject::RegisterSetting(const CStr& Name, IGUISetting* setting) | ||||
void IGUIObject::RegisterSetting(const CStr& Name, T& Value) | |||||
{ | { | ||||
if (SettingExists(Name)) | if (SettingExists(Name)) | ||||
LOGERROR("The setting '%s' already exists on the object '%s'!", Name.c_str(), GetPresentableName().c_str()); | LOGERROR("The setting '%s' already exists on the object '%s'!", Name.c_str(), GetPresentableName().c_str()); | ||||
else | else | ||||
m_Settings.emplace(Name, new CGUISetting<T>(*this, Name, Value)); | m_Settings.emplace(Name, setting); | ||||
} | } | ||||
bool IGUIObject::SettingExists(const CStr& Setting) const | void IGUIObject::ReregisterSetting(const CStr& Name, IGUISetting* setting) | ||||
{ | { | ||||
return m_Settings.find(Setting) != m_Settings.end(); | if (!SettingExists(Name)) | ||||
} | LOGERROR("The setting '%s' must already exist on the object '%s'!", Name.c_str(), GetPresentableName().c_str()); | ||||
else | |||||
template <typename T> | m_Settings.at(Name) = setting; | ||||
T& IGUIObject::GetSetting(const CStr& Setting) | |||||
{ | |||||
return static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting; | |||||
} | } | ||||
template <typename T> | bool IGUIObject::SettingExists(const CStr& Setting) const | ||||
const T& IGUIObject::GetSetting(const CStr& Setting) const | |||||
{ | { | ||||
return static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting; | return m_Settings.find(Setting) != m_Settings.end(); | ||||
} | } | ||||
bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage) | bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage) | ||||
{ | { | ||||
const std::map<CStr, IGUISetting*>::iterator it = m_Settings.find(Setting); | const std::map<CStr, IGUISetting*>::iterator it = m_Settings.find(Setting); | ||||
if (it == m_Settings.end()) | if (it == m_Settings.end()) | ||||
{ | { | ||||
LOGERROR("GUI object '%s' has no property called '%s', can't set parse and set value '%s'", GetPresentableName().c_str(), Setting.c_str(), Value.ToUTF8().c_str()); | LOGERROR("GUI object '%s' has no property called '%s', can't set parse and set value '%s'", GetPresentableName().c_str(), Setting.c_str(), Value.ToUTF8().c_str()); | ||||
return false; | return false; | ||||
} | } | ||||
return it->second->FromString(Value, SendMessage); | return it->second->FromString(Value, SendMessage); | ||||
} | } | ||||
template <typename T> | |||||
void IGUIObject::SetSetting(const CStr& Setting, T& Value, const bool SendMessage) | |||||
{ | |||||
PreSettingChange(Setting); | |||||
static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting = std::move(Value); | |||||
SettingChanged(Setting, SendMessage); | |||||
} | |||||
template <typename T> | |||||
void IGUIObject::SetSetting(const CStr& Setting, const T& Value, const bool SendMessage) | |||||
{ | |||||
PreSettingChange(Setting); | |||||
static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting = Value; | |||||
SettingChanged(Setting, SendMessage); | |||||
} | |||||
void IGUIObject::PreSettingChange(const CStr& Setting) | void IGUIObject::PreSettingChange(const CStr& Setting) | ||||
{ | { | ||||
if (Setting == "hotkey") | if (Setting == "hotkey") | ||||
m_pGUI.UnsetObjectHotkey(this, GetSetting<CStr>(Setting)); | m_pGUI.UnsetObjectHotkey(this, m_Hotkey); | ||||
} | } | ||||
void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage) | void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage) | ||||
{ | { | ||||
if (Setting == "size") | if (Setting == "size") | ||||
{ | { | ||||
// If setting was "size", we need to re-cache itself and all children | // If setting was "size", we need to re-cache itself and all children | ||||
RecurseObject(nullptr, &IGUIObject::UpdateCachedSize); | RecurseObject(nullptr, &IGUIObject::UpdateCachedSize); | ||||
} | } | ||||
else if (Setting == "hidden") | else if (Setting == "hidden") | ||||
{ | { | ||||
// Hiding an object requires us to reset it and all children | // Hiding an object requires us to reset it and all children | ||||
if (m_Hidden) | if (m_Hidden) | ||||
RecurseObject(nullptr, &IGUIObject::ResetStates); | RecurseObject(nullptr, &IGUIObject::ResetStates); | ||||
} | } | ||||
else if (Setting == "hotkey") | else if (Setting == "hotkey") | ||||
m_pGUI.SetObjectHotkey(this, GetSetting<CStr>(Setting)); | m_pGUI.SetObjectHotkey(this, m_Hotkey); | ||||
else if (Setting == "style") | else if (Setting == "style") | ||||
m_pGUI.SetObjectStyle(this, GetSetting<CStr>(Setting)); | m_pGUI.SetObjectStyle(this, m_Style); | ||||
if (SendMessage) | if (SendMessage) | ||||
{ | { | ||||
SGUIMessage msg(GUIM_SETTINGS_UPDATED, Setting); | SGUIMessage msg(GUIM_SETTINGS_UPDATED, Setting); | ||||
HandleMessage(msg); | HandleMessage(msg); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void IGUIObject::UpdateCachedSize() | void IGUIObject::UpdateCachedSize() | ||||
{ | { | ||||
// If absolute="false" and the object has got a parent, | // If absolute="false" and the object has got a parent, | ||||
// use its cached size instead of the screen. Notice | // use its cached size instead of the screen. Notice | ||||
// it must have just been cached for it to work. | // it must have just been cached for it to work. | ||||
if (!m_Absolute && m_pParent && !IsRootObject()) | if (!m_Absolute && m_pParent && !IsRootObject()) | ||||
m_CachedActualSize = m_Size.GetSize(m_pParent->m_CachedActualSize); | m_CachedActualSize = m_Size->GetSize(m_pParent->m_CachedActualSize); | ||||
else | else | ||||
m_CachedActualSize = m_Size.GetSize(CRect(0.f, 0.f, g_xres / g_GuiScale, g_yres / g_GuiScale)); | m_CachedActualSize = m_Size->GetSize(CRect(0.f, 0.f, g_xres / g_GuiScale, g_yres / g_GuiScale)); | ||||
// In a few cases, GUI objects have to resize to fill the screen | // In a few cases, GUI objects have to resize to fill the screen | ||||
// but maintain a constant aspect ratio. | // but maintain a constant aspect ratio. | ||||
// Adjust the size to be the max possible, centered in the original size: | // Adjust the size to be the max possible, centered in the original size: | ||||
if (m_AspectRatio) | if (m_AspectRatio) | ||||
{ | { | ||||
if (m_CachedActualSize.GetWidth() > m_CachedActualSize.GetHeight() * m_AspectRatio) | if (m_CachedActualSize.GetWidth() > m_CachedActualSize.GetHeight() * m_AspectRatio) | ||||
{ | { | ||||
Show All 27 Lines | bool IGUIObject::ApplyStyle(const CStr& StyleName) | ||||
// The default style may specify settings for any GUI object. | // The default style may specify settings for any GUI object. | ||||
// Other styles are reported if they specify a Setting that does not exist, | // Other styles are reported if they specify a Setting that does not exist, | ||||
// so that the XML author is informed and can correct the style. | // so that the XML author is informed and can correct the style. | ||||
for (const std::pair<const CStr, CStrW>& p : m_pGUI.GetStyle(StyleName).m_SettingsDefaults) | for (const std::pair<const CStr, CStrW>& p : m_pGUI.GetStyle(StyleName).m_SettingsDefaults) | ||||
{ | { | ||||
if (SettingExists(p.first)) | if (SettingExists(p.first)) | ||||
SetSettingFromString(p.first, p.second, true); | m_Settings.at(p.first)->FromString(p.second, true); | ||||
else if (StyleName != "default") | else if (StyleName != "default") | ||||
LOGWARNING("GUI object has no setting \"%s\", but the style \"%s\" defines it", p.first, StyleName.c_str()); | LOGWARNING("GUI object has no setting \"%s\", but the style \"%s\" defines it", p.first, StyleName.c_str()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
float IGUIObject::GetBufferedZ() const | float IGUIObject::GetBufferedZ() const | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | |||||
void IGUIObject::TraceMember(JSTracer* trc) | void IGUIObject::TraceMember(JSTracer* trc) | ||||
{ | { | ||||
// Please ensure to adapt the Tracer enabling and disabling in accordance with the GC things traced! | // Please ensure to adapt the Tracer enabling and disabling in accordance with the GC things traced! | ||||
for (std::pair<const CStr, JS::Heap<JSObject*>>& handler : m_ScriptHandlers) | for (std::pair<const CStr, JS::Heap<JSObject*>>& handler : m_ScriptHandlers) | ||||
JS::TraceEdge(trc, &handler.second, "IGUIObject::m_ScriptHandlers"); | JS::TraceEdge(trc, &handler.second, "IGUIObject::m_ScriptHandlers"); | ||||
} | } | ||||
// Instantiate templated functions: | |||||
// These functions avoid copies by working with a reference and move semantics. | |||||
#define TYPE(T) \ | |||||
template void IGUIObject::RegisterSetting<T>(const CStr& Name, T& Value); \ | |||||
template T& IGUIObject::GetSetting<T>(const CStr& Setting); \ | |||||
template const T& IGUIObject::GetSetting<T>(const CStr& Setting) const; \ | |||||
template void IGUIObject::SetSetting<T>(const CStr& Setting, T& Value, const bool SendMessage); \ | |||||
#include "gui/GUISettingTypes.h" | |||||
#undef TYPE | |||||
// Copying functions - discouraged except for primitives. | |||||
#define TYPE(T) \ | |||||
template void IGUIObject::SetSetting<T>(const CStr& Setting, const T& Value, const bool SendMessage); \ | |||||
#define GUITYPE_IGNORE_NONCOPYABLE | |||||
#include "gui/GUISettingTypes.h" | |||||
#undef GUITYPE_IGNORE_NONCOPYABLE | |||||
#undef TYPE |
Wildfire Games · Phabricator