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 (ArdourCanvas::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<ArdourCanvas::Rect> bbox = bounding_box ();
75 boost::optional<ArdourCanvas::Rect> pre_change_parent_bounding_box;
78 pre_change_parent_bounding_box = item_to_parent (bbox.get());
83 _canvas->item_moved (this, pre_change_parent_bounding_box);
86 _parent->child_changed ();
91 Item::set_x_position (Coord x)
93 set_position (Duple (x, _position.y));
97 Item::set_y_position (Coord y)
99 set_position (Duple (_position.x, y));
103 Item::raise_to_top ()
106 _parent->raise_child_to_top (this);
110 Item::raise (int levels)
113 _parent->raise_child (this, levels);
117 Item::lower_to_bottom ()
120 _parent->lower_child_to_bottom (this);
127 _canvas->item_shown_or_hidden (this);
134 _canvas->item_shown_or_hidden (this);
138 Item::item_to_parent (Duple const & d) const
140 return d.translate (_position);
144 Item::parent_to_item (Duple const & d) const
146 return d.translate (- _position);
150 Item::parent_to_item (ArdourCanvas::Rect const & d) const
152 return d.translate (- _position);
163 Item::reparent (Group* new_parent)
166 _parent->remove (this);
171 _parent = new_parent;
172 _canvas = _parent->canvas ();
182 /** @return Bounding box in this item's coordinates */
183 boost::optional<ArdourCanvas::Rect>
184 Item::bounding_box () const
186 if (_bounding_box_dirty) {
187 compute_bounding_box ();
190 assert (!_bounding_box_dirty);
191 return _bounding_box;
195 Item::height () const
197 boost::optional<ArdourCanvas::Rect> bb = bounding_box();
200 return bb->height ();
208 boost::optional<ArdourCanvas::Rect> bb = bounding_box().get();
217 /* XXX may be called even if bbox is not changing ... bit grotty */
219 Item::begin_change ()
221 _pre_change_bounding_box = bounding_box ();
227 _canvas->item_changed (this, _pre_change_bounding_box);
230 _parent->child_changed ();
235 Item::move (Duple movement)
237 set_position (position() + movement);
241 Item::add_item_state (XMLNode* node) const
243 node->add_property ("x-position", string_compose ("%1", _position.x));
244 node->add_property ("y-position", string_compose ("%1", _position.y));
245 node->add_property ("visible", _visible ? "yes" : "no");
249 Item::set_item_state (XMLNode const * node)
251 _position.x = atof (node->property("x-position")->value().c_str());
252 _position.y = atof (node->property("y-position")->value().c_str());
253 _visible = PBD::string_is_affirmative (node->property("visible")->value());
260 _canvas->grab (this);
271 Item::set_data (string const & key, void* data)
277 Item::get_data (string const & key) const
279 map<string, void*>::const_iterator i = _data.find (key);
280 if (i == _data.end ()) {
288 Item::item_to_canvas (Coord& x, Coord& y) const
291 Item const * i = this;
294 d = i->item_to_parent (d);
303 Item::canvas_to_item (Coord& x, Coord& y) const
306 Item const * i = this;
309 d = i->parent_to_item (d);
318 Item::item_to_canvas (ArdourCanvas::Rect const & area) const
320 ArdourCanvas::Rect r = area;
321 Item const * i = this;
324 r = i->item_to_parent (r);
332 Item::set_ignore_events (bool ignore)
334 _ignore_events = ignore;
338 Item::dump (ostream& o) const
340 boost::optional<ArdourCanvas::Rect> bb = bounding_box();
342 o << _canvas->indent() << whatami() << ' ' << this;
351 o << endl << _canvas->indent() << "\tbbox: " << bb.get();
360 Item::whatami () const
362 std::string type = demangle (typeid (*this).name());
363 return type.substr (type.find_last_of (':') + 1);
367 ArdourCanvas::operator<< (ostream& o, const Item& i)