Widgets: Fix ScrollAreaWidget
This commit is contained in:
parent
0fcf24f336
commit
e51695274c
|
|
@ -14,7 +14,7 @@
|
|||
#include <Nazara/Utility/Components.hpp>
|
||||
#include <Nazara/Widgets.hpp>
|
||||
#include <Nazara/Widgets/ImageButtonWidget.hpp>
|
||||
#include <Nazara/Widgets/ScrollbarWidget.hpp>
|
||||
#include <Nazara/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
|
@ -101,12 +101,19 @@ int main()
|
|||
Nz::CheckboxWidget* checkboxWidget = canvas2D.Add<Nz::CheckboxWidget>();
|
||||
//checkboxWidget->EnableTristate(true);
|
||||
checkboxWidget->SetPosition(800.f, 800.f);
|
||||
checkboxWidget->Resize({ 256.f, 256.f });
|
||||
checkboxWidget->Resize({ 256.f, 256 });
|
||||
checkboxWidget->SetState(true);
|
||||
|
||||
Nz::ScrollbarWidget* scrollBarWidget = canvas2D.Add<Nz::ScrollbarWidget>(Nz::ScrollbarOrientation::Vertical);
|
||||
Nz::TextAreaWidget* longTextArea = canvas2D.Add<Nz::TextAreaWidget>();
|
||||
longTextArea->EnableLineWrap(true);
|
||||
longTextArea->EnableMultiline(true);
|
||||
longTextArea->SetBackgroundColor(Nz::Color::White);
|
||||
longTextArea->SetTextColor(Nz::Color::Black);
|
||||
longTextArea->SetText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum");
|
||||
|
||||
Nz::ScrollAreaWidget* scrollBarWidget = canvas2D.Add<Nz::ScrollAreaWidget>(longTextArea);
|
||||
scrollBarWidget->SetPosition(1400.f, 800.f);
|
||||
scrollBarWidget->Resize({ 32.f, 256.f });
|
||||
scrollBarWidget->Resize({ 512.f, 256.f });
|
||||
|
||||
/*Nz::TextAreaWidget* textAreaWidget2 = canvas2D.Add<Nz::TextAreaWidget>();
|
||||
textAreaWidget2->SetPosition(800.f, 700.f);
|
||||
|
|
|
|||
|
|
@ -82,12 +82,12 @@ namespace Nz
|
|||
inline void Hide();
|
||||
inline bool IsVisible() const;
|
||||
|
||||
std::unique_ptr<BaseWidget> ReleaseFromParent();
|
||||
void Resize(const Vector2f& size);
|
||||
|
||||
void SetBackgroundColor(const Color& color);
|
||||
void SetCursor(SystemCursor systemCursor);
|
||||
void SetFocus();
|
||||
void SetParent(BaseWidget* widget);
|
||||
|
||||
inline void SetFixedHeight(float fixedHeight);
|
||||
inline void SetFixedSize(const Vector2f& fixedSize);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class ScrollbarWidget;
|
||||
|
||||
class NAZARA_WIDGETS_API ScrollAreaWidget : public BaseWidget
|
||||
{
|
||||
public:
|
||||
|
|
@ -23,8 +25,8 @@ namespace Nz
|
|||
|
||||
void EnableScrollbar(bool enable);
|
||||
|
||||
inline float GetScrollHeight() const;
|
||||
inline float GetScrollRatio() const;
|
||||
float GetScrollHeight() const;
|
||||
float GetScrollRatio() const;
|
||||
|
||||
inline bool HasScrollbar() const;
|
||||
inline bool IsScrollbarEnabled() const;
|
||||
|
|
@ -37,27 +39,15 @@ namespace Nz
|
|||
ScrollAreaWidget& operator=(ScrollAreaWidget&&) = default;
|
||||
|
||||
private:
|
||||
Nz::Rectf GetScrollbarRect() const;
|
||||
|
||||
void Layout() override;
|
||||
|
||||
void OnMouseButtonPress(int x, int y, Nz::Mouse::Button button) override;
|
||||
void OnMouseButtonRelease(int x, int y, Nz::Mouse::Button button) override;
|
||||
void OnMouseExit() override;
|
||||
void OnMouseMoved(int x, int y, int deltaX, int deltaY) override;
|
||||
void OnMouseWheelMoved(int x, int y, float delta) override;
|
||||
bool OnMouseWheelMoved(int x, int y, float delta) override;
|
||||
|
||||
std::unique_ptr<ScrollAreaWidgetStyle> m_style;
|
||||
BaseWidget* m_content;
|
||||
EntityHandle m_scrollbarBackgroundEntity;
|
||||
EntityHandle m_scrollbarEntity;
|
||||
Nz::SpriteRef m_scrollbarBackgroundSprite;
|
||||
Nz::SpriteRef m_scrollbarSprite;
|
||||
Nz::Vector2i m_grabbedDelta;
|
||||
bool m_isGrabbed;
|
||||
ScrollbarWidget* m_horizontalScrollbar;
|
||||
bool m_isScrollbarEnabled;
|
||||
bool m_hasScrollbar;
|
||||
float m_scrollRatio;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,10 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <NDK/Widgets/ScrollAreaWidget.hpp>
|
||||
#include <Nazara/Widgets/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline float ScrollAreaWidget::GetScrollHeight() const
|
||||
{
|
||||
return m_scrollRatio * m_content->GetHeight();
|
||||
}
|
||||
|
||||
inline float ScrollAreaWidget::GetScrollRatio() const
|
||||
{
|
||||
return m_scrollRatio;
|
||||
}
|
||||
|
||||
inline bool ScrollAreaWidget::HasScrollbar() const
|
||||
{
|
||||
return m_hasScrollbar;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ namespace Nz
|
|||
ScrollbarWidget& operator=(const ScrollbarWidget&) = delete;
|
||||
ScrollbarWidget& operator=(ScrollbarWidget&&) = default;
|
||||
|
||||
NazaraSignal(OnScrollbarValueUpdate, ScrollbarWidget* /*emitter*/, float /*newValue*/);
|
||||
|
||||
private:
|
||||
void Layout() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ namespace Nz
|
|||
inline void ScrollbarWidget::SetValue(float newValue)
|
||||
{
|
||||
m_value = Clamp(newValue, m_minimumValue, m_maximumValue);
|
||||
OnScrollbarValueUpdate(this, m_value);
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,20 @@ namespace Nz
|
|||
return m_canvas->IsKeyboardOwner(m_canvasIndex);
|
||||
}
|
||||
|
||||
std::unique_ptr<BaseWidget> BaseWidget::ReleaseFromParent()
|
||||
{
|
||||
if (!m_widgetParent)
|
||||
return {};
|
||||
|
||||
auto it = std::find_if(m_widgetParent->m_children.begin(), m_widgetParent->m_children.end(), [&](const std::unique_ptr<BaseWidget>& widgetPtr) { return widgetPtr.get() == this; });
|
||||
assert(it != m_widgetParent->m_children.end());
|
||||
|
||||
std::unique_ptr<BaseWidget> ownerPtr = std::move(*it);
|
||||
m_widgetParent->m_children.erase(it);
|
||||
|
||||
return ownerPtr;
|
||||
}
|
||||
|
||||
void BaseWidget::Resize(const Vector2f& size)
|
||||
{
|
||||
// Adjust new size
|
||||
|
|
@ -165,20 +179,6 @@ namespace Nz
|
|||
m_canvas->SetKeyboardOwner(m_canvasIndex);
|
||||
}
|
||||
|
||||
void BaseWidget::SetParent(BaseWidget* widget)
|
||||
{
|
||||
Canvas* oldCanvas = m_canvas;
|
||||
Canvas* newCanvas = widget->GetCanvas();
|
||||
|
||||
// Changing a widget canvas is a problem because of the canvas entities
|
||||
NazaraAssert(oldCanvas == newCanvas, "Transferring a widget between canvas is not yet supported");
|
||||
|
||||
Node::SetParent(widget);
|
||||
m_widgetParent = widget;
|
||||
|
||||
Layout();
|
||||
}
|
||||
|
||||
void BaseWidget::SetRenderingRect(const Rectf& renderingRect)
|
||||
{
|
||||
m_renderingRect = renderingRect;
|
||||
|
|
|
|||
|
|
@ -2,47 +2,35 @@
|
|||
// 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/Widgets/ScrollbarWidget.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_hasScrollbar(false)
|
||||
{
|
||||
m_content->SetParent(this);
|
||||
AddChild(m_content->ReleaseFromParent());
|
||||
m_content->SetPosition(Nz::Vector3f::Zero());
|
||||
|
||||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
//m_style = GetTheme()->CreateStyle(this);
|
||||
//SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
m_horizontalScrollbar = Add<ScrollbarWidget>(ScrollbarOrientation::Vertical);
|
||||
m_horizontalScrollbar->OnScrollbarValueUpdate.Connect([this](ScrollbarWidget*, float newValue)
|
||||
{
|
||||
float contentPosition = (GetHeight() - m_content->GetHeight()) * (1.f - newValue);
|
||||
|
||||
m_content->SetPosition(0.f, contentPosition);
|
||||
m_content->SetRenderingRect(Nz::Rectf(-std::numeric_limits<float>::infinity(), -contentPosition, std::numeric_limits<float>::infinity(), GetHeight()));
|
||||
});
|
||||
|
||||
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)
|
||||
|
|
@ -52,64 +40,49 @@ namespace Nz
|
|||
m_isScrollbarEnabled = enable;
|
||||
|
||||
bool isVisible = IsScrollbarVisible();
|
||||
m_scrollbarEntity->Enable(isVisible);
|
||||
m_scrollbarBackgroundEntity->Enable(isVisible);
|
||||
m_horizontalScrollbar->Show(isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
float ScrollAreaWidget::GetScrollHeight() const
|
||||
{
|
||||
return m_horizontalScrollbar->GetValue() * m_content->GetHeight();
|
||||
}
|
||||
|
||||
float ScrollAreaWidget::GetScrollRatio() const
|
||||
{
|
||||
return m_horizontalScrollbar->GetValue();
|
||||
}
|
||||
|
||||
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);
|
||||
m_horizontalScrollbar->SetValue(ratio);
|
||||
}
|
||||
|
||||
void ScrollAreaWidget::Layout()
|
||||
{
|
||||
constexpr float scrollBarBackgroundWidth = 20.f;
|
||||
constexpr float scrollBarWidth = scrollBarBackgroundWidth - 2.f * scrollbarPadding;
|
||||
float scrollBarWidth = m_horizontalScrollbar->GetPreferredWidth();
|
||||
|
||||
float areaWidth = GetWidth();
|
||||
float areaHeight = GetHeight();
|
||||
float contentHeight = m_content->GetHeight();
|
||||
|
||||
m_content->Resize({ areaWidth, areaHeight }); //< setting width with line wrap adjust preferred height
|
||||
float contentHeight = m_content->GetPreferredHeight();
|
||||
|
||||
if (contentHeight > areaHeight)
|
||||
{
|
||||
m_hasScrollbar = true;
|
||||
|
||||
Nz::Vector2f contentSize(GetWidth() - scrollBarBackgroundWidth, contentHeight);
|
||||
Nz::Vector2f contentSize(areaWidth - scrollBarWidth, contentHeight);
|
||||
m_content->Resize(contentSize);
|
||||
|
||||
if (m_isScrollbarEnabled)
|
||||
{
|
||||
m_scrollbarEntity->Enable();
|
||||
m_scrollbarBackgroundEntity->Enable();
|
||||
}
|
||||
m_horizontalScrollbar->Show();
|
||||
|
||||
float scrollBarHeight = std::max(std::floor(areaHeight * (areaHeight / contentHeight)), 20.f);
|
||||
m_horizontalScrollbar->SetPosition(contentSize.x, 0.f);
|
||||
m_horizontalScrollbar->Resize({ scrollBarWidth, GetHeight() });
|
||||
|
||||
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);
|
||||
ScrollToRatio(m_horizontalScrollbar->GetValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -117,8 +90,7 @@ namespace Nz
|
|||
|
||||
m_content->Resize(GetSize());
|
||||
|
||||
m_scrollbarEntity->Disable();
|
||||
m_scrollbarBackgroundEntity->Disable();
|
||||
m_horizontalScrollbar->Hide();
|
||||
|
||||
ScrollToRatio(0.f);
|
||||
}
|
||||
|
|
@ -126,79 +98,11 @@ namespace Nz
|
|||
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)
|
||||
bool 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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ namespace Nz
|
|||
m_style = GetTheme()->CreateStyle(this);
|
||||
SetRenderLayerCount(m_style->GetRenderLayerCount());
|
||||
|
||||
SetPreferredSize({ 32.f, 32.f });
|
||||
|
||||
const WidgetTheme::Config& themeConfig = GetTheme()->GetConfig();
|
||||
|
||||
m_scrollCenterButton = Add<ScrollbarButtonWidget>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue