scroll view: Add Hovered state for the scroll bar

This commit is contained in:
Peter Hartmann 2023-07-11 09:35:28 +02:00
parent 17d746fad6
commit 62c5bc5fdc
5 changed files with 94 additions and 7 deletions

View File

@ -1095,7 +1095,18 @@ void Editor::setupScrollViewMetrics()
using Q = QskScrollView;
for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } )
{
setMetric( subControl | A::Size, 2 );
setMetric( subControl | A::Size | Q::Hovered, 6,
{ QskStateCombination::CombinationNoState, Q::Pressed } );
setAlignment( subControl, Qt::AlignRight );
}
for ( auto subControl : { Q::HorizontalScrollHandle, Q::VerticalScrollHandle } )
{
setBoxShape( subControl, { 100, Qt::RelativeSize },
{ QskStateCombination::CombinationNoState, Q::Hovered | Q::Pressed } );
}
const auto handleExtent = 40.0;
setStrutSize( Q::HorizontalScrollHandle, handleExtent, 0.0 );

View File

@ -1129,7 +1129,7 @@ void Editor::setupScrollView()
for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } )
{
setMetric( subControl | A::Size, 10_dp );
setMetric( subControl | A::Size, 6_dp );
setPadding( subControl, 0 );
}
@ -1139,9 +1139,9 @@ void Editor::setupScrollView()
for ( auto subControl : { Q::HorizontalScrollHandle, Q::VerticalScrollHandle } )
{
setBoxShape( subControl, 3_dp );
setBoxShape( subControl, { 100, Qt::RelativeSize } );
setBoxBorderMetrics( subControl, 0 );
setGradient( subControl, m_pal.primary );
setGradient( subControl, m_pal.secondary );
setAnimation( subControl | A::Color, qskDuration );
}

View File

@ -62,6 +62,7 @@ QskScrollView::QskScrollView( QQuickItem* parent )
: Inherited( parent )
, m_data( new PrivateData() )
{
setAcceptHoverEvents( true );
}
QskScrollView::~QskScrollView()
@ -117,6 +118,17 @@ QskAspect::States QskScrollView::scrollHandleStates( Qt::Orientation orientation
if ( m_data->isScrolling == orientation )
states |= Pressed;
const auto subControl = ( orientation == Qt::Horizontal ) ? HorizontalScrollBar : VerticalScrollBar;
if( effectiveSkinHint( subControl | Hovered ).toBool() )
{
states |= Hovered;
}
else
{
states &= ~Hovered;
}
return states;
}
@ -234,6 +246,21 @@ void QskScrollView::mouseUngrabEvent()
m_data->resetScrolling( this );
}
void QskScrollView::hoverEnterEvent( QHoverEvent* event )
{
updateHoverHints( event );
}
void QskScrollView::hoverMoveEvent( QHoverEvent* event )
{
updateHoverHints( event );
}
void QskScrollView::hoverLeaveEvent( QHoverEvent* event )
{
updateHoverHints( event );
}
#ifndef QT_NO_WHEELEVENT
QPointF QskScrollView::scrollOffset( const QWheelEvent* event ) const
@ -325,4 +352,15 @@ Qt::Orientations QskScrollView::scrollableOrientations() const
return orientations;
}
void QskScrollView::updateHoverHints( QHoverEvent* event )
{
const auto pos = qskHoverPosition( event );
const bool hBarHovered = subControlRect( HorizontalScrollBar ).contains( pos );
setSkinHint( HorizontalScrollBar | Hovered, hBarHovered );
const bool yBarHovered = subControlRect( VerticalScrollBar ).contains( pos );
setSkinHint( VerticalScrollBar | Hovered, yBarHovered );
}
#include "moc_QskScrollView.cpp"

View File

@ -54,11 +54,17 @@ class QSK_EXPORT QskScrollView : public QskScrollBox
void mouseReleaseEvent( QMouseEvent* ) override;
void mouseUngrabEvent() override;
void hoverEnterEvent( QHoverEvent* ) override;
void hoverMoveEvent( QHoverEvent* ) override;
void hoverLeaveEvent( QHoverEvent* ) override;
#ifndef QT_NO_WHEELEVENT
QPointF scrollOffset( const QWheelEvent* ) const override;
#endif
private:
void updateHoverHints( QHoverEvent* );
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};

View File

@ -252,6 +252,8 @@ QRectF QskScrollViewSkinlet::scrollHandleRect( const QskScrollView* scrollView,
QskSkinStateChanger stateChanger( scrollView );
stateChanger.setStates( scrollView->scrollHandleStates( orientation ) );
const auto width = scrollView->metric( Q::VerticalScrollBar | QskAspect::Size );
const auto padding = scrollView->paddingHint( Q::VerticalScrollBar );
const auto strut = scrollView->strutSizeHint( Q::VerticalScrollHandle );
@ -262,6 +264,19 @@ QRectF QskScrollViewSkinlet::scrollHandleRect( const QskScrollView* scrollView,
qskAlignedHandle( y1, y2, sbRect.height(), strut.height(), top, bottom );
handleRect = sbRect;
handleRect.setWidth( width );
const auto alignment = scrollView->alignmentHint( Q::VerticalScrollBar );
if( alignment & Qt::AlignHCenter )
{
handleRect.moveCenter( sbRect.center() );
}
else if( alignment & Qt::AlignRight )
{
handleRect.moveRight( sbRect.right() );
}
handleRect.setTop( sbRect.y() + top );
handleRect.setBottom( sbRect.y() + bottom );
handleRect.adjust( padding.left(), 0, -padding.right(), 0 );
@ -273,6 +288,8 @@ QRectF QskScrollViewSkinlet::scrollHandleRect( const QskScrollView* scrollView,
QskSkinStateChanger stateChanger( scrollView );
stateChanger.setStates( scrollView->scrollHandleStates( orientation ) );
const auto height = scrollView->metric( Q::HorizontalScrollBar | QskAspect::Size );
const auto padding = scrollView->paddingHint( Q::HorizontalScrollBar );
const qreal x1 = pos.x() / scrollableSize.width();
@ -284,6 +301,19 @@ QRectF QskScrollViewSkinlet::scrollHandleRect( const QskScrollView* scrollView,
qskAlignedHandle( x1, x2, sbRect.width(), strut.width(), left, right );
handleRect = sbRect;
handleRect.setHeight( height );
const auto alignment = scrollView->alignmentHint( Q::HorizontalScrollBar );
if( alignment & Qt::AlignVCenter )
{
handleRect.moveCenter( sbRect.center() );
}
else if( alignment & Qt::AlignBottom )
{
handleRect.moveBottom( sbRect.bottom() );
}
handleRect.setLeft( sbRect.x() + left );
handleRect.setRight( sbRect.x() + right );
handleRect.adjust( 0, padding.top(), 0, -padding.bottom() );
@ -307,25 +337,27 @@ QRectF QskScrollViewSkinlet::scrollBarRect( const QskScrollView* scrollView,
QskSkinStateChanger stateChanger( scrollView );
stateChanger.setStates( scrollView->scrollHandleStates( orientation ) );
const auto h = qMax( scrollView->metric( Q::HorizontalScrollBar | A::Size ),
scrollView->metric( Q::HorizontalScrollBar | A::Size | Q::Hovered ) );
const qreal w = qMax( scrollView->metric( Q::VerticalScrollBar | A::Size ),
scrollView->metric( Q::VerticalScrollBar | A::Size | Q::Hovered ) );
if ( orientation == Qt::Horizontal )
{
const qreal h = scrollView->metric( Q::HorizontalScrollBar | A::Size );
r.setTop( r.bottom() - h );
if ( scrollOrientations & Qt::Vertical )
{
const qreal w = scrollView->metric( Q::VerticalScrollBar | A::Size );
r.setRight( r.right() - w );
}
}
else
{
const qreal w = scrollView->metric( Q::VerticalScrollBar | A::Size );
r.setLeft( r.right() - w );
if ( scrollOrientations & Qt::Horizontal )
{
const qreal h = scrollView->metric( Q::HorizontalScrollBar | A::Size );
r.setBottom( r.bottom() - h );
}
}