processing of all type of size constraints ( minimum/preferred/maximum )
completed
This commit is contained in:
parent
9e87cb7b23
commit
177bb699bc
@ -61,7 +61,11 @@ void ButtonBar::addIndicator( const char* name )
|
||||
label->setGraphic( QskGraphicIO::read( fileName ) );
|
||||
}
|
||||
|
||||
QSizeF ButtonBar::contentsSizeHint() const
|
||||
QSizeF ButtonBar::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
return QSizeF( -1, 20 );
|
||||
if ( which == Qt::PreferredSize )
|
||||
return QSizeF( -1, 20 );
|
||||
|
||||
return QSizeF();
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class ButtonBar : public QskLinearBox
|
||||
void addIndicator( const char* name );
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -132,8 +132,11 @@ class MarkerControlButton final : public QskPushButton
|
||||
}
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override
|
||||
QSizeF contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const override
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const qreal dim = 100;
|
||||
|
||||
if ( m_direction == Qsk::LeftToRight || m_direction == Qsk::RightToLeft )
|
||||
@ -167,10 +170,15 @@ class ControlButton final : public QskPushButton
|
||||
return QskPushButton::effectiveSubcontrol( subControl );
|
||||
}
|
||||
|
||||
QSizeF contentsSizeHint() const override
|
||||
QSizeF contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const override
|
||||
{
|
||||
qreal h = QskPushButton::contentsSizeHint().height();
|
||||
return QSizeF( h, h );
|
||||
if ( which == Qt::PreferredSize )
|
||||
{
|
||||
qreal h = QskPushButton::contentsSizeHint( which, QSizeF() ).height();
|
||||
return QSizeF( h, h );
|
||||
}
|
||||
|
||||
return QSizeF();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -19,11 +19,11 @@ namespace
|
||||
Control( const char* colorName, QQuickItem* parent = nullptr );
|
||||
Control( const char* colorName, qreal aspectRatio, QQuickItem* parent = nullptr );
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
void transpose();
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
qreal m_aspectRatio;
|
||||
};
|
||||
@ -65,14 +65,19 @@ Control::Control( const char* colorName, qreal aspectRatio, QQuickItem* parent )
|
||||
setPreferredHeight( 100 );
|
||||
}
|
||||
|
||||
qreal Control::heightForWidth( qreal width ) const
|
||||
QSizeF Control::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
return width / m_aspectRatio;
|
||||
}
|
||||
if ( which == Qt::PreferredSize )
|
||||
{
|
||||
if ( constraint.width() >= 0.0 )
|
||||
return QSizeF( -1.0, constraint.width() / m_aspectRatio );
|
||||
|
||||
qreal Control::widthForHeight( qreal height ) const
|
||||
{
|
||||
return height * m_aspectRatio;
|
||||
if ( constraint.height() >= 0.0 )
|
||||
return QSizeF( constraint.height() * m_aspectRatio, -1.0 );
|
||||
}
|
||||
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
void Control::transpose()
|
||||
|
@ -179,26 +179,33 @@ QskGraphic MyToggleButton::graphicAt( int index ) const
|
||||
return data.icon;
|
||||
}
|
||||
|
||||
QSizeF MyToggleButton::contentsSizeHint() const
|
||||
QSizeF MyToggleButton::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
const qreal width = metric( Panel | QskAspect::MinimumWidth );
|
||||
const qreal height = metric( Panel | QskAspect::MinimumHeight );
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
return QSizeF( width, height );
|
||||
}
|
||||
qreal w = constraint.width();
|
||||
qreal h = constraint.height();
|
||||
|
||||
// better use Minimum Width/Height hints TODO ...
|
||||
// better use Minimum Width/Height hints TODO ...
|
||||
constexpr qreal aspectRatio = 4.0 / 3.0;
|
||||
|
||||
static constexpr qreal aspectRatio = 4.0 / 3.0;
|
||||
if ( w >= 0.0 )
|
||||
{
|
||||
h = w / aspectRatio;
|
||||
}
|
||||
else if ( h >= 0.0 )
|
||||
{
|
||||
w = h * aspectRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = metric( Panel | QskAspect::MinimumWidth );
|
||||
h = metric( Panel | QskAspect::MinimumHeight );
|
||||
}
|
||||
|
||||
qreal MyToggleButton::heightForWidth( qreal width ) const
|
||||
{
|
||||
return width / aspectRatio;
|
||||
}
|
||||
|
||||
qreal MyToggleButton::widthForHeight( qreal height ) const
|
||||
{
|
||||
return height * aspectRatio;
|
||||
return QSizeF( w, h );
|
||||
}
|
||||
|
||||
void MyToggleButton::updateLayout()
|
||||
|
@ -29,9 +29,6 @@ class MyToggleButton : public QskAbstractButton
|
||||
void setIconAt( int index, const QString& icon );
|
||||
QString iconAt( int index ) const;
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
void setTextOptions( const QskTextOptions& );
|
||||
QskTextOptions textOptions() const;
|
||||
|
||||
@ -45,7 +42,7 @@ class MyToggleButton : public QskAbstractButton
|
||||
|
||||
protected:
|
||||
void updateLayout() override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -53,10 +53,15 @@ Slider::Slider( QQuickItem* parentItem )
|
||||
this, &QskControl::focusIndicatorRectChanged );
|
||||
}
|
||||
|
||||
QSizeF Slider::contentsSizeHint() const
|
||||
QSizeF Slider::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
const qreal extra = 40;
|
||||
return Inherited::contentsSizeHint() + QSizeF( 0, extra );
|
||||
auto size = Inherited::contentsSizeHint( which, constraint );
|
||||
|
||||
if ( which == Qt::PreferredSize && size.height() >= 0 )
|
||||
size.setHeight( size.height() + 40 );
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QRectF Slider::focusIndicatorRect() const
|
||||
|
@ -20,7 +20,7 @@ class Slider : public QskSlider
|
||||
QRectF focusIndicatorRect() const override;
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "Variable.h"
|
||||
#include "Expression.h"
|
||||
|
||||
#include <QskLayoutConstraint.h>
|
||||
#include <QskEvent.h>
|
||||
#include <QskQuick.h>
|
||||
|
||||
@ -122,14 +121,18 @@ void AnchorBox::PrivateData::setupSolver( int type, Solver& solver )
|
||||
|
||||
if ( type < 0 || type == Qt::MinimumSize )
|
||||
{
|
||||
const auto minSize = QskLayoutConstraint::sizeHint( item, Qt::MinimumSize );
|
||||
solver.addConstraint( r.right >= r.left + minSize.width() );
|
||||
solver.addConstraint( r.bottom >= r.top + minSize.height() );
|
||||
const auto minSize = qskSizeConstraint( item, Qt::MinimumSize );
|
||||
|
||||
if ( minSize.width() >= 0.0 )
|
||||
solver.addConstraint( r.right >= r.left + minSize.width() );
|
||||
|
||||
if ( minSize.height() >= 0.0 )
|
||||
solver.addConstraint( r.bottom >= r.top + minSize.height() );
|
||||
}
|
||||
|
||||
if ( type < 0 || type == Qt::PreferredSize )
|
||||
{
|
||||
const auto prefSize = QskLayoutConstraint::sizeHint( item, Qt::PreferredSize );
|
||||
const auto prefSize = qskSizeConstraint( item, Qt::PreferredSize );
|
||||
|
||||
Constraint c1( r.right == r.left + prefSize.width(), Strength::strong );
|
||||
solver.addConstraint( c1 );
|
||||
@ -140,11 +143,11 @@ void AnchorBox::PrivateData::setupSolver( int type, Solver& solver )
|
||||
|
||||
if ( type < 0 || type == Qt::MaximumSize )
|
||||
{
|
||||
const auto maxSize = QskLayoutConstraint::sizeHint( item, Qt::MaximumSize );
|
||||
if ( maxSize.width() < QskLayoutConstraint::unlimited )
|
||||
const auto maxSize = qskSizeConstraint( item, Qt::MaximumSize );
|
||||
if ( maxSize.width() >= 0.0 )
|
||||
solver.addConstraint( r.right <= r.left + maxSize.width() );
|
||||
|
||||
if ( maxSize.height() < QskLayoutConstraint::unlimited )
|
||||
if ( maxSize.height() >= 0.0 )
|
||||
solver.addConstraint( r.bottom <= r.top + maxSize.height() );
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,37 @@ void QskSizePolicy::setPolicy( Qt::Orientation orientation, Policy policy )
|
||||
setVerticalPolicy( policy );
|
||||
}
|
||||
|
||||
QskSizePolicy::ConstraintType QskSizePolicy::constraintType() const
|
||||
{
|
||||
if ( horizontalPolicy() & ConstrainedFlag )
|
||||
return QskSizePolicy::WidthForHeight;
|
||||
|
||||
if ( verticalPolicy() & ConstrainedFlag )
|
||||
return QskSizePolicy::HeightForWidth;
|
||||
|
||||
return QskSizePolicy::Unconstrained;
|
||||
}
|
||||
|
||||
Qt::SizeHint QskSizePolicy::effectiveSizeHintType(
|
||||
Qt::SizeHint which, Qt::Orientation orientation ) const
|
||||
{
|
||||
const auto policy = ( orientation == Qt::Horizontal )
|
||||
? horizontalPolicy() : verticalPolicy();
|
||||
|
||||
if ( which == Qt::MinimumSize )
|
||||
{
|
||||
if ( !( policy & ShrinkFlag ) )
|
||||
return Qt::PreferredSize;
|
||||
}
|
||||
else if ( which == Qt::MaximumSize )
|
||||
{
|
||||
if ( !( policy & ( GrowFlag | ExpandFlag ) ) )
|
||||
return Qt::PreferredSize;
|
||||
}
|
||||
|
||||
return which;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define QSK_SIZE_POLICY_H_
|
||||
|
||||
#include "QskGlobal.h"
|
||||
#include <qnamespace.h>
|
||||
#include <qmetatype.h>
|
||||
|
||||
class QDebug;
|
||||
@ -52,8 +53,17 @@ class QSK_EXPORT QskSizePolicy
|
||||
ConstrainedExpanding = ConstrainedFlag | Expanding
|
||||
};
|
||||
|
||||
enum ConstraintType
|
||||
{
|
||||
Unconstrained = 0,
|
||||
|
||||
WidthForHeight = 1 << 0,
|
||||
HeightForWidth = 1 << 1
|
||||
};
|
||||
|
||||
Q_ENUM( Flag )
|
||||
Q_ENUM( Policy )
|
||||
Q_ENUM( ConstraintType )
|
||||
|
||||
QskSizePolicy();
|
||||
QskSizePolicy( Policy horizontalPolicy, Policy verticalPolicy );
|
||||
@ -70,6 +80,12 @@ class QSK_EXPORT QskSizePolicy
|
||||
Policy policy( Qt::Orientation ) const;
|
||||
void setPolicy( Qt::Orientation, Policy );
|
||||
|
||||
ConstraintType constraintType() const;
|
||||
bool isConstrained( Qt::Orientation ) const;
|
||||
|
||||
Qt::SizeHint effectiveSizeHintType(
|
||||
Qt::SizeHint, Qt::Orientation ) const;
|
||||
|
||||
private:
|
||||
unsigned char m_horizontalPolicy;
|
||||
unsigned char m_verticalPolicy;
|
||||
@ -119,6 +135,11 @@ inline QskSizePolicy::Policy QskSizePolicy::verticalPolicy() const
|
||||
return static_cast< Policy >( m_verticalPolicy );
|
||||
}
|
||||
|
||||
inline bool QskSizePolicy::isConstrained( Qt::Orientation orientation ) const
|
||||
{
|
||||
return ( policy( orientation ) & ConstrainedFlag );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QSK_EXPORT QDebug operator<<( QDebug, const QskSizePolicy& );
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@ class QSK_EXPORT QskAnimationHint
|
||||
QEasingCurve::Type type = QEasingCurve::Linear ) noexcept
|
||||
: duration( duration )
|
||||
, type( type )
|
||||
, updateFlags( UpdateAuto )
|
||||
, updateFlags( UpdateAuto )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,29 +47,17 @@ QRectF QskBox::layoutRectForSize( const QSizeF& size ) const
|
||||
return innerBox( Panel, subControlRect( size, Panel ) );
|
||||
}
|
||||
|
||||
QSizeF QskBox::contentsSizeHint() const
|
||||
QSizeF QskBox::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( !m_hasPanel )
|
||||
return Inherited::contentsSizeHint();
|
||||
|
||||
QSizeF size( -1, -1 );
|
||||
|
||||
if ( autoLayoutChildren() )
|
||||
if ( m_hasPanel && which == Qt::PreferredSize )
|
||||
{
|
||||
const QSizeF hint = Inherited::contentsSizeHint();
|
||||
|
||||
if ( hint.width() > 0 )
|
||||
size.setWidth( hint.width() );
|
||||
|
||||
if ( hint.height() > 0 )
|
||||
size.setHeight( hint.height() );
|
||||
return QSizeF(
|
||||
metric( Panel | QskAspect::MinimumWidth ),
|
||||
metric( Panel | QskAspect::MinimumHeight ) );
|
||||
}
|
||||
|
||||
const QSizeF minSize(
|
||||
metric( Panel | QskAspect::MinimumWidth ),
|
||||
metric( Panel | QskAspect::MinimumHeight ) );
|
||||
|
||||
return outerBoxSize( Panel, size ).expandedTo( minSize );
|
||||
return Inherited::contentsSizeHint( which, constraint );
|
||||
}
|
||||
|
||||
#include "moc_QskBox.cpp"
|
||||
|
@ -27,15 +27,15 @@ class QSK_EXPORT QskBox : public QskControl
|
||||
|
||||
void setPanel( bool );
|
||||
bool hasPanel() const;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void panelChanged( bool );
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
bool m_hasPanel;
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "QskSkin.h"
|
||||
#include "QskSkinlet.h"
|
||||
#include "QskSkinHintTable.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskLayoutHint.h"
|
||||
|
||||
#include <qlocale.h>
|
||||
#include <qvector.h>
|
||||
@ -374,7 +374,7 @@ void QskControl::setLayoutHint( LayoutHint flag, bool on )
|
||||
d->layoutHints |= flag;
|
||||
else
|
||||
d->layoutHints &= ~flag;
|
||||
|
||||
|
||||
d->layoutConstraintChanged();
|
||||
}
|
||||
}
|
||||
@ -569,17 +569,17 @@ void QskControl::setExplicitSizeHint(
|
||||
|
||||
QSizeF QskControl::explicitSizeHint( Qt::SizeHint whichHint ) const
|
||||
{
|
||||
if ( whichHint >= Qt::MinimumSize && whichHint <= Qt::MaximumSize )
|
||||
return d_func()->explicitSizeHint( whichHint );
|
||||
if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
|
||||
return QSizeF();
|
||||
|
||||
return QSizeF( -1, -1 );
|
||||
return d_func()->explicitSizeHint( whichHint );
|
||||
}
|
||||
|
||||
QSizeF QskControl::implicitSizeHint(
|
||||
Qt::SizeHint whichHint, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
|
||||
return QSizeF( -1, -1 );
|
||||
return QSizeF();
|
||||
|
||||
if ( constraint.isValid() )
|
||||
{
|
||||
@ -587,108 +587,94 @@ QSizeF QskControl::implicitSizeHint(
|
||||
return constraint;
|
||||
}
|
||||
|
||||
QSizeF hint( -1, -1 );
|
||||
QSizeF hint;
|
||||
|
||||
if ( whichHint == Qt::PreferredSize )
|
||||
if ( whichHint == Qt::PreferredSize
|
||||
&& constraint.width() < 0.0 && constraint.height() < 0.0 )
|
||||
{
|
||||
if ( constraint.width() >= 0 )
|
||||
{
|
||||
hint.setWidth( constraint.width() );
|
||||
hint.setHeight( heightForWidth( constraint.width() ) );
|
||||
}
|
||||
else if ( constraint.height() >= 0 )
|
||||
{
|
||||
hint.setWidth( widthForHeight( constraint.height() ) );
|
||||
hint.setHeight( constraint.height() );
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = implicitSize();
|
||||
}
|
||||
// this one might be cached
|
||||
hint = implicitSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO ...
|
||||
hint = d_func()->implicitSizeHint( whichHint, constraint );
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
QSizeF QskControl::effectiveSizeHint(
|
||||
Qt::SizeHint whichHint, const QSizeF& constraint ) const
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
|
||||
if ( which < Qt::MinimumSize || which > Qt::MaximumSize )
|
||||
return QSizeF( 0, 0 );
|
||||
|
||||
if ( constraint.isValid() )
|
||||
return constraint;
|
||||
|
||||
const bool isConstrained =
|
||||
constraint.width() >= 0 || constraint.height() >= 0;
|
||||
|
||||
Q_D( const QskControl );
|
||||
|
||||
d->blockLayoutRequestEvents = false;
|
||||
|
||||
/*
|
||||
The explicit size has always precedence over te implicit size.
|
||||
QSizeF hint;
|
||||
|
||||
Implicit sizes are currently only implemented for preferred and
|
||||
explicitSizeHint returns valid explicit hints for minimum/maximum
|
||||
even if not being set by application code.
|
||||
/*
|
||||
The explicit size has always precedence over the implicit size,
|
||||
and will kill the effect of the constraint
|
||||
*/
|
||||
|
||||
QSizeF hint = d->explicitSizeHint( whichHint );
|
||||
hint = d->explicitSizeHint( which );
|
||||
|
||||
if ( !hint.isValid() )
|
||||
{
|
||||
#if 0
|
||||
if ( hint.width() >= 0 && constraint.width() >= 0 )
|
||||
constraint.setWidth( hint.width() );
|
||||
|
||||
if ( hint.height() >= 0 && constraint.height() >= 0 )
|
||||
constraint.setHeight( hint.height() );
|
||||
#endif
|
||||
|
||||
const auto implicit = implicitSizeHint( whichHint, constraint );
|
||||
const auto implicitHint = implicitSizeHint( which, constraint );
|
||||
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( implicit.width() );
|
||||
hint.setWidth( implicitHint.width() );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( implicit.height() );
|
||||
hint.setHeight( implicitHint.height() );
|
||||
}
|
||||
|
||||
if ( hint.width() >= 0 || hint.height() >= 0 )
|
||||
if ( !isConstrained && ( hint.width() >= 0 || hint.height() >= 0 ) )
|
||||
{
|
||||
/*
|
||||
We might need to normalize the hints, so that
|
||||
We normalize the unconstrained hints by the explicit hints, so that
|
||||
we always have: minimum <= preferred <= maximum.
|
||||
*/
|
||||
|
||||
if ( whichHint == Qt::MaximumSize )
|
||||
if ( which == Qt::MaximumSize )
|
||||
{
|
||||
const auto minimumHint = d->explicitSizeHint( Qt::MinimumSize );
|
||||
|
||||
if ( hint.width() >= 0 )
|
||||
hint.setWidth( qMax( hint.width(), minimumHint.width() ) );
|
||||
hint.rwidth() = qMax( hint.width(), minimumHint.width() );
|
||||
|
||||
if ( hint.height() >= 0 )
|
||||
hint.setHeight( qMax( hint.height(), minimumHint.height() ) );
|
||||
hint.rheight() = qMax( hint.height(), minimumHint.height() );
|
||||
}
|
||||
else if ( whichHint == Qt::PreferredSize )
|
||||
else if ( which == Qt::PreferredSize )
|
||||
{
|
||||
const auto minimumHint = d->explicitSizeHint( Qt::MinimumSize );
|
||||
const auto maximumHint = d->explicitSizeHint( Qt::MaximumSize );
|
||||
|
||||
if ( hint.width() >= 0 )
|
||||
{
|
||||
const auto minW = minimumHint.width();
|
||||
const auto maxW = qMax( minW, maximumHint.width() );
|
||||
if ( maximumHint.width() >= 0 )
|
||||
hint.rwidth() = qMin( hint.width(), maximumHint.width() );
|
||||
|
||||
hint.setWidth( qBound( minW, hint.width(), maxW ) );
|
||||
hint.rwidth() = qMax( hint.width(), minimumHint.width() );
|
||||
}
|
||||
|
||||
if ( hint.height() >= 0 )
|
||||
{
|
||||
const auto minH = minimumHint.height();
|
||||
const auto maxH = qMax( minH, maximumHint.height() );
|
||||
if ( maximumHint.height() >= 0 )
|
||||
hint.rheight() = qMin( hint.height(), maximumHint.height() );
|
||||
|
||||
hint.setHeight( qBound( minH, hint.height(), maxH ) );
|
||||
hint.rheight() = qMax( hint.height(), minimumHint.height() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -698,32 +684,18 @@ QSizeF QskControl::effectiveSizeHint(
|
||||
|
||||
qreal QskControl::heightForWidth( qreal width ) const
|
||||
{
|
||||
Q_D( const QskControl );
|
||||
const auto hint = effectiveSizeHint(
|
||||
Qt::PreferredSize, QSizeF( width, -1.0 ) );
|
||||
|
||||
d->blockLayoutRequestEvents = false;
|
||||
|
||||
if ( d->autoLayoutChildren )
|
||||
{
|
||||
using namespace QskLayoutConstraint;
|
||||
return constrainedMetric( HeightForWidth, this, width, constrainedChildrenMetric );
|
||||
}
|
||||
|
||||
return -1.0;
|
||||
return hint.height();
|
||||
}
|
||||
|
||||
qreal QskControl::widthForHeight( qreal height ) const
|
||||
{
|
||||
Q_D( const QskControl );
|
||||
const auto hint = effectiveSizeHint(
|
||||
Qt::PreferredSize, QSizeF( -1.0, height ) );
|
||||
|
||||
d->blockLayoutRequestEvents = false;
|
||||
|
||||
if ( d->autoLayoutChildren )
|
||||
{
|
||||
using namespace QskLayoutConstraint;
|
||||
return constrainedMetric( WidthForHeight, this, height, constrainedChildrenMetric );
|
||||
}
|
||||
|
||||
return -1.0;
|
||||
return hint.width();
|
||||
}
|
||||
|
||||
bool QskControl::event( QEvent* event )
|
||||
@ -918,10 +890,8 @@ void QskControl::updateItemPolish()
|
||||
// checking qskIsVisibleToParent ???
|
||||
if ( !qskIsTransparentForPositioner( child ) )
|
||||
{
|
||||
const auto itemRect = QskLayoutConstraint::boundedRect(
|
||||
child, rect, QskLayoutConstraint::layoutAlignmentHint( child ) );
|
||||
|
||||
qskSetItemGeometry( child, itemRect );
|
||||
const auto r = qskConstrainedItemRect( child, rect );
|
||||
qskSetItemGeometry( child, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -978,26 +948,30 @@ void QskControl::updateResources()
|
||||
{
|
||||
}
|
||||
|
||||
QSizeF QskControl::contentsSizeHint() const
|
||||
QSizeF QskControl::contentsSizeHint(
|
||||
Qt::SizeHint, const QSizeF& constraint ) const
|
||||
{
|
||||
qreal w = -1; // no hint
|
||||
qreal h = -1;
|
||||
return constraint;
|
||||
}
|
||||
|
||||
if ( d_func()->autoLayoutChildren )
|
||||
QSizeF QskControl::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( !d_func()->autoLayoutChildren )
|
||||
return QSizeF();
|
||||
|
||||
qreal w = constraint.width();
|
||||
qreal h = constraint.height();
|
||||
|
||||
const auto children = childItems();
|
||||
for ( const auto child : children )
|
||||
{
|
||||
const auto children = childItems();
|
||||
for ( const auto child : children )
|
||||
if ( qskIsVisibleToLayout( child ) )
|
||||
{
|
||||
if ( auto control = qskControlCast( child ) )
|
||||
{
|
||||
if ( !control->isTransparentForPositioner() )
|
||||
{
|
||||
const QSizeF hint = control->sizeHint();
|
||||
const auto hint = qskEffectiveSizeHint( child, which, constraint );
|
||||
|
||||
w = qMax( w, hint.width() );
|
||||
h = qMax( h, hint.height() );
|
||||
}
|
||||
}
|
||||
w = QskLayoutHint::combined( which, w, hint.width() );
|
||||
h = QskLayoutHint::combined( which, h, hint.height() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,12 +152,12 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
|
||||
QSizeF implicitSizeHint( Qt::SizeHint, const QSizeF& constraint ) const;
|
||||
|
||||
QSizeF sizeHint() const;
|
||||
qreal heightForWidth( qreal width ) const;
|
||||
qreal widthForHeight( qreal height ) const;
|
||||
|
||||
QSizeF effectiveSizeHint( Qt::SizeHint,
|
||||
const QSizeF& constraint = QSizeF() ) const;
|
||||
|
||||
virtual qreal heightForWidth( qreal width ) const;
|
||||
virtual qreal widthForHeight( qreal height ) const;
|
||||
|
||||
QLocale locale() const;
|
||||
void resetLocale();
|
||||
|
||||
@ -195,8 +195,8 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable
|
||||
virtual void updateResources();
|
||||
virtual void updateLayout();
|
||||
|
||||
protected:
|
||||
virtual QSizeF contentsSizeHint() const;
|
||||
virtual QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const;
|
||||
virtual QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const;
|
||||
|
||||
private:
|
||||
void setActiveFocusOnTab( bool ) = delete; // use setFocusPolicy
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "QskControlPrivate.h"
|
||||
#include "QskSetup.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskLayoutHint.h"
|
||||
|
||||
static inline void qskSendEventTo( QObject* object, QEvent::Type type )
|
||||
{
|
||||
@ -71,7 +71,7 @@ void QskControlPrivate::layoutConstraintChanged()
|
||||
|
||||
void QskControlPrivate::implicitSizeChanged()
|
||||
{
|
||||
if ( !q_func()->explicitSizeHint( Qt::PreferredSize ).isValid() )
|
||||
if ( !( explicitSizeHints && explicitSizeHints[ Qt::PreferredSize ].isValid() ) )
|
||||
{
|
||||
// when we have no explit size, the implicit size matters
|
||||
layoutConstraintChanged();
|
||||
@ -79,17 +79,95 @@ void QskControlPrivate::implicitSizeChanged()
|
||||
}
|
||||
|
||||
QSizeF QskControlPrivate::implicitSizeHint() const
|
||||
{
|
||||
return implicitSizeHint( Qt::PreferredSize, QSizeF() );
|
||||
}
|
||||
|
||||
QSizeF QskControlPrivate::implicitSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
Q_Q( const QskControl );
|
||||
|
||||
const auto m = q->margins();
|
||||
const auto dw = m.left() + m.right();
|
||||
const auto dh = m.top() + m.bottom();
|
||||
/*
|
||||
The hint is calculated from the contents ( usually scene graph nodes )
|
||||
and - when being a container - the children.
|
||||
*/
|
||||
QSizeF contentsHint;
|
||||
|
||||
const auto hint = q->contentsSizeHint();
|
||||
{
|
||||
const auto m = q->margins();
|
||||
const auto dw = m.left() + m.right();
|
||||
const auto dh = m.top() + m.bottom();
|
||||
|
||||
const qreal w = ( hint.width() >= 0 ) ? dw + hint.width() : -1.0;
|
||||
const qreal h = ( hint.height() >= 0 ) ? dh + hint.height() : -1.0;
|
||||
if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
contentsHint.setWidth( qMax( constraint.width() - dw, 0.0 ) );
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
contentsHint.setHeight( qMax( constraint.height() - dh, 0.0 ) );
|
||||
}
|
||||
|
||||
contentsHint = q->contentsSizeHint( which, contentsHint );
|
||||
|
||||
if ( contentsHint.rwidth() >= 0 )
|
||||
contentsHint.rwidth() += dw;
|
||||
|
||||
if ( contentsHint.rheight() >= 0 )
|
||||
contentsHint.rheight() += dh;
|
||||
}
|
||||
|
||||
QSizeF layoutHint;
|
||||
{
|
||||
if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
const QSizeF boundingSize( constraint.width(), 1e6 );
|
||||
const QSizeF layoutSize = q->layoutRectForSize( boundingSize ).size();
|
||||
|
||||
layoutHint = q->layoutSizeHint( which, QSizeF( layoutSize.width(), -1 ) );
|
||||
|
||||
if ( layoutHint.height() >= 0 )
|
||||
layoutHint.rheight() += boundingSize.height() - layoutSize.height();
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
const QSizeF boundingSize( 1e6, constraint.height() );
|
||||
const QSizeF layoutSize = q->layoutRectForSize( boundingSize ).size();
|
||||
|
||||
layoutHint = q->layoutSizeHint( which, QSizeF( -1, layoutSize.height() ) );
|
||||
|
||||
if ( layoutHint.width() >= 0 )
|
||||
layoutHint.rwidth() += boundingSize.width() - layoutSize.width();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
In situations, where layoutRectForSize depends on
|
||||
the size ( f.e when using a corner radius of Qt::RelativeSize )
|
||||
we will have wrong results. TODO ...
|
||||
*/
|
||||
const QSizeF boundingSize( 1000.0, 1000.0 );
|
||||
const QSizeF layoutSize = q->layoutRectForSize( boundingSize ).size();
|
||||
|
||||
layoutHint = q->layoutSizeHint( which, QSizeF() );
|
||||
|
||||
if ( layoutHint.width() >= 0 )
|
||||
layoutHint.rwidth() += boundingSize.width() - layoutSize.width();
|
||||
|
||||
if ( layoutHint.height() >= 0 )
|
||||
layoutHint.rheight() += boundingSize.height() - layoutSize.height();
|
||||
}
|
||||
}
|
||||
|
||||
// Combining both hints
|
||||
qreal w = constraint.width();
|
||||
qreal h = constraint.height();
|
||||
|
||||
if ( w < 0.0 )
|
||||
w = QskLayoutHint::combined( which, contentsHint.width(), layoutHint.width() );
|
||||
|
||||
if ( h < 0.0 )
|
||||
h = QskLayoutHint::combined( which, contentsHint.height(), layoutHint.height() );
|
||||
|
||||
return QSizeF( w, h );
|
||||
}
|
||||
@ -98,14 +176,7 @@ void QskControlPrivate::setExplicitSizeHint(
|
||||
Qt::SizeHint whichHint, const QSizeF& size )
|
||||
{
|
||||
if ( explicitSizeHints == nullptr )
|
||||
{
|
||||
using namespace QskLayoutConstraint;
|
||||
|
||||
explicitSizeHints = new QSizeF[3];
|
||||
explicitSizeHints[0] = defaultSizeHints[0];
|
||||
explicitSizeHints[1] = defaultSizeHints[1];
|
||||
explicitSizeHints[2] = defaultSizeHints[2];
|
||||
}
|
||||
|
||||
explicitSizeHints[ whichHint ] = size;
|
||||
}
|
||||
@ -113,10 +184,7 @@ void QskControlPrivate::setExplicitSizeHint(
|
||||
void QskControlPrivate::resetExplicitSizeHint( Qt::SizeHint whichHint )
|
||||
{
|
||||
if ( explicitSizeHints )
|
||||
{
|
||||
using namespace QskLayoutConstraint;
|
||||
explicitSizeHints[ whichHint ] = defaultSizeHints[ whichHint ];
|
||||
}
|
||||
explicitSizeHints[ whichHint ] = QSizeF();
|
||||
}
|
||||
|
||||
QSizeF QskControlPrivate::explicitSizeHint( Qt::SizeHint whichHint ) const
|
||||
@ -124,7 +192,7 @@ QSizeF QskControlPrivate::explicitSizeHint( Qt::SizeHint whichHint ) const
|
||||
if ( explicitSizeHints )
|
||||
return explicitSizeHints[ whichHint ];
|
||||
|
||||
return QskLayoutConstraint::defaultSizeHints[ whichHint ];
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
bool QskControlPrivate::maybeGesture( QQuickItem* child, QEvent* event )
|
||||
|
@ -30,12 +30,14 @@ class QskControlPrivate : public QskQuickItemPrivate
|
||||
void resetExplicitSizeHint( Qt::SizeHint );
|
||||
QSizeF explicitSizeHint( Qt::SizeHint ) const;
|
||||
|
||||
bool maybeGesture( QQuickItem*, QEvent* );
|
||||
|
||||
QSizeF implicitSizeHint( Qt::SizeHint, const QSizeF& ) const;
|
||||
QSizeF implicitSizeHint() const override final;
|
||||
|
||||
void implicitSizeChanged() override final;
|
||||
void layoutConstraintChanged() override final;
|
||||
|
||||
bool maybeGesture( QQuickItem*, QEvent* );
|
||||
|
||||
private:
|
||||
Q_DECLARE_PUBLIC( QskControl )
|
||||
|
||||
|
@ -50,7 +50,7 @@ QskFocusIndicator::~QskFocusIndicator()
|
||||
{
|
||||
}
|
||||
|
||||
bool QskFocusIndicator::contains( const QPointF & ) const
|
||||
bool QskFocusIndicator::contains( const QPointF& ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class QSK_EXPORT QskFocusIndicator : public QskControl
|
||||
QskFocusIndicator( QQuickItem* parent = nullptr );
|
||||
~QskFocusIndicator() override;
|
||||
|
||||
bool contains( const QPointF & ) const override;
|
||||
bool contains( const QPointF& ) const override;
|
||||
|
||||
protected:
|
||||
void windowChangeEvent( QskWindowChangeEvent* ) override;
|
||||
|
@ -449,7 +449,7 @@ void QskGestureRecognizer::reject()
|
||||
m_data->isReplayingEvents = true;
|
||||
|
||||
if ( window->mouseGrabberItem() == watchedItem )
|
||||
watchedItem->ungrabMouse();
|
||||
watchedItem->ungrabMouse();
|
||||
|
||||
if ( !events.isEmpty() &&
|
||||
( events[ 0 ]->type() == QEvent::MouseButtonPress ) )
|
||||
|
@ -248,27 +248,29 @@ void QskGraphicLabel::updateLayout()
|
||||
m_data->isSourceDirty = false;
|
||||
}
|
||||
|
||||
qreal QskGraphicLabel::heightForWidth( qreal width ) const
|
||||
QSizeF QskGraphicLabel::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
const QSizeF sz = effectiveSourceSize();
|
||||
if ( sz.isEmpty() )
|
||||
return 0;
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
return sz.height() * width / sz.width();
|
||||
}
|
||||
auto sz = effectiveSourceSize();
|
||||
|
||||
qreal QskGraphicLabel::widthForHeight( qreal height ) const
|
||||
{
|
||||
const QSizeF sz = effectiveSourceSize();
|
||||
if ( sz.isEmpty() )
|
||||
return 0;
|
||||
if ( !sz.isEmpty() )
|
||||
{
|
||||
if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
sz.setHeight( sz.height() * constraint.width() / sz.width() );
|
||||
sz.setWidth( constraint.width() );
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
sz.setWidth( sz.width() * constraint.height() / sz.height() );
|
||||
sz.setHeight( constraint.height() );
|
||||
}
|
||||
}
|
||||
|
||||
return sz.width() * height / sz.height();
|
||||
}
|
||||
|
||||
QSizeF QskGraphicLabel::contentsSizeHint() const
|
||||
{
|
||||
return effectiveSourceSize();
|
||||
return sz;
|
||||
}
|
||||
|
||||
QSizeF QskGraphicLabel::effectiveSourceSize() const
|
||||
|
@ -77,9 +77,6 @@ class QSK_EXPORT QskGraphicLabel : public QskControl
|
||||
void setFillMode( FillMode );
|
||||
FillMode fillMode() const;
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
void setGraphicRole( int role );
|
||||
@ -99,10 +96,11 @@ class QSK_EXPORT QskGraphicLabel : public QskControl
|
||||
protected:
|
||||
void changeEvent( QEvent* ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
virtual QskGraphic loadSource( const QUrl& ) const;
|
||||
|
||||
QSizeF contentsSizeHint(
|
||||
Qt::SizeHint, const QSizeF& constraint ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
|
@ -153,13 +153,18 @@ QskAspect::Subcontrol QskListView::textSubControlAt( int row, int col ) const
|
||||
return ( row == selectedRow() ) ? TextSelected : Text;
|
||||
}
|
||||
|
||||
QSizeF QskListView::contentsSizeHint() const
|
||||
QSizeF QskListView::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
qreal w = -1.0; // shouldn't we return something ???
|
||||
if ( m_data->preferredWidthFromColumns )
|
||||
|
||||
if ( which != Qt::MaximumSize )
|
||||
{
|
||||
w = scrollableSize().width();
|
||||
w += metric( QskScrollView::VerticalScrollBar );
|
||||
if ( m_data->preferredWidthFromColumns )
|
||||
{
|
||||
w = scrollableSize().width();
|
||||
w += metric( QskScrollView::VerticalScrollBar );
|
||||
}
|
||||
}
|
||||
|
||||
return QSizeF( w, -1.0 );
|
||||
|
@ -98,8 +98,8 @@ class QSK_EXPORT QskListView : public QskScrollView
|
||||
void mouseReleaseEvent( QMouseEvent* ) override;
|
||||
|
||||
void updateScrollableSize();
|
||||
QSizeF contentsSizeHint() const override;
|
||||
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
void componentComplete() override;
|
||||
|
||||
private:
|
||||
|
@ -97,8 +97,12 @@ void QskPageIndicator::setCurrentIndex( qreal index )
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF QskPageIndicator::contentsSizeHint() const
|
||||
QSizeF QskPageIndicator::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
using namespace QskAspect;
|
||||
|
||||
const qreal sizeBullet = metric( Bullet | Size );
|
||||
|
@ -50,7 +50,7 @@ class QSK_EXPORT QskPageIndicator : public QskControl
|
||||
void setCurrentIndex( qreal index );
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -256,7 +256,7 @@ void QskPopup::updateInputGrabber()
|
||||
/*
|
||||
In QQuickWindowPrivate::deliverPressOrReleaseEvent ( 5.12 )
|
||||
might crash, when we delete the grabber as a result of a
|
||||
mouse event somewehere below the popup.
|
||||
mouse event somewehere below the popup.
|
||||
*/
|
||||
m_data->inputGrabber->setParentItem( nullptr );
|
||||
m_data->inputGrabber->setParent( nullptr );
|
||||
|
@ -250,8 +250,11 @@ QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const
|
||||
return innerBox( Panel, subControlRect( size, Panel ) );
|
||||
}
|
||||
|
||||
QSizeF QskPushButton::contentsSizeHint() const
|
||||
QSizeF QskPushButton::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
QSizeF size( 0, 0 );
|
||||
|
||||
const QFontMetricsF fm( font() );
|
||||
|
@ -63,6 +63,7 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
|
||||
bool isFlat() const;
|
||||
|
||||
QFont font() const;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
public Q_SLOTS:
|
||||
@ -90,10 +91,10 @@ class QSK_EXPORT QskPushButton : public QskAbstractButton
|
||||
void changeEvent( QEvent* ) override;
|
||||
|
||||
void updateLayout() override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
|
||||
virtual QskGraphic loadGraphic( const QUrl& ) const;
|
||||
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "QskQuick.h"
|
||||
#include "QskControl.h"
|
||||
#include "QskFunctions.h"
|
||||
#include <qquickitem.h>
|
||||
|
||||
QSK_QT_PRIVATE_BEGIN
|
||||
@ -142,11 +143,68 @@ bool qskIsTransparentForPositioner( const QQuickItem* item )
|
||||
return QQuickItemPrivate::get( item )->isTransparentForPositioner();
|
||||
}
|
||||
|
||||
bool qskIsVisibleToLayout( const QQuickItem* item )
|
||||
{
|
||||
if ( item )
|
||||
{
|
||||
const auto d = QQuickItemPrivate::get( item );
|
||||
return !d->isTransparentForPositioner()
|
||||
&& ( d->explicitVisible || qskRetainSizeWhenHidden( item ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QskSizePolicy qskSizePolicy( const QQuickItem* item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->sizePolicy();
|
||||
|
||||
if ( item )
|
||||
{
|
||||
const QVariant v = item->property( "sizePolicy" );
|
||||
if ( v.canConvert< QskSizePolicy >() )
|
||||
return qvariant_cast< QskSizePolicy >( v );
|
||||
}
|
||||
|
||||
return QskSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred );
|
||||
}
|
||||
|
||||
Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->layoutAlignmentHint();
|
||||
|
||||
if ( item )
|
||||
{
|
||||
const QVariant v = item->property( "layoutAlignmentHint" );
|
||||
if ( v.canConvert< Qt::Alignment >() )
|
||||
return v.value< Qt::Alignment >();
|
||||
}
|
||||
|
||||
return Qt::Alignment();
|
||||
}
|
||||
|
||||
bool qskRetainSizeWhenHidden( const QQuickItem* item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->layoutHints() & QskControl::RetainSizeWhenHidden;
|
||||
|
||||
if ( item )
|
||||
{
|
||||
const QVariant v = item->property( "retainSizeWhenHidden" );
|
||||
if ( v.canConvert< bool >() )
|
||||
return v.value< bool >();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QQuickItem* qskNearestFocusScope( const QQuickItem* item )
|
||||
{
|
||||
if ( item )
|
||||
{
|
||||
for ( QQuickItem* scope = item->parentItem();
|
||||
for ( auto scope = item->parentItem();
|
||||
scope != nullptr; scope = scope->parentItem() )
|
||||
{
|
||||
if ( scope->isFocusScope() )
|
||||
@ -290,3 +348,224 @@ const QSGNode* qskPaintNode( const QQuickItem* item )
|
||||
|
||||
return QQuickItemPrivate::get( item )->paintNode;
|
||||
}
|
||||
|
||||
QSizeF qskEffectiveSizeHint( const QQuickItem* item,
|
||||
Qt::SizeHint whichHint, const QSizeF& constraint )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->effectiveSizeHint( whichHint, constraint );
|
||||
|
||||
if ( constraint.width() >= 0.0 || constraint.height() >= 0.0 )
|
||||
{
|
||||
// QQuickItem does not support dynamic constraints
|
||||
return constraint;
|
||||
}
|
||||
|
||||
if ( item == nullptr )
|
||||
return QSizeF();
|
||||
|
||||
/*
|
||||
Trying to retrieve something useful for non QskControls:
|
||||
|
||||
First are checking some properties, that usually match the
|
||||
names for the explicit hints. For the implicit hints we only
|
||||
have the implicitSize, what is interpreted as the implicit
|
||||
preferred size.
|
||||
*/
|
||||
QSizeF hint;
|
||||
|
||||
static const char* properties[] =
|
||||
{
|
||||
"minimumSize",
|
||||
"preferredSize",
|
||||
"maximumSize"
|
||||
};
|
||||
|
||||
const QVariant v = item->property( properties[ whichHint ] );
|
||||
if ( v.canConvert( QMetaType::QSizeF ) )
|
||||
hint = v.toSizeF();
|
||||
|
||||
if ( whichHint == Qt::PreferredSize )
|
||||
{
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( item->implicitWidth() );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( item->implicitHeight() );
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
static QSizeF qskBoundedConstraint( const QQuickItem* item,
|
||||
const QSizeF& constraint, QskSizePolicy policy )
|
||||
{
|
||||
Qt::Orientation orientation;
|
||||
|
||||
if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
orientation = Qt::Horizontal;
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
orientation = Qt::Vertical;
|
||||
}
|
||||
else
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
|
||||
const auto whichMin = policy.effectiveSizeHintType( Qt::MinimumSize, orientation );
|
||||
const auto whichMax = policy.effectiveSizeHintType( Qt::MaximumSize, orientation );
|
||||
|
||||
const auto hintMin = qskEffectiveSizeHint( item, whichMin );
|
||||
const auto hintMax = ( whichMax == whichMin )
|
||||
? hintMin : qskEffectiveSizeHint( item, whichMax );
|
||||
|
||||
QSizeF size;
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
{
|
||||
if ( hintMax.width() >= 0.0 )
|
||||
size.rwidth() = qMin( constraint.width(), hintMax.width() );
|
||||
|
||||
size.rwidth() = qMax( constraint.width(), hintMin.width() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( hintMax.height() >= 0.0 )
|
||||
size.rheight() = qMin( constraint.height(), hintMax.height() );
|
||||
|
||||
size.rheight() = qMax( constraint.height(), hintMin.height() );
|
||||
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QSizeF qskSizeConstraint( const QQuickItem* item,
|
||||
Qt::SizeHint which, const QSizeF& constraint )
|
||||
{
|
||||
if ( item == nullptr )
|
||||
return QSizeF( 0, 0 );
|
||||
|
||||
if ( constraint.isValid() )
|
||||
return constraint;
|
||||
|
||||
const auto policy = qskSizePolicy( item );
|
||||
|
||||
const auto whichH = policy.effectiveSizeHintType( which, Qt::Horizontal );
|
||||
const auto whichV = policy.effectiveSizeHintType( which, Qt::Vertical );
|
||||
|
||||
QSizeF size;
|
||||
|
||||
int constraintType = QskSizePolicy::Unconstrained;
|
||||
|
||||
if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
const auto c = qskBoundedConstraint( item, constraint, policy );
|
||||
size = qskEffectiveSizeHint( item, whichV, c );
|
||||
|
||||
if ( ( whichH != whichV ) || ( size.height() != c.height() ) )
|
||||
constraintType = QskSizePolicy::WidthForHeight;
|
||||
}
|
||||
else if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
const auto c = qskBoundedConstraint( item, constraint, policy );
|
||||
size = qskEffectiveSizeHint( item, whichH, c );
|
||||
|
||||
if ( ( whichV != whichH ) || ( size.width() != c.height() ) )
|
||||
constraintType = QskSizePolicy::HeightForWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
constraintType = policy.constraintType();
|
||||
|
||||
switch( constraintType )
|
||||
{
|
||||
case QskSizePolicy::WidthForHeight:
|
||||
{
|
||||
size = qskEffectiveSizeHint( item, whichV );
|
||||
break;
|
||||
}
|
||||
case QskSizePolicy::HeightForWidth:
|
||||
{
|
||||
size = qskEffectiveSizeHint( item, whichH );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
size = qskEffectiveSizeHint( item, whichH );
|
||||
|
||||
if ( whichV != whichH )
|
||||
constraintType = QskSizePolicy::HeightForWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch( constraintType )
|
||||
{
|
||||
case QskSizePolicy::HeightForWidth:
|
||||
{
|
||||
const QSizeF c( size.width(), -1.0 );
|
||||
size.setHeight( qskEffectiveSizeHint( item, whichV, c ).height() );
|
||||
break;
|
||||
}
|
||||
case QskSizePolicy::WidthForHeight:
|
||||
{
|
||||
const QSizeF c( -1.0, size.height() );
|
||||
size.setWidth( qskEffectiveSizeHint( item, whichH, c ).width() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QSizeF qskConstrainedItemSize( const QQuickItem* item, const QSizeF& size )
|
||||
{
|
||||
QSizeF constraint;
|
||||
|
||||
switch( static_cast< int >( qskSizePolicy( item ).constraintType() ) )
|
||||
{
|
||||
case QskSizePolicy::WidthForHeight:
|
||||
{
|
||||
constraint.setHeight( size.height() );
|
||||
break;
|
||||
}
|
||||
case QskSizePolicy::HeightForWidth:
|
||||
{
|
||||
constraint.setWidth( size.width() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto max = qskSizeConstraint( item, Qt::MaximumSize, constraint );
|
||||
|
||||
qreal width = size.width();
|
||||
qreal height = size.height();
|
||||
|
||||
if ( max.width() >= 0.0 )
|
||||
width = qMin( width, max.width() );
|
||||
|
||||
if ( max.height() >= 0.0 )
|
||||
height = qMin( height, max.height() );
|
||||
|
||||
#if 1
|
||||
const auto min = qskSizeConstraint( item, Qt::MinimumSize, constraint );
|
||||
|
||||
width = qMax( width, min.width() );
|
||||
height = qMax( height, min.height() );
|
||||
#endif
|
||||
|
||||
return QSizeF( width, height );
|
||||
}
|
||||
|
||||
QRectF qskConstrainedItemRect( const QQuickItem* item,
|
||||
const QRectF& rect, Qt::Alignment alignment )
|
||||
{
|
||||
const auto size = qskConstrainedItemSize( item, rect.size() );
|
||||
return qskAlignedRectF( rect, size.width(), size.height(), alignment );
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include <qnamespace.h>
|
||||
#include <qquickitem.h>
|
||||
|
||||
class QskSizePolicy;
|
||||
|
||||
class QQuickItem;
|
||||
class QSGNode;
|
||||
class QRectF;
|
||||
@ -30,6 +32,21 @@ QSK_EXPORT bool qskIsPolishScheduled( const QQuickItem* );
|
||||
|
||||
QSK_EXPORT void qskSetTransparentForPositioner( QQuickItem*, bool );
|
||||
QSK_EXPORT bool qskIsTransparentForPositioner( const QQuickItem* );
|
||||
QSK_EXPORT bool qskIsVisibleToLayout( const QQuickItem* );
|
||||
|
||||
QSK_EXPORT QSizeF qskEffectiveSizeHint( const QQuickItem*,
|
||||
Qt::SizeHint, const QSizeF& constraint = QSizeF() );
|
||||
|
||||
QSK_EXPORT QSizeF qskSizeConstraint( const QQuickItem*,
|
||||
Qt::SizeHint, const QSizeF& constraint = QSizeF() );
|
||||
|
||||
QSK_EXPORT QSizeF qskConstrainedItemSize( const QQuickItem*, const QSizeF& );
|
||||
QSK_EXPORT QRectF qskConstrainedItemRect(
|
||||
const QQuickItem*, const QRectF&, Qt::Alignment );
|
||||
|
||||
QSK_EXPORT QskSizePolicy qskSizePolicy( const QQuickItem* );
|
||||
QSK_EXPORT Qt::Alignment qskLayoutAlignmentHint( const QQuickItem* );
|
||||
QSK_EXPORT bool qskRetainSizeWhenHidden( const QQuickItem* );
|
||||
|
||||
QSK_EXPORT QRectF qskItemRect( const QQuickItem* );
|
||||
|
||||
@ -69,7 +86,26 @@ template< typename T >
|
||||
inline T qskFindAncestorOf( const QQuickItem* item )
|
||||
{
|
||||
return qskFindAncestorOf< std::remove_const< T > >(
|
||||
const_cast< QQuickItem * >( item ) );
|
||||
const_cast< QQuickItem* >( item ) );
|
||||
}
|
||||
|
||||
inline qreal qskHeightForWidth(
|
||||
const QQuickItem* item, Qt::SizeHint which, qreal width )
|
||||
{
|
||||
return qskEffectiveSizeHint(
|
||||
item, which, QSizeF( width, -1.0 ) ).height();
|
||||
}
|
||||
|
||||
inline qreal qskWidthForHeight(
|
||||
const QQuickItem* item, Qt::SizeHint which, qreal height )
|
||||
{
|
||||
return qskEffectiveSizeHint(
|
||||
item, which, QSizeF( -1.0, height ) ).width();
|
||||
}
|
||||
|
||||
inline QRectF qskConstrainedItemRect( const QQuickItem* item, const QRectF& rect )
|
||||
{
|
||||
return qskConstrainedItemRect( item, rect, qskLayoutAlignmentHint( item ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "QskScrollArea.h"
|
||||
#include "QskEvent.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskQuick.h"
|
||||
#include "QskScrollViewSkinlet.h"
|
||||
|
||||
@ -423,7 +422,7 @@ void QskScrollArea::updateLayout()
|
||||
|
||||
void QskScrollArea::adjustItem()
|
||||
{
|
||||
QQuickItem* item = m_data->clipItem->scrolledItem();
|
||||
auto item = m_data->clipItem->scrolledItem();
|
||||
|
||||
if ( item == nullptr )
|
||||
{
|
||||
@ -434,7 +433,7 @@ void QskScrollArea::adjustItem()
|
||||
{
|
||||
if ( m_data->isItemResizable )
|
||||
{
|
||||
const QRectF rect = viewContentsRect();
|
||||
auto size = viewContentsRect().size();
|
||||
|
||||
#if 0
|
||||
/*
|
||||
@ -443,13 +442,13 @@ void QskScrollArea::adjustItem()
|
||||
moment we ignore this and start with a simplified code.
|
||||
*/
|
||||
#endif
|
||||
const auto newSize = QskLayoutConstraint::boundedSize( item, rect.size() );
|
||||
item->setSize( newSize );
|
||||
size = qskConstrainedItemSize( item, size );
|
||||
item->setSize( size );
|
||||
}
|
||||
|
||||
m_data->enableAutoTranslation( this, false );
|
||||
|
||||
setScrollableSize( QSizeF( item->width(), item->height() ) );
|
||||
setScrollableSize( item->size() );
|
||||
setScrollPos( scrollPos() );
|
||||
|
||||
m_data->enableAutoTranslation( this, true );
|
||||
|
@ -70,8 +70,12 @@ qreal QskSeparator::thickness() const
|
||||
return metric( QskSeparator::Panel | QskAspect::Size );
|
||||
}
|
||||
|
||||
QSizeF QskSeparator::contentsSizeHint() const
|
||||
QSizeF QskSeparator::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const qreal m = thickness();
|
||||
|
||||
if ( m_orientation == Qt::Horizontal )
|
||||
|
@ -41,7 +41,7 @@ class QSK_EXPORT QskSeparator : public QskControl
|
||||
void thicknessChanged();
|
||||
|
||||
protected:
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
Qt::Orientation m_orientation;
|
||||
|
@ -74,21 +74,21 @@ QSK_QT_PRIVATE_END
|
||||
#include "QskStatusIndicator.h"
|
||||
#include "QskStatusIndicatorSkinlet.h"
|
||||
|
||||
static inline QskSkinlet *qskNewSkinlet( const QMetaObject* metaObject, QskSkin* skin )
|
||||
static inline QskSkinlet* qskNewSkinlet( const QMetaObject* metaObject, QskSkin* skin )
|
||||
{
|
||||
const QByteArray signature = metaObject->className() + QByteArrayLiteral( "(QskSkin*)" );
|
||||
|
||||
QskSkinlet *skinlet = nullptr;
|
||||
QskSkinlet* skinlet = nullptr;
|
||||
|
||||
const int index = metaObject->indexOfConstructor( signature.constData() );
|
||||
if ( index >= 0 )
|
||||
{
|
||||
void *param[] = { &skinlet, &skin };
|
||||
void* param[] = { &skinlet, &skin };
|
||||
metaObject->static_metacall( QMetaObject::CreateInstance, index, param );
|
||||
}
|
||||
|
||||
return skinlet;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -108,8 +108,12 @@ bool QskSlider::isTracking() const
|
||||
return m_data->tracking;
|
||||
}
|
||||
|
||||
QSizeF QskSlider::contentsSizeHint() const
|
||||
QSizeF QskSlider::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const qreal dim = metric( QskSlider::Panel | QskAspect::Size );
|
||||
return ( m_data->orientation == Qt::Horizontal )
|
||||
? QSizeF( 4 * dim, dim ) : QSizeF( dim, 4 * dim );
|
||||
|
@ -53,7 +53,7 @@ class QSK_EXPORT QskSlider : public QskRangeControl
|
||||
void mouseMoveEvent( QMouseEvent* e ) override;
|
||||
void mouseReleaseEvent( QMouseEvent* e ) override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
QSizeF handleSize() const;
|
||||
QRectF handleRect() const;
|
||||
|
@ -153,23 +153,13 @@ QskColorFilter QskStatusIndicator::graphicFilter( int status ) const
|
||||
return effectiveGraphicFilter( QskStatusIndicator::Graphic );
|
||||
}
|
||||
|
||||
qreal QskStatusIndicator::heightForWidth( qreal width ) const
|
||||
QSizeF QskStatusIndicator::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
return sizeConstraint( Qt::Horizontal, width );
|
||||
}
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
qreal QskStatusIndicator::widthForHeight( qreal height ) const
|
||||
{
|
||||
return sizeConstraint( Qt::Vertical, height );
|
||||
}
|
||||
|
||||
qreal QskStatusIndicator::sizeConstraint(
|
||||
Qt::Orientation orientation, qreal constraint ) const
|
||||
{
|
||||
if ( constraint <= 0.0 )
|
||||
return 0.0;
|
||||
|
||||
qreal value = 0.0;
|
||||
QSizeF sz;
|
||||
|
||||
for ( auto& statusData : m_data->map )
|
||||
{
|
||||
@ -177,36 +167,24 @@ qreal QskStatusIndicator::sizeConstraint(
|
||||
|
||||
if ( !statusData.graphic.isEmpty() )
|
||||
{
|
||||
const QSizeF sz = statusData.graphic.defaultSize();
|
||||
if ( !sz.isEmpty() )
|
||||
auto hint = statusData.graphic.defaultSize();
|
||||
|
||||
if ( !hint.isEmpty() )
|
||||
{
|
||||
qreal v;
|
||||
if ( orientation == Qt::Horizontal )
|
||||
v = sz.height() * constraint / sz.width();
|
||||
else
|
||||
v = sz.width() * constraint / sz.height();
|
||||
|
||||
if ( v > value )
|
||||
value = v;
|
||||
if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
hint.setHeight( sz.height() * constraint.width() / sz.width() );
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
hint.setWidth( sz.width() * constraint.height() / sz.height() );
|
||||
}
|
||||
}
|
||||
|
||||
sz = sz.expandedTo( hint );
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
QSizeF QskStatusIndicator::contentsSizeHint() const
|
||||
{
|
||||
QSizeF sz( 0, 0 );
|
||||
|
||||
for ( auto& statusData : m_data->map )
|
||||
{
|
||||
statusData.ensureGraphic( this );
|
||||
|
||||
if ( !statusData.graphic.isEmpty() )
|
||||
sz = sz.expandedTo( statusData.graphic.defaultSize() );
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,6 @@ class QSK_EXPORT QskStatusIndicator : public QskControl
|
||||
virtual QskColorFilter graphicFilter( int status ) const;
|
||||
virtual QskGraphic loadSource( const QUrl& ) const;
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
int status() const;
|
||||
bool hasStatus( int status ) const;
|
||||
|
||||
@ -51,11 +48,9 @@ class QSK_EXPORT QskStatusIndicator : public QskControl
|
||||
void changeEvent( QEvent* ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
qreal sizeConstraint( Qt::Orientation, qreal ) const;
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
@ -240,22 +240,21 @@ QRectF QskSubWindow::layoutRectForSize( const QSizeF& size ) const
|
||||
return innerBox( Panel, rect );
|
||||
}
|
||||
|
||||
QSizeF QskSubWindow::contentsSizeHint() const
|
||||
QSizeF QskSubWindow::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
// the size we get from the children
|
||||
auto hint = Inherited::contentsSizeHint();
|
||||
auto hint = Inherited::layoutSizeHint( which, constraint );
|
||||
|
||||
#if 1
|
||||
// should be Minimum Width/Height from the hints
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( qskDpiScaled( 100 ) );
|
||||
if ( which == Qt::PreferredSize )
|
||||
{
|
||||
// should be Minimum Width/Height from the skin hints
|
||||
if ( hint.width() < 0.0 )
|
||||
hint.setWidth( qskDpiScaled( 100 ) );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( qskDpiScaled( 80 ) );
|
||||
#endif
|
||||
|
||||
hint = outerBoxSize( Panel, hint );
|
||||
hint.setHeight( hint.height() + subControlRect( TitleBar ).height() );
|
||||
if ( hint.height() < 0.0 )
|
||||
hint.setHeight( qskDpiScaled( 80 ) );
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ class QSK_EXPORT QskSubWindow : public QskPopup
|
||||
bool testWindowButton( WindowButton ) const;
|
||||
|
||||
QRectF titleBarRect() const;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -89,9 +90,9 @@ class QSK_EXPORT QskSubWindow : public QskPopup
|
||||
|
||||
protected:
|
||||
bool event( QEvent* ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
void updateLayout() override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
void itemChange( QQuickItem::ItemChange,
|
||||
const QQuickItem::ItemChangeData& ) override;
|
||||
|
@ -261,9 +261,9 @@ void QskTabBar::removeTab( int index )
|
||||
nextButton->setChecked( true );
|
||||
m_data->connectButton( nextButton, this, true );
|
||||
}
|
||||
|
||||
|
||||
m_data->currentIndex = nextIndex;
|
||||
|
||||
|
||||
Q_EMIT countChanged( count() );
|
||||
Q_EMIT currentIndexChanged( nextIndex );
|
||||
}
|
||||
|
@ -86,8 +86,12 @@ QskTextOptions QskTabButton::textOptions() const
|
||||
return m_data->textOptions;
|
||||
}
|
||||
|
||||
QSizeF QskTabButton::contentsSizeHint() const
|
||||
QSizeF QskTabButton::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
QSizeF size( metric( Panel | QskAspect::MinimumWidth ),
|
||||
metric( Panel | QskAspect::MinimumHeight ) );
|
||||
|
||||
|
@ -49,7 +49,7 @@ class QSK_EXPORT QskTabButton : public QskAbstractButton
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* ) override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -198,13 +198,14 @@ int QskTabView::count() const
|
||||
return m_data->tabBar->count();
|
||||
}
|
||||
|
||||
QSizeF QskTabView::contentsSizeHint() const
|
||||
QSizeF QskTabView::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( m_data->tabBar == nullptr || m_data->tabBar->count() == 0 )
|
||||
return Inherited::contentsSizeHint();
|
||||
if ( which != Qt::PreferredSize )
|
||||
return constraint;
|
||||
|
||||
const QSizeF barHint = m_data->tabBar->sizeHint();
|
||||
const QSizeF boxHint = m_data->stackBox->sizeHint();
|
||||
const auto barHint = m_data->tabBar->sizeHint();
|
||||
const auto boxHint = m_data->stackBox->sizeHint();
|
||||
|
||||
qreal w, h;
|
||||
|
||||
@ -229,16 +230,10 @@ void QskTabView::setCurrentIndex( int index )
|
||||
|
||||
bool QskTabView::event( QEvent* event )
|
||||
{
|
||||
switch ( event->type() )
|
||||
if ( event->type() == QEvent::LayoutRequest )
|
||||
{
|
||||
case QEvent::LayoutRequest:
|
||||
{
|
||||
resetImplicitSize();
|
||||
polish();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
resetImplicitSize();
|
||||
polish();
|
||||
}
|
||||
|
||||
return Inherited::event( event );
|
||||
@ -247,7 +242,7 @@ bool QskTabView::event( QEvent* event )
|
||||
void QskTabView::updateLayout()
|
||||
{
|
||||
if ( maybeUnresized() )
|
||||
return;
|
||||
return;
|
||||
|
||||
m_data->tabBar->setGeometry( subControlRect( TabBar ) );
|
||||
|
||||
|
@ -78,7 +78,7 @@ class QSK_EXPORT QskTabView : public QskControl
|
||||
bool event( QEvent* event ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -441,8 +441,11 @@ void QskTextInput::focusOutEvent( QFocusEvent* event )
|
||||
Inherited::focusOutEvent( event );
|
||||
}
|
||||
|
||||
QSizeF QskTextInput::contentsSizeHint() const
|
||||
QSizeF QskTextInput::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
using namespace QskAspect;
|
||||
|
||||
auto input = m_data->textInput;
|
||||
|
@ -197,9 +197,9 @@ class QSK_EXPORT QskTextInput : public QskControl
|
||||
void keyPressEvent( QKeyEvent* ) override;
|
||||
void keyReleaseEvent( QKeyEvent* ) override;
|
||||
|
||||
void updateLayout() override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
void updateLayout() override;
|
||||
void updateNode( QSGNode* ) override;
|
||||
|
||||
private:
|
||||
|
@ -208,81 +208,67 @@ QFont QskTextLabel::font() const
|
||||
return effectiveFont( QskTextLabel::Text );
|
||||
}
|
||||
|
||||
QSizeF QskTextLabel::contentsSizeHint() const
|
||||
QSizeF QskTextLabel::contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
const auto font = effectiveFont( Text );
|
||||
|
||||
if ( !m_data->text.isEmpty() )
|
||||
{
|
||||
return QskTextRenderer::textSize(
|
||||
m_data->text, font, m_data->effectiveOptions() );
|
||||
}
|
||||
QSizeF hint;
|
||||
|
||||
return QSizeF( 0, QFontMetricsF( font ).height() );
|
||||
}
|
||||
|
||||
qreal QskTextLabel::heightForWidth( qreal width ) const
|
||||
{
|
||||
const auto font = effectiveFont( Text );
|
||||
const qreal lineHeight = QFontMetricsF( font ).height();
|
||||
|
||||
qreal h = 0;
|
||||
|
||||
const auto m = margins();
|
||||
|
||||
if ( m_data->text.isEmpty() )
|
||||
{
|
||||
h = lineHeight;
|
||||
if ( constraint.height() < 0.0 )
|
||||
hint.setHeight( qCeil( lineHeight ) );
|
||||
}
|
||||
else if ( m_data->textOptions.effectiveElideMode() != Qt::ElideNone )
|
||||
else if ( constraint.width() >= 0.0 )
|
||||
{
|
||||
h = lineHeight;
|
||||
if ( m_data->textOptions.effectiveElideMode() != Qt::ElideNone )
|
||||
{
|
||||
hint.setHeight( qCeil( lineHeight ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
In case of QskTextOptions::NoWrap we could count
|
||||
the line numbers and calculate the height from
|
||||
lineHeight. TODO ...
|
||||
*/
|
||||
qreal maxHeight = std::numeric_limits< qreal >::max();
|
||||
if ( maxHeight / lineHeight > m_data->textOptions.maximumLineCount() )
|
||||
{
|
||||
// be careful with overflows
|
||||
maxHeight = m_data->textOptions.maximumLineCount() * lineHeight;
|
||||
}
|
||||
|
||||
QSizeF size( constraint.width(), maxHeight );
|
||||
size = QskTextRenderer::textSize(
|
||||
m_data->text, font, m_data->effectiveOptions(), size );
|
||||
|
||||
hint.setHeight( qCeil( size.height() ) );
|
||||
}
|
||||
}
|
||||
else if ( constraint.height() >= 0.0 )
|
||||
{
|
||||
const qreal maxWidth = std::numeric_limits< qreal >::max();
|
||||
|
||||
QSizeF size( maxWidth, constraint.height() );
|
||||
size = QskTextRenderer::textSize( m_data->text, font,
|
||||
m_data->effectiveOptions(), size );
|
||||
|
||||
hint.setWidth( qCeil( size.width() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
In case of QskTextOptions::NoWrap we could count
|
||||
the line numbers and calculate the height from
|
||||
lineHeight. TODO ...
|
||||
*/
|
||||
qreal maxHeight = std::numeric_limits< qreal >::max();
|
||||
if ( maxHeight / lineHeight > m_data->textOptions.maximumLineCount() )
|
||||
{
|
||||
// be careful with overflows
|
||||
maxHeight = m_data->textOptions.maximumLineCount() * lineHeight;
|
||||
}
|
||||
|
||||
qreal w = width - m.left() + m.right();
|
||||
|
||||
QSizeF size( w, maxHeight );
|
||||
size = QskTextRenderer::textSize(
|
||||
m_data->text, font, m_data->effectiveOptions(), size );
|
||||
|
||||
h = size.height();
|
||||
hint = QskTextRenderer::textSize(
|
||||
m_data->text, font, m_data->effectiveOptions() );
|
||||
}
|
||||
|
||||
h += m.top() + m.bottom();
|
||||
|
||||
return qCeil( h );
|
||||
}
|
||||
|
||||
qreal QskTextLabel::widthForHeight( qreal height ) const
|
||||
{
|
||||
if ( m_data->text.isEmpty() )
|
||||
{
|
||||
return Inherited::widthForHeight( height );
|
||||
}
|
||||
|
||||
const auto font = effectiveFont( Text );
|
||||
const qreal maxWidth = std::numeric_limits< qreal >::max();
|
||||
|
||||
const auto m = margins();
|
||||
|
||||
QSizeF size( maxWidth, height - m.top() + m.bottom() );
|
||||
size = QskTextRenderer::textSize( m_data->text, font,
|
||||
m_data->effectiveOptions(), size );
|
||||
|
||||
return qCeil( size.width() + m.left() + m.right() );
|
||||
return hint;
|
||||
}
|
||||
|
||||
void QskTextLabel::changeEvent( QEvent* event )
|
||||
|
@ -60,9 +60,6 @@ class QSK_EXPORT QskTextLabel : public QskControl
|
||||
void setAlignment( Qt::Alignment );
|
||||
Qt::Alignment alignment() const;
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
QFont font() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -77,7 +74,7 @@ class QSK_EXPORT QskTextLabel : public QskControl
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* ) override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -120,7 +120,8 @@ QskAspect::Subcontrol QskDialogButtonBox::effectiveSubcontrol(
|
||||
return Inherited::effectiveSubcontrol( subControl );
|
||||
}
|
||||
|
||||
QSizeF QskDialogButtonBox::contentsSizeHint() const
|
||||
QSizeF QskDialogButtonBox::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( m_data->dirtyLayout )
|
||||
{
|
||||
@ -128,7 +129,7 @@ QSizeF QskDialogButtonBox::contentsSizeHint() const
|
||||
m_data->dirtyLayout = false;
|
||||
}
|
||||
|
||||
return outerBoxSize( Panel, m_data->layoutBox->sizeHint() );
|
||||
return m_data->layoutBox->effectiveSizeHint( which, constraint );
|
||||
}
|
||||
|
||||
void QskDialogButtonBox::invalidateLayout()
|
||||
|
@ -77,12 +77,11 @@ class QSK_EXPORT QskDialogButtonBox : public QskBox
|
||||
|
||||
protected:
|
||||
bool event( QEvent* event ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
void updateLayout() override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
virtual QskPushButton* createButton( QskDialog::Action ) const;
|
||||
|
||||
void invalidateLayout();
|
||||
|
||||
private:
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "QskDialogSubWindow.h"
|
||||
#include "QskDialogButtonBox.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskPushButton.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
@ -27,75 +26,6 @@ static inline void qskSetRejectOnClose( QskDialogSubWindow* subWindow, bool on )
|
||||
}
|
||||
}
|
||||
|
||||
static inline qreal qskConstrainedValue( QskLayoutConstraint::Type type,
|
||||
const QskControl* control, qreal widthOrHeight )
|
||||
{
|
||||
auto subWindow = static_cast< const QskDialogSubWindow* >( control );
|
||||
|
||||
if ( type == QskLayoutConstraint::WidthForHeight )
|
||||
{
|
||||
qreal width = -1.0;
|
||||
qreal height = widthOrHeight;
|
||||
|
||||
if ( auto buttonBox = subWindow->buttonBox() )
|
||||
{
|
||||
if ( buttonBox->isVisibleTo( subWindow ) )
|
||||
{
|
||||
const auto hint = buttonBox->sizeHint();
|
||||
|
||||
width = hint.width();
|
||||
height -= hint.height();
|
||||
}
|
||||
}
|
||||
|
||||
if ( auto contentItem = qskControlCast( subWindow->contentItem() ) )
|
||||
{
|
||||
if ( contentItem->isVisibleTo( subWindow ) )
|
||||
{
|
||||
const auto m = subWindow->contentPadding();
|
||||
height -= m.top() + m.bottom();
|
||||
|
||||
qreal w = contentItem->widthForHeight( height );
|
||||
|
||||
if ( w >= 0 )
|
||||
{
|
||||
w += m.left() + m.right();
|
||||
width = qMax( width, w );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
else
|
||||
{
|
||||
qreal width = widthOrHeight;
|
||||
qreal height = -1.0;
|
||||
|
||||
if ( auto buttonBox = subWindow->buttonBox() )
|
||||
{
|
||||
if ( buttonBox->isVisibleTo( subWindow ) )
|
||||
height += buttonBox->sizeHint().height();
|
||||
}
|
||||
|
||||
if ( auto contentItem = qskControlCast( subWindow->contentItem() ) )
|
||||
{
|
||||
if ( qskIsVisibleTo( contentItem, subWindow ) )
|
||||
{
|
||||
const auto& m = subWindow->contentPadding();
|
||||
width -= m.left() + m.right();
|
||||
|
||||
const qreal h = contentItem->heightForWidth( width );
|
||||
|
||||
if ( h >= 0 )
|
||||
height += h + m.top() + m.bottom();
|
||||
}
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
class QskDialogSubWindow::PrivateData
|
||||
{
|
||||
public:
|
||||
@ -438,7 +368,7 @@ void QskDialogSubWindow::updateLayout()
|
||||
|
||||
auto rect = layoutRect();
|
||||
|
||||
if ( m_data->buttonBox && m_data->buttonBox->isVisibleTo( this ) )
|
||||
if ( m_data->buttonBox && m_data->buttonBox->isVisibleToParent() )
|
||||
{
|
||||
const auto h = m_data->buttonBox->sizeHint().height();
|
||||
rect.setBottom( rect.bottom() - h );
|
||||
@ -453,49 +383,68 @@ void QskDialogSubWindow::updateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
qreal QskDialogSubWindow::heightForWidth( qreal width ) const
|
||||
QSizeF QskDialogSubWindow::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::HeightForWidth, this, width, qskConstrainedValue );
|
||||
}
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
qreal QskDialogSubWindow::widthForHeight( qreal height ) const
|
||||
{
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::WidthForHeight, this, height, qskConstrainedValue );
|
||||
}
|
||||
QSizeF buttonBoxHint;
|
||||
|
||||
qreal constraintHeight = constraint.height();
|
||||
|
||||
if ( auto buttonBox = m_data->buttonBox )
|
||||
{
|
||||
if ( buttonBox->isVisibleToLayout() )
|
||||
{
|
||||
buttonBoxHint = buttonBox->effectiveSizeHint(
|
||||
which, QSizeF( constraint.width(), -1 ) );
|
||||
|
||||
if ( constraint.width() >= 0.0 )
|
||||
buttonBoxHint.rwidth() = constraint.width();
|
||||
|
||||
if ( constraintHeight >= 0.0 && buttonBoxHint.height() >= 0.0 )
|
||||
{
|
||||
constraintHeight -= buttonBoxHint.height();
|
||||
constraintHeight = qMax( constraintHeight, 0.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF contentHint;
|
||||
|
||||
if ( qskIsVisibleToLayout( m_data->contentItem ) )
|
||||
{
|
||||
const auto& m = m_data->contentPadding;
|
||||
const qreal dw = m.left() + m.right();
|
||||
const qreal dh = m.top() + m.bottom();
|
||||
|
||||
qreal constraintWidth = constraint.width();
|
||||
|
||||
if ( constraintWidth > 0.0 )
|
||||
constraintWidth = qMax( constraintWidth - dw, 0.0 );
|
||||
|
||||
if ( constraintHeight > 0.0 )
|
||||
constraintHeight = qMax( constraintHeight - dh, 0.0 );
|
||||
|
||||
contentHint = qskEffectiveSizeHint( m_data->contentItem,
|
||||
which, QSizeF( constraintWidth, constraintHeight ) );
|
||||
|
||||
if ( contentHint.width() >= 0 )
|
||||
contentHint.rwidth() += dw;
|
||||
|
||||
if ( contentHint.height() >= 0 )
|
||||
contentHint.rheight() += dh;
|
||||
}
|
||||
|
||||
QSizeF QskDialogSubWindow::contentsSizeHint() const
|
||||
{
|
||||
qreal w = -1;
|
||||
w = qMax( w, buttonBoxHint.width() );
|
||||
w = qMax( w, contentHint.width() );
|
||||
|
||||
qreal h = -1;
|
||||
|
||||
if ( m_data->buttonBox && m_data->buttonBox->isVisibleTo( this ) )
|
||||
{
|
||||
const auto hint = m_data->buttonBox->sizeHint();
|
||||
|
||||
w = hint.width();
|
||||
h = hint.height();
|
||||
}
|
||||
|
||||
if ( auto* control = qskControlCast( m_data->contentItem ) )
|
||||
{
|
||||
const auto hint = control->sizeHint();
|
||||
|
||||
const auto& m = m_data->contentPadding;
|
||||
|
||||
if ( hint.width() >= 0 )
|
||||
w = qMax( w, hint.width() + m.left() + m.right() );
|
||||
|
||||
if ( hint.height() >= 0 )
|
||||
h += hint.height() + m.top() + m.bottom();
|
||||
}
|
||||
|
||||
const qreal sz = 400.0; // something
|
||||
const auto innerSize = layoutRectForSize( QSizeF( sz, sz ) ).size();
|
||||
|
||||
w += sz - innerSize.width();
|
||||
h += sz - innerSize.height();
|
||||
if ( buttonBoxHint.height() > 0.0 && contentHint.height() > 0.0 )
|
||||
h = buttonBoxHint.height() + contentHint.height();
|
||||
|
||||
return QSizeF( w, h );
|
||||
}
|
||||
|
@ -51,9 +51,6 @@ class QSK_EXPORT QskDialogSubWindow : public QskSubWindow
|
||||
void setContentPadding( const QMarginsF& );
|
||||
QMarginsF contentPadding() const;
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished( QskDialog::DialogCode );
|
||||
void accepted();
|
||||
@ -72,7 +69,7 @@ class QSK_EXPORT QskDialogSubWindow : public QskSubWindow
|
||||
void updateLayout() override;
|
||||
void aboutToShow() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
virtual QskDialogButtonBox* createButtonBox();
|
||||
|
||||
|
@ -48,9 +48,13 @@ namespace
|
||||
|
||||
#if 1
|
||||
// how to find a reasonable default size ???
|
||||
QSizeF contentsSizeHint() const override
|
||||
QSizeF contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const override
|
||||
{
|
||||
return QSizeF( 500, 500 );
|
||||
if ( which == Qt::PreferredSize )
|
||||
return QSizeF( 500, 500 );
|
||||
|
||||
return QSizeF();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -51,9 +51,13 @@ namespace
|
||||
|
||||
#if 1
|
||||
// how to find a reasonable default size ???
|
||||
QSizeF contentsSizeHint() const override
|
||||
QSizeF contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const override
|
||||
{
|
||||
return QSizeF( 500, 500 );
|
||||
if ( which == Qt::PreferredSize )
|
||||
return QSizeF( 500, 500 );
|
||||
|
||||
return QSizeF();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -29,8 +29,12 @@ namespace
|
||||
setTextOptions( options );
|
||||
}
|
||||
|
||||
QSizeF contentsSizeHint() const override
|
||||
QSizeF contentsSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& ) const override
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
auto size = QFontMetricsF( font() ).size( Qt::TextSingleLine, text() );
|
||||
|
||||
const QSizeF minSize( metric( Panel | QskAspect::MinimumWidth ),
|
||||
|
@ -295,56 +295,38 @@ QskVirtualKeyboard::Mode QskVirtualKeyboard::mode() const
|
||||
return m_data->mode;
|
||||
}
|
||||
|
||||
QSizeF QskVirtualKeyboard::contentsSizeHint() const
|
||||
QSizeF QskVirtualKeyboard::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
constexpr qreal ratio = qreal( RowCount ) / ColumnCount;
|
||||
|
||||
const qreal w = 600;
|
||||
return QSizeF( w, ratio * w );
|
||||
}
|
||||
qreal w = constraint.width();
|
||||
qreal h = constraint.height();
|
||||
|
||||
qreal QskVirtualKeyboard::heightForWidth( qreal width ) const
|
||||
{
|
||||
/*
|
||||
Not necessarily correct, when
|
||||
subControlRect( Panel ) != contentsRect: TODO ...
|
||||
*/
|
||||
constexpr qreal ratio = qreal( RowCount ) / ColumnCount;
|
||||
const auto margins = this->margins();
|
||||
if ( h >= 0 )
|
||||
{
|
||||
const auto padding = innerPadding( Panel, QSizeF( h, h ) );
|
||||
const auto dw = padding.left() + padding.right();
|
||||
const auto dh = padding.top() + padding.bottom();
|
||||
|
||||
width -= margins.left() + margins.right();
|
||||
w = ( h - dh ) / ratio + dw;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( w < 0 )
|
||||
w = 600;
|
||||
|
||||
const auto padding = innerPadding(
|
||||
Panel, QSizeF( width, width ) );
|
||||
const auto padding = innerPadding( Panel, QSizeF( w, w ) );
|
||||
const auto dw = padding.left() + padding.right();
|
||||
const auto dh = padding.top() + padding.bottom();
|
||||
|
||||
width -= padding.left() + padding.right();
|
||||
h = ( w - dw ) * ratio + dh;
|
||||
}
|
||||
|
||||
qreal height = width * ratio;
|
||||
|
||||
height += padding.top() + padding.bottom();
|
||||
height += margins.top() + margins.bottom();
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
qreal QskVirtualKeyboard::widthForHeight( qreal height ) const
|
||||
{
|
||||
constexpr qreal ratio = qreal( RowCount ) / ColumnCount;
|
||||
const auto margins = this->margins();
|
||||
|
||||
height -= margins.top() + margins.bottom();
|
||||
|
||||
const auto padding = innerPadding(
|
||||
Panel, QSizeF( height, height ) );
|
||||
|
||||
height -= padding.top() + padding.bottom();
|
||||
|
||||
qreal width = height / ratio;
|
||||
|
||||
width += padding.left() + padding.right();
|
||||
width += margins.left() + margins.right();
|
||||
|
||||
return width;
|
||||
return QSizeF( w, h );
|
||||
}
|
||||
|
||||
void QskVirtualKeyboard::updateLayout()
|
||||
|
@ -35,9 +35,6 @@ class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
||||
|
||||
void updateLocale( const QLocale& );
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
QskAspect::Subcontrol effectiveSubcontrol(
|
||||
QskAspect::Subcontrol ) const override;
|
||||
|
||||
@ -49,7 +46,7 @@ class QSK_EXPORT QskVirtualKeyboard : public QskBox
|
||||
|
||||
protected:
|
||||
void updateLayout() override;
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
void buttonPressed();
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "QskGridBox.h"
|
||||
#include "QskGridLayoutEngine.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskEvent.h"
|
||||
#include <algorithm>
|
||||
|
||||
@ -341,38 +340,16 @@ void QskGridBox::updateLayout()
|
||||
m_data->engine.setGeometries( layoutRect() );
|
||||
}
|
||||
|
||||
QSizeF QskGridBox::contentsSizeHint() const
|
||||
QSizeF QskGridBox::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
if ( count() == 0 )
|
||||
return QSizeF( 0, 0 );
|
||||
if ( which == Qt::MaximumSize )
|
||||
{
|
||||
// we can extend beyond the maximum size of the children
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
return m_data->engine.sizeHint( Qt::PreferredSize, QSizeF() );
|
||||
}
|
||||
|
||||
qreal QskGridBox::heightForWidth( qreal width ) const
|
||||
{
|
||||
auto constrainedHeight =
|
||||
[this]( QskLayoutConstraint::Type, const QskControl*, qreal width )
|
||||
{
|
||||
const QSizeF constraint( width, -1 );
|
||||
return m_data->engine.sizeHint( Qt::PreferredSize, constraint ).height();
|
||||
};
|
||||
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::HeightForWidth, this, width, constrainedHeight );
|
||||
}
|
||||
|
||||
qreal QskGridBox::widthForHeight( qreal height ) const
|
||||
{
|
||||
auto constrainedWidth =
|
||||
[this]( QskLayoutConstraint::Type, const QskControl*, qreal height )
|
||||
{
|
||||
const QSizeF constraint( -1, height );
|
||||
return m_data->engine.sizeHint( Qt::PreferredSize, constraint ).width();
|
||||
};
|
||||
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::WidthForHeight, this, height, constrainedWidth );
|
||||
return m_data->engine.sizeHint( which, constraint );
|
||||
}
|
||||
|
||||
void QskGridBox::geometryChangeEvent( QskGeometryChangeEvent* event )
|
||||
|
@ -99,9 +99,6 @@ class QSK_EXPORT QskGridBox : public QskBox
|
||||
Q_INVOKABLE void setRowFixedHeight( int row, qreal height );
|
||||
Q_INVOKABLE void setColumnFixedWidth( int column, qreal width );
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void invalidate();
|
||||
void clear( bool autoDelete = false );
|
||||
@ -116,7 +113,7 @@ class QSK_EXPORT QskGridBox : public QskBox
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "QskGridLayoutEngine.h"
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskLayoutChain.h"
|
||||
#include "QskSizePolicy.h"
|
||||
#include "QskQuick.h"
|
||||
@ -172,9 +171,7 @@ namespace
|
||||
QRect minimumGrid() const;
|
||||
|
||||
bool isIgnored() const;
|
||||
|
||||
QskLayoutChain::CellData cell(
|
||||
Qt::Orientation, qreal constraint ) const;
|
||||
QskLayoutChain::CellData cell( Qt::Orientation ) const;
|
||||
|
||||
void transpose();
|
||||
|
||||
@ -247,17 +244,12 @@ QRect Element::minimumGrid() const
|
||||
|
||||
bool Element::isIgnored() const
|
||||
{
|
||||
if ( !m_isSpacer && !QskLayoutConstraint::retainSizeWhenHidden( m_item ) )
|
||||
return !qskIsVisibleToParent( m_item );
|
||||
|
||||
return false;
|
||||
return !( m_isSpacer || qskIsVisibleToLayout( m_item ) );
|
||||
}
|
||||
|
||||
QskLayoutChain::CellData Element::cell(
|
||||
Qt::Orientation orientation, qreal constraint ) const
|
||||
QskLayoutChain::CellData Element::cell( Qt::Orientation orientation ) const
|
||||
{
|
||||
const auto policy = QskLayoutConstraint::sizePolicy(
|
||||
m_item ).policy( orientation );
|
||||
const auto policy = qskSizePolicy( m_item ).policy( orientation );
|
||||
|
||||
QskLayoutChain::CellData cell;
|
||||
cell.isValid = true;
|
||||
@ -266,9 +258,6 @@ QskLayoutChain::CellData Element::cell(
|
||||
if ( policy & QskSizePolicy::ExpandFlag )
|
||||
cell.stretch = 1;
|
||||
|
||||
if ( !m_isSpacer )
|
||||
cell.hint = QskLayoutConstraint::layoutHint( m_item, orientation, constraint );
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@ -601,7 +590,10 @@ void QskGridLayoutEngine::setupChain( Qt::Orientation orientation,
|
||||
if ( !constraints.isEmpty() )
|
||||
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
||||
|
||||
chain.expandCell( grid.top(), element.cell( orientation, constraint ) );
|
||||
auto cell = element.cell( orientation );
|
||||
cell.hint = layoutHint( element.item(), orientation, constraint );
|
||||
|
||||
chain.expandCell( grid.top(), cell );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -624,7 +616,9 @@ void QskGridLayoutEngine::setupChain( Qt::Orientation orientation,
|
||||
if ( !constraints.isEmpty() )
|
||||
constraint = qskSegmentLength( constraints, grid.left(), grid.right() );
|
||||
|
||||
chain.expandCells( grid.top(), grid.height(),
|
||||
element->cell( orientation, constraint ) );
|
||||
auto cell = element->cell( orientation );
|
||||
cell.hint = layoutHint( element->item(), orientation, constraint );
|
||||
|
||||
chain.expandCells( grid.top(), grid.height(), cell );
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskLayoutChain.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
|
||||
#include <qvarlengtharray.h>
|
||||
#include <qvector.h>
|
||||
@ -133,9 +132,9 @@ void QskLayoutChain::expandCells(
|
||||
if ( multiCell.hint.preferred() > chainHint.preferred() )
|
||||
preferred = chain.segments( multiCell.hint.preferred() );
|
||||
|
||||
if ( chainHint.maximum() == QskLayoutConstraint::unlimited )
|
||||
if ( chainHint.maximum() == QskLayoutHint::unlimited )
|
||||
{
|
||||
if ( multiCell.hint.maximum() < QskLayoutConstraint::unlimited )
|
||||
if ( multiCell.hint.maximum() < QskLayoutHint::unlimited )
|
||||
maximum = chain.segments( multiCell.hint.maximum() );
|
||||
}
|
||||
|
||||
@ -174,7 +173,7 @@ void QskLayoutChain::finish()
|
||||
|
||||
if ( !m_cells.empty() )
|
||||
{
|
||||
const auto maxMaximum = QskLayoutConstraint::unlimited;
|
||||
const auto maxMaximum = QskLayoutHint::unlimited;
|
||||
|
||||
for ( auto& cell : m_cells )
|
||||
{
|
||||
|
@ -1,507 +0,0 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskControl.h"
|
||||
#include "QskSizePolicy.h"
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskQuick.h"
|
||||
#include "QskFunctions.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
static inline qreal qskHintFor(
|
||||
const QQuickItem* item, const char* method, qreal widthOrHeight )
|
||||
{
|
||||
if ( item->metaObject()->indexOfMethod( method ) >= 0 )
|
||||
{
|
||||
qreal value;
|
||||
|
||||
( void ) QMetaObject::invokeMethod(
|
||||
const_cast< QQuickItem* >( item ), method, Qt::DirectConnection,
|
||||
Q_RETURN_ARG( qreal, value ), Q_ARG( qreal, widthOrHeight ) );
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline bool qskHasHintFor( const QQuickItem* item, const char* method )
|
||||
{
|
||||
if ( item->metaObject()->indexOfMethod( method ) >= 0 )
|
||||
{
|
||||
bool enabled;
|
||||
|
||||
( void ) QMetaObject::invokeMethod( const_cast< QQuickItem* >( item ),
|
||||
method, Qt::DirectConnection, Q_RETURN_ARG( bool, enabled ) );
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline QSizeF qskEffectiveSizeHint(
|
||||
const QQuickItem* item, Qt::SizeHint whichHint )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->effectiveSizeHint( whichHint );
|
||||
|
||||
QSizeF hint( -1.0, -1.0 ); // no hint
|
||||
|
||||
const char* properties[] =
|
||||
{
|
||||
"minimumSize",
|
||||
"preferredSize",
|
||||
"maximumSize"
|
||||
};
|
||||
|
||||
const QVariant v = item->property( properties[ whichHint ] );
|
||||
if ( v.canConvert( QMetaType::QSizeF ) )
|
||||
hint = v.toSizeF();
|
||||
|
||||
switch ( whichHint )
|
||||
{
|
||||
case Qt::MinimumSize:
|
||||
{
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( 0.0 );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( 0.0 );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::PreferredSize:
|
||||
{
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( item->implicitWidth() );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( item->implicitHeight() );
|
||||
|
||||
break;
|
||||
}
|
||||
case Qt::MaximumSize:
|
||||
{
|
||||
if ( hint.width() < 0 )
|
||||
hint.setWidth( QskLayoutConstraint::unlimited );
|
||||
|
||||
if ( hint.height() < 0 )
|
||||
hint.setHeight( QskLayoutConstraint::unlimited );
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
QskLayoutConstraint::Type QskLayoutConstraint::constraintType( const QQuickItem* item )
|
||||
{
|
||||
if ( item == nullptr )
|
||||
return Unconstrained;
|
||||
|
||||
Type constraintType = Unconstrained;
|
||||
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
{
|
||||
const auto policy = control->sizePolicy();
|
||||
if ( policy.horizontalPolicy() == QskSizePolicy::Constrained )
|
||||
{
|
||||
constraintType = WidthForHeight;
|
||||
}
|
||||
else if ( policy.verticalPolicy() == QskSizePolicy::Constrained )
|
||||
{
|
||||
constraintType = HeightForWidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( qskHasHintFor( item, "hasWidthForHeight" ) )
|
||||
{
|
||||
constraintType = WidthForHeight;
|
||||
}
|
||||
else if ( qskHasHintFor( item, "hasHeightForWidth" ) )
|
||||
{
|
||||
constraintType = HeightForWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
bool QskLayoutConstraint::isConstrained(
|
||||
const QQuickItem* item, Qt::Orientation orientation )
|
||||
{
|
||||
switch( constraintType( item ) )
|
||||
{
|
||||
case QskLayoutConstraint::WidthForHeight:
|
||||
return orientation == Qt::Horizontal;
|
||||
|
||||
case QskLayoutConstraint::HeightForWidth:
|
||||
return orientation == Qt::Vertical;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
qreal QskLayoutConstraint::heightForWidth( const QQuickItem* item, qreal width )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->heightForWidth( width );
|
||||
|
||||
return qskHintFor( item, "heightForWidth", width );
|
||||
}
|
||||
|
||||
qreal QskLayoutConstraint::widthForHeight( const QQuickItem* item, qreal height )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->widthForHeight( height );
|
||||
|
||||
return qskHintFor( item, "widthForHeight", height );
|
||||
}
|
||||
|
||||
qreal QskLayoutConstraint::constrainedMetric(
|
||||
Type type, const QskControl* control, qreal widthOrHeight,
|
||||
std::function< qreal( Type, const QskControl*, qreal ) > constrainFunction )
|
||||
{
|
||||
#if 1
|
||||
/*
|
||||
In case of having a corner radius of Qt::RelativeSize
|
||||
we might have a wrong result when using QskLayoutConstraint::unlimited.
|
||||
No idea how to solve this in a generic way: TODO ...
|
||||
*/
|
||||
#endif
|
||||
|
||||
const qreal upperLimit = 1e6;
|
||||
|
||||
if ( type == WidthForHeight )
|
||||
{
|
||||
const QSizeF outer( upperLimit, widthOrHeight );
|
||||
const QSizeF inner = control->layoutRectForSize( outer ).size();
|
||||
|
||||
qreal width = constrainFunction( type, control, inner.height() );
|
||||
|
||||
if ( width >= 0.0 )
|
||||
width += outer.width() - inner.width();
|
||||
|
||||
return width;
|
||||
}
|
||||
else
|
||||
{
|
||||
const QSizeF outer( widthOrHeight, upperLimit );
|
||||
const QSizeF inner = control->layoutRectForSize( outer ).size();
|
||||
|
||||
qreal height = constrainFunction( type, control, inner.width() );
|
||||
|
||||
if ( height >= 0.0 )
|
||||
height += outer.height() - inner.height();
|
||||
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
qreal QskLayoutConstraint::constrainedChildrenMetric(
|
||||
Type type, const QskControl* control, qreal constraint )
|
||||
{
|
||||
auto constrainFunction =
|
||||
( type == WidthForHeight ) ? widthForHeight : heightForWidth;
|
||||
|
||||
qreal constrainedValue = -1.0;
|
||||
|
||||
const auto children = control->childItems();
|
||||
for ( auto child : children )
|
||||
{
|
||||
if ( !qskIsTransparentForPositioner( child ) )
|
||||
{
|
||||
if ( qskIsVisibleToParent( child ) || retainSizeWhenHidden( child ) )
|
||||
{
|
||||
const auto v = constrainFunction( child, constraint );
|
||||
if ( v > constrainedValue )
|
||||
constrainedValue = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return constrainedValue;
|
||||
}
|
||||
|
||||
QskSizePolicy QskLayoutConstraint::sizePolicy( const QQuickItem* item )
|
||||
{
|
||||
if ( item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
return control->sizePolicy();
|
||||
|
||||
const QVariant v = item->property( "sizePolicy" );
|
||||
if ( v.canConvert< QskSizePolicy >() )
|
||||
return qvariant_cast< QskSizePolicy >( v );
|
||||
}
|
||||
|
||||
return QskSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred );
|
||||
}
|
||||
|
||||
QSizeF QskLayoutConstraint::boundedSize( const QQuickItem* item, const QSizeF& size )
|
||||
{
|
||||
qreal width, height;
|
||||
|
||||
switch( constraintType( item ) )
|
||||
{
|
||||
case WidthForHeight:
|
||||
{
|
||||
const auto hintV = layoutHint( item, Qt::Vertical, -1 );
|
||||
height = qBound( hintV.minimum(), size.height(), hintV.maximum() );
|
||||
|
||||
const auto hintH = layoutHint( item, Qt::Horizontal, height );
|
||||
width = qBound( hintH.minimum(), size.width(), hintH.maximum() );
|
||||
|
||||
break;
|
||||
}
|
||||
case HeightForWidth:
|
||||
{
|
||||
const auto hintH = layoutHint( item, Qt::Horizontal, -1 );
|
||||
width = qBound( hintH.minimum(), size.width(), hintH.maximum() );
|
||||
|
||||
const auto hintV = layoutHint( item, Qt::Vertical, width );
|
||||
height = qBound( hintV.minimum(), size.height(), hintV.maximum() );
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
const auto hintH = layoutHint( item, Qt::Horizontal, -1 );
|
||||
const auto hintV = layoutHint( item, Qt::Vertical, -1 );
|
||||
|
||||
width = qBound( hintH.minimum(), size.width(), hintH.maximum() );
|
||||
height = qBound( hintV.minimum(), size.height(), hintV.maximum() );
|
||||
}
|
||||
}
|
||||
|
||||
return QSizeF( width, height );
|
||||
|
||||
}
|
||||
|
||||
qreal QskLayoutConstraint::sizeHint( const QQuickItem* item,
|
||||
Qt::SizeHint whichHint, Qt::Orientation orientation, qreal constraint )
|
||||
{
|
||||
if ( orientation == Qt::Horizontal )
|
||||
return sizeHint( item, whichHint, QSizeF( -1.0, constraint ) ).width();
|
||||
else
|
||||
return sizeHint( item, whichHint, QSizeF( constraint, -1.0 ) ).height();
|
||||
}
|
||||
|
||||
QSizeF QskLayoutConstraint::sizeHint( const QQuickItem* item,
|
||||
Qt::SizeHint whichHint, const QSizeF& constraint )
|
||||
{
|
||||
if ( item == nullptr || whichHint < Qt::MinimumSize || whichHint > Qt::MaximumSize )
|
||||
return QSizeF( 0, 0 );
|
||||
|
||||
if ( constraint.isValid() )
|
||||
return constraint;
|
||||
|
||||
QSizeF hint( 0, 0 );
|
||||
|
||||
Type constraintType = Unconstrained;
|
||||
|
||||
if ( whichHint == Qt::PreferredSize )
|
||||
constraintType = QskLayoutConstraint::constraintType( item );
|
||||
|
||||
if ( constraintType != Unconstrained )
|
||||
{
|
||||
const quint32 growFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
||||
|
||||
if ( constraint.width() > 0 ) // && constrainedType == HeightForWidth ??
|
||||
{
|
||||
qreal w = constraint.width();
|
||||
|
||||
if ( !( sizePolicy( item ).policy( Qt::Horizontal ) & growFlags ) )
|
||||
{
|
||||
const auto maxW = qskEffectiveSizeHint( item, Qt::PreferredSize ).width();
|
||||
|
||||
if ( maxW >= 0.0 )
|
||||
w = qMin( w, maxW );
|
||||
}
|
||||
|
||||
hint.setWidth( w );
|
||||
hint.setHeight( heightForWidth( item, w ) );
|
||||
}
|
||||
else if ( constraint.height() > 0 ) // && constrainedType == WidthForHeight ??
|
||||
{
|
||||
qreal h = constraint.height();
|
||||
|
||||
if ( !( sizePolicy( item ).policy( Qt::Vertical ) & growFlags ) )
|
||||
{
|
||||
const auto maxH = qskEffectiveSizeHint( item, Qt::PreferredSize ).height();
|
||||
|
||||
if ( maxH >= 0.0 )
|
||||
h = qMin( h, maxH );
|
||||
}
|
||||
|
||||
hint.setWidth( widthForHeight( item, h ) );
|
||||
hint.setHeight( h );
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = qskEffectiveSizeHint( item, Qt::PreferredSize );
|
||||
|
||||
if ( constraintType == WidthForHeight )
|
||||
hint.setWidth( widthForHeight( item, hint.height() ) );
|
||||
else
|
||||
hint.setHeight( heightForWidth( item, hint.width() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = qskEffectiveSizeHint( item, whichHint );
|
||||
}
|
||||
|
||||
hint = hint.expandedTo( QSizeF( 0.0, 0.0 ) );
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
QRectF QskLayoutConstraint::boundedRect( const QQuickItem* item,
|
||||
const QRectF& rect, Qt::Alignment alignment )
|
||||
{
|
||||
auto size = boundedSize( item, rect.size() );
|
||||
#if 0
|
||||
size = size.boundedTo( rect.size() ); // ignoring minimumSize
|
||||
#endif
|
||||
|
||||
return qskAlignedRectF( rect, size.width(), size.height(), alignment );
|
||||
}
|
||||
|
||||
QskLayoutHint QskLayoutConstraint::layoutHint(
|
||||
const QQuickItem* item, Qt::Orientation orientation, qreal constraint )
|
||||
{
|
||||
if ( item == nullptr )
|
||||
return QskLayoutHint();
|
||||
|
||||
const auto policy = sizePolicy( item ).policy( orientation );
|
||||
|
||||
if ( constraint >= 0.0 )
|
||||
{
|
||||
if ( !isConstrained( item, orientation ) )
|
||||
constraint = -1.0;
|
||||
}
|
||||
|
||||
qreal minimum, preferred, maximum;
|
||||
|
||||
const auto expandFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
||||
|
||||
if ( ( policy & QskSizePolicy::ShrinkFlag ) &&
|
||||
( policy & expandFlags ) && ( policy & QskSizePolicy::IgnoreFlag ) )
|
||||
{
|
||||
// we don't need to calculate the preferred size
|
||||
|
||||
minimum = sizeHint( item, Qt::MinimumSize, orientation, constraint );
|
||||
maximum = sizeHint( item, Qt::MaximumSize, orientation, constraint );
|
||||
preferred = minimum;
|
||||
}
|
||||
else
|
||||
{
|
||||
preferred = sizeHint( item, Qt::PreferredSize, orientation, constraint );
|
||||
|
||||
if ( policy & QskSizePolicy::ShrinkFlag )
|
||||
minimum = sizeHint( item, Qt::MinimumSize, orientation, constraint );
|
||||
else
|
||||
minimum = preferred;
|
||||
|
||||
if ( policy & expandFlags )
|
||||
maximum = sizeHint( item, Qt::MaximumSize, orientation, constraint );
|
||||
else
|
||||
maximum = preferred;
|
||||
|
||||
if ( policy & QskSizePolicy::IgnoreFlag )
|
||||
preferred = minimum;
|
||||
}
|
||||
|
||||
return QskLayoutHint( minimum, preferred, maximum );
|
||||
}
|
||||
|
||||
static const char s_alignmentProperty[] = "layoutAlignmentHint";
|
||||
static const char s_retainSizeWhenHiddenProperty[] = "layoutRetainSizeWhenHidden";
|
||||
|
||||
Qt::Alignment QskLayoutConstraint::layoutAlignmentHint( const QQuickItem* item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
{
|
||||
return control->layoutAlignmentHint();
|
||||
}
|
||||
else if ( item )
|
||||
{
|
||||
const QVariant v = item->property( s_alignmentProperty );
|
||||
if ( v.canConvert< Qt::Alignment >() )
|
||||
return v.value< Qt::Alignment >();
|
||||
}
|
||||
|
||||
return Qt::Alignment();
|
||||
}
|
||||
|
||||
void QskLayoutConstraint::setLayoutAlignmentHint(
|
||||
QQuickItem* item, Qt::Alignment alignment )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
{
|
||||
control->setLayoutAlignmentHint( alignment );
|
||||
}
|
||||
else if ( item )
|
||||
{
|
||||
QVariant v;
|
||||
if ( alignment )
|
||||
v.setValue( alignment );
|
||||
|
||||
item->setProperty( s_alignmentProperty, v );
|
||||
}
|
||||
}
|
||||
|
||||
bool QskLayoutConstraint::retainSizeWhenHidden( const QQuickItem* item )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
{
|
||||
return control->layoutHints() & QskControl::RetainSizeWhenHidden;
|
||||
}
|
||||
else if ( item )
|
||||
{
|
||||
const QVariant v = item->property( s_retainSizeWhenHiddenProperty );
|
||||
if ( v.canConvert< bool >() )
|
||||
return v.toBool();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QskLayoutConstraint::setRetainSizeWhenHidden( QQuickItem* item, bool on )
|
||||
{
|
||||
if ( auto control = qskControlCast( item ) )
|
||||
{
|
||||
control->setLayoutHint( QskControl::RetainSizeWhenHidden, on );
|
||||
}
|
||||
else if ( item )
|
||||
{
|
||||
QVariant v;
|
||||
if ( on )
|
||||
v.setValue( on );
|
||||
|
||||
item->setProperty( s_retainSizeWhenHiddenProperty, v );
|
||||
}
|
||||
}
|
||||
|
||||
bool QskLayoutConstraint::isVisibleToLayout( const QQuickItem* item )
|
||||
{
|
||||
if ( item )
|
||||
{
|
||||
if ( !qskIsTransparentForPositioner( item ) )
|
||||
return qskIsVisibleToParent( item ) || retainSizeWhenHidden( item );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_LAYOUT_CONSTRAINT_H
|
||||
#define QSK_LAYOUT_CONSTRAINT_H
|
||||
|
||||
#include "QskGlobal.h"
|
||||
|
||||
#include <qnamespace.h>
|
||||
#include <qsize.h>
|
||||
#include <limits>
|
||||
#include <functional>
|
||||
|
||||
class QskSizePolicy;
|
||||
class QskControl;
|
||||
class QskLayoutHint;
|
||||
class QQuickItem;
|
||||
class QSizeF;
|
||||
class QRectF;
|
||||
|
||||
namespace QskLayoutConstraint
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Unconstrained = 0,
|
||||
|
||||
WidthForHeight = 1 << 0,
|
||||
HeightForWidth = 1 << 1
|
||||
};
|
||||
|
||||
QSK_EXPORT qreal heightForWidth( const QQuickItem*, qreal width );
|
||||
QSK_EXPORT qreal widthForHeight( const QQuickItem*, qreal height );
|
||||
|
||||
QSK_EXPORT Type constraintType( const QQuickItem* );
|
||||
QSK_EXPORT bool isConstrained( const QQuickItem*, Qt::Orientation );
|
||||
|
||||
QSK_EXPORT qreal constrainedMetric(
|
||||
Type, const QskControl*, qreal value,
|
||||
std::function< qreal( Type, const QskControl*, qreal ) > );
|
||||
|
||||
QSK_EXPORT qreal constrainedChildrenMetric(
|
||||
Type, const QskControl*, qreal constraint );
|
||||
|
||||
QSK_EXPORT QskSizePolicy sizePolicy( const QQuickItem* );
|
||||
|
||||
// size/rect bounded by the layout hints
|
||||
QSK_EXPORT QSizeF boundedSize( const QQuickItem*, const QSizeF& );
|
||||
QSK_EXPORT QRectF boundedRect(
|
||||
const QQuickItem*, const QRectF&, Qt::Alignment );
|
||||
|
||||
QSK_EXPORT QSizeF sizeHint( const QQuickItem*,
|
||||
Qt::SizeHint, const QSizeF& constraint = QSizeF() );
|
||||
|
||||
QSK_EXPORT qreal sizeHint(
|
||||
const QQuickItem*, Qt::SizeHint, Qt::Orientation, qreal constraint );
|
||||
|
||||
QSK_EXPORT QskLayoutHint layoutHint(
|
||||
const QQuickItem*, Qt::Orientation, qreal constraint );
|
||||
|
||||
QSK_EXPORT Qt::Alignment layoutAlignmentHint( const QQuickItem* );
|
||||
QSK_EXPORT void setLayoutAlignmentHint( QQuickItem*, Qt::Alignment );
|
||||
|
||||
QSK_EXPORT bool retainSizeWhenHidden( const QQuickItem* );
|
||||
QSK_EXPORT void setRetainSizeWhenHidden( QQuickItem*, bool );
|
||||
|
||||
QSK_EXPORT bool isVisibleToLayout( const QQuickItem* );
|
||||
|
||||
const qreal unlimited = std::numeric_limits< float >::max();
|
||||
const QSizeF defaultSizeHints[] = { { 0, 0 }, { -1, -1 }, { unlimited, unlimited } };
|
||||
}
|
||||
|
||||
#endif
|
@ -5,9 +5,99 @@
|
||||
|
||||
#include "QskLayoutEngine2D.h"
|
||||
#include "QskLayoutChain.h"
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
#include <qguiapplication.h>
|
||||
|
||||
static QSizeF qskItemConstraint( const QQuickItem* item, const QSizeF& constraint )
|
||||
{
|
||||
QSizeF hint( 0, 0 );
|
||||
|
||||
const auto sizePolicy = qskSizePolicy( item );
|
||||
|
||||
const auto constraintType = sizePolicy.constraintType();
|
||||
const auto which = Qt::PreferredSize;
|
||||
|
||||
if ( constraintType != QskSizePolicy::Unconstrained )
|
||||
{
|
||||
const quint32 growFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
||||
|
||||
if ( constraint.width() > 0 ) // && constrainedType == HeightForWidth ??
|
||||
{
|
||||
qreal w = constraint.width();
|
||||
|
||||
if ( !( sizePolicy.policy( Qt::Horizontal ) & growFlags ) )
|
||||
{
|
||||
const auto maxW = qskEffectiveSizeHint( item, which ).width();
|
||||
|
||||
if ( maxW >= 0.0 )
|
||||
w = qMin( w, maxW );
|
||||
}
|
||||
|
||||
hint.setWidth( w );
|
||||
hint.setHeight( qskHeightForWidth( item, which, w ) );
|
||||
}
|
||||
else if ( constraint.height() > 0 ) // && constrainedType == WidthForHeight ??
|
||||
{
|
||||
qreal h = constraint.height();
|
||||
|
||||
if ( !( sizePolicy.policy( Qt::Vertical ) & growFlags ) )
|
||||
{
|
||||
const auto maxH = qskEffectiveSizeHint( item, which ).height();
|
||||
|
||||
if ( maxH >= 0.0 )
|
||||
h = qMin( h, maxH );
|
||||
}
|
||||
|
||||
hint.setWidth( qskWidthForHeight( item, which, h ) );
|
||||
hint.setHeight( h );
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = qskEffectiveSizeHint( item, which );
|
||||
|
||||
if ( constraintType == QskSizePolicy::WidthForHeight )
|
||||
hint.setWidth( qskWidthForHeight( item, which, hint.height() ) );
|
||||
else
|
||||
hint.setHeight( qskHeightForWidth( item, which, hint.width() ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hint = qskEffectiveSizeHint( item, which );
|
||||
}
|
||||
|
||||
hint = hint.expandedTo( QSizeF( 0.0, 0.0 ) );
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
static inline qreal qskLayoutConstraint( const QQuickItem* item,
|
||||
Qt::Orientation orientation, qreal constraint )
|
||||
{
|
||||
if ( orientation == Qt::Horizontal )
|
||||
return qskItemConstraint( item, QSizeF( -1.0, constraint ) ).width();
|
||||
else
|
||||
return qskItemConstraint( item, QSizeF( constraint, -1.0 ) ).height();
|
||||
}
|
||||
|
||||
static inline qreal qskEffectiveConstraint( const QQuickItem* item,
|
||||
Qt::SizeHint which, Qt::Orientation orientation )
|
||||
{
|
||||
qreal value;
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
value = qskEffectiveSizeHint( item, which ).width();
|
||||
else
|
||||
value = qskEffectiveSizeHint( item, which ).height();
|
||||
|
||||
if ( value < 0.0 )
|
||||
value = ( which == Qt::MaximumSize ) ? QskLayoutHint::unlimited : 0.0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class LayoutData
|
||||
@ -259,11 +349,11 @@ void QskLayoutEngine2D::layoutItem( QQuickItem* item, const QRect& grid ) const
|
||||
if ( layoutData == nullptr || item == nullptr )
|
||||
return;
|
||||
|
||||
auto alignment = QskLayoutConstraint::layoutAlignmentHint( item );
|
||||
auto alignment = qskLayoutAlignmentHint( item );
|
||||
alignment = m_data->effectiveAlignment( alignment );
|
||||
|
||||
QRectF rect = layoutData->geometryAt( grid );
|
||||
rect = QskLayoutConstraint::boundedRect(item, rect, alignment );
|
||||
auto rect = layoutData->geometryAt( grid );
|
||||
rect = qskConstrainedItemRect( item, rect, alignment );
|
||||
|
||||
if ( layoutData->direction == Qt::RightToLeft )
|
||||
{
|
||||
@ -298,7 +388,7 @@ QSizeF QskLayoutEngine2D::sizeHint(
|
||||
m_data->blockInvalidate = true;
|
||||
|
||||
if ( ( constraint.width() >= 0 ) &&
|
||||
( constraintType() == QskLayoutConstraint::HeightForWidth ) )
|
||||
( constraintType() == QskSizePolicy::HeightForWidth ) )
|
||||
{
|
||||
setupChain( Qt::Horizontal );
|
||||
|
||||
@ -306,7 +396,7 @@ QSizeF QskLayoutEngine2D::sizeHint(
|
||||
setupChain( Qt::Vertical, constraints );
|
||||
}
|
||||
else if ( ( constraint.height() >= 0 ) &&
|
||||
( constraintType() == QskLayoutConstraint::WidthForHeight ) )
|
||||
( constraintType() == QskSizePolicy::WidthForHeight ) )
|
||||
{
|
||||
setupChain( Qt::Vertical );
|
||||
|
||||
@ -327,6 +417,54 @@ QSizeF QskLayoutEngine2D::sizeHint(
|
||||
return QSizeF( width, height );
|
||||
}
|
||||
|
||||
QskLayoutHint QskLayoutEngine2D::layoutHint( const QQuickItem* item,
|
||||
Qt::Orientation orientation, qreal constraint ) const
|
||||
{
|
||||
if ( item == nullptr )
|
||||
return QskLayoutHint();
|
||||
|
||||
const auto policy = qskSizePolicy( item ).policy( orientation );
|
||||
|
||||
if ( constraint >= 0.0 )
|
||||
{
|
||||
if ( !( policy & QskSizePolicy::ConstrainedFlag ) )
|
||||
constraint = -1.0;
|
||||
}
|
||||
|
||||
qreal minimum, preferred, maximum;
|
||||
|
||||
const auto expandFlags = QskSizePolicy::GrowFlag | QskSizePolicy::ExpandFlag;
|
||||
|
||||
if ( ( policy & QskSizePolicy::ShrinkFlag ) &&
|
||||
( policy & expandFlags ) && ( policy & QskSizePolicy::IgnoreFlag ) )
|
||||
{
|
||||
// we don't need to calculate the preferred size
|
||||
|
||||
minimum = qskEffectiveConstraint( item, Qt::MinimumSize, orientation );
|
||||
maximum = qskEffectiveConstraint( item, Qt::MaximumSize, orientation );
|
||||
preferred = minimum;
|
||||
}
|
||||
else
|
||||
{
|
||||
preferred = qskLayoutConstraint( item, orientation, constraint );
|
||||
|
||||
if ( policy & QskSizePolicy::ShrinkFlag )
|
||||
minimum = qskEffectiveConstraint( item, Qt::MinimumSize, orientation );
|
||||
else
|
||||
minimum = preferred;
|
||||
|
||||
if ( policy & expandFlags )
|
||||
maximum = qskEffectiveConstraint( item, Qt::MaximumSize, orientation );
|
||||
else
|
||||
maximum = preferred;
|
||||
|
||||
if ( policy & QskSizePolicy::IgnoreFlag )
|
||||
preferred = minimum;
|
||||
}
|
||||
|
||||
return QskLayoutHint( minimum, preferred, maximum );
|
||||
}
|
||||
|
||||
void QskLayoutEngine2D::setupChain( Qt::Orientation orientation ) const
|
||||
{
|
||||
setupChain( orientation, QskLayoutChain::Segments() );
|
||||
@ -371,7 +509,7 @@ void QskLayoutEngine2D::updateSegments( const QSizeF& size ) const
|
||||
|
||||
switch( constraintType() )
|
||||
{
|
||||
case QskLayoutConstraint::WidthForHeight:
|
||||
case QskSizePolicy::WidthForHeight:
|
||||
{
|
||||
setupChain( Qt::Vertical );
|
||||
rows = rowChain.segments( size.height() );
|
||||
@ -381,7 +519,7 @@ void QskLayoutEngine2D::updateSegments( const QSizeF& size ) const
|
||||
|
||||
break;
|
||||
}
|
||||
case QskLayoutConstraint::HeightForWidth:
|
||||
case QskSizePolicy::HeightForWidth:
|
||||
{
|
||||
setupChain( Qt::Horizontal );
|
||||
columns = columnChain.segments( size.width() );
|
||||
@ -426,28 +564,26 @@ void QskLayoutEngine2D::invalidate( int what )
|
||||
}
|
||||
}
|
||||
|
||||
QskLayoutConstraint::Type QskLayoutEngine2D::constraintType() const
|
||||
QskSizePolicy::ConstraintType QskLayoutEngine2D::constraintType() const
|
||||
{
|
||||
if ( m_data->constraintType < 0 )
|
||||
{
|
||||
auto constraintType = QskLayoutConstraint::Unconstrained;
|
||||
auto constraintType = QskSizePolicy::Unconstrained;
|
||||
|
||||
for ( int i = 0; i < count(); i++ )
|
||||
{
|
||||
const auto type = QskLayoutConstraint::constraintType( itemAt( i ) );
|
||||
const auto type = qskSizePolicy( itemAt( i ) ).constraintType();
|
||||
|
||||
using namespace QskLayoutConstraint;
|
||||
|
||||
if ( type != Unconstrained )
|
||||
if ( type != QskSizePolicy::Unconstrained )
|
||||
{
|
||||
if ( constraintType == Unconstrained )
|
||||
if ( constraintType == QskSizePolicy::Unconstrained )
|
||||
{
|
||||
constraintType = type;
|
||||
}
|
||||
else if ( constraintType != type )
|
||||
{
|
||||
qWarning( "QskLayoutEngine2D: conflicting constraints");
|
||||
constraintType = Unconstrained;
|
||||
constraintType = QskSizePolicy::Unconstrained;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -455,6 +591,6 @@ QskLayoutConstraint::Type QskLayoutEngine2D::constraintType() const
|
||||
m_data->constraintType = constraintType;
|
||||
}
|
||||
|
||||
return static_cast< QskLayoutConstraint::Type >( m_data->constraintType );
|
||||
return static_cast< QskSizePolicy::ConstraintType >( m_data->constraintType );
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,14 @@
|
||||
|
||||
#include "QskGlobal.h"
|
||||
#include "QskLayoutChain.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskSizePolicy.h"
|
||||
|
||||
#include <qnamespace.h>
|
||||
#include <memory>
|
||||
|
||||
class QQuickItem;
|
||||
class QskLayoutHint;
|
||||
|
||||
class QskLayoutEngine2D
|
||||
{
|
||||
public:
|
||||
@ -55,6 +58,8 @@ class QskLayoutEngine2D
|
||||
protected:
|
||||
|
||||
void layoutItem( QQuickItem*, const QRect& grid ) const;
|
||||
QskLayoutHint layoutHint( const QQuickItem*,
|
||||
Qt::Orientation, qreal constraint ) const;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -73,7 +78,7 @@ class QskLayoutEngine2D
|
||||
virtual int effectiveCount( Qt::Orientation ) const = 0;
|
||||
|
||||
virtual void invalidateElementCache() = 0;
|
||||
QskLayoutConstraint::Type constraintType() const;
|
||||
QskSizePolicy::ConstraintType constraintType() const;
|
||||
|
||||
void setupChain( Qt::Orientation ) const;
|
||||
void setupChain( Qt::Orientation, const QskLayoutChain::Segments& ) const;
|
||||
|
@ -4,11 +4,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskControl.h"
|
||||
#include <qnamespace.h>
|
||||
|
||||
QskLayoutHint::QskLayoutHint()
|
||||
: QskLayoutHint( 0.0, 0.0, QskLayoutConstraint::unlimited )
|
||||
: QskLayoutHint( 0.0, 0.0, QskLayoutHint::unlimited )
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,7 +75,21 @@ void QskLayoutHint::normalize()
|
||||
bool QskLayoutHint::isDefault() const
|
||||
{
|
||||
return ( m_minimum == 0.0 ) && ( m_preferred == 0.0 )
|
||||
&& ( m_maximum == QskLayoutConstraint::unlimited );
|
||||
&& ( m_maximum == QskLayoutHint::unlimited );
|
||||
}
|
||||
|
||||
qreal QskLayoutHint::combined( int which, qreal value1, qreal value2 )
|
||||
{
|
||||
if ( value1 < 0.0 )
|
||||
return value2;
|
||||
|
||||
if ( value2 < 0.0 )
|
||||
return value1;
|
||||
|
||||
if ( which == Qt::MaximumSize )
|
||||
return qMin( value1, value2 );
|
||||
else
|
||||
return qMax( value1, value2 );
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
@ -84,7 +98,7 @@ bool QskLayoutHint::isDefault() const
|
||||
|
||||
static inline QString qskHintValueString( qreal value )
|
||||
{
|
||||
if ( value >= QskLayoutConstraint::unlimited )
|
||||
if ( value >= QskLayoutHint::unlimited )
|
||||
return QStringLiteral( "unlimited" );
|
||||
else
|
||||
return QString::number( value );
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "QskGlobal.h"
|
||||
#include <qglobal.h>
|
||||
#include <limits>
|
||||
|
||||
class QDebug;
|
||||
|
||||
@ -44,6 +45,9 @@ class QSK_EXPORT QskLayoutHint
|
||||
void expandPreferred( qreal value );
|
||||
void expandMaximum( qreal value );
|
||||
|
||||
static qreal combined( int which, qreal value1, qreal value2 );
|
||||
static constexpr qreal unlimited = std::numeric_limits< float >::max();
|
||||
|
||||
private:
|
||||
qreal m_minimum;
|
||||
qreal m_preferred;
|
||||
|
@ -5,8 +5,6 @@
|
||||
|
||||
#include "QskLinearBox.h"
|
||||
#include "QskLinearLayoutEngine.h"
|
||||
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskEvent.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
@ -188,33 +186,16 @@ void QskLinearBox::updateLayout()
|
||||
m_data->engine.setGeometries( layoutRect() );
|
||||
}
|
||||
|
||||
QSizeF QskLinearBox::contentsSizeHint() const
|
||||
QSizeF QskLinearBox::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
return m_data->engine.sizeHint( Qt::PreferredSize, QSizeF() );
|
||||
}
|
||||
if ( which == Qt::MaximumSize )
|
||||
{
|
||||
// we can extend beyond the maximum size of the children
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
qreal QskLinearBox::heightForWidth( qreal width ) const
|
||||
{
|
||||
auto constrainedHeight =
|
||||
[this]( QskLayoutConstraint::Type, const QskControl*, qreal width )
|
||||
{
|
||||
return m_data->engine.heightForWidth( width );
|
||||
};
|
||||
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::HeightForWidth, this, width, constrainedHeight );
|
||||
}
|
||||
|
||||
qreal QskLinearBox::widthForHeight( qreal height ) const
|
||||
{
|
||||
auto constrainedWidth =
|
||||
[this]( QskLayoutConstraint::Type, const QskControl*, qreal height )
|
||||
{
|
||||
return m_data->engine.widthForHeight( height );
|
||||
};
|
||||
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::WidthForHeight, this, height, constrainedWidth );
|
||||
return m_data->engine.sizeHint( which, constraint );
|
||||
}
|
||||
|
||||
void QskLinearBox::geometryChangeEvent( QskGeometryChangeEvent* event )
|
||||
|
@ -54,9 +54,6 @@ class QSK_EXPORT QskLinearBox : public QskIndexedLayoutBox
|
||||
void removeItem( const QQuickItem* );
|
||||
void removeAt( int index );
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
Qt::Orientation orientation() const;
|
||||
void setOrientation( Qt::Orientation );
|
||||
|
||||
@ -108,7 +105,7 @@ class QSK_EXPORT QskLinearBox : public QskIndexedLayoutBox
|
||||
void itemChange( ItemChange, const ItemChangeData& ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
void autoAddItem( QQuickItem* ) override final;
|
||||
void autoRemoveItem( QQuickItem* ) override final;
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "QskLinearLayoutEngine.h"
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskLayoutChain.h"
|
||||
#include "QskSizePolicy.h"
|
||||
#include "QskQuick.h"
|
||||
@ -36,8 +35,8 @@ namespace
|
||||
|
||||
bool isIgnored() const;
|
||||
|
||||
QskLayoutChain::CellData cell( Qt::Orientation,
|
||||
bool isLayoutOrientation, qreal constraint ) const;
|
||||
QskLayoutChain::CellData cell(
|
||||
Qt::Orientation, bool isLayoutOrientation ) const;
|
||||
|
||||
private:
|
||||
|
||||
@ -100,14 +99,11 @@ inline void Element::setStretch( int stretch )
|
||||
|
||||
bool Element::isIgnored() const
|
||||
{
|
||||
if ( !m_isSpacer && !QskLayoutConstraint::retainSizeWhenHidden( m_item ) )
|
||||
return !qskIsVisibleToParent( m_item );
|
||||
|
||||
return false;
|
||||
return !( m_isSpacer || qskIsVisibleToLayout( m_item ) );
|
||||
}
|
||||
|
||||
QskLayoutChain::CellData Element::cell( Qt::Orientation orientation,
|
||||
bool isLayoutOrientation, qreal constraint ) const
|
||||
QskLayoutChain::CellData Element::cell(
|
||||
Qt::Orientation orientation, bool isLayoutOrientation ) const
|
||||
{
|
||||
QskLayoutChain::CellData cell;
|
||||
cell.canGrow = true;
|
||||
@ -115,9 +111,7 @@ QskLayoutChain::CellData Element::cell( Qt::Orientation orientation,
|
||||
|
||||
if ( !m_isSpacer )
|
||||
{
|
||||
cell.hint = QskLayoutConstraint::layoutHint( m_item, orientation, constraint );
|
||||
|
||||
const auto policy = QskLayoutConstraint::sizePolicy( m_item ).policy( orientation );
|
||||
const auto policy = qskSizePolicy( m_item ).policy( orientation );
|
||||
|
||||
if ( isLayoutOrientation )
|
||||
{
|
||||
@ -302,12 +296,11 @@ bool QskLinearLayoutEngine::removeAt( int index )
|
||||
if ( element->isIgnored() )
|
||||
m_data->sumIgnored--;
|
||||
|
||||
const auto itemType =
|
||||
QskLayoutConstraint::constraintType( element->item() );
|
||||
const auto itemType = qskSizePolicy( element->item() ).constraintType();
|
||||
|
||||
int invalidationMode = LayoutCache;
|
||||
|
||||
if ( itemType > QskLayoutConstraint::Unconstrained )
|
||||
if ( itemType > QskSizePolicy::Unconstrained )
|
||||
invalidationMode |= ElementCache;
|
||||
|
||||
m_data->elements.erase( m_data->elements.begin() + index );
|
||||
@ -435,8 +428,10 @@ void QskLinearLayoutEngine::setupChain( Qt::Orientation orientation,
|
||||
if ( !constraints.isEmpty() )
|
||||
constraint = constraints[index1].length;
|
||||
|
||||
const auto cell = element.cell(
|
||||
orientation, isLayoutOrientation, constraint );
|
||||
auto cell = element.cell( orientation, isLayoutOrientation );
|
||||
|
||||
if ( element.item() )
|
||||
cell.hint = layoutHint( element.item(), orientation, constraint );
|
||||
|
||||
chain.expandCell( index2, cell );
|
||||
|
||||
|
@ -5,36 +5,12 @@
|
||||
|
||||
#include "QskStackBox.h"
|
||||
#include "QskStackBoxAnimator.h"
|
||||
#include "QskLayoutConstraint.h"
|
||||
#include "QskLayoutHint.h"
|
||||
#include "QskEvent.h"
|
||||
#include "QskQuick.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
static qreal qskConstrainedValue( QskLayoutConstraint::Type type,
|
||||
const QskControl* control, qreal widthOrHeight )
|
||||
{
|
||||
using namespace QskLayoutConstraint;
|
||||
|
||||
auto constrainFunction =
|
||||
( type == WidthForHeight ) ? widthForHeight : heightForWidth;
|
||||
|
||||
qreal constrainedValue = -1;
|
||||
auto stackBox = static_cast< const QskStackBox* >( control );
|
||||
|
||||
for ( int i = 0; i < stackBox->itemCount(); i++ )
|
||||
{
|
||||
if ( const auto item = stackBox->itemAtIndex( i ) )
|
||||
{
|
||||
const qreal v = constrainFunction( item, widthOrHeight );
|
||||
if ( v > constrainedValue )
|
||||
constrainedValue = v;
|
||||
}
|
||||
}
|
||||
|
||||
return constrainedValue;
|
||||
}
|
||||
|
||||
class QskStackBox::PrivateData
|
||||
{
|
||||
public:
|
||||
@ -328,11 +304,11 @@ QRectF QskStackBox::geometryForItemAt( int index ) const
|
||||
|
||||
if ( const auto item = m_data->items.value( index ) )
|
||||
{
|
||||
auto alignment = QskLayoutConstraint::layoutAlignmentHint( item );
|
||||
auto alignment = qskLayoutAlignmentHint( item );
|
||||
if ( alignment == 0 )
|
||||
alignment = m_data->defaultAlignment;
|
||||
|
||||
return QskLayoutConstraint::boundedRect( item, r, alignment );
|
||||
return qskConstrainedItemRect( item, r, alignment );
|
||||
}
|
||||
|
||||
return QRectF( r.x(), r.y(), 0.0, 0.0 );
|
||||
@ -352,91 +328,93 @@ void QskStackBox::updateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF QskStackBox::contentsSizeHint() const
|
||||
QSizeF QskStackBox::layoutSizeHint(
|
||||
Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
#if 1
|
||||
// needs to reimplemented TODO ...
|
||||
|
||||
if ( which != Qt::PreferredSize )
|
||||
return QSizeF();
|
||||
|
||||
if ( itemCount() == 0 )
|
||||
return QSizeF( 0, 0 );
|
||||
#endif
|
||||
return QSizeF();
|
||||
|
||||
if ( constraint.width() >= 0 || constraint.height() >= 0 )
|
||||
{
|
||||
qreal value = -1;
|
||||
|
||||
for ( const auto& item : qskAsConst( m_data->items ) )
|
||||
{
|
||||
const auto hint = qskEffectiveSizeHint(
|
||||
item, Qt::PreferredSize, constraint );
|
||||
|
||||
if ( constraint.width() >= 0 )
|
||||
value = qMax( hint.height(), value );
|
||||
else
|
||||
value = qMax( hint.width(), value );
|
||||
}
|
||||
|
||||
if ( constraint.width() >= 0 )
|
||||
return QSizeF( constraint.width(), value );
|
||||
else
|
||||
return QSizeF( value, constraint.height() );
|
||||
}
|
||||
|
||||
qreal width = -1;
|
||||
qreal height = -1;
|
||||
|
||||
using namespace QskLayoutConstraint;
|
||||
|
||||
int constraintTypes = Unconstrained;
|
||||
int constraintTypes = QskSizePolicy::Unconstrained;
|
||||
|
||||
for ( const auto item : qskAsConst( m_data->items ) )
|
||||
{
|
||||
const auto type = constraintType( item );
|
||||
if ( type != Unconstrained )
|
||||
const auto type = qskSizePolicy( item ).constraintType();
|
||||
if ( type != QskSizePolicy::Unconstrained )
|
||||
{
|
||||
constraintTypes |= type;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto hint = QskLayoutConstraint::sizeHint(
|
||||
item, Qt::PreferredSize, QSizeF( -1, -1 ) );
|
||||
|
||||
if ( hint.width() >= width )
|
||||
width = hint.width();
|
||||
const auto hint = qskSizeConstraint( item, which, constraint );
|
||||
|
||||
if ( hint.height() >= height )
|
||||
height = hint.height();
|
||||
}
|
||||
width = QskLayoutHint::combined( which, width, hint.width() );
|
||||
height = QskLayoutHint::combined( which, height, hint.height() );
|
||||
}
|
||||
|
||||
#if 1
|
||||
// does this work ???
|
||||
|
||||
if ( constraintTypes & WidthForHeight )
|
||||
if ( constraintTypes & QskSizePolicy::WidthForHeight )
|
||||
{
|
||||
const QSizeF constraint( -1, height );
|
||||
|
||||
for ( const auto& item : qskAsConst( m_data->items ) )
|
||||
{
|
||||
if ( constraintType( item ) == WidthForHeight )
|
||||
{
|
||||
const auto hint = QskLayoutConstraint::sizeHint(
|
||||
item, Qt::PreferredSize, constraint );
|
||||
const auto sizePolicy = qskSizePolicy( item );
|
||||
|
||||
width = qMax( width, hint.width() );
|
||||
if ( sizePolicy.constraintType() == QskSizePolicy::WidthForHeight )
|
||||
{
|
||||
const auto hint = qskSizeConstraint( item, which, constraint );
|
||||
width = QskLayoutHint::combined( which, width, hint.width() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( constraintTypes & HeightForWidth )
|
||||
if ( constraintTypes & QskSizePolicy::HeightForWidth )
|
||||
{
|
||||
const QSizeF constraint( width, -1 );
|
||||
|
||||
for ( const auto& item : qskAsConst( m_data->items ) )
|
||||
{
|
||||
if ( constraintType( item ) == HeightForWidth )
|
||||
{
|
||||
const QSizeF hint = QskLayoutConstraint::sizeHint(
|
||||
item, Qt::PreferredSize, constraint );
|
||||
const auto sizePolicy = qskSizePolicy( item );
|
||||
|
||||
height = qMax( height, hint.height() );
|
||||
if ( sizePolicy.constraintType() == QskSizePolicy::HeightForWidth )
|
||||
{
|
||||
const auto hint = qskSizeConstraint( item, which, constraint );
|
||||
height = QskLayoutHint::combined( which, height, hint.height() );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return QSizeF( width, height );
|
||||
}
|
||||
|
||||
qreal QskStackBox::heightForWidth( qreal width ) const
|
||||
{
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::HeightForWidth, this, width, qskConstrainedValue );
|
||||
}
|
||||
|
||||
qreal QskStackBox::widthForHeight( qreal height ) const
|
||||
{
|
||||
return QskLayoutConstraint::constrainedMetric(
|
||||
QskLayoutConstraint::WidthForHeight, this, height, qskConstrainedValue );
|
||||
}
|
||||
|
||||
bool QskStackBox::event( QEvent* event )
|
||||
{
|
||||
switch ( static_cast< int >( event->type() ) )
|
||||
|
@ -51,9 +51,6 @@ class QSK_EXPORT QskStackBox : public QskIndexedLayoutBox
|
||||
const QskStackBoxAnimator* animator() const;
|
||||
QskStackBoxAnimator* animator();
|
||||
|
||||
qreal heightForWidth( qreal width ) const override;
|
||||
qreal widthForHeight( qreal height ) const override;
|
||||
|
||||
QRectF geometryForItemAt( int index ) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -72,7 +69,7 @@ class QSK_EXPORT QskStackBox : public QskIndexedLayoutBox
|
||||
bool event( QEvent* ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
QSizeF contentsSizeHint() const override;
|
||||
QSizeF layoutSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
void autoAddItem( QQuickItem* ) override final;
|
||||
void autoRemoveItem( QQuickItem* ) override final;
|
||||
|
@ -243,7 +243,6 @@ HEADERS += \
|
||||
layouts/QskGridBox.h \
|
||||
layouts/QskGridLayoutEngine.h \
|
||||
layouts/QskIndexedLayoutBox.h \
|
||||
layouts/QskLayoutConstraint.h \
|
||||
layouts/QskLayoutChain.h \
|
||||
layouts/QskLayoutEngine2D.cpp \
|
||||
layouts/QskLayoutHint.h \
|
||||
@ -257,7 +256,6 @@ SOURCES += \
|
||||
layouts/QskGridLayoutEngine.cpp \
|
||||
layouts/QskIndexedLayoutBox.cpp \
|
||||
layouts/QskLayoutChain.cpp \
|
||||
layouts/QskLayoutConstraint.cpp \
|
||||
layouts/QskLayoutEngine2D.cpp \
|
||||
layouts/QskLayoutHint.cpp \
|
||||
layouts/QskLinearBox.cpp \
|
||||
|
Loading…
x
Reference in New Issue
Block a user