disable QskSpinBox buttons when reaching minimum/maximum
This commit is contained in:
parent
a4b2bcde16
commit
99079a666e
|
@ -1059,6 +1059,8 @@ void Editor::setupSpinBox()
|
|||
setAlignment( subControl, Qt::AlignCenter );
|
||||
#if 1
|
||||
setFontRole( subControl, QskSkin::TinyFont ); // until it is no graphic
|
||||
setColor( subControl, m_pal.themeForeground );
|
||||
setColor( subControl | Q::Disabled, m_pal.darker200 );
|
||||
#endif
|
||||
setAnimation( subControl | A::Color, 100 );
|
||||
}
|
||||
|
|
|
@ -65,6 +65,19 @@ class QskSpinBox::PrivateData
|
|||
return this->repeatTimer.isActive() && ( this->key == Qt::Key_unknown );
|
||||
}
|
||||
|
||||
inline bool isTimerBlocked( QskSpinBox* spinBox, qreal offset ) const
|
||||
{
|
||||
if ( !this->wrapping )
|
||||
{
|
||||
if ( offset >= 0.0 )
|
||||
return spinBox->value() >= spinBox->maximum();
|
||||
else
|
||||
return spinBox->value() <= spinBox->minimum();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void setAutoRepeat( QskSpinBox* spinBox, qreal offset )
|
||||
{
|
||||
this->autoRepeatIncrement = offset;
|
||||
|
@ -278,7 +291,17 @@ void QskSpinBox::mousePressEvent( QMouseEvent* event )
|
|||
{
|
||||
if ( auto subcontrol = buttonAt( this, qskMousePosition( event ) ) )
|
||||
{
|
||||
if ( !m_data->repeatTimer.isActive() )
|
||||
bool acceptPress = !m_data->repeatTimer.isActive();
|
||||
|
||||
if ( acceptPress && !m_data->wrapping )
|
||||
{
|
||||
if ( subcontrol == QskSpinBox::DownPanel )
|
||||
acceptPress = value() > minimum();
|
||||
else
|
||||
acceptPress = value() < maximum();
|
||||
}
|
||||
|
||||
if ( acceptPress )
|
||||
{
|
||||
auto offset = stepSize();
|
||||
if ( event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) )
|
||||
|
@ -288,7 +311,9 @@ void QskSpinBox::mousePressEvent( QMouseEvent* event )
|
|||
offset = -offset;
|
||||
|
||||
increment( offset );
|
||||
m_data->setAutoRepeat( this, offset );
|
||||
|
||||
if ( !m_data->isTimerBlocked( this, offset ) )
|
||||
m_data->setAutoRepeat( this, offset );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -339,8 +364,11 @@ void QskSpinBox::keyPressEvent( QKeyEvent* event )
|
|||
{
|
||||
increment( offset );
|
||||
|
||||
m_data->setAutoRepeat( this, offset );
|
||||
m_data->key = event->key();
|
||||
if ( !m_data->isTimerBlocked( this, offset ) )
|
||||
{
|
||||
m_data->setAutoRepeat( this, offset );
|
||||
m_data->key = event->key();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -367,7 +395,11 @@ void QskSpinBox::timerEvent( QTimerEvent* event )
|
|||
if ( skinStates() & ( QskSpinBox::Increasing | QskSpinBox::Decreasing ) )
|
||||
{
|
||||
increment( m_data->autoRepeatIncrement );
|
||||
m_data->repeatTimer.start( m_data->autoRepeatInterval, this );
|
||||
|
||||
if ( m_data->isTimerBlocked( this, m_data->autoRepeatIncrement ) )
|
||||
m_data->setAutoRepeat( this, 0.0 );
|
||||
else
|
||||
m_data->repeatTimer.start( m_data->autoRepeatInterval, this );
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -91,7 +91,7 @@ class QSK_EXPORT QskSpinBox : public QskBoundedValueInput
|
|||
void decimalsChanged( int );
|
||||
void textChanged();
|
||||
|
||||
private:
|
||||
protected:
|
||||
void timerEvent( QTimerEvent* ) override;
|
||||
|
||||
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||
|
@ -102,6 +102,7 @@ class QSK_EXPORT QskSpinBox : public QskBoundedValueInput
|
|||
void keyPressEvent( QKeyEvent* ) override;
|
||||
void keyReleaseEvent( QKeyEvent* ) override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
|
|
@ -6,9 +6,36 @@
|
|||
#include "QskSpinBoxSkinlet.h"
|
||||
#include "QskSpinBox.h"
|
||||
#include "QskFunctions.h"
|
||||
#include "QskSkinStateChanger.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
|
||||
static inline QskAspect::States qskButtonStates(
|
||||
const QskSkinnable* skinnable, QskAspect::Subcontrol subControl )
|
||||
{
|
||||
using Q = QskSpinBox;
|
||||
|
||||
auto spinBox = static_cast< const QskSpinBox* >( skinnable );
|
||||
|
||||
auto states = spinBox->skinStates();
|
||||
|
||||
if ( spinBox->isEnabled() && !spinBox->isWrapping() )
|
||||
{
|
||||
if ( subControl == Q::DownIndicator || subControl == Q::DownPanel )
|
||||
{
|
||||
if ( spinBox->value() <= spinBox->minimum() )
|
||||
states |= QskControl::Disabled;
|
||||
}
|
||||
else if ( subControl == Q::UpIndicator || subControl == Q::UpPanel )
|
||||
{
|
||||
if ( spinBox->value() >= spinBox->maximum() )
|
||||
states |= QskControl::Disabled;
|
||||
}
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
QskSpinBoxSkinlet::QskSpinBoxSkinlet( QskSkin* )
|
||||
{
|
||||
setNodeRoles( { UpPanel, DownPanel, TextPanel,
|
||||
|
@ -20,6 +47,9 @@ QRectF QskSpinBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
|
|||
{
|
||||
using Q = QskSpinBox;
|
||||
|
||||
QskSkinStateChanger stateChanger( skinnable );
|
||||
stateChanger.setStates( qskButtonStates( skinnable, subControl ) );
|
||||
|
||||
if ( subControl == Q::DownIndicator )
|
||||
return skinnable->subControlContentsRect( contentsRect, Q::DownPanel );
|
||||
|
||||
|
@ -43,28 +73,40 @@ QSGNode* QskSpinBoxSkinlet::updateSubNode(
|
|||
{
|
||||
using Q = QskSpinBox;
|
||||
|
||||
QskSkinStateChanger stateChanger( skinnable );
|
||||
|
||||
switch( nodeRole )
|
||||
{
|
||||
case UpPanel:
|
||||
{
|
||||
stateChanger.setStates( qskButtonStates( skinnable, Q::UpPanel ) );
|
||||
return updateBoxNode( skinnable, node, Q::UpPanel );
|
||||
}
|
||||
|
||||
case DownPanel:
|
||||
{
|
||||
stateChanger.setStates( qskButtonStates( skinnable, Q::DownPanel ) );
|
||||
return updateBoxNode( skinnable, node, Q::DownPanel );
|
||||
}
|
||||
|
||||
case UpIndicator:
|
||||
{
|
||||
stateChanger.setStates( qskButtonStates( skinnable, Q::UpIndicator ) );
|
||||
return updateTextNode( skinnable, node,
|
||||
QStringLiteral( "+" ), Q::UpIndicator );
|
||||
}
|
||||
|
||||
case DownIndicator:
|
||||
{
|
||||
stateChanger.setStates( qskButtonStates( skinnable, Q::DownIndicator ) );
|
||||
return updateTextNode( skinnable, node,
|
||||
QStringLiteral( "-" ), Q::DownIndicator );
|
||||
}
|
||||
|
||||
case TextPanel:
|
||||
{
|
||||
return updateBoxNode( skinnable, node, Q::TextPanel );
|
||||
}
|
||||
|
||||
case Text:
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue