diff --git a/examples/WidgetDemo/main.cpp b/examples/WidgetDemo/main.cpp index 8df31e688..9707ab5cf 100644 --- a/examples/WidgetDemo/main.cpp +++ b/examples/WidgetDemo/main.cpp @@ -47,10 +47,6 @@ int main(int argc, char* argv[]) buttonWidget->SetPosition(200.f, 400.f); buttonWidget->UpdateText(Nz::SimpleTextDrawer::Draw("Press me senpai", 72)); buttonWidget->Resize(buttonWidget->GetPreferredSize()); - buttonWidget->OnButtonTrigger.Connect([&](const Nz::ButtonWidget*) - { - labelWidget->UpdateText(Nz::SimpleTextDrawer::Draw("You clicked the button " + std::to_string(++clickCount) + " times", 72)); - }); Nz::TextureSamplerInfo samplerInfo; samplerInfo.anisotropyLevel = 8; @@ -101,6 +97,19 @@ int main(int argc, char* argv[]) builder << Nz::Color::Blue() << "Rich " << Nz::TextStyle::Bold << "text" << Nz::TextStyle_Regular << builder.CharacterSize(36) << Nz::Color::Black() << "\nAnd a even " << builder.CharacterSize(48) << Nz::Color::Red() << "bigger" << builder.CharacterSize(24) << Nz::Color::Black() << " text"; textAreaWidget2->Resize(Nz::Vector2f(500.f, textAreaWidget2->GetPreferredHeight())); + Nz::ProgressBarWidget* progressBarWidget = canvas2D.Add(); + progressBarWidget->SetPosition(200.f, 600.f); + progressBarWidget->Resize({ 512.f, 64.f }); + + buttonWidget->OnButtonTrigger.Connect([&](const Nz::ButtonWidget*) + { + labelWidget->UpdateText(Nz::SimpleTextDrawer::Draw("You clicked the button " + std::to_string(++clickCount) + " times", 72)); + if (progressBarWidget->GetFraction() >= 1.f) + progressBarWidget->SetFraction(0.f); + else + progressBarWidget->SetFraction(progressBarWidget->GetFraction() + 0.1001f); //< ensures ten clicks go over 1 + }); + entt::handle viewer2D = world.CreateEntity(); { viewer2D.emplace(); diff --git a/include/Nazara/Widgets.hpp b/include/Nazara/Widgets.hpp index 304a13232..ca7783802 100644 --- a/include/Nazara/Widgets.hpp +++ b/include/Nazara/Widgets.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Widgets/DefaultWidgetTheme.hpp b/include/Nazara/Widgets/DefaultWidgetTheme.hpp index a46bf1fd4..b1eed5d2c 100644 --- a/include/Nazara/Widgets/DefaultWidgetTheme.hpp +++ b/include/Nazara/Widgets/DefaultWidgetTheme.hpp @@ -26,6 +26,7 @@ namespace Nz std::unique_ptr CreateStyle(CheckboxWidget* checkboxWidget) const override; std::unique_ptr CreateStyle(ImageButtonWidget* imageButtonWidget) const override; std::unique_ptr CreateStyle(LabelWidget* labelWidget) const override; + std::unique_ptr CreateStyle(ProgressBarWidget* progressBarWidget) const override; std::unique_ptr CreateStyle(ScrollAreaWidget* scrollAreaWidget) const override; std::unique_ptr CreateStyle(ScrollbarWidget* scrollbarWidget) const override; std::unique_ptr CreateStyle(ScrollbarButtonWidget* scrollbarButtonWidget) const override; @@ -43,6 +44,7 @@ namespace Nz std::shared_ptr m_checkboxCheckMaterial; std::shared_ptr m_checkboxTristateMaterial; std::shared_ptr m_hoveredMaterial; + std::shared_ptr m_progressBarMaterial; std::shared_ptr m_scrollbarBackgroundHorizontalMaterial; std::shared_ptr m_scrollbarBackgroundVerticalMaterial; std::shared_ptr m_scrollbarButtonMaterial; diff --git a/include/Nazara/Widgets/ProgressBarWidget.hpp b/include/Nazara/Widgets/ProgressBarWidget.hpp new file mode 100644 index 000000000..66c27db26 --- /dev/null +++ b/include/Nazara/Widgets/ProgressBarWidget.hpp @@ -0,0 +1,43 @@ +// Copyright (C) 2024 Jérôme "SirLynix" 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 + +#pragma once + +#ifndef NAZARA_WIDGETS_PROGRESSBARWIDGET_HPP +#define NAZARA_WIDGETS_PROGRESSBARWIDGET_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_WIDGETS_API ProgressBarWidget : public BaseWidget + { + public: + ProgressBarWidget(BaseWidget* parent); + ProgressBarWidget(const ProgressBarWidget&) = delete; + ProgressBarWidget(ProgressBarWidget&&) = delete; + ~ProgressBarWidget() = default; + + inline float GetFraction() const; + + void Layout() override; + + void OnRenderLayerUpdated(int baseRenderLayer) override; + + inline void SetFraction(float fraction); + + ProgressBarWidget& operator=(const ProgressBarWidget&) = delete; + ProgressBarWidget& operator=(ProgressBarWidget&&) = delete; + + private: + std::unique_ptr m_style; + float m_fraction; + }; +} + +#include + +#endif // NAZARA_WIDGETS_PROGRESSBARWIDGET_HPP diff --git a/include/Nazara/Widgets/ProgressBarWidget.inl b/include/Nazara/Widgets/ProgressBarWidget.inl new file mode 100644 index 000000000..bb8562fa7 --- /dev/null +++ b/include/Nazara/Widgets/ProgressBarWidget.inl @@ -0,0 +1,23 @@ +// Copyright (C) 2024 Jérôme "SirLynix" 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 + +namespace Nz +{ + inline float ProgressBarWidget::GetFraction() const + { + return m_fraction; + } + + inline void ProgressBarWidget::SetFraction(float fraction) + { + m_fraction = std::clamp(fraction, 0.f, 1.f); + Layout(); + } +} + +#include diff --git a/include/Nazara/Widgets/SimpleWidgetStyles.hpp b/include/Nazara/Widgets/SimpleWidgetStyles.hpp index 974a70a2f..f5e383ee3 100644 --- a/include/Nazara/Widgets/SimpleWidgetStyles.hpp +++ b/include/Nazara/Widgets/SimpleWidgetStyles.hpp @@ -179,6 +179,44 @@ namespace Nz std::shared_ptr m_textSprite; entt::entity m_entity; }; + + class NAZARA_WIDGETS_API SimpleProgressBarWidgetStyle : public ProgressBarWidgetStyle + { + public: + struct StyleConfig; + + SimpleProgressBarWidgetStyle(ProgressBarWidget* progressBarWidget, StyleConfig styleConfig); + SimpleProgressBarWidgetStyle(const SimpleProgressBarWidgetStyle&) = delete; + SimpleProgressBarWidgetStyle(SimpleProgressBarWidgetStyle&&) = default; + ~SimpleProgressBarWidgetStyle() = default; + + void Layout(const Vector2f& size) override; + + void UpdateRenderLayer(int baseRenderLayer) override; + + SimpleProgressBarWidgetStyle& operator=(const SimpleProgressBarWidgetStyle&) = delete; + SimpleProgressBarWidgetStyle& operator=(SimpleProgressBarWidgetStyle&&) = default; + + struct StyleConfig + { + std::shared_ptr backgroundMaterial; + Color progressBarBeginColor; + Color progressBarEndColor; + float backgroundCornerSize; + float backgroundCornerTexCoords; + float barOffset; + }; + + private: + std::shared_ptr m_backgroundMaterial; + std::shared_ptr m_backgroundSprite; + std::shared_ptr m_progressBarSprite; + entt::entity m_backgroundEntity; + entt::entity m_barEntity; + Color m_progressBarBeginColor; + Color m_progressBarEndColor; + float m_barOffset; + }; class NAZARA_WIDGETS_API SimpleScrollAreaWidgetStyle : public ScrollAreaWidgetStyle { diff --git a/include/Nazara/Widgets/WidgetTheme.hpp b/include/Nazara/Widgets/WidgetTheme.hpp index 6c1873003..f30e1bfb3 100644 --- a/include/Nazara/Widgets/WidgetTheme.hpp +++ b/include/Nazara/Widgets/WidgetTheme.hpp @@ -24,6 +24,8 @@ namespace Nz class ImageButtonWidgetStyle; class LabelWidget; class LabelWidgetStyle; + class ProgressBarWidget; + class ProgressBarWidgetStyle; class ScrollAreaWidget; class ScrollAreaWidgetStyle; class ScrollbarWidget; @@ -45,6 +47,7 @@ namespace Nz virtual std::unique_ptr CreateStyle(CheckboxWidget* checkboxWidget) const = 0; virtual std::unique_ptr CreateStyle(ImageButtonWidget* imageButtonWidget) const = 0; virtual std::unique_ptr CreateStyle(LabelWidget* labelWidget) const = 0; + virtual std::unique_ptr CreateStyle(ProgressBarWidget* labelWidget) const = 0; virtual std::unique_ptr CreateStyle(ScrollAreaWidget* scrollareaWidget) const = 0; virtual std::unique_ptr CreateStyle(ScrollbarWidget* scrollbarWidget) const = 0; virtual std::unique_ptr CreateStyle(ScrollbarButtonWidget* scrollbarButtonWidget) const = 0; @@ -183,6 +186,20 @@ namespace Nz LabelWidgetStyle& operator=(const LabelWidgetStyle&) = delete; LabelWidgetStyle& operator=(LabelWidgetStyle&&) = default; }; + + class NAZARA_WIDGETS_API ProgressBarWidgetStyle : public BaseWidgetStyle + { + public: + using BaseWidgetStyle::BaseWidgetStyle; + ProgressBarWidgetStyle(const ProgressBarWidgetStyle&) = delete; + ProgressBarWidgetStyle(ProgressBarWidgetStyle&&) = default; + ~ProgressBarWidgetStyle() = default; + + virtual void Layout(const Vector2f& size) = 0; + + ProgressBarWidgetStyle& operator=(const ProgressBarWidgetStyle&) = delete; + ProgressBarWidgetStyle& operator=(ProgressBarWidgetStyle&&) = default; + }; class NAZARA_WIDGETS_API ScrollAreaWidgetStyle : public BaseWidgetStyle { diff --git a/src/Nazara/Widgets/DefaultWidgetTheme.cpp b/src/Nazara/Widgets/DefaultWidgetTheme.cpp index 943d7c759..be4eb7b45 100644 --- a/src/Nazara/Widgets/DefaultWidgetTheme.cpp +++ b/src/Nazara/Widgets/DefaultWidgetTheme.cpp @@ -14,7 +14,7 @@ namespace Nz namespace { const UInt8 s_defaultThemeButtonImage[] = { - #include + #include }; const UInt8 s_defaultThemeButtonHoveredImage[] = { @@ -49,6 +49,10 @@ namespace Nz #include }; + const UInt8 s_defaultThemeProgressBarBackgroundImage[] = { + #include + }; + const UInt8 s_defaultThemeScrollbarHorizontalBackgroundImage[] = { #include }; @@ -146,6 +150,9 @@ namespace Nz m_checkboxCheckMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxCheckImage, sizeof(s_defaultThemeCheckboxCheckImage), texParams)); m_checkboxTristateMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxTristateImage, sizeof(s_defaultThemeCheckboxTristateImage), texParams)); + // ProgressBar materials + m_progressBarMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeProgressBarBackgroundImage, sizeof(s_defaultThemeProgressBarBackgroundImage), texParams)); + // Scrollbar materials m_scrollbarBackgroundHorizontalMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarHorizontalBackgroundImage, sizeof(s_defaultThemeScrollbarHorizontalBackgroundImage), texParams)); m_scrollbarBackgroundVerticalMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarVerticalBackgroundImage, sizeof(s_defaultThemeScrollbarVerticalBackgroundImage), texParams)); @@ -179,7 +186,7 @@ namespace Nz { SimpleButtonWidgetStyle::StyleConfig styleConfig; styleConfig.cornerSize = 20.f; - styleConfig.cornerTexCoords = 20.f / 128.f; + styleConfig.cornerTexCoords = 20.f / 42.f; styleConfig.hoveredMaterial = m_buttonHoveredMaterial; styleConfig.material = m_buttonMaterial; styleConfig.pressedHoveredMaterial = m_buttonPressedHoveredMaterial; @@ -216,6 +223,19 @@ namespace Nz return std::make_unique(labelWidget, Widgets::Instance()->GetTransparentMaterial()); } + std::unique_ptr DefaultWidgetTheme::CreateStyle(ProgressBarWidget* progressBarWidget) const + { + SimpleProgressBarWidgetStyle::StyleConfig styleConfig; + styleConfig.backgroundCornerSize = 16.f; + styleConfig.backgroundCornerTexCoords = 16.f / 64.f; + styleConfig.backgroundMaterial = m_progressBarMaterial; + styleConfig.barOffset = 12.f; + styleConfig.progressBarBeginColor = Nz::Color::DarkGreen(); + styleConfig.progressBarEndColor = Nz::Color::Green(); + + return std::make_unique(progressBarWidget, styleConfig); + } + std::unique_ptr DefaultWidgetTheme::CreateStyle(ScrollAreaWidget* scrollAreaWidget) const { return std::make_unique(scrollAreaWidget); diff --git a/src/Nazara/Widgets/ProgressBarWidget.cpp b/src/Nazara/Widgets/ProgressBarWidget.cpp new file mode 100644 index 000000000..a94ddf230 --- /dev/null +++ b/src/Nazara/Widgets/ProgressBarWidget.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2024 Jérôme "SirLynix" 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 + +namespace Nz +{ + ProgressBarWidget::ProgressBarWidget(BaseWidget* parent) : + BaseWidget(parent), + m_fraction(0.f) + { + m_style = GetTheme()->CreateStyle(this); + SetRenderLayerCount(m_style->GetRenderLayerCount()); + + Layout(); + } + + void ProgressBarWidget::Layout() + { + BaseWidget::Layout(); + m_style->Layout(GetSize()); + } + + void ProgressBarWidget::OnRenderLayerUpdated(int baseRenderLayer) + { + m_style->UpdateRenderLayer(baseRenderLayer); + } +} diff --git a/src/Nazara/Widgets/Resources/DefaultTheme/ProgressBarBackground.png b/src/Nazara/Widgets/Resources/DefaultTheme/ProgressBarBackground.png new file mode 100644 index 000000000..226610aff Binary files /dev/null and b/src/Nazara/Widgets/Resources/DefaultTheme/ProgressBarBackground.png differ diff --git a/src/Nazara/Widgets/SimpleWidgetStyles.cpp b/src/Nazara/Widgets/SimpleWidgetStyles.cpp index 5dfdaa33c..760506047 100644 --- a/src/Nazara/Widgets/SimpleWidgetStyles.cpp +++ b/src/Nazara/Widgets/SimpleWidgetStyles.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,7 @@ namespace Nz m_sprite->SetMaterial(m_material); } + /************************************************************************/ SimpleCheckboxWidgetStyle::SimpleCheckboxWidgetStyle(CheckboxWidget* buttonWidget, StyleConfig config) : CheckboxWidgetStyle(buttonWidget, 2), @@ -197,6 +199,7 @@ namespace Nz m_backgroundSprite->SetMaterial(m_material); } + /************************************************************************/ SimpleImageButtonWidgetStyle::SimpleImageButtonWidgetStyle(ImageButtonWidget* imageButtonWidget, StyleConfig config) : ImageButtonWidgetStyle(imageButtonWidget, 1), @@ -337,6 +340,7 @@ namespace Nz } } + /************************************************************************/ SimpleLabelWidgetStyle::SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr material, std::shared_ptr hoveredMaterial) : LabelWidgetStyle(labelWidget, 1), @@ -389,7 +393,62 @@ namespace Nz { m_textSprite->Update(drawer); } + + /************************************************************************/ + SimpleProgressBarWidgetStyle::SimpleProgressBarWidgetStyle(ProgressBarWidget* progressBarWidget, StyleConfig config) : + ProgressBarWidgetStyle(progressBarWidget, 2), + m_backgroundMaterial(std::move(config.backgroundMaterial)), + m_progressBarBeginColor(config.progressBarBeginColor), + m_progressBarEndColor(config.progressBarEndColor), + m_barOffset(config.barOffset) + { + assert(m_backgroundMaterial); + + auto& registry = GetRegistry(); + UInt32 renderMask = GetRenderMask(); + + SlicedSprite::Corner backgroundCorner; + backgroundCorner.size = Vector2f(config.backgroundCornerSize, config.backgroundCornerSize); + backgroundCorner.textureCoords = Vector2f(config.backgroundCornerTexCoords, config.backgroundCornerTexCoords); + + m_backgroundSprite = std::make_shared(m_backgroundMaterial); + m_backgroundSprite->SetCorners(backgroundCorner, backgroundCorner); + + m_backgroundEntity = CreateGraphicsEntity(); + registry.get(m_backgroundEntity).AttachRenderable(m_backgroundSprite, renderMask); + + m_progressBarSprite = std::make_shared(Widgets::Instance()->GetTransparentMaterial()); + m_progressBarSprite->SetCornerColor(RectCorner::LeftBottom, m_progressBarBeginColor); + m_progressBarSprite->SetCornerColor(RectCorner::LeftTop, m_progressBarBeginColor); + m_progressBarSprite->SetCornerColor(RectCorner::RightBottom, m_progressBarEndColor); + m_progressBarSprite->SetCornerColor(RectCorner::RightTop, m_progressBarEndColor); + + m_barEntity = CreateGraphicsEntity(); + registry.get(m_barEntity).AttachRenderable(m_progressBarSprite, renderMask); + registry.get(m_barEntity).SetPosition(m_barOffset, m_barOffset); + } + + void SimpleProgressBarWidgetStyle::Layout(const Vector2f& size) + { + float fraction = GetOwnerWidget()->GetFraction(); + float width = std::max(fraction * (size.x - m_barOffset * 2.f), 0.f); + + Color endColor = Lerp(m_progressBarBeginColor, m_progressBarEndColor, fraction); + m_progressBarSprite->SetCornerColor(RectCorner::RightBottom, endColor); + m_progressBarSprite->SetCornerColor(RectCorner::RightTop, endColor); + + m_backgroundSprite->SetSize(size); + m_progressBarSprite->SetSize({ width, size.y - m_barOffset * 2.f }); + } + + void SimpleProgressBarWidgetStyle::UpdateRenderLayer(int baseRenderLayer) + { + m_backgroundSprite->UpdateRenderLayer(baseRenderLayer); + m_progressBarSprite->UpdateRenderLayer(baseRenderLayer + 1); + } + + /************************************************************************/ SimpleScrollAreaWidgetStyle::SimpleScrollAreaWidgetStyle(ScrollAreaWidget* scrollAreaWidget) : ScrollAreaWidgetStyle(scrollAreaWidget, 0) @@ -431,6 +490,7 @@ namespace Nz m_backgroundScrollbarSprite->UpdateRenderLayer(baseRenderLayer); } + /************************************************************************/ SimpleScrollbarButtonWidgetStyle::SimpleScrollbarButtonWidgetStyle(ScrollbarButtonWidget* scrollbarButtonWidget, StyleConfig config) : ScrollbarButtonWidgetStyle(scrollbarButtonWidget, 1),