Widgets: Add CheckboxWidget

This commit is contained in:
Jérôme Leclercq
2021-12-01 10:47:21 +01:00
parent 26d6448076
commit a4c0cc8c34
10 changed files with 395 additions and 2 deletions

View File

@@ -0,0 +1,71 @@
// Copyright (C) 2021 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/CheckboxWidget.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
{
CheckboxWidget::CheckboxWidget(BaseWidget* parent) :
BaseWidget(parent),
m_state(CheckboxState::Unchecked),
m_isTristateEnabled(false)
{
m_style = GetTheme()->CreateStyle(this);
Layout();
}
void CheckboxWidget::SetState(CheckboxState checkboxState)
{
OnCheckboxStateUpdate(this, checkboxState);
m_state = checkboxState;
m_style->OnNewState(m_state);
}
void CheckboxWidget::Layout()
{
BaseWidget::Layout();
m_style->Layout(GetSize());
}
void CheckboxWidget::OnMouseButtonPress(int /*x*/, int /*y*/, Mouse::Button button)
{
if (button == Mouse::Left)
m_style->OnPress();
}
void CheckboxWidget::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(x, y))
SwitchToNextState();
}
}
void CheckboxWidget::OnMouseEnter()
{
m_style->OnHoverBegin();
}
void CheckboxWidget::OnMouseExit()
{
m_style->OnHoverEnd();
}
}

View File

@@ -29,6 +29,22 @@ namespace Nz
const UInt8 ButtonPressedHoveredImage[] = {
#include <Nazara/Widgets/Resources/DefaultTheme/ButtonPressedHovered.png.h>
};
const UInt8 CheckboxBackgroundImage[] = {
#include <Nazara/Widgets/Resources/DefaultTheme/CheckboxBackground.png.h>
};
const UInt8 CheckboxBackgroundHoveredImage[] = {
#include <Nazara/Widgets/Resources/DefaultTheme/CheckboxBackgroundHovered.png.h>
};
const UInt8 CheckboxCheckImage[] = {
#include <Nazara/Widgets/Resources/DefaultTheme/CheckboxCheck.png.h>
};
const UInt8 CheckboxTristateImage[] = {
#include <Nazara/Widgets/Resources/DefaultTheme/CheckboxTristate.png.h>
};
}
DefaultWidgetTheme::DefaultWidgetTheme()
@@ -60,6 +76,12 @@ namespace Nz
m_buttonHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(ButtonHoveredImage, sizeof(ButtonHoveredImage), texParams));
m_buttonPressedMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(ButtonPressedImage, sizeof(ButtonPressedImage), texParams));
m_buttonPressedHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(ButtonPressedHoveredImage, sizeof(ButtonPressedHoveredImage), texParams));
// Checkbox material
m_checkboxBackgroundMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(CheckboxBackgroundImage, sizeof(CheckboxBackgroundImage), texParams));
m_checkboxBackgroundHoveredMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(CheckboxBackgroundHoveredImage, sizeof(CheckboxBackgroundHoveredImage), texParams));
m_checkboxCheckMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(CheckboxCheckImage, sizeof(CheckboxCheckImage), texParams));
m_checkboxTristateMaterial = CreateMaterialFromTexture(Texture::LoadFromMemory(CheckboxTristateImage, sizeof(CheckboxTristateImage), texParams));
}
std::unique_ptr<ButtonWidgetStyle> DefaultWidgetTheme::CreateStyle(ButtonWidget* buttonWidget) const
@@ -75,8 +97,21 @@ namespace Nz
return std::make_unique<SimpleButtonWidgetStyle>(buttonWidget, styleConfig);
}
std::unique_ptr<LabelWidgetStyle> DefaultWidgetTheme::CreateStyle(LabelWidget* buttonWidget) const
std::unique_ptr<CheckboxWidgetStyle> DefaultWidgetTheme::CreateStyle(CheckboxWidget* checkboxWidget) const
{
return std::make_unique<SimpleLabelWidgetStyle>(buttonWidget, Widgets::Instance()->GetTransparentMaterial());
SimpleCheckboxWidgetStyle::StyleConfig styleConfig;
styleConfig.backgroundCornerSize = 10.f;
styleConfig.backgroundCornerTexCoords = 10.f / 64.f;
styleConfig.backgroundHoveredMaterial = m_checkboxBackgroundHoveredMaterial;
styleConfig.backgroundMaterial = m_checkboxBackgroundMaterial;
styleConfig.checkMaterial = m_checkboxCheckMaterial;
styleConfig.tristateMaterial = m_checkboxTristateMaterial;
return std::make_unique<SimpleCheckboxWidgetStyle>(checkboxWidget, styleConfig);
}
std::unique_ptr<LabelWidgetStyle> DefaultWidgetTheme::CreateStyle(LabelWidget* labelWidget) const
{
return std::make_unique<SimpleLabelWidgetStyle>(labelWidget, Widgets::Instance()->GetTransparentMaterial());
}
}

View File

@@ -7,6 +7,7 @@
#include <Nazara/Utility/Components/NodeComponent.hpp>
#include <Nazara/Widgets/ButtonWidget.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/CheckboxWidget.hpp>
#include <Nazara/Widgets/LabelWidget.hpp>
#include <Nazara/Widgets/Widgets.hpp>
#include <Nazara/Widgets/Debug.hpp>
@@ -95,6 +96,92 @@ namespace Nz
}
SimpleCheckboxWidgetStyle::SimpleCheckboxWidgetStyle(CheckboxWidget* buttonWidget, StyleConfig config) :
CheckboxWidgetStyle(buttonWidget),
m_checkMaterial(std::move(config.checkMaterial)),
m_hoveredMaterial(std::move(config.backgroundHoveredMaterial)),
m_material(std::move(config.backgroundMaterial)),
m_tristateMaterial(std::move(config.tristateMaterial)),
m_isHovered(false)
{
assert(m_material);
assert(m_checkMaterial);
assert(m_tristateMaterial);
auto& registry = GetRegistry();
UInt32 renderMask = GetRenderMask();
SlicedSprite::Corner corner;
corner.size.Set(config.backgroundCornerSize);
corner.textureCoords.Set(config.backgroundCornerTexCoords);
m_backgroundSprite = std::make_shared<SlicedSprite>(m_material);
m_backgroundSprite->SetCorners(corner, corner);
m_checkSprite = std::make_shared<Sprite>(m_checkMaterial);
m_backgroundEntity = CreateGraphicsEntity();
registry.get<GraphicsComponent>(m_backgroundEntity).AttachRenderable(m_backgroundSprite, renderMask);
m_checkEntity = CreateGraphicsEntity();
{
auto& gfxComponent = registry.get<GraphicsComponent>(m_checkEntity);
gfxComponent.AttachRenderable(m_checkSprite, renderMask);
gfxComponent.Hide();
}
}
void SimpleCheckboxWidgetStyle::Layout(const Vector2f& size)
{
m_backgroundSprite->SetSize(size);
Vector2f checkSize = size * 0.66f;
m_checkSprite->SetSize(checkSize);
GetRegistry().get<NodeComponent>(m_checkEntity).SetPosition(size.x / 2.f - checkSize.x / 2.f, size.y / 2.f - checkSize.y / 2.f);
}
void SimpleCheckboxWidgetStyle::OnHoverBegin()
{
m_isHovered = true;
UpdateMaterial(m_isHovered);
}
void SimpleCheckboxWidgetStyle::OnHoverEnd()
{
m_isHovered = false;
UpdateMaterial(m_isHovered);
}
void SimpleCheckboxWidgetStyle::OnNewState(CheckboxState newState)
{
switch (newState)
{
case CheckboxState::Unchecked:
{
GetRegistry().get<GraphicsComponent>(m_checkEntity).Hide();
break;
}
case CheckboxState::Tristate:
case CheckboxState::Checked:
{
m_checkSprite->SetMaterial((newState == CheckboxState::Checked) ? m_checkMaterial : m_tristateMaterial);
GetRegistry().get<GraphicsComponent>(m_checkEntity).Show();
break;
}
}
}
void SimpleCheckboxWidgetStyle::UpdateMaterial(bool hovered)
{
if (hovered && m_hoveredMaterial)
m_backgroundSprite->SetMaterial(m_hoveredMaterial);
else
m_backgroundSprite->SetMaterial(m_material);
}
SimpleLabelWidgetStyle::SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial) :
LabelWidgetStyle(labelWidget),
m_hoveredMaterial(std::move(hoveredMaterial)),

View File

@@ -48,6 +48,27 @@ namespace Nz
}
void CheckboxWidgetStyle::OnHoverBegin()
{
}
void CheckboxWidgetStyle::OnHoverEnd()
{
}
void CheckboxWidgetStyle::OnNewState(CheckboxState newState)
{
}
void CheckboxWidgetStyle::OnPress()
{
}
void CheckboxWidgetStyle::OnRelease()
{
}
void LabelWidgetStyle::OnHoverBegin()
{
}