Draws GUI elements by Z order.

Tested By: wraitii
Differential Revision: https://code.wildfiregames.com/D3780
This was SVN commit r25229.
This commit is contained in:
vladislavbelov 2021-04-11 11:27:53 +00:00
parent 35ed55cfd6
commit 8eb4871c9b
8 changed files with 90 additions and 39 deletions

View file

@ -5,7 +5,7 @@
type="image"
>
<!-- MiniMap -->
<object name="minimap" size="8 8 100%-8 100%-8" type="minimap" z="20" mask="true"/>
<object name="minimap" size="8 8 100%-8 100%-8" type="minimap" mask="true"/>
<!-- Background image -->
<object

View file

@ -308,7 +308,7 @@ function displaySingle(entState)
});
let isGaia = playerState.civ == "gaia";
Engine.GetGUIObjectByName("playerCivIcon").sprite = isGaia ? "" : "stretched:grayscale:" + civEmblem;
Engine.GetGUIObjectByName("playerCivIcon").sprite = isGaia ? "" : "cropped:1.0, 0.15625 center:grayscale:" + civEmblem;
Engine.GetGUIObjectByName("player").tooltip = isGaia ? "" : civName;
// TODO: we should require all entities to have icons

View file

@ -4,6 +4,26 @@
size="4 4 100%-4 100%-44"
>
<!-- Names and civilization emblem etc. (This must come before the attack and resistance icon to avoid clipping issues.) -->
<object size="0 92 100% 100%" name="statsArea" type="image" sprite="edgedPanelShader">
<!-- Civilization tooltip. -->
<object size="0 38 100% 62" tooltip_style="sessionToolTip">
<!-- Civilization emblem. -->
<object size="50%-64 50%-10 50%+64 50%+10" name="playerCivIcon" type="image" ghost="true"/>
<!-- Player color band. -->
<object name="playerColorBackground" type="image" sprite="playerColorBackground" ghost="true"/>
<object type="image" sprite="bottomEdgedPanelShader" ghost="true"/>
<!-- Player name. -->
<object size="0 50%-10 100% 50%+10" name="player" type="text" style="largeCenteredOutlinedText"/>
</object>
<!-- Primary and secondary names. -->
<object>
<object size="0 2 100% 22" name="primary" ghost="true" type="text" style="PrimaryNameCentered"/>
<object size="0 17 100% 37" name="secondary" ghost="true" type="text" style="SecondaryNameCentered"/>
</object>
</object>
<!-- Stats Bars -->
<object size= "0 0 100% 96" type="image" tooltip_style="sessionToolTip">
@ -81,7 +101,7 @@
<object type="image" sprite="statsBarShaderVertical" ghost="true"/>
</object>
<object z="20" size="4 4 20 20" name="rankIcon" type="image" tooltip_style="sessionToolTip">
<object size="4 4 20 20" name="rankIcon" type="image" tooltip_style="sessionToolTip">
<translatableAttribute id="tooltip">Rank</translatableAttribute>
</object>
@ -93,28 +113,4 @@
</object>
</object>
</object>
<!-- Names and civilization emblem etc. (This must come before the attack and resistance icon to avoid clipping issues.) -->
<object size="0 92 100% 100%" name="statsArea" type="image" sprite="edgedPanelShader">
<!-- Primary and secondary names. -->
<object z="30">
<object size="0 2 100% 22" name="primary" ghost="true" type="text" style="PrimaryNameCentered"/>
<object size="0 17 100% 37" name="secondary" ghost="true" type="text" style="SecondaryNameCentered"/>
</object>
<!-- Civilization tooltip. -->
<object size="0 38 100% 62" tooltip_style="sessionToolTip">
<!-- Images to clip off the top and bottom of the civilization emblem. -->
<object z="20" size="0 50%-64 100% 50%-12" ghost="true" type="image" sprite="remove"/>
<object z="20" size="0 50%+12 100% 50%+64" ghost="true" type="image" sprite="remove"/>
<!-- Civilization emblem. -->
<object size="50%-64 50%-64 50%+64 50%+64" name="playerCivIcon" type="image" ghost="true"/>
<!-- Player color band. -->
<object name="playerColorBackground" type="image" sprite="playerColorBackground" ghost="true"/>
<object type="image" sprite="bottomEdgedPanelShader" ghost="true"/>
<!-- Player name. -->
<object size="0 50%-10 100% 50%+10" z="30" name="player" type="text" style="largeCenteredOutlinedText"/>
</object>
</object>
</object>

View file

@ -299,10 +299,6 @@
<!-- Shading -->
<!-- ================================ ================================ -->
<sprite name="remove">
<image backcolor="0 0 0 0" size="0 0 100% 100%"/>
</sprite>
<sprite name="panelShader">
<image texture="session/panel_shader.png"
size="0 0 100% 100%"

View file

@ -25,6 +25,8 @@
#include "gui/Scripting/ScriptFunctions.h"
#include "gui/Scripting/JSInterface_GUIProxy.h"
#include "i18n/L10n.h"
#include "lib/allocators/DynamicArena.h"
#include "lib/allocators/STLAllocators.h"
#include "lib/bits.h"
#include "lib/input.h"
#include "lib/sysdep/sysdep.h"
@ -65,13 +67,40 @@ const CStr CGUI::EventNameMouseLeftRelease = "MouseLeftRelease";
const CStr CGUI::EventNameMouseRightDoubleClick = "MouseRightDoubleClick";
const CStr CGUI::EventNameMouseRightRelease = "MouseRightRelease";
namespace
{
struct VisibleObject
{
IGUIObject* object;
// Index of the object in a depth-first search inside GUI tree.
size_t index;
// Cached value of GetBufferedZ to avoid recursive calls in a deep hierarchy.
float bufferedZ;
};
template<class Container>
void CollectVisibleObjectsRecursively(const std::vector<IGUIObject*>& objects, Container* visibleObjects)
{
for (IGUIObject* const& object : objects)
{
if (!object->IsHidden())
{
visibleObjects->emplace_back(VisibleObject{object, visibleObjects->size(), 0.0f});
CollectVisibleObjectsRecursively(object->GetChildren(), visibleObjects);
}
}
}
} // anonynous namespace
CGUI::CGUI(const shared_ptr<ScriptContext>& context)
: m_BaseObject(std::make_unique<CGUIDummyObject>(*this)),
m_FocusedObject(nullptr),
m_InternalNameNumber(0),
m_MouseButtons(0)
{
m_ScriptInterface.reset(new ScriptInterface("Engine", "GUIPage", context));
m_ScriptInterface = std::make_shared<ScriptInterface>("Engine", "GUIPage", context);
m_ScriptInterface->SetCallbackData(this);
GuiScriptingInit(*m_ScriptInterface);
@ -302,7 +331,22 @@ void CGUI::Draw()
// drawn on top of everything else
glClear(GL_DEPTH_BUFFER_BIT);
m_BaseObject->RecurseObject(&IGUIObject::IsHidden, &IGUIObject::Draw);
using Arena = Allocators::DynamicArena<128 * KiB>;
using ObjectListAllocator = ProxyAllocator<VisibleObject, Arena>;
Arena arena;
std::vector<VisibleObject, ObjectListAllocator> visibleObjects((ObjectListAllocator(arena)));
CollectVisibleObjectsRecursively(m_BaseObject->GetChildren(), &visibleObjects);
for (VisibleObject& visibleObject : visibleObjects)
visibleObject.bufferedZ = visibleObject.object->GetBufferedZ();
std::sort(visibleObjects.begin(), visibleObjects.end(), [](const VisibleObject& visibleObject1, const VisibleObject& visibleObject2) -> bool {
if (visibleObject1.bufferedZ != visibleObject2.bufferedZ)
return visibleObject1.bufferedZ < visibleObject2.bufferedZ;
return visibleObject1.index < visibleObject2.index;
});
for (const VisibleObject& visibleObject : visibleObjects)
visibleObject.object->Draw();
}
void CGUI::DrawSprite(const CGUISpriteInstance& Sprite, const float& Z, const CRect& Rect, const CRect& UNUSED(Clipping))

View file

@ -102,7 +102,6 @@ void GUIRenderer::UpdateDrawCallCache(const CGUI& pGUI, DrawCalls& Calls, const
SGUIImage* Image = new SGUIImage();
Image->m_TextureName = TextureName;
// Allow grayscale images for disabled portraits
if (SpriteName.Find("grayscale:") != -1)
{
Image->m_Effects = std::make_shared<SGUIImageEffects>();
@ -118,13 +117,23 @@ void GUIRenderer::UpdateDrawCallCache(const CGUI& pGUI, DrawCalls& Calls, const
// TODO: Should check (nicely) that this is a valid file?
SGUIImage* Image = new SGUIImage();
const bool centered = SpriteName.Find("center:") != -1;
CStr info = SpriteName.AfterLast("cropped:").BeforeFirst(":");
double xRatio = info.BeforeFirst(",").ToDouble();
double yRatio = info.AfterLast(",").ToDouble();
Image->m_TextureSize = CGUISize(CRect(0, 0, 0, 0), CRect(0, 0, 100/xRatio, 100/yRatio));
const CRect percentSize = centered
? CRect(50 - 50 / xRatio, 50 - 50 / yRatio, 50 + 50 / xRatio, 50 + 50 / yRatio)
: CRect(0, 0, 100 / xRatio, 100 / yRatio);
Image->m_TextureSize = CGUISize(CRect(0, 0, 0, 0), percentSize);
Image->m_TextureName = TextureName;
if (SpriteName.Find("grayscale:") != -1)
{
Image->m_Effects = std::make_shared<SGUIImageEffects>();
Image->m_Effects->m_Greyscale = true;
}
Sprite->AddImage(Image);
Sprites[SpriteName] = Sprite;

View file

@ -147,8 +147,6 @@ void CTooltip::HandleMessage(SGUIMessage& Message)
void CTooltip::Draw()
{
float z = 900.f; // TODO: Find a nicer way of putting the tooltip on top of everything else
// Normally IGUITextOwner will handle this updating but since SetupText can modify the position
// we need to call it now *before* we do the rest of the drawing
if (!m_GeneratedTextsValid)
@ -157,7 +155,13 @@ void CTooltip::Draw()
m_GeneratedTextsValid = true;
}
const float z = GetBufferedZ();
m_pGUI.DrawSprite(m_Sprite, z, m_CachedActualSize);
DrawText(0, m_TextColor, m_CachedActualSize.TopLeft(), z + 0.1f);
}
float CTooltip::GetBufferedZ() const
{
// TODO: Find a nicer way of putting the tooltip on top of everything else.
return 900.f;
}

View file

@ -50,6 +50,8 @@ protected:
virtual void Draw();
virtual float GetBufferedZ() const;
// Settings
float m_BufferZone;
CGUIString m_Caption;