From b416caf1bb484d059fd76519d5645d1944125d1f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 3 Aug 2021 23:21:55 -0600 Subject: [PATCH] canvas: several steps further with box packing and size allocation --- libs/canvas/arc.cc | 8 +-- libs/canvas/box.cc | 81 +++++++++++++------------- libs/canvas/canvas.cc | 12 ++-- libs/canvas/canvas/arc.h | 2 +- libs/canvas/canvas/box.h | 5 +- libs/canvas/canvas/constraint_packer.h | 2 +- libs/canvas/canvas/item.h | 3 +- libs/canvas/canvas/rectangle.h | 2 +- libs/canvas/canvas/widget.h | 2 +- libs/canvas/constraint_packer.cc | 2 +- libs/canvas/item.cc | 16 ++++- libs/canvas/rectangle.cc | 10 +--- libs/canvas/widget.cc | 10 +--- 13 files changed, 75 insertions(+), 80 deletions(-) diff --git a/libs/canvas/arc.cc b/libs/canvas/arc.cc index d734286531..0ca1898586 100644 --- a/libs/canvas/arc.cc +++ b/libs/canvas/arc.cc @@ -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 (); } diff --git a/libs/canvas/box.cc b/libs/canvas/box.cc index 5ab7e1b461..df45a176a5 100644 --- a/libs/canvas/box.cc +++ b/libs/canvas/box.cc @@ -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::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::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 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); } } diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index deded75e48..6d8900a62b 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -125,9 +125,9 @@ Canvas::render (Rect const & area, Cairo::RefPtr 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::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 self = Glib::RefPtr::cast_const (get_window ()); if (!self) { - std::cerr << " no self window\n"; winpos = Duple (0, 0); return false; } diff --git a/libs/canvas/canvas/arc.h b/libs/canvas/canvas/arc.h index ca99870348..9ea717d481 100644 --- a/libs/canvas/canvas/arc.h +++ b/libs/canvas/canvas/arc.h @@ -37,7 +37,7 @@ public: void render (Rect const & area, Cairo::RefPtr) 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); diff --git a/libs/canvas/canvas/box.h b/libs/canvas/canvas/box.h index 9dbb1c0d60..fc7ccf5b5a 100644 --- a/libs/canvas/canvas/box.h +++ b/libs/canvas/canvas/box.h @@ -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 diff --git a/libs/canvas/canvas/constraint_packer.h b/libs/canvas/canvas/constraint_packer.h index a751708c28..2871d51863 100644 --- a/libs/canvas/canvas/constraint_packer.h +++ b/libs/canvas/canvas/constraint_packer.h @@ -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 context) const; diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h index e0eb1b1d31..8a0fb05d55 100644 --- a/libs/canvas/canvas/item.h +++ b/libs/canvas/canvas/item.h @@ -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); diff --git a/libs/canvas/canvas/rectangle.h b/libs/canvas/canvas/rectangle.h index 64e9f35fc8..2ce8b18b1f 100644 --- a/libs/canvas/canvas/rectangle.h +++ b/libs/canvas/canvas/rectangle.h @@ -37,7 +37,7 @@ public: void render (Rect const &, Cairo::RefPtr) const; void compute_bounding_box () const; - void size_allocate (Rect const&); + void _size_allocate (Rect const&); Rect const & get () const { return _rect; diff --git a/libs/canvas/canvas/widget.h b/libs/canvas/canvas/widget.h index 974fc8c473..c322901d3a 100644 --- a/libs/canvas/canvas/widget.h +++ b/libs/canvas/canvas/widget.h @@ -38,7 +38,7 @@ public: void render (Rect const &, Cairo::RefPtr) const; void compute_bounding_box () const; - void size_allocate (Rect const &); + void _size_allocate (Rect const &); CairoWidget const & get () const { return _widget; diff --git a/libs/canvas/constraint_packer.cc b/libs/canvas/constraint_packer.cc index a1e2e1c121..96cdadc8d2 100644 --- a/libs/canvas/constraint_packer.cc +++ b/libs/canvas/constraint_packer.cc @@ -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 uw (in_alloc, true); double expanded_size; diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index fe9293bf56..ae9a47a448 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -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 { diff --git a/libs/canvas/rectangle.cc b/libs/canvas/rectangle.cc index 04830a7aee..224a7e8dee 100644 --- a/libs/canvas/rectangle.cc +++ b/libs/canvas/rectangle.cc @@ -91,7 +91,6 @@ Rectangle::render (Rect const & area, Cairo::RefPtr 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 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); } } diff --git a/libs/canvas/widget.cc b/libs/canvas/widget.cc index 08a39bdb36..19c7e76ea0 100644 --- a/libs/canvas/widget.cc +++ b/libs/canvas/widget.cc @@ -78,7 +78,6 @@ Widget::render (Rect const & area, Cairo::RefPtr 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 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 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 */