2005-09-25 14:42:24 -04:00
/*
2019-08-02 17:26:43 -04:00
* Copyright ( C ) 2005 - 2007 Doug McLain < doug @ nostar . net >
* Copyright ( C ) 2005 - 2009 Taybin Rutkin < taybin @ taybin . com >
* Copyright ( C ) 2005 - 2019 Paul Davis < paul @ linuxaudiosystems . com >
* Copyright ( C ) 2005 Karsten Wiese < fzuuzf @ googlemail . com >
* Copyright ( C ) 2006 - 2009 Sampo Savolainen < v2 @ iki . fi >
* Copyright ( C ) 2006 - 2015 David Robillard < d @ drobilla . net >
* Copyright ( C ) 2006 - 2017 Tim Mayberry < mojofunk @ gmail . com >
* Copyright ( C ) 2007 - 2012 Carl Hetherington < carl @ carlh . net >
* Copyright ( C ) 2008 Hans Baier < hansfbaier @ googlemail . com >
* Copyright ( C ) 2012 - 2019 Robin Gareus < robin @ gareus . org >
* Copyright ( C ) 2013 - 2015 Colin Fletcher < colin . m . fletcher @ googlemail . com >
* Copyright ( C ) 2014 - 2017 Nick Mainsbridge < mainsbridge @ gmail . com >
* Copyright ( C ) 2014 - 2019 Ben Loftis < ben @ harrisonconsoles . com >
* Copyright ( C ) 2015 André Nusser < andre . nusser @ googlemail . com >
*
* 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 . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2005-09-25 14:42:24 -04:00
2007-05-11 11:06:12 -04:00
/* Note: public Editor methods are documented in public_editor.h */
2009-06-17 18:08:51 -04:00
# include <stdint.h>
2005-09-25 14:42:24 -04:00
# include <unistd.h>
# include <cstdlib>
# include <cmath>
# include <string>
# include <algorithm>
2009-06-17 18:08:51 -04:00
# include <map>
2005-09-25 14:42:24 -04:00
Merged revisions 6293,6296-6306,6308 via svnmerge from
svn+ssh://ardoursvn@subversion.ardour.org/ardour2/branches/build_fixes
........
r6293 | trutkin | 2009-12-05 08:49:37 -0500 (Sat, 05 Dec 2009) | 2 lines
fix if-statement in build script
........
r6296 | trutkin | 2009-12-05 09:30:19 -0500 (Sat, 05 Dec 2009) | 5 lines
rearrange GTKOSX and darwin dependencies
- moved some GTKOSX include paths to generic darwin
- made GTKOSX dependent on being on darwin anyways
........
r6297 | trutkin | 2009-12-05 09:35:09 -0500 (Sat, 05 Dec 2009) | 2 lines
move coreaudio and audiounit handling to darwin section
........
r6298 | trutkin | 2009-12-05 09:53:40 -0500 (Sat, 05 Dec 2009) | 3 lines
use True/False instead of 1/0
fix another if-statement where it should be an elif-statement
........
r6299 | trutkin | 2009-12-05 14:11:09 -0500 (Sat, 05 Dec 2009) | 10 lines
fixes to get libardour building
- can't cast away volatile, so copy _transport_frame before emitting it.
- const_reverse_iterator::operator!=() isn't defined in this version of gcc.
- removed annoying HERE WE ARE CAAudioFile.h #warning.
- removed unnecessary include of sndfile.h in session.h.
- we don't want to set -march=i686 on the mac, so indent this if-statement so
it's only run on linux.
- DEBUG_STR() fails in the NDEBUG case, so wrap its use in an #ifndef NDEBUG
........
r6300 | trutkin | 2009-12-05 15:48:29 -0500 (Sat, 05 Dec 2009) | 2 lines
remove old scons-style CXXFLAGS_FOO in favor of just CXXFLAGS
........
r6301 | trutkin | 2009-12-05 16:01:10 -0500 (Sat, 05 Dec 2009) | 8 lines
clean up configure flags
- removed useless --aubio and --syslibs flags. The syslibs value is ignored
as we don't bring our own libraries with us anymoreand we use aubio
automatically if it's available
- added ways to turn off fpu_optimization and NLS
- fixed compiling on the mac without fpu_optimization
........
r6302 | trutkin | 2009-12-05 18:12:46 -0500 (Sat, 05 Dec 2009) | 5 lines
go back to prior uselib method for COREAUDIO, AUDIOUNIT, and GTKOSX
- fixed compile of CoreAudioSource
- re-did inclusion of coremidi_midiport.cc to depend on COREAUDIO presence
........
r6303 | trutkin | 2009-12-05 18:59:02 -0500 (Sat, 05 Dec 2009) | 5 lines
fixed compiler warnings about classes with virtual member functions, but no virtual destructor.
- Changed Metering to not use foo() = 0; to indicate it shouldn't be instantiated, but
private: Metering(), which is more idiomatic.
........
r6304 | trutkin | 2009-12-05 19:25:41 -0500 (Sat, 05 Dec 2009) | 2 lines
TOP_MENUBAR isn't used when building ardour.menus. Removed.
........
r6305 | trutkin | 2009-12-05 19:46:11 -0500 (Sat, 05 Dec 2009) | 5 lines
fix some AudioUnit compile errors
- update AudioUnit to use ChanCount
- fix some namespacing issues in audio_unit.h
........
r6306 | trutkin | 2009-12-05 20:08:48 -0500 (Sat, 05 Dec 2009) | 2 lines
make --extra-warn useful
........
r6308 | trutkin | 2009-12-05 22:59:42 -0500 (Sat, 05 Dec 2009) | 10 lines
fix compiling/linking with --coreaudio
- rearrange ardour_ui.h header in editor.cc to avoid conflict
- midi++ depends on OSX as well as COREAUDIO
- fixed including frameworks
- tweaked --extra-warn again. it's kinda redundent with --strict
- improved indentation in wscript
- use #ifdef HAVE_COREMIDI, not #if HAVE_COREMIDI. #if isn't interchangable
with #ifdef and won't work if HAVE_COREMIDI is defined with no value.
........
git-svn-id: svn://localhost/ardour2/branches/3.0@6310 d708f5d6-7413-0410-9779-e7cbd77b26cf
2009-12-05 23:35:48 -05:00
# include "ardour_ui.h"
/*
* ardour_ui . h include was moved to the top of the list
* due to a conflicting definition of ' Style ' between
* Apple ' s MacTypes . h and BarController .
*/
2007-10-11 18:07:47 -04:00
# include <boost/none.hpp>
2005-09-25 14:42:24 -04:00
# include <sigc++/bind.h>
2009-02-25 13:26:51 -05:00
# include "pbd/convert.h"
# include "pbd/error.h"
# include "pbd/enumwriter.h"
# include "pbd/memento_command.h"
2009-07-01 19:20:18 -04:00
# include "pbd/unknown_type.h"
2012-03-06 21:11:59 -05:00
# include "pbd/unwind.h"
2013-01-18 10:56:41 -05:00
# include "pbd/stacktrace.h"
2014-06-25 08:28:36 -04:00
# include "pbd/timersub.h"
2005-09-25 14:42:24 -04:00
2007-03-19 03:07:38 -04:00
# include <glibmm/miscutils.h>
2014-01-17 09:24:18 -05:00
# include <glibmm/uriutils.h>
2005-11-25 19:06:46 -05:00
# include <gtkmm/image.h>
# include <gdkmm/color.h>
# include <gdkmm/bitmap.h>
2014-03-23 19:11:42 -04:00
# include <gtkmm/menu.h>
# include <gtkmm/menuitem.h>
2011-03-03 22:10:48 -05:00
# include "gtkmm2ext/bindings.h"
# include "gtkmm2ext/gtk_ui.h"
2017-07-16 18:00:11 -04:00
# include "gtkmm2ext/keyboard.h"
2011-03-03 22:10:48 -05:00
# include "gtkmm2ext/utils.h"
# include "gtkmm2ext/window_title.h"
# include "gtkmm2ext/cell_renderer_pixbuf_toggle.h"
2005-09-25 14:42:24 -04:00
2016-03-11 11:26:27 -05:00
# include "ardour/analysis_graph.h"
2009-02-25 13:26:51 -05:00
# include "ardour/audio_track.h"
2012-05-24 02:09:29 -04:00
# include "ardour/audioengine.h"
2009-02-25 13:26:51 -05:00
# include "ardour/audioregion.h"
2015-03-31 10:05:15 -04:00
# include "ardour/lmath.h"
2009-02-25 13:26:51 -05:00
# include "ardour/location.h"
# include "ardour/profile.h"
2016-06-03 15:15:30 -04:00
# include "ardour/route.h"
2009-02-25 13:26:51 -05:00
# include "ardour/route_group.h"
2012-05-24 02:09:29 -04:00
# include "ardour/session_playlists.h"
2009-02-25 13:26:51 -05:00
# include "ardour/tempo.h"
# include "ardour/utils.h"
2016-05-21 16:36:08 -04:00
# include "ardour/vca_manager.h"
2016-06-03 15:15:30 -04:00
# include "ardour/vca.h"
2006-05-23 15:54:52 -04:00
2013-04-04 00:32:52 -04:00
# include "canvas/debug.h"
2018-07-03 15:39:28 -04:00
# include "canvas/note.h"
2013-04-04 00:32:52 -04:00
# include "canvas/text.h"
2017-07-15 11:38:28 -04:00
# include "widgets/ardour_spacer.h"
2017-07-16 22:55:52 -04:00
# include "widgets/eventboxext.h"
2017-07-15 11:38:28 -04:00
# include "widgets/tooltips.h"
2009-02-25 13:39:39 -05:00
# include "control_protocol/control_protocol.h"
2005-09-25 14:42:24 -04:00
2011-07-06 20:37:13 -04:00
# include "actions.h"
# include "analysis_window.h"
2020-01-15 16:01:30 -05:00
# include "ardour_message.h"
2011-06-02 13:50:37 -04:00
# include "audio_clock.h"
2006-08-01 13:19:38 -04:00
# include "audio_region_view.h"
2006-07-23 08:03:19 -04:00
# include "audio_streamview.h"
2006-11-19 11:45:16 -05:00
# include "audio_time_axis.h"
2011-07-06 20:37:13 -04:00
# include "automation_time_axis.h"
# include "bundle_manager.h"
# include "crossfade_edit.h"
# include "debug.h"
# include "editing.h"
2016-08-26 23:44:57 -04:00
# include "editing_convert.h"
2011-07-06 20:37:13 -04:00
# include "editor.h"
# include "editor_cursors.h"
2009-05-30 14:25:59 -04:00
# include "editor_drag.h"
2009-06-20 09:41:55 -04:00
# include "editor_group_tabs.h"
2009-11-12 00:47:05 -05:00
# include "editor_locations.h"
2011-07-06 20:37:13 -04:00
# include "editor_regions.h"
# include "editor_route_groups.h"
# include "editor_routes.h"
2009-07-03 19:51:58 -04:00
# include "editor_snapshots.h"
2018-11-15 10:21:55 -05:00
# include "editor_sources.h"
2010-06-17 20:05:44 -04:00
# include "editor_summary.h"
2016-08-26 23:44:57 -04:00
# include "enums_convert.h"
2016-03-11 11:26:27 -05:00
# include "export_report.h"
2011-07-06 20:37:13 -04:00
# include "global_port_matrix.h"
# include "gui_object.h"
# include "gui_thread.h"
# include "keyboard.h"
2016-02-23 09:42:53 -05:00
# include "luainstance.h"
2011-07-06 20:37:13 -04:00
# include "marker.h"
2014-12-25 15:32:10 -05:00
# include "midi_region_view.h"
2011-07-06 20:37:13 -04:00
# include "midi_time_axis.h"
# include "mixer_strip.h"
2011-11-15 14:33:09 -05:00
# include "mixer_ui.h"
2010-11-16 09:53:16 -05:00
# include "mouse_cursors.h"
2014-12-25 15:32:10 -05:00
# include "note_base.h"
2011-07-06 20:37:13 -04:00
# include "playlist_selector.h"
# include "public_editor.h"
2015-06-26 12:34:55 -04:00
# include "quantize_dialog.h"
2011-07-06 20:37:13 -04:00
# include "region_layering_order_editor.h"
# include "rgb_macros.h"
# include "rhythm_ferret.h"
2016-06-06 12:52:48 -04:00
# include "route_sorter.h"
2011-07-06 20:37:13 -04:00
# include "selection.h"
2016-03-11 11:26:27 -05:00
# include "simple_progress_dialog.h"
2011-07-06 20:37:13 -04:00
# include "sfdb_ui.h"
2018-02-09 10:59:39 -05:00
# include "grid_lines.h"
2011-07-06 20:37:13 -04:00
# include "time_axis_view.h"
2016-12-16 20:31:41 -05:00
# include "time_info_box.h"
2014-12-25 10:02:00 -05:00
# include "timers.h"
2015-01-02 09:44:54 -05:00
# include "ui_config.h"
2011-07-06 20:37:13 -04:00
# include "utils.h"
2016-05-21 16:36:08 -04:00
# include "vca_time_axis.h"
2014-06-30 16:32:38 -04:00
# include "verbose_cursor.h"
2005-09-25 14:42:24 -04:00
2016-07-14 14:44:52 -04:00
# include "pbd/i18n.h"
2005-09-25 14:42:24 -04:00
using namespace std ;
using namespace ARDOUR ;
2017-07-15 11:38:28 -04:00
using namespace ArdourWidgets ;
2014-06-25 15:27:37 -04:00
using namespace ARDOUR_UI_UTILS ;
Large nasty commit in the form of a 5000 line patch chock-full of completely
unecessary changes. (Sorry, doing a "sprint" based thing, this is the end of the first one)
Achieved MIDI track and bus creation, associated Jack port and diskstream creation, and minimal GUI stuff for creating them. Should be set to start work on actually recording and playing midi to/from disk now.
Relevant (significant) changes:
- Creation of a Buffer class. Base class is type agnostic so things can point to a buffer but not care what kind it is (otherwise it'd be a template). Derived into AudioBuffer and MidiBuffer, with a type tag because checking type is necessary in parts of the code where dynamic_cast wouldn't be wise. Originally I considered this a hack, but passing around a type proved to be a very good solution to all the other problems (below). There is a 1:1 mapping between jack port data types and ardour Buffer types (with a conversion function), but that's easily removed if it ever becomes necessary. Having the type scoped in the Buffer class is maybe not the best spot for it, but whatever (this is proof of concept kinda stuff right now...)
- IO now has a "default" port type (passed to the constructor and stored as a member), used by ensure_io (and similar) to create n ports. IO::register_***_port has a type argument that defaults to the default type if not passed. Rationale: previous IO API is identical, no changes needed to existing code, but path is paved for multiple port types in one IO, which we will need for eg synth plugin inserts, among other things. This is not quite ideal (best would be to only have the two port register functions and have them take a type), but the alternative is a lot of work (namely destroying the 'ensure' functions and everything that uses them) for very little gain. (I am convinced after quite a few tries at the whiteboard that subclassing IO in any way is not a feasible option, look at it's inheritance diagram in Doxygen and you can see why)
- AudioEngine::register_audio_input_port is now register_input_port and takes a type argument. Ditto for output.
- (Most significant change) AudioDiskstream abstracted into Distream, and sibling MidiDiskstream created. Very much still a work in progress, but Diskstream is there to switch references over to (most already are), which is the important part. It is still unclear what the MIDI diskstream's relation to channels is, but I'm pretty sure they will be single channel only (so SMF Type 0) since noone can come up with a reason otherwise.
- MidiTrack creation. Same thing as AudioTrack but with a different default type basically. No big deal here.
- Random cleanups and variable renamings etc. because I have OCD and can't help myself. :)
Known broken: Loading of sessions containing MIDI tracks.
git-svn-id: svn://localhost/ardour2/branches/midi@641 d708f5d6-7413-0410-9779-e7cbd77b26cf
2006-06-26 12:01:34 -04:00
using namespace PBD ;
2005-09-25 14:42:24 -04:00
using namespace Gtk ;
2005-11-02 15:33:47 -05:00
using namespace Glib ;
2005-09-25 16:33:00 -04:00
using namespace Gtkmm2ext ;
2005-09-25 14:42:24 -04:00
using namespace Editing ;
2006-04-25 16:23:50 -04:00
using PBD : : internationalize ;
2006-06-13 03:27:52 -04:00
using PBD : : atoi ;
2009-12-04 17:51:32 -05:00
using Gtkmm2ext : : Keyboard ;
2006-04-25 16:23:50 -04:00
2014-12-28 09:01:49 -05:00
double Editor : : timebar_height = 15.0 ;
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
static const gchar * _grid_type_strings [ ] = {
2008-01-10 16:20:59 -05:00
N_ ( " No Grid " ) ,
2018-02-09 10:59:39 -05:00
N_ ( " Bar " ) ,
N_ ( " 1/4 Note " ) ,
N_ ( " 1/8 Note " ) ,
N_ ( " 1/16 Note " ) ,
N_ ( " 1/32 Note " ) ,
N_ ( " 1/64 Note " ) ,
N_ ( " 1/128 Note " ) ,
N_ ( " 1/3 (8th triplet) " ) , // or "1/12" ?
N_ ( " 1/6 (16th triplet) " ) ,
N_ ( " 1/12 (32nd triplet) " ) ,
N_ ( " 1/24 (64th triplet) " ) ,
N_ ( " 1/5 (8th quintuplet) " ) ,
N_ ( " 1/10 (16th quintuplet) " ) ,
N_ ( " 1/20 (32nd quintuplet) " ) ,
N_ ( " 1/7 (8th septuplet) " ) ,
N_ ( " 1/14 (16th septuplet) " ) ,
N_ ( " 1/28 (32nd septuplet) " ) ,
2018-02-12 10:15:26 -05:00
N_ ( " Timecode " ) ,
2018-02-09 10:59:39 -05:00
N_ ( " MinSec " ) ,
2018-02-26 18:02:24 -05:00
N_ ( " CD Frames " ) ,
2005-09-25 14:42:24 -04:00
0
} ;
2007-11-07 20:40:25 -05:00
static const gchar * _edit_point_strings [ ] = {
N_ ( " Playhead " ) ,
N_ ( " Marker " ) ,
N_ ( " Mouse " ) ,
0
} ;
2014-07-09 16:48:19 -04:00
static const gchar * _edit_mode_strings [ ] = {
N_ ( " Slide " ) ,
N_ ( " Splice " ) ,
N_ ( " Ripple " ) ,
2015-05-18 13:27:50 -04:00
N_ ( " Lock " ) ,
2014-07-09 16:48:19 -04:00
0
} ;
2006-11-19 11:45:16 -05:00
static const gchar * _zoom_focus_strings [ ] = {
2006-10-21 15:01:50 -04:00
N_ ( " Left " ) ,
N_ ( " Right " ) ,
N_ ( " Center " ) ,
2007-10-11 18:07:47 -04:00
N_ ( " Playhead " ) ,
2016-04-22 23:02:39 -04:00
N_ ( " Mouse " ) ,
N_ ( " Edit point " ) ,
2005-09-25 14:42:24 -04:00
0
} ;
2008-01-10 17:22:29 -05:00
# ifdef USE_RUBBERBAND
static const gchar * _rb_opt_strings [ ] = {
N_ ( " Mushy " ) ,
N_ ( " Smooth " ) ,
N_ ( " Balanced multitimbral mixture " ) ,
N_ ( " Unpitched percussion with stable notes " ) ,
N_ ( " Crisp monophonic instrumental " ) ,
N_ ( " Unpitched solo percussion " ) ,
2010-08-13 12:50:29 -04:00
N_ ( " Resample without preserving pitch " ) ,
2008-01-10 17:22:29 -05:00
0
} ;
# endif
2018-02-24 07:54:15 -05:00
/* Robin says: this should be odd to accomodate cairo drawing offset (width/2 rounds up to pixel boundary) */
2018-02-15 17:32:37 -05:00
# ifdef __APPLE__
# define COMBO_TRIANGLE_WIDTH 19 // ArdourButton _diameter (11) + 2 * arrow-padding (2*2) + 2 * text-padding (2*5)
2018-02-14 09:15:45 -05:00
# else
# define COMBO_TRIANGLE_WIDTH 11 // as-measured for win/linux.
# endif
2014-07-30 18:27:12 -04:00
2007-03-18 02:07:08 -04:00
Editor : : Editor ( )
2015-07-07 22:12:21 -04:00
: PublicEditor ( global_hpacker )
, editor_mixer_strip_width ( Wide )
, constructed ( false )
, _playlist_selector ( 0 )
2016-12-16 20:31:41 -05:00
, _time_info_box ( 0 )
2015-07-07 22:12:21 -04:00
, no_save_visual ( false )
2017-09-18 12:39:17 -04:00
, _leftmost_sample ( 0 )
2015-07-07 22:12:21 -04:00
, samples_per_pixel ( 2048 )
, zoom_focus ( ZoomFocusPlayhead )
, mouse_mode ( MouseObject )
2018-02-09 10:59:39 -05:00
, pre_internal_grid_type ( GridTypeBeat )
2015-07-07 22:12:21 -04:00
, pre_internal_snap_mode ( SnapOff )
2018-02-09 10:59:39 -05:00
, internal_grid_type ( GridTypeBeat )
2015-07-07 22:12:21 -04:00
, internal_snap_mode ( SnapOff )
, _join_object_range_state ( JOIN_OBJECT_RANGE_NONE )
, _notebook_shrunk ( false )
, location_marker_color ( 0 )
, location_range_color ( 0 )
, location_loop_color ( 0 )
, location_punch_color ( 0 )
, location_cd_marker_color ( 0 )
, entered_marker ( 0 )
, _show_marker_lines ( false )
, clicked_axisview ( 0 )
, clicked_routeview ( 0 )
, clicked_regionview ( 0 )
, clicked_selection ( 0 )
, clicked_control_point ( 0 )
, button_release_can_deselect ( true )
2015-01-10 12:07:31 -05:00
, _mouse_changed_selection ( false )
2015-07-07 22:12:21 -04:00
, _popup_region_menu_item ( 0 )
, _track_canvas ( 0 )
, _track_canvas_viewport ( 0 )
, within_track_canvas ( false )
, _verbose_cursor ( 0 )
, tempo_group ( 0 )
, meter_group ( 0 )
, marker_group ( 0 )
, range_marker_group ( 0 )
, transport_marker_group ( 0 )
, cd_marker_group ( 0 )
, _time_markers_group ( 0 )
, hv_scroll_group ( 0 )
, h_scroll_group ( 0 )
, cursor_scroll_group ( 0 )
, no_scroll_group ( 0 )
, _trackview_group ( 0 )
, _drag_motion_group ( 0 )
, _canvas_drop_zone ( 0 )
, no_ruler_shown_update ( false )
, ruler_grabbed_widget ( 0 )
, ruler_dialog ( 0 )
, minsec_mark_interval ( 0 )
, minsec_mark_modulo ( 0 )
, minsec_nmarks ( 0 )
2017-07-23 13:20:35 -04:00
, timecode_ruler_scale ( timecode_show_many_hours )
2015-07-07 22:12:21 -04:00
, timecode_mark_modulo ( 0 )
, timecode_nmarks ( 0 )
, _samples_ruler_interval ( 0 )
2017-07-23 13:20:35 -04:00
, bbt_ruler_scale ( bbt_show_many )
2015-07-07 22:12:21 -04:00
, bbt_bars ( 0 )
, bbt_nmarks ( 0 )
, bbt_bar_helper_on ( 0 )
, bbt_accent_modulo ( 0 )
, timecode_ruler ( 0 )
, bbt_ruler ( 0 )
, samples_ruler ( 0 )
, minsec_ruler ( 0 )
, visible_timebars ( 0 )
, editor_ruler_menu ( 0 )
, tempo_bar ( 0 )
, meter_bar ( 0 )
, marker_bar ( 0 )
, range_marker_bar ( 0 )
, transport_marker_bar ( 0 )
, cd_marker_bar ( 0 )
2010-01-01 17:11:15 -05:00
, minsec_label ( _ ( " Mins:Secs " ) )
2009-07-28 16:51:28 -04:00
, bbt_label ( _ ( " Bars:Beats " ) )
2009-10-26 10:38:58 -04:00
, timecode_label ( _ ( " Timecode " ) )
2011-01-18 07:51:02 -05:00
, samples_label ( _ ( " Samples " ) )
2009-07-28 16:51:28 -04:00
, tempo_label ( _ ( " Tempo " ) )
, meter_label ( _ ( " Meter " ) )
, mark_label ( _ ( " Location Markers " ) )
, range_mark_label ( _ ( " Range Markers " ) )
, transport_mark_label ( _ ( " Loop/Punch Ranges " ) )
, cd_mark_label ( _ ( " CD Markers " ) )
2013-03-12 17:00:09 -04:00
, videotl_label ( _ ( " Video Timeline " ) )
2015-07-07 22:12:21 -04:00
, videotl_group ( 0 )
2018-02-09 09:21:45 -05:00
, snapped_cursor ( 0 )
2015-07-07 22:12:21 -04:00
, playhead_cursor ( 0 )
2018-02-09 10:59:39 -05:00
, _region_boundary_cache_dirty ( true )
2009-07-28 16:51:28 -04:00
, edit_packer ( 4 , 4 , true )
, vertical_adjustment ( 0.0 , 0.0 , 10.0 , 400.0 )
2013-04-13 07:29:49 -04:00
, horizontal_adjustment ( 0.0 , 0.0 , 1e16 )
, unused_adjustment ( 0.0 , 0.0 , 10.0 , 400.0 )
, controls_layout ( unused_adjustment , vertical_adjustment )
2015-07-07 22:12:21 -04:00
, _scroll_callbacks ( 0 )
, _visible_canvas_width ( 0 )
, _visible_canvas_height ( 0 )
, _full_canvas_height ( 0 )
, edit_controls_left_menu ( 0 )
, edit_controls_right_menu ( 0 )
2017-04-01 07:33:59 -04:00
, visual_change_queued ( false )
2017-03-23 14:21:50 -04:00
, _last_update_time ( 0 )
, _err_screen_engine ( 0 )
2015-07-07 22:12:21 -04:00
, cut_buffer_start ( 0 )
, cut_buffer_length ( 0 )
, button_bindings ( 0 )
2017-07-26 21:22:21 -04:00
, last_paste_pos ( - 1 )
2015-07-07 22:12:21 -04:00
, paste_count ( 0 )
, sfbrowser ( 0 )
, current_interthread_info ( 0 )
, analysis_window ( 0 )
, select_new_marker ( false )
, last_scrub_x ( 0 )
, scrubbing_direction ( 0 )
, scrub_reversals ( 0 )
, scrub_reverse_distance ( 0 )
, have_pending_keyboard_selection ( false )
, pending_keyboard_selection_start ( 0 )
2018-02-09 10:59:39 -05:00
, _grid_type ( GridTypeBeat )
2015-07-07 22:12:21 -04:00
, _snap_mode ( SnapOff )
, ignore_gui_changes ( false )
, _drags ( new DragManager ( this ) )
, lock_dialog ( 0 )
2015-07-08 12:45:36 -04:00
/* , last_event_time { 0, 0 } */ /* this initialization style requires C++11 */
2015-07-07 22:12:21 -04:00
, _dragging_playhead ( false )
, _follow_playhead ( true )
, _stationary_playhead ( false )
, _maximised ( false )
2018-02-09 10:59:39 -05:00
, grid_lines ( 0 )
2015-07-07 22:12:21 -04:00
, global_rect_group ( 0 )
, time_line_group ( 0 )
2016-04-13 14:16:24 -04:00
, tempo_marker_menu ( 0 )
, meter_marker_menu ( 0 )
2015-07-07 22:12:21 -04:00
, marker_menu ( 0 )
, range_marker_menu ( 0 )
, new_transport_marker_menu ( 0 )
, marker_menu_item ( 0 )
, bbt_beat_subdivision ( 4 )
, _visible_track_count ( - 1 )
, toolbar_selection_clock_table ( 2 , 3 )
, automation_mode_button ( _ ( " mode " ) )
2017-06-07 12:14:44 -04:00
, selection ( new Selection ( this , true ) )
, cut_buffer ( new Selection ( this , false ) )
2015-07-07 22:12:21 -04:00
, _selection_memento ( new SelectionMemento ( ) )
, _all_region_actions_sensitized ( false )
, _ignore_region_action ( false )
, _last_region_menu_was_main ( false )
2017-02-17 19:25:13 -05:00
, _track_selection_change_without_scroll ( false )
2017-10-21 11:27:03 -04:00
, _editor_track_selection_change_without_scroll ( false )
2015-07-07 22:12:21 -04:00
, cd_marker_bar_drag_rect ( 0 )
, range_bar_drag_rect ( 0 )
, transport_bar_drag_rect ( 0 )
, transport_bar_range_rect ( 0 )
, transport_bar_preroll_rect ( 0 )
, transport_bar_postroll_rect ( 0 )
, transport_loop_range_rect ( 0 )
, transport_punch_range_rect ( 0 )
, transport_punchin_line ( 0 )
, transport_punchout_line ( 0 )
, transport_preroll_rect ( 0 )
, transport_postroll_rect ( 0 )
, temp_location ( 0 )
, rubberband_rect ( 0 )
, _route_groups ( 0 )
, _routes ( 0 )
, _regions ( 0 )
, _snapshots ( 0 )
, _locations ( 0 )
, autoscroll_horizontal_allowed ( false )
, autoscroll_vertical_allowed ( false )
, autoscroll_cnt ( 0 )
, autoscroll_widget ( 0 )
, show_gain_after_trim ( false )
2014-12-22 08:30:23 -05:00
, selection_op_cmd_depth ( 0 )
, selection_op_history_it ( 0 )
2016-05-18 14:06:20 -04:00
, no_save_instant ( false )
2015-07-07 22:12:21 -04:00
, current_timefx ( 0 )
, current_mixer_strip ( 0 )
, show_editor_mixer_when_tracks_arrive ( false )
, nudge_clock ( new AudioClock ( X_ ( " nudge " ) , false , X_ ( " nudge " ) , true , false , true ) )
, current_stepping_trackview ( 0 )
, last_track_height_step_timestamp ( 0 )
, entered_track ( 0 )
, entered_regionview ( 0 )
, clear_entered_track ( false )
, _edit_point ( EditAtMouse )
, meters_running ( false )
, rhythm_ferret ( 0 )
, _have_idled ( false )
, resize_idle_id ( - 1 )
, _pending_resize_amount ( 0 )
, _pending_resize_view ( 0 )
2009-07-28 16:51:28 -04:00
, _pending_locate_request ( false )
2010-02-07 20:25:06 -05:00
, _pending_initial_locate ( false )
2015-07-07 22:12:21 -04:00
, _summary ( 0 )
, _group_tabs ( 0 )
, _last_motion_y ( 0 )
, layering_order_editor ( 0 )
2010-09-01 21:06:19 -04:00
, _last_cut_copy_source_track ( 0 )
2010-09-28 13:27:58 -04:00
, _region_selection_change_updates_region_list ( true )
2015-07-07 22:12:21 -04:00
, _cursors ( 0 )
2011-11-15 14:33:09 -05:00
, _following_mixer_selection ( false )
2012-05-31 10:39:48 -04:00
, _control_point_toggled_on_press ( false )
2012-06-17 12:57:21 -04:00
, _stepping_axis_view ( 0 )
2015-06-26 12:34:55 -04:00
, quantize_dialog ( 0 )
2015-05-06 12:10:41 -04:00
, _main_menu_disabler ( 0 )
2005-09-25 14:42:24 -04:00
{
/* we are a singleton */
PublicEditor : : _instance = this ;
2008-03-17 16:54:03 -04:00
_have_idled = false ;
2015-10-05 10:17:49 -04:00
2015-07-08 12:45:36 -04:00
last_event_time . tv_sec = 0 ;
last_event_time . tv_usec = 0 ;
2014-12-22 08:30:23 -05:00
selection_op_history . clear ( ) ;
2014-12-14 08:13:38 -05:00
before . clear ( ) ;
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
grid_type_strings = I18N ( _grid_type_strings ) ;
2007-11-07 20:40:25 -05:00
zoom_focus_strings = I18N ( _zoom_focus_strings ) ;
2014-07-09 16:48:19 -04:00
edit_mode_strings = I18N ( _edit_mode_strings ) ;
2007-11-07 20:40:25 -05:00
edit_point_strings = I18N ( _edit_point_strings ) ;
2008-01-10 17:22:29 -05:00
# ifdef USE_RUBBERBAND
rb_opt_strings = I18N ( _rb_opt_strings ) ;
2010-08-13 12:50:29 -04:00
rb_current_opt = 4 ;
2008-01-10 17:22:29 -05:00
# endif
2009-10-14 12:10:01 -04:00
2014-03-23 19:11:42 -04:00
build_edit_mode_menu ( ) ;
build_zoom_focus_menu ( ) ;
2014-03-25 08:21:08 -04:00
build_track_count_menu ( ) ;
2018-02-09 10:59:39 -05:00
build_grid_type_menu ( ) ;
2014-03-23 19:11:42 -04:00
build_edit_point_menu ( ) ;
2015-10-22 19:19:24 -04:00
location_marker_color = UIConfiguration : : instance ( ) . color ( " location marker " ) ;
location_range_color = UIConfiguration : : instance ( ) . color ( " location range " ) ;
location_cd_marker_color = UIConfiguration : : instance ( ) . color ( " location cd marker " ) ;
location_loop_color = UIConfiguration : : instance ( ) . color ( " location loop " ) ;
location_punch_color = UIConfiguration : : instance ( ) . color ( " location punch " ) ;
2006-03-12 22:27:58 -05:00
2017-05-05 07:58:59 -04:00
timebar_height = std : : max ( 12. , ceil ( 15. * UIConfiguration : : instance ( ) . get_ui_scale ( ) ) ) ;
2007-10-11 18:07:47 -04:00
2014-12-28 09:01:49 -05:00
TimeAxisView : : setup_sizes ( ) ;
2015-07-23 07:23:47 -04:00
ArdourMarker : : setup_sizes ( timebar_height ) ;
2016-05-07 13:54:52 -04:00
TempoCurve : : setup_sizes ( timebar_height ) ;
2014-12-28 09:01:49 -05:00
2013-01-24 08:17:36 -05:00
bbt_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
bbt_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
bbt_label . set_alignment ( 1.0 , 0.5 ) ;
bbt_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
bbt_label . hide ( ) ;
bbt_label . set_no_show_all ( ) ;
2013-01-24 08:17:36 -05:00
minsec_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
minsec_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
minsec_label . set_alignment ( 1.0 , 0.5 ) ;
minsec_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
minsec_label . hide ( ) ;
minsec_label . set_no_show_all ( ) ;
2013-01-24 08:17:36 -05:00
timecode_label . set_name ( " EditorRulerLabel " ) ;
2009-10-26 10:38:58 -04:00
timecode_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
timecode_label . set_alignment ( 1.0 , 0.5 ) ;
timecode_label . set_padding ( 5 , 0 ) ;
timecode_label . hide ( ) ;
timecode_label . set_no_show_all ( ) ;
2013-01-24 08:17:36 -05:00
samples_label . set_name ( " EditorRulerLabel " ) ;
2011-01-18 07:51:02 -05:00
samples_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
samples_label . set_alignment ( 1.0 , 0.5 ) ;
samples_label . set_padding ( 5 , 0 ) ;
samples_label . hide ( ) ;
samples_label . set_no_show_all ( ) ;
2008-09-10 17:27:39 -04:00
2013-01-24 08:17:36 -05:00
tempo_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
tempo_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
tempo_label . set_alignment ( 1.0 , 0.5 ) ;
tempo_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
tempo_label . hide ( ) ;
tempo_label . set_no_show_all ( ) ;
2011-06-01 13:00:29 -04:00
2013-01-24 08:17:36 -05:00
meter_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
meter_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2009-06-17 14:11:04 -04:00
meter_label . set_alignment ( 1.0 , 0.5 ) ;
2005-09-25 14:42:24 -04:00
meter_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
meter_label . hide ( ) ;
meter_label . set_no_show_all ( ) ;
2011-06-01 13:00:29 -04:00
2013-01-24 08:17:36 -05:00
mark_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
mark_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
mark_label . set_alignment ( 1.0 , 0.5 ) ;
mark_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
mark_label . hide ( ) ;
mark_label . set_no_show_all ( ) ;
2011-06-01 13:00:29 -04:00
2013-01-24 08:17:36 -05:00
cd_mark_label . set_name ( " EditorRulerLabel " ) ;
2008-01-10 16:20:59 -05:00
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 ) ;
2008-10-22 02:41:51 -04:00
cd_mark_label . hide ( ) ;
cd_mark_label . set_no_show_all ( ) ;
2011-06-01 13:00:29 -04:00
2013-03-12 17:00:09 -04:00
videotl_bar_height = 4 ;
videotl_label . set_name ( " EditorRulerLabel " ) ;
videotl_label . set_size_request ( - 1 , ( int ) timebar_height * videotl_bar_height ) ;
videotl_label . set_alignment ( 1.0 , 0.5 ) ;
videotl_label . set_padding ( 5 , 0 ) ;
videotl_label . hide ( ) ;
videotl_label . set_no_show_all ( ) ;
2013-01-24 08:17:36 -05:00
range_mark_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
range_mark_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
range_mark_label . set_alignment ( 1.0 , 0.5 ) ;
range_mark_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
range_mark_label . hide ( ) ;
range_mark_label . set_no_show_all ( ) ;
2011-06-01 13:00:29 -04:00
2013-01-24 08:17:36 -05:00
transport_mark_label . set_name ( " EditorRulerLabel " ) ;
2005-09-25 16:33:00 -04:00
transport_mark_label . set_size_request ( - 1 , ( int ) timebar_height ) ;
2005-09-25 14:42:24 -04:00
transport_mark_label . set_alignment ( 1.0 , 0.5 ) ;
transport_mark_label . set_padding ( 5 , 0 ) ;
2008-10-22 02:41:51 -04:00
transport_mark_label . hide ( ) ;
transport_mark_label . set_no_show_all ( ) ;
initialize_canvas ( ) ;
2011-06-01 13:00:29 -04:00
2016-09-06 16:17:39 -04:00
CairoWidget : : set_focus_handler ( sigc : : mem_fun ( ARDOUR_UI : : instance ( ) , & ARDOUR_UI : : reset_focus ) ) ;
2014-09-16 12:46:39 -04:00
2009-12-17 18:36:52 -05:00
_summary = new EditorSummary ( this ) ;
2008-09-10 17:27:39 -04:00
2009-12-11 18:29:48 -05:00
selection - > TimeChanged . connect ( sigc : : mem_fun ( * this , & Editor : : time_selection_changed ) ) ;
2018-02-11 10:39:45 -05:00
selection - > TracksChanged . connect ( sigc : : mem_fun ( * this , & Editor : : track_selection_changed ) ) ;
2011-06-01 13:00:29 -04:00
2009-12-11 18:29:48 -05:00
editor_regions_selection_changed_connection = selection - > RegionsChanged . connect ( sigc : : mem_fun ( * this , & Editor : : region_selection_changed ) ) ;
2011-06-01 13:00:29 -04:00
2009-12-11 18:29:48 -05:00
selection - > PointsChanged . connect ( sigc : : mem_fun ( * this , & Editor : : point_selection_changed ) ) ;
selection - > MarkersChanged . connect ( sigc : : mem_fun ( * this , & Editor : : marker_selection_changed ) ) ;
2008-10-22 02:41:51 -04:00
edit_controls_vbox . set_spacing ( 0 ) ;
2009-12-11 18:29:48 -05:00
vertical_adjustment . signal_value_changed ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : tie_vertical_scrolling ) , true ) ;
2013-04-04 00:32:52 -04:00
_track_canvas - > signal_map_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : track_canvas_map_handler ) ) ;
2008-10-22 02:41:51 -04:00
2009-06-20 09:41:55 -04:00
HBox * h = manage ( new HBox ) ;
_group_tabs = new EditorGroupTabs ( this ) ;
2019-09-25 15:02:31 -04:00
h - > pack_start ( * _group_tabs , PACK_SHRINK ) ;
2009-06-20 09:41:55 -04:00
h - > pack_start ( edit_controls_vbox ) ;
controls_layout . add ( * h ) ;
2009-10-14 12:10:01 -04:00
2008-10-22 02:41:51 -04:00
controls_layout . set_name ( " EditControlsBase " ) ;
2014-06-09 10:02:38 -04:00
controls_layout . add_events ( Gdk : : BUTTON_PRESS_MASK | Gdk : : BUTTON_RELEASE_MASK | Gdk : : ENTER_NOTIFY_MASK | Gdk : : LEAVE_NOTIFY_MASK | Gdk : : SCROLL_MASK ) ;
2009-12-11 18:29:48 -05:00
controls_layout . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : edit_controls_button_release ) ) ;
2014-06-09 10:02:38 -04:00
controls_layout . signal_scroll_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : control_layout_scroll ) , false ) ;
2008-10-22 02:41:51 -04:00
2010-11-16 09:53:16 -05:00
_cursors = new MouseCursors ;
2015-01-02 09:44:54 -05:00
_cursors - > set_cursor_set ( UIConfiguration : : instance ( ) . get_icon_set ( ) ) ;
cerr < < " Set cursor set to " < < UIConfiguration : : instance ( ) . get_icon_set ( ) < < endl ;
2008-10-22 02:41:51 -04:00
2014-12-20 01:11:28 -05:00
/* Push default cursor to ever-present bottom of cursor stack. */
push_canvas_cursor ( _cursors - > grabber ) ;
2013-04-05 11:27:26 -04:00
ArdourCanvas : : GtkCanvas * time_pad = manage ( new ArdourCanvas : : GtkCanvas ( ) ) ;
2011-06-01 13:00:29 -04:00
2013-04-04 18:45:27 -04:00
ArdourCanvas : : Line * pad_line_1 = new ArdourCanvas : : Line ( time_pad - > root ( ) ) ;
pad_line_1 - > set ( ArdourCanvas : : Duple ( 0.0 , 1.0 ) , ArdourCanvas : : Duple ( 100.0 , 1.0 ) ) ;
2013-04-04 00:32:52 -04:00
pad_line_1 - > set_outline_color ( 0xFF0000FF ) ;
2008-10-22 02:41:51 -04:00
pad_line_1 - > show ( ) ;
2011-06-01 13:00:29 -04:00
2018-02-24 07:54:15 -05:00
/* CAIROCANVAS */
2013-04-05 11:27:26 -04:00
time_pad - > show ( ) ;
2008-10-22 02:41:51 -04:00
2005-09-25 14:42:24 -04:00
edit_packer . set_col_spacings ( 0 ) ;
edit_packer . set_row_spacings ( 0 ) ;
edit_packer . set_homogeneous ( false ) ;
2006-03-17 12:39:21 -05:00
edit_packer . set_border_width ( 0 ) ;
2005-09-25 14:42:24 -04:00
edit_packer . set_name ( " EditorWindow " ) ;
2008-09-14 15:52:34 -04:00
2014-06-11 23:54:04 -04:00
time_bars_event_box . add ( time_bars_vbox ) ;
time_bars_event_box . set_events ( Gdk : : BUTTON_PRESS_MASK | Gdk : : BUTTON_RELEASE_MASK ) ;
time_bars_event_box . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : ruler_label_button_release ) ) ;
2018-02-19 09:05:55 -05:00
ArdourWidgets : : ArdourDropShadow * axis_view_shadow = manage ( new ( ArdourWidgets : : ArdourDropShadow ) ) ;
2018-02-24 07:54:15 -05:00
axis_view_shadow - > set_size_request ( 4 , - 1 ) ;
2018-02-19 09:05:55 -05:00
axis_view_shadow - > set_name ( " EditorWindow " ) ;
axis_view_shadow - > show ( ) ;
edit_packer . attach ( * axis_view_shadow , 0 , 1 , 0 , 2 , FILL , FILL | EXPAND , 0 , 0 ) ;
2014-06-11 23:54:04 -04:00
/* labels for the time bars */
2018-02-19 09:05:55 -05:00
edit_packer . attach ( time_bars_event_box , 1 , 2 , 0 , 1 , FILL , SHRINK , 0 , 0 ) ;
2009-06-17 14:11:04 -04:00
/* track controls */
2018-02-19 09:05:55 -05:00
edit_packer . attach ( controls_layout , 1 , 2 , 1 , 2 , FILL , FILL | EXPAND , 0 , 0 ) ;
2014-06-11 23:54:04 -04:00
/* canvas */
2018-02-19 09:05:55 -05:00
edit_packer . attach ( * _track_canvas_viewport , 2 , 3 , 0 , 2 , FILL | EXPAND , FILL | EXPAND , 0 , 0 ) ;
2005-09-25 14:42:24 -04:00
2006-06-30 04:03:43 -04:00
bottom_hbox . set_border_width ( 2 ) ;
2005-09-25 14:42:24 -04:00
bottom_hbox . set_spacing ( 3 ) ;
2017-05-05 07:31:49 -04:00
PresentationInfo : : Change . connect ( * this , MISSING_INVALIDATOR , boost : : bind ( & Editor : : presentation_info_changed , this , _1 ) , gui_context ( ) ) ;
2009-07-03 14:37:15 -04:00
_route_groups = new EditorRouteGroups ( this ) ;
_routes = new EditorRoutes ( this ) ;
2009-07-03 18:42:22 -04:00
_regions = new EditorRegions ( this ) ;
2018-11-15 10:21:55 -05:00
_sources = new EditorSources ( this ) ;
2009-07-03 19:51:58 -04:00
_snapshots = new EditorSnapshots ( this ) ;
2009-11-12 00:47:05 -05:00
_locations = new EditorLocations ( this ) ;
2017-03-10 14:39:46 -05:00
_time_info_box = new TimeInfoBox ( " EditorTimeInfo " , true ) ;
2005-09-25 14:42:24 -04:00
2014-09-17 09:37:39 -04:00
/* these are static location signals */
Location : : start_changed . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : location_changed , this , _1 ) , gui_context ( ) ) ;
Location : : end_changed . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : location_changed , this , _1 ) , gui_context ( ) ) ;
Location : : changed . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : location_changed , this , _1 ) , gui_context ( ) ) ;
2019-08-12 12:28:19 -04:00
add_notebook_page ( _ ( " Tracks & Busses " ) , _routes - > widget ( ) ) ;
2018-11-15 10:21:55 -05:00
add_notebook_page ( _ ( " Sources " ) , _sources - > widget ( ) ) ;
2011-01-04 21:06:51 -05:00
add_notebook_page ( _ ( " Regions " ) , _regions - > widget ( ) ) ;
add_notebook_page ( _ ( " Snapshots " ) , _snapshots - > widget ( ) ) ;
2012-04-28 11:25:59 -04:00
add_notebook_page ( _ ( " Track & Bus Groups " ) , _route_groups - > widget ( ) ) ;
2011-01-04 21:06:51 -05:00
add_notebook_page ( _ ( " Ranges & Marks " ) , _locations - > widget ( ) ) ;
_the_notebook . set_show_tabs ( true ) ;
_the_notebook . set_scrollable ( true ) ;
_the_notebook . popup_disable ( ) ;
_the_notebook . set_tab_pos ( Gtk : : POS_RIGHT ) ;
_the_notebook . show_all ( ) ;
_notebook_shrunk = false ;
2009-06-17 16:10:43 -04:00
2016-05-26 10:46:28 -04:00
/* Pick up some settings we need to cache, early */
XMLNode * settings = ARDOUR_UI : : instance ( ) - > editor_settings ( ) ;
2016-08-26 23:44:57 -04:00
if ( settings ) {
settings - > get_property ( " notebook-shrunk " , _notebook_shrunk ) ;
2016-05-26 10:46:28 -04:00
}
2016-06-13 09:53:10 -04:00
editor_summary_pane . set_check_divider_position ( true ) ;
2016-05-26 10:46:28 -04:00
editor_summary_pane . add ( edit_packer ) ;
2009-11-20 10:26:34 -05:00
2017-07-18 11:37:35 -04:00
Button * summary_arrow_left = manage ( new Button ) ;
summary_arrow_left - > add ( * manage ( new Arrow ( ARROW_LEFT , SHADOW_NONE ) ) ) ;
summary_arrow_left - > signal_pressed ( ) . connect ( sigc : : hide_return ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : scroll_press ) , LEFT ) ) ) ;
summary_arrow_left - > signal_released ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : scroll_release ) ) ;
2011-06-01 13:00:29 -04:00
2017-07-18 11:37:35 -04:00
Button * summary_arrow_right = manage ( new Button ) ;
summary_arrow_right - > add ( * manage ( new Arrow ( ARROW_RIGHT , SHADOW_NONE ) ) ) ;
summary_arrow_right - > signal_pressed ( ) . connect ( sigc : : hide_return ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : scroll_press ) , RIGHT ) ) ) ;
summary_arrow_right - > signal_released ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : scroll_release ) ) ;
2011-06-01 13:00:29 -04:00
2009-11-30 23:10:06 -05:00
VBox * summary_arrows_left = manage ( new VBox ) ;
2017-07-18 11:37:35 -04:00
summary_arrows_left - > pack_start ( * summary_arrow_left ) ;
2011-06-01 13:00:29 -04:00
2009-11-30 23:10:06 -05:00
VBox * summary_arrows_right = manage ( new VBox ) ;
2017-07-18 11:37:35 -04:00
summary_arrows_right - > pack_start ( * summary_arrow_right ) ;
2009-11-30 23:10:06 -05:00
2018-06-09 13:08:15 -04:00
Frame * summary_frame = manage ( new Frame ) ;
summary_frame - > set_shadow_type ( Gtk : : SHADOW_ETCHED_IN ) ;
2011-06-01 13:00:29 -04:00
2018-06-09 13:08:15 -04:00
summary_frame - > add ( * _summary ) ;
summary_frame - > show ( ) ;
2009-11-20 10:26:34 -05:00
2009-12-21 20:13:06 -05:00
_summary_hbox . pack_start ( * summary_arrows_left , false , false ) ;
2018-06-09 13:08:15 -04:00
_summary_hbox . pack_start ( * summary_frame , true , true ) ;
2009-12-21 20:13:06 -05:00
_summary_hbox . pack_start ( * summary_arrows_right , false , false ) ;
2011-06-01 13:00:29 -04:00
2019-09-25 15:02:31 -04:00
editor_summary_pane . add ( _summary_hbox ) ;
2016-06-13 09:53:10 -04:00
edit_pane . set_check_divider_position ( true ) ;
2016-05-26 10:46:28 -04:00
edit_pane . add ( editor_summary_pane ) ;
2019-09-25 15:02:31 -04:00
_editor_list_vbox . pack_start ( * _time_info_box , false , false , 0 ) ;
_editor_list_vbox . pack_start ( _the_notebook ) ;
edit_pane . add ( _editor_list_vbox ) ;
edit_pane . set_child_minsize ( _editor_list_vbox , 30 ) ; /* rough guess at width of notebook tabs */
2009-10-14 12:10:01 -04:00
2016-05-27 21:26:56 -04:00
edit_pane . set_drag_cursor ( * _cursors - > expand_left_right ) ;
editor_summary_pane . set_drag_cursor ( * _cursors - > expand_up_down ) ;
2010-06-07 21:29:33 -04:00
2016-05-29 13:43:56 -04:00
float fract ;
2016-09-04 18:02:36 -04:00
if ( ! settings | | ! settings - > get_property ( " edit-horizontal-pane-pos " , fract ) | | fract > 1.0 ) {
/* initial allocation is 90% to canvas, 10% to notebook */
fract = 0.90 ;
}
edit_pane . set_divider ( 0 , fract ) ;
2016-05-29 13:43:56 -04:00
2016-09-04 18:02:36 -04:00
if ( ! settings | | ! settings - > get_property ( " edit-vertical-pane-pos " , fract ) | | fract > 1.0 ) {
/* initial allocation is 90% to canvas, 10% to summary */
fract = 0.90 ;
2016-05-26 10:46:28 -04:00
}
2016-09-04 18:02:36 -04:00
editor_summary_pane . set_divider ( 0 , fract ) ;
2012-06-22 12:48:56 -04:00
2018-02-19 09:05:55 -05:00
global_vpacker . set_spacing ( 0 ) ;
2016-12-18 10:02:13 -05:00
global_vpacker . set_border_width ( 0 ) ;
2016-12-18 14:29:19 -05:00
2018-02-24 07:54:15 -05:00
/* the next three EventBoxes provide the ability for their child widgets to have a background color. That is all. */
2017-01-18 19:28:21 -05:00
2018-02-24 07:54:15 -05:00
Gtk : : EventBox * ebox = manage ( new Gtk : : EventBox ) ; // a themeable box
2017-01-18 19:21:48 -05:00
ebox - > set_name ( " EditorWindow " ) ;
2018-02-19 09:05:55 -05:00
ebox - > add ( ebox_hpacker ) ;
2017-01-18 19:21:48 -05:00
2018-02-24 07:54:15 -05:00
Gtk : : EventBox * epane_box = manage ( new EventBoxExt ) ; // a themeable box
2017-01-18 19:21:48 -05:00
epane_box - > set_name ( " EditorWindow " ) ;
epane_box - > add ( edit_pane ) ;
2018-02-24 07:54:15 -05:00
Gtk : : EventBox * epane_box2 = manage ( new EventBoxExt ) ; // a themeable box
2017-01-18 19:21:48 -05:00
epane_box2 - > set_name ( " EditorWindow " ) ;
epane_box2 - > add ( global_vpacker ) ;
2018-02-19 09:05:55 -05:00
ArdourWidgets : : ArdourDropShadow * toolbar_shadow = manage ( new ( ArdourWidgets : : ArdourDropShadow ) ) ;
2018-02-24 07:54:15 -05:00
toolbar_shadow - > set_size_request ( - 1 , 4 ) ;
2018-02-19 09:05:55 -05:00
toolbar_shadow - > set_mode ( ArdourWidgets : : ArdourDropShadow : : DropShadowBoth ) ;
toolbar_shadow - > set_name ( " EditorWindow " ) ;
2018-02-24 07:54:15 -05:00
toolbar_shadow - > show ( ) ;
2018-02-19 09:05:55 -05:00
global_vpacker . pack_start ( * toolbar_shadow , false , false ) ;
2017-01-18 19:21:48 -05:00
global_vpacker . pack_start ( * ebox , false , false ) ;
global_vpacker . pack_start ( * epane_box , true , true ) ;
global_hpacker . pack_start ( * epane_box2 , true , true ) ;
2005-09-25 14:42:24 -04:00
2015-07-27 17:12:35 -04:00
/* need to show the "contents" widget so that notebook will show if tab is switched to
*/
2015-10-26 14:35:06 -04:00
global_hpacker . show ( ) ;
2018-02-19 09:05:55 -05:00
ebox_hpacker . show ( ) ;
ebox - > show ( ) ;
2015-07-27 17:12:35 -04:00
2005-12-31 13:20:42 -05:00
/* register actions now so that set_state() can find them and set toggles/checks etc */
2009-10-14 12:10:01 -04:00
2015-07-15 15:05:30 -04:00
load_bindings ( ) ;
2018-12-11 05:06:26 -05:00
register_actions ( ) ;
2008-01-10 16:20:59 -05:00
2009-09-12 13:49:57 -04:00
setup_toolbar ( ) ;
2005-09-25 14:42:24 -04:00
_playlist_selector = new PlaylistSelector ( ) ;
2009-12-11 18:29:48 -05:00
_playlist_selector - > signal_delete_event ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( just_hide_it ) , static_cast < Window * > ( _playlist_selector ) ) ) ;
2005-09-25 14:42:24 -04:00
2012-04-25 08:58:19 -04:00
RegionView : : RegionViewGoingAway . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : catch_vanishing_regionview , this , _1 ) , gui_context ( ) ) ;
2005-09-25 14:42:24 -04:00
/* nudge stuff */
2014-03-23 19:11:42 -04:00
nudge_forward_button . set_name ( " nudge button " ) ;
2015-05-24 15:45:39 -04:00
nudge_forward_button . set_icon ( ArdourIcon : : NudgeRight ) ;
2005-09-25 14:42:24 -04:00
2014-03-23 19:11:42 -04:00
nudge_backward_button . set_name ( " nudge button " ) ;
2015-05-24 15:45:39 -04:00
nudge_backward_button . set_icon ( ArdourIcon : : NudgeLeft ) ;
2005-09-25 14:42:24 -04:00
fade_context_menu . set_name ( " ArdourContextMenu " ) ;
2013-07-23 11:15:23 -04:00
Gtkmm2ext : : Keyboard : : the_keyboard ( ) . ZoomVerticalModifierReleased . connect ( sigc : : mem_fun ( * this , & Editor : : zoom_vertical_modifier_released ) ) ;
2015-10-05 10:17:49 -04:00
2006-04-05 21:52:45 -04:00
/* allow external control surfaces/protocols to do various things */
2010-03-30 11:18:43 -04:00
ControlProtocol : : ZoomToSession . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : temporal_zoom_session , this ) , gui_context ( ) ) ;
ControlProtocol : : ZoomIn . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : temporal_zoom_step , this , false ) , gui_context ( ) ) ;
ControlProtocol : : ZoomOut . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : temporal_zoom_step , this , true ) , gui_context ( ) ) ;
2012-04-09 11:50:38 -04:00
ControlProtocol : : Undo . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : undo , this , true ) , gui_context ( ) ) ;
ControlProtocol : : Redo . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : redo , this , true ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
ControlProtocol : : ScrollTimeline . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_scroll , this , _1 ) , gui_context ( ) ) ;
2012-04-25 23:46:18 -04:00
ControlProtocol : : StepTracksUp . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_step_tracks_up , this ) , gui_context ( ) ) ;
ControlProtocol : : StepTracksDown . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_step_tracks_down , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
ControlProtocol : : GotoView . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_view , this , _1 ) , gui_context ( ) ) ;
2012-04-09 14:53:51 -04:00
ControlProtocol : : CloseDialog . connect ( * this , invalidator ( * this ) , Keyboard : : close_current_dialog , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
ControlProtocol : : VerticalZoomInAll . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_vertical_zoom_in_all , this ) , gui_context ( ) ) ;
ControlProtocol : : VerticalZoomOutAll . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_vertical_zoom_out_all , this ) , gui_context ( ) ) ;
ControlProtocol : : VerticalZoomInSelected . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_vertical_zoom_in_selected , this ) , gui_context ( ) ) ;
ControlProtocol : : VerticalZoomOutSelected . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_vertical_zoom_out_selected , this ) , gui_context ( ) ) ;
2012-04-09 14:53:51 -04:00
2016-07-06 13:37:30 -04:00
ControlProtocol : : AddStripableToSelection . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_select , this , _1 , Selection : : Add ) , gui_context ( ) ) ;
ControlProtocol : : RemoveStripableFromSelection . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_select , this , _1 , Selection : : Toggle ) , gui_context ( ) ) ;
ControlProtocol : : SetStripableSelection . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_select , this , _1 , Selection : : Set ) , gui_context ( ) ) ;
ControlProtocol : : ToggleStripableSelection . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_select , this , _1 , Selection : : Toggle ) , gui_context ( ) ) ;
ControlProtocol : : ClearStripableSelection . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : control_unselect , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
BasicUI : : AccessAction . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : access_action , this , _1 , _2 ) , gui_context ( ) ) ;
2011-06-01 13:00:29 -04:00
2016-05-21 08:34:09 -04:00
/* handle escape */
ARDOUR_UI : : instance ( ) - > Escape . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : escape , this ) , gui_context ( ) ) ;
2009-12-21 13:23:07 -05:00
/* problematic: has to return a value and thus cannot be x-thread */
Session : : AskAboutPlaylistDeletion . connect_same_thread ( * this , boost : : bind ( & Editor : : playlist_deletion_dialog , this , _1 ) ) ;
2006-09-18 23:29:16 -04:00
2012-04-25 08:58:19 -04:00
Config - > ParameterChanged . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : parameter_changed , this , _1 ) , gui_context ( ) ) ;
2015-01-02 09:44:54 -05:00
UIConfiguration : : instance ( ) . ParameterChanged . connect ( sigc : : mem_fun ( * this , & Editor : : ui_parameter_changed ) ) ;
2006-10-21 15:01:50 -04:00
2012-04-25 08:58:19 -04:00
TimeAxisView : : CatchDeletion . connect ( * this , invalidator ( * this ) , boost : : bind ( & Editor : : timeaxisview_deleted , this , _1 ) , gui_context ( ) ) ;
2009-12-25 16:06:52 -05:00
2010-11-03 18:19:29 -04:00
_ignore_region_action = false ;
2010-11-03 22:05:08 -04:00
_last_region_menu_was_main = false ;
2010-11-03 18:19:29 -04:00
2010-11-10 13:29:32 -05:00
_show_marker_lines = false ;
2017-07-01 12:42:24 -04:00
/* Button bindings */
2011-03-03 22:10:48 -05:00
2015-08-08 08:36:29 -04:00
button_bindings = new Bindings ( " editor-mouse " ) ;
2011-03-03 22:10:48 -05:00
XMLNode * node = button_settings ( ) ;
2017-07-01 12:42:24 -04:00
if ( node ) {
for ( XMLNodeList : : const_iterator i = node - > children ( ) . begin ( ) ; i ! = node - > children ( ) . end ( ) ; + + i ) {
button_bindings - > load_operation ( * * i ) ;
}
}
2011-03-03 22:10:48 -05:00
2005-09-25 14:42:24 -04:00
constructed = true ;
2014-06-30 16:32:38 -04:00
/* grab current parameter state */
boost : : function < void ( string ) > pc ( boost : : bind ( & Editor : : ui_parameter_changed , this , _1 ) ) ;
2015-01-02 09:44:54 -05:00
UIConfiguration : : instance ( ) . map_parameters ( pc ) ;
2010-09-18 23:31:03 -04:00
setup_fade_images ( ) ;
2014-06-30 16:32:38 -04:00
2018-02-09 10:59:39 -05:00
set_grid_to ( GridTypeNone ) ;
2005-09-25 14:42:24 -04:00
}
Editor : : ~ Editor ( )
{
2019-03-07 10:40:16 -05:00
delete tempo_marker_menu ;
delete meter_marker_menu ;
2019-03-07 15:24:15 -05:00
delete marker_menu ;
delete range_marker_menu ;
delete new_transport_marker_menu ;
2019-03-07 10:40:16 -05:00
delete editor_ruler_menu ;
delete _popup_region_menu_item ;
2016-07-25 11:38:59 -04:00
delete button_bindings ;
2009-07-03 14:37:15 -04:00
delete _routes ;
delete _route_groups ;
2013-04-04 00:32:52 -04:00
delete _track_canvas_viewport ;
2010-01-12 11:14:49 -05:00
delete _drags ;
2014-09-10 20:34:09 -04:00
delete nudge_clock ;
2016-07-25 11:38:59 -04:00
delete _verbose_cursor ;
2015-06-26 12:34:55 -04:00
delete quantize_dialog ;
2015-09-12 14:05:46 -04:00
delete _summary ;
delete _group_tabs ;
delete _regions ;
delete _snapshots ;
delete _locations ;
delete _playlist_selector ;
2016-12-16 20:31:41 -05:00
delete _time_info_box ;
2017-01-20 05:48:59 -05:00
delete selection ;
delete cut_buffer ;
delete _cursors ;
LuaInstance : : destroy_instance ( ) ;
2015-11-02 13:25:15 -05:00
for ( list < XMLNode * > : : iterator i = selection_op_history . begin ( ) ; i ! = selection_op_history . end ( ) ; + + i ) {
delete * i ;
}
2017-01-20 05:48:59 -05:00
for ( std : : map < ARDOUR : : FadeShape , Gtk : : Image * > : : const_iterator i = _xfade_in_images . begin ( ) ; i ! = _xfade_in_images . end ( ) ; + + i ) {
delete i - > second ;
}
for ( std : : map < ARDOUR : : FadeShape , Gtk : : Image * > : : const_iterator i = _xfade_out_images . begin ( ) ; i ! = _xfade_out_images . end ( ) ; + + i ) {
delete i - > second ;
}
2005-09-25 14:42:24 -04:00
}
2011-03-03 22:10:48 -05:00
XMLNode *
Editor : : button_settings ( ) const
{
XMLNode * settings = ARDOUR_UI : : instance ( ) - > editor_settings ( ) ;
XMLNode * node = find_named_node ( * settings , X_ ( " Buttons " ) ) ;
if ( ! node ) {
node = new XMLNode ( X_ ( " Buttons " ) ) ;
}
return node ;
}
2012-11-20 14:43:43 -05:00
bool
Editor : : get_smart_mode ( ) const
{
2018-02-09 10:59:39 -05:00
return ( ( current_mouse_mode ( ) = = MouseObject ) & & smart_mode_action - > get_active ( ) ) ;
2012-11-20 14:43:43 -05:00
}
2005-09-25 14:42:24 -04:00
void
2006-07-23 08:03:19 -04:00
Editor : : catch_vanishing_regionview ( RegionView * rv )
2005-09-25 14:42:24 -04:00
{
/* note: the selection will take care of the vanishing
audioregionview by itself .
*/
2010-01-12 11:14:49 -05:00
if ( _drags - > active ( ) & & _drags - > have_item ( rv - > get_canvas_group ( ) ) & & ! _drags - > ending ( ) ) {
_drags - > abort ( ) ;
2009-02-27 20:52:45 -05:00
}
2005-09-25 14:42:24 -04:00
if ( clicked_regionview = = rv ) {
clicked_regionview = 0 ;
}
if ( entered_regionview = = rv ) {
set_entered_regionview ( 0 ) ;
}
2010-11-03 18:19:29 -04:00
if ( ! _all_region_actions_sensitized ) {
sensitize_all_region_actions ( true ) ;
}
2005-09-25 14:42:24 -04:00
}
void
2006-07-23 08:03:19 -04:00
Editor : : set_entered_regionview ( RegionView * rv )
2005-09-25 14:42:24 -04:00
{
if ( rv = = entered_regionview ) {
return ;
}
if ( entered_regionview ) {
entered_regionview - > exited ( ) ;
}
2014-06-18 10:24:59 -04:00
entered_regionview = rv ;
if ( entered_regionview ! = 0 ) {
2014-12-08 23:00:00 -05:00
entered_regionview - > entered ( ) ;
2005-09-25 14:42:24 -04:00
}
2010-11-03 18:19:29 -04:00
2010-11-03 22:05:08 -04:00
if ( ! _all_region_actions_sensitized & & _last_region_menu_was_main ) {
2010-11-03 18:19:29 -04:00
/* This RegionView entry might have changed what region actions
are allowed , so sensitize them all in case a key is pressed .
*/
sensitize_all_region_actions ( true ) ;
}
2005-09-25 14:42:24 -04:00
}
void
2009-07-09 13:58:13 -04:00
Editor : : set_entered_track ( TimeAxisView * tav )
2005-09-25 14:42:24 -04:00
{
if ( entered_track ) {
entered_track - > exited ( ) ;
}
2014-06-18 10:24:59 -04:00
entered_track = tav ;
if ( entered_track ) {
2005-09-25 14:42:24 -04:00
entered_track - > entered ( ) ;
}
}
void
Editor : : instant_save ( )
{
2018-12-06 21:36:48 -05:00
if ( ! constructed | | ! _session | | no_save_instant ) {
2005-09-25 14:42:24 -04:00
return ;
}
2018-12-06 21:36:48 -05:00
_session - > add_instant_xml ( get_state ( ) ) ;
2005-09-25 14:42:24 -04:00
}
2012-04-09 14:53:51 -04:00
void
Editor : : control_vertical_zoom_in_all ( )
{
tav_zoom_smooth ( false , true ) ;
}
void
Editor : : control_vertical_zoom_out_all ( )
{
tav_zoom_smooth ( true , true ) ;
}
void
Editor : : control_vertical_zoom_in_selected ( )
{
tav_zoom_smooth ( false , false ) ;
}
void
Editor : : control_vertical_zoom_out_selected ( )
{
tav_zoom_smooth ( true , false ) ;
}
void
Editor : : control_view ( uint32_t view )
{
goto_visual_state ( view ) ;
}
2012-04-09 12:15:55 -04:00
void
Editor : : control_unselect ( )
{
selection - > clear_tracks ( ) ;
}
2016-07-06 13:37:30 -04:00
void
Editor : : control_select ( boost : : shared_ptr < Stripable > s , Selection : : Operation op )
{
2017-05-05 07:31:49 -04:00
TimeAxisView * tav = time_axis_view_from_stripable ( s ) ;
2016-07-06 13:37:30 -04:00
if ( tav ) {
switch ( op ) {
case Selection : : Add :
selection - > add ( tav ) ;
break ;
case Selection : : Toggle :
selection - > toggle ( tav ) ;
break ;
case Selection : : Extend :
break ;
case Selection : : Set :
selection - > set ( tav ) ;
break ;
}
} else {
selection - > clear_tracks ( ) ;
}
}
2012-04-25 23:46:18 -04:00
void
Editor : : control_step_tracks_up ( )
{
scroll_tracks_up_line ( ) ;
}
void
Editor : : control_step_tracks_down ( )
{
scroll_tracks_down_line ( ) ;
}
2006-04-06 12:51:27 -04:00
void
Editor : : control_scroll ( float fraction )
{
2009-12-11 18:29:48 -05:00
ENSURE_GUI_THREAD ( * this , & Editor : : control_scroll , fraction )
2006-04-06 12:51:27 -04:00
2009-12-17 13:24:23 -05:00
if ( ! _session ) {
2006-04-06 12:51:27 -04:00
return ;
}
2013-04-12 11:21:12 -04:00
double step = fraction * current_page_samples ( ) ;
2006-04-06 12:51:27 -04:00
2007-10-11 18:07:47 -04:00
/*
_control_scroll_target is an optional < T >
2009-10-14 12:10:01 -04:00
2017-09-18 12:39:17 -04:00
it acts like a pointer to an samplepos_t , with
2007-10-11 18:07:47 -04:00
a operator conversion to boolean to check
that it has a value could possibly use
2017-09-18 12:39:17 -04:00
playhead_cursor - > current_sample to store the
2007-10-11 18:07:47 -04:00
value and a boolean in the class to know
when it ' s out of date
*/
if ( ! _control_scroll_target ) {
2017-09-18 12:39:17 -04:00
_control_scroll_target = _session - > transport_sample ( ) ;
2007-10-11 18:07:47 -04:00
_dragging_playhead = true ;
}
2017-09-18 12:39:17 -04:00
if ( ( fraction < 0.0f ) & & ( * _control_scroll_target < = ( samplepos_t ) fabs ( step ) ) ) {
2007-10-11 18:07:47 -04:00
* _control_scroll_target = 0 ;
2017-09-18 12:39:17 -04:00
} else if ( ( fraction > 0.0f ) & & ( max_samplepos - * _control_scroll_target < step ) ) {
* _control_scroll_target = max_samplepos - ( current_page_samples ( ) * 2 ) ; // allow room for slop in where the PH is on the screen
2006-04-06 12:51:27 -04:00
} else {
2017-09-18 12:39:17 -04:00
* _control_scroll_target + = ( samplepos_t ) trunc ( step ) ;
2006-04-06 12:51:27 -04:00
}
/* move visuals, we'll catch up with it later */
2007-10-11 18:07:47 -04:00
playhead_cursor - > set_position ( * _control_scroll_target ) ;
UpdateAllTransportClocks ( * _control_scroll_target ) ;
2009-10-14 12:10:01 -04:00
2013-04-12 11:21:12 -04:00
if ( * _control_scroll_target > ( current_page_samples ( ) / 2 ) ) {
2006-04-06 12:51:27 -04:00
/* try to center PH in window */
2013-04-12 11:21:12 -04:00
reset_x_origin ( * _control_scroll_target - ( current_page_samples ( ) / 2 ) ) ;
2006-04-06 12:51:27 -04:00
} else {
2007-01-11 15:36:35 -05:00
reset_x_origin ( 0 ) ;
2006-04-06 12:51:27 -04:00
}
2007-10-11 18:07:47 -04:00
/*
Now we do a timeout to actually bring the session to the right place
according to the playhead . This is to avoid reading disk buffers on every
call to control_scroll , which is driven by ScrollTimeline and therefore
probably by a control surface wheel which can generate lots of events .
*/
/* cancel the existing timeout */
2006-04-06 12:51:27 -04:00
control_scroll_connection . disconnect ( ) ;
2007-10-11 18:07:47 -04:00
/* add the next timeout */
2006-04-06 12:51:27 -04:00
2009-12-11 18:29:48 -05:00
control_scroll_connection = Glib : : signal_timeout ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : deferred_control_scroll ) , * _control_scroll_target ) , 250 ) ;
2006-04-06 12:51:27 -04:00
}
bool
2017-09-18 12:39:17 -04:00
Editor : : deferred_control_scroll ( samplepos_t /*target*/ )
2006-04-06 12:51:27 -04:00
{
2020-01-17 18:35:28 -05:00
_session - > request_locate ( * _control_scroll_target , RollIfAppropriate ) ;
2018-02-24 07:54:15 -05:00
/* reset for next stream */
2007-10-11 18:07:47 -04:00
_control_scroll_target = boost : : none ;
_dragging_playhead = false ;
2006-04-06 12:51:27 -04:00
return false ;
}
2008-09-10 11:03:30 -04:00
void
2017-08-09 08:04:05 -04:00
Editor : : access_action ( const std : : string & action_group , const std : : string & action_item )
2008-09-10 11:03:30 -04:00
{
2009-12-17 13:24:23 -05:00
if ( ! _session ) {
2008-09-10 11:03:30 -04:00
return ;
}
2009-12-11 18:29:48 -05:00
ENSURE_GUI_THREAD ( * this , & Editor : : access_action , action_group , action_item )
2008-09-10 11:03:30 -04:00
RefPtr < Action > act ;
2019-03-19 12:52:19 -04:00
try {
act = ActionManager : : get_action ( action_group . c_str ( ) , action_item . c_str ( ) ) ;
if ( act ) {
act - > activate ( ) ;
}
} catch ( ActionManager : : MissingActionException const & e ) {
cerr < < " MissingActionException: " < < e . what ( ) < < endl ;
2008-09-10 11:03:30 -04:00
}
}
2017-08-09 08:04:05 -04:00
void
Editor : : set_toggleaction ( const std : : string & action_group , const std : : string & action_item , bool s )
{
ActionManager : : set_toggleaction_state ( action_group . c_str ( ) , action_item . c_str ( ) , s ) ;
}
2005-09-25 14:42:24 -04:00
void
2005-09-25 22:48:59 -04:00
Editor : : on_realize ( )
2005-09-25 14:42:24 -04:00
{
2005-12-21 16:37:18 -05:00
Realized ( ) ;
2014-06-25 08:28:36 -04:00
2015-01-02 09:44:54 -05:00
if ( UIConfiguration : : instance ( ) . get_lock_gui_after_seconds ( ) ) {
2014-06-25 11:34:37 -04:00
start_lock_event_timing ( ) ;
}
2014-06-25 08:28:36 -04:00
}
void
Editor : : start_lock_event_timing ( )
{
/* check if we should lock the GUI every 30 seconds */
Glib : : signal_timeout ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : lock_timeout_callback ) , 30 * 1000 ) ;
}
bool
Editor : : generic_event_handler ( GdkEvent * ev )
{
switch ( ev - > type ) {
case GDK_BUTTON_PRESS :
case GDK_BUTTON_RELEASE :
case GDK_MOTION_NOTIFY :
case GDK_KEY_PRESS :
case GDK_KEY_RELEASE :
2015-07-07 22:12:21 -04:00
if ( contents ( ) . is_mapped ( ) ) {
gettimeofday ( & last_event_time , 0 ) ;
}
2014-06-25 08:28:36 -04:00
break ;
2014-09-16 12:46:39 -04:00
case GDK_LEAVE_NOTIFY :
switch ( ev - > crossing . detail ) {
case GDK_NOTIFY_UNKNOWN :
case GDK_NOTIFY_INFERIOR :
case GDK_NOTIFY_ANCESTOR :
2015-10-04 14:51:05 -04:00
break ;
2014-09-16 12:46:39 -04:00
case GDK_NOTIFY_VIRTUAL :
case GDK_NOTIFY_NONLINEAR :
case GDK_NOTIFY_NONLINEAR_VIRTUAL :
/* leaving window, so reset focus, thus ending any and
all text entry operations .
*/
2016-09-06 16:17:39 -04:00
ARDOUR_UI : : instance ( ) - > reset_focus ( & contents ( ) ) ;
2014-09-16 12:46:39 -04:00
break ;
}
break ;
2014-06-25 08:28:36 -04:00
default :
break ;
}
2014-09-16 12:46:39 -04:00
2014-06-25 08:28:36 -04:00
return false ;
}
bool
Editor : : lock_timeout_callback ( )
{
struct timeval now , delta ;
gettimeofday ( & now , 0 ) ;
timersub ( & now , & last_event_time , & delta ) ;
2015-01-02 09:44:54 -05:00
if ( delta . tv_sec > ( time_t ) UIConfiguration : : instance ( ) . get_lock_gui_after_seconds ( ) ) {
2014-06-25 08:28:36 -04:00
lock ( ) ;
/* don't call again. Returning false will effectively
disconnect us from the timer callback .
unlock ( ) will call start_lock_event_timing ( ) to get things
started again .
*/
return false ;
}
return true ;
2005-09-25 14:42:24 -04:00
}
void
2017-09-18 12:39:17 -04:00
Editor : : map_position_change ( samplepos_t sample )
2005-09-25 14:42:24 -04:00
{
2017-09-18 12:39:17 -04:00
ENSURE_GUI_THREAD ( * this , & Editor : : map_position_change , sample )
2005-09-25 14:42:24 -04:00
2010-07-08 20:58:20 -04:00
if ( _session = = 0 ) {
2005-09-25 14:42:24 -04:00
return ;
}
2010-07-08 20:58:20 -04:00
if ( _follow_playhead ) {
2017-09-18 12:39:17 -04:00
center_screen ( sample ) ;
2010-07-08 20:58:20 -04:00
}
2020-03-25 20:35:28 -04:00
if ( ! _session - > locate_initiated ( ) ) {
playhead_cursor - > set_position ( sample ) ;
}
2009-10-14 12:10:01 -04:00
}
2005-09-25 14:42:24 -04:00
void
2017-09-18 12:39:17 -04:00
Editor : : center_screen ( samplepos_t sample )
2005-09-25 14:42:24 -04:00
{
2017-09-18 12:39:17 -04:00
samplecnt_t const page = _visible_canvas_width * samples_per_pixel ;
2005-09-25 14:42:24 -04:00
/* if we're off the page, then scroll.
*/
2009-10-14 12:10:01 -04:00
2017-09-18 12:39:17 -04:00
if ( sample < _leftmost_sample | | sample > = _leftmost_sample + page ) {
center_screen_internal ( sample , page ) ;
2005-09-25 14:42:24 -04:00
}
}
void
2017-09-18 12:39:17 -04:00
Editor : : center_screen_internal ( samplepos_t sample , float page )
2005-09-25 14:42:24 -04:00
{
page / = 2 ;
2009-10-14 12:10:01 -04:00
2017-09-18 12:39:17 -04:00
if ( sample > page ) {
sample - = ( samplepos_t ) page ;
2005-09-25 14:42:24 -04:00
} else {
2017-09-18 12:39:17 -04:00
sample = 0 ;
2005-09-25 14:42:24 -04:00
}
2017-09-18 12:39:17 -04:00
reset_x_origin ( sample ) ;
2005-09-25 14:42:24 -04:00
}
void
Editor : : update_title ( )
{
2015-07-07 22:12:21 -04:00
ENSURE_GUI_THREAD ( * this , & Editor : : update_title ) ;
2005-09-25 14:42:24 -04:00
2015-07-07 22:12:21 -04:00
if ( ! own_window ( ) ) {
return ;
}
2015-10-26 14:35:06 -04:00
2009-12-17 13:24:23 -05:00
if ( _session ) {
bool dirty = _session - > dirty ( ) ;
2005-09-25 14:42:24 -04:00
2007-03-19 03:07:38 -04:00
string session_name ;
2005-09-25 14:42:24 -04:00
2009-12-17 13:24:23 -05:00
if ( _session - > snap_name ( ) ! = _session - > name ( ) ) {
session_name = _session - > snap_name ( ) ;
2007-03-19 03:07:38 -04:00
} else {
2009-12-17 13:24:23 -05:00
session_name = _session - > name ( ) ;
2005-09-25 14:42:24 -04:00
}
if ( dirty ) {
2007-03-19 03:07:38 -04:00
session_name = " * " + session_name ;
2005-09-25 14:42:24 -04:00
}
2007-03-19 03:07:38 -04:00
WindowTitle title ( session_name ) ;
2015-11-16 13:06:20 -05:00
title + = S_ ( " Window|Editor " ) ;
2007-03-19 03:07:38 -04:00
title + = Glib : : get_application_name ( ) ;
2015-07-07 22:12:21 -04:00
own_window ( ) - > set_title ( title . get_string ( ) ) ;
2012-10-10 11:19:58 -04:00
} else {
/* ::session_going_away() will have taken care of it */
2005-09-25 14:42:24 -04:00
}
}
void
2009-12-17 13:24:23 -05:00
Editor : : set_session ( Session * t )
2005-09-25 14:42:24 -04:00
{
2009-12-17 13:24:23 -05:00
SessionHandlePtr : : set_session ( t ) ;
2009-12-17 18:36:52 -05:00
if ( ! _session ) {
return ;
}
2018-02-24 07:54:15 -05:00
/* initialize _leftmost_sample to the extents of the session
* this prevents a bogus setting of leftmost = " 0 " if the summary view asks for the leftmost sample
* before the visible state has been loaded from instant . xml */
2017-09-18 12:39:17 -04:00
_leftmost_sample = session_gui_extents ( ) . first ;
2018-02-24 07:54:15 -05:00
2009-12-17 13:24:23 -05:00
_playlist_selector - > set_session ( _session ) ;
2011-06-02 13:50:37 -04:00
nudge_clock - > set_session ( _session ) ;
2009-12-17 13:24:23 -05:00
_summary - > set_session ( _session ) ;
_group_tabs - > set_session ( _session ) ;
_route_groups - > set_session ( _session ) ;
_regions - > set_session ( _session ) ;
2018-11-15 10:21:55 -05:00
_sources - > set_session ( _session ) ;
2009-12-17 13:24:23 -05:00
_snapshots - > set_session ( _session ) ;
_routes - > set_session ( _session ) ;
_locations - > set_session ( _session ) ;
2016-12-16 20:31:41 -05:00
_time_info_box - > set_session ( _session ) ;
2009-12-17 13:24:23 -05:00
if ( rhythm_ferret ) {
rhythm_ferret - > set_session ( _session ) ;
}
if ( analysis_window ) {
analysis_window - > set_session ( _session ) ;
}
if ( sfbrowser ) {
sfbrowser - > set_session ( _session ) ;
}
2009-05-01 16:30:22 -04:00
compute_fixed_ruler_scale ( ) ;
2011-10-19 20:05:31 -04:00
/* Make sure we have auto loop and auto punch ranges */
Location * loc = _session - > locations ( ) - > auto_loop_location ( ) ;
2014-01-27 21:27:13 -05:00
if ( loc ! = 0 ) {
2011-10-19 20:05:31 -04:00
loc - > set_name ( _ ( " Loop " ) ) ;
}
loc = _session - > locations ( ) - > auto_punch_location ( ) ;
2014-01-27 21:27:13 -05:00
if ( loc ! = 0 ) {
2018-02-24 07:54:15 -05:00
/* force name */
2011-10-19 20:05:31 -04:00
loc - > set_name ( _ ( " Punch " ) ) ;
}
refresh_location_display ( ) ;
/* This must happen after refresh_location_display(), as (amongst other things) we restore
2018-02-24 07:54:15 -05:00
* the selected Marker ; this needs the LocationMarker list to be available .
*/
2007-01-11 14:50:49 -05:00
XMLNode * node = ARDOUR_UI : : instance ( ) - > editor_settings ( ) ;
2009-10-15 14:56:11 -04:00
set_state ( * node , Stateful : : loading_state_version ) ;
2007-01-11 14:50:49 -05:00
2017-05-05 07:31:49 -04:00
/* catch up on selection state, etc. */
PropertyChange sc ;
sc . add ( Properties : : selected ) ;
presentation_info_changed ( sc ) ;
2007-01-11 14:50:49 -05:00
/* catch up with the playhead */
2020-01-20 13:14:28 -05:00
_session - > request_locate ( playhead_cursor - > current_sample ( ) , MustStop ) ;
2010-02-07 20:25:06 -05:00
_pending_initial_locate = true ;
2007-01-11 14:50:49 -05:00
2005-09-25 14:42:24 -04:00
update_title ( ) ;
/* 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 ,
2013-08-07 22:22:11 -04:00
but use PBD : : Signal < T > : : connect ( ) which accepts an event loop
( " context " ) where the handler will be asked to run .
2005-09-25 14:42:24 -04:00
*/
2012-04-25 08:58:19 -04:00
_session - > StepEditStatusChange . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : step_edit_status_change , this , _1 ) , gui_context ( ) ) ;
2010-03-30 11:18:43 -04:00
_session - > TransportStateChange . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : map_transport_state , this ) , gui_context ( ) ) ;
2017-03-31 08:11:49 -04:00
_session - > TransportLooped . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : transport_looped , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > PositionChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : map_position_change , this , _1 ) , gui_context ( ) ) ;
2016-05-21 16:36:08 -04:00
_session - > vca_manager ( ) . VCAAdded . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : add_vcas , this , _1 ) , gui_context ( ) ) ;
2012-06-27 18:57:06 -04:00
_session - > RouteAdded . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : add_routes , this , _1 ) , gui_context ( ) ) ;
2010-03-30 11:18:43 -04:00
_session - > DirtyChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : update_title , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > tempo_map ( ) . PropertyChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : tempo_map_changed , this , _1 ) , gui_context ( ) ) ;
2017-01-26 11:05:32 -05:00
_session - > tempo_map ( ) . MetricPositionChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : tempometric_position_changed , this , _1 ) , gui_context ( ) ) ;
2010-03-30 11:18:43 -04:00
_session - > Located . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : located , this ) , gui_context ( ) ) ;
2012-04-25 08:58:19 -04:00
_session - > config . ParameterChanged . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : parameter_changed , this , _1 ) , gui_context ( ) ) ;
_session - > StateSaved . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : session_state_saved , this , _1 ) , gui_context ( ) ) ;
_session - > locations ( ) - > added . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : add_new_location , this , _1 ) , gui_context ( ) ) ;
_session - > locations ( ) - > removed . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : location_gone , this , _1 ) , gui_context ( ) ) ;
2010-03-30 11:18:43 -04:00
_session - > locations ( ) - > changed . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : refresh_location_display , this ) , gui_context ( ) ) ;
_session - > history ( ) . Changed . connect ( _session_connections , invalidator ( * this ) , boost : : bind ( & Editor : : history_changed , this ) , gui_context ( ) ) ;
2006-09-18 23:29:16 -04:00
2018-02-09 09:21:45 -05:00
playhead_cursor - > track_canvas_item ( ) . reparent ( ( ArdourCanvas : : Item * ) get_cursor_scroll_group ( ) ) ;
2013-04-04 00:32:52 -04:00
playhead_cursor - > show ( ) ;
2008-09-20 05:06:49 -04:00
2018-02-09 09:21:45 -05:00
snapped_cursor - > track_canvas_item ( ) . reparent ( ( ArdourCanvas : : Item * ) get_cursor_scroll_group ( ) ) ;
snapped_cursor - > set_color ( UIConfiguration : : instance ( ) . color ( " edit point " ) ) ;
snapped_cursor - > show ( ) ;
2009-12-12 10:02:15 -05:00
boost : : function < void ( string ) > pc ( boost : : bind ( & Editor : : parameter_changed , this , _1 ) ) ;
Config - > map_parameters ( pc ) ;
2009-12-17 13:24:23 -05:00
_session - > config . map_parameters ( pc ) ;
2009-10-14 12:10:01 -04:00
2008-12-12 09:43:24 -05:00
restore_ruler_visibility ( ) ;
2010-02-18 08:59:49 -05:00
//tempo_map_changed (PropertyChange (0));
2009-12-17 13:24:23 -05:00
_session - > tempo_map ( ) . apply_with_metrics ( * this , & Editor : : draw_metric_marks ) ;
2008-12-12 09:43:24 -05:00
2005-09-25 14:42:24 -04:00
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2013-04-12 11:31:50 -04:00
( static_cast < TimeAxisView * > ( * i ) ) - > set_samples_per_pixel ( samples_per_pixel ) ;
2005-09-25 14:42:24 -04:00
}
2014-12-25 10:02:00 -05:00
super_rapid_screen_update_connection = Timers : : super_rapid_connect (
2010-02-07 20:25:06 -05:00
sigc : : mem_fun ( * this , & Editor : : super_rapid_screen_update )
) ;
2011-06-01 13:00:29 -04:00
2008-02-19 17:10:27 -05:00
/* register for undo history */
2011-10-18 09:18:47 -04:00
_session - > register_with_memento_command_factory ( id ( ) , this ) ;
2014-12-14 08:13:38 -05:00
_session - > register_with_memento_command_factory ( _selection_memento - > id ( ) , _selection_memento ) ;
2009-10-14 12:10:01 -04:00
2016-02-23 09:42:53 -05:00
LuaInstance : : instance ( ) - > set_session ( _session ) ;
2010-02-07 20:25:06 -05:00
start_updating_meters ( ) ;
2005-09-25 14:42:24 -04:00
}
2012-05-10 15:14:11 -04:00
void
2012-05-11 17:30:36 -04:00
Editor : : fill_xfade_menu ( Menu_Helpers : : MenuList & items , bool start )
2012-05-10 15:14:11 -04:00
{
using namespace Menu_Helpers ;
2012-05-11 17:30:36 -04:00
void ( Editor : : * emf ) ( FadeShape ) ;
std : : map < ARDOUR : : FadeShape , Gtk : : Image * > * images ;
if ( start ) {
images = & _xfade_in_images ;
emf = & Editor : : set_fade_in_shape ;
} else {
images = & _xfade_out_images ;
emf = & Editor : : set_fade_out_shape ;
}
items . push_back (
ImageMenuElem (
_ ( " Linear (for highly correlated material) " ) ,
* ( * images ) [ FadeLinear ] ,
sigc : : bind ( sigc : : mem_fun ( * this , emf ) , FadeLinear )
)
) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
dynamic_cast < ImageMenuItem * > ( & items . back ( ) ) - > set_always_show_image ( ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
items . push_back (
ImageMenuElem (
2013-01-05 09:07:00 -05:00
_ ( " Constant power " ) ,
2012-05-11 17:30:36 -04:00
* ( * images ) [ FadeConstantPower ] ,
sigc : : bind ( sigc : : mem_fun ( * this , emf ) , FadeConstantPower )
) ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
dynamic_cast < ImageMenuItem * > ( & items . back ( ) ) - > set_always_show_image ( ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
items . push_back (
ImageMenuElem (
_ ( " Symmetric " ) ,
* ( * images ) [ FadeSymmetric ] ,
sigc : : bind ( sigc : : mem_fun ( * this , emf ) , FadeSymmetric )
)
) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
dynamic_cast < ImageMenuItem * > ( & items . back ( ) ) - > set_always_show_image ( ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
items . push_back (
ImageMenuElem (
_ ( " Slow " ) ,
* ( * images ) [ FadeSlow ] ,
sigc : : bind ( sigc : : mem_fun ( * this , emf ) , FadeSlow )
) ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
dynamic_cast < ImageMenuItem * > ( & items . back ( ) ) - > set_always_show_image ( ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
items . push_back (
ImageMenuElem (
_ ( " Fast " ) ,
* ( * images ) [ FadeFast ] ,
sigc : : bind ( sigc : : mem_fun ( * this , emf ) , FadeFast )
) ) ;
2015-10-05 10:17:49 -04:00
2012-05-11 17:30:36 -04:00
dynamic_cast < ImageMenuItem * > ( & items . back ( ) ) - > set_always_show_image ( ) ;
}
/** Pop up a context menu for when the user clicks on a start crossfade */
void
2014-05-29 01:49:26 -04:00
Editor : : popup_xfade_in_context_menu ( int button , int32_t time , ArdourCanvas : : Item * item , ItemType /*item_type*/ )
2012-05-11 17:30:36 -04:00
{
using namespace Menu_Helpers ;
2014-12-17 03:06:23 -05:00
AudioRegionView * arv = dynamic_cast < AudioRegionView * > ( ( RegionView * ) item - > get_data ( " regionview " ) ) ;
if ( ! arv ) {
return ;
}
2012-05-11 17:30:36 -04:00
MenuList & items ( xfade_in_context_menu . items ( ) ) ;
2014-05-29 01:49:26 -04:00
items . clear ( ) ;
2012-05-11 17:30:36 -04:00
2014-05-29 01:49:26 -04:00
if ( arv - > audio_region ( ) - > fade_in_active ( ) ) {
items . push_back ( MenuElem ( _ ( " Deactivate " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_fade_in_active ) , false ) ) ) ;
} else {
items . push_back ( MenuElem ( _ ( " Activate " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_fade_in_active ) , true ) ) ) ;
2012-05-11 17:30:36 -04:00
}
2014-05-29 01:49:26 -04:00
items . push_back ( SeparatorElem ( ) ) ;
fill_xfade_menu ( items , true ) ;
2012-05-11 17:30:36 -04:00
xfade_in_context_menu . popup ( button , time ) ;
}
/** Pop up a context menu for when the user clicks on an end crossfade */
void
2014-05-29 01:49:26 -04:00
Editor : : popup_xfade_out_context_menu ( int button , int32_t time , ArdourCanvas : : Item * item , ItemType /*item_type*/ )
2005-09-25 14:42:24 -04:00
{
using namespace Menu_Helpers ;
2014-12-17 03:06:23 -05:00
AudioRegionView * arv = dynamic_cast < AudioRegionView * > ( ( RegionView * ) item - > get_data ( " regionview " ) ) ;
if ( ! arv ) {
return ;
}
2005-09-25 14:42:24 -04:00
2014-05-29 01:49:26 -04:00
MenuList & items ( xfade_out_context_menu . items ( ) ) ;
2012-05-16 10:20:12 -04:00
items . clear ( ) ;
2005-09-25 14:42:24 -04:00
2014-05-29 01:49:26 -04:00
if ( arv - > audio_region ( ) - > fade_out_active ( ) ) {
items . push_back ( MenuElem ( _ ( " Deactivate " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_fade_out_active ) , false ) ) ) ;
} else {
items . push_back ( MenuElem ( _ ( " Activate " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_fade_out_active ) , true ) ) ) ;
2005-09-25 14:42:24 -04:00
}
2014-05-29 01:49:26 -04:00
items . push_back ( SeparatorElem ( ) ) ;
fill_xfade_menu ( items , false ) ;
xfade_out_context_menu . popup ( button , time ) ;
2005-09-25 14:42:24 -04:00
}
void
2010-11-14 11:49:59 -05:00
Editor : : popup_track_context_menu ( int button , int32_t time , ItemType item_type , bool with_selection )
2005-09-25 14:42:24 -04:00
{
2008-01-12 18:45:50 -05:00
using namespace Menu_Helpers ;
2010-11-14 11:49:59 -05:00
Menu * ( Editor : : * build_menu_function ) ( ) ;
2008-01-12 18:45:50 -05:00
Menu * menu ;
switch ( item_type ) {
case RegionItem :
case RegionViewName :
case RegionViewNameHighlight :
2010-06-17 08:45:51 -04:00
case LeftFrameHandle :
case RightFrameHandle :
2008-01-12 18:45:50 -05:00
if ( with_selection ) {
build_menu_function = & Editor : : build_track_selection_context_menu ;
} else {
build_menu_function = & Editor : : build_track_region_context_menu ;
}
break ;
case SelectionItem :
if ( with_selection ) {
build_menu_function = & Editor : : build_track_selection_context_menu ;
} else {
build_menu_function = & Editor : : build_track_context_menu ;
}
break ;
case StreamItem :
Fix odd right click crash on master track.
To reproduce. Launch, right click in ruler area then drag down
until over the master track and let go.
#0 0x0000555555ba1d44 in boost::shared_ptr<ARDOUR::Route>::get() const (this=0x8) at /usr/include/boost/smart_ptr/shared_ptr.hpp:748
#1 0x0000555555ba0a2f in boost::dynamic_pointer_cast<ARDOUR::Track, ARDOUR::Route>(boost::shared_ptr<ARDOUR::Route> const&) (r=...)
at /usr/include/boost/smart_ptr/shared_ptr.hpp:904
#2 0x000055555650b92b in RouteUI::track() const (this=0x0) at ../gtk2_ardour/route_ui.cc:1885
#3 0x0000555555d0b92f in Editor::popup_track_context_menu(int, int, ItemType, bool) (this=
0x555557a3efd0, button=1, time=600214966, item_type=StreamItem, with_selection=false) at ../gtk2_ardour/editor.cc:1595
#4 0x0000555555e1a4cf in Editor::button_release_handler(ArdourCanvas::Item*, _GdkEvent*, ItemType) (this=0x555557a3efd0, item=
0x555557b2fe00, event=0x7fffffffc310, item_type=StreamItem) at ../gtk2_ardour/editor_mouse.cc:1543
....
2020-03-03 14:49:04 -05:00
if ( clicked_routeview ! = 0 & & clicked_routeview - > track ( ) ) {
2008-01-12 18:45:50 -05:00
build_menu_function = & Editor : : build_track_context_menu ;
} else {
build_menu_function = & Editor : : build_track_bus_context_menu ;
}
break ;
default :
/* probably shouldn't happen but if it does, we don't care */
return ;
}
2010-11-14 11:49:59 -05:00
menu = ( this - > * build_menu_function ) ( ) ;
2008-01-12 18:45:50 -05:00
menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
/* now handle specific situations */
switch ( item_type ) {
case RegionItem :
case RegionViewName :
case RegionViewNameHighlight :
2010-11-25 15:37:39 -05:00
case LeftFrameHandle :
case RightFrameHandle :
2008-01-12 18:45:50 -05:00
break ;
case SelectionItem :
break ;
case StreamItem :
break ;
default :
/* probably shouldn't happen but if it does, we don't care */
return ;
}
if ( item_type ! = SelectionItem & & clicked_routeview & & clicked_routeview - > audio_track ( ) ) {
/* Bounce to disk */
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
using namespace Menu_Helpers ;
MenuList & edit_items = menu - > items ( ) ;
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
switch ( clicked_routeview - > audio_track ( ) - > freeze_state ( ) ) {
case AudioTrack : : NoFreeze :
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Freeze " ) , sigc : : mem_fun ( * this , & Editor : : freeze_route ) ) ) ;
2008-01-12 18:45:50 -05:00
break ;
case AudioTrack : : Frozen :
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Unfreeze " ) , sigc : : mem_fun ( * this , & Editor : : unfreeze_route ) ) ) ;
2008-01-12 18:45:50 -05:00
break ;
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
case AudioTrack : : UnFrozen :
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Freeze " ) , sigc : : mem_fun ( * this , & Editor : : freeze_route ) ) ) ;
2008-01-12 18:45:50 -05:00
break ;
}
}
2008-02-10 13:16:25 -05:00
if ( item_type = = StreamItem & & clicked_routeview ) {
clicked_routeview - > build_underlay_menu ( menu ) ;
}
2010-11-03 22:05:08 -04:00
/* When the region menu is opened, we setup the actions so that they look right
in the menu .
*/
2017-02-15 13:50:51 -05:00
sensitize_the_right_region_actions ( false ) ;
2010-11-03 22:05:08 -04:00
_last_region_menu_was_main = false ;
menu - > signal_hide ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : sensitize_all_region_actions ) , true ) ) ;
2008-01-12 18:45:50 -05:00
menu - > popup ( button , time ) ;
2005-09-25 14:42:24 -04:00
}
Menu *
2010-11-14 11:49:59 -05:00
Editor : : build_track_context_menu ( )
2005-09-25 14:42:24 -04:00
{
using namespace Menu_Helpers ;
2016-04-22 23:02:39 -04:00
MenuList & edit_items = track_context_menu . items ( ) ;
2005-09-25 14:42:24 -04:00
edit_items . clear ( ) ;
2008-01-12 18:45:50 -05:00
add_dstream_context_items ( edit_items ) ;
return & track_context_menu ;
}
Menu *
2010-11-14 11:49:59 -05:00
Editor : : build_track_bus_context_menu ( )
2008-01-12 18:45:50 -05:00
{
using namespace Menu_Helpers ;
2016-04-22 23:02:39 -04:00
MenuList & edit_items = track_context_menu . items ( ) ;
2008-01-12 18:45:50 -05:00
edit_items . clear ( ) ;
add_bus_context_items ( edit_items ) ;
return & track_context_menu ;
}
Menu *
2010-11-14 11:49:59 -05:00
Editor : : build_track_region_context_menu ( )
2008-01-12 18:45:50 -05:00
{
using namespace Menu_Helpers ;
MenuList & edit_items = track_region_context_menu . items ( ) ;
edit_items . clear ( ) ;
2010-07-18 21:43:11 -04:00
/* we've just cleared the track region context menu, so the menu that these
two items were on will have disappeared ; stop them dangling .
*/
2009-07-09 13:58:13 -04:00
RouteTimeAxisView * rtv = dynamic_cast < RouteTimeAxisView * > ( clicked_axisview ) ;
2008-01-12 18:45:50 -05:00
if ( rtv ) {
2010-04-21 16:42:22 -04:00
boost : : shared_ptr < Track > tr ;
2008-01-12 18:45:50 -05:00
boost : : shared_ptr < Playlist > pl ;
2009-10-14 12:10:01 -04:00
2011-02-27 11:43:48 -05:00
if ( ( tr = rtv - > track ( ) ) ) {
add_region_context_items ( edit_items , tr ) ;
2008-01-12 18:45:50 -05:00
}
}
add_dstream_context_items ( edit_items ) ;
return & track_region_context_menu ;
}
2006-03-12 16:58:52 -05:00
void
2016-03-11 11:26:27 -05:00
Editor : : loudness_analyze_region_selection ( )
{
if ( ! _session ) {
return ;
}
Selection & s ( PublicEditor : : instance ( ) . get_selection ( ) ) ;
RegionSelection ars = s . regions ;
ARDOUR : : AnalysisGraph ag ( _session ) ;
2017-09-18 12:39:17 -04:00
samplecnt_t total_work = 0 ;
2016-03-11 11:26:27 -05:00
for ( RegionSelection : : iterator j = ars . begin ( ) ; j ! = ars . end ( ) ; + + j ) {
AudioRegionView * arv = dynamic_cast < AudioRegionView * > ( * j ) ;
if ( ! arv ) {
continue ;
}
if ( ! boost : : dynamic_pointer_cast < AudioRegion > ( arv - > region ( ) ) ) {
continue ;
}
assert ( dynamic_cast < RouteTimeAxisView * > ( & arv - > get_time_axis_view ( ) ) ) ;
total_work + = arv - > region ( ) - > length ( ) ;
}
SimpleProgressDialog spd ( _ ( " Region Loudness Analysis " ) , sigc : : mem_fun ( ag , & AnalysisGraph : : cancel ) ) ;
ScopedConnection c ;
2017-09-18 12:39:17 -04:00
ag . set_total_samples ( total_work ) ;
2016-03-11 11:26:27 -05:00
ag . Progress . connect_same_thread ( c , boost : : bind ( & SimpleProgressDialog : : update_progress , & spd , _1 , _2 ) ) ;
spd . show ( ) ;
for ( RegionSelection : : iterator j = ars . begin ( ) ; j ! = ars . end ( ) ; + + j ) {
AudioRegionView * arv = dynamic_cast < AudioRegionView * > ( * j ) ;
if ( ! arv ) {
continue ;
}
boost : : shared_ptr < AudioRegion > ar = boost : : dynamic_pointer_cast < AudioRegion > ( arv - > region ( ) ) ;
if ( ! ar ) {
continue ;
}
ag . analyze_region ( ar ) ;
}
spd . hide ( ) ;
if ( ! ag . canceled ( ) ) {
ExportReport er ( _ ( " Audio Report/Analysis " ) , ag . results ( ) ) ;
er . run ( ) ;
}
}
void
Editor : : loudness_analyze_range_selection ( )
{
if ( ! _session ) {
return ;
}
Selection & s ( PublicEditor : : instance ( ) . get_selection ( ) ) ;
TimeSelection ts = s . time ;
ARDOUR : : AnalysisGraph ag ( _session ) ;
2017-09-18 12:39:17 -04:00
samplecnt_t total_work = 0 ;
2016-03-11 11:26:27 -05:00
for ( TrackSelection : : iterator i = s . tracks . begin ( ) ; i ! = s . tracks . end ( ) ; + + i ) {
boost : : shared_ptr < AudioPlaylist > pl = boost : : dynamic_pointer_cast < AudioPlaylist > ( ( * i ) - > playlist ( ) ) ;
if ( ! pl ) {
continue ;
}
RouteUI * rui = dynamic_cast < RouteUI * > ( * i ) ;
if ( ! pl | | ! rui ) {
continue ;
}
for ( std : : list < AudioRange > : : iterator j = ts . begin ( ) ; j ! = ts . end ( ) ; + + j ) {
total_work + = j - > length ( ) ;
}
}
SimpleProgressDialog spd ( _ ( " Range Loudness Analysis " ) , sigc : : mem_fun ( ag , & AnalysisGraph : : cancel ) ) ;
ScopedConnection c ;
2017-09-18 12:39:17 -04:00
ag . set_total_samples ( total_work ) ;
2016-03-11 11:26:27 -05:00
ag . Progress . connect_same_thread ( c , boost : : bind ( & SimpleProgressDialog : : update_progress , & spd , _1 , _2 ) ) ;
spd . show ( ) ;
for ( TrackSelection : : iterator i = s . tracks . begin ( ) ; i ! = s . tracks . end ( ) ; + + i ) {
boost : : shared_ptr < AudioPlaylist > pl = boost : : dynamic_pointer_cast < AudioPlaylist > ( ( * i ) - > playlist ( ) ) ;
if ( ! pl ) {
continue ;
}
RouteUI * rui = dynamic_cast < RouteUI * > ( * i ) ;
if ( ! pl | | ! rui ) {
continue ;
}
ag . analyze_range ( rui - > route ( ) , pl , ts ) ;
}
spd . hide ( ) ;
if ( ! ag . canceled ( ) ) {
ExportReport er ( _ ( " Audio Report/Analysis " ) , ag . results ( ) ) ;
er . run ( ) ;
}
}
void
Editor : : spectral_analyze_region_selection ( )
2006-03-12 16:58:52 -05:00
{
if ( analysis_window = = 0 ) {
analysis_window = new AnalysisWindow ( ) ;
2009-12-17 13:24:23 -05:00
if ( _session ! = 0 )
analysis_window - > set_session ( _session ) ;
2006-03-12 16:58:52 -05:00
analysis_window - > show_all ( ) ;
}
2006-03-12 17:35:39 -05:00
analysis_window - > set_regionmode ( ) ;
analysis_window - > analyze ( ) ;
2009-10-14 12:10:01 -04:00
2006-03-12 16:58:52 -05:00
analysis_window - > present ( ) ;
}
2006-03-12 17:35:39 -05:00
void
2016-03-11 11:26:27 -05:00
Editor : : spectral_analyze_range_selection ( )
2006-03-12 17:35:39 -05:00
{
if ( analysis_window = = 0 ) {
analysis_window = new AnalysisWindow ( ) ;
2009-12-17 13:24:23 -05:00
if ( _session ! = 0 )
analysis_window - > set_session ( _session ) ;
2006-03-12 17:35:39 -05:00
analysis_window - > show_all ( ) ;
}
analysis_window - > set_rangemode ( ) ;
analysis_window - > analyze ( ) ;
2009-10-14 12:10:01 -04:00
2006-03-12 17:35:39 -05:00
analysis_window - > present ( ) ;
}
2008-01-12 18:45:50 -05:00
Menu *
2010-11-14 11:49:59 -05:00
Editor : : build_track_selection_context_menu ( )
2008-01-12 18:45:50 -05:00
{
using namespace Menu_Helpers ;
MenuList & edit_items = track_selection_context_menu . items ( ) ;
edit_items . clear ( ) ;
add_selection_context_items ( edit_items ) ;
// edit_items.push_back (SeparatorElem());
// add_dstream_context_items (edit_items);
return & track_selection_context_menu ;
}
2006-03-12 17:35:39 -05:00
2005-09-25 14:42:24 -04:00
void
2011-02-27 11:43:48 -05:00
Editor : : add_region_context_items ( Menu_Helpers : : MenuList & edit_items , boost : : shared_ptr < Track > track )
2005-09-25 14:42:24 -04:00
{
using namespace Menu_Helpers ;
2011-06-01 13:00:29 -04:00
2005-09-25 14:42:24 -04:00
/* OK, stick the region submenu at the top of the list, and then add
the standard items .
*/
2010-11-03 18:19:29 -04:00
RegionSelection rs = get_regions_from_selection_and_entered ( ) ;
2011-06-01 13:00:29 -04:00
2010-11-03 18:19:29 -04:00
string menu_item_name = ( rs . size ( ) = = 1 ) ? rs . front ( ) - > region ( ) - > name ( ) : _ ( " Selected Regions " ) ;
2008-01-12 18:45:50 -05:00
2010-11-03 18:19:29 -04:00
if ( _popup_region_menu_item = = 0 ) {
2017-07-01 16:53:40 -04:00
_popup_region_menu_item = new MenuItem ( menu_item_name , false ) ;
2010-11-03 18:19:29 -04:00
_popup_region_menu_item - > set_submenu ( * dynamic_cast < Menu * > ( ActionManager : : get_widget ( X_ ( " /PopupRegionMenu " ) ) ) ) ;
_popup_region_menu_item - > show ( ) ;
} else {
_popup_region_menu_item - > set_label ( menu_item_name ) ;
}
2017-03-04 13:34:41 -05:00
/* No layering allowed in later is higher layering model */
2015-05-09 13:15:50 -04:00
RefPtr < Action > act = ActionManager : : get_action ( X_ ( " EditorMenu " ) , X_ ( " RegionMenuLayering " ) ) ;
if ( act & & Config - > get_layer_model ( ) = = LaterHigher ) {
act - > set_sensitive ( false ) ;
} else if ( act ) {
act - > set_sensitive ( true ) ;
}
2017-09-18 12:39:17 -04:00
const samplepos_t position = get_preferred_edit_position ( EDIT_IGNORE_NONE , true ) ;
2011-02-27 11:43:48 -05:00
2010-11-03 18:19:29 -04:00
edit_items . push_back ( * _popup_region_menu_item ) ;
2015-05-09 13:15:50 -04:00
if ( Config - > get_layer_model ( ) = = Manual & & track - > playlist ( ) - > count_regions_at ( position ) > 1 & & ( layering_order_editor = = 0 | | ! layering_order_editor - > is_visible ( ) ) ) {
2011-12-26 18:38:56 -05:00
edit_items . push_back ( * manage ( _region_actions - > get_action ( " choose-top-region-context-menu " ) - > create_menu_item ( ) ) ) ;
2010-08-25 15:28:33 -04:00
}
2008-01-12 18:45:50 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2005-09-25 14:42:24 -04:00
}
2007-05-10 07:53:35 -04:00
/** Add context menu items relevant to selection ranges.
* @ param edit_items List to add the items to .
*/
2005-09-25 14:42:24 -04:00
void
Editor : : add_selection_context_items ( Menu_Helpers : : MenuList & edit_items )
{
using namespace Menu_Helpers ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Play Range " ) , sigc : : mem_fun ( * this , & Editor : : play_selection ) ) ) ;
edit_items . push_back ( MenuElem ( _ ( " Loop Range " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_loop_from_selection ) , true ) ) ) ;
2006-03-12 22:27:58 -05:00
2014-07-23 12:28:45 -04:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2016-12-13 02:10:30 -05:00
edit_items . push_back ( MenuElem ( _ ( " Zoom to Range " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : temporal_zoom_selection ) , Horizontal ) ) ) ;
2014-07-23 12:28:45 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2016-03-11 11:26:27 -05:00
edit_items . push_back ( MenuElem ( _ ( " Loudness Analysis " ) , sigc : : mem_fun ( * this , & Editor : : loudness_analyze_range_selection ) ) ) ;
edit_items . push_back ( MenuElem ( _ ( " Spectral Analysis " ) , sigc : : mem_fun ( * this , & Editor : : spectral_analyze_range_selection ) ) ) ;
2020-07-20 23:51:56 -04:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2020-07-21 21:26:19 -04:00
edit_items . push_back ( MenuElem ( _ ( " Loudness Assistant... " ) , sigc : : mem_fun ( * this , & Editor : : analyze_range_export ) ) ) ;
2011-04-17 09:55:41 -04:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2007-10-11 18:07:47 -04:00
2011-04-17 09:55:41 -04:00
edit_items . push_back (
MenuElem (
_ ( " Move Range Start to Previous Region Boundary " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : move_range_selection_start_or_end_to_region_boundary ) , false , false )
)
) ;
edit_items . push_back (
MenuElem (
_ ( " Move Range Start to Next Region Boundary " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : move_range_selection_start_or_end_to_region_boundary ) , false , true )
)
) ;
2011-06-01 13:00:29 -04:00
2011-04-17 09:55:41 -04:00
edit_items . push_back (
MenuElem (
_ ( " Move Range End to Previous Region Boundary " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : move_range_selection_start_or_end_to_region_boundary ) , true , false )
)
) ;
edit_items . push_back (
MenuElem (
_ ( " Move Range End to Next Region Boundary " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : move_range_selection_start_or_end_to_region_boundary ) , true , true )
)
) ;
2011-06-01 13:00:29 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2014-12-30 19:52:44 -05:00
edit_items . push_back ( MenuElem ( _ ( " Separate " ) , mem_fun ( * this , & Editor : : separate_region_from_selection ) ) ) ;
2018-10-22 17:46:44 -04:00
// edit_items.push_back (MenuElem (_("Convert to Region in Region List"), sigc::mem_fun(*this, &Editor::new_region_from_selection)));
2009-10-14 12:10:01 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Select All in Range " ) , sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_time_selection ) ) ) ;
2007-10-11 18:07:47 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2015-01-07 16:31:05 -05:00
edit_items . push_back ( MenuElem ( _ ( " Set Loop from Selection " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_loop_from_selection ) , false ) ) ) ;
edit_items . push_back ( MenuElem ( _ ( " Set Punch from Selection " ) , sigc : : mem_fun ( * this , & Editor : : set_punch_from_selection ) ) ) ;
edit_items . push_back ( MenuElem ( _ ( " Set Session Start/End from Selection " ) , sigc : : mem_fun ( * this , & Editor : : set_session_extents_from_selection ) ) ) ;
2009-10-14 12:10:01 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Add Range Markers " ) , sigc : : mem_fun ( * this , & Editor : : add_location_from_selection ) ) ) ;
2009-10-14 12:10:01 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Crop Region to Range " ) , sigc : : mem_fun ( * this , & Editor : : crop_region_to_selection ) ) ) ;
2012-07-04 17:31:06 -04:00
edit_items . push_back ( MenuElem ( _ ( " Duplicate Range " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : duplicate_range ) , false ) ) ) ;
2009-10-14 12:10:01 -04:00
2009-02-16 21:34:38 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Consolidate Range " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : bounce_range_selection ) , true , false ) ) ) ;
2015-11-29 14:17:11 -05:00
edit_items . push_back ( MenuElem ( _ ( " Consolidate Range with Processing " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : bounce_range_selection ) , true , true ) ) ) ;
2018-10-22 17:46:44 -04:00
edit_items . push_back ( MenuElem ( _ ( " Bounce Range to Source List " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : bounce_range_selection ) , false , false ) ) ) ;
edit_items . push_back ( MenuElem ( _ ( " Bounce Range to Source List with Processing " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : bounce_range_selection ) , false , true ) ) ) ;
2011-10-17 20:24:29 -04:00
edit_items . push_back ( MenuElem ( _ ( " Export Range... " ) , sigc : : mem_fun ( * this , & Editor : : export_selection ) ) ) ;
2013-10-12 16:55:54 -04:00
if ( ARDOUR_UI : : instance ( ) - > video_timeline - > get_duration ( ) > 0 ) {
2015-02-27 17:17:26 -05:00
edit_items . push_back ( MenuElem ( _ ( " Export Video Range... " ) , sigc : : bind ( sigc : : mem_fun ( * ( ARDOUR_UI : : instance ( ) ) , & ARDOUR_UI : : export_video ) , true ) ) ) ;
2013-10-12 16:55:54 -04:00
}
2005-09-25 14:42:24 -04:00
}
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
void
2008-01-12 18:45:50 -05:00
Editor : : add_dstream_context_items ( Menu_Helpers : : MenuList & edit_items )
2005-09-25 14:42:24 -04:00
{
using namespace Menu_Helpers ;
/* Playback */
Menu * play_menu = manage ( new Menu ) ;
MenuList & play_items = play_menu - > items ( ) ;
play_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2015-11-29 14:17:11 -05:00
play_items . push_back ( MenuElem ( _ ( " Play from Edit Point " ) , sigc : : mem_fun ( * this , & Editor : : play_from_edit_point ) ) ) ;
play_items . push_back ( MenuElem ( _ ( " Play from Start " ) , sigc : : mem_fun ( * this , & Editor : : play_from_start ) ) ) ;
2010-01-13 20:04:27 -05:00
play_items . push_back ( MenuElem ( _ ( " Play Region " ) , sigc : : mem_fun ( * this , & Editor : : play_selected_region ) ) ) ;
2008-01-12 18:45:50 -05:00
play_items . push_back ( SeparatorElem ( ) ) ;
2010-11-03 18:19:29 -04:00
play_items . push_back ( MenuElem ( _ ( " Loop Region " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_loop_from_region ) , true ) ) ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
edit_items . push_back ( MenuElem ( _ ( " Play " ) , * play_menu ) ) ;
/* Selection */
Menu * select_menu = manage ( new Menu ) ;
MenuList & select_items = select_menu - > items ( ) ;
select_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Select All in Track " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_in_track ) , Selection : : Set ) ) ) ;
2014-07-06 14:53:56 -04:00
select_items . push_back ( MenuElem ( _ ( " Select All Objects " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_objects ) , Selection : : Set ) ) ) ;
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Invert Selection in Track " ) , sigc : : mem_fun ( * this , & Editor : : invert_selection_in_track ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Invert Selection " ) , sigc : : mem_fun ( * this , & Editor : : invert_selection ) ) ) ;
2005-09-25 14:42:24 -04:00
select_items . push_back ( SeparatorElem ( ) ) ;
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Set Range to Loop Range " ) , sigc : : mem_fun ( * this , & Editor : : set_selection_from_loop ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Set Range to Punch Range " ) , sigc : : mem_fun ( * this , & Editor : : set_selection_from_punch ) ) ) ;
2015-04-24 14:09:48 -04:00
select_items . push_back ( MenuElem ( _ ( " Set Range to Selected Regions " ) , sigc : : mem_fun ( * this , & Editor : : set_selection_from_region ) ) ) ;
2008-01-12 18:45:50 -05:00
select_items . push_back ( SeparatorElem ( ) ) ;
2015-10-07 17:56:14 -04:00
select_items . push_back ( MenuElem ( _ ( " Select All After Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_edit ) , true , true ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select All Before Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_edit ) , false , true ) ) ) ;
2009-12-11 18:29:48 -05:00
select_items . push_back ( MenuElem ( _ ( " Select All After Playhead " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_cursor ) , playhead_cursor , true ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select All Before Playhead " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_cursor ) , playhead_cursor , false ) ) ) ;
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Select All Between Playhead and Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_between ) , false ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select All Within Playhead and Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_between ) , true ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select Range Between Playhead and Edit Point " ) , sigc : : mem_fun ( * this , & Editor : : select_range_between ) ) ) ;
2007-05-10 07:53:35 -04:00
2005-09-25 14:42:24 -04:00
edit_items . push_back ( MenuElem ( _ ( " Select " ) , * select_menu ) ) ;
/* Cut-n-Paste */
Menu * cutnpaste_menu = manage ( new Menu ) ;
MenuList & cutnpaste_items = cutnpaste_menu - > items ( ) ;
cutnpaste_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2009-12-11 18:29:48 -05:00
cutnpaste_items . push_back ( MenuElem ( _ ( " Cut " ) , sigc : : mem_fun ( * this , & Editor : : cut ) ) ) ;
cutnpaste_items . push_back ( MenuElem ( _ ( " Copy " ) , sigc : : mem_fun ( * this , & Editor : : copy ) ) ) ;
2011-12-30 12:28:05 -05:00
cutnpaste_items . push_back ( MenuElem ( _ ( " Paste " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : paste ) , 1.0f , true ) ) ) ;
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
cutnpaste_items . push_back ( SeparatorElem ( ) ) ;
2010-11-03 18:19:29 -04:00
cutnpaste_items . push_back ( MenuElem ( _ ( " Align " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : align_regions ) , ARDOUR : : SyncPoint ) ) ) ;
cutnpaste_items . push_back ( MenuElem ( _ ( " Align Relative " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : align_regions_relative ) , ARDOUR : : SyncPoint ) ) ) ;
2008-01-12 18:45:50 -05:00
edit_items . push_back ( MenuElem ( _ ( " Edit " ) , * cutnpaste_menu ) ) ;
/* Adding new material */
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2019-07-30 14:02:15 -04:00
edit_items . push_back ( MenuElem ( _ ( " Insert Selected Region " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : insert_source_list_selection ) , 1.0f ) ) ) ;
2009-12-11 18:29:48 -05:00
edit_items . push_back ( MenuElem ( _ ( " Insert Existing Media " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : add_external_audio_action ) , ImportToTrack ) ) ) ;
2008-01-12 18:45:50 -05:00
/* Nudge track */
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
Menu * nudge_menu = manage ( new Menu ( ) ) ;
MenuList & nudge_items = nudge_menu - > items ( ) ;
nudge_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2007-11-12 17:23:01 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2012-05-16 19:03:47 -04:00
nudge_items . push_back ( MenuElem ( _ ( " Nudge Entire Track Later " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , false , true ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Track After Edit Point Later " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , true , true ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Entire Track Earlier " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , false , false ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Track After Edit Point Earlier " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , true , false ) ) ) ) ;
2007-11-12 17:23:01 -05:00
2008-01-12 18:45:50 -05:00
edit_items . push_back ( MenuElem ( _ ( " Nudge " ) , * nudge_menu ) ) ;
}
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
void
Editor : : add_bus_context_items ( Menu_Helpers : : MenuList & edit_items )
{
using namespace Menu_Helpers ;
/* Playback */
Menu * play_menu = manage ( new Menu ) ;
MenuList & play_items = play_menu - > items ( ) ;
play_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2015-11-29 14:17:11 -05:00
play_items . push_back ( MenuElem ( _ ( " Play from Edit Point " ) , sigc : : mem_fun ( * this , & Editor : : play_from_edit_point ) ) ) ;
play_items . push_back ( MenuElem ( _ ( " Play from Start " ) , sigc : : mem_fun ( * this , & Editor : : play_from_start ) ) ) ;
2008-01-12 18:45:50 -05:00
edit_items . push_back ( MenuElem ( _ ( " Play " ) , * play_menu ) ) ;
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
/* Selection */
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
Menu * select_menu = manage ( new Menu ) ;
MenuList & select_items = select_menu - > items ( ) ;
select_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Select All in Track " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_in_track ) , Selection : : Set ) ) ) ;
2014-07-06 14:53:56 -04:00
select_items . push_back ( MenuElem ( _ ( " Select All Objects " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_objects ) , Selection : : Set ) ) ) ;
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Invert Selection in Track " ) , sigc : : mem_fun ( * this , & Editor : : invert_selection_in_track ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Invert Selection " ) , sigc : : mem_fun ( * this , & Editor : : invert_selection ) ) ) ;
2008-01-12 18:45:50 -05:00
select_items . push_back ( SeparatorElem ( ) ) ;
2015-10-07 17:56:14 -04:00
select_items . push_back ( MenuElem ( _ ( " Select All After Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_edit ) , true , true ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select All Before Edit Point " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_edit ) , false , true ) ) ) ;
2010-01-13 20:04:27 -05:00
select_items . push_back ( MenuElem ( _ ( " Select All After Playhead " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_cursor ) , playhead_cursor , true ) ) ) ;
select_items . push_back ( MenuElem ( _ ( " Select All Before Playhead " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : select_all_selectables_using_cursor ) , playhead_cursor , false ) ) ) ;
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
edit_items . push_back ( MenuElem ( _ ( " Select " ) , * select_menu ) ) ;
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
/* Cut-n-Paste */
2019-03-07 11:00:47 -05:00
#if 0 // unused, why?
2008-01-12 18:45:50 -05:00
Menu * cutnpaste_menu = manage ( new Menu ) ;
MenuList & cutnpaste_items = cutnpaste_menu - > items ( ) ;
cutnpaste_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2009-12-11 18:29:48 -05:00
cutnpaste_items . push_back ( MenuElem ( _ ( " Cut " ) , sigc : : mem_fun ( * this , & Editor : : cut ) ) ) ;
cutnpaste_items . push_back ( MenuElem ( _ ( " Copy " ) , sigc : : mem_fun ( * this , & Editor : : copy ) ) ) ;
2011-12-30 12:28:05 -05:00
cutnpaste_items . push_back ( MenuElem ( _ ( " Paste " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : paste ) , 1.0f , true ) ) ) ;
2019-03-07 11:00:47 -05:00
# endif
2005-09-25 14:42:24 -04:00
2008-01-12 18:45:50 -05:00
Menu * nudge_menu = manage ( new Menu ( ) ) ;
MenuList & nudge_items = nudge_menu - > items ( ) ;
nudge_menu - > set_name ( " ArdourContextMenu " ) ;
2009-10-14 12:10:01 -04:00
2008-01-12 18:45:50 -05:00
edit_items . push_back ( SeparatorElem ( ) ) ;
2012-05-16 19:03:47 -04:00
nudge_items . push_back ( MenuElem ( _ ( " Nudge Entire Track Later " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , false , true ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Track After Edit Point Later " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , true , true ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Entire Track Earlier " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , false , false ) ) ) ) ;
nudge_items . push_back ( MenuElem ( _ ( " Nudge Track After Edit Point Earlier " ) , ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : nudge_track ) , true , false ) ) ) ) ;
2008-01-12 18:45:50 -05:00
edit_items . push_back ( MenuElem ( _ ( " Nudge " ) , * nudge_menu ) ) ;
2005-09-25 14:42:24 -04:00
}
2018-02-09 10:59:39 -05:00
GridType
Editor : : grid_type ( ) const
2009-10-26 19:43:04 -04:00
{
2018-02-09 10:59:39 -05:00
return _grid_type ;
2009-10-26 19:43:04 -04:00
}
2016-03-28 11:23:29 -04:00
bool
2018-02-09 10:59:39 -05:00
Editor : : grid_musical ( ) const
{
switch ( _grid_type ) {
case GridTypeBeatDiv32 :
case GridTypeBeatDiv28 :
case GridTypeBeatDiv24 :
case GridTypeBeatDiv20 :
case GridTypeBeatDiv16 :
case GridTypeBeatDiv14 :
case GridTypeBeatDiv12 :
case GridTypeBeatDiv10 :
case GridTypeBeatDiv8 :
case GridTypeBeatDiv7 :
case GridTypeBeatDiv6 :
case GridTypeBeatDiv5 :
case GridTypeBeatDiv4 :
case GridTypeBeatDiv3 :
case GridTypeBeatDiv2 :
case GridTypeBeat :
case GridTypeBar :
2016-03-28 11:23:29 -04:00
return true ;
2018-02-09 10:59:39 -05:00
case GridTypeNone :
2018-02-26 19:38:18 -05:00
case GridTypeTimecode :
2018-02-09 10:59:39 -05:00
case GridTypeMinSec :
2018-02-26 18:02:24 -05:00
case GridTypeCDFrame :
2018-02-09 10:59:39 -05:00
return false ;
2016-03-28 11:23:29 -04:00
}
return false ;
}
2018-02-09 10:59:39 -05:00
bool
Editor : : grid_nonmusical ( ) const
{
switch ( _grid_type ) {
2018-02-26 19:38:18 -05:00
case GridTypeTimecode :
2018-02-09 10:59:39 -05:00
case GridTypeMinSec :
2018-02-26 18:02:24 -05:00
case GridTypeCDFrame :
2018-02-09 10:59:39 -05:00
return true ;
case GridTypeBeatDiv32 :
case GridTypeBeatDiv28 :
case GridTypeBeatDiv24 :
case GridTypeBeatDiv20 :
case GridTypeBeatDiv16 :
case GridTypeBeatDiv14 :
case GridTypeBeatDiv12 :
case GridTypeBeatDiv10 :
case GridTypeBeatDiv8 :
case GridTypeBeatDiv7 :
case GridTypeBeatDiv6 :
case GridTypeBeatDiv5 :
case GridTypeBeatDiv4 :
case GridTypeBeatDiv3 :
case GridTypeBeatDiv2 :
case GridTypeBeat :
case GridTypeBar :
case GridTypeNone :
return false ;
}
return false ;
}
2009-10-26 19:43:04 -04:00
SnapMode
Editor : : snap_mode ( ) const
{
return _snap_mode ;
}
2005-09-25 14:42:24 -04:00
void
2018-07-26 18:25:01 -04:00
Editor : : show_rulers_for_grid ( )
2008-09-10 11:03:30 -04:00
{
2018-07-26 18:25:01 -04:00
/* show appropriate rulers for this grid setting. */
2018-02-24 07:54:15 -05:00
if ( grid_musical ( ) ) {
2018-02-09 10:59:39 -05:00
ruler_tempo_action - > set_active ( true ) ;
ruler_meter_action - > set_active ( true ) ;
ruler_bbt_action - > set_active ( true ) ;
2018-07-26 18:25:01 -04:00
if ( UIConfiguration : : instance ( ) . get_rulers_follow_grid ( ) ) {
2018-07-26 14:53:36 -04:00
ruler_timecode_action - > set_active ( false ) ;
ruler_minsec_action - > set_active ( false ) ;
ruler_samples_action - > set_active ( false ) ;
}
} else if ( _grid_type = = GridTypeTimecode ) {
2018-02-09 10:59:39 -05:00
ruler_timecode_action - > set_active ( true ) ;
2018-07-26 18:25:01 -04:00
if ( UIConfiguration : : instance ( ) . get_rulers_follow_grid ( ) ) {
2018-07-26 14:53:36 -04:00
ruler_tempo_action - > set_active ( false ) ;
ruler_meter_action - > set_active ( false ) ;
ruler_bbt_action - > set_active ( false ) ;
ruler_minsec_action - > set_active ( false ) ;
ruler_samples_action - > set_active ( false ) ;
}
} else if ( _grid_type = = GridTypeMinSec ) {
2018-02-09 10:59:39 -05:00
ruler_minsec_action - > set_active ( true ) ;
2018-07-26 18:25:01 -04:00
if ( UIConfiguration : : instance ( ) . get_rulers_follow_grid ( ) ) {
2018-07-26 14:53:36 -04:00
ruler_tempo_action - > set_active ( false ) ;
ruler_meter_action - > set_active ( false ) ;
ruler_bbt_action - > set_active ( false ) ;
ruler_timecode_action - > set_active ( false ) ;
ruler_samples_action - > set_active ( false ) ;
}
} else if ( _grid_type = = GridTypeCDFrame ) {
ruler_cd_marker_action - > set_active ( true ) ;
2018-02-26 19:52:28 -05:00
ruler_minsec_action - > set_active ( true ) ;
2018-02-26 18:02:24 -05:00
2018-07-26 18:25:01 -04:00
if ( UIConfiguration : : instance ( ) . get_rulers_follow_grid ( ) ) {
2018-07-26 14:53:36 -04:00
ruler_tempo_action - > set_active ( false ) ;
ruler_meter_action - > set_active ( false ) ;
ruler_bbt_action - > set_active ( false ) ;
ruler_timecode_action - > set_active ( false ) ;
ruler_samples_action - > set_active ( false ) ;
}
2006-11-19 11:45:16 -05:00
}
2018-07-26 18:25:01 -04:00
}
void
Editor : : set_grid_to ( GridType gt )
{
if ( _grid_type = = gt ) { // already set
return ;
}
unsigned int grid_ind = ( unsigned int ) gt ;
if ( internal_editing ( ) & & UIConfiguration : : instance ( ) . get_grid_follows_internal ( ) ) {
internal_grid_type = gt ;
} else {
pre_internal_grid_type = gt ;
}
_grid_type = gt ;
if ( grid_ind > grid_type_strings . size ( ) - 1 ) {
grid_ind = 0 ;
_grid_type = ( GridType ) grid_ind ;
}
string str = grid_type_strings [ grid_ind ] ;
if ( str ! = grid_type_selector . get_text ( ) ) {
grid_type_selector . set_text ( str ) ;
}
2018-07-26 18:25:42 -04:00
if ( UIConfiguration : : instance ( ) . get_show_grids_ruler ( ) ) {
show_rulers_for_grid ( ) ;
}
2005-09-25 14:42:24 -04:00
instant_save ( ) ;
2018-02-24 07:54:15 -05:00
if ( grid_musical ( ) ) {
2017-09-18 12:39:17 -04:00
compute_bbt_ruler_scale ( _leftmost_sample , _leftmost_sample + current_page_samples ( ) ) ;
2016-10-18 12:56:43 -04:00
update_tempo_based_rulers ( ) ;
2012-11-27 17:48:59 -05:00
}
2008-02-19 17:10:27 -05:00
2018-02-09 10:59:39 -05:00
mark_region_boundary_cache_dirty ( ) ;
2010-05-25 19:14:41 -04:00
2018-02-09 10:59:39 -05:00
redisplay_grid ( false ) ;
2015-01-07 19:05:21 -05:00
2010-05-25 19:14:41 -04:00
SnapChanged ( ) ; /* EMIT SIGNAL */
2005-09-25 14:42:24 -04:00
}
void
Editor : : set_snap_mode ( SnapMode mode )
{
2014-12-16 23:02:28 -05:00
if ( internal_editing ( ) ) {
internal_snap_mode = mode ;
} else {
pre_internal_snap_mode = mode ;
}
2013-01-18 10:56:41 -05:00
_snap_mode = mode ;
2018-02-24 07:54:15 -05:00
if ( _snap_mode = = SnapOff ) {
2018-02-09 10:59:39 -05:00
snap_mode_button . set_active_state ( Gtkmm2ext : : Off ) ;
} else {
snap_mode_button . set_active_state ( Gtkmm2ext : : ExplicitActive ) ;
2006-11-19 11:45:16 -05:00
}
2005-09-25 14:42:24 -04:00
instant_save ( ) ;
}
2015-05-15 14:15:52 -04:00
2007-11-07 20:40:25 -05:00
void
2008-03-17 16:54:03 -04:00
Editor : : set_edit_point_preference ( EditPoint ep , bool force )
2007-11-07 20:40:25 -05:00
{
2019-03-29 09:53:07 -04:00
if ( Profile - > get_mixbus ( ) ) {
if ( ep = = EditAtSelectedMarker ) {
ep = EditAtPlayhead ;
}
}
2008-03-17 16:54:03 -04:00
bool changed = ( _edit_point ! = ep ) ;
2008-01-10 16:20:59 -05:00
2007-11-07 20:40:25 -05:00
_edit_point = ep ;
2014-11-18 02:19:03 -05:00
string str = edit_point_strings [ ( int ) ep ] ;
2014-03-23 19:11:42 -04:00
if ( str ! = edit_point_selector . get_text ( ) ) {
edit_point_selector . set_text ( str ) ;
2007-11-07 20:40:25 -05:00
}
2014-12-23 13:46:53 -05:00
update_all_enter_cursors ( ) ;
2008-02-16 17:43:18 -05:00
2008-03-17 16:54:03 -04:00
if ( ! force & & ! changed ) {
2008-01-10 16:20:59 -05:00
return ;
}
2008-10-03 14:24:38 -04:00
const char * action = NULL ;
2008-03-17 16:54:03 -04:00
switch ( _edit_point ) {
case EditAtPlayhead :
action = " edit-at-playhead " ;
break ;
case EditAtSelectedMarker :
2019-03-29 09:52:25 -04:00
action = " edit-at-selected-marker " ;
2008-03-17 16:54:03 -04:00
break ;
case EditAtMouse :
action = " edit-at-mouse " ;
break ;
}
2018-12-12 11:22:38 -05:00
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( " Editor " , action ) ;
tact - > set_active ( true ) ;
2008-03-17 16:54:03 -04:00
2017-09-18 12:39:17 -04:00
samplepos_t foo ;
2008-04-11 10:06:50 -04:00
bool in_track_canvas ;
2017-09-18 12:39:17 -04:00
if ( ! mouse_sample ( foo , in_track_canvas ) ) {
2008-04-11 10:06:50 -04:00
in_track_canvas = false ;
}
reset_canvas_action_sensitivity ( in_track_canvas ) ;
2017-02-16 04:29:32 -05:00
sensitize_the_right_region_actions ( false ) ;
2008-04-11 10:06:50 -04:00
2007-11-07 20:40:25 -05:00
instant_save ( ) ;
}
2005-09-25 14:42:24 -04:00
int
2015-07-07 22:12:21 -04:00
Editor : : set_state ( const XMLNode & node , int version )
2005-09-25 14:42:24 -04:00
{
2011-10-18 09:18:47 -04:00
set_id ( node ) ;
2016-05-18 14:06:20 -04:00
PBD : : Unwinder < bool > nsi ( no_save_instant , true ) ;
2016-08-26 23:44:57 -04:00
bool yn ;
2006-02-13 11:08:32 -05:00
2015-07-07 22:12:21 -04:00
Tabbable : : set_state ( node , version ) ;
2015-10-26 14:35:06 -04:00
2017-09-18 12:39:17 -04:00
samplepos_t ph_pos ;
2016-08-26 23:44:57 -04:00
if ( _session & & node . get_property ( " playhead " , ph_pos ) ) {
if ( ph_pos > = 0 ) {
playhead_cursor - > set_position ( ph_pos ) ;
2014-10-22 12:17:59 -04:00
} else {
warning < < _ ( " Playhead position stored with a negative value - ignored (use zero instead) " ) < < endmsg ;
playhead_cursor - > set_position ( 0 ) ;
}
2007-01-11 14:50:49 -05:00
} else {
playhead_cursor - > set_position ( 0 ) ;
}
2011-06-01 13:00:29 -04:00
2016-08-26 23:44:57 -04:00
node . get_property ( " mixer-width " , editor_mixer_strip_width ) ;
2007-04-29 13:23:11 -04:00
2016-08-26 23:44:57 -04:00
node . get_property ( " zoom-focus " , zoom_focus ) ;
zoom_focus_selection_done ( zoom_focus ) ;
2005-09-25 14:42:24 -04:00
2016-08-26 23:44:57 -04:00
double z ;
if ( node . get_property ( " zoom " , z ) ) {
2013-06-18 23:02:54 -04:00
/* older versions of ardour used floating point samples_per_pixel */
2016-08-26 23:44:57 -04:00
reset_zoom ( llrintf ( z ) ) ;
2010-08-28 21:06:05 -04:00
} else {
2013-04-12 11:31:50 -04:00
reset_zoom ( samples_per_pixel ) ;
2005-09-25 14:42:24 -04:00
}
2016-08-26 23:44:57 -04:00
int32_t cnt ;
if ( node . get_property ( " visible-track-count " , cnt ) ) {
set_visible_track_count ( cnt ) ;
2014-03-25 10:33:18 -04:00
}
2018-02-09 10:59:39 -05:00
GridType grid_type ;
if ( ! node . get_property ( " grid-type " , grid_type ) ) {
grid_type = _grid_type ;
2005-09-25 14:42:24 -04:00
}
2018-02-09 10:59:39 -05:00
set_grid_to ( grid_type ) ;
2005-09-25 14:42:24 -04:00
2016-08-26 23:44:57 -04:00
SnapMode sm ;
if ( node . get_property ( " snap-mode " , sm ) ) {
snap_mode_selection_done ( sm ) ;
2016-05-18 14:07:11 -04:00
/* set text of Dropdown. in case _snap_mode == SnapOff (default)
* snap_mode_selection_done ( ) will only mark an already active item as active
* which does not trigger set_text ( ) .
*/
2016-08-26 23:44:57 -04:00
set_snap_mode ( sm ) ;
2016-06-06 14:26:23 -04:00
} else {
set_snap_mode ( _snap_mode ) ;
2012-02-13 09:34:21 -05:00
}
2018-02-09 10:59:39 -05:00
node . get_property ( " internal-grid-type " , internal_grid_type ) ;
2016-08-26 23:44:57 -04:00
node . get_property ( " internal-snap-mode " , internal_snap_mode ) ;
2018-02-09 10:59:39 -05:00
node . get_property ( " pre-internal-grid-type " , pre_internal_grid_type ) ;
2016-08-26 23:44:57 -04:00
node . get_property ( " pre-internal-snap-mode " , pre_internal_snap_mode ) ;
2014-12-16 23:02:28 -05:00
2016-08-26 23:44:57 -04:00
std : : string mm_str ;
if ( node . get_property ( " mouse-mode " , mm_str ) ) {
MouseMode m = str2mousemode ( mm_str ) ;
2006-02-13 11:08:32 -05:00
set_mouse_mode ( m , true ) ;
} else {
set_mouse_mode ( MouseObject , true ) ;
}
2017-09-18 12:39:17 -04:00
samplepos_t lf_pos ;
2016-08-26 23:44:57 -04:00
if ( node . get_property ( " left-frame " , lf_pos ) ) {
if ( lf_pos < 0 ) {
lf_pos = 0 ;
2009-11-27 20:53:41 -05:00
}
2016-08-26 23:44:57 -04:00
reset_x_origin ( lf_pos ) ;
2009-11-27 20:53:41 -05:00
}
2016-08-26 23:44:57 -04:00
double y_origin ;
if ( node . get_property ( " y-origin " , y_origin ) ) {
reset_y_origin ( y_origin ) ;
2010-02-07 20:25:06 -05:00
}
2019-02-28 16:56:35 -05:00
yn = false ;
node . get_property ( " join-object-range " , yn ) ;
{
RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " MouseMode " ) , X_ ( " set-mouse-mode-object-range " ) ) ;
/* do it twice to force the change */
tact - > set_active ( ! yn ) ;
tact - > set_active ( yn ) ;
2012-11-26 17:43:10 -05:00
set_mouse_mode ( mouse_mode , true ) ;
2010-01-01 17:11:15 -05:00
}
2016-08-26 23:44:57 -04:00
EditPoint ep ;
if ( node . get_property ( " edit-point " , ep ) ) {
set_edit_point_preference ( ep , true ) ;
2016-06-06 14:26:23 -04:00
} else {
set_edit_point_preference ( _edit_point ) ;
2009-08-01 22:17:14 -04:00
}
2016-08-26 23:44:57 -04:00
if ( node . get_property ( " follow-playhead " , yn ) ) {
2007-04-22 14:01:10 -04:00
set_follow_playhead ( yn ) ;
2005-09-25 14:42:24 -04:00
}
2016-08-26 23:44:57 -04:00
if ( node . get_property ( " stationary-playhead " , yn ) ) {
2010-11-25 15:37:39 -05:00
set_stationary_playhead ( yn ) ;
}
2011-06-01 13:00:29 -04:00
2018-11-15 10:24:37 -05:00
if ( node . get_property ( " show-editor-mixer " , yn ) ) {
2005-09-25 14:42:24 -04:00
2018-12-12 11:22:38 -05:00
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " show-editor-mixer " ) ) ;
2010-11-10 13:29:32 -05:00
/* do it twice to force the change */
tact - > set_active ( ! yn ) ;
tact - > set_active ( yn ) ;
2005-09-25 14:42:24 -04:00
}
2009-10-14 12:10:01 -04:00
2019-02-28 16:56:35 -05:00
yn = false ;
node . get_property ( " show-editor-list " , yn ) ;
{
2018-12-12 11:22:38 -05:00
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " show-editor-list " ) ) ;
2010-11-10 13:29:32 -05:00
/* do it twice to force the change */
tact - > set_active ( ! yn ) ;
tact - > set_active ( yn ) ;
2007-06-15 03:39:20 -04:00
}
2005-09-25 14:42:24 -04:00
2016-08-26 23:44:57 -04:00
int32_t el_page ;
if ( node . get_property ( X_ ( " editor-list-page " ) , el_page ) ) {
_the_notebook . set_current_page ( el_page ) ;
2010-04-05 13:38:54 -04:00
}
2019-02-28 16:56:35 -05:00
yn = false ;
node . get_property ( X_ ( " show-marker-lines " ) , yn ) ;
{
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " show-marker-lines " ) ) ;
/* do it twice to force the change */
2010-11-10 13:29:32 -05:00
tact - > set_active ( ! yn ) ;
tact - > set_active ( yn ) ;
}
2010-08-17 22:20:15 -04:00
XMLNodeList children = node . children ( ) ;
for ( XMLNodeList : : const_iterator i = children . begin ( ) ; i ! = children . end ( ) ; + + i ) {
selection - > set_state ( * * i , Stateful : : current_state_version ) ;
2010-09-18 22:18:59 -04:00
_regions - > set_state ( * * i ) ;
2017-02-14 11:15:16 -05:00
_locations - > set_state ( * * i ) ;
2010-08-17 22:20:15 -04:00
}
2016-08-26 23:44:57 -04:00
if ( node . get_property ( " maximised " , yn ) ) {
2018-12-12 11:22:38 -05:00
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Common " ) , X_ ( " ToggleMaximalEditor " ) ) ;
bool fs = tact - > get_active ( ) ;
2014-03-21 10:20:25 -04:00
if ( yn ^ fs ) {
2012-01-24 22:03:25 -05:00
ActionManager : : do_action ( " Common " , " ToggleMaximalEditor " ) ;
}
}
2017-09-18 12:39:17 -04:00
samplepos_t nudge_clock_value ;
2016-08-26 23:44:57 -04:00
if ( node . get_property ( " nudge-clock-value " , nudge_clock_value ) ) {
nudge_clock - > set ( nudge_clock_value ) ;
2012-03-17 10:10:44 -04:00
} else {
nudge_clock - > set_mode ( AudioClock : : Timecode ) ;
2017-09-18 12:39:17 -04:00
nudge_clock - > set ( _session - > sample_rate ( ) * 5 , true ) ;
2012-03-17 10:10:44 -04:00
}
2015-03-21 14:31:02 -04:00
{
/* apply state
* Not all properties may have been in XML , but
* those that are linked to a private variable may need changing
*/
2018-12-12 11:22:38 -05:00
RefPtr < ToggleAction > tact ;
2015-03-21 14:31:02 -04:00
2018-12-12 11:22:38 -05:00
tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " toggle-follow-playhead " ) ) ;
2015-03-21 14:31:02 -04:00
yn = _follow_playhead ;
2018-12-12 11:22:38 -05:00
if ( tact - > get_active ( ) ! = yn ) {
tact - > set_active ( yn ) ;
2015-03-21 14:31:02 -04:00
}
2018-12-12 11:22:38 -05:00
tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " toggle-stationary-playhead " ) ) ;
2015-03-21 14:31:02 -04:00
yn = _stationary_playhead ;
2018-12-12 11:22:38 -05:00
if ( tact - > get_active ( ) ! = yn ) {
tact - > set_active ( yn ) ;
2015-03-21 14:31:02 -04:00
}
}
2018-11-04 12:46:21 -05:00
return 0 ;
2005-09-25 14:42:24 -04:00
}
XMLNode &
Editor : : get_state ( )
{
2015-07-09 12:40:51 -04:00
XMLNode * node = new XMLNode ( X_ ( " Editor " ) ) ;
2005-09-25 14:42:24 -04:00
2016-08-26 23:44:57 -04:00
node - > set_property ( " id " , id ( ) . to_s ( ) ) ;
2015-07-07 22:12:21 -04:00
2015-07-09 12:40:51 -04:00
node - > add_child_nocopy ( Tabbable : : get_state ( ) ) ;
2015-10-26 14:35:06 -04:00
2016-08-26 23:44:57 -04:00
node - > set_property ( " edit-horizontal-pane-pos " , edit_pane . get_divider ( ) ) ;
node - > set_property ( " notebook-shrunk " , _notebook_shrunk ) ;
node - > set_property ( " edit-vertical-pane-pos " , editor_summary_pane . get_divider ( ) ) ;
2015-10-26 14:35:06 -04:00
2015-07-09 12:40:51 -04:00
maybe_add_mixer_strip_width ( * node ) ;
2009-10-14 12:10:01 -04:00
2016-08-26 23:44:57 -04:00
node - > set_property ( " zoom-focus " , zoom_focus ) ;
node - > set_property ( " zoom " , samples_per_pixel ) ;
2018-02-09 10:59:39 -05:00
node - > set_property ( " grid-type " , _grid_type ) ;
2016-08-26 23:44:57 -04:00
node - > set_property ( " snap-mode " , _snap_mode ) ;
2018-02-09 10:59:39 -05:00
node - > set_property ( " internal-grid-type " , internal_grid_type ) ;
2016-08-26 23:44:57 -04:00
node - > set_property ( " internal-snap-mode " , internal_snap_mode ) ;
2018-02-09 10:59:39 -05:00
node - > set_property ( " pre-internal-grid-type " , pre_internal_grid_type ) ;
2016-08-26 23:44:57 -04:00
node - > set_property ( " pre-internal-snap-mode " , pre_internal_snap_mode ) ;
node - > set_property ( " edit-point " , _edit_point ) ;
node - > set_property ( " visible-track-count " , _visible_track_count ) ;
2017-09-18 12:39:17 -04:00
node - > set_property ( " playhead " , playhead_cursor - > current_sample ( ) ) ;
node - > set_property ( " left-frame " , _leftmost_sample ) ;
2016-08-26 23:44:57 -04:00
node - > set_property ( " y-origin " , vertical_adjustment . get_value ( ) ) ;
node - > set_property ( " maximised " , _maximised ) ;
node - > set_property ( " follow-playhead " , _follow_playhead ) ;
node - > set_property ( " stationary-playhead " , _stationary_playhead ) ;
node - > set_property ( " mouse-mode " , mouse_mode ) ;
node - > set_property ( " join-object-range " , smart_mode_action - > get_active ( ) ) ;
2009-10-14 12:10:01 -04:00
2018-12-12 11:22:38 -05:00
Glib : : RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " show-editor-mixer " ) ) ;
node - > set_property ( X_ ( " show-editor-mixer " ) , tact - > get_active ( ) ) ;
2009-10-14 12:10:01 -04:00
2018-12-12 11:22:38 -05:00
tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " show-editor-list " ) ) ;
node - > set_property ( X_ ( " show-editor-list " ) , tact - > get_active ( ) ) ;
2006-01-30 22:27:25 -05:00
2016-08-26 23:44:57 -04:00
node - > set_property ( X_ ( " editor-list-page " ) , _the_notebook . get_current_page ( ) ) ;
2010-04-05 13:38:54 -04:00
2016-08-26 23:44:57 -04:00
if ( button_bindings ) {
XMLNode * bb = new XMLNode ( X_ ( " Buttons " ) ) ;
button_bindings - > save ( * bb ) ;
node - > add_child_nocopy ( * bb ) ;
}
2011-03-03 22:10:48 -05:00
2016-08-26 23:44:57 -04:00
node - > set_property ( X_ ( " show-marker-lines " ) , _show_marker_lines ) ;
2010-11-10 13:29:32 -05:00
2015-07-09 12:40:51 -04:00
node - > add_child_nocopy ( selection - > get_state ( ) ) ;
node - > add_child_nocopy ( _regions - > get_state ( ) ) ;
2011-06-01 13:00:29 -04:00
2016-08-26 23:44:57 -04:00
node - > set_property ( " nudge-clock-value " , nudge_clock - > current_duration ( ) ) ;
2012-03-17 10:10:44 -04:00
2017-02-14 11:15:16 -05:00
node - > add_child_nocopy ( _locations - > get_state ( ) ) ;
2016-02-23 09:42:53 -05:00
2015-07-09 12:40:51 -04:00
return * node ;
2005-09-25 14:42:24 -04:00
}
2014-06-08 14:41:29 -04:00
/** if @param trackview_relative_offset is true, @param y y is an offset into the trackview area, in pixel units
* if @ param trackview_relative_offset is false , @ param y y is a global canvas * coordinate , in pixel units
2014-06-03 15:57:56 -04:00
*
2009-01-05 22:18:09 -05:00
* @ return pair : TimeAxisView that y is over , layer index .
2014-06-03 15:57:56 -04:00
*
2009-01-05 22:18:09 -05:00
* TimeAxisView may be 0. Layer index is the layer number if the TimeAxisView is valid and is
2011-12-29 17:14:15 -05:00
* in stacked or expanded region display mode , otherwise 0.
2009-01-05 22:18:09 -05:00
*/
2011-12-26 20:42:49 -05:00
std : : pair < TimeAxisView * , double >
2014-06-18 10:24:59 -04:00
Editor : : trackview_by_y_position ( double y , bool trackview_relative_offset ) const
2005-09-25 14:42:24 -04:00
{
2014-06-08 14:41:29 -04:00
if ( ! trackview_relative_offset ) {
y - = _trackview_group - > canvas_origin ( ) . y ;
}
2014-06-08 11:26:25 -04:00
if ( y < 0 ) {
2018-02-24 07:54:15 -05:00
return std : : make_pair ( ( TimeAxisView * ) 0 , 0 ) ;
2014-06-08 11:26:25 -04:00
}
2014-06-08 14:41:29 -04:00
2014-06-18 10:24:59 -04:00
for ( TrackViewList : : const_iterator iter = track_views . begin ( ) ; iter ! = track_views . end ( ) ; + + iter ) {
2015-10-05 10:17:49 -04:00
2014-06-08 11:26:25 -04:00
std : : pair < TimeAxisView * , double > const r = ( * iter ) - > covers_y_position ( y ) ;
2015-10-05 10:17:49 -04:00
2014-06-08 11:26:25 -04:00
if ( r . first ) {
return r ;
2005-09-25 14:42:24 -04:00
}
}
2014-06-08 14:41:29 -04:00
2018-02-24 07:54:15 -05:00
return std : : make_pair ( ( TimeAxisView * ) 0 , 0 ) ;
2005-09-25 14:42:24 -04:00
}
2018-02-09 09:21:45 -05:00
void
Editor : : set_snapped_cursor_position ( samplepos_t pos )
{
2018-02-24 07:54:15 -05:00
if ( _edit_point = = EditAtMouse ) {
2018-02-09 09:21:45 -05:00
snapped_cursor - > set_position ( pos ) ;
}
}
2009-08-24 16:26:34 -04:00
/** Snap a position to the grid, if appropriate, taking into account current
* grid settings and also the state of any snap modifier keys that may be pressed .
* @ param start Position to snap .
2009-12-21 20:12:41 -05:00
* @ param event Event to get current key modifier information from , or 0.
2009-08-24 16:26:34 -04:00
*/
void
2018-07-26 15:23:59 -04:00
Editor : : snap_to_with_modifier ( MusicSample & start , GdkEvent const * event , RoundMode direction , SnapPref pref )
2009-08-24 16:26:34 -04:00
{
2009-12-21 20:12:41 -05:00
if ( ! _session | | ! event ) {
2009-08-24 16:26:34 -04:00
return ;
}
2015-05-21 12:12:58 -04:00
if ( ArdourKeyboard : : indicates_snap ( event - > button . state ) ) {
2009-10-26 19:43:04 -04:00
if ( _snap_mode = = SnapOff ) {
2018-07-26 15:23:59 -04:00
snap_to_internal ( start , direction , pref ) ;
2017-01-26 08:41:17 -05:00
} else {
2017-09-18 12:39:17 -04:00
start . set ( start . sample , 0 ) ;
2009-08-24 16:26:34 -04:00
}
} else {
2009-10-26 19:43:04 -04:00
if ( _snap_mode ! = SnapOff ) {
2018-07-26 15:23:59 -04:00
snap_to_internal ( start , direction , pref ) ;
2015-05-22 13:09:48 -04:00
} else if ( ArdourKeyboard : : indicates_snap_delta ( event - > button . state ) ) {
/* SnapOff, but we pressed the snap_delta modifier */
2018-07-26 15:23:59 -04:00
snap_to_internal ( start , direction , pref ) ;
2017-01-26 08:41:17 -05:00
} else {
2017-09-18 12:39:17 -04:00
start . set ( start . sample , 0 ) ;
2009-08-24 16:26:34 -04:00
}
}
}
2005-09-25 14:42:24 -04:00
void
2018-07-26 15:23:59 -04:00
Editor : : snap_to ( MusicSample & start , RoundMode direction , SnapPref pref , bool ensure_snap )
2005-09-25 14:42:24 -04:00
{
2015-05-22 13:09:48 -04:00
if ( ! _session | | ( _snap_mode = = SnapOff & & ! ensure_snap ) ) {
2017-09-18 12:39:17 -04:00
start . set ( start . sample , 0 ) ;
2005-09-25 14:42:24 -04:00
return ;
}
2018-07-26 15:23:59 -04:00
snap_to_internal ( start , direction , pref , ensure_snap ) ;
2015-05-16 14:26:05 -04:00
}
2020-04-05 14:08:33 -04:00
static void
2018-02-24 07:54:15 -05:00
check_best_snap ( samplepos_t presnap , samplepos_t & test , samplepos_t & dist , samplepos_t & best )
2008-02-19 17:10:27 -05:00
{
2018-02-24 07:54:15 -05:00
samplepos_t diff = abs ( test - presnap ) ;
if ( diff < dist ) {
2018-02-09 10:59:39 -05:00
dist = diff ;
best = test ;
2009-10-26 10:38:58 -04:00
}
2017-01-26 08:41:17 -05:00
2018-02-24 07:54:15 -05:00
test = max_samplepos ; // reset this so it doesn't get accidentally reused
2009-10-26 10:38:58 -04:00
}
2018-07-26 15:23:59 -04:00
MusicSample
2018-07-26 18:25:01 -04:00
Editor : : snap_to_timecode ( MusicSample presnap , RoundMode direction , SnapPref gpref )
2009-10-26 10:38:58 -04:00
{
2018-07-26 15:23:59 -04:00
samplepos_t start = presnap . sample ;
const samplepos_t one_timecode_second = ( samplepos_t ) ( rint ( _session - > timecode_frames_per_second ( ) ) * _session - > samples_per_timecode_frame ( ) ) ;
samplepos_t one_timecode_minute = ( samplepos_t ) ( rint ( _session - > timecode_frames_per_second ( ) ) * _session - > samples_per_timecode_frame ( ) * 60 ) ;
2018-02-11 13:05:23 -05:00
2018-07-26 18:25:01 -04:00
TimecodeRulerScale scale = ( gpref ! = SnapToGrid_Unscaled ) ? timecode_ruler_scale : timecode_show_samples ;
2009-10-26 10:38:58 -04:00
2018-07-26 15:23:59 -04:00
switch ( scale ) {
case timecode_show_bits :
case timecode_show_samples :
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
fmod ( ( double ) start , ( double ) _session - > samples_per_timecode_frame ( ) ) = = 0 ) {
/* start is already on a whole timecode frame, do nothing */
} else if ( ( ( direction = = 0 ) & & ( fmod ( ( double ) start , ( double ) _session - > samples_per_timecode_frame ( ) ) > ( _session - > samples_per_timecode_frame ( ) / 2 ) ) ) | | ( direction > 0 ) ) {
start = ( samplepos_t ) ( ceil ( ( double ) start / _session - > samples_per_timecode_frame ( ) ) * _session - > samples_per_timecode_frame ( ) ) ;
} else {
start = ( samplepos_t ) ( floor ( ( double ) start / _session - > samples_per_timecode_frame ( ) ) * _session - > samples_per_timecode_frame ( ) ) ;
}
break ;
2009-10-14 12:10:01 -04:00
2018-07-26 15:23:59 -04:00
case timecode_show_seconds :
if ( _session - > config . get_timecode_offset_negative ( ) ) {
start + = _session - > config . get_timecode_offset ( ) ;
} else {
start - = _session - > config . get_timecode_offset ( ) ;
}
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
( start % one_timecode_second = = 0 ) ) {
/* start is already on a whole second, do nothing */
} else if ( ( ( direction = = 0 ) & & ( start % one_timecode_second > one_timecode_second / 2 ) ) | | direction > 0 ) {
start = ( samplepos_t ) ceil ( ( double ) start / one_timecode_second ) * one_timecode_second ;
} else {
start = ( samplepos_t ) floor ( ( double ) start / one_timecode_second ) * one_timecode_second ;
}
2017-01-26 08:41:17 -05:00
2018-07-26 15:23:59 -04:00
if ( _session - > config . get_timecode_offset_negative ( ) ) {
start - = _session - > config . get_timecode_offset ( ) ;
} else {
start + = _session - > config . get_timecode_offset ( ) ;
}
break ;
2017-01-26 08:41:17 -05:00
2018-07-26 15:23:59 -04:00
case timecode_show_minutes :
case timecode_show_hours :
case timecode_show_many_hours :
if ( _session - > config . get_timecode_offset_negative ( ) ) {
start + = _session - > config . get_timecode_offset ( ) ;
} else {
start - = _session - > config . get_timecode_offset ( ) ;
}
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
( start % one_timecode_minute = = 0 ) ) {
/* start is already on a whole minute, do nothing */
} else if ( ( ( direction = = 0 ) & & ( start % one_timecode_minute > one_timecode_minute / 2 ) ) | | direction > 0 ) {
start = ( samplepos_t ) ceil ( ( double ) start / one_timecode_minute ) * one_timecode_minute ;
} else {
start = ( samplepos_t ) floor ( ( double ) start / one_timecode_minute ) * one_timecode_minute ;
}
if ( _session - > config . get_timecode_offset_negative ( ) ) {
start - = _session - > config . get_timecode_offset ( ) ;
} else {
start + = _session - > config . get_timecode_offset ( ) ;
}
break ;
default :
fatal < < " Editor::smpte_snap_to_internal() called with non-timecode snap type! " < < endmsg ;
2018-02-09 10:59:39 -05:00
}
2009-10-14 12:10:01 -04:00
2018-07-26 15:23:59 -04:00
MusicSample ret ( start , 0 ) ;
return ret ;
}
MusicSample
2018-07-26 18:25:01 -04:00
Editor : : snap_to_minsec ( MusicSample presnap , RoundMode direction , SnapPref gpref )
2018-07-26 15:23:59 -04:00
{
MusicSample ret ( presnap ) ;
2018-12-12 11:22:38 -05:00
2018-07-26 15:23:59 -04:00
const samplepos_t one_second = _session - > sample_rate ( ) ;
const samplepos_t one_minute = one_second * 60 ;
const samplepos_t one_hour = one_minute * 60 ;
2018-07-26 18:25:01 -04:00
MinsecRulerScale scale = ( gpref ! = SnapToGrid_Unscaled ) ? minsec_ruler_scale : minsec_show_seconds ;
2018-07-26 15:23:59 -04:00
switch ( scale ) {
case minsec_show_msecs :
case minsec_show_seconds : {
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
presnap . sample % one_second = = 0 ) {
/* start is already on a whole second, do nothing */
} else if ( ( ( direction = = 0 ) & & ( presnap . sample % one_second > one_second / 2 ) ) | | ( direction > 0 ) ) {
ret . sample = ( samplepos_t ) ceil ( ( double ) presnap . sample / one_second ) * one_second ;
2018-02-09 10:59:39 -05:00
} else {
2018-07-26 15:23:59 -04:00
ret . sample = ( samplepos_t ) floor ( ( double ) presnap . sample / one_second ) * one_second ;
2018-02-09 10:59:39 -05:00
}
2018-07-26 15:23:59 -04:00
} break ;
case minsec_show_minutes : {
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
presnap . sample % one_minute = = 0 ) {
/* start is already on a whole minute, do nothing */
} else if ( ( ( direction = = 0 ) & & ( presnap . sample % one_minute > one_minute / 2 ) ) | | ( direction > 0 ) ) {
ret . sample = ( samplepos_t ) ceil ( ( double ) presnap . sample / one_minute ) * one_minute ;
} else {
ret . sample = ( samplepos_t ) floor ( ( double ) presnap . sample / one_minute ) * one_minute ;
}
} break ;
default : {
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
presnap . sample % one_hour = = 0 ) {
/* start is already on a whole hour, do nothing */
} else if ( ( ( direction = = 0 ) & & ( presnap . sample % one_hour > one_hour / 2 ) ) | | ( direction > 0 ) ) {
ret . sample = ( samplepos_t ) ceil ( ( double ) presnap . sample / one_hour ) * one_hour ;
} else {
ret . sample = ( samplepos_t ) floor ( ( double ) presnap . sample / one_hour ) * one_hour ;
}
} break ;
}
2018-12-12 11:22:38 -05:00
2018-07-26 15:23:59 -04:00
return ret ;
}
MusicSample
2018-07-26 18:25:01 -04:00
Editor : : snap_to_cd_frames ( MusicSample presnap , RoundMode direction , SnapPref gpref )
2018-07-26 15:23:59 -04:00
{
2018-07-26 18:25:01 -04:00
if ( ( gpref ! = SnapToGrid_Unscaled ) & & ( minsec_ruler_scale ! = minsec_show_msecs ) ) {
return snap_to_minsec ( presnap , direction , gpref ) ;
2018-12-12 11:22:38 -05:00
}
2018-07-26 15:23:59 -04:00
const samplepos_t one_second = _session - > sample_rate ( ) ;
MusicSample ret ( presnap ) ;
2018-12-12 11:22:38 -05:00
2018-07-26 15:23:59 -04:00
if ( ( direction = = RoundUpMaybe | | direction = = RoundDownMaybe ) & &
presnap . sample % ( one_second / 75 ) = = 0 ) {
/* start is already on a whole CD sample, do nothing */
} else if ( ( ( direction = = 0 ) & & ( presnap . sample % ( one_second / 75 ) > ( one_second / 75 ) / 2 ) ) | | ( direction > 0 ) ) {
ret . sample = ( samplepos_t ) ceil ( ( double ) presnap . sample / ( one_second / 75 ) ) * ( one_second / 75 ) ;
} else {
ret . sample = ( samplepos_t ) floor ( ( double ) presnap . sample / ( one_second / 75 ) ) * ( one_second / 75 ) ;
}
return ret ;
}
MusicSample
2018-07-26 18:25:01 -04:00
Editor : : snap_to_bbt ( MusicSample presnap , RoundMode direction , SnapPref gpref )
2018-07-26 15:23:59 -04:00
{
MusicSample ret ( presnap ) ;
2018-12-12 11:22:38 -05:00
2018-07-26 18:25:01 -04:00
if ( gpref ! = SnapToGrid_Unscaled ) { // use the visual grid lines which are limited by the zoom scale that the user selected
2018-07-26 15:23:59 -04:00
int divisor = 2 ;
switch ( _grid_type ) {
case GridTypeBeatDiv3 :
case GridTypeBeatDiv6 :
case GridTypeBeatDiv12 :
case GridTypeBeatDiv24 :
divisor = 3 ;
break ;
case GridTypeBeatDiv5 :
case GridTypeBeatDiv10 :
case GridTypeBeatDiv20 :
divisor = 5 ;
break ;
case GridTypeBeatDiv7 :
case GridTypeBeatDiv14 :
case GridTypeBeatDiv28 :
divisor = 7 ;
break ;
default :
divisor = 2 ;
} ;
BBTRulerScale scale = bbt_ruler_scale ;
switch ( scale ) {
case bbt_show_many :
case bbt_show_64 :
case bbt_show_16 :
case bbt_show_4 :
case bbt_show_1 :
ret = _session - > tempo_map ( ) . round_to_bar ( presnap . sample , direction ) ;
break ;
case bbt_show_quarters :
ret = _session - > tempo_map ( ) . round_to_beat ( presnap . sample , direction ) ;
break ;
case bbt_show_eighths :
ret = _session - > tempo_map ( ) . round_to_quarter_note_subdivision ( presnap . sample , 1 * divisor , direction ) ;
break ;
case bbt_show_sixteenths :
ret = _session - > tempo_map ( ) . round_to_quarter_note_subdivision ( presnap . sample , 2 * divisor , direction ) ;
break ;
case bbt_show_thirtyseconds :
ret = _session - > tempo_map ( ) . round_to_quarter_note_subdivision ( presnap . sample , 4 * divisor , direction ) ;
break ;
2005-09-25 14:42:24 -04:00
}
2018-07-26 15:23:59 -04:00
} else {
ret = _session - > tempo_map ( ) . round_to_quarter_note_subdivision ( presnap . sample , get_grid_beat_divisions ( _grid_type ) , direction ) ;
2018-02-09 10:59:39 -05:00
}
2018-12-12 11:22:38 -05:00
2018-07-26 15:23:59 -04:00
return ret ;
}
2017-01-26 08:41:17 -05:00
2018-07-26 15:23:59 -04:00
ARDOUR : : MusicSample
2018-07-26 18:25:01 -04:00
Editor : : snap_to_grid ( MusicSample presnap , RoundMode direction , SnapPref gpref )
2018-07-26 15:23:59 -04:00
{
MusicSample ret ( presnap ) ;
2018-12-12 11:22:38 -05:00
2018-07-26 18:25:01 -04:00
if ( grid_musical ( ) ) {
2018-07-26 15:23:59 -04:00
ret = snap_to_bbt ( presnap , direction , gpref ) ;
}
2018-12-12 11:22:38 -05:00
2018-07-26 15:23:59 -04:00
switch ( _grid_type ) {
case GridTypeTimecode :
ret = snap_to_timecode ( presnap , direction , gpref ) ;
break ;
case GridTypeMinSec :
ret = snap_to_minsec ( presnap , direction , gpref ) ;
break ;
case GridTypeCDFrame :
ret = snap_to_cd_frames ( presnap , direction , gpref ) ;
break ;
default :
{ }
} ;
return ret ;
2018-02-09 10:59:39 -05:00
}
2017-01-26 08:41:17 -05:00
2018-02-09 10:59:39 -05:00
samplepos_t
2018-07-26 15:23:59 -04:00
Editor : : snap_to_marker ( samplepos_t presnap , RoundMode direction )
2018-02-09 10:59:39 -05:00
{
samplepos_t before ;
samplepos_t after ;
samplepos_t test ;
2020-03-28 09:10:36 -04:00
if ( _session - > locations ( ) - > list ( ) . empty ( ) ) {
/* No marks to snap to, so just don't snap */
2020-03-30 12:16:09 -04:00
return 0 ;
2020-03-28 09:10:36 -04:00
}
2018-02-09 10:59:39 -05:00
_session - > locations ( ) - > marks_either_side ( presnap , before , after ) ;
2020-03-28 09:10:36 -04:00
if ( before = = max_samplepos ) {
2018-02-09 10:59:39 -05:00
test = after ;
} else if ( after = = max_samplepos ) {
test = before ;
} else {
if ( ( direction = = RoundUpMaybe | | direction = = RoundUpAlways ) ) {
test = after ;
} else if ( ( direction = = RoundDownMaybe | | direction = = RoundDownAlways ) ) {
test = before ;
2018-02-24 07:54:15 -05:00
} else if ( direction = = 0 ) {
2018-02-09 10:59:39 -05:00
if ( ( presnap - before ) < ( after - presnap ) ) {
test = before ;
} else {
test = after ;
}
}
}
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
return test ;
}
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
void
2018-07-26 15:23:59 -04:00
Editor : : snap_to_internal ( MusicSample & start , RoundMode direction , SnapPref pref , bool ensure_snap )
2018-02-09 10:59:39 -05:00
{
2020-04-05 14:08:33 -04:00
UIConfiguration const & uic ( UIConfiguration : : instance ( ) ) ;
2018-02-09 10:59:39 -05:00
const samplepos_t presnap = start . sample ;
2005-09-25 14:42:24 -04:00
2018-02-24 07:54:15 -05:00
samplepos_t test = max_samplepos ; // for each snap, we'll use this value
samplepos_t dist = max_samplepos ; // this records the distance of the best snap result we've found so far
samplepos_t best = max_samplepos ; // this records the best snap-result we've found so far
2005-09-25 14:42:24 -04:00
2018-02-24 07:54:15 -05:00
/* check snap-to-marker */
2020-04-05 14:08:33 -04:00
if ( ( pref = = SnapToAny_Visual ) & & uic . get_snap_to_marks ( ) ) {
2018-07-26 15:23:59 -04:00
test = snap_to_marker ( presnap , direction ) ;
2020-04-05 14:08:33 -04:00
check_best_snap ( presnap , test , dist , best ) ;
2018-02-09 10:59:39 -05:00
}
2005-09-25 14:42:24 -04:00
2018-02-24 07:54:15 -05:00
/* check snap-to-region-{start/end/sync} */
2020-04-05 14:08:33 -04:00
if ( ( pref = = SnapToAny_Visual ) & & ( uic . get_snap_to_region_start ( ) | | uic . get_snap_to_region_end ( ) | | uic . get_snap_to_region_sync ( ) ) ) {
2020-03-30 19:21:39 -04:00
2020-04-05 14:08:33 -04:00
if ( ! region_boundary_cache . empty ( ) ) {
2005-09-25 14:42:24 -04:00
2020-04-05 14:08:33 -04:00
vector < samplepos_t > : : iterator prev = region_boundary_cache . begin ( ) ;
vector < samplepos_t > : : iterator next = std : : upper_bound ( region_boundary_cache . begin ( ) , region_boundary_cache . end ( ) , presnap ) ;
2009-08-22 15:45:40 -04:00
if ( next ! = region_boundary_cache . begin ( ) ) {
prev = next ;
prev - - ;
}
2020-04-22 16:37:43 -04:00
if ( next = = region_boundary_cache . end ( ) ) {
next - - ;
}
2008-02-19 17:10:27 -05:00
2020-03-30 19:21:57 -04:00
if ( ( direction = = RoundUpMaybe | | direction = = RoundUpAlways ) ) {
2018-05-02 17:37:14 -04:00
test = * next ;
2020-03-30 19:21:57 -04:00
} else if ( ( direction = = RoundDownMaybe | | direction = = RoundDownAlways ) ) {
2018-05-02 17:37:14 -04:00
test = * prev ;
2020-03-30 19:21:57 -04:00
} else if ( direction = = 0 ) {
2018-05-02 17:37:14 -04:00
if ( ( presnap - * prev ) < ( * next - presnap ) ) {
test = * prev ;
} else {
test = * next ;
}
2005-09-25 14:42:24 -04:00
}
2018-06-09 13:08:15 -04:00
2009-10-14 12:10:01 -04:00
}
2017-01-26 08:41:17 -05:00
2020-04-05 14:08:33 -04:00
check_best_snap ( presnap , test , dist , best ) ;
2005-09-25 14:42:24 -04:00
}
2018-02-24 07:54:15 -05:00
/* check Grid */
2020-04-05 14:08:33 -04:00
if ( uic . get_snap_to_grid ( ) & & ( _grid_type ! = GridTypeNone ) ) {
MusicSample pre ( presnap , 0 ) ;
2018-07-26 18:25:01 -04:00
MusicSample post = snap_to_grid ( pre , direction , pref ) ;
2020-04-05 14:08:33 -04:00
check_best_snap ( presnap , post . sample , dist , best ) ;
2018-02-09 10:59:39 -05:00
}
2009-10-14 12:10:01 -04:00
2020-04-05 14:09:42 -04:00
if ( max_samplepos = = best ) {
return ;
}
2018-02-24 07:54:15 -05:00
/* now check "magnetic" state: is the grid within reasonable on-screen distance to trigger a snap?
* this also helps to avoid snapping to somewhere the user can ' t see . ( i . e . : I clicked on a region and it disappeared ! ! )
* ToDo : Perhaps this should only occur if EditPointMouse ?
*/
2020-04-05 14:09:42 -04:00
samplecnt_t snap_threshold_s = pixel_to_sample ( uic . get_snap_threshold ( ) ) ;
if ( ! ensure_snap & & : : llabs ( presnap - best ) > snap_threshold_s ) {
2005-09-25 14:42:24 -04:00
return ;
}
2018-02-09 10:59:39 -05:00
start . set ( best , 0 ) ;
2005-09-25 14:42:24 -04:00
}
2007-08-06 01:30:18 -04:00
2005-09-25 14:42:24 -04:00
void
Editor : : setup_toolbar ( )
{
2006-06-30 04:03:43 -04:00
HBox * mode_box = manage ( new HBox ) ;
mode_box - > set_border_width ( 2 ) ;
2014-07-09 15:32:13 -04:00
mode_box - > set_spacing ( 2 ) ;
2010-01-01 17:11:15 -05:00
2012-02-03 13:31:10 -05:00
HBox * mouse_mode_box = manage ( new HBox ) ;
2012-11-26 17:43:10 -05:00
HBox * mouse_mode_hbox = manage ( new HBox ) ;
VBox * mouse_mode_vbox = manage ( new VBox ) ;
Alignment * mouse_mode_align = manage ( new Alignment ) ;
2012-02-03 13:31:10 -05:00
2014-09-08 16:02:16 -04:00
Glib : : RefPtr < SizeGroup > mouse_mode_size_group = SizeGroup : : create ( SIZE_GROUP_VERTICAL ) ;
mouse_mode_size_group - > add_widget ( smart_mode_button ) ;
2012-02-03 13:31:10 -05:00
mouse_mode_size_group - > add_widget ( mouse_move_button ) ;
2019-09-29 11:11:43 -04:00
mouse_mode_size_group - > add_widget ( mouse_cut_button ) ;
2012-02-03 13:31:10 -05:00
mouse_mode_size_group - > add_widget ( mouse_select_button ) ;
mouse_mode_size_group - > add_widget ( mouse_timefx_button ) ;
2019-04-08 21:16:09 -04:00
if ( ! Profile - > get_mixbus ( ) ) {
mouse_mode_size_group - > add_widget ( mouse_audition_button ) ;
}
2012-02-03 13:31:10 -05:00
mouse_mode_size_group - > add_widget ( mouse_draw_button ) ;
2014-12-08 23:00:00 -05:00
mouse_mode_size_group - > add_widget ( mouse_content_button ) ;
2012-02-03 13:31:10 -05:00
2016-12-20 12:48:02 -05:00
if ( ! Profile - > get_mixbus ( ) ) {
mouse_mode_size_group - > add_widget ( zoom_in_button ) ;
mouse_mode_size_group - > add_widget ( zoom_out_button ) ;
mouse_mode_size_group - > add_widget ( zoom_out_full_button ) ;
mouse_mode_size_group - > add_widget ( zoom_focus_selector ) ;
mouse_mode_size_group - > add_widget ( tav_shrink_button ) ;
mouse_mode_size_group - > add_widget ( tav_expand_button ) ;
2016-12-20 13:01:59 -05:00
} else {
mouse_mode_size_group - > add_widget ( zoom_preset_selector ) ;
mouse_mode_size_group - > add_widget ( visible_tracks_selector ) ;
2016-12-20 12:48:02 -05:00
}
2014-09-08 19:24:17 -04:00
2018-02-09 10:59:39 -05:00
mouse_mode_size_group - > add_widget ( grid_type_selector ) ;
mouse_mode_size_group - > add_widget ( snap_mode_button ) ;
2014-09-08 19:24:17 -04:00
mouse_mode_size_group - > add_widget ( edit_point_selector ) ;
mouse_mode_size_group - > add_widget ( edit_mode_selector ) ;
mouse_mode_size_group - > add_widget ( * nudge_clock ) ;
mouse_mode_size_group - > add_widget ( nudge_forward_button ) ;
mouse_mode_size_group - > add_widget ( nudge_backward_button ) ;
2012-11-26 17:43:10 -05:00
mouse_mode_hbox - > set_spacing ( 2 ) ;
2019-09-25 15:02:31 -04:00
mouse_mode_hbox - > pack_start ( smart_mode_button , false , false ) ;
2014-04-10 13:30:25 -04:00
2012-11-26 17:43:10 -05:00
mouse_mode_hbox - > pack_start ( mouse_move_button , false , false ) ;
mouse_mode_hbox - > pack_start ( mouse_select_button , false , false ) ;
2014-07-11 16:41:28 -04:00
2019-09-29 11:11:43 -04:00
mouse_mode_hbox - > pack_start ( mouse_cut_button , false , false ) ;
2014-07-11 16:41:28 -04:00
if ( ! ARDOUR : : Profile - > get_mixbus ( ) ) {
2018-02-11 10:39:45 -05:00
mouse_mode_hbox - > pack_start ( mouse_audition_button , false , false ) ;
2014-07-11 16:41:28 -04:00
}
2015-10-05 10:17:49 -04:00
2019-09-25 15:02:31 -04:00
mouse_mode_hbox - > pack_start ( mouse_timefx_button , false , false ) ;
mouse_mode_hbox - > pack_start ( mouse_draw_button , false , false ) ;
mouse_mode_hbox - > pack_start ( mouse_content_button , false , false ) ;
2012-02-03 13:31:10 -05:00
2012-11-26 17:43:10 -05:00
mouse_mode_vbox - > pack_start ( * mouse_mode_hbox ) ;
2012-02-03 13:31:10 -05:00
2012-11-26 17:43:10 -05:00
mouse_mode_align - > add ( * mouse_mode_vbox ) ;
mouse_mode_align - > set ( 0.5 , 1.0 , 0.0 , 0.0 ) ;
2012-02-03 13:31:10 -05:00
2012-11-26 17:43:10 -05:00
mouse_mode_box - > pack_start ( * mouse_mode_align , false , false ) ;
2010-02-08 22:17:02 -05:00
2014-03-23 19:11:42 -04:00
edit_mode_selector . set_name ( " mouse mode button " ) ;
2006-06-30 04:03:43 -04:00
2019-09-25 15:02:31 -04:00
mode_box - > pack_start ( edit_mode_selector , false , false ) ;
mode_box - > pack_start ( * ( manage ( new ArdourVSpacer ( ) ) ) , false , false , 3 ) ;
mode_box - > pack_start ( edit_point_selector , false , false ) ;
mode_box - > pack_start ( * ( manage ( new ArdourVSpacer ( ) ) ) , false , false , 3 ) ;
2015-10-26 14:35:06 -04:00
2012-02-03 13:31:10 -05:00
mode_box - > pack_start ( * mouse_mode_box , false , false ) ;
2015-10-26 14:35:06 -04:00
2006-06-30 04:03:43 -04:00
/* Zoom */
2009-10-14 12:10:01 -04:00
2011-11-11 12:35:22 -05:00
_zoom_box . set_spacing ( 2 ) ;
_zoom_box . set_border_width ( 2 ) ;
2005-09-25 14:42:24 -04:00
2011-11-10 13:04:34 -05:00
RefPtr < Action > act ;
2014-07-11 15:50:51 -04:00
zoom_preset_selector . set_name ( " zoom button " ) ;
2016-12-20 12:48:02 -05:00
zoom_preset_selector . set_icon ( ArdourIcon : : ZoomExpand ) ;
2014-07-11 15:50:51 -04:00
2014-03-25 07:35:41 -04:00
zoom_in_button . set_name ( " zoom button " ) ;
2015-05-24 17:10:02 -04:00
zoom_in_button . set_icon ( ArdourIcon : : ZoomIn ) ;
2011-11-10 13:04:34 -05:00
act = ActionManager : : get_action ( X_ ( " Editor " ) , X_ ( " temporal-zoom-in " ) ) ;
2012-12-06 15:48:44 -05:00
zoom_in_button . set_related_action ( act ) ;
2009-10-14 12:10:01 -04:00
2014-03-25 07:35:41 -04:00
zoom_out_button . set_name ( " zoom button " ) ;
2015-05-24 17:10:02 -04:00
zoom_out_button . set_icon ( ArdourIcon : : ZoomOut ) ;
2011-11-10 13:04:34 -05:00
act = ActionManager : : get_action ( X_ ( " Editor " ) , X_ ( " temporal-zoom-out " ) ) ;
2012-12-06 15:48:44 -05:00
zoom_out_button . set_related_action ( act ) ;
2005-09-25 14:42:24 -04:00
2014-03-25 07:35:41 -04:00
zoom_out_full_button . set_name ( " zoom button " ) ;
2015-05-24 17:10:02 -04:00
zoom_out_full_button . set_icon ( ArdourIcon : : ZoomFull ) ;
2011-11-10 13:04:34 -05:00
act = ActionManager : : get_action ( X_ ( " Editor " ) , X_ ( " zoom-to-session " ) ) ;
2012-12-06 15:48:44 -05:00
zoom_out_full_button . set_related_action ( act ) ;
2007-01-28 12:44:13 -05:00
2014-03-25 07:35:41 -04:00
zoom_focus_selector . set_name ( " zoom button " ) ;
2005-09-25 14:42:24 -04:00
2014-07-09 16:11:58 -04:00
if ( ARDOUR : : Profile - > get_mixbus ( ) ) {
2014-07-11 15:50:51 -04:00
_zoom_box . pack_start ( zoom_preset_selector , false , false ) ;
2014-07-09 16:11:58 -04:00
} else {
_zoom_box . pack_start ( zoom_out_button , false , false ) ;
_zoom_box . pack_start ( zoom_in_button , false , false ) ;
_zoom_box . pack_start ( zoom_out_full_button , false , false ) ;
_zoom_box . pack_start ( zoom_focus_selector , false , false ) ;
2014-04-10 13:30:25 -04:00
}
2011-06-01 13:00:29 -04:00
2009-08-24 18:28:00 -04:00
/* Track zoom buttons */
2016-12-18 14:29:19 -05:00
_track_box . set_spacing ( 2 ) ;
_track_box . set_border_width ( 2 ) ;
2014-03-25 08:21:08 -04:00
visible_tracks_selector . set_name ( " zoom button " ) ;
2014-07-11 15:50:51 -04:00
if ( Profile - > get_mixbus ( ) ) {
2016-12-20 12:48:02 -05:00
visible_tracks_selector . set_icon ( ArdourIcon : : TimeAxisExpand ) ;
2014-07-11 15:50:51 -04:00
} else {
2014-07-29 23:44:57 -04:00
set_size_request_to_display_given_text ( visible_tracks_selector , _ ( " All " ) , 30 , 2 ) ;
2014-07-11 15:50:51 -04:00
}
2014-03-25 08:21:08 -04:00
2014-03-25 10:43:04 -04:00
tav_expand_button . set_name ( " zoom button " ) ;
2015-05-24 18:26:09 -04:00
tav_expand_button . set_icon ( ArdourIcon : : TimeAxisExpand ) ;
2014-03-25 10:43:04 -04:00
act = ActionManager : : get_action ( X_ ( " Editor " ) , X_ ( " expand-tracks " ) ) ;
tav_expand_button . set_related_action ( act ) ;
tav_shrink_button . set_name ( " zoom button " ) ;
2015-05-24 18:26:09 -04:00
tav_shrink_button . set_icon ( ArdourIcon : : TimeAxisShrink ) ;
2014-03-25 10:43:04 -04:00
act = ActionManager : : get_action ( X_ ( " Editor " ) , X_ ( " shrink-tracks " ) ) ;
tav_shrink_button . set_related_action ( act ) ;
2014-07-11 15:50:51 -04:00
if ( ARDOUR : : Profile - > get_mixbus ( ) ) {
2016-12-18 14:29:19 -05:00
_track_box . pack_start ( visible_tracks_selector ) ;
2014-07-11 15:50:51 -04:00
} else {
2016-12-18 14:29:19 -05:00
_track_box . pack_start ( visible_tracks_selector ) ;
_track_box . pack_start ( tav_shrink_button ) ;
_track_box . pack_start ( tav_expand_button ) ;
2014-04-10 13:30:25 -04:00
}
2014-03-25 10:43:04 -04:00
2012-12-06 15:48:44 -05:00
snap_box . set_spacing ( 2 ) ;
2006-06-30 04:03:43 -04:00
snap_box . set_border_width ( 2 ) ;
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
grid_type_selector . set_name ( " mouse mode button " ) ;
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
snap_mode_button . set_name ( " mouse mode button " ) ;
2007-11-07 20:40:25 -05:00
2014-03-23 19:11:42 -04:00
edit_point_selector . set_name ( " mouse mode button " ) ;
2005-09-25 14:42:24 -04:00
2018-02-09 10:59:39 -05:00
snap_box . pack_start ( snap_mode_button , false , false ) ;
snap_box . pack_start ( grid_type_selector , false , false ) ;
2016-12-18 14:29:19 -05:00
2006-06-30 13:15:45 -04:00
/* Nudge */
2005-09-25 14:42:24 -04:00
2006-06-30 13:15:45 -04:00
HBox * nudge_box = manage ( new HBox ) ;
2011-11-11 12:35:22 -05:00
nudge_box - > set_spacing ( 2 ) ;
2006-06-30 13:15:45 -04:00
nudge_box - > set_border_width ( 2 ) ;
2005-09-25 14:42:24 -04:00
2009-12-11 18:29:48 -05:00
nudge_forward_button . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : nudge_forward_release ) , false ) ;
nudge_backward_button . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : nudge_backward_release ) , false ) ;
2005-09-25 14:42:24 -04:00
2006-06-30 13:15:45 -04:00
nudge_box - > pack_start ( nudge_backward_button , false , false ) ;
nudge_box - > pack_start ( nudge_forward_button , false , false ) ;
2011-06-02 13:50:37 -04:00
nudge_box - > pack_start ( * nudge_clock , false , false ) ;
2006-01-07 21:56:49 -05:00
2005-09-25 14:42:24 -04:00
2006-06-30 13:15:45 -04:00
/* Pack everything in... */
2005-09-25 14:42:24 -04:00
2014-07-09 15:32:13 -04:00
toolbar_hbox . set_spacing ( 2 ) ;
2016-12-18 10:02:13 -05:00
toolbar_hbox . set_border_width ( 2 ) ;
2005-09-25 14:42:24 -04:00
2018-02-19 09:05:55 -05:00
ArdourWidgets : : ArdourDropShadow * tool_shadow = manage ( new ( ArdourWidgets : : ArdourDropShadow ) ) ;
2018-02-24 07:54:15 -05:00
tool_shadow - > set_size_request ( 4 , - 1 ) ;
2018-02-19 09:05:55 -05:00
tool_shadow - > show ( ) ;
ebox_hpacker . pack_start ( * tool_shadow , false , false ) ;
ebox_hpacker . pack_start ( ebox_vpacker , true , true ) ;
2018-02-24 07:54:15 -05:00
Gtk : : EventBox * spacer = manage ( new Gtk : : EventBox ) ; // extra space under the mouse toolbar, for aesthetics
2018-02-19 09:05:55 -05:00
spacer - > set_name ( " EditorWindow " ) ;
spacer - > set_size_request ( - 1 , 4 ) ;
spacer - > show ( ) ;
ebox_vpacker . pack_start ( toolbar_hbox , false , false ) ;
ebox_vpacker . pack_start ( * spacer , false , false ) ;
ebox_vpacker . show ( ) ;
2015-07-27 18:05:42 -04:00
toolbar_hbox . pack_start ( * mode_box , false , false ) ;
2019-09-25 15:02:31 -04:00
toolbar_hbox . pack_start ( * ( manage ( new ArdourVSpacer ( ) ) ) , false , false , 3 ) ;
toolbar_hbox . pack_start ( snap_box , false , false ) ;
toolbar_hbox . pack_start ( * ( manage ( new ArdourVSpacer ( ) ) ) , false , false , 3 ) ;
toolbar_hbox . pack_start ( * nudge_box , false , false ) ;
toolbar_hbox . pack_end ( _zoom_box , false , false , 2 ) ;
toolbar_hbox . pack_end ( * ( manage ( new ArdourVSpacer ( ) ) ) , false , false , 3 ) ;
toolbar_hbox . pack_end ( _track_box , false , false ) ;
2006-06-30 04:03:43 -04:00
2016-12-18 14:29:19 -05:00
toolbar_hbox . show_all ( ) ;
2005-09-25 14:42:24 -04:00
}
2014-03-23 19:11:42 -04:00
void
Editor : : build_edit_point_menu ( )
{
using namespace Menu_Helpers ;
2018-02-24 07:54:15 -05:00
edit_point_selector . AddMenuElem ( MenuElem ( edit_point_strings [ ( int ) EditAtPlayhead ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_point_selection_done ) , ( EditPoint ) EditAtPlayhead ) ) ) ;
2014-07-09 17:33:48 -04:00
if ( ! Profile - > get_mixbus ( ) )
2018-02-24 07:54:15 -05:00
edit_point_selector . AddMenuElem ( MenuElem ( edit_point_strings [ ( int ) EditAtSelectedMarker ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_point_selection_done ) , ( EditPoint ) EditAtSelectedMarker ) ) ) ;
edit_point_selector . AddMenuElem ( MenuElem ( edit_point_strings [ ( int ) EditAtMouse ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_point_selection_done ) , ( EditPoint ) EditAtMouse ) ) ) ;
2014-07-09 16:48:19 -04:00
2014-08-30 12:26:03 -04:00
set_size_request_to_display_given_text ( edit_point_selector , edit_point_strings , COMBO_TRIANGLE_WIDTH , 2 ) ;
2014-03-23 19:11:42 -04:00
}
void
Editor : : build_edit_mode_menu ( )
{
using namespace Menu_Helpers ;
2015-10-05 10:17:49 -04:00
2018-02-24 07:54:15 -05:00
edit_mode_selector . AddMenuElem ( MenuElem ( edit_mode_strings [ ( int ) Slide ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_mode_selection_done ) , ( EditMode ) Slide ) ) ) ;
edit_mode_selector . AddMenuElem ( MenuElem ( edit_mode_strings [ ( int ) Ripple ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_mode_selection_done ) , ( EditMode ) Ripple ) ) ) ;
edit_mode_selector . AddMenuElem ( MenuElem ( edit_mode_strings [ ( int ) Lock ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_mode_selection_done ) , ( EditMode ) Lock ) ) ) ;
/* Note: Splice was removed */
2014-03-23 19:11:42 -04:00
2014-08-30 12:26:03 -04:00
set_size_request_to_display_given_text ( edit_mode_selector , edit_mode_strings , COMBO_TRIANGLE_WIDTH , 2 ) ;
2014-03-23 19:11:42 -04:00
}
void
2018-02-09 10:59:39 -05:00
Editor : : build_grid_type_menu ( )
2014-03-23 19:11:42 -04:00
{
using namespace Menu_Helpers ;
2018-02-24 07:54:15 -05:00
/* main grid: bars, quarter-notes, etc */
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeNone ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeNone ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBar ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBar ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeat ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeat ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv2 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv2 ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv4 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv4 ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv8 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv8 ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv16 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv16 ) ) ) ;
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv32 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv32 ) ) ) ;
/* triplet grid */
2018-02-09 10:59:39 -05:00
grid_type_selector . AddMenuElem ( SeparatorElem ( ) ) ;
Gtk : : Menu * _triplet_menu = manage ( new Menu ) ;
MenuList & triplet_items ( _triplet_menu - > items ( ) ) ;
{
2018-02-24 07:54:15 -05:00
triplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv3 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv3 ) ) ) ;
triplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv6 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv6 ) ) ) ;
triplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv12 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv12 ) ) ) ;
triplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv24 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv24 ) ) ) ;
2018-02-09 10:59:39 -05:00
}
grid_type_selector . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Triplets " ) , * _triplet_menu ) ) ;
2014-07-09 16:48:19 -04:00
2018-02-24 07:54:15 -05:00
/* quintuplet grid */
2018-02-09 10:59:39 -05:00
Gtk : : Menu * _quintuplet_menu = manage ( new Menu ) ;
MenuList & quintuplet_items ( _quintuplet_menu - > items ( ) ) ;
{
2018-02-24 07:54:15 -05:00
quintuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv5 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv5 ) ) ) ;
quintuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv10 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv10 ) ) ) ;
quintuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv20 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv20 ) ) ) ;
2018-02-09 10:59:39 -05:00
}
grid_type_selector . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Quintuplets " ) , * _quintuplet_menu ) ) ;
2014-03-23 19:11:42 -04:00
2018-02-24 07:54:15 -05:00
/* septuplet grid */
2018-02-09 10:59:39 -05:00
Gtk : : Menu * _septuplet_menu = manage ( new Menu ) ;
MenuList & septuplet_items ( _septuplet_menu - > items ( ) ) ;
{
2018-02-24 07:54:15 -05:00
septuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv7 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv7 ) ) ) ;
septuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv14 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv14 ) ) ) ;
septuplet_items . push_back ( MenuElem ( grid_type_strings [ ( int ) GridTypeBeatDiv28 ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeBeatDiv28 ) ) ) ;
2018-02-09 10:59:39 -05:00
}
grid_type_selector . AddMenuElem ( Menu_Helpers : : MenuElem ( _ ( " Septuplets " ) , * _septuplet_menu ) ) ;
2014-03-23 19:11:42 -04:00
2018-02-09 10:59:39 -05:00
grid_type_selector . AddMenuElem ( SeparatorElem ( ) ) ;
2018-02-26 19:38:18 -05:00
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeTimecode ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeTimecode ) ) ) ;
2018-02-24 07:54:15 -05:00
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeMinSec ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeMinSec ) ) ) ;
2018-02-26 18:02:24 -05:00
grid_type_selector . AddMenuElem ( MenuElem ( grid_type_strings [ ( int ) GridTypeCDFrame ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : grid_type_selection_done ) , ( GridType ) GridTypeCDFrame ) ) ) ;
2014-03-23 19:11:42 -04:00
}
2010-02-08 19:50:24 -05:00
void
Editor : : setup_tooltips ( )
{
2015-11-29 14:17:11 -05:00
set_tooltip ( smart_mode_button , _ ( " Smart Mode (add range functions to Grab Mode) " ) ) ;
2015-01-05 00:32:14 -05:00
set_tooltip ( mouse_move_button , _ ( " Grab Mode (select/move objects) " ) ) ;
set_tooltip ( mouse_cut_button , _ ( " Cut Mode (split regions) " ) ) ;
set_tooltip ( mouse_select_button , _ ( " Range Mode (select time ranges) " ) ) ;
set_tooltip ( mouse_draw_button , _ ( " Draw Mode (draw and edit gain/notes/automation) " ) ) ;
set_tooltip ( mouse_timefx_button , _ ( " Stretch Mode (time-stretch audio and midi regions, preserving pitch) " ) ) ;
set_tooltip ( mouse_audition_button , _ ( " Audition Mode (listen to regions) " ) ) ;
set_tooltip ( mouse_content_button , _ ( " Internal Edit Mode (edit notes and automation points) " ) ) ;
set_tooltip ( * _group_tabs , _ ( " Groups: click to (de)activate \n Context-click for other operations " ) ) ;
set_tooltip ( nudge_forward_button , _ ( " Nudge Region/Selection Later " ) ) ;
set_tooltip ( nudge_backward_button , _ ( " Nudge Region/Selection Earlier " ) ) ;
set_tooltip ( zoom_in_button , _ ( " Zoom In " ) ) ;
set_tooltip ( zoom_out_button , _ ( " Zoom Out " ) ) ;
set_tooltip ( zoom_preset_selector , _ ( " Zoom to Time Scale " ) ) ;
set_tooltip ( zoom_out_full_button , _ ( " Zoom to Session " ) ) ;
2015-11-29 14:17:11 -05:00
set_tooltip ( zoom_focus_selector , _ ( " Zoom Focus " ) ) ;
2015-01-05 00:32:14 -05:00
set_tooltip ( tav_expand_button , _ ( " Expand Tracks " ) ) ;
set_tooltip ( tav_shrink_button , _ ( " Shrink Tracks " ) ) ;
set_tooltip ( visible_tracks_selector , _ ( " Number of visible tracks " ) ) ;
2018-02-09 10:59:39 -05:00
set_tooltip ( grid_type_selector , _ ( " Grid Mode " ) ) ;
set_tooltip ( snap_mode_button , _ ( " Snap Mode \n \n Right-click to visit Snap preferences. " ) ) ;
2015-11-29 14:17:11 -05:00
set_tooltip ( edit_point_selector , _ ( " Edit Point " ) ) ;
2015-01-05 00:32:14 -05:00
set_tooltip ( edit_mode_selector , _ ( " Edit Mode " ) ) ;
set_tooltip ( nudge_clock , _ ( " Nudge Clock \n (controls distance used to nudge regions and selections) " ) ) ;
2010-02-08 19:50:24 -05:00
}
2005-09-25 14:42:24 -04:00
int
2009-05-04 21:24:44 -04:00
Editor : : convert_drop_to_paths (
2010-09-14 11:45:21 -04:00
vector < string > & paths ,
2009-07-21 11:55:17 -04:00
const RefPtr < Gdk : : DragContext > & /*context*/ ,
gint /*x*/ ,
gint /*y*/ ,
2009-05-04 21:24:44 -04:00
const SelectionData & data ,
2009-07-21 11:55:17 -04:00
guint /*info*/ ,
guint /*time*/ )
2009-10-14 12:10:01 -04:00
{
2009-12-17 13:24:23 -05:00
if ( _session = = 0 ) {
2005-09-25 14:42:24 -04:00
return - 1 ;
}
2011-06-01 13:00:29 -04:00
2010-09-14 12:51:02 -04:00
vector < string > uris = data . get_uris ( ) ;
2005-09-25 14:42:24 -04:00
2005-12-29 19:34:21 -05:00
if ( uris . empty ( ) ) {
2007-10-11 18:07:47 -04:00
2005-12-29 19:34:21 -05:00
/* This is seriously fucked up. Nautilus doesn't say that its URI lists
are actually URI lists . So do it by hand .
*/
2005-09-25 14:42:24 -04:00
2005-12-29 19:34:21 -05:00
if ( data . get_target ( ) ! = " text/plain " ) {
return - 1 ;
}
2009-10-14 12:10:01 -04:00
/* Parse the "uri-list" format that Nautilus provides,
2008-12-12 09:43:24 -05:00
where each pathname is delimited by \ r \ n .
THERE MAY BE NO NULL TERMINATING CHAR ! ! !
2005-12-29 19:34:21 -05:00
*/
2008-12-12 09:43:24 -05:00
2010-09-14 12:51:02 -04:00
string txt = data . get_text ( ) ;
2013-06-23 07:37:50 -04:00
char * p ;
2005-12-29 19:34:21 -05:00
const char * q ;
2005-09-25 14:42:24 -04:00
2013-06-23 07:37:50 -04:00
p = ( char * ) malloc ( txt . length ( ) + 1 ) ;
txt . copy ( p , txt . length ( ) , 0 ) ;
p [ txt . length ( ) ] = ' \0 ' ;
2008-12-12 09:43:24 -05:00
2005-12-29 19:34:21 -05:00
while ( p )
{
if ( * p ! = ' # ' )
{
while ( g_ascii_isspace ( * p ) )
p + + ;
2009-10-14 12:10:01 -04:00
2005-12-29 19:34:21 -05:00
q = p ;
2008-12-12 09:43:24 -05:00
while ( * q & & ( * q ! = ' \n ' ) & & ( * q ! = ' \r ' ) ) {
2005-12-29 19:34:21 -05:00
q + + ;
2008-12-12 09:43:24 -05:00
}
2009-10-14 12:10:01 -04:00
2005-12-29 19:34:21 -05:00
if ( q > p )
{
q - - ;
while ( q > p & & g_ascii_isspace ( * q ) )
q - - ;
2009-10-14 12:10:01 -04:00
2005-12-29 19:34:21 -05:00
if ( q > p )
{
2010-09-14 12:51:02 -04:00
uris . push_back ( string ( p , q - p + 1 ) ) ;
2005-12-29 19:34:21 -05:00
}
}
2005-09-25 14:42:24 -04:00
}
2005-12-29 19:34:21 -05:00
p = strchr ( p , ' \n ' ) ;
if ( p )
p + + ;
2005-09-25 14:42:24 -04:00
}
2008-12-12 09:43:24 -05:00
free ( ( void * ) p ) ;
2009-10-14 12:10:01 -04:00
2005-12-29 19:34:21 -05:00
if ( uris . empty ( ) ) {
return - 1 ;
2005-09-25 14:42:24 -04:00
}
}
2009-10-14 12:10:01 -04:00
2010-09-14 12:51:02 -04:00
for ( vector < string > : : iterator i = uris . begin ( ) ; i ! = uris . end ( ) ; + + i ) {
2005-12-29 19:34:21 -05:00
if ( ( * i ) . substr ( 0 , 7 ) = = " file:// " ) {
2014-01-17 09:24:18 -05:00
paths . push_back ( Glib : : filename_from_uri ( * i ) ) ;
2005-09-25 14:42:24 -04:00
}
}
2005-12-29 19:34:21 -05:00
return 0 ;
2005-09-25 14:42:24 -04:00
}
void
Editor : : new_tempo_section ( )
{
}
void
Editor : : map_transport_state ( )
{
2012-10-10 11:19:58 -04:00
ENSURE_GUI_THREAD ( * this , & Editor : : map_transport_state ) ;
2005-09-25 14:42:24 -04:00
2010-03-30 20:59:09 -04:00
if ( _session & & _session - > transport_stopped ( ) ) {
2005-09-25 14:42:24 -04:00
have_pending_keyboard_selection = false ;
}
2007-03-19 03:07:38 -04:00
2014-01-27 21:27:13 -05:00
update_loop_range_view ( ) ;
2005-09-25 14:42:24 -04:00
}
2017-03-31 08:11:49 -04:00
void
Editor : : transport_looped ( )
{
/* reset Playhead position interpolation.
* see Editor : : super_rapid_screen_update
*/
_last_update_time = 0 ;
}
2005-09-25 14:42:24 -04:00
/* UNDO/REDO */
2014-12-22 08:30:23 -05:00
void
Editor : : begin_selection_op_history ( )
{
selection_op_cmd_depth = 0 ;
selection_op_history_it = 0 ;
2015-02-07 07:33:09 -05:00
while ( ! selection_op_history . empty ( ) ) {
delete selection_op_history . front ( ) ;
selection_op_history . pop_front ( ) ;
}
2014-12-22 08:30:23 -05:00
selection_undo_action - > set_sensitive ( false ) ;
selection_redo_action - > set_sensitive ( false ) ;
selection_op_history . push_front ( & _selection_memento - > get_state ( ) ) ;
}
void
Editor : : begin_reversible_selection_op ( string name )
{
if ( _session ) {
2015-01-10 20:55:48 -05:00
//cerr << name << endl;
2014-12-22 08:30:23 -05:00
/* begin/commit pairs can be nested */
selection_op_cmd_depth + + ;
}
}
void
Editor : : commit_reversible_selection_op ( )
{
if ( _session ) {
if ( selection_op_cmd_depth = = 1 ) {
if ( selection_op_history_it > 0 & & selection_op_history_it < selection_op_history . size ( ) ) {
2018-02-24 07:54:15 -05:00
/* The user has undone some selection ops and then made a new one,
* making anything earlier in the list invalid .
*/
2015-10-05 10:17:49 -04:00
2014-12-22 08:30:23 -05:00
list < XMLNode * > : : iterator it = selection_op_history . begin ( ) ;
2015-02-07 07:33:09 -05:00
list < XMLNode * > : : iterator e_it = it ;
advance ( e_it , selection_op_history_it ) ;
2015-10-05 10:17:49 -04:00
2018-02-24 07:54:15 -05:00
for ( ; it ! = e_it ; + + it ) {
2015-02-07 07:33:09 -05:00
delete * it ;
}
selection_op_history . erase ( selection_op_history . begin ( ) , e_it ) ;
2014-12-22 08:30:23 -05:00
}
2015-01-10 12:07:31 -05:00
2014-12-22 08:30:23 -05:00
selection_op_history . push_front ( & _selection_memento - > get_state ( ) ) ;
selection_op_history_it = 0 ;
2015-01-10 12:07:31 -05:00
selection_undo_action - > set_sensitive ( true ) ;
selection_redo_action - > set_sensitive ( false ) ;
2014-12-22 08:30:23 -05:00
}
if ( selection_op_cmd_depth > 0 ) {
selection_op_cmd_depth - - ;
}
}
}
void
2014-12-23 12:29:43 -05:00
Editor : : undo_selection_op ( )
2014-12-22 08:30:23 -05:00
{
if ( _session ) {
selection_op_history_it + + ;
uint32_t n = 0 ;
for ( std : : list < XMLNode * > : : iterator i = selection_op_history . begin ( ) ; i ! = selection_op_history . end ( ) ; + + i ) {
if ( n = = selection_op_history_it ) {
_selection_memento - > set_state ( * ( * i ) , Stateful : : current_state_version ) ;
selection_redo_action - > set_sensitive ( true ) ;
}
+ + n ;
}
/* is there an earlier entry? */
if ( ( selection_op_history_it + 1 ) > = selection_op_history . size ( ) ) {
selection_undo_action - > set_sensitive ( false ) ;
}
}
}
void
2014-12-23 12:29:43 -05:00
Editor : : redo_selection_op ( )
2014-12-22 08:30:23 -05:00
{
if ( _session ) {
if ( selection_op_history_it > 0 ) {
selection_op_history_it - - ;
}
uint32_t n = 0 ;
for ( std : : list < XMLNode * > : : iterator i = selection_op_history . begin ( ) ; i ! = selection_op_history . end ( ) ; + + i ) {
if ( n = = selection_op_history_it ) {
_selection_memento - > set_state ( * ( * i ) , Stateful : : current_state_version ) ;
selection_undo_action - > set_sensitive ( true ) ;
}
+ + n ;
}
if ( selection_op_history_it = = 0 ) {
selection_redo_action - > set_sensitive ( false ) ;
}
}
}
2005-09-25 14:42:24 -04:00
void
Editor : : begin_reversible_command ( string name )
{
2009-12-17 13:24:23 -05:00
if ( _session ) {
2014-12-14 08:13:38 -05:00
before . push_back ( & _selection_memento - > get_state ( ) ) ;
2009-12-17 13:24:23 -05:00
_session - > begin_reversible_command ( name ) ;
2005-09-25 14:42:24 -04:00
}
}
2011-01-19 12:38:56 -05:00
void
Editor : : begin_reversible_command ( GQuark q )
{
if ( _session ) {
2014-12-14 08:13:38 -05:00
before . push_back ( & _selection_memento - > get_state ( ) ) ;
2011-01-19 12:38:56 -05:00
_session - > begin_reversible_command ( q ) ;
}
}
2015-02-05 07:32:57 -05:00
void
Editor : : abort_reversible_command ( )
{
if ( _session ) {
2015-02-07 07:33:09 -05:00
while ( ! before . empty ( ) ) {
delete before . front ( ) ;
before . pop_front ( ) ;
}
2015-02-05 07:32:57 -05:00
_session - > abort_reversible_command ( ) ;
}
}
2005-09-25 14:42:24 -04:00
void
Editor : : commit_reversible_command ( )
{
2009-12-17 13:24:23 -05:00
if ( _session ) {
2014-12-14 08:13:38 -05:00
if ( before . size ( ) = = 1 ) {
_session - > add_command ( new MementoCommand < SelectionMemento > ( * ( _selection_memento ) , before . front ( ) , & _selection_memento - > get_state ( ) ) ) ;
2015-02-05 03:57:56 -05:00
redo_action - > set_sensitive ( false ) ;
2014-12-22 13:09:21 -05:00
undo_action - > set_sensitive ( true ) ;
2014-12-22 08:30:23 -05:00
begin_selection_op_history ( ) ;
2014-12-14 08:13:38 -05:00
}
2014-12-22 08:30:23 -05:00
if ( before . empty ( ) ) {
cerr < < " Please call begin_reversible_command() before commit_reversible_command(). " < < endl ;
} else {
2014-12-14 08:13:38 -05:00
before . pop_back ( ) ;
}
2010-02-18 09:44:08 -05:00
_session - > commit_reversible_command ( ) ;
2005-09-25 14:42:24 -04:00
}
}
void
2006-11-19 11:45:16 -05:00
Editor : : history_changed ( )
2005-09-25 14:42:24 -04:00
{
string label ;
2009-12-17 13:24:23 -05:00
if ( undo_action & & _session ) {
if ( _session - > undo_depth ( ) = = 0 ) {
2011-11-28 14:46:30 -05:00
label = S_ ( " Command|Undo " ) ;
2006-11-19 11:45:16 -05:00
} else {
2011-11-28 14:46:30 -05:00
label = string_compose ( S_ ( " Command|Undo (%1) " ) , _session - > next_undo ( ) ) ;
2005-09-25 14:42:24 -04:00
}
2006-11-19 11:45:16 -05:00
undo_action - > property_label ( ) = label ;
2005-09-25 14:42:24 -04:00
}
2009-12-17 13:24:23 -05:00
if ( redo_action & & _session ) {
if ( _session - > redo_depth ( ) = = 0 ) {
2006-11-19 11:45:16 -05:00
label = _ ( " Redo " ) ;
2015-09-26 10:59:44 -04:00
redo_action - > set_sensitive ( false ) ;
2006-11-19 11:45:16 -05:00
} else {
2009-12-17 13:24:23 -05:00
label = string_compose ( _ ( " Redo (%1) " ) , _session - > next_redo ( ) ) ;
2015-09-26 10:59:44 -04:00
redo_action - > set_sensitive ( true ) ;
2006-11-19 11:45:16 -05:00
}
redo_action - > property_label ( ) = label ;
2005-09-25 14:42:24 -04:00
}
}
void
2012-07-04 17:31:06 -04:00
Editor : : duplicate_range ( bool with_dialog )
2005-09-25 14:42:24 -04:00
{
2008-01-10 16:20:59 -05:00
float times = 1.0f ;
2005-09-25 14:42:24 -04:00
2010-11-03 18:19:29 -04:00
RegionSelection rs = get_regions_from_selection_and_entered ( ) ;
2007-04-12 19:20:37 -04:00
2018-02-24 07:54:15 -05:00
if ( selection - > time . length ( ) = = 0 & & rs . empty ( ) ) {
2010-11-03 18:19:29 -04:00
return ;
2008-01-10 16:20:59 -05:00
}
2005-09-25 14:42:24 -04:00
2008-01-10 16:20:59 -05:00
if ( with_dialog ) {
2005-09-25 14:42:24 -04:00
2010-04-17 20:25:03 -04:00
ArdourDialog win ( _ ( " Duplicate " ) ) ;
2010-04-29 21:21:43 -04:00
Label label ( _ ( " Number of duplications: " ) ) ;
2008-01-10 16:20:59 -05:00
Adjustment adjustment ( 1.0 , 1.0 , 1000000.0 , 1.0 , 5.0 ) ;
2008-02-01 22:57:35 -05:00
SpinButton spinner ( adjustment , 0.0 , 1 ) ;
HBox hbox ;
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
win . get_vbox ( ) - > set_spacing ( 12 ) ;
2008-02-01 22:57:35 -05:00
win . get_vbox ( ) - > pack_start ( hbox ) ;
hbox . set_border_width ( 6 ) ;
hbox . pack_start ( label , PACK_EXPAND_PADDING , 12 ) ;
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
/* dialogs have ::add_action_widget() but that puts the spinner in the wrong
place , visually . so do this by hand .
*/
2009-10-14 12:10:01 -04:00
2008-02-01 22:57:35 -05:00
hbox . pack_start ( spinner , PACK_EXPAND_PADDING , 12 ) ;
2009-12-11 18:29:48 -05:00
spinner . signal_activate ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( win , & ArdourDialog : : response ) , RESPONSE_ACCEPT ) ) ;
2008-02-01 22:57:35 -05:00
spinner . grab_focus ( ) ;
hbox . show ( ) ;
2008-01-10 16:20:59 -05:00
label . show ( ) ;
spinner . show ( ) ;
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
win . add_button ( Stock : : CANCEL , RESPONSE_CANCEL ) ;
2008-02-01 22:57:35 -05:00
win . add_button ( _ ( " Duplicate " ) , RESPONSE_ACCEPT ) ;
win . set_default_response ( RESPONSE_ACCEPT ) ;
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
spinner . grab_focus ( ) ;
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
switch ( win . run ( ) ) {
case RESPONSE_ACCEPT :
break ;
default :
return ;
}
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
times = adjustment . get_value ( ) ;
2005-09-25 14:42:24 -04:00
}
2018-02-09 10:59:39 -05:00
if ( ( current_mouse_mode ( ) = = MouseRange ) ) {
2012-12-06 10:59:01 -05:00
if ( selection - > time . length ( ) ) {
duplicate_selection ( times ) ;
}
} else if ( get_smart_mode ( ) ) {
if ( selection - > time . length ( ) ) {
duplicate_selection ( times ) ;
2015-10-04 14:51:05 -04:00
} else
2012-12-06 10:59:01 -05:00
duplicate_some_regions ( rs , times ) ;
2008-01-10 16:20:59 -05:00
} else {
2008-02-16 17:43:18 -05:00
duplicate_some_regions ( rs , times ) ;
2005-09-25 14:42:24 -04:00
}
}
2008-01-10 16:20:59 -05:00
void
Editor : : set_edit_mode ( EditMode m )
{
Config - > set_edit_mode ( m ) ;
}
void
Editor : : cycle_edit_mode ( )
{
switch ( Config - > get_edit_mode ( ) ) {
case Slide :
2015-10-26 15:17:42 -04:00
Config - > set_edit_mode ( Ripple ) ;
2008-01-10 16:20:59 -05:00
break ;
2014-07-02 15:53:24 -04:00
case Splice :
Ripple mode: basic implementation
Add a value for Ripple to EditMode enum.
Add Ripple edit mode to edit mode dropdown, by adding it to the
Editor::build_edit_mode_menu() helper function, and remove the old code that
added items to the (now unused) Editor::edit_mode_strings.
Add the regions that should be affected by the drag to RegionDrag::_views so
that the drag carries them along automatically.
Use a copy of the RegionList in Playlist::core_ripple(), since bad things
happen when iterating over regions and they get moved around in the list.
Handle rippling in removal of regions from playlist.
When dragging in ripple mode, exclude all regions that lie before the
original start position of the selected regions being dragged from
rippling: this is what Mixbus does.
Make editor dragging respect snap-to settings, by using the existing
compute_x_delta() function, which did almost the right thing. Move setting
of _last_frame_position out of that function so all ripple-dragged regions
can move.
Ripple when dragging from region list: even though Mixbus doesn't do this, it
seems like a good idea.
Prevent multi-track selection being dragged across tracks, by making
RegionMotionDrag::y_movement_allowed() virtual, and overriding it in
RegionRippleDrag to forbid dragging of selections containing regions on more
than one track to dofferent tracks in ripple mode.
Remember which TimeAxisView a ripple-mode drag that's allowed cross-track
drags started from, so that the effect of rippling regions after any region
that's dragged off that track can be undone.
2013-10-23 16:50:01 -04:00
case Ripple :
2015-05-18 13:27:50 -04:00
Config - > set_edit_mode ( Lock ) ;
2008-02-16 17:43:18 -05:00
break ;
2015-05-18 13:27:50 -04:00
case Lock :
2008-01-10 16:20:59 -05:00
Config - > set_edit_mode ( Slide ) ;
break ;
}
}
2005-11-15 21:57:22 -05:00
void
2018-02-24 07:54:15 -05:00
Editor : : edit_mode_selection_done ( EditMode m )
2005-09-25 14:42:24 -04:00
{
2018-02-24 07:54:15 -05:00
Config - > set_edit_mode ( m ) ;
2009-10-14 12:10:01 -04:00
}
2005-09-25 14:42:24 -04:00
2005-11-15 21:57:22 -05:00
void
2018-02-09 10:59:39 -05:00
Editor : : grid_type_selection_done ( GridType gridtype )
2014-03-23 19:11:42 -04:00
{
2018-02-09 10:59:39 -05:00
RefPtr < RadioAction > ract = grid_type_action ( gridtype ) ;
2006-11-19 11:45:16 -05:00
if ( ract ) {
ract - > set_active ( ) ;
}
2009-10-14 12:10:01 -04:00
}
2005-09-25 14:42:24 -04:00
2005-11-15 21:57:22 -05:00
void
2014-03-23 19:11:42 -04:00
Editor : : snap_mode_selection_done ( SnapMode mode )
2005-09-25 14:42:24 -04:00
{
2006-11-19 11:45:16 -05:00
RefPtr < RadioAction > ract = snap_mode_action ( mode ) ;
if ( ract ) {
ract - > set_active ( true ) ;
}
2005-09-25 14:42:24 -04:00
}
2008-01-10 16:20:59 -05:00
void
Editor : : cycle_edit_point ( bool with_marker )
{
2014-07-09 17:33:48 -04:00
if ( Profile - > get_mixbus ( ) )
with_marker = false ;
2008-01-10 16:20:59 -05:00
switch ( _edit_point ) {
case EditAtMouse :
set_edit_point_preference ( EditAtPlayhead ) ;
break ;
case EditAtPlayhead :
if ( with_marker ) {
set_edit_point_preference ( EditAtSelectedMarker ) ;
} else {
set_edit_point_preference ( EditAtMouse ) ;
}
break ;
case EditAtSelectedMarker :
set_edit_point_preference ( EditAtMouse ) ;
break ;
}
}
2007-11-07 20:40:25 -05:00
void
2014-03-23 19:11:42 -04:00
Editor : : edit_point_selection_done ( EditPoint ep )
2007-11-07 20:40:25 -05:00
{
2018-02-24 07:54:15 -05:00
set_edit_point_preference ( ep ) ;
2007-11-07 20:40:25 -05:00
}
2005-11-15 21:57:22 -05:00
void
2014-03-23 19:11:42 -04:00
Editor : : build_zoom_focus_menu ( )
2005-09-25 14:42:24 -04:00
{
2014-03-23 19:11:42 -04:00
using namespace Menu_Helpers ;
2009-10-14 12:10:01 -04:00
2018-02-24 07:54:15 -05:00
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusLeft ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusLeft ) ) ) ;
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusRight ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusRight ) ) ) ;
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusCenter ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusCenter ) ) ) ;
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusPlayhead ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusPlayhead ) ) ) ;
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusMouse ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusMouse ) ) ) ;
zoom_focus_selector . AddMenuElem ( MenuElem ( zoom_focus_strings [ ( int ) ZoomFocusEdit ] , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : zoom_focus_selection_done ) , ( ZoomFocus ) ZoomFocusEdit ) ) ) ;
2014-07-09 16:48:19 -04:00
2014-08-30 12:26:03 -04:00
set_size_request_to_display_given_text ( zoom_focus_selector , zoom_focus_strings , COMBO_TRIANGLE_WIDTH , 2 ) ;
2014-03-23 19:11:42 -04:00
}
2005-09-25 14:42:24 -04:00
2014-03-23 19:11:42 -04:00
void
2018-02-24 07:54:15 -05:00
Editor : : zoom_focus_selection_done ( ZoomFocus f )
2014-03-23 19:11:42 -04:00
{
RefPtr < RadioAction > ract = zoom_focus_action ( f ) ;
2006-11-19 11:45:16 -05:00
if ( ract ) {
ract - > set_active ( ) ;
}
2009-10-14 12:10:01 -04:00
}
2005-09-25 14:42:24 -04:00
2014-03-25 08:21:08 -04:00
void
Editor : : build_track_count_menu ( )
{
using namespace Menu_Helpers ;
2014-07-11 15:50:51 -04:00
if ( ! Profile - > get_mixbus ( ) ) {
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 1 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 1 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 2 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 2 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 3 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 3 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 4 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 4 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 8 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 8 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 12 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 12 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 16 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 16 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 20 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 20 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 24 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 24 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 32 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 32 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( X_ ( " 64 " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 64 ) ) ) ;
2015-01-11 12:46:36 -05:00
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Selection " ) , sigc : : mem_fun ( * this , & Editor : : fit_selection ) ) ) ;
2014-07-11 15:50:51 -04:00
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " All " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 0 ) ) ) ;
} else {
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 1 track " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 1 ) ) ) ;
2014-07-23 12:28:45 -04:00
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 2 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 2 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 4 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 4 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 8 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 8 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 16 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 16 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 24 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 24 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 32 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 32 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit 48 tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 48 ) ) ) ;
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit All tracks " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_visible_track_count ) , 0 ) ) ) ;
2015-01-11 12:46:36 -05:00
visible_tracks_selector . AddMenuElem ( MenuElem ( _ ( " Fit Selection " ) , sigc : : mem_fun ( * this , & Editor : : fit_selection ) ) ) ;
2014-07-11 15:50:51 -04:00
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 10 ms " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 10 ) ) ) ;
2014-07-23 12:28:45 -04:00
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 100 ms " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 100 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 1 sec " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 1 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 10 sec " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 10 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 1 min " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 60 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 10 min " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 10 * 60 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 1 hour " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 60 * 60 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 8 hours " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 8 * 60 * 60 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to 24 hours " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : set_zoom_preset ) , 24 * 60 * 60 * 1000 ) ) ) ;
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to Session " ) , sigc : : mem_fun ( * this , & Editor : : temporal_zoom_session ) ) ) ;
2017-08-27 00:06:29 -04:00
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to Extents " ) , sigc : : mem_fun ( * this , & Editor : : temporal_zoom_extents ) ) ) ;
2016-12-13 02:10:30 -05:00
zoom_preset_selector . AddMenuElem ( MenuElem ( _ ( " Zoom to Range/Region Selection " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : temporal_zoom_selection ) , Horizontal ) ) ) ;
2014-07-11 15:50:51 -04:00
}
}
void
Editor : : set_zoom_preset ( int64_t ms )
{
2018-02-24 07:54:15 -05:00
if ( ms < = 0 ) {
2014-07-11 15:50:51 -04:00
temporal_zoom_session ( ) ;
return ;
}
2015-10-05 10:17:49 -04:00
2017-09-18 12:39:17 -04:00
ARDOUR : : samplecnt_t const sample_rate = ARDOUR : : AudioEngine : : instance ( ) - > sample_rate ( ) ;
2018-02-24 07:54:15 -05:00
temporal_zoom ( ( sample_rate * ms / 1000 ) / _visible_canvas_width ) ;
2014-03-25 08:21:08 -04:00
}
void
Editor : : set_visible_track_count ( int32_t n )
{
2014-03-25 10:33:18 -04:00
_visible_track_count = n ;
/* if the canvas hasn't really been allocated any size yet, just
record the desired number of visible tracks and return . when canvas
allocation happens , we will get called again and then we can do the
real work .
*/
2015-10-05 10:17:49 -04:00
2014-03-25 10:33:18 -04:00
if ( _visible_canvas_height < = 1 ) {
2014-03-25 08:21:08 -04:00
return ;
}
2014-03-25 09:01:26 -04:00
int h ;
2014-03-25 08:21:08 -04:00
string str ;
2014-12-23 12:41:32 -05:00
DisplaySuspender ds ;
2015-10-05 10:17:49 -04:00
2014-03-25 08:21:08 -04:00
if ( _visible_track_count > 0 ) {
2014-07-15 18:09:04 -04:00
h = trackviews_height ( ) / _visible_track_count ;
2014-03-25 08:21:08 -04:00
std : : ostringstream s ;
s < < _visible_track_count ;
str = s . str ( ) ;
2014-03-25 10:33:18 -04:00
} else if ( _visible_track_count = = 0 ) {
2014-07-15 18:09:04 -04:00
uint32_t n = 0 ;
2017-07-19 14:37:57 -04:00
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2014-07-15 18:09:04 -04:00
if ( ( * i ) - > marked_for_display ( ) ) {
+ + n ;
2017-07-19 14:37:57 -04:00
TimeAxisView : : Children cl ( ( * i ) - > get_child_list ( ) ) ;
for ( TimeAxisView : : Children : : const_iterator j = cl . begin ( ) ; j ! = cl . end ( ) ; + + j ) {
if ( ( * j ) - > marked_for_display ( ) ) {
+ + n ;
}
}
2014-07-15 18:09:04 -04:00
}
}
2017-07-19 14:37:57 -04:00
if ( n = = 0 ) {
visible_tracks_selector . set_text ( X_ ( " * " ) ) ;
return ;
}
2014-07-15 18:09:04 -04:00
h = trackviews_height ( ) / n ;
str = _ ( " All " ) ;
2014-03-25 10:33:18 -04:00
} else {
2015-10-04 14:51:05 -04:00
/* negative value means that the visible track count has
2014-03-25 10:33:18 -04:00
been overridden by explicit track height changes .
*/
visible_tracks_selector . set_text ( X_ ( " * " ) ) ;
return ;
2014-03-25 08:21:08 -04:00
}
2014-03-25 10:33:18 -04:00
2014-03-25 09:01:26 -04:00
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2015-03-19 16:55:28 -04:00
( * i ) - > set_height ( h , TimeAxisView : : HeightPerLane ) ;
2014-03-25 09:01:26 -04:00
}
2015-10-05 10:17:49 -04:00
2014-03-25 08:21:08 -04:00
if ( str ! = visible_tracks_selector . get_text ( ) ) {
visible_tracks_selector . set_text ( str ) ;
}
}
2014-03-25 10:33:18 -04:00
void
Editor : : override_visible_track_count ( )
{
2014-10-20 14:33:28 -04:00
_visible_track_count = - 1 ;
2018-02-24 07:54:15 -05:00
visible_tracks_selector . set_text ( _ ( " * " ) ) ;
2014-03-25 10:33:18 -04:00
}
2011-04-19 06:18:21 -04:00
bool
2005-09-25 14:42:24 -04:00
Editor : : edit_controls_button_release ( GdkEventButton * ev )
{
if ( Keyboard : : is_context_menu_event ( ev ) ) {
2016-05-05 21:08:46 -04:00
ARDOUR_UI : : instance ( ) - > add_route ( ) ;
2011-04-19 06:18:21 -04:00
} else if ( ev - > button = = 1 ) {
selection - > clear_tracks ( ) ;
2005-09-25 14:42:24 -04:00
}
2011-06-01 13:00:29 -04:00
2011-04-19 06:18:21 -04:00
return true ;
2005-09-25 14:42:24 -04:00
}
2011-04-19 06:43:43 -04:00
bool
2005-09-25 14:42:24 -04:00
Editor : : mouse_select_button_release ( GdkEventButton * ev )
{
/* this handles just right-clicks */
if ( ev - > button ! = 3 ) {
2007-01-28 12:44:13 -05:00
return false ;
2005-09-25 14:42:24 -04:00
}
2007-01-28 12:44:13 -05:00
return true ;
2005-09-25 14:42:24 -04:00
}
void
Editor : : set_zoom_focus ( ZoomFocus f )
{
2006-11-19 11:45:16 -05:00
string str = zoom_focus_strings [ ( int ) f ] ;
2014-03-23 19:11:42 -04:00
if ( str ! = zoom_focus_selector . get_text ( ) ) {
zoom_focus_selector . set_text ( str ) ;
2006-11-19 11:45:16 -05:00
}
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
if ( zoom_focus ! = f ) {
zoom_focus = f ;
instant_save ( ) ;
}
}
2012-12-13 11:20:37 -05:00
void
Editor : : cycle_zoom_focus ( )
{
switch ( zoom_focus ) {
case ZoomFocusLeft :
set_zoom_focus ( ZoomFocusRight ) ;
break ;
case ZoomFocusRight :
set_zoom_focus ( ZoomFocusCenter ) ;
break ;
case ZoomFocusCenter :
set_zoom_focus ( ZoomFocusPlayhead ) ;
break ;
case ZoomFocusPlayhead :
set_zoom_focus ( ZoomFocusMouse ) ;
break ;
case ZoomFocusMouse :
set_zoom_focus ( ZoomFocusEdit ) ;
break ;
case ZoomFocusEdit :
set_zoom_focus ( ZoomFocusLeft ) ;
break ;
}
}
2005-09-25 14:42:24 -04:00
void
2018-02-09 10:59:39 -05:00
Editor : : update_grid ( )
2005-09-25 14:42:24 -04:00
{
2018-02-24 07:54:15 -05:00
if ( grid_musical ( ) ) {
2018-02-09 10:59:39 -05:00
std : : vector < TempoMap : : BBTPoint > grid ;
if ( bbt_ruler_scale ! = bbt_show_many ) {
2017-09-18 12:39:17 -04:00
compute_current_bbt_points ( grid , _leftmost_sample , _leftmost_sample + current_page_samples ( ) ) ;
2015-10-04 14:51:05 -04:00
}
2018-02-09 10:59:39 -05:00
maybe_draw_grid_lines ( ) ;
2018-02-24 07:54:15 -05:00
} else if ( grid_nonmusical ( ) ) {
2018-02-09 10:59:39 -05:00
maybe_draw_grid_lines ( ) ;
} else {
hide_grid_lines ( ) ;
2005-09-25 14:42:24 -04:00
}
}
2005-12-31 13:20:42 -05:00
void
Editor : : toggle_follow_playhead ( )
{
2018-12-12 11:22:38 -05:00
RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " toggle-follow-playhead " ) ) ;
set_follow_playhead ( tact - > get_active ( ) ) ;
2005-12-31 13:20:42 -05:00
}
2011-01-04 21:28:28 -05:00
/** @param yn true to follow playhead, otherwise false.
* @ param catch_up true to reset the editor view to show the playhead ( if yn = = true ) , otherwise false .
*/
2005-09-25 14:42:24 -04:00
void
2011-01-04 21:28:28 -05:00
Editor : : set_follow_playhead ( bool yn , bool catch_up )
2005-09-25 14:42:24 -04:00
{
if ( _follow_playhead ! = yn ) {
2011-01-04 21:28:28 -05:00
if ( ( _follow_playhead = yn ) = = true & & catch_up ) {
2005-09-25 14:42:24 -04:00
/* catch up */
2010-02-07 20:25:06 -05:00
reset_x_origin_to_follow_playhead ( ) ;
2005-09-25 14:42:24 -04:00
}
instant_save ( ) ;
}
}
2010-03-16 11:33:04 -04:00
void
Editor : : toggle_stationary_playhead ( )
{
2018-12-12 11:22:38 -05:00
RefPtr < ToggleAction > tact = ActionManager : : get_toggle_action ( X_ ( " Editor " ) , X_ ( " toggle-stationary-playhead " ) ) ;
set_stationary_playhead ( tact - > get_active ( ) ) ;
2010-03-16 11:33:04 -04:00
}
void
Editor : : set_stationary_playhead ( bool yn )
{
2010-11-25 15:37:39 -05:00
if ( _stationary_playhead ! = yn ) {
if ( ( _stationary_playhead = yn ) = = true ) {
2018-02-24 07:54:15 -05:00
/* catch up -- FIXME need a 3.0 equivalent of this 2.X call */
2010-11-25 15:37:39 -05:00
// update_current_screen ();
}
instant_save ( ) ;
}
2010-03-16 11:33:04 -04:00
}
2005-09-25 14:42:24 -04:00
PlaylistSelector &
Editor : : playlist_selector ( ) const
{
return * _playlist_selector ;
}
2017-09-18 12:39:17 -04:00
samplecnt_t
Editor : : get_paste_offset ( samplepos_t pos , unsigned paste_count , samplecnt_t duration )
2014-11-14 20:04:09 -05:00
{
if ( paste_count = = 0 ) {
/* don't bother calculating an offset that will be zero anyway */
return 0 ;
}
/* calculate basic unsnapped multi-paste offset */
2017-09-18 12:39:17 -04:00
samplecnt_t offset = paste_count * duration ;
2014-11-14 20:04:09 -05:00
2014-11-16 17:04:27 -05:00
/* snap offset so pos + offset is aligned to the grid */
2017-09-18 12:39:17 -04:00
MusicSample offset_pos ( pos + offset , 0 ) ;
2014-11-16 17:04:27 -05:00
snap_to ( offset_pos , RoundUpMaybe ) ;
2017-09-18 12:39:17 -04:00
offset = offset_pos . sample - pos ;
2014-11-14 20:04:09 -05:00
return offset ;
}
2015-01-07 18:30:25 -05:00
unsigned
2017-09-18 12:39:17 -04:00
Editor : : get_grid_beat_divisions ( samplepos_t position )
2015-01-07 18:30:25 -05:00
{
2018-02-09 10:59:39 -05:00
switch ( _grid_type ) {
case GridTypeBeatDiv32 : return 32 ;
case GridTypeBeatDiv28 : return 28 ;
case GridTypeBeatDiv24 : return 24 ;
case GridTypeBeatDiv20 : return 20 ;
case GridTypeBeatDiv16 : return 16 ;
case GridTypeBeatDiv14 : return 14 ;
case GridTypeBeatDiv12 : return 12 ;
case GridTypeBeatDiv10 : return 10 ;
case GridTypeBeatDiv8 : return 8 ;
case GridTypeBeatDiv7 : return 7 ;
case GridTypeBeatDiv6 : return 6 ;
case GridTypeBeatDiv5 : return 5 ;
case GridTypeBeatDiv4 : return 4 ;
case GridTypeBeatDiv3 : return 3 ;
case GridTypeBeatDiv2 : return 2 ;
2018-08-13 13:55:19 -04:00
case GridTypeBeat : return 1 ;
case GridTypeBar : return 1 ;
2018-02-09 10:59:39 -05:00
case GridTypeNone : return 0 ;
2018-02-26 19:38:18 -05:00
case GridTypeTimecode : return 0 ;
2018-02-09 10:59:39 -05:00
case GridTypeMinSec : return 0 ;
2018-02-26 18:02:24 -05:00
case GridTypeCDFrame : return 0 ;
2018-02-09 10:59:39 -05:00
default : return 0 ;
2015-01-07 18:30:25 -05:00
}
return 0 ;
}
2016-06-11 12:46:13 -04:00
/** returns the current musical grid divisiions using the supplied modifier mask from a GtkEvent.
if the grid is non - musical , returns 0.
if the grid is snapped to bars , returns - 1.
@ param event_state the current keyboard modifier mask .
*/
2016-11-16 11:13:16 -05:00
int32_t
2016-06-11 12:46:13 -04:00
Editor : : get_grid_music_divisions ( uint32_t event_state )
{
2018-02-09 10:59:39 -05:00
if ( snap_mode ( ) = = SnapOff & & ! ArdourKeyboard : : indicates_snap ( event_state ) ) {
2016-06-11 12:46:13 -04:00
return 0 ;
}
2018-02-09 10:59:39 -05:00
if ( snap_mode ( ) ! = SnapOff & & ArdourKeyboard : : indicates_snap ( event_state ) ) {
2016-06-11 12:46:13 -04:00
return 0 ;
}
2018-02-09 10:59:39 -05:00
switch ( _grid_type ) {
case GridTypeBeatDiv32 : return 32 ;
case GridTypeBeatDiv28 : return 28 ;
case GridTypeBeatDiv24 : return 24 ;
case GridTypeBeatDiv20 : return 20 ;
case GridTypeBeatDiv16 : return 16 ;
case GridTypeBeatDiv14 : return 14 ;
case GridTypeBeatDiv12 : return 12 ;
case GridTypeBeatDiv10 : return 10 ;
case GridTypeBeatDiv8 : return 8 ;
case GridTypeBeatDiv7 : return 7 ;
case GridTypeBeatDiv6 : return 6 ;
case GridTypeBeatDiv5 : return 5 ;
case GridTypeBeatDiv4 : return 4 ;
case GridTypeBeatDiv3 : return 3 ;
case GridTypeBeatDiv2 : return 2 ;
case GridTypeBeat : return 1 ;
case GridTypeBar : return - 1 ;
case GridTypeNone : return 0 ;
2018-02-26 19:38:18 -05:00
case GridTypeTimecode : return 0 ;
2018-02-09 10:59:39 -05:00
case GridTypeMinSec : return 0 ;
2018-02-26 18:02:24 -05:00
case GridTypeCDFrame : return 0 ;
2016-06-11 12:46:13 -04:00
}
return 0 ;
}
2017-09-24 12:03:54 -04:00
Temporal : : Beats
2017-09-18 12:39:17 -04:00
Editor : : get_grid_type_as_beats ( bool & success , samplepos_t position )
2009-08-26 23:09:30 -04:00
{
success = true ;
2015-01-07 18:30:25 -05:00
const unsigned divisions = get_grid_beat_divisions ( position ) ;
if ( divisions ) {
2017-09-24 12:03:54 -04:00
return Temporal : : Beats ( 1.0 / ( double ) get_grid_beat_divisions ( position ) ) ;
2015-01-07 18:30:25 -05:00
}
2018-02-09 10:59:39 -05:00
switch ( _grid_type ) {
case GridTypeBeat :
2017-09-24 12:03:54 -04:00
return Temporal : : Beats ( 4.0 / _session - > tempo_map ( ) . meter_at_sample ( position ) . note_divisor ( ) ) ;
2018-02-09 10:59:39 -05:00
case GridTypeBar :
2009-12-17 13:24:23 -05:00
if ( _session ) {
2017-09-18 12:39:17 -04:00
const Meter & m = _session - > tempo_map ( ) . meter_at_sample ( position ) ;
2017-09-24 12:03:54 -04:00
return Temporal : : Beats ( ( 4.0 * m . divisions_per_bar ( ) ) / m . note_divisor ( ) ) ;
2009-08-26 23:09:30 -04:00
}
break ;
default :
success = false ;
break ;
}
2017-09-24 12:03:54 -04:00
return Temporal : : Beats ( ) ;
2009-08-26 23:09:30 -04:00
}
2017-09-18 12:39:17 -04:00
samplecnt_t
Editor : : get_nudge_distance ( samplepos_t pos , samplecnt_t & next )
2005-09-25 14:42:24 -04:00
{
2017-09-18 12:39:17 -04:00
samplecnt_t ret ;
2005-09-25 14:42:24 -04:00
2011-06-02 13:50:37 -04:00
ret = nudge_clock - > current_duration ( pos ) ;
2005-09-25 14:42:24 -04:00
next = ret + 1 ; /* XXXX fix me */
return ret ;
}
int
2007-01-09 18:24:54 -05:00
Editor : : playlist_deletion_dialog ( boost : : shared_ptr < Playlist > pl )
2005-09-25 14:42:24 -04:00
{
2010-05-02 19:54:25 -04:00
ArdourDialog dialog ( _ ( " Playlist Deletion " ) ) ;
2005-10-06 15:10:57 -04:00
Label label ( string_compose ( _ ( " Playlist %1 is currently unused. \n "
2011-05-02 19:21:53 -04:00
" If it is kept, its audio files will not be cleaned. \n "
" If it is deleted, audio files used by it alone will be cleaned. " ) ,
2007-01-09 18:24:54 -05:00
pl - > name ( ) ) ) ;
2009-10-14 12:10:01 -04:00
2006-01-04 22:18:44 -05:00
dialog . set_position ( WIN_POS_CENTER ) ;
2005-11-27 16:17:41 -05:00
dialog . get_vbox ( ) - > pack_start ( label ) ;
2005-09-25 14:42:24 -04:00
2007-01-09 18:24:54 -05:00
label . show ( ) ;
2015-11-21 16:45:43 -05:00
dialog . add_button ( _ ( " Delete All Unused " ) , RESPONSE_YES ) ; // needs clarification. this and all remaining ones
2011-05-02 19:21:53 -04:00
dialog . add_button ( _ ( " Delete Playlist " ) , RESPONSE_ACCEPT ) ;
2016-01-05 09:48:35 -05:00
Button * keep = dialog . add_button ( _ ( " Keep Playlist " ) , RESPONSE_REJECT ) ;
2015-11-21 16:45:43 -05:00
dialog . add_button ( _ ( " Keep Remaining " ) , RESPONSE_NO ) ; // ditto
2005-11-27 16:17:41 -05:00
dialog . add_button ( _ ( " Cancel " ) , RESPONSE_CANCEL ) ;
2005-09-25 14:42:24 -04:00
2018-02-24 07:54:15 -05:00
/* by default gtk uses the left most button */
2016-01-05 09:48:35 -05:00
keep - > grab_focus ( ) ;
2005-11-27 16:17:41 -05:00
switch ( dialog . run ( ) ) {
2015-11-21 16:45:43 -05:00
case RESPONSE_NO :
/* keep this and all remaining ones */
return - 2 ;
break ;
2015-11-21 15:12:17 -05:00
case RESPONSE_YES :
/* delete this and all others */
return 2 ;
break ;
2005-11-27 16:17:41 -05:00
case RESPONSE_ACCEPT :
2005-09-25 14:42:24 -04:00
/* delete the playlist */
2015-11-21 15:12:17 -05:00
return 1 ;
2005-09-25 14:42:24 -04:00
break ;
2005-11-27 16:17:41 -05:00
case RESPONSE_REJECT :
/* keep the playlist */
2015-11-21 15:12:17 -05:00
return 0 ;
2005-09-25 14:42:24 -04:00
break ;
2005-11-27 16:17:41 -05:00
2005-09-25 14:42:24 -04:00
default :
2005-11-25 19:06:46 -05:00
break ;
2005-09-25 14:42:24 -04:00
}
2005-11-25 19:06:46 -05:00
2005-11-27 16:17:41 -05:00
return - 1 ;
2005-09-25 14:42:24 -04:00
}
bool
2017-09-18 12:39:17 -04:00
Editor : : audio_region_selection_covers ( samplepos_t where )
2005-09-25 14:42:24 -04:00
{
2006-07-23 08:03:19 -04:00
for ( RegionSelection : : iterator a = selection - > regions . begin ( ) ; a ! = selection - > regions . end ( ) ; + + a ) {
2006-08-29 17:21:48 -04:00
if ( ( * a ) - > region ( ) - > covers ( where ) ) {
2005-09-25 14:42:24 -04:00
return true ;
}
}
return false ;
}
2018-10-22 17:46:44 -04:00
void
Editor : : cleanup_regions ( )
{
_regions - > remove_unused_regions ( ) ;
}
2005-09-25 14:42:24 -04:00
void
Editor : : prepare_for_cleanup ( )
{
2006-07-23 08:03:19 -04:00
cut_buffer - > clear_regions ( ) ;
2005-09-25 14:42:24 -04:00
cut_buffer - > clear_playlists ( ) ;
2006-07-23 08:03:19 -04:00
selection - > clear_regions ( ) ;
2005-09-25 14:42:24 -04:00
selection - > clear_playlists ( ) ;
2008-09-10 11:03:30 -04:00
2009-07-03 18:42:22 -04:00
_regions - > suspend_redisplay ( ) ;
2008-09-10 11:03:30 -04:00
}
void
Editor : : finish_cleanup ( )
{
2009-07-03 18:42:22 -04:00
_regions - > resume_redisplay ( ) ;
2005-09-25 14:42:24 -04:00
}
Location *
Editor : : transport_loop_location ( )
{
2009-12-17 13:24:23 -05:00
if ( _session ) {
return _session - > locations ( ) - > auto_loop_location ( ) ;
2005-09-25 14:42:24 -04:00
} else {
return 0 ;
}
}
Location *
Editor : : transport_punch_location ( )
{
2009-12-17 13:24:23 -05:00
if ( _session ) {
return _session - > locations ( ) - > auto_punch_location ( ) ;
2005-09-25 14:42:24 -04:00
} else {
return 0 ;
}
}
2005-12-17 08:39:27 -05:00
2005-12-23 10:34:02 -05:00
bool
Editor : : control_layout_scroll ( GdkEventScroll * ev )
{
2014-06-09 10:02:38 -04:00
/* Just forward to the normal canvas scroll method. The coordinate
systems are different but since the canvas is always larger than the
track headers , and aligned with the trackview area , this will work .
2005-12-23 10:34:02 -05:00
2014-06-09 10:02:38 -04:00
In the not too distant future this layout is going away anyway and
headers will be on the canvas .
*/
2014-06-13 14:27:59 -04:00
return canvas_scroll_event ( ev , false ) ;
2005-12-21 16:15:37 -05:00
}
2006-01-04 22:18:44 -05:00
void
2010-09-02 13:01:36 -04:00
Editor : : session_state_saved ( string )
2006-01-04 22:18:44 -05:00
{
2011-06-01 13:00:29 -04:00
update_title ( ) ;
2009-07-03 19:51:58 -04:00
_snapshots - > redisplay ( ) ;
2006-01-04 22:18:44 -05:00
}
2012-06-13 00:21:46 -04:00
void
Editor : : maximise_editing_space ( )
{
if ( _maximised ) {
return ;
}
2015-07-22 17:49:41 -04:00
Gtk : : Window * toplevel = current_toplevel ( ) ;
2010-11-14 08:48:24 -05:00
2015-07-22 17:49:41 -04:00
if ( toplevel ) {
toplevel - > fullscreen ( ) ;
_maximised = true ;
}
2011-07-17 14:22:43 -04:00
}
2006-01-19 13:05:31 -05:00
void
2012-06-13 00:21:46 -04:00
Editor : : restore_editing_space ( )
2006-01-19 13:05:31 -05:00
{
2012-06-13 00:21:46 -04:00
if ( ! _maximised ) {
2012-01-24 22:03:25 -05:00
return ;
2010-06-07 21:29:33 -04:00
}
2011-06-01 13:00:29 -04:00
2015-07-22 17:49:41 -04:00
Gtk : : Window * toplevel = current_toplevel ( ) ;
2006-11-19 11:45:16 -05:00
2015-07-22 17:49:41 -04:00
if ( toplevel ) {
toplevel - > unfullscreen ( ) ;
_maximised = false ;
}
2006-01-19 13:05:31 -05:00
}
2006-03-07 21:50:53 -05:00
2007-10-06 12:24:08 -04:00
/**
* Make new playlists for a given track and also any others that belong
2013-04-05 17:16:33 -04:00
* to the same active route group with the ` select ' property .
2007-10-06 12:24:08 -04:00
* @ param v Track .
*/
2009-10-14 12:10:01 -04:00
void
2009-07-09 13:58:13 -04:00
Editor : : new_playlists ( TimeAxisView * v )
2006-03-07 21:50:53 -05:00
{
begin_reversible_command ( _ ( " new playlists " ) ) ;
2008-10-06 14:04:12 -04:00
vector < boost : : shared_ptr < ARDOUR : : Playlist > > playlists ;
2019-03-19 00:14:40 -04:00
_session - > playlists ( ) - > get ( playlists ) ;
2016-06-05 15:54:37 -04:00
mapover_tracks ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : mapped_use_new_playlist ) , playlists ) , v , ARDOUR : : Properties : : group_select . property_id ) ;
2006-03-07 21:50:53 -05:00
commit_reversible_command ( ) ;
}
2007-10-06 12:24:08 -04:00
/**
* Use a copy of the current playlist for a given track and also any others that belong
2013-04-05 17:16:33 -04:00
* to the same active route group with the ` select ' property .
2007-10-06 12:24:08 -04:00
* @ param v Track .
*/
2006-03-07 21:50:53 -05:00
void
2009-07-09 13:58:13 -04:00
Editor : : copy_playlists ( TimeAxisView * v )
2006-03-07 21:50:53 -05:00
{
begin_reversible_command ( _ ( " copy playlists " ) ) ;
2008-10-06 14:04:12 -04:00
vector < boost : : shared_ptr < ARDOUR : : Playlist > > playlists ;
2019-03-19 00:14:40 -04:00
_session - > playlists ( ) - > get ( playlists ) ;
2016-06-05 15:54:37 -04:00
mapover_tracks ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : mapped_use_copy_playlist ) , playlists ) , v , ARDOUR : : Properties : : group_select . property_id ) ;
2006-03-07 21:50:53 -05:00
commit_reversible_command ( ) ;
}
2009-06-25 16:58:32 -04:00
/** Clear the current playlist for a given track and also any others that belong
2013-04-05 17:16:33 -04:00
* to the same active route group with the ` select ' property .
2007-10-06 12:24:08 -04:00
* @ param v Track .
*/
2009-10-14 12:10:01 -04:00
void
2009-07-09 13:58:13 -04:00
Editor : : clear_playlists ( TimeAxisView * v )
2006-03-07 21:50:53 -05:00
{
2015-10-05 10:17:49 -04:00
begin_reversible_command ( _ ( " clear playlists " ) ) ;
2008-10-06 14:04:12 -04:00
vector < boost : : shared_ptr < ARDOUR : : Playlist > > playlists ;
2019-03-19 00:14:40 -04:00
_session - > playlists ( ) - > get ( playlists ) ;
2016-06-05 15:54:37 -04:00
mapover_tracks ( sigc : : mem_fun ( * this , & Editor : : mapped_clear_playlist ) , v , ARDOUR : : Properties : : group_select . property_id ) ;
2006-03-07 21:50:53 -05:00
commit_reversible_command ( ) ;
}
2009-10-14 12:10:01 -04:00
void
2009-07-09 13:58:13 -04:00
Editor : : mapped_use_new_playlist ( RouteTimeAxisView & atv , uint32_t sz , vector < boost : : shared_ptr < ARDOUR : : Playlist > > const & playlists )
2006-03-07 21:50:53 -05:00
{
2016-11-25 08:24:15 -05:00
atv . use_new_playlist ( sz > 1 ? false : true , playlists , false ) ;
2006-03-07 21:50:53 -05:00
}
void
2009-07-09 13:58:13 -04:00
Editor : : mapped_use_copy_playlist ( RouteTimeAxisView & atv , uint32_t sz , vector < boost : : shared_ptr < ARDOUR : : Playlist > > const & playlists )
2006-03-07 21:50:53 -05:00
{
2016-11-25 08:24:15 -05:00
atv . use_new_playlist ( sz > 1 ? false : true , playlists , true ) ;
2006-03-07 21:50:53 -05:00
}
2009-10-14 12:10:01 -04:00
void
2009-07-21 11:55:17 -04:00
Editor : : mapped_clear_playlist ( RouteTimeAxisView & atv , uint32_t /*sz*/ )
2006-03-07 21:50:53 -05:00
{
2009-07-09 13:58:13 -04:00
atv . clear_playlist ( ) ;
2006-03-07 21:50:53 -05:00
}
2006-03-09 18:44:39 -05:00
2014-12-14 08:13:38 -05:00
double
Editor : : get_y_origin ( ) const
{
return vertical_adjustment . get_value ( ) ;
}
2010-02-07 20:25:06 -05:00
/** Queue up a change to the viewport x origin.
2017-09-18 12:39:17 -04:00
* @ param sample New x origin .
2010-02-07 20:25:06 -05:00
*/
2007-01-11 15:36:35 -05:00
void
2017-09-18 12:39:17 -04:00
Editor : : reset_x_origin ( samplepos_t sample )
2007-01-11 15:36:35 -05:00
{
2012-06-20 10:14:22 -04:00
pending_visual_change . add ( VisualChange : : TimeOrigin ) ;
2017-09-18 12:39:17 -04:00
pending_visual_change . time_origin = sample ;
2012-06-20 10:14:22 -04:00
ensure_visual_change_idle_handler ( ) ;
2007-01-11 15:36:35 -05:00
}
2009-06-13 13:52:51 -04:00
void
Editor : : reset_y_origin ( double y )
{
2012-06-20 10:14:22 -04:00
pending_visual_change . add ( VisualChange : : YOrigin ) ;
pending_visual_change . y_origin = y ;
ensure_visual_change_idle_handler ( ) ;
2009-06-13 13:52:51 -04:00
}
2007-01-11 15:36:35 -05:00
void
2017-09-18 12:39:17 -04:00
Editor : : reset_zoom ( samplecnt_t spp )
2007-01-11 15:36:35 -05:00
{
2013-06-18 23:02:54 -04:00
if ( spp = = samples_per_pixel ) {
2012-06-20 10:14:27 -04:00
return ;
}
2012-06-20 10:14:22 -04:00
pending_visual_change . add ( VisualChange : : ZoomLevel ) ;
2013-06-18 23:02:54 -04:00
pending_visual_change . samples_per_pixel = spp ;
2012-06-20 10:14:22 -04:00
ensure_visual_change_idle_handler ( ) ;
2007-01-11 15:36:35 -05:00
}
void
2017-09-18 12:39:17 -04:00
Editor : : reposition_and_zoom ( samplepos_t sample , double fpu )
2007-01-11 15:36:35 -05:00
{
2017-09-18 12:39:17 -04:00
reset_x_origin ( sample ) ;
2007-01-11 15:36:35 -05:00
reset_zoom ( fpu ) ;
2008-09-10 11:03:30 -04:00
if ( ! no_save_visual ) {
undo_visual_stack . push_back ( current_visual_state ( false ) ) ;
}
}
2012-03-06 21:11:59 -05:00
Editor : : VisualState : : VisualState ( bool with_tracks )
: gui_state ( with_tracks ? new GUIObjectState : 0 )
2011-07-06 20:37:13 -04:00
{
}
Editor : : VisualState : : ~ VisualState ( )
{
delete gui_state ;
}
2008-09-10 11:03:30 -04:00
Editor : : VisualState *
Editor : : current_visual_state ( bool with_tracks )
{
2012-03-06 21:11:59 -05:00
VisualState * vs = new VisualState ( with_tracks ) ;
2008-09-10 11:03:30 -04:00
vs - > y_position = vertical_adjustment . get_value ( ) ;
2013-04-12 11:31:50 -04:00
vs - > samples_per_pixel = samples_per_pixel ;
2017-09-18 12:39:17 -04:00
vs - > _leftmost_sample = _leftmost_sample ;
2008-09-10 11:03:30 -04:00
vs - > zoom_focus = zoom_focus ;
2015-10-05 10:17:49 -04:00
if ( with_tracks ) {
2016-07-05 17:49:50 -04:00
vs - > gui_state - > set_state ( ARDOUR_UI : : instance ( ) - > gui_object_state - > get_state ( ) ) ;
2008-09-10 11:03:30 -04:00
}
2009-10-14 12:10:01 -04:00
2008-09-10 11:03:30 -04:00
return vs ;
2007-01-11 15:36:35 -05:00
}
void
2008-09-10 11:03:30 -04:00
Editor : : undo_visual_state ( )
2007-01-11 15:36:35 -05:00
{
2008-09-10 11:03:30 -04:00
if ( undo_visual_stack . empty ( ) ) {
2008-01-10 16:20:59 -05:00
return ;
}
2007-01-11 15:36:35 -05:00
2008-09-10 11:03:30 -04:00
VisualState * vs = undo_visual_stack . back ( ) ;
undo_visual_stack . pop_back ( ) ;
2012-03-06 21:11:59 -05:00
redo_visual_stack . push_back ( current_visual_state ( vs ? vs - > gui_state ! = 0 : false ) ) ;
2014-11-16 21:58:05 -05:00
if ( vs ) {
use_visual_state ( * vs ) ;
}
2008-09-10 11:03:30 -04:00
}
2008-01-10 16:20:59 -05:00
2008-09-10 11:03:30 -04:00
void
Editor : : redo_visual_state ( )
{
if ( redo_visual_stack . empty ( ) ) {
return ;
}
VisualState * vs = redo_visual_stack . back ( ) ;
redo_visual_stack . pop_back ( ) ;
2012-03-06 21:11:59 -05:00
2018-02-24 07:54:15 -05:00
/* XXX: can 'vs' really be 0? Is there a place that puts NULL pointers onto the stack? */
2014-11-16 21:58:05 -05:00
undo_visual_stack . push_back ( current_visual_state ( vs ? ( vs - > gui_state ! = 0 ) : false ) ) ;
2012-03-06 21:11:59 -05:00
2014-11-16 21:58:05 -05:00
if ( vs ) {
use_visual_state ( * vs ) ;
}
2008-09-10 11:03:30 -04:00
}
void
Editor : : swap_visual_state ( )
{
if ( undo_visual_stack . empty ( ) ) {
redo_visual_state ( ) ;
} else {
undo_visual_state ( ) ;
}
}
void
Editor : : use_visual_state ( VisualState & vs )
{
2012-03-06 21:11:59 -05:00
PBD : : Unwinder < bool > nsv ( no_save_visual , true ) ;
2014-06-28 20:52:56 -04:00
DisplaySuspender ds ;
2008-09-10 11:03:30 -04:00
vertical_adjustment . set_value ( vs . y_position ) ;
set_zoom_focus ( vs . zoom_focus ) ;
2017-09-18 12:39:17 -04:00
reposition_and_zoom ( vs . _leftmost_sample , vs . samples_per_pixel ) ;
2015-10-05 10:17:49 -04:00
2012-03-06 21:11:59 -05:00
if ( vs . gui_state ) {
2016-07-05 17:49:50 -04:00
ARDOUR_UI : : instance ( ) - > gui_object_state - > set_state ( vs . gui_state - > get_state ( ) ) ;
2015-10-05 10:17:49 -04:00
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2015-03-21 11:50:47 -04:00
( * i ) - > clear_property_cache ( ) ;
2012-03-06 21:11:59 -05:00
( * i ) - > reset_visual_state ( ) ;
}
2009-10-14 12:10:01 -04:00
}
2008-10-14 10:20:29 -04:00
2011-07-06 20:37:13 -04:00
_routes - > update_visibility ( ) ;
2008-01-10 16:20:59 -05:00
}
2012-06-20 10:14:27 -04:00
/** This is the core function that controls the zoom level of the canvas. It is called
* whenever one or more calls are made to reset_zoom ( ) . It executes in an idle handler .
2014-07-02 15:53:24 -04:00
* @ param spp new number of samples per pixel
2012-06-20 10:14:27 -04:00
*/
2008-01-10 16:20:59 -05:00
void
2017-09-18 12:39:17 -04:00
Editor : : set_samples_per_pixel ( samplecnt_t spp )
2008-01-10 16:20:59 -05:00
{
2014-07-02 15:53:24 -04:00
if ( spp < 1 ) {
return ;
}
2017-09-18 12:39:17 -04:00
const samplecnt_t three_days = 3 * 24 * 60 * 60 * ( _session ? _session - > sample_rate ( ) : 48000 ) ;
const samplecnt_t lots_of_pixels = 4000 ;
2014-07-02 15:53:24 -04:00
/* if the zoom level is greater than what you'd get trying to display 3
* days of audio on a really big screen , then it ' s too big .
*/
if ( spp * lots_of_pixels > three_days ) {
return ;
}
2013-06-18 23:02:54 -04:00
samples_per_pixel = spp ;
2017-03-26 23:26:58 -04:00
}
2013-06-18 23:02:54 -04:00
2017-03-26 23:26:58 -04:00
void
Editor : : on_samples_per_pixel_changed ( )
{
2012-11-26 17:43:10 -05:00
bool const showing_time_selection = selection - > time . length ( ) > 0 ;
2012-03-25 08:12:08 -04:00
2017-09-18 12:39:17 -04:00
if ( showing_time_selection & & selection - > time . start ( ) ! = selection - > time . end_sample ( ) ) {
2009-12-13 16:27:19 -05:00
for ( TrackViewList : : iterator i = selection - > tracks . begin ( ) ; i ! = selection - > tracks . end ( ) ; + + i ) {
( * i ) - > reshow_selection ( selection - > time ) ;
2007-01-11 15:36:35 -05:00
}
}
ZoomChanged ( ) ; /* EMIT_SIGNAL */
2013-10-31 03:10:18 -04:00
ArdourCanvas : : GtkCanvasViewport * c ;
c = get_track_canvas ( ) ;
if ( c ) {
c - > canvas ( ) - > zoomed ( ) ;
}
2008-01-10 16:20:59 -05:00
2008-09-10 17:27:39 -04:00
if ( playhead_cursor ) {
2017-09-18 12:39:17 -04:00
playhead_cursor - > set_position ( playhead_cursor - > current_sample ( ) ) ;
2008-09-10 17:27:39 -04:00
}
2007-01-11 15:36:35 -05:00
2009-06-29 10:29:53 -04:00
refresh_location_display ( ) ;
2009-06-16 20:29:56 -04:00
_summary - > set_overlays_dirty ( ) ;
2009-06-10 21:05:01 -04:00
2010-11-12 17:51:54 -05:00
update_marker_labels ( ) ;
2007-01-11 15:36:35 -05:00
instant_save ( ) ;
}
2017-09-18 12:39:17 -04:00
samplepos_t
2016-12-16 09:02:29 -05:00
Editor : : playhead_cursor_sample ( ) const
{
2017-09-18 12:39:17 -04:00
return playhead_cursor - > current_sample ( ) ;
2016-12-16 09:02:29 -05:00
}
2013-03-12 17:00:09 -04:00
void
Editor : : queue_visual_videotimeline_update ( )
{
2017-06-28 12:46:07 -04:00
pending_visual_change . add ( VisualChange : : VideoTimeline ) ;
2013-03-12 17:00:09 -04:00
ensure_visual_change_idle_handler ( ) ;
}
2009-06-15 18:45:05 -04:00
void
Editor : : ensure_visual_change_idle_handler ( )
{
2009-06-13 13:52:51 -04:00
if ( pending_visual_change . idle_handler_id < 0 ) {
2018-02-24 07:54:15 -05:00
/* see comment in add_to_idle_resize above. */
2014-10-29 13:31:13 -04:00
pending_visual_change . idle_handler_id = g_idle_add_full ( G_PRIORITY_HIGH_IDLE + 10 , _idle_visual_changer , this , NULL ) ;
2013-04-04 18:45:27 -04:00
pending_visual_change . being_handled = false ;
2009-06-15 18:45:05 -04:00
}
2009-06-13 13:52:51 -04:00
}
2007-01-11 15:36:35 -05:00
int
Editor : : _idle_visual_changer ( void * arg )
{
return static_cast < Editor * > ( arg ) - > idle_visual_changer ( ) ;
}
2017-04-01 07:33:59 -04:00
void
Editor : : pre_render ( )
{
visual_change_queued = false ;
if ( pending_visual_change . pending ! = 0 ) {
ensure_visual_change_idle_handler ( ) ;
}
}
2007-01-11 15:36:35 -05:00
int
Editor : : idle_visual_changer ( )
{
2017-06-28 12:42:10 -04:00
pending_visual_change . idle_handler_id = - 1 ;
2017-04-01 07:33:59 -04:00
if ( pending_visual_change . pending = = 0 ) {
return 0 ;
}
2012-06-25 20:07:45 -04:00
/* set_horizontal_position() below (and maybe other calls) call
gtk_main_iteration ( ) , so it ' s possible that a signal will be handled
half - way through this method . If this signal wants an
idle_visual_changer we must schedule another one after this one , so
mark the idle_handler_id as - 1 here to allow that . Also make a note
that we are doing the visual change , so that changes in response to
super - rapid - screen - update can be dropped if we are still processing
the last one .
*/
2012-11-27 08:21:21 -05:00
2017-04-01 07:33:59 -04:00
if ( visual_change_queued ) {
return 0 ;
}
2012-06-25 20:07:45 -04:00
pending_visual_change . being_handled = true ;
2015-10-05 10:17:49 -04:00
2014-03-20 13:29:29 -04:00
VisualChange vc = pending_visual_change ;
2007-01-11 15:36:35 -05:00
pending_visual_change . pending = ( VisualChange : : Type ) 0 ;
2008-01-10 16:20:59 -05:00
2014-03-20 13:29:29 -04:00
visual_changer ( vc ) ;
2010-10-17 19:35:05 -04:00
2014-03-20 13:29:29 -04:00
pending_visual_change . being_handled = false ;
2013-06-25 21:56:10 -04:00
2017-04-01 07:33:59 -04:00
visual_change_queued = true ;
2014-03-20 13:29:29 -04:00
return 0 ; /* this is always a one-shot call */
}
void
Editor : : visual_changer ( const VisualChange & vc )
{
2017-03-26 23:26:58 -04:00
/**
* Changed first so the correct horizontal canvas position is calculated in
* Editor : : set_horizontal_position
*/
2014-03-20 13:29:29 -04:00
if ( vc . pending & VisualChange : : ZoomLevel ) {
set_samples_per_pixel ( vc . samples_per_pixel ) ;
2013-03-12 17:00:09 -04:00
}
2014-03-20 13:29:29 -04:00
if ( vc . pending & VisualChange : : TimeOrigin ) {
2017-03-26 23:26:58 -04:00
double new_time_origin = sample_to_pixel_unrounded ( vc . time_origin ) ;
set_horizontal_position ( new_time_origin ) ;
2008-12-12 09:43:24 -05:00
}
2013-03-12 17:00:09 -04:00
2014-03-20 13:29:29 -04:00
if ( vc . pending & VisualChange : : YOrigin ) {
vertical_adjustment . set_value ( vc . y_origin ) ;
2009-06-13 13:52:51 -04:00
}
2009-10-14 12:10:01 -04:00
2017-03-26 23:26:58 -04:00
/**
* Now the canvas is in the final state before render the canvas items that
* support the Item : : prepare_for_render interface can calculate the correct
* item to visible canvas intersection .
*/
if ( vc . pending & VisualChange : : ZoomLevel ) {
on_samples_per_pixel_changed ( ) ;
compute_fixed_ruler_scale ( ) ;
compute_bbt_ruler_scale ( vc . time_origin , pending_visual_change . time_origin + current_page_samples ( ) ) ;
update_tempo_based_rulers ( ) ;
2008-12-12 09:43:24 -05:00
}
2013-04-11 13:49:29 -04:00
2014-03-20 13:29:29 -04:00
if ( ! ( vc . pending & VisualChange : : ZoomLevel ) ) {
2018-02-24 07:54:15 -05:00
/* If the canvas is not being zoomed then the canvas items will not change
2017-03-26 23:26:58 -04:00
* and cause Item : : prepare_for_render to be called so do it here manually .
* Not ideal , but I can ' t think of a better solution atm .
*/
_track_canvas - > prepare_for_render ( ) ;
}
2018-02-24 07:54:15 -05:00
/* If we are only scrolling vertically there is no need to update these */
2017-03-26 23:26:58 -04:00
if ( vc . pending ! = VisualChange : : YOrigin ) {
update_fixed_rulers ( ) ;
2018-02-09 10:59:39 -05:00
redisplay_grid ( true ) ;
2009-10-14 12:10:01 -04:00
2017-06-28 12:46:07 -04:00
/* video frames & position need to be updated for zoom, horiz-scroll
* and ( explicitly ) VisualChange : : VideoTimeline .
*/
update_video_timeline ( ) ;
}
2017-03-26 23:26:58 -04:00
2009-06-16 20:29:56 -04:00
_summary - > set_overlays_dirty ( ) ;
2007-01-11 15:36:35 -05:00
}
2007-01-28 12:44:13 -05:00
struct EditorOrderTimeAxisSorter {
2009-07-09 13:58:13 -04:00
bool operator ( ) ( const TimeAxisView * a , const TimeAxisView * b ) const {
2009-01-01 19:17:55 -05:00
return a - > order ( ) < b - > order ( ) ;
2007-01-28 12:44:13 -05:00
}
} ;
2009-10-14 12:10:01 -04:00
2007-01-28 12:44:13 -05:00
void
2011-12-10 14:20:15 -05:00
Editor : : sort_track_selection ( TrackViewList & sel )
2007-01-28 12:44:13 -05:00
{
EditorOrderTimeAxisSorter cmp ;
2011-12-10 14:20:15 -05:00
sel . sort ( cmp ) ;
2007-01-28 12:44:13 -05:00
}
2017-09-18 12:39:17 -04:00
samplepos_t
2013-10-20 17:02:56 -04:00
Editor : : get_preferred_edit_position ( EditIgnoreOption ignore , bool from_context_menu , bool from_outside_canvas )
2007-11-07 20:40:25 -05:00
{
bool ignored ;
2017-09-18 12:39:17 -04:00
samplepos_t where = 0 ;
2008-01-10 16:20:59 -05:00
EditPoint ep = _edit_point ;
2007-11-07 20:40:25 -05:00
2016-12-08 04:44:26 -05:00
if ( Profile - > get_mixbus ( ) ) {
if ( ep = = EditAtSelectedMarker ) {
2015-02-03 14:33:22 -05:00
ep = EditAtPlayhead ;
2016-12-08 04:44:26 -05:00
}
}
2015-01-07 20:46:21 -05:00
if ( from_outside_canvas & & ( ep = = EditAtMouse ) ) {
ep = EditAtPlayhead ;
} else if ( from_context_menu & & ( ep = = EditAtMouse ) ) {
2017-03-04 13:34:41 -05:00
return canvas_event_sample ( & context_click_event , 0 , 0 ) ;
2011-12-30 12:28:05 -05:00
}
2008-01-10 16:20:59 -05:00
if ( entered_marker ) {
2017-07-01 12:42:24 -04:00
DEBUG_TRACE ( DEBUG : : CutNPaste , string_compose ( " GPEP: use entered marker @ %1 \n " , entered_marker - > position ( ) ) ) ;
2008-01-10 16:20:59 -05:00
return entered_marker - > position ( ) ;
}
2018-02-24 07:54:15 -05:00
if ( ( ignore = = EDIT_IGNORE_PHEAD ) & & ep = = EditAtPlayhead ) {
2008-01-10 16:20:59 -05:00
ep = EditAtSelectedMarker ;
}
2018-02-24 07:54:15 -05:00
if ( ( ignore = = EDIT_IGNORE_MOUSE ) & & ep = = EditAtMouse ) {
2013-10-20 17:02:56 -04:00
ep = EditAtPlayhead ;
}
2017-09-18 12:39:17 -04:00
MusicSample snap_mf ( 0 , 0 ) ;
2017-01-26 08:41:17 -05:00
2008-01-10 16:20:59 -05:00
switch ( ep ) {
2007-11-07 20:40:25 -05:00
case EditAtPlayhead :
2018-02-27 14:08:40 -05:00
if ( _dragging_playhead ) {
/* NOTE: since the user is dragging with the mouse, this operation will implicitly be Snapped */
where = playhead_cursor - > current_sample ( ) ;
2015-02-03 14:33:22 -05:00
} else {
2017-09-18 12:39:17 -04:00
where = _session - > audible_sample ( ) ;
2015-02-03 14:33:22 -05:00
}
2017-07-01 12:42:24 -04:00
DEBUG_TRACE ( DEBUG : : CutNPaste , string_compose ( " GPEP: use playhead @ %1 \n " , where ) ) ;
2007-11-12 17:23:01 -05:00
break ;
2009-10-14 12:10:01 -04:00
2007-11-07 20:40:25 -05:00
case EditAtSelectedMarker :
if ( ! selection - > markers . empty ( ) ) {
2008-01-10 16:20:59 -05:00
bool is_start ;
Location * loc = find_location_from_marker ( selection - > markers . front ( ) , is_start ) ;
2007-11-07 20:40:25 -05:00
if ( loc ) {
2008-01-10 16:20:59 -05:00
if ( is_start ) {
where = loc - > start ( ) ;
} else {
where = loc - > end ( ) ;
}
2017-07-01 12:42:24 -04:00
DEBUG_TRACE ( DEBUG : : CutNPaste , string_compose ( " GPEP: use selected marker @ %1 \n " , where ) ) ;
2007-11-12 17:23:01 -05:00
break ;
2007-11-07 20:40:25 -05:00
}
2009-10-14 12:10:01 -04:00
}
2019-09-18 11:27:56 -04:00
/* fallthrough */
2009-10-14 12:10:01 -04:00
2007-11-07 20:40:25 -05:00
default :
case EditAtMouse :
2017-09-18 12:39:17 -04:00
if ( ! mouse_sample ( where , ignored ) ) {
2007-11-12 17:23:01 -05:00
/* XXX not right but what can we do ? */
return 0 ;
}
2017-09-18 12:39:17 -04:00
snap_mf . sample = where ;
2017-01-26 08:41:17 -05:00
snap_to ( snap_mf ) ;
2017-09-18 12:39:17 -04:00
where = snap_mf . sample ;
2017-07-01 12:42:24 -04:00
DEBUG_TRACE ( DEBUG : : CutNPaste , string_compose ( " GPEP: use mouse @ %1 \n " , where ) ) ;
2007-11-12 17:23:01 -05:00
break ;
2007-11-07 20:40:25 -05:00
}
2007-11-12 17:23:01 -05:00
return where ;
2007-11-07 20:40:25 -05:00
}
2007-10-11 18:07:47 -04:00
void
2017-09-18 12:39:17 -04:00
Editor : : set_loop_range ( samplepos_t start , samplepos_t end , string cmd )
2007-10-11 18:07:47 -04:00
{
2009-12-17 13:24:23 -05:00
if ( ! _session ) return ;
2007-10-11 18:07:47 -04:00
begin_reversible_command ( cmd ) ;
2009-10-14 12:10:01 -04:00
2007-10-11 18:07:47 -04:00
Location * tll ;
if ( ( tll = transport_loop_location ( ) ) = = 0 ) {
2016-12-28 09:39:31 -05:00
Location * loc = new Location ( * _session , start , end , _ ( " Loop " ) , Location : : IsAutoLoop , get_grid_music_divisions ( 0 ) ) ;
2009-12-17 13:24:23 -05:00
XMLNode & before = _session - > locations ( ) - > get_state ( ) ;
_session - > locations ( ) - > add ( loc , true ) ;
_session - > set_auto_loop_location ( loc ) ;
XMLNode & after = _session - > locations ( ) - > get_state ( ) ;
_session - > add_command ( new MementoCommand < Locations > ( * ( _session - > locations ( ) ) , & before , & after ) ) ;
2008-03-17 16:54:03 -04:00
} else {
2009-05-04 21:24:44 -04:00
XMLNode & before = tll - > get_state ( ) ;
2007-10-11 18:07:47 -04:00
tll - > set_hidden ( false , this ) ;
tll - > set ( start , end ) ;
2009-05-04 21:24:44 -04:00
XMLNode & after = tll - > get_state ( ) ;
2009-12-17 13:24:23 -05:00
_session - > add_command ( new MementoCommand < Location > ( * tll , & before , & after ) ) ;
2007-10-11 18:07:47 -04:00
}
2009-10-14 12:10:01 -04:00
2007-10-11 18:07:47 -04:00
commit_reversible_command ( ) ;
}
void
2017-09-18 12:39:17 -04:00
Editor : : set_punch_range ( samplepos_t start , samplepos_t end , string cmd )
2007-10-11 18:07:47 -04:00
{
2009-12-17 13:24:23 -05:00
if ( ! _session ) return ;
2007-10-11 18:07:47 -04:00
begin_reversible_command ( cmd ) ;
2009-10-14 12:10:01 -04:00
2007-10-11 18:07:47 -04:00
Location * tpl ;
if ( ( tpl = transport_punch_location ( ) ) = = 0 ) {
2016-12-28 09:39:31 -05:00
Location * loc = new Location ( * _session , start , end , _ ( " Punch " ) , Location : : IsAutoPunch , get_grid_music_divisions ( 0 ) ) ;
2009-12-17 13:24:23 -05:00
XMLNode & before = _session - > locations ( ) - > get_state ( ) ;
_session - > locations ( ) - > add ( loc , true ) ;
2014-01-27 21:27:13 -05:00
_session - > set_auto_punch_location ( loc ) ;
2009-12-17 13:24:23 -05:00
XMLNode & after = _session - > locations ( ) - > get_state ( ) ;
_session - > add_command ( new MementoCommand < Locations > ( * ( _session - > locations ( ) ) , & before , & after ) ) ;
2014-12-14 08:13:38 -05:00
} else {
2009-05-04 21:24:44 -04:00
XMLNode & before = tpl - > get_state ( ) ;
2007-10-11 18:07:47 -04:00
tpl - > set_hidden ( false , this ) ;
tpl - > set ( start , end ) ;
2009-05-04 21:24:44 -04:00
XMLNode & after = tpl - > get_state ( ) ;
2009-12-17 13:24:23 -05:00
_session - > add_command ( new MementoCommand < Location > ( * tpl , & before , & after ) ) ;
2007-10-11 18:07:47 -04:00
}
2009-10-14 12:10:01 -04:00
2007-10-11 18:07:47 -04:00
commit_reversible_command ( ) ;
}
2009-07-21 15:55:12 -04:00
/** Find regions which exist at a given time, and optionally on a given list of tracks.
* @ param rs List to which found regions are added .
* @ param where Time to look at .
* @ param ts Tracks to look on ; if this is empty , all tracks are examined .
*/
2008-02-16 17:43:18 -05:00
void
2017-09-18 12:39:17 -04:00
Editor : : get_regions_at ( RegionSelection & rs , samplepos_t where , const TrackViewList & ts ) const
2007-11-12 17:23:01 -05:00
{
2009-12-13 14:09:52 -05:00
const TrackViewList * tracks ;
2007-11-12 17:23:01 -05:00
if ( ts . empty ( ) ) {
tracks = & track_views ;
} else {
tracks = & ts ;
}
2009-12-13 14:09:52 -05:00
for ( TrackViewList : : const_iterator t = tracks - > begin ( ) ; t ! = tracks - > end ( ) ; + + t ) {
2011-01-19 13:35:11 -05:00
2009-07-09 13:58:13 -04:00
RouteTimeAxisView * rtv = dynamic_cast < RouteTimeAxisView * > ( * t ) ;
2011-01-19 13:35:11 -05:00
2009-02-16 02:04:27 -05:00
if ( rtv ) {
2010-04-21 16:42:22 -04:00
boost : : shared_ptr < Track > tr ;
2007-11-12 17:23:01 -05:00
boost : : shared_ptr < Playlist > pl ;
2009-10-14 12:10:01 -04:00
2010-04-21 16:42:22 -04:00
if ( ( tr = rtv - > track ( ) ) & & ( ( pl = tr - > playlist ( ) ) ) ) {
2007-11-12 17:23:01 -05:00
2017-04-17 06:12:49 -04:00
boost : : shared_ptr < RegionList > regions = pl - > regions_at ( where ) ;
2007-11-12 17:23:01 -05:00
2012-01-27 11:29:01 -05:00
for ( RegionList : : iterator i = regions - > begin ( ) ; i ! = regions - > end ( ) ; + + i ) {
2009-02-16 02:04:27 -05:00
RegionView * rv = rtv - > view ( ) - > find_view ( * i ) ;
2007-11-12 17:23:01 -05:00
if ( rv ) {
2008-09-10 11:03:30 -04:00
rs . add ( rv ) ;
2007-11-12 17:23:01 -05:00
}
}
}
}
}
}
2008-02-16 17:43:18 -05:00
void
2017-09-18 12:39:17 -04:00
Editor : : get_regions_after ( RegionSelection & rs , samplepos_t where , const TrackViewList & ts ) const
2008-01-10 16:20:59 -05:00
{
2009-12-13 14:09:52 -05:00
const TrackViewList * tracks ;
2008-01-10 16:20:59 -05:00
if ( ts . empty ( ) ) {
tracks = & track_views ;
} else {
tracks = & ts ;
}
2009-12-13 14:09:52 -05:00
for ( TrackViewList : : const_iterator t = tracks - > begin ( ) ; t ! = tracks - > end ( ) ; + + t ) {
2009-07-09 13:58:13 -04:00
RouteTimeAxisView * rtv = dynamic_cast < RouteTimeAxisView * > ( * t ) ;
2009-02-16 02:04:27 -05:00
if ( rtv ) {
2010-04-21 16:42:22 -04:00
boost : : shared_ptr < Track > tr ;
2008-01-10 16:20:59 -05:00
boost : : shared_ptr < Playlist > pl ;
2009-10-14 12:10:01 -04:00
2010-04-21 16:42:22 -04:00
if ( ( tr = rtv - > track ( ) ) & & ( ( pl = tr - > playlist ( ) ) ) ) {
2008-01-10 16:20:59 -05:00
2017-09-18 12:39:17 -04:00
boost : : shared_ptr < RegionList > regions = pl - > regions_touched ( where , max_samplepos ) ;
2008-01-10 16:20:59 -05:00
2012-01-27 11:29:01 -05:00
for ( RegionList : : iterator i = regions - > begin ( ) ; i ! = regions - > end ( ) ; + + i ) {
2008-01-10 16:20:59 -05:00
2009-02-16 02:04:27 -05:00
RegionView * rv = rtv - > view ( ) - > find_view ( * i ) ;
2008-01-10 16:20:59 -05:00
if ( rv ) {
2013-03-12 16:42:51 -04:00
rs . add ( rv ) ;
2008-01-10 16:20:59 -05:00
}
}
}
}
}
}
2010-12-29 21:21:12 -05:00
/** Get regions using the following method:
2010-10-19 18:08:39 -04:00
*
2014-07-05 21:47:43 -04:00
* Make a region list using :
* ( a ) any selected regions
* ( b ) the intersection of any selected tracks and the edit point ( * )
* ( c ) if neither exists , and edit_point = = mouse , then whatever region is under the mouse
2010-12-29 21:21:12 -05:00
*
2014-07-05 21:47:43 -04:00
* ( * ) NOTE : in this case , if ' No Selection = All Tracks ' is active , search all tracks
2010-12-29 21:21:12 -05:00
*
2014-07-05 21:47:43 -04:00
* Note that we have forced the rule that selected regions and selected tracks are mutually exclusive
2009-07-21 15:55:12 -04:00
*/
2010-10-19 20:19:09 -04:00
RegionSelection
2017-02-10 16:12:28 -05:00
Editor : : get_regions_from_selection_and_edit_point ( EditIgnoreOption ignore , bool from_context_menu , bool from_outside_canvas )
2007-11-12 17:23:01 -05:00
{
2010-12-29 21:21:12 -05:00
RegionSelection regions ;
2011-06-01 13:00:29 -04:00
2018-02-24 07:54:15 -05:00
if ( _edit_point = = EditAtMouse & & entered_regionview & & selection - > tracks . empty ( ) & & selection - > regions . empty ( ) ) {
2010-12-29 21:21:12 -05:00
regions . add ( entered_regionview ) ;
2014-07-03 15:48:20 -04:00
} else {
regions = selection - > regions ;
2010-10-19 18:08:39 -04:00
}
2009-10-14 12:10:01 -04:00
2018-02-24 07:54:15 -05:00
if ( regions . empty ( ) ) {
2013-04-05 17:16:33 -04:00
TrackViewList tracks = selection - > tracks ;
2008-02-16 17:43:18 -05:00
2013-04-05 17:16:33 -04:00
if ( ! tracks . empty ( ) ) {
/* no region selected or entered, but some selected tracks:
* act on all regions on the selected tracks at the edit point
2015-10-04 14:51:05 -04:00
*/
2017-09-18 12:39:17 -04:00
samplepos_t const where = get_preferred_edit_position ( ignore , from_context_menu , from_outside_canvas ) ;
2014-07-07 10:13:19 -04:00
get_regions_at ( regions , where , tracks ) ;
}
}
return regions ;
}
/** Get regions using the following method:
*
* Make a region list using :
* ( a ) any selected regions
* ( b ) the intersection of any selected tracks and the edit point ( * )
* ( c ) if neither exists , then whatever region is under the mouse
*
* ( * ) NOTE : in this case , if ' No Selection = All Tracks ' is active , search all tracks
*
* Note that we have forced the rule that selected regions and selected tracks are mutually exclusive
*/
RegionSelection
2017-09-18 12:39:17 -04:00
Editor : : get_regions_from_selection_and_mouse ( samplepos_t pos )
2014-07-07 10:13:19 -04:00
{
RegionSelection regions ;
2018-02-24 07:54:15 -05:00
if ( entered_regionview & & selection - > tracks . empty ( ) & & selection - > regions . empty ( ) ) {
2014-07-07 10:13:19 -04:00
regions . add ( entered_regionview ) ;
} else {
regions = selection - > regions ;
}
2018-02-24 07:54:15 -05:00
if ( regions . empty ( ) ) {
2014-07-07 10:13:19 -04:00
TrackViewList tracks = selection - > tracks ;
if ( ! tracks . empty ( ) ) {
/* no region selected or entered, but some selected tracks:
* act on all regions on the selected tracks at the edit point
2015-10-04 14:51:05 -04:00
*/
2014-07-07 10:21:47 -04:00
get_regions_at ( regions , pos , tracks ) ;
2012-05-27 15:36:27 -04:00
}
2008-02-16 17:43:18 -05:00
}
2014-07-05 21:47:43 -04:00
2010-12-29 21:21:12 -05:00
return regions ;
2007-11-12 17:23:01 -05:00
}
2008-01-10 16:20:59 -05:00
2011-01-19 13:35:11 -05:00
/** 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 .
*/
2010-11-03 18:19:29 -04:00
RegionSelection
2016-04-08 18:33:03 -04:00
Editor : : get_regions_from_selection_and_entered ( ) const
2010-11-03 18:19:29 -04:00
{
2011-01-19 13:35:11 -05:00
RegionSelection regions = selection - > regions ;
2011-06-01 13:00:29 -04:00
2011-01-19 13:35:11 -05:00
if ( regions . empty ( ) & & entered_regionview ) {
regions . add ( entered_regionview ) ;
2010-11-03 18:19:29 -04:00
}
2013-04-05 17:16:33 -04:00
return regions ;
2010-11-03 18:19:29 -04:00
}
2014-12-14 08:13:38 -05:00
void
2015-01-10 12:07:31 -05:00
Editor : : get_regionviews_by_id ( PBD : : ID const id , RegionSelection & regions ) const
2014-12-14 08:13:38 -05:00
{
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2015-01-10 12:07:31 -05:00
RouteTimeAxisView * rtav ;
2015-10-05 10:17:49 -04:00
2015-01-10 12:07:31 -05:00
if ( ( rtav = dynamic_cast < RouteTimeAxisView * > ( * i ) ) ! = 0 ) {
2014-12-14 08:13:38 -05:00
boost : : shared_ptr < Playlist > pl ;
std : : vector < boost : : shared_ptr < Region > > results ;
boost : : shared_ptr < Track > tr ;
2015-10-05 10:17:49 -04:00
2015-01-10 12:07:31 -05:00
if ( ( tr = rtav - > track ( ) ) = = 0 ) {
2014-12-14 08:13:38 -05:00
/* bus */
continue ;
}
2015-10-05 10:17:49 -04:00
2014-12-14 08:13:38 -05:00
if ( ( pl = ( tr - > playlist ( ) ) ) ! = 0 ) {
boost : : shared_ptr < Region > r = pl - > region_by_id ( id ) ;
if ( r ) {
2015-01-10 12:07:31 -05:00
RegionView * rv = rtav - > view ( ) - > find_view ( r ) ;
if ( rv ) {
regions . push_back ( rv ) ;
2014-12-14 08:13:38 -05:00
}
}
}
}
}
}
2015-01-10 12:07:31 -05:00
void
2017-09-24 12:03:54 -04:00
Editor : : get_per_region_note_selection ( list < pair < PBD : : ID , set < boost : : shared_ptr < Evoral : : Note < Temporal : : Beats > > > > > & selection ) const
2015-01-10 12:07:31 -05:00
{
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
MidiTimeAxisView * mtav ;
2015-01-10 20:55:48 -05:00
2015-01-10 12:07:31 -05:00
if ( ( mtav = dynamic_cast < MidiTimeAxisView * > ( * i ) ) ! = 0 ) {
mtav - > get_per_region_note_selection ( selection ) ;
}
}
2015-10-05 10:17:49 -04:00
2015-01-10 12:07:31 -05:00
}
2008-01-10 16:20:59 -05:00
void
2013-01-04 17:46:51 -05:00
Editor : : get_regions_corresponding_to ( boost : : shared_ptr < Region > region , vector < RegionView * > & regions , bool src_comparison )
2008-01-10 16:20:59 -05:00
{
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2009-10-14 12:10:01 -04:00
2009-07-09 13:58:13 -04:00
RouteTimeAxisView * tatv ;
2009-10-14 12:10:01 -04:00
2009-07-09 13:58:13 -04:00
if ( ( tatv = dynamic_cast < RouteTimeAxisView * > ( * i ) ) ! = 0 ) {
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
boost : : shared_ptr < Playlist > pl ;
vector < boost : : shared_ptr < Region > > results ;
RegionView * marv ;
2010-04-21 16:42:22 -04:00
boost : : shared_ptr < Track > tr ;
2009-10-14 12:10:01 -04:00
2010-04-21 16:42:22 -04:00
if ( ( tr = tatv - > track ( ) ) = = 0 ) {
2008-01-10 16:20:59 -05:00
/* bus */
continue ;
}
2009-10-14 12:10:01 -04:00
2010-04-21 16:42:22 -04:00
if ( ( pl = ( tr - > playlist ( ) ) ) ! = 0 ) {
2013-01-04 17:46:51 -05:00
if ( src_comparison ) {
pl - > get_source_equivalent_regions ( region , results ) ;
} else {
pl - > get_region_list_equivalent_regions ( region , results ) ;
}
2008-01-10 16:20:59 -05:00
}
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
for ( vector < boost : : shared_ptr < Region > > : : iterator ir = results . begin ( ) ; ir ! = results . end ( ) ; + + ir ) {
if ( ( marv = tatv - > view ( ) - > find_view ( * ir ) ) ! = 0 ) {
regions . push_back ( marv ) ;
}
}
2009-10-14 12:10:01 -04:00
2008-01-10 16:20:59 -05:00
}
}
2009-10-14 12:10:01 -04:00
}
2008-02-01 22:57:35 -05:00
2017-02-23 16:31:03 -05:00
RegionView *
2017-02-24 07:03:24 -05:00
Editor : : regionview_from_region ( boost : : shared_ptr < Region > region ) const
2017-02-23 16:31:03 -05:00
{
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
RouteTimeAxisView * tatv ;
if ( ( tatv = dynamic_cast < RouteTimeAxisView * > ( * i ) ) ! = 0 ) {
if ( ! tatv - > track ( ) ) {
continue ;
}
RegionView * marv = tatv - > view ( ) - > find_view ( region ) ;
if ( marv ) {
return marv ;
}
}
}
return NULL ;
}
2017-02-24 07:03:24 -05:00
RouteTimeAxisView *
Editor : : rtav_from_route ( boost : : shared_ptr < Route > route ) const
{
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
RouteTimeAxisView * rtav ;
if ( ( rtav = dynamic_cast < RouteTimeAxisView * > ( * i ) ) ! = 0 ) {
if ( rtav - > route ( ) = = route ) {
return rtav ;
}
}
}
return NULL ;
}
2008-02-01 22:57:35 -05:00
void
Editor : : show_rhythm_ferret ( )
{
if ( rhythm_ferret = = 0 ) {
rhythm_ferret = new RhythmFerret ( * this ) ;
}
2009-12-17 13:24:23 -05:00
rhythm_ferret - > set_session ( _session ) ;
2008-02-01 22:57:35 -05:00
rhythm_ferret - > show ( ) ;
rhythm_ferret - > present ( ) ;
}
2008-03-17 16:54:03 -04:00
void
Editor : : first_idle ( )
{
2020-01-15 16:01:30 -05:00
ArdourMessageDialog * dialog = 0 ;
2015-10-05 10:17:49 -04:00
2009-10-14 12:10:01 -04:00
if ( track_views . size ( ) > 1 ) {
2015-10-30 10:54:54 -04:00
Timers : : TimerSuspender t ;
2020-01-15 16:01:30 -05:00
dialog = new ArdourMessageDialog (
2011-11-15 08:30:55 -05:00
string_compose ( _ ( " Please wait while %1 loads visual data. " ) , PROGRAM_NAME ) ,
true
2011-11-14 21:06:09 -05:00
) ;
2008-03-17 16:54:03 -04:00
dialog - > present ( ) ;
2016-07-25 08:51:23 -04:00
ARDOUR_UI : : instance ( ) - > flush_pending ( 60 ) ;
2008-03-17 16:54:03 -04:00
}
for ( TrackViewList : : iterator t = track_views . begin ( ) ; t ! = track_views . end ( ) ; + + t ) {
( * t ) - > first_idle ( ) ;
}
2008-12-12 09:43:24 -05:00
2017-04-01 11:14:06 -04:00
/* now that all regionviews should exist, setup region selection */
RegionSelection rs ;
for ( list < PBD : : ID > : : iterator pr = selection - > regions . pending . begin ( ) ; pr ! = selection - > regions . pending . end ( ) ; + + pr ) {
/* this is cumulative: rs is NOT cleared each time */
get_regionviews_by_id ( * pr , rs ) ;
}
selection - > set ( rs ) ;
2018-02-24 07:54:15 -05:00
/* first idle adds route children (automation tracks), so we need to redisplay here */
2009-07-03 14:37:15 -04:00
_routes - > redisplay ( ) ;
2009-10-14 12:10:01 -04:00
2011-11-15 08:30:55 -05:00
delete dialog ;
2014-12-22 08:30:23 -05:00
2014-12-22 12:52:29 -05:00
if ( _session - > undo_depth ( ) = = 0 ) {
undo_action - > set_sensitive ( false ) ;
}
redo_action - > set_sensitive ( false ) ;
2014-12-22 08:30:23 -05:00
begin_selection_op_history ( ) ;
2008-03-17 16:54:03 -04:00
_have_idled = true ;
}
2008-09-10 11:03:30 -04:00
2010-03-18 22:49:01 -04:00
gboolean
Editor : : _idle_resize ( gpointer arg )
2008-09-10 11:03:30 -04:00
{
2009-06-17 18:08:51 -04:00
return ( ( Editor * ) arg ) - > idle_resize ( ) ;
2008-09-10 11:03:30 -04:00
}
void
2009-07-09 13:58:13 -04:00
Editor : : add_to_idle_resize ( TimeAxisView * view , int32_t h )
2008-09-10 11:03:30 -04:00
{
2009-06-17 18:08:51 -04:00
if ( resize_idle_id < 0 ) {
2014-10-21 07:20:17 -04:00
/* https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#G-PRIORITY-HIGH-IDLE:CAPS
* GTK + uses G_PRIORITY_HIGH_IDLE + 10 for resizing operations , and G_PRIORITY_HIGH_IDLE + 20 for redrawing operations .
* ( This is done to ensure that any pending resizes are processed before any pending redraws , so that widgets are not redrawn twice unnecessarily . )
*/
resize_idle_id = g_idle_add_full ( G_PRIORITY_HIGH_IDLE + 10 , _idle_resize , this , NULL ) ;
2009-06-17 18:43:27 -04:00
_pending_resize_amount = 0 ;
2008-09-10 11:03:30 -04:00
}
2009-06-17 18:08:51 -04:00
/* make a note of the smallest resulting height, so that we can clamp the
lower limit at TimeAxisView : : hSmall */
2008-09-10 11:03:30 -04:00
2009-06-17 18:08:51 -04:00
int32_t min_resulting = INT32_MAX ;
2008-09-10 11:03:30 -04:00
2009-06-17 18:43:27 -04:00
_pending_resize_amount + = h ;
_pending_resize_view = view ;
min_resulting = min ( min_resulting , int32_t ( _pending_resize_view - > current_height ( ) ) + _pending_resize_amount ) ;
2009-06-26 10:06:49 -04:00
if ( selection - > tracks . contains ( _pending_resize_view ) ) {
2009-12-13 14:09:52 -05:00
for ( TrackViewList : : iterator i = selection - > tracks . begin ( ) ; i ! = selection - > tracks . end ( ) ; + + i ) {
2009-06-26 10:06:49 -04:00
min_resulting = min ( min_resulting , int32_t ( ( * i ) - > current_height ( ) ) + _pending_resize_amount ) ;
}
2008-09-10 11:03:30 -04:00
}
2009-06-17 18:08:51 -04:00
if ( min_resulting < 0 ) {
min_resulting = 0 ;
}
2008-09-10 11:03:30 -04:00
2009-06-17 18:08:51 -04:00
/* clamp */
2010-05-10 20:09:41 -04:00
if ( uint32_t ( min_resulting ) < TimeAxisView : : preset_height ( HeightSmall ) ) {
_pending_resize_amount + = TimeAxisView : : preset_height ( HeightSmall ) - min_resulting ;
2008-09-10 11:03:30 -04:00
}
}
2009-06-17 18:08:51 -04:00
/** Handle pending resizing of tracks */
2008-09-10 11:03:30 -04:00
bool
Editor : : idle_resize ( )
{
2009-06-17 18:43:27 -04:00
_pending_resize_view - > idle_resize ( _pending_resize_view - > current_height ( ) + _pending_resize_amount ) ;
2009-06-26 08:18:57 -04:00
2009-07-09 13:58:13 -04:00
if ( dynamic_cast < AutomationTimeAxisView * > ( _pending_resize_view ) = = 0 & &
2009-06-26 10:06:49 -04:00
selection - > tracks . contains ( _pending_resize_view ) ) {
2009-10-14 12:10:01 -04:00
2009-12-13 14:09:52 -05:00
for ( TrackViewList : : iterator i = selection - > tracks . begin ( ) ; i ! = selection - > tracks . end ( ) ; + + i ) {
2009-06-26 08:18:57 -04:00
if ( * i ! = _pending_resize_view ) {
( * i ) - > idle_resize ( ( * i ) - > current_height ( ) + _pending_resize_amount ) ;
}
}
2008-09-10 11:03:30 -04:00
}
2009-10-14 12:10:01 -04:00
2010-11-25 15:37:39 -05:00
_pending_resize_amount = 0 ;
2009-06-23 18:13:05 -04:00
_group_tabs - > set_dirty ( ) ;
2008-09-10 11:03:30 -04:00
resize_idle_id = - 1 ;
2009-10-14 12:10:01 -04:00
2008-09-10 11:03:30 -04:00
return false ;
}
2009-02-16 19:12:22 -05:00
void
Editor : : located ( )
{
2010-01-05 20:37:38 -05:00
ENSURE_GUI_THREAD ( * this , & Editor : : located ) ;
2009-02-16 19:12:22 -05:00
2012-10-10 11:19:58 -04:00
if ( _session ) {
2017-09-18 12:39:17 -04:00
playhead_cursor - > set_position ( _session - > audible_sample ( ) ) ;
2012-10-10 11:19:58 -04:00
if ( _follow_playhead & & ! _pending_initial_locate ) {
reset_x_origin_to_follow_playhead ( ) ;
}
2010-02-07 20:25:06 -05:00
}
2009-02-16 19:12:22 -05:00
_pending_locate_request = false ;
2010-02-07 20:25:06 -05:00
_pending_initial_locate = false ;
2017-03-31 08:11:49 -04:00
_last_update_time = 0 ;
2009-02-16 19:12:22 -05:00
}
2009-06-10 21:05:01 -04:00
void
2014-12-14 08:13:38 -05:00
Editor : : region_view_added ( RegionView * rv )
2009-06-10 21:05:01 -04:00
{
2015-01-10 12:07:31 -05:00
MidiRegionView * mrv = dynamic_cast < MidiRegionView * > ( rv ) ;
if ( mrv ) {
2016-10-15 08:50:02 -04:00
list < pair < PBD : : ID const , list < Evoral : : event_id_t > > > : : iterator rnote ;
2015-01-10 12:07:31 -05:00
for ( rnote = selection - > pending_midi_note_selection . begin ( ) ; rnote ! = selection - > pending_midi_note_selection . end ( ) ; + + rnote ) {
if ( rv - > region ( ) - > id ( ) = = ( * rnote ) . first ) {
mrv - > select_notes ( ( * rnote ) . second ) ;
selection - > pending_midi_note_selection . erase ( rnote ) ;
break ;
}
}
}
2014-06-17 07:44:36 -04:00
_summary - > set_background_dirty ( ) ;
2018-02-09 10:59:39 -05:00
mark_region_boundary_cache_dirty ( ) ;
2009-06-10 21:05:01 -04:00
}
2009-06-13 13:52:51 -04:00
2011-01-30 08:24:41 -05:00
void
Editor : : region_view_removed ( )
{
2014-06-17 07:44:36 -04:00
_summary - > set_background_dirty ( ) ;
2018-02-09 10:59:39 -05:00
mark_region_boundary_cache_dirty ( ) ;
2011-01-30 08:24:41 -05:00
}
2017-05-05 07:31:49 -04:00
AxisView *
Editor : : axis_view_by_stripable ( boost : : shared_ptr < Stripable > s ) const
2009-07-17 09:18:58 -04:00
{
2016-07-06 13:37:30 -04:00
for ( TrackViewList : : const_iterator j = track_views . begin ( ) ; j ! = track_views . end ( ) ; + + j ) {
if ( ( * j ) - > stripable ( ) = = s ) {
return * j ;
2009-07-17 09:18:58 -04:00
}
}
return 0 ;
}
2017-05-05 07:31:49 -04:00
AxisView *
Editor : : axis_view_by_control ( boost : : shared_ptr < AutomationControl > c ) const
{
for ( TrackViewList : : const_iterator j = track_views . begin ( ) ; j ! = track_views . end ( ) ; + + j ) {
if ( ( * j ) - > control ( ) = = c ) {
return * j ;
}
2017-05-05 13:06:51 -04:00
TimeAxisView : : Children kids = ( * j ) - > get_child_list ( ) ;
for ( TimeAxisView : : Children : : iterator k = kids . begin ( ) ; k ! = kids . end ( ) ; + + k ) {
if ( ( * k ) - > control ( ) = = c ) {
return ( * k ) . get ( ) ;
}
}
2017-05-05 07:31:49 -04:00
}
return 0 ;
}
2009-07-17 09:18:58 -04:00
2009-12-13 14:09:52 -05:00
TrackViewList
2009-12-09 22:25:32 -05:00
Editor : : axis_views_from_routes ( boost : : shared_ptr < RouteList > r ) const
2009-06-21 15:59:56 -04:00
{
2009-12-13 14:09:52 -05:00
TrackViewList t ;
2009-10-14 12:10:01 -04:00
2009-12-09 22:25:32 -05:00
for ( RouteList : : const_iterator i = r - > begin ( ) ; i ! = r - > end ( ) ; + + i ) {
2017-05-05 07:31:49 -04:00
TimeAxisView * tv = time_axis_view_from_stripable ( * i ) ;
2009-07-17 09:18:58 -04:00
if ( tv ) {
t . push_back ( tv ) ;
2009-06-21 15:59:56 -04:00
}
}
return t ;
}
2014-06-28 17:22:15 -04:00
void
Editor : : suspend_route_redisplay ( )
{
if ( _routes ) {
_routes - > suspend_redisplay ( ) ;
}
}
void
Editor : : resume_route_redisplay ( )
{
if ( _routes ) {
2015-04-30 12:28:27 -04:00
_routes - > redisplay ( ) ; // queue redisplay
2014-06-28 17:22:15 -04:00
_routes - > resume_redisplay ( ) ;
}
}
2016-05-21 16:36:08 -04:00
void
2016-06-03 15:15:30 -04:00
Editor : : add_vcas ( VCAList & vlist )
2016-05-21 16:36:08 -04:00
{
2016-06-03 15:15:30 -04:00
StripableList sl ;
2016-05-21 16:36:08 -04:00
2016-06-03 15:15:30 -04:00
for ( VCAList : : iterator v = vlist . begin ( ) ; v ! = vlist . end ( ) ; + + v ) {
sl . push_back ( boost : : dynamic_pointer_cast < Stripable > ( * v ) ) ;
2016-05-21 16:36:08 -04:00
}
2016-06-03 15:15:30 -04:00
add_stripables ( sl ) ;
2016-05-21 16:36:08 -04:00
}
2009-07-01 19:20:18 -04:00
void
2016-06-03 15:15:30 -04:00
Editor : : add_routes ( RouteList & rlist )
2009-07-01 19:20:18 -04:00
{
2016-06-03 15:15:30 -04:00
StripableList sl ;
for ( RouteList : : iterator r = rlist . begin ( ) ; r ! = rlist . end ( ) ; + + r ) {
sl . push_back ( * r ) ;
}
add_stripables ( sl ) ;
}
2009-10-14 12:10:01 -04:00
2016-06-03 15:15:30 -04:00
void
Editor : : add_stripables ( StripableList & sl )
{
list < TimeAxisView * > new_views ;
boost : : shared_ptr < VCA > v ;
boost : : shared_ptr < Route > r ;
2015-03-12 11:47:16 -04:00
TrackViewList new_selection ;
bool from_scratch = ( track_views . size ( ) = = 0 ) ;
2009-07-01 19:20:18 -04:00
2017-06-16 17:45:16 -04:00
sl . sort ( Stripable : : Sorter ( ) ) ;
2016-06-05 15:59:00 -04:00
2016-06-03 15:15:30 -04:00
for ( StripableList : : iterator s = sl . begin ( ) ; s ! = sl . end ( ) ; + + s ) {
2009-07-01 19:20:18 -04:00
2019-08-26 22:01:19 -04:00
if ( ( * s ) - > is_foldbackbus ( ) ) {
continue ;
}
2016-06-03 15:15:30 -04:00
if ( ( v = boost : : dynamic_pointer_cast < VCA > ( * s ) ) ! = 0 ) {
2009-07-01 19:20:18 -04:00
2016-06-03 15:15:30 -04:00
VCATimeAxisView * vtv = new VCATimeAxisView ( * this , _session , * _track_canvas ) ;
vtv - > set_vca ( v ) ;
new_views . push_back ( vtv ) ;
2009-07-01 19:20:18 -04:00
2016-06-03 15:15:30 -04:00
} else if ( ( r = boost : : dynamic_pointer_cast < Route > ( * s ) ) ! = 0 ) {
if ( r - > is_auditioner ( ) | | r - > is_monitor ( ) ) {
continue ;
}
2009-07-01 19:20:18 -04:00
2016-06-03 15:15:30 -04:00
RouteTimeAxisView * rtv ;
DataType dt = r - > input ( ) - > default_type ( ) ;
2009-10-14 12:10:01 -04:00
2016-06-03 15:15:30 -04:00
if ( dt = = ARDOUR : : DataType : : AUDIO ) {
rtv = new AudioTimeAxisView ( * this , _session , * _track_canvas ) ;
rtv - > set_route ( r ) ;
} else if ( dt = = ARDOUR : : DataType : : MIDI ) {
rtv = new MidiTimeAxisView ( * this , _session , * _track_canvas ) ;
rtv - > set_route ( r ) ;
} else {
throw unknown_type ( ) ;
}
2009-10-14 12:10:01 -04:00
2016-06-03 15:15:30 -04:00
new_views . push_back ( rtv ) ;
track_views . push_back ( rtv ) ;
new_selection . push_back ( rtv ) ;
rtv - > effective_gain_display ( ) ;
rtv - > view ( ) - > RegionViewAdded . connect ( sigc : : mem_fun ( * this , & Editor : : region_view_added ) ) ;
rtv - > view ( ) - > RegionViewRemoved . connect ( sigc : : mem_fun ( * this , & Editor : : region_view_removed ) ) ;
}
2009-07-01 19:20:18 -04:00
}
2013-12-28 10:15:00 -05:00
if ( new_views . size ( ) > 0 ) {
2016-06-03 15:15:30 -04:00
_routes - > time_axis_views_added ( new_views ) ;
//_summary->routes_added (new_selection); /* XXX requires RouteTimeAxisViewList */
2013-12-28 10:15:00 -05:00
}
2009-07-01 19:20:18 -04:00
2016-06-03 15:15:30 -04:00
/* note: !new_selection.empty() means that we got some routes rather
* than just VCAs
*/
if ( ! from_scratch & & ! new_selection . empty ( ) ) {
2017-03-26 10:12:10 -04:00
selection - > set ( new_selection ) ;
2015-03-12 11:47:16 -04:00
begin_selection_op_history ( ) ;
}
2016-06-03 15:15:30 -04:00
if ( show_editor_mixer_when_tracks_arrive & & ! new_selection . empty ( ) ) {
2009-07-01 19:20:18 -04:00
show_editor_mixer ( true ) ;
}
editor_list_button . set_sensitive ( true ) ;
}
void
2009-12-25 16:06:52 -05:00
Editor : : timeaxisview_deleted ( TimeAxisView * tv )
2009-07-01 19:20:18 -04:00
{
2014-06-30 12:31:01 -04:00
if ( tv = = entered_track ) {
entered_track = 0 ;
}
2009-12-25 16:06:52 -05:00
if ( _session & & _session - > deletion_in_progress ( ) ) {
/* the situation is under control */
2009-12-22 19:33:03 -05:00
return ;
}
2009-11-09 18:43:13 -05:00
2009-12-25 16:06:52 -05:00
ENSURE_GUI_THREAD ( * this , & Editor : : timeaxisview_deleted , tv ) ;
2009-07-01 19:20:18 -04:00
2019-08-24 12:21:08 -04:00
if ( dynamic_cast < AutomationTimeAxisView * > ( tv ) ) {
selection - > remove ( tv ) ;
return ;
}
2010-08-09 10:11:24 -04:00
RouteTimeAxisView * rtav = dynamic_cast < RouteTimeAxisView * > ( tv ) ;
2011-06-01 13:00:29 -04:00
2009-12-22 15:21:43 -05:00
_routes - > route_removed ( tv ) ;
2010-08-09 13:27:56 -04:00
TimeAxisView : : Children c = tv - > get_child_list ( ) ;
for ( TimeAxisView : : Children : : const_iterator i = c . begin ( ) ; i ! = c . end ( ) ; + + i ) {
if ( entered_track = = i - > get ( ) ) {
entered_track = 0 ;
2010-08-09 10:11:24 -04:00
}
}
2009-12-25 16:06:52 -05:00
/* remove it from the list of track views */
TrackViewList : : iterator i ;
if ( ( i = find ( track_views . begin ( ) , track_views . end ( ) , tv ) ) ! = track_views . end ( ) ) {
i = track_views . erase ( i ) ;
2009-07-01 19:20:18 -04:00
}
2009-10-14 12:10:01 -04:00
2019-08-24 12:37:28 -04:00
/* Update the route that is shown in the editor-mixer. */
if ( ! rtav ) {
return ;
2011-06-01 13:00:29 -04:00
}
2009-12-25 16:06:52 -05:00
2019-08-24 12:37:28 -04:00
boost : : shared_ptr < Route > route = rtav - > route ( ) ;
2009-12-25 16:06:52 -05:00
if ( current_mixer_strip & & current_mixer_strip - > route ( ) = = route ) {
TimeAxisView * next_tv ;
2009-12-22 15:21:43 -05:00
2009-12-25 16:06:52 -05:00
if ( track_views . empty ( ) ) {
next_tv = 0 ;
} else if ( i = = track_views . end ( ) ) {
next_tv = track_views . front ( ) ;
} else {
next_tv = ( * i ) ;
}
2011-06-01 13:00:29 -04:00
2017-01-13 02:43:18 -05:00
// skip VCAs (cannot be selected, n/a in editor-mixer)
if ( dynamic_cast < VCATimeAxisView * > ( next_tv ) ) {
/* VCAs are sorted last in line -- route_sorter.h, jump to top */
next_tv = track_views . front ( ) ;
}
if ( dynamic_cast < VCATimeAxisView * > ( next_tv ) ) {
/* just in case: no master, only a VCA remains */
next_tv = 0 ;
}
2011-06-01 13:00:29 -04:00
2009-12-25 16:06:52 -05:00
if ( next_tv ) {
set_selected_mixer_strip ( * next_tv ) ;
} else {
/* make the editor mixer strip go away setting the
* button to inactive ( which also unticks the menu option )
*/
2011-06-01 13:00:29 -04:00
2019-03-20 14:15:47 -04:00
ActionManager : : uncheck_toggleaction ( " Editor/show-editor-mixer " ) ;
2009-12-25 16:06:52 -05:00
}
2011-06-01 13:00:29 -04:00
}
2009-07-01 19:20:18 -04:00
}
void
2011-03-07 08:05:45 -05:00
Editor : : hide_track_in_display ( TimeAxisView * tv , bool apply_to_selection )
2009-07-01 19:20:18 -04:00
{
2017-02-24 07:03:24 -05:00
if ( ! tv ) {
return ;
}
2017-09-11 12:30:32 -04:00
DisplaySuspender ds ;
PresentationInfo : : ChangeSuspender cs ;
2011-03-07 08:05:45 -05:00
if ( apply_to_selection ) {
2018-02-24 07:54:15 -05:00
for ( TrackSelection : : iterator i = selection - > tracks . begin ( ) ; i ! = selection - > tracks . end ( ) ; ) {
2009-07-01 19:20:18 -04:00
2011-03-07 08:05:45 -05:00
TrackSelection : : iterator j = i ;
+ + j ;
2011-06-01 13:00:29 -04:00
2011-03-07 08:05:45 -05:00
hide_track_in_display ( * i , false ) ;
2011-06-01 13:00:29 -04:00
2011-03-07 08:05:45 -05:00
i = j ;
}
} else {
RouteTimeAxisView * rtv = dynamic_cast < RouteTimeAxisView * > ( tv ) ;
2011-06-01 13:00:29 -04:00
2011-03-07 08:05:45 -05:00
if ( rtv & & current_mixer_strip & & ( rtv - > route ( ) = = current_mixer_strip - > route ( ) ) ) {
2018-02-24 07:54:15 -05:00
/* this will hide the mixer strip */
2011-03-07 08:05:45 -05:00
set_selected_mixer_strip ( * tv ) ;
}
2011-06-01 13:00:29 -04:00
2011-03-07 08:05:45 -05:00
_routes - > hide_track_in_display ( * tv ) ;
2009-07-01 19:20:18 -04:00
}
}
2017-02-24 07:03:24 -05:00
void
Editor : : show_track_in_display ( TimeAxisView * tv , bool move_into_view )
{
if ( ! tv ) {
return ;
}
_routes - > show_track_in_display ( * tv ) ;
if ( move_into_view ) {
ensure_time_axis_view_is_visible ( * tv , false ) ;
}
}
2009-07-01 19:20:18 -04:00
bool
2009-07-03 14:37:15 -04:00
Editor : : sync_track_view_list_and_routes ( )
2009-07-01 19:20:18 -04:00
{
2009-12-13 14:09:52 -05:00
track_views = TrackViewList ( _routes - > views ( ) ) ;
2009-10-14 12:10:01 -04:00
2015-08-08 09:58:44 -04:00
_summary - > set_background_dirty ( ) ;
2009-07-01 19:20:18 -04:00
_group_tabs - > set_dirty ( ) ;
2009-10-14 12:10:01 -04:00
2009-07-01 19:20:18 -04:00
return false ; // do not call again (until needed)
}
void
2009-07-09 13:58:13 -04:00
Editor : : foreach_time_axis_view ( sigc : : slot < void , TimeAxisView & > theslot )
2009-07-01 19:20:18 -04:00
{
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2009-07-09 13:58:13 -04:00
theslot ( * * i ) ;
2009-07-01 19:20:18 -04:00
}
}
2017-08-06 16:16:36 -04:00
/** Find a StripableTimeAxisView by the ID of its stripable */
StripableTimeAxisView *
Editor : : get_stripable_time_axis_by_id ( const PBD : : ID & id ) const
2009-07-01 19:20:18 -04:00
{
2017-08-06 16:16:36 -04:00
StripableTimeAxisView * v ;
2009-07-01 19:20:18 -04:00
2010-08-17 22:20:15 -04:00
for ( TrackViewList : : const_iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
2017-08-06 16:16:36 -04:00
if ( ( v = dynamic_cast < StripableTimeAxisView * > ( * i ) ) ! = 0 ) {
if ( v - > stripable ( ) - > id ( ) = = id ) {
2009-07-01 19:20:18 -04:00
return v ;
}
}
}
2009-07-09 13:58:13 -04:00
return 0 ;
2009-07-01 19:20:18 -04:00
}
2009-07-03 14:37:15 -04:00
void
Editor : : fit_route_group ( RouteGroup * g )
{
2009-12-13 14:09:52 -05:00
TrackViewList ts = axis_views_from_routes ( g - > route_list ( ) ) ;
2009-07-03 14:37:15 -04:00
fit_tracks ( ts ) ;
}
2009-07-03 18:42:22 -04:00
void
Editor : : consider_auditioning ( boost : : shared_ptr < Region > region )
{
boost : : shared_ptr < AudioRegion > r = boost : : dynamic_pointer_cast < AudioRegion > ( region ) ;
if ( r = = 0 ) {
2009-12-17 13:24:23 -05:00
_session - > cancel_audition ( ) ;
2009-07-03 18:42:22 -04:00
return ;
}
2009-12-17 13:24:23 -05:00
if ( _session - > is_auditioning ( ) ) {
_session - > cancel_audition ( ) ;
2009-07-03 18:42:22 -04:00
if ( r = = last_audition_region ) {
return ;
}
}
2009-12-17 13:24:23 -05:00
_session - > audition_region ( r ) ;
2009-07-03 18:42:22 -04:00
last_audition_region = r ;
}
void
Editor : : hide_a_region ( boost : : shared_ptr < Region > r )
{
r - > set_hidden ( true ) ;
}
void
2010-03-30 21:11:48 -04:00
Editor : : show_a_region ( boost : : shared_ptr < Region > r )
2009-07-03 18:42:22 -04:00
{
2010-03-30 21:11:48 -04:00
r - > set_hidden ( false ) ;
2009-07-03 18:42:22 -04:00
}
void
Editor : : audition_region_from_region_list ( )
{
2009-12-11 18:29:48 -05:00
_regions - > selection_mapover ( sigc : : mem_fun ( * this , & Editor : : consider_auditioning ) ) ;
2009-07-03 18:42:22 -04:00
}
2010-07-24 12:40:56 -04:00
void
Editor : : step_edit_status_change ( bool yn )
{
2010-11-25 15:37:39 -05:00
if ( yn ) {
start_step_editing ( ) ;
} else {
stop_step_editing ( ) ;
}
2010-07-24 12:40:56 -04:00
}
2009-09-05 10:11:48 -04:00
void
Editor : : start_step_editing ( )
{
2009-12-11 18:29:48 -05:00
step_edit_connection = Glib : : signal_timeout ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : check_step_edit ) , 20 ) ;
2009-09-05 10:11:48 -04:00
}
void
Editor : : stop_step_editing ( )
{
step_edit_connection . disconnect ( ) ;
}
bool
Editor : : check_step_edit ( )
{
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
MidiTimeAxisView * mtv = dynamic_cast < MidiTimeAxisView * > ( * i ) ;
if ( mtv ) {
mtv - > check_step_edit ( ) ;
}
}
return true ; // do it again, till we stop
}
2009-11-30 23:10:06 -05:00
2010-06-16 20:02:45 -04:00
bool
2011-03-01 19:30:19 -05:00
Editor : : scroll_press ( Direction dir )
2009-11-30 23:10:06 -05:00
{
2010-06-16 20:02:45 -04:00
+ + _scroll_callbacks ;
2011-06-01 13:00:29 -04:00
2010-06-16 20:02:45 -04:00
if ( _scroll_connection . connected ( ) & & _scroll_callbacks < 5 ) {
/* delay the first auto-repeat */
return true ;
}
2011-03-01 19:30:19 -05:00
switch ( dir ) {
case LEFT :
scroll_backward ( 1 ) ;
break ;
2010-06-16 20:02:45 -04:00
2011-03-01 19:30:19 -05:00
case RIGHT :
scroll_forward ( 1 ) ;
break ;
2009-11-30 23:10:06 -05:00
2011-03-01 19:30:19 -05:00
case UP :
2014-07-14 12:35:44 -04:00
scroll_up_one_track ( ) ;
2011-03-01 19:30:19 -05:00
break ;
2010-06-16 20:02:45 -04:00
2011-03-01 19:30:19 -05:00
case DOWN :
2014-07-14 12:35:44 -04:00
scroll_down_one_track ( ) ;
2011-03-01 19:30:19 -05:00
break ;
2010-06-16 20:02:45 -04:00
}
/* do hacky auto-repeat */
if ( ! _scroll_connection . connected ( ) ) {
2011-03-01 19:30:19 -05:00
_scroll_connection = Glib : : signal_timeout ( ) . connect (
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : scroll_press ) , dir ) , 100
) ;
2011-06-01 13:00:29 -04:00
2010-06-16 20:02:45 -04:00
_scroll_callbacks = 0 ;
}
return true ;
}
void
2011-03-01 19:30:19 -05:00
Editor : : scroll_release ( )
2010-06-16 20:02:45 -04:00
{
_scroll_connection . disconnect ( ) ;
2009-11-30 23:10:06 -05:00
}
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
/** Queue a change for the Editor viewport x origin to follow the playhead */
2010-02-07 18:11:17 -05:00
void
2010-02-07 20:25:06 -05:00
Editor : : reset_x_origin_to_follow_playhead ( )
2010-02-07 18:11:17 -05:00
{
2017-09-18 12:39:17 -04:00
samplepos_t const sample = playhead_cursor - > current_sample ( ) ;
2010-02-07 18:11:17 -05:00
2017-09-18 12:39:17 -04:00
if ( sample < _leftmost_sample | | sample > _leftmost_sample + current_page_samples ( ) ) {
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
if ( _session - > transport_speed ( ) < 0 ) {
2011-06-01 13:00:29 -04:00
2017-09-18 12:39:17 -04:00
if ( sample > ( current_page_samples ( ) / 2 ) ) {
center_screen ( sample - ( current_page_samples ( ) / 2 ) ) ;
2010-02-07 20:25:06 -05:00
} else {
2013-04-12 11:21:12 -04:00
center_screen ( current_page_samples ( ) / 2 ) ;
2010-02-07 20:25:06 -05:00
}
2011-06-01 13:00:29 -04:00
2010-02-07 20:25:06 -05:00
} else {
2011-06-01 13:00:29 -04:00
2017-09-18 12:39:17 -04:00
samplepos_t l = 0 ;
2015-10-05 10:17:49 -04:00
2017-09-18 12:39:17 -04:00
if ( sample < _leftmost_sample ) {
2010-02-07 20:25:06 -05:00
/* moving left */
if ( _session - > transport_rolling ( ) ) {
/* rolling; end up with the playhead at the right of the page */
2017-09-18 12:39:17 -04:00
l = sample - current_page_samples ( ) ;
2010-02-07 20:25:06 -05:00
} else {
2012-01-31 14:24:26 -05:00
/* not rolling: end up with the playhead 1/4 of the way along the page */
2017-09-18 12:39:17 -04:00
l = sample - current_page_samples ( ) / 4 ;
2010-02-07 20:25:06 -05:00
}
} else {
/* moving right */
if ( _session - > transport_rolling ( ) ) {
/* rolling: end up with the playhead on the left of the page */
2017-09-18 12:39:17 -04:00
l = sample ;
2010-02-07 20:25:06 -05:00
} else {
2012-01-31 14:24:26 -05:00
/* not rolling: end up with the playhead 3/4 of the way along the page */
2017-09-18 12:39:17 -04:00
l = sample - 3 * current_page_samples ( ) / 4 ;
2010-02-07 20:25:06 -05:00
}
}
2012-01-31 14:24:26 -05:00
if ( l < 0 ) {
l = 0 ;
}
2015-10-05 10:17:49 -04:00
2013-04-12 11:21:12 -04:00
center_screen_internal ( l + ( current_page_samples ( ) / 2 ) , current_page_samples ( ) ) ;
2010-02-07 18:11:17 -05:00
}
2010-02-07 20:25:06 -05:00
}
}
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
void
Editor : : super_rapid_screen_update ( )
{
if ( ! _session | | ! _session - > engine ( ) . running ( ) ) {
return ;
}
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
/* METERING / MIXER STRIPS */
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
/* update track meters, if required */
2015-07-07 22:12:21 -04:00
if ( contents ( ) . is_mapped ( ) & & meters_running ) {
2010-02-07 20:25:06 -05:00
RouteTimeAxisView * rtv ;
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
if ( ( rtv = dynamic_cast < RouteTimeAxisView * > ( * i ) ) ! = 0 ) {
rtv - > fast_update ( ) ;
}
}
}
2010-02-07 18:11:17 -05:00
2010-02-07 20:25:06 -05:00
/* and any current mixer strip */
if ( current_mixer_strip ) {
current_mixer_strip - > fast_update ( ) ;
}
2010-02-07 18:11:17 -05:00
2017-03-31 08:11:49 -04:00
bool latent_locate = false ;
2017-09-18 12:39:17 -04:00
samplepos_t sample = _session - > audible_sample ( & latent_locate ) ;
2017-03-23 14:21:50 -04:00
const int64_t now = g_get_monotonic_time ( ) ;
double err = 0 ;
2010-02-07 18:11:17 -05:00
2017-06-29 12:40:51 -04:00
if ( _session - > exporting ( ) ) {
/* freewheel/export may be faster or slower than transport_speed() / SR.
* Also exporting multiple ranges locates / jumps without a _pending_locate_request .
*/
_last_update_time = 0 ;
}
2018-11-10 21:38:34 -05:00
if ( ! _session - > transport_rolling ( ) | | _session - > is_auditioning ( ) ) {
2018-02-24 06:55:48 -05:00
/* Do not interpolate the playhead position; just set it */
2018-02-23 14:48:29 -05:00
_last_update_time = 0 ;
}
2017-03-23 14:21:50 -04:00
if ( _last_update_time > 0 ) {
2017-06-29 12:40:51 -04:00
/* interpolate and smoothen playhead position */
2017-09-18 12:39:17 -04:00
const double ds = ( now - _last_update_time ) * _session - > transport_speed ( ) * _session - > nominal_sample_rate ( ) * 1e-6 ;
samplepos_t guess = playhead_cursor - > current_sample ( ) + rint ( ds ) ;
err = sample - guess ;
2010-02-07 18:11:17 -05:00
2017-03-23 14:21:50 -04:00
guess + = err * .12 + _err_screen_engine ; // time-constant based on 25fps (super_rapid_screen_update)
_err_screen_engine + = .0144 * ( err - _err_screen_engine ) ; // tc^2
2010-02-07 18:11:17 -05:00
2017-03-23 14:21:50 -04:00
#if 0 // DEBUG
printf ( " eng: %ld gui:%ld (%+6.1f) diff: %6.1f (err: %7.2f) \n " ,
2017-09-18 12:39:17 -04:00
sample , guess , ds ,
2017-03-23 14:21:50 -04:00
err , _err_screen_engine ) ;
# endif
2010-02-07 18:11:17 -05:00
2017-09-18 12:39:17 -04:00
sample = guess ;
2017-03-23 14:21:50 -04:00
} else {
_err_screen_engine = 0 ;
}
2011-06-01 13:00:29 -04:00
2017-03-31 08:11:49 -04:00
if ( err > 8192 | | latent_locate ) {
2017-03-23 14:21:50 -04:00
// in case of x-runs or freewheeling
_last_update_time = 0 ;
2017-09-18 12:39:17 -04:00
sample = _session - > audible_sample ( ) ;
2017-03-23 14:21:50 -04:00
} else {
_last_update_time = now ;
}
2018-02-09 10:59:39 -05:00
2018-02-24 07:54:15 -05:00
/* snapped cursor stuff (the snapped_cursor shows where an operation is going to occur) */
2018-02-09 09:21:45 -05:00
bool ignored ;
MusicSample where ( sample , 0 ) ;
2018-02-24 07:54:15 -05:00
if ( ! UIConfiguration : : instance ( ) . get_show_snapped_cursor ( ) ) {
2018-02-09 09:21:45 -05:00
snapped_cursor - > hide ( ) ;
2018-02-24 07:54:15 -05:00
} else if ( _edit_point = = EditAtPlayhead & & ! _dragging_playhead ) {
2018-02-27 14:08:40 -05:00
/* EditAtPlayhead does not snap */
2018-02-24 07:54:15 -05:00
} else if ( _edit_point = = EditAtSelectedMarker ) {
/* NOTE: I don't think EditAtSelectedMarker should snap. They are what they are.
* however , the current editing code - does - snap so I ' ll draw it that way for now .
*/
if ( ! selection - > markers . empty ( ) ) {
2018-02-09 14:43:20 -05:00
MusicSample ms ( selection - > markers . front ( ) - > position ( ) , 0 ) ;
2018-02-24 07:54:15 -05:00
snap_to ( ms ) ; // should use snap_to_with_modifier?
snapped_cursor - > set_position ( ms . sample ) ;
2018-02-09 14:43:20 -05:00
snapped_cursor - > show ( ) ;
}
2020-04-01 16:54:00 -04:00
} else if ( _edit_point = = EditAtMouse & & mouse_sample ( where . sample , ignored ) ) {
/* cursor is in the editing canvas. show it. */
2018-02-09 09:21:45 -05:00
snapped_cursor - > show ( ) ;
2020-04-01 16:54:00 -04:00
} else {
/* mouse is out of the editing canvas, or edit-point isn't mouse. Hide the snapped_cursor */
2018-02-09 09:21:45 -05:00
snapped_cursor - > hide ( ) ;
}
2018-02-09 10:59:39 -05:00
2018-02-09 09:21:45 -05:00
/* There are a few reasons why we might not update the playhead / viewport stuff:
*
* 1. we don ' t update things when there ' s a pending locate request , otherwise
* when the editor requests a locate there is a chance that this method
* will move the playhead before the locate request is processed , causing
* a visual glitch .
* 2. if we ' re not rolling , there ' s nothing to do here ( locates are handled elsewhere ) .
* 3. if we ' re still at the same frame that we were last time , there ' s nothing to do .
*/
if ( _pending_locate_request ) {
_last_update_time = 0 ;
return ;
}
if ( _dragging_playhead ) {
_last_update_time = 0 ;
return ;
}
2011-06-01 13:00:29 -04:00
2017-09-18 12:39:17 -04:00
if ( playhead_cursor - > current_sample ( ) = = sample ) {
2017-03-23 14:21:50 -04:00
return ;
}
2020-03-25 20:35:28 -04:00
if ( ! _pending_locate_request ) {
playhead_cursor - > set_position ( sample ) ;
}
2017-03-23 14:21:50 -04:00
2017-09-18 12:39:17 -04:00
if ( _session - > requested_return_sample ( ) > = 0 ) {
2017-03-23 14:21:50 -04:00
_last_update_time = 0 ;
return ;
}
if ( ! _follow_playhead | | pending_visual_change . being_handled ) {
/* We only do this if we aren't already
* handling a visual change ( ie if
* pending_visual_change . being_handled is
* false ) so that these requests don ' t stack
* up there are too many of them to handle in
* time .
*/
return ;
}
2011-06-01 13:00:29 -04:00
2017-03-23 14:21:50 -04:00
if ( ! _stationary_playhead ) {
reset_x_origin_to_follow_playhead ( ) ;
} else {
2017-09-18 12:39:17 -04:00
samplepos_t const sample = playhead_cursor - > current_sample ( ) ;
double target = ( ( double ) sample - ( double ) current_page_samples ( ) / 2.0 ) ;
2017-03-23 14:21:50 -04:00
if ( target < = 0.0 ) {
target = 0.0 ;
}
2018-02-24 07:54:15 -05:00
/* compare to EditorCursor::set_position() */
2017-09-18 12:39:17 -04:00
double const old_pos = sample_to_pixel_unrounded ( _leftmost_sample ) ;
2017-03-23 14:21:50 -04:00
double const new_pos = sample_to_pixel_unrounded ( target ) ;
if ( rint ( new_pos ) ! = rint ( old_pos ) ) {
reset_x_origin ( pixel_to_sample ( new_pos ) ) ;
}
2010-02-07 18:11:17 -05:00
}
}
void
Editor : : session_going_away ( )
{
_have_idled = false ;
_session_connections . drop_connections ( ) ;
2010-02-07 20:25:06 -05:00
super_rapid_screen_update_connection . disconnect ( ) ;
2011-06-01 13:00:29 -04:00
2010-02-07 18:11:17 -05:00
selection - > clear ( ) ;
cut_buffer - > clear ( ) ;
clicked_regionview = 0 ;
clicked_axisview = 0 ;
clicked_routeview = 0 ;
entered_regionview = 0 ;
entered_track = 0 ;
2017-03-23 14:21:50 -04:00
_last_update_time = 0 ;
2010-02-07 18:11:17 -05:00
_drags - > abort ( ) ;
2013-04-04 00:32:52 -04:00
playhead_cursor - > hide ( ) ;
2010-02-07 18:11:17 -05:00
/* rip everything out of the list displays */
_regions - > clear ( ) ;
2018-11-15 10:21:55 -05:00
_sources - > clear ( ) ;
2010-02-07 18:11:17 -05:00
_routes - > clear ( ) ;
_route_groups - > clear ( ) ;
/* do this first so that deleting a track doesn't reset cms to null
and thus cause a leak .
*/
if ( current_mixer_strip ) {
if ( current_mixer_strip - > get_parent ( ) ! = 0 ) {
global_hpacker . remove ( * current_mixer_strip ) ;
}
delete current_mixer_strip ;
current_mixer_strip = 0 ;
}
/* delete all trackviews */
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
delete * i ;
}
track_views . clear ( ) ;
2011-06-02 13:50:37 -04:00
nudge_clock - > set_session ( 0 ) ;
2010-02-07 18:11:17 -05:00
editor_list_button . set_active ( false ) ;
editor_list_button . set_sensitive ( false ) ;
/* clear tempo/meter rulers */
remove_metric_marks ( ) ;
clear_marker_display ( ) ;
2018-02-09 10:59:39 -05:00
hide_grid_lines ( ) ;
delete grid_lines ;
grid_lines = 0 ;
2017-06-08 11:08:59 -04:00
2012-10-10 11:19:58 -04:00
stop_step_editing ( ) ;
2015-10-05 10:17:49 -04:00
2015-07-07 22:12:21 -04:00
if ( own_window ( ) ) {
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
/* get rid of any existing editor mixer strip */
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
WindowTitle title ( Glib : : get_application_name ( ) ) ;
title + = _ ( " Editor " ) ;
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
own_window ( ) - > set_title ( title . get_string ( ) ) ;
}
2010-02-07 18:11:17 -05:00
SessionHandlePtr : : session_going_away ( ) ;
}
2016-02-23 09:42:53 -05:00
void
Editor : : trigger_script ( int i )
{
LuaInstance : : instance ( ) - > call_action ( i ) ;
}
2010-02-07 18:11:17 -05:00
void
Editor : : show_editor_list ( bool yn )
{
if ( yn ) {
2016-12-22 21:56:01 -05:00
_editor_list_vbox . show ( ) ;
2010-02-07 18:11:17 -05:00
} else {
2016-12-22 21:56:01 -05:00
_editor_list_vbox . hide ( ) ;
2010-02-07 18:11:17 -05:00
}
}
2010-07-24 12:40:56 -04:00
2010-08-25 15:28:33 -04:00
void
2011-12-26 18:38:56 -05:00
Editor : : change_region_layering_order ( bool from_context_menu )
2010-08-25 15:28:33 -04:00
{
2017-09-18 12:39:17 -04:00
const samplepos_t position = get_preferred_edit_position ( EDIT_IGNORE_NONE , from_context_menu ) ;
2011-06-01 13:00:29 -04:00
2010-11-25 15:37:39 -05:00
if ( ! clicked_routeview ) {
if ( layering_order_editor ) {
layering_order_editor - > hide ( ) ;
}
2010-08-25 15:28:33 -04:00
return ;
}
2010-11-25 15:37:39 -05:00
boost : : shared_ptr < Track > track = boost : : dynamic_pointer_cast < Track > ( clicked_routeview - > route ( ) ) ;
2010-08-25 15:28:33 -04:00
2010-11-25 15:37:39 -05:00
if ( ! track ) {
return ;
}
2010-08-25 15:28:33 -04:00
boost : : shared_ptr < Playlist > pl = track - > playlist ( ) ;
if ( ! pl ) {
2010-11-25 15:37:39 -05:00
return ;
}
2011-06-01 13:00:29 -04:00
2010-11-25 15:37:39 -05:00
if ( layering_order_editor = = 0 ) {
2011-12-26 18:38:56 -05:00
layering_order_editor = new RegionLayeringOrderEditor ( * this ) ;
2010-11-25 15:37:39 -05:00
}
2010-08-25 15:28:33 -04:00
2012-01-23 20:31:42 -05:00
layering_order_editor - > set_context ( clicked_routeview - > name ( ) , _session , clicked_routeview , pl , position ) ;
2010-11-25 15:37:39 -05:00
layering_order_editor - > maybe_present ( ) ;
2010-08-25 15:28:33 -04:00
}
void
2010-11-03 18:19:29 -04:00
Editor : : update_region_layering_order_editor ( )
2010-08-25 15:28:33 -04:00
{
if ( layering_order_editor & & layering_order_editor - > is_visible ( ) ) {
2011-12-26 18:38:56 -05:00
change_region_layering_order ( true ) ;
2010-08-25 15:28:33 -04:00
}
}
2010-09-18 23:31:03 -04:00
void
Editor : : setup_fade_images ( )
{
2014-05-28 13:46:31 -04:00
_xfade_in_images [ FadeLinear ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadein-linear " ) ) ) ;
2014-05-28 16:20:28 -04:00
_xfade_in_images [ FadeSymmetric ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadein-symmetric " ) ) ) ;
_xfade_in_images [ FadeFast ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadein-fast-cut " ) ) ) ;
_xfade_in_images [ FadeSlow ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadein-slow-cut " ) ) ) ;
_xfade_in_images [ FadeConstantPower ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadein-constant-power " ) ) ) ;
2012-05-11 17:30:36 -04:00
_xfade_out_images [ FadeLinear ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadeout-linear " ) ) ) ;
2014-05-28 16:20:28 -04:00
_xfade_out_images [ FadeSymmetric ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadeout-symmetric " ) ) ) ;
_xfade_out_images [ FadeFast ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadeout-fast-cut " ) ) ) ;
_xfade_out_images [ FadeSlow ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadeout-slow-cut " ) ) ) ;
_xfade_out_images [ FadeConstantPower ] = new Gtk : : Image ( get_icon_path ( X_ ( " fadeout-constant-power " ) ) ) ;
2012-05-10 15:14:11 -04:00
2010-09-18 23:31:03 -04:00
}
2010-11-03 18:19:29 -04:00
/** @return Gtk::manage()d menu item for a given action from `editor_actions' */
Gtk : : MenuItem &
Editor : : action_menu_item ( std : : string const & name )
{
2010-11-14 11:49:25 -05:00
Glib : : RefPtr < Action > a = editor_actions - > get_action ( name ) ;
assert ( a ) ;
2011-06-01 13:00:29 -04:00
2010-11-14 11:49:25 -05:00
return * manage ( a - > create_menu_item ( ) ) ;
2010-11-03 18:19:29 -04:00
}
2010-11-10 13:29:32 -05:00
2011-01-04 21:06:51 -05:00
void
Editor : : add_notebook_page ( string const & name , Gtk : : Widget & widget )
{
EventBox * b = manage ( new EventBox ) ;
b - > signal_button_press_event ( ) . connect ( sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : notebook_tab_clicked ) , & widget ) ) ;
Label * l = manage ( new Label ( name ) ) ;
l - > set_angle ( - 90 ) ;
b - > add ( * l ) ;
b - > show_all ( ) ;
_the_notebook . append_page ( widget , * b ) ;
}
bool
Editor : : notebook_tab_clicked ( GdkEventButton * ev , Gtk : : Widget * page )
{
if ( ev - > type = = GDK_BUTTON_PRESS | | ev - > type = = GDK_2BUTTON_PRESS ) {
_the_notebook . set_current_page ( _the_notebook . page_num ( * page ) ) ;
}
if ( ev - > type = = GDK_2BUTTON_PRESS ) {
/* double-click on a notebook tab shrinks or expands the notebook */
if ( _notebook_shrunk ) {
2012-01-24 22:03:25 -05:00
if ( pre_notebook_shrink_pane_width ) {
2016-05-26 10:46:28 -04:00
edit_pane . set_divider ( 0 , * pre_notebook_shrink_pane_width ) ;
2012-01-24 22:03:25 -05:00
}
2011-01-04 21:06:51 -05:00
_notebook_shrunk = false ;
} else {
2016-05-26 10:46:28 -04:00
pre_notebook_shrink_pane_width = edit_pane . get_divider ( ) ;
2012-01-24 22:03:25 -05:00
/* this expands the LHS of the edit pane to cover the notebook
PAGE but leaves the tabs visible .
*/
2016-05-26 10:46:28 -04:00
edit_pane . set_divider ( 0 , edit_pane . get_divider ( ) + page - > get_width ( ) ) ;
2011-01-04 21:06:51 -05:00
_notebook_shrunk = true ;
}
}
return true ;
}
2011-01-29 09:48:59 -05:00
2011-07-17 16:10:31 -04:00
void
Editor : : popup_control_point_context_menu ( ArdourCanvas : : Item * item , GdkEvent * event )
{
using namespace Menu_Helpers ;
2015-10-05 10:17:49 -04:00
2011-07-17 16:10:31 -04:00
MenuList & items = _control_point_context_menu . items ( ) ;
items . clear ( ) ;
2015-10-05 10:17:49 -04:00
2011-07-17 16:10:31 -04:00
items . push_back ( MenuElem ( _ ( " Edit... " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_control_point ) , item ) ) ) ;
items . push_back ( MenuElem ( _ ( " Delete " ) , sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : remove_control_point ) , item ) ) ) ;
if ( ! can_remove_control_point ( item ) ) {
items . back ( ) . set_sensitive ( false ) ;
}
_control_point_context_menu . popup ( event - > button . button , event - > button . time ) ;
}
2011-11-15 14:33:09 -05:00
2014-12-25 15:32:10 -05:00
void
Editor : : popup_note_context_menu ( ArdourCanvas : : Item * item , GdkEvent * event )
{
using namespace Menu_Helpers ;
NoteBase * note = reinterpret_cast < NoteBase * > ( item - > get_data ( " notebase " ) ) ;
if ( ! note ) {
return ;
}
/* We need to get the selection here and pass it to the operations, since
popping up the menu will cause a region leave event which clears
entered_regionview . */
MidiRegionView & mrv = note - > region_view ( ) ;
const RegionSelection rs = get_regions_from_selection_and_entered ( ) ;
2015-10-31 14:22:55 -04:00
const uint32_t sel_size = mrv . selection_size ( ) ;
2014-12-25 15:32:10 -05:00
MenuList & items = _note_context_menu . items ( ) ;
items . clear ( ) ;
2015-10-31 14:22:55 -04:00
if ( sel_size > 0 ) {
items . push_back ( MenuElem ( _ ( " Delete " ) ,
sigc : : mem_fun ( mrv , & MidiRegionView : : delete_selection ) ) ) ;
}
2015-10-31 15:06:31 -04:00
items . push_back ( MenuElem ( _ ( " Edit... " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : edit_notes ) , & mrv ) ) ) ;
if ( sel_size ! = 1 ) {
items . back ( ) . set_sensitive ( false ) ;
2015-10-31 14:22:55 -04:00
}
2015-10-15 09:44:09 -04:00
items . push_back ( MenuElem ( _ ( " Transpose... " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : transpose_regions ) , rs ) ) ) ;
2015-10-31 14:22:55 -04:00
2015-10-31 15:06:31 -04:00
items . push_back ( MenuElem ( _ ( " Legatize " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : legatize_regions ) , rs , false ) ) ) ;
if ( sel_size < 2 ) {
items . back ( ) . set_sensitive ( false ) ;
2015-10-31 14:22:55 -04:00
}
2014-12-25 15:32:10 -05:00
items . push_back ( MenuElem ( _ ( " Quantize... " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : quantize_regions ) , rs ) ) ) ;
2015-10-31 14:22:55 -04:00
2015-10-31 15:06:31 -04:00
items . push_back ( MenuElem ( _ ( " Remove Overlap " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : legatize_regions ) , rs , true ) ) ) ;
if ( sel_size < 2 ) {
items . back ( ) . set_sensitive ( false ) ;
2015-10-31 14:22:55 -04:00
}
2014-12-28 15:50:57 -05:00
items . push_back ( MenuElem ( _ ( " Transform... " ) ,
sigc : : bind ( sigc : : mem_fun ( * this , & Editor : : transform_regions ) , rs ) ) ) ;
2014-12-25 15:32:10 -05:00
_note_context_menu . popup ( event - > button . button , event - > button . time ) ;
}
2012-06-17 12:57:21 -04:00
void
2013-07-23 11:15:23 -04:00
Editor : : zoom_vertical_modifier_released ( )
2012-06-17 12:57:21 -04:00
{
_stepping_axis_view = 0 ;
}
2014-06-10 14:39:08 -04:00
void
Editor : : ui_parameter_changed ( string parameter )
{
if ( parameter = = " icon-set " ) {
2014-06-13 17:15:23 -04:00
while ( ! _cursor_stack . empty ( ) ) {
2014-12-20 01:11:28 -05:00
_cursor_stack . pop_back ( ) ;
2014-06-13 17:15:23 -04:00
}
2015-01-02 09:44:54 -05:00
_cursors - > set_cursor_set ( UIConfiguration : : instance ( ) . get_icon_set ( ) ) ;
2014-12-20 01:11:28 -05:00
_cursor_stack . push_back ( _cursors - > grabber ) ;
2016-05-27 12:59:07 -04:00
edit_pane . set_drag_cursor ( * _cursors - > expand_left_right ) ;
editor_summary_pane . set_drag_cursor ( * _cursors - > expand_up_down ) ;
2014-06-30 16:32:38 -04:00
} else if ( parameter = = " draggable-playhead " ) {
if ( _verbose_cursor ) {
2015-01-02 09:44:54 -05:00
playhead_cursor - > set_sensitive ( UIConfiguration : : instance ( ) . get_draggable_playhead ( ) ) ;
2014-06-30 16:32:38 -04:00
}
2018-07-03 15:39:28 -04:00
} else if ( parameter = = " use-note-bars-for-velocity " ) {
ArdourCanvas : : Note : : set_show_velocity_bars ( UIConfiguration : : instance ( ) . get_use_note_bars_for_velocity ( ) ) ;
_track_canvas - > request_redraw ( _track_canvas - > visible_area ( ) ) ;
2018-07-03 17:02:20 -04:00
} else if ( parameter = = " use-note-color-for-velocity " ) {
2018-07-03 18:33:11 -04:00
/* handled individually by each MidiRegionView */
2014-06-10 14:39:08 -04:00
}
}
2015-07-07 22:12:21 -04:00
Gtk : : Window *
2015-07-09 12:40:51 -04:00
Editor : : use_own_window ( bool and_fill_it )
2015-07-07 22:12:21 -04:00
{
bool new_window = ! own_window ( ) ;
2015-10-26 14:35:06 -04:00
2015-07-09 12:40:51 -04:00
Gtk : : Window * win = Tabbable : : use_own_window ( and_fill_it ) ;
2015-07-07 22:12:21 -04:00
if ( win & & new_window ) {
win - > set_name ( " EditorWindow " ) ;
ARDOUR_UI : : instance ( ) - > setup_toplevel_window ( * win , _ ( " Editor " ) , this ) ;
// win->signal_realize().connect (*this, &Editor::on_realize);
2016-02-22 14:42:40 -05:00
win - > signal_event ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( & Keyboard : : catch_user_event_for_pre_dialog_focus ) , win ) ) ;
2015-07-07 22:12:21 -04:00
win - > signal_event ( ) . connect ( sigc : : mem_fun ( * this , & Editor : : generic_event_handler ) ) ;
2015-08-10 14:31:59 -04:00
win - > set_data ( " ardour-bindings " , bindings ) ;
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
update_title ( ) ;
}
DisplaySuspender ds ;
contents ( ) . show_all ( ) ;
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
/* XXX: this is a bit unfortunate; it would probably
be nicer if we could just call show ( ) above rather
than needing the show_all ( )
*/
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
/* re-hide stuff if necessary */
editor_list_button_toggled ( ) ;
parameter_changed ( " show-summary " ) ;
parameter_changed ( " show-group-tabs " ) ;
parameter_changed ( " show-zoom-tools " ) ;
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
/* now reset all audio_time_axis heights, because widgets might need
to be re - hidden
*/
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
TimeAxisView * tv ;
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
for ( TrackViewList : : iterator i = track_views . begin ( ) ; i ! = track_views . end ( ) ; + + i ) {
tv = ( static_cast < TimeAxisView * > ( * i ) ) ;
tv - > reset_height ( ) ;
}
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
if ( current_mixer_strip ) {
current_mixer_strip - > hide_things ( ) ;
current_mixer_strip - > parameter_changed ( " mixer-element-visibility " ) ;
}
2015-10-26 14:35:06 -04:00
2015-07-07 22:12:21 -04:00
return win ;
}