playing with constraint based layouting
This commit is contained in:
parent
bebdd80c9e
commit
35b98e4b69
256
playground/anchors/AnchorBox.cpp
Normal file
256
playground/anchors/AnchorBox.cpp
Normal file
@ -0,0 +1,256 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#include "AnchorBox.h"
|
||||
|
||||
#include "Solver.h"
|
||||
#include "Constraint.h"
|
||||
#include "Variable.h"
|
||||
#include "Expression.h"
|
||||
|
||||
#include <QskLayoutConstraint.h>
|
||||
#include <QskEvent.h>
|
||||
#include <QskQuick.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
static inline Qt::Orientation qskOrientation( int edge )
|
||||
{
|
||||
return ( edge <= Qt::AnchorRight ) ? Qt::Horizontal : Qt::Vertical;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class Geometry
|
||||
{
|
||||
public:
|
||||
Expression expressionAt( int anchorPoint )
|
||||
{
|
||||
switch( anchorPoint )
|
||||
{
|
||||
case Qt::AnchorLeft:
|
||||
return Term( left );
|
||||
|
||||
case Qt::AnchorHorizontalCenter:
|
||||
return centerH();
|
||||
|
||||
case Qt::AnchorRight:
|
||||
return Term( right );
|
||||
|
||||
case Qt::AnchorTop:
|
||||
return Term( top );
|
||||
|
||||
case Qt::AnchorVerticalCenter:
|
||||
return centerV();
|
||||
|
||||
case Qt::AnchorBottom:
|
||||
return Term( bottom );
|
||||
}
|
||||
|
||||
return Expression();
|
||||
}
|
||||
|
||||
Expression length( Qt::Orientation orientation )
|
||||
{
|
||||
return ( orientation == Qt::Horizontal ) ? width() : height();
|
||||
}
|
||||
|
||||
QRectF rect() const
|
||||
{
|
||||
return QRectF( left.value(), top.value(),
|
||||
right.value() - left.value(), bottom.value() - top.value() );
|
||||
}
|
||||
|
||||
Expression width() const { return right - left; }
|
||||
Expression height() const { return bottom - top; }
|
||||
|
||||
Expression centerH() const { return left + 0.5 * width(); }
|
||||
Expression centerV() const { return top + 0.5 * height(); }
|
||||
|
||||
Variable left, right, top, bottom;
|
||||
};
|
||||
|
||||
class Anchor
|
||||
{
|
||||
public:
|
||||
QQuickItem* item1 = nullptr;
|
||||
Qt::AnchorPoint edge1;
|
||||
|
||||
QQuickItem* item2 = nullptr;
|
||||
Qt::AnchorPoint edge2;
|
||||
};
|
||||
}
|
||||
|
||||
class AnchorBox::PrivateData
|
||||
{
|
||||
public:
|
||||
void setupSolver( int type, Solver& );
|
||||
|
||||
QMap< QQuickItem*, Geometry > geometries;
|
||||
QVector< Anchor > anchors;
|
||||
};
|
||||
|
||||
void AnchorBox::PrivateData::setupSolver( int type, Solver& solver )
|
||||
{
|
||||
for ( const auto& anchor : anchors )
|
||||
{
|
||||
auto& r1 = geometries[ anchor.item1 ];
|
||||
auto& r2 = geometries[ anchor.item2 ];
|
||||
|
||||
solver.addConstraint( r1.expressionAt( anchor.edge1 )
|
||||
== r2.expressionAt( anchor.edge2 ) );
|
||||
|
||||
#if 1
|
||||
if ( type < 0 )
|
||||
{
|
||||
const auto s1 = 1.0;
|
||||
const auto s2 = 1.0;
|
||||
const auto o = qskOrientation( anchor.edge1 );
|
||||
|
||||
Constraint c( r1.length( o ) * s1 == r2.length( o ) * s2, Strength::medium );
|
||||
solver.addConstraint( c );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for ( auto it = geometries.begin(); it != geometries.end(); ++it )
|
||||
{
|
||||
const auto item = it.key();
|
||||
auto& r = it.value();
|
||||
|
||||
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() );
|
||||
}
|
||||
|
||||
if ( type < 0 || type == Qt::PreferredSize )
|
||||
{
|
||||
const auto prefSize = QskLayoutConstraint::sizeHint( item, Qt::PreferredSize );
|
||||
|
||||
Constraint c1( r.right == r.left + prefSize.width(), Strength::strong );
|
||||
solver.addConstraint( c1 );
|
||||
|
||||
Constraint c2( r.bottom == r.top + prefSize.height(), Strength::strong );
|
||||
solver.addConstraint( c2 );
|
||||
}
|
||||
|
||||
if ( type < 0 || type == Qt::MaximumSize )
|
||||
{
|
||||
const auto maxSize = QskLayoutConstraint::sizeHint( item, Qt::MaximumSize );
|
||||
if ( maxSize.width() < QskLayoutConstraint::unlimited )
|
||||
solver.addConstraint( r.right <= r.left + maxSize.width() );
|
||||
|
||||
if ( maxSize.height() < QskLayoutConstraint::unlimited )
|
||||
solver.addConstraint( r.bottom <= r.top + maxSize.height() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnchorBox::AnchorBox( QQuickItem* parent )
|
||||
: QskControl( parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
(void)m_data->geometries[ this ];
|
||||
}
|
||||
|
||||
AnchorBox::~AnchorBox()
|
||||
{
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchor( QQuickItem* item,
|
||||
Qt::AnchorPoint edge1, Qt::AnchorPoint edge2 )
|
||||
{
|
||||
addAnchor( item, edge1, this, edge2 );
|
||||
}
|
||||
|
||||
void AnchorBox::addAnchor( QQuickItem* item1, Qt::AnchorPoint edge1,
|
||||
QQuickItem* item2, Qt::AnchorPoint edge2 )
|
||||
{
|
||||
if ( item1 == item2 || item1 == nullptr || item2 == nullptr )
|
||||
return;
|
||||
|
||||
if ( item1 != this )
|
||||
{
|
||||
if ( item1->parent() == nullptr )
|
||||
item1->setParent( this );
|
||||
|
||||
if ( item1->parentItem() != this )
|
||||
item1->setParentItem( this );
|
||||
}
|
||||
|
||||
if ( item2 != this )
|
||||
{
|
||||
if ( item2->parent() == nullptr )
|
||||
item2->setParent( this );
|
||||
|
||||
if ( item2->parentItem() != this )
|
||||
item2->setParentItem( this );
|
||||
}
|
||||
|
||||
(void)m_data->geometries[ item1 ];
|
||||
(void)m_data->geometries[ item2 ];
|
||||
|
||||
Anchor anchor;
|
||||
anchor.item1 = item1;
|
||||
anchor.edge1 = edge1;
|
||||
anchor.item2 = item2;
|
||||
anchor.edge2 = edge2;
|
||||
|
||||
m_data->anchors += anchor;
|
||||
}
|
||||
|
||||
QSizeF AnchorBox::boxHint( Qt::SizeHint which )
|
||||
{
|
||||
Solver solver;
|
||||
m_data->setupSolver( which, solver );
|
||||
solver.updateVariables();
|
||||
|
||||
auto& r0 = m_data->geometries[ this ];
|
||||
|
||||
return QSizeF( r0.rect().size() );
|
||||
}
|
||||
|
||||
void AnchorBox::setItemGeometries( const QRectF& rect )
|
||||
{
|
||||
Solver solver;
|
||||
m_data->setupSolver( -1, solver );
|
||||
|
||||
auto& r0 = m_data->geometries[ this ];
|
||||
|
||||
solver.addConstraint( r0.left == rect.left() );
|
||||
solver.addConstraint( r0.right == rect.right() );
|
||||
solver.addConstraint( r0.top == rect.top() );
|
||||
solver.addConstraint( r0.bottom == rect.bottom() );
|
||||
|
||||
solver.updateVariables();
|
||||
|
||||
const auto& geometries = m_data->geometries;
|
||||
for ( auto it = geometries.begin(); it != geometries.end(); ++it )
|
||||
qskSetItemGeometry( it.key(), it.value().rect() );
|
||||
|
||||
#if 0
|
||||
qDebug() << "=== Rect:" << rect;
|
||||
for ( auto it = geometries.begin(); it != geometries.end(); ++it )
|
||||
qDebug() << it.key()->objectName() << it.value().rect();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AnchorBox::geometryChangeEvent( QskGeometryChangeEvent* event )
|
||||
{
|
||||
Inherited::geometryChangeEvent( event );
|
||||
|
||||
if ( event->isResized() )
|
||||
polish();
|
||||
}
|
||||
|
||||
void AnchorBox::updateLayout()
|
||||
{
|
||||
if ( !maybeUnresized() )
|
||||
setItemGeometries( layoutRect() );
|
||||
}
|
||||
|
||||
#include "moc_AnchorBox.cpp"
|
38
playground/anchors/AnchorBox.h
Normal file
38
playground/anchors/AnchorBox.h
Normal file
@ -0,0 +1,38 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the QSkinny License, Version 1.0
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef ANCHOR_BOX_H
|
||||
#define ANCHOR_BOX_H
|
||||
|
||||
#include "QskControl.h"
|
||||
|
||||
class AnchorBox : public QskControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using Inherited = QskControl;
|
||||
|
||||
public:
|
||||
AnchorBox( QQuickItem* parent = nullptr );
|
||||
~AnchorBox() override;
|
||||
|
||||
void addAnchor( QQuickItem*, Qt::AnchorPoint, Qt::AnchorPoint );
|
||||
void addAnchor( QQuickItem*, Qt::AnchorPoint, QQuickItem*, Qt::AnchorPoint );
|
||||
|
||||
QSizeF boxHint( Qt::SizeHint );
|
||||
|
||||
protected:
|
||||
void geometryChangeEvent( QskGeometryChangeEvent* ) override;
|
||||
void updateLayout() override;
|
||||
|
||||
private:
|
||||
void setItemGeometries( const QRectF& );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
285
playground/anchors/Constraint.cpp
Normal file
285
playground/anchors/Constraint.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
#include "Constraint.h"
|
||||
#include "Expression.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
static Expression reduce( const Expression& expr )
|
||||
{
|
||||
std::map< Variable, double > vars;
|
||||
|
||||
for ( auto term : expr.terms() )
|
||||
vars[ term.variable() ] += term.coefficient();
|
||||
|
||||
const std::vector< Term > terms( vars.begin(), vars.end() );
|
||||
return Expression( terms, expr.constant() );
|
||||
}
|
||||
|
||||
class Constraint::Data
|
||||
{
|
||||
public:
|
||||
Data( const Expression& expr, RelationalOperator op, double strength )
|
||||
: expression( reduce( expr ) )
|
||||
, strength( Strength::clip( strength ) )
|
||||
, op( op )
|
||||
{
|
||||
}
|
||||
|
||||
Expression expression;
|
||||
double strength;
|
||||
RelationalOperator op;
|
||||
};
|
||||
|
||||
|
||||
Constraint::Constraint( const Expression& expr, RelationalOperator op, double strength )
|
||||
: m_data( std::make_shared< Data >( expr, op, strength ) )
|
||||
{
|
||||
}
|
||||
|
||||
Constraint::Constraint( const Constraint& other, double strength )
|
||||
: Constraint( other.expression(), other.oper(), strength )
|
||||
{
|
||||
}
|
||||
|
||||
Constraint::~Constraint()
|
||||
{
|
||||
}
|
||||
|
||||
const Expression& Constraint::expression() const
|
||||
{
|
||||
return m_data->expression;
|
||||
}
|
||||
|
||||
RelationalOperator Constraint::oper() const
|
||||
{
|
||||
return m_data->op;
|
||||
}
|
||||
|
||||
double Constraint::strength() const
|
||||
{
|
||||
return m_data->strength;
|
||||
}
|
||||
|
||||
Constraint operator==( const Expression& first, const Expression& second )
|
||||
{
|
||||
return Constraint( first - second, OP_EQ );
|
||||
}
|
||||
|
||||
Constraint operator==( const Expression& expression, const Term& term )
|
||||
{
|
||||
return expression == Expression( term );
|
||||
}
|
||||
|
||||
Constraint operator==( const Expression& expression, const Variable& variable )
|
||||
{
|
||||
return expression == Term( variable );
|
||||
}
|
||||
|
||||
Constraint operator==( const Expression& expression, double constant )
|
||||
{
|
||||
return expression == Expression( constant );
|
||||
}
|
||||
|
||||
Constraint operator<=( const Expression& first, const Expression& second )
|
||||
{
|
||||
return Constraint( first - second, OP_LE );
|
||||
}
|
||||
|
||||
Constraint operator<=( const Expression& expression, const Term& term )
|
||||
{
|
||||
return expression <= Expression( term );
|
||||
}
|
||||
|
||||
Constraint operator<=( const Expression& expression, const Variable& variable )
|
||||
{
|
||||
return expression <= Term( variable );
|
||||
}
|
||||
|
||||
Constraint operator<=( const Expression& expression, double constant )
|
||||
{
|
||||
return expression <= Expression( constant );
|
||||
}
|
||||
|
||||
Constraint operator>=( const Expression& first, const Expression& second )
|
||||
{
|
||||
return Constraint( first - second, OP_GE );
|
||||
}
|
||||
|
||||
Constraint operator>=( const Expression& expression, const Term& term )
|
||||
{
|
||||
return expression >= Expression( term );
|
||||
}
|
||||
|
||||
Constraint operator>=( const Expression& expression, const Variable& variable )
|
||||
{
|
||||
return expression >= Term( variable );
|
||||
}
|
||||
|
||||
Constraint operator>=( const Expression& expression, double constant )
|
||||
{
|
||||
return expression >= Expression( constant );
|
||||
}
|
||||
|
||||
Constraint operator==( const Term& term, const Expression& expression )
|
||||
{
|
||||
return expression == term;
|
||||
}
|
||||
|
||||
Constraint operator==( const Term& first, const Term& second )
|
||||
{
|
||||
return Expression( first ) == second;
|
||||
}
|
||||
|
||||
Constraint operator==( const Term& term, const Variable& variable )
|
||||
{
|
||||
return Expression( term ) == variable;
|
||||
}
|
||||
|
||||
Constraint operator==( const Term& term, double constant )
|
||||
{
|
||||
return Expression( term ) == constant;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Term& term, const Expression& expression )
|
||||
{
|
||||
return expression >= term;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Term& first, const Term& second )
|
||||
{
|
||||
return Expression( first ) <= second;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Term& term, const Variable& variable )
|
||||
{
|
||||
return Expression( term ) <= variable;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Term& term, double constant )
|
||||
{
|
||||
return Expression( term ) <= constant;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Term& term, const Expression& expression )
|
||||
{
|
||||
return expression <= term;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Term& first, const Term& second )
|
||||
{
|
||||
return Expression( first ) >= second;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Term& term, const Variable& variable )
|
||||
{
|
||||
return Expression( term ) >= variable;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Term& term, double constant )
|
||||
{
|
||||
return Expression( term ) >= constant;
|
||||
}
|
||||
|
||||
Constraint operator==( const Variable& variable, const Expression& expression )
|
||||
{
|
||||
return expression == variable;
|
||||
}
|
||||
|
||||
Constraint operator==( const Variable& variable, const Term& term )
|
||||
{
|
||||
return term == variable;
|
||||
}
|
||||
|
||||
Constraint operator==( const Variable& first, const Variable& second )
|
||||
{
|
||||
return Term( first ) == second;
|
||||
}
|
||||
|
||||
Constraint operator==( const Variable& variable, double constant )
|
||||
{
|
||||
return Term( variable ) == constant;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Variable& variable, const Expression& expression )
|
||||
{
|
||||
return expression >= variable;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Variable& variable, const Term& term )
|
||||
{
|
||||
return term >= variable;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Variable& first, const Variable& second )
|
||||
{
|
||||
return Term( first ) <= second;
|
||||
}
|
||||
|
||||
Constraint operator<=( const Variable& variable, double constant )
|
||||
{
|
||||
return Term( variable ) <= constant;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Variable& variable, const Expression& expression )
|
||||
{
|
||||
return expression <= variable;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Variable& variable, const Term& term )
|
||||
{
|
||||
return term <= variable;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Variable& first, const Variable& second )
|
||||
{
|
||||
return Term( first ) >= second;
|
||||
}
|
||||
|
||||
Constraint operator>=( const Variable& variable, double constant )
|
||||
{
|
||||
return Term( variable ) >= constant;
|
||||
}
|
||||
|
||||
Constraint operator==( double constant, const Expression& expression )
|
||||
{
|
||||
return expression == constant;
|
||||
}
|
||||
|
||||
Constraint operator==( double constant, const Term& term )
|
||||
{
|
||||
return term == constant;
|
||||
}
|
||||
|
||||
Constraint operator==( double constant, const Variable& variable )
|
||||
{
|
||||
return variable == constant;
|
||||
}
|
||||
|
||||
Constraint operator<=( double constant, const Expression& expression )
|
||||
{
|
||||
return expression >= constant;
|
||||
}
|
||||
|
||||
Constraint operator<=( double constant, const Term& term )
|
||||
{
|
||||
return term >= constant;
|
||||
}
|
||||
|
||||
Constraint operator<=( double constant, const Variable& variable )
|
||||
{
|
||||
return variable >= constant;
|
||||
}
|
||||
|
||||
Constraint operator>=( double constant, const Expression& expression )
|
||||
{
|
||||
return expression <= constant;
|
||||
}
|
||||
|
||||
Constraint operator>=( double constant, const Term& term )
|
||||
{
|
||||
return term <= constant;
|
||||
}
|
||||
|
||||
Constraint operator>=( double constant, const Variable& variable )
|
||||
{
|
||||
return variable <= constant;
|
||||
}
|
117
playground/anchors/Constraint.h
Normal file
117
playground/anchors/Constraint.h
Normal file
@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
|
||||
#include "Strength.h"
|
||||
#include <memory>
|
||||
|
||||
class Expression;
|
||||
class Variable;
|
||||
class Term;
|
||||
|
||||
enum RelationalOperator { OP_LE, OP_GE, OP_EQ };
|
||||
|
||||
class Constraint
|
||||
{
|
||||
public:
|
||||
|
||||
Constraint() = default;
|
||||
|
||||
Constraint( const Expression&, RelationalOperator,
|
||||
double strength = Strength::required );
|
||||
|
||||
Constraint( const Constraint&, double strength );
|
||||
|
||||
~Constraint();
|
||||
|
||||
const Expression& expression() const;
|
||||
RelationalOperator oper() const;
|
||||
double strength() const;
|
||||
|
||||
bool operator!() const { return !m_data; }
|
||||
|
||||
private:
|
||||
class Data;
|
||||
std::shared_ptr< Data > m_data;
|
||||
|
||||
friend bool operator<( const Constraint&, const Constraint& );
|
||||
friend bool operator==( const Constraint&, const Constraint& );
|
||||
friend bool operator!=( const Constraint&, const Constraint& );
|
||||
};
|
||||
|
||||
inline bool operator<( const Constraint& lhs, const Constraint& rhs )
|
||||
{
|
||||
return lhs.m_data < rhs.m_data;
|
||||
}
|
||||
|
||||
inline bool operator==( const Constraint& lhs, const Constraint& rhs )
|
||||
{
|
||||
return lhs.m_data == rhs.m_data;
|
||||
}
|
||||
|
||||
inline bool operator!=( const Constraint& lhs, const Constraint& rhs )
|
||||
{
|
||||
return lhs.m_data != rhs.m_data;
|
||||
}
|
||||
|
||||
inline Constraint operator|( const Constraint& constraint, double strength )
|
||||
{
|
||||
return Constraint( constraint, strength );
|
||||
}
|
||||
|
||||
inline Constraint operator|( double strength, const Constraint& constraint )
|
||||
{
|
||||
return constraint | strength;
|
||||
}
|
||||
|
||||
extern Constraint operator==( const Expression&, const Expression& );
|
||||
extern Constraint operator<=( const Expression&, const Expression& );
|
||||
extern Constraint operator>=( const Expression&, const Expression& );
|
||||
|
||||
extern Constraint operator==( const Expression&, const Term& );
|
||||
extern Constraint operator<=( const Expression&, const Term& );
|
||||
extern Constraint operator>=( const Expression&, const Term& );
|
||||
extern Constraint operator==( const Term&, const Expression& );
|
||||
extern Constraint operator<=( const Term&, const Expression& );
|
||||
extern Constraint operator>=( const Term&, const Expression& );
|
||||
|
||||
extern Constraint operator==( const Expression&, const Variable& );
|
||||
extern Constraint operator<=( const Expression&, const Variable& );
|
||||
extern Constraint operator>=( const Expression&, const Variable& );
|
||||
extern Constraint operator==( const Variable&, const Expression& );
|
||||
extern Constraint operator<=( const Variable&, const Expression& );
|
||||
extern Constraint operator>=( const Variable&, const Expression& );
|
||||
|
||||
extern Constraint operator==( const Expression&, double );
|
||||
extern Constraint operator<=( const Expression&, double );
|
||||
extern Constraint operator>=( const Expression&, double );
|
||||
extern Constraint operator==( double, const Expression& );
|
||||
extern Constraint operator<=( double, const Expression& );
|
||||
extern Constraint operator>=( double, const Expression& );
|
||||
|
||||
extern Constraint operator==( const Term&, const Term& );
|
||||
extern Constraint operator<=( const Term&, const Term& );
|
||||
extern Constraint operator>=( const Term&, const Term& );
|
||||
|
||||
extern Constraint operator==( const Term&, const Variable& );
|
||||
extern Constraint operator<=( const Term&, const Variable& );
|
||||
extern Constraint operator>=( const Term&, const Variable& );
|
||||
extern Constraint operator==( const Variable&, const Term& );
|
||||
extern Constraint operator<=( const Variable&, const Term& );
|
||||
extern Constraint operator>=( const Variable&, const Term& );
|
||||
|
||||
extern Constraint operator==( const Term&, double );
|
||||
extern Constraint operator<=( const Term&, double );
|
||||
extern Constraint operator>=( const Term&, double );
|
||||
extern Constraint operator==( double, const Term& );
|
||||
extern Constraint operator<=( double, const Term& );
|
||||
extern Constraint operator>=( double, const Term& );
|
||||
|
||||
extern Constraint operator==( const Variable&, const Variable& );
|
||||
extern Constraint operator<=( const Variable&, const Variable& );
|
||||
extern Constraint operator>=( const Variable&, const Variable& );
|
||||
|
||||
extern Constraint operator==( const Variable&, double );
|
||||
extern Constraint operator<=( const Variable&, double );
|
||||
extern Constraint operator>=( const Variable&, double );
|
||||
extern Constraint operator==( double, const Variable& );
|
||||
extern Constraint operator<=( double, const Variable& );
|
||||
extern Constraint operator>=( double, const Variable& );
|
226
playground/anchors/Expression.cpp
Normal file
226
playground/anchors/Expression.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "Expression.h"
|
||||
#include "Term.h"
|
||||
|
||||
Expression::Expression( double constant )
|
||||
: m_constant( constant )
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Expression( const Term& term, double constant )
|
||||
: m_terms( 1, term )
|
||||
, m_constant( constant )
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Expression( const std::vector< Term >&& terms, double constant )
|
||||
: m_terms( std::move( terms ) )
|
||||
, m_constant( constant )
|
||||
{
|
||||
}
|
||||
|
||||
Expression::Expression( const std::vector< Term >& terms, double constant )
|
||||
: m_terms( terms )
|
||||
, m_constant( constant )
|
||||
{
|
||||
}
|
||||
|
||||
double Expression::value() const
|
||||
{
|
||||
double result = m_constant;
|
||||
|
||||
for ( const auto& term : m_terms )
|
||||
result += term.value();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Expression operator*( const Expression& expression, double coefficient )
|
||||
{
|
||||
std::vector< Term > terms;
|
||||
terms.reserve( expression.terms().size() );
|
||||
|
||||
for ( const auto& term : expression.terms() )
|
||||
terms.push_back( term * coefficient );
|
||||
|
||||
return Expression( std::move( terms ), expression.constant() * coefficient );
|
||||
}
|
||||
|
||||
Expression operator/( const Expression& expression, double denominator )
|
||||
{
|
||||
return expression * ( 1.0 / denominator );
|
||||
}
|
||||
|
||||
Expression operator-( const Expression& expression )
|
||||
{
|
||||
return expression * -1.0;
|
||||
}
|
||||
|
||||
Expression operator*( double coefficient, const Expression& expression )
|
||||
{
|
||||
return expression * coefficient;
|
||||
}
|
||||
|
||||
Expression operator+( const Expression& first, const Expression& second )
|
||||
{
|
||||
std::vector< Term > terms;
|
||||
terms.reserve( first.terms().size() + second.terms().size() );
|
||||
terms.insert( terms.begin(), first.terms().begin(), first.terms().end() );
|
||||
terms.insert( terms.end(), second.terms().begin(), second.terms().end() );
|
||||
|
||||
return Expression( std::move( terms ), first.constant() + second.constant() );
|
||||
}
|
||||
|
||||
Expression operator+( const Expression& expression, const Term& term )
|
||||
{
|
||||
std::vector< Term > terms;
|
||||
terms.reserve( expression.terms().size() + 1 );
|
||||
terms.insert( terms.begin(), expression.terms().begin(), expression.terms().end() );
|
||||
terms.push_back( term );
|
||||
|
||||
return Expression( std::move( terms ), expression.constant() );
|
||||
}
|
||||
|
||||
Expression operator+( const Expression& expression, const Variable& variable )
|
||||
{
|
||||
return expression + Term( variable );
|
||||
}
|
||||
|
||||
Expression operator+( const Expression& expression, double constant )
|
||||
{
|
||||
return Expression( expression.terms(), expression.constant() + constant );
|
||||
}
|
||||
|
||||
Expression operator-( const Expression& first, const Expression& second )
|
||||
{
|
||||
return first + -second;
|
||||
}
|
||||
|
||||
Expression operator-( const Expression& expression, const Term& term )
|
||||
{
|
||||
return expression + -term;
|
||||
}
|
||||
|
||||
Expression operator-( const Expression& expression, const Variable& variable )
|
||||
{
|
||||
return expression + -variable;
|
||||
}
|
||||
|
||||
Expression operator-( const Expression& expression, double constant )
|
||||
{
|
||||
return expression + -constant;
|
||||
}
|
||||
|
||||
Expression operator+( const Term& term, const Expression& expression )
|
||||
{
|
||||
return expression + term;
|
||||
}
|
||||
|
||||
Expression operator+( const Term& first, const Term& second )
|
||||
{
|
||||
std::vector< Term > terms;
|
||||
terms.reserve( 2 );
|
||||
terms.push_back( first );
|
||||
terms.push_back( second );
|
||||
|
||||
return Expression( std::move( terms ) );
|
||||
}
|
||||
|
||||
Expression operator+( const Term& term, const Variable& variable )
|
||||
{
|
||||
return term + Term( variable );
|
||||
}
|
||||
|
||||
Expression operator+( const Term& term, double constant )
|
||||
{
|
||||
return Expression( term, constant );
|
||||
}
|
||||
|
||||
Expression operator-( const Term& term, const Expression& expression )
|
||||
{
|
||||
return -expression + term;
|
||||
}
|
||||
|
||||
Expression operator-( const Term& first, const Term& second )
|
||||
{
|
||||
return first + -second;
|
||||
}
|
||||
|
||||
Expression operator-( const Term& term, const Variable& variable )
|
||||
{
|
||||
return term + -variable;
|
||||
}
|
||||
|
||||
Expression operator-( const Term& term, double constant )
|
||||
{
|
||||
return term + -constant;
|
||||
}
|
||||
|
||||
Expression operator+( const Variable& variable, const Expression& expression )
|
||||
{
|
||||
return expression + variable;
|
||||
}
|
||||
|
||||
Expression operator+( const Variable& variable, const Term& term )
|
||||
{
|
||||
return term + variable;
|
||||
}
|
||||
|
||||
Expression operator+( const Variable& first, const Variable& second )
|
||||
{
|
||||
return Term( first ) + second;
|
||||
}
|
||||
|
||||
Expression operator+( const Variable& variable, double constant )
|
||||
{
|
||||
return Term( variable ) + constant;
|
||||
}
|
||||
|
||||
Expression operator-( const Variable& variable, const Expression& expression )
|
||||
{
|
||||
return variable + -expression;
|
||||
}
|
||||
|
||||
Expression operator-( const Variable& variable, const Term& term )
|
||||
{
|
||||
return variable + -term;
|
||||
}
|
||||
|
||||
Expression operator-( const Variable& first, const Variable& second )
|
||||
{
|
||||
return first + -second;
|
||||
}
|
||||
|
||||
Expression operator-( const Variable& variable, double constant )
|
||||
{
|
||||
return variable + -constant;
|
||||
}
|
||||
|
||||
Expression operator+( double constant, const Expression& expression )
|
||||
{
|
||||
return expression + constant;
|
||||
}
|
||||
|
||||
Expression operator+( double constant, const Term& term )
|
||||
{
|
||||
return term + constant;
|
||||
}
|
||||
|
||||
Expression operator+( double constant, const Variable& variable )
|
||||
{
|
||||
return variable + constant;
|
||||
}
|
||||
|
||||
Expression operator-( double constant, const Expression& expression )
|
||||
{
|
||||
return -expression + constant;
|
||||
}
|
||||
|
||||
Expression operator-( double constant, const Term& term )
|
||||
{
|
||||
return -term + constant;
|
||||
}
|
||||
|
||||
Expression operator-( double constant, const Variable& variable )
|
||||
{
|
||||
return -variable + constant;
|
||||
}
|
68
playground/anchors/Expression.h
Normal file
68
playground/anchors/Expression.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Term.h"
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
Expression( double constant = 0.0 );
|
||||
Expression( const Term&, double constant = 0.0 );
|
||||
|
||||
Expression( const std::vector< Term >&, double constant = 0.0 );
|
||||
Expression( const std::vector< Term >&&, double constant = 0.0 );
|
||||
|
||||
const std::vector< Term >& terms() const { return m_terms; }
|
||||
double constant() const { return m_constant; }
|
||||
|
||||
double value() const;
|
||||
|
||||
private:
|
||||
std::vector< Term > m_terms;
|
||||
double m_constant;
|
||||
};
|
||||
|
||||
extern Expression operator-( const Expression& );
|
||||
|
||||
extern Expression operator+( const Expression&, const Expression& );
|
||||
extern Expression operator-( const Expression&, const Expression& );
|
||||
|
||||
extern Expression operator+( const Expression&, const Term& );
|
||||
extern Expression operator-( const Expression&, const Term& );
|
||||
extern Expression operator+( const Term&, const Expression&);
|
||||
extern Expression operator-( const Term&, const Expression&);
|
||||
|
||||
extern Expression operator+( const Expression&, const Variable& );
|
||||
extern Expression operator-( const Expression&, const Variable& );
|
||||
extern Expression operator-( const Variable&, const Expression&);
|
||||
extern Expression operator+( const Variable&, const Expression&);
|
||||
|
||||
extern Expression operator*( const Expression&, double );
|
||||
extern Expression operator/( const Expression&, double );
|
||||
extern Expression operator+( const Expression&, double );
|
||||
extern Expression operator-( const Expression&, double );
|
||||
extern Expression operator*( double, const Expression&);
|
||||
extern Expression operator+( double, const Expression&);
|
||||
extern Expression operator-( double, const Expression&);
|
||||
|
||||
extern Expression operator+( const Term&, const Term& );
|
||||
extern Expression operator-( const Term&, const Term& );
|
||||
|
||||
extern Expression operator+( const Term&, const Variable& );
|
||||
extern Expression operator-( const Term&, const Variable& );
|
||||
extern Expression operator-( const Variable&, const Term&);
|
||||
extern Expression operator+( const Variable&, const Term&);
|
||||
|
||||
extern Expression operator+( const Term&, double );
|
||||
extern Expression operator-( const Term&, double );
|
||||
extern Expression operator+( double, const Term&);
|
||||
extern Expression operator-( double, const Term&);
|
||||
|
||||
extern Expression operator+( const Variable&, const Variable& );
|
||||
extern Expression operator-( const Variable&, const Variable& );
|
||||
|
||||
extern Expression operator+( const Variable&, double );
|
||||
extern Expression operator-( const Variable&, double );
|
||||
extern Expression operator+( double, const Variable& );
|
||||
extern Expression operator-( double, const Variable& );
|
||||
|
1090
playground/anchors/Solver.cpp
Normal file
1090
playground/anchors/Solver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
33
playground/anchors/Solver.h
Normal file
33
playground/anchors/Solver.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <memory>
|
||||
|
||||
class Variable;
|
||||
class Constraint;
|
||||
class SimplexSolver;
|
||||
|
||||
class Solver
|
||||
{
|
||||
public:
|
||||
|
||||
Solver();
|
||||
~Solver();
|
||||
|
||||
void addConstraint( const Constraint& );
|
||||
void removeConstraint( const Constraint& );
|
||||
bool hasConstraint( const Constraint& ) const;
|
||||
|
||||
void addEditVariable( const Variable&, double strength );
|
||||
void removeEditVariable( const Variable& );
|
||||
|
||||
bool hasEditVariable( const Variable& ) const;
|
||||
void suggestValue( const Variable&, double value );
|
||||
|
||||
void updateVariables();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY( Solver )
|
||||
std::unique_ptr< SimplexSolver > m_solver;
|
||||
};
|
26
playground/anchors/Strength.h
Normal file
26
playground/anchors/Strength.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Strength
|
||||
{
|
||||
inline double create( double a, double b, double c, double w = 1.0 )
|
||||
{
|
||||
double result = 0.0;
|
||||
result += std::max( 0.0, std::min( 1000.0, a * w ) ) * 1000000.0;
|
||||
result += std::max( 0.0, std::min( 1000.0, b * w ) ) * 1000.0;
|
||||
result += std::max( 0.0, std::min( 1000.0, c * w ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const double required = create( 1000.0, 1000.0, 1000.0 );
|
||||
const double strong = create( 1.0, 0.0, 0.0 );
|
||||
const double medium = create( 0.0, 1.0, 0.0 );
|
||||
const double weak = create( 0.0, 0.0, 1.0 );
|
||||
|
||||
inline double clip( double value )
|
||||
{
|
||||
return std::max( 0.0, std::min( required, value ) );
|
||||
}
|
||||
}
|
81
playground/anchors/Term.h
Normal file
81
playground/anchors/Term.h
Normal file
@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include "Variable.h"
|
||||
|
||||
class Term
|
||||
{
|
||||
public:
|
||||
|
||||
Term( const Variable& variable, double coefficient = 1.0 )
|
||||
: m_variable( variable )
|
||||
, m_coefficient( coefficient )
|
||||
{
|
||||
}
|
||||
|
||||
// to facilitate efficient map -> vector copies
|
||||
Term( const std::pair< const Variable, double >& pair )
|
||||
: m_variable( pair.first )
|
||||
, m_coefficient( pair.second )
|
||||
{
|
||||
}
|
||||
|
||||
const Variable& variable() const
|
||||
{
|
||||
return m_variable;
|
||||
}
|
||||
|
||||
double coefficient() const
|
||||
{
|
||||
return m_coefficient;
|
||||
}
|
||||
|
||||
double value() const
|
||||
{
|
||||
return m_coefficient * m_variable.value();
|
||||
}
|
||||
|
||||
private:
|
||||
Variable m_variable;
|
||||
double m_coefficient;
|
||||
};
|
||||
|
||||
inline Term operator*( const Variable& variable, double coefficient )
|
||||
{
|
||||
return Term( variable, coefficient );
|
||||
}
|
||||
|
||||
inline Term operator/( const Variable& variable, double denominator )
|
||||
{
|
||||
return variable * ( 1.0 / denominator );
|
||||
}
|
||||
|
||||
inline Term operator-( const Variable& variable )
|
||||
{
|
||||
return variable * -1.0;
|
||||
}
|
||||
|
||||
inline Term operator*( const Term& term, double coefficient )
|
||||
{
|
||||
return Term( term.variable(), term.coefficient() * coefficient );
|
||||
}
|
||||
|
||||
inline Term operator/( const Term& term, double denominator )
|
||||
{
|
||||
return term * ( 1.0 / denominator );
|
||||
}
|
||||
|
||||
inline Term operator-( const Term& term )
|
||||
{
|
||||
return term * -1.0;
|
||||
}
|
||||
|
||||
inline Term operator*( double coefficient, const Term& term )
|
||||
{
|
||||
return term * coefficient;
|
||||
}
|
||||
|
||||
inline Term operator*( double coefficient, const Variable& variable )
|
||||
{
|
||||
return variable * coefficient;
|
||||
}
|
46
playground/anchors/Variable.h
Normal file
46
playground/anchors/Variable.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Variable
|
||||
{
|
||||
public:
|
||||
Variable( double value = 0.0 )
|
||||
: m_value( std::make_shared< double >(value) )
|
||||
{
|
||||
}
|
||||
|
||||
Variable( const Variable& v )
|
||||
: m_value( v.m_value )
|
||||
{
|
||||
}
|
||||
|
||||
Variable& operator=( const Variable& v )
|
||||
{
|
||||
m_value = v.m_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
double value() const
|
||||
{
|
||||
return m_value ? *m_value : 0.0;
|
||||
}
|
||||
|
||||
void setValue(double x)
|
||||
{
|
||||
*m_value = x;
|
||||
}
|
||||
|
||||
bool equals( const Variable& other )
|
||||
{
|
||||
return m_value == other.m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr< double > m_value;
|
||||
|
||||
friend bool operator<( const Variable& lhs, const Variable& rhs )
|
||||
{
|
||||
return lhs.m_value < rhs.m_value;
|
||||
}
|
||||
};
|
21
playground/anchors/anchors.pro
Normal file
21
playground/anchors/anchors.pro
Normal file
@ -0,0 +1,21 @@
|
||||
CONFIG += qskexample
|
||||
|
||||
HEADERS += \
|
||||
Constraint.h \
|
||||
Expression.h \
|
||||
Solver.h \
|
||||
Strength.h \
|
||||
Term.h \
|
||||
Variable.h
|
||||
|
||||
SOURCES += \
|
||||
Expression.cpp \
|
||||
Constraint.cpp \
|
||||
Solver.cpp
|
||||
|
||||
HEADERS += \
|
||||
AnchorBox.h
|
||||
|
||||
SOURCES += \
|
||||
AnchorBox.cpp \
|
||||
main.cpp
|
190
playground/anchors/main.cpp
Normal file
190
playground/anchors/main.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* This file may be used under the terms of the 3-clause BSD License
|
||||
*****************************************************************************/
|
||||
|
||||
#include "AnchorBox.h"
|
||||
|
||||
#include <SkinnyFont.h>
|
||||
#include <SkinnyShortcut.h>
|
||||
|
||||
#include <QskControl.h>
|
||||
#include <QskObjectCounter.h>
|
||||
#include <QskWindow.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QDebug>
|
||||
|
||||
class Rectangle : public QskControl
|
||||
{
|
||||
public:
|
||||
Rectangle( const char* colorName, QQuickItem* parent = nullptr )
|
||||
: QskControl( parent)
|
||||
, m_colorName( colorName )
|
||||
{
|
||||
setObjectName( colorName );
|
||||
|
||||
initSizePolicy( QskSizePolicy::Preferred, QskSizePolicy::Preferred );
|
||||
|
||||
setMinimumSize( 10, 10 );
|
||||
setPreferredSize( 100, 100 );
|
||||
setMaximumSize( 1000, 1000 );
|
||||
|
||||
setBackgroundColor( colorName );
|
||||
}
|
||||
|
||||
protected:
|
||||
void geometryChangeEvent( QskGeometryChangeEvent* event ) override
|
||||
{
|
||||
QskControl::geometryChangeEvent( event );
|
||||
#if 0
|
||||
qDebug() << m_colorName << size();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_colorName;
|
||||
};
|
||||
|
||||
|
||||
class MyBox : public AnchorBox
|
||||
{
|
||||
public:
|
||||
MyBox( QQuickItem* parent = nullptr )
|
||||
: AnchorBox( parent )
|
||||
{
|
||||
setObjectName( "Box" );
|
||||
|
||||
setup1();
|
||||
}
|
||||
|
||||
void setup1();
|
||||
void setup2();
|
||||
void setup3();
|
||||
|
||||
protected:
|
||||
virtual void geometryChangeEvent( QskGeometryChangeEvent* event ) override
|
||||
{
|
||||
AnchorBox::geometryChangeEvent( event );
|
||||
#if 1
|
||||
qDebug() << boxHint( Qt::MinimumSize );
|
||||
qDebug() << boxHint( Qt::PreferredSize );
|
||||
qDebug() << boxHint( Qt::MaximumSize );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
void MyBox::setup1()
|
||||
{
|
||||
auto a = new Rectangle( "PaleVioletRed" );
|
||||
auto b = new Rectangle( "DarkSeaGreen" );
|
||||
auto c = new Rectangle( "SkyBlue" );
|
||||
auto d = new Rectangle( "Coral" );
|
||||
auto e = new Rectangle( "NavajoWhite" );
|
||||
auto f = new Rectangle( "Peru" );
|
||||
auto g = new Rectangle( "Olive" );
|
||||
|
||||
addAnchor( a, Qt::AnchorTop, Qt::AnchorTop );
|
||||
addAnchor( b, Qt::AnchorTop, Qt::AnchorTop );
|
||||
|
||||
addAnchor( c, Qt::AnchorTop, a, Qt::AnchorBottom );
|
||||
addAnchor( c, Qt::AnchorTop, b, Qt::AnchorBottom );
|
||||
addAnchor( c, Qt::AnchorBottom, d, Qt::AnchorTop );
|
||||
addAnchor( c, Qt::AnchorBottom, e, Qt::AnchorTop );
|
||||
|
||||
addAnchor( d, Qt::AnchorBottom, Qt::AnchorBottom );
|
||||
addAnchor( e, Qt::AnchorBottom, Qt::AnchorBottom );
|
||||
|
||||
addAnchor( c, Qt::AnchorTop, f, Qt::AnchorTop );
|
||||
addAnchor( c, Qt::AnchorVerticalCenter, f, Qt::AnchorBottom );
|
||||
addAnchor( f, Qt::AnchorBottom, g, Qt::AnchorTop );
|
||||
addAnchor( c, Qt::AnchorBottom, g, Qt::AnchorBottom );
|
||||
|
||||
// horizontal
|
||||
addAnchor( a, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( d, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( a, Qt::AnchorRight, b, Qt::AnchorLeft );
|
||||
|
||||
addAnchor( a, Qt::AnchorRight, c, Qt::AnchorLeft );
|
||||
addAnchor( c, Qt::AnchorRight, e, Qt::AnchorLeft );
|
||||
|
||||
addAnchor( b, Qt::AnchorRight, Qt::AnchorRight );
|
||||
addAnchor( e, Qt::AnchorRight, Qt::AnchorRight );
|
||||
addAnchor( d, Qt::AnchorRight, e, Qt::AnchorLeft );
|
||||
|
||||
addAnchor( f, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( g, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( f, Qt::AnchorRight, g, Qt::AnchorRight );
|
||||
}
|
||||
|
||||
void MyBox::setup2()
|
||||
{
|
||||
auto a = new Rectangle( "PaleVioletRed" );
|
||||
|
||||
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 Rectangle( "SkyBlue" );
|
||||
addAnchor( a, Qt::AnchorBottom, c, Qt::AnchorTop );
|
||||
addAnchor( a, Qt::AnchorRight, c, Qt::AnchorRight );
|
||||
|
||||
auto d = new Rectangle( "Coral" );
|
||||
addAnchor( c, Qt::AnchorLeft, d, Qt::AnchorLeft );
|
||||
addAnchor( c, Qt::AnchorBottom, d, Qt::AnchorTop );
|
||||
addAnchor( d, Qt::AnchorRight, Qt::AnchorRight );
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyBox::setup3()
|
||||
{
|
||||
auto a = new Rectangle( "PaleVioletRed" );
|
||||
auto b = new Rectangle( "DarkSeaGreen" );
|
||||
auto c = new Rectangle( "SkyBlue" );
|
||||
auto d = new Rectangle( "Coral" );
|
||||
|
||||
addAnchor( a, Qt::AnchorTop, Qt::AnchorTop );
|
||||
|
||||
addAnchor( a, Qt::AnchorLeft, Qt::AnchorLeft );
|
||||
addAnchor( a, Qt::AnchorRight, b, Qt::AnchorLeft );
|
||||
addAnchor( b, Qt::AnchorRight, c, Qt::AnchorLeft );
|
||||
addAnchor( c, Qt::AnchorRight, d, Qt::AnchorLeft );
|
||||
addAnchor( d, Qt::AnchorRight, Qt::AnchorRight );
|
||||
|
||||
auto e = new Rectangle( "NavajoWhite" );
|
||||
#if 1
|
||||
e->setMinimumWidth( 100 );
|
||||
#endif
|
||||
addAnchor( a, Qt::AnchorBottom, e, Qt::AnchorTop );
|
||||
addAnchor( c, Qt::AnchorRight, e, Qt::AnchorRight );
|
||||
addAnchor( b, Qt::AnchorLeft, e, Qt::AnchorLeft );
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
#ifdef ITEM_STATISTICS
|
||||
QskObjectCounter counter( true );
|
||||
#endif
|
||||
|
||||
QGuiApplication app( argc, argv );
|
||||
|
||||
SkinnyFont::init( &app );
|
||||
SkinnyShortcut::enable( SkinnyShortcut::Quit | SkinnyShortcut::DebugShortcuts );
|
||||
|
||||
auto box = new MyBox();
|
||||
|
||||
QskWindow window;
|
||||
window.addItem( box );
|
||||
window.resize( 600, 600 );
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
anchors \
|
||||
dialogbuttons \
|
||||
invoker \
|
||||
inputpanel \
|
||||
|
Loading…
x
Reference in New Issue
Block a user