summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-05-22 23:05:18 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2014-06-03 16:12:00 -0400
commit54a56cd3c6b8d6ffaea3343c4f4a79b52c586661 (patch)
tree0af2fd7af2929cbad1df79d49d03497fc09f022b /libs/canvas
parentf17b84ad10eef7249c49a0e9d94b259ddbb87345 (diff)
various changes to get independent scrolling to work better in canvas. mostly tweaks relating to how scroll offsets are used during rendering.
Event handling offsets still require work.
Diffstat (limited to 'libs/canvas')
-rw-r--r--libs/canvas/canvas.cc20
-rw-r--r--libs/canvas/canvas/canvas.h4
-rw-r--r--libs/canvas/canvas/item.h9
-rw-r--r--libs/canvas/canvas/scroll_group.h10
-rw-r--r--libs/canvas/group.cc2
-rw-r--r--libs/canvas/item.cc59
-rw-r--r--libs/canvas/scroll_group.cc19
7 files changed, 62 insertions, 61 deletions
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc
index f29bdba72c..9f37529960 100644
--- a/libs/canvas/canvas.cc
+++ b/libs/canvas/canvas.cc
@@ -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.
diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h
index 3f7d6fd519..1f801c3f00 100644
--- a/libs/canvas/canvas/canvas.h
+++ b/libs/canvas/canvas/canvas.h
@@ -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;
diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h
index 2b873ee1fc..aa9796a288 100644
--- a/libs/canvas/canvas/item.h
+++ b/libs/canvas/canvas/item.h
@@ -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&);
diff --git a/libs/canvas/canvas/scroll_group.h b/libs/canvas/canvas/scroll_group.h
index 36d98538a1..2df491e93b 100644
--- a/libs/canvas/canvas/scroll_group.h
+++ b/libs/canvas/canvas/scroll_group.h
@@ -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;
diff --git a/libs/canvas/group.cc b/libs/canvas/group.cc
index 509be0b51a..95fdbc8c62 100644
--- a/libs/canvas/group.cc
+++ b/libs/canvas/group.cc
@@ -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
diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc
index 3ca73bbf9f..0706df6bae 100644
--- a/libs/canvas/item.cc
+++ b/libs/canvas/item.cc
@@ -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()));
}
}
diff --git a/libs/canvas/scroll_group.cc b/libs/canvas/scroll_group.cc
index 94ea869971..76bca50aee 100644
--- a/libs/canvas/scroll_group.cc
+++ b/libs/canvas/scroll_group.cc
@@ -17,6 +17,10 @@
*/
#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);
}
-