forked from 0ad/0ad
Change GUI settings to explicitly be member variables.
Completes work starting in D2313 /a33fd55e81
: - Make C++ mistakes where values can be changed without messages being sent easier to notice / harder to do. - Make the IGUISetting interface more flexible, allowing custom settings implementing their own logic. This is used to clean up hotkey code introduced in33af6da5e1
. Side effects: - FromJSVal_Vector clears the vector being passed in. I have some vague memory of not doing that in D24 /2bae30c454
as an optimisation, but it seems more like a footgun to me. - Most usage of SetSettingFromString is replaced by direct method calls, as we can generally cast to the proper GUI object type. Where we can't, it is kept as a poor's man virtual dispatch. - It moves a few member variables elsewhere, e.g. TextOwner now gets its own member variable settings. Differential Revision: https://code.wildfiregames.com/D3892 This was SVN commit r25392.
This commit is contained in:
parent
4db5467717
commit
8b08f4ae7a
@ -441,8 +441,7 @@ void CGUI::SetObjectStyle(IGUIObject* pObject, const CStr& styleName)
|
||||
{
|
||||
// If the style is not recognised (or an empty string) then ApplyStyle will
|
||||
// emit an error message. Thus we don't need to handle it here.
|
||||
if (pObject->ApplyStyle(styleName))
|
||||
pObject->m_Style = styleName;
|
||||
pObject->ApplyStyle(styleName);
|
||||
}
|
||||
|
||||
void CGUI::UnsetObjectStyle(IGUIObject* pObject)
|
||||
@ -684,6 +683,12 @@ IGUIObject* CGUI::Xeromyces_ReadObject(const XMBData& xmb, XMBElement element, I
|
||||
{
|
||||
CStr name(attr.Value);
|
||||
|
||||
if (name.Left(2) == "__")
|
||||
{
|
||||
LOGERROR("GUI: Names starting with '__' are reserved for the engine (object: %s)", name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const std::pair<CStr, CStr>& sub : NameSubst)
|
||||
name.Replace(sub.first, sub.second);
|
||||
|
||||
@ -894,10 +899,10 @@ IGUIObject* CGUI::Xeromyces_ReadObject(const XMBData& xmb, XMBElement element, I
|
||||
if (object->m_Absolute)
|
||||
// If the object is absolute, we'll have to get the parent's Z buffered,
|
||||
// and add to that!
|
||||
object->SetSetting<float>("z", pParent->GetBufferedZ() + 10.f, false);
|
||||
object->m_Z.Set(pParent->GetBufferedZ() + 10.f, false);
|
||||
else
|
||||
// If the object is relative, then we'll just store Z as "10"
|
||||
object->SetSetting<float>("z", 10.f, false);
|
||||
object->m_Z.Set(10.f, false);
|
||||
}
|
||||
|
||||
if (!AddObject(*pParent, *object))
|
||||
|
@ -23,67 +23,107 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
|
||||
template<typename T>
|
||||
|
||||
CGUISetting<T>::CGUISetting(IGUIObject& pObject, const CStr& Name, T& Value)
|
||||
: m_pSetting(Value), m_Name(Name), m_pObject(pObject)
|
||||
IGUISetting::IGUISetting(const CStr& name, IGUIObject* owner) : m_pObject(*owner)
|
||||
{
|
||||
m_pObject.RegisterSetting(name, this);
|
||||
}
|
||||
|
||||
IGUISetting::IGUISetting(IGUISetting&& o) : m_pObject(o.m_pObject)
|
||||
{
|
||||
m_pObject.ReregisterSetting(o.GetName(), this);
|
||||
}
|
||||
|
||||
bool IGUISetting::FromString(const CStrW& value, const bool sendMessage)
|
||||
{
|
||||
if (!DoFromString(value))
|
||||
return false;
|
||||
|
||||
OnSettingChange(GetName(), sendMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
|
||||
*/
|
||||
bool IGUISetting::FromJSVal(const ScriptRequest& rq, JS::HandleValue value, const bool sendMessage)
|
||||
{
|
||||
if (!DoFromJSVal(rq, value))
|
||||
return false;
|
||||
|
||||
OnSettingChange(GetName(), sendMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
void IGUISetting::OnSettingChange(const CStr& setting, bool sendMessage)
|
||||
{
|
||||
m_pObject.SettingChanged(setting, sendMessage);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool CGUISetting<T>::FromString(const CStrW& Value, const bool SendMessage)
|
||||
bool CGUISimpleSetting<T>::DoFromString(const CStrW& value)
|
||||
{
|
||||
T settingValue;
|
||||
|
||||
if (!CGUI::ParseString<T>(&m_pObject.GetGUI(), Value, settingValue))
|
||||
return false;
|
||||
|
||||
m_pObject.SetSetting<T>(m_Name, settingValue, SendMessage);
|
||||
return true;
|
||||
return CGUI::ParseString<T>(&m_pObject.GetGUI(), value, m_Setting);
|
||||
};
|
||||
|
||||
template<>
|
||||
bool CGUISetting<CGUIColor>::FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage)
|
||||
bool CGUISimpleSetting<CGUIColor>::DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value)
|
||||
{
|
||||
CGUIColor settingValue;
|
||||
if (Value.isString())
|
||||
if (value.isString())
|
||||
{
|
||||
CStr name;
|
||||
if (!ScriptInterface::FromJSVal(rq, Value, name))
|
||||
if (!ScriptInterface::FromJSVal(rq, value, name))
|
||||
return false;
|
||||
|
||||
if (!settingValue.ParseString(m_pObject.GetGUI(), name))
|
||||
if (!m_Setting.ParseString(m_pObject.GetGUI(), name))
|
||||
{
|
||||
LOGERROR("Invalid color '%s'", name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!ScriptInterface::FromJSVal<CColor>(rq, Value, settingValue))
|
||||
return false;
|
||||
|
||||
m_pObject.SetSetting<CGUIColor>(m_Name, settingValue, SendMessage);
|
||||
return true;
|
||||
return ScriptInterface::FromJSVal<CColor>(rq, value, m_Setting);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool CGUISetting<T>::FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage)
|
||||
bool CGUISimpleSetting<T>::DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value)
|
||||
{
|
||||
T settingValue;
|
||||
if (!ScriptInterface::FromJSVal<T>(rq, Value, settingValue))
|
||||
return false;
|
||||
|
||||
m_pObject.SetSetting<T>(m_Name, settingValue, SendMessage);
|
||||
return true;
|
||||
return ScriptInterface::FromJSVal<T>(rq, value, m_Setting);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void CGUISetting<T>::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value)
|
||||
void CGUISimpleSetting<T>::ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value)
|
||||
{
|
||||
ScriptInterface::ToJSVal<T>(rq, Value, m_pSetting);
|
||||
ScriptInterface::ToJSVal<T>(rq, value, m_Setting);
|
||||
};
|
||||
|
||||
/**
|
||||
* Explicitly instantiate CGUISimpleSetting for the basic types.
|
||||
*/
|
||||
#define TYPE(T) \
|
||||
template class CGUISetting<T>; \
|
||||
template class CGUISimpleSetting<T>;
|
||||
|
||||
TYPE(bool)
|
||||
TYPE(i32)
|
||||
TYPE(u32)
|
||||
TYPE(float)
|
||||
TYPE(CVector2D)
|
||||
#include "ps/CStr.h"
|
||||
TYPE(CStr)
|
||||
TYPE(CStrW)
|
||||
// TODO: make these inherit from CGUISimpleSetting directly.
|
||||
#include "gui/SettingTypes/CGUISize.h"
|
||||
TYPE(CGUISize)
|
||||
TYPE(CGUIColor)
|
||||
#include "gui/CGUISprite.h"
|
||||
TYPE(CGUISpriteInstance)
|
||||
#include "gui/SettingTypes/CGUIString.h"
|
||||
TYPE(CGUIString)
|
||||
#include "gui/SettingTypes/EAlign.h"
|
||||
TYPE(EAlign)
|
||||
TYPE(EVAlign)
|
||||
#include "gui/SettingTypes/CGUIList.h"
|
||||
TYPE(CGUIList)
|
||||
#include "gui/SettingTypes/CGUISeries.h"
|
||||
TYPE(CGUISeries)
|
||||
|
||||
#include "gui/GUISettingTypes.h"
|
||||
#undef TYPE
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -20,6 +20,9 @@
|
||||
|
||||
#include "gui/ObjectBases/IGUIObject.h"
|
||||
|
||||
class IGUIObject;
|
||||
class ScriptRequest;
|
||||
|
||||
/**
|
||||
* This setting interface allows GUI objects to call setting function functions without having to know the setting type.
|
||||
* This is fact is used for setting the value from a JS value or XML value (string) and when deleting the setting,
|
||||
@ -29,69 +32,94 @@ class IGUISetting
|
||||
{
|
||||
public:
|
||||
NONCOPYABLE(IGUISetting);
|
||||
IGUISetting(const CStr& name, IGUIObject* owner);
|
||||
|
||||
IGUISetting() = default;
|
||||
/**
|
||||
* Parses the given string and assigns to the setting value. Used for parsing XML attributes.
|
||||
*/
|
||||
bool FromString(const CStrW& value, const bool sendMessage);
|
||||
|
||||
/**
|
||||
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
|
||||
*/
|
||||
bool FromJSVal(const ScriptRequest& rq, JS::HandleValue value, const bool sendMessage);
|
||||
|
||||
/**
|
||||
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
|
||||
*/
|
||||
virtual void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value) = 0;
|
||||
|
||||
protected:
|
||||
IGUISetting(IGUISetting&& o);
|
||||
virtual ~IGUISetting() = default;
|
||||
|
||||
/**
|
||||
* Parses the given string and assigns to the setting value. Used for parsing XML attributes.
|
||||
*/
|
||||
virtual bool FromString(const CStrW& Value, const bool SendMessage) = 0;
|
||||
virtual bool DoFromString(const CStrW& value) = 0;
|
||||
virtual bool DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) = 0;
|
||||
|
||||
/**
|
||||
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
|
||||
* Triggers the IGUIObject logic when a setting changes.
|
||||
* This should be called by derived classes when something externally visible changes,
|
||||
* unless overloaded to provide similar behaviour.
|
||||
*/
|
||||
virtual bool FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) = 0;
|
||||
virtual void OnSettingChange(const CStr& setting, bool sendMessage);
|
||||
|
||||
/**
|
||||
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
|
||||
*/
|
||||
virtual void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value) = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CGUISetting : public IGUISetting
|
||||
{
|
||||
public:
|
||||
NONCOPYABLE(CGUISetting);
|
||||
|
||||
CGUISetting(IGUIObject& pObject, const CStr& Name, T& Value);
|
||||
|
||||
/**
|
||||
* Parses the given string and assigns to the setting value. Used for parsing XML attributes.
|
||||
*/
|
||||
bool FromString(const CStrW& Value, const bool SendMessage) override;
|
||||
|
||||
/**
|
||||
* Parses the given JS::Value using ScriptInterface::FromJSVal and assigns it to the setting data.
|
||||
*/
|
||||
bool FromJSVal(const ScriptRequest& rq, JS::HandleValue Value, const bool SendMessage) override;
|
||||
|
||||
/**
|
||||
* Converts the setting data to a JS::Value using ScriptInterface::ToJSVal.
|
||||
*/
|
||||
void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue Value) override;
|
||||
|
||||
/**
|
||||
* These members are public because they are either unmodifiable or free to be modified.
|
||||
* In particular it avoids the need for setter templates specialized depending on copiability.
|
||||
* Return the name of the setting, from JS.
|
||||
*/
|
||||
virtual CStr GetName() const = 0;
|
||||
|
||||
/**
|
||||
* The object that stores this setting.
|
||||
*/
|
||||
IGUIObject& m_pObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps a T. Makes sure the appropriate setting functions are called when modifying T,
|
||||
* and likewise makes sure that JS/xml settings affect T appropriately,
|
||||
* while being as transparent as possible to use from C++ code.
|
||||
*/
|
||||
template<typename T>
|
||||
class CGUISimpleSetting : public IGUISetting
|
||||
{
|
||||
public:
|
||||
template<typename... Args>
|
||||
CGUISimpleSetting(IGUIObject* pObject, const CStr& Name, Args&&... args)
|
||||
: IGUISetting(Name, pObject), m_Name(Name), m_Setting(args...)
|
||||
{}
|
||||
NONCOPYABLE(CGUISimpleSetting);
|
||||
MOVABLE(CGUISimpleSetting);
|
||||
|
||||
operator const T&() const { return m_Setting; }
|
||||
const T& operator*() const { return m_Setting; }
|
||||
const T* operator->() const { return &m_Setting; }
|
||||
|
||||
/**
|
||||
* Property name identifying the setting.
|
||||
* 'Uglified' getter when you want direct access without triggering messages.
|
||||
*/
|
||||
T& GetMutable() { return m_Setting; }
|
||||
|
||||
/**
|
||||
* 'Uglified' operator=, so that SendMessage is explicit.
|
||||
*/
|
||||
void Set(T value, bool sendMessage)
|
||||
{
|
||||
m_Setting = std::move(value);
|
||||
OnSettingChange(m_Name, sendMessage);
|
||||
}
|
||||
|
||||
protected:
|
||||
CStr GetName() const override
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
|
||||
bool DoFromString(const CStrW& value) override;
|
||||
bool DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) override;
|
||||
void ToJSVal(const ScriptRequest& rq, JS::MutableHandleValue value) override;
|
||||
|
||||
const CStr m_Name;
|
||||
|
||||
/**
|
||||
* Holds a reference to the value of the setting.
|
||||
* The setting value is stored in the member class to optimize for draw calls of that class.
|
||||
*/
|
||||
T& m_pSetting;
|
||||
T m_Setting;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CGUISETTINGS
|
||||
|
@ -59,7 +59,7 @@ void SGenerateTextImage::SetupSpriteCall(
|
||||
m_Indentation = Size.Width + BufferZone * 2;
|
||||
}
|
||||
|
||||
CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const IGUIObject* pObject)
|
||||
CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject)
|
||||
{
|
||||
if (string.m_Words.empty())
|
||||
return;
|
||||
@ -76,13 +76,6 @@ CGUIText::CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& Font
|
||||
int pos_last_img = -1; // Position in the string where last img (either left or right) were encountered.
|
||||
// in order to avoid duplicate processing.
|
||||
|
||||
// get the alignment type for the control we are computing the text for since
|
||||
// we are computing the horizontal alignment in this method in order to not have
|
||||
// to run through the TextCalls a second time in the CalculateTextPosition method again
|
||||
EAlign align = EAlign::LEFT;
|
||||
if (pObject->SettingExists("text_align"))
|
||||
align = pObject->GetSetting<EAlign>("text_align");
|
||||
|
||||
// Go through string word by word
|
||||
for (int i = 0; i < static_cast<int>(string.m_Words.size()) - 1; ++i)
|
||||
{
|
||||
|
@ -159,10 +159,11 @@ public:
|
||||
* can be changed by tags.
|
||||
* @param Width Width, 0 if no word-wrapping.
|
||||
* @param BufferZone space between text and edge, and space between text and images.
|
||||
* @param Align Horizontal alignment (left / center / right).
|
||||
* @param pObject Optional parameter for error output. Used *only* if error parsing fails,
|
||||
* and we need to be able to output which object the error occurred in to aid the user.
|
||||
*/
|
||||
CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const IGUIObject* pObject);
|
||||
CGUIText(const CGUI& pGUI, const CGUIString& string, const CStrW& FontW, const float Width, const float BufferZone, const EAlign align, const IGUIObject* pObject);
|
||||
|
||||
/**
|
||||
* Draw this CGUIText object
|
||||
|
@ -1,50 +0,0 @@
|
||||
/* Copyright (C) 2021 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is used by all bits of GUI code that need to repeat some code
|
||||
for a variety of types (to avoid repeating the list of types in half a dozen
|
||||
places, and to make it much easier to add a new type). Just do
|
||||
#define TYPE(T) your_code_involving_T;
|
||||
#include "gui/SettingTypes/GUISettingTypes.h"
|
||||
#undef TYPE
|
||||
to handle every possible type.
|
||||
*/
|
||||
|
||||
#ifndef GUITYPE_IGNORE_COPYABLE
|
||||
#include "gui/SettingTypes/EAlign.h"
|
||||
TYPE(bool)
|
||||
TYPE(i32)
|
||||
TYPE(u32)
|
||||
TYPE(float)
|
||||
TYPE(EAlign)
|
||||
TYPE(EVAlign)
|
||||
TYPE(CVector2D)
|
||||
#endif
|
||||
|
||||
#ifndef GUITYPE_IGNORE_NONCOPYABLE
|
||||
#include "gui/SettingTypes/CGUIList.h"
|
||||
#include "gui/SettingTypes/CGUISeries.h"
|
||||
TYPE(CGUISize)
|
||||
TYPE(CGUIColor)
|
||||
TYPE(CGUIList)
|
||||
TYPE(CGUISeries)
|
||||
TYPE(CGUISpriteInstance)
|
||||
TYPE(CGUIString)
|
||||
TYPE(CStr)
|
||||
TYPE(CStrW)
|
||||
#endif
|
@ -20,7 +20,7 @@
|
||||
#include "GUITooltip.h"
|
||||
|
||||
#include "gui/CGUI.h"
|
||||
#include "gui/ObjectBases/IGUIObject.h"
|
||||
#include "gui/ObjectTypes/CTooltip.h"
|
||||
#include "lib/timer.h"
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
@ -102,30 +102,21 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, const CVector2D& pos, const CStr&
|
||||
if (style.empty())
|
||||
return;
|
||||
|
||||
// Must be a CTooltip*
|
||||
IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style);
|
||||
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
||||
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
||||
if (!tooltipobj || !tooltipobj->SettingExists("use_object"))
|
||||
{
|
||||
LOGERROR("Cannot find tooltip named '%s'", style.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
IGUIObject* usedobj; // object actually used to display the tooltip in
|
||||
IGUIObject* usedobj; // object actually used to display the tooltip in.
|
||||
|
||||
const CStr& usedObjectName = tooltipobj->GetSetting<CStr>("use_object");
|
||||
const CStr& usedObjectName = tooltipobj->GetUsedObject();
|
||||
if (usedObjectName.empty())
|
||||
{
|
||||
usedobj = tooltipobj;
|
||||
|
||||
if (usedobj->SettingExists("_mousepos"))
|
||||
{
|
||||
usedobj->SetSetting<CVector2D>("_mousepos", pos, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR("Object '%s' used by tooltip '%s' isn't a tooltip object!", usedObjectName.c_str(), style.c_str());
|
||||
return;
|
||||
}
|
||||
tooltipobj->SetMousePos(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -148,8 +139,7 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, const CVector2D& pos, const CStr&
|
||||
return;
|
||||
}
|
||||
|
||||
// Every IGUIObject has a "hidden" setting
|
||||
usedobj->SetSetting<bool>("hidden", false, true);
|
||||
usedobj->SetHidden(false);
|
||||
}
|
||||
|
||||
void GUITooltip::HideTooltip(const CStr& style, CGUI& pGUI)
|
||||
@ -157,15 +147,14 @@ void GUITooltip::HideTooltip(const CStr& style, CGUI& pGUI)
|
||||
if (style.empty())
|
||||
return;
|
||||
|
||||
// Must be a CTooltip*
|
||||
IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style);
|
||||
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
||||
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
||||
if (!tooltipobj || !tooltipobj->SettingExists("use_object") || !tooltipobj->SettingExists("hide_object"))
|
||||
{
|
||||
LOGERROR("Cannot find tooltip named '%s' or it is not a tooltip", style.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
const CStr& usedObjectName = tooltipobj->GetSetting<CStr>("use_object");
|
||||
const CStr& usedObjectName = tooltipobj->GetUsedObject();
|
||||
if (!usedObjectName.empty())
|
||||
{
|
||||
IGUIObject* usedobj = pGUI.FindObjectByName(usedObjectName);
|
||||
@ -179,18 +168,17 @@ void GUITooltip::HideTooltip(const CStr& style, CGUI& pGUI)
|
||||
return;
|
||||
}
|
||||
|
||||
if (tooltipobj->GetSetting<bool>("hide_object"))
|
||||
// Every IGUIObject has a "hidden" setting
|
||||
usedobj->SetSetting<bool>("hidden", true, true);
|
||||
if (tooltipobj->ShouldHideObject())
|
||||
usedobj->SetHidden(true);
|
||||
}
|
||||
else
|
||||
tooltipobj->SetSetting<bool>("hidden", true, true);
|
||||
tooltipobj->SetHidden(true);
|
||||
}
|
||||
|
||||
static i32 GetTooltipDelay(const CStr& style, CGUI& pGUI)
|
||||
{
|
||||
// Must be a CTooltip*
|
||||
IGUIObject* tooltipobj = pGUI.FindObjectByName("__tooltip_" + style);
|
||||
// Objects in __tooltip_ are guaranteed to be CTooltip* by the engine.
|
||||
CTooltip* tooltipobj = static_cast<CTooltip*>(pGUI.FindObjectByName("__tooltip_" + style));
|
||||
|
||||
if (!tooltipobj)
|
||||
{
|
||||
@ -198,7 +186,7 @@ static i32 GetTooltipDelay(const CStr& style, CGUI& pGUI)
|
||||
return 500;
|
||||
}
|
||||
|
||||
return tooltipobj->GetSetting<i32>("delay");
|
||||
return tooltipobj->GetTooltipDelay();
|
||||
}
|
||||
|
||||
void GUITooltip::Update(IGUIObject* Nearest, const CVector2D& MousePos, CGUI& GUI)
|
||||
|
@ -33,17 +33,12 @@ IGUIButtonBehavior::IGUIButtonBehavior(IGUIObject& pObject)
|
||||
: m_pObject(pObject),
|
||||
m_Pressed(),
|
||||
m_PressedRight(),
|
||||
m_SoundDisabled(),
|
||||
m_SoundEnter(),
|
||||
m_SoundLeave(),
|
||||
m_SoundPressed(),
|
||||
m_SoundReleased()
|
||||
m_SoundDisabled(&pObject, "sound_disabled"),
|
||||
m_SoundEnter(&pObject, "sound_enter"),
|
||||
m_SoundLeave(&pObject, "sound_leave"),
|
||||
m_SoundPressed(&pObject, "sound_pressed"),
|
||||
m_SoundReleased(&pObject, "sound_released")
|
||||
{
|
||||
m_pObject.RegisterSetting("sound_disabled", m_SoundDisabled);
|
||||
m_pObject.RegisterSetting("sound_enter", m_SoundEnter);
|
||||
m_pObject.RegisterSetting("sound_leave", m_SoundLeave);
|
||||
m_pObject.RegisterSetting("sound_pressed", m_SoundPressed);
|
||||
m_pObject.RegisterSetting("sound_released", m_SoundReleased);
|
||||
}
|
||||
|
||||
IGUIButtonBehavior::~IGUIButtonBehavior()
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -84,12 +84,11 @@ protected:
|
||||
bool m_Pressed;
|
||||
bool m_PressedRight;
|
||||
|
||||
// Settings
|
||||
CStrW m_SoundDisabled;
|
||||
CStrW m_SoundEnter;
|
||||
CStrW m_SoundLeave;
|
||||
CStrW m_SoundPressed;
|
||||
CStrW m_SoundReleased;
|
||||
CGUISimpleSetting<CStrW> m_SoundDisabled;
|
||||
CGUISimpleSetting<CStrW> m_SoundEnter;
|
||||
CGUISimpleSetting<CStrW> m_SoundLeave;
|
||||
CGUISimpleSetting<CStrW> m_SoundPressed;
|
||||
CGUISimpleSetting<CStrW> m_SoundReleased;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -43,43 +43,22 @@ IGUIObject::IGUIObject(CGUI& pGUI)
|
||||
m_pParent(),
|
||||
m_MouseHovering(),
|
||||
m_LastClickTime(),
|
||||
m_Enabled(),
|
||||
m_Hidden(),
|
||||
m_Size(),
|
||||
m_Style(),
|
||||
m_Hotkey(),
|
||||
m_Z(),
|
||||
m_Absolute(),
|
||||
m_Ghost(),
|
||||
m_AspectRatio(),
|
||||
m_Tooltip(),
|
||||
m_TooltipStyle()
|
||||
m_Enabled(this, "enabled", true),
|
||||
m_Hidden(this, "hidden", false),
|
||||
m_Size(this, "size"),
|
||||
m_Style(this, "style"),
|
||||
m_Hotkey(this, "hotkey"),
|
||||
m_Z(this, "z"),
|
||||
m_Absolute(this, "absolute", true),
|
||||
m_Ghost(this, "ghost", false),
|
||||
m_AspectRatio(this, "aspectratio"),
|
||||
m_Tooltip(this, "tooltip"),
|
||||
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()
|
||||
{
|
||||
for (const std::pair<const CStr, IGUISetting*>& p : m_Settings)
|
||||
delete p.second;
|
||||
|
||||
if (!m_ScriptHandlers.empty())
|
||||
JS_RemoveExtraGCRootsTracer(m_pGUI.GetScriptInterface()->GetGeneralJSContext(), Trace, this);
|
||||
|
||||
@ -102,13 +81,20 @@ void IGUIObject::UnregisterChild(IGUIObject* child)
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void IGUIObject::RegisterSetting(const CStr& Name, T& Value)
|
||||
void IGUIObject::RegisterSetting(const CStr& Name, IGUISetting* setting)
|
||||
{
|
||||
if (SettingExists(Name))
|
||||
LOGERROR("The setting '%s' already exists on the object '%s'!", Name.c_str(), GetPresentableName().c_str());
|
||||
else
|
||||
m_Settings.emplace(Name, new CGUISetting<T>(*this, Name, Value));
|
||||
m_Settings.emplace(Name, setting);
|
||||
}
|
||||
|
||||
void IGUIObject::ReregisterSetting(const CStr& Name, IGUISetting* setting)
|
||||
{
|
||||
if (!SettingExists(Name))
|
||||
LOGERROR("The setting '%s' must already exist on the object '%s'!", Name.c_str(), GetPresentableName().c_str());
|
||||
else
|
||||
m_Settings.at(Name) = setting;
|
||||
}
|
||||
|
||||
bool IGUIObject::SettingExists(const CStr& Setting) const
|
||||
@ -116,18 +102,6 @@ bool IGUIObject::SettingExists(const CStr& Setting) const
|
||||
return m_Settings.find(Setting) != m_Settings.end();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& IGUIObject::GetSetting(const CStr& Setting)
|
||||
{
|
||||
return static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& IGUIObject::GetSetting(const CStr& Setting) const
|
||||
{
|
||||
return static_cast<CGUISetting<T>* >(m_Settings.at(Setting))->m_pSetting;
|
||||
}
|
||||
|
||||
bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage)
|
||||
{
|
||||
const std::map<CStr, IGUISetting*>::iterator it = m_Settings.find(Setting);
|
||||
@ -139,28 +113,6 @@ bool IGUIObject::SetSettingFromString(const CStr& Setting, const CStrW& Value, c
|
||||
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)
|
||||
{
|
||||
if (Setting == "hotkey")
|
||||
m_pGUI.UnsetObjectHotkey(this, GetSetting<CStr>(Setting));
|
||||
}
|
||||
|
||||
void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage)
|
||||
{
|
||||
if (Setting == "size")
|
||||
@ -174,10 +126,8 @@ void IGUIObject::SettingChanged(const CStr& Setting, const bool SendMessage)
|
||||
if (m_Hidden)
|
||||
RecurseObject(nullptr, &IGUIObject::ResetStates);
|
||||
}
|
||||
else if (Setting == "hotkey")
|
||||
m_pGUI.SetObjectHotkey(this, GetSetting<CStr>(Setting));
|
||||
else if (Setting == "style")
|
||||
m_pGUI.SetObjectStyle(this, GetSetting<CStr>(Setting));
|
||||
m_pGUI.SetObjectStyle(this, m_Style);
|
||||
|
||||
if (SendMessage)
|
||||
{
|
||||
@ -254,9 +204,9 @@ void IGUIObject::UpdateCachedSize()
|
||||
// use its cached size instead of the screen. Notice
|
||||
// it must have just been cached for it to work.
|
||||
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
|
||||
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
|
||||
// but maintain a constant aspect ratio.
|
||||
@ -300,7 +250,7 @@ bool IGUIObject::ApplyStyle(const CStr& StyleName)
|
||||
for (const std::pair<const CStr, CStrW>& p : m_pGUI.GetStyle(StyleName).m_SettingsDefaults)
|
||||
{
|
||||
if (SettingExists(p.first))
|
||||
SetSettingFromString(p.first, p.second, true);
|
||||
m_Settings.at(p.first)->FromString(p.second, true);
|
||||
else if (StyleName != "default")
|
||||
LOGWARNING("GUI object has no setting \"%s\", but the style \"%s\" defines it", p.first, StyleName.c_str());
|
||||
}
|
||||
@ -548,23 +498,3 @@ void IGUIObject::TraceMember(JSTracer* trc)
|
||||
for (std::pair<const CStr, JS::Heap<JSObject*>>& handler : 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
|
||||
|
@ -25,6 +25,8 @@
|
||||
#ifndef INCLUDED_IGUIOBJECT
|
||||
#define INCLUDED_IGUIOBJECT
|
||||
|
||||
#include "gui/CGUISetting.h"
|
||||
#include "gui/SettingTypes/CGUIHotkey.h"
|
||||
#include "gui/SettingTypes/CGUISize.h"
|
||||
#include "gui/SGUIMessage.h"
|
||||
#include "lib/input.h" // just for IN_PASS
|
||||
@ -55,6 +57,9 @@ class IGUIObject
|
||||
{
|
||||
friend class CGUI;
|
||||
|
||||
// For triggering message update handlers.
|
||||
friend class IGUISetting;
|
||||
|
||||
// Allow getProperty to access things like GetParent()
|
||||
template <typename T>
|
||||
friend class JSI_GUIProxy;
|
||||
@ -113,14 +118,11 @@ public:
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Registers the given setting variables with the GUI object.
|
||||
* Registers the given setting with the GUI object.
|
||||
* Enable XML and JS to modify the given variable.
|
||||
*
|
||||
* @param Type Setting type
|
||||
* @param Name Setting reference name
|
||||
*/
|
||||
template<typename T>
|
||||
void RegisterSetting(const CStr& Name, T& Value);
|
||||
void RegisterSetting(const CStr& Name, IGUISetting* setting);
|
||||
void ReregisterSetting(const CStr& Name, IGUISetting* setting);
|
||||
|
||||
/**
|
||||
* Returns whether there is a setting with the given name registered.
|
||||
@ -130,40 +132,14 @@ public:
|
||||
*/
|
||||
bool SettingExists(const CStr& Setting) const;
|
||||
|
||||
/**
|
||||
* Get a mutable reference to the setting.
|
||||
* If no such setting exists, an exception of type std::out_of_range is thrown.
|
||||
* If the value is modified, there is no GUIM_SETTINGS_UPDATED message sent.
|
||||
*/
|
||||
template <typename T>
|
||||
T& GetSetting(const CStr& Setting);
|
||||
|
||||
template <typename T>
|
||||
const T& GetSetting(const CStr& Setting) const;
|
||||
|
||||
/**
|
||||
* Set a setting by string, regardless of what type it is.
|
||||
* Used to parse setting values from XML files.
|
||||
* For example a CRect(10,10,20,20) is created from "10 10 20 20".
|
||||
* Returns false if the conversion fails, otherwise true.
|
||||
* @return false if the setting does not exist or the conversion fails, otherwise true.
|
||||
*/
|
||||
bool SetSettingFromString(const CStr& Setting, const CStrW& Value, const bool SendMessage);
|
||||
|
||||
/**
|
||||
* Assigns the given value to the setting identified by the given name.
|
||||
* Uses move semantics, so do not read from Value after this call.
|
||||
*
|
||||
* @param SendMessage If true, a GUIM_SETTINGS_UPDATED message will be broadcasted to all GUI objects.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetSetting(const CStr& Setting, T& Value, const bool SendMessage);
|
||||
|
||||
/**
|
||||
* This variant will copy the value.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetSetting(const CStr& Setting, const T& Value, const bool SendMessage);
|
||||
|
||||
/**
|
||||
* Returns whether this object is set to be hidden or ghost.
|
||||
*/
|
||||
@ -174,6 +150,8 @@ public:
|
||||
*/
|
||||
bool IsHidden() const;
|
||||
|
||||
void SetHidden(bool hidden) { m_Hidden.Set(hidden, true); }
|
||||
|
||||
/**
|
||||
* Returns whether this object is set to be hidden or ghost.
|
||||
*/
|
||||
@ -473,7 +451,6 @@ private:
|
||||
/**
|
||||
* Updates some internal data depending on the setting changed.
|
||||
*/
|
||||
void PreSettingChange(const CStr& Setting);
|
||||
void SettingChanged(const CStr& Setting, const bool SendMessage);
|
||||
|
||||
/**
|
||||
@ -545,18 +522,17 @@ protected:
|
||||
// Cached JSObject representing this GUI object.
|
||||
std::unique_ptr<IGUIProxyObject> m_JSObject;
|
||||
|
||||
// Cache references to settings for performance
|
||||
bool m_Enabled;
|
||||
bool m_Hidden;
|
||||
CGUISize m_Size;
|
||||
CStr m_Style;
|
||||
CStr m_Hotkey;
|
||||
float m_Z;
|
||||
bool m_Absolute;
|
||||
bool m_Ghost;
|
||||
float m_AspectRatio;
|
||||
CStrW m_Tooltip;
|
||||
CStr m_TooltipStyle;
|
||||
CGUISimpleSetting<bool> m_Enabled;
|
||||
CGUISimpleSetting<bool> m_Hidden;
|
||||
CGUISimpleSetting<CGUISize> m_Size;
|
||||
CGUISimpleSetting<CStr> m_Style;
|
||||
CGUIHotkey m_Hotkey;
|
||||
CGUISimpleSetting<float> m_Z;
|
||||
CGUISimpleSetting<bool> m_Absolute;
|
||||
CGUISimpleSetting<bool> m_Ghost;
|
||||
CGUISimpleSetting<float> m_AspectRatio;
|
||||
CGUISimpleSetting<CStrW> m_Tooltip;
|
||||
CGUISimpleSetting<CStr> m_TooltipStyle;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_IGUIOBJECT
|
||||
|
@ -28,8 +28,10 @@
|
||||
#include <math.h>
|
||||
|
||||
IGUITextOwner::IGUITextOwner(IGUIObject& pObject)
|
||||
: m_pObject(pObject),
|
||||
m_GeneratedTextsValid()
|
||||
: m_pObject(pObject),
|
||||
m_GeneratedTextsValid(),
|
||||
m_TextAlign(&pObject, "text_align", EAlign::LEFT),
|
||||
m_TextVAlign(&pObject, "text_valign", EVAlign::TOP)
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,7 +48,7 @@ CGUIText& IGUITextOwner::AddText()
|
||||
CGUIText& IGUITextOwner::AddText(const CGUIString& Text, const CStrW& Font, const float& Width, const float& BufferZone)
|
||||
{
|
||||
// Avoids a move constructor
|
||||
m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, &m_pObject);
|
||||
m_GeneratedTexts.emplace_back(m_pObject.GetGUI(), Text, Font, Width, BufferZone, m_TextAlign, &m_pObject);
|
||||
return m_GeneratedTexts.back();
|
||||
}
|
||||
|
||||
@ -104,7 +106,7 @@ void IGUITextOwner::CalculateTextPosition(CRect& ObjSize, CVector2D& TextPos, CG
|
||||
// loop through all of the TextCall objects again.
|
||||
TextPos.X = ObjSize.left;
|
||||
|
||||
switch (m_pObject.GetSetting<EVAlign>("text_valign"))
|
||||
switch (m_TextVAlign)
|
||||
{
|
||||
case EVAlign::TOP:
|
||||
TextPos.Y = ObjSize.top;
|
||||
|
@ -30,6 +30,8 @@ GUI Object Base - Text Owner
|
||||
#ifndef INCLUDED_IGUITEXTOWNER
|
||||
#define INCLUDED_IGUITEXTOWNER
|
||||
|
||||
#include "gui/CGUISetting.h"
|
||||
#include "gui/SettingTypes/EAlign.h"
|
||||
#include "maths/Rect.h"
|
||||
|
||||
#include <vector>
|
||||
@ -112,6 +114,9 @@ protected:
|
||||
*/
|
||||
void CalculateTextPosition(CRect& ObjSize, CVector2D& TextPos, CGUIText& Text);
|
||||
|
||||
CGUISimpleSetting<EAlign> m_TextAlign;
|
||||
CGUISimpleSetting<EVAlign> m_TextVAlign;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reference to the IGUIObject.
|
||||
|
@ -27,34 +27,18 @@ CButton::CButton(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUIButtonBehavior(*static_cast<IGUIObject*>(this)),
|
||||
IGUITextOwner(*static_cast<IGUIObject*>(this)),
|
||||
m_BufferZone(),
|
||||
m_Caption(),
|
||||
m_Font(),
|
||||
m_Sprite(),
|
||||
m_SpriteOver(),
|
||||
m_SpritePressed(),
|
||||
m_SpriteDisabled(),
|
||||
m_TextAlign(),
|
||||
m_TextVAlign(),
|
||||
m_TextColor(),
|
||||
m_TextColorOver(),
|
||||
m_TextColorPressed(),
|
||||
m_TextColorDisabled()
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Caption(this, "caption"),
|
||||
m_Font(this, "font"),
|
||||
m_Sprite(this, "sprite"),
|
||||
m_SpriteOver(this, "sprite_over"),
|
||||
m_SpritePressed(this, "sprite_pressed"),
|
||||
m_SpriteDisabled(this, "sprite_disabled"),
|
||||
m_TextColor(this, "textcolor"),
|
||||
m_TextColorOver(this, "textcolor_over"),
|
||||
m_TextColorPressed(this, "textcolor_pressed"),
|
||||
m_TextColorDisabled(this, "textcolor_disabled")
|
||||
{
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("caption", m_Caption);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
RegisterSetting("sprite_over", m_SpriteOver);
|
||||
RegisterSetting("sprite_pressed", m_SpritePressed);
|
||||
RegisterSetting("sprite_disabled", m_SpriteDisabled);
|
||||
RegisterSetting("text_align", m_TextAlign);
|
||||
RegisterSetting("text_valign", m_TextVAlign);
|
||||
RegisterSetting("textcolor", m_TextColor);
|
||||
RegisterSetting("textcolor_over", m_TextColorOver);
|
||||
RegisterSetting("textcolor_pressed", m_TextColorPressed);
|
||||
RegisterSetting("textcolor_disabled", m_TextColorDisabled);
|
||||
|
||||
AddText();
|
||||
}
|
||||
|
||||
@ -66,7 +50,7 @@ void CButton::SetupText()
|
||||
{
|
||||
ENSURE(m_GeneratedTexts.size() == 1);
|
||||
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, this);
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_CachedActualSize.GetWidth(), m_BufferZone, m_TextAlign, this);
|
||||
CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]);
|
||||
}
|
||||
|
||||
@ -110,13 +94,13 @@ void CButton::Draw()
|
||||
const CGUIColor& CButton::ChooseColor()
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return m_TextColorDisabled ? m_TextColorDisabled : m_TextColor;
|
||||
return *m_TextColorDisabled ? m_TextColorDisabled : m_TextColor;
|
||||
|
||||
if (!m_MouseHovering)
|
||||
return m_TextColor;
|
||||
|
||||
if (m_Pressed)
|
||||
return m_TextColorPressed ? m_TextColorPressed : m_TextColor;
|
||||
return *m_TextColorPressed ? m_TextColorPressed : m_TextColor;
|
||||
|
||||
return m_TextColorOver ? m_TextColorOver : m_TextColor;
|
||||
return *m_TextColorOver ? m_TextColorOver : m_TextColor;
|
||||
}
|
||||
|
@ -77,19 +77,17 @@ protected:
|
||||
virtual void CreateJSObject();
|
||||
|
||||
// Settings
|
||||
float m_BufferZone;
|
||||
CGUIString m_Caption;
|
||||
CStrW m_Font;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
CGUISpriteInstance m_SpriteOver;
|
||||
CGUISpriteInstance m_SpritePressed;
|
||||
CGUISpriteInstance m_SpriteDisabled;
|
||||
EAlign m_TextAlign;
|
||||
EVAlign m_TextVAlign;
|
||||
CGUIColor m_TextColor;
|
||||
CGUIColor m_TextColorOver;
|
||||
CGUIColor m_TextColorPressed;
|
||||
CGUIColor m_TextColorDisabled;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CGUIString> m_Caption;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteOver;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpritePressed;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteDisabled;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColor;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorOver;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorPressed;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorDisabled;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CBUTTON
|
||||
|
@ -33,25 +33,15 @@
|
||||
CChart::CChart(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUITextOwner(*static_cast<IGUIObject*>(this)),
|
||||
m_AxisColor(),
|
||||
m_AxisWidth(),
|
||||
m_BufferZone(),
|
||||
m_Font(),
|
||||
m_FormatX(),
|
||||
m_FormatY(),
|
||||
m_SeriesColor(),
|
||||
m_SeriesSetting(),
|
||||
m_TextAlign()
|
||||
m_AxisColor(this, "axis_color"),
|
||||
m_AxisWidth(this, "axis_width"),
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Font(this, "font"),
|
||||
m_FormatX(this, "format_x"),
|
||||
m_FormatY(this, "format_y"),
|
||||
m_SeriesColor(this, "series_color"),
|
||||
m_SeriesSetting(this, "series")
|
||||
{
|
||||
RegisterSetting("axis_color", m_AxisColor);
|
||||
RegisterSetting("axis_width", m_AxisWidth);
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("format_x", m_FormatX);
|
||||
RegisterSetting("format_y", m_FormatY);
|
||||
RegisterSetting("series_color", m_SeriesColor);
|
||||
RegisterSetting("series", m_SeriesSetting);
|
||||
RegisterSetting("text_align", m_TextAlign);
|
||||
}
|
||||
|
||||
CChart::~CChart()
|
||||
@ -184,16 +174,16 @@ CRect CChart::GetChartRect() const
|
||||
void CChart::UpdateSeries()
|
||||
{
|
||||
m_Series.clear();
|
||||
m_Series.resize(m_SeriesSetting.m_Series.size());
|
||||
m_Series.resize(m_SeriesSetting->m_Series.size());
|
||||
|
||||
for (size_t i = 0; i < m_SeriesSetting.m_Series.size(); ++i)
|
||||
for (size_t i = 0; i < m_SeriesSetting->m_Series.size(); ++i)
|
||||
{
|
||||
CChartData& data = m_Series[i];
|
||||
|
||||
if (i < m_SeriesColor.m_Items.size() && !data.m_Color.ParseString(m_pGUI, m_SeriesColor.m_Items[i].GetOriginalString().ToUTF8(), 0))
|
||||
LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(m_SeriesColor.m_Items[i].GetOriginalString()));
|
||||
if (i < m_SeriesColor->m_Items.size() && !data.m_Color.ParseString(m_pGUI, m_SeriesColor->m_Items[i].GetOriginalString().ToUTF8(), 0))
|
||||
LOGWARNING("GUI: Error parsing 'series_color' (\"%s\")", utf8_from_wstring(m_SeriesColor->m_Items[i].GetOriginalString()));
|
||||
|
||||
data.m_Points = m_SeriesSetting.m_Series[i];
|
||||
data.m_Points = m_SeriesSetting->m_Series[i];
|
||||
}
|
||||
UpdateBounds();
|
||||
|
||||
|
@ -82,15 +82,14 @@ protected:
|
||||
bool m_EqualX, m_EqualY;
|
||||
|
||||
// Settings
|
||||
CGUIColor m_AxisColor;
|
||||
float m_AxisWidth;
|
||||
float m_BufferZone;
|
||||
CStrW m_Font;
|
||||
CStrW m_FormatX;
|
||||
CStrW m_FormatY;
|
||||
CGUIList m_SeriesColor;
|
||||
CGUISeries m_SeriesSetting;
|
||||
EAlign m_TextAlign;
|
||||
CGUISimpleSetting<CGUIColor> m_AxisColor;
|
||||
CGUISimpleSetting<float> m_AxisWidth;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<CStrW> m_FormatX;
|
||||
CGUISimpleSetting<CStrW> m_FormatY;
|
||||
CGUISimpleSetting<CGUIList> m_SeriesColor;
|
||||
CGUISimpleSetting<CGUISeries> m_SeriesSetting;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -24,25 +24,16 @@
|
||||
CCheckBox::CCheckBox(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUIButtonBehavior(*static_cast<IGUIObject*>(this)),
|
||||
m_Checked(),
|
||||
m_SpriteUnchecked(),
|
||||
m_SpriteUncheckedOver(),
|
||||
m_SpriteUncheckedPressed(),
|
||||
m_SpriteUncheckedDisabled(),
|
||||
m_SpriteChecked(),
|
||||
m_SpriteCheckedOver(),
|
||||
m_SpriteCheckedPressed(),
|
||||
m_SpriteCheckedDisabled()
|
||||
m_Checked(this, "checked"),
|
||||
m_SpriteUnchecked(this, "sprite"),
|
||||
m_SpriteUncheckedOver(this, "sprite_over"),
|
||||
m_SpriteUncheckedPressed(this, "sprite_pressed"),
|
||||
m_SpriteUncheckedDisabled(this, "sprite_disabled"),
|
||||
m_SpriteChecked(this, "sprite2"),
|
||||
m_SpriteCheckedOver(this, "sprite2_over"),
|
||||
m_SpriteCheckedPressed(this, "sprite2_pressed"),
|
||||
m_SpriteCheckedDisabled(this, "sprite2_disabled")
|
||||
{
|
||||
RegisterSetting("checked", m_Checked),
|
||||
RegisterSetting("sprite", m_SpriteUnchecked);
|
||||
RegisterSetting("sprite_over", m_SpriteUncheckedOver);
|
||||
RegisterSetting("sprite_pressed", m_SpriteUncheckedPressed);
|
||||
RegisterSetting("sprite_disabled", m_SpriteUncheckedDisabled);
|
||||
RegisterSetting("sprite2", m_SpriteChecked);
|
||||
RegisterSetting("sprite2_over", m_SpriteCheckedOver);
|
||||
RegisterSetting("sprite2_pressed", m_SpriteCheckedPressed);
|
||||
RegisterSetting("sprite2_disabled", m_SpriteCheckedDisabled);
|
||||
}
|
||||
|
||||
CCheckBox::~CCheckBox()
|
||||
@ -64,7 +55,7 @@ void CCheckBox::HandleMessage(SGUIMessage& Message)
|
||||
{
|
||||
case GUIM_PRESSED:
|
||||
{
|
||||
SetSetting<bool>("checked", !m_Checked, true);
|
||||
m_Checked.Set(!m_Checked, true);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -47,15 +47,15 @@ public:
|
||||
|
||||
protected:
|
||||
// Settings
|
||||
bool m_Checked;
|
||||
CGUISpriteInstance m_SpriteUnchecked;
|
||||
CGUISpriteInstance m_SpriteUncheckedOver;
|
||||
CGUISpriteInstance m_SpriteUncheckedPressed;
|
||||
CGUISpriteInstance m_SpriteUncheckedDisabled;
|
||||
CGUISpriteInstance m_SpriteChecked;
|
||||
CGUISpriteInstance m_SpriteCheckedOver;
|
||||
CGUISpriteInstance m_SpriteCheckedPressed;
|
||||
CGUISpriteInstance m_SpriteCheckedDisabled;
|
||||
CGUISimpleSetting<bool> m_Checked;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteUnchecked;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteUncheckedOver;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteUncheckedPressed;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteUncheckedDisabled;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteChecked;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteCheckedOver;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteCheckedPressed;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteCheckedDisabled;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CCHECKBOX
|
||||
|
@ -32,46 +32,27 @@ CDropDown::CDropDown(CGUI& pGUI)
|
||||
m_Open(),
|
||||
m_HideScrollBar(),
|
||||
m_ElementHighlight(-1),
|
||||
m_ButtonWidth(),
|
||||
m_DropDownSize(),
|
||||
m_DropDownBuffer(),
|
||||
m_MinimumVisibleItems(),
|
||||
m_SoundClosed(),
|
||||
m_SoundEnter(),
|
||||
m_SoundLeave(),
|
||||
m_SoundOpened(),
|
||||
m_SpriteDisabled(),
|
||||
m_SpriteList(),
|
||||
m_Sprite2(),
|
||||
m_Sprite2Over(),
|
||||
m_Sprite2Pressed(),
|
||||
m_Sprite2Disabled(),
|
||||
m_TextColorDisabled(),
|
||||
m_TextVAlign()
|
||||
m_ButtonWidth(this, "button_width"),
|
||||
m_DropDownSize(this, "dropdown_size"),
|
||||
m_DropDownBuffer(this, "dropdown_buffer"),
|
||||
m_MinimumVisibleItems(this, "minimum_visible_items"),
|
||||
m_SoundClosed(this, "sound_closed"),
|
||||
m_SoundEnter(this, "sound_enter"),
|
||||
m_SoundLeave(this, "sound_leave"),
|
||||
m_SoundOpened(this, "sound_opened"),
|
||||
// Setting "sprite" is registered by CList and used as the background
|
||||
m_SpriteDisabled(this, "sprite_disabled"),
|
||||
m_SpriteList(this, "sprite_list"), // Background of the drop down list
|
||||
m_Sprite2(this, "sprite2"), // Button that sits to the right
|
||||
m_Sprite2Over(this, "sprite2_over"),
|
||||
m_Sprite2Pressed(this, "sprite2_pressed"),
|
||||
m_Sprite2Disabled(this, "sprite2_disabled"),
|
||||
m_TextColorDisabled(this, "textcolor_disabled")
|
||||
// Add these in CList! And implement TODO
|
||||
//RegisterSetting("textcolor_over");
|
||||
//RegisterSetting("textcolor_pressed");
|
||||
{
|
||||
RegisterSetting("button_width", m_ButtonWidth);
|
||||
RegisterSetting("dropdown_size", m_DropDownSize);
|
||||
RegisterSetting("dropdown_buffer", m_DropDownBuffer);
|
||||
RegisterSetting("minimum_visible_items", m_MinimumVisibleItems);
|
||||
RegisterSetting("sound_closed", m_SoundClosed);
|
||||
RegisterSetting("sound_enter", m_SoundEnter);
|
||||
RegisterSetting("sound_leave", m_SoundLeave);
|
||||
RegisterSetting("sound_opened", m_SoundOpened);
|
||||
// Setting "sprite" is registered by CList and used as the background
|
||||
RegisterSetting("sprite_disabled", m_SpriteDisabled);
|
||||
RegisterSetting("sprite_list", m_SpriteList); // Background of the drop down list
|
||||
RegisterSetting("sprite2", m_Sprite2); // Button that sits to the right
|
||||
RegisterSetting("sprite2_over", m_Sprite2Over);
|
||||
RegisterSetting("sprite2_pressed", m_Sprite2Pressed);
|
||||
RegisterSetting("sprite2_disabled", m_Sprite2Disabled);
|
||||
RegisterSetting("textcolor_disabled", m_TextColorDisabled);
|
||||
RegisterSetting("text_valign", m_TextVAlign);
|
||||
// Add these in CList! And implement TODO
|
||||
//RegisterSetting("textcolor_over");
|
||||
//RegisterSetting("textcolor_pressed");
|
||||
|
||||
// Scrollbar is forced to be true.
|
||||
SetSetting<bool>("scrollbar", true, true);
|
||||
m_ScrollBar.Set(true, true);
|
||||
}
|
||||
|
||||
CDropDown::~CDropDown()
|
||||
@ -128,7 +109,7 @@ void CDropDown::HandleMessage(SGUIMessage& Message)
|
||||
CRect rect = GetListRect();
|
||||
mouse.Y += scroll;
|
||||
int set = -1;
|
||||
for (int i = 0; i < static_cast<int>(m_List.m_Items.size()); ++i)
|
||||
for (int i = 0; i < static_cast<int>(m_List->m_Items.size()); ++i)
|
||||
{
|
||||
if (mouse.Y >= rect.top + m_ItemsYPositions[i] &&
|
||||
mouse.Y < rect.top + m_ItemsYPositions[i+1] &&
|
||||
@ -178,7 +159,7 @@ void CDropDown::HandleMessage(SGUIMessage& Message)
|
||||
|
||||
if (!m_Open)
|
||||
{
|
||||
if (m_List.m_Items.empty())
|
||||
if (m_List->m_Items.empty())
|
||||
return;
|
||||
|
||||
m_Open = true;
|
||||
@ -228,7 +209,7 @@ void CDropDown::HandleMessage(SGUIMessage& Message)
|
||||
break;
|
||||
|
||||
++m_ElementHighlight;
|
||||
SetSetting<i32>("selected", m_ElementHighlight, true);
|
||||
m_Selected.Set(m_ElementHighlight, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -243,7 +224,7 @@ void CDropDown::HandleMessage(SGUIMessage& Message)
|
||||
break;
|
||||
|
||||
--m_ElementHighlight;
|
||||
SetSetting<i32>("selected", m_ElementHighlight, true);
|
||||
m_Selected.Set(m_ElementHighlight, true);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -299,7 +280,7 @@ InReaction CDropDown::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
return IN_PASS;
|
||||
// Set current selected item to highlighted, before
|
||||
// then really processing these in CList::ManuallyHandleKeys()
|
||||
SetSetting<i32>("selected", m_ElementHighlight, true);
|
||||
m_Selected.Set(m_ElementHighlight, true);
|
||||
update_highlight = true;
|
||||
break;
|
||||
|
||||
@ -324,13 +305,13 @@ InReaction CDropDown::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
int closest = -1;
|
||||
int bestIndex = -1;
|
||||
int difference = 1250;
|
||||
for (int i = 0; i < static_cast<int>(m_List.m_Items.size()); ++i)
|
||||
for (int i = 0; i < static_cast<int>(m_List->m_Items.size()); ++i)
|
||||
{
|
||||
int indexOfDifference = 0;
|
||||
int diff = 0;
|
||||
for (size_t j = 0; j < m_InputBuffer.length(); ++j)
|
||||
{
|
||||
diff = std::abs(static_cast<int>(m_List.m_Items[i].GetRawString().LowerCase()[j]) - static_cast<int>(m_InputBuffer[j]));
|
||||
diff = std::abs(static_cast<int>(m_List->m_Items[i].GetRawString().LowerCase()[j]) - static_cast<int>(m_InputBuffer[j]));
|
||||
if (diff == 0)
|
||||
indexOfDifference = j+1;
|
||||
else
|
||||
@ -346,7 +327,7 @@ InReaction CDropDown::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
// let's select the closest element. There should basically always be one.
|
||||
if (closest != -1)
|
||||
{
|
||||
SetSetting<i32>("selected", closest, true);
|
||||
m_Selected.Set(closest, true);
|
||||
update_highlight = true;
|
||||
GetScrollBar(0).SetPos(m_ItemsYPositions[closest] - 60);
|
||||
}
|
||||
@ -453,15 +434,15 @@ void CDropDown::Draw()
|
||||
|
||||
if (!m_Enabled)
|
||||
{
|
||||
m_pGUI.DrawSprite(m_Sprite2Disabled ? m_Sprite2Disabled : m_Sprite2, bz + 0.05f, rect);
|
||||
m_pGUI.DrawSprite(*m_Sprite2Disabled ? m_Sprite2Disabled : m_Sprite2, bz + 0.05f, rect);
|
||||
}
|
||||
else if (m_Open)
|
||||
{
|
||||
m_pGUI.DrawSprite(m_Sprite2Pressed ? m_Sprite2Pressed : m_Sprite2, bz + 0.05f, rect);
|
||||
m_pGUI.DrawSprite(*m_Sprite2Pressed ? m_Sprite2Pressed : m_Sprite2, bz + 0.05f, rect);
|
||||
}
|
||||
else if (m_MouseHovering)
|
||||
{
|
||||
m_pGUI.DrawSprite(m_Sprite2Over ? m_Sprite2Over : m_Sprite2, bz + 0.05f, rect);
|
||||
m_pGUI.DrawSprite(*m_Sprite2Over ? m_Sprite2Over : m_Sprite2, bz + 0.05f, rect);
|
||||
}
|
||||
else
|
||||
m_pGUI.DrawSprite(m_Sprite2, bz + 0.05f, rect);
|
||||
@ -483,12 +464,12 @@ void CDropDown::Draw()
|
||||
|
||||
// TODO: drawScrollbar as an argument of DrawList?
|
||||
if (m_HideScrollBar)
|
||||
m_ScrollBar = false;
|
||||
m_ScrollBar.Set(false, false);
|
||||
|
||||
DrawList(m_ElementHighlight, m_SpriteList, m_SpriteSelectArea, m_TextColor);
|
||||
|
||||
if (m_HideScrollBar)
|
||||
m_ScrollBar = old;
|
||||
m_ScrollBar.Set(old, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,22 +123,21 @@ protected:
|
||||
double m_TimeOfLastInput;
|
||||
|
||||
// Settings
|
||||
float m_ButtonWidth;
|
||||
float m_DropDownSize;
|
||||
float m_DropDownBuffer;
|
||||
u32 m_MinimumVisibleItems;
|
||||
CStrW m_SoundClosed;
|
||||
CStrW m_SoundEnter;
|
||||
CStrW m_SoundLeave;
|
||||
CStrW m_SoundOpened;
|
||||
CGUISpriteInstance m_SpriteDisabled;
|
||||
CGUISpriteInstance m_SpriteList;
|
||||
CGUISpriteInstance m_Sprite2;
|
||||
CGUISpriteInstance m_Sprite2Over;
|
||||
CGUISpriteInstance m_Sprite2Pressed;
|
||||
CGUISpriteInstance m_Sprite2Disabled;
|
||||
CGUIColor m_TextColorDisabled;
|
||||
EVAlign m_TextVAlign;
|
||||
CGUISimpleSetting<float> m_ButtonWidth;
|
||||
CGUISimpleSetting<float> m_DropDownSize;
|
||||
CGUISimpleSetting<float> m_DropDownBuffer;
|
||||
CGUISimpleSetting<u32> m_MinimumVisibleItems;
|
||||
CGUISimpleSetting<CStrW> m_SoundClosed;
|
||||
CGUISimpleSetting<CStrW> m_SoundEnter;
|
||||
CGUISimpleSetting<CStrW> m_SoundLeave;
|
||||
CGUISimpleSetting<CStrW> m_SoundOpened;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteDisabled;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteList;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite2;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite2Over;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite2Pressed;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite2Disabled;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorDisabled;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CDROPDOWN
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -45,9 +45,8 @@ template<> bool ScriptInterface::FromJSVal(const ScriptRequest&, const JS::Handl
|
||||
|
||||
JSVAL_VECTOR(CHotkeyPicker::Key);
|
||||
|
||||
CHotkeyPicker::CHotkeyPicker(CGUI& pGUI) : IGUIObject(pGUI), m_TimeToCombination(1.f)
|
||||
CHotkeyPicker::CHotkeyPicker(CGUI& pGUI) : IGUIObject(pGUI), m_TimeToCombination(this, "time_to_combination", 1.f)
|
||||
{
|
||||
RegisterSetting("time_to_combination", m_TimeToCombination);
|
||||
// 8 keys at the same time is probably more than we'll ever need.
|
||||
m_KeysPressed.reserve(8);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -59,7 +59,7 @@ protected:
|
||||
void FireEvent(const CStr& event);
|
||||
|
||||
// Time without changes until a "combination" event is sent.
|
||||
float m_TimeToCombination;
|
||||
CGUISimpleSetting<float> m_TimeToCombination;
|
||||
// Time of the last registered key change.
|
||||
double m_LastKeyChange;
|
||||
|
||||
|
@ -23,9 +23,8 @@
|
||||
|
||||
CImage::CImage(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
m_Sprite()
|
||||
m_Sprite(this, "sprite")
|
||||
{
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
}
|
||||
|
||||
CImage::~CImage()
|
||||
|
@ -45,8 +45,7 @@ protected:
|
||||
*/
|
||||
virtual void Draw();
|
||||
|
||||
// Settings
|
||||
CGUISpriteInstance m_Sprite;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CIMAGE
|
||||
|
@ -56,40 +56,24 @@ CInput::CInput(CGUI& pGUI)
|
||||
m_iComposedLength(),
|
||||
m_iComposedPos(),
|
||||
m_iInsertPos(),
|
||||
m_BufferPosition(),
|
||||
m_BufferZone(),
|
||||
m_Caption(),
|
||||
m_Font(),
|
||||
m_MaskChar(),
|
||||
m_Mask(),
|
||||
m_MaxLength(),
|
||||
m_MultiLine(),
|
||||
m_Readonly(),
|
||||
m_ScrollBar(),
|
||||
m_ScrollBarStyle(),
|
||||
m_Sprite(),
|
||||
m_SpriteSelectArea(),
|
||||
m_TextColor(),
|
||||
m_TextColorSelected()
|
||||
m_BufferPosition(this, "buffer_position"),
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Caption(this, "caption"),
|
||||
m_Font(this, "font"),
|
||||
m_MaskChar(this, "mask_char"),
|
||||
m_Mask(this, "mask"),
|
||||
m_MaxLength(this, "max_length"),
|
||||
m_MultiLine(this, "multiline"),
|
||||
m_Readonly(this, "readonly"),
|
||||
m_ScrollBar(this, "scrollbar"),
|
||||
m_ScrollBarStyle(this, "scrollbar_style"),
|
||||
m_Sprite(this, "sprite"),
|
||||
m_SpriteSelectArea(this, "sprite_selectarea"),
|
||||
m_TextColor(this, "textcolor"),
|
||||
m_TextColorSelected(this, "textcolor_selected"),
|
||||
m_PlaceholderText(this, "placeholder_text"),
|
||||
m_PlaceholderColor(this, "placeholder_color")
|
||||
{
|
||||
RegisterSetting("buffer_position", m_BufferPosition);
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("caption", m_Caption);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("mask_char", m_MaskChar);
|
||||
RegisterSetting("mask", m_Mask);
|
||||
RegisterSetting("max_length", m_MaxLength);
|
||||
RegisterSetting("multiline", m_MultiLine);
|
||||
RegisterSetting("readonly", m_Readonly);
|
||||
RegisterSetting("scrollbar", m_ScrollBar);
|
||||
RegisterSetting("scrollbar_style", m_ScrollBarStyle);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
RegisterSetting("sprite_selectarea", m_SpriteSelectArea);
|
||||
RegisterSetting("textcolor", m_TextColor);
|
||||
RegisterSetting("textcolor_selected", m_TextColorSelected);
|
||||
RegisterSetting("placeholder_text", m_PlaceholderText);
|
||||
RegisterSetting("placeholder_color", m_PlaceholderColor);
|
||||
|
||||
CFG_GET_VAL("gui.cursorblinkrate", m_CursorBlinkRate);
|
||||
|
||||
CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI);
|
||||
@ -103,12 +87,12 @@ CInput::~CInput()
|
||||
|
||||
void CInput::UpdateBufferPositionSetting()
|
||||
{
|
||||
SetSetting<i32>("buffer_position", m_iBufferPos, false);
|
||||
m_BufferPosition.Set(m_iBufferPos, false);
|
||||
}
|
||||
|
||||
void CInput::ClearComposedText()
|
||||
{
|
||||
m_Caption.erase(m_iInsertPos, m_iComposedLength);
|
||||
m_Caption.GetMutable().erase(m_iInsertPos, m_iComposedLength);
|
||||
m_iBufferPos = m_iInsertPos;
|
||||
UpdateBufferPositionSetting();
|
||||
m_iComposedLength = 0;
|
||||
@ -119,6 +103,10 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
{
|
||||
ENSURE(m_iBufferPos != -1);
|
||||
|
||||
// Get direct access to silently mutate m_Caption.
|
||||
// (Messages don't currently need to be sent)
|
||||
CStrW& caption = m_Caption.GetMutable();
|
||||
|
||||
switch (ev->ev.type)
|
||||
{
|
||||
case SDL_HOTKEYDOWN:
|
||||
@ -139,7 +127,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
std::wstring text = wstring_from_utf8(ev->ev.text.text);
|
||||
|
||||
// Check max length
|
||||
if (m_MaxLength != 0 && m_Caption.length() + text.length() > static_cast<size_t>(m_MaxLength))
|
||||
if (m_MaxLength != 0 && caption.length() + text.length() > static_cast<size_t>(m_MaxLength))
|
||||
return IN_HANDLED;
|
||||
|
||||
m_WantedX = 0.0f;
|
||||
@ -153,10 +141,10 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
m_ComposingText = false;
|
||||
}
|
||||
|
||||
if (m_iBufferPos == static_cast<int>(m_Caption.length()))
|
||||
m_Caption.append(text);
|
||||
if (m_iBufferPos == static_cast<int>(caption.length()))
|
||||
caption.append(text);
|
||||
else
|
||||
m_Caption.insert(m_iBufferPos, text);
|
||||
caption.insert(m_iBufferPos, text);
|
||||
|
||||
UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1);
|
||||
|
||||
@ -197,7 +185,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
|
||||
m_ComposingText = ev->ev.edit.start != 0 || rawLength != 0;
|
||||
if (m_ComposingText)
|
||||
{
|
||||
m_Caption.insert(m_iInsertPos, wtext);
|
||||
caption.insert(m_iInsertPos, wtext);
|
||||
|
||||
// The text buffer is limited to SDL_TEXTEDITINGEVENT_TEXT_SIZE bytes, yet start
|
||||
// increases without limit, so don't let it advance beyond the composed text length
|
||||
@ -263,6 +251,10 @@ void CInput::ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
|
||||
wchar_t cooked = 0;
|
||||
|
||||
// Get direct access to silently mutate m_Caption.
|
||||
// (Messages don't currently need to be sent)
|
||||
CStrW& caption = m_Caption.GetMutable();
|
||||
|
||||
switch (keyCode)
|
||||
{
|
||||
case SDLK_TAB:
|
||||
@ -282,15 +274,15 @@ void CInput::ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
{
|
||||
m_iBufferPos_Tail = -1;
|
||||
|
||||
if (m_Caption.empty() || m_iBufferPos == 0)
|
||||
if (caption.empty() || m_iBufferPos == 0)
|
||||
break;
|
||||
|
||||
if (m_iBufferPos == static_cast<int>(m_Caption.length()))
|
||||
m_Caption = m_Caption.Left(static_cast<long>(m_Caption.length()) - 1);
|
||||
if (m_iBufferPos == static_cast<int>(caption.length()))
|
||||
caption = caption.Left(static_cast<long>(caption.length()) - 1);
|
||||
else
|
||||
m_Caption =
|
||||
m_Caption.Left(m_iBufferPos - 1) +
|
||||
m_Caption.Right(static_cast<long>(m_Caption.length()) - m_iBufferPos);
|
||||
caption =
|
||||
caption.Left(m_iBufferPos - 1) +
|
||||
caption.Right(static_cast<long>(caption.length()) - m_iBufferPos);
|
||||
|
||||
--m_iBufferPos;
|
||||
|
||||
@ -309,12 +301,12 @@ void CInput::ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
DeleteCurSelection();
|
||||
else
|
||||
{
|
||||
if (m_Caption.empty() || m_iBufferPos == static_cast<int>(m_Caption.length()))
|
||||
if (caption.empty() || m_iBufferPos == static_cast<int>(caption.length()))
|
||||
break;
|
||||
|
||||
m_Caption =
|
||||
m_Caption.Left(m_iBufferPos) +
|
||||
m_Caption.Right(static_cast<long>(m_Caption.length()) - (m_iBufferPos + 1));
|
||||
caption =
|
||||
caption.Left(m_iBufferPos) +
|
||||
caption.Right(static_cast<long>(caption.length()) - (m_iBufferPos + 1));
|
||||
|
||||
UpdateText(m_iBufferPos, m_iBufferPos + 1, m_iBufferPos);
|
||||
}
|
||||
@ -344,7 +336,7 @@ void CInput::ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
return;
|
||||
|
||||
// Check max length
|
||||
if (m_MaxLength != 0 && m_Caption.length() >= static_cast<size_t>(m_MaxLength))
|
||||
if (m_MaxLength != 0 && caption.length() >= static_cast<size_t>(m_MaxLength))
|
||||
break;
|
||||
|
||||
m_WantedX = 0.0f;
|
||||
@ -353,12 +345,12 @@ void CInput::ManuallyMutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
DeleteCurSelection();
|
||||
m_iBufferPos_Tail = -1;
|
||||
|
||||
if (m_iBufferPos == static_cast<int>(m_Caption.length()))
|
||||
m_Caption += cooked;
|
||||
if (m_iBufferPos == static_cast<int>(caption.length()))
|
||||
caption += cooked;
|
||||
else
|
||||
m_Caption =
|
||||
m_Caption.Left(m_iBufferPos) + cooked +
|
||||
m_Caption.Right(static_cast<long>(m_Caption.length()) - m_iBufferPos);
|
||||
caption =
|
||||
caption.Left(m_iBufferPos) + cooked +
|
||||
caption.Right(static_cast<long>(caption.length()) - m_iBufferPos);
|
||||
|
||||
UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos + 1);
|
||||
|
||||
@ -375,6 +367,8 @@ void CInput::ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
{
|
||||
bool shiftKeyPressed = g_scancodes[SDL_SCANCODE_LSHIFT] || g_scancodes[SDL_SCANCODE_RSHIFT];
|
||||
|
||||
const CStrW& caption = *m_Caption;
|
||||
|
||||
switch (keyCode)
|
||||
{
|
||||
case SDLK_HOME:
|
||||
@ -411,7 +405,7 @@ void CInput::ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
}
|
||||
|
||||
m_iBufferPos = static_cast<long>(m_Caption.length());
|
||||
m_iBufferPos = static_cast<long>(caption.length());
|
||||
m_WantedX = 0.0f;
|
||||
|
||||
UpdateAutoScroll();
|
||||
@ -474,7 +468,7 @@ void CInput::ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
else if (!SelectingText())
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
|
||||
if (m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
if (m_iBufferPos < static_cast<int>(caption.length()))
|
||||
++m_iBufferPos;
|
||||
}
|
||||
else
|
||||
@ -607,7 +601,7 @@ void CInput::ManuallyImmutableHandleKeyDownEvent(const SDL_Keycode keyCode)
|
||||
|
||||
void CInput::SetupGeneratedPlaceholderText()
|
||||
{
|
||||
m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, this);
|
||||
m_GeneratedPlaceholderText = CGUIText(m_pGUI, m_PlaceholderText, m_Font, 0, m_BufferZone, EAlign::LEFT, this);
|
||||
m_GeneratedPlaceholderTextValid = true;
|
||||
}
|
||||
|
||||
@ -617,6 +611,10 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
|
||||
std::string hotkey = static_cast<const char*>(ev->ev.user.data1);
|
||||
|
||||
// Get direct access to silently mutate m_Caption.
|
||||
// (Messages don't currently need to be sent)
|
||||
CStrW& caption = m_Caption.GetMutable();
|
||||
|
||||
if (hotkey == "paste")
|
||||
{
|
||||
if (m_Readonly)
|
||||
@ -632,18 +630,18 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
SDL_free(utf8_text);
|
||||
|
||||
// Check max length
|
||||
if (m_MaxLength != 0 && m_Caption.length() + text.length() > static_cast<size_t>(m_MaxLength))
|
||||
text = text.substr(0, static_cast<size_t>(m_MaxLength) - m_Caption.length());
|
||||
if (m_MaxLength != 0 && caption.length() + text.length() > static_cast<size_t>(m_MaxLength))
|
||||
text = text.substr(0, static_cast<size_t>(m_MaxLength) - caption.length());
|
||||
|
||||
if (SelectingText())
|
||||
DeleteCurSelection();
|
||||
|
||||
if (m_iBufferPos == static_cast<int>(m_Caption.length()))
|
||||
m_Caption += text;
|
||||
if (m_iBufferPos == static_cast<int>(caption.length()))
|
||||
caption += text;
|
||||
else
|
||||
m_Caption =
|
||||
m_Caption.Left(m_iBufferPos) + text +
|
||||
m_Caption.Right(static_cast<long>(m_Caption.length()) - m_iBufferPos);
|
||||
caption =
|
||||
caption.Left(m_iBufferPos) + text +
|
||||
caption.Right(static_cast<long>(caption.length()) - m_iBufferPos);
|
||||
|
||||
UpdateText(m_iBufferPos, m_iBufferPos, m_iBufferPos+1);
|
||||
|
||||
@ -678,7 +676,7 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
virtualTo = m_iBufferPos;
|
||||
}
|
||||
|
||||
CStrW text = m_Caption.Left(virtualTo).Right(virtualTo - virtualFrom);
|
||||
CStrW text = caption.Left(virtualTo).Right(virtualTo - virtualFrom);
|
||||
|
||||
SDL_SetClipboardText(text.ToUTF8().c_str());
|
||||
|
||||
@ -702,10 +700,10 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
if (SelectingText())
|
||||
DeleteCurSelection();
|
||||
|
||||
if (!m_Caption.empty() && m_iBufferPos != 0)
|
||||
if (!caption.empty() && m_iBufferPos != 0)
|
||||
{
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
CStrW searchString = m_Caption.Left(m_iBufferPos);
|
||||
CStrW searchString = caption.Left(m_iBufferPos);
|
||||
|
||||
// If we are starting in whitespace, adjust position until we get a non whitespace
|
||||
while (m_iBufferPos > 0)
|
||||
@ -748,22 +746,22 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
if (SelectingText())
|
||||
DeleteCurSelection();
|
||||
|
||||
if (!m_Caption.empty() && m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
if (!caption.empty() && m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
// Delete the word to the right of the cursor
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
|
||||
// Delete chars to the right unit we hit whitespace
|
||||
while (++m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos]) || iswpunct(m_Caption[m_iBufferPos]))
|
||||
if (iswspace(caption[m_iBufferPos]) || iswpunct(caption[m_iBufferPos]))
|
||||
break;
|
||||
}
|
||||
|
||||
// Eliminate any whitespace behind the word we just deleted
|
||||
while (m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
while (m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (!iswspace(m_Caption[m_iBufferPos]))
|
||||
if (!iswspace(caption[m_iBufferPos]))
|
||||
break;
|
||||
|
||||
++m_iBufferPos;
|
||||
@ -786,9 +784,9 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
else if (!SelectingText())
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
|
||||
if (!m_Caption.empty() && m_iBufferPos != 0)
|
||||
if (!caption.empty() && m_iBufferPos != 0)
|
||||
{
|
||||
CStrW searchString = m_Caption.Left(m_iBufferPos);
|
||||
CStrW searchString = caption.Left(m_iBufferPos);
|
||||
|
||||
// If we are starting in whitespace, adjust position until we get a non whitespace
|
||||
while (m_iBufferPos > 0)
|
||||
@ -839,19 +837,19 @@ InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev)
|
||||
else if (!SelectingText())
|
||||
m_iBufferPos_Tail = m_iBufferPos;
|
||||
|
||||
if (!m_Caption.empty() && m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
if (!caption.empty() && m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
// Select chars to the right until we hit whitespace
|
||||
while (++m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos]) || iswpunct(m_Caption[m_iBufferPos]))
|
||||
if (iswspace(caption[m_iBufferPos]) || iswpunct(caption[m_iBufferPos]))
|
||||
break;
|
||||
}
|
||||
|
||||
// Also select any whitespace following the word we just selected
|
||||
while (m_iBufferPos < static_cast<int>(m_Caption.length()))
|
||||
while (m_iBufferPos < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (!iswspace(m_Caption[m_iBufferPos]))
|
||||
if (!iswspace(caption[m_iBufferPos]))
|
||||
break;
|
||||
|
||||
++m_iBufferPos;
|
||||
@ -886,6 +884,9 @@ void CInput::HandleMessage(SGUIMessage& Message)
|
||||
IGUIObject::HandleMessage(Message);
|
||||
IGUIScrollBarOwner::HandleMessage(Message);
|
||||
|
||||
// Cleans up operator[] usage.
|
||||
const CStrW& caption = *m_Caption;
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
@ -984,20 +985,20 @@ void CInput::HandleMessage(SGUIMessage& Message)
|
||||
if (m_ComposingText)
|
||||
break;
|
||||
|
||||
if (m_Caption.empty())
|
||||
if (caption.empty())
|
||||
break;
|
||||
|
||||
m_iBufferPos = m_iBufferPos_Tail = GetMouseHoveringTextPosition();
|
||||
|
||||
if (m_iBufferPos >= (int)m_Caption.length())
|
||||
m_iBufferPos = m_iBufferPos_Tail = m_Caption.length() - 1;
|
||||
if (m_iBufferPos >= (int)caption.length())
|
||||
m_iBufferPos = m_iBufferPos_Tail = caption.length() - 1;
|
||||
|
||||
// See if we are clicking over whitespace
|
||||
if (iswspace(m_Caption[m_iBufferPos]))
|
||||
if (iswspace(caption[m_iBufferPos]))
|
||||
{
|
||||
// see if we are in a section of whitespace greater than one character
|
||||
if ((m_iBufferPos + 1 < (int) m_Caption.length() && iswspace(m_Caption[m_iBufferPos + 1])) ||
|
||||
(m_iBufferPos - 1 > 0 && iswspace(m_Caption[m_iBufferPos - 1])))
|
||||
if ((m_iBufferPos + 1 < (int) caption.length() && iswspace(caption[m_iBufferPos + 1])) ||
|
||||
(m_iBufferPos - 1 > 0 && iswspace(caption[m_iBufferPos - 1])))
|
||||
{
|
||||
//
|
||||
// We are clicking in an area with more than one whitespace character
|
||||
@ -1007,7 +1008,7 @@ void CInput::HandleMessage(SGUIMessage& Message)
|
||||
// skip the whitespace
|
||||
while (m_iBufferPos > 0)
|
||||
{
|
||||
if (!iswspace(m_Caption[m_iBufferPos - 1]))
|
||||
if (!iswspace(caption[m_iBufferPos - 1]))
|
||||
break;
|
||||
|
||||
m_iBufferPos--;
|
||||
@ -1015,52 +1016,52 @@ void CInput::HandleMessage(SGUIMessage& Message)
|
||||
// now go until we hit white space or punctuation
|
||||
while (m_iBufferPos > 0)
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos - 1]))
|
||||
if (iswspace(caption[m_iBufferPos - 1]))
|
||||
break;
|
||||
|
||||
m_iBufferPos--;
|
||||
|
||||
if (iswpunct(m_Caption[m_iBufferPos]))
|
||||
if (iswpunct(caption[m_iBufferPos]))
|
||||
break;
|
||||
}
|
||||
|
||||
// [2] Then the right
|
||||
// go right until we are not in whitespace
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (!iswspace(m_Caption[m_iBufferPos_Tail]))
|
||||
if (!iswspace(caption[m_iBufferPos_Tail]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_iBufferPos_Tail == static_cast<int>(m_Caption.length()))
|
||||
if (m_iBufferPos_Tail == static_cast<int>(caption.length()))
|
||||
break;
|
||||
|
||||
// now go to the right until we hit whitespace or punctuation
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail]))
|
||||
if (iswspace(caption[m_iBufferPos_Tail]) || iswpunct(caption[m_iBufferPos_Tail]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// single whitespace so select word to the right
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (!iswspace(m_Caption[m_iBufferPos_Tail]))
|
||||
if (!iswspace(caption[m_iBufferPos_Tail]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_iBufferPos_Tail == static_cast<int>(m_Caption.length()))
|
||||
if (m_iBufferPos_Tail == static_cast<int>(caption.length()))
|
||||
break;
|
||||
|
||||
// Don't include the leading whitespace
|
||||
m_iBufferPos = m_iBufferPos_Tail;
|
||||
|
||||
// now go to the right until we hit whitespace or punctuation
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(m_Caption.length()))
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(caption.length()))
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail]))
|
||||
if (iswspace(caption[m_iBufferPos_Tail]) || iswpunct(caption[m_iBufferPos_Tail]))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1071,17 +1072,17 @@ void CInput::HandleMessage(SGUIMessage& Message)
|
||||
// go until we hit white space or punctuation
|
||||
while (m_iBufferPos > 0)
|
||||
{
|
||||
if (iswspace(m_Caption[m_iBufferPos - 1]))
|
||||
if (iswspace(caption[m_iBufferPos - 1]))
|
||||
break;
|
||||
|
||||
m_iBufferPos--;
|
||||
|
||||
if (iswpunct(m_Caption[m_iBufferPos]))
|
||||
if (iswpunct(caption[m_iBufferPos]))
|
||||
break;
|
||||
}
|
||||
// go to the right until we hit whitespace or punctuation
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(m_Caption.length()))
|
||||
if (iswspace(m_Caption[m_iBufferPos_Tail]) || iswpunct(m_Caption[m_iBufferPos_Tail]))
|
||||
while (++m_iBufferPos_Tail < static_cast<int>(caption.length()))
|
||||
if (iswspace(caption[m_iBufferPos_Tail]) || iswpunct(caption[m_iBufferPos_Tail]))
|
||||
break;
|
||||
}
|
||||
UpdateAutoScroll();
|
||||
@ -1206,11 +1207,11 @@ void CInput::Draw()
|
||||
if (m_ScrollBar && m_MultiLine)
|
||||
IGUIScrollBarOwner::Draw();
|
||||
|
||||
CStrIntern font_name(m_Font.ToUTF8());
|
||||
CStrIntern font_name(m_Font->ToUTF8());
|
||||
|
||||
wchar_t mask_char = L'*';
|
||||
if (m_Mask && m_MaskChar.length() > 0)
|
||||
mask_char = m_MaskChar[0];
|
||||
if (m_Mask && m_MaskChar->length() > 0)
|
||||
mask_char = (*m_MaskChar)[0];
|
||||
|
||||
m_pGUI.DrawSprite(m_Sprite, bz, m_CachedActualSize);
|
||||
|
||||
@ -1407,7 +1408,7 @@ void CInput::Draw()
|
||||
if (i < (int)it->m_ListOfX.size())
|
||||
{
|
||||
if (!m_Mask)
|
||||
x_pointer += font.GetCharacterWidth(m_Caption[it->m_ListStart + i]);
|
||||
x_pointer += font.GetCharacterWidth((*m_Caption)[it->m_ListStart + i]);
|
||||
else
|
||||
x_pointer += font.GetCharacterWidth(mask_char);
|
||||
}
|
||||
@ -1493,7 +1494,7 @@ void CInput::Draw()
|
||||
if (i != (int)it->m_ListOfX.size())
|
||||
{
|
||||
if (!m_Mask)
|
||||
textRenderer.PrintfAdvance(L"%lc", m_Caption[it->m_ListStart + i]);
|
||||
textRenderer.PrintfAdvance(L"%lc", (*m_Caption)[it->m_ListStart + i]);
|
||||
else
|
||||
textRenderer.PrintfAdvance(L"%lc", mask_char);
|
||||
}
|
||||
@ -1527,7 +1528,7 @@ void CInput::Draw()
|
||||
|
||||
tech->EndPass();
|
||||
|
||||
if (m_Caption.empty() && !m_PlaceholderText.GetRawString().empty())
|
||||
if (m_Caption->empty() && !m_PlaceholderText->GetRawString().empty())
|
||||
DrawPlaceholderText(bz, cliparea);
|
||||
}
|
||||
|
||||
@ -1541,18 +1542,20 @@ void CInput::DrawPlaceholderText(float z, const CRect& clipping)
|
||||
|
||||
void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
{
|
||||
if (m_MaxLength != 0 && m_Caption.length() > static_cast<size_t>(m_MaxLength))
|
||||
m_Caption = m_Caption.substr(0, m_MaxLength);
|
||||
CStrW& caption = m_Caption.GetMutable();
|
||||
|
||||
CStrIntern font_name(m_Font.ToUTF8());
|
||||
if (m_MaxLength != 0 && caption.length() > static_cast<size_t>(m_MaxLength))
|
||||
caption = caption.substr(0, m_MaxLength);
|
||||
|
||||
CStrIntern font_name(m_Font->ToUTF8());
|
||||
|
||||
wchar_t mask_char = L'*';
|
||||
if (m_Mask && m_MaskChar.length() > 0)
|
||||
mask_char = m_MaskChar[0];
|
||||
if (m_Mask && m_MaskChar->length() > 0)
|
||||
mask_char = (*m_MaskChar)[0];
|
||||
|
||||
// Ensure positions are valid after caption changes
|
||||
m_iBufferPos = std::min(m_iBufferPos, static_cast<int>(m_Caption.size()));
|
||||
m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, static_cast<int>(m_Caption.size()));
|
||||
m_iBufferPos = std::min(m_iBufferPos, static_cast<int>(caption.size()));
|
||||
m_iBufferPos_Tail = std::min(m_iBufferPos_Tail, static_cast<int>(caption.size()));
|
||||
UpdateBufferPositionSetting();
|
||||
|
||||
if (font_name.empty())
|
||||
@ -1568,7 +1571,7 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
int to = 0; // make sure it's initialized
|
||||
|
||||
if (to_before == -1)
|
||||
to = static_cast<int>(m_Caption.length());
|
||||
to = static_cast<int>(caption.length());
|
||||
|
||||
CFontMetrics font(font_name);
|
||||
|
||||
@ -1671,7 +1674,7 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
if (destroy_row_to != m_CharacterPositions.end())
|
||||
to = destroy_row_to->m_ListStart; // notice it will iterate [from, to), so it will never reach to.
|
||||
else
|
||||
to = static_cast<int>(m_Caption.length());
|
||||
to = static_cast<int>(caption.length());
|
||||
|
||||
|
||||
// Setup the first row
|
||||
@ -1698,7 +1701,7 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
check_point_row_start += delta;
|
||||
check_point_row_end += delta;
|
||||
|
||||
if (to != static_cast<int>(m_Caption.length()))
|
||||
if (to != static_cast<int>(caption.length()))
|
||||
to += delta;
|
||||
}
|
||||
}
|
||||
@ -1711,9 +1714,9 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
|
||||
for (int i = from; i < to; ++i)
|
||||
{
|
||||
if (m_Caption[i] == L'\n' && m_MultiLine)
|
||||
if (caption[i] == L'\n' && m_MultiLine)
|
||||
{
|
||||
if (i == to-1 && to != static_cast<int>(m_Caption.length()))
|
||||
if (i == to-1 && to != static_cast<int>(caption.length()))
|
||||
break; // it will be added outside
|
||||
|
||||
current_line = m_CharacterPositions.insert(current_line, row);
|
||||
@ -1726,12 +1729,12 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_Caption[i] == L' '/* || TODO Gee (2004-10-13): the '-' disappears, fix.
|
||||
m_Caption[i] == L'-'*/)
|
||||
if (caption[i] == L' '/* || TODO Gee (2004-10-13): the '-' disappears, fix.
|
||||
caption[i] == L'-'*/)
|
||||
last_word_started = i+1;
|
||||
|
||||
if (!m_Mask)
|
||||
x_pos += font.GetCharacterWidth(m_Caption[i]);
|
||||
x_pos += font.GetCharacterWidth(caption[i]);
|
||||
else
|
||||
x_pos += font.GetCharacterWidth(mask_char);
|
||||
|
||||
@ -1856,7 +1859,7 @@ void CInput::UpdateText(int from, int to_before, int to_after)
|
||||
if (destroy_row_to != m_CharacterPositions.end())
|
||||
to = destroy_row_to->m_ListStart; // notice it will iterate [from, to[, so it will never reach to.
|
||||
else
|
||||
to = static_cast<int>(m_Caption.length());
|
||||
to = static_cast<int>(caption.length());
|
||||
|
||||
|
||||
// Set current line, new rows will be added before current_line, so
|
||||
@ -1909,7 +1912,7 @@ int CInput::GetMouseHoveringTextPosition() const
|
||||
|
||||
// Now get the height of the font.
|
||||
// TODO: Get the real font
|
||||
CFontMetrics font(CStrIntern(m_Font.ToUTF8()));
|
||||
CFontMetrics font(CStrIntern(m_Font->ToUTF8()));
|
||||
float spacing = (float)font.GetLineSpacing();
|
||||
|
||||
// Change mouse position relative to text.
|
||||
@ -2000,9 +2003,9 @@ void CInput::DeleteCurSelection()
|
||||
virtualTo = m_iBufferPos;
|
||||
}
|
||||
|
||||
m_Caption =
|
||||
m_Caption.Left(virtualFrom) +
|
||||
m_Caption.Right(static_cast<long>(m_Caption.length()) - virtualTo);
|
||||
// Silently change.
|
||||
m_Caption.Set(m_Caption->Left(virtualFrom) + m_Caption->Right(static_cast<long>(m_Caption->length()) - virtualTo),
|
||||
false);
|
||||
|
||||
UpdateText(virtualFrom, virtualTo, virtualFrom);
|
||||
|
||||
@ -2038,7 +2041,7 @@ void CInput::UpdateAutoScroll()
|
||||
|
||||
// Now get the height of the font.
|
||||
// TODO: Get the real font
|
||||
CFontMetrics font(CStrIntern(m_Font.ToUTF8()));
|
||||
CFontMetrics font(CStrIntern(m_Font->ToUTF8()));
|
||||
float spacing = (float)font.GetLineSpacing();
|
||||
//float height = font.GetHeight();
|
||||
|
||||
|
@ -216,24 +216,23 @@ protected:
|
||||
static const CStr EventNamePress;
|
||||
static const CStr EventNameTab;
|
||||
|
||||
// Settings
|
||||
i32 m_BufferPosition;
|
||||
float m_BufferZone;
|
||||
CStrW m_Caption;
|
||||
CGUIString m_PlaceholderText;
|
||||
CStrW m_Font;
|
||||
CStrW m_MaskChar;
|
||||
bool m_Mask;
|
||||
i32 m_MaxLength;
|
||||
bool m_MultiLine;
|
||||
bool m_Readonly;
|
||||
bool m_ScrollBar;
|
||||
CStr m_ScrollBarStyle;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
CGUISpriteInstance m_SpriteSelectArea;
|
||||
CGUIColor m_TextColor;
|
||||
CGUIColor m_TextColorSelected;
|
||||
CGUIColor m_PlaceholderColor;
|
||||
CGUISimpleSetting<i32> m_BufferPosition;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CStrW> m_Caption;
|
||||
CGUISimpleSetting<CGUIString> m_PlaceholderText;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<CStrW> m_MaskChar;
|
||||
CGUISimpleSetting<bool> m_Mask;
|
||||
CGUISimpleSetting<i32> m_MaxLength;
|
||||
CGUISimpleSetting<bool> m_MultiLine;
|
||||
CGUISimpleSetting<bool> m_Readonly;
|
||||
CGUISimpleSetting<bool> m_ScrollBar;
|
||||
CGUISimpleSetting<CStr> m_ScrollBarStyle;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteSelectArea;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColor;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorSelected;
|
||||
CGUISimpleSetting<CGUIColor> m_PlaceholderColor;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CINPUT
|
||||
|
@ -38,49 +38,25 @@ CList::CList(CGUI& pGUI)
|
||||
m_Modified(false),
|
||||
m_PrevSelectedItem(-1),
|
||||
m_LastItemClickTime(0),
|
||||
m_BufferZone(),
|
||||
m_Font(),
|
||||
m_ScrollBar(),
|
||||
m_ScrollBarStyle(),
|
||||
m_ScrollBottom(false),
|
||||
m_SoundDisabled(),
|
||||
m_SoundSelected(),
|
||||
m_Sprite(),
|
||||
m_SpriteSelectArea(),
|
||||
m_TextAlign(),
|
||||
m_TextColor(),
|
||||
m_TextColorSelected(),
|
||||
m_Selected(),
|
||||
m_AutoScroll(),
|
||||
m_Hovered(),
|
||||
m_List(),
|
||||
m_ListData()
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Font(this, "font"),
|
||||
m_ScrollBar(this, "scrollbar", false),
|
||||
m_ScrollBarStyle(this, "scrollbar_style"),
|
||||
m_ScrollBottom(this, "scroll_bottom", false),
|
||||
m_SoundDisabled(this, "sound_disabled"),
|
||||
m_SoundSelected(this, "sound_selected"),
|
||||
m_Sprite(this, "sprite"),
|
||||
// Add sprite_disabled! TODO
|
||||
m_SpriteSelectArea(this, "sprite_selectarea"),
|
||||
m_TextColor(this, "textcolor"),
|
||||
m_TextColorSelected(this, "textcolor_selected"),
|
||||
m_Selected(this, "selected", -1), // Index selected. -1 is none.
|
||||
m_AutoScroll(this, "auto_scroll", false),
|
||||
m_Hovered(this, "hovered", -1),
|
||||
// Each list item has both a name (in 'list') and an associated data string (in 'list_data')
|
||||
m_List(this, "list"),
|
||||
m_ListData(this, "list_data")
|
||||
{
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("scrollbar", m_ScrollBar);
|
||||
RegisterSetting("scrollbar_style", m_ScrollBarStyle);
|
||||
RegisterSetting("scroll_bottom", m_ScrollBottom);
|
||||
RegisterSetting("sound_disabled", m_SoundDisabled);
|
||||
RegisterSetting("sound_selected", m_SoundSelected);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
// Add sprite_disabled! TODO
|
||||
RegisterSetting("sprite_selectarea", m_SpriteSelectArea);
|
||||
RegisterSetting("text_align", m_TextAlign);
|
||||
RegisterSetting("textcolor", m_TextColor);
|
||||
RegisterSetting("textcolor_selected", m_TextColorSelected);
|
||||
RegisterSetting("selected", m_Selected); // Index selected. -1 is none.
|
||||
RegisterSetting("auto_scroll", m_AutoScroll);
|
||||
RegisterSetting("hovered", m_Hovered);
|
||||
// Each list item has both a name (in 'list') and an associated data string (in 'list_data')
|
||||
RegisterSetting("list", m_List);
|
||||
RegisterSetting("list_data", m_ListData);
|
||||
|
||||
SetSetting<bool>("scrollbar", false, true);
|
||||
SetSetting<i32>("selected", -1, true);
|
||||
SetSetting<i32>("hovered", -1, true);
|
||||
SetSetting<bool>("auto_scroll", false, true);
|
||||
|
||||
// Add scroll-bar
|
||||
CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI);
|
||||
bar->SetRightAligned(true);
|
||||
@ -123,14 +99,14 @@ void CList::SetupText(bool append)
|
||||
if (append && !m_ItemsYPositions.empty())
|
||||
buffered_y = m_ItemsYPositions.back();
|
||||
|
||||
m_ItemsYPositions.resize(m_List.m_Items.size() + 1);
|
||||
m_ItemsYPositions.resize(m_List->m_Items.size() + 1);
|
||||
|
||||
for (size_t i = append ? m_List.m_Items.size() - 1 : 0; i < m_List.m_Items.size(); ++i)
|
||||
for (size_t i = append ? m_List->m_Items.size() - 1 : 0; i < m_List->m_Items.size(); ++i)
|
||||
{
|
||||
CGUIText* text;
|
||||
|
||||
if (!m_List.m_Items[i].GetOriginalString().empty())
|
||||
text = &AddText(m_List.m_Items[i], m_Font, width, m_BufferZone);
|
||||
if (!m_List->m_Items[i].GetOriginalString().empty())
|
||||
text = &AddText(m_List->m_Items[i], m_Font, width, m_BufferZone);
|
||||
else
|
||||
{
|
||||
// Minimum height of a space character of the current font size
|
||||
@ -143,7 +119,7 @@ void CList::SetupText(bool append)
|
||||
buffered_y += text->GetSize().Height;
|
||||
}
|
||||
|
||||
m_ItemsYPositions[m_List.m_Items.size()] = buffered_y;
|
||||
m_ItemsYPositions[m_List->m_Items.size()] = buffered_y;
|
||||
|
||||
// Setup scrollbar
|
||||
if (m_ScrollBar)
|
||||
@ -221,7 +197,7 @@ void CList::HandleMessage(SGUIMessage& Message)
|
||||
int hovered = GetHoveredItem();
|
||||
if (hovered == -1)
|
||||
break;
|
||||
SetSetting<i32>("selected", hovered, true);
|
||||
m_Selected.Set(hovered, true);
|
||||
UpdateAutoScroll();
|
||||
PlaySound(m_SoundSelected);
|
||||
|
||||
@ -240,7 +216,7 @@ void CList::HandleMessage(SGUIMessage& Message)
|
||||
if (m_Hovered == -1)
|
||||
break;
|
||||
|
||||
SetSetting<i32>("hovered", -1, true);
|
||||
m_Hovered.Set(-1, true);
|
||||
ScriptEvent(EventNameHoverChange);
|
||||
break;
|
||||
}
|
||||
@ -251,7 +227,7 @@ void CList::HandleMessage(SGUIMessage& Message)
|
||||
if (hovered == m_Hovered)
|
||||
break;
|
||||
|
||||
SetSetting<i32>("hovered", hovered, true);
|
||||
m_Hovered.Set(hovered, true);
|
||||
ScriptEvent(EventNameHoverChange);
|
||||
break;
|
||||
}
|
||||
@ -369,7 +345,7 @@ void CList::DrawList(const int& selected, const CGUISpriteInstance& sprite, cons
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_List.m_Items.size(); ++i)
|
||||
for (size_t i = 0; i < m_List->m_Items.size(); ++i)
|
||||
{
|
||||
if (m_ItemsYPositions[i+1] - scroll < 0 ||
|
||||
m_ItemsYPositions[i] - scroll > rect.GetHeight())
|
||||
@ -400,8 +376,8 @@ void CList::DrawList(const int& selected, const CGUISpriteInstance& sprite, cons
|
||||
void CList::AddItem(const CGUIString& str, const CGUIString& data)
|
||||
{
|
||||
// Do not send a settings-changed message
|
||||
m_List.m_Items.push_back(str);
|
||||
m_ListData.m_Items.push_back(data);
|
||||
m_List.GetMutable().m_Items.push_back(str);
|
||||
m_ListData.GetMutable().m_Items.push_back(data);
|
||||
|
||||
SetupText(true);
|
||||
}
|
||||
@ -428,9 +404,9 @@ bool CList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& child
|
||||
|
||||
void CList::SelectNextElement()
|
||||
{
|
||||
if (m_Selected != static_cast<int>(m_List.m_Items.size()) - 1)
|
||||
if (m_Selected != static_cast<int>(m_List->m_Items.size()) - 1)
|
||||
{
|
||||
SetSetting<i32>("selected", m_Selected + 1, true);
|
||||
m_Selected.Set(m_Selected + 1, true);
|
||||
PlaySound(m_SoundSelected);
|
||||
}
|
||||
}
|
||||
@ -439,7 +415,7 @@ void CList::SelectPrevElement()
|
||||
{
|
||||
if (m_Selected > 0)
|
||||
{
|
||||
SetSetting<i32>("selected", m_Selected - 1, true);
|
||||
m_Selected.Set(m_Selected - 1, true);
|
||||
PlaySound(m_SoundSelected);
|
||||
}
|
||||
}
|
||||
@ -447,15 +423,15 @@ void CList::SelectPrevElement()
|
||||
void CList::SelectFirstElement()
|
||||
{
|
||||
if (m_Selected >= 0)
|
||||
SetSetting<i32>("selected", 0, true);
|
||||
m_Selected.Set(0, true);
|
||||
}
|
||||
|
||||
void CList::SelectLastElement()
|
||||
{
|
||||
const int index = static_cast<int>(m_List.m_Items.size()) - 1;
|
||||
const int index = static_cast<int>(m_List->m_Items.size()) - 1;
|
||||
|
||||
if (m_Selected != index)
|
||||
SetSetting<i32>("selected", index, true);
|
||||
m_Selected.Set(index, true);
|
||||
}
|
||||
|
||||
void CList::UpdateAutoScroll()
|
||||
@ -494,7 +470,7 @@ int CList::GetHoveredItem()
|
||||
mouse.X <= GetScrollBar(0).GetOuterRect().right)
|
||||
return -1;
|
||||
|
||||
for (size_t i = 0; i < m_List.m_Items.size(); ++i)
|
||||
for (size_t i = 0; i < m_List->m_Items.size(); ++i)
|
||||
if (mouse.Y >= rect.top + m_ItemsYPositions[i] &&
|
||||
mouse.Y < rect.top + m_ItemsYPositions[i + 1])
|
||||
return i;
|
||||
|
@ -126,24 +126,22 @@ protected:
|
||||
|
||||
virtual int GetHoveredItem();
|
||||
|
||||
// Settings
|
||||
float m_BufferZone;
|
||||
CStrW m_Font;
|
||||
bool m_ScrollBar;
|
||||
CStr m_ScrollBarStyle;
|
||||
bool m_ScrollBottom;
|
||||
CStrW m_SoundDisabled;
|
||||
CStrW m_SoundSelected;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
CGUISpriteInstance m_SpriteSelectArea;
|
||||
EAlign m_TextAlign;
|
||||
CGUIColor m_TextColor;
|
||||
CGUIColor m_TextColorSelected;
|
||||
i32 m_Selected;
|
||||
bool m_AutoScroll;
|
||||
i32 m_Hovered;
|
||||
CGUIList m_List;
|
||||
CGUIList m_ListData;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<bool> m_ScrollBar;
|
||||
CGUISimpleSetting<CStr> m_ScrollBarStyle;
|
||||
CGUISimpleSetting<bool> m_ScrollBottom;
|
||||
CGUISimpleSetting<CStrW> m_SoundDisabled;
|
||||
CGUISimpleSetting<CStrW> m_SoundSelected;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteSelectArea;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColor;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorSelected;
|
||||
CGUISimpleSetting<i32> m_Selected;
|
||||
CGUISimpleSetting<bool> m_AutoScroll;
|
||||
CGUISimpleSetting<i32> m_Hovered;
|
||||
CGUISimpleSetting<CGUIList> m_List;
|
||||
CGUISimpleSetting<CGUIList> m_ListData;
|
||||
|
||||
private:
|
||||
static const CStr EventNameSelectionChange;
|
||||
|
@ -109,11 +109,9 @@ const CStr CMiniMap::EventNameWorldClick = "WorldClick";
|
||||
CMiniMap::CMiniMap(CGUI& pGUI) :
|
||||
IGUIObject(pGUI),
|
||||
m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f),
|
||||
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(false),
|
||||
m_EntitiesDrawn(0), m_IndexArray(GL_STATIC_DRAW), m_VertexArray(GL_DYNAMIC_DRAW), m_Mask(this, "mask", false),
|
||||
m_NextBlinkTime(0.0), m_PingDuration(25.0), m_BlinkState(false), m_WaterHeight(0.0)
|
||||
{
|
||||
RegisterSetting("mask", m_Mask);
|
||||
|
||||
m_Clicking = false;
|
||||
m_MouseHovering = false;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -84,7 +84,7 @@ protected:
|
||||
bool m_TerrainDirty;
|
||||
|
||||
// Whether to draw a black square around and under the minimap.
|
||||
bool m_Mask;
|
||||
CGUISimpleSetting<bool> m_Mask;
|
||||
|
||||
ssize_t m_Width, m_Height;
|
||||
|
||||
|
@ -33,26 +33,19 @@ const CStr COList::EventNameSelectionColumnChange = "SelectionColumnChange";
|
||||
|
||||
COList::COList(CGUI& pGUI)
|
||||
: CList(pGUI),
|
||||
m_SpriteHeading(),
|
||||
m_Sortable(),
|
||||
m_SelectedColumn(),
|
||||
m_SelectedColumnOrder(),
|
||||
m_SpriteAsc(),
|
||||
m_SpriteDesc(),
|
||||
m_SpriteNotSorted()
|
||||
m_SpriteHeading(this, "sprite_heading"),
|
||||
m_Sortable(this, "sortable"), // The actual sorting is done in JS for more versatility
|
||||
m_SelectedColumn(this, "selected_column"),
|
||||
m_SelectedColumnOrder(this, "selected_column_order"),
|
||||
m_SpriteAsc(this, "sprite_asc"), // Show the order of sorting
|
||||
m_SpriteDesc(this, "sprite_desc"),
|
||||
m_SpriteNotSorted(this, "sprite_not_sorted")
|
||||
{
|
||||
RegisterSetting("sprite_heading", m_SpriteHeading);
|
||||
RegisterSetting("sortable", m_Sortable); // The actual sorting is done in JS for more versatility
|
||||
RegisterSetting("selected_column", m_SelectedColumn);
|
||||
RegisterSetting("selected_column_order", m_SelectedColumnOrder);
|
||||
RegisterSetting("sprite_asc", m_SpriteAsc); // Show the order of sorting
|
||||
RegisterSetting("sprite_desc", m_SpriteDesc);
|
||||
RegisterSetting("sprite_not_sorted", m_SpriteNotSorted);
|
||||
}
|
||||
|
||||
void COList::SetupText()
|
||||
{
|
||||
m_ItemsYPositions.resize(m_List.m_Items.size() + 1);
|
||||
m_ItemsYPositions.resize(m_List->m_Items.size() + 1);
|
||||
|
||||
// Delete all generated texts. Some could probably be saved,
|
||||
// but this is easier, and this function will never be called
|
||||
@ -82,7 +75,7 @@ void COList::SetupText()
|
||||
// Generate texts
|
||||
float buffered_y = 0.f;
|
||||
|
||||
for (size_t i = 0; i < m_List.m_Items.size(); ++i)
|
||||
for (size_t i = 0; i < m_List->m_Items.size(); ++i)
|
||||
{
|
||||
m_ItemsYPositions[i] = buffered_y;
|
||||
float shift = 0.0f;
|
||||
@ -93,8 +86,8 @@ void COList::SetupText()
|
||||
width *= m_TotalAvailableColumnWidth;
|
||||
|
||||
CGUIText* text;
|
||||
if (!column.m_List.m_Items[i].GetOriginalString().empty())
|
||||
text = &AddText(column.m_List.m_Items[i], m_Font, width, m_BufferZone);
|
||||
if (!column.m_List->m_Items[i].GetOriginalString().empty())
|
||||
text = &AddText(column.m_List->m_Items[i], m_Font, width, m_BufferZone);
|
||||
else
|
||||
{
|
||||
// Minimum height of a space character of the current font size
|
||||
@ -107,7 +100,7 @@ void COList::SetupText()
|
||||
buffered_y += shift;
|
||||
}
|
||||
|
||||
m_ItemsYPositions[m_List.m_Items.size()] = buffered_y;
|
||||
m_ItemsYPositions[m_List->m_Items.size()] = buffered_y;
|
||||
|
||||
if (m_ScrollBar)
|
||||
{
|
||||
@ -158,14 +151,14 @@ void COList::HandleMessage(SGUIMessage& Message)
|
||||
mouse.X < leftTopCorner.X + width &&
|
||||
mouse.Y < leftTopCorner.Y + m_HeadingHeight)
|
||||
{
|
||||
if (column.m_Id != m_SelectedColumn)
|
||||
if (column.m_Id != static_cast<CStr>(m_SelectedColumn))
|
||||
{
|
||||
SetSetting<i32>("selected_column_order", -1, true);
|
||||
m_SelectedColumnOrder.Set(-1, true);
|
||||
CStr selected_column = column.m_Id;
|
||||
SetSetting<CStr>("selected_column", selected_column, true);
|
||||
m_SelectedColumn.Set(selected_column, true);
|
||||
}
|
||||
else
|
||||
SetSetting<i32>("selected_column_order", -m_SelectedColumnOrder, true);
|
||||
m_SelectedColumnOrder.Set(-m_SelectedColumnOrder, true);
|
||||
|
||||
ScriptEvent(EventNameSelectionColumnChange);
|
||||
PlaySound(m_SoundSelected);
|
||||
@ -199,7 +192,14 @@ bool COList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& chil
|
||||
}
|
||||
else if (child.GetNodeName() == elmt_column)
|
||||
{
|
||||
COListColumn column;
|
||||
CStr id;
|
||||
XERO_ITER_ATTR(child, attr)
|
||||
{
|
||||
if (attr.Name == attr_id)
|
||||
id = attr.Value;
|
||||
}
|
||||
|
||||
COListColumn column(this, id);
|
||||
|
||||
for (XMBAttribute attr : child.GetAttributes())
|
||||
{
|
||||
@ -211,17 +211,13 @@ bool COList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& chil
|
||||
if (!CGUI::ParseString<CGUIColor>(&m_pGUI, attr_value.FromUTF8(), column.m_TextColor))
|
||||
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.data(), attr_value.c_str());
|
||||
}
|
||||
else if (attr_name == "id")
|
||||
{
|
||||
column.m_Id = attr_value;
|
||||
}
|
||||
else if (attr_name == "hidden")
|
||||
{
|
||||
bool hidden = false;
|
||||
if (!CGUI::ParseString<bool>(&m_pGUI, attr_value.FromUTF8(), hidden))
|
||||
LOGERROR("GUI: Error parsing '%s' (\"%s\")", attr_name.data(), attr_value.c_str());
|
||||
else
|
||||
column.m_Hidden = hidden;
|
||||
column.m_Hidden.Set(hidden, false);
|
||||
}
|
||||
else if (attr_name == "width")
|
||||
{
|
||||
@ -282,13 +278,6 @@ bool COList::HandleAdditionalChildren(const XMBData& xmb, const XMBElement& chil
|
||||
void COList::AdditionalChildrenHandled()
|
||||
{
|
||||
SetupText();
|
||||
|
||||
// Do this after the last push_back call to avoid iterator invalidation
|
||||
for (COListColumn& column : m_Columns)
|
||||
{
|
||||
RegisterSetting("list_" + column.m_Id, column.m_List);
|
||||
RegisterSetting("hidden_" + column.m_Id, column.m_Hidden);
|
||||
}
|
||||
}
|
||||
|
||||
void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, const CGUISpriteInstance& sprite_selected, const CGUIColor& textcolor)
|
||||
@ -367,18 +356,18 @@ void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, con
|
||||
if (m_Sortable)
|
||||
{
|
||||
const CGUISpriteInstance* pSprite;
|
||||
if (m_SelectedColumn == column.m_Id)
|
||||
if (*m_SelectedColumn == column.m_Id)
|
||||
{
|
||||
if (m_SelectedColumnOrder == 0)
|
||||
LOGERROR("selected_column_order must not be 0");
|
||||
|
||||
if (m_SelectedColumnOrder != -1)
|
||||
pSprite = &m_SpriteAsc;
|
||||
pSprite = &*m_SpriteAsc;
|
||||
else
|
||||
pSprite = &m_SpriteDesc;
|
||||
pSprite = &*m_SpriteDesc;
|
||||
}
|
||||
else
|
||||
pSprite = &m_SpriteNotSorted;
|
||||
pSprite = &*m_SpriteNotSorted;
|
||||
|
||||
m_pGUI.DrawSprite(*pSprite, bz + 0.1f, CRect(leftTopCorner + CVector2D(width - SORT_SPRITE_DIM, 0), leftTopCorner + CVector2D(width, SORT_SPRITE_DIM)));
|
||||
}
|
||||
@ -391,7 +380,7 @@ void COList::DrawList(const int& selected, const CGUISpriteInstance& sprite, con
|
||||
|
||||
// Draw list items for each column
|
||||
const size_t objectsCount = m_Columns.size();
|
||||
for (size_t i = 0; i < m_List.m_Items.size(); ++i)
|
||||
for (size_t i = 0; i < m_List->m_Items.size(); ++i)
|
||||
{
|
||||
if (m_ItemsYPositions[i+1] - scroll < 0 ||
|
||||
m_ItemsYPositions[i] - scroll > rect.GetHeight())
|
||||
|
@ -25,18 +25,21 @@
|
||||
/**
|
||||
* Represents a column.
|
||||
*/
|
||||
struct COListColumn
|
||||
class COListColumn
|
||||
{
|
||||
public:
|
||||
COListColumn(IGUIObject* owner, const CStr& cid)
|
||||
: m_Width(0), m_Id(cid), m_List(owner, "list_" + cid), m_Hidden(owner, "hidden_" + cid, false)
|
||||
{}
|
||||
// Avoid copying the strings.
|
||||
NONCOPYABLE(COListColumn);
|
||||
MOVABLE(COListColumn);
|
||||
COListColumn() : m_Width(0), m_Hidden(false) {}
|
||||
CGUIColor m_TextColor;
|
||||
CStr m_Id;
|
||||
float m_Width;
|
||||
CStrW m_Heading; // CGUIString??
|
||||
CGUIList m_List;
|
||||
bool m_Hidden;
|
||||
CGUISimpleSetting<CGUIList> m_List;
|
||||
CGUISimpleSetting<bool> m_Hidden;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -73,14 +76,13 @@ protected:
|
||||
*/
|
||||
std::vector<COListColumn> m_Columns;
|
||||
|
||||
// Settings
|
||||
CGUISpriteInstance m_SpriteHeading;
|
||||
bool m_Sortable;
|
||||
CStr m_SelectedColumn;
|
||||
i32 m_SelectedColumnOrder;
|
||||
CGUISpriteInstance m_SpriteAsc;
|
||||
CGUISpriteInstance m_SpriteDesc;
|
||||
CGUISpriteInstance m_SpriteNotSorted;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteHeading;
|
||||
CGUISimpleSetting<bool> m_Sortable;
|
||||
CGUISimpleSetting<CStr> m_SelectedColumn;
|
||||
CGUISimpleSetting<i32> m_SelectedColumnOrder;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteAsc;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteDesc;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteNotSorted;
|
||||
|
||||
private:
|
||||
static const CStr EventNameSelectionColumnChange;
|
||||
|
@ -23,13 +23,10 @@
|
||||
|
||||
CProgressBar::CProgressBar(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
m_SpriteBackground(),
|
||||
m_SpriteBar(),
|
||||
m_Progress()
|
||||
m_SpriteBackground(this, "sprite_background"),
|
||||
m_SpriteBar(this, "sprite_bar"),
|
||||
m_Progress(this, "progress") // Between 0 and 100.
|
||||
{
|
||||
RegisterSetting("sprite_background", m_SpriteBackground);
|
||||
RegisterSetting("sprite_bar", m_SpriteBar);
|
||||
RegisterSetting("progress", m_Progress); // between 0 and 100
|
||||
}
|
||||
|
||||
CProgressBar::~CProgressBar()
|
||||
@ -46,9 +43,9 @@ void CProgressBar::HandleMessage(SGUIMessage& Message)
|
||||
if (Message.value == "progress")
|
||||
{
|
||||
if (m_Progress > 100.f)
|
||||
SetSetting<float>("progress", 100.f, true);
|
||||
m_Progress.Set(100.f, true);
|
||||
else if (m_Progress < 0.f)
|
||||
SetSetting<float>("progress", 0.f, true);
|
||||
m_Progress.Set(0.f, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -45,9 +45,9 @@ protected:
|
||||
void HandleMessage(SGUIMessage& Message);
|
||||
|
||||
// Settings
|
||||
CGUISpriteInstance m_SpriteBackground;
|
||||
CGUISpriteInstance m_SpriteBar;
|
||||
float m_Progress;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteBackground;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteBar;
|
||||
CGUISimpleSetting<float> m_Progress;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CPROGRESSBAR
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -27,7 +27,6 @@ CRadioButton::CRadioButton(CGUI& pGUI)
|
||||
void CRadioButton::HandleMessage(SGUIMessage& Message)
|
||||
{
|
||||
IGUIButtonBehavior::HandleMessage(Message);
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
case GUIM_PRESSED:
|
||||
@ -36,10 +35,11 @@ void CRadioButton::HandleMessage(SGUIMessage& Message)
|
||||
// Notice, if you use other objects within the parent object that has got
|
||||
// the setting "checked", it too will change. Hence NO OTHER OBJECTS THAN
|
||||
// RADIO BUTTONS SHOULD BE WITHIN IT!
|
||||
obj->SetSetting<bool>("checked", false, true);
|
||||
// TODO: this should be enforced in the engine, and then we could cast IGUIObject* to CRadioButton*.
|
||||
obj->SetSettingFromString("checked", L"false", true);
|
||||
}
|
||||
|
||||
SetSetting<bool>("checked", true, true);
|
||||
m_Checked.Set(true, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2019 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -21,7 +21,7 @@
|
||||
#include "gui/ObjectTypes/CCheckBox.h"
|
||||
|
||||
/**
|
||||
* Just like a check box, but it'll nullify its siblings (of the same kind),
|
||||
* Just like a check box, but it'll nullify its siblings,
|
||||
* and it won't switch itself.
|
||||
*
|
||||
* @see CCheckBox
|
||||
|
@ -27,21 +27,14 @@ const CStr CSlider::EventNameValueChange = "ValueChange";
|
||||
CSlider::CSlider(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUIButtonBehavior(*static_cast<IGUIObject*>(this)),
|
||||
m_ButtonSide(),
|
||||
m_MaxValue(),
|
||||
m_MinValue(),
|
||||
m_Sprite(),
|
||||
m_SpriteBar(),
|
||||
m_Value()
|
||||
m_ButtonSide(this, "button_width"),
|
||||
m_MaxValue(this, "max_value"),
|
||||
m_MinValue(this, "min_value"),
|
||||
m_Sprite(this, "sprite"),
|
||||
m_SpriteBar(this, "sprite_bar"),
|
||||
m_Value(this, "value")
|
||||
{
|
||||
RegisterSetting("button_width", m_ButtonSide);
|
||||
RegisterSetting("max_value", m_MaxValue);
|
||||
RegisterSetting("min_value", m_MinValue);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
RegisterSetting("sprite_bar", m_SpriteBar);
|
||||
RegisterSetting("value", m_Value);
|
||||
|
||||
m_Value = Clamp(m_Value, m_MinValue, m_MaxValue);
|
||||
m_Value.Set(Clamp<float>(m_Value, m_MinValue, m_MaxValue), false);
|
||||
}
|
||||
|
||||
CSlider::~CSlider()
|
||||
@ -61,7 +54,7 @@ float CSlider::GetSliderRatio() const
|
||||
|
||||
void CSlider::IncrementallyChangeValue(const float difference)
|
||||
{
|
||||
m_Value = Clamp(m_Value + difference, m_MinValue, m_MaxValue);
|
||||
m_Value.Set(Clamp<float>(m_Value + difference, m_MinValue, m_MaxValue), true);
|
||||
UpdateValue();
|
||||
}
|
||||
|
||||
@ -72,11 +65,13 @@ void CSlider::HandleMessage(SGUIMessage& Message)
|
||||
|
||||
switch (Message.type)
|
||||
{
|
||||
/*
|
||||
case GUIM_SETTINGS_UPDATED:
|
||||
{
|
||||
m_Value = Clamp(m_Value, m_MinValue, m_MaxValue);
|
||||
m_Value.Set(Clamp<float>(m_Value, m_MinValue, m_MaxValue), true);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
case GUIM_MOUSE_WHEEL_DOWN:
|
||||
{
|
||||
if (m_Pressed)
|
||||
@ -119,7 +114,6 @@ void CSlider::Draw()
|
||||
|
||||
void CSlider::UpdateValue()
|
||||
{
|
||||
SetSetting<float>("value", m_Value, true);
|
||||
ScriptEvent(EventNameValueChange);
|
||||
}
|
||||
|
||||
|
@ -61,12 +61,12 @@ protected:
|
||||
void IncrementallyChangeValue(const float value);
|
||||
|
||||
// Settings
|
||||
float m_ButtonSide;
|
||||
float m_MinValue;
|
||||
float m_MaxValue;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
CGUISpriteInstance m_SpriteBar;
|
||||
float m_Value;
|
||||
CGUISimpleSetting<float> m_ButtonSide;
|
||||
CGUISimpleSetting<float> m_MinValue;
|
||||
CGUISimpleSetting<float> m_MaxValue;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_SpriteBar;
|
||||
CGUISimpleSetting<float> m_Value;
|
||||
|
||||
private:
|
||||
CVector2D m_Mouse;
|
||||
|
@ -27,38 +27,18 @@ CText::CText(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUIScrollBarOwner(*static_cast<IGUIObject*>(this)),
|
||||
IGUITextOwner(*static_cast<IGUIObject*>(this)),
|
||||
m_BufferZone(),
|
||||
m_Caption(),
|
||||
m_Clip(),
|
||||
m_Font(),
|
||||
m_ScrollBar(),
|
||||
m_ScrollBarStyle(),
|
||||
m_ScrollBottom(),
|
||||
m_ScrollTop(),
|
||||
m_Sprite(),
|
||||
m_TextAlign(),
|
||||
m_TextVAlign(),
|
||||
m_TextColor(),
|
||||
m_TextColorDisabled()
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Caption(this, "caption"),
|
||||
m_Clip(this, "clip", true),
|
||||
m_Font(this, "font"),
|
||||
m_ScrollBar(this, "scrollbar", false),
|
||||
m_ScrollBarStyle(this, "scrollbar_style"),
|
||||
m_ScrollBottom(this, "scroll_bottom"),
|
||||
m_ScrollTop(this, "scroll_top"),
|
||||
m_Sprite(this, "sprite"),
|
||||
m_TextColor(this, "textcolor"),
|
||||
m_TextColorDisabled(this, "textcolor_disabled")
|
||||
{
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("caption", m_Caption);
|
||||
RegisterSetting("clip", m_Clip);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("scrollbar", m_ScrollBar);
|
||||
RegisterSetting("scrollbar_style", m_ScrollBarStyle);
|
||||
RegisterSetting("scroll_bottom", m_ScrollBottom);
|
||||
RegisterSetting("scroll_top", m_ScrollTop);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
RegisterSetting("text_align", m_TextAlign);
|
||||
RegisterSetting("text_valign", m_TextVAlign);
|
||||
RegisterSetting("textcolor", m_TextColor);
|
||||
RegisterSetting("textcolor_disabled", m_TextColorDisabled);
|
||||
|
||||
//SetSetting<bool>("ghost", true, true);
|
||||
SetSetting<bool>("scrollbar", false, true);
|
||||
SetSetting<bool>("clip", true, true);
|
||||
|
||||
// Add scroll-bar
|
||||
CGUIScrollBarVertical* bar = new CGUIScrollBarVertical(pGUI);
|
||||
bar->SetRightAligned(true);
|
||||
@ -82,7 +62,7 @@ void CText::SetupText()
|
||||
if (m_ScrollBar && GetScrollBar(0).GetStyle())
|
||||
width -= GetScrollBar(0).GetStyle()->m_Width;
|
||||
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, this);
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, width, m_BufferZone, m_TextAlign, this);
|
||||
|
||||
if (!m_ScrollBar)
|
||||
CalculateTextPosition(m_CachedActualSize, m_TextPos, m_GeneratedTexts[0]);
|
||||
|
@ -74,20 +74,17 @@ protected:
|
||||
*/
|
||||
CVector2D m_TextPos;
|
||||
|
||||
// Settings
|
||||
float m_BufferZone;
|
||||
CGUIString m_Caption;
|
||||
bool m_Clip;
|
||||
CStrW m_Font;
|
||||
bool m_ScrollBar;
|
||||
CStr m_ScrollBarStyle;
|
||||
bool m_ScrollBottom;
|
||||
bool m_ScrollTop;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
EAlign m_TextAlign;
|
||||
EVAlign m_TextVAlign;
|
||||
CGUIColor m_TextColor;
|
||||
CGUIColor m_TextColorDisabled;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CGUIString> m_Caption;
|
||||
CGUISimpleSetting<bool> m_Clip;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<bool> m_ScrollBar;
|
||||
CGUISimpleSetting<CStr> m_ScrollBarStyle;
|
||||
CGUISimpleSetting<bool> m_ScrollBottom;
|
||||
CGUISimpleSetting<bool> m_ScrollTop;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColor;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColorDisabled;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CTEXT
|
||||
|
@ -28,46 +28,24 @@
|
||||
CTooltip::CTooltip(CGUI& pGUI)
|
||||
: IGUIObject(pGUI),
|
||||
IGUITextOwner(*static_cast<IGUIObject*>(this)),
|
||||
m_BufferZone(),
|
||||
m_Caption(),
|
||||
m_Font(),
|
||||
m_Sprite(),
|
||||
m_Delay(),
|
||||
m_TextColor(),
|
||||
m_MaxWidth(),
|
||||
m_Offset(),
|
||||
m_Anchor(),
|
||||
m_TextAlign(),
|
||||
m_Independent(),
|
||||
m_MousePos(),
|
||||
m_UseObject(),
|
||||
m_HideObject()
|
||||
m_BufferZone(this, "buffer_zone"),
|
||||
m_Caption(this, "caption"),
|
||||
m_Font(this, "font"),
|
||||
m_Sprite(this, "sprite"),
|
||||
m_Delay(this, "delay", 500), // in milliseconds
|
||||
m_TextColor(this, "textcolor"),
|
||||
m_MaxWidth(this, "maxwidth"),
|
||||
m_Offset(this, "offset"),
|
||||
m_Anchor(this, "anchor", EVAlign::BOTTOM),
|
||||
// This is used for tooltips that are hidden/revealed manually by scripts, rather than through the standard tooltip display mechanism
|
||||
m_Independent(this, "independent"),
|
||||
// Private settings:
|
||||
// This is set by GUITooltip
|
||||
m_MousePos(this, "_mousepos"),
|
||||
// If the tooltip is just a reference to another object:
|
||||
m_UseObject(this, "use_object"),
|
||||
m_HideObject(this, "hide_object")
|
||||
{
|
||||
// If the tooltip is an object by itself:
|
||||
RegisterSetting("buffer_zone", m_BufferZone);
|
||||
RegisterSetting("caption", m_Caption);
|
||||
RegisterSetting("font", m_Font);
|
||||
RegisterSetting("sprite", m_Sprite);
|
||||
RegisterSetting("delay", m_Delay); // in milliseconds
|
||||
RegisterSetting("textcolor", m_TextColor);
|
||||
RegisterSetting("maxwidth", m_MaxWidth);
|
||||
RegisterSetting("offset", m_Offset);
|
||||
RegisterSetting("anchor", m_Anchor);
|
||||
RegisterSetting("text_align", m_TextAlign);
|
||||
// This is used for tooltips that are hidden/revealed manually by scripts, rather than through the standard tooltip display mechanism
|
||||
RegisterSetting("independent", m_Independent);
|
||||
// Private settings:
|
||||
// This is set by GUITooltip
|
||||
RegisterSetting("_mousepos", m_MousePos);
|
||||
// If the tooltip is just a reference to another object:
|
||||
RegisterSetting("use_object", m_UseObject);
|
||||
RegisterSetting("hide_object", m_HideObject);
|
||||
|
||||
// Defaults
|
||||
SetSetting<i32>("delay", 500, true);
|
||||
SetSetting<EVAlign>("anchor", EVAlign::BOTTOM, true);
|
||||
SetSetting<EAlign>("text_align", EAlign::LEFT, true);
|
||||
|
||||
// Set up a blank piece of text, to be replaced with a more
|
||||
// interesting message later
|
||||
AddText();
|
||||
@ -81,7 +59,7 @@ void CTooltip::SetupText()
|
||||
{
|
||||
ENSURE(m_GeneratedTexts.size() == 1);
|
||||
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, this);
|
||||
m_GeneratedTexts[0] = CGUIText(m_pGUI, m_Caption, m_Font, m_MaxWidth, m_BufferZone, m_TextAlign, this);
|
||||
|
||||
// Position the tooltip relative to the mouse:
|
||||
|
||||
@ -91,21 +69,21 @@ void CTooltip::SetupText()
|
||||
float textheight = m_GeneratedTexts[0].GetSize().Height;
|
||||
|
||||
CGUISize size;
|
||||
size.pixel.left = mousepos.X + m_Offset.X;
|
||||
size.pixel.left = mousepos.X + m_Offset->X;
|
||||
size.pixel.right = size.pixel.left + textwidth;
|
||||
|
||||
switch (m_Anchor)
|
||||
{
|
||||
case EVAlign::TOP:
|
||||
size.pixel.top = mousepos.Y + m_Offset.Y;
|
||||
size.pixel.top = mousepos.Y + m_Offset->Y;
|
||||
size.pixel.bottom = size.pixel.top + textheight;
|
||||
break;
|
||||
case EVAlign::BOTTOM:
|
||||
size.pixel.bottom = mousepos.Y + m_Offset.Y;
|
||||
size.pixel.bottom = mousepos.Y + m_Offset->Y;
|
||||
size.pixel.top = size.pixel.bottom - textheight;
|
||||
break;
|
||||
case EVAlign::CENTER:
|
||||
size.pixel.top = mousepos.Y + m_Offset.Y - textheight/2.f;
|
||||
size.pixel.top = mousepos.Y + m_Offset->Y - textheight/2.f;
|
||||
size.pixel.bottom = size.pixel.top + textwidth;
|
||||
break;
|
||||
default:
|
||||
@ -130,7 +108,7 @@ void CTooltip::SetupText()
|
||||
else if (size.pixel.right > screenw)
|
||||
size.pixel.left -= (size.pixel.right-screenw), size.pixel.right = screenw;
|
||||
|
||||
SetSetting<CGUISize>("size", size, true);
|
||||
m_Size.Set(size, true);
|
||||
}
|
||||
|
||||
void CTooltip::UpdateCachedSize()
|
||||
|
@ -35,6 +35,11 @@ public:
|
||||
CTooltip(CGUI& pGUI);
|
||||
virtual ~CTooltip();
|
||||
|
||||
const CStr& GetUsedObject() const { return m_UseObject; }
|
||||
i32 GetTooltipDelay() const { return m_Delay; }
|
||||
bool ShouldHideObject() const { return m_HideObject; }
|
||||
void SetMousePos(const CVector2D& vec) { m_MousePos.Set(vec, true); }
|
||||
|
||||
protected:
|
||||
void SetupText();
|
||||
|
||||
@ -52,21 +57,19 @@ protected:
|
||||
|
||||
virtual float GetBufferedZ() const;
|
||||
|
||||
// Settings
|
||||
float m_BufferZone;
|
||||
CGUIString m_Caption;
|
||||
CStrW m_Font;
|
||||
CGUISpriteInstance m_Sprite;
|
||||
i32 m_Delay;
|
||||
CGUIColor m_TextColor;
|
||||
float m_MaxWidth;
|
||||
CVector2D m_Offset;
|
||||
EVAlign m_Anchor;
|
||||
EAlign m_TextAlign;
|
||||
bool m_Independent;
|
||||
CVector2D m_MousePos;
|
||||
CStr m_UseObject;
|
||||
bool m_HideObject;
|
||||
CGUISimpleSetting<float> m_BufferZone;
|
||||
CGUISimpleSetting<CGUIString> m_Caption;
|
||||
CGUISimpleSetting<CStrW> m_Font;
|
||||
CGUISimpleSetting<CGUISpriteInstance> m_Sprite;
|
||||
CGUISimpleSetting<i32> m_Delay;
|
||||
CGUISimpleSetting<CGUIColor> m_TextColor;
|
||||
CGUISimpleSetting<float> m_MaxWidth;
|
||||
CGUISimpleSetting<CVector2D> m_Offset;
|
||||
CGUISimpleSetting<EVAlign> m_Anchor;
|
||||
CGUISimpleSetting<bool> m_Independent;
|
||||
CGUISimpleSetting<CVector2D> m_MousePos;
|
||||
CGUISimpleSetting<CStr> m_UseObject;
|
||||
CGUISimpleSetting<bool> m_HideObject;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CTOOLTIP
|
||||
|
46
source/gui/SettingTypes/CGUIHotkey.cpp
Normal file
46
source/gui/SettingTypes/CGUIHotkey.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/* Copyright (C) 2021 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/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "CGUIHotkey.h"
|
||||
|
||||
#include "gui/ObjectBases/IGUIObject.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
|
||||
bool CGUIHotkey::DoFromString(const CStrW& value)
|
||||
{
|
||||
m_pObject.GetGUI().UnsetObjectHotkey(&m_pObject, m_Setting);
|
||||
m_Setting = value.ToUTF8();
|
||||
m_pObject.GetGUI().SetObjectHotkey(&m_pObject, m_Setting);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGUIHotkey::DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value)
|
||||
{
|
||||
m_pObject.GetGUI().UnsetObjectHotkey(&m_pObject, m_Setting);
|
||||
if (!ScriptInterface::FromJSVal(rq, value, m_Setting))
|
||||
return false;
|
||||
m_pObject.GetGUI().SetObjectHotkey(&m_pObject, m_Setting);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGUIHotkey::OnSettingChange(const CStr& setting, bool sendMessage)
|
||||
{
|
||||
IGUISetting::OnSettingChange(setting, sendMessage);
|
||||
}
|
||||
|
40
source/gui/SettingTypes/CGUIHotkey.h
Normal file
40
source/gui/SettingTypes/CGUIHotkey.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* Copyright (C) 2021 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/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CGUIHOTKEY
|
||||
#define INCLUDED_CGUIHOTKEY
|
||||
|
||||
#include "gui/CGUISetting.h"
|
||||
#include "ps/CStr.h"
|
||||
|
||||
/**
|
||||
* Manages a hotkey setting for a GUI object.
|
||||
*/
|
||||
class CGUIHotkey : public CGUISimpleSetting<CStr>
|
||||
{
|
||||
public:
|
||||
CGUIHotkey(IGUIObject* pObject, const CStr& Name) : CGUISimpleSetting<CStr>(pObject, Name)
|
||||
{}
|
||||
NONCOPYABLE(CGUIHotkey);
|
||||
MOVABLE(CGUIHotkey);
|
||||
|
||||
bool DoFromString(const CStrW& value) override;
|
||||
bool DoFromJSVal(const ScriptRequest& rq, JS::HandleValue value) override;
|
||||
void OnSettingChange(const CStr& setting, bool sendMessage) override;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_CGUIHOTKEY
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2020 Wildfire Games.
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -59,6 +59,7 @@ template<typename T> static bool FromJSVal_vector(const ScriptRequest& rq, JS::H
|
||||
if (!JS::GetArrayLength(rq.cx, obj, &length))
|
||||
FAIL("Failed to get array length");
|
||||
|
||||
out.clear();
|
||||
out.reserve(length);
|
||||
for (u32 i = 0; i < length; ++i)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user