Ardour  9.0-pre0-1463-gd654d98661
canvas/canvas/item.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Carl Hetherington <carl@carlh.net>
3  * Copyright (C) 2013-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2014-2015 Robin Gareus <robin@gareus.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef __CANVAS_ITEM_H__
22 #define __CANVAS_ITEM_H__
23 
24 #include <stdint.h>
25 
26 #include <ydk/gdk.h>
27 
28 #include <cairomm/context.h>
29 
30 #include "pbd/signals.h"
31 
32 #include "canvas/fill.h"
33 #include "canvas/lookup_table.h"
34 #include "canvas/outline.h"
35 #include "canvas/types.h"
36 #include "canvas/visibility.h"
37 
38 namespace ArdourCanvas
39 {
40 
41 class Canvas;
42 class ScrollGroup;
43 class ConstrainedItem;
44 
56 class LIBCANVAS_API Item : public Fill, public Outline
57 {
58 public:
59  Item (Canvas *);
60  Item (Item *);
61  Item (Item *, Duple const& p);
62  virtual ~Item ();
63 
64  void redraw () const;
65 
77  virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0;
78 
84  virtual void prepare_for_render (Rect const & area) const { }
85  virtual bool needs_prepare_for_render () const { return false; }
86 
96  virtual void add_items_at_point (Duple point, std::vector<Item const *>& items) const;
97 
103  virtual bool covers (Duple const& point) const;
104 
106  virtual void compute_bounding_box () const = 0;
107 
108  void grab ();
109  void ungrab ();
110 
111  void unparent ();
112  void reparent (Item *, bool already_added = false);
113 
115  Item* parent () const {
116  return _parent;
117  }
118 
119  uint32_t depth() const;
120  const Item* closest_ancestor_with (const Item& other) const;
121  bool common_ancestor_within (uint32_t, const Item& other) const;
122 
126  bool is_ancestor_of (const Item& candidate) const {
127  return candidate.is_descendant_of (*this);
128  }
129 
133  bool is_descendant_of (const Item& candidate) const;
134 
138  void move (Duple);
139 
141  Duple position () const {
142  return _position;
143  }
144 
147 
148  ScrollGroup* scroll_parent() const { return _scroll_parent; }
149 
150  /* layout-related methods */
151 
152  virtual void size_request (double& w, double& h) const;
153  void set_size_request (double w, double h);
154  void set_size_request_to_display_given_text (const std::vector<std::string>& strings, gint hpadding, gint vpadding);
155 
156  void size_allocate (Rect const&);
157  virtual void _size_allocate (Rect const&);
158  virtual void size_allocate_children (Rect const & r);
159  Rect allocation() const { return _allocation; }
160  void set_layout_sensitive (bool);
161  bool layout_sensitive () const { return _layout_sensitive; }
162 
168  Rect bounding_box () const;
169 
170  Coord height() const;
171  Coord width() const;
172 
173  Duple item_to_parent (Duple const &) const;
174  Rect item_to_parent (Rect const &) const;
175  Duple parent_to_item (Duple const &) const;
176  Rect parent_to_item (Rect const &) const;
177 
178  /* XXX: it's a pity these two aren't the same form as item_to_parent etc.,
179  * but it makes a bit of a mess in the rest of the code if they are not.
180  */
181  void canvas_to_item (Coord &, Coord &) const;
182  void item_to_canvas (Coord &, Coord &) const;
183 
184  Duple canvas_to_item (Duple const&) const;
185  Rect item_to_canvas (Rect const&) const;
186  Duple item_to_canvas (Duple const&) const;
187  Rect canvas_to_item (Rect const&) const;
188 
189  Duple item_to_window (Duple const&, bool rounded = true) const;
190  Duple window_to_item (Duple const&) const;
191  Rect item_to_window (Rect const&, bool rounded = true) const;
192  Rect window_to_item (Rect const&) const;
193 
194  void raise_to_top ();
195  void raise (int);
197 
198  virtual void hide ();
199  virtual void show ();
200 
203 
207  bool self_visible () const {
208  return _visible;
209  }
210 
211  bool visible () const;
212 
214  Canvas* canvas () const {
215  return _canvas;
216  }
217 
218  void set_ignore_events (bool);
219  bool ignore_events () const {
220  return _ignore_events;
221  }
222 
223  void set_data (std::string const &, void *);
224  void* get_data (std::string const &) const;
225 
226  /* nested item ("grouping") API */
227  virtual void add (Item *);
228  virtual void add_front (Item *);
229  virtual void remove (Item *);
230  /* XXX this should become virtual also */
231  void clear (bool with_delete = false);
232 
233  std::list<Item*> const & items () const {
234  return _items;
235  }
236 
238  void raise_child (Item *, int);
240  virtual void child_changed (bool bbox_changed);
241 
242  PackOptions pack_options () const { return _pack_options; }
244 
246 
247 
248  /* This is a sigc++ signal because it is solely
249  concerned with GUI stuff and is thus single-threaded
250  */
251 
252  template <class T>
254  typedef T result_type;
255  template <class U>
256  result_type operator () (U first, U last) {
257  while (first != last) {
258  if (*first) {
259  return true;
260  }
261  ++first;
262  }
263  return false;
264  }
265  };
266 
267  sigc::signal1<bool, GdkEvent*, EventAccumulator<bool> > Event;
268 
269 #ifdef CANVAS_DEBUG
270  std::string name;
271  std::string whoami() const { return whatami() + '/' + name; }
272 #else
273  std::string whoami() const { return whatami(); }
274 #endif
275 
276  const std::string& tooltip () const { return _tooltip; }
277  void set_tooltip (const std::string&);
278 
281 
282  virtual void dump (std::ostream&) const;
283  std::string whatami() const;
284 
285  bool resize_queued() const { return _resize_queued; }
286  void queue_resize();
287 
288  bool scroll_translation() const { return _scroll_translation; }
290 
291  /* only derived containers need to implement this, but this
292  is where they compute the sizes and position and their
293  children. A fixed-layout container (i.e. one where every child
294  has just had its position fixed via ::set_position()) does not
295  need to do anything here. Only box/table/grid style containers,
296  where the position of one child depends on the position and size of
297  other children, need to provide an implementation.
298  */
299  virtual void layout();
300 
301  protected:
302  friend class Fill;
303  friend class Outline;
304 
308  void begin_change ();
312  void end_change ();
321 
330  bool _visible;
333 
337 
338  void set_bbox_clean () const;
339  void set_bbox_dirty () const;
340  bool bbox_dirty() const { return _bounding_box_dirty; }
341 
344 
345  /* XXX: this is a bit grubby */
346  std::map<std::string, void *> _data;
347 
348  /* nesting ("grouping") API */
349 
350  void invalidate_lut () const;
351  void clear_items (bool with_delete);
352 
353  void ensure_lut () const;
354  mutable LookupTable* _lut;
355  /* our items, from lowest to highest in the stack */
356  std::list<Item*> _items;
357 
358  void add_child_bounding_boxes (bool include_hidden = false) const;
359  void render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
360  void prepare_for_render_children (Rect const & area) const;
361 
363  public:
365 
369 
370 private:
371  void init ();
372 
373  std::string _tooltip;
377  mutable bool _bounding_box_dirty;
378 
381 
383 };
384 
385 extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
386 
387 /* RAII wrapper for blocking item change notifications */
388 
390 {
391  public:
392  ItemChangeBlocker (Item& i) : item (i) { item.block_change_notifications (); }
393  ~ItemChangeBlocker() { item.block_change_notifications (); }
394  private:
396 };
397 
398 }
399 
400 #endif
#define LIBCANVAS_API
virtual void remove(Item *)
void raise_child(Item *, int)
std::list< Item * > const & items() const
Duple position_offset() const
void add_child_bounding_boxes(bool include_hidden=false) const
Rect window_to_item(Rect const &) const
void set_bbox_dirty() const
Rect parent_to_item(Rect const &) const
void item_to_canvas(Coord &, Coord &) const
bool layout_sensitive() const
void propagate_show_hide()
void set_bbox_clean() const
virtual void _size_allocate(Rect const &)
std::list< Item * > _items
void start_tooltip_timeout()
virtual void add_items_at_point(Duple point, std::vector< Item const * > &items) const
virtual void render(Rect const &area, Cairo::RefPtr< Cairo::Context >) const =0
void set_x_position(Coord)
Rect item_to_parent(Rect const &) const
sigc::signal1< bool, GdkEvent *, EventAccumulator< bool > > Event
Duple canvas_to_item(Duple const &) const
void block_change_notifications()
void set_position(Duple)
void set_pack_options(PackOptions)
void disable_scroll_translation()
void redraw() const
const Item * closest_ancestor_with(const Item &other) const
Rect item_to_canvas(Rect const &) const
std::string whoami() const
Rect bounding_box() const
Item(Item *, Duple const &p)
virtual void child_changed(bool bbox_changed)
PackOptions pack_options() const
void invalidate_lut() const
virtual bool covers(Duple const &point) const
void begin_visual_change()
const std::string & tooltip() const
virtual void size_allocate_children(Rect const &r)
void set_layout_sensitive(bool)
void clear(bool with_delete=false)
Coord height() const
void set_size_request_to_display_given_text(const std::vector< std::string > &strings, gint hpadding, gint vpadding)
bool is_descendant_of(const Item &candidate) const
bool ignore_events() const
void unblock_change_notifications()
uint32_t depth() const
Duple item_to_window(Duple const &, bool rounded=true) const
Canvas * canvas() const
Duple item_to_parent(Duple const &) const
Duple scroll_offset() const
void canvas_to_item(Coord &, Coord &) const
void lower_child_to_bottom(Item *)
Coord width() const
std::string whatami() const
Duple window_to_item(Duple const &) const
Duple item_to_canvas(Duple const &) const
void set_ignore_events(bool)
virtual void show()
Duple parent_to_item(Duple const &) const
void render_children(Rect const &area, Cairo::RefPtr< Cairo::Context > context) const
Rect item_to_window(Rect const &, bool rounded=true) const
void size_allocate(Rect const &)
void set_tooltip(const std::string &)
Duple window_origin() const
void raise_child_to_top(Item *)
virtual void dump(std::ostream &) const
std::map< std::string, void * > _data
void set_size_request(double w, double h)
void stop_tooltip_timeout()
void ensure_lut() const
void prepare_for_render_children(Rect const &area) const
bool is_ancestor_of(const Item &candidate) const
virtual void layout()
ScrollGroup * _scroll_parent
void move(Duple)
virtual void add(Item *)
virtual void size_request(double &w, double &h) const
void set_y_position(Coord)
bool scroll_translation() const
virtual void hide()
bool common_ancestor_within(uint32_t, const Item &other) const
bool resize_queued() const
void set_data(std::string const &, void *)
void reparent(Item *, bool already_added=false)
bool visible() const
Duple canvas_origin() const
ScrollGroup * scroll_parent() const
static int default_items_per_cell
void clear_items(bool with_delete)
virtual void compute_bounding_box() const =0
virtual void prepare_for_render(Rect const &area) const
virtual void add_front(Item *)
virtual bool needs_prepare_for_render() const
Rect canvas_to_item(Rect const &) const
void * get_data(std::string const &) const
GtkImageIconNameData name
Definition: gtkimage.h:6
std::ostream & operator<<(std::ostream &, const ArdourCanvas::Item &)