Widgets: Improve BoxLayout

This commit is contained in:
SirLynix
2023-05-14 18:53:56 +02:00
parent f1cd5ad048
commit 3712b641f8
10 changed files with 223 additions and 79 deletions

View File

@@ -48,8 +48,8 @@ namespace Nz
void EnableBackground(bool enable);
template<typename F> void ForEachWidgetChild(F iterator);
template<typename F> void ForEachWidgetChild(F iterator) const;
template<typename F> void ForEachWidgetChild(F&& iterator, bool onlyVisible = true);
template<typename F> void ForEachWidgetChild(F&& iterator, bool onlyVisible = true) const;
//virtual BaseWidget* Clone() const = 0;
@@ -74,6 +74,7 @@ namespace Nz
inline Vector2f GetSize() const;
const std::shared_ptr<WidgetTheme>& GetTheme() const;
inline std::size_t GetVisibleWidgetChildCount() const;
inline float GetWidth() const;
inline std::size_t GetWidgetChildCount() const;
@@ -108,6 +109,8 @@ namespace Nz
BaseWidget& operator=(const BaseWidget&) = delete;
BaseWidget& operator=(BaseWidget&&) = delete;
NazaraSignal(OnWidgetResized, const BaseWidget* /*widget*/, const Vector2f& /*size*/);
protected:
virtual void Layout();
@@ -125,6 +128,10 @@ namespace Nz
virtual bool IsFocusable() const;
inline bool IsInside(float x, float y) const;
virtual void OnChildAdded(const BaseWidget* child);
virtual void OnChildPreferredSizeUpdated(const BaseWidget* child);
virtual void OnChildVisibilityUpdated(const BaseWidget* child);
virtual void OnChildRemoved(const BaseWidget* child);
virtual void OnFocusLost();
virtual void OnFocusReceived();
virtual bool OnKeyPressed(const WindowEvent::KeyEvent& key);
@@ -135,8 +142,8 @@ namespace Nz
virtual bool OnMouseButtonPress(int x, int y, Mouse::Button button);
virtual bool OnMouseButtonRelease(int x, int y, Mouse::Button button);
virtual bool OnMouseButtonTriplePress(int x, int y, Mouse::Button button);
virtual bool OnMouseWheelMoved(int x, int y, float delta);
virtual void OnMouseExit();
virtual bool OnMouseWheelMoved(int x, int y, float delta);
virtual void OnRenderLayerUpdated(int baseRenderLayer);
virtual void OnParentResized(const Vector2f& newSize);
virtual bool OnTextEntered(char32_t character, bool repeated);
@@ -173,7 +180,7 @@ namespace Nz
std::shared_ptr<Sprite> m_backgroundSprite;
std::shared_ptr<WidgetTheme> m_theme;
std::vector<WidgetEntity> m_entities;
std::vector<std::unique_ptr<BaseWidget>> m_children;
std::vector<std::unique_ptr<BaseWidget>> m_widgetChilds;
entt::registry* m_registry;
Canvas* m_canvas;
Color m_backgroundColor;
@@ -183,7 +190,7 @@ namespace Nz
Vector2f m_minimumSize;
Vector2f m_preferredSize;
Vector2f m_size;
BaseWidget* m_widgetParent;
BaseWidget* m_parentWidget;
bool m_visible;
int m_baseRenderLayer;
int m_renderLayerCount;

View File

@@ -21,7 +21,7 @@ namespace Nz
m_minimumSize(0.f),
m_preferredSize(-1),
m_size(50.f, 50.f),
m_widgetParent(nullptr),
m_parentWidget(nullptr),
m_visible(true),
m_baseRenderLayer(0),
m_renderLayerCount(1)
@@ -44,32 +44,33 @@ namespace Nz
widget->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount);
widget->Show(widget->IsVisible() && m_visible);
m_children.emplace_back(std::move(widget));
m_widgetChilds.emplace_back(std::move(widget));
OnChildAdded(m_widgetChilds.back().get());
}
inline void BaseWidget::Center()
{
NazaraAssert(m_widgetParent, "Widget has no parent");
NazaraAssert(m_parentWidget, "Widget has no parent");
Vector2f parentSize = m_widgetParent->GetSize();
Vector2f parentSize = m_parentWidget->GetSize();
Vector2f mySize = GetSize();
SetPosition((parentSize.x - mySize.x) / 2.f, (parentSize.y - mySize.y) / 2.f);
}
inline void BaseWidget::CenterHorizontal()
{
NazaraAssert(m_widgetParent, "Widget has no parent");
NazaraAssert(m_parentWidget, "Widget has no parent");
Vector2f parentSize = m_widgetParent->GetSize();
Vector2f parentSize = m_parentWidget->GetSize();
Vector2f mySize = GetSize();
SetPosition((parentSize.x - mySize.x) / 2.f, GetPosition(CoordSys::Local).y);
}
inline void BaseWidget::CenterVertical()
{
NazaraAssert(m_widgetParent, "Widget has no parent");
NazaraAssert(m_parentWidget, "Widget has no parent");
Vector2f parentSize = m_widgetParent->GetSize();
Vector2f parentSize = m_parentWidget->GetSize();
Vector2f mySize = GetSize();
SetPosition(GetPosition(CoordSys::Local).x, (parentSize.y - mySize.y) / 2.f);
}
@@ -80,17 +81,27 @@ namespace Nz
}
template<typename F>
inline void BaseWidget::ForEachWidgetChild(F iterator)
void BaseWidget::ForEachWidgetChild(F&& iterator, bool onlyVisible)
{
for (const auto& child : m_children)
for (const auto& child : m_widgetChilds)
{
if (onlyVisible && !child->IsVisible())
continue;
iterator(child.get());
}
}
template<typename F>
inline void BaseWidget::ForEachWidgetChild(F iterator) const
void BaseWidget::ForEachWidgetChild(F&& iterator, bool onlyVisible) const
{
for (const auto& child : m_children)
iterator(static_cast<const BaseWidget*>(child.get()));
for (const auto& child : m_widgetChilds)
{
if (onlyVisible && !child->IsVisible())
continue;
iterator(child.get());
}
}
inline const Color& BaseWidget::GetBackgroundColor() const
@@ -173,6 +184,15 @@ namespace Nz
return m_theme;
}
inline std::size_t BaseWidget::GetVisibleWidgetChildCount() const
{
std::size_t visibleChild = 0;
for (const auto& child : m_widgetChilds)
visibleChild += (child->IsVisible()) ? 1 : 0;
return visibleChild;
}
inline float BaseWidget::GetWidth() const
{
return m_size.x;
@@ -180,7 +200,7 @@ namespace Nz
inline std::size_t BaseWidget::GetWidgetChildCount() const
{
return m_children.size();
return m_widgetChilds.size();
}
inline void BaseWidget::Hide()
@@ -227,7 +247,8 @@ namespace Nz
inline void BaseWidget::SetMaximumSize(const Vector2f& maximumSize)
{
m_maximumSize = maximumSize;
m_maximumSize.x = std::max(m_minimumSize.x, maximumSize.x);
m_maximumSize.y = std::max(m_minimumSize.y, maximumSize.y);
Vector2f size = GetSize();
if (size.x > m_maximumSize.x || size.y > m_maximumSize.y)
@@ -252,7 +273,8 @@ namespace Nz
inline void BaseWidget::SetMinimumSize(const Vector2f& minimumSize)
{
m_minimumSize = minimumSize;
m_minimumSize.x = std::min(minimumSize.x, m_maximumSize.x);
m_minimumSize.y = std::min(minimumSize.y, m_maximumSize.y);
Vector2f size = GetSize();
if (size.x < m_minimumSize.x || size.y < m_minimumSize.y)
@@ -294,16 +316,20 @@ namespace Nz
OnRenderLayerUpdated(GetBaseRenderLayer());
for (const auto& widgetPtr : m_children)
for (const auto& widgetPtr : m_widgetChilds)
widgetPtr->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount);
}
}
inline void BaseWidget::SetPreferredSize(const Vector2f& preferredSize)
{
m_preferredSize = preferredSize;
if (m_preferredSize != preferredSize)
{
m_preferredSize = preferredSize;
//Resize(m_preferredSize);
if (m_parentWidget)
m_parentWidget->OnChildPreferredSizeUpdated(this);
}
}
inline void BaseWidget::SetRenderLayerCount(int renderLayerCount)
@@ -311,7 +337,7 @@ namespace Nz
if (m_renderLayerCount != renderLayerCount)
{
m_renderLayerCount = renderLayerCount;
for (const auto& widgetPtr : m_children)
for (const auto& widgetPtr : m_widgetChilds)
widgetPtr->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount);
}
}
@@ -323,7 +349,7 @@ namespace Nz
inline void BaseWidget::NotifyParentResized(const Vector2f& newSize)
{
for (const auto& widgetPtr : m_children)
for (const auto& widgetPtr : m_widgetChilds)
widgetPtr->OnParentResized(newSize);
}
@@ -334,3 +360,4 @@ namespace Nz
}
#include <Nazara/Widgets/DebugOff.hpp>

View File

@@ -27,6 +27,13 @@ namespace Nz
BoxLayout& operator=(BoxLayout&&) = delete;
private:
void OnChildAdded(const BaseWidget* child) override;
void OnChildPreferredSizeUpdated(const BaseWidget* child) override;
void OnChildVisibilityUpdated(const BaseWidget* child) override;
void OnChildRemoved(const BaseWidget* child) override;
void RecomputePreferredSize();
struct State;
std::unique_ptr<State> m_state;

View File

@@ -11,8 +11,10 @@ namespace Nz
{
enum class BoxLayoutOrientation
{
Horizontal,
Vertical
BottomToTop,
LeftToRight,
RightToLeft,
TopToBottom
};
enum class CheckboxState