Add widgets (WIP)
This commit is contained in:
181
include/Nazara/Widgets/BaseWidget.hpp
Normal file
181
include/Nazara/Widgets/BaseWidget.hpp
Normal file
@@ -0,0 +1,181 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_BASEWIDGET_HPP
|
||||
#define NAZARA_BASEWIDGET_HPP
|
||||
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Platform/Event.hpp>
|
||||
#include <Nazara/Platform/Mouse.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
#include <Nazara/Widgets/Config.hpp>
|
||||
#include <entt/entity/entity.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class Canvas;
|
||||
|
||||
class NAZARA_WIDGETS_API BaseWidget : public Nz::Node
|
||||
{
|
||||
friend Canvas;
|
||||
|
||||
public:
|
||||
BaseWidget(BaseWidget* parent);
|
||||
BaseWidget(const BaseWidget&) = delete;
|
||||
BaseWidget(BaseWidget&&) = delete;
|
||||
virtual ~BaseWidget();
|
||||
|
||||
template<typename T, typename... Args> T* Add(Args&&... args);
|
||||
inline void AddChild(std::unique_ptr<BaseWidget>&& widget);
|
||||
|
||||
inline void Center();
|
||||
inline void CenterHorizontal();
|
||||
inline void CenterVertical();
|
||||
|
||||
void ClearFocus();
|
||||
inline void ClearRenderingRect();
|
||||
|
||||
void Destroy();
|
||||
|
||||
void EnableBackground(bool enable);
|
||||
|
||||
template<typename F> void ForEachWidgetChild(F iterator);
|
||||
template<typename F> void ForEachWidgetChild(F iterator) const;
|
||||
|
||||
//virtual BaseWidget* Clone() const = 0;
|
||||
|
||||
inline const Color& GetBackgroundColor() const;
|
||||
inline Canvas* GetCanvas();
|
||||
inline Nz::SystemCursor GetCursor() const;
|
||||
inline float GetHeight() const;
|
||||
|
||||
inline float GetMaximumHeight() const;
|
||||
inline Nz::Vector2f GetMaximumSize() const;
|
||||
inline float GetMaximumWidth() const;
|
||||
|
||||
inline float GetMinimumHeight() const;
|
||||
inline Nz::Vector2f GetMinimumSize() const;
|
||||
inline float GetMinimumWidth() const;
|
||||
|
||||
inline float GetPreferredHeight() const;
|
||||
inline Nz::Vector2f GetPreferredSize() const;
|
||||
inline float GetPreferredWidth() const;
|
||||
|
||||
inline const Nz::Rectf& GetRenderingRect() const;
|
||||
|
||||
inline Nz::Vector2f GetSize() const;
|
||||
inline float GetWidth() const;
|
||||
inline std::size_t GetWidgetChildCount() const;
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
inline void Hide();
|
||||
inline bool IsVisible() const;
|
||||
|
||||
void Resize(const Nz::Vector2f& size);
|
||||
|
||||
void SetBackgroundColor(const Color& color);
|
||||
void SetCursor(Nz::SystemCursor systemCursor);
|
||||
void SetFocus();
|
||||
void SetParent(BaseWidget* widget);
|
||||
|
||||
inline void SetFixedHeight(float fixedHeight);
|
||||
inline void SetFixedSize(const Nz::Vector2f& fixedSize);
|
||||
inline void SetFixedWidth(float fixedWidth);
|
||||
|
||||
inline void SetMaximumHeight(float maximumHeight);
|
||||
inline void SetMaximumSize(const Nz::Vector2f& maximumSize);
|
||||
inline void SetMaximumWidth(float maximumWidth);
|
||||
|
||||
inline void SetMinimumHeight(float minimumHeight);
|
||||
inline void SetMinimumSize(const Nz::Vector2f& minimumSize);
|
||||
inline void SetMinimumWidth(float minimumWidth);
|
||||
|
||||
virtual void SetRenderingRect(const Nz::Rectf& renderingRect);
|
||||
|
||||
void Show(bool show = true);
|
||||
|
||||
BaseWidget& operator=(const BaseWidget&) = delete;
|
||||
BaseWidget& operator=(BaseWidget&&) = delete;
|
||||
|
||||
protected:
|
||||
entt::entity CreateEntity();
|
||||
void DestroyEntity(entt::entity entity);
|
||||
virtual void Layout();
|
||||
|
||||
void InvalidateNode() override;
|
||||
|
||||
inline entt::registry& GetRegistry();
|
||||
inline const entt::registry& GetRegistry() const;
|
||||
Nz::Rectf GetScissorRect() const;
|
||||
|
||||
virtual bool IsFocusable() const;
|
||||
virtual void OnFocusLost();
|
||||
virtual void OnFocusReceived();
|
||||
virtual bool OnKeyPressed(const Nz::WindowEvent::KeyEvent& key);
|
||||
virtual void OnKeyReleased(const Nz::WindowEvent::KeyEvent& key);
|
||||
virtual void OnMouseEnter();
|
||||
virtual void OnMouseMoved(int x, int y, int deltaX, int deltaY);
|
||||
virtual void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button);
|
||||
virtual void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button);
|
||||
virtual void OnMouseWheelMoved(int x, int y, float delta);
|
||||
virtual void OnMouseExit();
|
||||
virtual void OnParentResized(const Nz::Vector2f& newSize);
|
||||
virtual void OnTextEntered(char32_t character, bool repeated);
|
||||
virtual void OnTextEdited(const std::array<char, 32>& characters, int length);
|
||||
|
||||
inline void SetPreferredSize(const Nz::Vector2f& preferredSize);
|
||||
|
||||
virtual void ShowChildren(bool show);
|
||||
|
||||
private:
|
||||
inline BaseWidget();
|
||||
|
||||
void DestroyChild(BaseWidget* widget);
|
||||
void DestroyChildren();
|
||||
inline bool IsRegisteredToCanvas() const;
|
||||
inline void NotifyParentResized(const Nz::Vector2f& newSize);
|
||||
void RegisterToCanvas();
|
||||
inline void UpdateCanvasIndex(std::size_t index);
|
||||
void UnregisterFromCanvas();
|
||||
void UpdatePositionAndSize();
|
||||
|
||||
struct WidgetEntity
|
||||
{
|
||||
entt::entity handle;
|
||||
bool isEnabled = true;
|
||||
|
||||
//NazaraSlot(Ndk::Entity, OnEntityDisabled, onDisabledSlot);
|
||||
//NazaraSlot(Ndk::Entity, OnEntityEnabled, onEnabledSlot);
|
||||
};
|
||||
|
||||
static constexpr std::size_t InvalidCanvasIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
std::optional<entt::entity> m_backgroundEntity;
|
||||
std::size_t m_canvasIndex;
|
||||
std::shared_ptr<Nz::Sprite> m_backgroundSprite;
|
||||
std::vector<WidgetEntity> m_entities;
|
||||
std::vector<std::unique_ptr<BaseWidget>> m_children;
|
||||
entt::registry* m_registry;
|
||||
Canvas* m_canvas;
|
||||
Color m_backgroundColor;
|
||||
Nz::Rectf m_renderingRect;
|
||||
Nz::SystemCursor m_cursor;
|
||||
Nz::Vector2f m_maximumSize;
|
||||
Nz::Vector2f m_minimumSize;
|
||||
Nz::Vector2f m_preferredSize;
|
||||
Nz::Vector2f m_size;
|
||||
BaseWidget* m_widgetParent;
|
||||
bool m_visible;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/BaseWidget.inl>
|
||||
|
||||
#endif // NAZARA_BASEWIDGET_HPP
|
||||
276
include/Nazara/Widgets/BaseWidget.inl
Normal file
276
include/Nazara/Widgets/BaseWidget.inl
Normal file
@@ -0,0 +1,276 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Widgets/BaseWidget.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline BaseWidget::BaseWidget() :
|
||||
m_canvasIndex(InvalidCanvasIndex),
|
||||
m_registry(nullptr),
|
||||
m_canvas(nullptr),
|
||||
m_backgroundColor(Color(230, 230, 230, 255)),
|
||||
m_renderingRect(-std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()),
|
||||
m_cursor(Nz::SystemCursor::Default),
|
||||
m_maximumSize(std::numeric_limits<float>::infinity()),
|
||||
m_minimumSize(0.f),
|
||||
m_preferredSize(-1),
|
||||
m_size(50.f, 50.f),
|
||||
m_widgetParent(nullptr),
|
||||
m_visible(true)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
inline T* BaseWidget::Add(Args&&... args)
|
||||
{
|
||||
std::unique_ptr<T> widget = std::make_unique<T>(this, std::forward<Args>(args)...);
|
||||
T* widgetPtr = widget.get();
|
||||
AddChild(std::move(widget));
|
||||
|
||||
return widgetPtr;
|
||||
}
|
||||
|
||||
inline void BaseWidget::AddChild(std::unique_ptr<BaseWidget>&& widget)
|
||||
{
|
||||
widget->Show(m_visible);
|
||||
widget->SetParent(this);
|
||||
m_children.emplace_back(std::move(widget));
|
||||
}
|
||||
|
||||
inline void BaseWidget::Center()
|
||||
{
|
||||
NazaraAssert(m_widgetParent, "Widget has no parent");
|
||||
|
||||
Nz::Vector2f parentSize = m_widgetParent->GetSize();
|
||||
Nz::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");
|
||||
|
||||
Nz::Vector2f parentSize = m_widgetParent->GetSize();
|
||||
Nz::Vector2f mySize = GetSize();
|
||||
SetPosition((parentSize.x - mySize.x) / 2.f, GetPosition(Nz::CoordSys::Local).y);
|
||||
}
|
||||
|
||||
inline void BaseWidget::CenterVertical()
|
||||
{
|
||||
NazaraAssert(m_widgetParent, "Widget has no parent");
|
||||
|
||||
Nz::Vector2f parentSize = m_widgetParent->GetSize();
|
||||
Nz::Vector2f mySize = GetSize();
|
||||
SetPosition(GetPosition(Nz::CoordSys::Local).x, (parentSize.y - mySize.y) / 2.f);
|
||||
}
|
||||
|
||||
inline void BaseWidget::ClearRenderingRect()
|
||||
{
|
||||
SetRenderingRect(Nz::Rectf(-std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline void BaseWidget::ForEachWidgetChild(F iterator)
|
||||
{
|
||||
for (const auto& child : m_children)
|
||||
iterator(child.get());
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
inline void BaseWidget::ForEachWidgetChild(F iterator) const
|
||||
{
|
||||
for (const auto& child : m_children)
|
||||
iterator(static_cast<const BaseWidget*>(child.get()));
|
||||
}
|
||||
|
||||
inline const Color& BaseWidget::GetBackgroundColor() const
|
||||
{
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
inline Canvas* BaseWidget::GetCanvas()
|
||||
{
|
||||
return m_canvas;
|
||||
}
|
||||
|
||||
inline Nz::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 Nz::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 Nz::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 Nz::Vector2f BaseWidget::GetPreferredSize() const
|
||||
{
|
||||
return m_preferredSize;
|
||||
}
|
||||
|
||||
inline float BaseWidget::GetPreferredWidth() const
|
||||
{
|
||||
return m_preferredSize.x;
|
||||
}
|
||||
|
||||
inline const Nz::Rectf& BaseWidget::GetRenderingRect() const
|
||||
{
|
||||
return m_renderingRect;
|
||||
}
|
||||
|
||||
inline Nz::Vector2f BaseWidget::GetSize() const
|
||||
{
|
||||
return Nz::Vector2f(GetWidth(), GetHeight());
|
||||
}
|
||||
|
||||
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::IsVisible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetFixedHeight(float fixedHeight)
|
||||
{
|
||||
SetMaximumHeight(fixedHeight);
|
||||
SetMinimumHeight(fixedHeight);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetFixedSize(const Nz::Vector2f& fixedSize)
|
||||
{
|
||||
SetMaximumSize(fixedSize);
|
||||
SetMinimumSize(fixedSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetFixedWidth(float fixedWidth)
|
||||
{
|
||||
SetMaximumWidth(fixedWidth);
|
||||
SetMinimumWidth(fixedWidth);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetMaximumHeight(float maximumHeight)
|
||||
{
|
||||
Nz::Vector2f maximumSize = GetMaximumSize();
|
||||
maximumSize.y = maximumHeight;
|
||||
|
||||
SetMaximumSize(maximumSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetMaximumSize(const Nz::Vector2f& maximumSize)
|
||||
{
|
||||
m_maximumSize = maximumSize;
|
||||
|
||||
Nz::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)
|
||||
{
|
||||
Nz::Vector2f maximumSize = GetMaximumSize();
|
||||
maximumSize.x = maximumWidth;
|
||||
|
||||
SetMaximumSize(maximumSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetMinimumHeight(float minimumHeight)
|
||||
{
|
||||
Nz::Vector2f minimumSize = GetMinimumSize();
|
||||
minimumSize.y = minimumHeight;
|
||||
|
||||
SetMinimumSize(minimumSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetMinimumSize(const Nz::Vector2f& minimumSize)
|
||||
{
|
||||
m_minimumSize = minimumSize;
|
||||
|
||||
Nz::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)
|
||||
{
|
||||
Nz::Vector2f minimumSize = GetMinimumSize();
|
||||
minimumSize.x = minimumWidth;
|
||||
|
||||
SetMinimumSize(minimumSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::SetPreferredSize(const Nz::Vector2f& preferredSize)
|
||||
{
|
||||
m_preferredSize = preferredSize;
|
||||
|
||||
//Resize(m_preferredSize);
|
||||
}
|
||||
|
||||
inline bool BaseWidget::IsRegisteredToCanvas() const
|
||||
{
|
||||
return m_canvas && m_canvasIndex != InvalidCanvasIndex;
|
||||
}
|
||||
|
||||
inline void BaseWidget::NotifyParentResized(const Nz::Vector2f& newSize)
|
||||
{
|
||||
for (const auto& widgetPtr : m_children)
|
||||
widgetPtr->OnParentResized(newSize);
|
||||
}
|
||||
|
||||
inline void BaseWidget::UpdateCanvasIndex(std::size_t index)
|
||||
{
|
||||
m_canvasIndex = index;
|
||||
}
|
||||
}
|
||||
72
include/Nazara/Widgets/ButtonWidget.hpp
Normal file
72
include/Nazara/Widgets/ButtonWidget.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_BUTTONWIDGET_HPP
|
||||
#define NAZARA_BUTTONWIDGET_HPP
|
||||
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Widgets/BaseWidget.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractTextDrawer;
|
||||
|
||||
class NAZARA_WIDGETS_API ButtonWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
ButtonWidget(BaseWidget* parent);
|
||||
ButtonWidget(const ButtonWidget&) = delete;
|
||||
ButtonWidget(ButtonWidget&&) = default;
|
||||
~ButtonWidget() = default;
|
||||
|
||||
inline const Color& GetColor() const;
|
||||
inline const Color& GetCornerColor() const;
|
||||
inline const Color& GetHoverColor() const;
|
||||
inline const Color& GetHoverCornerColor() const;
|
||||
inline const Color& GetPressColor() const;
|
||||
inline const Color& GetPressCornerColor() const;
|
||||
|
||||
inline const std::shared_ptr<Texture>& GetTexture() const;
|
||||
inline const std::shared_ptr<Texture>& GetHoverTexture() const;
|
||||
inline const std::shared_ptr<Texture>& GetPressTexture() const;
|
||||
|
||||
inline void SetColor(const Color& color, const Color& cornerColor);
|
||||
inline void SetHoverColor(const Color& color, const Color& cornerColor);
|
||||
inline void SetPressColor(const Color& color, const Color& cornerColor);
|
||||
|
||||
inline void UpdateText(const AbstractTextDrawer& drawer);
|
||||
|
||||
ButtonWidget& operator=(const ButtonWidget&) = delete;
|
||||
ButtonWidget& operator=(ButtonWidget&&) = default;
|
||||
|
||||
NazaraSignal(OnButtonTrigger, const ButtonWidget* /*button*/);
|
||||
|
||||
private:
|
||||
void Layout() override;
|
||||
|
||||
void OnMouseEnter() override;
|
||||
void OnMouseButtonPress(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseButtonRelease(int x, int y, Mouse::Button button) override;
|
||||
void OnMouseExit() override;
|
||||
|
||||
std::shared_ptr<Sprite> m_gradientSprite;
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
entt::entity m_textEntity;
|
||||
entt::entity m_gradientEntity;
|
||||
Color m_color;
|
||||
Color m_cornerColor;
|
||||
Color m_hoverColor;
|
||||
Color m_hoverCornerColor;
|
||||
Color m_pressColor;
|
||||
Color m_pressCornerColor;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/ButtonWidget.inl>
|
||||
|
||||
#endif // NDK_WIDGETS_BUTTONWIDGET_HPP
|
||||
71
include/Nazara/Widgets/ButtonWidget.inl
Normal file
71
include/Nazara/Widgets/ButtonWidget.inl
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Widgets/ButtonWidget.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline const Color& ButtonWidget::GetColor() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
inline const Color& ButtonWidget::GetCornerColor() const
|
||||
{
|
||||
return m_cornerColor;
|
||||
}
|
||||
|
||||
inline const Color& ButtonWidget::GetHoverColor() const
|
||||
{
|
||||
return m_hoverColor;
|
||||
}
|
||||
|
||||
inline const Color& ButtonWidget::GetHoverCornerColor() const
|
||||
{
|
||||
return m_hoverCornerColor;
|
||||
}
|
||||
|
||||
inline const Color& ButtonWidget::GetPressColor() const
|
||||
{
|
||||
return m_pressColor;
|
||||
}
|
||||
|
||||
inline const Color& ButtonWidget::GetPressCornerColor() const
|
||||
{
|
||||
return m_pressCornerColor;
|
||||
}
|
||||
|
||||
inline void ButtonWidget::SetColor(const Color& color, const Color& cornerColor)
|
||||
{
|
||||
m_color = color;
|
||||
m_cornerColor = cornerColor;
|
||||
|
||||
m_gradientSprite->SetColor(m_color);
|
||||
m_gradientSprite->SetCornerColor(Nz::RectCorner::LeftBottom, m_cornerColor);
|
||||
m_gradientSprite->SetCornerColor(Nz::RectCorner::RightBottom, m_cornerColor);
|
||||
}
|
||||
|
||||
inline void ButtonWidget::SetHoverColor(const Color& color, const Color& cornerColor)
|
||||
{
|
||||
m_hoverColor = color;
|
||||
m_hoverCornerColor = cornerColor;
|
||||
}
|
||||
|
||||
inline void ButtonWidget::SetPressColor(const Color& color, const Color& cornerColor)
|
||||
{
|
||||
m_pressColor = color;
|
||||
m_pressCornerColor = cornerColor;
|
||||
}
|
||||
|
||||
inline void ButtonWidget::UpdateText(const Nz::AbstractTextDrawer& drawer)
|
||||
{
|
||||
m_textSprite->Update(drawer);
|
||||
|
||||
Nz::Vector2f textSize = Nz::Vector2f(m_textSprite->GetAABB().GetLengths());
|
||||
SetMinimumSize(textSize);
|
||||
SetPreferredSize(textSize + Nz::Vector2f(20.f, 10.f));
|
||||
|
||||
Layout();
|
||||
}
|
||||
}
|
||||
88
include/Nazara/Widgets/Canvas.hpp
Normal file
88
include/Nazara/Widgets/Canvas.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// 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_CANVAS_HPP
|
||||
#define NAZARA_CANVAS_HPP
|
||||
|
||||
#include <Nazara/Platform/CursorController.hpp>
|
||||
#include <Nazara/Platform/EventHandler.hpp>
|
||||
#include <Nazara/Widgets/BaseWidget.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_WIDGETS_API Canvas : public BaseWidget
|
||||
{
|
||||
friend BaseWidget;
|
||||
|
||||
public:
|
||||
inline Canvas(entt::registry& registry, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController);
|
||||
Canvas(const Canvas&) = delete;
|
||||
Canvas(Canvas&&) = delete;
|
||||
inline ~Canvas();
|
||||
|
||||
inline entt::registry& GetRegistry();
|
||||
inline const entt::registry& GetRegistry() const;
|
||||
|
||||
Canvas& operator=(const Canvas&) = delete;
|
||||
Canvas& operator=(Canvas&&) = delete;
|
||||
|
||||
NazaraSignal(OnUnhandledKeyPressed, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnUnhandledKeyReleased, const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::KeyEvent& /*event*/);
|
||||
|
||||
protected:
|
||||
inline void ClearKeyboardOwner(std::size_t canvasIndex);
|
||||
|
||||
inline bool IsKeyboardOwner(std::size_t canvasIndex) const;
|
||||
|
||||
inline void NotifyWidgetBoxUpdate(std::size_t index);
|
||||
inline void NotifyWidgetCursorUpdate(std::size_t index);
|
||||
|
||||
std::size_t RegisterWidget(BaseWidget* widget);
|
||||
|
||||
inline void SetKeyboardOwner(std::size_t canvasIndex);
|
||||
|
||||
void UnregisterWidget(std::size_t index);
|
||||
|
||||
private:
|
||||
void OnEventMouseButtonPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseButtonRelease(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseLeft(const Nz::EventHandler* eventHandler);
|
||||
void OnEventMouseMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseMoveEvent& event);
|
||||
void OnEventMouseWheelMoved(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::MouseWheelEvent& event);
|
||||
void OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
|
||||
void OnEventTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event);
|
||||
void OnEventTextEdited(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::EditEvent& event);
|
||||
|
||||
struct WidgetEntry
|
||||
{
|
||||
BaseWidget* widget;
|
||||
Nz::Boxf box;
|
||||
Nz::SystemCursor cursor;
|
||||
};
|
||||
|
||||
NazaraSlot(Nz::EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnKeyReleased, m_keyReleasedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnMouseButtonReleased, m_mouseButtonReleasedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnMouseLeft, m_mouseLeftSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot);
|
||||
NazaraSlot(Nz::EventHandler, OnTextEdited, m_textEditedSlot);
|
||||
|
||||
std::size_t m_keyboardOwner;
|
||||
std::size_t m_hoveredWidget;
|
||||
std::vector<WidgetEntry> m_widgetEntries;
|
||||
entt::registry& m_registry;
|
||||
Nz::CursorControllerHandle m_cursorController;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/Canvas.inl>
|
||||
|
||||
#endif // NDK_CANVAS_HPP
|
||||
99
include/Nazara/Widgets/Canvas.inl
Normal file
99
include/Nazara/Widgets/Canvas.inl
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Widgets module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Widgets/Canvas.hpp>
|
||||
#include <Nazara/Platform/Cursor.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline Canvas::Canvas(entt::registry& registry, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController) :
|
||||
m_keyboardOwner(InvalidCanvasIndex),
|
||||
m_hoveredWidget(InvalidCanvasIndex),
|
||||
m_registry(registry),
|
||||
m_cursorController(cursorController)
|
||||
{
|
||||
m_canvas = this;
|
||||
m_widgetParent = nullptr;
|
||||
|
||||
// Register ourselves as a widget to handle cursor change
|
||||
RegisterToCanvas();
|
||||
|
||||
// Connect to every meaningful event
|
||||
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, this, &Canvas::OnEventKeyPressed);
|
||||
m_keyReleasedSlot.Connect(eventHandler.OnKeyReleased, this, &Canvas::OnEventKeyReleased);
|
||||
m_mouseButtonPressedSlot.Connect(eventHandler.OnMouseButtonPressed, this, &Canvas::OnEventMouseButtonPressed);
|
||||
m_mouseButtonReleasedSlot.Connect(eventHandler.OnMouseButtonReleased, this, &Canvas::OnEventMouseButtonRelease);
|
||||
m_mouseLeftSlot.Connect(eventHandler.OnMouseLeft, this, &Canvas::OnEventMouseLeft);
|
||||
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnEventMouseMoved);
|
||||
m_mouseWheelMovedSlot.Connect(eventHandler.OnMouseWheelMoved, this, &Canvas::OnEventMouseWheelMoved);
|
||||
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnEventTextEntered);
|
||||
m_textEditedSlot.Connect(eventHandler.OnTextEdited, this, &Canvas::OnEventTextEdited);
|
||||
}
|
||||
|
||||
inline Canvas::~Canvas()
|
||||
{
|
||||
// Destroy children explicitly because they signal us when getting destroyed, and that can't happen after our own destruction
|
||||
DestroyChildren();
|
||||
|
||||
// Prevent our parent from trying to call us
|
||||
m_canvasIndex = InvalidCanvasIndex;
|
||||
}
|
||||
|
||||
inline entt::registry& Canvas::GetRegistry()
|
||||
{
|
||||
return m_registry;
|
||||
}
|
||||
|
||||
inline const entt::registry& Canvas::GetRegistry() const
|
||||
{
|
||||
return m_registry;
|
||||
}
|
||||
|
||||
inline void Canvas::ClearKeyboardOwner(std::size_t canvasIndex)
|
||||
{
|
||||
if (m_keyboardOwner == canvasIndex)
|
||||
SetKeyboardOwner(InvalidCanvasIndex);
|
||||
}
|
||||
|
||||
inline bool Canvas::IsKeyboardOwner(std::size_t canvasIndex) const
|
||||
{
|
||||
return m_keyboardOwner == canvasIndex;
|
||||
}
|
||||
|
||||
inline void Canvas::NotifyWidgetBoxUpdate(std::size_t index)
|
||||
{
|
||||
WidgetEntry& entry = m_widgetEntries[index];
|
||||
|
||||
Nz::Vector3f pos = entry.widget->GetPosition(Nz::CoordSys::Global);
|
||||
Nz::Vector2f size = entry.widget->GetSize();
|
||||
|
||||
entry.box.Set(pos.x, pos.y, pos.z, size.x, size.y, 1.f);
|
||||
}
|
||||
|
||||
inline void Canvas::NotifyWidgetCursorUpdate(std::size_t index)
|
||||
{
|
||||
WidgetEntry& entry = m_widgetEntries[index];
|
||||
|
||||
entry.cursor = entry.widget->GetCursor();
|
||||
if (m_cursorController && m_hoveredWidget == index)
|
||||
m_cursorController->UpdateCursor(Nz::Cursor::Get(entry.cursor));
|
||||
}
|
||||
|
||||
inline void Canvas::SetKeyboardOwner(std::size_t canvasIndex)
|
||||
{
|
||||
if (m_keyboardOwner != canvasIndex)
|
||||
{
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
m_widgetEntries[m_keyboardOwner].widget->OnFocusLost();
|
||||
|
||||
m_keyboardOwner = canvasIndex;
|
||||
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
m_widgetEntries[m_keyboardOwner].widget->OnFocusReceived();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/DebugOff.hpp>
|
||||
53
include/Nazara/Widgets/Config.hpp
Normal file
53
include/Nazara/Widgets/Config.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Nazara Engine - Widgets module
|
||||
|
||||
Copyright (C) 2020 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_WIDGETS_HPP
|
||||
#define NAZARA_CONFIG_WIDGETS_HPP
|
||||
|
||||
/*!
|
||||
* \defgroup widgets (NazaraWidgets) Widgets module
|
||||
* Widgets module including classes to handle widgets...
|
||||
*/
|
||||
|
||||
/// Each modification of a parameter needs a recompilation of the module
|
||||
|
||||
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
|
||||
#define NAZARA_WIDGETS_MANAGE_MEMORY 0
|
||||
|
||||
/// Checking the values and types of certain constants
|
||||
#include <Nazara/Widgets/ConfigCheck.hpp>
|
||||
|
||||
#if !defined(NAZARA_STATIC)
|
||||
#ifdef NAZARA_WIDGETS_BUILD
|
||||
#define NAZARA_WIDGETS_API NAZARA_EXPORT
|
||||
#else
|
||||
#define NAZARA_WIDGETS_API NAZARA_IMPORT
|
||||
#endif
|
||||
#else
|
||||
#define NAZARA_WIDGETS_API
|
||||
#endif
|
||||
|
||||
#endif // NAZARA_CONFIG_WIDGETS_HPP
|
||||
23
include/Nazara/Widgets/ConfigCheck.hpp
Normal file
23
include/Nazara/Widgets/ConfigCheck.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// 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_CONFIG_CHECK_WIDGETS_HPP
|
||||
#define NAZARA_CONFIG_CHECK_WIDGETS_HPP
|
||||
|
||||
/// This file is used to check the constant values defined in Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
|
||||
// We force the value of MANAGE_MEMORY in debug
|
||||
#if defined(NAZARA_DEBUG) && !NAZARA_WIDGETS_MANAGE_MEMORY
|
||||
#undef NAZARA_WIDGETS_MANAGE_MEMORY
|
||||
#define NAZARA_WIDGETS_MANAGE_MEMORY 0
|
||||
#endif
|
||||
|
||||
#undef NazaraCheckTypeAndVal
|
||||
|
||||
#endif // NAZARA_CONFIG_CHECK_WIDGETS_HPP
|
||||
8
include/Nazara/Widgets/Debug.hpp
Normal file
8
include/Nazara/Widgets/Debug.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Widgets/Config.hpp>
|
||||
#if NAZARA_WIDGETS_MANAGE_MEMORY
|
||||
#include <Nazara/Core/Debug/NewRedefinition.hpp>
|
||||
#endif
|
||||
9
include/Nazara/Widgets/DebugOff.hpp
Normal file
9
include/Nazara/Widgets/DebugOff.hpp
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// We assume that Debug.hpp has already been included, same thing for Config.hpp
|
||||
#if NAZARA_WIDGETS_MANAGE_MEMORY
|
||||
#undef delete
|
||||
#undef new
|
||||
#endif
|
||||
39
include/Nazara/Widgets/LabelWidget.hpp
Normal file
39
include/Nazara/Widgets/LabelWidget.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LABELWIDGET_HPP
|
||||
#define NAZARA_LABELWIDGET_HPP
|
||||
|
||||
#include <Nazara/Graphics/TextSprite.hpp>
|
||||
#include <Nazara/Widgets/BaseWidget.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractTextDrawer;
|
||||
class TextSprite;
|
||||
|
||||
class NAZARA_WIDGETS_API LabelWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
LabelWidget(BaseWidget* parent);
|
||||
LabelWidget(const LabelWidget&) = delete;
|
||||
LabelWidget(LabelWidget&&) = default;
|
||||
~LabelWidget() = default;
|
||||
|
||||
inline void UpdateText(const AbstractTextDrawer& drawer, float scale = 1.f);
|
||||
|
||||
LabelWidget& operator=(const LabelWidget&) = delete;
|
||||
LabelWidget& operator=(LabelWidget&&) = default;
|
||||
|
||||
private:
|
||||
entt::entity m_textEntity;
|
||||
std::shared_ptr<TextSprite> m_textSprite;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/LabelWidget.inl>
|
||||
|
||||
#endif
|
||||
17
include/Nazara/Widgets/LabelWidget.inl
Normal file
17
include/Nazara/Widgets/LabelWidget.inl
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Development Kit"
|
||||
// For conditions of distribution and use, see copyright notice in Prerequisites.hpp
|
||||
|
||||
#include <Nazara/Widgets/LabelWidget.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline void LabelWidget::UpdateText(const Nz::AbstractTextDrawer& drawer, float scale)
|
||||
{
|
||||
m_textSprite->Update(drawer, scale);
|
||||
|
||||
Nz::Vector2f size = Nz::Vector2f(m_textSprite->GetAABB().GetLengths());
|
||||
SetMinimumSize(size);
|
||||
SetPreferredSize(size);
|
||||
}
|
||||
}
|
||||
39
include/Nazara/Widgets/Widgets.hpp
Normal file
39
include/Nazara/Widgets/Widgets.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2020 Jérôme Leclercq
|
||||
// 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_HPP
|
||||
#define NAZARA_WIDGETS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ModuleBase.hpp>
|
||||
#include <Nazara/Core/ECS.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Widgets/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_WIDGETS_API Widgets : public ModuleBase<Widgets>
|
||||
{
|
||||
friend ModuleBase;
|
||||
|
||||
public:
|
||||
using Dependencies = TypeList<ECS, Graphics>;
|
||||
|
||||
struct Config;
|
||||
|
||||
Widgets(Config config);
|
||||
~Widgets() = default;
|
||||
|
||||
struct Config {};
|
||||
|
||||
private:
|
||||
static Widgets* s_instance;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/Widgets.inl>
|
||||
|
||||
#endif
|
||||
12
include/Nazara/Widgets/Widgets.inl
Normal file
12
include/Nazara/Widgets/Widgets.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Widgets/Widgets.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Widgets/DebugOff.hpp>
|
||||
Reference in New Issue
Block a user