Scrolling layout

This commit is contained in:
IlyaShurupov 2024-10-17 16:46:49 +03:00
parent 03b2b5d038
commit 047d67c4fa
14 changed files with 288 additions and 35 deletions

View file

@ -11,8 +11,10 @@ void BasicLayout::pickRect(bool vertical) {
auto current = getArea();
auto children = getChildrenEnclosure();
auto parent = getParentEnclosure();
RectF newArea = current;
children.shrinkFromCenter(-mLayoutMargin, true);
RectF newArea;
if (vertical) {
auto rangeY = pickRange(current.getRangeY(), children.getRangeY(), parent.getRangeY(), true);
newArea = RectF(current.getRangeX(), rangeY);
@ -143,5 +145,5 @@ void BasicLayout::adjustLayout(bool vertical) {
RectF BasicLayout::getAvailableChildArea() const {
auto out = WidgetLayout::getAvailableChildArea();
return out.scaleFromCenter(mLayoutMargin, true);
return out.shrinkFromCenter(mLayoutMargin, true);
}

View file

@ -0,0 +1,53 @@
#include "ScrollableLayout.hpp"
// fixme : this dependency should be removed
#include "ScrollableWidget.hpp"
using namespace tp;
void ScrollableLayout::updateLayout(bool vertical) {
if (vertical) return;
// TODO : make better interface to get scroller and content widget
if (children().size() != 2) return;
auto scroller = dynamic_cast<ScrollableBarWidget*>(children().front());
auto content = children().back();
if (!scroller || !content) return;
updateWidgetRects(getArea(), content, scroller);
}
void ScrollableLayout::updateWidgetRects(const RectF& area, Widget* content, ScrollableBarWidget* scroller) const {
bool dir = scroller->getDirection();
// update content
// auto contentItems = content->getLayout()->getChildrenEnclosure();
// content->getLayout()->setArea(contentItems.shrinkFromCenter(-10, true));
content->getLayout()->pickRect(dir);
auto sizeFactor = (area.size[dir] / content->getLayout()->getArea().size[dir]);
auto splitFactor = 1 - ((sizeFactor > 1.f) ? 0 : mScrollerSize / area.size[!dir]);
auto holderArea = area.splitByFactorHL(splitFactor);
auto contentArea = content->getLayout()->getArea();
auto scrollerArea = area.splitByFactorHR(splitFactor);
scroller->updateSizeFactor(sizeFactor);
contentArea.pos[dir] = -scroller->getPosFactor() * contentArea.size[dir];
contentArea.size[!dir] = holderArea.size[!dir];
contentArea.pos[!dir] = 0;
scroller->getLayout()->setArea(scrollerArea);
content->getLayout()->setArea(contentArea);
}
RectF ScrollableLayout::getAvailableChildArea() const {
auto out = getArea();
// dont constrain on scroll axis
out.pos = -FLT_MAX / 4;
out.size = FLT_MAX / 2;
return out;
}