qskinny/src/controls/QskSliderSkinlet.cpp

226 lines
5.9 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskSliderSkinlet.h"
2018-08-03 08:30:23 +02:00
#include "QskSlider.h"
2017-07-21 18:21:34 +02:00
#include "QskAspect.h"
#include "QskBoxBorderMetrics.h"
2017-07-21 18:21:34 +02:00
#include "QskFunctions.h"
static inline QMarginsF qskPadding(
2017-07-21 18:21:34 +02:00
const QskSlider* slider, QskAspect::Subcontrol subControl )
{
return slider->paddingHint( subControl ) +
2018-08-03 08:15:28 +02:00
slider->boxBorderMetricsHint( subControl ).widths();
2017-07-21 18:21:34 +02:00
}
2018-08-03 08:15:28 +02:00
QskSliderSkinlet::QskSliderSkinlet( QskSkin* skin )
: Inherited( skin )
2017-07-21 18:21:34 +02:00
{
setNodeRoles( { PanelRole, GrooveRole, FillRole, HandleRole } );
}
QskSliderSkinlet::~QskSliderSkinlet()
{
}
2017-07-21 18:21:34 +02:00
QRectF QskSliderSkinlet::subControlRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
2017-07-21 18:21:34 +02:00
{
const auto slider = static_cast< const QskSlider* >( skinnable );
if ( subControl == QskSlider::Panel )
2017-09-01 11:55:55 +02:00
{
return panelRect( slider, contentsRect );
2017-09-01 11:55:55 +02:00
}
2017-07-21 18:21:34 +02:00
if ( subControl == QskSlider::Groove )
2017-09-01 11:55:55 +02:00
{
return grooveRect( slider, contentsRect );
2017-09-01 11:55:55 +02:00
}
2017-07-21 18:21:34 +02:00
if ( subControl == QskSlider::Fill )
2017-09-01 11:55:55 +02:00
{
return fillRect( slider, contentsRect );
2017-09-01 11:55:55 +02:00
}
2017-07-21 18:21:34 +02:00
if ( subControl == QskSlider::Handle )
2017-09-01 11:55:55 +02:00
{
return handleRect( slider, contentsRect );
2017-09-01 11:55:55 +02:00
}
2017-07-21 18:21:34 +02:00
if ( subControl == QskSlider::Scale )
2017-09-01 11:55:55 +02:00
{
return scaleRect( slider, contentsRect );
2017-09-01 11:55:55 +02:00
}
2017-07-21 18:21:34 +02:00
return Inherited::subControlRect( skinnable, contentsRect, subControl );
2017-07-21 18:21:34 +02:00
}
2017-09-01 11:55:55 +02:00
QSGNode* QskSliderSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{
const auto slider = static_cast< const QskSlider* >( skinnable );
2018-08-03 08:15:28 +02:00
switch ( nodeRole )
2017-09-01 11:55:55 +02:00
{
case PanelRole:
{
return updateBoxNode( slider, node, QskSlider::Panel );
2017-09-01 11:55:55 +02:00
}
case GrooveRole:
{
return updateBoxNode( slider, node, QskSlider::Groove );
2017-09-01 11:55:55 +02:00
}
case FillRole:
{
return updateBoxNode( slider, node, QskSlider::Fill );
2017-09-01 11:55:55 +02:00
}
case HandleRole:
{
return updateBoxNode( slider, node, QskSlider::Handle );
2017-09-01 11:55:55 +02:00
}
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
QRectF QskSliderSkinlet::panelRect(
const QskSlider* slider, const QRectF& contentsRect ) const
2017-07-21 18:21:34 +02:00
{
auto r = contentsRect;
2017-07-21 18:21:34 +02:00
const qreal size = slider->metric( QskSlider::Panel | QskAspect::Size ); // 0: no hint
2017-07-21 18:21:34 +02:00
if ( size > 0 && size < r.height() )
{
const auto alignment = slider->alignmentHint( QskSlider::Panel );
2017-07-21 18:21:34 +02:00
if ( slider->orientation() == Qt::Horizontal )
r = qskAlignedRectF( r, r.width(), size, alignment & Qt::AlignVertical_Mask );
else
r = qskAlignedRectF( r, size, r.height(), alignment & Qt::AlignHorizontal_Mask );
}
return r;
}
QRectF QskSliderSkinlet::innerRect( const QskSlider* slider,
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
2017-07-21 18:21:34 +02:00
{
QRectF r = subControlRect( slider, contentsRect, QskSlider::Panel );
2017-07-21 18:21:34 +02:00
r = r.marginsRemoved( qskPadding( slider, QskSlider::Panel ) );
QskSkinHintStatus status;
const qreal extent = slider->metric( subControl | QskAspect::Size, &status );
2017-07-21 18:21:34 +02:00
if ( slider->orientation() == Qt::Horizontal )
{
if ( status.isValid() && ( extent < r.height() ) )
2017-07-21 18:21:34 +02:00
{
r.setTop( r.center().y() - 0.5 * extent );
r.setHeight( extent );
2017-07-21 18:21:34 +02:00
}
}
else
{
if ( status.isValid() && ( extent < r.width() ) )
2017-07-21 18:21:34 +02:00
{
r.setLeft( r.center().x() - 0.5 * extent );
r.setWidth( extent );
2017-07-21 18:21:34 +02:00
}
}
return r;
}
QRectF QskSliderSkinlet::grooveRect(
const QskSlider* slider, const QRectF& rect ) const
2017-07-21 18:21:34 +02:00
{
return innerRect( slider, rect, QskSlider::Groove );
2017-07-21 18:21:34 +02:00
}
QRectF QskSliderSkinlet::scaleRect(
const QskSlider* slider, const QRectF& rect ) const
2017-07-21 18:21:34 +02:00
{
return innerRect( slider, rect, QskSlider::Groove );
2017-07-21 18:21:34 +02:00
}
QRectF QskSliderSkinlet::fillRect(
const QskSlider* slider, const QRectF& contentsRect ) const
2017-07-21 18:21:34 +02:00
{
using Q = QskSlider;
auto r = subControlRect( slider, contentsRect, Q::Panel );
r = r.marginsRemoved( qskPadding( slider, Q::Panel ) );
2017-07-21 18:21:34 +02:00
qreal pos = slider->metric( Q::Handle | QskAspect::Position );
2017-07-21 18:21:34 +02:00
pos = qBound( 0.0, pos, 1.0 );
auto fillRect = innerRect( slider, contentsRect, Q::Fill );
2017-07-21 18:21:34 +02:00
if ( slider->orientation() == Qt::Horizontal )
{
fillRect.setLeft( r.left() );
fillRect.setRight( r.left() + pos * r.width() );
}
else
{
fillRect.setBottom( r.bottom() );
fillRect.setTop( r.bottom() - pos * r.height() );
}
return fillRect;
}
QRectF QskSliderSkinlet::handleRect(
const QskSlider* slider, const QRectF& contentsRect ) const
2017-07-21 18:21:34 +02:00
{
using Q = QskSlider;
2017-07-21 18:21:34 +02:00
auto r = subControlRect( slider, contentsRect, Q::Panel );
r = r.marginsRemoved( qskPadding( slider, Q::Panel ) );
2017-07-21 18:21:34 +02:00
const bool isHorizontal = slider->orientation() == Qt::Horizontal;
qreal extent;
2017-07-21 18:21:34 +02:00
{
QskSkinHintStatus status;
extent = slider->metric( Q::Handle | QskAspect::Size, &status );
2017-07-21 18:21:34 +02:00
if ( !status.isValid() )
extent = isHorizontal ? r.height() : r.width();
2017-07-21 18:21:34 +02:00
}
QRectF handleRect( 0, 0, extent, extent );
if ( extent > 0 )
{
handleRect = handleRect.marginsRemoved(
slider->marginHint( Q::Handle) );
}
2017-07-21 18:21:34 +02:00
qreal pos = slider->metric( Q::Handle | QskAspect::Position );
2017-07-21 18:21:34 +02:00
pos = qBound( 0.0, pos, 1.0 );
if ( slider->orientation() == Qt::Horizontal )
{
pos = r.left() + pos * r.width();
handleRect.moveCenter( QPointF( pos, r.center().y() ) );
}
else
{
pos = r.bottom() - pos * r.height();
handleRect.moveCenter( QPointF( r.center().x(), pos ) );
}
return handleRect;
}
#include "moc_QskSliderSkinlet.cpp"