Canvas: add a nice new syntax for constraint packing
This commit is contained in:
parent
d6745f043c
commit
502a9e80dc
|
@ -45,16 +45,48 @@ class /* LIBCANVAS_API */ ConstrainedItem
|
||||||
kiwi::Variable& bottom () { return _bottom; }
|
kiwi::Variable& bottom () { return _bottom; }
|
||||||
kiwi::Variable& width () { return _width; }
|
kiwi::Variable& width () { return _width; }
|
||||||
kiwi::Variable& height () { return _height; }
|
kiwi::Variable& height () { return _height; }
|
||||||
|
|
||||||
kiwi::Variable& center_x () { return _center_x; }
|
kiwi::Variable& center_x () { return _center_x; }
|
||||||
kiwi::Variable& center_y () { return _center_y; }
|
kiwi::Variable& center_y () { return _center_y; }
|
||||||
|
|
||||||
|
kiwi::Variable const & left () const { return _left; }
|
||||||
|
kiwi::Variable const & right () const { return _right; }
|
||||||
|
kiwi::Variable const & top () const { return _top; }
|
||||||
|
kiwi::Variable const & bottom () const { return _bottom; }
|
||||||
|
kiwi::Variable const & width () const { return _width; }
|
||||||
|
kiwi::Variable const & height () const { return _height; }
|
||||||
|
kiwi::Variable const & center_x () const { return _center_x; }
|
||||||
|
kiwi::Variable const & center_y () const { return _center_y; }
|
||||||
|
|
||||||
|
kiwi::Variable& left_padding () { return _left_padding; }
|
||||||
|
kiwi::Variable& right_padding () { return _right_padding; }
|
||||||
|
kiwi::Variable& top_padding () { return _top_padding; }
|
||||||
|
kiwi::Variable& bottom_padding () { return _bottom_padding; }
|
||||||
|
|
||||||
void constrained (ConstraintPacker const & parent);
|
void constrained (ConstraintPacker const & parent);
|
||||||
virtual bool involved (kiwi::Constraint const &) const;
|
virtual bool involved (kiwi::Constraint const &) const;
|
||||||
|
|
||||||
std::vector<kiwi::Constraint> const & constraints() const { return _constraints; }
|
std::vector<kiwi::Constraint> const & constraints() const { return _constraints; }
|
||||||
void add_constraint (kiwi::Constraint const & c) { _constraints.push_back (c); }
|
void add_constraint (kiwi::Constraint const & c) { _constraints.push_back (c); }
|
||||||
|
|
||||||
|
ConstrainedItem& at (Duple const &);
|
||||||
|
ConstrainedItem& size (Duple const &);
|
||||||
|
ConstrainedItem& box (Rect const &);
|
||||||
|
|
||||||
|
ConstrainedItem& left_of (ConstrainedItem const &, Distance pad = 0);
|
||||||
|
ConstrainedItem& right_of (ConstrainedItem const &, Distance pad = 0);
|
||||||
|
ConstrainedItem& above (ConstrainedItem const &, Distance pad = 0);
|
||||||
|
ConstrainedItem& below (ConstrainedItem const &, Distance pad = 0);
|
||||||
|
ConstrainedItem& x_centered (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& y_centered (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& centered_on (ConstrainedItem const &, Distance xoffset = 0, Distance yoffset = 0);
|
||||||
|
ConstrainedItem& top_aligned_with (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& bottom_aligned_with (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& left_aligned_with (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& right_aligned_with (ConstrainedItem const &, Distance offset = 0);
|
||||||
|
ConstrainedItem& same_size_as (ConstrainedItem const &, Distance wdelta = 0, Distance hdelta = 0);
|
||||||
|
ConstrainedItem& same_width_as (ConstrainedItem const &, Distance delta = 0);
|
||||||
|
ConstrainedItem& same_height_as (ConstrainedItem const &, Distance delta = 0);
|
||||||
|
|
||||||
virtual void dump (std::ostream&);
|
virtual void dump (std::ostream&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -67,6 +99,10 @@ class /* LIBCANVAS_API */ ConstrainedItem
|
||||||
kiwi::Variable _bottom;
|
kiwi::Variable _bottom;
|
||||||
kiwi::Variable _width;
|
kiwi::Variable _width;
|
||||||
kiwi::Variable _height;
|
kiwi::Variable _height;
|
||||||
|
kiwi::Variable _left_padding;
|
||||||
|
kiwi::Variable _right_padding;
|
||||||
|
kiwi::Variable _top_padding;
|
||||||
|
kiwi::Variable _bottom_padding;
|
||||||
|
|
||||||
/* derived */
|
/* derived */
|
||||||
|
|
||||||
|
@ -87,17 +123,6 @@ class /* LIBCANVAS_API */ BoxConstrainedItem : public ConstrainedItem
|
||||||
kiwi::Variable& top_margin () { return _top_margin; }
|
kiwi::Variable& top_margin () { return _top_margin; }
|
||||||
kiwi::Variable& bottom_margin () { return _bottom_margin; }
|
kiwi::Variable& bottom_margin () { return _bottom_margin; }
|
||||||
|
|
||||||
/* Padding is not for use by items or anyone except the parent
|
|
||||||
* (constraint) container. It is used to space out items that are set
|
|
||||||
* to expand inside a container but not to "fill" (i.e. the extra space
|
|
||||||
* is assigned to padding around the item, not the item itself).
|
|
||||||
*/
|
|
||||||
|
|
||||||
kiwi::Variable& left_padding () { return _left_padding; }
|
|
||||||
kiwi::Variable& right_padding () { return _right_padding; }
|
|
||||||
kiwi::Variable& top_padding () { return _top_padding; }
|
|
||||||
kiwi::Variable& bottom_padding () { return _bottom_padding; }
|
|
||||||
|
|
||||||
PackOptions primary_axis_pack_options() const { return _primary_axis_pack_options; }
|
PackOptions primary_axis_pack_options() const { return _primary_axis_pack_options; }
|
||||||
PackOptions secondary_axis_pack_options() const { return _secondary_axis_pack_options; }
|
PackOptions secondary_axis_pack_options() const { return _secondary_axis_pack_options; }
|
||||||
|
|
||||||
|
@ -108,10 +133,6 @@ class /* LIBCANVAS_API */ BoxConstrainedItem : public ConstrainedItem
|
||||||
kiwi::Variable _right_margin;
|
kiwi::Variable _right_margin;
|
||||||
kiwi::Variable _top_margin;
|
kiwi::Variable _top_margin;
|
||||||
kiwi::Variable _bottom_margin;
|
kiwi::Variable _bottom_margin;
|
||||||
kiwi::Variable _left_padding;
|
|
||||||
kiwi::Variable _right_padding;
|
|
||||||
kiwi::Variable _top_padding;
|
|
||||||
kiwi::Variable _bottom_padding;
|
|
||||||
|
|
||||||
PackOptions _primary_axis_pack_options;
|
PackOptions _primary_axis_pack_options;
|
||||||
PackOptions _secondary_axis_pack_options;
|
PackOptions _secondary_axis_pack_options;
|
||||||
|
@ -120,4 +141,3 @@ class /* LIBCANVAS_API */ BoxConstrainedItem : public ConstrainedItem
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -284,11 +284,11 @@ cBox::size_allocate (Rect const & r)
|
||||||
_solver.suggestValue (expanded_item_size, expanded_size);
|
_solver.suggestValue (expanded_item_size, expanded_size);
|
||||||
|
|
||||||
_solver.updateVariables ();
|
_solver.updateVariables ();
|
||||||
//solver.dump (cerr);
|
_solver.dump (cerr);
|
||||||
|
|
||||||
//for (ConstrainedItemMap::const_iterator o = constrained_map.begin(); o != constrained_map.end(); ++o) {
|
for (ConstrainedItemMap::const_iterator o = constrained_map.begin(); o != constrained_map.end(); ++o) {
|
||||||
//o->second->dump (cerr);
|
o->second->dump (cerr);
|
||||||
//}
|
}
|
||||||
|
|
||||||
apply (&_solver);
|
apply (&_solver);
|
||||||
|
|
||||||
|
@ -299,8 +299,11 @@ cBox::size_allocate (Rect const & r)
|
||||||
void
|
void
|
||||||
cBox::update_constraints ()
|
cBox::update_constraints ()
|
||||||
{
|
{
|
||||||
ConstraintPacker::update_constraints ();
|
/* must totally override ConstraintPacker::update_constraints() */
|
||||||
|
|
||||||
|
_solver.reset ();
|
||||||
|
_solver.addEditVariable (width, kiwi::strength::strong);
|
||||||
|
_solver.addEditVariable (height, kiwi::strength::strong);
|
||||||
_solver.addEditVariable (expanded_item_size, kiwi::strength::strong);
|
_solver.addEditVariable (expanded_item_size, kiwi::strength::strong);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -506,6 +509,8 @@ cBox::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
|
||||||
|
|
||||||
if (fill()) {
|
if (fill()) {
|
||||||
|
|
||||||
|
cerr << whoami() << " setting fill context with 0x" << std::hex << _fill_color << std::dec << " draw " << draw << endl;
|
||||||
|
|
||||||
setup_fill_context (context);
|
setup_fill_context (context);
|
||||||
context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
|
context->rectangle (draw.x0, draw.y0, draw.width(), draw.height());
|
||||||
context->fill_preserve ();
|
context->fill_preserve ();
|
||||||
|
|
|
@ -37,6 +37,10 @@ ConstrainedItem::ConstrainedItem (Item& i)
|
||||||
, _bottom (_item.name + " bottom")
|
, _bottom (_item.name + " bottom")
|
||||||
, _width (_item.name + " width")
|
, _width (_item.name + " width")
|
||||||
, _height (_item.name + " height")
|
, _height (_item.name + " height")
|
||||||
|
, _left_padding (_item.name + " left_padding")
|
||||||
|
, _right_padding (_item.name + " right_padding")
|
||||||
|
, _top_padding (_item.name + " top_padding")
|
||||||
|
, _bottom_padding (_item.name + " bottom_padding")
|
||||||
, _center_x (_item.name + " center_x")
|
, _center_x (_item.name + " center_x")
|
||||||
, _center_y (_item.name + " center_y")
|
, _center_y (_item.name + " center_y")
|
||||||
{
|
{
|
||||||
|
@ -46,6 +50,9 @@ ConstrainedItem::ConstrainedItem (Item& i)
|
||||||
|
|
||||||
_constraints.push_back (center_x() == left() + (width() / 2.));
|
_constraints.push_back (center_x() == left() + (width() / 2.));
|
||||||
_constraints.push_back (center_y() == top() + (height() / 2.));
|
_constraints.push_back (center_y() == top() + (height() / 2.));
|
||||||
|
|
||||||
|
_constraints.push_back (_right == _left + _width);
|
||||||
|
_constraints.push_back (_bottom == _top + _height);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstrainedItem::~ConstrainedItem ()
|
ConstrainedItem::~ConstrainedItem ()
|
||||||
|
@ -74,6 +81,10 @@ ConstrainedItem::dump (std::ostream& out)
|
||||||
<< '\t' << "bottom: " << _bottom.value() << '\n'
|
<< '\t' << "bottom: " << _bottom.value() << '\n'
|
||||||
<< '\t' << "width: " << _width.value() << '\n'
|
<< '\t' << "width: " << _width.value() << '\n'
|
||||||
<< '\t' << "height: " << _height.value() << '\n'
|
<< '\t' << "height: " << _height.value() << '\n'
|
||||||
|
<< '\t' << "right_padding: " << _right_padding.value() << '\n'
|
||||||
|
<< '\t' << "left_padding: " << _left_padding.value() << '\n'
|
||||||
|
<< '\t' << "top_padding: " << _top_padding.value() << '\n'
|
||||||
|
<< '\t' << "bottom_padding: " << _bottom_padding.value() << '\n'
|
||||||
<< '\t' << "center_x: " << _center_x.value() << '\n'
|
<< '\t' << "center_x: " << _center_x.value() << '\n'
|
||||||
<< '\t' << "center_y: " << _center_y.value() << '\n';
|
<< '\t' << "center_y: " << _center_y.value() << '\n';
|
||||||
}
|
}
|
||||||
|
@ -103,10 +114,6 @@ BoxConstrainedItem::BoxConstrainedItem (Item& parent, PackOptions primary_axis_o
|
||||||
, _right_margin (_item.name + " right_margin")
|
, _right_margin (_item.name + " right_margin")
|
||||||
, _top_margin (_item.name + " top_margin")
|
, _top_margin (_item.name + " top_margin")
|
||||||
, _bottom_margin (_item.name + " bottom_margin")
|
, _bottom_margin (_item.name + " bottom_margin")
|
||||||
, _left_padding (_item.name + " left_padding")
|
|
||||||
, _right_padding (_item.name + " right_padding")
|
|
||||||
, _top_padding (_item.name + " top_padding")
|
|
||||||
, _bottom_padding (_item.name + " bottom_padding")
|
|
||||||
, _primary_axis_pack_options (primary_axis_opts)
|
, _primary_axis_pack_options (primary_axis_opts)
|
||||||
, _secondary_axis_pack_options (secondary_axis_opts)
|
, _secondary_axis_pack_options (secondary_axis_opts)
|
||||||
{
|
{
|
||||||
|
@ -141,9 +148,126 @@ BoxConstrainedItem::dump (std::ostream& out)
|
||||||
out << '\t' << "left_margin: " << _left_margin.value() << '\n'
|
out << '\t' << "left_margin: " << _left_margin.value() << '\n'
|
||||||
<< '\t' << "right_margin: " << _right_margin.value() << '\n'
|
<< '\t' << "right_margin: " << _right_margin.value() << '\n'
|
||||||
<< '\t' << "top_margin: " << _top_margin.value() << '\n'
|
<< '\t' << "top_margin: " << _top_margin.value() << '\n'
|
||||||
<< '\t' << "bottom_margin: " << _bottom_margin.value() << '\n'
|
<< '\t' << "bottom_margin: " << _bottom_margin.value() << '\n';
|
||||||
<< '\t' << "right_padding: " << _right_padding.value() << '\n'
|
|
||||||
<< '\t' << "left_padding: " << _left_padding.value() << '\n'
|
|
||||||
<< '\t' << "top_padding: " << _top_padding.value() << '\n'
|
|
||||||
<< '\t' << "bottom_padding: " << _bottom_padding.value() << '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::at (Duple const & d)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_left == d.x);
|
||||||
|
_constraints.push_back (_top == d.y);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::size (Duple const & d)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_width == d.x);
|
||||||
|
_constraints.push_back (_height == d.y);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::box (Rect const & r)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_left == r.x0);
|
||||||
|
_constraints.push_back (_top == r.y0);
|
||||||
|
_constraints.push_back (_width == r.width());
|
||||||
|
_constraints.push_back (_height == r.height());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::left_of (ConstrainedItem const & other, Distance by)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_right_padding == by);
|
||||||
|
_constraints.push_back (_right == other.left() + _right_padding);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::right_of (ConstrainedItem const & other, Distance by)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_left_padding == by);
|
||||||
|
_constraints.push_back (_left == other.right() + _left_padding);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::above (ConstrainedItem const & other, Distance by)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_bottom_padding == by);
|
||||||
|
_constraints.push_back (_bottom == other.top() + _bottom_padding);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::below (ConstrainedItem const & other, Distance by)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_top_padding == by);
|
||||||
|
_constraints.push_back (_top == other.bottom() + _top_padding);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::centered_on (ConstrainedItem const & other, Distance xoffset, Distance yoffset)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_center_x == other.center_x() + xoffset);
|
||||||
|
_constraints.push_back (_center_y == other.center_y() + yoffset);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::top_aligned_with (ConstrainedItem const & other, Distance offset)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_top == other.top() + offset);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::bottom_aligned_with (ConstrainedItem const & other, Distance offset)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_bottom == other.bottom() + offset);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::left_aligned_with (ConstrainedItem const & other, Distance offset)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_left == other.left() + offset);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::right_aligned_with (ConstrainedItem const & other, Distance offset)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_right == other.right() + offset);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::same_size_as (ConstrainedItem const & other, Distance wdelta, Distance hdelta)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_width == other.width() + wdelta);
|
||||||
|
_constraints.push_back (_height == other.height() + hdelta);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::same_width_as (ConstrainedItem const & other, Distance delta)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_width == other.width() + delta);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstrainedItem&
|
||||||
|
ConstrainedItem::same_height_as (ConstrainedItem const & other, Distance delta)
|
||||||
|
{
|
||||||
|
_constraints.push_back (_height == other.height() + delta);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,11 +131,13 @@ void
|
||||||
ConstraintPacker::constrain (kiwi::Constraint const &c)
|
ConstraintPacker::constrain (kiwi::Constraint const &c)
|
||||||
{
|
{
|
||||||
constraint_list.push_back (c);
|
constraint_list.push_back (c);
|
||||||
|
_need_constraint_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConstraintPacker::preferred_size (Duple& minimum, Duple& natural) const
|
ConstraintPacker::preferred_size (Duple& minimum, Duple& natural) const
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
/* our parent wants to know how big we are.
|
/* our parent wants to know how big we are.
|
||||||
|
|
||||||
We may have some intrinsic size (i.e. "everything in this constraint
|
We may have some intrinsic size (i.e. "everything in this constraint
|
||||||
|
@ -150,40 +152,17 @@ ConstraintPacker::preferred_size (Duple& minimum, Duple& natural) const
|
||||||
We may have no intrinsic dimensions at all. This is the tricky one.
|
We may have no intrinsic dimensions at all. This is the tricky one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
kiwi::Solver s;
|
if (_need_constraint_update) {
|
||||||
|
const_cast<ConstraintPacker*>(this)->update_constraints ();
|
||||||
|
}
|
||||||
|
|
||||||
if (_intrinsic_width > 0) {
|
if (_intrinsic_width > 0) {
|
||||||
|
_solver.suggestValue (width, _intrinsic_width);
|
||||||
s.addEditVariable (width, kiwi::strength::strong);
|
|
||||||
s.suggestValue (width, _intrinsic_width);
|
|
||||||
|
|
||||||
} else if (_intrinsic_height > 0) {
|
} else if (_intrinsic_height > 0) {
|
||||||
|
_solver.suggestValue (height, _intrinsic_height);
|
||||||
s.addEditVariable (height, kiwi::strength::strong);
|
|
||||||
s.suggestValue (height, _intrinsic_height);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ConstrainedItemMap::const_iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) {
|
_solver.updateVariables ();
|
||||||
|
|
||||||
Duple min, natural;
|
|
||||||
ConstrainedItem* ci = x->second;
|
|
||||||
|
|
||||||
x->first->preferred_size (min, natural);
|
|
||||||
|
|
||||||
s.addConstraint (ci->width() >= min.width() | kiwi::strength::required);
|
|
||||||
s.addConstraint (ci->height() >= min.height() | kiwi::strength::required);
|
|
||||||
s.addConstraint (ci->width() == natural.width() | kiwi::strength::medium);
|
|
||||||
s.addConstraint (ci->height() == natural.width() | kiwi::strength::medium);
|
|
||||||
|
|
||||||
add_constraints (s, ci);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ConstraintList::const_iterator c = constraint_list.begin(); c != constraint_list.end(); ++c) {
|
|
||||||
s.addConstraint (*c);
|
|
||||||
}
|
|
||||||
|
|
||||||
s.updateVariables ();
|
|
||||||
|
|
||||||
Duple ret;
|
Duple ret;
|
||||||
|
|
||||||
|
@ -191,6 +170,10 @@ ConstraintPacker::preferred_size (Duple& minimum, Duple& natural) const
|
||||||
natural.y = height.value ();
|
natural.y = height.value ();
|
||||||
|
|
||||||
minimum = natural;
|
minimum = natural;
|
||||||
|
#endif
|
||||||
|
natural.x = 100;
|
||||||
|
natural.y = 100;
|
||||||
|
minimum = natural;
|
||||||
|
|
||||||
cerr << "CP::sr returns " << natural<< endl;
|
cerr << "CP::sr returns " << natural<< endl;
|
||||||
}
|
}
|
||||||
|
@ -202,36 +185,22 @@ ConstraintPacker::size_allocate (Rect const & r)
|
||||||
|
|
||||||
Item::size_allocate (r);
|
Item::size_allocate (r);
|
||||||
|
|
||||||
kiwi::Solver s;
|
if (_need_constraint_update) {
|
||||||
|
update_constraints ();
|
||||||
s.addConstraint (width == r.width());
|
|
||||||
s.addConstraint (height == r.height());
|
|
||||||
|
|
||||||
// s.addEditVariable (width, kiwi::strength::strong);
|
|
||||||
// s.addEditVariable (height, kiwi::strength::strong);
|
|
||||||
// s.suggestValue (width, r.width());
|
|
||||||
// s.suggestValue (height, r.height());
|
|
||||||
|
|
||||||
for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) {
|
|
||||||
|
|
||||||
Duple min, natural;
|
|
||||||
ConstrainedItem* ci = x->second;
|
|
||||||
|
|
||||||
x->first->preferred_size (min, natural);
|
|
||||||
|
|
||||||
s.addConstraint (ci->width() >= min.width() | kiwi::strength::required);
|
|
||||||
s.addConstraint (ci->height() >= min.height() | kiwi::strength::required);
|
|
||||||
s.addConstraint (ci->width() == natural.width() | kiwi::strength::medium);
|
|
||||||
s.addConstraint (ci->height() == natural.width() | kiwi::strength::medium);
|
|
||||||
|
|
||||||
add_constraints (s, ci);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ConstraintList::const_iterator c = constraint_list.begin(); c != constraint_list.end(); ++c) {
|
_solver.suggestValue (width, r.width());
|
||||||
s.addConstraint (*c);
|
_solver.suggestValue (height, r.height());
|
||||||
}
|
_solver.updateVariables ();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
_solver.dump (cerr);
|
||||||
|
|
||||||
|
for (ConstrainedItemMap::const_iterator o = constrained_map.begin(); o != constrained_map.end(); ++o) {
|
||||||
|
o->second->dump (cerr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
s.updateVariables ();
|
|
||||||
apply (0);
|
apply (0);
|
||||||
|
|
||||||
_bounding_box_dirty = true;
|
_bounding_box_dirty = true;
|
||||||
|
@ -324,4 +293,23 @@ ConstraintPacker::update_constraints ()
|
||||||
_solver.reset ();
|
_solver.reset ();
|
||||||
_solver.addEditVariable (width, kiwi::strength::strong);
|
_solver.addEditVariable (width, kiwi::strength::strong);
|
||||||
_solver.addEditVariable (height, kiwi::strength::strong);
|
_solver.addEditVariable (height, kiwi::strength::strong);
|
||||||
|
|
||||||
|
for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) {
|
||||||
|
|
||||||
|
Duple min, natural;
|
||||||
|
ConstrainedItem* ci = x->second;
|
||||||
|
|
||||||
|
x->first->preferred_size (min, natural);
|
||||||
|
|
||||||
|
_solver.addConstraint (ci->width() >= min.width() | kiwi::strength::required);
|
||||||
|
_solver.addConstraint (ci->height() >= min.height() | kiwi::strength::required);
|
||||||
|
_solver.addConstraint (ci->width() == natural.width() | kiwi::strength::medium);
|
||||||
|
_solver.addConstraint (ci->height() == natural.width() | kiwi::strength::medium);
|
||||||
|
|
||||||
|
add_constraints (_solver, ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ConstraintList::const_iterator c = constraint_list.begin(); c != constraint_list.end(); ++c) {
|
||||||
|
_solver.addConstraint (*c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,6 @@ main (int argc, char* argv[])
|
||||||
vbox->set_fill_color (0xff0000ff);
|
vbox->set_fill_color (0xff0000ff);
|
||||||
vbox->set_margin (20);
|
vbox->set_margin (20);
|
||||||
|
|
||||||
#if 1
|
|
||||||
vbox->pack_start (r1, PackOptions(PackExpand|PackFill));
|
vbox->pack_start (r1, PackOptions(PackExpand|PackFill));
|
||||||
vbox->pack_start (r2, PackOptions(PackExpand|PackFill));
|
vbox->pack_start (r2, PackOptions(PackExpand|PackFill));
|
||||||
vbox->pack_start (r3, PackOptions(PackExpand|PackFill));
|
vbox->pack_start (r3, PackOptions(PackExpand|PackFill));
|
||||||
|
@ -90,7 +89,7 @@ main (int argc, char* argv[])
|
||||||
hbox1->pack_start (r6, PackOptions(PackExpand|PackFill));
|
hbox1->pack_start (r6, PackOptions(PackExpand|PackFill));
|
||||||
|
|
||||||
BoxConstrainedItem* hb1;
|
BoxConstrainedItem* hb1;
|
||||||
ConstrainedItem* ci;
|
BoxConstrainedItem* ci;
|
||||||
|
|
||||||
hb1 = vbox->pack_start (hbox1, PackOptions (PackExpand|PackFill));
|
hb1 = vbox->pack_start (hbox1, PackOptions (PackExpand|PackFill));
|
||||||
|
|
||||||
|
@ -105,6 +104,8 @@ main (int argc, char* argv[])
|
||||||
ci = vbox->pack_start (circle, PackOptions (PackExpand|PackFill));
|
ci = vbox->pack_start (circle, PackOptions (PackExpand|PackFill));
|
||||||
ci->add_constraint (ci->height() == 0.5 * hb1->height());
|
ci->add_constraint (ci->height() == 0.5 * hb1->height());
|
||||||
ci->add_constraint (ci->center_x() == ci4->center_x());
|
ci->add_constraint (ci->center_x() == ci4->center_x());
|
||||||
|
ci->add_constraint (ci->top_padding() == 10);
|
||||||
|
ci->add_constraint (ci->bottom_padding() == 10);
|
||||||
|
|
||||||
cBox* hbox2 = new cBox (c, Horizontal);
|
cBox* hbox2 = new cBox (c, Horizontal);
|
||||||
hbox2->name = "hbox2";
|
hbox2->name = "hbox2";
|
||||||
|
@ -121,11 +122,11 @@ main (int argc, char* argv[])
|
||||||
txt->set ("hello world");
|
txt->set ("hello world");
|
||||||
|
|
||||||
ConstrainedItem* hb2 = vbox->pack_start (hbox2, PackOptions (PackExpand|PackFill));
|
ConstrainedItem* hb2 = vbox->pack_start (hbox2, PackOptions (PackExpand|PackFill));
|
||||||
|
ConstrainedItem* ti = hbox2->pack_start (txt, PackOptions (PackExpand), PackOptions (0));
|
||||||
|
|
||||||
ConstrainedItem* ti = hbox2->pack_start (txt, PackOptions (PackExpand|PackFill));
|
|
||||||
ti->add_constraint (ti->center_x() == hb2->center_x());
|
ti->add_constraint (ti->center_x() == hb2->center_x());
|
||||||
ti->add_constraint (ti->center_y() == hb2->center_y() + 20);
|
ti->add_constraint (ti->center_y() == hb2->center_y());
|
||||||
#endif
|
|
||||||
win.show_all ();
|
win.show_all ();
|
||||||
app.run ();
|
app.run ();
|
||||||
|
|
||||||
|
|
128
libs/canvas/constraint_test4.cc
Normal file
128
libs/canvas/constraint_test4.cc
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <gtkmm/adjustment.h>
|
||||||
|
#include <gtkmm/main.h>
|
||||||
|
#include <gtkmm/window.h>
|
||||||
|
|
||||||
|
#include "gtkmm2ext/colors.h"
|
||||||
|
|
||||||
|
#include "canvas/box.h"
|
||||||
|
#include "canvas/canvas.h"
|
||||||
|
#include "canvas/cbox.h"
|
||||||
|
#include "canvas/circle.h"
|
||||||
|
#include "canvas/constrained_item.h"
|
||||||
|
#include "canvas/constraint_packer.h"
|
||||||
|
#include "canvas/rectangle.h"
|
||||||
|
#include "canvas/text.h"
|
||||||
|
|
||||||
|
using namespace ArdourCanvas;
|
||||||
|
using namespace Gtk;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char* argv[])
|
||||||
|
{
|
||||||
|
Gtk::Main app (&argc, &argv);
|
||||||
|
|
||||||
|
Gtk::Window win;
|
||||||
|
Gtk::Adjustment hadj (0, 0, 1000, 1, 10);
|
||||||
|
Gtk::Adjustment vadj (0, 0, 1000, 1, 10);
|
||||||
|
GtkCanvasViewport cview (hadj, vadj);
|
||||||
|
Canvas* c = cview.canvas ();
|
||||||
|
|
||||||
|
c->set_background_color (0xffffffff);
|
||||||
|
|
||||||
|
srandom (time ((time_t) 0));
|
||||||
|
|
||||||
|
cview.set_size_request (100, 100);
|
||||||
|
|
||||||
|
win.add (cview);
|
||||||
|
|
||||||
|
/* Make some items */
|
||||||
|
|
||||||
|
Rectangle* r1 = new Rectangle (c);
|
||||||
|
Rectangle* r2 = new Rectangle (c);
|
||||||
|
Rectangle* r3 = new Rectangle (c);
|
||||||
|
|
||||||
|
r1->set_fill_color (Gtkmm2ext::random_color());
|
||||||
|
r2->set_fill_color (Gtkmm2ext::random_color());
|
||||||
|
r3->set_fill_color (Gtkmm2ext::random_color());
|
||||||
|
|
||||||
|
r1->name = "L";
|
||||||
|
r2->name = "R";
|
||||||
|
r3->name = "C";
|
||||||
|
|
||||||
|
r1->set_intrinsic_size (20, 20);
|
||||||
|
r2->set_intrinsic_size (30, 30);
|
||||||
|
r3->set_intrinsic_size (40, 40);
|
||||||
|
|
||||||
|
Text* txt = new Text (c);
|
||||||
|
txt->name = "text";
|
||||||
|
Pango::FontDescription font ("Sans");
|
||||||
|
txt->set_font_description (font);
|
||||||
|
txt->set ("hello world");
|
||||||
|
|
||||||
|
Rectangle* bb = new Rectangle (c);
|
||||||
|
bb->set_fill_color (Gtkmm2ext::random_color());
|
||||||
|
|
||||||
|
Circle* circ = new Circle (c);
|
||||||
|
circ->name = "circle";
|
||||||
|
circ->set_fill_color (Gtkmm2ext::random_color());
|
||||||
|
circ->set_outline_color (Gtkmm2ext::random_color());
|
||||||
|
|
||||||
|
/* create a container */
|
||||||
|
|
||||||
|
ConstraintPacker* packer = new ConstraintPacker (c->root());
|
||||||
|
|
||||||
|
/* add stuff */
|
||||||
|
|
||||||
|
ConstrainedItem* left = packer->add_constrained (r1);
|
||||||
|
ConstrainedItem* right = packer->add_constrained (r2);
|
||||||
|
ConstrainedItem* center = packer->add_constrained (r3);
|
||||||
|
ConstrainedItem* text = packer->add_constrained (txt);
|
||||||
|
ConstrainedItem* bens_box = packer->add_constrained (bb);
|
||||||
|
ConstrainedItem* circle = packer->add_constrained (circ);
|
||||||
|
|
||||||
|
/* first, constraints that connect an item dimension to the container dimensions or a constant */
|
||||||
|
packer->constrain (left->left() == 0);
|
||||||
|
packer->constrain (left->height() == packer->height);
|
||||||
|
packer->constrain (left->top() == 0);
|
||||||
|
packer->constrain (left->width() == 0.5 * packer->width);
|
||||||
|
packer->constrain (right->right() == packer->width);
|
||||||
|
packer->constrain (center->height() == 0.5 * packer->height);
|
||||||
|
|
||||||
|
/* second, constraints that connect an item dimension to other items */
|
||||||
|
center->right_of (*left, 50);
|
||||||
|
right->right_of (*center);
|
||||||
|
center->same_width_as (*right);
|
||||||
|
right->same_width_as (*center);
|
||||||
|
right->same_height_as (*left);
|
||||||
|
center->top_aligned_with (*left);
|
||||||
|
right->top_aligned_with (*center);
|
||||||
|
|
||||||
|
/* XXX this needs to somehow move into ConstraintPacker but I currently
|
||||||
|
* see no way to build a constraint from a container of
|
||||||
|
* ConstrainedItems
|
||||||
|
*/
|
||||||
|
|
||||||
|
packer->constrain (left->width() + right->width() + center->width() +
|
||||||
|
left->left_padding() + left->right_padding() +
|
||||||
|
center->left_padding() + center->right_padding() +
|
||||||
|
right->left_padding() + right->right_padding()
|
||||||
|
== packer->width);
|
||||||
|
|
||||||
|
/* Text at a fixed position */
|
||||||
|
text->at (Duple (150, 50));
|
||||||
|
/* Rectangle of fixed position and size */
|
||||||
|
bens_box->box (Rect (40, 40, 80, 80));
|
||||||
|
|
||||||
|
/* a circle sized and centered */
|
||||||
|
circle->size (Duple (30, 30));
|
||||||
|
circle->centered_on (*center);
|
||||||
|
|
||||||
|
win.show_all ();
|
||||||
|
app.run ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -190,6 +190,15 @@ def build(bld):
|
||||||
constraint_test3.name = 'constraint_test3'
|
constraint_test3.name = 'constraint_test3'
|
||||||
constraint_test3.target = 'constraint_test3'
|
constraint_test3.target = 'constraint_test3'
|
||||||
constraint_test3.install_path = ''
|
constraint_test3.install_path = ''
|
||||||
|
|
||||||
|
constraint_test4_src = [ 'constraint_test4.cc' ]
|
||||||
|
constraint_test4 = bld (features = 'cxx cxxprogram')
|
||||||
|
constraint_test4.source = constraint_test4_src
|
||||||
|
constraint_test4.includes = obj.includes + ['../pbd', '../gtkmm2ext']
|
||||||
|
constraint_test4.use = [ 'GTKMM', 'libcanvas', 'libgtkmm2ext' ]
|
||||||
|
constraint_test4.name = 'constraint_test4'
|
||||||
|
constraint_test4.target = 'constraint_test4'
|
||||||
|
constraint_test4.install_path = ''
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
autowaf.shutdown()
|
autowaf.shutdown()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user