canvas: remove intrinsic size concept, fall back to requested size; converge on gtk style size_request

This commit is contained in:
Paul Davis 2021-08-01 21:18:35 -06:00
parent 08150c1547
commit a1c67b4ad7
14 changed files with 258 additions and 188 deletions

View File

@ -20,6 +20,7 @@
#include <algorithm>
#include "pbd/unwind.h"
#include "pbd/stacktrace.h"
#include "canvas/box.h"
#include "canvas/rectangle.h"
@ -35,6 +36,7 @@ Box::Box (Canvas* canvas, Orientation o)
, homogenous (false)
, ignore_child_changes (false)
{
set_layout_sensitive (true);
}
Box::Box (Item* parent, Orientation o)
@ -46,6 +48,7 @@ Box::Box (Item* parent, Orientation o)
, homogenous (false)
, ignore_child_changes (false)
{
set_layout_sensitive (true);
}
@ -58,6 +61,7 @@ Box::Box (Item* parent, Duple const & p, Orientation o)
, homogenous (false)
, ignore_child_changes (false)
{
set_layout_sensitive (true);
set_position (p);
set_outline_width (3);
}
@ -143,7 +147,16 @@ Box::set_homogenous (bool yn)
}
void
Box::reposition_children ()
Box::size_allocate (Rect const & alloc)
{
_position = Duple (alloc.x0, alloc.y0);
_allocation = alloc;
reposition_children (alloc.width(), alloc.height());
}
void
Box::size_request (Distance& w, Distance& h) const
{
Duple previous_edge = Duple (left_margin+left_padding, top_margin+top_padding);
Distance largest_width = 0;
@ -152,7 +165,7 @@ Box::reposition_children ()
if (homogenous) {
for (std::list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
for (std::list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
Rect bb = (*i)->bounding_box();
if (bb) {
largest_height = std::max (largest_height, bb.height());
@ -166,22 +179,37 @@ Box::reposition_children ()
Rect r;
{
PBD::Unwinder<bool> uw (ignore_child_changes, true);
for (std::list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) {
(*i)->set_position (previous_edge);
if (homogenous) {
(*i)->size_allocate (uniform_size);
}
for (std::list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
double width;
double height;
Rect isize;
(*i)->size_request (width, height);
if (homogenous) {
if (((*i)->pack_options() & PackOptions (PackExpand|PackFill)) == PackOptions (PackExpand|PackFill)) {
if (orientation == Vertical) {
/* use the item's own height and our computed width */
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + uniform_size.width(), previous_edge.y + height);
} else {
/* use the item's own width and our computed height */
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + uniform_size.height());
}
} else {
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height);
}
} else {
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height);
}
std::cerr << "\tset " << (*i)->whoami() << " to " << isize << std::endl;
width = isize.width();
height = isize.height();
r = r.extend (Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height));
if (orientation == Vertical) {
@ -221,21 +249,125 @@ Box::reposition_children ()
r = r.expand (0, right_margin + right_padding, bottom_margin + bottom_padding, 0);
set (r);
w = r.width();
h = r.height();
}
void
Box::size_request (double& w, double& h) const
Box::reposition_children (Distance width, Distance height)
{
w = width();
h = height();
}
void
Box::size_allocate_children (Rect const & r)
{
std::cerr << "Box allocated " << r << std::endl;
Item::size_allocate_children (r);
Duple previous_edge = Duple (left_margin+left_padding, top_margin+top_padding);
Distance largest_width = 0;
Distance largest_height = 0;
Rect uniform_size;
std::cerr << "\n\n\n\n\nREPO C WITHIN " << width << " x " << height << std::endl;
PBD::stacktrace (std::cerr, 20);
if (homogenous) {
for (std::list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
Rect bb = (*i)->bounding_box();
if (bb) {
largest_height = std::max (largest_height, bb.height());
largest_width = std::max (largest_width, bb.width());
}
}
const Distance contents_width = width - (left_margin + left_padding + right_margin + right_padding);
const Distance contents_height = height - (top_margin + top_padding + bottom_margin + bottom_padding);
const Distance item_width = (contents_width - ((_items.size() - 1) * spacing)) / _items.size();
const Distance item_height = (contents_height - ((_items.size() - 1) * spacing)) / _items.size();
if (orientation == Vertical && (largest_width < item_width)) {
largest_width = item_width;
std::cerr << "Vertbox, use width " << width << " for largest (iw " << item_width << ")\n";
}
if (orientation == Horizontal && (largest_height < item_height)) {
largest_height = item_height;
std::cerr << "Hozbox, use height " << height << " for largest (ih " << item_height << ")\n";
}
uniform_size = Rect (0, 0, largest_width, largest_height);
std::cerr << "\tuniform size: " << uniform_size << std::endl;
}
Rect r;
{
PBD::Unwinder<bool> uw (ignore_child_changes, true);
for (std::list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
double width;
double height;
Rect isize;
(*i)->size_request (width, height);
if (homogenous) {
if (((*i)->pack_options() & PackOptions (PackExpand|PackFill)) == PackOptions (PackExpand|PackFill)) {
if (orientation == Vertical) {
/* use the item's own height and our computed width */
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + uniform_size.width(), previous_edge.y + height);
} else {
/* use the item's own width and our computed height */
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + uniform_size.height());
}
} else {
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height);
}
} else {
isize = Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height);
}
std::cerr << "\tset " << (*i)->whoami() << " to " << isize << std::endl;
(*i)->size_allocate (isize);
width = isize.width();
height = isize.height();
r = r.extend (Rect (previous_edge.x, previous_edge.y, previous_edge.x + width, previous_edge.y + height));
if (orientation == Vertical) {
Distance shift = 0;
if (!(*i)->visible()) {
/* invisible child */
if (!collapse_on_hide) {
/* still add in its size */
shift += height;
}
} else {
shift += height;
}
previous_edge = previous_edge.translate (Duple (0, spacing + shift));
} else {
Distance shift = 0;
if (!(*i)->visible()) {
if (!collapse_on_hide) {
shift += width;
}
} else {
shift += width;
}
previous_edge = previous_edge.translate (Duple (spacing + shift, 0));
}
}
}
/* left and top margins+padding already reflected in child bboxes */
r = r.expand (0, right_margin + right_padding, bottom_margin + bottom_padding, 0);
}
void
@ -268,7 +400,8 @@ Box::layout ()
Item::layout ();
if (yes_do_it) {
reposition_children ();
std::cerr << "LAYOUT with " << _allocation << std::endl;
reposition_children (_allocation.width(), _allocation.height());
}
}
@ -283,7 +416,7 @@ Box::child_changed (bool bbox_changed)
Item::child_changed (bbox_changed);
reposition_children ();
reposition_children (_allocation.width(), _allocation.height());
}
void
@ -291,7 +424,7 @@ Box::set_collapse_on_hide (bool yn)
{
if (collapse_on_hide != yn) {
collapse_on_hide = yn;
reposition_children ();
reposition_children (_allocation.width(), _allocation.height());
}
}

View File

@ -1537,14 +1537,13 @@ GtkCanvasViewport::scrolled ()
void
GtkCanvasViewport::on_size_request (Gtk::Requisition* req)
{
Duple minimum;
Duple natural;
Distance width;
Distance height;
cerr << "GCV::osr()\n";
_canvas.root()->preferred_size (minimum, natural);
cerr << "size canvas to " << natural << endl;
_canvas.request_size (natural);
_canvas.root()->size_request (width, height);
cerr << "OSR size canvas to " << width << " x " << height << endl;
_canvas.request_size (Duple (width, height));
req->width = natural.width();
req->height = natural.height();
req->width = width;
req->height = height;
}

View File

@ -68,7 +68,7 @@ public:
void compute_bounding_box () const;
void size_request (double& w, double& h) const;
void size_allocate_children (Rect const & r);
void size_allocate (Rect const & r);
protected:
Orientation orientation;
@ -80,9 +80,9 @@ public:
private:
bool collapse_on_hide;
bool homogenous;
bool ignore_child_changes;
mutable bool ignore_child_changes;
void reposition_children ();
void reposition_children (Distance width, Distance height);
};
class LIBCANVAS_API VBox : public Box

View File

@ -62,8 +62,8 @@ public:
void compute_bounding_box () const;
void preferred_size (Duple& mininum, Duple& natural) const;
void size_allocate (Rect const &);
void size_request (Distance& w, Distance& h) const;
void render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
@ -98,7 +98,7 @@ public:
void add_constraints (kiwi::Solver&, ConstrainedItem*) const;
void non_const_preferred_size (Duple& mininum, Duple& natural);
void non_const_size_request (Distance& w, Distance& h);
virtual void update_constraints ();
void add_vertical_box_constraints (kiwi::Solver& solver, BoxConstrainedItem* ci, BoxConstrainedItem* prev, double main_dimenion, double second_dimension, kiwi::Variable& alloc_var);
@ -109,7 +109,7 @@ public:
BoxPackedItems packed;
BoxConstrainedItem* pack (Item*, PackOptions primary_axis_packing, PackOptions secondary_axis_packing);
void box_preferred_size (Duple& mininum, Duple& natural) const;
void box_size_request (Distance& w, Distance& h) const;
};
}

View File

@ -151,14 +151,11 @@ public:
virtual void size_request (double& w, double& h) const;
void set_size_request (double w, double h);
virtual void preferred_size (Duple& minimum, Duple& natural) const;
virtual void size_allocate (Rect const&);
virtual void size_allocate_children (Rect const & r);
Rect allocation() const { return _allocation; }
void set_layout_sensitive (bool);
bool layout_sensitive () const { return _layout_sensitive; }
virtual Duple intrinsic_size() const { return Duple (_intrinsic_width, _intrinsic_height); }
virtual void set_intrinsic_size (Distance, Distance);
/** bounding box is the public API to get the area covered by the item
* (which may differ from its allocation). The returned Rect is in item
@ -339,8 +336,6 @@ public:
Rect _allocation;
bool _layout_sensitive;
Distance _intrinsic_width;
Distance _intrinsic_height;
/* XXX: this is a bit grubby */
std::map<std::string, void *> _data;
@ -364,8 +359,8 @@ public:
Duple position_offset() const;
bool _resize_queued;
double requested_width;
double requested_height;
double _requested_width;
double _requested_height;
private:
void init ();

View File

@ -28,7 +28,7 @@ namespace ArdourCanvas {
class LIBCANVAS_API Root : public Container
{
public:
void preferred_size (Duple&, Duple&) const;
void size_request (Distance& w, Distance& h) const;
private:
friend class Canvas;

View File

@ -108,7 +108,8 @@ ConstraintPacker::child_changed (bool bbox_changed)
for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) {
Duple i = x->first->intrinsic_size();
Duple i;
x->first->size_request (i.x, i.y);
if (r) {
@ -156,14 +157,7 @@ ConstraintPacker::constrain (kiwi::Constraint const &c)
}
void
ConstraintPacker::preferred_size (Duple& minimum, Duple& natural) const
{
const_cast<ConstraintPacker*>(this)->non_const_preferred_size (minimum, natural);
}
void
ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
ConstraintPacker::box_size_request (Distance& w, Distance& h) const
{
BoxPackedItems::size_type n_expanding = 0;
BoxPackedItems::size_type n_nonexpanding = 0;
@ -171,11 +165,12 @@ ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
Distance non_expanding_used = 0;
Distance largest = 0;
Distance largest_opposite = 0;
Duple i_min, i_natural;
Distance width;
Distance height;
for (BoxPackedItems::const_iterator o = packed.begin(); o != packed.end(); ++o) {
(*o)->item().preferred_size (i_min, i_natural);
(*o)->item().size_request (width, height);
// cerr << '\t' << (*o)->item().whoami() << " min " << i_min << " nat " << i_natural << endl;
@ -183,15 +178,15 @@ ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
n_expanding++;
if (_orientation == Vertical) {
if (i_natural.height() > largest) {
largest = i_natural.height();
if (height > largest) {
largest = height;
}
} else {
if (i_natural.width() > largest) {
largest = i_natural.width();
if (width > largest) {
largest = width;;
}
if (i_natural.height() > largest) {
largest_opposite = i_natural.height();
if (height > largest) {
largest_opposite = height;
}
}
@ -199,9 +194,9 @@ ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
n_nonexpanding++;
if (_orientation == Vertical) {
non_expanding_used += i_natural.height();
non_expanding_used += height;
} else {
non_expanding_used += i_natural.width();
non_expanding_used += width;
}
}
@ -210,12 +205,12 @@ ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
*/
if (_orientation == Vertical) {
if (i_natural.width() > largest_opposite) {
largest_opposite = i_natural.width();
if (width > largest_opposite) {
largest_opposite = width;
}
} else {
if (i_natural.height() > largest_opposite) {
largest_opposite = i_natural.height();
if (height > largest_opposite) {
largest_opposite = height;
}
}
@ -226,27 +221,29 @@ ConstraintPacker::box_preferred_size (Duple& min, Duple& natural) const
if (_orientation == Vertical) {
// cerr << "+++ vertical box, neu = " << non_expanding_used << " neuo " << non_expanding_used_opposite << " largest = " << largest << " opp " << largest_opposite << " total " << total << endl;
min.y = non_expanding_used + (n_expanding * largest) + _top_margin + _bottom_margin + ((total - 1) * _spacing);
min.x = largest_opposite + _left_margin + _right_margin;
height = non_expanding_used + (n_expanding * largest) + _top_margin + _bottom_margin + ((total - 1) * _spacing);
width= largest_opposite + _left_margin + _right_margin;
} else {
// cerr << "+++ horiz box, neu = " << non_expanding_used << " neuo " << non_expanding_used_opposite << " largest = " << largest << " opp " << largest_opposite << " total " << total << endl;
min.x = non_expanding_used + (n_expanding * largest) + _left_margin + _right_margin + ((total - 1) * _spacing);
min.y = largest_opposite + _top_margin + _bottom_margin;
width = non_expanding_used + (n_expanding * largest) + _left_margin + _right_margin + ((total - 1) * _spacing);
height = largest_opposite + _top_margin + _bottom_margin;
}
// cerr << whoami() << " preferred-size = " << min << endl;
natural = min;
}
void
ConstraintPacker::non_const_preferred_size (Duple& minimum, Duple& natural)
ConstraintPacker::size_request (Distance& w, Distance& h) const
{
const_cast<ConstraintPacker*>(this)->non_const_size_request (w, h);
}
void
ConstraintPacker::non_const_size_request (Distance& w, Distance& h)
{
/* our parent wants to know how big we are.
We may have some intrinsic size (i.e. "everything in this constraint
layout should fit into WxH". Just up two constraints on our width
layout should fit into WxH". Just add two constraints on our width
and height, and solve.
We may have one intrinsic dimension (i.e. "everything in this
@ -259,16 +256,13 @@ ConstraintPacker::non_const_preferred_size (Duple& minimum, Duple& natural)
if (packed.size() == constrained_map.size()) {
/* All child items were packed using ::pack() */
Duple m, n;
box_preferred_size (m, n);
natural = Duple (std::min (100.0, n.x), std::min (100.0, n.y));
minimum = natural;
box_size_request (w, h);
return;
}
if (_intrinsic_width == 0 && _intrinsic_height == 0) {
natural = Duple (100.0, 100.0);
minimum = natural;
if (_requested_width < 0 && _requested_height < 0) {
w = 100;
h = 100;
return;
}
@ -276,10 +270,10 @@ ConstraintPacker::non_const_preferred_size (Duple& minimum, Duple& natural)
const_cast<ConstraintPacker*>(this)->update_constraints ();
}
if (_intrinsic_width > 0) {
_solver.suggestValue (width, _intrinsic_width);
} else if (_intrinsic_height > 0) {
_solver.suggestValue (height, _intrinsic_height);
if (_requested_width > 0) {
_solver.suggestValue (width, _requested_width);
} else if (_requested_height > 0) {
_solver.suggestValue (height, _requested_height);
}
_solver.updateVariables ();
@ -287,13 +281,8 @@ ConstraintPacker::non_const_preferred_size (Duple& minimum, Duple& natural)
Rect bb (bounding_box());
Duple ret;
natural.x = std::max (bb.width(), _intrinsic_width);
natural.y = std::max (bb.height(), _intrinsic_width);
minimum.x = std::min (bb.width(), _intrinsic_width);
minimum.y = std::min (bb.height(), _intrinsic_width);
w = std::max (bb.width(), _requested_width);
h = std::max (bb.height(), _requested_width);
/* put solver back to default state */
@ -325,14 +314,14 @@ ConstraintPacker::size_allocate (Rect const & r)
} else {
n_nonexpanding++;
Duple min, natural;
Distance w, h;
(*o)->item().preferred_size (min, natural);
(*o)->item().size_request (w, h);
if (_orientation == Vertical) {
non_expanding_used += natural.height();
non_expanding_used += h;
} else {
non_expanding_used += natural.width();
non_expanding_used += w;
}
}
@ -360,9 +349,9 @@ ConstraintPacker::size_allocate (Rect const & r)
_solver.updateVariables ();
#if 0
PBD::stacktrace (cerr, 100);
// _canvas->dump (cerr);
// _solver.dump (cerr);
// PBD::stacktrace (cerr, 100);
_canvas->dump (cerr);
_solver.dump (cerr);
for (ConstrainedItemMap::const_iterator o = constrained_map.begin(); o != constrained_map.end(); ++o) {
o->second->dump (cerr);
@ -481,14 +470,14 @@ ConstraintPacker::update_constraints ()
for (BoxPackedItems::iterator o = packed.begin(); o != packed.end(); ++o) {
Duple min, natural;
Distance w, h;
(*o)->item().preferred_size (min, natural);
(*o)->item().size_request (w,h);
if (_orientation == Vertical) {
add_vertical_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, natural.height(), natural.width(), width);
add_vertical_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, h, w, width);
} else {
add_horizontal_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, natural.width(), natural.height(), height);
add_horizontal_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, w, h, height);
}
prev = o;
@ -503,15 +492,13 @@ ConstraintPacker::update_constraints ()
continue;
}
Duple min, natural;
Distance w, h;
ConstrainedItem* ci = x->second;
x->first->preferred_size (min, natural);
x->first->size_request (w, h);
_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);
_solver.addConstraint ((ci->width() == w) | kiwi::strength::medium);
_solver.addConstraint ((ci->height() == h) | kiwi::strength::medium);
add_constraints (_solver, ci);
}

View File

@ -50,9 +50,9 @@ main (int argc, char* argv[])
r2->name = "r2";
r3->name = "r3";
//r1->set_intrinsic_size (20, 20);
//r2->set_intrinsic_size (30, 30);
//r3->set_intrinsic_size (40, 40);
//r1->set_size_request (20, 20);
//r2->set_size_request (30, 30);
//r3->set_size_request (40, 40);
ConstraintPacker* vbox = new ConstraintPacker (c->root(), Vertical);
vbox->name = "vbox";

View File

@ -34,7 +34,7 @@ using std::endl;
for (int i = 0; i < SQUARED; ++i) {
rects[i] = new Rectangle (c);
rects[i]->name = string_compose ("r%1-%2", number, i);
rects[i]->set_intrinsic_size (8, 12);
rects[i]->set_size_request (8, 12);
rects[i]->set_outline_color (0xff0000ff);
rects[i]->set_fill_color (Gtkmm2ext::random_color());

View File

@ -50,9 +50,9 @@ main (int argc, char* argv[])
r2->name = "r2";
r3->name = "r3";
r1->set_intrinsic_size (20, 20);
r2->set_intrinsic_size (30, 30);
r3->set_intrinsic_size (40, 40);
r1->set_size_request (20, 20);
r2->set_size_request (30, 30);
r3->set_size_request (40, 40);
ConstraintPacker* packer = new ConstraintPacker (c->root());

View File

@ -50,9 +50,9 @@ main (int argc, char* argv[])
r2->name = "R";
r3->name = "C";
r1->set_intrinsic_size (20, 20);
r2->set_intrinsic_size (30, 30);
r3->set_intrinsic_size (40, 40);
r1->set_size_request (20, 20);
r2->set_size_request (30, 30);
r3->set_size_request (40, 40);
Text* txt = new Text (c);
txt->name = "text";
@ -74,7 +74,7 @@ main (int argc, char* argv[])
/* give it a minimum size */
packer->set_intrinsic_size (100, 100);
packer->set_size_request (100, 100);
/* add stuff */

View File

@ -45,12 +45,10 @@ Item::Item (Canvas* canvas)
, _bounding_box_dirty (true)
, _pack_options (PackOptions (0))
, _layout_sensitive (false)
, _intrinsic_width (-1.)
, _intrinsic_height(-1.)
, _lut (0)
, _resize_queued (false)
, requested_width (-1)
, requested_height (-1)
, _requested_width (-1)
, _requested_height (-1)
, _ignore_events (false)
{
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
@ -66,12 +64,10 @@ Item::Item (Item* parent)
, _bounding_box_dirty (true)
, _pack_options (PackOptions (0))
, _layout_sensitive (false)
, _intrinsic_width (-1.)
, _intrinsic_height(-1.)
, _lut (0)
, _resize_queued (false)
, requested_width (-1)
, requested_height (-1)
, _requested_width (-1)
, _requested_height (-1)
, _ignore_events (false)
{
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
@ -94,8 +90,8 @@ Item::Item (Item* parent, Duple const& p)
, _bounding_box_dirty (true)
, _pack_options (PackOptions (0))
, _layout_sensitive (false)
, _intrinsic_width (-1.)
, _intrinsic_height(-1.)
, _requested_width (-1.)
, _requested_height(-1.)
, _lut (0)
, _resize_queued (false)
, _ignore_events (false)
@ -607,11 +603,7 @@ Item::grab_focus ()
void
Item::size_allocate (Rect const & r)
{
if (_layout_sensitive) {
_position = Duple (r.x0, r.y0);
_allocation = r;
}
_position = Duple (r.x0, r.y0);
size_allocate_children (r);
}
@ -639,8 +631,8 @@ Item::size_request (double& w, double& h) const
{
Rect r (bounding_box());
w = std::max (requested_width, r.width());
h = std::max (requested_height, r.height());
w = _requested_width < 0 ? r.width() : _requested_width;
h = _requested_width < 0 ? r.height() : _requested_height;
}
void
@ -649,8 +641,8 @@ Item::set_size_request (double w, double h)
/* allow reset to zero or require that both are positive */
begin_change ();
requested_width = w;
requested_height = h;
_requested_width = w;
_requested_height = h;
_bounding_box_dirty = true;
end_change ();
}
@ -1274,51 +1266,14 @@ ArdourCanvas::operator<< (ostream& o, const Item& i)
return o;
}
void
Item::set_intrinsic_size (Distance w, Distance h)
{
_intrinsic_width = w;
_intrinsic_height = h;
}
void
Item::preferred_size (Duple& minimum, Duple& natural) const
{
/* this is the default mechanism to get a preferred size. It assumes
* items whose dimensions are essentially fixed externally by calling
* various methods that set the limits, and those same limits are used
* when computing the bounding box. So ... just get the bounding box,
* and use the dimensions it specifies.
*
* Note that items that fit this assumption also cannot have their size
* adjusted by a container that they are placed in, so their miniumum
* and natural sizes are the same.
*/
if (_intrinsic_height < 0 && _intrinsic_width < 0) {
/* intrinsic size untouched ... fall back on
arbitrary default (small) sizes.
*/
natural.x = 2;
natural.y = 2;
} else {
natural.x = _intrinsic_width;
natural.y = _intrinsic_height;
}
minimum.x = 1;
minimum.y = 1;
}
void
Item::set_layout_sensitive (bool yn)
{
_layout_sensitive = yn;
for (list<Item*>::const_iterator i = _items.begin(); i != _items.end(); ++i) {
(*i)->set_layout_sensitive (yn);
}
}
void

View File

@ -292,11 +292,12 @@ Rectangle::size_allocate (Rect const & r)
Item::size_allocate (r);
if (_layout_sensitive) {
/* Item::size_allocate() will have set _position, and then set
/* Set _position use the upper left of the Rect, and then set
the _rect member with values that use _position as the
origin.
*/
Rect r2 (0, 0, r.x1 - r.x0, r.y1 - r.y0);
// std::cerr << "rectangle " << whoami() << " set to "; dump (std::cerr); std::cerr << '\n';
set (r2);
}
}

View File

@ -34,16 +34,16 @@ Root::Root (Canvas* canvas)
}
void
Root::preferred_size (Duple& min, Duple& natural) const
Root::size_request (Distance& w, Distance& h) const
{
if (_items.size() == 1) {
cerr << "Call prefsize on " << _items.front()->whoami() << endl;
_items.front()->preferred_size (min, natural);
_items.front()->size_request (w, h);
return;
}
cerr << "use regular prefsize for root\n";
Item::preferred_size (min, natural);
Item::size_request (w, h);
}