13
0

Canvas: add a nice new syntax for constraint packing

This commit is contained in:
Paul Davis 2020-06-28 21:36:22 -06:00
parent d6745f043c
commit 502a9e80dc
7 changed files with 367 additions and 92 deletions

View File

@ -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

View File

@ -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 ();

View File

@ -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;
}

View File

@ -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);
}
} }

View File

@ -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 ();

View 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;
}

View File

@ -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()