qskinny/src/controls/QskRangeControl.cpp

292 lines
5.8 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 "QskRangeControl.h"
#include "QskAspect.h"
#include "QskFunctions.h"
class QskRangeControl::PrivateData
{
public:
PrivateData():
minimum( 0.0 ),
maximum( 1.0 ),
value( 0.0 ),
stepSize( 0.1 ),
pageSize( 1 ),
snap( false ),
readOnly( false )
{
}
qreal minimum;
qreal maximum;
qreal value;
qreal stepSize;
int pageSize;
bool snap : 1;
bool readOnly : 1;
};
QskRangeControl::QskRangeControl( QQuickItem* parent ):
QskControl( parent ),
m_data( new PrivateData() )
{
setAcceptedMouseButtons( Qt::LeftButton );
setWheelEnabled( true );
2017-07-21 18:21:34 +02:00
}
QskRangeControl::~QskRangeControl()
{
}
void QskRangeControl::setMinimum( qreal minimum )
{
if ( m_data->minimum == minimum )
return;
const auto oldRange = range();
m_data->minimum = minimum;
Q_EMIT minimumChanged( minimum );
if ( isComponentComplete() )
adjustRangeAndValue( false );
const auto newRange = range();
if ( oldRange != newRange )
Q_EMIT rangeChanged( newRange );
update();
}
qreal QskRangeControl::minimum() const
{
return m_data->minimum;
}
void QskRangeControl::setMaximum( qreal maximum )
{
if ( m_data->maximum == maximum )
return;
const auto oldRange = range();
m_data->maximum = maximum;
Q_EMIT maximumChanged( maximum );
if ( isComponentComplete() )
adjustRangeAndValue( true );
const auto newRange = range();
if ( oldRange != newRange )
Q_EMIT rangeChanged( newRange );
update();
}
qreal QskRangeControl::maximum() const
{
return m_data->maximum;
}
void QskRangeControl::adjustRangeAndValue( bool increasing )
{
if ( m_data->maximum < m_data->minimum )
{
if ( increasing )
{
m_data->minimum = m_data->maximum;
Q_EMIT minimumChanged( m_data->minimum );
}
else
{
m_data->maximum = m_data->minimum;
Q_EMIT maximumChanged( m_data->maximum );
}
}
qreal newValue = m_data->value;
if ( m_data->snap && m_data->stepSize != 0.0 )
newValue = qRound( newValue / m_data->stepSize ) * m_data->stepSize;
newValue = qBound( m_data->minimum, newValue, m_data->maximum );
if ( newValue != m_data->value )
{
m_data->value = newValue;
Q_EMIT valueChanged( newValue );
}
}
qreal QskRangeControl::range() const
{
return m_data->maximum - m_data->minimum;
}
qreal QskRangeControl::position() const
{
return ( value() - minimum() ) / range();
}
qreal QskRangeControl::fixupValue( qreal value ) const
{
return value;
}
void QskRangeControl::setValue( qreal value )
{
if ( isComponentComplete() )
{
if ( m_data->snap && m_data->stepSize != 0.0 )
value = qRound( value / m_data->stepSize ) * m_data->stepSize;
value = qBound( m_data->minimum, value, m_data->maximum );
}
value = fixupValue( value );
if ( !qskFuzzyCompare( value, m_data->value ) )
{
m_data->value = value;
Q_EMIT valueChanged( value );
update();
}
}
qreal QskRangeControl::value() const
{
return m_data->value;
}
void QskRangeControl::setStepSize( qreal stepSize )
{
if ( qskFuzzyCompare( m_data->stepSize, stepSize ) )
return;
m_data->stepSize = stepSize;
Q_EMIT stepSizeChanged( stepSize );
update();
}
qreal QskRangeControl::stepSize() const
{
return m_data->stepSize;
}
void QskRangeControl::setPageSize( int pageSize )
{
if ( m_data->pageSize == pageSize )
return;
m_data->pageSize = pageSize;
Q_EMIT pageSizeChanged( pageSize );
update();
}
int QskRangeControl::pageSize() const
{
return m_data->pageSize;
}
void QskRangeControl::setSnap( bool snap )
{
if ( m_data->snap == snap )
return;
m_data->snap = snap;
Q_EMIT snapChanged( snap );
if ( snap )
{
// Re-align value
}
}
bool QskRangeControl::snap() const
{
return m_data->snap;
}
void QskRangeControl::setReadOnly( bool readOnly )
{
if ( m_data->readOnly == readOnly )
return;
// we are killing user settings here !!
setFocusPolicy( m_data->readOnly ? Qt::NoFocus : Qt::StrongFocus );
setWheelEnabled( m_data->readOnly );
2017-07-21 18:21:34 +02:00
m_data->readOnly = readOnly;
Q_EMIT readOnlyChanged( readOnly );
}
bool QskRangeControl::isReadOnly() const
{
return m_data->readOnly;
}
void QskRangeControl::stepUp()
{
setValue( m_data->value + m_data->stepSize );
}
void QskRangeControl::stepDown()
{
setValue( m_data->value - m_data->stepSize );
}
void QskRangeControl::pageUp()
{
setValue( m_data->value + m_data->stepSize * m_data->pageSize );
}
void QskRangeControl::pageDown()
{
setValue( m_data->value - m_data->stepSize * m_data->pageSize );
}
void QskRangeControl::keyPressEvent( QKeyEvent* event )
{
if ( !isReadOnly() )
{
if ( event->key() == Qt::Key_Up || event->matches( QKeySequence::MoveToNextChar ) )
{
stepUp();
return;
}
if ( event->key() == Qt::Key_Down || event->matches( QKeySequence::MoveToPreviousChar ) )
{
stepDown();
return;
}
}
Inherited::keyPressEvent( event );
}
#ifndef QT_NO_WHEELEVENT
void QskRangeControl::wheelEvent( QWheelEvent* event )
{
const int steps = event->delta() / 120;
setValue( m_data->value + steps * m_data->stepSize );
}
#endif
void QskRangeControl::componentComplete()
{
Inherited::componentComplete();
adjustRangeAndValue( true );
}
#include "moc_QskRangeControl.cpp"