mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-21 06:06:25 +01:00
different approach to independent scrolling, involving ArdourCanvas::ScrollGroup
The idea now is that a scroll group item can be added to the canvas which will causes its children to scroll in either or both directions (horizontal or vertical). There are few complications: the position() of the ScrollGroup is ambiguous depending on whether you want it with scroll taken into account or not, so Item::canvas_position() was added, which defaults to the same value as Item::position() but is overridden by ScrollGroup to return the position independent of scrolling. This method is used when translating between item/canvas/window coordinate systems. Note that the basic idea is that we MOVE the scroll group when a scroll happens. This mirrors what happens in the GnomeCanvas, where Nick Mainsbridge came up with a great idea that allowed unification of the time bar and track canvases.
This commit is contained in:
parent
6e91e9fd5f
commit
cb9453b475
14 changed files with 200 additions and 122 deletions
|
|
@ -742,7 +742,20 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
|||
ArdourCanvas::Group* transport_marker_bar_group;
|
||||
ArdourCanvas::Group* cd_marker_bar_group;
|
||||
|
||||
/* The group containing all trackviews. Only scrolled vertically. */
|
||||
/* The group containing all other groups that are scrolled vertically
|
||||
and horizontally.
|
||||
*/
|
||||
ArdourCanvas::Group* hv_scroll_group;
|
||||
|
||||
/* The group containing all other groups that are scrolled vertically ONLY
|
||||
*/
|
||||
ArdourCanvas::Group* v_scroll_group;
|
||||
|
||||
/* The group containing all other groups that are scrolled horizontally ONLY
|
||||
*/
|
||||
ArdourCanvas::Group* h_scroll_group;
|
||||
|
||||
/* The group containing all trackviews. */
|
||||
ArdourCanvas::Group* _trackview_group;
|
||||
|
||||
/* The group used for region motion. Sits on top of _trackview_group */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "canvas/canvas.h"
|
||||
#include "canvas/rectangle.h"
|
||||
#include "canvas/pixbuf.h"
|
||||
#include "canvas/scroll_group.h"
|
||||
#include "canvas/text.h"
|
||||
#include "canvas/debug.h"
|
||||
|
||||
|
|
@ -65,7 +66,12 @@ Editor::initialize_canvas ()
|
|||
{
|
||||
_track_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, vertical_adjustment);
|
||||
_track_canvas = _track_canvas_viewport->canvas ();
|
||||
//_track_canvas->set_global_scroll (false);
|
||||
_track_canvas->set_global_scroll (false);
|
||||
|
||||
hv_scroll_group = new ArdourCanvas::ScrollGroup (_track_canvas->root(),
|
||||
ArdourCanvas::ScrollGroup::ScrollSensitivity (ArdourCanvas::ScrollGroup::ScrollsVertically|
|
||||
ArdourCanvas::ScrollGroup::ScrollsHorizontally));
|
||||
CANVAS_DEBUG_NAME (hv_scroll_group, "canvas hv scroll");
|
||||
|
||||
_verbose_cursor = new VerboseCursor (this);
|
||||
|
||||
|
|
@ -80,9 +86,9 @@ Editor::initialize_canvas ()
|
|||
// logo_item->property_width_set() = true;
|
||||
// logo_item->show ();
|
||||
}
|
||||
|
||||
|
||||
/*a group to hold global rects like punch/loop indicators */
|
||||
global_rect_group = new ArdourCanvas::Group (_track_canvas->root());
|
||||
global_rect_group = new ArdourCanvas::Group (hv_scroll_group);
|
||||
CANVAS_DEBUG_NAME (global_rect_group, "global rect group");
|
||||
|
||||
transport_loop_range_rect = new ArdourCanvas::Rectangle (global_rect_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, ArdourCanvas::COORD_MAX));
|
||||
|
|
@ -94,21 +100,20 @@ Editor::initialize_canvas ()
|
|||
transport_punch_range_rect->hide();
|
||||
|
||||
/*a group to hold time (measure) lines */
|
||||
time_line_group = new ArdourCanvas::Group (_track_canvas->root());
|
||||
time_line_group = new ArdourCanvas::Group (hv_scroll_group);
|
||||
CANVAS_DEBUG_NAME (time_line_group, "time line group");
|
||||
|
||||
_trackview_group = new ArdourCanvas::Group (_track_canvas->root());
|
||||
_trackview_group = new ArdourCanvas::Group (hv_scroll_group);
|
||||
//_trackview_group->set_scroll_sensitivity (ArdourCanvas::Group::ScrollSensitivity (ArdourCanvas::Group::ScrollsVertically|ArdourCanvas::Group::ScrollsHorizontally));
|
||||
CANVAS_DEBUG_NAME (_trackview_group, "Canvas TrackViews");
|
||||
|
||||
|
||||
_region_motion_group = new ArdourCanvas::Group (_trackview_group);
|
||||
CANVAS_DEBUG_NAME (_region_motion_group, "Canvas Region Motion");
|
||||
|
||||
/* TIME BAR CANVAS */
|
||||
|
||||
_time_bars_canvas_viewport = new ArdourCanvas::GtkCanvasViewport (horizontal_adjustment, unused_adjustment);
|
||||
_time_bars_canvas = _time_bars_canvas_viewport->canvas ();
|
||||
|
||||
_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));
|
||||
|
|
@ -177,14 +182,14 @@ Editor::initialize_canvas ()
|
|||
transport_bar_drag_rect->set_outline (false);
|
||||
transport_bar_drag_rect->hide ();
|
||||
|
||||
transport_punchin_line = new ArdourCanvas::Line (_track_canvas->root());
|
||||
transport_punchin_line = new ArdourCanvas::Line (hv_scroll_group);
|
||||
transport_punchin_line->set_x0 (0);
|
||||
transport_punchin_line->set_y0 (0);
|
||||
transport_punchin_line->set_x1 (0);
|
||||
transport_punchin_line->set_y1 (ArdourCanvas::COORD_MAX);
|
||||
transport_punchin_line->hide ();
|
||||
|
||||
transport_punchout_line = new ArdourCanvas::Line (_track_canvas->root());
|
||||
transport_punchout_line = new ArdourCanvas::Line (hv_scroll_group);
|
||||
transport_punchout_line->set_x0 (0);
|
||||
transport_punchout_line->set_y0 (0);
|
||||
transport_punchout_line->set_x1 (0);
|
||||
|
|
@ -192,12 +197,12 @@ Editor::initialize_canvas ()
|
|||
transport_punchout_line->hide();
|
||||
|
||||
// used to show zoom mode active zooming
|
||||
zoom_rect = new ArdourCanvas::Rectangle (_track_canvas->root(), ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0));
|
||||
zoom_rect = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0));
|
||||
zoom_rect->hide();
|
||||
zoom_rect->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_zoom_rect_event), (ArdourCanvas::Item*) 0));
|
||||
|
||||
// used as rubberband rect
|
||||
rubberband_rect = new ArdourCanvas::Rectangle (_trackview_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0));
|
||||
rubberband_rect = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0));
|
||||
rubberband_rect->hide();
|
||||
|
||||
tempo_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_tempo_bar_event), tempo_bar));
|
||||
|
|
@ -215,7 +220,7 @@ Editor::initialize_canvas ()
|
|||
}
|
||||
|
||||
|
||||
_canvas_bottom_rect = new ArdourCanvas::Rectangle (_track_canvas->root(), ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, 20));
|
||||
_canvas_bottom_rect = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, ArdourCanvas::COORD_MAX, 20));
|
||||
/* this thing is transparent */
|
||||
_canvas_bottom_rect->set_fill (false);
|
||||
_canvas_bottom_rect->set_outline (false);
|
||||
|
|
@ -591,8 +596,6 @@ Editor::autoscroll_canvas ()
|
|||
|
||||
/* vertical */
|
||||
|
||||
new_pixel = vertical_pos;
|
||||
|
||||
if (y < autoscroll_boundary.y0) {
|
||||
|
||||
/* scroll to make higher tracks visible */
|
||||
|
|
@ -931,7 +934,7 @@ Editor::get_time_bars_group () const
|
|||
ArdourCanvas::Group*
|
||||
Editor::get_track_canvas_group() const
|
||||
{
|
||||
return _track_canvas->root();
|
||||
return hv_scroll_group;
|
||||
}
|
||||
|
||||
ArdourCanvas::GtkCanvasViewport*
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ using namespace Gtk;
|
|||
|
||||
EditorCursor::EditorCursor (Editor& ed, bool (Editor::*callbck)(GdkEvent*,ArdourCanvas::Item*))
|
||||
: _editor (ed)
|
||||
, _time_bars_canvas_item (new ArdourCanvas::Arrow (_editor._time_bars_canvas->root ()))
|
||||
, _track_canvas_item (new ArdourCanvas::Line (_editor._track_canvas->root ()))
|
||||
, _time_bars_canvas_item (new ArdourCanvas::Arrow (_editor.get_time_bars_group()))
|
||||
, _track_canvas_item (new ArdourCanvas::Line (_editor.get_track_canvas_group()))
|
||||
, _length (1.0)
|
||||
{
|
||||
CANVAS_DEBUG_NAME (_time_bars_canvas_item, "timebars editor cursor");
|
||||
|
|
|
|||
|
|
@ -134,18 +134,22 @@ Editor::mouse_frame (framepos_t& where, bool& in_track_canvas) const
|
|||
framepos_t
|
||||
Editor::window_event_sample (GdkEvent const * event, double* pcx, double* pcy) const
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
ArdourCanvas::Duple d;
|
||||
|
||||
if (!gdk_event_get_coords (event, &x, &y)) {
|
||||
if (!gdk_event_get_coords (event, &d.x, &d.y)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* event coordinates are in window units, so convert to canvas
|
||||
* (i.e. account for scrolling)
|
||||
/* adjust for scrolling (the canvas used by Ardour has global scroll
|
||||
* disabled, so we have to do the adjustment explicitly).
|
||||
*/
|
||||
|
||||
ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (x, y));
|
||||
d.translate (ArdourCanvas::Duple (horizontal_adjustment.get_value(), vertical_adjustment.get_value()));
|
||||
|
||||
/* event coordinates are in window units, so convert to canvas
|
||||
*/
|
||||
|
||||
d = _track_canvas->window_to_canvas (d);
|
||||
|
||||
if (pcx) {
|
||||
*pcx = d.x;
|
||||
|
|
@ -317,7 +321,7 @@ Editor::set_canvas_cursor ()
|
|||
|
||||
vector<ArdourCanvas::Item const *> items;
|
||||
|
||||
_track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
|
||||
get_track_canvas_group()->add_items_at_point (ArdourCanvas::Duple (x,y), items);
|
||||
|
||||
// first item will be the upper most
|
||||
|
||||
|
|
@ -2101,7 +2105,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
|
|||
AutomationLine* al;
|
||||
Marker *marker;
|
||||
Location *loc;
|
||||
RegionView* rv;
|
||||
bool is_start;
|
||||
bool ret = true;
|
||||
|
||||
|
|
@ -2186,7 +2189,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type)
|
|||
case FadeOutTrimHandleItem:
|
||||
case FadeInHandleItem:
|
||||
case FadeOutHandleItem:
|
||||
rv = static_cast<RegionView*>(item->get_data ("regionview"));
|
||||
{
|
||||
ArdourCanvas::Rectangle *rect = dynamic_cast<ArdourCanvas::Rectangle *> (item);
|
||||
if (rect) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ VerboseCursor::VerboseCursor (Editor* editor)
|
|||
, _xoffset (0)
|
||||
, _yoffset (0)
|
||||
{
|
||||
_canvas_item = new ArdourCanvas::Text (_editor->_track_canvas->root());
|
||||
_canvas_item = new ArdourCanvas::Text (_editor->get_track_canvas_group());
|
||||
CANVAS_DEBUG_NAME (_canvas_item, "verbose canvas cursor");
|
||||
_canvas_item->set_ignore_events (true);
|
||||
_canvas_item->set_font_description (get_font_for_style (N_("VerboseCanvasCursor")));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
47
libs/canvas/canvas/scroll_group.h
Normal file
47
libs/canvas/canvas/scroll_group.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
63
libs/canvas/scroll_group.cc
Normal file
63
libs/canvas/scroll_group.cc
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ canvas_sources = [
|
|||
'polygon.cc',
|
||||
'rectangle.cc',
|
||||
'root_group.cc',
|
||||
'scroll_group.cc',
|
||||
'stateful_image.cc',
|
||||
'text.cc',
|
||||
'types.cc',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue