Squashed commit of the following:
commit c6aec22cbdbed31955e70ea73fc6863d9369ba22
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 11:34:55 2023 +0200
wip
commit 473946633e150129a3ba67ea321bda23fcd0f5a7
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 11:28:23 2023 +0200
wip
commit 368f6edac32457d6a060c2f2e8a722c0d15bf35c
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 11:26:46 2023 +0200
wip
commit eccffafec006d471cc691f3d10143219ec263c63
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 11:22:01 2023 +0200
wip
commit c5ae5025d4ed0ea7184fb8b4fa97df7f3ca54c0e
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 10:53:09 2023 +0200
wip
commit 174b1d946067c5b5c0bf4a9982d7b3f7f717d263
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 10:51:54 2023 +0200
wip
commit 3e89f17ea971adc19c89cca0eb38dc3e973a090e
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 10:15:17 2023 +0200
wip
commit 499a13ab74501c24f1e0effe56dfb9cf9ff9bf63
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Tue Oct 24 10:03:55 2023 +0200
wip
commit 935ffc6d23dcd20a2c70898f28063fcdffea0795
Merge: 82f44d41 0cf60b41
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Mon Oct 23 10:49:32 2023 +0200
Merge branch 'drawer' into Overlay
commit 0cf60b414cee9a26fa5a53f05938e69ab39294d7
Merge: da76eb6d 2013338d
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Mon Oct 23 10:49:13 2023 +0200
Merge branch 'features/drawer' into drawer
commit 82f44d41c03f8cedab8b1bf3f1c164dfa65200cf
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Sun Oct 22 10:44:50 2023 +0200
wip
commit 3b254ff4551d457e1581b5dbb85fae2dcf55e2cc
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Sun Oct 22 10:43:15 2023 +0200
wip
commit 81e2bd8b35fb4a361e67f8a56870d99ea05ffa4d
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Sun Oct 22 09:50:07 2023 +0200
wip
commit 916f5ca888f675bdded0b97b763de02c8c6c12ff
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 17:08:53 2023 +0200
wip
commit b3e8fd4d7cf4eab710b7781bb1e9dc730548d51b
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 17:03:12 2023 +0200
wip
commit da76eb6df5353029856084e6306db32cb2712b6b
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 16:05:19 2023 +0200
wip
commit 72fbd0b6fad4b33e09643e5a2c67833f6e2c4abd
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 15:21:14 2023 +0200
wip
commit 7f899d67d6c8f7f98212030ac0e83e86581cefff
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 15:00:42 2023 +0200
wip
commit 72872cad2a0749afe9c901775c18459ac4cd956a
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 13:49:05 2023 +0200
wip
commit f16572e29a5fe8851479e2be6e04ff2d991e9ebd
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 13:40:47 2023 +0200
wip
commit 4300a2cf225554f93cb492062f89af51dcc5df64
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 13:34:37 2023 +0200
wip
commit c85150bcb98934b144e4453f12fbe37c4900049f
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 13:32:44 2023 +0200
wip
commit 00d069d134319b0c3fb6d192cba32c31640e161f
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 13:21:45 2023 +0200
wip
commit 36b4a203a3d761d4a3a5e17e1ba2deb7f9b37740
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 12:52:52 2023 +0200
wip
commit e27fa8af6ddc233862ec431e2c129299e24f4ee0
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 11:12:42 2023 +0200
wip
commit 579a45149a92ffef72c569c79456a3a2c753e37c
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date: Fri Oct 20 10:57:51 2023 +0200
QskSlideIn added
This commit is contained in:
parent
2013338dd4
commit
e4b9b8bd1b
|
@ -23,10 +23,6 @@ namespace
|
||||||
Drawer( Qt::Edge edge, QQuickItem* parent )
|
Drawer( Qt::Edge edge, QQuickItem* parent )
|
||||||
: QskDrawer( parent )
|
: QskDrawer( parent )
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
setAnimationHint( transitionAspect(), 1000 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setEdge( edge );
|
setEdge( edge );
|
||||||
|
|
||||||
auto content = new QskControl( this );
|
auto content = new QskControl( this );
|
||||||
|
|
|
@ -620,12 +620,6 @@ void Editor::setupDialogButtonBoxColors(
|
||||||
|
|
||||||
void Editor::setupDrawerMetrics()
|
void Editor::setupDrawerMetrics()
|
||||||
{
|
{
|
||||||
using Q = QskDrawer;
|
|
||||||
using A = QskAspect;
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
setAnimation( Q::Panel | A::Metric | A::Position, 200 );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupDrawerColors( QskAspect::Section, const QskFluent2Theme& )
|
void Editor::setupDrawerColors( QskAspect::Section, const QskFluent2Theme& )
|
||||||
|
@ -744,7 +738,6 @@ void Editor::setupListViewColors(
|
||||||
void Editor::setupMenuMetrics()
|
void Editor::setupMenuMetrics()
|
||||||
{
|
{
|
||||||
using Q = QskMenu;
|
using Q = QskMenu;
|
||||||
using A = QskAspect;
|
|
||||||
|
|
||||||
setPadding( Q::Panel, { 4, 6, 4, 6 } );
|
setPadding( Q::Panel, { 4, 6, 4, 6 } );
|
||||||
setBoxBorderMetrics( Q::Panel, 1 );
|
setBoxBorderMetrics( Q::Panel, 1 );
|
||||||
|
@ -758,14 +751,6 @@ void Editor::setupMenuMetrics()
|
||||||
|
|
||||||
setStrutSize( Q::Icon, 12, 12 );
|
setStrutSize( Q::Icon, 12, 12 );
|
||||||
setPadding( Q::Icon, { 8, 8, 0, 8 } );
|
setPadding( Q::Icon, { 8, 8, 0, 8 } );
|
||||||
|
|
||||||
#if 1
|
|
||||||
setPosition( Q::Panel, 1 );
|
|
||||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
|
||||||
|
|
||||||
// copied from Mat3 - what are the correct values for Fluent2 ???
|
|
||||||
setAnimation( Q::Panel | A::Metric, 150 );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupMenuColors(
|
void Editor::setupMenuColors(
|
||||||
|
@ -876,10 +861,14 @@ void Editor::setupPageIndicatorColors(
|
||||||
void Editor::setupPopup( const QskFluent2Theme& theme )
|
void Editor::setupPopup( const QskFluent2Theme& theme )
|
||||||
{
|
{
|
||||||
using Q = QskPopup;
|
using Q = QskPopup;
|
||||||
|
using A = QskAspect;
|
||||||
|
|
||||||
const auto& pal = theme.palette;
|
const auto& pal = theme.palette;
|
||||||
|
|
||||||
|
setHint( Q::Overlay | A::Style, true );
|
||||||
setGradient( Q::Overlay, pal.background.overlay.defaultColor );
|
setGradient( Q::Overlay, pal.background.overlay.defaultColor );
|
||||||
|
|
||||||
|
setAnimation( Q::Popup, 200 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupProgressBarMetrics()
|
void Editor::setupProgressBarMetrics()
|
||||||
|
|
|
@ -331,6 +331,8 @@ void Editor::setupPopup()
|
||||||
|
|
||||||
setHint( Q::Overlay | A::Style, true );
|
setHint( Q::Overlay | A::Style, true );
|
||||||
setGradient( Q::Overlay, stateLayerColor( m_pal.outline, 0.8 ) );
|
setGradient( Q::Overlay, stateLayerColor( m_pal.outline, 0.8 ) );
|
||||||
|
|
||||||
|
setAnimation( Q::Popup, qskDuration );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupMenu()
|
void Editor::setupMenu()
|
||||||
|
@ -378,10 +380,6 @@ void Editor::setupMenu()
|
||||||
setColor( Q::Text, m_pal.onSurface );
|
setColor( Q::Text, m_pal.onSurface );
|
||||||
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
||||||
|
|
||||||
setPosition( Q::Panel, 1 );
|
|
||||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
|
||||||
|
|
||||||
setAnimation( Q::Panel | A::Metric, 150 );
|
|
||||||
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,10 +806,6 @@ void Editor::setupDialogButtonBox()
|
||||||
|
|
||||||
void Editor::setupDrawer()
|
void Editor::setupDrawer()
|
||||||
{
|
{
|
||||||
using Q = QskDrawer;
|
|
||||||
using A = QskAspect;
|
|
||||||
|
|
||||||
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupSlider()
|
void Editor::setupSlider()
|
||||||
|
|
|
@ -409,7 +409,9 @@ void Editor::setupPopup()
|
||||||
using Q = QskPopup;
|
using Q = QskPopup;
|
||||||
|
|
||||||
setHint( Q::Overlay | A::Style, true );
|
setHint( Q::Overlay | A::Style, true );
|
||||||
setGradient( Q::Overlay, QColor( 220, 220, 220, 150 ) );
|
setGradient( Q::Overlay, qRgba( 220, 220, 220, 150 ) );
|
||||||
|
|
||||||
|
setAnimation( Q::Popup, 200 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupMenu()
|
void Editor::setupMenu()
|
||||||
|
@ -446,10 +448,6 @@ void Editor::setupMenu()
|
||||||
setGraphicRole( Q::Icon | Q::Disabled, DisabledSymbol );
|
setGraphicRole( Q::Icon | Q::Disabled, DisabledSymbol );
|
||||||
setGraphicRole( Q::Icon | Q::Selected, CursorSymbol );
|
setGraphicRole( Q::Icon | Q::Selected, CursorSymbol );
|
||||||
|
|
||||||
setPosition( Q::Panel, 1 );
|
|
||||||
setPosition( Q::Panel | QskPopup::Closed, 0 );
|
|
||||||
|
|
||||||
setAnimation( Q::Panel | A::Metric, 150 );
|
|
||||||
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
setAnimation( Q::Cursor | A::Position | A::Metric, 75, QEasingCurve::OutCubic );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,10 +759,6 @@ void Editor::setupDialogButtonBox()
|
||||||
|
|
||||||
void Editor::setupDrawer()
|
void Editor::setupDrawer()
|
||||||
{
|
{
|
||||||
using A = QskAspect;
|
|
||||||
using Q = QskDrawer;
|
|
||||||
|
|
||||||
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTabButton()
|
void Editor::setupTabButton()
|
||||||
|
|
|
@ -210,6 +210,7 @@ list(APPEND HEADERS
|
||||||
controls/QskQuickItem.h
|
controls/QskQuickItem.h
|
||||||
controls/QskRadioBox.h
|
controls/QskRadioBox.h
|
||||||
controls/QskRadioBoxSkinlet.h
|
controls/QskRadioBoxSkinlet.h
|
||||||
|
controls/QskSlideIn.h
|
||||||
controls/QskScrollArea.h
|
controls/QskScrollArea.h
|
||||||
controls/QskScrollBox.h
|
controls/QskScrollBox.h
|
||||||
controls/QskScrollView.h
|
controls/QskScrollView.h
|
||||||
|
@ -316,6 +317,7 @@ list(APPEND SOURCES
|
||||||
controls/QskScrollBox.cpp
|
controls/QskScrollBox.cpp
|
||||||
controls/QskScrollView.cpp
|
controls/QskScrollView.cpp
|
||||||
controls/QskScrollViewSkinlet.cpp
|
controls/QskScrollViewSkinlet.cpp
|
||||||
|
controls/QskSlideIn.cpp
|
||||||
controls/QskRadioBox.cpp
|
controls/QskRadioBox.cpp
|
||||||
controls/QskRadioBoxSkinlet.cpp
|
controls/QskRadioBoxSkinlet.cpp
|
||||||
controls/QskSegmentedBar.cpp
|
controls/QskSegmentedBar.cpp
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "QskDrawer.h"
|
#include "QskDrawer.h"
|
||||||
#include "QskAspect.h"
|
#include "QskAspect.h"
|
||||||
#include "QskAnimationHint.h"
|
|
||||||
#include "QskQuick.h"
|
#include "QskQuick.h"
|
||||||
#include "QskEvent.h"
|
#include "QskEvent.h"
|
||||||
|
|
||||||
|
@ -15,24 +14,13 @@
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
#include <qstylehints.h>
|
#include <qstylehints.h>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
|
||||||
#include <private/qquickitem_p.h>
|
|
||||||
#include <private/qquickitemchangelistener_p.h>
|
|
||||||
QSK_QT_PRIVATE_END
|
|
||||||
|
|
||||||
/*
|
|
||||||
Only used for the sliding in animation. Do we want to
|
|
||||||
introduce a specific panel as background ???
|
|
||||||
*/
|
|
||||||
QSK_SUBCONTROL( QskDrawer, Panel )
|
|
||||||
|
|
||||||
static inline qreal qskDefaultDragMargin()
|
static inline qreal qskDefaultDragMargin()
|
||||||
{
|
{
|
||||||
// a skin hint ???
|
// a skin hint ???
|
||||||
return QGuiApplication::styleHints()->startDragDistance();
|
return QGuiApplication::styleHints()->startDragDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskCatchMouseEvents( QQuickItem* item )
|
static inline void qskCatchMouseEvents( QQuickItem* item )
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
// manipulating other items - do we really want to do this ?
|
// manipulating other items - do we really want to do this ?
|
||||||
|
@ -63,13 +51,12 @@ static bool qskCheckDirection( Qt::Edge edge, const QskPanGesture* gesture )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qskLayoutDrawer( const QRectF& rect, QskDrawer* drawer )
|
static inline QRectF qskAlignedToEdge(
|
||||||
|
const QRectF& rect, const QSizeF& size, Qt::Edge edge )
|
||||||
{
|
{
|
||||||
const auto size = qskSizeConstraint( drawer, Qt::PreferredSize );
|
|
||||||
|
|
||||||
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
||||||
|
|
||||||
switch( drawer->edge() )
|
switch( edge )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
{
|
{
|
||||||
|
@ -99,91 +86,7 @@ static void qskLayoutDrawer( const QRectF& rect, QskDrawer* drawer )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer->setGeometry( r );
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
static inline QRectF qskSlidingRect(
|
|
||||||
const QSizeF& size, Qt::Edge edge, qreal ratio )
|
|
||||||
{
|
|
||||||
auto x = 0.0;
|
|
||||||
auto y = 0.0;
|
|
||||||
|
|
||||||
ratio = 1.0 - ratio;
|
|
||||||
|
|
||||||
switch( edge )
|
|
||||||
{
|
|
||||||
case Qt::LeftEdge:
|
|
||||||
x = -ratio * size.width();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::RightEdge:
|
|
||||||
x = ratio * size.width();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::TopEdge:
|
|
||||||
y = -ratio * size.height();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
|
||||||
y = ratio * size.height();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QRectF( x, y, size.width(), size.height() );
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class GeometryListener final : public QQuickItemChangeListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GeometryListener( QQuickItem* item, QQuickItem* adjustedItem )
|
|
||||||
: m_item( item )
|
|
||||||
, m_adjustedItem( adjustedItem )
|
|
||||||
{
|
|
||||||
adjust();
|
|
||||||
setEnabled( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
~GeometryListener()
|
|
||||||
{
|
|
||||||
setEnabled( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void itemGeometryChanged( QQuickItem*,
|
|
||||||
QQuickGeometryChange, const QRectF& ) override
|
|
||||||
{
|
|
||||||
adjust();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void adjust()
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
const auto pos = m_adjustedItem->mapFromItem( m_item, QPointF() );
|
|
||||||
qskSetItemGeometry( m_adjustedItem,
|
|
||||||
pos.x(), pos.y(), m_item->width(), m_item->height() );
|
|
||||||
#else
|
|
||||||
qskLayoutDrawer( QRectF( QPointF(), m_item->size() ),
|
|
||||||
qobject_cast< QskDrawer* >( m_adjustedItem ) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEnabled( bool on )
|
|
||||||
{
|
|
||||||
const auto changeTypes = QQuickItemPrivate::Geometry;
|
|
||||||
|
|
||||||
auto d = QQuickItemPrivate::get( m_item );
|
|
||||||
if ( on )
|
|
||||||
d->addItemChangeListener( this, changeTypes );
|
|
||||||
else
|
|
||||||
d->removeItemChangeListener( this, changeTypes );
|
|
||||||
}
|
|
||||||
|
|
||||||
QQuickItem* m_item;
|
|
||||||
QQuickItem* m_adjustedItem;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -243,18 +146,8 @@ namespace
|
||||||
class QskDrawer::PrivateData
|
class QskDrawer::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline void resetListener( QskDrawer* drawer )
|
|
||||||
{
|
|
||||||
delete listener;
|
|
||||||
listener = nullptr;
|
|
||||||
|
|
||||||
if ( drawer->parentItem() && drawer->isVisible() )
|
|
||||||
listener = new GeometryListener( drawer->parentItem(), drawer );
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::Edge edge = Qt::LeftEdge;
|
Qt::Edge edge = Qt::LeftEdge;
|
||||||
GestureRecognizer* gestureRecognizer = nullptr;
|
GestureRecognizer* gestureRecognizer = nullptr;
|
||||||
GeometryListener* listener = nullptr;
|
|
||||||
|
|
||||||
qreal dragMargin = qskDefaultDragMargin();
|
qreal dragMargin = qskDefaultDragMargin();
|
||||||
};
|
};
|
||||||
|
@ -269,25 +162,11 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
|
||||||
|
|
||||||
setAutoLayoutChildren( true );
|
setAutoLayoutChildren( true );
|
||||||
setInteractive( true );
|
setInteractive( true );
|
||||||
|
setAdjustingToParentGeometry( true );
|
||||||
setPopupFlag( PopupFlag::CloseOnPressOutside, true );
|
|
||||||
setTransitionAspect( Panel | QskAspect::Position | QskAspect::Metric );
|
|
||||||
|
|
||||||
/*
|
|
||||||
The drawer wants to be on top of the parent - not being
|
|
||||||
layouted into its layoutRect(). So we opt out and do
|
|
||||||
the layout updates manually.
|
|
||||||
*/
|
|
||||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
|
||||||
m_data->resetListener( this );
|
|
||||||
|
|
||||||
connect( this, &QskPopup::openChanged, this, &QskDrawer::setSliding );
|
|
||||||
connect( this, &QskPopup::transitioningChanged, this, &QskDrawer::setIntermediate );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskDrawer::~QskDrawer()
|
QskDrawer::~QskDrawer()
|
||||||
{
|
{
|
||||||
delete m_data->listener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::Edge QskDrawer::edge() const
|
Qt::Edge QskDrawer::edge() const
|
||||||
|
@ -352,6 +231,24 @@ qreal QskDrawer::dragMargin() const
|
||||||
return m_data->dragMargin;
|
return m_data->dragMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QskDrawer::event( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::PolishRequest )
|
||||||
|
{
|
||||||
|
if ( isAdjustingToParentGeometry() && parentItem() )
|
||||||
|
{
|
||||||
|
auto r = qskItemRect( parentItem() );
|
||||||
|
r = qskAlignedToEdge( r, sizeConstraint( Qt::PreferredSize ), edge() );
|
||||||
|
|
||||||
|
setGeometry( r );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
|
|
||||||
void QskDrawer::keyPressEvent( QKeyEvent* event )
|
void QskDrawer::keyPressEvent( QKeyEvent* event )
|
||||||
{
|
{
|
||||||
if ( isOpen() )
|
if ( isOpen() )
|
||||||
|
@ -432,18 +329,6 @@ void QskDrawer::gestureEvent( QskGestureEvent* event )
|
||||||
Inherited::gestureEvent( event );
|
Inherited::gestureEvent( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
|
||||||
{
|
|
||||||
qreal ratio;
|
|
||||||
|
|
||||||
if ( isTransitioning() )
|
|
||||||
ratio = metric( transitionAspect() );
|
|
||||||
else
|
|
||||||
ratio = isOpen() ? 1.0 : 0.0;
|
|
||||||
|
|
||||||
return qskSlidingRect( size, m_data->edge, ratio );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
||||||
const QQuickItem::ItemChangeData& value )
|
const QQuickItem::ItemChangeData& value )
|
||||||
{
|
{
|
||||||
|
@ -456,85 +341,9 @@ void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
||||||
if ( parentItem() && isInteractive() )
|
if ( parentItem() && isInteractive() )
|
||||||
qskCatchMouseEvents( parentItem() );
|
qskCatchMouseEvents( parentItem() );
|
||||||
|
|
||||||
m_data->resetListener( this );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QQuickItem::ItemVisibleHasChanged:
|
|
||||||
{
|
|
||||||
m_data->resetListener( this );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskDrawer::setSliding( bool on )
|
|
||||||
{
|
|
||||||
const qreal from = on ? 0.0 : 1.0;
|
|
||||||
const qreal to = on ? 1.0 : 0.0;
|
|
||||||
|
|
||||||
const auto aspect = transitionAspect();
|
|
||||||
|
|
||||||
auto hint = animationHint( aspect );
|
|
||||||
hint.updateFlags = QskAnimationHint::UpdatePolish;
|
|
||||||
|
|
||||||
startTransition( aspect, hint, from, to );
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF QskDrawer::clipRect() const
|
|
||||||
{
|
|
||||||
if ( !isTransitioning() )
|
|
||||||
return Inherited::clipRect();
|
|
||||||
|
|
||||||
/*
|
|
||||||
When fading we want to clip against the edge, where the drawer
|
|
||||||
slides in/out. However the size of the drawer is often smaller than the
|
|
||||||
one of the parent and we would clip the overlay node
|
|
||||||
and all content, that is located outside the drawer geometry.
|
|
||||||
|
|
||||||
So we expand the clip rectangle to "unbounded" at the other edges.
|
|
||||||
|
|
||||||
Note, that clipping against "rounded" rectangles can't be done
|
|
||||||
properly by overloading clipRect. We would have to manipulate the clip node
|
|
||||||
manually - like it is done in QskScrollArea. TODO ..
|
|
||||||
*/
|
|
||||||
constexpr qreal d = std::numeric_limits< short >::max();
|
|
||||||
|
|
||||||
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
|
||||||
|
|
||||||
switch( m_data->edge )
|
|
||||||
{
|
|
||||||
case Qt::LeftEdge:
|
|
||||||
r.setLeft( 0.0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::RightEdge:
|
|
||||||
r.setRight( width() );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::TopEdge:
|
|
||||||
r.setTop( 0.0 );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
|
||||||
r.setBottom( height() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskDrawer::setIntermediate( bool on )
|
|
||||||
{
|
|
||||||
setClip( on );
|
|
||||||
Q_EMIT focusIndicatorRectChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF QskDrawer::focusIndicatorRect() const
|
|
||||||
{
|
|
||||||
if ( isTransitioning() )
|
|
||||||
return QRectF();
|
|
||||||
|
|
||||||
return Inherited::focusIndicatorRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_QskDrawer.cpp"
|
#include "moc_QskDrawer.cpp"
|
||||||
|
|
|
@ -6,14 +6,13 @@
|
||||||
#ifndef QSK_DRAWER_H
|
#ifndef QSK_DRAWER_H
|
||||||
#define QSK_DRAWER_H
|
#define QSK_DRAWER_H
|
||||||
|
|
||||||
#include "QskPopup.h"
|
#include "QskSlideIn.h"
|
||||||
#include <qnamespace.h>
|
|
||||||
|
|
||||||
class QSK_EXPORT QskDrawer : public QskPopup
|
class QSK_EXPORT QskDrawer : public QskSlideIn
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
using Inherited = QskPopup;
|
using Inherited = QskSlideIn;
|
||||||
|
|
||||||
Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged )
|
Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged )
|
||||||
|
|
||||||
|
@ -24,13 +23,11 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
||||||
WRITE setInteractive NOTIFY interactiveChanged )
|
WRITE setInteractive NOTIFY interactiveChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSK_SUBCONTROLS( Panel )
|
|
||||||
|
|
||||||
QskDrawer( QQuickItem* = nullptr );
|
QskDrawer( QQuickItem* = nullptr );
|
||||||
~QskDrawer() override;
|
~QskDrawer() override;
|
||||||
|
|
||||||
void setEdge( Qt::Edge );
|
void setEdge( Qt::Edge );
|
||||||
Qt::Edge edge() const;
|
Qt::Edge edge() const override final;
|
||||||
|
|
||||||
void setInteractive( bool );
|
void setInteractive( bool );
|
||||||
bool isInteractive() const;
|
bool isInteractive() const;
|
||||||
|
@ -39,26 +36,19 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
||||||
void resetDragMargin();
|
void resetDragMargin();
|
||||||
qreal dragMargin() const;
|
qreal dragMargin() const;
|
||||||
|
|
||||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
|
||||||
|
|
||||||
QRectF clipRect() const override;
|
|
||||||
QRectF focusIndicatorRect() const override;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void edgeChanged( Qt::Edge );
|
void edgeChanged( Qt::Edge );
|
||||||
void dragMarginChanged( qreal );
|
void dragMarginChanged( qreal );
|
||||||
void interactiveChanged( bool );
|
void interactiveChanged( bool );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool event( QEvent* ) override;
|
||||||
|
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
void gestureEvent( QskGestureEvent* ) override;
|
void gestureEvent( QskGestureEvent* ) override;
|
||||||
void keyPressEvent( QKeyEvent* ) override;
|
void keyPressEvent( QKeyEvent* ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSliding( bool );
|
|
||||||
|
|
||||||
void setIntermediate( bool );
|
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,6 @@ QskMenu::QskMenu( QQuickItem* parent )
|
||||||
, m_data( new PrivateData )
|
, m_data( new PrivateData )
|
||||||
{
|
{
|
||||||
setModal( true );
|
setModal( true );
|
||||||
setTransitionAspect( QskMenu::Panel | QskAspect::Position | QskAspect::Metric );
|
|
||||||
|
|
||||||
setPopupFlag( QskPopup::CloseOnPressOutside, true );
|
setPopupFlag( QskPopup::CloseOnPressOutside, true );
|
||||||
setPopupFlag( QskPopup::DeleteOnClose, true );
|
setPopupFlag( QskPopup::DeleteOnClose, true );
|
||||||
|
|
|
@ -236,8 +236,8 @@ QSGNode* QskMenuSkinlet::updateSubNode(
|
||||||
|
|
||||||
auto slideInNode = QskSGNode::ensureNode< QskSlideInNode >( node );
|
auto slideInNode = QskSGNode::ensureNode< QskSlideInNode >( node );
|
||||||
|
|
||||||
const auto progress = popup->metric( popup->transitionAspect() );
|
slideInNode->updateTranslation(
|
||||||
slideInNode->updateTranslation( rect, Qt::TopEdge, progress );
|
rect, Qt::TopEdge, popup->transitioningFactor() );
|
||||||
|
|
||||||
auto contentsNode = updateContentsNode( popup, slideInNode->contentsNode() );
|
auto contentsNode = updateContentsNode( popup, slideInNode->contentsNode() );
|
||||||
slideInNode->setContentsNode( contentsNode );
|
slideInNode->setContentsNode( contentsNode );
|
||||||
|
|
|
@ -19,9 +19,16 @@ QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( QskPopup, Popup )
|
||||||
QSK_SUBCONTROL( QskPopup, Overlay )
|
QSK_SUBCONTROL( QskPopup, Overlay )
|
||||||
|
|
||||||
QSK_SYSTEM_STATE( QskPopup, Closed, QskAspect::FirstSystemState << 1 )
|
QSK_SYSTEM_STATE( QskPopup, Closed, QskAspect::FirstSystemState << 1 )
|
||||||
|
|
||||||
|
static QskAspect qskTransitioningAspect()
|
||||||
|
{
|
||||||
|
return QskPopup::Popup | QskAspect::Metric;
|
||||||
|
}
|
||||||
|
|
||||||
static void qskSetFocus( QQuickItem* item, bool on )
|
static void qskSetFocus( QQuickItem* item, bool on )
|
||||||
{
|
{
|
||||||
if ( item->window() == nullptr )
|
if ( item->window() == nullptr )
|
||||||
|
@ -76,6 +83,23 @@ static bool qskReplayMousePress()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qskStartTransition( QskPopup* popup, bool on )
|
||||||
|
{
|
||||||
|
const auto aspect = qskTransitioningAspect();
|
||||||
|
|
||||||
|
auto hint = popup->animationHint( aspect.subControl() );
|
||||||
|
|
||||||
|
if ( hint.isValid() )
|
||||||
|
{
|
||||||
|
hint.updateFlags = QskAnimationHint::UpdatePolish | QskAnimationHint::UpdateNode;
|
||||||
|
|
||||||
|
const qreal from = on ? 0.0 : 1.0;
|
||||||
|
const qreal to = on ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
popup->startTransition( aspect, hint, from, to );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class InputGrabber final : public QskInputGrabber
|
class InputGrabber final : public QskInputGrabber
|
||||||
|
@ -139,7 +163,6 @@ class QskPopup::PrivateData
|
||||||
InputGrabber* inputGrabber = nullptr;
|
InputGrabber* inputGrabber = nullptr;
|
||||||
|
|
||||||
uint priority = 0;
|
uint priority = 0;
|
||||||
QskAspect transitionAspect;
|
|
||||||
|
|
||||||
int flags : 4;
|
int flags : 4;
|
||||||
bool isModal : 1;
|
bool isModal : 1;
|
||||||
|
@ -217,6 +240,8 @@ void QskPopup::setOpen( bool on )
|
||||||
else
|
else
|
||||||
Q_EMIT closed();
|
Q_EMIT closed();
|
||||||
|
|
||||||
|
qskStartTransition( this, on );
|
||||||
|
|
||||||
if ( isTransitioning() )
|
if ( isTransitioning() )
|
||||||
{
|
{
|
||||||
Q_EMIT transitioningChanged( true );
|
Q_EMIT transitioningChanged( true );
|
||||||
|
@ -240,7 +265,15 @@ bool QskPopup::isOpen() const
|
||||||
|
|
||||||
bool QskPopup::isTransitioning() const
|
bool QskPopup::isTransitioning() const
|
||||||
{
|
{
|
||||||
return runningHintAnimator( m_data->transitionAspect ) != nullptr;
|
return runningHintAnimator( qskTransitioningAspect() ) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskPopup::transitioningFactor() const
|
||||||
|
{
|
||||||
|
if ( auto animator = runningHintAnimator( qskTransitioningAspect() ) )
|
||||||
|
return animator->currentValue().value< qreal >();
|
||||||
|
|
||||||
|
return isOpen() ? 1.0 : 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskPopup::overlayRect() const
|
QRectF QskPopup::overlayRect() const
|
||||||
|
@ -291,44 +324,23 @@ void QskPopup::updateInputGrabber()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QskAspect QskPopup::transitionAspect() const
|
|
||||||
{
|
|
||||||
return m_data->transitionAspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskPopup::setTransitionAspect( QskAspect aspect )
|
|
||||||
{
|
|
||||||
auto transitionAspect = aspect;
|
|
||||||
transitionAspect.clearStates(); // animated values are always stateless
|
|
||||||
|
|
||||||
if ( transitionAspect == m_data->transitionAspect )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( isTransitioning() )
|
|
||||||
{
|
|
||||||
// stop the running animation TODO ...
|
|
||||||
}
|
|
||||||
|
|
||||||
m_data->transitionAspect = transitionAspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QskPopup::isTransitionAccepted( QskAspect aspect ) const
|
bool QskPopup::isTransitionAccepted( QskAspect aspect ) const
|
||||||
{
|
{
|
||||||
if ( isVisible() )
|
if ( isVisible() && !isInitiallyPainted() )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Usually we suppress transitions, when a control has never been
|
||||||
|
painted before as there is no valid starting point. Popups are
|
||||||
|
different as we want to have smooth fade/slide appearances.
|
||||||
|
*/
|
||||||
if ( ( aspect.value() == 0 ) )
|
if ( ( aspect.value() == 0 ) )
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( aspect == m_data->transitionAspect )
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ( aspect.isColor() )
|
if ( aspect.subControl() == effectiveSubcontrol( QskPopup::Popup ) )
|
||||||
{
|
return true;
|
||||||
if ( aspect.subControl() == effectiveSubcontrol( QskPopup::Overlay ) )
|
|
||||||
return true;
|
if ( aspect.subControl() == effectiveSubcontrol( QskPopup::Overlay ) )
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::isTransitionAccepted( aspect );
|
return Inherited::isTransitionAccepted( aspect );
|
||||||
|
@ -472,10 +484,10 @@ bool QskPopup::event( QEvent* event )
|
||||||
}
|
}
|
||||||
case QskEvent::Animator:
|
case QskEvent::Animator:
|
||||||
{
|
{
|
||||||
const auto animtorEvent = static_cast< QskAnimatorEvent* >( event );
|
const auto animatorEvent = static_cast< QskAnimatorEvent* >( event );
|
||||||
|
|
||||||
if ( ( animtorEvent->state() == QskAnimatorEvent::Terminated )
|
if ( ( animatorEvent->state() == QskAnimatorEvent::Terminated )
|
||||||
&& ( animtorEvent->aspect() == m_data->transitionAspect ) )
|
&& ( animatorEvent->aspect() == qskTransitioningAspect() ) )
|
||||||
{
|
{
|
||||||
if ( !isOpen() )
|
if ( !isOpen() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,7 +24,7 @@ class QSK_EXPORT QskPopup : public QskControl
|
||||||
using Inherited = QskControl;
|
using Inherited = QskControl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSK_SUBCONTROLS( Overlay )
|
QSK_SUBCONTROLS( Popup, Overlay )
|
||||||
QSK_STATES( Closed )
|
QSK_STATES( Closed )
|
||||||
|
|
||||||
enum PopupFlag
|
enum PopupFlag
|
||||||
|
@ -56,11 +56,8 @@ class QSK_EXPORT QskPopup : public QskControl
|
||||||
void setPriority( uint );
|
void setPriority( uint );
|
||||||
uint priority() const;
|
uint priority() const;
|
||||||
|
|
||||||
// transitions between open/closed states
|
|
||||||
QskAspect transitionAspect() const;
|
|
||||||
void setTransitionAspect( QskAspect );
|
|
||||||
|
|
||||||
bool isTransitioning() const;
|
bool isTransitioning() const;
|
||||||
|
qreal transitioningFactor() const;
|
||||||
|
|
||||||
bool isOpen() const;
|
bool isOpen() const;
|
||||||
bool isClosed() const;
|
bool isClosed() const;
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
|
|
||||||
#include "QskPopupSkinlet.h"
|
#include "QskPopupSkinlet.h"
|
||||||
#include "QskPopup.h"
|
#include "QskPopup.h"
|
||||||
|
#include "QskRgbValue.h"
|
||||||
|
|
||||||
|
static inline QRgb qskInterpolatedRgb( QRgb rgb, qreal factor )
|
||||||
|
{
|
||||||
|
return QskRgb::toTransparent( rgb, qRound( factor * qAlpha( rgb ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
||||||
: Inherited( skin )
|
: Inherited( skin )
|
||||||
|
@ -28,13 +34,43 @@ QRectF QskPopupSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||||
QSGNode* QskPopupSkinlet::updateSubNode(
|
QSGNode* QskPopupSkinlet::updateSubNode(
|
||||||
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||||
{
|
{
|
||||||
|
const auto popup = static_cast< const QskPopup* >( skinnable );
|
||||||
|
|
||||||
switch ( nodeRole )
|
switch ( nodeRole )
|
||||||
{
|
{
|
||||||
case OverlayRole:
|
case OverlayRole:
|
||||||
return updateBoxNode( skinnable, node, QskPopup::Overlay );
|
return updateOverlayNode( popup, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSGNode* QskPopupSkinlet::updateOverlayNode(
|
||||||
|
const QskPopup* popup, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
using Q = QskPopup;
|
||||||
|
|
||||||
|
const auto factor = popup->transitioningFactor();
|
||||||
|
if ( factor <= 0.0 )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto rect = popup->subControlRect( Q::Overlay );
|
||||||
|
if ( rect.isEmpty() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto gradient = popup->gradientHint( Q::Overlay );
|
||||||
|
|
||||||
|
if ( gradient.isVisible() && factor != 1.0 )
|
||||||
|
{
|
||||||
|
auto stops = gradient.stops();
|
||||||
|
|
||||||
|
for ( auto& stop : stops )
|
||||||
|
stop.setRgb( qskInterpolatedRgb( stop.rgb(), factor ) );
|
||||||
|
|
||||||
|
gradient.setStops( stops );
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateBoxNode( popup, node, rect, gradient, QskPopup::Overlay );
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_QskPopupSkinlet.cpp"
|
#include "moc_QskPopupSkinlet.cpp"
|
||||||
|
|
|
@ -0,0 +1,236 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskSlideIn.h"
|
||||||
|
#include "QskAnimationHint.h"
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qquickitem_p.h>
|
||||||
|
#include <private/qquickitemchangelistener_p.h>
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Using an eventFilter for QskEvent::GeometryChange instead ???
|
||||||
|
|
||||||
|
class GeometryListener final : public QQuickItemChangeListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GeometryListener( QQuickItem* item, QQuickItem* adjustedItem )
|
||||||
|
: m_item( item )
|
||||||
|
, m_adjustedItem( adjustedItem )
|
||||||
|
{
|
||||||
|
adjust();
|
||||||
|
setEnabled( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
~GeometryListener()
|
||||||
|
{
|
||||||
|
setEnabled( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void itemGeometryChanged( QQuickItem*,
|
||||||
|
QQuickGeometryChange, const QRectF& ) override
|
||||||
|
{
|
||||||
|
adjust();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void adjust()
|
||||||
|
{
|
||||||
|
QEvent event( QEvent::PolishRequest );
|
||||||
|
QCoreApplication::sendEvent( m_adjustedItem, &event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEnabled( bool on )
|
||||||
|
{
|
||||||
|
const auto changeTypes = QQuickItemPrivate::Geometry;
|
||||||
|
|
||||||
|
auto d = QQuickItemPrivate::get( m_item );
|
||||||
|
if ( on )
|
||||||
|
d->addItemChangeListener( this, changeTypes );
|
||||||
|
else
|
||||||
|
d->removeItemChangeListener( this, changeTypes );
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* m_item;
|
||||||
|
QQuickItem* m_adjustedItem;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class QskSlideIn::PrivateData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline void resetListener( QskSlideIn* slideIn )
|
||||||
|
{
|
||||||
|
delete listener;
|
||||||
|
listener = nullptr;
|
||||||
|
|
||||||
|
if ( adjustingToParentGeometry )
|
||||||
|
{
|
||||||
|
if ( slideIn->parentItem() && slideIn->isVisible() )
|
||||||
|
listener = new GeometryListener( slideIn->parentItem(), slideIn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool adjustingToParentGeometry = false;
|
||||||
|
GeometryListener* listener = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskSlideIn::QskSlideIn( QQuickItem* parentItem )
|
||||||
|
: Inherited ( parentItem )
|
||||||
|
, m_data( new PrivateData )
|
||||||
|
{
|
||||||
|
setPopupFlag( PopupFlag::CloseOnPressOutside, true );
|
||||||
|
|
||||||
|
/*
|
||||||
|
A slider wants to be on top of its parent - not being
|
||||||
|
layouted into its layoutRect(). So we opt out and do
|
||||||
|
the layout updates manually.
|
||||||
|
*/
|
||||||
|
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||||
|
|
||||||
|
connect( this, &QskPopup::transitioningChanged,
|
||||||
|
this, &QskSlideIn::setIntermediate );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskSlideIn::~QskSlideIn()
|
||||||
|
{
|
||||||
|
delete m_data->listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSlideIn::setAdjustingToParentGeometry( bool on )
|
||||||
|
{
|
||||||
|
if ( on != m_data->adjustingToParentGeometry )
|
||||||
|
{
|
||||||
|
m_data->adjustingToParentGeometry = on;
|
||||||
|
m_data->resetListener( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskSlideIn::isAdjustingToParentGeometry() const
|
||||||
|
{
|
||||||
|
return m_data->adjustingToParentGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSlideIn::itemChange( QQuickItem::ItemChange change,
|
||||||
|
const QQuickItem::ItemChangeData& value )
|
||||||
|
{
|
||||||
|
Inherited::itemChange( change, value );
|
||||||
|
|
||||||
|
switch( static_cast< int >( change ) )
|
||||||
|
{
|
||||||
|
case QQuickItem::ItemParentHasChanged:
|
||||||
|
case QQuickItem::ItemVisibleHasChanged:
|
||||||
|
{
|
||||||
|
m_data->resetListener( this );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskSlideIn::event( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::PolishRequest )
|
||||||
|
{
|
||||||
|
// isVisible ???
|
||||||
|
if ( m_data->adjustingToParentGeometry && parentItem() )
|
||||||
|
{
|
||||||
|
setSize( parentItem()->size() );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::event( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSlideIn::setIntermediate( bool on )
|
||||||
|
{
|
||||||
|
setClip( on );
|
||||||
|
Q_EMIT focusIndicatorRectChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskSlideIn::focusIndicatorRect() const
|
||||||
|
{
|
||||||
|
if ( isTransitioning() )
|
||||||
|
return QRectF();
|
||||||
|
|
||||||
|
return Inherited::focusIndicatorRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskSlideIn::clipRect() const
|
||||||
|
{
|
||||||
|
if ( !isTransitioning() )
|
||||||
|
return Inherited::clipRect();
|
||||||
|
|
||||||
|
/*
|
||||||
|
When sliding we want to clip against the edge, where the drawer
|
||||||
|
slides in/out. However the size of the slidein is often smaller than the
|
||||||
|
one of the parent and we would clip the overlay node
|
||||||
|
and all content, that is located outside the drawer geometry.
|
||||||
|
|
||||||
|
So we expand the clip rectangle to "unbounded" at the other edges.
|
||||||
|
|
||||||
|
Note, that clipping against "rounded" rectangles can't be done
|
||||||
|
properly by overloading clipRect. We would have to manipulate the clip node
|
||||||
|
manually - like it is done in QskScrollArea. TODO ..
|
||||||
|
*/
|
||||||
|
constexpr qreal d = std::numeric_limits< short >::max();
|
||||||
|
|
||||||
|
QRectF r( -d, -d, 2.0 * d, 2.0 * d );
|
||||||
|
|
||||||
|
switch( edge() )
|
||||||
|
{
|
||||||
|
case Qt::LeftEdge:
|
||||||
|
r.setLeft( 0.0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::RightEdge:
|
||||||
|
r.setRight( width() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::TopEdge:
|
||||||
|
r.setTop( 0.0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
r.setBottom( height() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskSlideIn::layoutRectForSize( const QSizeF& size ) const
|
||||||
|
{
|
||||||
|
const auto ratio = 1.0 - transitioningFactor();
|
||||||
|
|
||||||
|
auto x = 0.0;
|
||||||
|
auto y = 0.0;
|
||||||
|
|
||||||
|
switch( edge() )
|
||||||
|
{
|
||||||
|
case Qt::LeftEdge:
|
||||||
|
x = -ratio * size.width();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::RightEdge:
|
||||||
|
x = ratio * size.width();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::TopEdge:
|
||||||
|
y = -ratio * size.height();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
y = ratio * size.height();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QRectF( x, y, size.width(), size.height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskSlideIn.cpp"
|
|
@ -0,0 +1,44 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_SLIDE_IN_H
|
||||||
|
#define QSK_SLIDE_IN_H
|
||||||
|
|
||||||
|
#include "QskPopup.h"
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
class QSK_EXPORT QskSlideIn : public QskPopup
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
using Inherited = QskPopup;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~QskSlideIn() override;
|
||||||
|
|
||||||
|
virtual Qt::Edge edge() const = 0;
|
||||||
|
|
||||||
|
QRectF focusIndicatorRect() const override;
|
||||||
|
QRectF clipRect() const override;
|
||||||
|
|
||||||
|
void setAdjustingToParentGeometry( bool on );
|
||||||
|
bool isAdjustingToParentGeometry() const;
|
||||||
|
|
||||||
|
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QskSlideIn( QQuickItem* = nullptr );
|
||||||
|
|
||||||
|
bool event( QEvent* ) override;
|
||||||
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setIntermediate( bool );
|
||||||
|
|
||||||
|
class PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue