Change some declarations from 'struct' to 'class' (and vice-versa)
[ardour.git] / libs / canvas / canvas / item.h
index da061f5bfc7a7e6b975f28beada5df157a701501..9b058ab83afd1d366d4b809899d04191ac07033b 100644 (file)
 
 #include "canvas/visibility.h"
 #include "canvas/types.h"
+#include "canvas/fill.h"
+#include "canvas/outline.h"
+#include "canvas/lookup_table.h"
 
 namespace ArdourCanvas
 {
+struct Rect;   
 
 class Canvas;
-class Group;
-class Rect;    
+class ScrollGroup;
 
 /** The parent class for anything that goes on the canvas.
  *
@@ -49,12 +52,12 @@ class Rect;
  *  and all except the `root group' have a pointer to their parent group.
  */
        
-class LIBCANVAS_API Item
+class LIBCANVAS_API Item : public Fill, public Outline
 {
 public:
        Item (Canvas *);
-       Item (Group *);
-       Item (Group *, Duple);
+       Item (Item *);
+       Item (Item *, Duple const& p);
        virtual ~Item ();
 
         void redraw () const;
@@ -72,9 +75,16 @@ public:
         */
        virtual void render (Rect const & area, Cairo::RefPtr<Cairo::Context>) const = 0;
 
-       virtual void add_items_at_point (Duple, std::vector<Item const *>& items) const {
-               items.push_back (this);
-       }
+       /** Adds one or more items to the vector @param items based on their
+        * covering @param point which is in **window** coordinates
+        *
+        * Note that Item::add_items_at_window_point() is only intended to be 
+        * called on items already looked up in a LookupTable (i.e. by a
+        * parent) and thus known to cover @param point already.
+        *
+        * Derived classes may add more items than themselves (e.g. containers).
+        */
+       virtual void add_items_at_point (Duple /*point*/, std::vector<Item const *>& items) const;
 
         virtual bool covers (Duple const &) const;
 
@@ -85,10 +95,10 @@ public:
        void ungrab ();
        
        void unparent ();
-       void reparent (Group *);
+       void reparent (Item *);
 
        /** @return Parent group, or 0 if this is the root group */
-       Group* parent () const {
+       Item* parent () const {
                return _parent;
        }
     
@@ -117,6 +127,11 @@ public:
                return _position;
        }
 
+       Duple window_origin() const;
+       Duple canvas_origin() const;
+
+       ScrollGroup* scroll_parent() const { return _scroll_parent; }
+
        boost::optional<Rect> bounding_box () const;
         Coord height() const;
         Coord width() const;
@@ -125,21 +140,23 @@ public:
        Rect item_to_parent (Rect const &) const;
        Duple parent_to_item (Duple const &) const;
        Rect parent_to_item (Rect const &) const;
-       /* XXX: it's a pity these aren't the same form as item_to_parent etc.,
+
+       /* XXX: it's a pity these two aren't the same form as item_to_parent etc.,
           but it makes a bit of a mess in the rest of the code if they are not.
        */
-
         void canvas_to_item (Coord &, Coord &) const;
-        Duple canvas_to_item (Duple const &) const;
        void item_to_canvas (Coord &, Coord &) const;
-       Rect item_to_canvas (Rect const &) const;
-       Rect canvas_to_item (Rect const &) const;
-        Duple item_to_canvas (Duple const &) const;
 
-        Duple item_to_window (Duple const&) const;
+        Duple canvas_to_item (Duple const&) const;
+       Rect item_to_canvas (Rect const&) const;
+        Duple item_to_canvas (Duple const&) const;
+       Rect canvas_to_item (Rect const&) const;
+
+        Duple item_to_window (Duple const&, bool rounded = true) const;
         Duple window_to_item (Duple const&) const;
         Rect item_to_window (Rect const&) const;
-
+        Rect window_to_item (Rect const&) const;
+        
        void raise_to_top ();
        void raise (int);
        void lower_to_bottom ();
@@ -166,6 +183,21 @@ public:
 
        void set_data (std::string const &, void *);
        void* get_data (std::string const &) const;
+
+       /* nested item ("grouping") API */
+       void add (Item *);
+       void remove (Item *);
+        void clear (bool with_delete = false);
+       std::list<Item*> const & items () const {
+               return _items;
+       }
+       void raise_child_to_top (Item *);
+       void raise_child (Item *, int);
+       void lower_child_to_bottom (Item *);
+       void child_changed ();
+
+       static int default_items_per_cell;
+
        
        /* This is a sigc++ signal because it is solely
           concerned with GUI stuff and is thus single-threaded
@@ -200,6 +232,8 @@ public:
         std::string whatami() const;
 
 protected:
+       friend class Fill;
+       friend class Outline;
 
         /** To be called at the beginning of any property change that
         *  may alter the bounding box of this item
@@ -220,7 +254,9 @@ protected:
 
        Canvas* _canvas;
        /** parent group; may be 0 if we are the root group or if we have been unparent()ed */
-       Group* _parent;
+       Item* _parent;
+       /** scroll parent group; may be 0 if we are the root group or if we have been unparent()ed */
+       ScrollGroup* _scroll_parent;
        /** position of this item in parent coordinates */
        Duple _position;
        /** true if this item is visible (ie to be drawn), otherwise false */
@@ -236,10 +272,28 @@ protected:
        /* XXX: this is a bit grubby */
        std::map<std::string, void *> _data;
 
+       /* nesting ("grouping") API */
+
+       void invalidate_lut () const;
+       void clear_items (bool with_delete);
+
+       void ensure_lut () const;
+       mutable LookupTable* _lut;
+       /* our items, from lowest to highest in the stack */
+       std::list<Item*> _items;
+
+       void add_child_bounding_boxes() const;
+       void render_children (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const;
+
 private:
        void init ();
 
        bool _ignore_events;
+
+       Duple scroll_offset() const;
+       Duple position_offset() const;
+
+       void find_scroll_parent ();
 };
 
 extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);