7#include "QskControlPrivate.h"
10#include "QskFunctions.h"
15#include "QskSkinlet.h"
16#include "QskSkinHintTable.h"
17#include "QskMargins.h"
18#include "QskTreeNode.h"
29static inline
void qskSendEventTo( QObject*
object, QEvent::Type type )
32 QCoreApplication::sendEvent(
object, &event );
35static inline bool qskMaybeGesture( QQuickItem* item,
36 const QQuickItem* child,
const QEvent* event )
38 if ( qskIsTouchOrMouseEvent( event->type() ) )
41 QCoreApplication::sendEvent( item, &ev );
43 return ev.maybeGesture();
50 :
QskItem( *( new QskControlPrivate() ), parent )
55 QskControlPrivate::resolveLocale(
this );
56 QskControlPrivate::resolveSection(
this );
62#if defined( QT_DEBUG )
63 if (
auto w = window() )
65 if(
this == w->mouseGrabberItem() )
68 qWarning() <<
"QskControl::~QskControl: probably suicide situation detected, "
69 "control is the mouse grabber item" <<
this;
79 if ( on != d->autoLayoutChildren )
81 d->autoLayoutChildren = on;
89 return d_func()->autoLayoutChildren;
130 qskSendEventTo(
this, QEvent::ContentsRectChange );
139 qskSendEventTo(
this, QEvent::ContentsRectChange );
151 return qskValidOrEmptyInnerRect(
rect(),
margins() );
162 QRectF
rect( 0.0, 0.0, size.width(), size.height() );
176 QRectF
rect( 0.0, 0.0, size.width(), size.height() );
184 return d_func()->locale;
191 d->explicitLocale =
true;
193 if ( d->locale !=
locale )
195 extern void qskInheritLocale( QObject*,
const QLocale& );
198 qskSendEventTo(
this, QEvent::LocaleChange );
200 qskInheritLocale(
this,
locale );
208 if ( d->explicitLocale )
210 d->explicitLocale =
false;
211 QskControlPrivate::resolveLocale(
this );
215void QskControl::setSection( QskAspect::Section section )
217 if ( section > QskAspect::LastSection )
219 qWarning() <<
"Trying to set an invalid section, ignored";
225 d->explicitSection =
true;
227 if ( d->section != section )
229 extern void qskInheritSection(
QskControl*,
const QskAspect::Section );
231 d->section = section;
236 qskInheritSection(
this, section );
240void QskControl::resetSection()
244 if ( d->explicitSection )
246 d->explicitSection =
false;
247 QskControlPrivate::resolveSection(
this );
251QskAspect::Section QskControl::section()
const
253 return static_cast< QskAspect::Section
>( d_func()->section );
257 QskSizePolicy::Policy horizontalPolicy,
258 QskSizePolicy::Policy verticalPolicy )
269 d->sizePolicy.setHorizontalPolicy( horizontalPolicy );
270 d->sizePolicy.setVerticalPolicy( verticalPolicy );
272 if ( horizontalPolicy == QskSizePolicy::Constrained
273 && verticalPolicy == QskSizePolicy::Constrained )
275 qWarning(
"QskControl::initSizePolicy: conflicting constraints" );
283 if ( policy != d->sizePolicy )
285 d->sizePolicy = policy;
286 d->layoutConstraintChanged();
288 if ( policy.policy( Qt::Horizontal ) == QskSizePolicy::Constrained
289 && policy.policy( Qt::Vertical ) == QskSizePolicy::Constrained )
291 qWarning(
"QskControl::setSizePolicy: conflicting constraints" );
297 QskSizePolicy::Policy horizontalPolicy,
298 QskSizePolicy::Policy verticalPolicy )
304 Qt::Orientation orientation, QskSizePolicy::Policy policy )
308 if ( d->sizePolicy.policy( orientation ) != policy )
310 d->sizePolicy.setPolicy( orientation, policy );
311 d->layoutConstraintChanged();
317 return d_func()->sizePolicy;
322 return d_func()->sizePolicy.policy( orientation );
337 if ( layoutAlignmentHint() != alignment )
339 d->layoutAlignmentHint = alignment;
340 d->layoutConstraintChanged();
344Qt::Alignment QskControl::layoutAlignmentHint()
const
346 return static_cast< Qt::Alignment
>( d_func()->layoutAlignmentHint );
373 d->layoutConstraintChanged();
377void QskControl::resetPlacementPolicy()
387 d->placementPolicy(
true ), d->placementPolicy(
false ) );
392 return d_func()->placementPolicy( visiblity ==
Qsk::Visible );
402 return qskIsVisibleToLayout(
this );
407 setExplicitSizeHint( Qt::PreferredSize, size );
412 setExplicitSizeHint( Qt::PreferredSize, QSizeF( width, height ) );
417 const qreal height = explicitSizeHint( Qt::PreferredSize ).height();
418 setExplicitSizeHint( Qt::PreferredSize, QSizeF( width, height ) );
423 const qreal width = explicitSizeHint( Qt::PreferredSize ).width();
424 setExplicitSizeHint( Qt::PreferredSize, QSizeF( width, height ) );
429 setExplicitSizeHint( Qt::MinimumSize, size );
434 setExplicitSizeHint( Qt::MinimumSize, QSizeF( width, height ) );
439 const qreal height = explicitSizeHint( Qt::MinimumSize ).height();
440 setExplicitSizeHint( Qt::MinimumSize, QSizeF( width, height ) );
445 const qreal width = explicitSizeHint( Qt::MinimumSize ).width();
446 setExplicitSizeHint( Qt::MinimumSize, QSizeF( width, height ) );
451 setExplicitSizeHint( Qt::MaximumSize, size );
456 setExplicitSizeHint( Qt::MaximumSize, QSizeF( width, height ) );
461 const qreal height = explicitSizeHint( Qt::MaximumSize ).height();
462 setExplicitSizeHint( Qt::MaximumSize, QSizeF( width, height ) );
467 const qreal width = explicitSizeHint( Qt::MaximumSize ).width();
468 setExplicitSizeHint( Qt::MaximumSize, QSizeF( width, height ) );
473 const QSizeF newSize = size.expandedTo( QSizeF( 0, 0 ) );
475 const QskSizePolicy policy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
479 if ( policy != d->sizePolicy ||
480 d->explicitSizeHint( Qt::PreferredSize ) != newSize )
482 d->sizePolicy = policy;
483 d->setExplicitSizeHint( Qt::PreferredSize, newSize );
485 d->layoutConstraintChanged();
501 auto size = d->explicitSizeHint( Qt::PreferredSize );
503 if ( ( d->sizePolicy.horizontalPolicy() != QskSizePolicy::Fixed ) ||
504 ( size.width() != width ) )
506 size.setWidth( width );
508 d->sizePolicy.setHorizontalPolicy( QskSizePolicy::Fixed );
509 d->setExplicitSizeHint( Qt::PreferredSize, size );
511 d->layoutConstraintChanged();
522 auto size = d->explicitSizeHint( Qt::PreferredSize );
524 if ( ( d->sizePolicy.verticalPolicy() != QskSizePolicy::Fixed ) ||
525 ( size.height() != height ) )
527 size.setHeight( height );
529 d->sizePolicy.setVerticalPolicy( QskSizePolicy::Fixed );
530 d->setExplicitSizeHint( Qt::PreferredSize, size );
532 d->layoutConstraintChanged();
536void QskControl::resetExplicitSizeHint( Qt::SizeHint whichHint )
538 if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize )
542 const auto oldHint = d->explicitSizeHint( whichHint );
543 d->resetExplicitSizeHint( whichHint );
545 if ( oldHint != d->explicitSizeHint( whichHint ) )
546 d->layoutConstraintChanged();
550void QskControl::setExplicitSizeHint( Qt::SizeHint whichHint,
const QSizeF& size )
552 if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize )
554 const QSizeF newSize( ( size.width() < 0 ) ? -1.0 : size.width(),
555 ( size.height() < 0 ) ? -1.0 : size.height() );
559 if ( newSize != d->explicitSizeHint( whichHint ) )
561 d->setExplicitSizeHint( whichHint, newSize );
562 d->layoutConstraintChanged();
567void QskControl::setExplicitSizeHint(
568 Qt::SizeHint whichHint, qreal width, qreal height )
570 setExplicitSizeHint( whichHint, QSizeF( width, height ) );
573QSizeF QskControl::explicitSizeHint( Qt::SizeHint whichHint )
const
575 if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
578 return d_func()->explicitSizeHint( whichHint );
581QSizeF QskControl::implicitSizeHint(
582 Qt::SizeHint whichHint,
const QSizeF& constraint )
const
584 if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
587 if ( constraint.isValid() )
595 if ( whichHint == Qt::PreferredSize
596 && constraint.width() < 0.0 && constraint.height() < 0.0 )
603 hint = d_func()->implicitSizeHint( whichHint, constraint );
609QSizeF QskControl::effectiveSizeHint(
610 Qt::SizeHint which,
const QSizeF& constraint )
const
612 if ( which < Qt::MinimumSize || which > Qt::MaximumSize )
613 return QSizeF( 0, 0 );
615 if ( constraint.isValid() )
618 const bool isConstrained =
619 constraint.width() >= 0 || constraint.height() >= 0;
623 d->blockLayoutRequestEvents =
false;
632 hint = d->explicitSizeHint( which );
634 if ( !hint.isValid() )
636 const auto implicitHint = implicitSizeHint( which, constraint );
638 if ( hint.width() < 0 )
639 hint.setWidth( implicitHint.width() );
641 if ( hint.height() < 0 )
642 hint.setHeight( implicitHint.height() );
645 if ( !isConstrained && ( hint.width() >= 0 || hint.height() >= 0 ) )
652 if ( which == Qt::MaximumSize )
654 const auto minimumHint = d->explicitSizeHint( Qt::MinimumSize );
656 if ( hint.width() >= 0 )
657 hint.rwidth() = qMax( hint.width(), minimumHint.width() );
659 if ( hint.height() >= 0 )
660 hint.rheight() = qMax( hint.height(), minimumHint.height() );
662 else if ( which == Qt::PreferredSize )
664 const auto minimumHint = d->explicitSizeHint( Qt::MinimumSize );
665 const auto maximumHint = d->explicitSizeHint( Qt::MaximumSize );
667 if ( hint.width() >= 0 )
669 if ( maximumHint.width() >= 0 )
670 hint.rwidth() = qMin( hint.width(), maximumHint.width() );
672 hint.rwidth() = qMax( hint.width(), minimumHint.width() );
675 if ( hint.height() >= 0 )
677 if ( maximumHint.height() >= 0 )
678 hint.rheight() = qMin( hint.height(), maximumHint.height() );
680 hint.rheight() = qMax( hint.height(), minimumHint.height() );
690 const auto hint = effectiveSizeHint(
691 Qt::PreferredSize, QSizeF( width, -1.0 ) );
693 return hint.height();
698 const auto hint = effectiveSizeHint(
699 Qt::PreferredSize, QSizeF( -1.0, height ) );
705 Qt::SizeHint which,
const QSizeF& constraint )
const
707 return qskSizeConstraint(
this, which, constraint );
710bool QskControl::event( QEvent* event )
712 switch (
static_cast< int >( event->type() ) )
714 case QEvent::EnabledChange:
719 case QEvent::LocaleChange:
724 case QEvent::ContentsRectChange:
732 case QEvent::LayoutRequest:
742 case QEvent::StyleChange:
758 case QskEvent::Gesture:
763 case QEvent::MouseButtonPress:
775 if ( qskMaybeGesture(
this,
this, event ) )
780 if ( !event->isAccepted() )
791 if ( qskMaybeGesture(
this,
nullptr, event ) )
799 if ( qskMaybeGesture(
this,
this, event ) )
805bool QskControl::childMouseEventFilter( QQuickItem* child, QEvent* event )
825 return qskMaybeGesture(
this, child, event );
834 Inherited::hoverEnterEvent( event );
840 Inherited::hoverLeaveEvent( event );
845 const QQuickItem::ItemChangeData& value )
847 switch (
static_cast< int >( change ) )
849 case QQuickItem::ItemParentHasChanged:
853 if ( !d_func()->explicitLocale )
854 QskControlPrivate::resolveLocale(
this );
856 if ( !d_func()->explicitSection )
857 QskControlPrivate::resolveSection(
this );
862 qskSendEventTo(
this, QEvent::ParentChange );
867 case QQuickItem::ItemChildAddedChange:
868 case QQuickItem::ItemChildRemovedChange:
872 if ( qskIsVisibleToLayout( value.item ) )
875 if ( qskIsAdjustableByLayout( value.item ) )
880 case QQuickItem::ItemActiveFocusHasChanged:
891 const QRectF& newGeometry,
const QRectF& oldGeometry )
895 if ( newGeometry.size() != oldGeometry.size() )
902void QskControl::updateItemPolish()
906 if ( width() >= 0.0 || height() >= 0.0 )
912 const auto children = childItems();
913 for (
auto child : children )
915 if ( qskIsAdjustableByLayout( child ) )
917 const auto r = qskConstrainedItemRect( child,
rect );
918 qskSetItemGeometry( child, r );
927QSGNode* QskControl::updateItemPaintNode( QSGNode* node )
929 if ( node ==
nullptr )
945 if ( d->width <= 0.0 && d->height <= 0.0 )
953 const QRectF r( 0.0, 0.0, size.width(), size.height() );
954 return qskValidOrEmptyInnerRect( r,
margins() );
967void QskControl::updateLayout()
971void QskControl::updateResources()
975QSizeF QskControl::contentsSizeHint(
976 Qt::SizeHint which,
const QSizeF& constraint )
const
981QSizeF QskControl::layoutSizeHint(
982 Qt::SizeHint which,
const QSizeF& constraint )
const
990 const auto children = childItems();
992 for (
const auto child : children )
994 if ( !qskIsVisibleToLayout( child ) )
997 const auto policy = qskSizePolicy( child );
999 if ( constraint.width() >= 0.0 && policy.isConstrained( Qt::Vertical ) )
1001 const auto hint = qskSizeConstraint( child, which, constraint );
1002 h = qMax( h, hint.height() );
1004 else if ( constraint.height() >= 0.0 && policy.isConstrained( Qt::Horizontal ) )
1006 const auto hint = qskSizeConstraint( child, which, constraint );
1007 w = qMax( w, hint.width() );
1011 const auto hint = qskSizeConstraint( child, which, QSizeF() );
1013 w = qMax( w, hint.width() );
1014 h = qMax( h, hint.height() );
1018 return QSizeF( w, h );
1025 for (
auto mo =
metaObject(); mo !=
nullptr; mo = mo->superClass() )
1029 for (
auto subControl : moSubControls )
1033 if ( subControlEffective == subControl )
1043 if ( !
subControls.contains( subControlEffective ) )
1054#include "moc_QskControl.cpp"
Lookup key for a QskSkinHintTable.
static QVector< Subcontrol > subControls(const QMetaObject *)
Subcontrol
For use within the rendering or lay-outing of a specific QskSkinnable.
Base class of all controls.
void setMaximumWidth(qreal width)
void setLocale(const QLocale &)
QRectF subControlRect(QskAspect::Subcontrol) const
void localeChanged(const QLocale &)
static const QskAspect::State Disabled
static const QskAspect::State Hovered
void setMaximumHeight(qreal height)
void setFixedSize(const QSizeF &)
void hoverLeaveEvent(QHoverEvent *) override
bool isVisibleToLayout() const
void setMinimumHeight(qreal height)
qreal widthForHeight(qreal height) const
virtual QRectF focusIndicatorClipRect() const
void setAutoLayoutChildren(bool)
void setLayoutAlignmentHint(Qt::Alignment)
qreal heightForWidth(qreal width) const
void setSizePolicy(QskSizePolicy)
QRectF subControlContentsRect(QskAspect::Subcontrol) const
virtual QRectF focusIndicatorRect() const
void marginsChanged(const QMarginsF &)
void itemChange(ItemChange, const ItemChangeData &) override
void setPlacementPolicy(QskPlacementPolicy)
void setMinimumSize(const QSizeF &)
QRectF layoutRect() const
void setFixedWidth(qreal width)
void setPreferredSize(const QSizeF &)
void setPreferredWidth(qreal width)
QRectF contentsRect() const
void setPreferredHeight(qreal height)
void setBackground(const QskGradient &)
static const QskAspect::State Focused
QskPlacementPolicy placementPolicy
void hoverEnterEvent(QHoverEvent *) override
void geometryChange(const QRectF &, const QRectF &) override
void initSizePolicy(QskSizePolicy::Policy, QskSizePolicy::Policy)
virtual QRectF layoutRectForSize(const QSizeF &) const
void setBackgroundColor(const QColor &)
void setMinimumWidth(qreal width)
void setMaximumSize(const QSizeF &)
void setFixedHeight(qreal height)
QskControl(QQuickItem *parent=nullptr)
QVector< QskAspect::Subcontrol > subControls() const
QSizeF implicitSize() const
bool isVisibleToParent() const
void geometryChange(const QRectF &, const QRectF &) override
void itemChange(ItemChange, const ItemChangeData &) override
bool event(QEvent *) override
bool maybeUnresized() const
Policy hiddenPolicy
Policy for the item, when being hidden ( to its parent )
Policy visiblePolicy
Policy for the item, when being visible ( to its parent )
QMarginsF paddingHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a padding hint.
bool resetColor(QskAspect)
Removes a color hint from the local table.
QskGradient gradientHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a color hint as gradient.
bool setPaddingHint(QskAspect, qreal)
Sets a padding hint.
bool setGradientHint(QskAspect, const QskGradient &)
Sets a gradient as color hint.
virtual const QMetaObject * metaObject() const =0
const QskSkinlet * skinlet() const
const QskSkinlet * effectiveSkinlet() const
void setSkinlet(const QskSkinlet *)
Set an individual skinlet to render/display the content.
void setSkinStateFlag(QskAspect::State, bool on=true)
QskAspect::Subcontrol effectiveSubcontrol(QskAspect::Subcontrol) const
QColor color(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a color hint.
bool resetPaddingHint(QskAspect)
Removes a padding hint from the local table.
virtual void updateNode(QSGNode *)
Visibility
Visibility of an object.