Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Client/gui/CGUIElement_Impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,3 +733,30 @@ inline void CGUIElement_Impl::ForceRedraw()
{
m_pWindow->forceRedraw();
}

namespace {
void RecursivelyForceRedrawAutoWindows(CEGUI::Window* pWindow)
{
for (uint i = 0; i < pWindow->getChildCount(); ++i)
{
CEGUI::Window* pChild = pWindow->getChildAtIdx(i);
if (pChild->getName().find("__auto_") != CEGUI::String::npos)
{
pChild->forceRedraw();
RecursivelyForceRedrawAutoWindows(pChild);
}
}
}
}

void CGUIElement_Impl::SetColorCodesEnabled(bool bEnabled)
{
m_pWindow->setUserString("ColorCodesEnabled", bEnabled ? "True" : "False");
m_pWindow->forceRedraw();
RecursivelyForceRedrawAutoWindows(m_pWindow);
}

bool CGUIElement_Impl::GetColorCodesEnabled()
{
return m_pWindow->isUserStringDefined("ColorCodesEnabled") && m_pWindow->getUserString("ColorCodesEnabled") == "True";
}
3 changes: 3 additions & 0 deletions Client/gui/CGUIElement_Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class CGUIElement_Impl : public CGUIElement

void ForceRedraw();

void SetColorCodesEnabled(bool bEnabled);
bool GetColorCodesEnabled();

void SetUserData(void* pData) { m_pData = pData; }
void* GetUserData() { return m_pData; }

Expand Down
13 changes: 13 additions & 0 deletions Client/gui/CGUIElement_Inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,19 @@ void ForceRedraw()
{
CGUIElement_Impl::ForceRedraw();
};

// Forwarding methods to the base CGUIElement_Impl implementation to resolve
// diamond multiple-inheritance issues so subclasses aren't treated as abstract.
#ifndef SETCOLORCODESENABLED_HACK
void SetColorCodesEnabled(bool bEnabled)
{
CGUIElement_Impl::SetColorCodesEnabled(bEnabled);
};
#endif
bool GetColorCodesEnabled()
{
return CGUIElement_Impl::GetColorCodesEnabled();
};
void SetAlwaysOnTop(bool bAlwaysOnTop)
{
CGUIElement_Impl::SetAlwaysOnTop(bAlwaysOnTop);
Expand Down
20 changes: 20 additions & 0 deletions Client/gui/CGUITab_Impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,23 @@ bool CGUITab_Impl::IsEnabled()
CEGUI::TabControl* pControl = reinterpret_cast<CEGUI::TabControl*>(((CGUITabPanel_Impl*)pParent)->m_pWindow);
return !pControl->getButtonForTabContents(m_pWindow)->isDisabled();
}

void CGUITab_Impl::SetColorCodesEnabled(bool bEnabled)
{
CGUIElement_Impl::SetColorCodesEnabled(bEnabled);

if (m_pParent && m_pParent->GetType() == CGUI_TABPANEL)
{
CGUIElement_Impl* pParent = static_cast<CGUIElement_Impl*>(m_pParent);
CEGUI::TabControl* pTabControl = reinterpret_cast<CEGUI::TabControl*>(((CGUITabPanel_Impl*)pParent)->m_pWindow);
if (pTabControl)
{
CEGUI::TabButton* pButton = pTabControl->getButtonForTabContents(m_pWindow);
if (pButton)
{
pButton->setUserString("ColorCodesEnabled", bEnabled ? "True" : "False");
pButton->forceRedraw();
}
}
}
}
4 changes: 4 additions & 0 deletions Client/gui/CGUITab_Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ class CGUITab_Impl : public CGUITab, public CGUIElement_Impl, public CGUITabList

#define SETVISIBLE_HACK
#define SETENABLED_HACK
#define SETCOLORCODESENABLED_HACK
#include "CGUIElement_Inc.h"
#undef SETCOLORCODESENABLED_HACK
#undef SETENABLED_HACK
#undef SETVISIBLE_HACK

void SetVisible(bool bVisible);
bool IsVisible();
void SetEnabled(bool bEnabled);
bool IsEnabled();

void SetColorCodesEnabled(bool bEnabled);
};
72 changes: 72 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ void CLuaGUIDefs::LoadFunctions()
{"guiGetProperty", GUIGetProperty},
{"guiGetProperties", GUIGetProperties},
{"guiGetAlpha", GUIGetAlpha},
{"guiSetColorCodesEnabled", GUISetColorCodesEnabled},
{"guiGetColorCodesEnabled", GUIGetColorCodesEnabled},
{"guiGetText", GUIGetText},
{"guiGetFont", GUIGetFont},
{"guiGetSize", GUIGetSize},
Expand Down Expand Up @@ -249,6 +251,7 @@ void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM)
lua_classfunction(luaVM, "getScreenSize", "guiGetScreenSize");
lua_classfunction(luaVM, "getProperties", "guiGetProperties");
lua_classfunction(luaVM, "getAlpha", "guiGetAlpha");
lua_classfunction(luaVM, "getColorCodesEnabled", "guiGetColorCodesEnabled");
lua_classfunction(luaVM, "getFont", "guiGetFont");
lua_classfunction(luaVM, "getEnabled", "guiGetEnabled");
lua_classfunction(luaVM, "getVisible", "guiGetVisible");
Expand All @@ -259,6 +262,7 @@ void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM)

lua_classfunction(luaVM, "setInputEnabled", "guiSetInputEnabled");
lua_classfunction(luaVM, "setAlpha", "guiSetAlpha");
lua_classfunction(luaVM, "setColorCodesEnabled", "guiSetColorCodesEnabled");
lua_classfunction(luaVM, "setEnabled", "guiSetEnabled");
lua_classfunction(luaVM, "setFont", "guiSetFont");
lua_classfunction(luaVM, "setVisible", "guiSetVisible");
Expand All @@ -282,6 +286,7 @@ void CLuaGUIDefs::AddGuiElementClass(lua_State* luaVM)
lua_classvariable(luaVM, "visible", "guiSetVisible", "guiGetVisible");
lua_classvariable(luaVM, "properties", NULL, "guiGetProperties");
lua_classvariable(luaVM, "alpha", "guiSetAlpha", "guiGetAlpha");
lua_classvariable(luaVM, "colorCodesEnabled", "guiSetColorCodesEnabled", "guiGetColorCodesEnabled");
lua_classvariable(luaVM, "enabled", "guiSetEnabled", "guiGetEnabled");
lua_classvariable(luaVM, "text", "guiSetText", "guiGetText");
lua_classvariable(luaVM, "size", "guiSetSize", "guiGetSize");
Expand Down Expand Up @@ -1864,6 +1869,73 @@ int CLuaGUIDefs::GUIGetAlpha(lua_State* luaVM)
return 1;
}

static void RecursivelySetColorCodesEnabled(CClientGUIElement* pElement, bool bEnabled)
{
pElement->GetCGUIElement()->SetColorCodesEnabled(bEnabled);
CElementListSnapshotRef pSnapshot = pElement->GetChildrenListSnapshot();
for (CClientEntity* pChild : *pSnapshot)
{
if (pChild->GetType() == CCLIENTGUI)
{
RecursivelySetColorCodesEnabled(static_cast<CClientGUIElement*>(pChild), bEnabled);
}
}
}

int CLuaGUIDefs::GUISetColorCodesEnabled(lua_State* luaVM)
{
// bool guiSetColorCodesEnabled ( element guiElement, bool enabled [, bool includeChildren = false ] )
CClientGUIElement* guiElement;
bool bEnabled;
bool bIncludeChildren = false;

CScriptArgReader argStream(luaVM);
argStream.ReadUserData(guiElement);
argStream.ReadBool(bEnabled);
if (argStream.NextIsBool())
argStream.ReadBool(bIncludeChildren);

if (!argStream.HasErrors())
{
if (bIncludeChildren)
{
RecursivelySetColorCodesEnabled(guiElement, bEnabled);
}
else
{
guiElement->GetCGUIElement()->SetColorCodesEnabled(bEnabled);
}

lua_pushboolean(luaVM, true);
return 1;
}
else
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());

lua_pushboolean(luaVM, false);
return 1;
}

int CLuaGUIDefs::GUIGetColorCodesEnabled(lua_State* luaVM)
{
// bool guiGetColorCodesEnabled ( element guiElement )
CClientGUIElement* guiElement;

CScriptArgReader argStream(luaVM);
argStream.ReadUserData(guiElement);

if (!argStream.HasErrors())
{
lua_pushboolean(luaVM, guiElement->GetCGUIElement()->GetColorCodesEnabled());
return 1;
}
else
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());

lua_pushboolean(luaVM, false);
return 1;
}

int CLuaGUIDefs::GUISetVisible(lua_State* luaVM)
{
// bool guiSetVisible ( element guiElement, bool state )
Expand Down
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaGUIDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ class CLuaGUIDefs : public CLuaDefs
LUA_DECLARE(GUIGetPosition);
LUA_DECLARE(GUIGetVisible);
LUA_DECLARE(GUIGetAlpha);
LUA_DECLARE(GUISetColorCodesEnabled);
LUA_DECLARE(GUIGetColorCodesEnabled);
LUA_DECLARE(GUIGetProperty);
LUA_DECLARE(GUIGetProperties);
LUA_DECLARE(GUICheckBoxGetSelected);
Expand Down
3 changes: 3 additions & 0 deletions Client/sdk/gui/CGUIElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class CGUIElement

virtual void ForceRedraw() = 0;

virtual void SetColorCodesEnabled(bool bEnabled) = 0;
virtual bool GetColorCodesEnabled() = 0;

virtual CRect2D AbsoluteToRelative(const CRect2D& Rect) = 0;
virtual CVector2D AbsoluteToRelative(const CVector2D& Vector) = 0;

Expand Down
5 changes: 5 additions & 0 deletions vendor/cegui-0.4.0-custom/include/CEGUIFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ class CEGUIEXPORT Font
*************************************************************************/
static const argb_t DefaultColour; //!< Colour value used whenever a colour is not specified.

// When true, drawTextLine/drawTextLineJustified parse inline #RRGGBB color codes.
// CEGUIWindow::drawSelf() sets this per-window before populateRenderCache() and
// resets it to false afterwards, giving per-element opt-in behaviour.
static bool s_colorCodesEnabled;


/*************************************************************************
Text drawing methods
Expand Down
1 change: 1 addition & 0 deletions vendor/cegui-0.4.0-custom/include/CEGUIRenderCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ namespace CEGUI
Rect customClipper;
bool usingCustomClipper;
bool clipToDisplay;
bool colorCodesEnabled; // Stores whether inline color codes formatting should be parsed when rendering this text.
};

typedef std::vector<ImageInfo> ImageryList;
Expand Down
73 changes: 71 additions & 2 deletions vendor/cegui-0.4.0-custom/src/CEGUIFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@
// Start of CEGUI namespace section
namespace CEGUI
{
// Forward declaration of ParseColorCode to allow calls in early member functions (e.g. getTextExtent, getCharAtPixel) before its definition.
static bool ParseColorCode(const String& text, size_t c, float& r, float& g, float& b);

/*************************************************************************
static data definitions
*************************************************************************/
const argb_t Font::DefaultColour = 0xFFFFFFFF;
bool Font::s_colorCodesEnabled = false;
const uint Font::InterGlyphPadSpace = 2;

// XML related strings
Expand Down Expand Up @@ -223,6 +227,13 @@ float Font::getTextExtent(const String& text, float x_scale) const

for (size_t c = 0; c < char_count; ++c)
{
float cr, cg, cb;
if (ParseColorCode(text, c, cr, cg, cb))
{
c += 6;
continue;
}

const SCharSize* pCharSize = MapFind ( d_sizes_map, text[c] ); // Ask sub font if not
if ( !pCharSize && !d_is_subfont )
{
Expand Down Expand Up @@ -284,6 +295,13 @@ size_t Font::getCharAtPixel(const String& text, size_t start_char, float pixel,

for (size_t c = start_char; c < char_count; ++c)
{
float cr, cg, cb;
if (ParseColorCode(text, c, cr, cg, cb))
{
c += 6;
continue;
}

pos = d_cp_map.find(text[c]);

if (pos != end)
Expand Down Expand Up @@ -741,6 +759,32 @@ size_t Font::getNextWord(const String& in_string, size_t start_idx, String& out_
/*************************************************************************
Draw a line of text. No formatting is applied.
*************************************************************************/
// Returns true and fills r/g/b (0.0-1.0) if text[c] begins a valid #RRGGBB color code.
// A color code is exactly 7 chars: '#' followed by 6 hex digits. If text[c] is '#'
// but the following chars are not all hex digits, the '#' is treated as a literal char.
static bool ParseColorCode(const String& text, size_t c, float& r, float& g, float& b)
{
if (!Font::s_colorCodesEnabled)
return false;
if (text[c] != '#' || c + 7 > text.length())
return false;

int digits[6];
for (int k = 0; k < 6; ++k)
{
utf32 ch = text[c + 1 + k];
if (ch >= '0' && ch <= '9') digits[k] = ch - '0';
else if (ch >= 'a' && ch <= 'f') digits[k] = ch - 'a' + 10;
else if (ch >= 'A' && ch <= 'F') digits[k] = ch - 'A' + 10;
else return false;
}

r = static_cast<float>((digits[0] << 4) | digits[1]) / 255.0f;
g = static_cast<float>((digits[2] << 4) | digits[3]) / 255.0f;
b = static_cast<float>((digits[4] << 4) | digits[5]) / 255.0f;
return true;
}

void Font::drawTextLine(const String& text, const Vector3& position, const Rect& clip_rect, const ColourRect& colours, float x_scale, float y_scale) const
{
Vector3 cur_pos(position);
Expand All @@ -752,8 +796,19 @@ void Font::drawTextLine(const String& text, const Vector3& position, const Rect&

const_cast < Font* > ( this )->refreshStringForGlyphs ( text ); // Refresh our glyph set if there are new characters

ColourRect current_colours = colours;

for (size_t c = 0; c < char_count; ++c)
{
// Handle inline #RRGGBB color codes — skip the 7-char sequence and update color.
float cr, cg, cb;
if (ParseColorCode(text, c, cr, cg, cb))
{
current_colours = ColourRect(colour(cr, cg, cb, colours.d_top_left.getAlpha()));
c += 6;
continue;
}

pos = d_cp_map.find(text[c]);

const Image* img;
Expand Down Expand Up @@ -792,7 +847,7 @@ void Font::drawTextLine(const String& text, const Vector3& position, const Rect&
}
cur_pos.d_y = base_y - (img->getOffsetY() - img->getOffsetY() * y_scale);
Size sz(img->getWidth() * x_scale, img->getHeight() * y_scale);
img->draw(cur_pos, sz, clip_rect, colours);
img->draw(cur_pos, sz, clip_rect, current_colours);
cur_pos.d_x += horz_advance * x_scale;

}
Expand All @@ -818,24 +873,38 @@ void Font::drawTextLineJustified(const String& text, const Rect& draw_area, cons
uint space_count = 0;
size_t c;
for (c = 0; c < char_count; ++c)
{
float cr, cg, cb;
if (ParseColorCode(text, c, cr, cg, cb)) { c += 6; continue; }
if ((text[c] == ' ') || (text[c] == '\t')) ++space_count;
}

// The width that must be added to each space character in order to transform the left aligned text in justified text
float shared_lost_space = 0.0;
if (space_count > 0) shared_lost_space = lost_space / (float)space_count;

const_cast < Font* > ( this )->refreshStringForGlyphs ( text ); // Refresh our glyph set if there are new characters

ColourRect current_colours = colours;

for (c = 0; c < char_count; ++c)
{
float cr, cg, cb;
if (ParseColorCode(text, c, cr, cg, cb))
{
current_colours = ColourRect(colour(cr, cg, cb, colours.d_top_left.getAlpha()));
c += 6;
continue;
}

pos = d_cp_map.find(text[c]);

if (pos != end)
{
const Image* img = pos->second.d_image;
cur_pos.d_y = base_y - (img->getOffsetY() - img->getOffsetY() * y_scale);
Size sz(img->getWidth() * x_scale, img->getHeight() * y_scale);
img->draw(cur_pos, sz, clip_rect, colours);
img->draw(cur_pos, sz, clip_rect, current_colours);
cur_pos.d_x += (float)pos->second.d_horz_advance * x_scale;
// That's where we adjust the size of each space character
if ((text[c] == ' ') || (text[c] == '\t')) cur_pos.d_x += shared_lost_space;
Expand Down
Loading