summaryrefslogtreecommitdiff
path: root/gtk2_ardour/editor_canvas.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2005-11-28 22:40:22 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2005-11-28 22:40:22 +0000
commit4c7b9537a3386942ff34bbd7a025e5e70fbbc10b (patch)
tree596cd0f152b6aa9209ba913e39f83eacc1df4cdc /gtk2_ardour/editor_canvas.cc
parent2b49b2433b6dc06a52b0848af62373c747f18ac9 (diff)
added file
git-svn-id: svn://localhost/trunk/ardour2@140 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/editor_canvas.cc')
-rw-r--r--gtk2_ardour/editor_canvas.cc357
1 files changed, 357 insertions, 0 deletions
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
new file mode 100644
index 0000000000..181697d4e2
--- /dev/null
+++ b/gtk2_ardour/editor_canvas.cc
@@ -0,0 +1,357 @@
+/*
+ Copyright (C) 2005 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.
+
+ $Id$
+*/
+
+#include <libgnomecanvasmm/init.h>
+#include <jack/types.h>
+
+#include "editor.h"
+#include "waveview.h"
+#include "simplerect.h"
+#include "simpleline.h"
+#include "imageframe.h"
+#include "waveview_p.h"
+#include "simplerect_p.h"
+#include "simpleline_p.h"
+#include "imageframe_p.h"
+#include "canvas_impl.h"
+#include "editing.h"
+#include "rgb_macros.h"
+#include "utils.h"
+#include "time_axis_view.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace sigc;
+using namespace ARDOUR;
+using namespace Gtk;
+using namespace Glib;
+using namespace Gtkmm2ext;
+using namespace Editing;
+
+/* XXX this is a hack. it ought to be the maximum value of an jack_nframes_t */
+
+const double max_canvas_coordinate = (double) JACK_MAX_FRAMES;
+
+extern "C"
+{
+
+GType gnome_canvas_simpleline_get_type(void);
+GType gnome_canvas_simplerect_get_type(void);
+GType gnome_canvas_waveview_get_type(void);
+GType gnome_canvas_imageframe_get_type(void);
+
+}
+
+static void ardour_canvas_type_init()
+{
+ // Map gtypes to gtkmm wrapper-creation functions:
+
+ Glib::wrap_register(gnome_canvas_simpleline_get_type(), &Gnome::Canvas::SimpleLine_Class::wrap_new);
+ Glib::wrap_register(gnome_canvas_simplerect_get_type(), &Gnome::Canvas::SimpleRect_Class::wrap_new);
+ Glib::wrap_register(gnome_canvas_waveview_get_type(), &Gnome::Canvas::WaveView_Class::wrap_new);
+ Glib::wrap_register(gnome_canvas_imageframe_get_type(), &Gnome::Canvas::ImageFrame_Class::wrap_new);
+
+ // Register the gtkmm gtypes:
+
+ (void) Gnome::Canvas::WaveView::get_type();
+ (void) Gnome::Canvas::SimpleLine::get_type();
+ (void) Gnome::Canvas::SimpleRect::get_type();
+ (void) Gnome::Canvas::ImageFrame::get_type();
+}
+
+void
+Editor::initialize_canvas ()
+{
+ ArdourCanvas::init ();
+ ardour_canvas_type_init ();
+
+ /* adjust sensitivity for "picking" items */
+
+ // GNOME_CANVAS(track_canvas)->close_enough = 2;
+
+ track_canvas.signal_event().connect (bind (mem_fun (*this, &Editor::track_canvas_event), (ArdourCanvas::Item*) 0));
+ track_canvas.set_name ("EditorMainCanvas");
+ track_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
+ track_canvas.signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas));
+
+ /* set up drag-n-drop */
+ vector<Gtk::TargetEntry> target_table;
+
+ target_table.push_back (TargetEntry ("STRING"));
+ target_table.push_back (TargetEntry ("text/plain"));
+ target_table.push_back (TargetEntry ("text/uri-list"));
+ target_table.push_back (TargetEntry ("application/x-rootwin-drop"));
+
+ // GTK2FIX
+ // track_canvas.drag_dest_set (target_table, DEST_DEFAULT_ALL, GdkDragAction (Gdk::ACTION_COPY|Gdk::ACTION_MOVE));
+ // track_canvas.signal_drag_data_received().connect (mem_fun(*this, &Editor::track_canvas_drag_data_received));
+
+ /* stuff for the verbose canvas cursor */
+
+ Pango::FontDescription font = get_font_for_style (N_("VerboseCanvasCursor"));
+
+ verbose_canvas_cursor = new ArdourCanvas::Text (*track_canvas.root());
+ verbose_canvas_cursor->property_font_desc() = font;
+ // GTK2FIX
+ // verbose_canvas_cursor->property_anchor() = GTK_ANCHOR_NW;
+ verbose_canvas_cursor->property_fill_color_rgba() = color_map[cVerboseCanvasCursor];
+
+ verbose_cursor_visible = false;
+
+ /* a group to hold time (measure) lines */
+
+ time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
+ cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
+
+ time_canvas.set_name ("EditorTimeCanvas");
+ time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
+
+ meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
+ tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
+ marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0);
+ range_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 3.0);
+ transport_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 4.0);
+
+ tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ tempo_bar->property_fill_color_rgba() = color_map[cTempoBar];
+ tempo_bar->property_outline_pixels() = 0;
+
+ meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ meter_bar->property_fill_color_rgba() = color_map[cMeterBar];
+ meter_bar->property_outline_pixels() = 0;
+
+ marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ marker_bar->property_fill_color_rgba() = color_map[cMarkerBar];
+ marker_bar->property_outline_pixels() = 0;
+
+ range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ range_marker_bar->property_fill_color_rgba() = color_map[cRangeMarkerBar];
+ range_marker_bar->property_outline_pixels() = 0;
+
+ transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ transport_marker_bar->property_fill_color_rgba() = color_map[cTransportMarkerBar];
+ transport_marker_bar->property_outline_pixels() = 0;
+
+ range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ range_bar_drag_rect->property_fill_color_rgba() = color_map[cRangeDragBarRectFill];
+ range_bar_drag_rect->property_outline_color_rgba() = color_map[cRangeDragBarRect];
+ range_bar_drag_rect->property_outline_pixels() = 0;
+ range_bar_drag_rect->hide ();
+
+ transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height);
+ transport_bar_drag_rect ->property_fill_color_rgba() = color_map[cTransportDragRectFill];
+ transport_bar_drag_rect->property_outline_color_rgba() = color_map[cTransportDragRect];
+ transport_bar_drag_rect->property_outline_pixels() = 0;
+ transport_bar_drag_rect->hide ();
+
+ marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0));
+ marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0));
+
+ marker_drag_line = new ArdourCanvas::Line (*track_canvas.root());
+ marker_drag_line->property_width_pixels() = 1;
+ marker_drag_line->property_fill_color_rgba() = color_map[cMarkerDragLine];
+ marker_drag_line->property_points() = marker_drag_line_points;
+ marker_drag_line->hide();
+
+ range_marker_drag_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0);
+ range_marker_drag_rect->property_fill_color_rgba() = color_map[cRangeDragRectFill];
+ range_marker_drag_rect->property_outline_color_rgba() = color_map[cRangeDragRect];
+ range_marker_drag_rect->hide ();
+
+ transport_loop_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0);
+ transport_loop_range_rect->property_fill_color_rgba() = color_map[cTransportLoopRectFill];
+ transport_loop_range_rect->property_outline_color_rgba() = color_map[cTransportLoopRect];
+ transport_loop_range_rect->property_outline_pixels() = 1;
+ transport_loop_range_rect->hide();
+
+ transport_punch_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0);
+ transport_punch_range_rect->property_fill_color_rgba() = color_map[cTransportPunchRectFill];
+ transport_punch_range_rect->property_outline_color_rgba() = color_map[cTransportPunchRect];
+ transport_punch_range_rect->property_outline_pixels() = 0;
+ transport_punch_range_rect->hide();
+
+ transport_loop_range_rect->lower_to_bottom (); // loop on the bottom
+
+ transport_punchin_line = new ArdourCanvas::SimpleLine (*time_line_group);
+ transport_punchin_line->property_x1() = 0.0;
+ transport_punchin_line->property_y1() = 0.0;
+ transport_punchin_line->property_x2() = 0.0;
+ transport_punchin_line->property_y2() = 0.0;
+ transport_punchin_line->property_color_rgba() = color_map[cPunchInLine];
+ transport_punchin_line->hide ();
+
+ transport_punchout_line = new ArdourCanvas::SimpleLine (*time_line_group);
+ transport_punchout_line->property_x1() = 0.0;
+ transport_punchout_line->property_y1() = 0.0;
+ transport_punchout_line->property_x2() = 0.0;
+ transport_punchout_line->property_y2() = 0.0;
+ transport_punchout_line->property_color_rgba() = color_map[cPunchOutLine];
+ transport_punchout_line->hide();
+
+ // used to show zoom mode active zooming
+ zoom_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0);
+ zoom_rect->property_fill_color_rgba() = color_map[cZoomRectFill];
+ zoom_rect->property_outline_color_rgba() = color_map[cZoomRect];
+ zoom_rect->property_outline_pixels() = 1;
+ zoom_rect->hide();
+
+ zoom_rect->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_zoom_rect_event), (ArdourCanvas::Item*) 0));
+
+ // used as rubberband rect
+ rubberband_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0);
+ rubberband_rect->property_outline_color_rgba() = color_map[cRubberBandRect];
+ rubberband_rect->property_fill_color_rgba() = (guint32) color_map[cRubberBandRectFill];
+ rubberband_rect->property_outline_pixels() = 1;
+ rubberband_rect->hide();
+
+ tempo_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_tempo_bar_event), tempo_bar));
+ meter_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_meter_bar_event), meter_bar));
+ marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_marker_bar_event), marker_bar));
+ range_marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_range_marker_bar_event), range_marker_bar));
+ transport_marker_bar->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_transport_marker_bar_event), transport_marker_bar));
+
+ /* separator lines */
+
+ tempo_line = new ArdourCanvas::SimpleLine (*tempo_group, 0, timebar_height, max_canvas_coordinate, timebar_height);
+ tempo_line->property_color_rgba() = RGBA_TO_UINT (0,0,0,255);
+
+ meter_line = new ArdourCanvas::SimpleLine (*meter_group, 0, timebar_height, max_canvas_coordinate, timebar_height);
+ meter_line->property_color_rgba() = RGBA_TO_UINT (0,0,0,255);
+
+ marker_line = new ArdourCanvas::SimpleLine (*marker_group, 0, timebar_height, max_canvas_coordinate, timebar_height);
+ marker_line->property_color_rgba() = RGBA_TO_UINT (0,0,0,255);
+
+ range_marker_line = new ArdourCanvas::SimpleLine (*range_marker_group, 0, timebar_height, max_canvas_coordinate, timebar_height);
+ range_marker_line->property_color_rgba() = RGBA_TO_UINT (0,0,0,255);
+
+ transport_marker_line = new ArdourCanvas::SimpleLine (*transport_marker_group, 0, timebar_height, max_canvas_coordinate, timebar_height);
+ transport_marker_line->property_color_rgba() = RGBA_TO_UINT (0,0,0,255);
+
+ ZoomChanged.connect (bind (mem_fun(*this, &Editor::update_loop_range_view), false));
+ ZoomChanged.connect (bind (mem_fun(*this, &Editor::update_punch_range_view), false));
+
+ double time_height = timebar_height * 5;
+ double time_width = FLT_MAX/frames_per_unit;
+ time_canvas.set_scroll_region(0.0, 0.0, time_width, time_height);
+
+ edit_cursor = new Cursor (*this, "blue", &Editor::canvas_edit_cursor_event);
+ playhead_cursor = new Cursor (*this, "red", &Editor::canvas_playhead_cursor_event);
+
+ track_canvas.signal_size_allocate().connect (mem_fun(*this, &Editor::track_canvas_allocate));
+}
+
+void
+Editor::reset_scrolling_region (Gtk::Allocation* alloc)
+{
+ guint32 last_canvas_unit;
+ double height;
+ guint32 canvas_alloc_height, canvas_alloc_width;
+ TrackViewList::iterator i;
+ static bool first_time = true;
+
+ /* We need to make sure that the canvas always has its
+ scrolling region set to larger of:
+
+ - the size allocated for it (within the container its packed in)
+ - the size required to see the entire session
+
+ If we don't ensure at least the first of these, the canvas
+ does some wierd and in my view unnecessary stuff to center
+ itself within the allocated area, which causes bad, bad
+ results.
+
+ XXX GnomeCanvas has fixed this, and has an option to
+ control the centering behaviour.
+ */
+
+ last_canvas_unit = (guint32) ceil ((float) max_frames / frames_per_unit);
+
+ height = 0;
+
+ if (session) {
+ for (i = track_views.begin(); i != track_views.end(); ++i) {
+ if ((*i)->control_parent) {
+ height += (*i)->effective_height;
+ height += track_spacing;
+ }
+ }
+
+ if (height) {
+ height -= track_spacing;
+ }
+ }
+
+ canvas_height = (guint32) height;
+
+ if (alloc) {
+ canvas_alloc_height = alloc->get_height();
+ canvas_alloc_width = alloc->get_width();
+ } else {
+ canvas_alloc_height = track_canvas.get_height();
+ canvas_alloc_width = track_canvas.get_width();
+ }
+
+ canvas_height = max (canvas_height, canvas_alloc_height);
+ track_canvas.set_scroll_region ( 0.0, 0.0, max (last_canvas_unit, canvas_alloc_width), canvas_height);
+
+ if (edit_cursor) edit_cursor->set_length (canvas_alloc_height);
+ if (playhead_cursor) playhead_cursor->set_length (canvas_alloc_height);
+
+ if (marker_drag_line) {
+ marker_drag_line_points.back().set_x(canvas_height);
+ // cerr << "set mlA points, nc = " << marker_drag_line_points.num_points << endl;
+ marker_drag_line->property_points() = marker_drag_line_points;
+ }
+ if (range_marker_drag_rect) {
+ range_marker_drag_rect->property_y1() = 0.0;
+ range_marker_drag_rect->property_y2() = (double) canvas_height;
+ }
+
+ if (transport_loop_range_rect) {
+ transport_loop_range_rect->property_y1() = 0.0;
+ transport_loop_range_rect->property_y2() = (double) canvas_height;
+ }
+
+ if (transport_punch_range_rect) {
+ transport_punch_range_rect->property_y1() = 0.0;
+ transport_punch_range_rect->property_y2() = (double) canvas_height;
+ }
+
+ if (transport_punchin_line) {
+ transport_punchin_line->property_y1() = 0.0;
+ transport_punchin_line->property_y2() = (double) canvas_height;
+ }
+
+ if (transport_punchout_line) {
+ transport_punchout_line->property_y1() = 0.0;
+ transport_punchout_line->property_y2() = (double) canvas_height;
+ }
+
+ update_fixed_rulers ();
+
+ if (is_visible() && first_time) {
+ tempo_map_changed (Change (0));
+ first_time = false;
+ } else {
+ redisplay_tempo ();
+ }
+}
+