6#include "QskScrollViewSkinlet.h"
7#include "QskScrollView.h"
12#include "QskSkinStateChanger.h"
16static void qskAlignedHandle( qreal start, qreal end,
17 qreal scrollBarLength, qreal minHandleLength,
18 qreal& handleStart, qreal& handleEnd )
21 minHandleLength = qMax( 4.0, minHandleLength );
22 minHandleLength = qMin( minHandleLength, scrollBarLength );
24 handleStart = start * scrollBarLength;
25 handleEnd = end * scrollBarLength;
27 const qreal handleLength = handleEnd - handleStart;
28 if ( handleLength < minHandleLength )
30 const qreal extra = minHandleLength - handleLength;
32 handleStart -= extra * handleStart / scrollBarLength;
33 handleEnd += extra * ( ( scrollBarLength - handleEnd ) / scrollBarLength );
35 else if ( handleLength > scrollBarLength )
37 const qreal extra = scrollBarLength - handleLength;
39 handleStart -= extra * handleStart / scrollBarLength;
40 handleEnd += extra * ( ( scrollBarLength - handleEnd ) / scrollBarLength );
44static qreal qskScrollBarExtent(
45 const QskScrollView* scrollView, Qt::Orientation orientation )
47 const auto subControl = ( orientation == Qt::Horizontal )
48 ? QskScrollView::HorizontalScrollBar :
QskScrollView::VerticalScrollBar;
51 stateChanger.setStates( scrollView->scrollBarStates( subControl ) );
56QskScrollViewSkinlet::QskScrollViewSkinlet(
QskSkin* skin )
59 setNodeRoles( { PanelRole, ViewportRole, ContentsRootRole,
60 HorizontalScrollBarRole, HorizontalScrollHandleRole,
61 VerticalScrollBarRole, VerticalScrollHandleRole } );
64QskScrollViewSkinlet::~QskScrollViewSkinlet() =
default;
66QRectF QskScrollViewSkinlet::subControlRect(
const QskSkinnable* skinnable,
71 const auto scrollView =
static_cast< const QskScrollView*
>( skinnable );
73 if ( subControl == Q::Panel )
76 if ( subControl == Q::Viewport )
77 return viewportRect( scrollView, contentsRect );
79 if ( subControl == Q::HorizontalScrollBar )
80 return scrollBarRect( scrollView, contentsRect, Qt::Horizontal );
82 if ( subControl == Q::HorizontalScrollHandle )
83 return scrollHandleRect( scrollView, contentsRect, Qt::Horizontal );
85 if ( subControl == Q::VerticalScrollBar )
86 return scrollBarRect( scrollView, contentsRect, Qt::Vertical );
88 if ( subControl == Q::VerticalScrollHandle )
89 return scrollHandleRect( scrollView, contentsRect, Qt::Vertical );
91 return Inherited::subControlRect( skinnable, contentsRect, subControl );
94QSGNode* QskScrollViewSkinlet::updateSubNode(
95 const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node )
const
99 const auto scrollView =
static_cast< const QskScrollView*
>( skinnable );
104 return updateBoxNode( skinnable, node, Q::Panel );
107 return updateBoxNode( skinnable, node, Q::Viewport );
109 case HorizontalScrollHandleRole:
110 return updateScrollBarNode( scrollView, Q::HorizontalScrollHandle, node );
112 case VerticalScrollHandleRole:
113 return updateScrollBarNode( scrollView, Q::VerticalScrollHandle, node );
115 case HorizontalScrollBarRole:
116 return updateScrollBarNode( scrollView, Q::HorizontalScrollBar, node );
118 case VerticalScrollBarRole:
119 return updateScrollBarNode( scrollView, Q::VerticalScrollBar, node );
121 case ContentsRootRole:
122 return updateContentsRootNode( scrollView, node );
126 return Inherited::updateSubNode( skinnable, nodeRole, node );
129QSGNode* QskScrollViewSkinlet::updateScrollBarNode(
const QskScrollView* scrollView,
132 const auto rect = subControlRect( scrollView,
136 stateChanger.setStates( scrollView->scrollBarStates( subControl ) );
138 return updateBoxNode( scrollView, node, rect, subControl );
141QSGNode* QskScrollViewSkinlet::updateContentsRootNode(
144 auto* clipNode = updateBoxClipNode( scrollView, node, QskScrollView::Viewport );
145 if ( clipNode ==
nullptr )
148 auto oldContentsNode = QskSGNode::findChildNode( clipNode, ContentsRootRole );
149 auto contentsNode = updateContentsNode( scrollView, oldContentsNode );
160 QskSGNode::setNodeRole( contentsNode, ContentsRootRole );
162 if ( contentsNode->parent() != clipNode )
163 clipNode->appendChildNode( contentsNode );
166 if ( oldContentsNode && oldContentsNode != contentsNode )
168 clipNode->removeChildNode( oldContentsNode );
170 if ( oldContentsNode->flags() & QSGNode::OwnedByParent )
171 delete oldContentsNode;
177QSGNode* QskScrollViewSkinlet::updateContentsNode(
183QRectF QskScrollViewSkinlet::viewportRect(
184 const QskScrollView* scrollView,
const QRectF& contentsRect )
const
188 const auto orientation = scrollView->scrollableOrientations();
190 auto vr = subControlRect( scrollView, contentsRect, Q::Panel );
191 const qreal spacing = scrollView->
spacingHint( Q::Panel );
193 if ( orientation & Qt::Vertical )
195 const auto r = subControlRect(
196 scrollView, contentsRect, Q::VerticalScrollBar );
198 if ( r.width() > 0.0 )
199 vr.setWidth( vr.width() - r.width() - spacing );
202 if ( orientation & Qt::Horizontal )
204 const auto r = subControlRect(
205 scrollView, contentsRect, Q::HorizontalScrollBar );
207 if ( r.height() >= 0.0 )
208 vr.setHeight( vr.height() - r.height() - spacing );
211 if ( vr.width() < 0.0 )
214 if ( vr.height() < 0.0 )
220QRectF QskScrollViewSkinlet::scrollHandleRect(
const QskScrollView* scrollView,
221 const QRectF& contentsRect, Qt::Orientation orientation )
const
225 const auto scrollOrientations = scrollView->scrollableOrientations();
226 if ( !( orientation & scrollOrientations ) )
229 const auto pos = scrollView->scrollPos();
231 const auto vRect = subControlRect(
232 scrollView, contentsRect, QskScrollView::Viewport );
234 const auto scrollableSize = scrollView->scrollableSize();
238 if ( orientation == Qt::Vertical )
240 const auto sbRect = subControlRect( scrollView, contentsRect, Q::VerticalScrollBar );
243 stateChanger.setStates( scrollView->scrollBarStates( Q::VerticalScrollBar ) );
245 const auto padding = scrollView->
paddingHint( Q::VerticalScrollBar );
246 const auto strut = scrollView->
strutSizeHint( Q::VerticalScrollHandle );
248 const qreal y1 = pos.y() / scrollableSize.height();
249 const qreal y2 = ( pos.y() + vRect.height() ) / scrollableSize.height();
252 qskAlignedHandle( y1, y2, sbRect.height(), strut.height(), top, bottom );
255 handleRect.setTop( sbRect.y() + top );
256 handleRect.setBottom( sbRect.y() + bottom );
257 handleRect.adjust( padding.left(), 0, -padding.right(), 0 );
261 const auto sbRect = subControlRect( scrollView, contentsRect, Q::HorizontalScrollBar );
264 stateChanger.setStates( scrollView->scrollBarStates( Q::HorizontalScrollBar ) );
266 const auto padding = scrollView->
paddingHint( Q::HorizontalScrollBar );
268 const qreal x1 = pos.x() / scrollableSize.width();
269 const qreal x2 = ( pos.x() + vRect.width() ) / scrollableSize.width();
271 const auto strut = scrollView->
strutSizeHint( Q::HorizontalScrollHandle );
274 qskAlignedHandle( x1, x2, sbRect.width(), strut.width(), left, right );
277 handleRect.setLeft( sbRect.x() + left );
278 handleRect.setRight( sbRect.x() + right );
279 handleRect.adjust( 0, padding.top(), 0, -padding.bottom() );
285QRectF QskScrollViewSkinlet::scrollBarRect(
const QskScrollView* scrollView,
286 const QRectF& contentsRect, Qt::Orientation orientation )
const
290 const auto scrollOrientations = scrollView->scrollableOrientations();
291 if ( !( orientation & scrollOrientations ) )
294 auto r = subControlRect( scrollView, contentsRect, Q::Panel );
296 if ( orientation == Qt::Horizontal )
298 const qreal h = qskScrollBarExtent( scrollView, Qt::Horizontal );
299 r.setTop( r.bottom() - h );
301 if ( scrollOrientations & Qt::Vertical )
303 const qreal w = qskScrollBarExtent( scrollView, Qt::Vertical );
304 r.setRight( r.right() - w );
309 const qreal w = qskScrollBarExtent( scrollView, Qt::Vertical );
310 r.setLeft( r.right() - w );
312 if ( scrollOrientations & Qt::Horizontal )
314 const qreal h = qskScrollBarExtent( scrollView, Qt::Horizontal );
315 r.setBottom( r.bottom() - h );
322#include "moc_QskScrollViewSkinlet.cpp"
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
QRectF contentsRect() const
qreal spacingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a spacing hint.
QMarginsF paddingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a padding hint.
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.
qreal metric(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a metric hint.