// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Widgets module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include namespace Nz { inline BaseWidget::BaseWidget(std::shared_ptr theme) : m_canvasIndex(InvalidCanvasIndex), m_theme(std::move(theme)), m_registry(nullptr), m_canvas(nullptr), m_backgroundColor(Color(0.9f, 0.9f, 0.9f, 1.f)), m_renderingRect(-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()), m_cursor(SystemCursor::Default), m_maximumSize(std::numeric_limits::infinity()), m_minimumSize(0.f), m_preferredSize(-1), m_size(50.f, 50.f), m_widgetParent(nullptr), m_visible(true), m_baseRenderLayer(0), m_renderLayerCount(1) { } template T* BaseWidget::Add(Args&&... args) { std::unique_ptr widget = std::make_unique(this, std::forward(args)...); T* widgetPtr = widget.get(); AddChild(std::move(widget)); return widgetPtr; } inline void BaseWidget::AddChild(std::unique_ptr&& widget) { widget->SetParent(this); widget->SetBaseRenderLayer(m_baseRenderLayer + m_renderLayerCount); widget->Show(widget->IsVisible() && m_visible); m_children.emplace_back(std::move(widget)); } inline void BaseWidget::Center() { NazaraAssert(m_widgetParent, "Widget has no parent"); Vector2f parentSize = m_widgetParent->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"); Vector2f parentSize = m_widgetParent->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"); Vector2f parentSize = m_widgetParent->GetSize(); Vector2f mySize = GetSize(); SetPosition(GetPosition(CoordSys::Local).x, (parentSize.y - mySize.y) / 2.f); } inline void BaseWidget::ClearRenderingRect() { SetRenderingRect(Rectf(-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity())); } template inline void BaseWidget::ForEachWidgetChild(F iterator) { for (const auto& child : m_children) iterator(child.get()); } template inline void BaseWidget::ForEachWidgetChild(F iterator) const { for (const auto& child : m_children) iterator(static_cast(child.get())); } inline const Color& BaseWidget::GetBackgroundColor() const { return m_backgroundColor; } inline Canvas* BaseWidget::GetCanvas() { return m_canvas; } inline SystemCursor BaseWidget::GetCursor() const { return m_cursor; } inline float BaseWidget::GetHeight() const { return m_size.y; } inline float BaseWidget::GetMaximumHeight() const { return m_maximumSize.y; } inline Vector2f BaseWidget::GetMaximumSize() const { return m_maximumSize; } inline float BaseWidget::GetMaximumWidth() const { return m_maximumSize.x; } inline float BaseWidget::GetMinimumHeight() const { return m_minimumSize.y; } inline Vector2f BaseWidget::GetMinimumSize() const { return m_minimumSize; } inline float BaseWidget::GetMinimumWidth() const { return m_minimumSize.x; } inline float BaseWidget::GetPreferredHeight() const { return m_preferredSize.y; } inline Vector2f BaseWidget::GetPreferredSize() const { return m_preferredSize; } inline float BaseWidget::GetPreferredWidth() const { return m_preferredSize.x; } inline const Rectf& BaseWidget::GetRenderingRect() const { return m_renderingRect; } inline Vector2f BaseWidget::GetSize() const { return Vector2f(GetWidth(), GetHeight()); } inline const std::shared_ptr& BaseWidget::GetTheme() const { return m_theme; } inline float BaseWidget::GetWidth() const { return m_size.x; } inline std::size_t BaseWidget::GetWidgetChildCount() const { return m_children.size(); } inline void BaseWidget::Hide() { return Show(false); } inline bool BaseWidget::IsInside(float x, float y) const { Rectf rect(0.f, 0.f, m_size.x, m_size.y); return rect.Contains(x, y); } inline bool BaseWidget::IsVisible() const { return m_visible; } inline void BaseWidget::SetFixedHeight(float fixedHeight) { SetMaximumHeight(fixedHeight); SetMinimumHeight(fixedHeight); } inline void BaseWidget::SetFixedSize(const Vector2f& fixedSize) { SetMaximumSize(fixedSize); SetMinimumSize(fixedSize); } inline void BaseWidget::SetFixedWidth(float fixedWidth) { SetMaximumWidth(fixedWidth); SetMinimumWidth(fixedWidth); } inline void BaseWidget::SetMaximumHeight(float maximumHeight) { Vector2f maximumSize = GetMaximumSize(); maximumSize.y = maximumHeight; SetMaximumSize(maximumSize); } inline void BaseWidget::SetMaximumSize(const Vector2f& maximumSize) { m_maximumSize = maximumSize; Vector2f size = GetSize(); if (size.x > m_maximumSize.x || size.y > m_maximumSize.y) Resize(size); //< Will clamp automatically } inline void BaseWidget::SetMaximumWidth(float maximumWidth) { Vector2f maximumSize = GetMaximumSize(); maximumSize.x = maximumWidth; SetMaximumSize(maximumSize); } inline void BaseWidget::SetMinimumHeight(float minimumHeight) { Vector2f minimumSize = GetMinimumSize(); minimumSize.y = minimumHeight; SetMinimumSize(minimumSize); } inline void BaseWidget::SetMinimumSize(const Vector2f& minimumSize) { m_minimumSize = minimumSize; Vector2f size = GetSize(); if (size.x < m_minimumSize.x || size.y < m_minimumSize.y) Resize(size); //< Will clamp automatically } inline void BaseWidget::SetMinimumWidth(float minimumWidth) { Vector2f minimumSize = GetMinimumSize(); minimumSize.x = minimumWidth; SetMinimumSize(minimumSize); } inline int BaseWidget::GetBaseRenderLayer() const { return m_baseRenderLayer + ((m_backgroundEntity.has_value()) ? 1 : 0); } inline entt::registry& BaseWidget::GetRegistry() { assert(m_registry); return *m_registry; } inline const entt::registry& BaseWidget::GetRegistry() const { assert(m_registry); 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; } inline void BaseWidget::NotifyParentResized(const Vector2f& newSize) { for (const auto& widgetPtr : m_children) widgetPtr->OnParentResized(newSize); } inline void BaseWidget::UpdateCanvasIndex(std::size_t index) { m_canvasIndex = index; } } #include