Widgets: Fix manually hidden entities being incorrectly shown when widget itself is shown

This commit is contained in:
SirLynix 2023-08-24 07:54:33 +02:00
parent e145501568
commit 1b7a89213d
10 changed files with 63 additions and 45 deletions

View File

@ -226,8 +226,8 @@ namespace Nz
m_cursorPositionBegin = NormalizeCursorPosition(fromPosition);
m_cursorPositionEnd = NormalizeCursorPosition(toPosition);
RefreshCursorColor();
RefreshCursorSize();
RefreshCursorColor();
}
}
@ -251,8 +251,8 @@ namespace Nz
m_cursorPositionBegin = cursorPosition;
m_cursorPositionEnd = m_cursorPositionBegin;
RefreshCursorColor();
RefreshCursorSize();
RefreshCursorColor();
}
}

View File

@ -8,6 +8,7 @@
#define NAZARA_WIDGETS_BASEWIDGET_HPP
#include <Nazara/Graphics/Sprite.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Platform/Mouse.hpp>
#include <Nazara/Platform/WindowEvent.hpp>
#include <Nazara/Utility/Node.hpp>
@ -116,6 +117,7 @@ namespace Nz
virtual void Layout();
entt::entity CreateEntity();
entt::entity CreateGraphicsEntity(Node* parent = nullptr);
void DestroyEntity(entt::entity entity);
inline int GetBaseRenderLayer() const;
@ -173,6 +175,9 @@ namespace Nz
struct WidgetEntity
{
entt::entity handle;
bool wasVisible;
NazaraSlot(GraphicsComponent, OnVisibilityUpdate, onVisibilityUpdate);
};
static constexpr std::size_t InvalidCanvasIndex = std::numeric_limits<std::size_t>::max();
@ -193,6 +198,7 @@ namespace Nz
Vector2f m_preferredSize;
Vector2f m_size;
BaseWidget* m_parentWidget;
bool m_disableVisibilitySignal;
bool m_visible;
int m_baseRenderLayer;
int m_renderLayerCount;

View File

@ -21,6 +21,7 @@ namespace Nz
m_preferredSize(-1),
m_size(50.f, 50.f),
m_parentWidget(nullptr),
m_disableVisibilitySignal(false),
m_visible(true),
m_baseRenderLayer(0),
m_renderLayerCount(1)

View File

@ -85,7 +85,7 @@ namespace Nz
virtual ~BaseWidgetStyle();
inline entt::entity CreateEntity();
entt::entity CreateGraphicsEntity();
inline entt::entity CreateGraphicsEntity(Node* parent = nullptr);
inline void DestroyEntity(entt::entity entity);
template<typename T> T* GetOwnerWidget() const;

View File

@ -26,6 +26,11 @@ namespace Nz
return m_widgetOwner->CreateEntity();
}
inline entt::entity BaseWidgetStyle::CreateGraphicsEntity(Node* parent)
{
return m_widgetOwner->CreateGraphicsEntity(parent);
}
inline void BaseWidgetStyle::DestroyEntity(entt::entity entity)
{
m_widgetOwner->DestroyEntity(entity);

View File

@ -36,13 +36,12 @@ namespace Nz
auto& registry = GetRegistry();
m_textEntity = CreateEntity();
m_textEntity = CreateGraphicsEntity();
auto& gfxComponent = registry.emplace<GraphicsComponent>(m_textEntity, IsVisible());
auto& gfxComponent = registry.get<GraphicsComponent>(m_textEntity);
gfxComponent.AttachRenderable(m_textSprite, GetCanvas()->GetRenderMask());
auto& textNode = GetRegistry().emplace<NodeComponent>(m_textEntity);
textNode.SetParent(this);
auto& textNode = registry.get<NodeComponent>(m_textEntity);
textNode.SetPosition(s_textAreaPaddingWidth, GetHeight() - s_textAreaPaddingHeight);
SetCursor(SystemCursor::Text);
@ -59,8 +58,8 @@ namespace Nz
m_cursorPositionBegin = Vector2ui::Zero();
m_cursorPositionEnd = Vector2ui::Zero();
RefreshCursorColor();
RefreshCursorSize();
RefreshCursorColor();
}
void AbstractTextAreaWidget::EnableLineWrap(bool enable)
@ -598,23 +597,16 @@ namespace Nz
std::size_t oldSpriteCount = m_cursors.size();
if (m_cursors.size() < selectionLineCount)
{
Color cursorColor = GetCursorColor();
Recti scissorBox = GetScissorBox();
bool isVisible = IsVisible() && HasFocus();
m_cursors.resize(selectionLineCount);
for (std::size_t i = oldSpriteCount; i < m_cursors.size(); ++i)
{
m_cursors[i].sprite = std::make_shared<Sprite>(Widgets::Instance()->GetTransparentMaterial());
m_cursors[i].sprite->SetColor(cursorColor);
m_cursors[i].sprite->UpdateRenderLayer(GetBaseRenderLayer() + 1);
m_cursors[i].entity = CreateEntity();
registry.emplace<NodeComponent>(m_cursors[i].entity).SetParent(textNode);
m_cursors[i].entity = CreateGraphicsEntity(&textNode);
auto& cursorGfx = registry.emplace<GraphicsComponent>(m_cursors[i].entity, isVisible);
auto& cursorGfx = registry.get<GraphicsComponent>(m_cursors[i].entity);
cursorGfx.AttachRenderable(m_cursors[i].sprite, GetCanvas()->GetRenderMask());
cursorGfx.UpdateScissorBox(scissorBox);
}
}
else if (m_cursors.size() > selectionLineCount)

View File

@ -95,9 +95,8 @@ namespace Nz
m_backgroundSprite->UpdateRenderLayer(m_baseRenderLayer);
}
entt::entity backgroundEntity = CreateEntity();
m_registry->emplace<GraphicsComponent>(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask());
m_registry->emplace<NodeComponent>(backgroundEntity).SetParent(this);
entt::entity backgroundEntity = CreateGraphicsEntity();
m_registry->get<GraphicsComponent>(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask());
m_backgroundEntity = backgroundEntity;
@ -204,13 +203,20 @@ namespace Nz
else
UnregisterFromCanvas();
m_disableVisibilitySignal = true;
auto& registry = GetRegistry();
for (WidgetEntity& entity : m_entities)
for (WidgetEntity& widgetEntity : m_entities)
{
if (GraphicsComponent* gfx = registry.try_get<GraphicsComponent>(entity.handle))
gfx->Show(show);
if (GraphicsComponent* gfx = registry.try_get<GraphicsComponent>(widgetEntity.handle))
{
if ((show && widgetEntity.wasVisible) || !show)
gfx->Show(show);
}
}
m_disableVisibilitySignal = false;
ShowChildren(show);
if (m_parentWidget)
@ -225,10 +231,38 @@ namespace Nz
m_entities.emplace_back();
WidgetEntity& newWidgetEntity = m_entities.back();
newWidgetEntity.handle = newEntity;
newWidgetEntity.wasVisible = true;
return newEntity;
}
entt::entity BaseWidget::CreateGraphicsEntity(Node* parent)
{
entt::entity entity = CreateEntity();
auto& gfxComponent = m_registry->emplace<GraphicsComponent>(entity, IsVisible());
gfxComponent.UpdateScissorBox(GetScissorBox());
m_registry->emplace<NodeComponent>(entity).SetParent((parent) ? parent : this);
WidgetEntity& newWidgetEntity = m_entities.back();
newWidgetEntity.onVisibilityUpdate.Connect(gfxComponent.OnVisibilityUpdate, [this, entity](GraphicsComponent* /*graphicsComponent*/, bool newVisibilityState)
{
if (m_disableVisibilitySignal)
return;
auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity)
{
return widgetEntity.handle == entity;
});
NazaraAssert(it != m_entities.end(), "Entity does not belong to this widget");
it->wasVisible = newVisibilityState;
});
return entity;
}
void BaseWidget::DestroyEntity(entt::entity entity)
{
auto it = std::find_if(m_entities.begin(), m_entities.end(), [&](const WidgetEntity& widgetEntity) { return widgetEntity.handle == entity; });

View File

@ -18,13 +18,10 @@ namespace Nz
auto& registry = GetRegistry();
m_entity = CreateEntity();
m_entity = CreateGraphicsEntity();
auto& gfxComponent = registry.emplace<GraphicsComponent>(m_entity, IsVisible());
auto& gfxComponent = registry.get<GraphicsComponent>(m_entity);
gfxComponent.AttachRenderable(m_sprite, GetCanvas()->GetRenderMask());
auto& nodeComponent = registry.emplace<NodeComponent>(m_entity);
nodeComponent.SetParent(this);
}
void ImageWidget::Layout()

View File

@ -3,11 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Widgets/LabelWidget.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/AbstractTextDrawer.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <Nazara/Widgets/Debug.hpp>
namespace Nz

View File

@ -3,8 +3,6 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Widgets/WidgetTheme.hpp>
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/Debug.hpp>
@ -14,17 +12,6 @@ namespace Nz
BaseWidgetStyle::~BaseWidgetStyle() = default;
entt::entity BaseWidgetStyle::CreateGraphicsEntity()
{
auto& registry = GetRegistry();
entt::entity entity = CreateEntity();
registry.emplace<GraphicsComponent>(entity, m_widgetOwner->IsVisible());
registry.emplace<NodeComponent>(entity).SetParent(m_widgetOwner);
return entity;
}
UInt32 BaseWidgetStyle::GetRenderMask() const
{
return m_widgetOwner->GetCanvas()->GetRenderMask();