WIP
@@ -15,8 +15,8 @@
|
||||
namespace Nz
|
||||
{
|
||||
/*!
|
||||
* \ingroup NDK
|
||||
* \class Ndk::BaseWidget
|
||||
* \ingroup Widgets
|
||||
* \class BaseWidget
|
||||
* \brief Abstract class serving as a base class for all widgets
|
||||
*/
|
||||
|
||||
@@ -288,8 +288,9 @@ namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseButtonDoublePress(int /*x*/, int /*y*/, Mouse::Button /*button*/)
|
||||
void BaseWidget::OnMouseButtonDoublePress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
return OnMouseButtonPress(x, y, button);
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button /*button*/)
|
||||
@@ -300,8 +301,9 @@ namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseButtonTriplePress(int /*x*/, int /*y*/, Mouse::Button /*button*/)
|
||||
void BaseWidget::OnMouseButtonTriplePress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
return OnMouseButtonPress(x, y, button);
|
||||
}
|
||||
|
||||
void BaseWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float /*delta*/)
|
||||
|
||||
142
src/Nazara/Widgets/BoxLayout.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
// 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
|
||||
|
||||
#if 0
|
||||
|
||||
#include <Nazara/Widgets/BoxLayout.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/StackVector.hpp>
|
||||
#include <kiwi/kiwi.h>
|
||||
#include <NDK/Widgets/BoxLayout.hpp>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct BoxLayout::State
|
||||
{
|
||||
std::vector<kiwi::Variable> sizeVar;
|
||||
kiwi::Solver solver;
|
||||
};
|
||||
|
||||
BoxLayout::BoxLayout(BaseWidget* parent, BoxLayoutOrientation orientation) :
|
||||
BaseWidget(parent),
|
||||
m_orientation(orientation),
|
||||
m_spacing(5.f)
|
||||
{
|
||||
m_state = std::make_unique<State>();
|
||||
}
|
||||
|
||||
BoxLayout::~BoxLayout() = default;
|
||||
|
||||
void BoxLayout::Layout()
|
||||
{
|
||||
BaseWidget::Layout();
|
||||
|
||||
std::size_t axis;
|
||||
|
||||
switch (m_orientation)
|
||||
{
|
||||
case BoxLayoutOrientation_Horizontal:
|
||||
axis = 0; //< x
|
||||
break;
|
||||
|
||||
case BoxLayoutOrientation_Vertical:
|
||||
axis = 1; //< y
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: Keep solver state when widgets don't change
|
||||
std::size_t widgetChildCount = GetWidgetChildCount();
|
||||
if (widgetChildCount == 0)
|
||||
return;
|
||||
|
||||
m_state->solver.reset();
|
||||
|
||||
m_state->sizeVar.clear();
|
||||
m_state->sizeVar.reserve(widgetChildCount);
|
||||
|
||||
kiwi::Expression sizeSum;
|
||||
|
||||
Nz::Vector2f layoutSize = GetSize();
|
||||
float availableSpace = layoutSize[axis] - m_spacing * (widgetChildCount - 1);
|
||||
float perfectSpacePerWidget = availableSpace / widgetChildCount;
|
||||
|
||||
// Handle size
|
||||
ForEachWidgetChild([&](BaseWidget* child)
|
||||
{
|
||||
if (!child->IsVisible())
|
||||
return;
|
||||
|
||||
float maximumSize = child->GetMaximumSize()[axis];
|
||||
float minimumSize = child->GetMinimumSize()[axis];
|
||||
|
||||
m_state->sizeVar.emplace_back();
|
||||
auto& sizeVar = m_state->sizeVar.back();
|
||||
|
||||
m_state->solver.addConstraint({ sizeVar >= minimumSize | kiwi::strength::required });
|
||||
|
||||
if (maximumSize < std::numeric_limits<float>::infinity())
|
||||
m_state->solver.addConstraint({ sizeVar <= maximumSize | kiwi::strength::required });
|
||||
|
||||
m_state->solver.addConstraint({ sizeVar >= perfectSpacePerWidget | kiwi::strength::medium });
|
||||
|
||||
sizeSum = sizeSum + sizeVar;
|
||||
});
|
||||
|
||||
kiwi::Variable targetSize("LayoutSize");
|
||||
|
||||
m_state->solver.addConstraint(sizeSum <= targetSize | kiwi::strength::strong);
|
||||
|
||||
m_state->solver.addEditVariable(targetSize, kiwi::strength::strong);
|
||||
m_state->solver.suggestValue(targetSize, availableSpace);
|
||||
|
||||
m_state->solver.updateVariables();
|
||||
|
||||
std::size_t varIndex = 0;
|
||||
|
||||
float remainingSize = availableSpace;
|
||||
|
||||
ForEachWidgetChild([&](BaseWidget* child)
|
||||
{
|
||||
if (!child->IsVisible())
|
||||
return;
|
||||
|
||||
Nz::Vector2f newSize = layoutSize;
|
||||
newSize[axis] = m_state->sizeVar[varIndex].value();
|
||||
|
||||
child->Resize(newSize);
|
||||
remainingSize -= newSize[axis];
|
||||
|
||||
varIndex++;
|
||||
});
|
||||
|
||||
float spacing = m_spacing + remainingSize / (widgetChildCount - 1);
|
||||
|
||||
// Handle position
|
||||
float cursor = 0.f;
|
||||
bool first = true;
|
||||
ForEachWidgetChild([&](BaseWidget* child)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
cursor += spacing;
|
||||
|
||||
Nz::Vector2f position = Nz::Vector2f(0.f, 0.f);
|
||||
position[axis] = cursor;
|
||||
|
||||
child->SetPosition(position);
|
||||
|
||||
cursor += child->GetSize()[axis];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,15 +3,7 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Widgets/ButtonWidget.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/MaterialPass.hpp>
|
||||
#include <Nazara/Graphics/SlicedSprite.hpp>
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
#include <Nazara/Utility/AbstractTextDrawer.hpp>
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Widgets/Canvas.hpp>
|
||||
#include <Nazara/Widgets/Widgets.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
@@ -56,7 +48,7 @@ namespace Nz
|
||||
|
||||
// If user clicks inside button and holds it outside, a release mouse button event will be triggered outside of the widget
|
||||
// we don't want this to trigger the button, so double-check
|
||||
if (IsInside(x, y))
|
||||
if (IsInside(float(x), float(y)))
|
||||
OnButtonTrigger(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +45,85 @@ namespace Nz
|
||||
const UInt8 s_defaultThemeCheckboxTristateImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/CheckboxTristate.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/Hovered.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarHorizontalBackgroundImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarBackgroundHorizontal.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarVerticalBackgroundImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarBackgroundVertical.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowDownImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowDown.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowDownHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowDownHovered.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowDownPressedImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowDownPressed.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowLeftImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowLeft.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowLeftHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowLeftHovered.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowLeftPressedImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowLeftPressed.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowRightImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowRight.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowRightHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowRightHovered.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowRightPressedImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowRightPressed.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowUpImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowUp.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowUpHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowUpHovered.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarArrowUpPressedImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowUpPressed.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarCenterImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarCenter.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarGrabbedImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarCenterGrabbed.png.h>
|
||||
};
|
||||
|
||||
const UInt8 s_defaultThemeScrollbarHoveredImage[] = {
|
||||
#include <Nazara/Widgets/Resources/DefaultTheme/ScrollbarCenterHovered.png.h>
|
||||
};
|
||||
}
|
||||
|
||||
DefaultWidgetTheme::DefaultWidgetTheme()
|
||||
{
|
||||
TextureParams texParams;
|
||||
texParams.renderDevice = Graphics::Instance()->GetRenderDevice();
|
||||
texParams.loadFormat = PixelFormat::RGBA8_SRGB;
|
||||
texParams.loadFormat = PixelFormat::RGBA8; //< TODO: Re-enable gamma correction
|
||||
|
||||
auto CreateMaterialFromTexture = [](std::shared_ptr<Texture> texture)
|
||||
{
|
||||
@@ -70,18 +142,48 @@ namespace Nz
|
||||
|
||||
return material;
|
||||
};
|
||||
|
||||
// Button material
|
||||
|
||||
m_hoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeHoveredImage, sizeof(s_defaultThemeHoveredImage), texParams));
|
||||
|
||||
// Button materials
|
||||
m_buttonMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeButtonImage, sizeof(s_defaultThemeButtonImage), texParams));
|
||||
m_buttonHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeButtonHoveredImage, sizeof(s_defaultThemeButtonHoveredImage), texParams));
|
||||
m_buttonPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeButtonPressedImage, sizeof(s_defaultThemeButtonPressedImage), texParams));
|
||||
m_buttonPressedHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeButtonPressedHoveredImage, sizeof(s_defaultThemeButtonPressedHoveredImage), texParams));
|
||||
|
||||
// Checkbox material
|
||||
// Checkbox materials
|
||||
m_checkboxBackgroundMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxBackgroundImage, sizeof(s_defaultThemeCheckboxBackgroundImage), texParams));
|
||||
m_checkboxBackgroundHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxBackgroundHoveredImage, sizeof(s_defaultThemeCheckboxBackgroundHoveredImage), texParams));
|
||||
m_checkboxCheckMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxCheckImage, sizeof(s_defaultThemeCheckboxCheckImage), texParams));
|
||||
m_checkboxTristateMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeCheckboxTristateImage, sizeof(s_defaultThemeCheckboxTristateImage), 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));
|
||||
|
||||
// Config
|
||||
m_config.scrollbarButtonCornerSize = 0.f;
|
||||
m_config.scrollbarButtonCornerTexcoords = 0.f;
|
||||
|
||||
m_scrollbarButtonMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarCenterImage, sizeof(s_defaultThemeScrollbarCenterImage), texParams));
|
||||
m_scrollbarButtonGrabbedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarGrabbedImage, sizeof(s_defaultThemeScrollbarGrabbedImage), texParams));
|
||||
m_scrollbarButtonHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarHoveredImage, sizeof(s_defaultThemeScrollbarHoveredImage), texParams));
|
||||
|
||||
m_config.scrollbarButtonDownMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowDownImage, sizeof(s_defaultThemeScrollbarArrowDownImage), texParams));
|
||||
m_config.scrollbarButtonDownHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowDownHoveredImage, sizeof(s_defaultThemeScrollbarArrowDownHoveredImage), texParams));
|
||||
m_config.scrollbarButtonDownPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowDownPressedImage, sizeof(s_defaultThemeScrollbarArrowDownPressedImage), texParams));
|
||||
|
||||
m_config.scrollbarButtonLeftMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowLeftImage, sizeof(s_defaultThemeScrollbarArrowLeftImage), texParams));
|
||||
m_config.scrollbarButtonLeftHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowLeftHoveredImage, sizeof(s_defaultThemeScrollbarArrowLeftHoveredImage), texParams));
|
||||
m_config.scrollbarButtonLeftPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowLeftPressedImage, sizeof(s_defaultThemeScrollbarArrowLeftPressedImage), texParams));
|
||||
|
||||
m_config.scrollbarButtonRightMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowRightImage, sizeof(s_defaultThemeScrollbarArrowRightImage), texParams));
|
||||
m_config.scrollbarButtonRightHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowRightHoveredImage, sizeof(s_defaultThemeScrollbarArrowRightHoveredImage), texParams));
|
||||
m_config.scrollbarButtonRightPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowRightPressedImage, sizeof(s_defaultThemeScrollbarArrowRightPressedImage), texParams));
|
||||
|
||||
m_config.scrollbarButtonUpMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowUpImage, sizeof(s_defaultThemeScrollbarArrowUpImage), texParams));
|
||||
m_config.scrollbarButtonUpHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowUpHoveredImage, sizeof(s_defaultThemeScrollbarArrowUpHoveredImage), texParams));
|
||||
m_config.scrollbarButtonUpPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(s_defaultThemeScrollbarArrowUpPressedImage, sizeof(s_defaultThemeScrollbarArrowUpPressedImage), texParams));
|
||||
}
|
||||
|
||||
std::unique_ptr<ButtonWidgetStyle> DefaultWidgetTheme::CreateStyle(ButtonWidget* buttonWidget) const
|
||||
@@ -110,8 +212,45 @@ namespace Nz
|
||||
return std::make_unique<SimpleCheckboxWidgetStyle>(checkboxWidget, styleConfig);
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageButtonWidgetStyle> DefaultWidgetTheme::CreateStyle(ImageButtonWidget* imageButtonWidget) const
|
||||
{
|
||||
SimpleImageButtonWidgetStyle::StyleConfig styleConfig;
|
||||
styleConfig.hoveredCornerSize = 8.f;
|
||||
styleConfig.hoveredCornerTexCoords = 8.f / 64.f;
|
||||
styleConfig.hoveredMaterial = m_hoveredMaterial;
|
||||
|
||||
return std::make_unique<SimpleImageButtonWidgetStyle>(imageButtonWidget, styleConfig);
|
||||
}
|
||||
|
||||
std::unique_ptr<LabelWidgetStyle> DefaultWidgetTheme::CreateStyle(LabelWidget* labelWidget) const
|
||||
{
|
||||
return std::make_unique<SimpleLabelWidgetStyle>(labelWidget, Widgets::Instance()->GetTransparentMaterial());
|
||||
}
|
||||
|
||||
std::unique_ptr<ScrollAreaWidgetStyle> DefaultWidgetTheme::CreateStyle(ScrollAreaWidget* scrollAreaWidget) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScrollbarWidgetStyle> DefaultWidgetTheme::CreateStyle(ScrollbarWidget* scrollBarWidget) const
|
||||
{
|
||||
SimpleScrollbarWidgetStyle::StyleConfig styleConfig;
|
||||
styleConfig.backgroundHorizontalMaterial = m_scrollbarBackgroundHorizontalMaterial;
|
||||
styleConfig.backgroundVerticalMaterial = m_scrollbarBackgroundVerticalMaterial;
|
||||
|
||||
return std::make_unique<SimpleScrollbarWidgetStyle>(scrollBarWidget, styleConfig);
|
||||
}
|
||||
|
||||
std::unique_ptr<ScrollbarButtonWidgetStyle> DefaultWidgetTheme::CreateStyle(ScrollbarButtonWidget* scrollbarButtonWidget) const
|
||||
{
|
||||
SimpleScrollbarButtonWidgetStyle::StyleConfig styleConfig;
|
||||
styleConfig.cornerSize = 16.f;
|
||||
styleConfig.cornerTexCoords = 16.f / 64.f;
|
||||
styleConfig.grabbedMaterial = m_scrollbarButtonGrabbedMaterial;
|
||||
styleConfig.hoveredMaterial = m_scrollbarButtonHoveredMaterial;
|
||||
styleConfig.material = m_scrollbarButtonMaterial;
|
||||
|
||||
return std::make_unique<SimpleScrollbarButtonWidgetStyle>(scrollbarButtonWidget, styleConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
91
src/Nazara/Widgets/ImageButtonWidget.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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 <Nazara/Widgets/ImageButtonWidget.hpp>
|
||||
#include <Nazara/Graphics/BasicMaterial.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial, std::shared_ptr<Material> pressedMaterial, float cornerSize, float cornerTexCoords) :
|
||||
BaseWidget(parent),
|
||||
m_hoveredMaterial(std::move(hoveredMaterial)),
|
||||
m_material(std::move(material)),
|
||||
m_pressedMaterial(std::move(pressedMaterial)),
|
||||
m_color(Color::White),
|
||||
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
||||
m_cornerSize(cornerSize),
|
||||
m_cornerTexCoords(cornerTexCoords)
|
||||
{
|
||||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
UpdatePreferredSize();
|
||||
Layout();
|
||||
}
|
||||
|
||||
void ImageButtonWidget::Layout()
|
||||
{
|
||||
BaseWidget::Layout();
|
||||
m_style->Layout(GetSize());
|
||||
}
|
||||
|
||||
void ImageButtonWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
m_style->OnPress();
|
||||
}
|
||||
|
||||
void ImageButtonWidget::OnMouseButtonRelease(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
{
|
||||
m_style->OnRelease();
|
||||
|
||||
// If user clicks inside button and holds it outside, a release mouse button event will be triggered outside of the widget
|
||||
// we don't want this to trigger the button, so double-check
|
||||
if (IsInside(float(x), float(y)))
|
||||
OnButtonTrigger(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButtonWidget::OnMouseEnter()
|
||||
{
|
||||
m_style->OnHoverBegin();
|
||||
}
|
||||
|
||||
void ImageButtonWidget::OnMouseExit()
|
||||
{
|
||||
m_style->OnHoverEnd();
|
||||
}
|
||||
|
||||
void ImageButtonWidget::OnRenderLayerUpdated(int baseRenderLayer)
|
||||
{
|
||||
m_style->UpdateRenderLayer(baseRenderLayer);
|
||||
}
|
||||
|
||||
void ImageButtonWidget::UpdatePreferredSize()
|
||||
{
|
||||
const Rectf& textureCoords = GetTextureCoords();
|
||||
|
||||
// TODO: Move this in a separate function
|
||||
if (const auto& material = m_material->FindPass("ForwardPass"))
|
||||
{
|
||||
BasicMaterial mat(*material);
|
||||
if (mat.HasDiffuseMap())
|
||||
{
|
||||
// Material should always have textures but we're better safe than sorry
|
||||
if (const auto& texture = mat.GetDiffuseMap())
|
||||
{
|
||||
Vector2f textureSize = Vector2f(Vector2ui(texture->GetSize()));
|
||||
textureSize.x *= textureCoords.width;
|
||||
textureSize.y *= textureCoords.height;
|
||||
|
||||
SetPreferredSize(textureSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ImageWidget::ImageWidget(BaseWidget* parent) :
|
||||
ImageWidget::ImageWidget(BaseWidget* parent, std::shared_ptr<Material> material) :
|
||||
BaseWidget(parent)
|
||||
{
|
||||
m_sprite = std::make_shared<Sprite>(Widgets::Instance()->GetTransparentMaterial());
|
||||
@@ -25,6 +25,8 @@ namespace Nz
|
||||
|
||||
auto& nodeComponent = registry.emplace<NodeComponent>(m_entity);
|
||||
nodeComponent.SetParent(this);
|
||||
|
||||
SetMaterial(std::move(material));
|
||||
}
|
||||
|
||||
void ImageWidget::Layout()
|
||||
|
||||
106
src/Nazara/Widgets/ProgressBarWidget.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright (C) 2022 Samy Bensaid
|
||||
// This file is part of the "Nazara Engine - Widgets module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#if 0
|
||||
|
||||
#include <Nazara/Widgets/ProgressBarWidget.hpp>
|
||||
#include <NDK/Components/GraphicsComponent.hpp>
|
||||
#include <NDK/Components/NodeComponent.hpp>
|
||||
#include <NDK/Widgets/ProgressBarWidget.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
float ProgressBarWidget::s_borderScale { 16.f };
|
||||
Nz::Color ProgressBarWidget::s_borderColor { Nz::Color::Black };
|
||||
Nz::Color ProgressBarWidget::s_barBackgroundColor { Nz::Color { 225, 225, 225 } };
|
||||
Nz::Color ProgressBarWidget::s_barBackgroundCornerColor { Nz::Color { 255, 255, 255 } };
|
||||
Nz::Color ProgressBarWidget::s_barColor { Nz::Color { 0, 225, 0 } };
|
||||
Nz::Color ProgressBarWidget::s_barCornerColor { Nz::Color { 220, 255, 220 } };
|
||||
|
||||
ProgressBarWidget::ProgressBarWidget(BaseWidget* parent) :
|
||||
BaseWidget(parent),
|
||||
m_textColor { Nz::Color::Black },
|
||||
m_textMargin { 16.f },
|
||||
m_value { 0u }
|
||||
{
|
||||
m_borderSprite = Nz::Sprite::New(Nz::Material::New("Basic2D"));
|
||||
m_barBackgroundSprite = Nz::Sprite::New(Nz::Material::New("Basic2D"));
|
||||
m_barSprite = Nz::Sprite::New(Nz::Material::New("Basic2D"));
|
||||
|
||||
m_borderSprite->SetColor(s_borderColor);
|
||||
SetBarBackgroundColor(s_barBackgroundColor, s_barBackgroundCornerColor);
|
||||
SetBarColor(s_barColor, s_barCornerColor);
|
||||
|
||||
|
||||
m_borderEntity = CreateEntity();
|
||||
m_borderEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
m_borderEntity->AddComponent<GraphicsComponent>().Attach(m_borderSprite);
|
||||
|
||||
m_barEntity = CreateEntity();
|
||||
m_barEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
GraphicsComponent& graphics = m_barEntity->AddComponent<GraphicsComponent>();
|
||||
|
||||
graphics.Attach(m_barBackgroundSprite, 1);
|
||||
graphics.Attach(m_barSprite, 2);
|
||||
|
||||
|
||||
m_textSprite = Nz::TextSprite::New();
|
||||
m_textEntity = CreateEntity();
|
||||
|
||||
m_textEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
m_textEntity->AddComponent<GraphicsComponent>().Attach(m_textSprite);
|
||||
|
||||
UpdateText();
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
const Nz::Color& ProgressBarWidget::GetDefaultBarColor()
|
||||
{
|
||||
return s_barColor;
|
||||
}
|
||||
|
||||
const Nz::Color& ProgressBarWidget::GetDefaultBarCornerColor()
|
||||
{
|
||||
return s_barCornerColor;
|
||||
}
|
||||
|
||||
const Nz::Color& ProgressBarWidget::GetDefaultBarBackgroundColor()
|
||||
{
|
||||
return s_barBackgroundColor;
|
||||
}
|
||||
|
||||
const Nz::Color& ProgressBarWidget::GetDefaultBarBackgroundCornerColor()
|
||||
{
|
||||
return s_barBackgroundCornerColor;
|
||||
}
|
||||
|
||||
|
||||
void ProgressBarWidget::Layout()
|
||||
{
|
||||
Nz::Vector2f size = GetSize();
|
||||
Nz::Vector2f progressBarSize = size;
|
||||
|
||||
if (IsTextEnabled())
|
||||
{
|
||||
UpdateText();
|
||||
|
||||
Nz::Vector3f textSize = m_textSprite->GetBoundingVolume().obb.localBox.GetLengths();
|
||||
m_textEntity->GetComponent<NodeComponent>().SetPosition(size.x - textSize.x, size.y / 2.f - textSize.y);
|
||||
|
||||
progressBarSize -= { textSize.x + m_textMargin, 0.f };
|
||||
}
|
||||
|
||||
m_borderSprite->SetSize(progressBarSize);
|
||||
Nz::Vector2f borderSize = GetProgressBarBorderSize();
|
||||
|
||||
m_barBackgroundSprite->SetSize(progressBarSize - (borderSize * 2.f));
|
||||
m_barSprite->SetSize((progressBarSize.x - (borderSize.x * 2.f)) / 100.f * static_cast<float>(m_value), progressBarSize.y - (borderSize.y * 2.f));
|
||||
|
||||
m_barEntity->GetComponent<NodeComponent>().SetPosition(borderSize.x, borderSize.y);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
BIN
src/Nazara/Widgets/Resources/DefaultTheme/Hovered.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowDown.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowLeft.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/Nazara/Widgets/Resources/DefaultTheme/ScrollbarArrowUp.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 230 B |
BIN
src/Nazara/Widgets/Resources/DefaultTheme/ScrollbarCenter.png
Normal file
|
After Width: | Height: | Size: 721 B |
|
After Width: | Height: | Size: 552 B |
|
After Width: | Height: | Size: 900 B |
BIN
src/Nazara/Widgets/Resources/DefaultTheme/VerticalSlider.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 566 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
204
src/Nazara/Widgets/ScrollAreaWidget.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
// 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
|
||||
|
||||
#if 0
|
||||
|
||||
#include <Nazara/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr float scrollbarPadding = 5.f;
|
||||
}
|
||||
|
||||
ScrollAreaWidget::ScrollAreaWidget(BaseWidget* parent, BaseWidget* content) :
|
||||
BaseWidget(parent),
|
||||
m_content(content),
|
||||
m_isGrabbed(false),
|
||||
m_isScrollbarEnabled(true),
|
||||
m_scrollRatio(0.f)
|
||||
{
|
||||
m_content->SetParent(this);
|
||||
m_content->SetPosition(Nz::Vector3f::Zero());
|
||||
|
||||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
Resize(m_content->GetSize()); //< will automatically layout
|
||||
|
||||
m_scrollbarBackgroundSprite = Nz::Sprite::New();
|
||||
m_scrollbarBackgroundSprite->SetColor(Nz::Color(62, 62, 62));
|
||||
|
||||
m_scrollbarBackgroundEntity = CreateEntity();
|
||||
m_scrollbarBackgroundEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
m_scrollbarBackgroundEntity->AddComponent<GraphicsComponent>().Attach(m_scrollbarBackgroundSprite, 1);
|
||||
|
||||
m_scrollbarSprite = Nz::Sprite::New();
|
||||
m_scrollbarSprite->SetColor(Nz::Color(104, 104, 104));
|
||||
|
||||
m_scrollbarEntity = CreateEntity();
|
||||
m_scrollbarEntity->AddComponent<NodeComponent>().SetParent(this);
|
||||
m_scrollbarEntity->AddComponent<GraphicsComponent>().Attach(m_scrollbarSprite);
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::EnableScrollbar(bool enable)
|
||||
{
|
||||
if (m_isScrollbarEnabled != enable)
|
||||
{
|
||||
m_isScrollbarEnabled = enable;
|
||||
|
||||
bool isVisible = IsScrollbarVisible();
|
||||
m_scrollbarEntity->Enable(isVisible);
|
||||
m_scrollbarBackgroundEntity->Enable(isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::ScrollToRatio(float ratio)
|
||||
{
|
||||
m_scrollRatio = Nz::Clamp(ratio, 0.f, 1.f);
|
||||
|
||||
float widgetHeight = GetHeight();
|
||||
float maxHeight = widgetHeight - m_scrollbarSprite->GetSize().y - 2.f * scrollbarPadding;
|
||||
|
||||
auto& scrollbarNode = m_scrollbarEntity->GetComponent<NodeComponent>();
|
||||
scrollbarNode.SetPosition(Nz::Vector2f(scrollbarNode.GetPosition(Nz::CoordSys_Local).x, scrollbarPadding + m_scrollRatio * maxHeight));
|
||||
|
||||
float contentPosition = m_scrollRatio * (widgetHeight - m_content->GetHeight());
|
||||
|
||||
m_content->SetPosition(0.f, contentPosition);
|
||||
m_content->SetRenderingRect(Nz::Rectf(-std::numeric_limits<float>::infinity(), -contentPosition, std::numeric_limits<float>::infinity(), widgetHeight));
|
||||
}
|
||||
|
||||
Nz::Rectf ScrollAreaWidget::GetScrollbarRect() const
|
||||
{
|
||||
Nz::Vector2f scrollBarPosition = Nz::Vector2f(m_scrollbarEntity->GetComponent<NodeComponent>().GetPosition(Nz::CoordSys_Local));
|
||||
Nz::Vector2f scrollBarSize = m_scrollbarSprite->GetSize();
|
||||
return Nz::Rectf(scrollBarPosition.x, scrollBarPosition.y, scrollBarSize.x, scrollBarSize.y);
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::Layout()
|
||||
{
|
||||
constexpr float scrollBarBackgroundWidth = 20.f;
|
||||
constexpr float scrollBarWidth = scrollBarBackgroundWidth - 2.f * scrollbarPadding;
|
||||
|
||||
float areaHeight = GetHeight();
|
||||
float contentHeight = m_content->GetHeight();
|
||||
|
||||
if (contentHeight > areaHeight)
|
||||
{
|
||||
m_hasScrollbar = true;
|
||||
|
||||
Nz::Vector2f contentSize(GetWidth() - scrollBarBackgroundWidth, contentHeight);
|
||||
m_content->Resize(contentSize);
|
||||
|
||||
if (m_isScrollbarEnabled)
|
||||
{
|
||||
m_scrollbarEntity->Enable();
|
||||
m_scrollbarBackgroundEntity->Enable();
|
||||
}
|
||||
|
||||
float scrollBarHeight = std::max(std::floor(areaHeight * (areaHeight / contentHeight)), 20.f);
|
||||
|
||||
m_scrollbarBackgroundSprite->SetSize(scrollBarBackgroundWidth, areaHeight);
|
||||
m_scrollbarSprite->SetSize(scrollBarWidth, scrollBarHeight);
|
||||
|
||||
m_scrollbarBackgroundEntity->GetComponent<NodeComponent>().SetPosition(contentSize.x, 0.f);
|
||||
m_scrollbarEntity->GetComponent<NodeComponent>().SetPosition(contentSize.x + (scrollBarBackgroundWidth - scrollBarWidth) / 2.f, 0.f);
|
||||
|
||||
ScrollToRatio(m_scrollRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hasScrollbar = false;
|
||||
|
||||
m_content->Resize(GetSize());
|
||||
|
||||
m_scrollbarEntity->Disable();
|
||||
m_scrollbarBackgroundEntity->Disable();
|
||||
|
||||
ScrollToRatio(0.f);
|
||||
}
|
||||
|
||||
BaseWidget::Layout();
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::OnMouseButtonPress(int x, int y, Nz::Mouse::Button button)
|
||||
{
|
||||
if (button != Nz::Mouse::Left)
|
||||
return;
|
||||
|
||||
if (!m_isGrabbed)
|
||||
{
|
||||
m_style->OnGrab();
|
||||
|
||||
auto& scrollbarNode = m_scrollbarEntity->GetComponent<NodeComponent>();
|
||||
|
||||
m_grabbedDelta.Set(x, int(y - scrollbarNode.GetPosition(Nz::CoordSys_Local).y));
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button)
|
||||
{
|
||||
if (button != Nz::Mouse::Left)
|
||||
return;
|
||||
|
||||
if (m_scrollbarStatus == ScrollBarStatus::Grabbed)
|
||||
{
|
||||
Nz::Rectf scrollBarRect = GetScrollbarRect();
|
||||
UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(float(x), float(y)))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::OnMouseExit()
|
||||
{
|
||||
//if (m_scrollbarStatus == ScrollBarStatus::Hovered)
|
||||
UpdateScrollbarStatus(ScrollBarStatus::None);
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
|
||||
{
|
||||
if (m_scrollbarStatus == ScrollBarStatus::Grabbed)
|
||||
{
|
||||
float height = GetHeight();
|
||||
float maxHeight = height - m_scrollbarSprite->GetSize().y;
|
||||
float newHeight = Nz::Clamp(float(y - m_grabbedDelta.y), 0.f, maxHeight);
|
||||
|
||||
ScrollToHeight(newHeight / maxHeight * m_content->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
Nz::Rectf scrollBarRect = GetScrollbarRect();
|
||||
UpdateScrollbarStatus((scrollBarRect.Contains(Nz::Vector2f(float(x), float(y)))) ? ScrollBarStatus::Hovered : ScrollBarStatus::None);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float delta)
|
||||
{
|
||||
constexpr float scrollStep = 100.f;
|
||||
|
||||
ScrollToHeight(GetScrollHeight() - scrollStep * delta);
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::UpdateScrollbarStatus(ScrollBarStatus status)
|
||||
{
|
||||
if (m_scrollbarStatus != status)
|
||||
{
|
||||
Nz::Color newColor;
|
||||
switch (status)
|
||||
{
|
||||
case ScrollBarStatus::Grabbed: newColor = Nz::Color(235, 235, 235); break;
|
||||
case ScrollBarStatus::Hovered: newColor = Nz::Color(152, 152, 152); break;
|
||||
case ScrollBarStatus::None: newColor = Nz::Color(104, 104, 104); break;
|
||||
}
|
||||
|
||||
m_scrollbarSprite->SetColor(newColor);
|
||||
m_scrollbarStatus = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
68
src/Nazara/Widgets/ScrollbarButtonWidget.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
// 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 <Nazara/Widgets/ScrollbarButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ScrollbarButtonWidget::ScrollbarButtonWidget(BaseWidget* parent) :
|
||||
BaseWidget(parent),
|
||||
m_isGrabbed(false)
|
||||
{
|
||||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::Layout()
|
||||
{
|
||||
BaseWidget::Layout();
|
||||
m_style->Layout(GetSize());
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnMouseButtonPress(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
{
|
||||
m_isGrabbed = true;
|
||||
OnButtonGrabbed(this, x, y);
|
||||
|
||||
m_style->OnGrab();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnMouseButtonRelease(int x, int y, Mouse::Button button)
|
||||
{
|
||||
if (button == Mouse::Left)
|
||||
{
|
||||
m_isGrabbed = false;
|
||||
OnButtonReleased(this);
|
||||
|
||||
m_style->OnRelease();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnMouseEnter()
|
||||
{
|
||||
m_style->OnHoverBegin();
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnMouseExit()
|
||||
{
|
||||
m_style->OnHoverEnd();
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnMouseMoved(int x, int y, int /*deltaX*/, int /*deltaY*/)
|
||||
{
|
||||
if (m_isGrabbed)
|
||||
OnButtonMoved(this, x, y);
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidget::OnRenderLayerUpdated(int baseRenderLayer)
|
||||
{
|
||||
m_style->UpdateRenderLayer(baseRenderLayer);
|
||||
}
|
||||
}
|
||||
151
src/Nazara/Widgets/ScrollbarWidget.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
// 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 <Nazara/Widgets/ScrollbarWidget.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Widgets/ImageButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/ScrollbarButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
ScrollbarWidget::ScrollbarWidget(BaseWidget* parent, ScrollbarOrientation orientation) :
|
||||
BaseWidget(parent),
|
||||
m_orientation(orientation),
|
||||
m_isGrabbed(false),
|
||||
m_maximumValue(1.f),
|
||||
m_minimumValue(0.f),
|
||||
m_step(0.5f),
|
||||
m_value(0.f)
|
||||
{
|
||||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
const WidgetTheme::Config& themeConfig = GetTheme()->GetConfig();
|
||||
|
||||
m_scrollCenterButton = Add<ScrollbarButtonWidget>();
|
||||
|
||||
m_scrollCenterButton->OnButtonReleased.Connect([this](const ScrollbarButtonWidget*)
|
||||
{
|
||||
m_style->OnButtonRelease();
|
||||
});
|
||||
|
||||
if (m_orientation == ScrollbarOrientation::Horizontal)
|
||||
{
|
||||
m_scrollCenterButton->OnButtonGrabbed.Connect([this](const ScrollbarButtonWidget*, int x, int /*y*/)
|
||||
{
|
||||
m_grabbedPosition = x;
|
||||
m_grabbedValue = GetValue();
|
||||
m_style->OnButtonGrab();
|
||||
});
|
||||
|
||||
m_scrollCenterButton->OnButtonMoved.Connect([this](const ScrollbarButtonWidget*, int x, int /*y*/)
|
||||
{
|
||||
int deltaX = x - m_grabbedPosition;
|
||||
if (deltaX == 0)
|
||||
return;
|
||||
|
||||
float scrollbarWidth = m_step * GetWidth();
|
||||
float remainingWidth = GetWidth() - m_scrollBackButton->GetWidth() - scrollbarWidth;
|
||||
float valueRange = m_maximumValue - m_minimumValue;
|
||||
|
||||
SetValue(m_grabbedValue + deltaX * valueRange / remainingWidth);
|
||||
});
|
||||
|
||||
m_scrollBackButton = Add<ImageButtonWidget>(themeConfig.scrollbarButtonLeftMaterial, themeConfig.scrollbarButtonLeftHoveredMaterial, themeConfig.scrollbarButtonLeftPressedMaterial, themeConfig.scrollbarButtonCornerSize, themeConfig.scrollbarButtonCornerTexcoords);
|
||||
m_scrollNextButton = Add<ImageButtonWidget>(themeConfig.scrollbarButtonRightMaterial, themeConfig.scrollbarButtonRightHoveredMaterial, themeConfig.scrollbarButtonRightPressedMaterial, themeConfig.scrollbarButtonCornerSize, themeConfig.scrollbarButtonCornerTexcoords);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scrollCenterButton->OnButtonGrabbed.Connect([this](const ScrollbarButtonWidget* button, int /*x*/, int y)
|
||||
{
|
||||
m_grabbedPosition = button->GetPosition().y + y;
|
||||
m_grabbedValue = GetValue();
|
||||
m_style->OnButtonGrab();
|
||||
});
|
||||
|
||||
m_scrollCenterButton->OnButtonMoved.Connect([this](const ScrollbarButtonWidget* button, int /*x*/, int y)
|
||||
{
|
||||
int deltaY = m_grabbedPosition - (button->GetPosition().y + y);
|
||||
if (deltaY == 0)
|
||||
return;
|
||||
|
||||
float scrollbarHeight = m_step * GetHeight();
|
||||
float remainingHeight = GetHeight() - m_scrollBackButton->GetHeight() - scrollbarHeight;
|
||||
float valueRange = m_maximumValue - m_minimumValue;
|
||||
|
||||
SetValue(m_grabbedValue + deltaY * valueRange / remainingHeight);
|
||||
});
|
||||
|
||||
m_scrollBackButton = Add<ImageButtonWidget>(themeConfig.scrollbarButtonUpMaterial, themeConfig.scrollbarButtonUpHoveredMaterial, themeConfig.scrollbarButtonUpPressedMaterial, themeConfig.scrollbarButtonCornerSize, themeConfig.scrollbarButtonCornerTexcoords);
|
||||
m_scrollNextButton = Add<ImageButtonWidget>(themeConfig.scrollbarButtonDownMaterial, themeConfig.scrollbarButtonDownHoveredMaterial, themeConfig.scrollbarButtonDownPressedMaterial, themeConfig.scrollbarButtonCornerSize, themeConfig.scrollbarButtonCornerTexcoords);
|
||||
}
|
||||
|
||||
m_scrollBackButton->OnButtonTrigger.Connect([this](const ImageButtonWidget*)
|
||||
{
|
||||
SetValue(GetValue() - 0.1f * (GetMaximumValue() - GetMinimumValue()));
|
||||
});
|
||||
|
||||
m_scrollNextButton->OnButtonTrigger.Connect([this](const ImageButtonWidget*)
|
||||
{
|
||||
SetValue(GetValue() + 0.1f * (GetMaximumValue() - GetMinimumValue()));
|
||||
});
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
void ScrollbarWidget::Layout()
|
||||
{
|
||||
BaseWidget::Layout();
|
||||
|
||||
float stepPct = m_step / (m_maximumValue - m_minimumValue);
|
||||
float valuePct = m_value / (m_maximumValue - m_minimumValue);
|
||||
float invValuePct = 1.f - valuePct; //< Remember we're Y up
|
||||
|
||||
Vector2f size = GetSize();
|
||||
if (m_orientation == ScrollbarOrientation::Horizontal)
|
||||
{
|
||||
m_scrollBackButton->Resize({ size.y, size.y });
|
||||
m_scrollNextButton->Resize({ size.y, size.y });
|
||||
m_scrollNextButton->SetPosition({ GetWidth() - m_scrollNextButton->GetWidth(), 0.f, 0.f });
|
||||
|
||||
float start = m_scrollBackButton->GetWidth();
|
||||
float remaining = size.x - start - m_scrollNextButton->GetWidth();
|
||||
float centerPosition = start + invValuePct * (remaining - remaining * stepPct);
|
||||
|
||||
m_scrollCenterButton->Resize({ remaining * stepPct, size.y });
|
||||
m_scrollCenterButton->SetPosition(start + centerPosition, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scrollBackButton->Resize({ size.x, size.x });
|
||||
m_scrollBackButton->SetPosition({ 0.f, GetHeight() - m_scrollBackButton->GetHeight(), 0.f });
|
||||
m_scrollNextButton->Resize({ size.x, size.x });
|
||||
|
||||
float start = m_scrollBackButton->GetHeight();
|
||||
float remaining = size.y - start - m_scrollNextButton->GetHeight();
|
||||
float centerPosition = start + invValuePct * (remaining - remaining * stepPct);
|
||||
|
||||
m_scrollCenterButton->Resize({ size.x, remaining * stepPct });
|
||||
m_scrollCenterButton->SetPosition(0.f, centerPosition);
|
||||
}
|
||||
|
||||
m_style->Layout(size);
|
||||
}
|
||||
|
||||
void ScrollbarWidget::OnMouseEnter()
|
||||
{
|
||||
m_style->OnHoverBegin();
|
||||
}
|
||||
|
||||
void ScrollbarWidget::OnMouseExit()
|
||||
{
|
||||
m_style->OnHoverEnd();
|
||||
}
|
||||
|
||||
void ScrollbarWidget::OnRenderLayerUpdated(int baseRenderLayer)
|
||||
{
|
||||
m_style->UpdateRenderLayer(baseRenderLayer);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,10 @@
|
||||
#include <Nazara/Widgets/ButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/Canvas.hpp>
|
||||
#include <Nazara/Widgets/CheckboxWidget.hpp>
|
||||
#include <Nazara/Widgets/ImageButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/LabelWidget.hpp>
|
||||
#include <Nazara/Widgets/ScrollbarButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/ScrollbarWidget.hpp>
|
||||
#include <Nazara/Widgets/Widgets.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
@@ -56,26 +59,26 @@ namespace Nz
|
||||
|
||||
void SimpleButtonWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
UpdateMaterial(true, m_isPressed);
|
||||
m_isHovered = true;
|
||||
UpdateMaterial(m_isHovered, m_isPressed);
|
||||
}
|
||||
|
||||
void SimpleButtonWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
UpdateMaterial(false, m_isPressed);
|
||||
m_isHovered = false;
|
||||
UpdateMaterial(m_isHovered, m_isPressed);
|
||||
}
|
||||
|
||||
void SimpleButtonWidgetStyle::OnPress()
|
||||
{
|
||||
UpdateMaterial(m_isHovered, true);
|
||||
m_isPressed = true;
|
||||
UpdateMaterial(m_isHovered, m_isPressed);
|
||||
}
|
||||
|
||||
void SimpleButtonWidgetStyle::OnRelease()
|
||||
{
|
||||
UpdateMaterial(m_isHovered, false);
|
||||
m_isPressed = false;
|
||||
UpdateMaterial(m_isHovered, m_isPressed);
|
||||
}
|
||||
|
||||
void SimpleButtonWidgetStyle::UpdateRenderLayer(int baseRenderLayer)
|
||||
@@ -194,6 +197,140 @@ namespace Nz
|
||||
}
|
||||
|
||||
|
||||
SimpleImageButtonWidgetStyle::SimpleImageButtonWidgetStyle(ImageButtonWidget* imageButtonWidget, StyleConfig config) :
|
||||
ImageButtonWidgetStyle(imageButtonWidget, 1),
|
||||
m_isHovered(false),
|
||||
m_isPressed(false)
|
||||
{
|
||||
auto& registry = GetRegistry();
|
||||
UInt32 renderMask = GetRenderMask();
|
||||
|
||||
SlicedSprite::Corner hoveredCorner;
|
||||
hoveredCorner.size = Vector2f(config.hoveredCornerSize, config.hoveredCornerSize);
|
||||
hoveredCorner.textureCoords = Vector2f(config.hoveredCornerTexCoords, config.hoveredCornerTexCoords);
|
||||
|
||||
m_hoveredSprite = std::make_shared<SlicedSprite>(config.hoveredMaterial);
|
||||
m_hoveredSprite->SetCorners(hoveredCorner, hoveredCorner);
|
||||
|
||||
float imageCornerSize = imageButtonWidget->GetCornerSize();
|
||||
float imageCornerTexCoords = imageButtonWidget->GetCornerTexCoords();
|
||||
|
||||
SlicedSprite::Corner corner;
|
||||
corner.size = Vector2f(imageCornerSize, imageCornerSize);
|
||||
corner.textureCoords = Vector2f(imageCornerTexCoords, imageCornerTexCoords);
|
||||
|
||||
m_sprite = std::make_shared<SlicedSprite>(imageButtonWidget->GetMaterial());
|
||||
m_sprite->SetCorners(corner, corner);
|
||||
m_sprite->SetTextureCoords(imageButtonWidget->GetTextureCoords());
|
||||
|
||||
m_entity = CreateGraphicsEntity();
|
||||
|
||||
GraphicsComponent& gfxComponent = registry.get<GraphicsComponent>(m_entity);
|
||||
gfxComponent.AttachRenderable(m_sprite, renderMask);
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::Layout(const Vector2f& size)
|
||||
{
|
||||
m_hoveredSprite->SetSize(size);
|
||||
m_sprite->SetSize(size);
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
Update(true, m_isPressed);
|
||||
m_isHovered = true;
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
Update(false, m_isPressed);
|
||||
m_isHovered = false;
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::OnPress()
|
||||
{
|
||||
Update(m_isHovered, true);
|
||||
m_isPressed = true;
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::OnRelease()
|
||||
{
|
||||
Update(m_isHovered, false);
|
||||
m_isPressed = false;
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::OnUpdate()
|
||||
{
|
||||
ImageButtonWidget* owner = GetOwnerWidget<ImageButtonWidget>();
|
||||
|
||||
// If a hovering material was added while we're being hovered, we need to detach the hovering sprite
|
||||
if (owner->GetHoveredMaterial())
|
||||
{
|
||||
GraphicsComponent& gfxComponent = GetRegistry().get<GraphicsComponent>(m_entity);
|
||||
gfxComponent.DetachRenderable(m_hoveredSprite);
|
||||
}
|
||||
|
||||
m_sprite->SetTextureCoords(owner->GetTextureCoords());
|
||||
|
||||
Update(m_isHovered, m_isPressed);
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::UpdateRenderLayer(int baseRenderLayer)
|
||||
{
|
||||
m_sprite->UpdateRenderLayer(baseRenderLayer);
|
||||
m_hoveredSprite->UpdateRenderLayer(baseRenderLayer + 1);
|
||||
}
|
||||
|
||||
void SimpleImageButtonWidgetStyle::Update(bool hovered, bool pressed)
|
||||
{
|
||||
ImageButtonWidget* owner = GetOwnerWidget<ImageButtonWidget>();
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
if (const auto& pressedMaterial = owner->GetPressedMaterial())
|
||||
{
|
||||
m_sprite->SetColor(owner->GetColor());
|
||||
m_sprite->SetMaterial(pressedMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sprite->SetColor(owner->GetColor() * Nz::Color::FromRGB8(120, 0, 0));
|
||||
m_sprite->SetMaterial(owner->GetMaterial());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sprite->SetColor(owner->GetColor());
|
||||
m_sprite->SetMaterial(owner->GetMaterial());
|
||||
}
|
||||
|
||||
if (hovered)
|
||||
{
|
||||
if (const auto& hoveredMaterial = owner->GetHoveredMaterial())
|
||||
{
|
||||
if (!pressed)
|
||||
m_sprite->SetMaterial(hoveredMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pressed)
|
||||
m_sprite->SetMaterial(owner->GetMaterial());
|
||||
|
||||
GraphicsComponent& gfxComponent = GetRegistry().get<GraphicsComponent>(m_entity);
|
||||
gfxComponent.AttachRenderable(m_hoveredSprite, GetRenderMask());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pressed)
|
||||
m_sprite->SetMaterial(owner->GetMaterial());
|
||||
|
||||
GraphicsComponent& gfxComponent = GetRegistry().get<GraphicsComponent>(m_entity);
|
||||
gfxComponent.DetachRenderable(m_hoveredSprite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SimpleLabelWidgetStyle::SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial) :
|
||||
LabelWidgetStyle(labelWidget, 1),
|
||||
m_hoveredMaterial(std::move(hoveredMaterial)),
|
||||
@@ -245,4 +382,123 @@ namespace Nz
|
||||
{
|
||||
m_textSprite->Update(drawer);
|
||||
}
|
||||
|
||||
|
||||
SimpleScrollAreaWidgetStyle::SimpleScrollAreaWidgetStyle(ScrollAreaWidget* scrollAreaWidget) :
|
||||
ScrollAreaWidgetStyle((BaseWidget*) scrollAreaWidget, 0)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleScrollAreaWidgetStyle::Layout(const Vector2f& size)
|
||||
{
|
||||
}
|
||||
|
||||
void SimpleScrollAreaWidgetStyle::UpdateRenderLayer(int baseRenderLayer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SimpleScrollbarWidgetStyle::SimpleScrollbarWidgetStyle(ScrollbarWidget* scrollBarWidget, StyleConfig config) :
|
||||
ScrollbarWidgetStyle(scrollBarWidget, 1),
|
||||
m_config(std::move(config))
|
||||
{
|
||||
auto& registry = GetRegistry();
|
||||
UInt32 renderMask = GetRenderMask();
|
||||
|
||||
m_backgroundScrollbarSprite = std::make_shared<Sprite>((scrollBarWidget->GetOrientation() == ScrollbarOrientation::Horizontal) ? m_config.backgroundHorizontalMaterial : m_config.backgroundVerticalMaterial);
|
||||
|
||||
m_backgroundScrollbarSpriteEntity = CreateGraphicsEntity();
|
||||
registry.get<GraphicsComponent>(m_backgroundScrollbarSpriteEntity).AttachRenderable(m_backgroundScrollbarSprite, renderMask);
|
||||
|
||||
m_scrollbarSpriteEntity = CreateGraphicsEntity();
|
||||
registry.get<GraphicsComponent>(m_scrollbarSpriteEntity).AttachRenderable(m_scrollbarSprite, renderMask);
|
||||
}
|
||||
|
||||
void SimpleScrollbarWidgetStyle::Layout(const Vector2f& size)
|
||||
{
|
||||
float totalSize;
|
||||
if (GetOwnerWidget<ScrollbarWidget>()->GetOrientation() == ScrollbarOrientation::Horizontal)
|
||||
totalSize = size.x;
|
||||
else
|
||||
totalSize = size.y;
|
||||
|
||||
m_backgroundScrollbarSprite->SetSize(size);
|
||||
}
|
||||
|
||||
void SimpleScrollbarWidgetStyle::UpdateRenderLayer(int baseRenderLayer)
|
||||
{
|
||||
m_backgroundScrollbarSprite->UpdateRenderLayer(baseRenderLayer);
|
||||
}
|
||||
|
||||
|
||||
SimpleScrollbarButtonWidgetStyle::SimpleScrollbarButtonWidgetStyle(ScrollbarButtonWidget* scrollbarButtonWidget, StyleConfig config) :
|
||||
ScrollbarButtonWidgetStyle(scrollbarButtonWidget, 1),
|
||||
m_hoveredMaterial(std::move(config.hoveredMaterial)),
|
||||
m_material(std::move(config.material)),
|
||||
m_pressedMaterial(std::move(config.grabbedMaterial)),
|
||||
m_pressedHoveredMaterial(std::move(config.grabbedHoveredMaterial)),
|
||||
m_isHovered(false),
|
||||
m_isPressed(false)
|
||||
{
|
||||
assert(m_material);
|
||||
|
||||
auto& registry = GetRegistry();
|
||||
UInt32 renderMask = GetRenderMask();
|
||||
|
||||
SlicedSprite::Corner corner;
|
||||
corner.size.Set(config.cornerSize);
|
||||
corner.textureCoords.Set(config.cornerTexCoords);
|
||||
|
||||
m_sprite = std::make_shared<SlicedSprite>(m_material);
|
||||
m_sprite->SetCorners(corner, corner);
|
||||
|
||||
m_entity = CreateGraphicsEntity();
|
||||
registry.get<GraphicsComponent>(m_entity).AttachRenderable(m_sprite, renderMask);
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::Layout(const Vector2f& size)
|
||||
{
|
||||
m_sprite->SetSize(size);
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
Update(true, m_isPressed);
|
||||
m_isHovered = true;
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
Update(false, m_isPressed);
|
||||
m_isHovered = false;
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::OnGrab()
|
||||
{
|
||||
Update(m_isHovered, true);
|
||||
m_isPressed = true;
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::OnRelease()
|
||||
{
|
||||
Update(m_isHovered, false);
|
||||
m_isPressed = false;
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::UpdateRenderLayer(int baseRenderLayer)
|
||||
{
|
||||
m_sprite->UpdateRenderLayer(baseRenderLayer);
|
||||
}
|
||||
|
||||
void SimpleScrollbarButtonWidgetStyle::Update(bool hovered, bool pressed)
|
||||
{
|
||||
if (pressed && hovered && m_pressedHoveredMaterial)
|
||||
m_sprite->SetMaterial(m_pressedHoveredMaterial);
|
||||
else if (pressed && m_pressedMaterial)
|
||||
m_sprite->SetMaterial(m_pressedMaterial);
|
||||
else if (hovered && m_hoveredMaterial)
|
||||
m_sprite->SetMaterial(m_hoveredMaterial);
|
||||
else
|
||||
m_sprite->SetMaterial(m_material);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,23 @@ namespace Nz
|
||||
}
|
||||
|
||||
|
||||
void ImageButtonWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageButtonWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageButtonWidgetStyle::OnPress()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageButtonWidgetStyle::OnRelease()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LabelWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
}
|
||||
@@ -76,4 +93,38 @@ namespace Nz
|
||||
void LabelWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ScrollbarWidgetStyle::OnButtonGrab()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarWidgetStyle::OnButtonRelease()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ScrollbarButtonWidgetStyle::OnHoverBegin()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidgetStyle::OnHoverEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidgetStyle::OnGrab()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollbarButtonWidgetStyle::OnRelease()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||