non dynamic size constraints do work for simple use cases
This commit is contained in:
parent
a655c96c8b
commit
a7e30c2550
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <QskEvent.h>
|
||||
#include <QskQuick.h>
|
||||
#include <QskLayoutHint.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -20,6 +21,15 @@ static inline Qt::Orientation qskOrientation( int edge )
|
|||
return ( edge <= Qt::AnchorRight ) ? Qt::Horizontal : Qt::Vertical;
|
||||
}
|
||||
|
||||
static inline Qt::AnchorPoint qskAnchorPoint(
|
||||
Qt::Corner corner, Qt::Orientation orientation )
|
||||
{
|
||||
if ( orientation == Qt::Horizontal )
|
||||
return ( corner & 0x1 ) ? Qt::AnchorRight : Qt::AnchorLeft;
|
||||
else
|
||||
return ( corner >= 0x2 ) ? Qt::AnchorBottom : Qt::AnchorTop;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class Geometry
|
||||
|
@ -51,17 +61,23 @@ namespace
|
|||
return Expression();
|
||||
}
|
||||
|
||||
Expression length( Qt::Orientation orientation )
|
||||
inline Expression length( Qt::Orientation orientation )
|
||||
{
|
||||
return ( orientation == Qt::Horizontal ) ? width() : height();
|
||||
}
|
||||
|
||||
QRectF rect() const
|
||||
inline QRectF rect() const
|
||||
{
|
||||
return QRectF( m_left.value(), m_top.value(),
|
||||
m_right.value() - m_left.value(), m_bottom.value() - m_top.value() );
|
||||
}
|
||||
|
||||
inline QSizeF size() const
|
||||
{
|
||||
return QSizeF( m_right.value() - m_left.value(),
|
||||
m_bottom.value() - m_top.value() );
|
||||
}
|
||||
|
||||
inline Expression width() const { return m_right - m_left; }
|
||||
inline Expression height() const { return m_bottom - m_top; }
|
||||
|
||||
|
@ -91,12 +107,10 @@ namespace
|
|||
class AnchorBox::PrivateData
|
||||
{
|
||||
public:
|
||||
void setupSolver( Solver& );
|
||||
void setItemGeometries( const AnchorBox*, const QRectF& );
|
||||
|
||||
private:
|
||||
void setupAnchorConstraints( Solver& );
|
||||
void setupSizeConstraints( Solver& );
|
||||
void setupSizeConstraints( const AnchorBox*, bool, Solver& );
|
||||
|
||||
public:
|
||||
QMap< QQuickItem*, Geometry > geometries;
|
||||
|
@ -132,11 +146,15 @@ void AnchorBox::PrivateData::setupAnchorConstraints( Solver& solver )
|
|||
}
|
||||
}
|
||||
|
||||
void AnchorBox::PrivateData::setupSizeConstraints( Solver& solver )
|
||||
void AnchorBox::PrivateData::setupSizeConstraints(
|
||||
const AnchorBox* box, bool preferred, Solver& solver )
|
||||
{
|
||||
for ( auto it = geometries.begin(); it != geometries.end(); ++it )
|
||||
{
|
||||
const auto item = it.key();
|
||||
if ( item == box )
|
||||
continue;
|
||||
|
||||
auto& r = it.value();
|
||||
|
||||
{
|
||||
|
@ -150,6 +168,7 @@ void AnchorBox::PrivateData::setupSizeConstraints( Solver& solver )
|
|||
solver.addConstraint( r.bottom() >= r.top() + minSize.height() );
|
||||
}
|
||||
|
||||
if ( preferred )
|
||||
{
|
||||
// preferred size
|
||||
const auto prefSize = qskSizeConstraint( item, Qt::PreferredSize );
|
||||
|
@ -173,17 +192,13 @@ void AnchorBox::PrivateData::setupSizeConstraints( Solver& solver )
|
|||
}
|
||||
}
|
||||
|
||||
void AnchorBox::PrivateData::setupSolver( Solver& solver )
|
||||
{
|
||||
setupAnchorConstraints( solver );
|
||||
setupSizeConstraints( solver );
|
||||
}
|
||||
|
||||
void AnchorBox::PrivateData::setItemGeometries(
|
||||
const AnchorBox* box, const QRectF& rect )
|
||||
{
|
||||
// Unefficient as we are always starting from scratch TODO ...
|
||||
Solver solver;
|
||||
setupSolver( solver );
|
||||
setupAnchorConstraints( solver );
|
||||
setupSizeConstraints( box, true, solver );
|
||||
|
||||
const auto& r0 = geometries[ const_cast< AnchorBox* >( box ) ];
|
||||
|
||||
|
@ -215,6 +230,41 @@ AnchorBox::~AnchorBox()
|
|||
{
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchors( QQuickItem* item, Qt::Orientations orientations )
|
||||
{
|
||||
addAnchors( item, this, orientations );
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchors( QQuickItem* item1,
|
||||
QQuickItem* item2, Qt::Orientations orientations )
|
||||
{
|
||||
if ( orientations & Qt::Horizontal )
|
||||
{
|
||||
addAnchor( item1, Qt::AnchorLeft, item2, Qt::AnchorLeft );
|
||||
addAnchor( item1, Qt::AnchorRight, item2, Qt::AnchorRight );
|
||||
}
|
||||
if ( orientations & Qt::Vertical )
|
||||
{
|
||||
addAnchor( item1, Qt::AnchorTop, item2, Qt::AnchorTop );
|
||||
addAnchor( item1, Qt::AnchorBottom, item2, Qt::AnchorBottom );
|
||||
}
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchors( QQuickItem* item, Qt::Corner corner )
|
||||
{
|
||||
addAnchors( item, corner, this, corner );
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchors( QQuickItem* item1,
|
||||
Qt::Corner corner1, QQuickItem* item2, Qt::Corner corner2 )
|
||||
{
|
||||
addAnchor( item1, qskAnchorPoint( corner1, Qt::Horizontal ),
|
||||
item2, qskAnchorPoint( corner2, Qt::Horizontal ) );
|
||||
|
||||
addAnchor( item1, qskAnchorPoint( corner1, Qt::Vertical ),
|
||||
item2, qskAnchorPoint( corner2, Qt::Vertical ) );
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchor( QQuickItem* item,
|
||||
Qt::AnchorPoint edge1, Qt::AnchorPoint edge2 )
|
||||
{
|
||||
|
@ -257,9 +307,32 @@ void AnchorBox::addAnchor( QQuickItem* item1, Qt::AnchorPoint edge1,
|
|||
m_data->anchors += anchor;
|
||||
}
|
||||
|
||||
QSizeF AnchorBox::layoutSizeHint( Qt::SizeHint, const QSizeF& ) const
|
||||
QSizeF AnchorBox::layoutSizeHint( Qt::SizeHint which, const QSizeF& constraint ) const
|
||||
{
|
||||
return QSizeF();
|
||||
if ( constraint.width() >= 0.0 || constraint.height() >= 0.0 )
|
||||
{
|
||||
// TODO ...
|
||||
return QSizeF();
|
||||
}
|
||||
|
||||
const auto& r0 = m_data->geometries[ const_cast< AnchorBox* >( this ) ];
|
||||
|
||||
Solver solver;
|
||||
m_data->setupAnchorConstraints( solver );
|
||||
m_data->setupSizeConstraints( this, which == Qt::PreferredSize, solver );
|
||||
|
||||
if ( which != Qt::PreferredSize )
|
||||
{
|
||||
const qreal b = ( which == Qt::MinimumSize ) ? 0.0 : QskLayoutHint::unlimited;
|
||||
|
||||
// why do we need strong here ?
|
||||
solver.addConstraint( Constraint( r0.width() == b, Strength::strong ) );
|
||||
solver.addConstraint( Constraint( r0.height() == b, Strength::strong ) );
|
||||
}
|
||||
|
||||
solver.updateVariables();
|
||||
|
||||
return r0.size();
|
||||
}
|
||||
|
||||
void AnchorBox::geometryChangeEvent( QskGeometryChangeEvent* event )
|
||||
|
|
|
@ -18,8 +18,16 @@ class AnchorBox : public QskControl
|
|||
AnchorBox( QQuickItem* parent = nullptr );
|
||||
~AnchorBox() override;
|
||||
|
||||
// anchoring to the box
|
||||
void addAnchor( QQuickItem*, Qt::AnchorPoint, Qt::AnchorPoint );
|
||||
void addAnchors( QQuickItem*, Qt::Corner );
|
||||
void addAnchors( QQuickItem*, Qt::Orientations = Qt::Horizontal | Qt::Vertical );
|
||||
|
||||
// anchoring between 2 children
|
||||
void addAnchor( QQuickItem*, Qt::AnchorPoint, QQuickItem*, Qt::AnchorPoint );
|
||||
void addAnchors( QQuickItem*, Qt::Corner, QQuickItem*, Qt::Corner );
|
||||
void addAnchors( QQuickItem*, QQuickItem*,
|
||||
Qt::Orientations = Qt::Horizontal | Qt::Vertical );
|
||||
|
||||
protected:
|
||||
void geometryChangeEvent( QskGeometryChangeEvent* ) override;
|
||||
|
|
|
@ -54,7 +54,6 @@ class MyBox : public AnchorBox
|
|||
: AnchorBox( parent )
|
||||
{
|
||||
setObjectName( "Box" );
|
||||
|
||||
setup1();
|
||||
}
|
||||
|
||||
|
@ -115,27 +114,11 @@ void MyBox::setup1()
|
|||
void MyBox::setup2()
|
||||
{
|
||||
auto a = new TestRectangle( "PaleVioletRed" );
|
||||
auto b = new TestRectangle( "DarkSeaGreen" );
|
||||
|
||||
addAnchor( a, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( a, Qt::AnchorTop, Qt::AnchorTop );
|
||||
|
||||
|
||||
#if 0
|
||||
auto b = new Rectangle( "DarkSeaGreen" );
|
||||
addAnchor( a, Qt::AnchorRight, b, Qt::AnchorLeft );
|
||||
addAnchor( b, Qt::AnchorRight, m_layout, Qt::AnchorRight );
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
auto c = new TestRectangle( "SkyBlue" );
|
||||
addAnchor( a, Qt::AnchorBottom, c, Qt::AnchorTop );
|
||||
addAnchor( a, Qt::AnchorRight, c, Qt::AnchorRight );
|
||||
|
||||
auto d = new TestRectangle( "Coral" );
|
||||
addAnchor( c, Qt::AnchorLeft, d, Qt::AnchorLeft );
|
||||
addAnchor( c, Qt::AnchorBottom, d, Qt::AnchorTop );
|
||||
addAnchor( d, Qt::AnchorRight, Qt::AnchorRight );
|
||||
#endif
|
||||
addAnchors( a, Qt::TopLeftCorner );
|
||||
addAnchors( a, Qt::BottomRightCorner, b, Qt::TopLeftCorner );
|
||||
addAnchors( b, Qt::BottomRightCorner );
|
||||
}
|
||||
|
||||
void MyBox::setup3()
|
||||
|
@ -175,6 +158,14 @@ int main( int argc, char* argv[] )
|
|||
|
||||
auto box = new MyBox();
|
||||
|
||||
#if 1
|
||||
for ( int i = Qt::MinimumSize; i <= Qt::MaximumSize; i++ )
|
||||
{
|
||||
const auto which = static_cast< Qt::SizeHint >( i );
|
||||
qDebug() << which << box->effectiveSizeHint( which );
|
||||
}
|
||||
#endif
|
||||
|
||||
QskWindow window;
|
||||
window.addItem( box );
|
||||
window.resize( 600, 600 );
|
||||
|
|
Loading…
Reference in New Issue