various changes to get independent scrolling to work better in canvas. mostly tweaks...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 23 May 2014 03:05:18 +0000 (23:05 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 3 Jun 2014 20:12:00 +0000 (16:12 -0400)
Event handling offsets still require work.

libs/canvas/canvas.cc
libs/canvas/canvas/canvas.h
libs/canvas/canvas/item.h
libs/canvas/canvas/scroll_group.h
libs/canvas/group.cc
libs/canvas/item.cc
libs/canvas/scroll_group.cc

index f29bdba72c87840f210b6dff2319487a54299577..9f375299604d3bbe738b9260e78f32109d04b465 100644 (file)
@@ -80,7 +80,7 @@ Canvas::zoomed ()
 }
 
 /** Render an area of the canvas.
- *  @param area Area in canvas coordinates.
+ *  @param area Area in window coordinates.
  *  @param context Cairo context to render to.
  */
 void
@@ -207,13 +207,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 (_scroll_offset);
 }
 
 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 (-_scroll_offset);
 
        /* Note that this intentionally almost always returns integer coordinates */
 
@@ -283,9 +283,7 @@ Canvas::item_moved (Item* item, boost::optional<Rect> pre_change_parent_bounding
 void
 Canvas::queue_draw_item_area (Item* item, Rect area)
 {
-       ArdourCanvas::Rect canvas_area = item->item_to_canvas (area);
-       // cerr << "CANVAS " << this << " for " << item << ' ' << item->whatami() << ' ' << item->name << " invalidate " << area << " TRANSLATE AS " << canvas_area << " window = " << canvas_to_window (canvas_area) << std::endl;
-       request_redraw (canvas_area);
+       request_redraw (item->item_to_window (area));
 }
 
 /** Construct a GtkCanvas */
@@ -750,18 +748,12 @@ GtkCanvas::on_leave_notify_event (GdkEventCrossing* ev)
 }
 
 /** Called to request a redraw of our canvas.
- *  @param area Area to redraw, in canvas coordinates.
+ *  @param area Area to redraw, in window coordinates.
  */
 void
 GtkCanvas::request_redraw (Rect const & request)
 {
-       boost::optional<Rect> req = request.intersection (visible_area());
-
-       if (req) {
-               Rect r = req.get();
-               Rect area = canvas_to_window (r);
-               queue_draw_area (area.x0, area.y0, area.width(), area.height());
-       }
+       queue_draw_area (request.x0, request.y0, request.width(), request.height());
 }
 
 /** Called to request that we try to get a particular size for ourselves.
index 3f7d6fd5195f42eee7ae3e124b4e14d6da319ccf..1f801c3f00c4686fcc56c68bdd83f07a1e090ee4 100644 (file)
@@ -61,7 +61,7 @@ public:
        Canvas ();
        virtual ~Canvas () {}
 
-       /** called to request a redraw of an area of the canvas */
+       /** called to request a redraw of an area of the canvas in WINDOW coordinates */
        virtual void request_redraw (Rect const &) = 0;
        /** called to ask the canvas to request a particular size from its host */
        virtual void request_size (Duple) = 0;
@@ -90,7 +90,6 @@ public:
        void item_moved (Item *, boost::optional<Rect>);
 
         virtual Cairo::RefPtr<Cairo::Context> context () = 0;
-
         Rect canvas_to_window (Rect const&, bool rounded = true) const;
         Rect window_to_canvas (Rect const&) const;
         Duple canvas_to_window (Duple const&, bool rounded = true) const;
@@ -109,6 +108,7 @@ public:
         }
 
         void scroll_to (Coord x, Coord y);
+       Duple scroll_offset() const { return _scroll_offset; }
        void add_scroller (ScrollGroup& i);
         
         virtual Rect visible_area () const = 0;
index 2b873ee1fc6a8f41b557eddf8f998eeca696aea9..aa9796a288061377e535b8b57759552d25929de0 100644 (file)
@@ -37,6 +37,7 @@ namespace ArdourCanvas
 class Canvas;
 class Group;
 class Rect;    
+class ScrollGroup;
 
 /** The parent class for anything that goes on the canvas.
  *
@@ -119,10 +120,6 @@ public:
                return _position;
        }
 
-       virtual Duple canvas_position () const {
-               return _position;
-       }
-
        boost::optional<Rect> bounding_box () const;
         Coord height() const;
         Coord width() const;
@@ -224,6 +221,8 @@ protected:
        Canvas* _canvas;
        /** parent group; may be 0 if we are the root group or if we have been unparent()ed */
        Group* _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 */
@@ -246,6 +245,8 @@ private:
 
        Duple scroll_offset() const;
        Duple position_offset() const;
+
+       void find_scroll_parent ();
 };
 
 extern LIBCANVAS_API std::ostream& operator<< (std::ostream&, const ArdourCanvas::Item&);
index 36d98538a16ae736d520eaa3051fc12357f12ca0..2df491e93b01237e339da47d675fde1cda40e2ae 100644 (file)
@@ -35,16 +35,8 @@ class LIBCANVAS_API ScrollGroup : public Group
        explicit ScrollGroup (Group *, Duple, ScrollSensitivity);
 
        void scroll_to (Duple const& d);
-
-       /** return the normal "base" position of this item
-           rather its position as affected by any scroll
-           offset.
-       */
-       Duple canvas_position() const {
-               return _position.translate (_scroll_offset);
-       }
-
        Duple scroll_offset() const { return _scroll_offset; }
+
   private:
        ScrollSensitivity _scroll_sensitivity;
        Duple             _scroll_offset;
index 509be0b51a32cde0117ab07fc4595e74fbe276b8..95fdbc8c627d797b01cabeec1017c4087874314c 100644 (file)
@@ -61,7 +61,7 @@ Group::~Group ()
        clear_items (true);
 }
 
-/** @param area Area to draw in this group's coordinates.
+/** @param area Area to draw in window coordinates.
  *  @param context Context, set up with its origin at this group's position.
  */
 void
index 3ca73bbf9fcd1dc19383e6210ac03491bb72ad9a..0706df6baec8d762be32371eef00f89bff9eafff 100644 (file)
@@ -66,6 +66,8 @@ Item::init ()
                _parent->add (this);
        }
 
+       find_scroll_parent ();
+
        DEBUG_TRACE (DEBUG::CanvasItems, string_compose ("new canvas item %1\n", this));
 }      
 
@@ -89,18 +91,10 @@ Item::item_to_parent (ArdourCanvas::Rect const & r) const
 Duple
 Item::scroll_offset () const
 {
-       Item const * i = this;
-       Duple offset;
-
-       while (i) {
-               ScrollGroup const * sg = dynamic_cast<ScrollGroup const *> (i);
-               if (sg) {
-                       offset = offset.translate (sg->scroll_offset());
-               }
-               i = i->parent();
-       }
-
-       return offset;
+       if (_scroll_parent) {
+               return _scroll_parent->scroll_offset();
+       } 
+       return _canvas->scroll_offset();
 }
 
 Duple
@@ -110,7 +104,7 @@ Item::position_offset() const
        Duple offset;
 
        while (i) {
-               offset = offset.translate (i->canvas_position());
+               offset = offset.translate (i->position());
                i = i->parent();
        }
 
@@ -163,7 +157,12 @@ Item::canvas_to_item (Coord& x, Coord& y) const
 Duple
 Item::item_to_window (ArdourCanvas::Duple const & d, bool rounded) const
 {
-       return item_to_canvas (d).translate (-scroll_offset());
+       Duple ret = item_to_canvas (d).translate (-scroll_offset());
+
+       ret.x = round (ret.x);
+       ret.y = round (ret.y);
+
+       return ret;
 }
 
 Duple
@@ -175,7 +174,14 @@ Item::window_to_item (ArdourCanvas::Duple const & d) const
 ArdourCanvas::Rect
 Item::item_to_window (ArdourCanvas::Rect const & r) const
 {
-       return item_to_canvas (r).translate (-scroll_offset());
+       Rect ret = item_to_canvas (r).translate (-scroll_offset());
+
+       ret.x0 = round (ret.x0);
+       ret.x1 = round (ret.x1);
+       ret.y0 = round (ret.y0);
+       ret.y1 = round (ret.y1);
+
+       return ret;
 }
 
 ArdourCanvas::Rect
@@ -284,6 +290,7 @@ void
 Item::unparent ()
 {
        _parent = 0;
+       _scroll_parent = 0;
 }
 
 void
@@ -299,9 +306,29 @@ Item::reparent (Group* new_parent)
 
        _parent = new_parent;
        _canvas = _parent->canvas ();
+
+       find_scroll_parent ();
+
        _parent->add (this);
 }
 
+void
+Item::find_scroll_parent ()
+{
+       Item const * i = this;
+       ScrollGroup const * last_scroll_group = 0;
+
+       while (i) {
+               ScrollGroup const * sg = dynamic_cast<ScrollGroup const *> (i);
+               if (sg) {
+                       last_scroll_group = sg;
+               }
+               i = i->parent();
+       }
+       
+       _scroll_parent = const_cast<ScrollGroup*> (last_scroll_group);
+}
+
 bool
 Item::common_ancestor_within (uint32_t limit, const Item& other) const
 {
@@ -444,7 +471,7 @@ void
 Item::redraw () const
 {
        if (_visible && _bounding_box && _canvas) {
-               _canvas->request_redraw (item_to_canvas (_bounding_box.get()));
+               _canvas->request_redraw (item_to_window (_bounding_box.get()));
        }
 }      
 
index 94ea869971d18b321da474a03140a81a82324cdc..76bca50aeee473e6a7fef4a300606cc6e29d63f8 100644 (file)
 */
 
 #include <iostream>
+
+#include "pbd/compose.h"
+
+#include "canvas/debug.h"
 #include "canvas/scroll_group.h"
 
 using namespace std;
@@ -37,26 +41,11 @@ ScrollGroup::ScrollGroup (Group* parent, Duple position, ScrollSensitivity s)
 void
 ScrollGroup::scroll_to (Duple const& d)
 {
-       /* get the nominal position of the group without scroll being in effect
-        */
-
-       Duple base_pos (_position.translate (_scroll_offset));
-
-       /* compute a new position given our sensitivity to h- and v-scrolling 
-        */
-
        if (_scroll_sensitivity & ScrollsHorizontally) {
-               base_pos.x -= d.x;
                _scroll_offset.x = d.x;
        }
 
        if (_scroll_sensitivity & ScrollsVertically) {
-               base_pos.y -= d.y;
                _scroll_offset.y = d.y;
        }
-
-       /* move there */
-
-       set_position (base_pos);
 }
-