mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-15 19:16:40 +01:00
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.
This commit is contained in:
parent
f17b84ad10
commit
54a56cd3c6
7 changed files with 62 additions and 61 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue