X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fitem.cc;h=b553d8d6ae76ff0e9e9249f0e73523fa3822d2ed;hb=7a30e63eaad66ded1c47f5cdb2e0f28c3b0a1d4a;hp=90b53b5bfd5cadb1f33b20f29acbfe0ee4353bf7;hpb=053eaf77fde7639d4e200d36a9db99b2d4fc615b;p=ardour.git diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 90b53b5bfd..b553d8d6ae 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -1,6 +1,24 @@ +/* + Copyright (C) 2011-2013 Paul Davis + Author: Carl Hetherington + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include "pbd/compose.h" #include "pbd/stacktrace.h" -#include "pbd/xml++.h" #include "pbd/convert.h" #include "ardour/utils.h" @@ -52,28 +70,124 @@ Item::init () Item::~Item () { - if (_canvas) { - _canvas->item_going_away (this, _bounding_box); - } - if (_parent) { _parent->remove (this); } + + if (_canvas) { + _canvas->item_going_away (this, _bounding_box); + } } -Rect -Item::item_to_parent (Rect const & r) const +ArdourCanvas::Rect +Item::item_to_parent (ArdourCanvas::Rect const & r) const { return r.translate (_position); } +ArdourCanvas::Rect +Item::item_to_canvas (ArdourCanvas::Rect const & r) const +{ + Item const * i = this; + Duple offset; + + while (i) { + offset = offset.translate (i->position()); + i = i->parent(); + } + + return r.translate (offset); +} + +ArdourCanvas::Duple +Item::item_to_canvas (ArdourCanvas::Duple const & d) const +{ + Item const * i = this; + Duple offset; + + while (i) { + offset = offset.translate (i->position()); + i = i->parent(); + } + + return d.translate (offset); +} + +ArdourCanvas::Duple +Item::canvas_to_item (ArdourCanvas::Duple const & d) const +{ + Item const * i = this; + Duple offset; + + while (i) { + offset = offset.translate (-(i->position())); + i = i->parent(); + } + + return d.translate (offset); +} + +ArdourCanvas::Rect +Item::canvas_to_item (ArdourCanvas::Rect const & d) const +{ + Item const * i = this; + Duple offset; + + while (i) { + offset = offset.translate (-(i->position())); + i = i->parent(); + } + + return d.translate (offset); +} + +void +Item::item_to_canvas (Coord& x, Coord& y) const +{ + Duple d = item_to_canvas (Duple (x, y)); + + x = d.x; + y = d.y; +} + +void +Item::canvas_to_item (Coord& x, Coord& y) const +{ + Duple d = canvas_to_item (Duple (x, y)); + + x = d.x; + y = d.y; +} + +Duple +Item::item_to_window (ArdourCanvas::Duple const & d) const +{ + return _canvas->canvas_to_window (item_to_canvas (d)); +} + +Duple +Item::window_to_item (ArdourCanvas::Duple const & d) const +{ + return _canvas->window_to_canvas (canvas_to_item (d)); +} + +ArdourCanvas::Rect +Item::item_to_window (ArdourCanvas::Rect const & r) const +{ + return _canvas->canvas_to_window (item_to_canvas (r)); +} + /** Set the position of this item in the parent's coordinates */ void Item::set_position (Duple p) { - boost::optional bbox = bounding_box (); - boost::optional pre_change_parent_bounding_box; + boost::optional bbox = bounding_box (); + boost::optional pre_change_parent_bounding_box; + if (bbox) { + /* see the comment in Canvas::item_moved() to understand + * why we use the parent's bounding box here. + */ pre_change_parent_bounding_box = item_to_parent (bbox.get()); } @@ -145,8 +259,8 @@ Item::parent_to_item (Duple const & d) const return d.translate (- _position); } -Rect -Item::parent_to_item (Rect const & d) const +ArdourCanvas::Rect +Item::parent_to_item (ArdourCanvas::Rect const & d) const { return d.translate (- _position); } @@ -154,13 +268,14 @@ Item::parent_to_item (Rect const & d) const void Item::unparent () { - _canvas = 0; _parent = 0; } void Item::reparent (Group* new_parent) { + assert (_canvas == _parent->canvas()); + if (_parent) { _parent->remove (this); } @@ -179,7 +294,7 @@ Item::grab_focus () } /** @return Bounding box in this item's coordinates */ -boost::optional +boost::optional Item::bounding_box () const { if (_bounding_box_dirty) { @@ -193,7 +308,7 @@ Item::bounding_box () const Coord Item::height () const { - boost::optional bb = bounding_box(); + boost::optional bb = bounding_box(); if (bb) { return bb->height (); @@ -204,7 +319,7 @@ Item::height () const Coord Item::width () const { - boost::optional bb = bounding_box().get(); + boost::optional bb = bounding_box().get(); if (bb) { return bb->width (); @@ -213,7 +328,6 @@ Item::width () const return 0; } -/* XXX may be called even if bbox is not changing ... bit grotty */ void Item::begin_change () { @@ -231,25 +345,20 @@ Item::end_change () } void -Item::move (Duple movement) +Item::begin_visual_change () { - set_position (position() + movement); } void -Item::add_item_state (XMLNode* node) const +Item::end_visual_change () { - node->add_property ("x-position", string_compose ("%1", _position.x)); - node->add_property ("y-position", string_compose ("%1", _position.y)); - node->add_property ("visible", _visible ? "yes" : "no"); + _canvas->item_visual_property_changed (this); } void -Item::set_item_state (XMLNode const * node) +Item::move (Duple movement) { - _position.x = atof (node->property("x-position")->value().c_str()); - _position.y = atof (node->property("y-position")->value().c_str()); - _visible = PBD::string_is_affirmative (node->property("visible")->value()); + set_position (position() + movement); } void @@ -283,50 +392,6 @@ Item::get_data (string const & key) const return i->second; } -void -Item::item_to_canvas (Coord& x, Coord& y) const -{ - Duple d (x, y); - Item const * i = this; - - while (i) { - d = i->item_to_parent (d); - i = i->_parent; - } - - x = d.x; - y = d.y; -} - -void -Item::canvas_to_item (Coord& x, Coord& y) const -{ - Duple d (x, y); - Item const * i = this; - - while (i) { - d = i->parent_to_item (d); - i = i->_parent; - } - - x = d.x; - y = d.y; -} - -Rect -Item::item_to_canvas (Rect const & area) const -{ - Rect r = area; - Item const * i = this; - - while (i) { - r = i->item_to_parent (r); - i = i->parent (); - } - - return r; -} - void Item::set_ignore_events (bool ignore) { @@ -336,9 +401,10 @@ Item::set_ignore_events (bool ignore) void Item::dump (ostream& o) const { - boost::optional bb = bounding_box(); + boost::optional bb = bounding_box(); - o << _canvas->indent() << whatami() << ' ' << this; + o << _canvas->indent() << whatami() << ' ' << this << " Visible ? " << _visible; + o << " @ " << position(); #ifdef CANVAS_DEBUG if (!name.empty()) { @@ -348,6 +414,7 @@ Item::dump (ostream& o) const if (bb) { o << endl << _canvas->indent() << "\tbbox: " << bb.get(); + o << endl << _canvas->indent() << "\tCANVAS bbox: " << item_to_canvas (bb.get()); } else { o << " bbox unset"; }