initial redesign of canvas scrolling to facilitate independent x- and y-axis scrollin...
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 18 May 2014 16:22:23 +0000 (12:22 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 3 Jun 2014 20:09:06 +0000 (16:09 -0400)
This commit should cause no change in behaviour, but contains all the code and changes necessary
for the next step

gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/tempo_lines.cc
libs/canvas/canvas.cc
libs/canvas/canvas/canvas.h
libs/canvas/canvas/group.h
libs/canvas/canvas/item.h
libs/canvas/group.cc
libs/canvas/item.cc
libs/canvas/line.cc
libs/canvas/poly_line.cc

index 1736da96cb4a8e45ec4ae270095f71a52ec881dd..2b491e79743c30c11d9af71625d49236cb25f2e2 100644 (file)
@@ -65,10 +65,8 @@ Editor::initialize_canvas ()
 {
        _track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
        _track_canvas = _track_canvas_viewport->canvas ();
+       //_track_canvas->set_global_scroll (false);
 
-       _time_bars_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, unused_adjustment);
-       _time_bars_canvas = _time_bars_canvas_viewport->canvas ();
-       
        _verbose_cursor = new VerboseCursor (this);
 
        /* on the bottom, an image */
@@ -100,7 +98,15 @@ Editor::initialize_canvas ()
        CANVAS_DEBUG_NAME (time_line_group, "time line group");
 
        _trackview_group = new ArdourCanvas::Group (_track_canvas->root());
+       //_trackview_group->set_scroll_sensitivity (ArdourCanvas::Group::ScrollSensitivity (ArdourCanvas::Group::ScrollsVertically|ArdourCanvas::Group::ScrollsHorizontally));  
        CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews");
+       
+       
+       /* TIME BAR CANVAS */
+       
+       _time_bars_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, unused_adjustment);
+       _time_bars_canvas = _time_bars_canvas_viewport->canvas ();
+               
        _region_motion_group = new ArdourCanvas::Group (_trackview_group);
        CANVAS_DEBUG_NAME (_region_motion_group, "Canvas Region Motion");
 
index 3cf3ef83b7a5fe53a7bf3c309a31d4bf1a7225be..371feaff5826483c67668508c16eef0f4b9ad8bd 100644 (file)
@@ -1465,16 +1465,23 @@ Editor::update_punch_range_view ()
        Location* tpl;
 
        if ((_session->config.get_punch_in() || _session->config.get_punch_out()) && ((tpl = transport_punch_location()) != 0)) {
-               ArdourCanvas::Rect const v = _track_canvas->visible_area ();
 
+               double pixel_start;
+               double pixel_end;
+               
                if (_session->config.get_punch_in()) {
-                       transport_punch_range_rect->set_x0 (sample_to_pixel (tpl->start()));
-                       transport_punch_range_rect->set_x1 (_session->config.get_punch_out() ? sample_to_pixel (tpl->end()) : sample_to_pixel (max_framepos));
+                       pixel_start = sample_to_pixel (tpl->start());
+               } else {
+                       pixel_start = 0;
+               }
+               if (_session->config.get_punch_out()) {
+                       pixel_end = sample_to_pixel (tpl->end());
                } else {
-                       transport_punch_range_rect->set_x0 (0);
-                       transport_punch_range_rect->set_x1 (_session->config.get_punch_out() ? sample_to_pixel (tpl->end()) : v.width ());
+                       pixel_end = sample_to_pixel (max_framepos);
                }
                
+               transport_punch_range_rect->set_x0 (pixel_start);
+               transport_punch_range_rect->set_x1 (pixel_end);                 
                transport_punch_range_rect->show();
 
        } else {
index 828a4cc82ba8a390af7b320bfcf37d4c8663319b..917e141313e0bb7709009d6a551e484999a1307f 100644 (file)
@@ -65,7 +65,7 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
                  const ARDOUR::TempoMap::BBTPointList::const_iterator& end)
 {
        ARDOUR::TempoMap::BBTPointList::const_iterator i;
-       ArdourCanvas::Rect const visible = _canvas.visible_area ();
+       ArdourCanvas::Rect const visible = _group->window_to_item (_canvas.visible_area ());
        double  beat_density;
 
        uint32_t beats = 0;
index ceaa366c3554c823757dc999236362ae9ef746b6..8d4c1b885808c29aeb1afb90dc54601aff39bb60 100644 (file)
@@ -40,8 +40,7 @@ using namespace ArdourCanvas;
 /** Construct a new Canvas */
 Canvas::Canvas ()
        : _root (this)
-       , _scroll_offset_x (0)
-       , _scroll_offset_y (0)
+       , _global_scroll (true)
 {
        set_epoch ();
 }
@@ -49,12 +48,23 @@ Canvas::Canvas ()
 void
 Canvas::scroll_to (Coord x, Coord y)
 {
-       _scroll_offset_x = x;
-       _scroll_offset_y = y;
+       Duple d (x, y);
+       
+       if (_global_scroll) {
+               _scroll_offset = d;
+       }
+       
+       //_root.scroll_to (d);
 
        pick_current_item (0); // no current mouse position 
 }
 
+void
+Canvas::set_global_scroll (bool yn)
+{
+       _global_scroll = yn;
+}
+
 void
 Canvas::zoomed ()
 {
@@ -71,9 +81,9 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
 #ifdef CANVAS_DEBUG
        if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) {
                cerr << this << " RENDER: " << area << endl;
-               //cerr << "CANVAS @ " << this << endl;
-               //dump (cerr);
-               //cerr << "-------------------------\n";
+               cerr << "CANVAS @ " << this << endl;
+               dump (cerr);
+               cerr << "-------------------------\n";
        }
 #endif
 
@@ -189,13 +199,13 @@ Canvas::item_changed (Item* item, boost::optional<Rect> pre_change_bounding_box)
 Duple
 Canvas::window_to_canvas (Duple const & d) const
 {
-       return d.translate (Duple (_scroll_offset_x, _scroll_offset_y));
+       return d.translate (Duple (_scroll_offset.x, _scroll_offset.y));
 }
 
 Duple
 Canvas::canvas_to_window (Duple const & d, bool rounded) const
 {
-       Duple wd = d.translate (Duple (-_scroll_offset_x, -_scroll_offset_y));
+       Duple wd = d.translate (Duple (-_scroll_offset.x, -_scroll_offset.y));
 
        /* Note that this intentionally almost always returns integer coordinates */
        if (rounded) {
@@ -209,13 +219,13 @@ Canvas::canvas_to_window (Duple const & d, bool rounded) const
 Rect
 Canvas::window_to_canvas (Rect const & r) const
 {
-       return r.translate (Duple (_scroll_offset_x, _scroll_offset_y));
+       return r.translate (Duple (_scroll_offset.x, _scroll_offset.y));
 }
 
 Rect
 Canvas::canvas_to_window (Rect const & r, bool rounded) const
 {
-       Rect wr = r.translate (Duple (-_scroll_offset_x, -_scroll_offset_y));
+       Rect wr = r.translate (Duple (-_scroll_offset.x, -_scroll_offset.y));
 
        /* Note that this intentionally almost always returns integer coordinates */
 
@@ -802,8 +812,8 @@ GtkCanvas::unfocus (Item* item)
 Rect
 GtkCanvas::visible_area () const
 {
-       Distance const xo = _scroll_offset_x;
-       Distance const yo = _scroll_offset_y;
+       Distance const xo = _scroll_offset.x;
+       Distance const yo = _scroll_offset.y;
        return Rect (xo, yo, xo + get_allocation().get_width (), yo + get_allocation().get_height ());
 }
 
index b15c2f4d5488bd57f2ae61b4975186b3ec9ae58c..1e2a567d58b3c7db5603c7d62e1fc32b97a11f1a 100644 (file)
@@ -108,6 +108,8 @@ public:
         }
 
         void scroll_to (Coord x, Coord y);
+        void set_global_scroll (bool);
+        
         virtual Rect visible_area () const = 0;
 
         void zoomed();
@@ -122,8 +124,8 @@ protected:
        /** our root group */
        RootGroup _root;
 
-        Coord _scroll_offset_x;
-        Coord _scroll_offset_y;
+        Duple _scroll_offset;
+        bool _global_scroll;
 
         virtual void pick_current_item (int state) = 0;
         virtual void pick_current_item (Duple const &, int state) = 0;
index 94aabfded6da286198a5b992770b2732f577c4cf..a9150e7d0918291cde23ee5ad04fbf646aeaa952 100644 (file)
@@ -51,7 +51,9 @@ public:
        void raise_child (Item *, int);
        void lower_child_to_bottom (Item *);
        void child_changed ();
-
+       
+       void scroll_to (Duple const& d);
+       
        void add_items_at_point (Duple, std::vector<Item const *> &) const;
 
         void dump (std::ostream&) const;
index d7d4ba7254f9237999e923419659da7adc159d81..429df33894c915c2592df04d6c23d0c6df6fdcf9 100644 (file)
@@ -112,6 +112,17 @@ public:
        void set_y_position (Coord);
        void move (Duple);
 
+       enum ScrollSensitivity {
+               ScrollsVertically = 0x1,
+               ScrollsHorizontally = 0x2
+       };
+       
+       void set_scroll_sensitivity (ScrollSensitivity s);
+       ScrollSensitivity scroll_sensitivity () const { return _scroll_sensitivity; }
+
+       virtual void scroll_to (Duple const& d);
+       Duple scroll_offset() const { return _scroll_offset; }
+
        /** @return Position of this item in the parent's coordinates */
        Duple position () const {
                return _position;
@@ -125,21 +136,18 @@ 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&, 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 ();
@@ -240,6 +248,8 @@ private:
        void init ();
 
        bool _ignore_events;
+       ScrollSensitivity _scroll_sensitivity;
+       Duple _scroll_offset;
 };
 
 extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
index fbe252a17c96fc128d8ae5655237c7bb8efff1bb..b6df3dfee69172c9ef2ff8e971742294ff7d4416 100644 (file)
@@ -147,6 +147,16 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
        --render_depth;
 }
 
+void
+Group::scroll_to (Duple const& d)
+{
+       Item::scroll_to (d);
+       
+       for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ) {
+               (*i)->scroll_to (d);
+       }
+}
+
 void
 Group::compute_bounding_box () const
 {
index 674daa4275320042218d38cf6662732e6be3cce3..7a55e9604f365421882d46a013a835cebadb30f8 100644 (file)
@@ -35,6 +35,7 @@ using namespace ArdourCanvas;
 Item::Item (Canvas* canvas)
        : _canvas (canvas)
        , _parent (0)
+       , _scroll_sensitivity (ScrollSensitivity (0))
 {
        init ();
 }
@@ -42,6 +43,7 @@ Item::Item (Canvas* canvas)
 Item::Item (Group* parent)
        : _canvas (parent->canvas ())
        , _parent (parent)
+       , _scroll_sensitivity (ScrollSensitivity (0))
 {
        init ();
 }
@@ -50,6 +52,7 @@ Item::Item (Group* parent, Duple position)
        : _canvas (parent->canvas())
        , _parent (parent)
        , _position (position)
+       , _scroll_sensitivity (ScrollSensitivity (0))   
 {
        init ();
 }
@@ -79,6 +82,24 @@ Item::~Item ()
        }
 }
 
+void
+Item::scroll_to (Duple const& d)
+{
+       if (_scroll_sensitivity & ScrollsVertically) {
+               _scroll_offset.y = d.y;
+       }
+
+       if (_scroll_sensitivity & ScrollsHorizontally) {
+               _scroll_offset.x = d.x;
+       }
+}
+
+void
+Item::set_scroll_sensitivity (ScrollSensitivity s)
+{
+       _scroll_sensitivity = s;
+}
+
 ArdourCanvas::Rect
 Item::item_to_parent (ArdourCanvas::Rect const & r) const
 {
@@ -162,19 +183,57 @@ Item::canvas_to_item (Coord& x, Coord& y) const
 Duple
 Item::item_to_window (ArdourCanvas::Duple const & d, bool rounded) const
 {
-       return _canvas->canvas_to_window (item_to_canvas (d), rounded);
+       Item const * i = this;
+       Duple offset;
+
+       while (i) {
+               offset = offset.translate (i->scroll_offset());
+               i = i->parent();
+       }
+       
+       return _canvas->canvas_to_window (d.translate (offset), rounded);
 }
 
 Duple
 Item::window_to_item (ArdourCanvas::Duple const & d) const
 {
-       return _canvas->window_to_canvas (canvas_to_item (d));
+       Item const * i = this;
+       Duple offset;
+
+       while (i) {
+               offset = offset.translate (-i->scroll_offset());
+               i = i->parent();
+       }
+       
+       return _canvas->window_to_canvas (d.translate (offset));
 }
 
 ArdourCanvas::Rect
 Item::item_to_window (ArdourCanvas::Rect const & r) const
 {
-       return _canvas->canvas_to_window (item_to_canvas (r));
+       Item const * i = this;
+       Duple offset;
+
+       while (i) {
+               offset = offset.translate (i->scroll_offset());
+               i = i->parent();
+       }
+
+       return _canvas->canvas_to_window (item_to_canvas (r.translate (offset)));
+}
+
+ArdourCanvas::Rect
+Item::window_to_item (ArdourCanvas::Rect const & r) const
+{
+       Item const * i = this;
+       Duple offset;
+
+       while (i) {
+               offset = offset.translate (-i->scroll_offset());
+               i = i->parent();
+       }
+
+       return canvas_to_item (_canvas->window_to_canvas (r).translate (offset));
 }
 
 /** Set the position of this item in the parent's coordinates */
@@ -517,7 +576,7 @@ Item::dump (ostream& o) const
        boost::optional<ArdourCanvas::Rect> bb = bounding_box();
 
        o << _canvas->indent() << whatami() << ' ' << this << " Visible ? " << _visible;
-       o << " @ " << position();
+       o << " @ " << position() << " scrolled-to " << _scroll_offset;
        
 #ifdef CANVAS_DEBUG
        if (!name.empty()) {
index 8f04e2b27878699345feb26f2896e27095fe0aa4..33ec41fc3d4d3af8b0f6496c2c13724da0244e88 100644 (file)
@@ -180,7 +180,7 @@ Line::covers (Duple const & point) const
        double t;
        Duple a (_points[0]);
        Duple b (_points[1]);
-       const Rect visible (_canvas->visible_area());
+       const Rect visible (window_to_item (_canvas->visible_area()));
 
        /*
           Clamp the line endpoints to the visible area of the canvas. If we do
index ae6d15a8fdceb25d0d81eda7ec3b7618f1a3de50..f8a847c3b61f060e6a86e4efc00bb83946771aff 100644 (file)
@@ -59,7 +59,7 @@ PolyLine::covers (Duple const & point) const
 
        /* repeat for each line segment */
 
-       const Rect visible (_canvas->visible_area());
+       const Rect visible (window_to_item (_canvas->visible_area()));
 
        for (i = 1, j = 0; i < npoints; ++i, ++j) {