X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_ops.cc;h=6a21dd84322f5454ca5987d2b737d9ca7fee8e2e;hb=52275254a7adb9a446c104cc7dcfde82d1792786;hp=f7bbf2a16666d68d05b06d67d4fee6196156ad79;hpb=e8427ee2cb31e91fce54461056c6a430bb74add1;p=ardour.git diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index f7bbf2a166..6a21dd8432 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -82,6 +82,7 @@ #include "item_counts.h" #include "keyboard.h" #include "midi_region_view.h" +#include "mixer_ui.h" #include "mixer_strip.h" #include "mouse_cursors.h" #include "normalize_dialog.h" @@ -165,7 +166,8 @@ Editor::redo (uint32_t n) } void -Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int32_t sub_num) +Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int32_t sub_num, + bool snap_frame) { bool frozen = false; @@ -191,10 +193,14 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3 case SnapToRegionEnd: break; default: - snap_to (where); + if (snap_frame) { + snap_to (where); + } } } else { - snap_to (where); + if (snap_frame) { + snap_to (where); + } frozen = true; EditorFreeze(); /* Emit Signal */ @@ -272,7 +278,6 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3 if (working_on_selection) { // IFF we were working on selected regions, try to reinstate the other region selections that existed before the freeze/thaw. - _ignore_follow_edits = true; // a split will change the region selection in mysterious ways; it's not practical or wanted to follow this edit RegionSelectionAfterSplit rsas = Config->get_region_selection_after_split(); /* There are three classes of regions that we might want selected after splitting selected regions: @@ -299,13 +304,10 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3 } } } - _ignore_follow_edits = false; } else { - _ignore_follow_edits = true; if( working_on_selection ) { selection->add (latest_regionviews); //these are the new regions created after the split } - _ignore_follow_edits = false; } commit_reversible_command (); @@ -418,6 +420,7 @@ Editor::nudge_forward (bool next, bool force_playhead) bool is_start; bool in_command = false; + const int32_t divisions = get_grid_music_divisions (0); for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) { @@ -433,9 +436,9 @@ Editor::nudge_forward (bool next, bool force_playhead) distance = next_distance; } if (max_framepos - distance > loc->start() + loc->length()) { - loc->set_start (loc->start() + distance); + loc->set_start (loc->start() + distance, false, true, divisions); } else { - loc->set_start (max_framepos - loc->length()); + loc->set_start (max_framepos - loc->length(), false, true, divisions); } } else { distance = get_nudge_distance (loc->end(), next_distance); @@ -443,9 +446,9 @@ Editor::nudge_forward (bool next, bool force_playhead) distance = next_distance; } if (max_framepos - distance > loc->end()) { - loc->set_end (loc->end() + distance); + loc->set_end (loc->end() + distance, false, true, divisions); } else { - loc->set_end (max_framepos); + loc->set_end (max_framepos, false, true, divisions); } if (loc->is_session_range()) { _session->set_end_is_free (false); @@ -525,9 +528,9 @@ Editor::nudge_backward (bool next, bool force_playhead) distance = next_distance; } if (distance < loc->start()) { - loc->set_start (loc->start() - distance); + loc->set_start (loc->start() - distance, false, true, get_grid_music_divisions(0)); } else { - loc->set_start (0); + loc->set_start (0, false, true, get_grid_music_divisions(0)); } } else { distance = get_nudge_distance (loc->end(), next_distance); @@ -537,9 +540,9 @@ Editor::nudge_backward (bool next, bool force_playhead) } if (distance < loc->end() - loc->length()) { - loc->set_end (loc->end() - distance); + loc->set_end (loc->end() - distance, false, true, get_grid_music_divisions(0)); } else { - loc->set_end (loc->length()); + loc->set_end (loc->length(), false, true, get_grid_music_divisions(0)); } if (loc->is_session_range()) { _session->set_end_is_free (false); @@ -1153,7 +1156,7 @@ Editor::selected_marker_to_region_boundary (bool with_selection, int32_t dir) return; } - loc->move_to (target); + loc->move_to (target, 0); } void @@ -1230,7 +1233,7 @@ Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir) pos = track_frame_to_session_frame(pos, speed); - loc->move_to (pos); + loc->move_to (pos, 0); } void @@ -1277,7 +1280,7 @@ Editor::selected_marker_to_selection_start () return; } - loc->move_to (pos); + loc->move_to (pos, 0); } void @@ -1312,7 +1315,7 @@ Editor::selected_marker_to_selection_end () return; } - loc->move_to (pos); + loc->move_to (pos, 0); } void @@ -1364,6 +1367,7 @@ Editor::cursor_align (bool playhead_to_edit) _session->request_locate (selection->markers.front()->position(), _session->transport_rolling()); } else { + const int32_t divisions = get_grid_music_divisions (0); /* move selected markers to playhead */ for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) { @@ -1372,10 +1376,10 @@ Editor::cursor_align (bool playhead_to_edit) Location* loc = find_location_from_marker (*i, ignored); if (loc->is_mark()) { - loc->set_start (playhead_cursor->current_frame ()); + loc->set_start (playhead_cursor->current_frame (), false, true, divisions); } else { loc->set (playhead_cursor->current_frame (), - playhead_cursor->current_frame () + loc->length()); + playhead_cursor->current_frame () + loc->length(), true, divisions); } } } @@ -1709,25 +1713,43 @@ Editor::tav_zoom_smooth (bool coarser, bool force_all) } void -Editor::temporal_zoom_step_mouse_focus (bool coarser) +Editor::temporal_zoom_step_mouse_focus_scale (bool zoom_out, double scale) { Editing::ZoomFocus temp_focus = zoom_focus; zoom_focus = Editing::ZoomFocusMouse; - temporal_zoom_step (coarser); + temporal_zoom_step_scale (zoom_out, scale); zoom_focus = temp_focus; } void -Editor::temporal_zoom_step (bool coarser) +Editor::temporal_zoom_step_mouse_focus (bool zoom_out) +{ + temporal_zoom_step_mouse_focus_scale (zoom_out, 2.0); +} + +void +Editor::temporal_zoom_step (bool zoom_out) +{ + temporal_zoom_step_scale (zoom_out, 2.0); +} + +void +Editor::temporal_zoom_step_scale (bool zoom_out, double scale) { - ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, coarser) + ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, zoom_out, scale) framecnt_t nspp = samples_per_pixel; - if (coarser) { - nspp *= 2; + if (zoom_out) { + nspp *= scale; + if (nspp == samples_per_pixel) { + nspp *= 2.0; + } } else { - nspp /= 2; + nspp /= scale; + if (nspp == samples_per_pixel) { + nspp /= 2.0; + } } temporal_zoom (nspp); @@ -1749,6 +1771,7 @@ Editor::temporal_zoom (framecnt_t fpp) framepos_t leftmost_after_zoom = 0; framepos_t where; bool in_track_canvas; + bool use_mouse_frame = true; framecnt_t nfpp; double l; @@ -1809,18 +1832,13 @@ Editor::temporal_zoom (framecnt_t fpp) case ZoomFocusMouse: /* try to keep the mouse over the same point in the display */ - if (!mouse_frame (where, in_track_canvas)) { - /* use playhead instead */ - where = playhead_cursor->current_frame (); - - if (where < half_page_size) { - leftmost_after_zoom = 0; - } else { - leftmost_after_zoom = where - half_page_size; - } - - } else { + if (_drags->active()) { + where = _drags->current_pointer_frame (); + } else if (!mouse_frame (where, in_track_canvas)) { + use_mouse_frame = false; + } + if (use_mouse_frame) { l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where); if (l < 0) { @@ -1830,8 +1848,16 @@ Editor::temporal_zoom (framecnt_t fpp) } else { leftmost_after_zoom = (framepos_t) l; } - } + } else { + /* use playhead instead */ + where = playhead_cursor->current_frame (); + if (where < half_page_size) { + leftmost_after_zoom = 0; + } else { + leftmost_after_zoom = where - half_page_size; + } + } break; case ZoomFocusEdit: @@ -1894,53 +1920,6 @@ Editor::calc_extra_zoom_edges(framepos_t &start, framepos_t &end) } } -void -Editor::temporal_zoom_region (bool both_axes) -{ - framepos_t start = max_framepos; - framepos_t end = 0; - set tracks; - - if ( !get_selection_extents(start, end) ) - return; - - calc_extra_zoom_edges (start, end); - - /* if we're zooming on both axes we need to save track heights etc. - */ - - undo_visual_stack.push_back (current_visual_state (both_axes)); - - PBD::Unwinder nsv (no_save_visual, true); - - temporal_zoom_by_frame (start, end); - - if (both_axes) { - uint32_t per_track_height = (uint32_t) floor ((_visible_canvas_height - 10.0) / tracks.size()); - - /* set visible track heights appropriately */ - - for (set::iterator t = tracks.begin(); t != tracks.end(); ++t) { - (*t)->set_height (per_track_height); - } - - /* hide irrelevant tracks */ - - DisplaySuspender ds; - - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - if (find (tracks.begin(), tracks.end(), (*i)) == tracks.end()) { - hide_track_in_display (*i); - } - } - - vertical_adjustment.set_value (0.0); - } - - redo_visual_stack.push_back (current_visual_state (both_axes)); -} - - bool Editor::get_selection_extents (framepos_t &start, framepos_t &end) const { @@ -1982,7 +1961,7 @@ Editor::get_selection_extents (framepos_t &start, framepos_t &end) const void -Editor::temporal_zoom_selection (bool both_axes) +Editor::temporal_zoom_selection (Editing::ZoomAxis axes) { if (!selection) return; @@ -1990,23 +1969,18 @@ Editor::temporal_zoom_selection (bool both_axes) //ToDo: if control points are selected, zoom to that - //if region(s) are selected, zoom to that - if ( !selection->regions.empty() ) - temporal_zoom_region (both_axes); + if (axes == Horizontal || axes == Both) { - //if a range is selected, zoom to that - if (!selection->time.empty()) { - - framepos_t start, end; + framepos_t start, end; if (get_selection_extents (start, end)) { - calc_extra_zoom_edges(start, end); + calc_extra_zoom_edges (start, end); temporal_zoom_by_frame (start, end); } - - if (both_axes) - fit_selection(); } + if (axes == Vertical || axes == Both) { + fit_selection (); + } } void @@ -2173,7 +2147,7 @@ Editor::add_location_from_selection () framepos_t end = selection->time[clicked_selection].end; _session->locations()->next_available_name(rangename,"selection"); - Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker); + Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker, get_grid_music_divisions(0)); begin_reversible_command (_("add marker")); @@ -2196,7 +2170,7 @@ Editor::add_location_mark (framepos_t where) if (!choose_new_marker_name(markername)) { return; } - Location *location = new Location (*_session, where, where, markername, Location::IsMark); + Location *location = new Location (*_session, where, where, markername, Location::IsMark, get_grid_music_divisions (0)); begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); @@ -2325,7 +2299,7 @@ Editor::add_locations_from_region () boost::shared_ptr region = (*i)->region (); - Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); + Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker, 0); _session->locations()->add (location, true); commit = true; @@ -2366,7 +2340,7 @@ Editor::add_location_from_region () } // single range spanning all selected - Location *location = new Location (*_session, selection->regions.start(), selection->regions.end_frame(), markername, Location::IsRangeMarker); + Location *location = new Location (*_session, selection->regions.start(), selection->regions.end_frame(), markername, Location::IsRangeMarker, 0); _session->locations()->add (location, true); begin_reversible_command (_("add marker")); @@ -2421,7 +2395,7 @@ Editor::set_mark () return; } - _session->locations()->add (new Location (*_session, pos, 0, markername, Location::IsMark), true); + _session->locations()->add (new Location (*_session, pos, 0, markername, Location::IsMark, 0), true); } void @@ -2634,7 +2608,7 @@ Editor::get_preroll () void Editor::maybe_locate_with_edit_preroll ( framepos_t location ) { - if ( _session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _ignore_follow_edits || _session->config.get_external_sync() ) + if ( _session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _session->config.get_external_sync() ) return; location -= get_preroll(); @@ -2654,13 +2628,12 @@ Editor::maybe_locate_with_edit_preroll ( framepos_t location ) void Editor::play_with_preroll () { - { - framepos_t preroll = get_preroll(); - - framepos_t start, end; - if (!get_selection_extents ( start, end)) - return; + framepos_t preroll = get_preroll(); + framepos_t start, end; + if ( UIConfiguration::instance().get_follow_edits() && get_selection_extents ( start, end) ) { + framepos_t ret = start; + if (start > preroll) start = start - preroll; @@ -2671,6 +2644,16 @@ Editor::play_with_preroll () lar.push_back (ar); _session->request_play_range (&lar, true); + _session->set_requested_return_frame( ret ); //force auto-return to return to range start, without the preroll + } else { + framepos_t ph = playhead_cursor->current_frame (); + framepos_t start; + if (ph > preroll) + start = ph - preroll; + else + start = 0; + _session->request_locate ( start, true); + _session->set_requested_return_frame( ph ); //force auto-return to return to playhead location, without the preroll } } @@ -3707,10 +3690,8 @@ Editor::trim_region (bool front) if (front) { (*i)->region()->trim_front (where); - maybe_locate_with_edit_preroll ( where ); } else { (*i)->region()->trim_end (where); - maybe_locate_with_edit_preroll ( where ); } _session->add_command (new StatefulDiffCommand ((*i)->region())); @@ -4822,6 +4803,13 @@ Editor::paste_internal (framepos_t position, float times, const int32_t sub_num) commit_reversible_command (); } +void +Editor::duplicate_regions (float times) +{ + RegionSelection rs (get_regions_from_selection_and_entered()); + duplicate_some_regions (rs, times); +} + void Editor::duplicate_some_regions (RegionSelection& regions, float times) { @@ -4902,18 +4890,19 @@ Editor::duplicate_selection (float times) } if (in_command) { - // now "move" range selection to after the current range selection - framecnt_t distance = 0; - - if (clicked_selection) { - distance = selection->time[clicked_selection].end - - selection->time[clicked_selection].start; - } else { - distance = selection->time.end_frame() - selection->time.start(); - } + if (times == 1.0f) { + // now "move" range selection to after the current range selection + framecnt_t distance = 0; - selection->move_time (distance); + if (clicked_selection) { + distance = + selection->time[clicked_selection].end - selection->time[clicked_selection].start; + } else { + distance = selection->time.end_frame () - selection->time.start (); + } + selection->move_time (distance); + } commit_reversible_command (); } } @@ -5049,7 +5038,7 @@ Editor::normalize_region () NormalizeDialog dialog (rs.size() > 1); - if (dialog.run () == RESPONSE_CANCEL) { + if (dialog.run () != RESPONSE_ACCEPT) { return; } @@ -5374,6 +5363,11 @@ Editor::quantize_regions (const RegionSelection& rs) quantize_dialog = new QuantizeDialog (*this); } + if (quantize_dialog->is_mapped()) { + /* in progress already */ + return; + } + quantize_dialog->present (); const int r = quantize_dialog->run (); quantize_dialog->hide (); @@ -6181,7 +6175,7 @@ Editor::set_edit_point () Location* loc = find_location_from_marker (selection->markers.front(), ignored); if (loc) { - loc->move_to (where); + loc->move_to (where, get_grid_music_divisions(0)); } } } @@ -6206,9 +6200,11 @@ Editor::set_playhead_cursor () } } - if (UIConfiguration::instance().get_follow_edits() && (!_session || !_session->config.get_external_sync())) { - cancel_time_selection(); - } +//not sure what this was for; remove it for now. +// if (UIConfiguration::instance().get_follow_edits() && (!_session || !_session->config.get_external_sync())) { +// cancel_time_selection(); +// } + } void @@ -6358,6 +6354,59 @@ Editor::set_punch_from_selection () set_punch_range (start, end, _("set punch range from selection")); } +void +Editor::set_auto_punch_range () +{ + // auto punch in/out button from a single button + // If Punch In is unset, set punch range from playhead to end, enable punch in + // If Punch In is set, the next punch sets Punch Out, unless the playhead has been + // rewound beyond the Punch In marker, in which case that marker will be moved back + // to the current playhead position. + // If punch out is set, it clears the punch range and Punch In/Out buttons + + if (_session == 0) { + return; + } + + Location* tpl = transport_punch_location(); + framepos_t now = playhead_cursor->current_frame(); + framepos_t begin = now; + framepos_t end = _session->current_end_frame(); + + if (!_session->config.get_punch_in()) { + // First Press - set punch in and create range from here to eternity + set_punch_range (begin, end, _("Auto Punch In")); + _session->config.set_punch_in(true); + } else if (tpl && !_session->config.get_punch_out()) { + // Second press - update end range marker and set punch_out + if (now < tpl->start()) { + // playhead has been rewound - move start back and pretend nothing happened + begin = now; + set_punch_range (begin, end, _("Auto Punch In/Out")); + } else { + // normal case for 2nd press - set the punch out + end = playhead_cursor->current_frame (); + set_punch_range (tpl->start(), now, _("Auto Punch In/Out")); + _session->config.set_punch_out(true); + } + } else { + if (_session->config.get_punch_out()) { + _session->config.set_punch_out(false); + } + + if (_session->config.get_punch_in()) { + _session->config.set_punch_in(false); + } + + if (tpl) + { + // third press - unset punch in/out and remove range + _session->locations()->remove(tpl); + } + } + +} + void Editor::set_session_extents_from_selection () { @@ -7295,6 +7344,26 @@ edit your ardour.rc file to set the\n\ return; } + if (current_mixer_strip && routes.size () > 1 && std::find (routes.begin(), routes.end(), current_mixer_strip->route()) != routes.end ()) { + /* Route deletion calls Editor::timeaxisview_deleted() iteratively (for each deleted + * route). If the deleted route is currently displayed in the Editor-Mixer (highly + * likely because deletion requires selection) this will call + * Editor::set_selected_mixer_strip () which is expensive ( MixerStrip::set_route() ). + * It's likewise likely that the route that has just been displayed in the + * Editor-Mixer will be next in line for deletion. + * + * So simply switch to the master-bus (if present) + */ + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + if ((*i)->stripable ()->is_master ()) { + set_selected_mixer_strip (*(*i)); + break; + } + } + } + + Mixer_UI::instance()->selection().block_routes_changed (true); + selection->block_tracks_changed (true); { DisplaySuspender ds; boost::shared_ptr rl (new RouteList); @@ -7307,6 +7376,9 @@ edit your ardour.rc file to set the\n\ * destructors are called, * diskstream drops references, save_state is called (again for every track) */ + selection->block_tracks_changed (false); + Mixer_UI::instance()->selection().block_routes_changed (false); + selection->TracksChanged (); /* EMIT SIGNAL */ } void @@ -7328,7 +7400,7 @@ Editor::do_insert_time () } insert_time ( - get_preferred_edit_position (EDIT_IGNORE_MOUSE), + d.position(), d.distance(), d.intersected_region_action (), d.all_playlists(), @@ -7416,6 +7488,7 @@ Editor::insert_time ( /* markers */ if (markers_too) { bool moved = false; + const int32_t divisions = get_grid_music_divisions (0); XMLNode& before (_session->locations()->get_state()); Locations::LocationList copy (_session->locations()->list()); @@ -7432,9 +7505,9 @@ Editor::insert_time ( if ((*i)->start() >= pos) { // move end first, in case we're moving by more than the length of the range if (!(*i)->is_mark()) { - (*i)->set_end ((*i)->end() + frames); + (*i)->set_end ((*i)->end() + frames, false, true, divisions); } - (*i)->set_start ((*i)->start() + frames); + (*i)->set_start ((*i)->start() + frames, false, true, divisions); moved = true; } @@ -7477,7 +7550,6 @@ Editor::do_remove_time () return; } - framepos_t pos = get_preferred_edit_position (EDIT_IGNORE_MOUSE); InsertRemoveTimeDialog d (*this, true); int response = d.run (); @@ -7493,7 +7565,7 @@ Editor::do_remove_time () } remove_time ( - pos, + d.position(), distance, SplitIntersected, d.move_glued(), @@ -7548,6 +7620,7 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, } } + const int32_t divisions = get_grid_music_divisions (0); std::list loc_kill_list; /* markers */ @@ -7576,20 +7649,20 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, // if we're removing more time than the length of the range if ((*i)->start() >= pos && (*i)->start() < pos+frames) { // start is within cut - (*i)->set_start (pos); // bring the start marker to the beginning of the cut + (*i)->set_start (pos, false, true,divisions); // bring the start marker to the beginning of the cut moved = true; } else if ((*i)->start() >= pos+frames) { // start (and thus entire range) lies beyond end of cut - (*i)->set_start ((*i)->start() - frames); // slip the start marker back + (*i)->set_start ((*i)->start() - frames, false, true, divisions); // slip the start marker back moved = true; } if ((*i)->end() >= pos && (*i)->end() < pos+frames) { // end is inside cut - (*i)->set_end (pos); // bring the end to the cut + (*i)->set_end (pos, false, true, divisions); // bring the end to the cut moved = true; } else if ((*i)->end() >= pos+frames) { // end is beyond end of cut - (*i)->set_end ((*i)->end() - frames); // slip the end marker back + (*i)->set_end ((*i)->end() - frames, false, true, divisions); // slip the end marker back moved = true; } @@ -7598,7 +7671,7 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt, loc_kill_list.push_back(*i); moved = true; } else if ((*i)->start() >= pos) { - (*i)->set_start ((*i)->start() -frames); + (*i)->set_start ((*i)->start() -frames, false, true, divisions); moved = true; } @@ -7936,6 +8009,8 @@ Editor::toggle_midi_input_active (bool flip_others) _session->set_exclusive_input_active (rl, onoff, flip_others); } +static bool ok_fine (GdkEventAny*) { return true; } + void Editor::lock () { @@ -7944,6 +8019,7 @@ Editor::lock () Gtk::Image* padlock = manage (new Gtk::Image (ARDOUR_UI_UTILS::get_icon ("padlock_closed"))); lock_dialog->get_vbox()->pack_start (*padlock); + lock_dialog->signal_delete_event ().connect (sigc::ptr_fun (ok_fine)); ArdourButton* b = manage (new ArdourButton); b->set_name ("lock button"); @@ -7959,6 +8035,8 @@ Editor::lock () _main_menu_disabler = new MainMenuDisabler; lock_dialog->present (); + + lock_dialog->get_window()->set_decorations (Gdk::WMDecoration (0)); } void