NazaraEngine/src/Nazara/Widgets/ScrollAreaWidget.cpp

109 lines
2.9 KiB
C++

// Copyright (C) 2023 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/ScrollAreaWidget.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Widgets/ScrollbarWidget.hpp>
#include <Nazara/Widgets/Debug.hpp>
namespace Nz
{
ScrollAreaWidget::ScrollAreaWidget(BaseWidget* parent, BaseWidget* content) :
BaseWidget(parent),
m_content(content),
m_isScrollbarEnabled(true),
m_hasScrollbar(false)
{
AddChild(m_content->ReleaseFromParent());
m_content->SetPosition(Nz::Vector3f::Zero());
//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
}
void ScrollAreaWidget::EnableScrollbar(bool enable)
{
if (m_isScrollbarEnabled != enable)
{
m_isScrollbarEnabled = enable;
bool isVisible = IsScrollbarVisible();
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_horizontalScrollbar->SetValue(ratio);
}
void ScrollAreaWidget::Layout()
{
float scrollBarWidth = m_horizontalScrollbar->GetPreferredWidth();
float areaWidth = GetWidth();
float areaHeight = 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(areaWidth - scrollBarWidth, contentHeight);
m_content->Resize(contentSize);
if (m_isScrollbarEnabled)
m_horizontalScrollbar->Show();
m_horizontalScrollbar->SetPosition(contentSize.x, 0.f);
m_horizontalScrollbar->Resize({ scrollBarWidth, GetHeight() });
ScrollToRatio(m_horizontalScrollbar->GetValue());
}
else
{
m_hasScrollbar = false;
m_content->Resize(GetSize());
m_horizontalScrollbar->Hide();
ScrollToRatio(0.f);
}
BaseWidget::Layout();
}
bool ScrollAreaWidget::OnMouseWheelMoved(int /*x*/, int /*y*/, float delta)
{
constexpr float scrollStep = 100.f;
ScrollToHeight(GetScrollHeight() - scrollStep * delta);
return true;
}
}