QskMenu::Cursor animation added
This commit is contained in:
parent
1a0ea4a3c4
commit
78d39d242f
|
@ -303,6 +303,7 @@ void Editor::setupPopup()
|
||||||
|
|
||||||
void Editor::setupMenu()
|
void Editor::setupMenu()
|
||||||
{
|
{
|
||||||
|
using A = QskAspect;
|
||||||
using Q = QskMenu;
|
using Q = QskMenu;
|
||||||
|
|
||||||
const QColor c1( 78, 158, 38 );
|
const QColor c1( 78, 158, 38 );
|
||||||
|
@ -312,7 +313,7 @@ void Editor::setupMenu()
|
||||||
setVGradient( Q::Panel, c1, c2 );
|
setVGradient( Q::Panel, c1, c2 );
|
||||||
|
|
||||||
const bool isCascading = qskMaybeDesktopPlatform();
|
const bool isCascading = qskMaybeDesktopPlatform();
|
||||||
setFlagHint( Q::Panel | QskAspect::Style, isCascading );
|
setFlagHint( Q::Panel | A::Style, isCascading );
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
setPadding( Q::Separator, QMarginsF( 10, 0, 10, 0 ) );
|
setPadding( Q::Separator, QMarginsF( 10, 0, 10, 0 ) );
|
||||||
|
@ -329,10 +330,11 @@ void Editor::setupMenu()
|
||||||
setColor( Q::Text, QColor( 255, 255, 255 ) );
|
setColor( Q::Text, QColor( 255, 255, 255 ) );
|
||||||
setFontRole( Q::Text, QskSkin::SmallFont );
|
setFontRole( Q::Text, QskSkin::SmallFont );
|
||||||
|
|
||||||
setMetric( Q::Panel | QskAspect::Position, 0 );
|
setMetric( Q::Panel | A::Position, 0 );
|
||||||
setMetric( Q::Panel | QskAspect::Position | QskPopup::Closed, 1 );
|
setMetric( Q::Panel | A::Position | QskPopup::Closed, 1 );
|
||||||
|
|
||||||
setAnimation( Q::Panel | QskAspect::Metric, 200 );
|
setAnimation( Q::Panel | A::Metric, 150 );
|
||||||
|
setAnimation( Q::Cursor | A::Metric, 50, QEasingCurve::OutCubic );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTextLabel()
|
void Editor::setupTextLabel()
|
||||||
|
|
|
@ -36,7 +36,7 @@ class QskMenu::PrivateData
|
||||||
QskTextOptions textOptions;
|
QskTextOptions textOptions;
|
||||||
QPointF origin;
|
QPointF origin;
|
||||||
|
|
||||||
int currentIndex = 0;
|
int currentIndex = -1;
|
||||||
bool isPressed = false;
|
bool isPressed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -157,9 +157,13 @@ QskTextOptions QskMenu::textOptions() const
|
||||||
|
|
||||||
void QskMenu::setCurrentIndex( int index )
|
void QskMenu::setCurrentIndex( int index )
|
||||||
{
|
{
|
||||||
if( index >= 0 && index < count()
|
if( index < 0 || index >= count() )
|
||||||
&& ( index != m_data->currentIndex ) )
|
index = -1;
|
||||||
|
|
||||||
|
if( index != m_data->currentIndex )
|
||||||
{
|
{
|
||||||
|
setPositionHint( Cursor, index );
|
||||||
|
|
||||||
m_data->currentIndex = index;
|
m_data->currentIndex = index;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
|
@ -239,14 +243,29 @@ void QskMenu::wheelEvent( QWheelEvent* event )
|
||||||
|
|
||||||
void QskMenu::traverse( int steps )
|
void QskMenu::traverse( int steps )
|
||||||
{
|
{
|
||||||
auto& index = m_data->currentIndex;
|
if ( count() == 0 || ( steps % count() == 0 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto index = m_data->currentIndex + steps;
|
||||||
|
|
||||||
|
auto newIndex = index % count();
|
||||||
|
if ( newIndex < 0 )
|
||||||
|
newIndex += count();
|
||||||
|
|
||||||
|
if ( hasAnimationHint( Cursor | QskAspect::Metric ) )
|
||||||
|
{
|
||||||
|
// when cycling we want slide in
|
||||||
|
|
||||||
index = ( index + steps ) % count();
|
|
||||||
if ( index < 0 )
|
if ( index < 0 )
|
||||||
index += count();
|
setPositionHint( Cursor, count() );
|
||||||
|
|
||||||
update();
|
if ( index >= count() )
|
||||||
Q_EMIT currentIndexChanged( index );
|
setPositionHint( Cursor, -1 );
|
||||||
|
|
||||||
|
movePositionHint( Cursor, newIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentIndex( newIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskColorFilter QskMenu::graphicFilterAt( int index ) const
|
QskColorFilter QskMenu::graphicFilterAt( int index ) const
|
||||||
|
@ -288,6 +307,10 @@ void QskMenu::mouseReleaseEvent( QMouseEvent* event )
|
||||||
void QskMenu::aboutToShow()
|
void QskMenu::aboutToShow()
|
||||||
{
|
{
|
||||||
setGeometry( QRectF( m_data->origin, sizeConstraint() ) );
|
setGeometry( QRectF( m_data->origin, sizeConstraint() ) );
|
||||||
|
|
||||||
|
if ( m_data->currentIndex < 0 )
|
||||||
|
setCurrentIndex( 0 );
|
||||||
|
|
||||||
Inherited::aboutToShow();
|
Inherited::aboutToShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QskFunctions.h>
|
#include <QskFunctions.h>
|
||||||
#include <QskSkinStateChanger.h>
|
#include <QskSkinStateChanger.h>
|
||||||
#include <QskMargins.h>
|
#include <QskMargins.h>
|
||||||
|
#include <QskFunctions.h>
|
||||||
|
|
||||||
#include <qfontmetrics.h>
|
#include <qfontmetrics.h>
|
||||||
|
|
||||||
|
@ -222,20 +223,57 @@ QskMenuSkinlet::QskMenuSkinlet( QskSkin* skin )
|
||||||
appendNodeRoles( { PanelRole } );
|
appendNodeRoles( { PanelRole } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF QskMenuSkinlet::cursorRect(
|
||||||
|
const QskSkinnable* skinnable, const QRectF& contentsRect, int index ) const
|
||||||
|
{
|
||||||
|
const auto count = sampleCount( skinnable, QskMenu::Cell );
|
||||||
|
|
||||||
|
auto rect = sampleRect( skinnable, contentsRect,
|
||||||
|
QskMenu::Cell, qBound( 0, index, count ) );
|
||||||
|
|
||||||
|
if ( index < 0 )
|
||||||
|
rect.setBottom( rect.top() );
|
||||||
|
|
||||||
|
if ( index >= count )
|
||||||
|
rect.setTop( rect.bottom() );
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
QRectF QskMenuSkinlet::subControlRect(
|
QRectF QskMenuSkinlet::subControlRect(
|
||||||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||||
QskAspect::Subcontrol subControl ) const
|
QskAspect::Subcontrol subControl ) const
|
||||||
{
|
{
|
||||||
|
using Q = QskMenu;
|
||||||
|
|
||||||
const auto menu = static_cast< const QskMenu* >( skinnable );
|
const auto menu = static_cast< const QskMenu* >( skinnable );
|
||||||
|
|
||||||
if( subControl == QskMenu::Panel )
|
if( subControl == Q::Panel )
|
||||||
{
|
{
|
||||||
return contentsRect;
|
return contentsRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( subControl == QskMenu::Cursor )
|
if( subControl == Q::Cursor )
|
||||||
{
|
{
|
||||||
return menu->cellRect( menu->currentIndex() );
|
if ( menu->currentIndex() < 0 )
|
||||||
|
return QRectF();
|
||||||
|
|
||||||
|
const qreal pos = menu->positionHint( Q::Cursor );
|
||||||
|
|
||||||
|
const int pos1 = qFloor( pos );
|
||||||
|
const int pos2 = qCeil( pos );
|
||||||
|
|
||||||
|
auto rect = cursorRect( skinnable, contentsRect, pos1 );
|
||||||
|
|
||||||
|
if ( pos1 != pos2 )
|
||||||
|
{
|
||||||
|
const auto r = cursorRect( skinnable, contentsRect, pos2 );
|
||||||
|
|
||||||
|
const qreal ratio = ( pos - pos1 ) / ( pos2 - pos1 );
|
||||||
|
rect = qskInterpolatedRect( rect, r, ratio );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||||
|
|
|
@ -49,6 +49,8 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
|
||||||
QskAspect::Subcontrol, int index, QSGNode* ) const override;
|
QskAspect::Subcontrol, int index, QSGNode* ) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QRectF cursorRect( const QskSkinnable*, const QRectF&, int index ) const;
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue