a few changes to fix region dragging, all related to coordinate system handling, which is now much simpler with the new canvas; more debugging output when asked for
This commit is contained in:
parent
cfe4bfb732
commit
af4539f857
@ -1016,8 +1016,6 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
bool deferred_control_scroll (framepos_t);
|
||||
sigc::connection control_scroll_connection;
|
||||
|
||||
gdouble get_trackview_group_vertical_offset () const { return vertical_adjustment.get_value (); }
|
||||
|
||||
ArdourCanvas::Group* get_background_group () const { return _background_group; }
|
||||
ArdourCanvas::Group* get_trackview_group () const { return _trackview_group; }
|
||||
void tie_vertical_scrolling ();
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "canvas/rectangle.h"
|
||||
#include "canvas/pixbuf.h"
|
||||
#include "canvas/text.h"
|
||||
#include "canvas/debug.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
#include "editor.h"
|
||||
@ -101,10 +102,14 @@ Editor::initialize_canvas ()
|
||||
|
||||
|
||||
_background_group = new ArdourCanvas::Group (_track_canvas->root());
|
||||
CANVAS_DEBUG_NAME (_background_group, "Canvas Background");
|
||||
_master_group = new ArdourCanvas::Group (_track_canvas->root());
|
||||
CANVAS_DEBUG_NAME (_master_group, "Canvas Master");
|
||||
|
||||
_trackview_group = new ArdourCanvas::Group (_master_group);
|
||||
CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews");
|
||||
_region_motion_group = new ArdourCanvas::Group (_trackview_group);
|
||||
CANVAS_DEBUG_NAME (_region_motion_group, "Canvas Region Motion");
|
||||
|
||||
meter_bar_group = new ArdourCanvas::Group (_time_bars_canvas->root ());
|
||||
meter_bar = new ArdourCanvas::Rectangle (meter_bar_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, timebar_height - 1));
|
||||
@ -487,7 +492,7 @@ Editor::maybe_autoscroll (bool allow_horiz, bool allow_vert, bool moving_left, b
|
||||
/* Note whether we're fudging the autoscroll (see autoscroll_fudge_threshold) */
|
||||
_autoscroll_fudging = (distance < autoscroll_fudge_threshold ());
|
||||
|
||||
double const ty = _drags->current_pointer_y() - get_trackview_group_vertical_offset ();
|
||||
double const ty = _drags->current_pointer_y();
|
||||
|
||||
autoscroll_y = 0;
|
||||
autoscroll_x = 0;
|
||||
@ -558,7 +563,7 @@ Editor::autoscroll_canvas ()
|
||||
|
||||
if (autoscroll_y_distance != 0) {
|
||||
if (autoscroll_y > 0) {
|
||||
autoscroll_y_distance = (_drags->current_pointer_y() - (get_trackview_group_vertical_offset() + _visible_canvas_height)) / 3;
|
||||
autoscroll_y_distance = (_drags->current_pointer_y() - _visible_canvas_height) / 3;
|
||||
} else if (autoscroll_y < 0) {
|
||||
|
||||
autoscroll_y_distance = (vertical_adjustment.get_value () - _drags->current_pointer_y()) / 3;
|
||||
@ -754,23 +759,6 @@ Editor::set_horizontal_position (double p)
|
||||
HorizontalPositionChanged (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
// CAIROCANVAS
|
||||
#if 0
|
||||
void
|
||||
Editor::scroll_canvas_vertically ()
|
||||
{
|
||||
/* vertical scrolling only */
|
||||
|
||||
double y_delta;
|
||||
|
||||
y_delta = last_trackview_group_vertical_offset - get_trackview_group_vertical_offset ();
|
||||
_trackview_group->move (0, y_delta);
|
||||
_background_group->move (0, y_delta);
|
||||
|
||||
last_trackview_group_vertical_offset = get_trackview_group_vertical_offset ();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Editor::color_handler()
|
||||
{
|
||||
|
@ -670,12 +670,16 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
||||
/* Reparent to a non scrolling group so that we can keep the
|
||||
region selection above all time axis views.
|
||||
Reparenting means that we will have to move the region view
|
||||
later, as the two parent groups have different coordinates.
|
||||
within its new parent, as the two parent groups have different coordinates.
|
||||
*/
|
||||
|
||||
ArdourCanvas::Group* rvg = rv->get_canvas_group();
|
||||
Duple rv_canvas_offset = rvg->item_to_canvas (Duple (0,0));
|
||||
|
||||
rv->get_canvas_group()->reparent (_editor->_region_motion_group);
|
||||
|
||||
|
||||
rv->fake_set_opaque (true);
|
||||
rvg->set_position (rv_canvas_offset);
|
||||
}
|
||||
|
||||
/* If we have moved tracks, we'll fudge the layer delta so that the
|
||||
@ -725,8 +729,7 @@ RegionMotionDrag::motion (GdkEvent* event, bool first_move)
|
||||
|
||||
/* Get the y coordinate of the top of the track that this region is now on */
|
||||
tv->canvas_display()->item_to_canvas (x, y);
|
||||
y += _editor->get_trackview_group_vertical_offset();
|
||||
|
||||
|
||||
/* And adjust for the layer that it should be on */
|
||||
StreamView* cv = tv->view ();
|
||||
switch (cv->layer_display ()) {
|
||||
|
@ -193,9 +193,8 @@ Editor::draw_measures (ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
|
||||
if (tempo_lines == 0) {
|
||||
tempo_lines = new TempoLines (*_track_canvas_viewport, time_line_group, physical_screen_height(get_window()));
|
||||
}
|
||||
|
||||
// CAIROCANVAS
|
||||
// tempo_lines->draw (begin, end, frames_per_unit);
|
||||
|
||||
tempo_lines->draw (begin, end, samples_per_pixel);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -380,7 +380,6 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
|
||||
virtual Gtk::HBox& get_status_bar_packer() = 0;
|
||||
#endif
|
||||
|
||||
virtual gdouble get_trackview_group_vertical_offset () const = 0;
|
||||
virtual ArdourCanvas::Group* get_trackview_group () const = 0;
|
||||
virtual ArdourCanvas::Group* get_background_group () const = 0;
|
||||
|
||||
|
@ -123,11 +123,11 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
|
||||
// Tempo map hasn't changed and we're entirely within a clean
|
||||
// range, don't need to do anything. Yay.
|
||||
if (needed_left >= _clean_left && needed_right <= _clean_right) {
|
||||
// cout << endl << "*** LINE CACHE PERFECT HIT" << endl;
|
||||
// cerr << endl << "*** LINE CACHE PERFECT HIT" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//cout << endl << "*** LINE CACHE MISS" << endl;
|
||||
// cerr << endl << "*** LINE CACHE MISS" << endl;
|
||||
|
||||
bool invalidated = false;
|
||||
|
||||
@ -169,7 +169,7 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
|
||||
|
||||
// Steal from the right
|
||||
if (left->first > needed_left && li != steal && steal->first > needed_right) {
|
||||
//cout << "*** STEALING FROM RIGHT" << endl;
|
||||
// cerr << "*** STEALING FROM RIGHT" << endl;
|
||||
double const x = steal->first;
|
||||
line = steal->second;
|
||||
_lines.erase(steal);
|
||||
@ -208,7 +208,7 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
|
||||
|
||||
// Create a new line
|
||||
} else if (_lines.size() < needed || _lines.size() < MAX_CACHED_LINES) {
|
||||
//cout << "*** CREATING LINE" << endl;
|
||||
// cerr << "*** CREATING LINE" << endl;
|
||||
/* if we already have a line there ... don't sweat it */
|
||||
if (_lines.find (xpos) == _lines.end()) {
|
||||
line = new ArdourCanvas::Line (_group);
|
||||
@ -222,7 +222,7 @@ TempoLines::draw (const ARDOUR::TempoMap::BBTPointList::const_iterator& begin,
|
||||
|
||||
// Steal from the left
|
||||
} else {
|
||||
//cout << "*** STEALING FROM LEFT" << endl;
|
||||
// cerr << "*** STEALING FROM LEFT" << endl;
|
||||
if (_lines.find (xpos) == _lines.end()) {
|
||||
Lines::iterator steal = _lines.begin();
|
||||
double const x = steal->first;
|
||||
|
@ -373,7 +373,7 @@ TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
|
||||
*/
|
||||
int tx, ty;
|
||||
controls_ebox.translate_coordinates (*control_parent, ev->x, ev->y, tx, ty);
|
||||
ev->y = ty - _editor.get_trackview_group_vertical_offset();
|
||||
ev->y = ty;
|
||||
_editor.drags()->motion_handler ((GdkEvent *) ev, false);
|
||||
_editor.maybe_autoscroll (false, true, false, ev->y_root < _resize_drag_start);
|
||||
|
||||
|
@ -100,18 +100,6 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
|
||||
// checkpoint ("render", "-> render");
|
||||
render_count = 0;
|
||||
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (getenv ("ARDOUR_HARLEQUIN_CANVAS")) {
|
||||
/* light up the canvas to show redraws */
|
||||
context->set_source_rgba (random()%255 / 255.0,
|
||||
random()%255 / 255.0,
|
||||
random()%255 / 255.0,
|
||||
255);
|
||||
context->rectangle (area.x0, area.y0, area.width(), area.height());
|
||||
context->fill ();
|
||||
}
|
||||
#endif
|
||||
|
||||
context->save ();
|
||||
|
||||
/* clip to the requested area */
|
||||
@ -143,6 +131,17 @@ Canvas::render (Rect const & area, Cairo::RefPtr<Cairo::Context> const & context
|
||||
|
||||
context->restore ();
|
||||
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (getenv ("ARDOUR_HARLEQUIN_CANVAS")) {
|
||||
/* light up the canvas to show redraws */
|
||||
context->set_source_rgba (random()%255 / 255.0,
|
||||
random()%255 / 255.0,
|
||||
random()%255 / 255.0,
|
||||
255);
|
||||
context->rectangle (area.x0, area.y0, area.width(), area.height());
|
||||
context->fill ();
|
||||
}
|
||||
#endif
|
||||
// checkpoint ("render", "<- render");
|
||||
}
|
||||
|
||||
@ -225,10 +224,15 @@ void
|
||||
Canvas::item_moved (Item* item, boost::optional<Rect> pre_change_parent_bounding_box)
|
||||
{
|
||||
if (pre_change_parent_bounding_box) {
|
||||
/* request a redraw of where the item used to be; we have to use the
|
||||
parent's coordinates here as item bounding boxes do not change
|
||||
when the item moves.
|
||||
*/
|
||||
/* request a redraw of where the item used to be. The box has
|
||||
* to be in parent coordinate space since the bounding box of
|
||||
* an item does not change when moved. If we use
|
||||
* item->item_to_canvas() on the old bounding box, we will be
|
||||
* using the item's new position, and so will compute the wrong
|
||||
* invalidation area. If we use the parent (which has not
|
||||
* moved, then this will work.
|
||||
*/
|
||||
|
||||
queue_draw_item_area (item->parent(), pre_change_parent_bounding_box.get ());
|
||||
}
|
||||
|
||||
@ -246,7 +250,9 @@ Canvas::item_moved (Item* item, boost::optional<Rect> pre_change_parent_bounding
|
||||
void
|
||||
Canvas::queue_draw_item_area (Item* item, Rect area)
|
||||
{
|
||||
request_redraw (item->item_to_canvas (area));
|
||||
ArdourCanvas::Rect canvas_area = item->item_to_canvas (area);
|
||||
// cerr << "CANVAS Invalidate " << area << " TRANSLATE AS " << canvas_area << endl;
|
||||
request_redraw (canvas_area);
|
||||
}
|
||||
|
||||
/** @return An XML description of the canvas and its objects */
|
||||
@ -554,6 +560,7 @@ void
|
||||
GtkCanvas::request_redraw (Rect const & request)
|
||||
{
|
||||
Rect area = canvas_to_window (request);
|
||||
// cerr << "Invalidate " << request << " TRANSLATE AS " << area << endl;
|
||||
queue_draw_area (floor (area.x0), floor (area.y0), ceil (area.x1) - floor (area.x0), ceil (area.y1) - floor (area.y0));
|
||||
}
|
||||
|
||||
|
@ -108,9 +108,12 @@ public:
|
||||
/* XXX: it's a pity these 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;
|
||||
|
||||
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;
|
||||
Duple item_to_canvas (Duple const &) const;
|
||||
|
||||
void raise_to_top ();
|
||||
void raise (int);
|
||||
|
@ -278,6 +278,7 @@ Group::dump (ostream& o) const
|
||||
{
|
||||
o << _canvas->indent();
|
||||
o << "Group " << this << " [" << name << ']';
|
||||
o << " @ " << position();
|
||||
o << " Items: " << _items.size();
|
||||
o << " Visible ? " << _visible;
|
||||
|
||||
@ -285,6 +286,7 @@ Group::dump (ostream& o) const
|
||||
|
||||
if (bb) {
|
||||
o << endl << _canvas->indent() << " bbox: " << bb.get();
|
||||
o << endl << _canvas->indent() << " CANVAS bbox: " << item_to_canvas (bb.get());
|
||||
} else {
|
||||
o << " bbox unset";
|
||||
}
|
||||
|
@ -67,6 +67,66 @@ Item::item_to_parent (ArdourCanvas::Rect const & r) const
|
||||
return r.translate (_position);
|
||||
}
|
||||
|
||||
ArdourCanvas::Rect
|
||||
Item::item_to_canvas (ArdourCanvas::Rect const & r) const
|
||||
{
|
||||
Item const * i = this;
|
||||
Duple offset;
|
||||
|
||||
while (i) {
|
||||
offset = offset.translate (i->position());
|
||||
i = i->parent();
|
||||
}
|
||||
|
||||
return r.translate (offset);
|
||||
}
|
||||
|
||||
ArdourCanvas::Duple
|
||||
Item::item_to_canvas (ArdourCanvas::Duple const & d) const
|
||||
{
|
||||
Item const * i = this;
|
||||
Duple offset;
|
||||
|
||||
while (i) {
|
||||
offset = offset.translate (i->position());
|
||||
i = i->parent();
|
||||
}
|
||||
|
||||
return d.translate (offset);
|
||||
}
|
||||
|
||||
ArdourCanvas::Duple
|
||||
Item::canvas_to_item (ArdourCanvas::Duple const & d) const
|
||||
{
|
||||
Item const * i = this;
|
||||
Duple offset;
|
||||
|
||||
while (i) {
|
||||
offset = offset.translate (-(i->position()));
|
||||
i = i->parent();
|
||||
}
|
||||
|
||||
return d.translate (offset);
|
||||
}
|
||||
|
||||
void
|
||||
Item::item_to_canvas (Coord& x, Coord& y) const
|
||||
{
|
||||
Duple d = item_to_canvas (Duple (x, y));
|
||||
|
||||
x = d.x;
|
||||
y = d.y;
|
||||
}
|
||||
|
||||
void
|
||||
Item::canvas_to_item (Coord& x, Coord& y) const
|
||||
{
|
||||
Duple d = canvas_to_item (Duple (x, y));
|
||||
|
||||
x = d.x;
|
||||
y = d.y;
|
||||
}
|
||||
|
||||
/** Set the position of this item in the parent's coordinates */
|
||||
void
|
||||
Item::set_position (Duple p)
|
||||
@ -75,6 +135,9 @@ Item::set_position (Duple p)
|
||||
boost::optional<ArdourCanvas::Rect> pre_change_parent_bounding_box;
|
||||
|
||||
if (bbox) {
|
||||
/* see the comment in Canvas::item_moved() to understand
|
||||
* why we use the parent's bounding box here.
|
||||
*/
|
||||
pre_change_parent_bounding_box = item_to_parent (bbox.get());
|
||||
}
|
||||
|
||||
@ -284,50 +347,6 @@ Item::get_data (string const & key) const
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void
|
||||
Item::item_to_canvas (Coord& x, Coord& y) const
|
||||
{
|
||||
Duple d (x, y);
|
||||
Item const * i = this;
|
||||
|
||||
while (i) {
|
||||
d = i->item_to_parent (d);
|
||||
i = i->_parent;
|
||||
}
|
||||
|
||||
x = d.x;
|
||||
y = d.y;
|
||||
}
|
||||
|
||||
void
|
||||
Item::canvas_to_item (Coord& x, Coord& y) const
|
||||
{
|
||||
Duple d (x, y);
|
||||
Item const * i = this;
|
||||
|
||||
while (i) {
|
||||
d = i->parent_to_item (d);
|
||||
i = i->_parent;
|
||||
}
|
||||
|
||||
x = d.x;
|
||||
y = d.y;
|
||||
}
|
||||
|
||||
ArdourCanvas::Rect
|
||||
Item::item_to_canvas (ArdourCanvas::Rect const & area) const
|
||||
{
|
||||
ArdourCanvas::Rect r = area;
|
||||
Item const * i = this;
|
||||
|
||||
while (i) {
|
||||
r = i->item_to_parent (r);
|
||||
i = i->parent ();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
Item::set_ignore_events (bool ignore)
|
||||
{
|
||||
@ -340,6 +359,7 @@ Item::dump (ostream& o) const
|
||||
boost::optional<ArdourCanvas::Rect> bb = bounding_box();
|
||||
|
||||
o << _canvas->indent() << whatami() << ' ' << this;
|
||||
o << " @ " << position();
|
||||
|
||||
#ifdef CANVAS_DEBUG
|
||||
if (!name.empty()) {
|
||||
@ -349,6 +369,7 @@ Item::dump (ostream& o) const
|
||||
|
||||
if (bb) {
|
||||
o << endl << _canvas->indent() << "\tbbox: " << bb.get();
|
||||
o << endl << _canvas->indent() << "\tCANVAS bbox: " << item_to_canvas (bb.get());
|
||||
} else {
|
||||
o << " bbox unset";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user