diff options
Diffstat (limited to 'libs/canvas')
-rw-r--r-- | libs/canvas/canvas.cc | 17 | ||||
-rw-r--r-- | libs/canvas/canvas/item.h | 17 | ||||
-rw-r--r-- | libs/canvas/canvas/scroll_group.h | 47 | ||||
-rw-r--r-- | libs/canvas/canvas/wave_view.h | 2 | ||||
-rw-r--r-- | libs/canvas/group.cc | 10 | ||||
-rw-r--r-- | libs/canvas/item.cc | 61 | ||||
-rw-r--r-- | libs/canvas/scroll_group.cc | 63 | ||||
-rw-r--r-- | libs/canvas/wave_view.cc | 26 | ||||
-rw-r--r-- | libs/canvas/wscript | 1 |
9 files changed, 152 insertions, 92 deletions
diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index 8d4c1b8858..aad614d906 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -50,11 +50,9 @@ Canvas::scroll_to (Coord x, Coord y) { Duple d (x, y); - if (_global_scroll) { - _scroll_offset = d; - } - - //_root.scroll_to (d); + _scroll_offset = d; + + _root.scroll_to (d); pick_current_item (0); // no current mouse position } @@ -81,9 +79,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 @@ -208,13 +206,14 @@ Canvas::canvas_to_window (Duple const & d, bool rounded) const Duple wd = d.translate (Duple (-_scroll_offset.x, -_scroll_offset.y)); /* Note that this intentionally almost always returns integer coordinates */ + if (rounded) { wd.x = round (wd.x); wd.y = round (wd.y); } return wd; -} +} Rect Canvas::window_to_canvas (Rect const & r) const diff --git a/libs/canvas/canvas/item.h b/libs/canvas/canvas/item.h index 429df33894..487efae4d0 100644 --- a/libs/canvas/canvas/item.h +++ b/libs/canvas/canvas/item.h @@ -112,22 +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; } + virtual void scroll_to (Duple const&) {} /** @return Position of this item in the parent's coordinates */ Duple position () const { return _position; } + virtual Duple canvas_position () const { + return _position; + } + boost::optional<Rect> bounding_box () const; Coord height() const; Coord width() const; @@ -248,8 +243,6 @@ private: void init (); bool _ignore_events; - ScrollSensitivity _scroll_sensitivity; - Duple _scroll_offset; }; 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 new file mode 100644 index 0000000000..c2b26bf9d9 --- /dev/null +++ b/libs/canvas/canvas/scroll_group.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2014 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __CANVAS_SCROLL_GROUP_H__ +#define __CANVAS_SCROLL_GROUP_H__ + +#include "canvas/group.h" + +namespace ArdourCanvas { + +class LIBCANVAS_API ScrollGroup : public Group +{ + public: + enum ScrollSensitivity { + ScrollsVertically = 0x1, + ScrollsHorizontally = 0x2 + }; + + explicit ScrollGroup (Group *, ScrollSensitivity); + explicit ScrollGroup (Group *, Duple, ScrollSensitivity); + + void scroll_to (Duple const& d); + Duple canvas_position() const; + + private: + ScrollSensitivity _scroll_sensitivity; + Duple _scroll_offset; +}; + +} + +#endif diff --git a/libs/canvas/canvas/wave_view.h b/libs/canvas/canvas/wave_view.h index 307528c685..0ddffca180 100644 --- a/libs/canvas/canvas/wave_view.h +++ b/libs/canvas/canvas/wave_view.h @@ -173,7 +173,7 @@ private: void handle_clip_level_change (); void ensure_cache (ARDOUR::framepos_t sample_start, ARDOUR::framepos_t sample_end) const; - ArdourCanvas::Coord position (double) const; + ArdourCanvas::Coord y_extent (double) const; void draw_image (ARDOUR::PeakData*, int npeaks) const; }; diff --git a/libs/canvas/group.cc b/libs/canvas/group.cc index b6df3dfee6..509be0b51a 100644 --- a/libs/canvas/group.cc +++ b/libs/canvas/group.cc @@ -117,7 +117,9 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const << (*i)->whatami() << ' ' << (*i)->name - << " item = " + << " item " + << item_bbox.get() + << " window = " << item << " intersect = " << draw @@ -136,8 +138,8 @@ Group::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const #ifdef CANVAS_DEBUG if (DEBUG_ENABLED(PBD::DEBUG::CanvasRender)) { - cerr << string_compose ("%1skip render of %2 %3, no intersection\n", _canvas->render_indent(), (*i)->whatami(), - (*i)->name); + cerr << string_compose ("%1skip render of %2 %3, no intersection between %4 and %5\n", _canvas->render_indent(), (*i)->whatami(), + (*i)->name, item, area); } #endif @@ -152,7 +154,7 @@ Group::scroll_to (Duple const& d) { Item::scroll_to (d); - for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ) { + for (list<Item*>::iterator i = _items.begin(); i != _items.end(); ++i) { (*i)->scroll_to (d); } } diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 7a55e9604f..c6652f9d3a 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -35,7 +35,6 @@ using namespace ArdourCanvas; Item::Item (Canvas* canvas) : _canvas (canvas) , _parent (0) - , _scroll_sensitivity (ScrollSensitivity (0)) { init (); } @@ -43,7 +42,6 @@ Item::Item (Canvas* canvas) Item::Item (Group* parent) : _canvas (parent->canvas ()) , _parent (parent) - , _scroll_sensitivity (ScrollSensitivity (0)) { init (); } @@ -52,7 +50,6 @@ Item::Item (Group* parent, Duple position) : _canvas (parent->canvas()) , _parent (parent) , _position (position) - , _scroll_sensitivity (ScrollSensitivity (0)) { init (); } @@ -82,24 +79,6 @@ 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 { @@ -113,7 +92,7 @@ Item::item_to_canvas (ArdourCanvas::Rect const & r) const Duple offset; while (i) { - offset = offset.translate (i->position()); + offset = offset.translate (i->canvas_position()); i = i->parent(); } @@ -127,7 +106,7 @@ Item::item_to_canvas (ArdourCanvas::Duple const & d) const Duple offset; while (i) { - offset = offset.translate (i->position()); + offset = offset.translate (i->canvas_position()); i = i->parent(); } @@ -141,7 +120,7 @@ Item::canvas_to_item (ArdourCanvas::Duple const & d) const Duple offset; while (i) { - offset = offset.translate (-(i->position())); + offset = offset.translate (-(i->canvas_position())); i = i->parent(); } @@ -155,7 +134,7 @@ Item::canvas_to_item (ArdourCanvas::Rect const & d) const Duple offset; while (i) { - offset = offset.translate (-(i->position())); + offset = offset.translate (-(i->canvas_position())); i = i->parent(); } @@ -197,43 +176,19 @@ Item::item_to_window (ArdourCanvas::Duple const & d, bool rounded) const Duple Item::window_to_item (ArdourCanvas::Duple const & d) const { - 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)); + return canvas_to_item (_canvas->window_to_canvas (d)); } ArdourCanvas::Rect Item::item_to_window (ArdourCanvas::Rect const & r) const { - 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))); + return _canvas->canvas_to_window (item_to_canvas (r)); } 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)); + return canvas_to_item (_canvas->window_to_canvas (r)); } /** Set the position of this item in the parent's coordinates */ @@ -576,7 +531,7 @@ Item::dump (ostream& o) const boost::optional<ArdourCanvas::Rect> bb = bounding_box(); o << _canvas->indent() << whatami() << ' ' << this << " Visible ? " << _visible; - o << " @ " << position() << " scrolled-to " << _scroll_offset; + o << " @ " << position(); #ifdef CANVAS_DEBUG if (!name.empty()) { diff --git a/libs/canvas/scroll_group.cc b/libs/canvas/scroll_group.cc new file mode 100644 index 0000000000..bda6911ca7 --- /dev/null +++ b/libs/canvas/scroll_group.cc @@ -0,0 +1,63 @@ +/* + Copyright (C) 2014 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <iostream> +#include "canvas/scroll_group.h" + +using namespace std; +using namespace ArdourCanvas; + +ScrollGroup::ScrollGroup (Group* parent, ScrollSensitivity s) + : Group (parent) + , _scroll_sensitivity (s) +{ +} + +ScrollGroup::ScrollGroup (Group* parent, Duple position, ScrollSensitivity s) + : Group (parent, position) + , _scroll_sensitivity (s) +{ +} + +void +ScrollGroup::scroll_to (Duple const& d) +{ + Duple base_pos (position().translate (_scroll_offset)); + + 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; + } + + set_position (base_pos); +} + +Duple +ScrollGroup::canvas_position() const +{ + /* return the normal "base" position of this item + rather its position as affected by any scroll + offset. + */ + return _position.translate (_scroll_offset); +} diff --git a/libs/canvas/wave_view.cc b/libs/canvas/wave_view.cc index fa2c617d7b..3de5af1c51 100644 --- a/libs/canvas/wave_view.cc +++ b/libs/canvas/wave_view.cc @@ -219,7 +219,7 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const if (_logscaled) { for (int i = 0; i < n_peaks; ++i) { tips[i].bot = height(); - tips[i].top = position (alt_log_meter (fast_coefficient_to_dB (max (fabs (_peaks[i].max), fabs (_peaks[i].min))))); + tips[i].top = y_extent (alt_log_meter (fast_coefficient_to_dB (max (fabs (_peaks[i].max), fabs (_peaks[i].min))))); if (fabs (_peaks[i].max) >= clip_level) { tips[i].clip_max = true; @@ -231,7 +231,7 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const } } else {for (int i = 0; i < n_peaks; ++i) { tips[i].bot = height(); - tips[i].top = position (max (fabs (_peaks[i].max), fabs (_peaks[i].min))); + tips[i].top = y_extent (max (fabs (_peaks[i].max), fabs (_peaks[i].min))); if (fabs (_peaks[i].max) >= clip_level) { tips[i].clip_max = true; @@ -259,19 +259,19 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const } if (top > 0.0) { - top = position (alt_log_meter (fast_coefficient_to_dB (top))); + top = y_extent (alt_log_meter (fast_coefficient_to_dB (top))); } else if (top < 0.0) { - top = position (-alt_log_meter (fast_coefficient_to_dB (-top))); + top = y_extent (-alt_log_meter (fast_coefficient_to_dB (-top))); } else { - top = position (0.0); + top = y_extent (0.0); } if (bot > 0.0) { - bot = position (alt_log_meter (fast_coefficient_to_dB (bot))); + bot = y_extent (alt_log_meter (fast_coefficient_to_dB (bot))); } else if (bot < 0.0) { - bot = position (-alt_log_meter (fast_coefficient_to_dB (-bot))); + bot = y_extent (-alt_log_meter (fast_coefficient_to_dB (-bot))); } else { - bot = position (0.0); + bot = y_extent (0.0); } tips[i].top = top; @@ -289,8 +289,8 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const tips[i].clip_min = true; } - tips[i].top = position (_peaks[i].min); - tips[i].bot = position (_peaks[i].max); + tips[i].top = y_extent (_peaks[i].min); + tips[i].bot = y_extent (_peaks[i].max); } @@ -402,8 +402,8 @@ WaveView::draw_image (PeakData* _peaks, int n_peaks) const set_source_rgba (context, _zero_color); context->set_line_width (1.0); - context->move_to (0, position (0.0) + 0.5); - context->line_to (n_peaks, position (0.0) + 0.5); + context->move_to (0, y_extent (0.0) + 0.5); + context->line_to (n_peaks, y_extent (0.0) + 0.5); context->stroke (); } } @@ -668,7 +668,7 @@ WaveView::region_resized () } Coord -WaveView::position (double s) const +WaveView::y_extent (double s) const { /* it is important that this returns an integral value, so that we can ensure correct single pixel behaviour. diff --git a/libs/canvas/wscript b/libs/canvas/wscript index 913f8298fa..d0cbfc882f 100644 --- a/libs/canvas/wscript +++ b/libs/canvas/wscript @@ -50,6 +50,7 @@ canvas_sources = [ 'polygon.cc', 'rectangle.cc', 'root_group.cc', + 'scroll_group.cc', 'stateful_image.cc', 'text.cc', 'types.cc', |