implementation with basic functionality
This commit is contained in:
parent
48c170bfbf
commit
79d0f08eb6
|
@ -24,33 +24,34 @@ namespace
|
||||||
: QskDrawer( parent )
|
: QskDrawer( parent )
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
setAnimationHint( Panel | QskAspect::Position, 1000 );
|
setAnimationHint( faderAspect(), 1000 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setEdge( edge );
|
setEdge( edge );
|
||||||
setOverlay( true );
|
setOverlay( true );
|
||||||
|
|
||||||
auto content = new QskControl( this );
|
auto content = new QskControl( this );
|
||||||
|
content->setObjectName( "Content" );
|
||||||
|
|
||||||
switch( edge )
|
switch( edge )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
content->setBackgroundColor( QskRgb::Tomato );
|
content->setBackgroundColor( QskRgb::Tomato );
|
||||||
setFixedWidth( 100 );
|
content->setFixedWidth( 100 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
setFixedWidth( 200 );
|
content->setFixedWidth( 200 );
|
||||||
content->setBackgroundColor( QskRgb::Orchid );
|
content->setBackgroundColor( QskRgb::Orchid );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
setFixedHeight( 100 );
|
content->setFixedHeight( 100 );
|
||||||
content->setBackgroundColor( QskRgb::Wheat );
|
content->setBackgroundColor( QskRgb::Chartreuse );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
setFixedHeight( 200 );
|
content->setFixedHeight( 200 );
|
||||||
content->setBackgroundColor( QskRgb::Wheat );
|
content->setBackgroundColor( QskRgb::Wheat );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -65,16 +66,26 @@ namespace
|
||||||
{
|
{
|
||||||
setBackgroundColor( QskRgb::LightSteelBlue );
|
setBackgroundColor( QskRgb::LightSteelBlue );
|
||||||
|
|
||||||
setMargins( 50 );
|
setMargins( 10 );
|
||||||
setAutoLayoutChildren( true );
|
setAutoLayoutChildren( true );
|
||||||
|
|
||||||
(void) new QskPushButton( this );
|
|
||||||
|
|
||||||
for ( int i = 0; i < 4; i++ )
|
for ( int i = 0; i < 4; i++ )
|
||||||
{
|
{
|
||||||
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
const auto edge = static_cast< Qt::Edge >( 1 << i );
|
||||||
m_drawers[i] = new Drawer( edge, this );
|
m_drawers[i] = new Drawer( edge, this );
|
||||||
|
|
||||||
|
auto dragMargin = 30; // the default setting is pretty small
|
||||||
|
if ( edge == Qt::TopEdge )
|
||||||
|
{
|
||||||
|
// to check if dragging works above the button
|
||||||
|
dragMargin = 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_drawers[i]->setDragMargin( dragMargin );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto button = new QskPushButton( "Push Me", this );
|
||||||
|
button->setPreferredHeight( 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -87,7 +98,6 @@ namespace
|
||||||
MainBox( QQuickItem* parent = nullptr )
|
MainBox( QQuickItem* parent = nullptr )
|
||||||
: QskControl( parent )
|
: QskControl( parent )
|
||||||
{
|
{
|
||||||
setBackgroundColor( QskRgb::LemonChiffon );
|
|
||||||
setMargins( 40 );
|
setMargins( 40 );
|
||||||
setAutoLayoutChildren( true );
|
setAutoLayoutChildren( true );
|
||||||
|
|
||||||
|
|
|
@ -606,21 +606,15 @@ void Editor::setupDialogButtonBoxColors(
|
||||||
void Editor::setupDrawerMetrics()
|
void Editor::setupDrawerMetrics()
|
||||||
{
|
{
|
||||||
using Q = QskDrawer;
|
using Q = QskDrawer;
|
||||||
|
using A = QskAspect;
|
||||||
setPadding( Q::Panel, 5 );
|
|
||||||
setHint( Q::Overlay | QskAspect::Style, false );
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
setAnimation( Q::Panel | QskAspect::Position, 200 );
|
setAnimation( Q::Panel | A::Metric | A::Position, 200 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupDrawerColors(
|
void Editor::setupDrawerColors( QskAspect::Section, const QskFluent2Theme& )
|
||||||
QskAspect::Section section, const QskFluent2Theme& theme )
|
|
||||||
{
|
{
|
||||||
using Q = QskDrawer;
|
|
||||||
|
|
||||||
setGradient( Q::Panel | section, theme.palette.background.solid.base );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupFocusIndicatorMetrics()
|
void Editor::setupFocusIndicatorMetrics()
|
||||||
|
@ -735,6 +729,7 @@ 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 );
|
||||||
|
@ -748,6 +743,14 @@ 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, 0 );
|
||||||
|
setPosition( Q::Panel | QskPopup::Closed, 1 );
|
||||||
|
|
||||||
|
// copied from Mat3 - what are the correct values for Fluent2 ???
|
||||||
|
setAnimation( Q::Panel | A::Metric, 150 );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupMenuColors(
|
void Editor::setupMenuColors(
|
||||||
|
|
|
@ -379,7 +379,7 @@ void Editor::setupMenu()
|
||||||
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
setFontRole( Q::Text, QskMaterial3Skin::M3BodyMedium );
|
||||||
|
|
||||||
setPosition( Q::Panel, 0 );
|
setPosition( Q::Panel, 0 );
|
||||||
setPosition( Q::Panel | QskPopup::Closed, 1_dp );
|
setPosition( Q::Panel | QskPopup::Closed, 1 );
|
||||||
|
|
||||||
setAnimation( Q::Panel | A::Metric, 150 );
|
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 );
|
||||||
|
@ -809,12 +809,9 @@ void Editor::setupDialogButtonBox()
|
||||||
void Editor::setupDrawer()
|
void Editor::setupDrawer()
|
||||||
{
|
{
|
||||||
using Q = QskDrawer;
|
using Q = QskDrawer;
|
||||||
|
using A = QskAspect;
|
||||||
|
|
||||||
setPadding( Q::Panel, 5_dp );
|
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
||||||
setGradient( Q::Panel, m_pal.background );
|
|
||||||
setHint( Q::Overlay | QskAspect::Style, false );
|
|
||||||
|
|
||||||
setAnimation( Q::Panel | QskAspect::Position, qskDuration );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupSlider()
|
void Editor::setupSlider()
|
||||||
|
|
|
@ -759,13 +759,12 @@ void Editor::setupDialogButtonBox()
|
||||||
setBoxShape( Q::Panel, 2 );
|
setBoxShape( Q::Panel, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupDrawer() {
|
void Editor::setupDrawer()
|
||||||
|
{
|
||||||
|
using A = QskAspect;
|
||||||
using Q = QskDrawer;
|
using Q = QskDrawer;
|
||||||
|
|
||||||
setPadding( Q::Panel, 5 );
|
setAnimation( Q::Panel | A::Metric | A::Position, qskDuration );
|
||||||
setGradient( Q::Panel, m_pal.darker125 );
|
|
||||||
setAnimation( Q::Panel | QskAspect::Position, qskDuration );
|
|
||||||
setHint( Q::Overlay | QskAspect::Style, false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::setupTabButton()
|
void Editor::setupTabButton()
|
||||||
|
|
|
@ -115,6 +115,7 @@ list(APPEND HEADERS
|
||||||
nodes/QskRichTextRenderer.h
|
nodes/QskRichTextRenderer.h
|
||||||
nodes/QskScaleRenderer.h
|
nodes/QskScaleRenderer.h
|
||||||
nodes/QskSGNode.h
|
nodes/QskSGNode.h
|
||||||
|
nodes/QskSlideInNode.h
|
||||||
nodes/QskStrokeNode.h
|
nodes/QskStrokeNode.h
|
||||||
nodes/QskStippledLineRenderer.h
|
nodes/QskStippledLineRenderer.h
|
||||||
nodes/QskShapeNode.h
|
nodes/QskShapeNode.h
|
||||||
|
@ -146,6 +147,7 @@ list(APPEND SOURCES
|
||||||
nodes/QskRichTextRenderer.cpp
|
nodes/QskRichTextRenderer.cpp
|
||||||
nodes/QskScaleRenderer.cpp
|
nodes/QskScaleRenderer.cpp
|
||||||
nodes/QskSGNode.cpp
|
nodes/QskSGNode.cpp
|
||||||
|
nodes/QskSlideInNode.cpp
|
||||||
nodes/QskStrokeNode.cpp
|
nodes/QskStrokeNode.cpp
|
||||||
nodes/QskStippledLineRenderer.cpp
|
nodes/QskStippledLineRenderer.cpp
|
||||||
nodes/QskShapeNode.cpp
|
nodes/QskShapeNode.cpp
|
||||||
|
|
|
@ -12,48 +12,88 @@
|
||||||
#include "QskPanGestureRecognizer.h"
|
#include "QskPanGestureRecognizer.h"
|
||||||
#include "QskGesture.h"
|
#include "QskGesture.h"
|
||||||
|
|
||||||
|
#include <qguiapplication.h>
|
||||||
|
#include <qstylehints.h>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquickitem_p.h>
|
#include <private/qquickitem_p.h>
|
||||||
#include <private/qquickitemchangelistener_p.h>
|
#include <private/qquickitemchangelistener_p.h>
|
||||||
QSK_QT_PRIVATE_END
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
// we need a skinlet to draw the panel TODO ...
|
/*
|
||||||
|
Only used for the sliding in animation. Do we want to
|
||||||
|
introduce a specific panel as background ???
|
||||||
|
*/
|
||||||
QSK_SUBCONTROL( QskDrawer, Panel )
|
QSK_SUBCONTROL( QskDrawer, Panel )
|
||||||
|
|
||||||
static QRectF qskDrawerRect( const QRectF& rect,
|
static void qskCatchMouseEvents( QQuickItem* item )
|
||||||
Qt::Edge edge, qreal pos, const QSizeF& size )
|
|
||||||
{
|
{
|
||||||
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
#if 1
|
||||||
|
// manipulating other items - do we really want to do this ?
|
||||||
|
item->setAcceptedMouseButtons( Qt::LeftButton );
|
||||||
|
item->setFiltersChildMouseEvents( true );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
const auto progress = pos = 1.0 - pos;
|
static bool qskCheckDirection( Qt::Edge edge, const QskPanGesture* gesture )
|
||||||
|
{
|
||||||
|
const auto degrees = gesture->angle();
|
||||||
|
|
||||||
switch( edge )
|
switch( edge )
|
||||||
|
{
|
||||||
|
case Qt::LeftEdge:
|
||||||
|
return ( degrees < 90.0 ) || ( degrees ) > 270.0;
|
||||||
|
|
||||||
|
case Qt::RightEdge:
|
||||||
|
return ( degrees > 90.0 ) && ( degrees < 270.0 );
|
||||||
|
|
||||||
|
case Qt::TopEdge:
|
||||||
|
return degrees > 180.0;
|
||||||
|
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
return degrees < 180.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qskLayoutDrawer( const QRectF& rect, QskDrawer* drawer )
|
||||||
|
{
|
||||||
|
const auto size = qskSizeConstraint( drawer, Qt::PreferredSize );
|
||||||
|
|
||||||
|
QRectF r( 0.0, 0.0, size.width(), size.height() );
|
||||||
|
|
||||||
|
switch( drawer->edge() )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
{
|
{
|
||||||
r.moveRight( rect.left() + progress * size.width() );
|
r.setHeight( rect.height() );
|
||||||
|
r.moveRight( rect.left() + size.width() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
{
|
{
|
||||||
r.moveLeft( rect.right() - progress * size.width() );
|
r.setHeight( rect.height() );
|
||||||
|
r.moveLeft( rect.right() - size.width() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
{
|
{
|
||||||
r.moveBottom( rect.top() + progress * size.height() );
|
r.setWidth( rect.width() );
|
||||||
|
r.moveBottom( rect.top() + size.height() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
{
|
{
|
||||||
r.moveTop( rect.bottom() - progress * size.height() );
|
r.setWidth( rect.width() );
|
||||||
|
r.moveTop( rect.bottom() - size.height() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
drawer->setGeometry( r );
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -61,10 +101,11 @@ namespace
|
||||||
class GeometryListener final : public QQuickItemChangeListener
|
class GeometryListener final : public QQuickItemChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GeometryListener( QskDrawer* drawer )
|
GeometryListener( QQuickItem* item, QQuickItem* adjustedItem )
|
||||||
: m_drawer( drawer )
|
: m_item( item )
|
||||||
, m_parent( drawer->parentItem() )
|
, m_adjustedItem( adjustedItem )
|
||||||
{
|
{
|
||||||
|
adjust();
|
||||||
setEnabled( true );
|
setEnabled( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,31 +115,43 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void itemGeometryChanged( QQuickItem*,
|
void itemGeometryChanged( QQuickItem*,
|
||||||
QQuickGeometryChange, const QRectF& ) override
|
QQuickGeometryChange, const QRectF& ) override
|
||||||
{
|
{
|
||||||
m_drawer->polish();
|
adjust();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setEnabled( bool on )
|
void adjust()
|
||||||
{
|
{
|
||||||
if ( m_parent )
|
#if 0
|
||||||
{
|
const auto pos = m_adjustedItem->mapFromItem( m_item, QPointF() );
|
||||||
const auto changeTypes = QQuickItemPrivate::Geometry;
|
qskSetItemGeometry( m_adjustedItem,
|
||||||
|
pos.x(), pos.y(), m_item->width(), m_item->height() );
|
||||||
auto d = QQuickItemPrivate::get( m_parent );
|
#else
|
||||||
if ( on )
|
qskLayoutDrawer( QRectF( QPointF(), m_item->size() ),
|
||||||
d->addItemChangeListener( this, changeTypes );
|
qobject_cast< QskDrawer* >( m_adjustedItem ) );
|
||||||
else
|
#endif
|
||||||
d->removeItemChangeListener( this, changeTypes );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskDrawer* m_drawer = nullptr;
|
void setEnabled( bool on )
|
||||||
QQuickItem* m_parent = nullptr;
|
{
|
||||||
};
|
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
|
||||||
|
{
|
||||||
class GestureRecognizer : public QskPanGestureRecognizer
|
class GestureRecognizer : public QskPanGestureRecognizer
|
||||||
{
|
{
|
||||||
using Inherited = QskPanGestureRecognizer;
|
using Inherited = QskPanGestureRecognizer;
|
||||||
|
@ -112,33 +165,36 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QRectF gestureRect() const override
|
bool isAcceptedPos( const QPointF& pos ) const override
|
||||||
{
|
{
|
||||||
auto drawer = qobject_cast< QskDrawer* >( parent() );
|
auto drawer = qobject_cast< const QskDrawer* >( targetItem() );
|
||||||
|
|
||||||
|
const auto dragMargin = drawer->dragMargin();
|
||||||
|
if ( dragMargin <= 0.0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
const auto dist = 50;
|
|
||||||
auto rect = qskItemRect( watchedItem() );
|
auto rect = qskItemRect( watchedItem() );
|
||||||
|
|
||||||
switch( drawer->edge() )
|
switch( drawer->edge() )
|
||||||
{
|
{
|
||||||
case Qt::LeftEdge:
|
case Qt::LeftEdge:
|
||||||
rect.setRight( rect.left() + dist );
|
rect.setRight( rect.left() + dragMargin );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::RightEdge:
|
case Qt::RightEdge:
|
||||||
rect.setLeft( rect.right() - dist );
|
rect.setLeft( rect.right() - dragMargin );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::TopEdge:
|
case Qt::TopEdge:
|
||||||
rect.setBottom( rect.top() + dist );
|
rect.setBottom( rect.top() + dragMargin );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::BottomEdge:
|
case Qt::BottomEdge:
|
||||||
rect.setTop( rect.bottom() - dist );
|
rect.setTop( rect.bottom() - dragMargin );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rect.contains( pos );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -147,23 +203,26 @@ class QskDrawer::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Qt::Edge edge = Qt::LeftEdge;
|
Qt::Edge edge = Qt::LeftEdge;
|
||||||
|
GestureRecognizer* gestureRecognizer = nullptr;
|
||||||
GeometryListener* listener = nullptr;
|
GeometryListener* listener = nullptr;
|
||||||
|
|
||||||
|
// a skin hint ???
|
||||||
|
qreal dragMargin = QGuiApplication::styleHints()->startDragDistance();
|
||||||
};
|
};
|
||||||
|
|
||||||
QskDrawer::QskDrawer( QQuickItem* parentItem )
|
QskDrawer::QskDrawer( QQuickItem* parentItem )
|
||||||
: Inherited ( parentItem )
|
: Inherited ( parentItem )
|
||||||
, m_data( new PrivateData )
|
, m_data( new PrivateData )
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
setZ( 1 );
|
setZ( 1 );
|
||||||
|
#endif
|
||||||
|
|
||||||
setAutoLayoutChildren( true );
|
setPolishOnResize( true );
|
||||||
|
|
||||||
setPopupFlag( PopupFlag::CloseOnPressOutside, true );
|
setPopupFlag( PopupFlag::CloseOnPressOutside, true );
|
||||||
setFaderAspect( Panel | QskAspect::Position | QskAspect::Metric );
|
setFaderAspect( Panel | QskAspect::Position | QskAspect::Metric );
|
||||||
|
|
||||||
connect( this, &QskDrawer::closed,
|
|
||||||
this, [this]() { startFading( false ); } );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The drawer wants to be on top of the parent - not being
|
The drawer wants to be on top of the parent - not being
|
||||||
layouted into its layoutRect(). So we opt out and do
|
layouted into its layoutRect(). So we opt out and do
|
||||||
|
@ -172,17 +231,22 @@ QskDrawer::QskDrawer( QQuickItem* parentItem )
|
||||||
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
setPlacementPolicy( QskPlacementPolicy::Ignore );
|
||||||
if ( parentItem )
|
if ( parentItem )
|
||||||
{
|
{
|
||||||
/*
|
m_data->listener = new GeometryListener( parentItem, this );
|
||||||
QskPopup has an internal QskInputGrabber, that does something
|
qskCatchMouseEvents( parentItem );
|
||||||
very similar. Maybe we can make use of it ... TODO
|
|
||||||
*/
|
|
||||||
m_data->listener = new GeometryListener( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) new GestureRecognizer( this );
|
m_data->gestureRecognizer = new GestureRecognizer( this );
|
||||||
#if 1
|
|
||||||
parentItem->setAcceptedMouseButtons( Qt::LeftButton );
|
|
||||||
#endif
|
connect( this, &QskPopup::openChanged, this, &QskDrawer::setFading );
|
||||||
|
|
||||||
|
/*
|
||||||
|
When the content of the parentItem does not fit we will have
|
||||||
|
a difference between fading and normal state. To overcome this problem
|
||||||
|
we need to expand the rectangle of the QQuickDefaultClipNode manually to
|
||||||
|
the window borders: TODO ...
|
||||||
|
*/
|
||||||
|
connect( this, &QskPopup::fadingChanged, parentItem, &QQuickItem::setClip );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskDrawer::~QskDrawer()
|
QskDrawer::~QskDrawer()
|
||||||
|
@ -205,13 +269,36 @@ void QskDrawer::setEdge( Qt::Edge edge )
|
||||||
edgeChanged( edge );
|
edgeChanged( edge );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskDrawer::setDragMargin( qreal margin )
|
||||||
|
{
|
||||||
|
margin = std::max( margin, 0.0 );
|
||||||
|
|
||||||
|
if ( margin != m_data->dragMargin )
|
||||||
|
{
|
||||||
|
m_data->dragMargin = margin;
|
||||||
|
Q_EMIT dragMarginChanged( margin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal QskDrawer::dragMargin() const
|
||||||
|
{
|
||||||
|
return m_data->dragMargin;
|
||||||
|
}
|
||||||
|
|
||||||
void QskDrawer::gestureEvent( QskGestureEvent* event )
|
void QskDrawer::gestureEvent( QskGestureEvent* event )
|
||||||
{
|
{
|
||||||
if ( event->gesture()->type() == QskGesture::Pan )
|
if ( event->gesture()->type() == QskGesture::Pan )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
For the moment we treat the gesture like a swipe gesture
|
||||||
|
without dragging the drawer when moving the mouse. TODO ...
|
||||||
|
*/
|
||||||
const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() );
|
const auto gesture = static_cast< const QskPanGesture* >( event->gesture().get() );
|
||||||
if ( gesture->state() == QskGesture::Finished )
|
if ( gesture->state() == QskGesture::Finished )
|
||||||
open();
|
{
|
||||||
|
if ( qskCheckDirection( m_data->edge, gesture ) )
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -219,30 +306,89 @@ void QskDrawer::gestureEvent( QskGestureEvent* event )
|
||||||
Inherited::gestureEvent( event );
|
Inherited::gestureEvent( event );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskDrawer::layoutRectForSize( const QSizeF& size ) const
|
QSizeF QskDrawer::layoutSizeHint(
|
||||||
|
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||||
{
|
{
|
||||||
return Inherited::layoutRectForSize( size );
|
if ( which == Qt::MaximumSize )
|
||||||
|
return QSizeF();
|
||||||
|
|
||||||
|
qreal w = -1.0;
|
||||||
|
qreal h = -1.0;
|
||||||
|
|
||||||
|
const auto children = childItems();
|
||||||
|
|
||||||
|
for ( const auto child : children )
|
||||||
|
{
|
||||||
|
if ( !qskIsVisibleToLayout( child ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto policy = qskSizePolicy( child );
|
||||||
|
|
||||||
|
if ( constraint.width() >= 0.0 && policy.isConstrained( Qt::Vertical ) )
|
||||||
|
{
|
||||||
|
const auto hint = qskSizeConstraint( child, which, constraint );
|
||||||
|
h = qMax( h, hint.height() );
|
||||||
|
}
|
||||||
|
else if ( constraint.height() >= 0.0 && policy.isConstrained( Qt::Horizontal ) )
|
||||||
|
{
|
||||||
|
const auto hint = qskSizeConstraint( child, which, constraint );
|
||||||
|
w = qMax( w, hint.width() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto hint = qskSizeConstraint( child, which );
|
||||||
|
|
||||||
|
w = qMax( w, hint.width() );
|
||||||
|
h = qMax( h, hint.height() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSizeF( w, h );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskDrawer::updateLayout()
|
void QskDrawer::updateLayout()
|
||||||
{
|
{
|
||||||
if ( !( isOpen() || isFading() ) )
|
if ( !( isOpen() || isFading() ) || size().isEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto targetRect = qskItemRect( parentItem() );
|
auto dx = 0.0;
|
||||||
const auto size = qskConstrainedItemSize( this, targetRect.size() );
|
auto dy = 0.0;
|
||||||
|
|
||||||
const auto rect = qskDrawerRect( targetRect,
|
if ( isFading() )
|
||||||
m_data->edge, metric( faderAspect() ), size );
|
{
|
||||||
|
const auto f = metric( faderAspect() );
|
||||||
|
|
||||||
qskSetItemGeometry( this, rect );
|
switch( m_data->edge )
|
||||||
Inherited::updateLayout();
|
{
|
||||||
}
|
case Qt::LeftEdge:
|
||||||
|
dx = -f * width();
|
||||||
|
break;
|
||||||
|
|
||||||
void QskDrawer::aboutToShow()
|
case Qt::RightEdge:
|
||||||
{
|
dx = f * width();
|
||||||
startFading( true );
|
break;
|
||||||
Inherited::aboutToShow();
|
|
||||||
|
case Qt::TopEdge:
|
||||||
|
dy = -f * height();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::BottomEdge:
|
||||||
|
dy = f * height();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QRectF layoutRect( dx, dy, width(), height() );
|
||||||
|
|
||||||
|
const auto children = childItems();
|
||||||
|
for ( auto child : children )
|
||||||
|
{
|
||||||
|
if ( qskIsAdjustableByLayout( child ) )
|
||||||
|
{
|
||||||
|
const auto r = qskConstrainedItemRect( child, layoutRect );
|
||||||
|
qskSetItemGeometry( child, r );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
||||||
|
@ -250,23 +396,39 @@ void QskDrawer::itemChange( QQuickItem::ItemChange change,
|
||||||
{
|
{
|
||||||
Inherited::itemChange( change, value );
|
Inherited::itemChange( change, value );
|
||||||
|
|
||||||
if ( change == QQuickItem::ItemParentHasChanged )
|
switch( static_cast< int >( change ) )
|
||||||
{
|
{
|
||||||
delete m_data->listener;
|
case QQuickItem::ItemParentHasChanged:
|
||||||
m_data->listener = nullptr;
|
{
|
||||||
|
if ( parentItem() )
|
||||||
|
qskCatchMouseEvents( parentItem() );
|
||||||
|
|
||||||
if ( parentItem() )
|
Q_FALLTHROUGH();
|
||||||
m_data->listener = new GeometryListener( this );
|
}
|
||||||
|
case QQuickItem::ItemVisibleHasChanged:
|
||||||
|
{
|
||||||
|
delete m_data->listener;
|
||||||
|
m_data->listener = nullptr;
|
||||||
|
|
||||||
|
if ( parentItem() && isVisible() )
|
||||||
|
m_data->listener = new GeometryListener( parentItem(), this );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskDrawer::startFading( bool open )
|
void QskDrawer::setFading( bool on )
|
||||||
{
|
{
|
||||||
const auto from = open ? 1.0 : 0.0;
|
const qreal from = on ? 1.0 : 0.0;
|
||||||
const auto to = open ? 0.0 : 1.0;
|
const qreal to = on ? 0.0 : 1.0;
|
||||||
|
|
||||||
const auto hint = animationHint( Panel | QskAspect::Position );
|
const auto aspect = faderAspect();
|
||||||
startTransition( faderAspect(), hint, from, to );
|
|
||||||
|
auto hint = animationHint( aspect );
|
||||||
|
hint.updateFlags = QskAnimationHint::UpdatePolish;
|
||||||
|
|
||||||
|
startTransition( aspect, hint, from, to );
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskDrawer.cpp"
|
#include "moc_QskDrawer.cpp"
|
||||||
|
|
|
@ -17,6 +17,9 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
||||||
|
|
||||||
Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged )
|
Q_PROPERTY( Qt::Edge edge READ edge WRITE setEdge NOTIFY edgeChanged )
|
||||||
|
|
||||||
|
Q_PROPERTY( qreal dragMargin READ dragMargin
|
||||||
|
WRITE setDragMargin NOTIFY dragMarginChanged )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSK_SUBCONTROLS( Panel )
|
QSK_SUBCONTROLS( Panel )
|
||||||
|
|
||||||
|
@ -26,20 +29,23 @@ class QSK_EXPORT QskDrawer : public QskPopup
|
||||||
void setEdge( Qt::Edge );
|
void setEdge( Qt::Edge );
|
||||||
Qt::Edge edge() const;
|
Qt::Edge edge() const;
|
||||||
|
|
||||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
void setDragMargin( qreal );
|
||||||
|
qreal dragMargin() const;
|
||||||
|
|
||||||
void updateLayout() override;
|
void updateLayout() override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void edgeChanged( Qt::Edge );
|
void edgeChanged( Qt::Edge );
|
||||||
|
void dragMarginChanged( qreal );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void aboutToShow() override;
|
|
||||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||||
|
|
||||||
|
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||||
void gestureEvent( QskGestureEvent* ) override;
|
void gestureEvent( QskGestureEvent* ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startFading( bool );
|
void setFading( bool );
|
||||||
|
|
||||||
class PrivateData;
|
class PrivateData;
|
||||||
std::unique_ptr< PrivateData > m_data;
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
|
|
@ -142,12 +142,9 @@ Qt::MouseButtons QskGestureRecognizer::acceptedMouseButtons() const
|
||||||
return m_data->buttons;
|
return m_data->buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskGestureRecognizer::gestureRect() const
|
bool QskGestureRecognizer::isAcceptedPos( const QPointF& pos ) const
|
||||||
{
|
{
|
||||||
if ( m_data->watchedItem )
|
return m_data->watchedItem && m_data->watchedItem->contains( pos );
|
||||||
return qskItemRect( m_data->watchedItem );
|
|
||||||
|
|
||||||
return QRectF( 0.0, 0.0, -1.0, -1.0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskGestureRecognizer::setRejectOnTimeout( bool on )
|
void QskGestureRecognizer::setRejectOnTimeout( bool on )
|
||||||
|
@ -313,7 +310,7 @@ bool QskGestureRecognizer::processMouseEvent(
|
||||||
|
|
||||||
if ( event->type() == QEvent::MouseButtonPress )
|
if ( event->type() == QEvent::MouseButtonPress )
|
||||||
{
|
{
|
||||||
if ( !gestureRect().contains( pos ) )
|
if ( !isAcceptedPos( pos ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( m_data->state != Idle )
|
if ( m_data->state != Idle )
|
||||||
|
|
|
@ -73,7 +73,7 @@ class QSK_EXPORT QskGestureRecognizer : public QObject
|
||||||
|
|
||||||
State state() const;
|
State state() const;
|
||||||
|
|
||||||
virtual QRectF gestureRect() const;
|
virtual bool isAcceptedPos( const QPointF& ) const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void stateChanged( State from, State to );
|
void stateChanged( State from, State to );
|
||||||
|
|
|
@ -24,7 +24,7 @@ class QSK_EXPORT QskListViewSkinlet : public QskScrollViewSkinlet
|
||||||
public:
|
public:
|
||||||
enum NodeRole
|
enum NodeRole
|
||||||
{
|
{
|
||||||
TextRole,
|
TextRole = Inherited::RoleCount,
|
||||||
GraphicRole,
|
GraphicRole,
|
||||||
|
|
||||||
RoleCount
|
RoleCount
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
#include "QskGraphic.h"
|
#include "QskGraphic.h"
|
||||||
#include "QskColorFilter.h"
|
#include "QskColorFilter.h"
|
||||||
#include "QskTextOptions.h"
|
#include "QskTextOptions.h"
|
||||||
#include "QskSGNode.h"
|
|
||||||
#include "QskFunctions.h"
|
#include "QskFunctions.h"
|
||||||
#include "QskMargins.h"
|
#include "QskMargins.h"
|
||||||
#include "QskFunctions.h"
|
#include "QskFunctions.h"
|
||||||
#include "QskLabelData.h"
|
#include "QskLabelData.h"
|
||||||
|
|
||||||
|
#include "QskSGNode.h"
|
||||||
|
#include "QskSlideInNode.h"
|
||||||
|
|
||||||
#include <qfontmetrics.h>
|
#include <qfontmetrics.h>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
|
||||||
|
@ -209,11 +211,44 @@ QskMenuSkinlet::QskMenuSkinlet( QskSkin* skin )
|
||||||
: Inherited( skin )
|
: Inherited( skin )
|
||||||
, m_data( new PrivateData() )
|
, m_data( new PrivateData() )
|
||||||
{
|
{
|
||||||
appendNodeRoles( { PanelRole } );
|
appendNodeRoles( { ContentsRole, PanelRole } );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskMenuSkinlet::~QskMenuSkinlet() = default;
|
QskMenuSkinlet::~QskMenuSkinlet() = default;
|
||||||
|
|
||||||
|
QSGNode* QskMenuSkinlet::updateSubNode(
|
||||||
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
switch ( nodeRole )
|
||||||
|
{
|
||||||
|
case ContentsRole:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
QskSlideInNode works for controls made of nodes - not for
|
||||||
|
containers of other quick items. TODO ...
|
||||||
|
*/
|
||||||
|
|
||||||
|
const auto popup = static_cast< const QskPopup* >( skinnable );
|
||||||
|
|
||||||
|
auto rect = popup->contentsRect();
|
||||||
|
if ( rect.isEmpty() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto slideInNode = QskSGNode::ensureNode< QskSlideInNode >( node );
|
||||||
|
|
||||||
|
const auto progress = popup->metric( popup->faderAspect() );
|
||||||
|
slideInNode->updateTranslation( rect, Qt::TopEdge, progress );
|
||||||
|
|
||||||
|
auto contentsNode = updateContentsNode( popup, slideInNode->contentsNode() );
|
||||||
|
slideInNode->setContentsNode( contentsNode );
|
||||||
|
|
||||||
|
return slideInNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
|
}
|
||||||
|
|
||||||
QRectF QskMenuSkinlet::cursorRect(
|
QRectF QskMenuSkinlet::cursorRect(
|
||||||
const QskSkinnable* skinnable, const QRectF& contentsRect, int index ) const
|
const QskSkinnable* skinnable, const QRectF& contentsRect, int index ) const
|
||||||
{
|
{
|
||||||
|
@ -407,7 +442,8 @@ QskAspect::States QskMenuSkinlet::sampleStates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto cursorPos = menu->effectiveSkinHint( Q::Segment | Q::Hovered | A::Metric | A::Position ).toPointF();
|
const auto cursorPos = menu->effectiveSkinHint(
|
||||||
|
Q::Segment | Q::Hovered | A::Metric | A::Position ).toPointF();
|
||||||
|
|
||||||
if( !cursorPos.isNull() && menu->indexAtPosition( cursorPos ) == index )
|
if( !cursorPos.isNull() && menu->indexAtPosition( cursorPos ) == index )
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,9 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
|
||||||
public:
|
public:
|
||||||
enum NodeRole
|
enum NodeRole
|
||||||
{
|
{
|
||||||
PanelRole = QskPopupSkinlet::RoleCount,
|
ContentsRole = Inherited::RoleCount,
|
||||||
|
PanelRole,
|
||||||
|
|
||||||
RoleCount
|
RoleCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,7 +50,10 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
|
||||||
Qt::SizeHint, const QSizeF& ) const override;
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const override;
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
|
||||||
|
QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const;
|
||||||
QSGNode* updateMenuNode( const QskSkinnable*, QSGNode* ) const;
|
QSGNode* updateMenuNode( const QskSkinnable*, QSGNode* ) const;
|
||||||
|
|
||||||
QSGNode* updateSampleNode( const QskSkinnable*,
|
QSGNode* updateSampleNode( const QskSkinnable*,
|
||||||
|
|
|
@ -5,108 +5,11 @@
|
||||||
|
|
||||||
#include "QskPopupSkinlet.h"
|
#include "QskPopupSkinlet.h"
|
||||||
#include "QskPopup.h"
|
#include "QskPopup.h"
|
||||||
#include "QskSGNode.h"
|
|
||||||
|
|
||||||
#include <qtransform.h>
|
|
||||||
#include <qsgnode.h>
|
|
||||||
#include <qquickwindow.h>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
class RootNode : public QSGNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~RootNode() override
|
|
||||||
{
|
|
||||||
delete m_clipNode;
|
|
||||||
delete m_transformNode;
|
|
||||||
delete m_contentsNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setClipRect( const QRectF& rect )
|
|
||||||
{
|
|
||||||
if ( m_clipNode == nullptr )
|
|
||||||
{
|
|
||||||
m_clipNode = new QSGClipNode();
|
|
||||||
m_clipNode->setFlag( QSGNode::OwnedByParent, false );
|
|
||||||
m_clipNode->setIsRectangular( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_clipNode->setClipRect( rect );
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetClip()
|
|
||||||
{
|
|
||||||
delete m_clipNode;
|
|
||||||
m_clipNode = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTranslation( qreal dx, qreal dy )
|
|
||||||
{
|
|
||||||
if ( dx != 0.0 || dy != 0.0 )
|
|
||||||
{
|
|
||||||
if ( m_transformNode == nullptr )
|
|
||||||
{
|
|
||||||
m_transformNode = new QSGTransformNode();
|
|
||||||
m_transformNode->setFlag( QSGNode::OwnedByParent, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
QTransform transform;
|
|
||||||
transform.translate( dx, dy );
|
|
||||||
|
|
||||||
m_transformNode->setMatrix( transform );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete m_transformNode;
|
|
||||||
m_transformNode = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setContentsNode( QSGNode* contentsNode )
|
|
||||||
{
|
|
||||||
if ( m_contentsNode != contentsNode )
|
|
||||||
{
|
|
||||||
if ( contentsNode )
|
|
||||||
contentsNode->setFlag( QSGNode::OwnedByParent, false );
|
|
||||||
|
|
||||||
delete m_contentsNode;
|
|
||||||
m_contentsNode = contentsNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rearrangeNodes()
|
|
||||||
{
|
|
||||||
const std::initializer_list< QSGNode* > nodes =
|
|
||||||
{ m_clipNode, m_transformNode, m_contentsNode };
|
|
||||||
|
|
||||||
QSGNode* parentNode = this;
|
|
||||||
for ( auto node : nodes )
|
|
||||||
{
|
|
||||||
if ( node )
|
|
||||||
{
|
|
||||||
QskSGNode::setParentNode( node, parentNode );
|
|
||||||
parentNode = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QSGNode* contentsNode()
|
|
||||||
{
|
|
||||||
return m_contentsNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QSGClipNode* m_clipNode = nullptr;
|
|
||||||
QSGTransformNode* m_transformNode = nullptr;
|
|
||||||
QSGNode* m_contentsNode = nullptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
QskPopupSkinlet::QskPopupSkinlet( QskSkin* skin )
|
||||||
: Inherited( skin )
|
: Inherited( skin )
|
||||||
{
|
{
|
||||||
appendNodeRoles( { OverlayRole, ContentsRole } );
|
appendNodeRoles( { OverlayRole } );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskPopupSkinlet::~QskPopupSkinlet() = default;
|
QskPopupSkinlet::~QskPopupSkinlet() = default;
|
||||||
|
@ -125,54 +28,13 @@ 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 updateBoxNode( skinnable, node, QskPopup::Overlay );
|
||||||
|
|
||||||
case ContentsRole:
|
|
||||||
return updateExtraNode( popup, node );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode* QskPopupSkinlet::updateExtraNode( const QskPopup* popup, QSGNode* node ) const
|
|
||||||
{
|
|
||||||
auto cr = popup->contentsRect();
|
|
||||||
if ( cr.isEmpty() )
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto rootNode = QskSGNode::ensureNode< RootNode >( node );
|
|
||||||
|
|
||||||
const auto faderProgress = popup->metric( popup->faderAspect() );
|
|
||||||
if ( faderProgress > 0.0 && faderProgress <= 1.0 )
|
|
||||||
{
|
|
||||||
auto clipRect = QRectF( popup->mapFromScene( QPointF() ), popup->window()->size() );
|
|
||||||
clipRect.setTop( cr.top() );
|
|
||||||
|
|
||||||
rootNode->setClipRect( clipRect );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rootNode->resetClip();
|
|
||||||
}
|
|
||||||
|
|
||||||
rootNode->setTranslation( 0.0, -faderProgress * cr.height() );
|
|
||||||
|
|
||||||
auto contentsNode = updateContentsNode( popup, rootNode->contentsNode() );
|
|
||||||
rootNode->setContentsNode( contentsNode );
|
|
||||||
|
|
||||||
rootNode->rearrangeNodes();
|
|
||||||
|
|
||||||
return rootNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSGNode* QskPopupSkinlet::updateContentsNode( const QskPopup*, QSGNode* ) const
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_QskPopupSkinlet.cpp"
|
#include "moc_QskPopupSkinlet.cpp"
|
||||||
|
|
|
@ -20,8 +20,6 @@ class QSK_EXPORT QskPopupSkinlet : public QskSkinlet
|
||||||
enum NodeRole
|
enum NodeRole
|
||||||
{
|
{
|
||||||
OverlayRole,
|
OverlayRole,
|
||||||
ContentsRole,
|
|
||||||
|
|
||||||
RoleCount
|
RoleCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,10 +33,7 @@ class QSK_EXPORT QskPopupSkinlet : public QskSkinlet
|
||||||
QSGNode* updateSubNode( const QskSkinnable*,
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
quint8 nodeRole, QSGNode* ) const override;
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
|
||||||
virtual QSGNode* updateContentsNode( const QskPopup*, QSGNode* ) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSGNode* updateExtraNode( const QskPopup*, QSGNode* ) const;
|
|
||||||
QSGNode* updateOverlayNode( const QskPopup*, QSGNode* ) const;
|
QSGNode* updateOverlayNode( const QskPopup*, QSGNode* ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -136,15 +136,15 @@ namespace
|
||||||
setOrientations( Qt::Horizontal | Qt::Vertical );
|
setOrientations( Qt::Horizontal | Qt::Vertical );
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF gestureRect() const override
|
bool isAcceptedPos( const QPointF& pos ) const override
|
||||||
{
|
{
|
||||||
if ( auto scrollBox = qobject_cast< const QskScrollBox* >( watchedItem() ) )
|
if ( auto scrollBox = qobject_cast< const QskScrollBox* >( watchedItem() ) )
|
||||||
{
|
{
|
||||||
if ( qskIsScrollable( scrollBox, orientations() ) )
|
if ( qskIsScrollable( scrollBox, orientations() ) )
|
||||||
return scrollBox->viewContentsRect();
|
return scrollBox->viewContentsRect().contains( pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
return QRectF( 0.0, 0.0, -1.0, -1.0 ); // empty
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1259,13 +1259,19 @@ bool QskSkinnable::isTransitionAccepted( QskAspect aspect ) const
|
||||||
{
|
{
|
||||||
Q_UNUSED( aspect )
|
Q_UNUSED( aspect )
|
||||||
|
|
||||||
/*
|
|
||||||
Usually we only need smooth transitions, when state changes
|
|
||||||
happen while the skinnable is visible. There are few exceptions
|
|
||||||
like QskPopup::Closed, that is used to slide/fade in.
|
|
||||||
*/
|
|
||||||
if ( auto control = qskControlCast( owningItem() ) )
|
if ( auto control = qskControlCast( owningItem() ) )
|
||||||
return control->isInitiallyPainted();
|
{
|
||||||
|
/*
|
||||||
|
Usually we only need smooth transitions, when state changes
|
||||||
|
happen while the skinnable is visible. There are few exceptions
|
||||||
|
like QskPopup::Closed, that is used to slide/fade in.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( control->flags() & QQuickItem::ItemHasContents )
|
||||||
|
return control->isInitiallyPainted();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskSlideInNode.h"
|
||||||
|
#include "QskSGNode.h"
|
||||||
|
#include <qtransform.h>
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qsgnode_p.h>
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
class QskSlideInNodePrivate final : public QSGNodePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~QskSlideInNodePrivate()
|
||||||
|
{
|
||||||
|
delete clipNode;
|
||||||
|
delete transformNode;
|
||||||
|
delete contentsNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reparentContentNode( QskSlideInNode* node )
|
||||||
|
{
|
||||||
|
if ( contentsNode )
|
||||||
|
{
|
||||||
|
QSGNode* parentNode = transformNode;
|
||||||
|
|
||||||
|
if ( parentNode == nullptr )
|
||||||
|
parentNode = clipNode;
|
||||||
|
|
||||||
|
if ( parentNode == nullptr )
|
||||||
|
parentNode = node;
|
||||||
|
|
||||||
|
QskSGNode::setParentNode( contentsNode, parentNode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGClipNode* clipNode = nullptr;
|
||||||
|
QSGTransformNode* transformNode = nullptr;
|
||||||
|
QSGNode* contentsNode = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskSlideInNode::QskSlideInNode()
|
||||||
|
: QSGNode( *new QskSlideInNodePrivate, QSGNode::BasicNodeType )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QskSlideInNode::~QskSlideInNode() = default;
|
||||||
|
|
||||||
|
void QskSlideInNode::updateTranslation( const QRectF& rect,
|
||||||
|
Qt::Edge edge, qreal progress )
|
||||||
|
{
|
||||||
|
Q_UNUSED( edge ); // TODO ...
|
||||||
|
|
||||||
|
Q_D( QskSlideInNode );
|
||||||
|
|
||||||
|
{
|
||||||
|
// clipping
|
||||||
|
|
||||||
|
if ( progress > 0.0 && progress <= 1.0 )
|
||||||
|
{
|
||||||
|
if ( d->clipNode == nullptr )
|
||||||
|
{
|
||||||
|
d->clipNode = new QSGClipNode();
|
||||||
|
d->clipNode->setFlag( QSGNode::OwnedByParent, false );
|
||||||
|
d->clipNode->setIsRectangular( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
d->clipNode->setClipRect( rect );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete d->clipNode;
|
||||||
|
d->clipNode = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d->clipNode )
|
||||||
|
QskSGNode::setParentNode( d->clipNode, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// translation
|
||||||
|
|
||||||
|
qreal dx = 0.0;
|
||||||
|
qreal dy = -progress* rect.height();
|
||||||
|
|
||||||
|
if ( dx != 0.0 || dy != 0.0 )
|
||||||
|
{
|
||||||
|
if ( d->transformNode == nullptr )
|
||||||
|
{
|
||||||
|
d->transformNode = new QSGTransformNode();
|
||||||
|
d->transformNode->setFlag( QSGNode::OwnedByParent, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
QTransform transform;
|
||||||
|
transform.translate( dx, dy );
|
||||||
|
|
||||||
|
d->transformNode->setMatrix( transform );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete d->transformNode;
|
||||||
|
d->transformNode = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( d->transformNode )
|
||||||
|
{
|
||||||
|
QSGNode* parentNode = d->clipNode;
|
||||||
|
if ( parentNode == nullptr )
|
||||||
|
parentNode = this;
|
||||||
|
|
||||||
|
QskSGNode::setParentNode( d->transformNode, parentNode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->reparentContentNode( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskSlideInNode::setContentsNode( QSGNode* node )
|
||||||
|
{
|
||||||
|
Q_D( QskSlideInNode );
|
||||||
|
|
||||||
|
if ( d->contentsNode == node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( node )
|
||||||
|
node->setFlag( QSGNode::OwnedByParent, false );
|
||||||
|
|
||||||
|
delete d->contentsNode;
|
||||||
|
d->contentsNode = node;
|
||||||
|
|
||||||
|
d->reparentContentNode( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* QskSlideInNode::contentsNode()
|
||||||
|
{
|
||||||
|
return d_func()->contentsNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSGNode* QskSlideInNode::contentsNode() const
|
||||||
|
{
|
||||||
|
return d_func()->contentsNode;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_SLIDE_IN_NODE_H
|
||||||
|
#define QSK_SLIDE_IN_NODE_H
|
||||||
|
|
||||||
|
#include "QskGlobal.h"
|
||||||
|
|
||||||
|
#include <qsgnode.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
class QskSlideInNodePrivate;
|
||||||
|
|
||||||
|
class QSK_EXPORT QskSlideInNode : public QSGNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskSlideInNode();
|
||||||
|
~QskSlideInNode() override;
|
||||||
|
|
||||||
|
void updateTranslation( const QRectF&, Qt::Edge, qreal progress );
|
||||||
|
|
||||||
|
void setContentsNode( QSGNode* );
|
||||||
|
|
||||||
|
QSGNode* contentsNode();
|
||||||
|
const QSGNode* contentsNode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE( QskSlideInNode )
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue