From 5f13eb411ee69b4a810de4a7258c39384e5e1d4f Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 19 Jan 2011 18:35:11 +0000 Subject: Patch from Lincoln to fix rhythm ferret in various ways (#3715). git-svn-id: svn://localhost/ardour2/branches/3.0@8542 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/editor.cc | 107 ++++++++++++++++++++++++++++++++++++++++--- gtk2_ardour/editor.h | 5 +- gtk2_ardour/editor_ops.cc | 48 +++++++++++++------ gtk2_ardour/public_editor.h | 2 +- gtk2_ardour/rhythm_ferret.cc | 19 +++++--- gtk2_ardour/rhythm_ferret.h | 2 +- 6 files changed, 152 insertions(+), 31 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index ba8a5e93e8..0590b3a81d 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -420,30 +420,35 @@ Editor::Editor () tempo_label.set_padding (5,0); tempo_label.hide(); tempo_label.set_no_show_all(); + meter_label.set_name ("EditorTimeButton"); meter_label.set_size_request (-1, (int)timebar_height); meter_label.set_alignment (1.0, 0.5); meter_label.set_padding (5,0); meter_label.hide(); meter_label.set_no_show_all(); + mark_label.set_name ("EditorTimeButton"); mark_label.set_size_request (-1, (int)timebar_height); mark_label.set_alignment (1.0, 0.5); mark_label.set_padding (5,0); mark_label.hide(); mark_label.set_no_show_all(); + cd_mark_label.set_name ("EditorTimeButton"); cd_mark_label.set_size_request (-1, (int)timebar_height); cd_mark_label.set_alignment (1.0, 0.5); cd_mark_label.set_padding (5,0); cd_mark_label.hide(); cd_mark_label.set_no_show_all(); + range_mark_label.set_name ("EditorTimeButton"); range_mark_label.set_size_request (-1, (int)timebar_height); range_mark_label.set_alignment (1.0, 0.5); range_mark_label.set_padding (5,0); range_mark_label.hide(); range_mark_label.set_no_show_all(); + transport_mark_label.set_name ("EditorTimeButton"); transport_mark_label.set_size_request (-1, (int)timebar_height); transport_mark_label.set_alignment (1.0, 0.5); @@ -453,11 +458,14 @@ Editor::Editor () initialize_rulers (); initialize_canvas (); + _summary = new EditorSummary (this); selection->TimeChanged.connect (sigc::mem_fun(*this, &Editor::time_selection_changed)); selection->TracksChanged.connect (sigc::mem_fun(*this, &Editor::track_selection_changed)); + editor_regions_selection_changed_connection = selection->RegionsChanged.connect (sigc::mem_fun(*this, &Editor::region_selection_changed)); + selection->PointsChanged.connect (sigc::mem_fun(*this, &Editor::point_selection_changed)); selection->MarkersChanged.connect (sigc::mem_fun(*this, &Editor::marker_selection_changed)); @@ -484,8 +492,10 @@ Editor::Editor () ArdourCanvas::Canvas* time_pad = manage(new ArdourCanvas::Canvas()); ArdourCanvas::SimpleLine* pad_line_1 = manage(new ArdourCanvas::SimpleLine(*time_pad->root(), 0.0, 1.0, 100.0, 1.0)); + pad_line_1->property_color_rgba() = 0xFF0000FF; pad_line_1->show(); + time_pad->show(); time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 2); @@ -558,10 +568,12 @@ Editor::Editor () summary_arrows_left_left->add (*manage (new Arrow (ARROW_LEFT, SHADOW_NONE))); summary_arrows_left_left->signal_pressed().connect (sigc::hide_return (sigc::mem_fun (*this, &Editor::horizontal_scroll_left_press))); summary_arrows_left_left->signal_released().connect (sigc::mem_fun (*this, &Editor::horizontal_scroll_left_release)); + Button* summary_arrows_left_right = manage (new Button); summary_arrows_left_right->add (*manage (new Arrow (ARROW_RIGHT, SHADOW_NONE))); summary_arrows_left_right->signal_pressed().connect (sigc::hide_return (sigc::mem_fun (*this, &Editor::horizontal_scroll_right_press))); summary_arrows_left_right->signal_released().connect (sigc::mem_fun (*this, &Editor::horizontal_scroll_right_release)); + VBox* summary_arrows_left = manage (new VBox); summary_arrows_left->pack_start (*summary_arrows_left_left); summary_arrows_left->pack_start (*summary_arrows_left_right); @@ -570,16 +582,19 @@ Editor::Editor () summary_arrows_right_left->add (*manage (new Arrow (ARROW_LEFT, SHADOW_NONE))); summary_arrows_right_left->signal_pressed().connect (sigc::hide_return (sigc::mem_fun (*this, &Editor::horizontal_scroll_left_press))); summary_arrows_right_left->signal_released().connect (sigc::mem_fun (*this, &Editor::horizontal_scroll_left_release)); + Button* summary_arrows_right_right = manage (new Button); summary_arrows_right_right->add (*manage (new Arrow (ARROW_RIGHT, SHADOW_NONE))); summary_arrows_right_right->signal_pressed().connect (sigc::hide_return (sigc::mem_fun (*this, &Editor::horizontal_scroll_right_press))); summary_arrows_right_right->signal_released().connect (sigc::mem_fun (*this, &Editor::horizontal_scroll_right_release)); + VBox* summary_arrows_right = manage (new VBox); summary_arrows_right->pack_start (*summary_arrows_right_left); summary_arrows_right->pack_start (*summary_arrows_right_right); Frame* summary_frame = manage (new Frame); summary_frame->set_shadow_type (Gtk::SHADOW_ETCHED_IN); + summary_frame->add (*_summary); summary_frame->show (); @@ -1105,9 +1120,11 @@ Editor::set_session (Session *t) Location* loc = _session->locations()->auto_loop_location(); if (loc == 0) { loc = new Location (*_session, 0, _session->current_end_frame(), _("Loop"),(Location::Flags) (Location::IsAutoLoop | Location::IsHidden)); + if (loc->start() == loc->end()) { loc->set_end (loc->start() + 1); } + _session->locations()->add (loc, false); _session->set_auto_loop_location (loc); } else { @@ -1116,11 +1133,14 @@ Editor::set_session (Session *t) } loc = _session->locations()->auto_punch_location(); + if (loc == 0) { loc = new Location (*_session, 0, _session->current_end_frame(), _("Punch"), (Location::Flags) (Location::IsAutoPunch | Location::IsHidden)); + if (loc->start() == loc->end()) { loc->set_end (loc->start() + 1); } + _session->locations()->add (loc, false); _session->set_auto_punch_location (loc); } else { @@ -2127,7 +2147,7 @@ Editor::set_state (const XMLNode& node, int /*version*/) set_mouse_mode (MouseObject, true); } - if ((prop = node.property ("left-frame")) != 0){ + if ((prop = node.property ("left-frame")) != 0) { framepos_t pos; if (sscanf (prop->value().c_str(), "%" PRId64, &pos) == 1) { reset_x_origin (pos); @@ -4479,7 +4499,9 @@ Editor::get_regions_at (RegionSelection& rs, framepos_t where, const TrackViewLi } for (TrackViewList::const_iterator t = tracks->begin(); t != tracks->end(); ++t) { + RouteTimeAxisView* rtv = dynamic_cast(*t); + if (rtv) { boost::shared_ptr tr; boost::shared_ptr pl; @@ -4487,7 +4509,7 @@ Editor::get_regions_at (RegionSelection& rs, framepos_t where, const TrackViewLi if ((tr = rtv->track()) && ((pl = tr->playlist()))) { Playlist::RegionList* regions = pl->regions_at ( - (framepos_t) floor ( (double)where * tr->speed())); + (framepos_t) floor ( (double) where * tr->speed())); for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) { RegionView* rv = rtv->view()->find_view (*i); @@ -4539,6 +4561,17 @@ Editor::get_regions_after (RegionSelection& rs, framepos_t where, const TrackVie } } +/** Start with regions that are selected. Then add equivalent regions + * on tracks in the same active edit-enabled route group as any of + * the regions that we started with. + */ + +RegionSelection +Editor::get_regions_from_selection () +{ + return add_route_group_regions_to_selection (selection->regions); +} + /** Get regions using the following method: * * Make an initial region list using the selected regions, unless @@ -4588,10 +4621,10 @@ Editor::get_regions_from_selection_and_edit_point () for (RegionSelection::iterator i = regions.begin (); i != regions.end(); ++i) { RouteGroup* g = (*i)->get_time_axis_view().route_group (); + if (g && g->is_active() && g->is_edit()) { tracks.add (axis_views_from_routes (g->route_list())); } - } if (!tracks.empty()) { @@ -4603,17 +4636,77 @@ Editor::get_regions_from_selection_and_edit_point () return regions; } +/** Start with regions that are selected, or the entered regionview if none are selected. + * Then add equivalent regions on tracks in the same active edit-enabled route group as any + * of the regions that we started with. + */ RegionSelection Editor::get_regions_from_selection_and_entered () { - RegionSelection rs = selection->regions; + RegionSelection regions = selection->regions; - if (rs.empty() && entered_regionview) { - rs.add (entered_regionview); + if (regions.empty() && entered_regionview) { + regions.add (entered_regionview); } - return rs; + regions = add_route_group_regions_to_selection (regions); + + return regions; +} + +RegionSelection +Editor::add_route_group_regions_to_selection (RegionSelection regions) +{ + TrackViewList tracks; + + vector > equivalent_regions; + RegionSelection edit_group_regions; + + /* Add any other tracks that have regions that are in the same + edit-activated route group as one of our regions. + */ + for (RegionSelection::iterator i = regions.begin (); i != regions.end(); ++i) { + + RouteGroup* g = (*i)->get_time_axis_view().route_group (); + + if (g && g->is_active() && g->is_edit()) { + /* get tracks in the group */ + tracks.add (axis_views_from_routes (g->route_list())); + } + + /* iterate over the track list and get the equivalent regions for the current region */ + for (TrackViewList::iterator tr = tracks.begin (); tr != tracks.end(); ++tr) { + + if ( (*tr) == &(*i)->get_time_axis_view()) { + /* looking in same track as the original */ + continue; + } + + boost::shared_ptr pl; + + if ((pl = (*tr)->playlist()) != 0) { + pl->get_equivalent_regions ((*i)->region(), equivalent_regions); + } + + /* convert the regions to region views */ + for (vector >::iterator r = equivalent_regions.begin(); r != equivalent_regions.end(); ++r) { + + RegionView* rv; + + if ((rv = (*tr)->view()->find_view (*r)) != 0) { + edit_group_regions.add (rv); + } + } + } + + equivalent_regions.clear(); + tracks.clear(); + } + + regions.merge(edit_group_regions); + + return regions; } void diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index e500060b41..8adc647d76 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1070,7 +1070,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void lower_region_to_bottom (); void split_regions_at (framepos_t, RegionSelection&); void split_region_at_transients (); - void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret); + void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false); void crop_region_to_selection (); void crop_region_to (framepos_t start, framepos_t end); void set_sync_point (framepos_t, const RegionSelection&); @@ -1975,8 +1975,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void get_regions_at (RegionSelection&, framepos_t where, const TrackViewList& ts) const; void get_regions_after (RegionSelection&, framepos_t where, const TrackViewList& ts) const; + RegionSelection get_regions_from_selection (); RegionSelection get_regions_from_selection_and_edit_point (); RegionSelection get_regions_from_selection_and_entered (); + RegionSelection add_route_group_regions_to_selection (RegionSelection regions); void start_updating_meters (); void stop_updating_meters (); @@ -2020,6 +2022,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD Gtk::HBox _summary_hbox; EditorSummary* _summary; + void region_view_added (RegionView *); void update_canvas_now (); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 6eb837e5e4..bc7c625a80 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -863,7 +863,7 @@ Editor::cursor_to_region_point (EditorCursor* cursor, RegionPoint point, int32_t return; } - switch (point){ + switch (point) { case Start: pos = r->first_frame (); break; @@ -1054,7 +1054,7 @@ Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir) return; } - switch (point){ + switch (point) { case Start: pos = r->first_frame (); break; @@ -2863,7 +2863,9 @@ Editor::separate_under_selected_regions () { vector playlists; - RegionSelection rs = get_regions_from_selection_and_entered (); + RegionSelection rs; + + rs = get_regions_from_selection_and_entered(); if (!_session || rs.empty()) { return; @@ -3486,11 +3488,11 @@ Editor::trim_to_region(bool forward) region->clear_changes (); - if(forward){ + if (forward) { next_region = playlist->find_next_region (region->first_frame(), Start, 1); - if(!next_region){ + if (!next_region) { continue; } @@ -5739,11 +5741,13 @@ Editor::split_region_at_transients () } void -Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList& positions, bool can_ferret) +Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList& positions, bool can_ferret, bool select_new) { bool use_rhythmic_rodent = false; - + boost::shared_ptr pl = r->playlist(); + + list > new_regions; if (!pl) { return; @@ -5754,7 +5758,7 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList } - if (positions.size() > 20) { + if (positions.size() > 20 && can_ferret) { std::string msgstr = string_compose (_("You are about to split\n%1\ninto %2 pieces.\nThis could take a long time."), r->name(), positions.size() + 1); MessageDialog msg (msgstr, false, @@ -5808,7 +5812,7 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList while (x != positions.end()) { /* deal with positons that are out of scope of present region bounds */ - if (*x <= 0 || *x > r->length()){ + if (*x <= 0 || *x > r->length()) { ++x; continue; } @@ -5848,6 +5852,10 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList boost::shared_ptr nr = RegionFactory::create (r->sources(), plist, false); pl->add_region (nr, r->position() + pos); + + if (select_new) { + new_regions.push_front(nr); + } pos += len; ++x; @@ -5867,11 +5875,21 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList boost::shared_ptr nr = RegionFactory::create (r->sources(), plist, false); pl->add_region (nr, r->position() + pos); - + if (select_new) { + new_regions.push_front(nr); + } + pl->thaw (); _session->add_command (new StatefulDiffCommand (pl)); + + if (select_new) { + + for (list >::iterator i = new_regions.begin(); i != new_regions.end(); ++i){ + set_selected_regionview_from_region_list ((*i), Selection::Add); + } + } } void @@ -5954,7 +5972,7 @@ Editor::close_region_gaps () SpinButton spin_crossfade (1, 0); spin_crossfade.set_range (0, 15); spin_crossfade.set_increments (1, 1); - spin_crossfade.set_value (3); + spin_crossfade.set_value (5); table.attach (spin_crossfade, 1, 2, 0, 1); table.attach (*manage (new Label (_("ms"))), 2, 3, 0, 1); @@ -5964,9 +5982,9 @@ Editor::close_region_gaps () table.attach (*l, 0, 1, 1, 2); SpinButton spin_pullback (1, 0); - spin_pullback.set_range (0, 15); + spin_pullback.set_range (0, 100); spin_pullback.set_increments (1, 1); - spin_pullback.set_value (5); + spin_pullback.set_value(30); table.attach (spin_pullback, 1, 2, 1, 2); table.attach (*manage (new Label (_("ms"))), 2, 3, 1, 2); @@ -6201,9 +6219,9 @@ edit your ardour.rc file to set the\n\ msg.run (); return; } - + if (ntracks + nbusses == 0) { - return; + return; } if (ntracks > 1) { diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 5d054fe174..954dbcf16f 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -268,7 +268,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible { virtual void restore_editing_space () = 0; virtual framepos_t get_preferred_edit_position (bool ignore_playhead = false) = 0; virtual void toggle_meter_updating() = 0; - virtual void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret) = 0; + virtual void split_region_at_points (boost::shared_ptr, ARDOUR::AnalysisFeatureList&, bool can_ferret, bool select_new = false) = 0; virtual void mouse_add_new_marker (framepos_t where, bool is_cd=false, bool is_xrun=false) = 0; virtual void foreach_time_axis_view (sigc::slot) = 0; virtual void add_to_idle_resize (TimeAxisView*, int32_t) = 0; diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc index 5685cb56af..0eb9e96406 100644 --- a/gtk2_ardour/rhythm_ferret.cc +++ b/gtk2_ardour/rhythm_ferret.cc @@ -48,8 +48,8 @@ static const gchar * _onset_function_strings[] = { static const gchar * _operation_strings[] = { N_("Split region"), - N_("Set tempo map"), - N_("Conform region"), + N_("Snap regions"), + N_("Conform regions"), 0 }; @@ -168,7 +168,7 @@ RhythmFerret::Action RhythmFerret::get_action () const { if (operation_selector.get_active_row_number() == 1) { - return DefineTempoMap; + return SnapRegionsToGrid; } else if (operation_selector.get_active_row_number() == 2) { return ConformRegion; } @@ -321,6 +321,9 @@ RhythmFerret::do_action () case SplitRegion: do_split_action (); break; + case SnapRegionsToGrid: + editor.snap_regions_to_grid(); + break; case ConformRegion: editor.close_region_gaps(); break; @@ -332,7 +335,11 @@ RhythmFerret::do_action () void RhythmFerret::do_split_action () { - RegionSelection& regions (editor.get_selection().regions); + /* XXX: this is quite a special-case; (currently) the only operation which is + performed on the selection only (without entered_regionview or the edit point + being considered) + */ + RegionSelection regions = editor.get_regions_from_selection(); if (regions.empty()) { return; @@ -348,7 +355,7 @@ RhythmFerret::do_split_action () AnalysisFeatureList features; features = (*i)->region()->transients(); - merged_features.insert (merged_features.end(), features.begin(), features.end()); + merged_features.insert (merged_features.end(), features.begin(), features.end()); } merged_features.sort(); @@ -363,7 +370,7 @@ RhythmFerret::do_split_action () AnalysisFeatureList features; features = (*i)->region()->transients(); - editor.split_region_at_points ((*i)->region(), merged_features, false); + editor.split_region_at_points ((*i)->region(), merged_features, false, true); /* i is invalid at this point */ diff --git a/gtk2_ardour/rhythm_ferret.h b/gtk2_ardour/rhythm_ferret.h index a1a201531b..8132ad27b5 100644 --- a/gtk2_ardour/rhythm_ferret.h +++ b/gtk2_ardour/rhythm_ferret.h @@ -33,7 +33,7 @@ class RhythmFerret : public ArdourDialog { enum Action { SplitRegion, - DefineTempoMap, + SnapRegionsToGrid, ConformRegion }; -- cgit v1.2.3