merge 2.0-ongoing into 3.0 @ 3581 - 3710
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Sep 2008 21:27:39 +0000 (21:27 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 10 Sep 2008 21:27:39 +0000 (21:27 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3712 d708f5d6-7413-0410-9779-e7cbd77b26cf

51 files changed:
SConstruct
gtk2_ardour/SConscript
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_cursors.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_route_list.cc
gtk2_ardour/editor_rulers.cc
gtk2_ardour/editor_tempodisplay.cc
gtk2_ardour/lv2_plugin_ui.cc [new file with mode: 0644]
gtk2_ardour/lv2_plugin_ui.h [new file with mode: 0644]
gtk2_ardour/main.cc
gtk2_ardour/marker.cc
gtk2_ardour/mixer_ui.cc
gtk2_ardour/plugin_selector.cc
gtk2_ardour/plugin_ui.cc
gtk2_ardour/plugin_ui.h
gtk2_ardour/public_editor.h
gtk2_ardour/region_view.cc
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/streamview.cc
gtk2_ardour/streamview.h
gtk2_ardour/time_axis_view.cc
gtk2_ardour/time_axis_view_item.cc
gtk2_ardour/time_axis_view_item.h
gtk2_ardour/utils.cc
libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/region.h
libs/ardour/audio_unit.cc
libs/ardour/audioengine.cc
libs/ardour/lv2_plugin.cc
libs/ardour/rb_effect.cc
libs/ardour/region.cc
libs/ardour/sndfilesource.cc
libs/pbd/pbd/xml++.h
libs/pbd/xml++.cc
libs/surfaces/control_protocol/SConscript
libs/surfaces/generic_midi/SConscript
libs/surfaces/mackie/SConscript
libs/surfaces/tranzport/SConscript
libs/vamp-plugins/SConscript
svn_revision.h
tools/osx_packaging/app_build.rb

index c887145a0c03c958c12628a545be8935e138a518..6a20c5685fb28d21ab4a4d874208fd9a3e19a366 100644 (file)
@@ -54,7 +54,7 @@ opts.AddOptions(
     BoolOption('UNIVERSAL', 'Compile as universal binary.  Requires that external libraries are already universal.', 0),
     BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
     BoolOption('VST', 'Compile with support for VST', 0),
-    BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 0),
+    BoolOption('LV2', 'Compile with support for LV2 (if slv2 is available)', 1),
     BoolOption('GPROFILE', 'Compile with support for gprofile (Developers only)', 0),
     BoolOption('FREEDESKTOP', 'Install MIME type, icons and .desktop file as per the freedesktop.org spec (requires xdg-utils and shared-mime-info). "scons uninstall" removes associations in desktop database', 0),
     BoolOption('TRANZPORT', 'Compile with support for Frontier Designs (if libusb is available)', 1),
@@ -565,17 +565,14 @@ else:
        print 'FREESOUND support is not enabled.  Build with \'scons FREESOUND=1\' to enable.'
 
 if env['LV2']:
-       conf = env.Configure(custom_tests = { 'CheckPKGExists' : CheckPKGExists })
+       conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion})
        
-       if conf.CheckPKGExists ('slv2'):
+       if conf.CheckPKGVersion('slv2', '0.6.0'):
                libraries['slv2'] = LibraryInfo()
                libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
                 env.Append (CCFLAGS="-DHAVE_LV2")
        else:
-               print 'Building Ardour with LV2 support requires SLV2 >= 0.6.0'
-               print 'WARNING: SLV2 not found, or too old.  Ardour will be built without LV2 support.'
-               print 'Until the 2.4 release, Ardour requires SLV2 out of SVN.'
-               print 'Testing would be very much appreciated!  svn co http://svn.drobilla.net/lad/slv2'
+               print 'LV2 support is not enabled (SLV2 not found or older than 0.6.0)'
                env['LV2'] = 0
        conf.Finish()
 else:
@@ -767,6 +764,13 @@ if env['DIST_TARGET'] in ['panther', 'tiger', 'leopard' ]:
     # force tiger or later, to avoid issues on PPC which defaults
     # back to 10.1 if we don't tell it otherwise.
     env.Append (CCFLAGS="-DMAC_OS_X_VERSION_MIN_REQUIRED=1040")
+
+    if env['DIST_TARGET'] == 'leopard':
+        # need this to really build against the 10.4 SDK when building on leopard
+        # ideally this would be configurable, but lets just do that later when we need it
+        env.Append(CCFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk")
+        env.Append(LINKFLAGS="-mmacosx-version-min=10.4 -isysroot /Developer/SDKs/MacOSX10.4u.sdk")
+
 else:
     env['IS_OSX'] = 0
 
@@ -836,12 +840,13 @@ def prep_libcheck(topenv, libinfo):
        #
        # rationale: GTK-Quartz uses jhbuild and installs to /opt/gtk by default.
        #            All libraries needed should be built against this location
+       # However.. now jhbuild installs to ~/gtk/inst by default.. changed to accomodate this
        if topenv['GTKOSX']:
-               gtkroot = os.path.expanduser ("~");
-               libinfo.Append(CPPPATH="$GTKROOT/include", LIBPATH="$GTKROOT/lib")
-               libinfo.Append(CXXFLAGS="-I$GTKROOT/include", LINKFLAGS="-L$GTKROOT/lib")
-       libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
-       libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
+               GTKROOT = os.path.expanduser ('~/gtk/inst')
+               libinfo.Append(CPPPATH= GTKROOT + "/include", LIBPATH= GTKROOT + "/lib")
+               libinfo.Append(CXXFLAGS="-I" + GTKROOT + "/include", LINKFLAGS="-L" + GTKROOT + "/lib")
+       #libinfo.Append(CPPPATH="/opt/local/include", LIBPATH="/opt/local/lib")
+       #libinfo.Append(CXXFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
 
 prep_libcheck(env, env)
 
@@ -859,25 +864,25 @@ libraries['vamphost'] = LibraryInfo (LIBS='vamphostsdk',
 
 env['RUBBERBAND'] = False
 
-#conf = Configure (env)
-#
-#if conf.CheckHeader ('fftw3.h'):
-#    env['RUBBERBAND'] = True
-#    libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
-#                                           LIBPATH='#libs/rubberband',
-#                                           CPPPATH='#libs/rubberband',
-#                                           CCFLAGS='-DUSE_RUBBERBAND')
-#else:
-#    print ""
-#    print "-------------------------------------------------------------------------"
-#    print "You do not have the FFTW single-precision development package installed."
-#    print "This prevents Ardour from using the Rubberband library for timestretching"
-#    print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
-#    print "pitchshifting will not be available."
-#    print "-------------------------------------------------------------------------"
-#    print ""
-#
-#conf.Finish()
+conf = Configure (env)
+
+if conf.CheckHeader ('fftw3.h'):
+    env['RUBBERBAND'] = True
+    libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
+                                           LIBPATH='#libs/rubberband',
+                                           CPPPATH='#libs/rubberband',
+                                           CCFLAGS='-DUSE_RUBBERBAND')
+else:
+    print ""
+    print "-------------------------------------------------------------------------"
+    print "You do not have the FFTW single-precision development package installed."
+    print "This prevents Ardour from using the Rubberband library for timestretching"
+    print "and pitchshifting. It will fall back on SoundTouch for timestretch, and "
+    print "pitchshifting will not be available."
+    print "-------------------------------------------------------------------------"
+    print ""
+
+conf.Finish()
 
 #
 # Check for libusb
index 836755c0644f4d4ddbc90917f57376b0595cdbb6..136fe6a3db944bf4370041546f93c6713a5833a0 100644 (file)
@@ -286,8 +286,11 @@ if env['VST']:
        extra_sources += vst_files
        gtkardour.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst")
 
+lv2_files = [ 'lv2_plugin_ui.cc' ]
+
 if env['LV2']:
-       gtkardour.Append (CCFLAGS="-DHAVE_SLV2")
+       extra_sources += lv2_files
+       gtkardour.Append (CCFLAGS="-DHAVE_LV2")
        gtkardour.Merge ([libraries['slv2']])
 
 
@@ -432,7 +435,7 @@ else:
        keybindings_dict['%LEVEL4%'] = env['WINDOWS_KEY']
        keybindings_dict['%WINDOW%'] = 'Alt'
 
-for b in [ 'SAE-de', 'mnemonic-us', 'ergonomic-us' ]:
+for b in [ 'SAE-de',  'SAE-us', 'mnemonic-us', 'ergonomic-us' ]:
        target_file = b + '.bindings'
        src_file = target_file + '.in'
        Default (env.SubstInFile (target_file, src_file, SUBST_DICT = keybindings_dict))
index 1e55d2be1fcf14fef963e73cbd4fa4c34166a36c..9ed6d0e599c79d685678e9803cd675efa0b91597 100644 (file)
@@ -1344,7 +1344,7 @@ ARDOUR_UI::do_transport_locate (nframes_t new_position)
 }
 
 void
-ARDOUR_UI::transport_goto_start ()
+ARDOUR_UI::transport_goto_start ()  
 {
        if (session) {
                session->goto_start();
index a3dbc1d3d0761e3620d03ba66c6bbf7e02e1f8fa..23b9787408c9ea658db0556fe7d92b513461fae9 100644 (file)
@@ -104,6 +104,9 @@ AudioClock::AudioClock (std::string clock_name, bool transient, std::string widg
                Gtkmm2ext::set_size_request_to_display_given_text(*smpte_upper_info_label, "23.98",0,0);
                Gtkmm2ext::set_size_request_to_display_given_text(*smpte_lower_info_label, "NDF",0,0);
 
+               Gtkmm2ext::set_size_request_to_display_given_text(*bbt_upper_info_label, "88|88",0,0);
+               Gtkmm2ext::set_size_request_to_display_given_text(*bbt_lower_info_label, "888.88",0,0);
+
                frames_info_box.pack_start (*frames_upper_info_label, true, true);
                frames_info_box.pack_start (*frames_lower_info_label, true, true);
                smpte_info_box.pack_start (*smpte_upper_info_label, true, true);
@@ -644,11 +647,17 @@ AudioClock::set_bbt (nframes_t when, bool force)
        }
 
        sprintf (buf, "%03" PRIu32, bbt.bars);
-       bars_label.set_text (buf);
+       if (force || bars_label.get_text () != buf) {
+               bars_label.set_text (buf);
+       }
        sprintf (buf, "%02" PRIu32, bbt.beats);
-       beats_label.set_text (buf);
+       if (force || beats_label.get_text () != buf) {
+               beats_label.set_text (buf);
+       }
        sprintf (buf, "%04" PRIu32, bbt.ticks);
-       ticks_label.set_text (buf);
+       if (force || ticks_label.get_text () != buf) {
+               ticks_label.set_text (buf);
+       }
        
        if (bbt_upper_info_label) {
                nframes64_t pos;
index ab8940874ccd61f651bee76c0355924e5a180b55..6c276f3b0c96591c1a219afd87400e608439451c 100644 (file)
@@ -209,8 +209,7 @@ Editor::Editor ()
          range_mark_label (_("Range Markers")),
          transport_mark_label (_("Loop/Punch Ranges")),
          cd_mark_label (_("CD Markers")),
-
-         edit_packer (3, 3, true),
+         edit_packer (3, 4, true),
 
          /* the values here don't matter: layout widgets
             reset them as needed.
@@ -219,9 +218,6 @@ Editor::Editor ()
          vertical_adjustment (0.0, 0.0, 10.0, 400.0),
          horizontal_adjustment (0.0, 0.0, 20.0, 1200.0),
 
-         tempo_lines(0),
-         marker_tempo_lines(0),
-
          /* tool bar related */
 
          edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true),
@@ -375,7 +371,6 @@ Editor::Editor ()
        range_marker_drag_rect = 0;
        marker_drag_line = 0;
        tempo_map_change_idle_handler_id = -1;
-       canvas_hroizontally_scrolled_handler_id = -1;
        set_midi_edit_mode (MidiEditPencil, true);
        set_mouse_mode (MouseObject, true);
 
@@ -390,16 +385,10 @@ Editor::Editor ()
        initialize_canvas ();
 
        edit_controls_vbox.set_spacing (0);
-       horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled), false);
+       horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::scroll_canvas_horizontally), false);
        vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true);
-       
-       track_canvas->set_hadjustment (horizontal_adjustment);
-       track_canvas->set_vadjustment (vertical_adjustment);
-       time_canvas->set_hadjustment (horizontal_adjustment);
-
        track_canvas->signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler));
-       time_canvas->signal_map_event().connect (mem_fun (*this, &Editor::time_canvas_map_handler));
-       
+
        controls_layout.add (edit_controls_vbox);
        controls_layout.set_name ("EditControlsBase");
        controls_layout.add_events (Gdk::SCROLL_MASK);
@@ -436,9 +425,8 @@ Editor::Editor ()
        time_canvas_vbox.pack_start (*smpte_ruler, false, false);
        time_canvas_vbox.pack_start (*frames_ruler, false, false);
        time_canvas_vbox.pack_start (*bbt_ruler, false, false);
-       time_canvas_vbox.pack_start (*time_canvas, true, true);
-       time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 5);
-
+       //time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2);
+       time_canvas_vbox.set_size_request (-1, -1);
        bbt_label.set_name ("EditorTimeButton");
        bbt_label.set_size_request (-1, (int)timebar_height);
        bbt_label.set_alignment (1.0, 0.5);
@@ -455,6 +443,7 @@ Editor::Editor ()
        frame_label.set_size_request (-1, (int)timebar_height);
        frame_label.set_alignment (1.0, 0.5);
        frame_label.set_padding (5,0);
+
        tempo_label.set_name ("EditorTimeButton");
        tempo_label.set_size_request (-1, (int)timebar_height);
        tempo_label.set_alignment (1.0, 0.5);
@@ -479,26 +468,26 @@ Editor::Editor ()
        transport_mark_label.set_size_request (-1, (int)timebar_height);
        transport_mark_label.set_alignment (1.0, 0.5);
        transport_mark_label.set_padding (5,0);
+
+       ruler_label_vbox.pack_start (minsec_label, false, false);
+       ruler_label_vbox.pack_start (smpte_label, false, false);
+       ruler_label_vbox.pack_start (frame_label, false, false);
+       ruler_label_vbox.pack_start (bbt_label, false, false);
        
-       time_button_vbox.pack_start (minsec_label, false, false);
-       time_button_vbox.pack_start (smpte_label, false, false);
-       time_button_vbox.pack_start (frame_label, false, false);
-       time_button_vbox.pack_start (bbt_label, false, false);
+       ruler_label_event_box.add (ruler_label_vbox);   
+       ruler_label_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
+       ruler_label_event_box.set_name ("TimebarLabelBase");
+       ruler_label_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release));
+
        time_button_vbox.pack_start (meter_label, false, false);
        time_button_vbox.pack_start (tempo_label, false, false);
        time_button_vbox.pack_start (mark_label, false, false);
 
        time_button_event_box.add (time_button_vbox);
        time_button_event_box.set_name ("TimebarLabelBase");
-       time_button_frame.set_shadow_type (Gtk::SHADOW_NONE);
-       
        time_button_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
        time_button_event_box.signal_button_release_event().connect (mem_fun(*this, &Editor::ruler_label_button_release));
 
-       time_button_frame.add (time_button_event_box);
-       time_button_frame.set_name ("TimebarLabelBase");
-       time_button_frame.set_shadow_type (Gtk::SHADOW_ETCHED_OUT);
-
        /* these enable us to have a dedicated window (for cursor setting, etc.) 
           for the canvas areas.
        */
@@ -514,16 +503,16 @@ Editor::Editor ()
        edit_packer.set_border_width (0);
        edit_packer.set_name ("EditorWindow");
        
-       edit_packer.attach (edit_vscrollbar,         3, 4, 1, 2,    FILL,        FILL|EXPAND, 0, 0);
-
-       edit_packer.attach (time_button_frame,       0, 2, 0, 1,    FILL,        SHRINK, 0, 0);
-       edit_packer.attach (time_canvas_event_box,   2, 4, 0, 1,    FILL|EXPAND, FILL, 0, 0);
+       edit_packer.attach (edit_vscrollbar,         0, 1, 0, 4,    FILL,        FILL|EXPAND, 0, 0);
+       edit_packer.attach (ruler_label_event_box,       1, 2, 0, 1,    FILL,        SHRINK, 0, 0);
+       edit_packer.attach (time_button_event_box,       1, 2, 1, 2,    FILL,        SHRINK, 0, 0);
+       edit_packer.attach (time_canvas_event_box,   2, 3, 0, 1,    FILL|EXPAND, FILL, 0, 0);
 
-       edit_packer.attach (controls_layout,         1, 2, 1, 2,    FILL,        FILL|EXPAND, 0, 0);
-       edit_packer.attach (track_canvas_event_box,  2, 3, 1, 2,    FILL|EXPAND, FILL|EXPAND, 0, 0);
+       edit_packer.attach (controls_layout,         1, 2, 2, 3,    FILL,        FILL|EXPAND, 0, 0);
+       edit_packer.attach (track_canvas_event_box,  2, 3, 1, 3,    FILL|EXPAND, FILL|EXPAND, 0, 0);
 
-       edit_packer.attach (zoom_box,                1, 2, 2, 3,    FILL,         FILL, 0, 0);
-       edit_packer.attach (edit_hscrollbar,         2, 3, 2, 3,    FILL|EXPAND,  FILL, 0, 0);
+       edit_packer.attach (zoom_box,                1, 2, 3, 4,    FILL,         FILL, 0, 0);
+       edit_packer.attach (edit_hscrollbar,         2, 3, 3, 4,    FILL|EXPAND,  FILL, 0, 0);
 
        bottom_hbox.set_border_width (2);
        bottom_hbox.set_spacing (3);
@@ -854,20 +843,10 @@ Editor::~Editor()
                track_canvas = 0;
        }
 
-       if (time_canvas) {
-               delete time_canvas;
-               time_canvas = 0;
-       }
-
        if (track_canvas) {
                delete track_canvas;
                track_canvas = 0;
        }
-
-       if (time_canvas) {
-               delete time_canvas;
-               time_canvas = 0;
-       }
 }
 
 void
@@ -1103,6 +1082,7 @@ Editor::start_scrolling ()
 {
        scroll_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect 
                (mem_fun(*this, &Editor::update_current_screen));
+
 }
 
 void
@@ -1161,7 +1141,7 @@ Editor::handle_new_duration ()
        if (new_end > last_canvas_frame) {
                last_canvas_frame = new_end;
                horizontal_adjustment.set_upper (last_canvas_frame / frames_per_unit);
-               reset_scrolling_region ();
+               //reset_scrolling_region ();
        }
 
        horizontal_adjustment.set_value (leftmost_frame/frames_per_unit);
@@ -3562,13 +3542,23 @@ Editor::hide_verbose_canvas_cursor ()
 double
 Editor::clamp_verbose_cursor_x (double x)
 {
-       return min (horizontal_adjustment.get_value() + canvas_width - 75.0, x);
+       if (x < 0) {
+               x = 0;
+       } else {
+               x = min (canvas_width - 200.0, x);
+       }
+       return x;
 }
 
 double
 Editor::clamp_verbose_cursor_y (double y)
 {
-       return min (vertical_adjustment.get_value() + canvas_height - 50.0, y);
+       if (y < canvas_timebars_vsize) {
+               y = canvas_timebars_vsize;
+       } else {
+               y = min (canvas_height - 50, y);
+       }
+       return y;
 }
 
 void
@@ -3577,7 +3567,7 @@ Editor::set_verbose_canvas_cursor (const string & txt, double x, double y)
        verbose_canvas_cursor->property_text() = txt.c_str();
        /* don't get too close to the edge */
        verbose_canvas_cursor->property_x() = clamp_verbose_cursor_x (x);
-       verbose_canvas_cursor->property_y() = clamp_verbose_cursor_x (y);
+       verbose_canvas_cursor->property_y() = clamp_verbose_cursor_y (y);
 }
 
 void
@@ -4014,7 +4004,8 @@ void
 Editor::end_location_changed (Location* location)
 {
        ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::end_location_changed), location));
-       reset_scrolling_region ();
+       //reset_scrolling_region ();
+       horizontal_adjustment.set_upper ( location->start());
 }
 
 int
@@ -4405,6 +4396,7 @@ Editor::on_key_release_event (GdkEventKey* ev)
 void
 Editor::reset_x_origin (nframes64_t frame)
 {
+       //cerr << "resetting x origin" << endl;
        queue_visual_change (frame);
 }
 
@@ -4532,10 +4524,6 @@ Editor::set_frames_per_unit (double fpu)
                return;
        }
 
-       if (fpu == frames_per_unit) {
-               return;
-       }
-
        frames_per_unit = fpu;
        post_zoom ();
 }
@@ -4566,9 +4554,11 @@ Editor::post_zoom ()
        ZoomChanged (); /* EMIT_SIGNAL */
 
        reset_hscrollbar_stepping ();
-       reset_scrolling_region ();
+       //reset_scrolling_region ();
 
-       if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame);
+       if (playhead_cursor) {
+               playhead_cursor->set_position (playhead_cursor->current_frame);
+       }
 
        instant_save ();
 }
@@ -4576,10 +4566,12 @@ Editor::post_zoom ()
 void
 Editor::queue_visual_change (nframes64_t where)
 {
-       pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
-       pending_visual_change.time_origin = where;
+//     pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
+//     pending_visual_change.time_origin = where;
 
        if (pending_visual_change.idle_handler_id < 0) {
+               pending_visual_change.pending = VisualChange::Type (pending_visual_change.pending | VisualChange::TimeOrigin);
+               pending_visual_change.time_origin = where;
                pending_visual_change.idle_handler_id = g_idle_add (_idle_visual_changer, this);
        }
 }
@@ -4606,13 +4598,6 @@ int
 Editor::idle_visual_changer ()
 {
        VisualChange::Type p = pending_visual_change.pending;
-       nframes64_t csf, cef;
-
-       if (session) {
-               csf = session->current_start_frame();
-               cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker
-       }
-
        pending_visual_change.pending = (VisualChange::Type) 0;
 
        if (p & VisualChange::ZoomLevel) {
@@ -4624,26 +4609,29 @@ Editor::idle_visual_changer ()
                update_tempo_based_rulers ();
        }
        if (p & VisualChange::TimeOrigin) {
-               
-               nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+               nframes64_t csf, cef;
+               nframes64_t current_time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+               if (session) {
+                       csf = session->current_start_frame();
+                       cef = session->current_end_frame() + (current_page_frames() / 24);// Add a little extra so we can see the end marker
+               }
 
                /* if we seek beyond the current end of the canvas, move the end */
 
-               if (time_origin != pending_visual_change.time_origin) {
-                       
-                       if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) {
-                               last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames();
-                               horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit);
-                               reset_scrolling_region ();
-                       }
-                       
-                       horizontal_adjustment.set_value (pending_visual_change.time_origin/frames_per_unit);
+               if (current_time_origin != pending_visual_change.time_origin) {
+                       //if (horizontal_adjustment.get_upper() < pending_visual_change.time_origin) {
+                       last_canvas_frame = (cef > (pending_visual_change.time_origin + current_page_frames())) ? cef : pending_visual_change.time_origin + current_page_frames();
+                       horizontal_adjustment.set_upper ((cef - csf) / frames_per_unit);
+                       //}
+                       horizontal_adjustment.set_value (pending_visual_change.time_origin / frames_per_unit);
                } else {
                        update_fixed_rulers();
                        redisplay_tempo (true);
                }
        }
-
+       //cerr << "Editor::idle_visual_changer () called ha v:l:u:ps:fpu = " << horizontal_adjustment.get_value() << ":" << horizontal_adjustment.get_lower() << ":" << horizontal_adjustment.get_upper() << ":" << horizontal_adjustment.get_page_size() << ":" << frames_per_unit << endl;//DEBUG
        pending_visual_change.idle_handler_id = -1;
        return 0; /* this is always a one-shot call */
 }
@@ -5020,7 +5008,7 @@ Editor::queue_draw_resize_line (int at)
                        /* redraw where it used to be */
                        
                        
-                       Gdk::Rectangle r (xroot, old_resize_line_y - 1, controls_width + (int) canvas_width, 3);
+                       Gdk::Rectangle r (0, old_resize_line_y - 1, controls_width + (int) canvas_width, 3);
                        win->invalidate_rect (r, true);
                        cerr << "invalidate " << xroot << "," << old_resize_line_y - 1 << ' ' 
                             << controls_width + canvas_width << " x 3\n";
@@ -5028,7 +5016,7 @@ Editor::queue_draw_resize_line (int at)
 
                /* draw where it is */
 
-               Gdk::Rectangle r (xroot, at - 1, controls_width + (int) canvas_width, 3);
+               Gdk::Rectangle r (0, at - 1, controls_width + (int) canvas_width, 3);
                win->invalidate_rect (r, true);
        }
 #endif
@@ -5063,7 +5051,7 @@ Editor::on_expose_event (GdkEventExpose* ev)
                GdkRectangle lr;
                GdkRectangle intersection;
 
-               lr.x = xroot;
+               lr.x = 0;
                lr.y = resize_line_y;
                lr.width = controls_width + (int) canvas_width;
                lr.height = 3;
@@ -5084,15 +5072,17 @@ Editor::on_expose_event (GdkEventExpose* ev)
                                                 Gdk::JOIN_MITER);
                        
                        gdk_draw_line (win, gc->gobj(), 
-                                      xroot,
-                                      yroot + resize_line_y, 
-                                      xroot + (int) canvas_width + controls_width,
-                                      yroot + resize_line_y);
+                                      0,
+                                      resize_line_y, 
+                                      (int) canvas_width + controls_width,
+                                      resize_line_y);
+#if 0
                        cerr << "drew line @ " << xroot << ", " << yroot + resize_line_y 
                             << " to " << xroot + (int) canvas_width + controls_width
                             << ", " << yroot + resize_line_y
                             << endl;
-                       old_resize_line_y = yroot + resize_line_y;
+#endif
+                       old_resize_line_y = resize_line_y;
                        cerr << "NEXT EXPOSE SHOULD BE AT " << old_resize_line_y << endl;
                } else {
                        cerr << "no intersect with "
index e8af889ad12de63e8719a9685846baa4e21471bd..eb03922eaf8da83fbb8621d39fba1fd353a47b4d 100644 (file)
@@ -600,7 +600,6 @@ class Editor : public PublicEditor
        Gdk::Cursor* which_grabber_cursor ();
 
        ArdourCanvas::Canvas* track_canvas;
-       ArdourCanvas::Canvas* time_canvas;
 
        ArdourCanvas::Text* first_action_message;
        ArdourCanvas::Text* verbose_canvas_cursor;
@@ -620,7 +619,7 @@ class Editor : public PublicEditor
        Gtk::EventBox      time_canvas_event_box;
        Gtk::EventBox      track_canvas_event_box;
        Gtk::EventBox      time_button_event_box;
-       Gtk::Frame         time_button_frame;
+       Gtk::EventBox      ruler_label_event_box;
 
        ArdourCanvas::Group      *minsec_group;
        ArdourCanvas::Pixbuf     *logo_item;
@@ -633,6 +632,34 @@ class Editor : public PublicEditor
        ArdourCanvas::Group      *range_marker_group;
        ArdourCanvas::Group      *transport_marker_group;
        ArdourCanvas::Group*      cd_marker_group;
+
+       ArdourCanvas::Group*      timebar_group;
+
+       /* These bars never need to be scrolled */
+       ArdourCanvas::Group*      meter_bar_group;
+       ArdourCanvas::Group*      tempo_bar_group;
+       ArdourCanvas::Group*      marker_bar_group;
+       ArdourCanvas::Group*      range_marker_bar_group;
+       ArdourCanvas::Group*      transport_marker_bar_group;
+       ArdourCanvas::Group*      cd_marker_bar_group;
+
+       /* 
+          The _master_group is the group containing all items
+          that require horizontal scrolling..
+          It is primarily used to separate canvas items 
+          that require horizontal scrolling from those that do not. 
+       */
+       ArdourCanvas::Group* _master_group;
+       /* 
+          The _trackview_group is the group containing all trackviews.
+          It is only scrolled vertically.
+       */
+       ArdourCanvas::Group* _trackview_group;
+       /* 
+          This canvas group is used for region motion.
+          It sits on top of the _trackview_group 
+       */
+       ArdourCanvas::Group* _region_motion_group;
        
        enum RulerType {
                ruler_metric_smpte = 0,
@@ -755,6 +782,7 @@ class Editor : public PublicEditor
 
        static const double timebar_height;
        guint32 visible_timebars;
+       gdouble canvas_timebars_vsize;
        Gtk::Menu          *editor_ruler_menu;
        
        ArdourCanvas::SimpleRect* tempo_bar;
@@ -858,12 +886,12 @@ class Editor : public PublicEditor
        nframes64_t last_canvas_frame;
 
        bool track_canvas_map_handler (GdkEventAny*);
-       bool time_canvas_map_handler (GdkEventAny*);
 
        gint edit_controls_button_release (GdkEventButton*);
        Gtk::Menu *edit_controls_left_menu;
        Gtk::Menu *edit_controls_right_menu;
 
+       Gtk::VBox           ruler_label_vbox;
        Gtk::VBox           track_canvas_vbox;
        Gtk::VBox           time_canvas_vbox;
        Gtk::VBox           edit_controls_vbox;
@@ -874,7 +902,11 @@ class Editor : public PublicEditor
        bool deferred_control_scroll (nframes64_t);
        sigc::connection control_scroll_connection;
 
+       gdouble get_trackview_group_vertical_offset () const { return vertical_adjustment.get_value () - canvas_timebars_vsize;}
+       ArdourCanvas::Group* get_trackview_group () const { return _trackview_group; }
        void tie_vertical_scrolling ();
+       void scroll_canvas_horizontally ();
+       void scroll_canvas_vertically ();
        void canvas_horizontally_scrolled ();
        void canvas_scroll_to (nframes64_t);
 
@@ -1464,15 +1496,12 @@ public:
 
        bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
        bool track_canvas_scroll (GdkEventScroll* event);
-       bool time_canvas_scroll (GdkEventScroll* event);
 
        bool track_canvas_scroll_event (GdkEventScroll* event);
        bool track_canvas_button_press_event (GdkEventButton* event);
        bool track_canvas_button_release_event (GdkEventButton* event);
        bool track_canvas_motion_notify_event (GdkEventMotion* event);
 
-       bool time_canvas_scroll_event (GdkEventScroll* event);
-
        Gtk::Allocation canvas_allocation;
        bool canvas_idle_queued;
        void track_canvas_allocate (Gtk::Allocation alloc);
@@ -1489,9 +1518,6 @@ public:
 
        void handle_new_duration ();
        void initialize_canvas ();
-       int canvas_hroizontally_scrolled_handler_id;
-       void reset_horizontally_scrolling_region (Gtk::Allocation* alloc = 0);
-       void reset_scrolling_region (Gtk::Allocation* alloc = 0);
 
        /* display control */
        
@@ -1505,11 +1531,12 @@ public:
        
        ARDOUR::TempoMap::BBTPointList *current_bbt_points;
        
+       typedef vector<ArdourCanvas::SimpleLine*> TimeLineList;
+       TimeLineList free_measure_lines;
+       TimeLineList used_measure_lines;
+
        ArdourCanvas::Group* time_line_group;
-       ArdourCanvas::Group* marker_time_line_group;
-       
-       TempoLines* tempo_lines;
-       TempoLines* marker_tempo_lines;
+       ArdourCanvas::SimpleLine* get_time_line ();
 
        void hide_measures ();
        void draw_measures ();
@@ -1887,12 +1914,13 @@ public:
        uint32_t autoscroll_cnt;
        nframes64_t autoscroll_x_distance;
        double autoscroll_y_distance;
-     
+
        static gint _autoscroll_canvas (void *);
        bool autoscroll_canvas ();
        void start_canvas_autoscroll (int x, int y);
        void stop_canvas_autoscroll ();
        void maybe_autoscroll (GdkEventMotion*);
+       void maybe_autoscroll_horizontally (GdkEventMotion*);
        bool allow_vertical_scroll;
 
        /* trimming */
index 0be64cc80f20cf308be44fe9766e4a5d0ee1938d..9e0ecca93c6d600b2a19ba853ec953ae12486855 100644 (file)
@@ -100,10 +100,8 @@ Editor::initialize_canvas ()
 {
        if (getenv ("ARDOUR_NON_AA_CANVAS")) {
                track_canvas = new ArdourCanvas::Canvas ();
-               time_canvas = new ArdourCanvas::Canvas ();
        } else {
                track_canvas = new ArdourCanvas::CanvasAA ();
-               time_canvas = new ArdourCanvas::CanvasAA ();
        }
        
        ArdourCanvas::init ();
@@ -112,7 +110,7 @@ Editor::initialize_canvas ()
        /* don't try to center the canvas */
 
        track_canvas->set_center_scroll_region (false);
-       track_canvas->set_dither        (Gdk::RGB_DITHER_NONE);
+       track_canvas->set_dither (Gdk::RGB_DITHER_NONE);
 
        /* need to handle 4 specific types of events as catch-alls */
 
@@ -121,9 +119,6 @@ Editor::initialize_canvas ()
        track_canvas->signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event));
        track_canvas->signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event));
 
-       /* just scroll stuff for the timecanvas */
-       time_canvas->signal_scroll_event().connect (mem_fun (*this, &Editor::time_canvas_scroll_event));
-
        track_canvas->set_name ("EditorMainCanvas");
        track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK);
        track_canvas->signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas));
@@ -166,97 +161,100 @@ Editor::initialize_canvas ()
                // logo_item->property_width_set() = true;
                logo_item->show ();
        }
-       
-       /* a group to hold time (measure) lines */
-       
-       time_line_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0);
-       tempo_lines = new TempoLines(*track_canvas, time_line_group);
-       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);
-       time_canvas->set_flags (CAN_FOCUS);
-       time_canvas->set_center_scroll_region (false);
-       time_canvas->set_dither (Gdk::RGB_DITHER_NONE);
-       
-       marker_time_line_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
-       marker_tempo_lines = new TempoLines(*time_canvas, marker_time_line_group);
-       meter_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0);
-       tempo_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height);
-       range_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 2.0);
-       transport_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 3.0);
-       marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 4.0);
-       cd_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 5.0);
-       
-       tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+       _master_group = new ArdourCanvas::Group (*track_canvas->root());
 
-       tempo_bar->property_outline_what() = (0x1 | 0x8);
-       tempo_bar->property_outline_pixels() = 1;
+       _trackview_group = new ArdourCanvas::Group (*_master_group);
+       _region_motion_group = new ArdourCanvas::Group (*_master_group);
 
-       meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+       meter_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       meter_bar = new ArdourCanvas::SimpleRect (*meter_bar_group, 0.0, 0.0, 100, timebar_height);
 
        meter_bar->property_outline_what() = (0x1 | 0x8);
        meter_bar->property_outline_pixels() = 1;
-       
-       marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
-
-       marker_bar->property_outline_what() = (0x1 | 0x8);
-       marker_bar->property_outline_pixels() = 1;
 
-       cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+       tempo_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       tempo_bar = new ArdourCanvas::SimpleRect (*tempo_bar_group, 0.0, 0.0, 100, (timebar_height));
+       tempo_bar->property_outline_what() = (0x1 | 0x8);
+       tempo_bar->property_outline_pixels() = 0;
 
-       cd_marker_bar->property_outline_what() = (0x1 | 0x8);
-       cd_marker_bar->property_outline_pixels() = 1;
-       
-       range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+       range_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       range_marker_bar = new ArdourCanvas::SimpleRect (*range_marker_bar_group, 0.0, 0.0, 100, (timebar_height));
 
        range_marker_bar->property_outline_what() = (0x1 | 0x8);
        range_marker_bar->property_outline_pixels() = 1;
        
-       transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
+       transport_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_bar_group, 0.0, 0.0, 100, (timebar_height));
        transport_marker_bar->property_outline_what() = (0x1 | 0x8);
        transport_marker_bar->property_outline_pixels() = 1;
+
+       marker_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       marker_bar = new ArdourCanvas::SimpleRect (*marker_bar_group, 0.0, 0.0, 100, (timebar_height));
+       marker_bar->property_outline_what() = (0x1 | 0x8);
+       marker_bar->property_outline_pixels() = 0;
        
-       cd_marker_bar_drag_rect = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
-       cd_marker_bar_drag_rect->property_outline_pixels() = 0;
-       cd_marker_bar_drag_rect->hide ();
+       cd_marker_bar_group = new ArdourCanvas::Group (*track_canvas->root());
+       cd_marker_bar = new ArdourCanvas::SimpleRect (*cd_marker_bar_group, 0.0, 0.0, 100, (timebar_height));
+       cd_marker_bar->property_outline_what() = (0x1 | 0x8);
+       cd_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-1.0);
-       range_bar_drag_rect->property_outline_pixels() = 0;
 
-       transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
-       transport_bar_drag_rect->property_outline_pixels() = 0;
-       transport_bar_drag_rect->hide ();
+       /* a group to hold time (measure) lines */
        
+       time_line_group = new ArdourCanvas::Group (*_master_group, 0.0, 0.0);
+
+       range_marker_drag_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0);
+       //range_marker_drag_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0);
+       range_marker_drag_rect->hide ();
+
+       timebar_group =  new ArdourCanvas::Group (*track_canvas->root());
+       cursor_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0);
+
+       meter_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 5.0);
+       tempo_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 4.0);
+       range_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 3.0);
+       transport_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height * 2.0);
+       marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, timebar_height);
+       cd_marker_group = new ArdourCanvas::Group (*timebar_group, 0.0, 0.0);
+
        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_points.push_back(Gnome::Art::Point(0.0, 1.0));
 
-       marker_drag_line = new ArdourCanvas::Line (*track_canvas->root());
+       marker_drag_line = new ArdourCanvas::Line (*timebar_group);
        marker_drag_line->property_width_pixels() = 1;
        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->hide ();
-       
-       transport_loop_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0);
+       cd_marker_bar_drag_rect = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, 100, timebar_height);
+       cd_marker_bar_drag_rect->property_outline_pixels() = 0;
+       cd_marker_bar_drag_rect->hide ();
+
+       range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, 100, timebar_height);
+       range_bar_drag_rect->property_outline_pixels() = 0;
+
+       transport_bar_drag_rect = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, 100, timebar_height);
+       transport_bar_drag_rect->property_outline_pixels() = 0;
+       transport_bar_drag_rect->hide ();
+
+       transport_loop_range_rect = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0);
        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 = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0);
        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 = new ArdourCanvas::SimpleLine (*_master_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->hide ();
        
-       transport_punchout_line  = new ArdourCanvas::SimpleLine (*time_line_group);
+       transport_punchout_line  = new ArdourCanvas::SimpleLine (*_master_group);
        transport_punchout_line->property_x1() = 0.0;
        transport_punchout_line->property_y1() = 0.0;
        transport_punchout_line->property_x2() = 0.0;
@@ -264,14 +262,15 @@ Editor::initialize_canvas ()
        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 = new ArdourCanvas::SimpleRect (*_master_group, 0.0, 0.0, 0.0, 0.0);
        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 = new ArdourCanvas::SimpleRect (*_trackview_group, 0.0, 0.0, 0.0, 0.0);
+
        rubberband_rect->property_outline_pixels() = 1;
        rubberband_rect->hide();
        
@@ -284,10 +283,6 @@ Editor::initialize_canvas ()
        
        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);
 
        playhead_cursor = new Cursor (*this, &Editor::canvas_playhead_cursor_event);
 
@@ -343,72 +338,47 @@ Editor::track_canvas_size_allocated ()
                        }
                }
                
-               full_canvas_height = height;
+               full_canvas_height = height + canvas_timebars_vsize;
        }
 
        zoom_range_clock.set ((nframes64_t) floor ((canvas_width * frames_per_unit)));
        playhead_cursor->set_position (playhead_cursor->current_frame);
 
+       horizontal_adjustment.set_upper (session->current_end_frame()/frames_per_unit);
+       horizontal_adjustment.set_page_size (current_page_frames()/frames_per_unit);
+
        reset_hscrollbar_stepping ();
-       reset_scrolling_region ();
 
-       if (playhead_cursor) playhead_cursor->set_length (canvas_height);
+       if (playhead_cursor) {
+               playhead_cursor->set_length (canvas_height);
+       }
 
-       double y1 = vertical_adjustment.get_value ();
+       vertical_adjustment.set_page_size (canvas_height);
        
        for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {
-               (*x)->set_line_vpos (y1, canvas_height);
-       }
-
-       range_marker_drag_rect->property_y1() = y1;
-       range_marker_drag_rect->property_y2() = full_canvas_height;
-       transport_loop_range_rect->property_y1() = y1;
-       transport_loop_range_rect->property_y2() = full_canvas_height;
-       transport_punch_range_rect->property_y1() = y1;
-       transport_punch_range_rect->property_y2() = full_canvas_height;
-       transport_punchin_line->property_y1() = y1;
-       transport_punchin_line->property_y2() = full_canvas_height;
-       transport_punchout_line->property_y1() = y1;
-       transport_punchout_line->property_y2() = full_canvas_height;
-       
-       update_fixed_rulers();
-       redisplay_tempo (true);
-
-       Resized (); /* EMIT_SIGNAL */
-
-       return false;
-}
-
-void
-Editor::reset_scrolling_region (Gtk::Allocation* alloc)
-{
-       TreeModel::Children rows = route_display_model->children();
-       TreeModel::Children::iterator i;
-       double pos;
-
-        for (pos = 0, i = rows.begin(); i != rows.end(); ++i) {
-               TimeAxisView *tv = (*i)[route_display_columns.tv];
-               if (tv != 0 && !tv->hidden()) {
-                       pos += tv->effective_height;
-               }
+               (*x)->set_line_vpos (0, canvas_height);
        }
 
-       double last_canvas_unit =  max ((last_canvas_frame / frames_per_unit), canvas_width);
-       //cerr << "Editor::reset_scrolling_region () lcf:fpu:cw:lcu " << last_canvas_frame << ":" << frames_per_unit << ":" << canvas_width << ":" << last_canvas_unit << endl;//DEBUG
-       track_canvas->set_scroll_region (0.0, 0.0, last_canvas_unit, pos);
-
-       // XXX what is the correct height value for the time canvas ? this overstates it
-       time_canvas->set_scroll_region ( 0.0, 0.0, last_canvas_unit, canvas_height);
-
+       marker_drag_line_points.back().set_y(canvas_height);
        range_marker_drag_rect->property_y2() = canvas_height;
        transport_loop_range_rect->property_y2() = canvas_height;
        transport_punch_range_rect->property_y2() = canvas_height;
        transport_punchin_line->property_y2() = canvas_height;
        transport_punchout_line->property_y2() = canvas_height;
 
-       update_punch_range_view (true);
+       tempo_bar->property_x2() = canvas_width;
+       meter_bar->property_x2() = canvas_width;
+       marker_bar->property_x2() = canvas_width;
+       cd_marker_bar->property_x2() = canvas_width;
+       range_marker_bar->property_x2() = canvas_width;
+       transport_marker_bar->property_x2() = canvas_width;
+
+       update_fixed_rulers();
+       redisplay_tempo (true);
+
+       Resized (); /* EMIT_SIGNAL */
 
-       controls_layout.queue_resize();
+       return false;
 }
 
 void
@@ -446,7 +416,18 @@ Editor::controls_layout_size_request (Requisition* req)
        controls_layout.set_size (edit_controls_vbox.get_width(), (gint) pos);
        controls_layout.set_size_request(edit_controls_vbox.get_width(), -1);
        zoom_box.set_size_request(edit_controls_vbox.get_width(), -1);
-       time_button_frame.set_size_request(edit_controls_vbox.get_width(), -1);
+       time_button_event_box.set_size_request(edit_controls_vbox.get_width(), -1);
+
+       if ((vertical_adjustment.get_value() + canvas_height) >= vertical_adjustment.get_upper()) {
+               /* 
+                  We're increasing the size of the canvas while the bottom is visible.
+                  We scroll down to keep in step with the controls layout.
+               */
+               vertical_adjustment.set_upper (pos + canvas_timebars_vsize);
+               vertical_adjustment.set_value (pos + canvas_timebars_vsize - canvas_height);
+       } else {
+               vertical_adjustment.set_upper (pos + canvas_timebars_vsize);
+       }
 
        //cerr << "sizes = " << req->width << " " << edit_controls_vbox.get_width() << " " << controls_layout.get_width() << " " << zoom_box.get_width() << " " << time_button_frame.get_width() << endl;//DEBUG        
 }
@@ -458,13 +439,6 @@ Editor::track_canvas_map_handler (GdkEventAny* ev)
        return false;
 }
 
-bool
-Editor::time_canvas_map_handler (GdkEventAny* ev)
-{
-       time_canvas->get_window()->set_cursor (*timebar_cursor);
-       return false;
-}
-
 void  
 Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context,
                                         int x, int y, 
@@ -509,8 +483,8 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
        double wy;
 
        track_canvas->window_to_world (x, y, wx, wy);
-       wx += horizontal_adjustment.get_value();
-       wy += vertical_adjustment.get_value();
+       //wx += horizontal_adjustment.get_value();
+       //wy += vertical_adjustment.get_value();
        
        ev.type = GDK_BUTTON_RELEASE;
        ev.button.x = wx;
@@ -596,16 +570,25 @@ Editor::maybe_autoscroll (GdkEventMotion* event)
        nframes64_t frame = drag_info.current_pointer_frame;
        bool startit = false;
        double vertical_pos = vertical_adjustment.get_value();
+       double upper = vertical_adjustment.get_upper();
+
+       /* 
+          adjust the event.y to take account of the bounds 
+          of the _trackview_group 
+       */
+
+       double vsx1, vsx2, vsy1, vsy2;
+       _trackview_group->get_bounds (vsx1, vsy1, vsx2, vsy2);
 
        autoscroll_y = 0;
        autoscroll_x = 0;
 
-       if (event->y < vertical_pos) {
+       if ((event->y - vsy1) < vertical_pos) {
                autoscroll_y = -1;
                startit = true;
        }
 
-       if (event->y > vertical_pos + canvas_height) {
+       if ((event->y - vsy1) > (vertical_pos + canvas_height - canvas_timebars_vsize) && vertical_pos <= upper) {
                autoscroll_y = 1;
                startit = true;
        }
@@ -618,7 +601,6 @@ Editor::maybe_autoscroll (GdkEventMotion* event)
                }
 
        } else if (frame < leftmost_frame) {
-               
                if (leftmost_frame > 0) {
                        autoscroll_x = -1;
                        startit = true;
@@ -642,6 +624,43 @@ Editor::maybe_autoscroll (GdkEventMotion* event)
        last_autoscroll_y = autoscroll_y;
 }
 
+void
+Editor::maybe_autoscroll_horizontally (GdkEventMotion* event)
+{
+       nframes64_t rightmost_frame = leftmost_frame + current_page_frames();
+       nframes64_t frame = drag_info.current_pointer_frame;
+       bool startit = false;
+
+       autoscroll_y = 0;
+       autoscroll_x = 0;
+
+       if (frame > rightmost_frame) {
+
+               if (rightmost_frame < max_frames) {
+                       autoscroll_x = 1;
+                       startit = true;
+               }
+
+       } else if (frame < leftmost_frame) {
+               if (leftmost_frame > 0) {
+                       autoscroll_x = -1;
+                       startit = true;
+               }
+
+       }
+
+       if ((autoscroll_x != last_autoscroll_x) || (autoscroll_y != last_autoscroll_y) || (autoscroll_x == 0 && autoscroll_y == 0)) {
+               stop_canvas_autoscroll ();
+       }
+       
+       if (startit && autoscroll_timeout_tag < 0) {
+               start_canvas_autoscroll (autoscroll_x, autoscroll_y);
+       }
+
+       last_autoscroll_x = autoscroll_x;
+       last_autoscroll_y = autoscroll_y;
+}
+
 gint
 Editor::_autoscroll_canvas (void *arg)
 {
@@ -654,26 +673,63 @@ Editor::autoscroll_canvas ()
        nframes64_t new_frame;
        nframes64_t limit = max_frames - current_page_frames();
        GdkEventMotion ev;
-       nframes64_t target_frame;
        double new_pixel;
        double target_pixel;
 
+       if (autoscroll_x_distance != 0) {
+
+               if (autoscroll_cnt == 50) { /* 0.5 seconds */
+                       
+                       /* after about a while, speed up a bit by changing the timeout interval */
+                       
+                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f);
+                       
+               } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
+                       
+                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f);
+                       
+               } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
+                       
+                       /* after about another while, speed up by increasing the shift per callback */
+                       
+                       autoscroll_x_distance =  (nframes64_t) floor (current_page_frames()/10.0f);
+                       
+               } 
+       }
+
+       if (autoscroll_y_distance != 0) {
+
+               if (autoscroll_cnt == 50) { /* 0.5 seconds */
+                       
+                       /* after about a while, speed up a bit by changing the timeout interval */
+                       
+                       autoscroll_y_distance = 10;
+                       
+               } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
+                       
+                       autoscroll_y_distance = 20;
+                       
+               } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
+                       
+                       /* after about another while, speed up by increasing the shift per callback */
+                       
+                       autoscroll_y_distance =  40;
+               } 
+       }
+
        if (autoscroll_x < 0) {
                if (leftmost_frame < autoscroll_x_distance) {
                        new_frame = 0;
                } else {
                        new_frame = leftmost_frame - autoscroll_x_distance;
                }
-               target_frame = drag_info.current_pointer_frame - autoscroll_x_distance;
        } else if (autoscroll_x > 0) {
                if (leftmost_frame > limit - autoscroll_x_distance) {
                        new_frame = limit;
                } else {
                        new_frame = leftmost_frame + autoscroll_x_distance;
                }
-               target_frame = drag_info.current_pointer_frame + autoscroll_x_distance;
        } else {
-               target_frame = drag_info.current_pointer_frame;
                new_frame = leftmost_frame;
        }
 
@@ -711,23 +767,36 @@ Editor::autoscroll_canvas ()
                target_pixel = min (target_pixel, full_canvas_height - 10);
                
        } else {
-               target_pixel = drag_info.current_pointer_y;
+               target_pixel = drag_info.current_pointer_y;
                new_pixel = vertical_pos;
        }
 
-       /* now fake a motion event to get the object that is being dragged to move too */
 
-       ev.type = GDK_MOTION_NOTIFY;
-       ev.state &= Gdk::BUTTON1_MASK;
-       ev.x = frame_to_unit (target_frame);
-       ev.y = target_pixel;
-       motion_handler (drag_info.item, (GdkEvent*) &ev, drag_info.item_type, true);
 
        if ((new_frame == 0 || new_frame == limit) && (new_pixel == 0 || new_pixel == DBL_MAX)) {
                /* we are done */
                return false;
        }
 
+       if (new_frame != leftmost_frame) {
+               reset_x_origin (new_frame);
+       }
+
+       vertical_adjustment.set_value (new_pixel);
+
+       /* fake an event. */
+
+       Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window();
+       gint x, y;
+       Gdk::ModifierType mask;
+       canvas_window->get_pointer (x, y, mask);
+       ev.type = GDK_MOTION_NOTIFY;
+       ev.state &= Gdk::BUTTON1_MASK;
+       ev.x = x;
+       ev.y = y;
+
+       motion_handler (drag_info.item, (GdkEvent*) &ev, drag_info.item_type, true);
+
        autoscroll_cnt++;
 
        if (autoscroll_cnt == 1) {
@@ -739,53 +808,6 @@ Editor::autoscroll_canvas ()
 
        } 
 
-       if (new_frame != leftmost_frame) {
-               reset_x_origin (new_frame);
-       }
-
-       vertical_adjustment.set_value (new_pixel);
-
-       if (autoscroll_x_distance != 0) {
-
-               if (autoscroll_cnt == 50) { /* 0.5 seconds */
-                       
-                       /* after about a while, speed up a bit by changing the timeout interval */
-                       
-                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/30.0f);
-                       
-               } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
-                       
-                       autoscroll_x_distance = (nframes64_t) floor (current_page_frames()/20.0f);
-                       
-               } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
-                       
-                       /* after about another while, speed up by increasing the shift per callback */
-                       
-                       autoscroll_x_distance =  (nframes64_t) floor (current_page_frames()/10.0f);
-                       
-               } 
-       }
-
-       if (autoscroll_y_distance != 0) {
-
-               if (autoscroll_cnt == 50) { /* 0.5 seconds */
-                       
-                       /* after about a while, speed up a bit by changing the timeout interval */
-                       
-                       autoscroll_y_distance = 10;
-                       
-               } else if (autoscroll_cnt == 150) { /* 1.0 seconds */
-                       
-                       autoscroll_y_distance = 20;
-                       
-               } else if (autoscroll_cnt == 300) { /* 1.5 seconds */
-                       
-                       /* after about another while, speed up by increasing the shift per callback */
-                       
-                       autoscroll_y_distance =  40;
-               } 
-       }
-
        return true;
 }
 
@@ -813,6 +835,7 @@ Editor::start_canvas_autoscroll (int dx, int dy)
 void
 Editor::stop_canvas_autoscroll ()
 {
+
        if (autoscroll_timeout_tag >= 0) {
                g_source_remove (autoscroll_timeout_tag);
                autoscroll_timeout_tag = -1;
@@ -840,34 +863,49 @@ Editor::entered_track_canvas (GdkEventCrossing *ev)
 void
 Editor::tie_vertical_scrolling ()
 {
-       double y1 = vertical_adjustment.get_value();
-
-       playhead_cursor->set_y_axis (y1);
-
-       range_marker_drag_rect->property_y1() = y1;
-       range_marker_drag_rect->property_y2() = full_canvas_height;
-       transport_loop_range_rect->property_y1() = y1;
-       transport_loop_range_rect->property_y2() = full_canvas_height;
-       transport_punch_range_rect->property_y1() = y1;
-       transport_punch_range_rect->property_y2() = full_canvas_height;
-       transport_punchin_line->property_y1() = y1;
-       transport_punchin_line->property_y2() = full_canvas_height;
-       transport_punchout_line->property_y1() = y1;
-       transport_punchout_line->property_y2() = full_canvas_height;
-
-       if (!selection->markers.empty()) {
-               for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {            
-                       (*x)->set_line_vpos (y1, canvas_height);
-               }
-       }
+       scroll_canvas_vertically ();
 
-       if (logo_item) {
-               logo_item->property_y() = y1;
+       /* this will do an immediate redraw */
+
+       controls_layout.get_vadjustment()->set_value (vertical_adjustment.get_value());
+}
+
+void
+Editor::scroll_canvas_horizontally ()
+{
+       nframes64_t time_origin = (nframes64_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
+
+       if (time_origin != leftmost_frame) {
+               canvas_scroll_to (time_origin);
        }
 
-       /* this will do an immediate redraw */
+       /* horizontal scrolling only */
+       double x1, x2, y1, y2, x_delta;
 
-       controls_layout.get_vadjustment()->set_value (y1);
+       _master_group->get_bounds(x1, y1, x2, y2);
+       x_delta = x1 + horizontal_adjustment.get_value();
+
+       _master_group->move (-x_delta, 0);
+       timebar_group->move (-x_delta, 0);
+       cursor_group->move (-x_delta, 0);
+}
+
+void
+Editor::scroll_canvas_vertically ()
+{
+       /* vertical scrolling only */
+       double x1, x2, y1, y2, y_delta;
+
+       _trackview_group->get_bounds(x1, y1, x2, y2);
+       y_delta = y1 + vertical_adjustment.get_value() - canvas_timebars_vsize;
+
+       _trackview_group->move (0, -y_delta);
+       _region_motion_group->move (0, -y_delta);
+
+#ifndef GTKOSX
+       /* required to keep the controls_layout in lock step with the canvas group */
+       track_canvas->update_now ();
+#endif
 }
 
 void 
@@ -884,18 +922,13 @@ void
 Editor::canvas_scroll_to (nframes64_t time_origin)
 {
        leftmost_frame = time_origin;
-
        nframes64_t rightmost_frame = leftmost_frame + current_page_frames ();
 
        if (rightmost_frame > last_canvas_frame) {
                last_canvas_frame = rightmost_frame;
-               reset_scrolling_region ();
+               //reset_scrolling_region ();
        }
        
-       if (logo_item) {
-               logo_item->property_x() = horizontal_adjustment.get_value ();
-       }
-
        update_fixed_rulers ();
 
        redisplay_tempo (!_dragging_hscrollbar);
index dd107d8d0280a2c571a51bb06e5fb865c9af96e9..e55ab9bed0848d19cbf33d416b4146ef63403ae4 100644 (file)
@@ -72,9 +72,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                        */
                        track_canvas->get_pointer (x, y);
                        track_canvas->window_to_world (x, y, wx, wy);
-                       wx += horizontal_adjustment.get_value();
-                       wy += vertical_adjustment.get_value();
-                       
+
                        GdkEvent event;
                        event.type = GDK_BUTTON_RELEASE;
                        event.button.x = wx;
@@ -89,7 +87,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
                        if (!current_stepping_trackview) {
                                step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
-                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
+                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize))) {
                                        return false;
                                }
                        }
@@ -110,9 +108,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                        //if (ev->state == GDK_CONTROL_MASK) {
                        track_canvas->get_pointer (x, y);
                        track_canvas->window_to_world (x, y, wx, wy);
-                       wx += horizontal_adjustment.get_value();
-                       wy += vertical_adjustment.get_value();
-                       
+
                        GdkEvent event;
                        event.type = GDK_BUTTON_RELEASE;
                        event.button.x = wx;
@@ -127,7 +123,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev)
                } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
                        if (!current_stepping_trackview) {
                                step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
-                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
+                               if (!(current_stepping_trackview = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize))) {
                                        return false;
                                }
                        }
@@ -177,55 +173,6 @@ Editor::track_canvas_scroll_event (GdkEventScroll *event)
        return false;
 }
 
-bool
-Editor::time_canvas_scroll (GdkEventScroll* ev)
-{
-       nframes64_t xdelta;
-       int direction = ev->direction;
-
-       switch (direction) {
-       case GDK_SCROLL_UP:
-               temporal_zoom_step (true);
-               break;
-
-       case GDK_SCROLL_DOWN:
-               temporal_zoom_step (false);
-               break;  
-
-       case GDK_SCROLL_LEFT:
-               xdelta = (current_page_frames() / 2);
-               if (leftmost_frame > xdelta) {
-                       reset_x_origin (leftmost_frame - xdelta);
-               } else {
-                       reset_x_origin (0);
-               }
-               break;
-
-       case GDK_SCROLL_RIGHT:
-               xdelta = (current_page_frames() / 2);
-               if (max_frames - xdelta > leftmost_frame) {
-                       reset_x_origin (leftmost_frame + xdelta);
-               } else {
-                       reset_x_origin (max_frames - current_page_frames());
-               }
-               break;
-
-       default:
-               /* what? */
-               break;
-       }
-
-       return false;
-}
-
-bool
-Editor::time_canvas_scroll_event (GdkEventScroll *event)
-{
-       time_canvas->grab_focus();
-       time_canvas_scroll (event);
-       return false;
-}
-
 bool
 Editor::track_canvas_button_press_event (GdkEventButton *event)
 {
@@ -260,10 +207,6 @@ Editor::track_canvas_motion (GdkEvent *ev)
                verbose_canvas_cursor->property_y() = clamp_verbose_cursor_y (ev->motion.y + 20);
        }
 
-#ifdef GTKOSX
-       flush_canvas ();
-#endif
-
        return false;
 }
 
index 54786bcebf8c480327421f016b2a4a4d6b8afca9..ca00ec61d2eabe7b823a409d30d339704c54fa13 100644 (file)
@@ -38,8 +38,8 @@ Editor::Cursor::Cursor (Editor& ed, bool (Editor::*callbck)(GdkEvent*,ArdourCanv
        
        /* "randomly" initialize coords */
        
-       points.push_back(Gnome::Art::Point(-9383839.0, 0.0));
        points.push_back(Gnome::Art::Point(1.0, 0.0));
+       points.push_back(Gnome::Art::Point(1.0, 1.0));
 
        canvas_item.property_points() = points;
        canvas_item.property_width_pixels() = 1;
@@ -51,7 +51,6 @@ Editor::Cursor::Cursor (Editor& ed, bool (Editor::*callbck)(GdkEvent*,ArdourCanv
 
        canvas_item.set_data ("cursor", this);
        canvas_item.signal_event().connect (bind (mem_fun (ed, callbck), &canvas_item));
-
        current_frame = 1; /* force redraw at 0 */
 }
 
@@ -67,23 +66,15 @@ Editor::Cursor::set_position (nframes64_t frame)
 
        if (editor.session == 0) {
                canvas_item.hide();
-       } else {
-               canvas_item.show();
        }
-
        current_frame = frame;
-
        if (new_pos != points.front().get_x()) {
 
                points.front().set_x (new_pos);
                points.back().set_x (new_pos);
 
                canvas_item.property_points() = points;
-
-               ArdourCanvas::Points p = canvas_item.property_points();
        }
-
-       canvas_item.raise_to_top();
 }
 
 void
@@ -92,6 +83,9 @@ Editor::Cursor::set_length (double units)
        length = units; 
        points.back().set_y (points.front().get_y() + length);
        canvas_item.property_points() = points;
+       if (editor.session != 0) {
+               canvas_item.show();
+       }
 }
 
 void 
index 059855ccf5050cb58713e58a3d83b18b975ee142..8d86a0fbb2d3d5e09b9a843bff90137ad1218e5a 100644 (file)
@@ -1243,7 +1243,7 @@ Editor::marker_selection_changed ()
        }
 
        for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {
-               (*x)->add_line (cursor_group, vertical_adjustment.get_value(), canvas_height);
+               (*x)->add_line (cursor_group, 0, canvas_height);
                (*x)->show_line ();
        }
 
index 5c9208fcfbd0f45a5d11265654f76be4eba33ade..e770e099609afeb60522c7ed2c0f74267a2a5083 100644 (file)
@@ -203,7 +203,7 @@ Editor::update_current_screen ()
 
                if (_follow_playhead && session->requested_return_frame() < 0) {
 
-                       playhead_cursor->canvas_item.show();
+                       //playhead_cursor->canvas_item.show();
 
                        if (frame != last_update_frame) {
 
@@ -259,7 +259,10 @@ Editor::update_current_screen ()
 
          almost_done:
                last_update_frame = frame;
-
+#ifdef GTKOSX
+               /*XXX in a perfect world we would not have to do this. */
+               track_canvas->update_now();
+#endif
                if (current_mixer_strip) {
                        current_mixer_strip->fast_update ();
                }
index 384f40fdf6bbc8313b202a445ffb450661371230..7a05fcdc56a0e1925fdec16f33f6c4b6ffa36be6 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
     Copyright (C) 2000-2001 Paul Davis 
 
@@ -92,23 +93,15 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const
        pointer_window = canvas_window->get_pointer (x, y, mask);
 
        if (pointer_window == track_canvas->get_bin_window()) {
-
-               track_canvas->window_to_world (x, y, wx, wy);
+               wx = x;
+               wy = y;
                in_track_canvas = true;
 
        } else {
                in_track_canvas = false;
-
-               if (pointer_window == time_canvas->get_bin_window()) {
-                       time_canvas->window_to_world (x, y, wx, wy);
-               } else {
                        return false;
-               }
        }
 
-       wx += horizontal_adjustment.get_value();
-       wy += vertical_adjustment.get_value();
-
        GdkEvent event;
        event.type = GDK_BUTTON_RELEASE;
        event.button.x = wx;
@@ -138,10 +131,16 @@ Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const
        case GDK_BUTTON_PRESS:
        case GDK_2BUTTON_PRESS:
        case GDK_3BUTTON_PRESS:
-               track_canvas->w2c(event->button.x, event->button.y, *pcx, *pcy);
+
+               *pcx = event->button.x;
+               *pcy = event->button.y;
+               _trackview_group->w2i(*pcx, *pcy);
                break;
        case GDK_MOTION_NOTIFY:
-               track_canvas->w2c(event->motion.x, event->motion.y, *pcx, *pcy);
+       
+               *pcx = event->motion.x;
+               *pcy = event->motion.y;
+               _trackview_group->w2i(*pcx, *pcy);
                break;
        case GDK_ENTER_NOTIFY:
        case GDK_LEAVE_NOTIFY:
@@ -227,9 +226,9 @@ Editor::which_grabber_cursor ()
                return grabber_edit_point_cursor;
                break;
        default:
-               return grabber_cursor;
                break;
        }
+       return grabber_cursor;
 }
 
 void
@@ -609,7 +608,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                pointer_window = canvas_window->get_pointer (x, y, mask);
                
                if (pointer_window == track_canvas->get_bin_window()) {
-                       
                        track_canvas->window_to_world (x, y, wx, wy);
                        allow_vertical_scroll = true;
                } else {
@@ -770,8 +768,8 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                                        
                                case RegionViewName:
                                        /* rename happens on edit clicks */
-                                               start_trim (clicked_regionview->get_name_highlight(), event);
-                                               return true;
+                                       start_trim (clicked_regionview->get_name_highlight(), event);
+                                       return true;
                                        break;
 
                                case ControlPointItem:
@@ -1442,7 +1440,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case MeterBarItem:
        case TempoBarItem:
                if (is_drawable()) {
-                       time_canvas->get_window()->set_cursor (*timebar_cursor);
+                       track_canvas->get_window()->set_cursor (*timebar_cursor);
                }
                break;
 
@@ -1456,7 +1454,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case MeterMarkerItem:
        case TempoMarkerItem:
                if (is_drawable()) {
-                       time_canvas->get_window()->set_cursor (*timebar_cursor);
+                       track_canvas->get_window()->set_cursor (*timebar_cursor);
                }
                break;
        case FadeInHandleItem:
@@ -1569,7 +1567,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case TempoBarItem:
        case MarkerBarItem:
                if (is_drawable()) {
-                       time_canvas->get_window()->set_cursor (*timebar_cursor);
+                       track_canvas->get_window()->set_cursor (*timebar_cursor);
                }
                break;
                
@@ -1586,7 +1584,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case TempoMarkerItem:
                
                if (is_drawable()) {
-                       time_canvas->get_window()->set_cursor (*timebar_cursor);
+                       track_canvas->get_window()->set_cursor (*timebar_cursor);
                }
 
                break;
@@ -1721,7 +1719,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
                   where DISPLAY = :0.0, and given the cost of what the motion
                   event might do, its a good tradeoff.  
                */
-               
+
                track_canvas->get_pointer (x, y);
        } 
 
@@ -1781,6 +1779,9 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
        case PlayheadCursorItem:
        case MarkerItem:
        case ControlPointItem:
+       case RangeMarkerBarItem:
+       case TransportMarkerBarItem:
+       case CdMarkerBarItem:
        case TempoMarkerItem:
        case MeterMarkerItem:
        case RegionViewNameHighlight:
@@ -1802,13 +1803,13 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
          if (drag_info.item && (event->motion.state & Gdk::BUTTON1_MASK ||
                                 (event->motion.state & Gdk::BUTTON2_MASK))) {
                  if (!from_autoscroll) {
-                         maybe_autoscroll (&event->motion);
+                         maybe_autoscroll_horizontally (&event->motion);
                  }
                  (this->*(drag_info.motion_callback)) (item, event);
                  goto handled;
          }
          goto not_handled;
-         
+         break;
        default:
                break;
        }
@@ -2352,7 +2353,7 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
                // marker_drag_line->raise_to_top();
        } else {
                range_marker_drag_rect->show();
-               range_marker_drag_rect->raise_to_top();
+               //range_marker_drag_rect->raise_to_top();
        }
 
        if (is_start) {
@@ -3087,6 +3088,18 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
        show_verbose_time_cursor (drag_info.last_frame_position, 10);
 
        begin_reversible_command (_("move region(s)"));
+       /* 
+          the group containing moved regions may have been 
+          offset during autoscroll. reset its y offset
+          (we should really handle this in the same way 
+          we do with the x axis, but a simple way of achieving that 
+          eludes me right now). 
+       */
+
+       _region_motion_group->property_y() = 0;
+
+       /* sync the canvas to what we think is its current state */
+       track_canvas->update_now();
 }
 
 void
@@ -3133,6 +3146,8 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
        drag_info.motion_callback = &Editor::region_drag_motion_callback;
        drag_info.finished_callback = &Editor::region_drag_finished_callback;
        show_verbose_time_cursor (drag_info.last_frame_position, 10);
+
+       _region_motion_group->property_y() = 0;
 }
 
 void
@@ -3181,7 +3196,6 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event)
                vector<RegionView*> new_regionviews;
                
                for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
-
                        RegionView* rv;
                        RegionView* nrv;
 
@@ -3197,7 +3211,7 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event)
                        } else {
                                continue;
                        }
-                       
+
                        const boost::shared_ptr<const Region> original = arv->region();
                        boost::shared_ptr<Region> region_copy = RegionFactory::create (original);
                        boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (region_copy);
@@ -3225,6 +3239,14 @@ Editor::possibly_copy_regions_during_grab (GdkEvent* event)
                drag_info.data = new_regionviews.front();
 
                swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time);
+               /* 
+                  sync the canvas to what we think is its current state 
+                  without it, the canvas seems to 
+                  "forget" to update properly after the upcoming reparent() 
+                  ..only if the mouse is in rapid motion at the time of the grab. 
+                  something to do with regionview creation raking so long?
+                */
+               track_canvas->update_now();
        }
 }
 
@@ -3344,7 +3366,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        }
 
        original_pointer_order = drag_info.dest_trackview->order;
-               
+       
        /************************************************************
             Y-Delta Computation
        ************************************************************/   
@@ -3427,6 +3449,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
                        rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
                        rv2->get_canvas_group()->i2w (ix1, iy1);
+                       iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize;
+
                        TimeAxisView* tvp2 = trackview_by_y_position (iy1);
                        RouteTimeAxisView* rtv2 = dynamic_cast<RouteTimeAxisView*>(tvp2);
 
@@ -3512,10 +3536,9 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        /* compute the amount of pointer motion in frames, and where
           the region would be if we moved it by that much.
        */
-
        if ( drag_info.move_threshold_passed ) {
 
-               if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+               if (drag_info.current_pointer_frame >= drag_info.pointer_frame_offset) {
 
                        nframes64_t sync_frame;
                        nframes64_t sync_offset;
@@ -3550,7 +3573,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                if (pending_region_position > max_frames - rv->region()->length()) {
                        pending_region_position = drag_info.last_frame_position;
                }
-         
+
                // printf ("3: pending_region_position= %lu    %lu\n", pending_region_position, drag_info.last_frame_position );
 
                bool x_move_allowed;
@@ -3566,7 +3589,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                        x_move_allowed = !drag_info.x_constrained;
                }
 
-               if ( pending_region_position != drag_info.last_frame_position && x_move_allowed ) {
+               if (( pending_region_position != drag_info.last_frame_position) && x_move_allowed ) {
 
                        /* now compute the canvas unit distance we need to move the regionview
                           to make it appear at the new location.
@@ -3576,10 +3599,29 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                x_delta = ((double) (pending_region_position - drag_info.last_frame_position) / frames_per_unit);
                        } else {
                                x_delta = -((double) (drag_info.last_frame_position - pending_region_position) / frames_per_unit);
-                       }
+                               for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+
+                                       RegionView* rv2 = (*i);
+
+                                       // If any regionview is at zero, we need to know so we can stop further leftward motion.
+       
+                                       double ix1, ix2, iy1, iy2;
+                                       rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
+                                       rv2->get_canvas_group()->i2w (ix1, iy1);
+                       
+                                       if (-x_delta > ix1 + horizontal_adjustment.get_value()) {
+                                               //      do_move = false;
+                                               cerr << "illegal move" << endl;
+                                               x_delta = 0;
+                                               pending_region_position = drag_info.last_frame_position;
+                                               break;
+                                       }
+                               }
 
+                       }
+               
                        drag_info.last_frame_position = pending_region_position;
-           
+
                } else {
                        x_delta = 0;
                }
@@ -3599,41 +3641,16 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                   trackviews. nothing to do.
                */
                return;
-       } 
-
-
-       if (x_delta < 0) {
-               for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
-
-                       RegionView* rv2 = (*i);
-
-                       // If any regionview is at zero, we need to know so we can stop further leftward motion.
-                       
-                       double ix1, ix2, iy1, iy2;
-                       rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
-                       rv2->get_canvas_group()->i2w (ix1, iy1);
-
-                       if (ix1 <= 1) {
-                               x_delta = 0;
-                               break;
-                       }
-               }
        }
 
        /*************************************************************
            MOTION                                                                    
        ************************************************************/
-
-       bool do_move;
-
+       bool do_move = true;
        if (drag_info.first_move) {
-               if (drag_info.move_threshold_passed) {
-                       do_move = true;
-               } else {
+               if (!drag_info.move_threshold_passed) {
                        do_move = false;
                }
-       } else {
-               do_move = true;
        }
 
        if (do_move) {
@@ -3658,6 +3675,30 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
                        rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
                        rv->get_canvas_group()->i2w (ix1, iy1);
+
+                       if (drag_info.first_move) {
+
+                               // hide any dependent views 
+       
+                               rv->get_time_axis_view().hide_dependent_views (*rv);
+
+                               /* 
+                                  reparent to a non scrolling group so that we can keep the 
+                                  region selection above all time axis views.
+                                  reparenting means we have to move the rv as the two 
+                                  parent groups have different coordinates.
+                               */
+
+                               rv->get_canvas_group()->property_y() =  iy1 - 1;
+                               rv->get_canvas_group()->reparent(*_region_motion_group);
+
+                               rv->fake_set_opaque (true);
+                       }
+                       /* for evaluation of the track position of iy1, we have to adjust 
+                          to allow for the vertical scrolling adjustment and the height of the timebars.
+                       */
+                       iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize;
+
                        TimeAxisView* tvp2 = trackview_by_y_position (iy1);
                        RouteTimeAxisView* canvas_rtv = dynamic_cast<RouteTimeAxisView*>(tvp2);
                        RouteTimeAxisView* temp_rtv;
@@ -3720,7 +3761,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                }
                        }
 
-
                        /* prevent the regionview from being moved to before 
                           the zero position on the canvas.
                        */
@@ -3734,30 +3774,10 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
                                x_delta = max_frames - rv->region()->last_frame();
                        }
 
-
-                       if (drag_info.first_move) {
-
-                               /* hide any dependent views */
-                       
-                               rv->get_time_axis_view().hide_dependent_views (*rv);
-                       
-                               /* this is subtle. raising the regionview itself won't help,
-                                  because raise_to_top() just puts the item on the top of
-                                  its parent's stack. so, we need to put the trackview canvas_display group
-                                  on the top, since its parent is the whole canvas.
-                               */
-                       
-                               rv->get_canvas_group()->raise_to_top();
-                               rv->get_time_axis_view().canvas_display->raise_to_top();
-                               cursor_group->raise_to_top();
-
-                               rv->fake_set_opaque (true);
-                       }
-
                        if (drag_info.brushing) {
                                mouse_brush_insert_region (rv, pending_region_position);
                        } else {
-                               rv->move (x_delta, y_delta);                    
+                               rv->move (x_delta, y_delta);
                        }
 
                } /* foreach region */
@@ -3785,7 +3805,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
        vector<RegionView*> new_selection;
        typedef set<boost::shared_ptr<Playlist> > PlaylistSet;
        PlaylistSet modified_playlists;
-       pair<PlaylistSet::iterator,bool> insert_result;
+       PlaylistSet frozen_playlists;
+       list <sigc::connection> modified_playlist_connections;
+       pair<PlaylistSet::iterator,bool> insert_result, frozen_insert_result;
 
        /* first_move is set to false if the regionview has been moved in the 
           motion handler. 
@@ -3798,11 +3820,12 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
        nocommit = false;
 
-       /* The regionview has been moved at some stage during the grab so we need
+       /* XXX is this true??? i can''t tell the difference.
+          The regionview has been moved at some stage during the grab so we need
           to account for any mouse movement between this event and the last one. 
        */      
 
-       region_drag_motion_callback (item, event);
+       //region_drag_motion_callback (item, event);
 
        if (Config->get_edit_mode() == Splice && !pre_drag_region_selection.empty()) {
                selection->set (pre_drag_region_selection);
@@ -3853,11 +3876,12 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                double ix1, ix2, iy1, iy2;
                rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
                rv->get_canvas_group()->i2w (ix1, iy1);
+               iy1 += vertical_adjustment.get_value() - canvas_timebars_vsize;
+
                TimeAxisView* dest_tv = trackview_by_y_position (iy1);
                RouteTimeAxisView* dest_rtv = dynamic_cast<RouteTimeAxisView*>(dest_tv);
                double speed;
-               bool changed_tracks;
-               bool changed_position;
+               bool changed_tracks, changed_position;
                nframes64_t where;
 
                if (rv->region()->locked()) {
@@ -3877,24 +3901,26 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                changed_tracks = (dest_tv != &rv->get_time_axis_view());
 
                if (changed_position && !drag_info.x_constrained) {
+                       _master_group->w2i(ix1, iy1);
                        where = (nframes64_t) (unit_to_frame (ix1) * speed);
                } else {
                        where = rv->region()->position();
                }
                        
-               /* undo the previous hide_dependent_views so that xfades don't
-                  disappear on copying regions 
-               */
-               
-               rv->get_time_axis_view().reveal_dependent_views (*rv);
-               
                boost::shared_ptr<Region> new_region;
 
 
                if (drag_info.copy) {
                        /* we already made a copy */
                        new_region = rv->region();
-               } else {
+
+                       /* undo the previous hide_dependent_views so that xfades don't
+                          disappear on copying regions 
+                       */
+               
+                       //rv->get_time_axis_view().reveal_dependent_views (*rv);
+               
+               } else if (changed_tracks) {
                        new_region = RegionFactory::create (rv->region());
                }
 
@@ -3908,7 +3934,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        
                        insert_result = modified_playlists.insert (to_playlist);
                        if (insert_result.second) {
-                               session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));        
+                               session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
                        }
 
                        to_playlist->add_region (new_region, where);
@@ -3917,19 +3943,33 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                                                              
                        if (!latest_regionviews.empty()) {
                                // XXX why just the first one ? we only expect one
-                               dest_rtv->reveal_dependent_views (*latest_regionviews.front());
+                               // commented out in nick_m's canvas reworking. is that intended?
+                               //dest_atv->reveal_dependent_views (*latest_regionviews.front());
                                new_selection.push_back (latest_regionviews.front());
                        }
 
                } else {
-                       
+                       /* 
+                          motion on the same track. plonk the previously reparented region 
+                          back to its original canvas group (its streamview).
+                          No need to do anything for copies as they are fake regions which will be deleted.
+                       */
+
+                       rv->get_canvas_group()->reparent (*dest_rtv->view()->canvas_item());
+                       rv->get_canvas_group()->property_y() = 0;
+                 
                        /* just change the model */
                        
                        boost::shared_ptr<Playlist> playlist = dest_rtv->playlist();
 
                        insert_result = modified_playlists.insert (playlist);
                        if (insert_result.second) {
-                               session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));      
+                               session->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));
+                       }
+                       /* freeze to avoid lots of relayering in the case of a multi-region drag */
+                       frozen_insert_result = frozen_playlists.insert(playlist);
+                       if (frozen_insert_result.second) {
+                               playlist->freeze();
                        }
 
                        rv->region()->set_position (where, (void*) this);
@@ -3960,7 +4000,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
 
                        insert_result = modified_playlists.insert (from_playlist);
                        if (insert_result.second) {
-                               session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));    
+                               session->add_command (new MementoCommand<Playlist>(*from_playlist, &from_playlist->get_state(), 0));
                        }
 
                        from_playlist->remove_region ((rv->region()));
@@ -3996,7 +4036,6 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                        copies.push_back (rv);
                }
        }
-
        
        if (new_selection.empty()) {
                if (drag_info.copy) {
@@ -4012,6 +4051,10 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                */
                selection->set (new_selection);
        }
+
+       for (set<boost::shared_ptr<Playlist> >::iterator p = frozen_playlists.begin(); p != frozen_playlists.end(); ++p) {
+               (*p)->thaw();
+       }
                        
   out:
        if (!nocommit) {
@@ -4024,6 +4067,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
        for (vector<RegionView*>::iterator x = copies.begin(); x != copies.end(); ++x) {
                delete *x;
        }
+
 }
        
 void
@@ -4167,7 +4211,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos,
                set_verbose_canvas_cursor (buf, xpos + offset, ypos + offset);
        }
        else {
-               set_verbose_canvas_cursor (buf, drag_info.current_pointer_x + offset, drag_info.current_pointer_y + offset);
+               set_verbose_canvas_cursor (buf, drag_info.current_pointer_x + offset - horizontal_adjustment.get_value(), drag_info.current_pointer_y + offset - vertical_adjustment.get_value() + canvas_timebars_vsize);
        }
        show_verbose_canvas_cursor ();
 }
@@ -5088,7 +5132,7 @@ Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
 
                        update_marker_drag_item (temp_location);
                        range_marker_drag_rect->show();
-                       range_marker_drag_rect->raise_to_top();
+                       //range_marker_drag_rect->raise_to_top();
                        
                } 
                break;          
@@ -5369,8 +5413,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
                if (drag_info.current_pointer_y < drag_info.grab_y) {
                        y1 = drag_info.current_pointer_y;
                        y2 = drag_info.grab_y;
-               }
-               else {
+               } else {
                        y2 = drag_info.current_pointer_y;
                        y1 = drag_info.grab_y;
                }
@@ -5478,18 +5521,18 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
        nframes64_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position();
 
        float percentage = (double) newlen / (double) clicked_regionview->region()->length();
-
+       
 #ifndef USE_RUBBERBAND
        // Soundtouch uses percentage / 100 instead of normal (/ 1) 
        if (clicked_regionview->region()->data_type() == DataType::AUDIO) {
                percentage = (float) ((double) newlen - (double) clicked_regionview->region()->length()) / ((double) newlen) * 100.0f;
-#endif 
        }
-
+#endif 
+       
        begin_reversible_command (_("timestretch"));
-
+       
        // XXX how do timeFX on multiple regions ?
-
+       
        RegionSelection rs;
        rs.add (clicked_regionview);
 
index fd482a9dd6390c4701e4dfa824152e02616fef11..d52f4da231a54918dd7899b39c87d8d128fb0486 100644 (file)
@@ -1549,7 +1549,7 @@ Editor::scroll_tracks_down_line ()
 {
 
         Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
-       double vert_value = adj->get_value() + 20;
+       double vert_value = adj->get_value() + 60;
 
        if (vert_value>adj->get_upper() - canvas_height) {
                vert_value = adj->get_upper() - canvas_height;
@@ -1561,7 +1561,7 @@ void
 Editor::scroll_tracks_up_line ()
 {
         Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
-       adj->set_value (adj->get_value() - 20);
+       adj->set_value (adj->get_value() - 60);
 }
 
 /* ZOOM */
@@ -1875,8 +1875,9 @@ Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string
 void 
 Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
 {
-       if (!session) return;
-       
+       if (!session) {
+               return;
+       }
        double range_before = frame - leftmost_frame;
        double new_fpu;
        
@@ -1890,12 +1891,15 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
                range_before /= 1.61803399;
        }
 
-       if (new_fpu == frames_per_unit) return;
+       if (new_fpu == frames_per_unit)  {
+               return;
+       }
 
        nframes64_t new_leftmost = frame - (nframes64_t)range_before;
 
-       if (new_leftmost > frame) new_leftmost = 0;
-
+       if (new_leftmost > frame) {
+               new_leftmost = 0;
+       }
 //     begin_reversible_command (_("zoom to frame"));
 //     session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
 //     session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
@@ -2213,8 +2217,8 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        boost::shared_ptr<Playlist> playlist;
        
        track_canvas->window_to_world (x, y, wx, wy);
-       wx += horizontal_adjustment.get_value();
-       wy += vertical_adjustment.get_value();
+       //wx += horizontal_adjustment.get_value();
+       //wy += vertical_adjustment.get_value();
 
        GdkEvent event;
        event.type = GDK_BUTTON_RELEASE;
@@ -6038,7 +6042,6 @@ Editor::fit_tracks ()
                first_y_pos = std::min ((*t)->y_position, first_y_pos);
        }
 
-
        vertical_adjustment.set_value (first_y_pos);
 
        redo_visual_stack.push_back (current_visual_state());
index 54bc71e074792164c6a5ed00f35e638db16dfa20..121550f86f55bd74cf53d718c216e169bdae897e 100644 (file)
@@ -140,8 +140,8 @@ Editor::add_region_to_region_display (boost::shared_ptr<Region> region)
                for (i = rows.begin(); i != rows.end(); ++i) {
                        
                        boost::shared_ptr<Region> rr = (*i)[region_list_columns.region];
-
-                       if (region->region_list_equivalent (rr)) {
+                       
+                       if (rr && region->region_list_equivalent (rr)) {
                                return;
                        }
                }
index c12a30ca73e6e8086be174c25f640f33fa41e4ea..6213bf9d1e051cc1a550c599a74e576d00840c63 100644 (file)
@@ -364,7 +364,7 @@ Editor::redisplay_route_list ()
 
        cursor_group->raise_to_top ();
 
-       reset_scrolling_region ();
+       //reset_scrolling_region ();
 
        if (Config->get_sync_all_route_ordering() && !ignore_route_list_reorder) {
                ignore_route_order_sync = true;
@@ -401,7 +401,7 @@ Editor::hide_all_tracks (bool with_select)
           otherwise.
        */
 
-       reset_scrolling_region ();
+       //reset_scrolling_region ();
 }
 
 void
@@ -625,7 +625,9 @@ void
 Editor::route_list_delete (const Gtk::TreeModel::Path& path)
 {
        session->set_remote_control_ids();
+       ignore_route_list_reorder = true;
        redisplay_route_list ();
+       ignore_route_list_reorder = false;
 }
 
 void  
index dc62f669f88a495476a4f8a8bdaaf1facf2b7243..47ea8d01a093c43b0967076550b7c69e3da02118 100644 (file)
@@ -88,7 +88,7 @@ Editor::initialize_rulers ()
        minsec_ruler->set_size_request (-1, (int)timebar_height);
        gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_minsec_ruler), &ruler_metrics[ruler_metric_minsec]);
 
-       visible_timebars = 7; /* 4 here, 3 in time_canvas */
+       visible_timebars = 1; /*this will be changed below */
        ruler_pressed_button = 0;
 }
 
@@ -559,7 +559,9 @@ Editor::update_ruler_visibility ()
 {
        using namespace Box_Helpers;
        BoxList & lab_children =  time_button_vbox.children();
+       BoxList & ruler_lab_children =  ruler_label_vbox.children();
        BoxList & ruler_children =  time_canvas_vbox.children();
+       int visible_rulers = 0;
 
        if (no_ruler_shown_update) {
                return;
@@ -568,9 +570,10 @@ Editor::update_ruler_visibility ()
        visible_timebars = 0;
 
        lab_children.clear();
+       ruler_lab_children.clear();
 
        // leave the last one (the time_canvas) intact
-       while (ruler_children.size() > 1) {
+       while (ruler_children.size() > 0) {
                ruler_children.pop_front();
        }
 
@@ -628,31 +631,32 @@ Editor::update_ruler_visibility ()
        ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START));
        
        if (ruler_minsec_action->get_active()) {
-               lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START));
+               ruler_lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START));
                ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START));
-               visible_timebars++;
+               visible_rulers++;
        }
 
        if (ruler_timecode_action->get_active()) {
-               lab_children.push_back (Element(smpte_label, PACK_SHRINK, PACK_START));
+               ruler_lab_children.push_back (Element(smpte_label, PACK_SHRINK, PACK_START));
                ruler_children.insert (canvaspos, Element(*smpte_ruler, PACK_SHRINK, PACK_START));
-               visible_timebars++;
+               visible_rulers++;
        }
 
        if (ruler_samples_action->get_active()) {
-               lab_children.push_back (Element(frame_label, PACK_SHRINK, PACK_START));
+               ruler_lab_children.push_back (Element(frame_label, PACK_SHRINK, PACK_START));
                ruler_children.insert (canvaspos, Element(*frames_ruler, PACK_SHRINK, PACK_START));
-               visible_timebars++;
+               visible_rulers++;
        }
 
        if (ruler_bbt_action->get_active()) {
-               lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START));
+               ruler_lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START));
                ruler_children.insert (canvaspos, Element(*bbt_ruler, PACK_SHRINK, PACK_START));
-               visible_timebars++;
+               visible_rulers++;
        }
 
-       double tbpos = 1.0;
-       double old_unit_pos ;
+       double tbpos = 0.0;
+       double tbgpos = 0.0;
+       double old_unit_pos;
        
        if (ruler_meter_action->get_active()) {
                lab_children.push_back (Element(meter_label, PACK_SHRINK, PACK_START));
@@ -661,11 +665,17 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        meter_group->move ( 0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = meter_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       meter_bar_group->move ( 0.0, tbgpos - old_unit_pos);
+               }
+               meter_bar_group->show();
                meter_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
-       }
-       else {
+       } else {
+               meter_bar_group->hide();
                meter_group->hide();
        }
        
@@ -675,11 +685,17 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        tempo_group->move(0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = tempo_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       tempo_bar_group->move ( 0.0, tbgpos - old_unit_pos);
+               }
+               tempo_bar_group->show();
                tempo_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
-       }
-       else {
+       } else {
+               tempo_bar_group->hide();
                tempo_group->hide();
        }
        
@@ -689,10 +705,17 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        range_marker_group->move (0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = range_marker_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       range_marker_bar_group->move (0.0, tbgpos - old_unit_pos);
+               }
+               range_marker_bar_group->show();
                range_marker_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
        } else {
+               range_marker_bar_group->hide();
                range_marker_group->hide();
        }
 
@@ -702,11 +725,17 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        transport_marker_group->move ( 0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = transport_marker_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       transport_marker_bar_group->move ( 0.0, tbgpos - old_unit_pos);
+               }
+               transport_marker_bar_group->show();
                transport_marker_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
-       }
-       else {
+       } else {
+               transport_marker_bar_group->hide();
                transport_marker_group->hide();
        }
 
@@ -716,13 +745,19 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        cd_marker_group->move (0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = cd_marker_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       cd_marker_bar_group->move (0.0, tbgpos - old_unit_pos);
+               }
+               cd_marker_bar_group->show();
                cd_marker_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
                // make sure all cd markers show up in their respective places
                update_cd_marker_display();
-       }
-       else {
+       } else {
+               cd_marker_bar_group->hide();
                cd_marker_group->hide();
                // make sure all cd markers show up in their respective places
                update_cd_marker_display();
@@ -734,21 +769,42 @@ Editor::update_ruler_visibility ()
                if (tbpos != old_unit_pos) {
                        marker_group->move ( 0.0, tbpos - old_unit_pos);
                }
+               old_unit_pos = marker_bar_group->property_y();
+               if (tbgpos != old_unit_pos) {
+                       marker_bar_group->move ( 0.0, tbgpos - old_unit_pos);
+               }
+               marker_bar_group->show();
                marker_group->show();
                tbpos += timebar_height;
+               tbgpos += timebar_height;
                visible_timebars++;
-       }
-       else {
+       } else {
+               marker_bar_group->hide();
                marker_group->hide();
        }
        
-       time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars));
+       gdouble old_canvas_timebars_vsize = canvas_timebars_vsize;
+       canvas_timebars_vsize = timebar_height * visible_timebars;
+       gdouble vertical_pos_delta = canvas_timebars_vsize - old_canvas_timebars_vsize;
+
+       if (vertical_pos_delta < 0 && (vertical_adjustment.get_value() + canvas_height) >= vertical_adjustment.get_upper()) {
+               /*if we're at the bottom of the canvas, don't move the _trackview_grooup*/
+               vertical_adjustment.set_upper(vertical_adjustment.get_upper() + vertical_pos_delta);
+       } else {
+               vertical_adjustment.set_upper(vertical_adjustment.get_upper() + vertical_pos_delta);
+               _trackview_group->move (0, vertical_pos_delta);
+       }
+       ruler_label_vbox.set_size_request (-1, (int)(timebar_height * visible_rulers));
+
+       time_canvas_vbox.set_size_request (-1,-1);
        time_canvas_event_box.queue_resize();
        compute_fixed_ruler_scale();
        update_fixed_rulers();
+       redisplay_tempo (false);
 
        time_canvas_event_box.show_all();
-       time_button_frame.show_all();
+       ruler_label_event_box.show_all();
+       time_button_event_box.show_all();
 
        compute_current_bbt_points (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
        compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + (nframes64_t)(edit_packer.get_width() * frames_per_unit));
@@ -1704,7 +1760,7 @@ Editor::metric_get_frames (GtkCustomRulerMark **marks, gdouble lower, gdouble up
        nmarks = 5;
        *marks = (GtkCustomRulerMark *) g_malloc (sizeof(GtkCustomRulerMark) * nmarks);
        for (n = 0, pos = ilower; n < nmarks; pos += mark_interval, ++n) {
-               snprintf (buf, sizeof(buf), "%u", pos);
+               snprintf (buf, sizeof(buf), "%" PRIi64, pos);
                (*marks)[n].label = g_strdup (buf);
                (*marks)[n].position = pos;
                (*marks)[n].style = GtkCustomRulerMarkMajor;
index 1e5c02f5d8bcf2d2ca1106f1c14485a9892cb82e..49cee3e2395daa3fdfa66d4e3ff13266a19df3fc 100644 (file)
@@ -171,11 +171,36 @@ Editor::compute_current_bbt_points (nframes_t leftmost, nframes_t rightmost)
        current_bbt_points = session->tempo_map().get_points (session->tempo_map().frame_time (previous_beat), session->tempo_map().frame_time (next_beat) + 1);
 }
 
+ArdourCanvas::SimpleLine *
+Editor::get_time_line ()
+{
+         ArdourCanvas::SimpleLine *line;
+
+       if (free_measure_lines.empty()) {
+               line = new ArdourCanvas::SimpleLine (*time_line_group);
+               used_measure_lines.push_back (line);
+       } else {
+               line = free_measure_lines.front();
+               free_measure_lines.erase (free_measure_lines.begin());
+               used_measure_lines.push_back (line);
+       }
+
+       return line;
+}
+
 void
 Editor::hide_measures ()
 {
-       tempo_lines->hide();
-       marker_tempo_lines->hide();
+       // from old pre-merge 3.0
+       // tempo_lines->hide();
+       // marker_tempo_lines->hide();
+
+       for (TimeLineList::iterator i = used_measure_lines.begin(); i != used_measure_lines.end(); ++i) {
+               (*i)->hide();
+               free_measure_lines.push_back (*i);
+       }
+
+       used_measure_lines.clear ();
 }
 
 bool
@@ -195,16 +220,68 @@ Editor::draw_measures ()
                return;
        }
 
-       tempo_lines->draw(*current_bbt_points, frames_per_unit);
-       marker_tempo_lines->draw(*current_bbt_points, frames_per_unit);
+       TempoMap::BBTPointList::iterator i;
+       ArdourCanvas::SimpleLine *line;
+       gdouble xpos;
+       double beat_density;
+
+        uint32_t beats = 0;
+        uint32_t bars = 0;
+       uint32_t color;
+
+       if (current_bbt_points == 0 || current_bbt_points->empty()) {
+               return;
+       }
+
+       /* get the first bar spacing */
+
+       i = current_bbt_points->end();
+       i--;
+       bars = (*i).bar - (*current_bbt_points->begin()).bar;
+       beats = current_bbt_points->size() - bars;
+
+       beat_density =  (beats * 10.0f) / track_canvas->get_width ();
+
+       if (beat_density > 4.0f) {
+               /* if the lines are too close together, they become useless
+                */
+               return;
+       }
+
+       for (i = current_bbt_points->begin(); i != current_bbt_points->end(); ++i) {
+
+               switch ((*i).type) {
+               case TempoMap::Bar:
+                       break;
+
+               case TempoMap::Beat:
+                       
+                       if ((*i).beat == 1) {
+                               color = ARDOUR_UI::config()->canvasvar_MeasureLineBar.get();
+                       } else {
+                               color = ARDOUR_UI::config()->canvasvar_MeasureLineBeat.get();
+
+                               if (beat_density > 2.0) {
+                                       /* only draw beat lines if the gaps between beats are large.
+                                       */
+                                       break;
+                               }
+                       }
+
+                       xpos = frame_to_unit ((nframes64_t) (*i).frame);
+                       line = get_time_line ();
+                       line->property_x1() = xpos;
+                       line->property_x2() = xpos;
+                       line->property_y2() = canvas_height;
+                       line->property_color_rgba() = color;
+                       //line->raise_to_top();
+                       line->show();   
+                       break;
+               }
+       }
 
-       /*time_line_group->raise_to_top();
-       time_line_group->lower(1);*/
-       marker_time_line_group->raise_to_top();
-       //marker_time_line_group->lower(1);
-       
        /* the cursors are always on top of everything */
-       cursor_group->raise_to_top();
+       //cursor_group->raise_to_top();
 
        return;
 }
diff --git a/gtk2_ardour/lv2_plugin_ui.cc b/gtk2_ardour/lv2_plugin_ui.cc
new file mode 100644 (file)
index 0000000..2ca9166
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+    Copyright (C) 2008 Paul Davis 
+    Author: Dave Robillard
+
+    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 <ardour/insert.h>
+#include <ardour/lv2_plugin.h>
+
+#include "lv2_plugin_ui.h"
+
+using namespace Gtk;
+using namespace ARDOUR;
+using namespace PBD;
+
+void
+LV2PluginUI::lv2_ui_write(LV2UI_Controller controller,
+             uint32_t         port_index,
+             uint32_t         buffer_size,
+             uint32_t         format,
+             const void*      buffer)
+{
+       LV2PluginUI* me = (LV2PluginUI*)controller;
+       if (*(float*)buffer != me->_values[port_index])
+               me->_lv2->set_parameter(port_index, *(float*)buffer);
+}
+
+void
+LV2PluginUI::parameter_changed (uint32_t port_index, float val)
+{
+       if (val != _values[port_index]) {
+               const LV2UI_Descriptor* ui_desc = slv2_ui_instance_get_descriptor(_inst);
+               LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(_inst);
+               if (ui_desc->port_event)
+                       ui_desc->port_event(ui_handle, port_index, 4, 0, &val);
+               _values[port_index] = val;
+       }
+}
+
+LV2PluginUI::LV2PluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<LV2Plugin> lv2p)
+       : PlugUIBase (pi)
+       , _lv2(lv2p)
+{
+       _inst = slv2_ui_instantiate(
+                       _lv2->slv2_plugin(), _lv2->slv2_ui(), LV2PluginUI::lv2_ui_write, this,
+                       _lv2->features());
+                       
+       GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_inst);
+       _gui_widget = Glib::wrap(c_widget);
+       _gui_widget->show_all();
+       pack_start(*_gui_widget, true, true);
+       
+       uint32_t num_ports = slv2_plugin_get_num_ports(lv2p->slv2_plugin());
+       _values = new float[num_ports];
+       for (uint32_t i = 0; i < num_ports; ++i) {
+               bool ok;
+               _values[i] = lv2p->nth_parameter(i, ok);
+               if (ok)
+                       lv2_ui_write(this, i, 4, /* FIXME: format */0, &_values[i]);
+       }
+               
+       _lv2->ParameterChanged.connect(mem_fun(*this, &LV2PluginUI::parameter_changed));
+}
+
+LV2PluginUI::~LV2PluginUI ()
+{
+       delete[] _values;
+       // plugin destructor destroys the GUI
+}
+
+int
+LV2PluginUI::get_preferred_height ()
+{
+       Gtk::Requisition r = size_request();
+       return r.height;
+}
+
+int
+LV2PluginUI::get_preferred_width ()
+{
+       Gtk::Requisition r = size_request();
+       return r.width;
+}
+
+int
+LV2PluginUI::package (Gtk::Window& win)
+{
+       /* forward configure events to plugin window */
+       win.signal_configure_event().connect (mem_fun (*this, &LV2PluginUI::configure_handler));
+       return 0;
+}
+
+bool
+LV2PluginUI::configure_handler (GdkEventConfigure* ev)
+{
+       cout << "CONFIGURE" << endl;
+       return false;
+}
+
diff --git a/gtk2_ardour/lv2_plugin_ui.h b/gtk2_ardour/lv2_plugin_ui.h
new file mode 100644 (file)
index 0000000..5946d8b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+    Copyright (C) 2008 Paul Davis
+    Author: Dave Robillard
+
+    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 __ardour_lv2_plugin_ui_h__
+#define __ardour_lv2_plugin_ui_h__
+
+#include <vector>
+#include <map>
+#include <list>
+
+#include <sigc++/signal.h>
+#include <gtkmm/widget.h>
+
+#include <ardour_dialog.h>
+#include <ardour/types.h>
+#include "plugin_ui.h"
+
+#ifdef HAVE_LV2
+
+namespace ARDOUR {
+       class PluginInsert;
+       class LV2Plugin;
+}
+
+class LV2PluginUI : public PlugUIBase, public Gtk::VBox
+{
+  public:
+       LV2PluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::LV2Plugin>);
+       ~LV2PluginUI ();
+
+       gint get_preferred_height ();
+       gint get_preferred_width ();
+       bool start_updating(GdkEventAny*) {return false;}
+       bool stop_updating(GdkEventAny*) {return false;}
+
+       int package (Gtk::Window&);
+
+  private:
+       boost::shared_ptr<ARDOUR::LV2Plugin> _lv2;
+       
+       Gtk::Widget*   _gui_widget;
+       SLV2UIInstance _inst;
+       float*         _values;
+       
+       static void lv2_ui_write(
+                       LV2UI_Controller controller,
+                       uint32_t         port_index,
+                       uint32_t         buffer_size,
+                       uint32_t         format,
+                       const void*      buffer);
+       
+       void parameter_changed(uint32_t, float);
+       bool configure_handler (GdkEventConfigure*);
+       void save_plugin_setting ();
+};
+#endif // HAVE_LV2
+
+#endif /* __ardour_lv2_plugin_ui_h__ */
+
index abbf216eea9f06f95c86c38ad6d9a91c72b5e423..0edf450cd1b8003c1c98053706c211535778060d 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 #include <cstdlib>
+#include <signal.h>
 
 #include <sigc++/bind.h>
 #include <gtkmm/settings.h>
@@ -252,6 +253,7 @@ fixup_bundle_environment ()
        path += "/../Resources/gdk-pixbuf.loaders";
 
        setenv ("GDK_PIXBUF_MODULE_FILE", path.c_str(), 1);
+       cerr << "Set GDK_PIXBUF_MODULE_FILE to " << path << endl;
 
        if (getenv ("ARDOUR_WITH_JACK")) {
                // JACK driver dir
@@ -265,6 +267,12 @@ fixup_bundle_environment ()
 
 #endif
 
+static void
+sigpipe_handler (int sig)
+{
+       cerr << _("SIGPIPE received - JACK has probably died") << endl;
+}
+
 #ifdef VST_SUPPORT
 /* this is called from the entry point of a wine-compiled
    executable that is linked against gtk2_ardour built
@@ -278,9 +286,12 @@ int main (int argc, char *argv[])
 {
        vector<Glib::ustring> null_file_list;
        
+       cerr << "here we go\n";
+       
 #ifdef __APPLE__
        fixup_bundle_environment ();
 #endif
+       cerr << "just did it\n";
 
         Glib::thread_init();
        gtk_set_locale ();
@@ -339,6 +350,10 @@ int main (int argc, char *argv[])
 
        PBD::ID::init ();
 
+       if (::signal (SIGPIPE, sigpipe_handler)) {
+               cerr << _("Cannot install SIGPIPE error handler") << endl;
+       }
+
         try { 
                ui = new ARDOUR_UI (&argc, &argv);
        } catch (failed_constructor& err) {
index edfec8a600b466c8fb15454fa0fffbe8ea602cfb..9e77d0c9e733e10c24021ab2827de3b8edd80ecd 100644 (file)
@@ -245,7 +245,7 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
        mark->property_outline_color_rgba() = rgba;
        mark->property_width_pixels() = 1;
        Pango::FontDescription* font = get_font_for_style (N_("MarkerText"));
-
+       //cerr << " font->get_size() = " << font->get_size() << " is_absolute = " << pango_font_description_get_size_is_absolute(font->gobj()) << " to_string = " << font->to_string() << endl;
        text = new Text (*group);
        text->property_font_desc() = *font;
        text->property_text() = annotation.c_str();
index b2f8ece64ee1a3bc0aedc82681262a4697eb1caf..64e8ea09092d7ea5cb1ec6617cf9e39ea5628c05 100644 (file)
@@ -665,7 +665,9 @@ void
 Mixer_UI::track_list_delete (const Gtk::TreeModel::Path& path)
 {
        session->set_remote_control_ids();
+       ignore_route_reorder = true;
        redisplay_track_list ();
+       ignore_route_reorder = false;
 }
 
 void
index 87d5532d34575e52170fd4f9afe526fb8a04791f..b49d6a0b7702b769606defc5e8428be9a205e05e 100644 (file)
@@ -314,7 +314,7 @@ PluginSelector::ladspa_refiller (const std::string& filterstr)
 void
 PluginSelector::lv2_refiller (const std::string& filterstr)
 {
-#ifdef HAVE_SLV2
+#ifdef HAVE_LV2
        refiller (manager->lv2_plugin_info(), filterstr, "LV2");
 #endif
 }
@@ -520,7 +520,7 @@ PluginSelector::plugin_menu()
 #ifdef HAVE_AUDIOUNITS
        all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end());
 #endif
-#ifdef HAVE_SLV2
+#ifdef HAVE_LV2
        all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end());
 #endif
 
index d3c9effaa24b4efdee534045b9970a90dfe45d2b..a91a5bf9d1f875897d37c55b42852e855b6c4755 100644 (file)
 #ifdef VST_SUPPORT
 #include <ardour/vst_plugin.h>
 #endif
+#ifdef HAVE_LV2
+#include <ardour/lv2_plugin.h>
+#include "lv2_plugin_ui.h"
+#endif
 
 #include <lrdf.h>
 
@@ -86,6 +90,10 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
                        error << _("Eh? LADSPA plugins don't have editors!") << endmsg;
                        break;
 
+               case ARDOUR::LV2:
+                       have_gui = create_lv2_editor (insert);
+                       break;
+
                default:
 #ifndef VST_SUPPORT
                        error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)")
@@ -250,6 +258,30 @@ PluginUIWindow::app_activated (bool yn)
 #endif
 }
 
+bool
+PluginUIWindow::create_lv2_editor(boost::shared_ptr<PluginInsert> insert)
+{
+#ifndef HAVE_LV2
+       return false;
+#else
+
+       boost::shared_ptr<LV2Plugin> vp;
+       
+       if ((vp = boost::dynamic_pointer_cast<LV2Plugin> (insert->plugin())) == 0) {
+               error << _("create_lv2_editor called on non-LV2 plugin") << endmsg;
+               throw failed_constructor ();
+       } else {
+               LV2PluginUI* lpu = new LV2PluginUI (insert, vp);
+               _pluginui = lpu;
+               add (*lpu);
+               lpu->package (*this);
+       }
+
+       non_gtk_gui = false;
+       return true;
+#endif
+}
+
 bool
 PluginUIWindow::on_key_press_event (GdkEventKey* event)
 {
index acc1e4d53a6a40586ba98145cd6cdd2c75b07bcf..19c2774be0773bbced67db82bfc98e925aa3e76a 100644 (file)
@@ -234,6 +234,7 @@ class PluginUIWindow : public Gtk::Window
 
        bool create_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
        bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
+       bool create_lv2_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
 };
 
 #ifdef VST_SUPPORT
index 9994f422d4cab2543a564c178736f01347cbb860..937399e94f4121862d93d18c9819018a80542a53 100644 (file)
@@ -336,7 +336,12 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        static const int vertical_spacing;
        static const int horizontal_spacing;
 
+
+       virtual gdouble get_trackview_group_vertical_offset () const = 0;
+       virtual ArdourCanvas::Group* get_trackview_group () const = 0;
+
        /// Singleton instance, set up by Editor::Editor()
+
        static PublicEditor* _instance;
 
        friend class PluginUIWindow;
index 27f9c878193e63f15aad1ca00cceb9b215d6eb34..a7d6c04e71dd8b3828ea9ca705bb8218a01a927b 100644 (file)
@@ -230,7 +230,8 @@ RegionView::region_changed (Change what_changed)
        */
        /*
        if (what_changed & Region::LayerChanged) {
-               region_layered ();
+               // this is handled by the playlist i believe
+               //region_layered ();
        }
        */
        if (what_changed & Region::LockChanged) {
@@ -285,7 +286,7 @@ RegionView::region_layered ()
 {
        RouteTimeAxisView *rtv = dynamic_cast<RouteTimeAxisView*>(&get_time_axis_view());
        assert(rtv);
-       rtv->view()->region_layered (this);
+       //rtv->view()->region_layered (this);
 }
        
 void
index 77c7f59afc4e9da86e353dbdceccbae46b7fd0f7..b0b6a577f78a02d27286fb079a8cf6093bcb343f 100644 (file)
@@ -266,8 +266,10 @@ SoundFileBox::setup_labels (const ustring& filename)
                samplerate.set_name ("NewSessionSR2Label");
        }
 
-       length_clock.set (sf_info.length, true);
-       timecode_clock.set (sf_info.timecode, true);
+       double src_coef = (double) _session->nominal_frame_rate() / sf_info.samplerate;
+
+       length_clock.set (sf_info.length * src_coef + 0.5, true);
+       timecode_clock.set (sf_info.timecode * src_coef + 0.5, true);
 
        // this is a hack that is fixed in trunk, i think (august 26th, 2007)
 
index 0f52f07939af82a9fa0621c30edd006a8bf93d1d..7539683da5696df32f5e755f4afb6ab07f26d1f5 100644 (file)
@@ -49,7 +49,6 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group)
        : _trackview (tv)
        , owns_canvas_group(group == 0)
        , canvas_group(group ? group : new ArdourCanvas::Group(*_trackview.canvas_display))
-       , canvas_rect(new ArdourCanvas::SimpleRect (*canvas_group))
        , _samples_per_unit(_trackview.editor.get_current_zoom())
        , rec_updating(false)
        , rec_active(false)
@@ -63,11 +62,15 @@ StreamView::StreamView (RouteTimeAxisView& tv, ArdourCanvas::Group* group)
 {
        /* set_position() will position the group */
 
+       canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group);
        canvas_rect->property_x1() = 0.0;
        canvas_rect->property_y1() = 0.0;
-       canvas_rect->property_x2() = _trackview.editor.frame_to_pixel (max_frames);
+       canvas_rect->property_x2() = _trackview.editor.frame_to_pixel (max_frames - 1);
        canvas_rect->property_y2() = (double) tv.current_height();
-       canvas_rect->property_outline_what() = (guint32) (0x2|0x8);  // outline RHS and bottom 
+
+       // DR-way
+       // canvas_rect->property_outline_what() = (guint32) (0x2|0x8);  // outline RHS and bottom 
+       canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8);  // outline ends and bottom 
        // (Fill/Outline colours set in derived classes)
 
        canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview));
@@ -294,18 +297,12 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target)
 void
 StreamView::region_layered (RegionView* rv)
 {
-
-        /* 
-           Currently 'layer' has nothing to do with the desired canvas layer.
-            For now, ensure that multiple regionviews passed here in groups are 
-           ordered by 'layer' (lowest to highest). 
-
-           (see AudioStreamView::redisplay_diskstream ()).
-           We move them to the top layer as they arrive. 
-        */
-
-       rv->get_canvas_group()->raise_to_top();
+       /* don't ever leave it at the bottom, since then it doesn't
+          get events - the  parent group does instead ...
+          we need to raise it above the streamview's 
+          canvas_rect, hence the layer+1 here
+       */
+       rv->get_canvas_group()->raise (rv->region()->layer() + 1);
 }
 
 void
index 7cb5830dcbd5b053dde6abf9f457de08d0f03c39..e8acb7cd48168777bd64ffa0e29559eefb469457 100644 (file)
@@ -74,7 +74,7 @@ public:
 
        void set_layer_display (LayerDisplay);
 
-       ArdourCanvas::Item* canvas_item() { return canvas_group; }
+       ArdourCanvas::Group* canvas_item() { return canvas_group; }
 
        enum ColorTarget {
                RegionColor,
index 0973fb9c93e5b9016ad0f84e0b5ba08531d98f00..7858b536f89e8bde7d4d3a08ea9abc1925c0c44c 100644 (file)
@@ -83,7 +83,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
                need_size_info = false;
        }
 
-       canvas_display = new Group (*canvas.root(), 0.0, 0.0);
+       canvas_display = new Group (*ed.get_trackview_group (), 0.0, 0.0);
 
        ghost_group = new Group (*canvas_display);
        ghost_group->lower_to_bottom();
@@ -240,6 +240,7 @@ TimeAxisView::show_at (double y, int& nth, VBox *parent)
        */
 
        canvas_display->get_bounds (ix1, iy1, ix2, iy2);
+       iy1 += editor.get_trackview_group_vertical_offset ();
        Group* pg = canvas_display->property_parent();
        pg->i2w (ix1, iy1);
 
index fa520f4ca1500269d0f68094a8cb4e6e3e631c65..6ea16c4b25ebc8c47456d4689b2075c48ae19151 100644 (file)
@@ -150,7 +150,7 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo
        vestigial_frame = new ArdourCanvas::SimpleRect (*group);
        vestigial_frame->property_x1() = (double) 0.0;
        vestigial_frame->property_y1() = (double) 1.0;
-       vestigial_frame->property_x2() = 2.0;
+       vestigial_frame->property_x2() = (double) 2.0;
        vestigial_frame->property_y2() = (double) trackview.current_height();
        vestigial_frame->property_outline_what() = 0xF;
        vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
@@ -644,7 +644,7 @@ TimeAxisViewItem::get_canvas_frame()
 /**
  * 
  */
-ArdourCanvas::Item*
+ArdourCanvas::Group*
 TimeAxisViewItem::get_canvas_group()
 {
        return (group) ;
index 02becad3e758dc8fd745d8b8237896ecbe24fdd6..cc1c641f57de372906ade0ceb1cd6599d7b75b78 100644 (file)
@@ -216,7 +216,7 @@ class TimeAxisViewItem : public Selectable
     /**
      * 
      */
-    ArdourCanvas::Item* get_canvas_group();
+    ArdourCanvas::Group* get_canvas_group();
 
     /**
      * 
index 9008f8b8cd943aae0d71aa1b30f78da711220a65..f09ef1b27fcc2a20f5b723b9e3b017f2532ff712 100644 (file)
@@ -571,23 +571,21 @@ get_xpm (std::string name)
                
                sys::path data_file_path;
                
-               if (!find_file_in_search_path (spath, name, data_file_path)) {
+               if(!find_file_in_search_path (spath, name, data_file_path)) {
                        fatal << string_compose (_("cannot find XPM file for %1"), name) << endmsg;
-                       /*NOTREACHED*/
                }
-
+               
                try {
-                       xpm_map[name] = Gdk::Pixbuf::create_from_file (data_file_path.to_string());
-               }
-
-               catch(const Glib::Error& e)     {
+                       xpm_map[name] =  Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+               } catch(const Glib::Error& e)   {
                        warning << "Caught Glib::Error: " << e.what() << endmsg;
-               }
+               }
        }
 
        return xpm_map[name];
 }
 
+
 Glib::RefPtr<Gdk::Pixbuf>      
 get_icon (const char* cname)
 {
@@ -608,15 +606,11 @@ get_icon (const char* cname)
        Glib::RefPtr<Gdk::Pixbuf> img;
        try {
                img = Gdk::Pixbuf::create_from_file (data_file_path.to_string());
+       } catch (const Gdk::PixbufError &e) {
+               cerr << "Caught PixbufError: " << e.what() << endl;
+       } catch (...) {
+               g_message("Caught ... ");
        }
-       catch (const Gdk::PixbufError &e)
-    {
-        cerr << "Caught PixbufError: " << e.what() << endl;
-    }
-    catch (...)
-    {
-        g_message("Caught ... ");
-    }
 
        return img;
 }
@@ -701,7 +695,7 @@ set_pango_fontsize ()
 {
        long val = ARDOUR::Config->get_font_scale();
 
-       /* FT2 rendering */
+       /* FT2 rendering - used by GnomeCanvas, sigh */
 
        pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_for_display(), val/1024, val/1024);
 
index d20ece65bdb83acee97151cf79e0837def61560a..b3711c5588f88266ec0c418ee4c481e8ca0106a8 100644 (file)
@@ -60,9 +60,14 @@ class LV2Plugin : public ARDOUR::Plugin
        int         get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
        uint32_t    nth_parameter (uint32_t port, bool& ok) const;
 
+       const void* extension_data(const char* uri) { return _instance->lv2_descriptor->extension_data(uri); }
+
        SLV2Plugin slv2_plugin()         { return _plugin; }
+       SLV2UI     slv2_ui()             { return _ui; }
        SLV2Port   slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); }
        
+       const LV2_Feature* const* features() { return _features; }
+
        std::set<Parameter> automatable() const;
 
        void activate () { 
@@ -104,14 +109,14 @@ class LV2Plugin : public ARDOUR::Plugin
        int      set_state(const XMLNode& node);
        bool     save_preset(std::string name);
 
-       bool has_editor() const { return false; }
+       bool has_editor() const;
 
-       int require_output_streams (uint32_t);
-       
   private:
        void*                    _module;
        LV2World&                _world;
+       LV2_Feature**            _features;
        SLV2Plugin               _plugin;
+       SLV2UI                   _ui;
        SLV2Value                _name;
        SLV2Value                _author;
        SLV2Instance             _instance;
@@ -123,6 +128,11 @@ class LV2Plugin : public ARDOUR::Plugin
        bool                     _was_activated;
        vector<bool>             _port_is_input;
 
+       typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess;
+       LV2_DataAccess _data_access_extension_data;
+       LV2_Feature _data_access_feature;
+       LV2_Feature _instance_access_feature;
+
        void init (LV2World& world, SLV2Plugin plugin, nframes_t rate);
        void run (nframes_t nsamples);
        void latency_compute_run ();
@@ -149,6 +159,7 @@ struct LV2World {
        SLV2Value integer;
        SLV2Value toggled;
        SLV2Value srate;
+       SLV2Value gtk_gui;
 };
 
 
index 00315846b2e51e390f4faf14769775499af4b013..32f47d42d7c39eeae36585291aac1729a84a223b 100644 (file)
@@ -217,7 +217,7 @@ class Region : public Automatable, public boost::enable_shared_from_this<Region>
        const SourceList& master_sources() const { return _master_sources; }
 
        std::vector<string> master_source_names();
-       void set_master_sources (SourceList&);
+       void set_master_sources (const SourceList&);
        
        /* serialization */
        
index 4862ddcd12fe410fe5e474fbad075c4c6b0105ad..9c7ea0f13fda9b664c628989686ac27ebc0f7fb7 100644 (file)
@@ -1081,10 +1081,19 @@ AUPluginInfo::cached_io_configuration (const std::string& unique_id,
        
        ARDOUR::BootMessage (string_compose (_("Checking AudioUnit: %1"), name));
        
-       if (CAAudioUnit::Open (comp, unit) != noErr) {
+       try {
+
+               if (CAAudioUnit::Open (comp, unit) != noErr) {
+                       return false;
+               }
+
+       } catch (...) {
+
+               warning << string_compose (_("Could not load AU plugin %1 - ignored"), name) << endmsg;
                return false;
-       }
 
+       }
+               
        if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
                return false;
        }
index 76c0de9b242bedde7f08c1b0881541802b8556f6..6a76e98c3c5efdda5c23d72bccb3bba82105552d 100644 (file)
@@ -95,6 +95,7 @@ AudioEngine::~AudioEngine ()
                
                if (_running) {
                        jack_client_close (_jack);
+                       _jack = 0;
                }
                
                stop_metering_thread ();
@@ -121,6 +122,11 @@ _thread_init_callback (void *arg)
 int
 AudioEngine::start ()
 {
+       if (!_jack) {
+               error << _("AudioEngine::start() called while disconnected from JACK") << endmsg;
+               return -1;
+       }
+
        if (!_running) {
 
                if (session) {
@@ -179,17 +185,13 @@ AudioEngine::start ()
 int
 AudioEngine::stop (bool forever)
 {
-       if (_running) {
-               _running = false;
-               stop_metering_thread ();
+       if (_jack) {
                if (forever) {
-                       jack_client_t* foo = _jack;
-                       _jack = 0;
-                       jack_client_close (foo);
+                       disconnect_from_jack ();
                } else {
                        jack_deactivate (_jack);
+                       Stopped(); /* EMIT SIGNAL */
                }
-               Stopped(); /* EMIT SIGNAL */
        }
 
        return _running ? -1 : 0;
@@ -204,11 +206,13 @@ AudioEngine::get_sync_offset (nframes_t& offset) const
 
        jack_position_t pos;
        
-       (void) jack_transport_query (_jack, &pos);
-
-       if (pos.valid & JackVideoFrameOffset) {
-               offset = pos.video_offset;
-               return true;
+       if (_jack) {
+               (void) jack_transport_query (_jack, &pos);
+               
+               if (pos.valid & JackVideoFrameOffset) {
+                       offset = pos.video_offset;
+                       return true;
+               }
        }
 
 #endif
@@ -252,7 +256,7 @@ int
 AudioEngine::_xrun_callback (void *arg)
 {
        AudioEngine* ae = static_cast<AudioEngine*> (arg);
-       if (ae->jack()) {
+       if (ae->connected()) {
                ae->Xrun (); /* EMIT SIGNAL */
        }
        return 0;
@@ -262,7 +266,7 @@ int
 AudioEngine::_graph_order_callback (void *arg)
 {
        AudioEngine* ae = static_cast<AudioEngine*> (arg);
-       if (ae->jack()) {
+       if (ae->connected()) {
                ae->GraphReordered (); /* EMIT SIGNAL */
        }
        return 0;
@@ -894,7 +898,8 @@ AudioEngine::halted (void *arg)
        ae->_running = false;
        ae->_buffer_size = 0;
        ae->_frame_rate = 0;
-       ae->_jack = 0;
+
+       cerr << "!!! HALTED !!!\n";
 
        if (was_running) {
                ae->Halted(); /* EMIT SIGNAL */
@@ -1067,7 +1072,6 @@ AudioEngine::update_total_latency (const Port& port)
 void
 AudioEngine::transport_stop ()
 {
-       // cerr << "tell JACK to stop\n";
        if (_jack) {
                jack_transport_stop (_jack);
        }
@@ -1211,7 +1215,7 @@ AudioEngine::connect_to_jack (string client_name)
 {
        jack_client_name = client_name;
 
-       if ((_jack = jack_client_new (client_name.c_str())) == NULL) {
+       if ((_jack = jack_client_new (client_name.c_str())) == 0) {
                return -1;
        }
 
@@ -1223,29 +1227,36 @@ AudioEngine::connect_to_jack (string client_name)
 int 
 AudioEngine::disconnect_from_jack ()
 {
-       if (_jack == 0) {
+       if (!_jack) {
                return 0;
        }
 
-       jack_client_close (_jack);
+
+       if (_running) {
+               stop_metering_thread ();
+       }
+
+       { 
+               Glib::Mutex::Lock lm (_process_lock);
+               jack_client_close (_jack);
+               _jack = 0;
+       }
 
        _buffer_size = 0;
        _frame_rate = 0;
 
        if (_running) {
-               stop_metering_thread ();
                _running = false;
                Stopped(); /* EMIT SIGNAL */
        }
 
-       _jack = 0;
        return 0;
 }
 
 int
 AudioEngine::reconnect_to_jack ()
 {
-       if (_jack) {
+       if (_running) {
                disconnect_from_jack ();
                /* XXX give jackd a chance */
                Glib::usleep (250000);
@@ -1336,7 +1347,9 @@ void
 AudioEngine::update_total_latencies ()
 {
 #ifdef HAVE_JACK_RECOMPUTE_LATENCIES
-       jack_recompute_total_latencies (_jack);
+       if (_jack) {
+               jack_recompute_total_latencies (_jack);
+       }
 #endif
 }
                
index a38c851c215055707c7d29437937be0bc7ecb0cb..f6bb2ec4dd84057c0fba029a9e95d398d82fc83c 100644 (file)
 using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
-
+       
 LV2Plugin::LV2Plugin (AudioEngine& e, Session& session, LV2World& world, SLV2Plugin plugin, nframes_t rate)
        : Plugin (e, session)
        , _world(world)
+       , _features(NULL)
 {
        init (world, plugin, rate);
 }
@@ -54,6 +55,7 @@ LV2Plugin::LV2Plugin (AudioEngine& e, Session& session, LV2World& world, SLV2Plu
 LV2Plugin::LV2Plugin (const LV2Plugin &other)
        : Plugin (other)
        , _world(other._world)
+       , _features(NULL)
 {
        init (other._world, other._plugin, other._sample_rate);
 
@@ -68,12 +70,13 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
 {
        _world = world;
        _plugin = plugin;
+       _ui = NULL;
        _control_data = 0;
        _shadow_data = 0;
        _latency_control_port = 0;
        _was_activated = false;
-
-       _instance = slv2_plugin_instantiate(plugin, rate, NULL);
+       
+       _instance = slv2_plugin_instantiate(plugin, rate, _features);
        _name = slv2_plugin_get_name(plugin);
        assert(_name);
        _author = slv2_plugin_get_author_name(plugin);
@@ -90,6 +93,18 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
                slv2_value_free(_author);
                throw failed_constructor();
        }
+       
+       _instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
+       _instance_access_feature.data = (void*)_instance->lv2_handle;
+
+       _data_access_extension_data.extension_data = _instance->lv2_descriptor->extension_data;
+       _data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
+       _data_access_feature.data = &_data_access_extension_data;
+       
+       _features = (LV2_Feature**)malloc(sizeof(LV2_Feature*) * 3);
+       _features[0] = &_instance_access_feature;
+       _features[1] = &_data_access_feature;
+       _features[2] = NULL;
 
        _sample_rate = rate;
 
@@ -124,6 +139,17 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
                        _defaults[i] = 0.0f;
                }
        }
+       
+       SLV2UIs uis = slv2_plugin_get_uis(_plugin);
+       if (slv2_uis_size(uis) > 0) {
+               for (unsigned i=0; i < slv2_uis_size(uis); ++i) {
+                       SLV2UI ui = slv2_uis_get_at(uis, i);
+                       if (slv2_ui_is_a(ui, _world.gtk_gui)) {
+                               _ui = ui;
+                               break;
+                       }
+               }
+       }
 
        latency_compute_run ();
 }
@@ -243,6 +269,12 @@ LV2Plugin::save_preset (string name)
 {
        return Plugin::save_preset (name, "lv2");
 }
+       
+bool
+LV2Plugin::has_editor() const
+{
+       return (_ui != NULL);
+}
 
 int
 LV2Plugin::set_state(const XMLNode& node)
@@ -536,6 +568,7 @@ LV2World::LV2World()
        integer = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "integer");
        toggled = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "toggled");
        srate = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "sampleRate");
+       gtk_gui = slv2_value_new_uri(world, "http://lv2plug.in/ns/extensions/ui#GtkUI");
 }
 
 LV2World::~LV2World()
index 9d8ac311b79635c431bb2e0e2c9bba4a1130f423..d0a8a3abbf587bb0a517170e13ec7707a410cfd4 100644 (file)
@@ -60,8 +60,15 @@ RBEffect::~RBEffect ()
 }
 
 int
-RBEffect::run (boost::shared_ptr<AudioRegion> region)
+RBEffect::run (boost::shared_ptr<Region> r)
 {
+       boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (r);
+
+       if (!region) {
+               error << "RBEffect::run() passed a non-audio region! WTF?" << endmsg;
+               return -1;
+       }
+
        SourceList nsrcs;
        nframes_t done;
        int ret = -1;
@@ -158,9 +165,6 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
        stretcher.setExpectedInputDuration(read_duration);
        stretcher.setDebugLevel(1);
 
-       stretcher.setExpectedInputDuration(duration);
-       stretcher.setDebugLevel(1);
-
        /* the name doesn't need to be super-precise, but allow for 2 fractional
           digits just to disambiguate close but not identical FX
        */
@@ -288,8 +292,12 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
                        
                                for (uint32_t i = 0; i < nsrcs.size(); ++i) {
 
-                                       if (nsrcs[i]->write(buffers[i], this_read) !=
-                                           this_read) {
+                                       boost::shared_ptr<AudioSource> asrc = boost::dynamic_pointer_cast<AudioSource>(nsrcs[i]);
+                                       if (!asrc) {
+                                               continue;
+                                       }
+
+                                       if (asrc->write(buffers[i], this_read) != this_read) {
                                                error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg;
                                                goto out;
                                        }
@@ -305,7 +313,12 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
 
                        for (uint32_t i = 0; i < nsrcs.size(); ++i) {
 
-                               if (nsrcs[i]->write(buffers[i], this_read) !=
+                               boost::shared_ptr<AudioSource> asrc = boost::dynamic_pointer_cast<AudioSource>(nsrcs[i]);
+                               if (!asrc) {
+                                       continue;
+                               }
+                               
+                               if (asrc->write(buffers[i], this_read) !=
                                    this_read) {
                                        error << string_compose (_("error writing tempo-adjusted data to %1"), nsrcs[i]->name()) << endmsg;
                                        goto out;
@@ -334,14 +347,13 @@ RBEffect::run (boost::shared_ptr<AudioRegion> region)
 
        /* now reset ancestral data for each new region */
 
-       for (vector<boost::shared_ptr<AudioRegion> >::iterator x = results.begin(); x != results.end(); ++x) {
-
+       for (vector<boost::shared_ptr<Region> >::iterator x = results.begin(); x != results.end(); ++x) {
 
                (*x)->set_ancestral_data (read_start,
                                          read_duration,
                                          stretch,
                                          shift);
-               (*x)->set_master_sources (region->get_master_sources());
+               (*x)->set_master_sources (region->master_sources());
        }
 
   out:
index 6676222b54cf573e4e0f1e34bb9f7309eb6b468b..42564a8b5e9981d26201aa48dcdf42c4ea6b5c5d 100644 (file)
@@ -1406,7 +1406,7 @@ Region::master_source_names ()
 }
 
 void
-Region::set_master_sources (SourceList& srcs)
+Region::set_master_sources (const SourceList& srcs)
 {
        _master_sources = srcs;
 }
index b6efe27d36dad6447e158ccd8a4cac209bbe3f82..ed63fb61327fa915627e7b2383eabbababe77d2b 100644 (file)
@@ -160,8 +160,12 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
                memset (_broadcast_info, 0, sizeof (*_broadcast_info));
                
                snprintf_bounded_null_filled (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
-               snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %s)", Glib::get_real_name().c_str());
-               
+               snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %d.%d.%d %s", 
+                                             libardour3_major_version,
+                                             libardour3_minor_version,
+                                             libardour3_micro_version,
+                                             Glib::get_real_name().c_str());
+
                _broadcast_info->version = 1;  
                _broadcast_info->time_reference_low = 0;  
                _broadcast_info->time_reference_high = 0;  
@@ -551,14 +555,14 @@ SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow
        
        snprintf_bounded_null_filled (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
                                      1900 + now.tm_year,
-                                     now.tm_mon + 1, // move from 0..11 to 1..12
+                                     now.tm_mon + 1, // shift range from 0..11 to 1..12
                                      now.tm_mday);
        
        snprintf_bounded_null_filled (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
                                      now.tm_hour,
                                      now.tm_min,
                                      now.tm_sec);
-
+       
        /* now update header position taking header offset into account */
        
        set_header_timeline_position ();
index 290a449869128382604ad51c550bd79d0f4a06a8..83cc8ff91b40ed2f99b49e190a1e69c43b07721e 100644 (file)
@@ -78,6 +78,7 @@ private:
   XMLNodeList _children;
   XMLPropertyList _proplist;
   XMLPropertyMap _propmap;
+  mutable XMLNodeList _selected_children;
 
 public:
   XMLNode(const string& name);
index ec1ca5d2b9e0ba5c4605106c99a067d4f4592e8c..9643b5d3a831a905600a5f555d3b908b3c7759f0 100644 (file)
@@ -278,22 +278,21 @@ XMLNode::children(const string& n) const
 {
        /* returns all children matching name */
 
-       static XMLNodeList retval;
        XMLNodeConstIterator cur;
        
        if (n.empty()) {
                return _children;
        }
-               
-       retval.erase(retval.begin(), retval.end());
+
+       _selected_children.clear();
        
        for (cur = _children.begin(); cur != _children.end(); ++cur) {
                if ((*cur)->name() == n) {
-                       retval.insert(retval.end(), *cur);
+                       _selected_children.insert(_selected_children.end(), *cur);
                }
        }
                
-       return retval;
+       return _selected_children;
 }
 
 XMLNode *
index 22cb1f4961015b2fc5ef22027676a38582620e9f..2969a9e9419417520f18262a55a70b8cbb9432ef 100644 (file)
@@ -30,6 +30,7 @@ cp.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
 cp.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"")
 cp.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
 cp.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
+cp.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
 
 cp.Merge ([
     libraries['ardour'],
index 833f06923aaa52e44375f93e44815c2871672c82..253718a368e47bb6ef51eaf733b43fc19b1790f6 100644 (file)
@@ -30,6 +30,7 @@ genericmidi.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOUR
 genericmidi.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"")
 genericmidi.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
 genericmidi.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
+genericmidi.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
 
 genericmidi.Merge ([
        libraries['ardour'],
index 45ce63d3cda93da1480800a777470eb1c3ddf23f..655aba67ab53039da720fd4407a06007c52ec17c 100644 (file)
@@ -44,6 +44,7 @@ mackie.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
 mackie.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"")
 mackie.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"")
 mackie.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
+mackie.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
 
 mackie.Merge ([
     libraries['ardour'],
index fddd66c95d2e99f8a7e29e7587e819db64a4f334..9d46fe181703e09cf8c328e70b3f2308c40ad6c7 100644 (file)
@@ -52,6 +52,7 @@ tranzport.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
 #    tranzport.Append(CXXFLAGS="-DHAVE_TRANZPORT_KERNEL_DRIVER=1")
 
 #merge more into tranzport files for the right io lib
+tranzport.Append(CPPPATH = libraries['jack'].get('CPPPATH', []))
 
 tranzport.Merge ([
     libraries['ardour'],
index d0796af092f95950092b016e44e8b0e0d1a4354a..36a0c556398950df2637a9306acc72a4525d3bfe 100644 (file)
@@ -29,6 +29,9 @@ sources = plugin_files
 if vampplugs['AUBIO']:
     sources += aubio_files
     vampplugs.Merge ([libraries['aubio']])
+    vampplugs.Merge ([libraries['fftw3f']])
+else:
+    print 'WARNING: some VAMP plugins will not be built because this machine has no AUBIO support'
 
 libvampplugins = vampplugs.SharedLibrary('ardourvampplugins', sources)
 
index b3717976d04040bd65d5d540b325d8bdb302db6d..2fc8b08be9c7b78d58fb0e1f5a8a00648aa0a27e 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ardour_svn_revision_h__
 #define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "3530";
+static const char* ardour_svn_revision = "3581";
 #endif
index 18f6e6a65ead41a51cf1d417bbe17ab420546fa0..83f07c08ae20ad80952a0d2e7d2f6d9475a6387a 100755 (executable)
@@ -81,7 +81,7 @@ $stdout.print("Copying libs to #{libdir} ...\n");
 results.each do |s|
     s = s.split[0]
     # exclude frameworks, system libraries, X11 libraries, and libjack.
-    unless s =~ /System|\/usr\/lib|\/usr\/X11R6|libjack|:$/ then
+    unless s =~ /System|\/usr\/lib|\/usr\/X11|Jackmp|libjack|:$/ then
        #$stdout.print("Copying #{s}\n")
         `cp #{s} #{odir}/#{libdir}/`
     end
@@ -94,7 +94,7 @@ results.uniq!
 results.each do |s|
     s = s.split[0]
     # exclude frameworks, system libraries, X11 libraries, and libjack.
-    unless s =~ /System|\/usr\/lib|\/usr\/X11R6|libjack|:$/ then
+    unless s =~ /System|\/usr\/lib|\/usr\/X11|Jackmp|libjack|:$/ then
       sbase = File.basename(s)
       targfile = "#{odir}/#{libdir}/#{sbase}"
       #$stdout.print("Targ is : " + targfile + "\n")