more fiddling about with placing bits of the scroll/zoom operation in the idle callba...
[ardour.git] / gtk2_ardour / editor.cc
index 74822fc7ea79d2923cf8c772fbe11a1ad5854e88..6b8fc782dc79be8e526eb4a0445e64baee5bd8f1 100644 (file)
@@ -246,7 +246,6 @@ Editor::Editor (AudioEngine& eng)
        latest_regionview = 0;
        last_update_frame = 0;
        drag_info.item = 0;
-       last_audition_region = 0;
        current_mixer_strip = 0;
        current_bbt_points = 0;
 
@@ -272,7 +271,6 @@ Editor::Editor (AudioEngine& eng)
        first_action_message = 0;
        export_dialog = 0;
        show_gain_after_trim = false;
-       no_zoom_repos_update = false;
        ignore_route_list_reorder = false;
        no_route_list_redisplay = false;
        verbose_cursor_on = true;
@@ -285,7 +283,6 @@ Editor::Editor (AudioEngine& eng)
        _xfade_visibility = true;
        editor_ruler_menu = 0;
        no_ruler_shown_update = false;
-       edit_hscroll_dragging = false;
        edit_group_list_menu = 0;
        route_list_menu = 0;
        region_list_menu = 0;
@@ -646,7 +643,7 @@ Editor::Editor (AudioEngine& eng)
        edit_pane.pack1 (edit_packer, true, true);
        edit_pane.pack2 (the_notebook, false, true);
        
-       edit_pane.signal_size_allocate().connect_notify (bind (mem_fun(*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&edit_pane)));
+       edit_pane.signal_size_allocate().connect (bind (mem_fun(*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&edit_pane)));
 
        top_hbox.pack_start (toolbar_frame, true, true);
 
@@ -833,16 +830,6 @@ Editor::set_frames_per_unit (double fpu)
                zoom_range_clock.set (frames);
        }
 
-       /* only update these if we not about to call reposition_x_origin,
-          which will do the same updates.
-       */
-       
-       if (!no_zoom_repos_update) {
-               horizontal_adjustment.set_value (leftmost_frame/frames_per_unit);
-               update_fixed_rulers ();
-               tempo_map_changed (Change (0));
-       }
-
        if (mouse_mode == MouseRange && selection->time.start () != selection->time.end_frame ()) {
                if (!selection->tracks.empty()) {
                        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
@@ -895,6 +882,9 @@ Editor::reposition_x_origin (jack_nframes_t frame)
                }
 
                horizontal_adjustment.set_value (frame/frames_per_unit);
+       } else {
+               update_fixed_rulers();
+               tempo_map_changed (Change (0));
        }
 }
 
@@ -910,7 +900,7 @@ Editor::edit_cursor_clock_changed()
 void
 Editor::zoom_adjustment_changed ()
 {
-       if (session == 0 || no_zoom_repos_update) {
+       if (session == 0) {
                return;
        }
 
@@ -977,40 +967,28 @@ Editor::deferred_control_scroll (jack_nframes_t target)
 void 
 Editor::canvas_horizontally_scrolled ()
 {
-       leftmost_frame = (jack_nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
 
+       leftmost_frame = (jack_nframes_t) floor (horizontal_adjustment.get_value() * frames_per_unit);
        update_fixed_rulers ();
-       
-       if (!edit_hscroll_dragging) {
-               tempo_map_changed (Change (0));
-       } else {
-               update_tempo_based_rulers();
-       }
+       tempo_map_changed (Change (0));
+
 }
 
 void
 Editor::reposition_and_zoom (jack_nframes_t frame, double nfpu)
 {
        if (!repos_zoom_queued) {
-               Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::deferred_reposition_and_zoom), frame, nfpu));
                repos_zoom_queued = true;
+               Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::deferred_reposition_and_zoom), frame, nfpu));
        }
 }
 
 gint
 Editor::deferred_reposition_and_zoom (jack_nframes_t frame, double nfpu)
 {
-       /* if we need to force an update to the hscroller stuff,
-          don't set no_zoom_repos_update.
-       */
 
-       no_zoom_repos_update = (frame != leftmost_frame);
-       
        set_frames_per_unit (nfpu);
-       if (no_zoom_repos_update) {
-               reposition_x_origin  (frame);
-       }
-       no_zoom_repos_update = false;
+       reposition_x_origin  (frame);
        repos_zoom_queued = false;
        
        return FALSE;
@@ -1063,7 +1041,6 @@ void
 Editor::stop_scrolling ()
 {
        scroll_connection.disconnect ();
-       slower_update_connection.disconnect ();
 }
 
 void
@@ -1169,7 +1146,7 @@ Editor::connect_to_session (Session *t)
 
        update_title ();
 
-       session->going_away.connect (mem_fun(*this, &Editor::session_going_away));
+       session->GoingAway.connect (mem_fun(*this, &Editor::session_going_away));
 
        /* These signals can all be emitted by a non-GUI thread. Therefore the
           handlers for them must not attempt to directly interact with the GUI,
@@ -1307,7 +1284,8 @@ Editor::connect_to_session (Session *t)
        horizontal_adjustment.set_value (0);
 
        restore_ruler_visibility ();
-       tempo_map_changed (Change (0));
+       //tempo_map_changed (Change (0));
+       session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks);
 
        edit_cursor->set_position (0);
        playhead_cursor->set_position (0);
@@ -1342,6 +1320,7 @@ Editor::connect_to_session (Session *t)
        }
 
         /* register for undo history */
+
         session->register_with_memento_command_factory(_id, this);
 }
 
@@ -1399,13 +1378,14 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
        }
 
        MenuList& items (fade_context_menu.items());
+       AudioRegion& ar (*arv->audio_region().get()); // FIXME
 
        items.clear ();
 
        switch (item_type) {
        case FadeInItem:
        case FadeInHandleItem:
-               if (arv->audio_region().fade_in_active()) {
+               if (arv->audio_region()->fade_in_active()) {
                        items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), false)));
                } else {
                        items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), true)));
@@ -1413,16 +1393,16 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
                
                items.push_back (SeparatorElem());
                
-               items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
-               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
-               items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
-               items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
-               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
+               items.push_back (MenuElem (_("Linear"), bind (mem_fun (ar, &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
+               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (ar, &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
+               items.push_back (MenuElem (_("Slow"), bind (mem_fun (ar, &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
+               items.push_back (MenuElem (_("Fast"), bind (mem_fun (ar, &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
+               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (ar, &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
                break;
 
        case FadeOutItem:
        case FadeOutHandleItem:
-               if (arv->audio_region().fade_out_active()) {
+               if (arv->audio_region()->fade_out_active()) {
                        items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), false)));
                } else {
                        items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), true)));
@@ -1430,11 +1410,11 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
                
                items.push_back (SeparatorElem());
                
-               items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
-               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
-               items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
-               items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
-               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
+               items.push_back (MenuElem (_("Linear"), bind (mem_fun (ar, &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
+               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (ar, &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
+               items.push_back (MenuElem (_("Slow"), bind (mem_fun (ar, &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
+               items.push_back (MenuElem (_("Fast"), bind (mem_fun (ar, &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
+               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (ar, &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
 
                break;
        default:
@@ -1501,7 +1481,7 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
        case RegionViewNameHighlight:
                if (!with_selection) {
                        if (region_edit_menu_split_item) {
-                               if (clicked_regionview && clicked_regionview->region().covers (edit_cursor->current_frame)) {
+                               if (clicked_regionview && clicked_regionview->region()->covers (edit_cursor->current_frame)) {
                                        ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true);
                                } else {
                                        ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false);
@@ -1596,7 +1576,7 @@ Editor::build_track_region_context_menu (jack_nframes_t frame)
        AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
 
        if (atv) {
-               Diskstream* ds;
+               boost::shared_ptr<Diskstream> ds;
                Playlist* pl;
                
                if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
@@ -1623,7 +1603,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
        AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
 
        if (atv) {
-               Diskstream* ds;
+               boost::shared_ptr<Diskstream> ds;
                Playlist* pl;
                AudioPlaylist* apl;
 
@@ -1736,9 +1716,9 @@ Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Me
        }
 
        if (many) {
-               str = xfade->out().name();
+               str = xfade->out()->name();
                str += "->";
-               str += xfade->in().name();
+               str += xfade->in()->name();
        } else {
                str = _("Crossfade");
        }
@@ -1764,17 +1744,17 @@ Editor::xfade_edit_right_region ()
 }
 
 void
-Editor::add_region_context_items (AudioStreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items)
+Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region> region, Menu_Helpers::MenuList& edit_items)
 {
        using namespace Menu_Helpers;
        Menu     *region_menu = manage (new Menu);
        MenuList& items       = region_menu->items();
        region_menu->set_name ("ArdourContextMenu");
        
-       AudioRegion* ar = 0;
+       boost::shared_ptr<AudioRegion> ar;
 
        if (region) {
-               ar = dynamic_cast<AudioRegion*> (region);
+               ar = boost::dynamic_pointer_cast<AudioRegion> (region);
        }
 
        /* when this particular menu pops up, make the relevant region 
@@ -2123,6 +2103,9 @@ Editor::set_state (const XMLNode& node)
        int x, y, xoff, yoff;
        Gdk::Geometry g;
 
+       if ((prop = node.property ("id")) != 0) {
+               _id = prop->value ();
+       }
 
        if ((geometry = find_named_node (node, "geometry")) == 0) {
 
@@ -2244,6 +2227,7 @@ Editor::set_state (const XMLNode& node)
                }
        }
 
+
        return 0;
 }
 
@@ -2253,6 +2237,9 @@ Editor::get_state ()
        XMLNode* node = new XMLNode ("Editor");
        char buf[32];
 
+       _id.print (buf);
+       node->add_property ("id", buf);
+       
        if (is_realized()) {
                Glib::RefPtr<Gdk::Window> win = get_window();
                
@@ -2262,7 +2249,7 @@ Editor::get_state ()
                win->get_size(width, height);
                
                XMLNode* geometry = new XMLNode ("geometry");
-               char buf[32];
+
                snprintf(buf, sizeof(buf), "%d", width);
                geometry->add_property("x_size", string(buf));
                snprintf(buf, sizeof(buf), "%d", height);
@@ -3015,12 +3002,12 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
 
 void
 Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored, 
-                                                 RegionView* basis, vector<RegionView*>* all_equivs)
+                                                  RegionView* basis, vector<RegionView*>* all_equivs)
 {
        Playlist* pl;
-       vector<Region*> results;
+       vector<boost::shared_ptr<Region> > results;
        RegionView* marv;
-       Diskstream* ds;
+       boost::shared_ptr<Diskstream> ds;
 
        if ((ds = tv.get_diskstream()) == 0) {
                /* bus */
@@ -3037,8 +3024,8 @@ Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32
                pl->get_equivalent_regions (basis->region(), results);
        }
        
-       for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
-               if ((marv = tv.view()->find_view (**ir)) != 0) {
+       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+               if ((marv = tv.view()->find_view (*ir)) != 0) {
                        all_equivs->push_back (marv);
                }
        }
@@ -3138,55 +3125,55 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
                for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
                        if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
 
-                               if ((*x)->region().last_frame() > last_frame) {
-                                       last_frame = (*x)->region().last_frame();
+                               if ((*x)->region()->last_frame() > last_frame) {
+                                       last_frame = (*x)->region()->last_frame();
                                }
 
-                               if ((*x)->region().first_frame() < first_frame) {
-                                       first_frame = (*x)->region().first_frame();
+                               if ((*x)->region()->first_frame() < first_frame) {
+                                       first_frame = (*x)->region()->first_frame();
                                }
                        }
                }
 
                /* 2. figure out the boundaries for our search for new objects */
 
-               switch (clicked_regionview->region().coverage (first_frame, last_frame)) {
+               switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
                case OverlapNone:
                        cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = " 
-                            << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
+                            << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
 
-                       if (last_frame < clicked_regionview->region().first_frame()) {
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
                                first_frame = last_frame;
-                               last_frame = clicked_regionview->region().last_frame();
+                               last_frame = clicked_regionview->region()->last_frame();
                        } else {
                                last_frame = first_frame;
-                               first_frame = clicked_regionview->region().first_frame();
+                               first_frame = clicked_regionview->region()->first_frame();
                        }
                        break;
 
                case OverlapExternal:
                        cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = " 
-                            << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
+                            << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
 
-                       if (last_frame < clicked_regionview->region().first_frame()) {
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
                                first_frame = last_frame;
-                               last_frame = clicked_regionview->region().last_frame();
+                               last_frame = clicked_regionview->region()->last_frame();
                        } else {
                                last_frame = first_frame;
-                               first_frame = clicked_regionview->region().first_frame();
+                               first_frame = clicked_regionview->region()->first_frame();
                        }
                        break;
 
                case OverlapInternal:
                        cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = " 
-                            << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
+                            << clicked_regionview->region()->first_frame() << " .. " << clicked_regionview->region()->last_frame() << endl;
 
-                       if (last_frame < clicked_regionview->region().first_frame()) {
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
                                first_frame = last_frame;
-                               last_frame = clicked_regionview->region().last_frame();
+                               last_frame = clicked_regionview->region()->last_frame();
                        } else {
                                last_frame = first_frame;
-                               first_frame = clicked_regionview->region().first_frame();
+                               first_frame = clicked_regionview->region()->first_frame();
                        }
                        break;
 
@@ -3233,7 +3220,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
 }
 
 void
-Editor::set_selected_regionview_from_region_list (Region& region, Selection::Operation op)
+Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> region, Selection::Operation op)
 {
        vector<RegionView*> all_equivalent_regions;
 
@@ -3244,9 +3231,9 @@ Editor::set_selected_regionview_from_region_list (Region& region, Selection::Ope
                if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
                        
                        Playlist* pl;
-                       vector<Region*> results;
+                       vector<boost::shared_ptr<Region> > results;
                        RegionView* marv;
-                       Diskstream* ds;
+                       boost::shared_ptr<Diskstream> ds;
                        
                        if ((ds = tatv->get_diskstream()) == 0) {
                                /* bus */
@@ -3257,8 +3244,8 @@ Editor::set_selected_regionview_from_region_list (Region& region, Selection::Ope
                                pl->get_region_list_equivalent_regions (region, results);
                        }
                        
-                       for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
-                               if ((marv = tatv->view()->find_view (**ir)) != 0) {
+                       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+                               if ((marv = tatv->view()->find_view (*ir)) != 0) {
                                        all_equivalent_regions.push_back (marv);
                                }
                        }
@@ -3285,17 +3272,17 @@ Editor::set_selected_regionview_from_region_list (Region& region, Selection::Ope
 }
 
 bool
-Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, Region* r)
+Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, boost::shared_ptr<Region> r)
 {
        RegionView* rv;
-       Region* ar;
+       boost::shared_ptr<AudioRegion> ar;
 
-       if ((ar = dynamic_cast<Region*> (r)) == 0) {
-               return TRUE;
+       if ((ar = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
+               return true;
        }
 
-       if ((rv = sv->find_view (*ar)) == 0) {
-               return TRUE;
+       if ((rv = sv->find_view (ar)) == 0) {
+               return true;
        }
 
        /* don't reset the selection if its something other than 
@@ -3303,7 +3290,7 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv,
        */
 
        if (selection->regions.size() > 1) {
-               return TRUE;
+               return true;
        }
        
        begin_reversible_command (_("set selected regions"));
@@ -3312,7 +3299,7 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv,
 
        commit_reversible_command () ;
 
-       return TRUE;
+       return true;
 }
 
 void
@@ -3754,10 +3741,12 @@ Editor::get_valid_views (TimeAxisView* track, RouteGroup* group)
 void
 Editor::set_zoom_focus (ZoomFocus f)
 {
+       vector<string> txt = internationalize (zoom_focus_strings);
+       zoom_focus_selector.set_active_text (txt[(int)f]);
+       
        if (zoom_focus != f) {
                zoom_focus = f;
-               vector<string> txt = internationalize (zoom_focus_strings);
-               zoom_focus_selector.set_active_text (txt[(int)f]);
+
                ZoomFocusChanged (); /* EMIT_SIGNAL */
 
                instant_save ();
@@ -3960,7 +3949,7 @@ bool
 Editor::audio_region_selection_covers (jack_nframes_t where)
 {
        for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
-               if ((*a)->region().covers (where)) {
+               if ((*a)->region()->covers (where)) {
                        return true;
                }
        }