109 lines
2.9 KiB
C++
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;
|
|
}
|
|
}
|