Merge branch 'master' into features/menubutton
This commit is contained in:
commit
b273264629
|
@ -108,6 +108,6 @@ SpacesInSquareBrackets: true
|
|||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
UseCRLF: Always
|
||||
UseCRLF: true
|
||||
...
|
||||
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "ProgressBarPage.h"
|
||||
#include <QskProgressBar.h>
|
||||
|
||||
#include <QskAnimator.h>
|
||||
#include <QskGraphicProvider.h>
|
||||
#include <QskGraphic.h>
|
||||
#include <QskGradient.h>
|
||||
#include <QskHctColor.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskRgbValue.h>
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
namespace
|
||||
{
|
||||
class ProgressBar : public QskProgressBar
|
||||
|
@ -35,9 +40,32 @@ namespace
|
|||
colors += hctColor.toned( 45 ).rgb();
|
||||
colors += hctColor.toned( 30 ).rgb();
|
||||
|
||||
setBarGradient( qskBuildGradientStops( colors, true ) );
|
||||
setFillGradient( qskBuildGradientStops( colors, true ) );
|
||||
}
|
||||
};
|
||||
|
||||
class DeterminateIndicatorsAnimator : public QskAnimator
|
||||
{
|
||||
public:
|
||||
DeterminateIndicatorsAnimator( const QVector< QskProgressIndicator* >& indicators )
|
||||
: QskAnimator()
|
||||
, m_indicators( indicators )
|
||||
{
|
||||
setAutoRepeat( true );
|
||||
setDuration( 3000 );
|
||||
}
|
||||
|
||||
void advance( qreal value ) override
|
||||
{
|
||||
for( auto* indicator : m_indicators )
|
||||
{
|
||||
indicator->setValueAsRatio( value );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const QVector< QskProgressIndicator* > m_indicators;
|
||||
};
|
||||
}
|
||||
|
||||
ProgressBarPage::ProgressBarPage( QQuickItem* parent )
|
||||
|
@ -53,10 +81,7 @@ void ProgressBarPage::populate()
|
|||
hBox->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
||||
hBox->setSpacing( 20 );
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( hBox );
|
||||
bar->setValue( 35 );
|
||||
}
|
||||
QVector< QskProgressIndicator* > determinateIndicators;
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( hBox );
|
||||
|
@ -77,6 +102,11 @@ void ProgressBarPage::populate()
|
|||
bar->setValue( 25 );
|
||||
}
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( hBox );
|
||||
determinateIndicators.append( bar );
|
||||
}
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( hBox );
|
||||
bar->setIndeterminate( true );
|
||||
|
@ -106,8 +136,55 @@ void ProgressBarPage::populate()
|
|||
bar->setValue( 10 );
|
||||
}
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( vBox );
|
||||
determinateIndicators.append( bar );
|
||||
}
|
||||
|
||||
{
|
||||
auto bar = new ProgressBar( vBox );
|
||||
bar->setIndeterminate( true );
|
||||
}
|
||||
|
||||
const auto sizes = { QskProgressRing::SmallSize, QskProgressRing::NormalSize,
|
||||
QskProgressRing::LargeSize };
|
||||
|
||||
auto determinateRingsHBox = new QskLinearBox( Qt::Horizontal, vBox );
|
||||
|
||||
auto indeterminateRingsHBox = new QskLinearBox( Qt::Horizontal, vBox );
|
||||
|
||||
for( const auto size : sizes )
|
||||
{
|
||||
for( const auto indeterminate : { true, false } )
|
||||
{
|
||||
auto* ring = new QskProgressRing( determinateRingsHBox );
|
||||
ring->setSize( size );
|
||||
|
||||
QQuickItem* parentItem;
|
||||
|
||||
if( indeterminate )
|
||||
{
|
||||
parentItem = indeterminateRingsHBox;
|
||||
ring->setIndeterminate( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
parentItem = determinateRingsHBox;
|
||||
determinateIndicators.append( ring );
|
||||
}
|
||||
|
||||
ring->setParent( parentItem );
|
||||
ring->setParentItem( parentItem );
|
||||
}
|
||||
}
|
||||
|
||||
connect( this, &QskQuickItem::windowChanged, this, [this, determinateIndicators]( QQuickWindow* window )
|
||||
{
|
||||
if( window )
|
||||
{
|
||||
m_determinateIndicatorsAnimator.reset( new DeterminateIndicatorsAnimator( determinateIndicators ) );
|
||||
m_determinateIndicatorsAnimator->setWindow( window );
|
||||
m_determinateIndicatorsAnimator->start();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "Page.h"
|
||||
|
||||
class QskAnimator;
|
||||
|
||||
class ProgressBarPage : public Page
|
||||
{
|
||||
public:
|
||||
|
@ -14,4 +16,6 @@ class ProgressBarPage : public Page
|
|||
|
||||
private:
|
||||
void populate();
|
||||
|
||||
std::unique_ptr< QskAnimator > m_determinateIndicatorsAnimator;
|
||||
};
|
||||
|
|
|
@ -193,35 +193,6 @@ void Cube::switchToPosition( const Position position )
|
|||
doSwitch( direction, nextPosition );
|
||||
}
|
||||
|
||||
void Cube::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
Qsk::Direction direction;
|
||||
|
||||
switch( event->key() )
|
||||
{
|
||||
case Qt::Key_Up:
|
||||
direction = Qsk::TopToBottom;
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
direction = Qsk::BottomToTop;
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
direction = Qsk::LeftToRight;
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
direction = Qsk::RightToLeft;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switchPosition( direction );
|
||||
}
|
||||
|
||||
Cube::Position Cube::currentPosition() const
|
||||
{
|
||||
return static_cast< Position >( currentIndex() );
|
||||
|
@ -304,8 +275,6 @@ MainItem::MainItem( QQuickItem* parent )
|
|||
|
||||
// the current item needs to be the one at the Front:
|
||||
m_cube->setCurrentItem( dashboardPage );
|
||||
|
||||
installEventFilter( this );
|
||||
}
|
||||
|
||||
void MainItem::gestureEvent( QskGestureEvent* event )
|
||||
|
@ -332,33 +301,48 @@ void MainItem::gestureEvent( QskGestureEvent* event )
|
|||
}
|
||||
}
|
||||
|
||||
bool MainItem::eventFilter( QObject* object, QEvent* event )
|
||||
void MainItem::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
if ( event->type() == QEvent::KeyPress )
|
||||
{
|
||||
QCoreApplication::sendEvent( m_cube, event );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QObject::eventFilter( object, event );
|
||||
}
|
||||
}
|
||||
// maybe using shortcuts ?
|
||||
|
||||
bool MainItem::gestureFilter( QQuickItem* item, QEvent* event )
|
||||
Qsk::Direction direction;
|
||||
|
||||
switch( event->key() )
|
||||
{
|
||||
case Qt::Key_Up:
|
||||
direction = Qsk::TopToBottom;
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
direction = Qsk::BottomToTop;
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
direction = Qsk::LeftToRight;
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
direction = Qsk::RightToLeft;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
m_cube->switchPosition( direction );
|
||||
}
|
||||
bool MainItem::gestureFilter( const QQuickItem* item, const QEvent* event )
|
||||
{
|
||||
auto& recognizer = m_panRecognizer;
|
||||
|
||||
if( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
const auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
|
||||
if( ( item != this ) || ( recognizer.timeout() < 0 ) )
|
||||
{
|
||||
if( recognizer.hasProcessedBefore( mouseEvent ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
recognizer.setTimeout( ( item == this ) ? -1 : 100 );
|
||||
|
|
|
@ -40,22 +40,19 @@ class Cube : public QskStackBox
|
|||
explicit Cube( QQuickItem* parent = nullptr );
|
||||
|
||||
public Q_SLOTS:
|
||||
void switchPosition( const Qsk::Direction direction );
|
||||
void switchToPosition( const Cube::Position position );
|
||||
void switchPosition( const Qsk::Direction );
|
||||
void switchToPosition( const Cube::Position );
|
||||
|
||||
Q_SIGNALS:
|
||||
// might be different from indexChanged:
|
||||
void cubeIndexChanged( const int index );
|
||||
|
||||
protected:
|
||||
void keyPressEvent( QKeyEvent* event ) override;
|
||||
|
||||
private:
|
||||
Position currentPosition() const;
|
||||
Position neighbor( const Position position, const Qsk::Direction direction ) const;
|
||||
Position neighbor( const Position, const Qsk::Direction ) const;
|
||||
Qsk::Direction direction( const Position from, const Position to ) const;
|
||||
void updateEdge( Qsk::Direction direction, Position position );
|
||||
void doSwitch( Qsk::Direction direction, Position position );
|
||||
void updateEdge( Qsk::Direction, Position );
|
||||
void doSwitch( Qsk::Direction, Position );
|
||||
|
||||
Position m_destination;
|
||||
Edge m_currentEdge;
|
||||
|
@ -73,8 +70,9 @@ class MainItem : public QskControl
|
|||
MainItem( QQuickItem* parent = nullptr );
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override final;
|
||||
bool gestureFilter( QQuickItem*, QEvent* ) override final;
|
||||
void keyPressEvent( QKeyEvent* ) override final;
|
||||
|
||||
bool gestureFilter( const QQuickItem*, const QEvent* ) override final;
|
||||
void gestureEvent( QskGestureEvent* ) override final;
|
||||
|
||||
private:
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <QskBoxShapeMetrics.h>
|
||||
#include <QskColorFilter.h>
|
||||
#include <QskFunctions.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskShadowMetrics.h>
|
||||
#include <QskSkinHintTableEditor.h>
|
||||
#include <QskStateCombination.h>
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
#include "StoragePage.h"
|
||||
#include "Box.h"
|
||||
#include "CircularProgressBar.h"
|
||||
#include "Diagram.h"
|
||||
#include "EnergyMeter.h"
|
||||
#include "StorageBar.h"
|
||||
#include "StorageMeter.h"
|
||||
#include <QTimer>
|
||||
|
@ -17,7 +14,6 @@
|
|||
#include <QskGradient.h>
|
||||
#include <QskGradientStop.h>
|
||||
#include <QskGraphicLabel.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskSkin.h>
|
||||
#include <QskStackBox.h>
|
||||
|
|
|
@ -11,6 +11,7 @@ set(SOURCES
|
|||
LinearLayoutPage.h LinearLayoutPage.cpp
|
||||
DynamicConstraintsPage.h DynamicConstraintsPage.cpp
|
||||
StackLayoutPage.h StackLayoutPage.cpp
|
||||
SwipeViewPage.h SwipeViewPage.cpp
|
||||
main.cpp
|
||||
)
|
||||
qt_add_resources(SOURCES layouts.qrc)
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace
|
|||
|
||||
void incrementScrolling( Qt::Orientation orientation, int offset )
|
||||
{
|
||||
auto animator = dynamic_cast< QskStackBoxAnimator1* >( this->animator() );
|
||||
auto animator = qobject_cast< QskStackBoxAnimator1* >( this->animator() );
|
||||
|
||||
if ( animator == nullptr )
|
||||
{
|
||||
|
@ -109,7 +109,11 @@ namespace
|
|||
animator->setDuration( 1000 );
|
||||
}
|
||||
|
||||
animator->setOrientation( orientation );
|
||||
if ( orientation == Qt::Horizontal )
|
||||
animator->setDirection( offset > 0 ? Qsk::LeftToRight : Qsk::RightToLeft );
|
||||
else
|
||||
animator->setDirection( offset > 0 ? Qsk::TopToBottom : Qsk::BottomToTop );
|
||||
|
||||
setAnimator( animator );
|
||||
|
||||
setCurrentIndex( incrementedIndex( offset ) );
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SwipeViewPage.h"
|
||||
#include "TestRectangle.h"
|
||||
|
||||
#include <QskRgbValue.h>
|
||||
#include <QskSwipeView.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
class SwipeView : public QskSwipeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SwipeView( QQuickItem* parent = nullptr )
|
||||
: QskSwipeView( parent )
|
||||
{
|
||||
setObjectName( "SwipeView" );
|
||||
|
||||
setBackgroundColor( Qt::white );
|
||||
setDefaultAlignment( Qt::AlignCenter );
|
||||
setOrientation( Qt::Horizontal );
|
||||
|
||||
addRectangle( "Gold" );
|
||||
addRectangle( "SeaGreen" );
|
||||
addRectangle( "SlateBlue" );
|
||||
addRectangle( "Peru" );
|
||||
|
||||
for ( int i = 0; i < itemCount(); i += 2 )
|
||||
{
|
||||
if ( auto control = qskControlCast( itemAtIndex( i ) ) )
|
||||
control->setFixedSize( 200, 200 );
|
||||
}
|
||||
}
|
||||
private:
|
||||
void addRectangle( const char* colorName )
|
||||
{
|
||||
auto rect = new TestRectangle( colorName );
|
||||
rect->setText( QString::number( itemCount() + 1 ) );
|
||||
addItem( rect );
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
SwipeViewPage::SwipeViewPage( QQuickItem* parent )
|
||||
: QskLinearBox( Qt::Vertical, parent )
|
||||
{
|
||||
setObjectName( "SwipeViewPage" );
|
||||
|
||||
setMargins( 10 );
|
||||
setBackgroundColor( QskRgb::LightSteelBlue );
|
||||
|
||||
auto swipeView = new SwipeView();
|
||||
addItem( swipeView );
|
||||
}
|
||||
|
||||
#include "SwipeViewPage.moc"
|
|
@ -0,0 +1,14 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskLinearBox.h>
|
||||
|
||||
class SwipeViewPage : public QskLinearBox
|
||||
{
|
||||
public:
|
||||
SwipeViewPage( QQuickItem* parent = nullptr );
|
||||
};
|
|
@ -8,6 +8,7 @@
|
|||
#include "LinearLayoutPage.h"
|
||||
#include "GridLayoutPage.h"
|
||||
#include "StackLayoutPage.h"
|
||||
#include "SwipeViewPage.h"
|
||||
#include "TestRectangle.h"
|
||||
|
||||
#include <SkinnyShortcut.h>
|
||||
|
@ -37,7 +38,8 @@ namespace
|
|||
addTab( "Linear Layout", new LinearLayoutPage() );
|
||||
addTab( "Dynamic\nConstraints", new DynamicConstraintsPage() );
|
||||
addTab( "Stack Layout", new StackLayoutPage() );
|
||||
|
||||
addTab( "Swipe View", new SwipeViewPage() );
|
||||
|
||||
setCurrentIndex( 0 );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -79,6 +79,17 @@ class Thumbnail : public QskPushButton
|
|||
setStrutSizeHint( QskPushButton::Icon, -1, -1 );
|
||||
}
|
||||
|
||||
#if 0
|
||||
void mousePressEvent( QMouseEvent* event ) override
|
||||
{
|
||||
/*
|
||||
rgnore events: to check if the pae gesture recoognizer of the scroll
|
||||
area becomes active without timeout ( see QskScrollBox::mousePressEvent )
|
||||
*/
|
||||
event->setAccepted( false );
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
QskGraphic thumbnailGraphic( const QColor& color,
|
||||
int shape, const QSizeF& size ) const
|
||||
|
|
|
@ -105,6 +105,6 @@ inline void ChartSample::setSample(
|
|||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
class QDebug;
|
||||
QSK_EXPORT QDebug operator<<( QDebug, const ChartSample& );
|
||||
QDebug operator<<( QDebug, const ChartSample& );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <QskPlacementPolicy.h>
|
||||
#include <QskPopup.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskRadioBox.h>
|
||||
#include <QskScrollArea.h>
|
||||
|
@ -220,6 +221,7 @@ void QskQml::registerTypes()
|
|||
registerObject< QskFocusIndicator >();
|
||||
registerObject< QskSeparator >();
|
||||
registerObject< QskProgressBar >();
|
||||
registerObject< QskProgressRing >();
|
||||
registerObject< QskPushButton >();
|
||||
registerObject< QskScrollView >();
|
||||
registerObject< QskScrollArea >();
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include <QskCheckBox.h>
|
||||
#include <QskComboBox.h>
|
||||
#include <QskDialogButtonBox.h>
|
||||
#include <QskDrawer.h>
|
||||
#include <QskFocusIndicator.h>
|
||||
#include <QskGraphicLabel.h>
|
||||
#include <QskListView.h>
|
||||
|
@ -80,6 +81,7 @@
|
|||
#include <QskPageIndicator.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskRadioBox.h>
|
||||
#include <QskScrollView.h>
|
||||
#include <QskSegmentedBar.h>
|
||||
|
@ -194,6 +196,9 @@ namespace
|
|||
void setupDialogButtonBoxMetrics();
|
||||
void setupDialogButtonBoxColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
void setupDrawerMetrics();
|
||||
void setupDrawerColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
void setupFocusIndicatorMetrics();
|
||||
void setupFocusIndicatorColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
|
@ -212,6 +217,9 @@ namespace
|
|||
void setupProgressBarMetrics();
|
||||
void setupProgressBarColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
void setupProgressRingMetrics();
|
||||
void setupProgressRingColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
void setupPushButtonMetrics();
|
||||
void setupPushButtonColors( QskAspect::Section, const QskFluent2Theme& );
|
||||
|
||||
|
@ -285,12 +293,14 @@ void Editor::setupMetrics()
|
|||
setupCheckBoxMetrics();
|
||||
setupComboBoxMetrics();
|
||||
setupDialogButtonBoxMetrics();
|
||||
setupDrawerMetrics();
|
||||
setupFocusIndicatorMetrics();
|
||||
setupGraphicLabelMetrics();
|
||||
setupListViewMetrics();
|
||||
setupMenuMetrics();
|
||||
setupPageIndicatorMetrics();
|
||||
setupProgressBarMetrics();
|
||||
setupProgressRingMetrics();
|
||||
setupPushButtonMetrics();
|
||||
setupRadioBoxMetrics();
|
||||
setupScrollViewMetrics();
|
||||
|
@ -320,6 +330,7 @@ void Editor::setupColors( QskAspect::Section section, const QskFluent2Theme& the
|
|||
setupCheckBoxColors( section, theme );
|
||||
setupComboBoxColors( section, theme );
|
||||
setupDialogButtonBoxColors( section, theme );
|
||||
setupDrawerColors( section, theme );
|
||||
setupFocusIndicatorColors( section, theme );
|
||||
setupGraphicLabelColors( section, theme );
|
||||
setupGraphicLabelMetrics();
|
||||
|
@ -327,6 +338,7 @@ void Editor::setupColors( QskAspect::Section section, const QskFluent2Theme& the
|
|||
setupMenuColors( section, theme );
|
||||
setupPageIndicatorColors( section, theme );
|
||||
setupProgressBarColors( section, theme );
|
||||
setupProgressRingColors( section, theme );
|
||||
setupPushButtonColors( section, theme );
|
||||
setupRadioBoxColors( section, theme );
|
||||
setupScrollViewColors( section, theme );
|
||||
|
@ -591,6 +603,26 @@ void Editor::setupDialogButtonBoxColors(
|
|||
theme.palette.background.solid.base );
|
||||
}
|
||||
|
||||
void Editor::setupDrawerMetrics()
|
||||
{
|
||||
using Q = QskDrawer;
|
||||
|
||||
setPadding( Q::Panel, 5 );
|
||||
setHint( Q::Overlay | QskAspect::Style, false );
|
||||
|
||||
#if 1
|
||||
setAnimation( Q::Panel | QskAspect::Position, 200 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Editor::setupDrawerColors(
|
||||
QskAspect::Section section, const QskFluent2Theme& theme )
|
||||
{
|
||||
using Q = QskDrawer;
|
||||
|
||||
setGradient( Q::Panel | section, theme.palette.background.solid.base );
|
||||
}
|
||||
|
||||
void Editor::setupFocusIndicatorMetrics()
|
||||
{
|
||||
using Q = QskFocusIndicator;
|
||||
|
@ -612,8 +644,10 @@ void Editor::setupFocusIndicatorColors(
|
|||
void Editor::setupListViewMetrics()
|
||||
{
|
||||
using Q = QskListView;
|
||||
using A = QskAspect;
|
||||
|
||||
setBoxBorderMetrics( Q::Cell | Q::Selected, { 3, 0, 0, 0 } );
|
||||
for ( auto state : { A::NoState, Q::Hovered, Q::Pressed } )
|
||||
setBoxBorderMetrics( Q::Cell | state | Q::Selected, { 3, 0, 0, 0 } );
|
||||
#if 1
|
||||
// taken from M3 - what are the actual values, TODO ...
|
||||
setPadding( Q::Cell, { 16, 12, 16, 12 } );
|
||||
|
@ -637,7 +671,7 @@ void Editor::setupListViewColors(
|
|||
textColor = pal.fillColor.text.disabled;
|
||||
indicatorColor = pal.fillColor.accent.disabled;
|
||||
}
|
||||
if ( state1 == Q::Pressed )
|
||||
else if ( state1 == Q::Pressed )
|
||||
{
|
||||
textColor = pal.fillColor.text.secondary;
|
||||
indicatorColor = pal.fillColor.accent.defaultColor;
|
||||
|
@ -673,7 +707,7 @@ void Editor::setupListViewColors(
|
|||
const auto text = Q::Text | section | state1 | state2;
|
||||
|
||||
setGradient( cell, cellColor );
|
||||
|
||||
|
||||
{
|
||||
/*
|
||||
We are using a section of the left border to display a
|
||||
|
@ -693,6 +727,9 @@ void Editor::setupListViewColors(
|
|||
setColor( text, textColor );
|
||||
}
|
||||
}
|
||||
|
||||
setAnimation( Q::Cell | A::Color, 100 );
|
||||
setAnimation( Q::Text | A::Color, 100 );
|
||||
}
|
||||
|
||||
void Editor::setupMenuMetrics()
|
||||
|
@ -834,8 +871,8 @@ void Editor::setupProgressBarMetrics()
|
|||
setMetric( Q::Groove | A::Size, 1 );
|
||||
setBoxShape( Q::Groove, 100, Qt::RelativeSize );
|
||||
|
||||
setMetric( Q::Bar | A::Size, 3 );
|
||||
setBoxShape( Q::Bar, 100, Qt::RelativeSize );
|
||||
setMetric( Q::Fill | A::Size, 3 );
|
||||
setBoxShape( Q::Fill, 100, Qt::RelativeSize );
|
||||
}
|
||||
|
||||
void Editor::setupProgressBarColors(
|
||||
|
@ -846,7 +883,36 @@ void Editor::setupProgressBarColors(
|
|||
const auto& pal = theme.palette;
|
||||
|
||||
setGradient( Q::Groove | section, pal.strokeColor.controlStrong.defaultColor );
|
||||
setGradient( Q::Bar | section, pal.fillColor.accent.defaultColor );
|
||||
setGradient( Q::Fill | section, pal.fillColor.accent.defaultColor );
|
||||
}
|
||||
|
||||
void Editor::setupProgressRingMetrics()
|
||||
{
|
||||
using Q = QskProgressRing;
|
||||
using A = QskAspect;
|
||||
|
||||
static constexpr QskAspect::Variation SmallSize = A::Small;
|
||||
static constexpr QskAspect::Variation NormalSize = A::NoVariation;
|
||||
static constexpr QskAspect::Variation LargeSize = A::Large;
|
||||
|
||||
setStrutSize( Q::Fill | SmallSize, { 16, 16 } );
|
||||
setStrutSize( Q::Fill | NormalSize, { 32, 32 } );
|
||||
setStrutSize( Q::Fill | LargeSize, { 64, 64 } );
|
||||
|
||||
const auto startAngle = 90, spanAngle = -360;
|
||||
setArcMetrics( Q::Fill | SmallSize, startAngle, spanAngle, 1.5 );
|
||||
setArcMetrics( Q::Fill | NormalSize, startAngle, spanAngle, 3 );
|
||||
setArcMetrics( Q::Fill | LargeSize, startAngle, spanAngle, 6 );
|
||||
}
|
||||
|
||||
void Editor::setupProgressRingColors(
|
||||
QskAspect::Section section, const QskFluent2Theme& theme )
|
||||
{
|
||||
using Q = QskProgressRing;
|
||||
|
||||
const auto& pal = theme.palette;
|
||||
|
||||
setGradient( Q::Fill | section, pal.fillColor.accent.defaultColor );
|
||||
}
|
||||
|
||||
void Editor::setupPushButtonMetrics()
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <QskPageIndicator.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskRadioBox.h>
|
||||
#include <QskScrollView.h>
|
||||
#include <QskSegmentedBar.h>
|
||||
|
@ -94,6 +95,7 @@ namespace
|
|||
void setupPageIndicator();
|
||||
void setupPopup();
|
||||
void setupProgressBar();
|
||||
void setupProgressRing();
|
||||
void setupRadioBox();
|
||||
void setupPushButton();
|
||||
void setupScrollView();
|
||||
|
@ -161,6 +163,7 @@ void Editor::setup()
|
|||
setupPageIndicator();
|
||||
setupPopup();
|
||||
setupProgressBar();
|
||||
setupProgressRing();
|
||||
setupPushButton();
|
||||
setupRadioBox();
|
||||
setupScrollView();
|
||||
|
@ -431,9 +434,9 @@ void Editor::setupProgressBar()
|
|||
using A = QskAspect;
|
||||
using Q = QskProgressBar;
|
||||
|
||||
auto size = 5_dp;
|
||||
auto size = 4_dp;
|
||||
|
||||
for ( auto subControl : { Q::Groove, Q::Bar } )
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
setMetric( subControl | A::Size, size );
|
||||
setPadding( subControl, 0 );
|
||||
|
@ -443,12 +446,21 @@ void Editor::setupProgressBar()
|
|||
}
|
||||
|
||||
setMetric( Q::Groove | A::Size, size );
|
||||
setGradient( Q::Groove, m_pal.primaryContainer );
|
||||
setGradient( Q::Groove, m_pal.surfaceContainerHighest );
|
||||
|
||||
setGradient( Q::Groove | Q::Disabled, m_pal.onSurface12 );
|
||||
|
||||
setGradient( Q::Bar, m_pal.primary );
|
||||
setGradient( Q::Bar | Q::Disabled, m_pal.onSurface38 );
|
||||
setGradient( Q::Fill, m_pal.primary );
|
||||
setGradient( Q::Fill | Q::Disabled, m_pal.onSurface38 );
|
||||
}
|
||||
|
||||
void Editor::setupProgressRing()
|
||||
{
|
||||
using Q = QskProgressRing;
|
||||
|
||||
setStrutSize( Q::Fill, { 48_dp, 48_dp } );
|
||||
setGradient( Q::Fill, m_pal.primary );
|
||||
setArcMetrics( Q::Fill, 90, -360, 4_dp );
|
||||
}
|
||||
|
||||
void Editor::setupRadioBox()
|
||||
|
@ -538,7 +550,7 @@ void Editor::setupSegmentedBar()
|
|||
|
||||
setGradient( Q::Segment | Q::Selected | Q::Hovered,
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.hoverOpacity ) );
|
||||
|
||||
|
||||
setGradient( Q::Segment | Q::Selected | Q::Focused,
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.focusOpacity ) );
|
||||
|
||||
|
@ -800,8 +812,9 @@ void Editor::setupDrawer()
|
|||
|
||||
setPadding( Q::Panel, 5_dp );
|
||||
setGradient( Q::Panel, m_pal.background );
|
||||
setAnimation( Q::Panel | QskAspect::Position, qskDuration );
|
||||
setHint( Q::Overlay | QskAspect::Style, false );
|
||||
|
||||
setAnimation( Q::Panel | QskAspect::Position, qskDuration );
|
||||
}
|
||||
|
||||
void Editor::setupSlider()
|
||||
|
@ -1151,15 +1164,71 @@ void Editor::setupScrollView()
|
|||
void Editor::setupListView()
|
||||
{
|
||||
using Q = QskListView;
|
||||
using A = QskAspect;
|
||||
|
||||
setStrutSize( Q::Cell, { -1, 56 } );
|
||||
setPadding( Q::Cell, { 16_dp, 12_dp, 16_dp, 12_dp } );
|
||||
setStrutSize( Q::Cell, { -1, 56_dp } );
|
||||
setPadding( Q::Cell, { 16_dp, 8_dp, 24_dp, 8_dp } );
|
||||
|
||||
setBoxBorderColors( Q::Cell, m_pal.outline );
|
||||
setGradient( Q::Cell, m_pal.surface );
|
||||
setGradient( Q::Cell | Q::Selected, m_pal.primary12 );
|
||||
|
||||
for ( const auto state1 : { A::NoState, Q::Hovered, Q::Focused, Q::Pressed, Q::Disabled } )
|
||||
{
|
||||
for ( const auto state2 : { A::NoState, Q::Selected } )
|
||||
{
|
||||
QRgb cellColor;
|
||||
|
||||
if ( state2 == A::NoState )
|
||||
{
|
||||
if ( state1 == Q::Hovered )
|
||||
{
|
||||
cellColor = flattenedColor( m_pal.onSurface,
|
||||
m_pal.surface, m_pal.hoverOpacity );
|
||||
}
|
||||
else if ( state1 == Q::Pressed )
|
||||
{
|
||||
cellColor = flattenedColor( m_pal.onSurface,
|
||||
m_pal.primary12, m_pal.pressedOpacity );
|
||||
}
|
||||
else
|
||||
{
|
||||
cellColor = m_pal.surface;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( state1 == Q::Hovered )
|
||||
{
|
||||
cellColor = flattenedColor( m_pal.onSurface,
|
||||
m_pal.primary12, m_pal.focusOpacity );
|
||||
}
|
||||
else if ( state1 == Q::Focused )
|
||||
{
|
||||
cellColor = flattenedColor( m_pal.onSurface,
|
||||
m_pal.primary12, m_pal.focusOpacity );
|
||||
}
|
||||
else if ( state1 == Q::Disabled )
|
||||
{
|
||||
cellColor = m_pal.surfaceVariant;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellColor = m_pal.primary12;
|
||||
}
|
||||
}
|
||||
|
||||
setGradient( Q::Cell | state1 | state2, cellColor );
|
||||
}
|
||||
}
|
||||
|
||||
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
||||
|
||||
setColor( Q::Text, m_pal.onSurface );
|
||||
setColor( Q::Text | Q::Disabled, m_pal.onSurface38 );
|
||||
|
||||
#if 1
|
||||
setAnimation( Q::Cell | A::Color, 100 );
|
||||
setAnimation( Q::Text | A::Color, 100 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Editor::setupSubWindow()
|
||||
|
@ -1246,6 +1315,8 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme,
|
|||
outline = m_palettes[ NeutralVariant ].toned( 50 ).rgb();
|
||||
outlineVariant = m_palettes[ NeutralVariant ].toned( 80 ).rgb();
|
||||
|
||||
surfaceContainerHighest = m_palettes[ NeutralVariant ].toned( 90 ).rgb();
|
||||
|
||||
shadow = m_palettes[ Neutral ].toned( 0 ).rgb();
|
||||
}
|
||||
else if ( colorScheme == QskSkin::DarkScheme )
|
||||
|
@ -1280,6 +1351,8 @@ QskMaterial3Theme::QskMaterial3Theme( QskSkin::ColorScheme colorScheme,
|
|||
outline = m_palettes[ NeutralVariant ].toned( 60 ).rgb();
|
||||
outlineVariant = m_palettes[ NeutralVariant ].toned( 30 ).rgb();
|
||||
|
||||
surfaceContainerHighest = m_palettes[ NeutralVariant ].toned( 22 ).rgb();
|
||||
|
||||
shadow = m_palettes[ Neutral ].toned( 0 ).rgb();
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ class QSK_MATERIAL3_EXPORT QskMaterial3Theme
|
|||
QRgb outline;
|
||||
QRgb outlineVariant;
|
||||
|
||||
QRgb surfaceContainerHighest;
|
||||
|
||||
QRgb shadow;
|
||||
|
||||
QskShadowMetrics elevation0;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <QskPageIndicator.h>
|
||||
#include <QskPopup.h>
|
||||
#include <QskProgressBar.h>
|
||||
#include <QskProgressRing.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskRadioBox.h>
|
||||
#include <QskScrollView.h>
|
||||
|
@ -162,6 +163,7 @@ namespace
|
|||
void setupPageIndicator();
|
||||
void setupPopup();
|
||||
void setupProgressBar();
|
||||
void setupProgressRing();
|
||||
void setupPushButton();
|
||||
void setupRadioBox();
|
||||
void setupScrollView();
|
||||
|
@ -287,6 +289,7 @@ void Editor::setup()
|
|||
setupPageIndicator();
|
||||
setupPopup();
|
||||
setupProgressBar();
|
||||
setupProgressRing();
|
||||
setupPushButton();
|
||||
setupRadioBox();
|
||||
setupScrollView();
|
||||
|
@ -521,15 +524,35 @@ void Editor::setupProgressBar()
|
|||
using A = QskAspect;
|
||||
using Q = QskProgressBar;
|
||||
|
||||
for ( auto subControl : { Q::Groove, Q::Bar } )
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
setMetric( subControl | A::Size, 6 );
|
||||
setPadding( subControl, 0 );
|
||||
setBoxShape( subControl, 4 );
|
||||
}
|
||||
|
||||
setGradient( Q::Groove, m_pal.darker200 );
|
||||
setGradient( Q::Bar, m_pal.highlighted );
|
||||
setGradient( Q::Groove, m_pal.lighter110 );
|
||||
setGradient( Q::Fill, m_pal.highlighted );
|
||||
}
|
||||
|
||||
void Editor::setupProgressRing()
|
||||
{
|
||||
using A = QskAspect;
|
||||
using Q = QskProgressRing;
|
||||
|
||||
for ( auto subControl : { Q::Groove, Q::Fill } )
|
||||
{
|
||||
setMetric( subControl | A::Size, 6 );
|
||||
setPadding( subControl, 0 );
|
||||
setBoxShape( subControl, 4 );
|
||||
}
|
||||
|
||||
setArcMetrics( Q::Groove, 90, -360, 6 );
|
||||
setGradient( Q::Groove, m_pal.lighter110 );
|
||||
|
||||
setStrutSize( Q::Fill, { 60, 60 } );
|
||||
setGradient( Q::Fill, m_pal.highlighted );
|
||||
setArcMetrics( Q::Fill, 90, -360, 6 );
|
||||
}
|
||||
|
||||
void Editor::setupFocusIndicator()
|
||||
|
@ -1054,15 +1077,13 @@ void Editor::setupListView()
|
|||
setPadding( Q::Cell, QskMargins( 4, 8 ) );
|
||||
|
||||
setColor( Q::Text, m_pal.themeForeground );
|
||||
setColor( Q::Cell, Qt::white );
|
||||
|
||||
// alternating row colors
|
||||
setColor( Q::Cell | A::Lower, Qt::white );
|
||||
setColor( Q::Cell | Q::Selected | A::Lower, m_pal.highlighted );
|
||||
|
||||
setColor( Q::Cell | A::Upper, m_pal.contrasted );
|
||||
setColor( Q::Cell | Q::Selected | A::Upper, m_pal.highlighted );
|
||||
|
||||
setColor( Q::Text | Q::Selected, m_pal.highlightedText );
|
||||
for ( auto state : { A::NoState, Q::Hovered, Q::Pressed } )
|
||||
{
|
||||
setColor( Q::Cell | state | Q::Selected, m_pal.highlighted );
|
||||
setColor( Q::Text | state | Q::Selected, m_pal.highlightedText );
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::setupSubWindow()
|
||||
|
|
|
@ -197,10 +197,14 @@ list(APPEND HEADERS
|
|||
controls/QskPanGestureRecognizer.h
|
||||
controls/QskPopup.h
|
||||
controls/QskPopupSkinlet.h
|
||||
controls/QskPushButton.h
|
||||
controls/QskPushButtonSkinlet.h
|
||||
controls/QskProgressBar.h
|
||||
controls/QskProgressBarSkinlet.h
|
||||
controls/QskProgressIndicator.h
|
||||
controls/QskProgressIndicatorSkinlet.h
|
||||
controls/QskProgressRing.h
|
||||
controls/QskProgressRingSkinlet.h
|
||||
controls/QskPushButton.h
|
||||
controls/QskPushButtonSkinlet.h
|
||||
controls/QskQuick.h
|
||||
controls/QskQuickItem.h
|
||||
controls/QskRadioBox.h
|
||||
|
@ -237,6 +241,7 @@ list(APPEND HEADERS
|
|||
controls/QskSubWindowSkinlet.h
|
||||
controls/QskSwitchButton.h
|
||||
controls/QskSwitchButtonSkinlet.h
|
||||
controls/QskSwipeView.h
|
||||
controls/QskTabBar.h
|
||||
controls/QskTabButton.h
|
||||
controls/QskTabButtonSkinlet.h
|
||||
|
@ -296,10 +301,14 @@ list(APPEND SOURCES
|
|||
controls/QskPanGestureRecognizer.cpp
|
||||
controls/QskPopup.cpp
|
||||
controls/QskPopupSkinlet.cpp
|
||||
controls/QskPushButton.cpp
|
||||
controls/QskPushButtonSkinlet.cpp
|
||||
controls/QskProgressBar.cpp
|
||||
controls/QskProgressBarSkinlet.cpp
|
||||
controls/QskProgressIndicator.cpp
|
||||
controls/QskProgressIndicatorSkinlet.cpp
|
||||
controls/QskProgressRing.cpp
|
||||
controls/QskProgressRingSkinlet.cpp
|
||||
controls/QskPushButton.cpp
|
||||
controls/QskPushButtonSkinlet.cpp
|
||||
controls/QskQuick.cpp
|
||||
controls/QskQuickItem.cpp
|
||||
controls/QskQuickItemPrivate.cpp
|
||||
|
@ -336,6 +345,7 @@ list(APPEND SOURCES
|
|||
controls/QskSubWindowSkinlet.cpp
|
||||
controls/QskSwitchButton.cpp
|
||||
controls/QskSwitchButtonSkinlet.cpp
|
||||
controls/QskSwipeView.cpp
|
||||
controls/QskTabBar.cpp
|
||||
controls/QskTabButton.cpp
|
||||
controls/QskTabButtonSkinlet.cpp
|
||||
|
|
|
@ -31,6 +31,20 @@ static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
|||
QCoreApplication::sendEvent( object, &event );
|
||||
}
|
||||
|
||||
static inline bool qskMaybeGesture( QQuickItem* item,
|
||||
const QQuickItem* child, const QEvent* event )
|
||||
{
|
||||
if ( qskIsTouchOrMouseEvent( event->type() ) )
|
||||
{
|
||||
QskGestureFilterEvent ev( child, event );
|
||||
QCoreApplication::sendEvent( item, &ev );
|
||||
|
||||
return ev.maybeGesture();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QskControl::QskControl( QQuickItem* parent )
|
||||
: QskQuickItem( *( new QskControlPrivate() ), parent )
|
||||
{
|
||||
|
@ -791,6 +805,33 @@ bool QskControl::event( QEvent* event )
|
|||
|
||||
break;
|
||||
}
|
||||
case QskEvent::GestureFilter:
|
||||
{
|
||||
/*
|
||||
qskMaybeGesture is sending an event, so that it can be manipulated
|
||||
by event filters. F.e QskDrawer wants to add a gesture to
|
||||
some other control to initiate its appearance.
|
||||
*/
|
||||
|
||||
auto ev = static_cast< QskGestureFilterEvent* >( event );
|
||||
|
||||
if ( ev->event()->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( ev->event() );
|
||||
const auto pos =
|
||||
mapFromItem( ev->item(), qskMousePosition( mouseEvent ) );
|
||||
|
||||
if ( !gestureRect().contains( pos ) )
|
||||
{
|
||||
ev->setMaybeGesture( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ev->setMaybeGesture( gestureFilter( ev->item(), ev->event() ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case QskEvent::Gesture:
|
||||
{
|
||||
gestureEvent( static_cast< QskGestureEvent* >( event ) );
|
||||
|
@ -798,18 +839,18 @@ bool QskControl::event( QEvent* event )
|
|||
}
|
||||
}
|
||||
|
||||
if ( d_func()->maybeGesture( this, event ) )
|
||||
if ( qskMaybeGesture( this, this, event ) )
|
||||
return true;
|
||||
|
||||
return Inherited::event( event );
|
||||
}
|
||||
|
||||
bool QskControl::childMouseEventFilter( QQuickItem* item, QEvent* event )
|
||||
bool QskControl::childMouseEventFilter( QQuickItem* child, QEvent* event )
|
||||
{
|
||||
return d_func()->maybeGesture( item, event );
|
||||
return qskMaybeGesture( this, child, event );
|
||||
}
|
||||
|
||||
bool QskControl::gestureFilter( QQuickItem*, QEvent* )
|
||||
bool QskControl::gestureFilter( const QQuickItem*, const QEvent* )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
|
|||
void hoverLeaveEvent( QHoverEvent* ) override;
|
||||
|
||||
bool childMouseEventFilter( QQuickItem*, QEvent* ) override;
|
||||
virtual bool gestureFilter( QQuickItem*, QEvent* );
|
||||
virtual bool gestureFilter( const QQuickItem*, const QEvent* );
|
||||
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
void geometryChange( const QRectF&, const QRectF& ) override;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "QskLayoutMetrics.h"
|
||||
#include "QskObjectTree.h"
|
||||
#include "QskWindow.h"
|
||||
#include "QskEvent.h"
|
||||
|
||||
static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
||||
{
|
||||
|
@ -15,15 +16,6 @@ static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
|||
QCoreApplication::sendEvent( object, &event );
|
||||
}
|
||||
|
||||
static inline QPointF qskScenePosition( const QMouseEvent* event )
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
return event->scenePosition();
|
||||
#else
|
||||
return event->windowPos();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern bool qskInheritLocale( QskWindow*, const QLocale& );
|
||||
|
||||
namespace
|
||||
|
@ -309,41 +301,6 @@ QSizeF QskControlPrivate::explicitSizeHint( Qt::SizeHint whichHint ) const
|
|||
return QSizeF();
|
||||
}
|
||||
|
||||
bool QskControlPrivate::maybeGesture( QQuickItem* child, QEvent* event )
|
||||
{
|
||||
Q_Q( QskControl );
|
||||
|
||||
switch ( event->type() )
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
const auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
|
||||
auto pos = qskScenePosition( mouseEvent );
|
||||
pos = q->mapFromScene( pos );
|
||||
|
||||
if ( !q->gestureRect().contains( pos ) )
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseButtonDblClick:
|
||||
case QEvent::UngrabMouse:
|
||||
case QEvent::TouchBegin:
|
||||
case QEvent::TouchCancel:
|
||||
case QEvent::TouchUpdate:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return q->gestureFilter( child, event );
|
||||
}
|
||||
|
||||
bool QskControlPrivate::inheritLocale( QskControl* control, const QLocale& locale )
|
||||
{
|
||||
auto d = static_cast< QskControlPrivate* >( QQuickItemPrivate::get( control ) );
|
||||
|
|
|
@ -36,8 +36,6 @@ class QskControlPrivate : public QskQuickItemPrivate
|
|||
void implicitSizeChanged() override final;
|
||||
void layoutConstraintChanged() override final;
|
||||
|
||||
bool maybeGesture( QQuickItem*, QEvent* );
|
||||
|
||||
QskPlacementPolicy::Policy placementPolicy( bool visible ) const noexcept;
|
||||
void setPlacementPolicy( bool visible, QskPlacementPolicy::Policy );
|
||||
|
||||
|
|
|
@ -15,15 +15,15 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
|||
public:
|
||||
QSK_SUBCONTROLS( Panel, Overlay )
|
||||
|
||||
QskDrawer( QQuickItem* parentItem = nullptr );
|
||||
QskDrawer( QQuickItem* = nullptr );
|
||||
~QskDrawer() override;
|
||||
|
||||
void setEdge( Qt::Edge edge );
|
||||
void setEdge( Qt::Edge );
|
||||
Qt::Edge edge() const;
|
||||
|
||||
void updateLayout() override;
|
||||
|
||||
void setContent( QskControl* t );
|
||||
void setContent( QskControl* );
|
||||
|
||||
Q_SIGNALS:
|
||||
void edgeChanged( Qt::Edge );
|
||||
|
|
|
@ -154,6 +154,28 @@ bool qskIsButtonPressKey( const QKeyEvent* event )
|
|||
#endif
|
||||
}
|
||||
|
||||
bool qskIsTouchOrMouseEvent( QEvent::Type type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseMove:
|
||||
case QEvent::MouseButtonRelease:
|
||||
case QEvent::MouseButtonDblClick:
|
||||
case QEvent::UngrabMouse:
|
||||
|
||||
case QEvent::TouchBegin:
|
||||
case QEvent::TouchCancel:
|
||||
case QEvent::TouchUpdate:
|
||||
case QEvent::TouchEnd:
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QskEvent::QskEvent( QskEvent::Type type )
|
||||
: QEvent( static_cast< QEvent::Type >( type ) )
|
||||
{
|
||||
|
@ -249,3 +271,19 @@ QskAnimatorEvent* QskAnimatorEvent::clone() const
|
|||
{
|
||||
return new QskAnimatorEvent( *this );
|
||||
}
|
||||
|
||||
// -- QskGestureFilterEvent
|
||||
|
||||
QskGestureFilterEvent::QskGestureFilterEvent(
|
||||
const QQuickItem* item, const QEvent* event )
|
||||
: QskEvent( QskEvent::GestureFilter )
|
||||
, m_item( item )
|
||||
, m_event( event )
|
||||
, m_maybeGesture( false )
|
||||
{
|
||||
}
|
||||
|
||||
QskGestureFilterEvent* QskGestureFilterEvent::clone() const
|
||||
{
|
||||
return new QskGestureFilterEvent( *this );
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ class QSK_EXPORT QskEvent : public QEvent
|
|||
PopupRemoved,
|
||||
|
||||
Gesture,
|
||||
GestureFilter,
|
||||
|
||||
Animator,
|
||||
|
||||
|
@ -118,6 +119,29 @@ class QSK_EXPORT QskPopupEvent : public QskEvent
|
|||
QskPopup* m_popup;
|
||||
};
|
||||
|
||||
class QSK_EXPORT QskGestureFilterEvent : public QskEvent
|
||||
{
|
||||
public:
|
||||
QskGestureFilterEvent( const QQuickItem*, const QEvent* );
|
||||
|
||||
inline const QQuickItem* item() const { return m_item; }
|
||||
inline const QEvent* event() const { return m_event; }
|
||||
|
||||
inline void setMaybeGesture( bool on ) { m_maybeGesture = on; }
|
||||
inline bool maybeGesture() const { return m_maybeGesture; }
|
||||
|
||||
QskGestureFilterEvent* clone() const override;
|
||||
|
||||
protected:
|
||||
QSK_EVENT_DISABLE_COPY( QskGestureFilterEvent )
|
||||
|
||||
private:
|
||||
const QQuickItem* m_item;
|
||||
const QEvent* m_event;
|
||||
|
||||
bool m_maybeGesture;
|
||||
};
|
||||
|
||||
class QSK_EXPORT QskGestureEvent : public QskEvent
|
||||
{
|
||||
public:
|
||||
|
@ -178,4 +202,6 @@ QSK_EXPORT qreal qskWheelIncrement( const QWheelEvent* );
|
|||
QSK_EXPORT bool qskIsStandardKeyInput( const QKeyEvent*, QKeySequence::StandardKey );
|
||||
QSK_EXPORT bool qskIsButtonPressKey( const QKeyEvent* );
|
||||
|
||||
QSK_EXPORT bool qskIsTouchOrMouseEvent( QEvent::Type );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -295,7 +295,7 @@ QskGestureRecognizer::State QskGestureRecognizer::state() const
|
|||
}
|
||||
|
||||
bool QskGestureRecognizer::processEvent(
|
||||
QQuickItem* item, QEvent* event, bool blockReplayedEvents )
|
||||
const QQuickItem* item, const QEvent* event, bool blockReplayedEvents )
|
||||
{
|
||||
if ( m_data->isReplayingEvents && blockReplayedEvents )
|
||||
{
|
||||
|
@ -331,7 +331,7 @@ bool QskGestureRecognizer::processEvent(
|
|||
if ( buttons == Qt::NoButton )
|
||||
buttons = watchedItem->acceptedMouseButtons();
|
||||
|
||||
auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
if ( !( buttons & mouseEvent->button() ) )
|
||||
return false;
|
||||
|
||||
|
@ -383,7 +383,7 @@ bool QskGestureRecognizer::processEvent(
|
|||
{
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
m_data->pendingEvents += qskClonedMouseEvent( mouseEvent );
|
||||
|
||||
pressEvent( mouseEvent );
|
||||
|
@ -392,7 +392,7 @@ bool QskGestureRecognizer::processEvent(
|
|||
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
m_data->pendingEvents += qskClonedMouseEvent( mouseEvent );
|
||||
|
||||
moveEvent( mouseEvent );
|
||||
|
@ -401,7 +401,7 @@ bool QskGestureRecognizer::processEvent(
|
|||
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
m_data->pendingEvents += qskClonedMouseEvent( mouseEvent );
|
||||
|
||||
if ( m_data->state == Pending )
|
||||
|
|
|
@ -41,7 +41,7 @@ class QSK_EXPORT QskGestureRecognizer
|
|||
// timestamp, when the Idle state had been left
|
||||
ulong timestamp() const;
|
||||
|
||||
bool processEvent( QQuickItem*, QEvent*, bool blockReplayedEvents = true );
|
||||
bool processEvent( const QQuickItem*, const QEvent*, bool blockReplayedEvents = true );
|
||||
|
||||
void reject();
|
||||
void accept();
|
||||
|
|
|
@ -46,6 +46,43 @@ class QskListView::PrivateData
|
|||
{
|
||||
}
|
||||
|
||||
void setRowState( QskListView* listView, int row, QskAspect::State state )
|
||||
{
|
||||
using Q = QskListView;
|
||||
|
||||
auto& storedRow = ( state == Q::Hovered )
|
||||
? hoveredRow : ( ( state == Q::Pressed ) ? pressedRow : selectedRow );
|
||||
|
||||
if ( row == storedRow )
|
||||
return;
|
||||
|
||||
if ( storedRow >= 0 )
|
||||
{
|
||||
const auto states = listView->rowStates( storedRow );
|
||||
startTransitions( listView, storedRow, states, states & ~state );
|
||||
}
|
||||
|
||||
if ( row >= 0 )
|
||||
{
|
||||
const auto states = listView->rowStates( row );
|
||||
startTransitions( listView, row, states, states | state );
|
||||
}
|
||||
|
||||
storedRow = row;
|
||||
listView->update();
|
||||
}
|
||||
|
||||
private:
|
||||
inline void startTransitions( QskListView* listView, int row,
|
||||
QskAspect::States oldStates, QskAspect::States newStates )
|
||||
{
|
||||
using Q = QskListView;
|
||||
|
||||
listView->startHintTransitions(
|
||||
{ Q::Cell, Q::Text }, oldStates, newStates, row );
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
Currently we only support single selection. We can't navigate
|
||||
the current item ( = focus ) without changing the selection.
|
||||
|
@ -55,6 +92,8 @@ class QskListView::PrivateData
|
|||
bool preferredWidthFromColumns : 1;
|
||||
SelectionMode selectionMode : 4;
|
||||
|
||||
int hoveredRow = -1;
|
||||
int pressedRow = -1;
|
||||
int selectedRow = -1;
|
||||
};
|
||||
|
||||
|
@ -131,7 +170,8 @@ void QskListView::setSelectedRow( int row )
|
|||
|
||||
if ( row != m_data->selectedRow )
|
||||
{
|
||||
m_data->selectedRow = row;
|
||||
m_data->setRowState( this, row, Selected );
|
||||
|
||||
Q_EMIT selectedRowChanged( row );
|
||||
Q_EMIT focusIndicatorRectChanged();
|
||||
|
||||
|
@ -280,6 +320,7 @@ void QskListView::mousePressEvent( QMouseEvent* event )
|
|||
const int row = qskRowAt( this, qskMousePosition( event ) );
|
||||
if ( row >= 0 )
|
||||
{
|
||||
m_data->setRowState( this, row, Pressed );
|
||||
setSelectedRow( row );
|
||||
return;
|
||||
}
|
||||
|
@ -290,9 +331,44 @@ void QskListView::mousePressEvent( QMouseEvent* event )
|
|||
|
||||
void QskListView::mouseReleaseEvent( QMouseEvent* event )
|
||||
{
|
||||
m_data->setRowState( this, -1, Pressed );
|
||||
Inherited::mouseReleaseEvent( event );
|
||||
}
|
||||
|
||||
void QskListView::mouseUngrabEvent()
|
||||
{
|
||||
m_data->setRowState( this, -1, Pressed );
|
||||
Inherited::mouseUngrabEvent();
|
||||
}
|
||||
|
||||
void QskListView::hoverEnterEvent( QHoverEvent* event )
|
||||
{
|
||||
if ( m_data->selectionMode != NoSelection )
|
||||
{
|
||||
const int row = qskRowAt( this, qskHoverPosition( event ) );
|
||||
m_data->setRowState( this, row, Hovered );
|
||||
}
|
||||
|
||||
Inherited::hoverEnterEvent( event );
|
||||
}
|
||||
|
||||
void QskListView::hoverMoveEvent( QHoverEvent* event )
|
||||
{
|
||||
if ( m_data->selectionMode != NoSelection )
|
||||
{
|
||||
const int row = qskRowAt( this, qskHoverPosition( event ) );
|
||||
m_data->setRowState( this, row, Hovered );
|
||||
}
|
||||
|
||||
Inherited::hoverMoveEvent( event );
|
||||
}
|
||||
|
||||
void QskListView::hoverLeaveEvent( QHoverEvent* event )
|
||||
{
|
||||
m_data->setRowState( this, -1, Hovered );
|
||||
Inherited::hoverLeaveEvent( event );
|
||||
}
|
||||
|
||||
void QskListView::changeEvent( QEvent* event )
|
||||
{
|
||||
if ( event->type() == QEvent::StyleChange )
|
||||
|
@ -301,6 +377,25 @@ void QskListView::changeEvent( QEvent* event )
|
|||
Inherited::changeEvent( event );
|
||||
}
|
||||
|
||||
QskAspect::States QskListView::rowStates( int row ) const
|
||||
{
|
||||
auto states = skinStates();
|
||||
|
||||
if ( row >= 0 )
|
||||
{
|
||||
if ( row == m_data->selectedRow )
|
||||
states |= Selected;
|
||||
|
||||
if ( row == m_data->hoveredRow )
|
||||
states |= Hovered;
|
||||
|
||||
if ( row == m_data->pressedRow )
|
||||
states |= Pressed;
|
||||
}
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
|
||||
static qreal qskAlignedToRows( const qreal y0, qreal dy,
|
||||
|
|
|
@ -54,6 +54,7 @@ class QSK_EXPORT QskListView : public QskScrollView
|
|||
QskTextOptions textOptions() const;
|
||||
|
||||
Q_INVOKABLE int selectedRow() const;
|
||||
QskAspect::States rowStates( int ) const;
|
||||
|
||||
virtual int rowCount() const = 0;
|
||||
virtual int columnCount() const = 0;
|
||||
|
@ -83,6 +84,11 @@ class QSK_EXPORT QskListView : public QskScrollView
|
|||
|
||||
void mousePressEvent( QMouseEvent* ) override;
|
||||
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||
void mouseUngrabEvent() override;
|
||||
|
||||
void hoverEnterEvent( QHoverEvent* ) override;
|
||||
void hoverMoveEvent( QHoverEvent* ) override;
|
||||
void hoverLeaveEvent( QHoverEvent* ) override;
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
virtual QPointF scrollOffset( const QWheelEvent* ) const override;
|
||||
|
|
|
@ -196,7 +196,6 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
|||
const QskListView* listView, QSGNode* backgroundNode ) const
|
||||
{
|
||||
using Q = QskListView;
|
||||
using A = QskAspect;
|
||||
|
||||
auto listViewNode = static_cast< const ListViewNode* >( backgroundNode->parent() );
|
||||
|
||||
|
@ -205,14 +204,11 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
|||
for ( int row = listViewNode->rowMin(); row <= listViewNode->rowMax(); row++ )
|
||||
{
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ) );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ), row );
|
||||
|
||||
const auto rect = sampleRect( listView, listView->contentsRect(), Q::Cell, row );
|
||||
|
||||
const QskAspect aspect = Q::Cell | ( ( row % 2 ) ? A::Upper : A::Lower );
|
||||
const auto boxHints = listView->boxHints( aspect );
|
||||
|
||||
auto newNode = updateBoxNode( listView, rowNode, rect, boxHints );
|
||||
auto newNode = updateBoxNode( listView, rowNode, rect, Q::Cell );
|
||||
if ( newNode )
|
||||
{
|
||||
if ( newNode->parent() != backgroundNode )
|
||||
|
@ -395,7 +391,7 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
|||
using namespace QskSGNode;
|
||||
|
||||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ) );
|
||||
stateChanger.setStates( sampleStates( listView, Q::Cell, row ), row );
|
||||
|
||||
QSGNode* newNode = nullptr;
|
||||
|
||||
|
@ -470,12 +466,7 @@ QskAspect::States QskListViewSkinlet::sampleStates( const QskSkinnable* skinnabl
|
|||
if ( subControl == Q::Cell || subControl == Q::Text || subControl == Q::Graphic )
|
||||
{
|
||||
const auto listView = static_cast< const QskListView* >( skinnable );
|
||||
|
||||
auto states = listView->skinStates();
|
||||
if ( index == listView->selectedRow() )
|
||||
states |= Q::Selected;
|
||||
|
||||
return states;
|
||||
return listView->rowStates( index );
|
||||
}
|
||||
|
||||
return Inherited::sampleStates( skinnable, subControl, index );
|
||||
|
|
|
@ -6,91 +6,30 @@
|
|||
#include "QskProgressBar.h"
|
||||
|
||||
#include "QskIntervalF.h"
|
||||
#include "QskFunctions.h"
|
||||
#include "QskAnimator.h"
|
||||
#include "QskAspect.h"
|
||||
|
||||
QSK_SUBCONTROL( QskProgressBar, Groove )
|
||||
QSK_SUBCONTROL( QskProgressBar, Bar )
|
||||
|
||||
namespace
|
||||
{
|
||||
class PositionAnimator : public QskAnimator
|
||||
{
|
||||
public:
|
||||
PositionAnimator( QskProgressBar* progressBar )
|
||||
: m_progressBar( progressBar )
|
||||
{
|
||||
setAutoRepeat( true );
|
||||
setDuration( 1300 );
|
||||
|
||||
setWindow( progressBar->window() );
|
||||
}
|
||||
|
||||
void advance( qreal value ) override
|
||||
{
|
||||
if ( m_progressBar->setPositionHint( QskProgressBar::Bar, value ) )
|
||||
m_progressBar->update();
|
||||
}
|
||||
|
||||
private:
|
||||
QskProgressBar* m_progressBar;
|
||||
};
|
||||
}
|
||||
QSK_SUBCONTROL( QskProgressBar, Fill )
|
||||
|
||||
class QskProgressBar::PrivateData
|
||||
{
|
||||
public:
|
||||
void updateIndeterminateAnimator( QskProgressBar* progressBar )
|
||||
{
|
||||
if ( !isIndeterminate )
|
||||
{
|
||||
delete animator;
|
||||
animator = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( progressBar->window() && progressBar->isVisible() )
|
||||
{
|
||||
if ( animator == nullptr )
|
||||
animator = new PositionAnimator( progressBar );
|
||||
|
||||
animator->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( animator )
|
||||
animator->stop();
|
||||
}
|
||||
}
|
||||
|
||||
PositionAnimator* animator = nullptr;
|
||||
|
||||
qreal value = 0.0;
|
||||
qreal origin = 0.0;
|
||||
|
||||
bool hasOrigin = false;
|
||||
bool isIndeterminate = false;
|
||||
|
||||
Qt::Orientation orientation;
|
||||
};
|
||||
|
||||
QskProgressBar::QskProgressBar( Qt::Orientation orientation,
|
||||
qreal min, qreal max, QQuickItem* parent )
|
||||
: QskBoundedControl( min, max, parent )
|
||||
: Inherited( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
m_data->orientation = orientation;
|
||||
m_data->value = minimum();
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::Fixed );
|
||||
else
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::MinimumExpanding );
|
||||
|
||||
connect( this, &QskBoundedControl::boundariesChanged,
|
||||
this, &QskProgressBar::adjustValue );
|
||||
setSubcontrolProxy( Inherited::Groove, Groove );
|
||||
setSubcontrolProxy( Inherited::Fill, Fill );
|
||||
}
|
||||
|
||||
QskProgressBar::QskProgressBar( Qt::Orientation orientation, QQuickItem* parent )
|
||||
|
@ -115,7 +54,12 @@ QskProgressBar::QskProgressBar( QQuickItem* parent )
|
|||
|
||||
QskProgressBar::~QskProgressBar()
|
||||
{
|
||||
delete m_data->animator;
|
||||
}
|
||||
|
||||
QskAspect::Variation QskProgressBar::effectiveVariation() const
|
||||
{
|
||||
// so you can define different hints depending on the orientation
|
||||
return static_cast< QskAspect::Variation >( m_data->orientation );
|
||||
}
|
||||
|
||||
Qt::Orientation QskProgressBar::orientation() const
|
||||
|
@ -137,163 +81,4 @@ void QskProgressBar::setOrientation( Qt::Orientation orientation )
|
|||
}
|
||||
}
|
||||
|
||||
bool QskProgressBar::isIndeterminate() const
|
||||
{
|
||||
return m_data->isIndeterminate;
|
||||
}
|
||||
|
||||
void QskProgressBar::setIndeterminate( bool on )
|
||||
{
|
||||
if ( on == m_data->isIndeterminate )
|
||||
return;
|
||||
|
||||
m_data->isIndeterminate = on;
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
|
||||
update();
|
||||
Q_EMIT indeterminateChanged( on );
|
||||
}
|
||||
|
||||
QskAspect::Variation QskProgressBar::effectiveVariation() const
|
||||
{
|
||||
// so you can define different hints depending on the orientation
|
||||
return static_cast< QskAspect::Variation >( m_data->orientation );
|
||||
}
|
||||
|
||||
void QskProgressBar::setBarGradient( const QskGradient& gradient )
|
||||
{
|
||||
setGradientHint( Bar, gradient );
|
||||
}
|
||||
|
||||
void QskProgressBar::resetBarGradient()
|
||||
{
|
||||
resetColor( Bar );
|
||||
}
|
||||
|
||||
QskGradient QskProgressBar::barGradient() const
|
||||
{
|
||||
return gradientHint( QskProgressBar::Bar );
|
||||
}
|
||||
|
||||
void QskProgressBar::setExtent( qreal extent )
|
||||
{
|
||||
if ( extent < 0.0 )
|
||||
extent = 0.0;
|
||||
|
||||
if ( setMetric( Groove | QskAspect::Size, extent ) )
|
||||
Q_EMIT extentChanged( extent );
|
||||
}
|
||||
|
||||
void QskProgressBar::resetExtent()
|
||||
{
|
||||
if ( resetMetric( Groove | QskAspect::Size ) )
|
||||
Q_EMIT extentChanged( extent() );
|
||||
}
|
||||
|
||||
qreal QskProgressBar::extent() const
|
||||
{
|
||||
auto grooveSize = metric( Groove | QskAspect::Size );
|
||||
auto barSize = metric( Bar | QskAspect::Size );
|
||||
return qMax( grooveSize, barSize );
|
||||
}
|
||||
|
||||
void QskProgressBar::setOrigin( qreal origin )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
origin = boundedValue( origin );
|
||||
|
||||
if( !m_data->hasOrigin || !qskFuzzyCompare( m_data->origin, origin ) )
|
||||
{
|
||||
m_data->hasOrigin = true;
|
||||
m_data->origin = origin;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin );
|
||||
}
|
||||
}
|
||||
|
||||
void QskProgressBar::resetOrigin()
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
m_data->hasOrigin = false;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin() );
|
||||
}
|
||||
}
|
||||
|
||||
qreal QskProgressBar::origin() const
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
return boundedValue( m_data->origin );
|
||||
}
|
||||
|
||||
return minimum();
|
||||
}
|
||||
|
||||
void QskProgressBar::setValue( qreal value )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
value = boundedValue( value );
|
||||
|
||||
setValueInternal( value );
|
||||
}
|
||||
|
||||
qreal QskProgressBar::value() const
|
||||
{
|
||||
return m_data->value;
|
||||
}
|
||||
|
||||
void QskProgressBar::setValueAsRatio( qreal ratio )
|
||||
{
|
||||
ratio = qBound( 0.0, ratio, 1.0 );
|
||||
setValue( minimum() + ratio * boundaryLength() );
|
||||
}
|
||||
|
||||
qreal QskProgressBar::valueAsRatio() const
|
||||
{
|
||||
return valueAsRatio( m_data->value );
|
||||
}
|
||||
|
||||
void QskProgressBar::componentComplete()
|
||||
{
|
||||
Inherited::componentComplete();
|
||||
adjustValue();
|
||||
}
|
||||
|
||||
void QskProgressBar::adjustValue()
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
setValueInternal( boundedValue( m_data->value ) );
|
||||
}
|
||||
|
||||
void QskProgressBar::setValueInternal( qreal value )
|
||||
{
|
||||
if ( !qskFuzzyCompare( value, m_data->value ) )
|
||||
{
|
||||
m_data->value = value;
|
||||
Q_EMIT valueChanged( value );
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void QskProgressBar::itemChange( QQuickItem::ItemChange change,
|
||||
const QQuickItem::ItemChangeData& value )
|
||||
{
|
||||
switch( static_cast< int >( change ) )
|
||||
{
|
||||
case QQuickItem::ItemVisibleHasChanged:
|
||||
case QQuickItem::ItemSceneChange:
|
||||
{
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Inherited::itemChange( change, value );
|
||||
}
|
||||
|
||||
#include "moc_QskProgressBar.cpp"
|
||||
|
|
|
@ -6,34 +6,19 @@
|
|||
#ifndef QSK_PROGRESS_BAR_H
|
||||
#define QSK_PROGRESS_BAR_H
|
||||
|
||||
#include "QskBoundedControl.h"
|
||||
#include "QskProgressIndicator.h"
|
||||
|
||||
class QskIntervalF;
|
||||
|
||||
class QSK_EXPORT QskProgressBar : public QskBoundedControl
|
||||
class QSK_EXPORT QskProgressBar : public QskProgressIndicator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( Qt::Orientation orientation READ orientation
|
||||
WRITE setOrientation NOTIFY orientationChanged )
|
||||
|
||||
Q_PROPERTY( qreal extent READ extent
|
||||
WRITE setExtent RESET resetExtent NOTIFY extentChanged )
|
||||
|
||||
Q_PROPERTY( bool indeterminate READ isIndeterminate
|
||||
WRITE setIndeterminate NOTIFY indeterminateChanged )
|
||||
|
||||
Q_PROPERTY( qreal origin READ origin
|
||||
WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
|
||||
|
||||
Q_PROPERTY( qreal value READ value WRITE setValue NOTIFY valueChanged )
|
||||
Q_PROPERTY( qreal valueAsRatio READ valueAsRatio
|
||||
WRITE setValueAsRatio NOTIFY valueChanged )
|
||||
|
||||
using Inherited = QskBoundedControl;
|
||||
using Inherited = QskProgressIndicator;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Groove, Bar )
|
||||
QSK_SUBCONTROLS( Groove, Fill )
|
||||
|
||||
QskProgressBar( Qt::Orientation, QQuickItem* parent = nullptr );
|
||||
QskProgressBar( Qt::Orientation, qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
|
@ -43,50 +28,15 @@ class QSK_EXPORT QskProgressBar : public QskBoundedControl
|
|||
|
||||
~QskProgressBar() override;
|
||||
|
||||
QskAspect::Variation effectiveVariation() const override;
|
||||
|
||||
Qt::Orientation orientation() const;
|
||||
void setOrientation( Qt::Orientation orientation );
|
||||
|
||||
bool isIndeterminate() const;
|
||||
void setIndeterminate( bool on = true );
|
||||
|
||||
QskAspect::Variation effectiveVariation() const override;
|
||||
|
||||
void setBarGradient( const QskGradient& );
|
||||
void resetBarGradient();
|
||||
QskGradient barGradient() const;
|
||||
|
||||
void setExtent( qreal );
|
||||
void resetExtent();
|
||||
qreal extent() const;
|
||||
|
||||
void resetOrigin();
|
||||
qreal origin() const;
|
||||
|
||||
qreal value() const;
|
||||
qreal valueAsRatio() const; // [0.0, 1.0]
|
||||
using QskBoundedControl::valueAsRatio;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setValue( qreal );
|
||||
void setValueAsRatio( qreal );
|
||||
void setOrigin( qreal );
|
||||
|
||||
Q_SIGNALS:
|
||||
void orientationChanged( Qt::Orientation );
|
||||
void extentChanged( qreal );
|
||||
void indeterminateChanged( bool );
|
||||
void valueChanged( qreal );
|
||||
void originChanged( qreal );
|
||||
|
||||
protected:
|
||||
void componentComplete() override;
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
|
||||
private:
|
||||
void setValueInternal( qreal value );
|
||||
void adjustBoundaries( bool increasing );
|
||||
void adjustValue();
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
|
|
@ -7,51 +7,54 @@
|
|||
#include "QskProgressBar.h"
|
||||
#include "QskIntervalF.h"
|
||||
#include "QskBoxBorderMetrics.h"
|
||||
#include "QskGradientDirection.h"
|
||||
|
||||
#include <qeasingcurve.h>
|
||||
#include <cmath>
|
||||
|
||||
static inline QskIntervalF qskBarInterval( const QskProgressBar* bar )
|
||||
using Q = QskProgressBar;
|
||||
|
||||
namespace
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
||||
if ( bar->isIndeterminate() )
|
||||
QskIntervalF qskFillInterval( const Q* bar )
|
||||
{
|
||||
const auto pos = bar->positionHint( QskProgressBar::Bar );
|
||||
qreal pos1, pos2;
|
||||
|
||||
static const QEasingCurve curve( QEasingCurve::InOutCubic );
|
||||
|
||||
const qreal off = 0.15;
|
||||
|
||||
pos1 = curve.valueForProgress( qMax( pos - off, 0.0 ) );
|
||||
pos2 = curve.valueForProgress( qMin( pos + off, 1.0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pos1 = bar->valueAsRatio( bar->origin() );
|
||||
pos2 = bar->valueAsRatio( bar->value() );
|
||||
}
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
if ( bar->layoutMirroring() )
|
||||
if ( bar->isIndeterminate() )
|
||||
{
|
||||
pos1 = 1.0 - pos1;
|
||||
pos2 = 1.0 - pos2;
|
||||
const auto pos = bar->positionHint( QskProgressIndicator::Fill );
|
||||
|
||||
static const QEasingCurve curve( QEasingCurve::InOutCubic );
|
||||
|
||||
const qreal off = 0.15;
|
||||
|
||||
pos1 = curve.valueForProgress( qMax( pos - off, 0.0 ) );
|
||||
pos2 = curve.valueForProgress( qMin( pos + off, 1.0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pos1 = bar->valueAsRatio( bar->origin() );
|
||||
pos2 = bar->valueAsRatio( bar->value() );
|
||||
}
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
if ( bar->layoutMirroring() )
|
||||
{
|
||||
pos1 = 1.0 - pos1;
|
||||
pos2 = 1.0 - pos2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pos1 > pos2 )
|
||||
std::swap( pos1, pos2 );
|
||||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
|
||||
if ( pos1 > pos2 )
|
||||
std::swap( pos1, pos2 );
|
||||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
|
||||
QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
|
||||
: QskSkinlet( skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
setNodeRoles( { GrooveRole, BarRole } );
|
||||
}
|
||||
|
||||
QskProgressBarSkinlet::~QskProgressBarSkinlet()
|
||||
|
@ -62,7 +65,6 @@ QRectF QskProgressBarSkinlet::subControlRect(
|
|||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
using Q = QskProgressBar;
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
|
||||
if( subControl == Q::Groove )
|
||||
|
@ -84,7 +86,7 @@ QRectF QskProgressBarSkinlet::subControlRect(
|
|||
return rect;
|
||||
}
|
||||
|
||||
if( subControl == Q::Bar )
|
||||
if( subControl == Q::Fill )
|
||||
{
|
||||
return barRect( bar );
|
||||
}
|
||||
|
@ -92,30 +94,18 @@ QRectF QskProgressBarSkinlet::subControlRect(
|
|||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
QSGNode* QskProgressBarSkinlet::updateGrooveNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
switch( nodeRole )
|
||||
{
|
||||
case GrooveRole:
|
||||
{
|
||||
return updateBoxNode( skinnable, node, QskProgressBar::Groove );
|
||||
}
|
||||
|
||||
case BarRole:
|
||||
{
|
||||
const auto bar = static_cast< const QskProgressBar* >( skinnable );
|
||||
return updateBarNode( bar, node );
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
return updateBoxNode( indicator, node, Q::Groove );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressBarSkinlet::updateBarNode(
|
||||
const QskProgressBar* bar, QSGNode* node ) const
|
||||
QSGNode* QskProgressBarSkinlet::updateFillNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
const auto subControl = QskProgressBar::Bar;
|
||||
const auto bar = static_cast< const Q* >( indicator );
|
||||
|
||||
const auto subControl = Q::Fill;
|
||||
|
||||
const auto rect = bar->subControlRect( subControl );
|
||||
if ( rect.isEmpty() )
|
||||
|
@ -139,26 +129,27 @@ QSGNode* QskProgressBarSkinlet::updateBarNode(
|
|||
not supporting this yet. TODO ...
|
||||
*/
|
||||
|
||||
const auto intv = qskBarInterval( bar );
|
||||
const auto intv = qskFillInterval( bar );
|
||||
|
||||
const auto stops = qskExtractedGradientStops( gradient.stops(),
|
||||
intv.lowerBound(), intv.upperBound() );
|
||||
|
||||
gradient.setStops( stops );
|
||||
gradient.setLinearDirection( bar->orientation() );
|
||||
|
||||
gradient.setLinearDirection( static_cast< Qt::Orientation >( bar->orientation() ) );
|
||||
|
||||
if ( bar->orientation() == Qt::Vertical || bar->layoutMirroring() )
|
||||
gradient.reverse();
|
||||
}
|
||||
|
||||
return updateBoxNode( bar, node, rect, gradient, subControl );
|
||||
return updateBoxNode( indicator, node, rect, gradient, subControl );
|
||||
}
|
||||
|
||||
QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const
|
||||
QRectF QskProgressBarSkinlet::barRect( const Q* bar ) const
|
||||
{
|
||||
using Q = QskProgressBar;
|
||||
const auto subControl = Q::Groove;
|
||||
|
||||
const auto barSize = bar->metric( Q::Bar | QskAspect::Size );
|
||||
const auto barSize = bar->metric( Q::Fill | QskAspect::Size );
|
||||
auto rect = bar->subControlRect( subControl );
|
||||
|
||||
if ( bar->orientation() == Qt::Horizontal )
|
||||
|
@ -179,7 +170,7 @@ QRectF QskProgressBarSkinlet::barRect( const QskProgressBar* bar ) const
|
|||
|
||||
rect = rect.marginsRemoved( m );
|
||||
|
||||
const auto intv = qskBarInterval( bar );
|
||||
const auto intv = qskFillInterval( bar );
|
||||
|
||||
if( bar->orientation() == Qt::Horizontal )
|
||||
{
|
||||
|
@ -205,7 +196,7 @@ QSizeF QskProgressBarSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto bar = static_cast< const QskProgressBar* >( skinnable );
|
||||
const auto bar = static_cast< const Q* >( skinnable );
|
||||
|
||||
const auto extent = bar->extent();
|
||||
|
||||
|
|
|
@ -6,25 +6,17 @@
|
|||
#ifndef QSK_PROGRESS_BAR_SKINLET_H
|
||||
#define QSK_PROGRESS_BAR_SKINLET_H
|
||||
|
||||
#include "QskSkinlet.h"
|
||||
#include "QskProgressIndicatorSkinlet.h"
|
||||
|
||||
class QskProgressBar;
|
||||
|
||||
class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
|
||||
class QSK_EXPORT QskProgressBarSkinlet : public QskProgressIndicatorSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskSkinlet;
|
||||
using Inherited = QskProgressIndicatorSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole
|
||||
{
|
||||
GrooveRole,
|
||||
BarRole,
|
||||
|
||||
RoleCount
|
||||
};
|
||||
|
||||
Q_INVOKABLE QskProgressBarSkinlet( QskSkin* = nullptr );
|
||||
~QskProgressBarSkinlet() override;
|
||||
|
||||
|
@ -35,11 +27,10 @@ class QSK_EXPORT QskProgressBarSkinlet : public QskSkinlet
|
|||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
|
||||
private:
|
||||
QSGNode* updateBarNode( const QskProgressBar*, QSGNode* ) const;
|
||||
QRectF barRect( const QskProgressBar* ) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskProgressIndicator.h"
|
||||
|
||||
#include "QskIntervalF.h"
|
||||
#include "QskFunctions.h"
|
||||
#include "QskAnimator.h"
|
||||
#include "QskAspect.h"
|
||||
|
||||
QSK_SUBCONTROL( QskProgressIndicator, Groove )
|
||||
QSK_SUBCONTROL( QskProgressIndicator, Fill )
|
||||
|
||||
namespace
|
||||
{
|
||||
class PositionAnimator : public QskAnimator
|
||||
{
|
||||
public:
|
||||
PositionAnimator( QskProgressIndicator* indicator )
|
||||
: m_indicator( indicator )
|
||||
{
|
||||
setAutoRepeat( true );
|
||||
setDuration( 1300 );
|
||||
|
||||
setWindow( indicator->window() );
|
||||
}
|
||||
|
||||
void advance( qreal value ) override
|
||||
{
|
||||
if ( m_indicator->setPositionHint( QskProgressIndicator::Fill, value ) )
|
||||
m_indicator->update();
|
||||
}
|
||||
|
||||
private:
|
||||
QskProgressIndicator* m_indicator;
|
||||
};
|
||||
}
|
||||
|
||||
class QskProgressIndicator::PrivateData
|
||||
{
|
||||
public:
|
||||
void updateIndeterminateAnimator( QskProgressIndicator* indicator )
|
||||
{
|
||||
if ( !isIndeterminate )
|
||||
{
|
||||
delete animator;
|
||||
animator = nullptr;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( indicator->window() && indicator->isVisible() )
|
||||
{
|
||||
if ( animator == nullptr )
|
||||
animator = new PositionAnimator( indicator );
|
||||
|
||||
animator->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( animator )
|
||||
animator->stop();
|
||||
}
|
||||
}
|
||||
|
||||
PositionAnimator* animator = nullptr;
|
||||
|
||||
qreal value = 0.0;
|
||||
qreal origin = 0.0;
|
||||
|
||||
bool hasOrigin = false;
|
||||
bool isIndeterminate = false;
|
||||
};
|
||||
|
||||
QskProgressIndicator::QskProgressIndicator( qreal min, qreal max, QQuickItem* parent )
|
||||
: QskBoundedControl( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
m_data->value = minimum();
|
||||
|
||||
connect( this, &QskBoundedControl::boundariesChanged,
|
||||
this, &QskProgressIndicator::adjustValue );
|
||||
}
|
||||
|
||||
QskProgressIndicator::QskProgressIndicator( QQuickItem* parent )
|
||||
: QskProgressIndicator( 0.0, 100.0, parent )
|
||||
{
|
||||
}
|
||||
|
||||
QskProgressIndicator::QskProgressIndicator( const QskIntervalF& boundaries, QQuickItem* parent )
|
||||
: QskProgressIndicator( boundaries.lowerBound(), boundaries.upperBound(), parent )
|
||||
{
|
||||
}
|
||||
|
||||
QskProgressIndicator::~QskProgressIndicator()
|
||||
{
|
||||
delete m_data->animator;
|
||||
}
|
||||
|
||||
bool QskProgressIndicator::isIndeterminate() const
|
||||
{
|
||||
return m_data->isIndeterminate;
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setIndeterminate( bool on )
|
||||
{
|
||||
if ( on == m_data->isIndeterminate )
|
||||
return;
|
||||
|
||||
m_data->isIndeterminate = on;
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
|
||||
update();
|
||||
Q_EMIT indeterminateChanged( on );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setFillGradient( const QskGradient& gradient )
|
||||
{
|
||||
setGradientHint( Fill, gradient );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::resetFillGradient()
|
||||
{
|
||||
resetColor( Fill );
|
||||
}
|
||||
|
||||
QskGradient QskProgressIndicator::fillGradient() const
|
||||
{
|
||||
return gradientHint( Fill );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setExtent( qreal extent )
|
||||
{
|
||||
if ( extent < 0.0 )
|
||||
extent = 0.0;
|
||||
|
||||
if ( setMetric( Groove | QskAspect::Size, extent ) )
|
||||
Q_EMIT extentChanged( extent );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::resetExtent()
|
||||
{
|
||||
if ( resetMetric( Groove | QskAspect::Size ) )
|
||||
Q_EMIT extentChanged( extent() );
|
||||
}
|
||||
|
||||
qreal QskProgressIndicator::extent() const
|
||||
{
|
||||
auto grooveSize = metric( Groove | QskAspect::Size );
|
||||
auto fillSize = metric( Fill | QskAspect::Size );
|
||||
return qMax( grooveSize, fillSize );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setOrigin( qreal origin )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
origin = boundedValue( origin );
|
||||
|
||||
if( !m_data->hasOrigin || !qskFuzzyCompare( m_data->origin, origin ) )
|
||||
{
|
||||
m_data->hasOrigin = true;
|
||||
m_data->origin = origin;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin );
|
||||
}
|
||||
}
|
||||
|
||||
void QskProgressIndicator::resetOrigin()
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
m_data->hasOrigin = false;
|
||||
|
||||
update();
|
||||
Q_EMIT originChanged( origin() );
|
||||
}
|
||||
}
|
||||
|
||||
qreal QskProgressIndicator::origin() const
|
||||
{
|
||||
if ( m_data->hasOrigin )
|
||||
{
|
||||
return boundedValue( m_data->origin );
|
||||
}
|
||||
|
||||
return minimum();
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setValue( qreal value )
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
value = boundedValue( value );
|
||||
|
||||
setValueInternal( value );
|
||||
}
|
||||
|
||||
qreal QskProgressIndicator::value() const
|
||||
{
|
||||
return m_data->value;
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setValueAsRatio( qreal ratio )
|
||||
{
|
||||
ratio = qBound( 0.0, ratio, 1.0 );
|
||||
setValue( minimum() + ratio * boundaryLength() );
|
||||
}
|
||||
|
||||
qreal QskProgressIndicator::valueAsRatio() const
|
||||
{
|
||||
return valueAsRatio( m_data->value );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::componentComplete()
|
||||
{
|
||||
Inherited::componentComplete();
|
||||
adjustValue();
|
||||
}
|
||||
|
||||
void QskProgressIndicator::adjustValue()
|
||||
{
|
||||
if ( isComponentComplete() )
|
||||
setValueInternal( boundedValue( m_data->value ) );
|
||||
}
|
||||
|
||||
void QskProgressIndicator::setValueInternal( qreal value )
|
||||
{
|
||||
if ( !qskFuzzyCompare( value, m_data->value ) )
|
||||
{
|
||||
m_data->value = value;
|
||||
Q_EMIT valueChanged( value );
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void QskProgressIndicator::itemChange( QQuickItem::ItemChange change,
|
||||
const QQuickItem::ItemChangeData& value )
|
||||
{
|
||||
switch( static_cast< int >( change ) )
|
||||
{
|
||||
case QQuickItem::ItemVisibleHasChanged:
|
||||
case QQuickItem::ItemSceneChange:
|
||||
{
|
||||
m_data->updateIndeterminateAnimator( this );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Inherited::itemChange( change, value );
|
||||
}
|
||||
|
||||
#include "moc_QskProgressIndicator.cpp"
|
|
@ -0,0 +1,83 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_PROGRESS_INDICATOR_H
|
||||
#define QSK_PROGRESS_INDICATOR_H
|
||||
|
||||
#include "QskBoundedControl.h"
|
||||
|
||||
class QskIntervalF;
|
||||
|
||||
class QSK_EXPORT QskProgressIndicator : public QskBoundedControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( qreal extent READ extent
|
||||
WRITE setExtent RESET resetExtent NOTIFY extentChanged )
|
||||
|
||||
Q_PROPERTY( bool indeterminate READ isIndeterminate
|
||||
WRITE setIndeterminate NOTIFY indeterminateChanged )
|
||||
|
||||
Q_PROPERTY( qreal origin READ origin
|
||||
WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
|
||||
|
||||
Q_PROPERTY( qreal value READ value WRITE setValue NOTIFY valueChanged )
|
||||
Q_PROPERTY( qreal valueAsRatio READ valueAsRatio
|
||||
WRITE setValueAsRatio NOTIFY valueChanged )
|
||||
|
||||
using Inherited = QskBoundedControl;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Groove, Fill )
|
||||
|
||||
QskProgressIndicator( QQuickItem* parent = nullptr );
|
||||
QskProgressIndicator( qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
QskProgressIndicator( const QskIntervalF&, QQuickItem* parent = nullptr );
|
||||
|
||||
~QskProgressIndicator() override;
|
||||
|
||||
bool isIndeterminate() const;
|
||||
void setIndeterminate( bool on = true );
|
||||
|
||||
void setFillGradient( const QskGradient& );
|
||||
void resetFillGradient();
|
||||
QskGradient fillGradient() const;
|
||||
|
||||
void setExtent( qreal );
|
||||
void resetExtent();
|
||||
qreal extent() const;
|
||||
|
||||
void resetOrigin();
|
||||
qreal origin() const;
|
||||
|
||||
qreal value() const;
|
||||
qreal valueAsRatio() const; // [0.0, 1.0]
|
||||
using QskBoundedControl::valueAsRatio;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setValue( qreal );
|
||||
void setValueAsRatio( qreal );
|
||||
void setOrigin( qreal );
|
||||
|
||||
Q_SIGNALS:
|
||||
void extentChanged( qreal );
|
||||
void indeterminateChanged( bool );
|
||||
void valueChanged( qreal );
|
||||
void originChanged( qreal );
|
||||
|
||||
protected:
|
||||
void componentComplete() override;
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
|
||||
private:
|
||||
void setValueInternal( qreal value );
|
||||
void adjustBoundaries( bool increasing );
|
||||
void adjustValue();
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskProgressIndicatorSkinlet.h"
|
||||
#include "QskProgressIndicator.h"
|
||||
|
||||
QskProgressIndicatorSkinlet::QskProgressIndicatorSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
setNodeRoles( { GrooveRole, FillRole } );
|
||||
}
|
||||
|
||||
QskProgressIndicatorSkinlet::~QskProgressIndicatorSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QSGNode* QskProgressIndicatorSkinlet::updateSubNode(
|
||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||
{
|
||||
const auto indicator = static_cast< const QskProgressIndicator* >( skinnable );
|
||||
|
||||
switch( nodeRole )
|
||||
{
|
||||
case GrooveRole:
|
||||
{
|
||||
return updateGrooveNode( indicator, node );
|
||||
}
|
||||
|
||||
case FillRole:
|
||||
{
|
||||
return updateFillNode( indicator, node );
|
||||
}
|
||||
}
|
||||
|
||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_PROGRESS_INDICATOR_SKINLET_H
|
||||
#define QSK_PROGRESS_INDICATOR_SKINLET_H
|
||||
|
||||
#include "QskSkinlet.h"
|
||||
|
||||
class QskProgressIndicator;
|
||||
|
||||
class QSK_EXPORT QskProgressIndicatorSkinlet : public QskSkinlet
|
||||
{
|
||||
using Inherited = QskSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole
|
||||
{
|
||||
GrooveRole,
|
||||
FillRole,
|
||||
|
||||
RoleCount
|
||||
};
|
||||
|
||||
~QskProgressIndicatorSkinlet() override;
|
||||
|
||||
protected:
|
||||
QskProgressIndicatorSkinlet( QskSkin* = nullptr );
|
||||
|
||||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
|
||||
virtual QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const = 0;
|
||||
virtual QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2023 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskProgressRing.h"
|
||||
|
||||
#include "QskIntervalF.h"
|
||||
|
||||
QSK_SUBCONTROL( QskProgressRing, Groove )
|
||||
QSK_SUBCONTROL( QskProgressRing, Fill )
|
||||
|
||||
class QskProgressRing::PrivateData
|
||||
{
|
||||
public:
|
||||
int size : 2;
|
||||
};
|
||||
|
||||
QskProgressRing::QskProgressRing( qreal min, qreal max, QQuickItem* parent )
|
||||
: Inherited( min, max, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
m_data->size = NormalSize;
|
||||
|
||||
setSubcontrolProxy( Inherited::Groove, Groove );
|
||||
setSubcontrolProxy( Inherited::Fill, Fill );
|
||||
}
|
||||
|
||||
QskProgressRing::QskProgressRing( QQuickItem* parent )
|
||||
: QskProgressRing( 0.0, 100.0, parent )
|
||||
{
|
||||
}
|
||||
|
||||
QskProgressRing::QskProgressRing( const QskIntervalF& boundaries, QQuickItem* parent )
|
||||
: QskProgressRing( boundaries.lowerBound(), boundaries.upperBound(), parent )
|
||||
{
|
||||
}
|
||||
|
||||
QskProgressRing::~QskProgressRing()
|
||||
{
|
||||
}
|
||||
|
||||
QskAspect::Variation QskProgressRing::effectiveVariation() const
|
||||
{
|
||||
switch( size() )
|
||||
{
|
||||
case SmallSize:
|
||||
return QskAspect::Small;
|
||||
|
||||
case LargeSize:
|
||||
return QskAspect::Large;
|
||||
|
||||
default:
|
||||
return QskAspect::NoVariation;
|
||||
}
|
||||
}
|
||||
|
||||
void QskProgressRing::setSize( Size size )
|
||||
{
|
||||
if ( size != m_data->size )
|
||||
{
|
||||
m_data->size = size;
|
||||
|
||||
resetImplicitSize();
|
||||
update();
|
||||
|
||||
Q_EMIT sizeChanged( size );
|
||||
}
|
||||
}
|
||||
|
||||
QskProgressRing::Size QskProgressRing::size() const
|
||||
{
|
||||
return static_cast< Size >( m_data->size );
|
||||
}
|
||||
|
||||
#include "moc_QskProgressRing.cpp"
|
|
@ -0,0 +1,50 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2023 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_PROGRESS_RING_H
|
||||
#define QSK_PROGRESS_RING_H
|
||||
|
||||
#include "QskProgressIndicator.h"
|
||||
|
||||
class QSK_EXPORT QskProgressRing : public QskProgressIndicator
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( Size size READ size
|
||||
WRITE setSize NOTIFY sizeChanged )
|
||||
|
||||
using Inherited = QskProgressIndicator;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Groove, Fill )
|
||||
|
||||
enum Size
|
||||
{
|
||||
SmallSize = -1,
|
||||
NormalSize = 0,
|
||||
LargeSize = 1
|
||||
};
|
||||
Q_ENUM( Size )
|
||||
|
||||
QskProgressRing( QQuickItem* parent = nullptr );
|
||||
QskProgressRing( qreal min, qreal max, QQuickItem* parent = nullptr );
|
||||
QskProgressRing( const QskIntervalF&, QQuickItem* parent = nullptr );
|
||||
|
||||
~QskProgressRing() override;
|
||||
|
||||
QskAspect::Variation effectiveVariation() const override;
|
||||
|
||||
void setSize( Size );
|
||||
Size size() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void sizeChanged( Size );
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,125 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2023 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskProgressRingSkinlet.h"
|
||||
#include "QskArcMetrics.h"
|
||||
#include "QskProgressRing.h"
|
||||
#include "QskIntervalF.h"
|
||||
|
||||
using Q = QskProgressRing;
|
||||
|
||||
namespace
|
||||
{
|
||||
QskIntervalF qskFillInterval( const Q* ring )
|
||||
{
|
||||
qreal pos1, pos2;
|
||||
|
||||
if ( ring->isIndeterminate() )
|
||||
{
|
||||
const auto pos = ring->positionHint( QskProgressIndicator::Fill );
|
||||
|
||||
pos1 = pos2 = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos1 = ring->valueAsRatio( ring->origin() );
|
||||
pos2 = ring->valueAsRatio( ring->value() );
|
||||
}
|
||||
|
||||
if ( pos1 > pos2 )
|
||||
std::swap( pos1, pos2 );
|
||||
|
||||
return QskIntervalF( pos1, pos2 );
|
||||
}
|
||||
}
|
||||
|
||||
QskProgressRingSkinlet::QskProgressRingSkinlet( QskSkin* skin )
|
||||
: Inherited( skin )
|
||||
{
|
||||
}
|
||||
|
||||
QskProgressRingSkinlet::~QskProgressRingSkinlet()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF QskProgressRingSkinlet::subControlRect(
|
||||
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
const auto ring = static_cast< const Q* >( skinnable );
|
||||
|
||||
if( subControl == Q::Groove || subControl == Q::Fill )
|
||||
{
|
||||
auto rect = contentsRect;
|
||||
const auto size = ring->strutSizeHint( Q::Fill );
|
||||
|
||||
if( ring->layoutMirroring() )
|
||||
{
|
||||
rect.setLeft( rect.right() - size.width() );
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setWidth( size.width() );
|
||||
}
|
||||
|
||||
rect.setTop( rect.top() + 0.5 * ( rect.height() - size.height() ) );
|
||||
rect.setHeight( size.height() );
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressRingSkinlet::updateGrooveNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
return updateArcNode( indicator, node, Q::Groove );
|
||||
}
|
||||
|
||||
QSGNode* QskProgressRingSkinlet::updateFillNode(
|
||||
const QskProgressIndicator* indicator, QSGNode* node ) const
|
||||
{
|
||||
const auto ring = static_cast< const Q* >( indicator );
|
||||
|
||||
const auto subControl = Q::Fill;
|
||||
|
||||
const auto rect = ring->subControlRect( subControl );
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto gradient = ring->gradientHint( subControl );
|
||||
if ( !gradient.isVisible() )
|
||||
return nullptr;
|
||||
|
||||
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
|
||||
{
|
||||
const auto center = rect.center();
|
||||
const auto arcMetrics = ring->arcMetricsHint( Q::Fill );
|
||||
gradient.setConicDirection( center.x(), center.y(), arcMetrics.startAngle(), arcMetrics.spanAngle() );
|
||||
}
|
||||
|
||||
const auto interval = qskFillInterval( ring );
|
||||
const auto arcMetrics = ring->arcMetricsHint( subControl );
|
||||
|
||||
const auto startAngle = arcMetrics.startAngle() + interval.lowerBound() * arcMetrics.spanAngle();
|
||||
const auto spanAngle = interval.upperBound() * arcMetrics.spanAngle();
|
||||
|
||||
return updateArcNode( ring, node, rect, gradient, startAngle, spanAngle, subControl );
|
||||
}
|
||||
|
||||
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto ring = static_cast< const Q* >( skinnable );
|
||||
|
||||
const auto r = ring->strutSizeHint( Q::Fill );
|
||||
return r;
|
||||
}
|
||||
|
||||
#include "moc_QskProgressRingSkinlet.cpp"
|
|
@ -0,0 +1,34 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2023 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_PROGRESS_RING_SKINLET_H
|
||||
#define QSK_PROGRESS_RING_SKINLET_H
|
||||
|
||||
#include "QskProgressIndicatorSkinlet.h"
|
||||
|
||||
class QskProgressRing;
|
||||
|
||||
class QSK_EXPORT QskProgressRingSkinlet : public QskProgressIndicatorSkinlet
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
using Inherited = QskProgressIndicatorSkinlet;
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QskProgressRingSkinlet( QskSkin* = nullptr );
|
||||
~QskProgressRingSkinlet() override;
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||
|
||||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QSGNode* updateGrooveNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
QSGNode* updateFillNode( const QskProgressIndicator*, QSGNode* ) const override;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -540,7 +540,6 @@ void qskUngrabMouse( QQuickItem* item )
|
|||
|
||||
if ( qskIsMouseGrabber( item ) )
|
||||
item->ungrabMouse();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,25 @@ void QskScrollBox::geometryChangeEvent( QskGeometryChangeEvent* event )
|
|||
Inherited::geometryChangeEvent( event );
|
||||
}
|
||||
|
||||
void QskScrollBox::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
auto& recognizer = m_data->panRecognizer;
|
||||
if ( recognizer.hasProcessedBefore( event ) )
|
||||
{
|
||||
if ( m_data->panRecognizerTimeout != 0 )
|
||||
{
|
||||
recognizer.abort();
|
||||
recognizer.setTimeout( -1 );
|
||||
|
||||
recognizer.processEvent( this, event, false );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return Inherited::mousePressEvent( event );
|
||||
}
|
||||
|
||||
void QskScrollBox::gestureEvent( QskGestureEvent* event )
|
||||
{
|
||||
if ( event->gesture()->type() == QskGesture::Pan )
|
||||
|
@ -427,7 +446,7 @@ void QskScrollBox::wheelEvent( QWheelEvent* event )
|
|||
|
||||
#endif
|
||||
|
||||
bool QskScrollBox::gestureFilter( QQuickItem* item, QEvent* event )
|
||||
bool QskScrollBox::gestureFilter( const QQuickItem* item, const QEvent* event )
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
|
@ -458,38 +477,39 @@ bool QskScrollBox::gestureFilter( QQuickItem* item, QEvent* event )
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
This code is a bit tricky as the filter is called in different situations:
|
||||
|
||||
a) The press was on a child of the view
|
||||
b) The press was on the view
|
||||
|
||||
In case of b) things are simple and we can let the recognizer
|
||||
decide without timeout if it is was a gesture or not.
|
||||
|
||||
In case of a) we give the recognizer some time to decide - usually
|
||||
based on the distances of the following mouse events. If no decision
|
||||
could be made the recognizer aborts and replays the mouse events, so
|
||||
that the children can process them.
|
||||
|
||||
But if a child does not accept a mouse event it will be sent to
|
||||
its parent. So we might finally receive the reposted events, but then
|
||||
we can proceed as in b).
|
||||
*/
|
||||
|
||||
auto& recognizer = m_data->panRecognizer;
|
||||
recognizer.setTimeout( m_data->panRecognizerTimeout );
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
if ( ( item != this ) && ( recognizer.timeout() < 0 ) )
|
||||
/*
|
||||
This code is a bit tricky as the filter is called in different situations:
|
||||
|
||||
a) The press was on a child of the view
|
||||
b) The press was on the view
|
||||
|
||||
In case of b) things are simple and we can let the recognizer
|
||||
decide without timeout if it is was a gesture or not.
|
||||
|
||||
In case of a) we give the recognizer some time to decide - usually
|
||||
based on the distances of the following mouse events. If no decision
|
||||
could be made the recognizer aborts and replays the mouse events, so
|
||||
that the children can process them.
|
||||
|
||||
But if a child does not accept the mouse event it will be sent to
|
||||
its parent, finally ending up here for a second time.
|
||||
*/
|
||||
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
if ( recognizer.hasProcessedBefore( mouseEvent ) )
|
||||
{
|
||||
const auto mouseEvent = static_cast< QMouseEvent* >( event );
|
||||
|
||||
if ( recognizer.hasProcessedBefore( mouseEvent ) )
|
||||
return false;
|
||||
/*
|
||||
Note that the recognizer will be restarted without timout if the
|
||||
event ends up in in mousePressEvent ( = nobody else was interested )
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
recognizer.setTimeout( ( item == this ) ? -1 : m_data->panRecognizerTimeout );
|
||||
}
|
||||
|
||||
return recognizer.processEvent( item, event );
|
||||
|
|
|
@ -64,6 +64,8 @@ class QSK_EXPORT QskScrollBox : public QskControl
|
|||
protected:
|
||||
void geometryChangeEvent( QskGeometryChangeEvent* ) override;
|
||||
void windowChangeEvent( QskWindowChangeEvent* ) override;
|
||||
|
||||
void mousePressEvent( QMouseEvent* ) override;
|
||||
void gestureEvent( QskGestureEvent* ) override;
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
|
@ -71,7 +73,7 @@ class QSK_EXPORT QskScrollBox : public QskControl
|
|||
virtual QPointF scrollOffset( const QWheelEvent* ) const;
|
||||
#endif
|
||||
|
||||
bool gestureFilter( QQuickItem*, QEvent* ) override;
|
||||
bool gestureFilter( const QQuickItem*, const QEvent* ) override;
|
||||
void setScrollableSize( const QSizeF& );
|
||||
|
||||
private:
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
#include "QskProgressBar.h"
|
||||
#include "QskProgressBarSkinlet.h"
|
||||
|
||||
#include "QskProgressRing.h"
|
||||
#include "QskProgressRingSkinlet.h"
|
||||
|
||||
#include "QskRadioBox.h"
|
||||
#include "QskRadioBoxSkinlet.h"
|
||||
|
||||
|
@ -178,6 +181,7 @@ QskSkin::QskSkin( QObject* parent )
|
|||
declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
|
||||
declareSkinlet< QskTextInput, QskTextInputSkinlet >();
|
||||
declareSkinlet< QskProgressBar, QskProgressBarSkinlet >();
|
||||
declareSkinlet< QskProgressRing, QskProgressRingSkinlet >();
|
||||
declareSkinlet< QskRadioBox, QskRadioBoxSkinlet >();
|
||||
|
||||
const QFont font = QGuiApplication::font();
|
||||
|
|
|
@ -15,7 +15,7 @@ class QskSkinStateChanger
|
|||
QskSkinStateChanger( const QskSkinnable* );
|
||||
~QskSkinStateChanger();
|
||||
|
||||
void setStates( QskAspect::States );
|
||||
void setStates( QskAspect::States, int sampleIndex = -1 );
|
||||
void resetStates();
|
||||
|
||||
private:
|
||||
|
@ -34,16 +34,15 @@ inline QskSkinStateChanger::~QskSkinStateChanger()
|
|||
resetStates();
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::setStates( QskAspect::States states )
|
||||
inline void QskSkinStateChanger::setStates(
|
||||
QskAspect::States states, int sampleIndex )
|
||||
{
|
||||
if ( states != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( states );
|
||||
m_skinnable->replaceSkinStates( states, sampleIndex );
|
||||
}
|
||||
|
||||
inline void QskSkinStateChanger::resetStates()
|
||||
{
|
||||
if ( m_oldStates != m_skinnable->skinStates() )
|
||||
m_skinnable->replaceSkinStates( m_oldStates );
|
||||
m_skinnable->replaceSkinStates( m_oldStates, -1 );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -282,8 +282,6 @@ class QskSkinlet::PrivateData
|
|||
QskSkin* skin;
|
||||
QVector< quint8 > nodeRoles;
|
||||
|
||||
int animatorIndex = -1;
|
||||
|
||||
bool ownedBySkinnable : 1;
|
||||
};
|
||||
|
||||
|
@ -311,21 +309,6 @@ bool QskSkinlet::isOwnedBySkinnable() const
|
|||
return m_data->ownedBySkinnable;
|
||||
}
|
||||
|
||||
void QskSkinlet::setAnimatorIndex( int index )
|
||||
{
|
||||
m_data->animatorIndex = index;
|
||||
}
|
||||
|
||||
void QskSkinlet::resetAnimatorIndex()
|
||||
{
|
||||
m_data->animatorIndex = -1;
|
||||
}
|
||||
|
||||
int QskSkinlet::animatorIndex() const
|
||||
{
|
||||
return m_data->animatorIndex;
|
||||
}
|
||||
|
||||
void QskSkinlet::setNodeRoles( const QVector< quint8 >& nodeRoles )
|
||||
{
|
||||
m_data->nodeRoles = nodeRoles;
|
||||
|
@ -796,26 +779,7 @@ QSGNode* QskSkinlet::updateSeriesNode( const QskSkinnable* skinnable,
|
|||
const auto newStates = sampleStates( skinnable, subControl, i );
|
||||
|
||||
QskSkinStateChanger stateChanger( skinnable );
|
||||
stateChanger.setStates( newStates );
|
||||
|
||||
class IndexChanger
|
||||
{
|
||||
public:
|
||||
inline IndexChanger( const QskSkinlet* skinlet, int index )
|
||||
: m_skinlet( const_cast< QskSkinlet* >( skinlet ) )
|
||||
{
|
||||
m_skinlet->setAnimatorIndex( index );
|
||||
}
|
||||
|
||||
inline ~IndexChanger()
|
||||
{
|
||||
m_skinlet->resetAnimatorIndex();
|
||||
}
|
||||
private:
|
||||
QskSkinlet* m_skinlet;
|
||||
};
|
||||
|
||||
IndexChanger indexChanger( this, i );
|
||||
stateChanger.setStates( newStates, i );
|
||||
|
||||
newNode = updateSampleNode( skinnable, subControl, i, node );
|
||||
}
|
||||
|
|
|
@ -71,10 +71,6 @@ class QSK_EXPORT QskSkinlet
|
|||
void setOwnedBySkinnable( bool on );
|
||||
bool isOwnedBySkinnable() const;
|
||||
|
||||
void setAnimatorIndex( int );
|
||||
void resetAnimatorIndex();
|
||||
int animatorIndex() const;
|
||||
|
||||
// Helper functions for creating nodes
|
||||
|
||||
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
|
||||
|
|
|
@ -122,6 +122,16 @@ static inline T qskColor( const QskSkinnable* skinnable,
|
|||
aspect | QskAspect::Color, status ).value< T >();
|
||||
}
|
||||
|
||||
static inline constexpr QskAspect qskAnimatorAspect( const QskAspect aspect )
|
||||
{
|
||||
/*
|
||||
We do not need the extra bits that would slow down resolving
|
||||
the effective aspect in animatedHint.
|
||||
*/
|
||||
|
||||
return aspect.type() | aspect.subControl() | aspect.primitive();
|
||||
}
|
||||
|
||||
static inline void qskTriggerUpdates( QskAspect aspect, QQuickItem* item )
|
||||
{
|
||||
/*
|
||||
|
@ -238,6 +248,8 @@ class QskSkinnable::PrivateData
|
|||
QskSkinHintTable hintTable;
|
||||
QskHintAnimatorTable animators;
|
||||
|
||||
int sampleIndex = -1; // for the ugly QskSkinStateChanger hack
|
||||
|
||||
typedef std::map< QskAspect::Subcontrol, QskAspect::Subcontrol > ProxyMap;
|
||||
ProxyMap* subcontrolProxies = nullptr;
|
||||
|
||||
|
@ -983,11 +995,11 @@ QVariant QskSkinnable::animatedHint(
|
|||
|
||||
if ( !m_data->animators.isEmpty() )
|
||||
{
|
||||
const int index = effectiveSkinlet()->animatorIndex();
|
||||
const auto a = qskAnimatorAspect( aspect );
|
||||
|
||||
v = m_data->animators.currentValue( aspect, index );
|
||||
if ( !v.isValid() && index >= 0 )
|
||||
v = m_data->animators.currentValue( aspect, -1 );
|
||||
v = m_data->animators.currentValue( a, m_data->sampleIndex );
|
||||
if ( !v.isValid() && m_data->sampleIndex >= 0 )
|
||||
v = m_data->animators.currentValue( a, -1 );
|
||||
}
|
||||
|
||||
if ( status && v.isValid() )
|
||||
|
@ -1296,18 +1308,10 @@ void QskSkinnable::startHintTransition( QskAspect aspect, int index,
|
|||
v2.setValue( skin->graphicFilter( v2.toInt() ) );
|
||||
}
|
||||
|
||||
/*
|
||||
We do not need the extra bits that would slow down resolving
|
||||
the effective aspect in animatedHint.
|
||||
*/
|
||||
|
||||
aspect.clearStates();
|
||||
aspect.setSection( QskAspect::Body );
|
||||
aspect.setVariation( QskAspect::NoVariation );
|
||||
aspect.setAnimator( false );
|
||||
aspect = qskAnimatorAspect( aspect );
|
||||
|
||||
#if DEBUG_ANIMATOR
|
||||
qDebug() << aspect << animationHint.duration;
|
||||
qDebug() << aspect << index << animationHint.duration;
|
||||
#endif
|
||||
|
||||
auto animator = m_data->animators.animator( aspect, index );
|
||||
|
@ -1326,9 +1330,20 @@ void QskSkinnable::setSkinStateFlag( QskAspect::State stateFlag, bool on )
|
|||
setSkinStates( newState );
|
||||
}
|
||||
|
||||
void QskSkinnable::replaceSkinStates( QskAspect::States newStates )
|
||||
void QskSkinnable::replaceSkinStates(
|
||||
QskAspect::States newStates, int sampleIndex )
|
||||
{
|
||||
/*
|
||||
Hack time: we might need different hints for a specific instance
|
||||
of a subcontrol ( f.e the selected row in a list box ), what is not
|
||||
supported by QskAspect.
|
||||
|
||||
As a workaround we use QskSkinStateChanger, that sets/restores this state/index
|
||||
while retrieving the skin hints.
|
||||
*/
|
||||
|
||||
m_data->skinStates = newStates;
|
||||
m_data->sampleIndex = sampleIndex; // needed to find specific animators
|
||||
}
|
||||
|
||||
void QskSkinnable::addSkinStates( QskAspect::States states )
|
||||
|
|
|
@ -39,6 +39,7 @@ class QskGraphic;
|
|||
class QskSkin;
|
||||
class QskSkinlet;
|
||||
class QskSkinHintTable;
|
||||
class QskSkinStateChanger;
|
||||
|
||||
class QSK_EXPORT QskSkinHintStatus
|
||||
{
|
||||
|
@ -149,8 +150,6 @@ class QSK_EXPORT QskSkinnable
|
|||
void addSkinStates( QskAspect::States );
|
||||
void clearSkinStates( QskAspect::States );
|
||||
|
||||
void replaceSkinStates( QskAspect::States );
|
||||
|
||||
bool hasSkinState( QskAspect::State ) const;
|
||||
QskAspect::States skinStates() const;
|
||||
|
||||
|
@ -281,6 +280,9 @@ class QSK_EXPORT QskSkinnable
|
|||
QVariant interpolatedHint( QskAspect, QskSkinHintStatus* ) const;
|
||||
const QVariant& storedHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
|
||||
|
||||
friend class QskSkinStateChanger;
|
||||
void replaceSkinStates( QskAspect::States, int sampleIndex = -1 );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskSwipeView.h"
|
||||
|
||||
#include "QskEvent.h"
|
||||
#include "QskGesture.h"
|
||||
#include "QskPanGestureRecognizer.h"
|
||||
#include "QskStackBoxAnimator.h"
|
||||
#include "QskPlatform.h"
|
||||
|
||||
class QskSwipeView::PrivateData
|
||||
{
|
||||
public:
|
||||
QskPanGestureRecognizer panRecognizer;
|
||||
int duration = -1; // should be a skinHint
|
||||
};
|
||||
|
||||
QSK_SUBCONTROL( QskSwipeView, Panel )
|
||||
|
||||
QskSwipeView::QskSwipeView( QQuickItem* parent )
|
||||
: Inherited( parent )
|
||||
, m_data( new PrivateData() )
|
||||
{
|
||||
setFiltersChildMouseEvents( true );
|
||||
setAcceptedMouseButtons( Qt::LeftButton );
|
||||
|
||||
auto& recognizer = m_data->panRecognizer;
|
||||
|
||||
recognizer.setWatchedItem( this );
|
||||
|
||||
// should be skin hints, TODO
|
||||
recognizer.setOrientations( Qt::Horizontal );
|
||||
recognizer.setTimeout( 100 );
|
||||
|
||||
resetSwipeDistance();
|
||||
resetDuration();
|
||||
}
|
||||
|
||||
QskSwipeView::~QskSwipeView()
|
||||
{
|
||||
}
|
||||
|
||||
void QskSwipeView::setOrientation( Qt::Orientation orientation )
|
||||
{
|
||||
if ( orientation != this->orientation() )
|
||||
{
|
||||
m_data->panRecognizer.setOrientations( orientation );
|
||||
Q_EMIT orientationChanged( orientation );
|
||||
}
|
||||
}
|
||||
|
||||
Qt::Orientation QskSwipeView::orientation() const
|
||||
{
|
||||
return ( m_data->panRecognizer.orientations() == Qt::Vertical )
|
||||
? Qt::Vertical : Qt::Horizontal;
|
||||
}
|
||||
|
||||
int QskSwipeView::swipeDistance() const
|
||||
{
|
||||
return m_data->panRecognizer.minDistance();
|
||||
}
|
||||
|
||||
void QskSwipeView::setSwipeDistance( int distance )
|
||||
{
|
||||
const auto oldDistance = m_data->panRecognizer.minDistance();
|
||||
m_data->panRecognizer.setMinDistance( distance );
|
||||
|
||||
if ( oldDistance != m_data->panRecognizer.minDistance() )
|
||||
Q_EMIT swipeDistanceChanged( m_data->panRecognizer.minDistance() );
|
||||
}
|
||||
|
||||
void QskSwipeView::resetSwipeDistance()
|
||||
{
|
||||
setSwipeDistance( qRound( qskDpToPixels( 40 ) ) );
|
||||
}
|
||||
|
||||
int QskSwipeView::duration() const
|
||||
{
|
||||
return m_data->duration;
|
||||
}
|
||||
|
||||
void QskSwipeView::setDuration( int duration )
|
||||
{
|
||||
if ( duration != m_data->duration )
|
||||
{
|
||||
m_data->duration = duration;
|
||||
Q_EMIT durationChanged( duration );
|
||||
}
|
||||
}
|
||||
|
||||
void QskSwipeView::resetDuration()
|
||||
{
|
||||
setDuration( 500 );
|
||||
}
|
||||
|
||||
bool QskSwipeView::gestureFilter( const QQuickItem* item, const QEvent* event )
|
||||
{
|
||||
// see QskScrollBox.cpp
|
||||
|
||||
auto& recognizer = m_data->panRecognizer;
|
||||
|
||||
if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
auto mouseEvent = static_cast< const QMouseEvent* >( event );
|
||||
if ( recognizer.hasProcessedBefore( mouseEvent ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return recognizer.processEvent( item, event );
|
||||
|
||||
}
|
||||
|
||||
void QskSwipeView::gestureEvent( QskGestureEvent* event )
|
||||
{
|
||||
const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() );
|
||||
|
||||
if( gesture->type() == QskGesture::Pan && gesture->state() == QskGesture::Started )
|
||||
{
|
||||
if ( itemCount() <= 1 )
|
||||
return;
|
||||
|
||||
bool forwards;
|
||||
|
||||
if ( orientation() == Qt::Horizontal )
|
||||
forwards = gesture->angle() >= 90.0 && gesture->angle() <= 270.0;
|
||||
else
|
||||
forwards = gesture->angle() >= 180.0;
|
||||
|
||||
auto animator = qobject_cast< QskStackBoxAnimator1* >( this->animator() );
|
||||
|
||||
if ( animator == nullptr )
|
||||
animator = new QskStackBoxAnimator1( this );
|
||||
|
||||
if ( orientation() == Qt::Horizontal )
|
||||
animator->setDirection( forwards ? Qsk::LeftToRight : Qsk::RightToLeft );
|
||||
else
|
||||
animator->setDirection( forwards ? Qsk::TopToBottom : Qsk::BottomToTop );
|
||||
|
||||
animator->setDuration( m_data->duration );
|
||||
QskStackBox::setAnimator( animator );
|
||||
|
||||
auto newIndex = forwards ? currentIndex() + 1 : currentIndex() - 1;
|
||||
if( newIndex < 0 )
|
||||
newIndex += itemCount();
|
||||
|
||||
newIndex %= itemCount();
|
||||
|
||||
setCurrentIndex( newIndex );
|
||||
return;
|
||||
}
|
||||
|
||||
Inherited::gestureEvent( event );
|
||||
}
|
||||
|
||||
QskAspect::Subcontrol QskSwipeView::effectiveSubcontrol(
|
||||
QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == QskBox::Panel )
|
||||
return QskSwipeView::Panel;
|
||||
|
||||
return Inherited::effectiveSubcontrol( subControl );
|
||||
}
|
||||
|
||||
|
||||
#include "moc_QskSwipeView.cpp"
|
|
@ -0,0 +1,70 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_SWIPE_VIEW_H
|
||||
#define QSK_SWIPE_VIEW_H
|
||||
|
||||
#include "QskStackBox.h"
|
||||
|
||||
class QSK_EXPORT QskSwipeView : public QskStackBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( int duration READ duration
|
||||
WRITE setDuration RESET resetDuration NOTIFY durationChanged )
|
||||
|
||||
Q_PROPERTY( int swipeDistance READ swipeDistance
|
||||
WRITE setSwipeDistance RESET resetSwipeDistance NOTIFY swipeDistanceChanged )
|
||||
|
||||
Q_PROPERTY( Qt::Orientation orientation READ orientation
|
||||
WRITE setOrientation NOTIFY orientationChanged )
|
||||
|
||||
using Inherited = QskStackBox;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel )
|
||||
|
||||
QskSwipeView( QQuickItem* parent = nullptr );
|
||||
~QskSwipeView() override;
|
||||
|
||||
void setOrientation( Qt::Orientation );
|
||||
Qt::Orientation orientation() const;
|
||||
|
||||
// Duration is the time ( in ms ) used for changing between pages
|
||||
|
||||
int duration() const;
|
||||
void setDuration( int );
|
||||
void resetDuration();
|
||||
|
||||
/*
|
||||
Even if called "swipe view" we use a pan - no swipe - gesture.
|
||||
( = pages are moved before the gesture has been confirmed )
|
||||
|
||||
The swipe distance is the minimum distance in pixels of the pan gesture
|
||||
*/
|
||||
|
||||
int swipeDistance() const;
|
||||
void setSwipeDistance( int );
|
||||
void resetSwipeDistance();
|
||||
|
||||
QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol ) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void orientationChanged( Qt::Orientation );
|
||||
void durationChanged( int );
|
||||
void swipeDistanceChanged( int );
|
||||
|
||||
protected:
|
||||
bool gestureFilter( const QQuickItem*, const QEvent* ) override;
|
||||
void gestureEvent( QskGestureEvent* ) override;
|
||||
|
||||
private:
|
||||
void setAnimator( QskStackBoxAnimator* ) = delete;
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,53 +13,6 @@ QSK_QT_PRIVATE_BEGIN
|
|||
#include <private/qquickitem_p.h>
|
||||
QSK_QT_PRIVATE_END
|
||||
|
||||
static Qsk::Direction qskDirection(
|
||||
Qt::Orientation orientation, int from, int to, int itemCount )
|
||||
{
|
||||
Qsk::Direction direction;
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
{
|
||||
direction = Qsk::RightToLeft;
|
||||
|
||||
if ( to > from )
|
||||
{
|
||||
const bool isWrapping = ( from == 0 ) && ( to == itemCount - 1 );
|
||||
|
||||
if ( !isWrapping )
|
||||
direction = Qsk::LeftToRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool isWrapping = ( to == 0 ) && ( from == itemCount - 1 );
|
||||
|
||||
if ( isWrapping )
|
||||
direction = Qsk::LeftToRight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
direction = Qsk::BottomToTop;
|
||||
|
||||
if ( to > from )
|
||||
{
|
||||
const bool isWrapping = ( from == 0 ) && ( to == itemCount - 1 );
|
||||
|
||||
if ( !isWrapping )
|
||||
direction = Qsk::TopToBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool isWrapping = ( to == 0 ) && ( from == itemCount - 1 );
|
||||
|
||||
if ( isWrapping )
|
||||
direction = Qsk::TopToBottom;
|
||||
}
|
||||
}
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class RotationTransform : public QQuickTransform
|
||||
|
@ -240,7 +193,7 @@ void QskStackBoxAnimator::advance( qreal progress )
|
|||
|
||||
QskStackBoxAnimator1::QskStackBoxAnimator1( QskStackBox* parent )
|
||||
: QskStackBoxAnimator( parent )
|
||||
, m_orientation( Qt::Horizontal )
|
||||
, m_direction( Qsk::LeftToRight )
|
||||
, m_isDirty( false )
|
||||
, m_hasClip( false )
|
||||
{
|
||||
|
@ -251,27 +204,24 @@ QskStackBoxAnimator1::~QskStackBoxAnimator1()
|
|||
{
|
||||
}
|
||||
|
||||
void QskStackBoxAnimator1::setOrientation( Qt::Orientation orientation )
|
||||
void QskStackBoxAnimator1::setDirection( Qsk::Direction direction )
|
||||
{
|
||||
if ( m_orientation != orientation )
|
||||
if ( m_direction != direction )
|
||||
{
|
||||
stop();
|
||||
m_orientation = orientation;
|
||||
m_direction = direction;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::Orientation QskStackBoxAnimator1::orientation() const
|
||||
Qsk::Direction QskStackBoxAnimator1::direction() const
|
||||
{
|
||||
return m_orientation;
|
||||
return m_direction;
|
||||
}
|
||||
|
||||
void QskStackBoxAnimator1::setup()
|
||||
{
|
||||
auto stackBox = this->stackBox();
|
||||
|
||||
m_direction = qskDirection( m_orientation,
|
||||
startIndex(), endIndex(), stackBox->itemCount() );
|
||||
|
||||
m_hasClip = stackBox->clip();
|
||||
if ( !m_hasClip )
|
||||
stackBox->setClip( true );
|
||||
|
@ -283,7 +233,9 @@ void QskStackBoxAnimator1::setup()
|
|||
void QskStackBoxAnimator1::advanceIndex( qreal value )
|
||||
{
|
||||
auto stackBox = this->stackBox();
|
||||
const bool isHorizontal = m_orientation == Qt::Horizontal;
|
||||
|
||||
const bool isHorizontal = ( m_direction == Qsk::LeftToRight )
|
||||
|| ( m_direction == Qsk::RightToLeft );
|
||||
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
|
|
|
@ -49,14 +49,14 @@ class QSK_EXPORT QskStackBoxAnimator1 : public QskStackBoxAnimator
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation )
|
||||
Q_PROPERTY( Qsk::Direction direction READ direction WRITE setDirection )
|
||||
|
||||
public:
|
||||
QskStackBoxAnimator1( QskStackBox* );
|
||||
~QskStackBoxAnimator1() override;
|
||||
|
||||
void setOrientation( Qt::Orientation );
|
||||
Qt::Orientation orientation() const;
|
||||
void setDirection( Qsk::Direction );
|
||||
Qsk::Direction direction() const;
|
||||
|
||||
protected:
|
||||
bool eventFilter( QObject*, QEvent* ) override;
|
||||
|
@ -68,7 +68,6 @@ class QSK_EXPORT QskStackBoxAnimator1 : public QskStackBoxAnimator
|
|||
private:
|
||||
qreal m_itemOffset[ 2 ];
|
||||
|
||||
Qt::Orientation m_orientation : 2;
|
||||
Qsk::Direction m_direction : 4;
|
||||
bool m_isDirty : 1;
|
||||
bool m_hasClip : 1;
|
||||
|
|
Loading…
Reference in New Issue