Ardour  9.0-pre0-582-g084a23a80d
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 <gdk/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 
95  virtual void add_items_at_point (Duple point, std::vector<Item const *>& items) const;
96 
102  virtual bool covers (Duple const& point) const;
103 
105  virtual void compute_bounding_box () const = 0;
106 
107  void grab ();
108  void ungrab ();
109 
110  void unparent ();
111  void reparent (Item *, bool already_added = false);
112 
114  Item* parent () const {
115  return _parent;
116  }
117 
118  uint32_t depth() const;
119  const Item* closest_ancestor_with (const Item& other) const;
120  bool common_ancestor_within (uint32_t, const Item& other) const;
121 
125  bool is_ancestor_of (const Item& candidate) const {
126  return candidate.is_descendant_of (*this);
127  }
128 
132  bool is_descendant_of (const Item& candidate) const;
133 
137  void move (Duple);
138 
140  Duple position () const {
141  return _position;
142  }
143 
146 
147  ScrollGroup* scroll_parent() const { return _scroll_parent; }
148 
149  /* layout-related methods */
150 
151  virtual void size_request (double& w, double& h) const;
152  void set_size_request (double w, double h);
153  void set_size_request_to_display_given_text (const std::vector<std::string>& strings, gint hpadding, gint vpadding);
154 
155  void size_allocate (Rect const&);
156  virtual void _size_allocate (Rect const&);
157  virtual void size_allocate_children (Rect const & r);
158  Rect allocation() const { return _allocation; }
159  void set_layout_sensitive (bool);
160  bool layout_sensitive () const { return _layout_sensitive; }
161 
167  Rect bounding_box () const;
168 
169  Coord height() const;
170  Coord width() const;
171 
172  Duple item_to_parent (Duple const &) const;
173  Rect item_to_parent (Rect const &) const;
174  Duple parent_to_item (Duple const &) const;
175  Rect parent_to_item (Rect const &) const;
176 
177  /* XXX: it's a pity these two aren't the same form as item_to_parent etc.,
178  * but it makes a bit of a mess in the rest of the code if they are not.
179  */
180  void canvas_to_item (Coord &, Coord &) const;
181  void item_to_canvas (Coord &, Coord &) const;
182 
183  Duple canvas_to_item (Duple const&) const;
184  Rect item_to_canvas (Rect const&) const;
185  Duple item_to_canvas (Duple const&) const;
186  Rect canvas_to_item (Rect const&) const;
187 
188  Duple item_to_window (Duple const&, bool rounded = true) const;
189  Duple window_to_item (Duple const&) const;
190  Rect item_to_window (Rect const&, bool rounded = true) const;
191  Rect window_to_item (Rect const&) const;
192 
193  void raise_to_top ();
194  void raise (int);
196 
197  virtual void hide ();
198  virtual void show ();
199 
202 
206  bool self_visible () const {
207  return _visible;
208  }
209 
210  bool visible () const;
211 
213  Canvas* canvas () const {
214  return _canvas;
215  }
216 
217  void set_ignore_events (bool);
218  bool ignore_events () const {
219  return _ignore_events;
220  }
221 
222  void set_data (std::string const &, void *);
223  void* get_data (std::string const &) const;
224 
225  /* nested item ("grouping") API */
226  virtual void add (Item *);
227  virtual void add_front (Item *);
228  virtual void remove (Item *);
229  /* XXX this should become virtual also */
230  void clear (bool with_delete = false);
231 
232  std::list<Item*> const & items () const {
233  return _items;
234  }
235 
237  void raise_child (Item *, int);
239  virtual void child_changed (bool bbox_changed);
240 
241  PackOptions pack_options () const { return _pack_options; }
243 
245 
246 
247  /* This is a sigc++ signal because it is solely
248  concerned with GUI stuff and is thus single-threaded
249  */
250 
251  template <class T>
253  typedef T result_type;
254  template <class U>
255  result_type operator () (U first, U last) {
256  while (first != last) {
257  if (*first) {
258  return true;
259  }
260  ++first;
261  }
262  return false;
263  }
264  };
265 
266  sigc::signal1<bool, GdkEvent*, EventAccumulator<bool> > Event;
267 
268 #ifdef CANVAS_DEBUG
269  std::string name;
270  std::string whoami() const { return whatami() + '/' + name; }
271 #else
272  std::string whoami() const { return whatami(); }
273 #endif
274 
275  const std::string& tooltip () const { return _tooltip; }
276  void set_tooltip (const std::string&);
277 
280 
281  virtual void dump (std::ostream&) const;
282  std::string whatami() const;
283 
284  bool resize_queued() const { return _resize_queued; }
285  void queue_resize();
286 
287  bool scroll_translation() const { return _scroll_translation; }
289 
290  /* only derived containers need to implement this, but this
291  is where they compute the sizes and position and their
292  children. A fixed-layout container (i.e. one where every child
293  has just had its position fixed via ::set_position()) does not
294  need to do anything here. Only box/table/grid style containers,
295  where the position of one child depends on the position and size of
296  other children, need to provide an implementation.
297  */
298  virtual void layout();
299 
300  protected:
301  friend class Fill;
302  friend class Outline;
303 
307  void begin_change ();
311  void end_change ();
320 
329  bool _visible;
332 
336 
337  void set_bbox_clean () const;
338  void set_bbox_dirty () const;
339  bool bbox_dirty() const { return _bounding_box_dirty; }
340 
343 
344  /* XXX: this is a bit grubby */
345  std::map<std::string, void *> _data;
346 
347  /* nesting ("grouping") API */
348 
349  void invalidate_lut () const;
350  void clear_items (bool with_delete);
351 
352  void ensure_lut () const;
353  mutable LookupTable* _lut;
354  /* our items, from lowest to highest in the stack */
355  std::list<Item*> _items;
356 
357  void add_child_bounding_boxes (bool include_hidden = false) const;
358  void render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
359  void prepare_for_render_children (Rect const & area) const;
360 
362  public:
364 
368 
369 private:
370  void init ();
371 
372  std::string _tooltip;
376  mutable bool _bounding_box_dirty;
377 
380 
382 };
383 
384 extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
385 
386 /* RAII wrapper for blocking item change notifications */
387 
389 {
390  public:
391  ItemChangeBlocker (Item& i) : item (i) { item.block_change_notifications (); }
392  ~ItemChangeBlocker() { item.block_change_notifications (); }
393  private:
395 };
396 
397 }
398 
399 #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 *)
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 &)