canvas: provide a means of blocking change notifications from Item propagating up the object tree

This commit is contained in:
Paul Davis 2022-12-10 13:37:16 -07:00
parent 8237a8115c
commit ab34861388
2 changed files with 46 additions and 2 deletions

View File

@ -197,6 +197,9 @@ public:
virtual void hide ();
virtual void show ();
void block_change_notifications ();
void unblock_change_notifications ();
/** @return true if this item is visible (ie it will be rendered),
* otherwise false
*/
@ -374,10 +377,23 @@ private:
void find_scroll_parent ();
void propagate_show_hide ();
int change_blocked;
};
extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
/* RAII wrapper for blocking item change notifications */
class LIBCANVAS_API ItemChangeBlocker
{
public:
ItemChangeBlocker (Item& i) : item (i) { item.block_change_notifications (); }
~ItemChangeBlocker() { item.block_change_notifications (); }
private:
Item& item;
};
}
#endif

View File

@ -51,6 +51,7 @@ Item::Item (Canvas* canvas)
, _ignore_events (false)
, _scroll_translation (true)
, _bounding_box_dirty (true)
, change_blocked (0)
{
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
}
@ -71,6 +72,7 @@ Item::Item (Item* parent)
, _ignore_events (false)
, _scroll_translation (true)
, _bounding_box_dirty (true)
, change_blocked (0)
{
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
@ -98,6 +100,7 @@ Item::Item (Item* parent, Duple const& p)
, _ignore_events (false)
, _scroll_translation (true)
, _bounding_box_dirty (true)
, change_blocked (0)
{
DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
@ -750,12 +753,18 @@ Item::redraw () const
void
Item::begin_change ()
{
_pre_change_bounding_box = bounding_box ();
if (!change_blocked) {
_pre_change_bounding_box = bounding_box ();
}
}
void
Item::end_change ()
{
if (change_blocked) {
return;
}
if (visible()) {
_canvas->item_changed (this, _pre_change_bounding_box);
@ -1205,7 +1214,7 @@ Item::child_changed (bool bbox_changed)
set_bbox_dirty ();
}
if (_parent) {
if (!change_blocked && _parent) {
_parent->child_changed (bbox_changed);
}
}
@ -1359,3 +1368,22 @@ Item::disable_scroll_translation ()
{
_scroll_translation = false;
}
void
Item::block_change_notifications ()
{
if (!change_blocked) {
begin_change ();
}
change_blocked++;
}
void
Item::unblock_change_notifications ()
{
if (change_blocked) {
if (--change_blocked == 0) {
end_change ();
}
}
}