canvas: several steps further with box packing and size allocation

This commit is contained in:
Paul Davis 2021-08-03 23:21:55 -06:00
parent 88b95bc8f8
commit b416caf1bb
13 changed files with 75 additions and 80 deletions

View File

@ -152,11 +152,9 @@ Arc::covers (Duple const & point) const
}
void
Arc::size_allocate (Rect const & r)
Arc::_size_allocate (Rect const & r)
{
begin_change ();
Item::size_allocate (r);
Item::_size_allocate (r);
/* This is an arc - some section of a circle, so any difference between
* height and width cannot change what is drawn. Pick width arbitrarily
@ -167,6 +165,4 @@ Arc::size_allocate (Rect const & r)
_center = Duple ((r.width()/2.), (r.height() /2.));
_bounding_box_dirty = true;
end_change ();
}

View File

@ -147,12 +147,21 @@ Box::set_homogenous (bool yn)
}
void
Box::size_allocate (Rect const & alloc)
Box::_size_allocate (Rect const & alloc)
{
_position = Duple (alloc.x0, alloc.y0);
_allocation = alloc;
Rect old_alloc (_allocation);
Rectangle::_size_allocate (alloc);
reposition_children (alloc.width(), alloc.height());
bool width_shrinking = (old_alloc.width() > alloc.width());
bool height_shrinking = (old_alloc.height() > alloc.height());
reposition_children (alloc.width(), alloc.height(), width_shrinking, height_shrinking);
}
void
Box::size_allocate_children (Rect const &)
{
/* do nothing here */
}
void
@ -166,11 +175,11 @@ Box::size_request (Distance& w, Distance& h) const
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());
}
Distance iw, ih;
(*i)->size_request (iw, ih);
largest_height = std::max (largest_height, ih);
largest_width = std::max (largest_width, iw);
}
uniform_size = Rect (0, 0, largest_width, largest_height);
@ -205,8 +214,6 @@ Box::size_request (Distance& w, Distance& h) const
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();
@ -254,7 +261,7 @@ Box::size_request (Distance& w, Distance& h) const
}
void
Box::reposition_children (Distance width, Distance height)
Box::reposition_children (Distance width, Distance height, bool shrink_width, bool shrink_height)
{
Duple previous_edge = Duple (left_margin+left_padding, top_margin+top_padding);
@ -262,40 +269,39 @@ Box::reposition_children (Distance width, Distance height)
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());
Distance iw, ih;
(*i)->size_request (iw, ih);
if (!shrink_height) {
largest_height = std::max (largest_height, ih);
}
if (!shrink_width) {
largest_width = std::max (largest_width, iw);
}
}
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();
const Distance item_width = (contents_width - ((_items.size() - 1) * spacing));
const Distance item_height = (contents_height - ((_items.size() - 1) * spacing));;
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 == Vertical) {
if ((largest_width < item_width)) {
largest_width = item_width;
}
}
if (orientation == Horizontal && (largest_height < item_height)) {
largest_height = item_height;
std::cerr << "Hozbox, use height " << height << " for largest (ih " << item_height << ")\n";
if (orientation == Horizontal) {
if ((largest_height < item_height)) {
largest_height = item_height;
}
}
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);
@ -323,15 +329,11 @@ Box::reposition_children (Distance width, Distance height)
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;
@ -364,10 +366,6 @@ Box::reposition_children (Distance width, Distance height)
}
}
}
/* left and top margins+padding already reflected in child bboxes */
r = r.expand (0, right_margin + right_padding, bottom_margin + bottom_padding, 0);
}
void
@ -400,8 +398,7 @@ Box::layout ()
Item::layout ();
if (yes_do_it) {
std::cerr << "LAYOUT with " << _allocation << std::endl;
reposition_children (_allocation.width(), _allocation.height());
reposition_children (_allocation.width(), _allocation.height(), false, false);
}
}
@ -416,7 +413,7 @@ Box::child_changed (bool bbox_changed)
Item::child_changed (bbox_changed);
reposition_children (_allocation.width(), _allocation.height());
reposition_children (_allocation.width(), _allocation.height(), false, false);
}
void
@ -424,7 +421,7 @@ Box::set_collapse_on_hide (bool yn)
{
if (collapse_on_hide != yn) {
collapse_on_hide = yn;
reposition_children (_allocation.width(), _allocation.height());
reposition_children (_allocation.width(), _allocation.height(), false, false);
}
}

View File

@ -125,9 +125,9 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
#ifdef CANVAS_DEBUG
if (debug_render || DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
cerr << this << " RENDER: " << area << endl;
// cerr << "CANVAS @ " << this << endl;
// dump (cerr);
// cerr << "-------------------------\n";
cerr << "CANVAS @ " << this << endl;
dump (cerr);
cerr << "-------------------------\n";
}
#endif
@ -557,9 +557,9 @@ GtkCanvas::pick_current_item (Duple const & point, int state)
if (DEBUG_ENABLED(PBD::DEBUG::CanvasEnterLeave)) {
for (vector<Item const*>::const_iterator it = items.begin(); it != items.end(); ++it) {
#ifdef CANVAS_DEBUG
std::cerr << "\tItem " << (*it)->whatami() << '/' << (*it)->name << " ignore events ? " << (*it)->ignore_events() << " vis ? " << (*it)->visible() << std::endl;
// std::cerr << "\tItem " << (*it)->whatami() << '/' << (*it)->name << " ignore events ? " << (*it)->ignore_events() << " vis ? " << (*it)->visible() << std::endl;
#else
std::cerr << "\tItem " << (*it)->whatami() << '/' << " ignore events ? " << (*it)->ignore_events() << " vis ? " << (*it)->visible() << std::endl;
// std::cerr << "\tItem " << (*it)->whatami() << '/' << " ignore events ? " << (*it)->ignore_events() << " vis ? " << (*it)->visible() << std::endl;
#endif
}
}
@ -897,6 +897,7 @@ GtkCanvas::on_realize ()
void
GtkCanvas::on_size_allocate (Gtk::Allocation& a)
{
std::cerr << "GtkCanvas::size_allocate (" << a.get_width() << " x " << a.get_height() << ")\n";
EventBox::on_size_allocate (a);
if (_use_image_surface) {
@ -1133,7 +1134,6 @@ GtkCanvas::get_mouse_position (Duple& winpos) const
Glib::RefPtr<Gdk::Window> self = Glib::RefPtr<Gdk::Window>::cast_const (get_window ());
if (!self) {
std::cerr << " no self window\n";
winpos = Duple (0, 0);
return false;
}

View File

@ -37,7 +37,7 @@ public:
void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const;
void compute_bounding_box () const;
void size_allocate (Rect const & r);
void _size_allocate (Rect const & r);
void set_center (Duple const &);
void set_radius (Coord);

View File

@ -68,7 +68,8 @@ public:
void compute_bounding_box () const;
void size_request (double& w, double& h) const;
void size_allocate (Rect const & r);
void size_allocate_children (Rect const & r);
void _size_allocate (Rect const & r);
protected:
Orientation orientation;
@ -82,7 +83,7 @@ public:
bool homogenous;
mutable bool ignore_child_changes;
void reposition_children (Distance width, Distance height);
void reposition_children (Distance width, Distance height, bool width_shrink, bool height_shrink);
};
class LIBCANVAS_API VBox : public Box

View File

@ -62,7 +62,7 @@ public:
void compute_bounding_box () const;
void size_allocate (Rect 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;

View File

@ -151,7 +151,8 @@ public:
virtual void size_request (double& w, double& h) const;
void set_size_request (double w, double h);
virtual void size_allocate (Rect const&);
void size_allocate (Rect 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);

View File

@ -37,7 +37,7 @@ public:
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;
void compute_bounding_box () const;
void size_allocate (Rect const&);
void _size_allocate (Rect const&);
Rect const & get () const {
return _rect;

View File

@ -38,7 +38,7 @@ public:
void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;
void compute_bounding_box () const;
void size_allocate (Rect const &);
void _size_allocate (Rect const &);
CairoWidget const & get () const {
return _widget;

View File

@ -291,7 +291,7 @@ ConstraintPacker::non_const_size_request (Distance& w, Distance& h)
}
void
ConstraintPacker::size_allocate (Rect const & r)
ConstraintPacker::_size_allocate (Rect const & r)
{
PBD::Unwinder<bool> uw (in_alloc, true);
double expanded_size;

View File

@ -602,11 +602,24 @@ Item::grab_focus ()
void
Item::size_allocate (Rect const & r)
{
begin_change ();
_size_allocate (r);
_bounding_box_dirty = true;
end_change ();
}
void
Item::_size_allocate (Rect const & r)
{
if (_layout_sensitive) {
/* this definitely affects the item */
_position = Duple (r.x0, r.y0);
size_allocate_children (r);
/* this may have no effect on the item */
_allocation = r;
}
size_allocate_children (r);
}
void
@ -962,7 +975,6 @@ Item::add_child_bounding_boxes (bool include_hidden) const
}
Rect child_bbox = (*i)->item_to_parent (item_bbox);
if (have_one) {
bbox = bbox.extend (child_bbox);
} else {

View File

@ -91,7 +91,6 @@ Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) con
return;
}
if (_corner_radius) {
context->save ();
Gtkmm2ext::rounded_rectangle (context, self.x0, self.y0, self.width(), self.height(), _corner_radius);
@ -120,10 +119,6 @@ Rectangle::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) con
const double shift = _outline_width * 0.5;
self = self.translate (Duple (shift, shift));
if (name == "selection frame") {
std::cerr << "Render selection frame on " << self << std::endl;
}
if (_outline_what == ALL) {
if (_corner_radius) {
@ -287,9 +282,9 @@ Rectangle::vertical_fraction (double y) const
}
void
Rectangle::size_allocate (Rect const & r)
Rectangle::_size_allocate (Rect const & r)
{
Item::size_allocate (r);
Item::_size_allocate (r);
if (_layout_sensitive) {
/* Set _position use the upper left of the Rect, and then set
@ -297,7 +292,6 @@ Rectangle::size_allocate (Rect const & r)
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

@ -78,7 +78,6 @@ Widget::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
//std::cerr << "Render widget " << name << " @ " << position() << endl;
if (!_bounding_box) {
std::cerr << "no bbox\n";
return;
}
@ -86,7 +85,6 @@ Widget::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
Rect r = self.intersection (area);
if (!r) {
std::cerr << "no intersection\n";
return;
}
@ -110,9 +108,9 @@ Widget::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
}
void
Widget::size_allocate (Rect const & r)
Widget::_size_allocate (Rect const & r)
{
Item::size_allocate (r);
Item::_size_allocate (r);
Gtk::Allocation alloc;
alloc.set_x (0);
alloc.set_y (0);
@ -124,15 +122,11 @@ Widget::size_allocate (Rect const & r)
void
Widget::compute_bounding_box () const
{
std::cerr << "cbbox for widget\n";
GtkRequisition req = { 0, 0 };
Gtk::Allocation alloc;
_widget.size_request (req);
std::cerr << "widget wants " << req.width << " x " << req.height << "\n";
_bounding_box = Rect (0, 0, req.width, req.height);
/* make sure the widget knows that it got what it asked for */