From 8f897084d730e5e2d2c34c127ab5eeb01ce3b54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 1 Dec 2021 18:58:48 +0100 Subject: [PATCH] Widgets: Add support for render layer (fixes rendering) --- .../Nazara/Widgets/AbstractTextAreaWidget.hpp | 1 + include/Nazara/Widgets/BaseWidget.hpp | 7 +++ include/Nazara/Widgets/BaseWidget.inl | 48 ++++++++++++++++--- include/Nazara/Widgets/ButtonWidget.hpp | 2 + include/Nazara/Widgets/Canvas.hpp | 2 +- include/Nazara/Widgets/CheckboxWidget.hpp | 2 + include/Nazara/Widgets/LabelWidget.hpp | 2 + include/Nazara/Widgets/SimpleWidgetStyles.hpp | 4 ++ include/Nazara/Widgets/WidgetTheme.hpp | 6 ++- include/Nazara/Widgets/WidgetTheme.inl | 12 ++++- src/Nazara/Widgets/AbstractTextAreaWidget.cpp | 10 +++- src/Nazara/Widgets/BaseWidget.cpp | 10 ++++ src/Nazara/Widgets/ButtonWidget.cpp | 6 +++ src/Nazara/Widgets/Canvas.cpp | 4 +- src/Nazara/Widgets/CheckboxWidget.cpp | 6 +++ src/Nazara/Widgets/LabelWidget.cpp | 6 +++ src/Nazara/Widgets/SimpleWidgetStyles.cpp | 23 +++++++-- 17 files changed, 135 insertions(+), 16 deletions(-) diff --git a/include/Nazara/Widgets/AbstractTextAreaWidget.hpp b/include/Nazara/Widgets/AbstractTextAreaWidget.hpp index 260dd5c9e..866034a5b 100644 --- a/include/Nazara/Widgets/AbstractTextAreaWidget.hpp +++ b/include/Nazara/Widgets/AbstractTextAreaWidget.hpp @@ -109,6 +109,7 @@ namespace Nz void OnMouseButtonTriplePress(int x, int y, Mouse::Button button) override; void OnMouseEnter() override; void OnMouseMoved(int x, int y, int deltaX, int deltaY) override; + void OnRenderLayerUpdated(int baseRenderLayer) override; void OnTextEntered(char32_t character, bool repeated) override; virtual void PasteFromClipboard(const Vector2ui& targetPosition) = 0; diff --git a/include/Nazara/Widgets/BaseWidget.hpp b/include/Nazara/Widgets/BaseWidget.hpp index c531ec2d7..19f666277 100644 --- a/include/Nazara/Widgets/BaseWidget.hpp +++ b/include/Nazara/Widgets/BaseWidget.hpp @@ -114,6 +114,7 @@ namespace Nz entt::entity CreateEntity(); void DestroyEntity(entt::entity entity); + inline int GetBaseRenderLayer() const; inline entt::registry& GetRegistry(); inline const entt::registry& GetRegistry() const; @@ -123,6 +124,7 @@ namespace Nz virtual bool IsFocusable() const; inline bool IsInside(float x, float y) const; + virtual void OnFocusLost(); virtual void OnFocusReceived(); virtual bool OnKeyPressed(const WindowEvent::KeyEvent& key); @@ -135,11 +137,14 @@ namespace Nz virtual void OnMouseButtonTriplePress(int x, int y, Mouse::Button button); virtual void OnMouseWheelMoved(int x, int y, float delta); virtual void OnMouseExit(); + virtual void OnRenderLayerUpdated(int baseRenderLayer); virtual void OnParentResized(const Vector2f& newSize); virtual void OnTextEntered(char32_t character, bool repeated); virtual void OnTextEdited(const std::array& characters, int length); + inline void SetBaseRenderLayer(int baseRenderLayer); inline void SetPreferredSize(const Vector2f& preferredSize); + inline void SetRenderLayerCount(int renderLayerCount); virtual void ShowChildren(bool show); @@ -179,6 +184,8 @@ namespace Nz Vector2f m_size; BaseWidget* m_widgetParent; bool m_visible; + int m_baseRenderLayer; + int m_renderLayerCount; }; } diff --git a/include/Nazara/Widgets/BaseWidget.inl b/include/Nazara/Widgets/BaseWidget.inl index 7dd7ae4c1..ec6e6083c 100644 --- a/include/Nazara/Widgets/BaseWidget.inl +++ b/include/Nazara/Widgets/BaseWidget.inl @@ -23,12 +23,14 @@ namespace Nz m_preferredSize(-1), m_size(50.f, 50.f), m_widgetParent(nullptr), - m_visible(true) + m_visible(true), + m_baseRenderLayer(0), + m_renderLayerCount(1) { } template - inline T* BaseWidget::Add(Args&&... args) + T* BaseWidget::Add(Args&&... args) { std::unique_ptr widget = std::make_unique(this, std::forward(args)...); T* widgetPtr = widget.get(); @@ -39,8 +41,10 @@ namespace Nz inline void BaseWidget::AddChild(std::unique_ptr&& widget) { - widget->Show(m_visible); widget->SetParent(this); + widget->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount); + widget->Show(widget->IsVisible() && m_visible); + m_children.emplace_back(std::move(widget)); } @@ -264,11 +268,9 @@ namespace Nz SetMinimumSize(minimumSize); } - inline void BaseWidget::SetPreferredSize(const Vector2f& preferredSize) + inline int BaseWidget::GetBaseRenderLayer() const { - m_preferredSize = preferredSize; - - //Resize(m_preferredSize); + return m_baseRenderLayer + ((m_backgroundEntity.has_value()) ? 1 : 0); } inline entt::registry& BaseWidget::GetRegistry() @@ -283,6 +285,38 @@ namespace Nz return *m_registry; } + inline void BaseWidget::SetBaseRenderLayer(int baseRenderLayer) + { + if (m_baseRenderLayer != baseRenderLayer) + { + m_baseRenderLayer = baseRenderLayer; + if (m_backgroundSprite) + m_backgroundSprite->UpdateRenderLayer(m_baseRenderLayer); + + OnRenderLayerUpdated(GetBaseRenderLayer()); + + for (const auto& widgetPtr : m_children) + widgetPtr->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount); + } + } + + inline void BaseWidget::SetPreferredSize(const Vector2f& preferredSize) + { + m_preferredSize = preferredSize; + + //Resize(m_preferredSize); + } + + inline void BaseWidget::SetRenderLayerCount(int renderLayerCount) + { + if (m_renderLayerCount != renderLayerCount) + { + m_renderLayerCount = renderLayerCount; + for (const auto& widgetPtr : m_children) + widgetPtr->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount); + } + } + inline bool BaseWidget::IsRegisteredToCanvas() const { return m_canvas && m_canvasIndex != InvalidCanvasIndex; diff --git a/include/Nazara/Widgets/ButtonWidget.hpp b/include/Nazara/Widgets/ButtonWidget.hpp index de7a572e2..e0246a0e3 100644 --- a/include/Nazara/Widgets/ButtonWidget.hpp +++ b/include/Nazara/Widgets/ButtonWidget.hpp @@ -41,6 +41,8 @@ namespace Nz void OnMouseButtonRelease(int x, int y, Mouse::Button button) override; void OnMouseExit() override; + void OnRenderLayerUpdated(int baseRenderLayer) override; + std::unique_ptr m_style; }; } diff --git a/include/Nazara/Widgets/Canvas.hpp b/include/Nazara/Widgets/Canvas.hpp index 6f250881e..a3fe0feaa 100644 --- a/include/Nazara/Widgets/Canvas.hpp +++ b/include/Nazara/Widgets/Canvas.hpp @@ -20,7 +20,7 @@ namespace Nz friend BaseWidget; public: - Canvas(entt::registry& registry, EventHandler& eventHandler, CursorControllerHandle cursorController, UInt32 renderMask); + Canvas(entt::registry& registry, EventHandler& eventHandler, CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer = 0); Canvas(const Canvas&) = delete; Canvas(Canvas&&) = delete; inline ~Canvas(); diff --git a/include/Nazara/Widgets/CheckboxWidget.hpp b/include/Nazara/Widgets/CheckboxWidget.hpp index 5336ba6b2..dcf71aaf7 100644 --- a/include/Nazara/Widgets/CheckboxWidget.hpp +++ b/include/Nazara/Widgets/CheckboxWidget.hpp @@ -48,6 +48,8 @@ namespace Nz void OnMouseButtonRelease(int x, int y, Mouse::Button button) override; void OnMouseExit() override; + void OnRenderLayerUpdated(int baseRenderLayer) override; + std::unique_ptr m_style; CheckboxState m_state; bool m_isTristateEnabled; diff --git a/include/Nazara/Widgets/LabelWidget.hpp b/include/Nazara/Widgets/LabelWidget.hpp index 29b3aaacd..c91f37b38 100644 --- a/include/Nazara/Widgets/LabelWidget.hpp +++ b/include/Nazara/Widgets/LabelWidget.hpp @@ -33,6 +33,8 @@ namespace Nz void OnMouseEnter() override; void OnMouseExit() override; + void OnRenderLayerUpdated(int baseRenderLayer) override; + std::unique_ptr m_style; }; } diff --git a/include/Nazara/Widgets/SimpleWidgetStyles.hpp b/include/Nazara/Widgets/SimpleWidgetStyles.hpp index 84c263882..1e71d8bb4 100644 --- a/include/Nazara/Widgets/SimpleWidgetStyles.hpp +++ b/include/Nazara/Widgets/SimpleWidgetStyles.hpp @@ -31,6 +31,7 @@ namespace Nz void OnPress() override; void OnRelease() override; + void UpdateRenderLayer(int baseRenderLayer) override; void UpdateText(const AbstractTextDrawer& drawer) override; SimpleButtonWidgetStyle& operator=(const SimpleButtonWidgetStyle&) = delete; @@ -78,6 +79,8 @@ namespace Nz void OnHoverEnd() override; void OnNewState(CheckboxState newState) override; + void UpdateRenderLayer(int baseRenderLayer) override; + SimpleCheckboxWidgetStyle& operator=(const SimpleCheckboxWidgetStyle&) = delete; SimpleCheckboxWidgetStyle& operator=(SimpleCheckboxWidgetStyle&&) = default; @@ -119,6 +122,7 @@ namespace Nz void OnHoverBegin() override; void OnHoverEnd() override; + void UpdateRenderLayer(int baseRenderLayer) override; void UpdateText(const AbstractTextDrawer& drawer) override; SimpleLabelWidgetStyle& operator=(const SimpleLabelWidgetStyle&) = delete; diff --git a/include/Nazara/Widgets/WidgetTheme.hpp b/include/Nazara/Widgets/WidgetTheme.hpp index 131f3ac50..db698dd23 100644 --- a/include/Nazara/Widgets/WidgetTheme.hpp +++ b/include/Nazara/Widgets/WidgetTheme.hpp @@ -44,7 +44,7 @@ namespace Nz class NAZARA_WIDGETS_API BaseWidgetStyle { public: - inline BaseWidgetStyle(BaseWidget* widget); + inline BaseWidgetStyle(BaseWidget* widget, int renderLayerCount); BaseWidgetStyle(const BaseWidgetStyle&) = delete; BaseWidgetStyle(BaseWidgetStyle&&) = default; virtual ~BaseWidgetStyle(); @@ -56,12 +56,16 @@ namespace Nz inline entt::registry& GetRegistry(); inline const entt::registry& GetRegistry() const; UInt32 GetRenderMask() const; + inline int GetRenderLayerCount() const; + + virtual void UpdateRenderLayer(int baseRenderLayer) = 0; BaseWidgetStyle& operator=(const BaseWidgetStyle&) = delete; BaseWidgetStyle& operator=(BaseWidgetStyle&&) = default; private: BaseWidget* m_widgetOwner; + int m_renderLayerCount; }; class NAZARA_WIDGETS_API ButtonWidgetStyle : public BaseWidgetStyle diff --git a/include/Nazara/Widgets/WidgetTheme.inl b/include/Nazara/Widgets/WidgetTheme.inl index 9f1941592..17cf7bb2f 100644 --- a/include/Nazara/Widgets/WidgetTheme.inl +++ b/include/Nazara/Widgets/WidgetTheme.inl @@ -3,13 +3,16 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz { - inline BaseWidgetStyle::BaseWidgetStyle(BaseWidget* widget) : - m_widgetOwner(widget) + inline BaseWidgetStyle::BaseWidgetStyle(BaseWidget* widget, int renderLayerCount) : + m_widgetOwner(widget), + m_renderLayerCount(renderLayerCount) { + assert(m_renderLayerCount >= 0); } inline entt::entity BaseWidgetStyle::CreateEntity() @@ -31,6 +34,11 @@ namespace Nz { return m_widgetOwner->GetRegistry(); } + + inline int BaseWidgetStyle::GetRenderLayerCount() const + { + return m_renderLayerCount; + } } #include diff --git a/src/Nazara/Widgets/AbstractTextAreaWidget.cpp b/src/Nazara/Widgets/AbstractTextAreaWidget.cpp index d3430faab..8eb2a286e 100644 --- a/src/Nazara/Widgets/AbstractTextAreaWidget.cpp +++ b/src/Nazara/Widgets/AbstractTextAreaWidget.cpp @@ -471,6 +471,13 @@ namespace Nz SetSelection(m_selectionCursor, GetHoveredGlyph(float(x), float(y))); } + void AbstractTextAreaWidget::OnRenderLayerUpdated(int baseRenderLayer) + { + m_textSprite->UpdateRenderLayer(baseRenderLayer); + for (Cursor& cursor : m_cursors) + cursor.sprite->UpdateRenderLayer(baseRenderLayer + 1); + } + void AbstractTextAreaWidget::OnTextEntered(char32_t character, bool /*repeated*/) { if (m_readOnly) @@ -544,9 +551,10 @@ namespace Nz for (std::size_t i = oldSpriteCount; i < m_cursors.size(); ++i) { m_cursors[i].sprite = std::make_shared(Widgets::Instance()->GetTransparentMaterial()); + m_cursors[i].sprite->UpdateRenderLayer(GetBaseRenderLayer() + 1); m_cursors[i].entity = CreateEntity(); - registry.emplace(m_cursors[i].entity, HasFocus()).AttachRenderable(m_cursors[i].sprite); + registry.emplace(m_cursors[i].entity, IsVisible() && HasFocus()).AttachRenderable(m_cursors[i].sprite, GetCanvas()->GetRenderMask()); registry.emplace(m_cursors[i].entity).SetParent(textNode); } } diff --git a/src/Nazara/Widgets/BaseWidget.cpp b/src/Nazara/Widgets/BaseWidget.cpp index ed99e0b44..5a504da10 100644 --- a/src/Nazara/Widgets/BaseWidget.cpp +++ b/src/Nazara/Widgets/BaseWidget.cpp @@ -91,6 +91,7 @@ namespace Nz { m_backgroundSprite = std::make_shared((m_backgroundColor.IsOpaque()) ? Widgets::Instance()->GetOpaqueMaterial() : Widgets::Instance()->GetTransparentMaterial()); m_backgroundSprite->SetColor(m_backgroundColor); + m_backgroundSprite->UpdateRenderLayer(m_baseRenderLayer); entt::entity backgroundEntity = CreateEntity(); m_registry->emplace(backgroundEntity).AttachRenderable(m_backgroundSprite, GetCanvas()->GetRenderMask()); @@ -107,6 +108,11 @@ namespace Nz DestroyEntity(*m_backgroundEntity); m_backgroundSprite.reset(); } + + OnRenderLayerUpdated(GetBaseRenderLayer()); + + for (const auto& widgetPtr : m_children) + widgetPtr->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount); } /*! @@ -306,6 +312,10 @@ namespace Nz { } + void BaseWidget::OnRenderLayerUpdated(int /*firstRenderLayer*/) + { + } + void BaseWidget::OnParentResized(const Vector2f& /*newSize*/) { } diff --git a/src/Nazara/Widgets/ButtonWidget.cpp b/src/Nazara/Widgets/ButtonWidget.cpp index c8a18dcda..520a941f3 100644 --- a/src/Nazara/Widgets/ButtonWidget.cpp +++ b/src/Nazara/Widgets/ButtonWidget.cpp @@ -20,6 +20,7 @@ namespace Nz BaseWidget(parent) { m_style = GetTheme()->CreateStyle(this); + SetRenderLayerCount(m_style->GetRenderLayerCount()); Layout(); } @@ -69,4 +70,9 @@ namespace Nz { m_style->OnHoverEnd(); } + + void ButtonWidget::OnRenderLayerUpdated(int baseRenderLayer) + { + m_style->UpdateRenderLayer(baseRenderLayer); + } } diff --git a/src/Nazara/Widgets/Canvas.cpp b/src/Nazara/Widgets/Canvas.cpp index 1458c74dc..913b95e07 100644 --- a/src/Nazara/Widgets/Canvas.cpp +++ b/src/Nazara/Widgets/Canvas.cpp @@ -9,7 +9,7 @@ namespace Nz { - Canvas::Canvas(entt::registry& registry, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController, UInt32 renderMask) : + Canvas::Canvas(entt::registry& registry, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer) : BaseWidget(std::make_shared()), m_renderMask(renderMask), m_keyboardOwner(InvalidCanvasIndex), @@ -21,6 +21,8 @@ namespace Nz m_canvas = this; m_widgetParent = nullptr; + SetBaseRenderLayer(initialRenderLayer); + // Register ourselves as a widget to handle cursor change RegisterToCanvas(); diff --git a/src/Nazara/Widgets/CheckboxWidget.cpp b/src/Nazara/Widgets/CheckboxWidget.cpp index 6694b14d7..ca997289a 100644 --- a/src/Nazara/Widgets/CheckboxWidget.cpp +++ b/src/Nazara/Widgets/CheckboxWidget.cpp @@ -22,6 +22,7 @@ namespace Nz m_isTristateEnabled(false) { m_style = GetTheme()->CreateStyle(this); + SetRenderLayerCount(m_style->GetRenderLayerCount()); Layout(); } @@ -68,4 +69,9 @@ namespace Nz { m_style->OnHoverEnd(); } + + void CheckboxWidget::OnRenderLayerUpdated(int baseRenderLayer) + { + m_style->UpdateRenderLayer(baseRenderLayer); + } } diff --git a/src/Nazara/Widgets/LabelWidget.cpp b/src/Nazara/Widgets/LabelWidget.cpp index 092ce38eb..e9b958820 100644 --- a/src/Nazara/Widgets/LabelWidget.cpp +++ b/src/Nazara/Widgets/LabelWidget.cpp @@ -17,6 +17,7 @@ namespace Nz BaseWidget(parent) { m_style = GetTheme()->CreateStyle(this); + SetRenderLayerCount(m_style->GetRenderLayerCount()); Layout(); } @@ -41,4 +42,9 @@ namespace Nz { m_style->OnHoverEnd(); } + + void LabelWidget::OnRenderLayerUpdated(int baseRenderLayer) + { + m_style->UpdateRenderLayer(baseRenderLayer); + } } diff --git a/src/Nazara/Widgets/SimpleWidgetStyles.cpp b/src/Nazara/Widgets/SimpleWidgetStyles.cpp index 2ce54e4d4..c58bcae84 100644 --- a/src/Nazara/Widgets/SimpleWidgetStyles.cpp +++ b/src/Nazara/Widgets/SimpleWidgetStyles.cpp @@ -15,7 +15,7 @@ namespace Nz { SimpleButtonWidgetStyle::SimpleButtonWidgetStyle(ButtonWidget* buttonWidget, StyleConfig config) : - ButtonWidgetStyle(buttonWidget), + ButtonWidgetStyle(buttonWidget, 2), m_hoveredMaterial(std::move(config.hoveredMaterial)), m_material(std::move(config.material)), m_pressedMaterial(std::move(config.pressedMaterial)), @@ -78,6 +78,12 @@ namespace Nz UpdateMaterial(m_isHovered, m_isPressed); } + void SimpleButtonWidgetStyle::UpdateRenderLayer(int baseRenderLayer) + { + m_sprite->UpdateRenderLayer(baseRenderLayer); + m_textSprite->UpdateRenderLayer(baseRenderLayer + 1); + } + void SimpleButtonWidgetStyle::UpdateText(const AbstractTextDrawer& drawer) { m_textSprite->Update(drawer); @@ -97,7 +103,7 @@ namespace Nz SimpleCheckboxWidgetStyle::SimpleCheckboxWidgetStyle(CheckboxWidget* buttonWidget, StyleConfig config) : - CheckboxWidgetStyle(buttonWidget), + CheckboxWidgetStyle(buttonWidget, 2), m_checkMaterial(std::move(config.checkMaterial)), m_hoveredMaterial(std::move(config.backgroundHoveredMaterial)), m_material(std::move(config.backgroundMaterial)), @@ -173,6 +179,12 @@ namespace Nz } } + void SimpleCheckboxWidgetStyle::UpdateRenderLayer(int baseRenderLayer) + { + m_backgroundSprite->UpdateRenderLayer(baseRenderLayer); + m_checkSprite->UpdateRenderLayer(baseRenderLayer + 1); + } + void SimpleCheckboxWidgetStyle::UpdateMaterial(bool hovered) { if (hovered && m_hoveredMaterial) @@ -183,7 +195,7 @@ namespace Nz SimpleLabelWidgetStyle::SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr material, std::shared_ptr hoveredMaterial) : - LabelWidgetStyle(labelWidget), + LabelWidgetStyle(labelWidget, 1), m_hoveredMaterial(std::move(hoveredMaterial)), m_material(std::move(material)) { @@ -224,6 +236,11 @@ namespace Nz m_textSprite->SetMaterial(m_material); } + void SimpleLabelWidgetStyle::UpdateRenderLayer(int baseRenderLayer) + { + m_textSprite->UpdateRenderLayer(baseRenderLayer); + } + void SimpleLabelWidgetStyle::UpdateText(const AbstractTextDrawer& drawer) { m_textSprite->Update(drawer);