1 #include "pbd/compose.h"
2 #include "pbd/stacktrace.h"
4 #include "pbd/convert.h"
6 #include "ardour/utils.h"
8 #include "canvas/group.h"
9 #include "canvas/item.h"
10 #include "canvas/canvas.h"
11 #include "canvas/debug.h"
15 using namespace ArdourCanvas;
17 Item::Item (Canvas* canvas)
24 Item::Item (Group* parent)
25 : _canvas (parent->canvas ())
31 Item::Item (Group* parent, Duple position)
32 : _canvas (parent->canvas())
34 , _position (position)
43 _bounding_box_dirty = true;
44 _ignore_events = false;
50 DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
56 _canvas->item_going_away (this, _bounding_box);
60 _parent->remove (this);
65 Item::item_to_parent (Rect const & r) const
67 return r.translate (_position);
70 /** Set the position of this item in the parent's coordinates */
72 Item::set_position (Duple p)
74 boost::optional<Rect> bbox = bounding_box ();
75 boost::optional<Rect> pre_change_parent_bounding_box;
77 pre_change_parent_bounding_box = item_to_parent (bbox.get());
82 _canvas->item_moved (this, pre_change_parent_bounding_box);
85 _parent->child_changed ();
90 Item::set_x_position (Coord x)
92 set_position (Duple (x, _position.y));
96 Item::set_y_position (Coord y)
98 set_position (Duple (_position.x, y));
102 Item::raise_to_top ()
105 _parent->raise_child_to_top (this);
109 Item::raise (int levels)
112 _parent->raise_child (this, levels);
116 Item::lower_to_bottom ()
119 _parent->lower_child_to_bottom (this);
126 _canvas->item_shown_or_hidden (this);
133 _canvas->item_shown_or_hidden (this);
137 Item::item_to_parent (Duple const & d) const
139 return d.translate (_position);
143 Item::parent_to_item (Duple const & d) const
145 return d.translate (- _position);
149 Item::parent_to_item (Rect const & d) const
151 return d.translate (- _position);
162 Item::reparent (Group* new_parent)
165 _parent->remove (this);
170 _parent = new_parent;
171 _canvas = _parent->canvas ();
181 /** @return Bounding box in this item's coordinates */
182 boost::optional<Rect>
183 Item::bounding_box () const
185 if (_bounding_box_dirty) {
186 compute_bounding_box ();
189 assert (!_bounding_box_dirty);
190 return _bounding_box;
194 Item::height () const
196 boost::optional<Rect> bb = bounding_box();
199 return bb->height ();
207 boost::optional<Rect> bb = bounding_box().get();
216 /* XXX may be called even if bbox is not changing ... bit grotty */
218 Item::begin_change ()
220 _pre_change_bounding_box = bounding_box ();
226 _canvas->item_changed (this, _pre_change_bounding_box);
229 _parent->child_changed ();
234 Item::move (Duple movement)
236 set_position (position() + movement);
240 Item::add_item_state (XMLNode* node) const
242 node->add_property ("x-position", string_compose ("%1", _position.x));
243 node->add_property ("y-position", string_compose ("%1", _position.y));
244 node->add_property ("visible", _visible ? "yes" : "no");
248 Item::set_item_state (XMLNode const * node)
250 _position.x = atof (node->property("x-position")->value().c_str());
251 _position.y = atof (node->property("y-position")->value().c_str());
252 _visible = PBD::string_is_affirmative (node->property("visible")->value());
259 _canvas->grab (this);
270 Item::set_data (string const & key, void* data)
276 Item::get_data (string const & key) const
278 map<string, void*>::const_iterator i = _data.find (key);
279 if (i == _data.end ()) {
287 Item::item_to_canvas (Coord& x, Coord& y) const
290 Item const * i = this;
293 d = i->item_to_parent (d);
302 Item::canvas_to_item (Coord& x, Coord& y) const
305 Item const * i = this;
308 d = i->parent_to_item (d);
317 Item::item_to_canvas (Rect const & area) const
320 Item const * i = this;
323 r = i->item_to_parent (r);
331 Item::set_ignore_events (bool ignore)
333 _ignore_events = ignore;
337 Item::dump (ostream& o) const
339 boost::optional<Rect> bb = bounding_box();
341 o << _canvas->indent() << whatami() << ' ' << this;
350 o << endl << _canvas->indent() << "\tbbox: " << bb.get();
359 Item::whatami () const
361 std::string type = demangle (typeid (*this).name());
362 return type.substr (type.find_last_of (':') + 1);
366 ArdourCanvas::operator<< (ostream& o, const Item& i)