X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fitem.cc;h=ab8764a97a9677ad5ac138d4d85c27e054b83bb3;hb=736038556fa41607d54a57fd3339d4fd1782bddf;hp=593e7b4316a783af4fc521744765e13c453ec01f;hpb=ad017365f7a73f8ba57f667cc1aa36478b48c50e;p=ardour.git diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 593e7b4316..ab8764a97a 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -104,6 +104,21 @@ Item::~Item () delete _lut; } +bool +Item::visible() const +{ + Item const * i = this; + + while (i) { + if (!i->self_visible()) { + return false; + } + i = i->parent(); + } + + return true; +} + Duple Item::canvas_origin () const { @@ -216,14 +231,16 @@ Item::window_to_item (ArdourCanvas::Duple const & d) const } ArdourCanvas::Rect -Item::item_to_window (ArdourCanvas::Rect const & r) const +Item::item_to_window (ArdourCanvas::Rect const & r, bool rounded) const { Rect ret = item_to_canvas (r).translate (-scroll_offset()); - ret.x0 = round (ret.x0); - ret.x1 = round (ret.x1); - ret.y0 = round (ret.y0); - ret.y1 = round (ret.y1); + if (rounded) { + ret.x0 = round (ret.x0); + ret.x1 = round (ret.x1); + ret.y0 = round (ret.y0); + ret.y1 = round (ret.y1); + } return ret; } @@ -254,10 +271,17 @@ Item::set_position (Duple p) _position = p; - _canvas->item_moved (this, pre_change_parent_bounding_box); + /* only update canvas and parent if visible. Otherwise, this + will be done when ::show() is called. + */ + + if (visible()) { + _canvas->item_moved (this, pre_change_parent_bounding_box); + - if (_parent) { - _parent->child_changed (); + if (_parent) { + _parent->child_changed (); + } } } @@ -303,15 +327,28 @@ Item::hide () if (_visible) { _visible = false; - /* recompute parent bounding box, which may alter now that this - * child is hidden. - */ + /* children are all hidden because we are hidden, no need + to propagate change because our bounding box necessarily + includes them all already. thus our being hidden results + in (a) a redraw of the entire bounding box (b) no children + will be drawn. - if (_parent) { - _parent->child_changed (); + BUT ... current item in canvas might be one of our children, + which is now hidden. So propagate away. + */ + + for (list::iterator i = _items.begin(); i != _items.end(); ++i) { + + if ((*i)->self_visible()) { + /* item was visible but is now hidden because + we (its parent) are hidden + */ + (*i)->propagate_show_hide (); + } } - _canvas->item_shown_or_hidden (this); + + propagate_show_hide (); } } @@ -319,16 +356,32 @@ void Item::show () { if (!_visible) { - _visible = true; - /* bounding box may have changed while we were hidden */ + _visible = true; - if (_parent) { - _parent->child_changed (); + for (list::iterator i = _items.begin(); i != _items.end(); ++i) { + if ((*i)->self_visible()) { + /* item used to be hidden by us (its parent), + but is now visible + */ + (*i)->propagate_show_hide (); + } } - _canvas->item_shown_or_hidden (this); + propagate_show_hide (); + } +} + +void +Item::propagate_show_hide () +{ + /* bounding box may have changed while we were hidden */ + + if (_parent) { + _parent->child_changed (); } + + _canvas->item_shown_or_hidden (this); } Duple @@ -543,7 +596,7 @@ Item::height () const Coord Item::width () const { - boost::optional bb = bounding_box().get(); + boost::optional bb = bounding_box(); if (bb) { return bb->width (); @@ -555,7 +608,7 @@ Item::width () const void Item::redraw () const { - if (_visible && _bounding_box && _canvas) { + if (visible() && _bounding_box && _canvas) { _canvas->request_redraw (item_to_window (_bounding_box.get())); } } @@ -569,7 +622,7 @@ Item::begin_change () void Item::end_change () { - if (_visible) { + if (visible()) { _canvas->item_changed (this, _pre_change_bounding_box); if (_parent) { @@ -586,7 +639,7 @@ Item::begin_visual_change () void Item::end_visual_change () { - if (_visible) { + if (visible()) { _canvas->item_visual_property_changed (this); } } @@ -715,7 +768,7 @@ Item::render_children (Rect const & area, Cairo::RefPtr context) continue; } - Rect item = (*i)->item_to_window (item_bbox.get()); + Rect item = (*i)->item_to_window (item_bbox.get(), false); boost::optional d = item.intersection (area); if (d) { @@ -892,7 +945,9 @@ Item::raise_child_to_top (Item* i) _items.remove (i); _items.push_back (i); + invalidate_lut (); + redraw (); } void @@ -911,6 +966,7 @@ Item::raise_child (Item* i, int levels) _items.insert (j, i); invalidate_lut (); + redraw (); } void @@ -924,6 +980,7 @@ Item::lower_child_to_bottom (Item* i) _items.remove (i); _items.push_front (i); invalidate_lut (); + redraw (); } void @@ -1010,7 +1067,7 @@ Item::dump (ostream& o) const { boost::optional bb = bounding_box(); - o << _canvas->indent() << whatami() << ' ' << this << " Visible ? " << _visible; + o << _canvas->indent() << whatami() << ' ' << this << " self-Visible ? " << self_visible() << " visible ? " << visible(); o << " @ " << position(); #ifdef CANVAS_DEBUG @@ -1034,7 +1091,8 @@ Item::dump (ostream& o) const o << _canvas->indent(); o << " @ " << position(); o << " Items: " << _items.size(); - o << " Visible ? " << _visible; + o << " Self-Visible ? " << self_visible(); + o << " Visible ? " << visible(); boost::optional bb = bounding_box();