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 "QskPageIndicator.h"
|
2022-01-04 15:58:49 +01:00
|
|
|
#include "QskSkinlet.h"
|
|
|
|
#include "QskEvent.h"
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
QSK_SUBCONTROL( QskPageIndicator, Panel )
|
|
|
|
QSK_SUBCONTROL( QskPageIndicator, Bullet )
|
2022-01-04 13:58:34 +01:00
|
|
|
|
|
|
|
QSK_SYSTEM_STATE( QskPageIndicator, Selected, QskAspect::FirstSystemState << 1 )
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2022-01-04 15:58:49 +01:00
|
|
|
static void qskSetMouseAccepted( QskPageIndicator* indicator, bool on )
|
|
|
|
{
|
|
|
|
auto buttons = indicator->acceptedMouseButtons();
|
|
|
|
|
|
|
|
if ( on )
|
|
|
|
buttons |= Qt::LeftButton;
|
|
|
|
else
|
|
|
|
buttons &= ~Qt::LeftButton;
|
|
|
|
|
|
|
|
indicator->setAcceptedMouseButtons( buttons );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int qskKeyIncrement(
|
|
|
|
const QskPageIndicator* indicator, const QKeyEvent* event )
|
|
|
|
{
|
|
|
|
if ( event->matches( QKeySequence::MoveToNextChar ) )
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if ( event->matches( QKeySequence::MoveToPreviousChar ) )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
const auto key = event->key();
|
|
|
|
|
|
|
|
if ( indicator->orientation() == Qt::Horizontal )
|
|
|
|
{
|
|
|
|
const bool mirrored = indicator->layoutMirroring();
|
|
|
|
|
|
|
|
if ( key == Qt::Key_Left )
|
|
|
|
return mirrored ? 1 : -1;
|
|
|
|
|
|
|
|
if ( key == Qt::Key_Right )
|
|
|
|
return mirrored ? -1 : 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( key == Qt::Key_Up )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( key == Qt::Key_Down )
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
class QskPageIndicator::PrivateData
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
public:
|
|
|
|
PrivateData( int count )
|
|
|
|
: count( count )
|
2022-01-04 13:58:34 +01:00
|
|
|
, interactive( false )
|
2018-08-03 08:15:28 +02:00
|
|
|
, orientation( Qt::Horizontal )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-01-04 13:58:34 +01:00
|
|
|
qreal currentIndex = -1;
|
2022-01-04 15:58:49 +01:00
|
|
|
int pressedIndex = -1;
|
2022-01-04 13:58:34 +01:00
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
int count;
|
2022-01-04 13:58:34 +01:00
|
|
|
|
|
|
|
bool interactive : 1;
|
2017-07-21 18:21:34 +02:00
|
|
|
Qt::Orientation orientation : 2;
|
|
|
|
};
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskPageIndicator::QskPageIndicator( int count, QQuickItem* parent )
|
|
|
|
: Inherited( parent )
|
|
|
|
, m_data( new PrivateData( count ) )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
// as we don't stretch the bullets
|
2017-08-31 09:09:05 +02:00
|
|
|
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskPageIndicator::QskPageIndicator( QQuickItem* parent )
|
|
|
|
: QskPageIndicator( 0, parent )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskPageIndicator::~QskPageIndicator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskPageIndicator::count() const
|
|
|
|
{
|
|
|
|
return m_data->count;
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal QskPageIndicator::currentIndex() const
|
|
|
|
{
|
|
|
|
return m_data->currentIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
Qt::Orientation QskPageIndicator::orientation() const
|
|
|
|
{
|
|
|
|
return m_data->orientation;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::setOrientation( Qt::Orientation orientation )
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
if ( orientation != m_data->orientation )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
m_data->orientation = orientation;
|
|
|
|
|
|
|
|
resetImplicitSize();
|
|
|
|
update();
|
|
|
|
|
2020-12-17 16:14:56 +01:00
|
|
|
Q_EMIT orientationChanged( orientation );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 13:58:34 +01:00
|
|
|
bool QskPageIndicator::isInteractive() const
|
|
|
|
{
|
|
|
|
return m_data->interactive;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::setInteractive( bool on )
|
|
|
|
{
|
2022-01-04 15:58:49 +01:00
|
|
|
if ( on == m_data->interactive )
|
|
|
|
return;
|
2022-01-04 13:58:34 +01:00
|
|
|
|
2022-01-04 15:58:49 +01:00
|
|
|
m_data->interactive = on;
|
2022-01-04 13:58:34 +01:00
|
|
|
|
2022-01-04 15:58:49 +01:00
|
|
|
qskSetMouseAccepted( this, on );
|
|
|
|
setWheelEnabled( on );
|
|
|
|
setFocusPolicy( on ? Qt::StrongFocus : Qt::NoFocus );
|
|
|
|
|
|
|
|
// being interactive might have an impact on its representation
|
|
|
|
resetImplicitSize();
|
|
|
|
update();
|
|
|
|
|
|
|
|
Q_EMIT interactiveChanged( on );
|
2022-01-04 13:58:34 +01:00
|
|
|
}
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
void QskPageIndicator::setCount( int count )
|
|
|
|
{
|
|
|
|
if ( count != m_data->count )
|
|
|
|
{
|
|
|
|
m_data->count = count;
|
|
|
|
|
|
|
|
resetImplicitSize();
|
|
|
|
update();
|
|
|
|
|
2020-12-17 16:14:56 +01:00
|
|
|
Q_EMIT countChanged( count );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::setCurrentIndex( qreal index )
|
|
|
|
{
|
|
|
|
if ( index < 0 || index >= m_data->count )
|
|
|
|
index = -1;
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
if ( index != m_data->currentIndex )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
m_data->currentIndex = index;
|
|
|
|
update();
|
|
|
|
|
2020-12-17 16:14:56 +01:00
|
|
|
Q_EMIT currentIndexChanged( index );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 13:58:34 +01:00
|
|
|
qreal QskPageIndicator::valueRatioAt( int index ) const
|
|
|
|
{
|
|
|
|
if ( m_data->currentIndex >= 0.0 && index >= 0 )
|
|
|
|
{
|
|
|
|
qreal pos = m_data->currentIndex;
|
|
|
|
|
|
|
|
if ( index == 0 && pos > m_data->count - 1 )
|
|
|
|
pos -= m_data->count;
|
|
|
|
|
|
|
|
const qreal diff = 1.0 - std::abs( pos - index );
|
|
|
|
return std::max( diff, 0.0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2022-01-04 15:58:49 +01:00
|
|
|
QRectF QskPageIndicator::bulletRect( int index ) const
|
|
|
|
{
|
|
|
|
return effectiveSkinlet()->sampleRect(
|
|
|
|
this, contentsRect(), QskPageIndicator::Bullet, index );
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskPageIndicator::indexAtPosition( const QPointF& pos ) const
|
|
|
|
{
|
|
|
|
return effectiveSkinlet()->sampleIndexAt(
|
|
|
|
this, contentsRect(), QskPageIndicator::Bullet, pos );
|
|
|
|
}
|
|
|
|
|
2022-01-04 14:34:15 +01:00
|
|
|
QskAspect::Placement QskPageIndicator::effectivePlacement() const
|
|
|
|
{
|
|
|
|
return static_cast< QskAspect::Placement >( m_data->orientation );
|
|
|
|
}
|
|
|
|
|
2022-01-04 15:58:49 +01:00
|
|
|
void QskPageIndicator::mousePressEvent( QMouseEvent* event )
|
|
|
|
{
|
|
|
|
if ( event->button() == Qt::LeftButton )
|
|
|
|
{
|
|
|
|
const auto pos = qskMousePosition( event );
|
|
|
|
m_data->pressedIndex = indexAtPosition( pos );
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Inherited::mousePressEvent( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::mouseReleaseEvent( QMouseEvent* event )
|
|
|
|
{
|
|
|
|
if ( event->button() == Qt::LeftButton )
|
|
|
|
{
|
|
|
|
const auto index = m_data->pressedIndex;
|
|
|
|
m_data->pressedIndex = -1;
|
|
|
|
|
|
|
|
if ( index >= 0 )
|
|
|
|
{
|
|
|
|
const auto pos = qskMousePosition( event );
|
|
|
|
if ( indexAtPosition( pos ) == index )
|
|
|
|
Q_EMIT pageRequested( index );
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Inherited::mouseReleaseEvent( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::keyPressEvent( QKeyEvent* event )
|
|
|
|
{
|
|
|
|
if ( const int increment = qskKeyIncrement( this, event ) )
|
|
|
|
{
|
|
|
|
if ( const auto n = m_data->count )
|
|
|
|
{
|
|
|
|
int index = m_data->currentIndex;
|
|
|
|
if ( index < 0 && increment < 0 )
|
|
|
|
index = n;
|
|
|
|
|
|
|
|
// do we need an cycling on/off attribute, TODO ...
|
|
|
|
|
|
|
|
index = ( index + increment ) % n;
|
|
|
|
if ( index < 0 )
|
|
|
|
index += n;
|
|
|
|
|
|
|
|
Q_EMIT pageRequested( index );
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Inherited::keyPressEvent( event );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskPageIndicator::wheelEvent( QWheelEvent* event )
|
|
|
|
{
|
|
|
|
#if QT_VERSION < 0x050e00
|
|
|
|
const int delta = event->delta();
|
|
|
|
#else
|
|
|
|
const auto angleDelta = event->angleDelta();
|
|
|
|
|
|
|
|
const int delta = ( orientation() == Qt::Horizontal )
|
|
|
|
? angleDelta.x() : angleDelta.y();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Q_UNUSED( delta )
|
|
|
|
// TODO ...
|
|
|
|
}
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
#include "moc_QskPageIndicator.cpp"
|