diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-03-17 20:54:03 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-03-17 20:54:03 +0000 |
commit | 997e4b1f9cd7ccfc704b7c035051da7f60d831e7 (patch) | |
tree | 1236e40183b677abf4a2882e4cfe8e0a345eb24d /gtk2_ardour | |
parent | 19a4b990325577fc949ccd5d5fbad4520eb1df56 (diff) |
merge with 2.0-ongoing @ rev 3147
git-svn-id: svn://localhost/ardour2/branches/3.0@3152 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
83 files changed, 2273 insertions, 755 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 0d145e9a82..473ba61b08 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -36,6 +36,7 @@ gtkardour.Merge ([ libraries['fftw3'], libraries['fftw3f'], libraries['flac'], + libraries['freetype2'], libraries['gdkmm2'], libraries['glib2'], libraries['glibmm2'], @@ -410,12 +411,12 @@ if gtkardour['GTKOSX'] and gtkardour['NATIVE_OSX_KEYS']: keybindings_dict['%WINDOW%'] = 'Mod1' else: # - # Ctrl, Alt, Shift, Mod3(Meta) + # Ctrl, Alt, Shift, Mod4(Super/Windows/Hyper) # keybindings_dict['%PRIMARY%'] = 'Ctrl' keybindings_dict['%SECONDARY%'] = 'Alt' keybindings_dict['%TERTIARY%'] = 'Shift' - keybindings_dict['%LEVEL4%'] = 'Mod2' + keybindings_dict['%LEVEL4%'] = env['WINDOWS_KEY'] keybindings_dict['%WINDOW%'] = 'Alt' for b in [ 'SAE-de', 'mnemonic-us', 'ergonomic-us' ]: @@ -472,9 +473,41 @@ env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour3'), 'SAE-de env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3'), 'splash.png')) env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'pixmaps'), pixmap_files)) env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'ardour3', 'icons'), icon_files)) - env.Alias ('version', gtkardour.VersionBuild(['version.cc','version.h'], [])) - + +# This will install icons and MIME type as per freedesktop.org specs. # +if env['FREEDESKTOP']: + desktop_icon_install_prefix = install_prefix + '/share/icons/hicolor' + # Install the desktop icons to the default locations # + env.Alias('install', env.InstallAs(os.path.join(desktop_icon_install_prefix, '16x16', 'apps', 'ardour2.png'), 'icons/ardour_icon_16px.png')) + env.Alias('install', env.InstallAs(os.path.join(desktop_icon_install_prefix, '22x22', 'apps', 'ardour2.png'), 'icons/ardour_icon_22px.png')) + env.Alias('install', env.InstallAs(os.path.join(desktop_icon_install_prefix, '32x32', 'apps', 'ardour2.png'), 'icons/ardour_icon_32px.png')) + env.Alias('install', env.InstallAs(os.path.join(desktop_icon_install_prefix, '48x48', 'apps', 'ardour2.png'), 'icons/ardour_icon_48px.png')) + # Install the mime type xml file and its icon # + env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'mime', 'packages'), 'ardour2.xml')) + env.Alias('install', env.Install(os.path.join(desktop_icon_install_prefix, '48x48', 'mimetypes'), 'icons/application-x-ardour2.png')) + env.Alias('install', env.Command (os.path.join(install_prefix, 'share', 'mime'), [], 'update-mime-database $TARGET')) + # Update the icon cache # + env.Alias('install', env.Command (desktop_icon_install_prefix, [], 'touch --no-create $TARGET')) + env.Alias('install', env.Command (desktop_icon_install_prefix, [], 'gtk-update-icon-cache $TARGET')) + # Make the ardour2.desktop file and install it # + env.Alias('install', env.Command ('ardour2.desktop', 'ardour2.desktop.in', 'cat $SOURCES > $TARGET')) + env.Alias('install', env.Install(os.path.join(install_prefix, 'share', 'applications'), 'ardour2.desktop')) + env.Alias('install', env.Command (os.path.join(install_prefix, 'share', 'applications'), [], 'update-desktop-database $TARGET')) + # uninstall target.. needed to run update-mime-database and update-desktop-database after removal. #` + remove_desktop_files = env.Command ('another_frobnicatory_decoy', [], + [ Delete (install_prefix + '/share/mime/packages/ardour2.xml'), + Delete (install_prefix + '/share/applications/ardour2.desktop'), + Delete (desktop_icon_install_prefix + '/16x16/apps/ardour2.png'), + Delete (desktop_icon_install_prefix + '/22x22/apps/ardour2.png'), + Delete (desktop_icon_install_prefix + '/32x32/apps/ardour2.png'), + Delete (desktop_icon_install_prefix + '/48x48/apps/ardour2.png'), + Delete (desktop_icon_install_prefix + '/48x48/mimetypes/application-x-ardour2.png'), + Action ('update-mime-database ' + install_prefix + '/share/mime'), + Action ('gtk-update-icon-cache ' + desktop_icon_install_prefix), + Action ('update-desktop-database ' + install_prefix + '/share/applications')]) + env.Alias('uninstall', remove_desktop_files) + #dist env.Alias ('tarball', env.Distribute (env['DISTTREE'], [ 'SConscript', @@ -488,7 +521,9 @@ env.Alias ('tarball', env.Distribute (env['DISTTREE'], 'ardour-sae-ansi.bindings.in', 'ardour-sae-de.bindings.in', 'ardour3_ui_default.conf', - 'editor_xpms' + 'editor_xpms', + 'ardour2.xml', + 'ardour2.desktop.in' ] + gtkardour_files + vst_files + diff --git a/gtk2_ardour/about.cc b/gtk2_ardour/about.cc index a76fc3c619..9a1c0d0d45 100644 --- a/gtk2_ardour/about.cc +++ b/gtk2_ardour/about.cc @@ -158,6 +158,7 @@ static const char* authors[] = { N_("Colin Fletcher"), N_("Roland Stigge"), N_("Audun Halland"), + N_("Armand Klenk"), 0 }; diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc index 708d92ee56..8f84febbba 100644 --- a/gtk2_ardour/analysis_window.cc +++ b/gtk2_ardour/analysis_window.cc @@ -41,9 +41,8 @@ using namespace ARDOUR; using namespace PBD; -AnalysisWindow::AnalysisWindow() - : ArdourDialog(_("analysis window")), - +AnalysisWindow::AnalysisWindow() : + source_selection_label (_("Signal source")), source_selection_ranges_rb (_("Selected ranges")), source_selection_regions_rb (_("Selected regions")), @@ -51,9 +50,15 @@ AnalysisWindow::AnalysisWindow() display_model_label (_("Display model")), display_model_composite_separate_rb (_("Composite graphs for each track")), display_model_composite_all_tracks_rb (_("Composite graph of all tracks")), + + show_minmax_button (_("Show frequency power range")), + show_normalized_button (_("Normalize values")), - fft_graph (2048) + fft_graph (16384) { + set_name(_("FFT analysis window")); + set_title(_("FFT analysis window")); + track_list_ready = false; // Left side: track list + controls @@ -124,17 +129,31 @@ AnalysisWindow::AnalysisWindow() bind ( mem_fun(*this, &AnalysisWindow::display_model_changed), &display_model_composite_all_tracks_rb)); } - vbox.pack_start(hseparator2, false, false); + // Analyze button refresh_button.set_name("EditorGTKButton"); - refresh_button.set_label(_("Analyze data")); + refresh_button.set_label(_("Re-analyze data")); refresh_button.signal_clicked().connect ( bind ( mem_fun(*this, &AnalysisWindow::analyze_data), &refresh_button)); vbox.pack_start(refresh_button, false, false, 10); + + + // Feature checkboxes + + // minmax + show_minmax_button.signal_toggled().connect( mem_fun(*this, &AnalysisWindow::show_minmax_changed)); + vbox.pack_start(show_minmax_button, false, false); + + // normalize + show_normalized_button.signal_toggled().connect( mem_fun(*this, &AnalysisWindow::show_normalized_changed)); + vbox.pack_start(show_normalized_button, false, false); + + - hbox.pack_start(vbox); + + hbox.pack_start(vbox, Gtk::PACK_SHRINK); // Analysis window on the right fft_graph.ensure_style(); @@ -144,22 +163,9 @@ AnalysisWindow::AnalysisWindow() // And last we pack the hbox - get_vbox()->pack_start(hbox); - - hbox.show(); - vbox.show(); - track_list.show(); - source_selection_label.show(); - source_selection_ranges_rb.show(); - source_selection_regions_rb.show(); - hseparator1.show(); - display_model_label.show(); - display_model_composite_separate_rb.show(); - display_model_composite_all_tracks_rb.show(); - hseparator2.show(); - refresh_button.show(); - - //get_vbox()->show(); + add(hbox); + show_all(); + track_list.show_all(); } AnalysisWindow::~AnalysisWindow() @@ -168,6 +174,18 @@ AnalysisWindow::~AnalysisWindow() } void +AnalysisWindow::show_minmax_changed() +{ + fft_graph.set_show_minmax(show_minmax_button.get_active()); +} + +void +AnalysisWindow::show_normalized_changed() +{ + fft_graph.set_show_normalized(show_normalized_button.get_active()); +} + +void AnalysisWindow::set_rangemode() { source_selection_ranges_rb.set_active(true); diff --git a/gtk2_ardour/analysis_window.h b/gtk2_ardour/analysis_window.h index cd1243bb6a..45752c4a34 100644 --- a/gtk2_ardour/analysis_window.h +++ b/gtk2_ardour/analysis_window.h @@ -31,6 +31,7 @@ #include <gtkmm/label.h> #include <gtkmm/liststore.h> #include <gtkmm/separator.h> +#include <gtkmm/window.h> #include <gtkmm2ext/dndtreeview.h> @@ -42,7 +43,7 @@ #include "fft_result.h" -class AnalysisWindow : public ArdourDialog +class AnalysisWindow : public Gtk::Window { public: AnalysisWindow (); @@ -55,12 +56,18 @@ class AnalysisWindow : public ArdourDialog void analyze (); + const void set_session(ARDOUR::Session *session) { _session = session; }; + private: + ARDOUR::Session *_session; + void clear_tracklist(); void source_selection_changed (Gtk::RadioButton *); void display_model_changed (Gtk::RadioButton *); + void show_minmax_changed (); + void show_normalized_changed (); void analyze_data (Gtk::Button *); @@ -88,7 +95,8 @@ class AnalysisWindow : public ArdourDialog Gtk::TreeView track_list; Gtk::Label source_selection_label; - + + Gtk::RadioButton source_selection_ranges_rb; Gtk::RadioButton source_selection_regions_rb; @@ -98,9 +106,13 @@ class AnalysisWindow : public ArdourDialog Gtk::RadioButton display_model_composite_separate_rb; Gtk::RadioButton display_model_composite_all_tracks_rb; - Gtk::HSeparator hseparator2; - Gtk::Button refresh_button; + + + Gtk::CheckButton show_minmax_button; + Gtk::CheckButton show_normalized_button; + + // The graph FFTGraph fft_graph; diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index e8b8a20b5e..0c84bcc114 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -11,7 +11,6 @@ <menuitem action='Snapshot'/> <menuitem action='SaveTemplate'/> <separator/> - <menuitem action='AddTrackBus'/> <menu name='Files' action='Files'> <menuitem action='addExistingAudioFiles'/> @@ -27,6 +26,7 @@ </menu> <menuitem action='ToggleOptionsEditor'/> <menuitem action='About'/> + <menuitem action='Quit'/> </menu> <menu name='Transport' action='Transport'> @@ -50,17 +50,24 @@ <menuitem action='set-punch-from-region'/> </menu> + <separator/> <menuitem action='Forward'/> <menuitem action='Rewind'/> <menuitem action='TransitionToRoll'/> <menuitem action='TransitionToReverse'/> - <menuitem action='center-playhead'/> + <separator/> + + <menuitem action='set-playhead'/> - <menuitem action='playhead-to-edit'/> - <menuitem action='nudge-playhead-forward'/> - <menuitem action='nudge-playhead-backward'/> <menu action="MovePlayHeadMenu"> + + <menuitem action='playhead-to-edit'/> + <menuitem action='center-playhead'/> + <separator/> + <menuitem action='nudge-playhead-forward'/> + <menuitem action='nudge-playhead-backward'/> + <separator/> <menuitem action='tab-to-transient-forwards'/> <menuitem action='tab-to-transient-backwards'/> <separator/> @@ -101,13 +108,13 @@ </menu> <separator/> + <menuitem action='TogglePunch'/> <menuitem action='TogglePunchIn'/> <menuitem action='TogglePunchOut'/> <menuitem action='ToggleAutoInput'/> <menuitem action='ToggleAutoPlay'/> <menuitem action='ToggleAutoReturn'/> <menuitem action='ToggleClick'/> - <menuitem action='toggle-follow-playhead'/> <separator/> <menu action='LocateToMarker'> </menu> @@ -126,11 +133,14 @@ <menuitem action='editor-separate'/> <menuitem action='separate-from-loop'/> <menuitem action='separate-from-punch'/> + <separator/> + <menuitem action='split-region-at-transients'/> </menu> <separator/> <menuitem action='duplicate-region'/> <menuitem action='multi-duplicate-region'/> <menuitem action='region-fill-track'/> + <separator/> <menu action="AlignMenu"> <menuitem action='align-regions-start'/> <menuitem action='align-regions-start-relative'/> @@ -169,7 +179,26 @@ </menu> </menu> - <menu name='Regions' action='Regions'> + <menu action='TrackMenu'> + <menuitem action='AddTrackBus'/> + <menu action='TrackHeightMenu'> + <menuitem action='track-height-largest'/> + <menuitem action='track-height-large'/> + <menuitem action='track-height-larger'/> + <menuitem action='track-height-normal'/> + <menuitem action='track-height-smaller'/> + <menuitem action='track-height-small'/> + </menu> + <menu action='WaveformMenu'> + <menuitem action='toggle-waveform-visible'/> + <menuitem action='linear-waveforms'/> + <menuitem action='logarithmic-waveforms'/> + </menu> + <menuitem action='toggle-track-active'/> + <menuitem action='remove-track'/> + </menu> + + <menu action='RegionMenu'> <menuitem action='insert-region'/> <menuitem action='rename-region'/> <menuitem action='auto-rename-region'/> @@ -181,16 +210,13 @@ <menuitem action='remove-region-sync'/> <menuitem action='mute-unmute-region'/> <separator/> - <menuitem action='monoize-region'/> + <menuitem action='reverse-region'/> + <menuitem action='monoize-region'/> <menuitem action='normalize-region'/> - <menuitem action='split-region-at-transients'/> - <separator/> - <menu action="RegionGainMenu"> - <menuitem action='boost-region-gain'/> - <menuitem action='cut-region-gain'/> - </menu> + <menuitem action='boost-region-gain'/> + <menuitem action='cut-region-gain'/> <menuitem action='pitch-shift-region'/> - <menuitem action='reverse-region'/> + </menu> <menu name='View' action = 'View'> @@ -198,6 +224,7 @@ <menuitem action='show-editor-mixer'/> <menuitem action='ToggleMeasureVisibility'/> <menuitem action='ToggleLogoVisibility'/> + <separator/> <menu action="PrimaryClockMenu"> <menuitem action="primary-clock-bbt"/> <menuitem action="primary-clock-minsec"/> @@ -211,15 +238,15 @@ <menuitem action="secondary-clock-off"/> </menu> <menu action="RulerMenu"> - <menuitem action="toggle-bbt-ruler"/> <menuitem action="toggle-minsec-ruler"/> <menuitem action="toggle-samples-ruler"/> + <menuitem action="toggle-bbt-ruler"/> <separator/> <menuitem action="toggle-meter-ruler"/> <menuitem action="toggle-tempo-ruler"/> - <menuitem action="toggle-range-ruler"/> - <menuitem action="toggle-cd-marker-ruler"/> <menuitem action="toggle-loop-punch-ruler"/> + <menuitem action="toggle-cd-marker-ruler"/> + <menuitem action="toggle-marker-ruler"/> </menu> <menu action="ZoomMenu"> <menuitem action='temporal-zoom-in'/> @@ -235,22 +262,28 @@ <menuitem action='scroll-backward'/> </menu> <separator/> - <menu action="Windows"> - <menuitem action='goto-editor'/> - <menuitem action='goto-mixer'/> - <menuitem action='ToggleLocations'/> - <menuitem action='ToggleKeyEditor'/> - <menuitem action='ToggleThemeManager'/> - <menuitem action='ToggleBigClock'/> - <menuitem action='toggle-rhythm-ferret'/> - </menu> </menu> + <menu action="WindowMenu"> + <menuitem action='goto-editor'/> + <menuitem action='goto-mixer'/> + <menuitem action='ToggleLocations'/> + <menuitem action='ToggleKeyEditor'/> + <menuitem action='ToggleThemeManager'/> + <menuitem action='ToggleBigClock'/> + <menuitem action='toggle-rhythm-ferret'/> + </menu> + <menu name='Options' action='Options'> <menu action='Monitoring'> <menuitem action='UseSoftwareMonitoring'/> <menuitem action='UseExternalMonitoring'/> </menu> + <menu action="SyncMenu"> + <menuitem action='SendMMC'/> + <menuitem action='UseMMC'/> + <menuitem action='SendMTC'/> + </menu> <menu action="TempoMenu"> <menuitem action='set-tempo-from-region'/> <menuitem action='set-tempo-from-edit-range'/> @@ -267,9 +300,9 @@ <menuitem action='zoom-focus-mouse'/> </menu> <menu action="EditPointMenu"> - <menuitem action='edit-point-playhead'/> - <menuitem action='edit-point-mouse'/> - <menuitem action='edit-point-marker'/> + <menuitem action='edit-at-playhead'/> + <menuitem action='edit-at-mouse'/> + <menuitem action='edit-at-selected-marker'/> </menu> <menu action='KeyMouseActions'> <menuitem action='select-next-route'/> @@ -292,10 +325,23 @@ <menuitem action='cycle-snap-mode'/> <menuitem action='cycle-snap-choice'/> </menu> + <menuitem action='toggle-follow-playhead'/> </menu> </menubar> + <popup action="RulerMenuPopup"> + <menuitem action="toggle-minsec-ruler"/> + <menuitem action="toggle-samples-ruler"/> + <menuitem action="toggle-bbt-ruler"/> + <separator/> + <menuitem action="toggle-meter-ruler"/> + <menuitem action="toggle-tempo-ruler"/> + <menuitem action="toggle-loop-punch-ruler"/> + <menuitem action="toggle-cd-marker-ruler"/> + <menuitem action="toggle-marker-ruler"/> + </popup> + <popup name='redirectmenu'> <menuitem action='newplugin'/> <menuitem action='newinsert'/> diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 1860106b95..ff48f8366c 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -169,7 +169,7 @@ <menuitem action='select-next-route'/> <menuitem action='select-prev-route'/> </menu> - <menu name='Regions' action='Regions'> + <menu action='RegionMenu'> <menuitem action='split-region-at-transients'/> <menuitem action='crop'/> <menuitem action='duplicate-region'/> @@ -275,7 +275,7 @@ <menuitem action='scroll-playhead-forward'/> <menuitem action='scroll-playhead-backward'/> <separator/> - <menuitem action='ToggleWaveformVisibility'/> + <menuitem action='toggle-waveform-visible'/> <menuitem action='ToggleWaveformsWhileRecording'/> <menuitem action='ToggleMeasureVisibility'/> <separator/> @@ -298,7 +298,7 @@ <menuitem action='JACKLatency8192'/> </menu> </menu> - <menu name='Windows' action = 'Windows'> + <menu action = 'WindowMenu'> <menuitem action='ToggleMaximalEditor'/> <separator/> <menuitem action='goto-editor'/> @@ -456,6 +456,21 @@ </menu> </menubar> + <popup action="RulerMenuPopup"> + <menuitem action="toggle-minsec-ruler"/> + <menuitem action="toggle-timecode-ruler"/> + <menuitem action="toggle-samples-ruler"/> + <menuitem action="toggle-bbt-ruler"/> + <separator/> + <menuitem action="toggle-meter-ruler"/> + <menuitem action="toggle-timecode-ruler"/> + <menuitem action="toggle-tempo-ruler"/> + <menuitem action="toggle-range-ruler"/> + <menuitem action="toggle-marker-ruler"/> + <menuitem action="toggle-cd-marker-ruler"/> + <menuitem action="toggle-loop-punch-ruler"/> + </popup> + <popup name='processormenu'> <menuitem action='newplugin'/> <menuitem action='newinsert'/> diff --git a/gtk2_ardour/ardour2.desktop.in b/gtk2_ardour/ardour2.desktop.in new file mode 100644 index 0000000000..b5911e89b4 --- /dev/null +++ b/gtk2_ardour/ardour2.desktop.in @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Ardour +Comment=Ardour Digital Audio Workstation +Exec=ardour2 +Icon=ardour2 +Terminal=false +MimeType=application/x-ardour2; +Type=Application +Categories=AudioVideo;Audio;X-Recorders;X-Multitrack;X-Jack; diff --git a/gtk2_ardour/ardour2.xml b/gtk2_ardour/ardour2.xml new file mode 100644 index 0000000000..dd1c46ecf2 --- /dev/null +++ b/gtk2_ardour/ardour2.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> + <mime-type type="application/x-ardour2"> + <sub-class-of type="application/xml"/> + <comment>Ardour session file</comment> + <glob pattern="*.ardour"/> + </mime-type> +</mime-info> diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index f7a6c43b0f..421906fbfc 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -36,7 +36,6 @@ #include <gtkmm/accelmap.h> #include <pbd/error.h> -#include <pbd/misc.h> #include <pbd/basename.h> #include <pbd/compose.h> #include <pbd/failed_constructor.h> @@ -208,8 +207,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) have_disk_speed_dialog_displayed = false; session_loaded = false; last_speed_displayed = -1.0f; - - sys::path key_bindings_file; + ignore_dual_punch = false; last_configure_time.tv_sec = 0; last_configure_time.tv_usec = 0; @@ -256,6 +254,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) keyboard = new Keyboard; + reset_dpi(); + starting.connect (mem_fun(*this, &ARDOUR_UI::startup)); stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown)); @@ -641,7 +641,6 @@ ARDOUR_UI::startup () } BootMessage (_("Ardour is ready for use")); - show (); } @@ -2245,6 +2244,28 @@ ARDOUR_UI::loading_message (const std::string& msg) flush_pending (); } +void +ARDOUR_UI::idle_load (const Glib::ustring& path) +{ + if (session) { + if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) { + /* /path/to/foo => /path/to/foo, foo */ + load_session (path, basename_nosuffix (path)); + } else { + /* /path/to/foo/foo.ardour => /path/to/foo, foo */ + load_session (Glib::path_get_dirname (path), basename_nosuffix (path)); + } + } else { + ARDOUR_COMMAND_LINE::session_name = path; + if (new_session_dialog) { + /* make it break out of Dialog::run() and + start again. + */ + new_session_dialog->response (1); + } + } +} + bool ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be_new) { @@ -2252,8 +2273,10 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be Glib::ustring session_name; Glib::ustring session_path; Glib::ustring template_name; + int response; - int response = Gtk::RESPONSE_NONE; + begin: + response = Gtk::RESPONSE_NONE; if (!ARDOUR_COMMAND_LINE::session_name.empty()) { @@ -2297,6 +2320,13 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be /* handle possible negative responses */ switch (response) { + case 1: + /* sent by idle_load, meaning restart the whole process again */ + new_session_dialog->hide(); + new_session_dialog->reset(); + goto begin; + break; + case Gtk::RESPONSE_CANCEL: case Gtk::RESPONSE_DELETE_EVENT: if (!session) { @@ -2475,7 +2505,6 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na } loading_message (_("Please wait while Ardour loads your session")); - disable_screen_updates (); try { new_session = new Session (*engine, path, snap_name, mix_template); @@ -2547,7 +2576,6 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na session->set_clean (); } - enable_screen_updates (); flush_pending (); retval = 0; @@ -3249,6 +3277,11 @@ ARDOUR_UI::first_idle () if (session) { session->allow_auto_play (true); } + + if (editor) { + editor->first_idle(); + } + Keyboard::set_can_save_keybindings (true); return false; } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index d35d87a423..0eb02d8821 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -100,6 +100,7 @@ namespace ALSA { #define FRAME_NAME "BaseFrame" extern sigc::signal<void> ColorsChanged; +extern sigc::signal<void> DPIReset; class ARDOUR_UI : public Gtkmm2ext::UI { @@ -116,7 +117,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI void show_about (); void hide_about (); - int load_session (const Glib::ustring & path, const Glib::ustring& snapshot, Glib::ustring mix_template = Glib::ustring()); + void idle_load (const Glib::ustring& path); + int load_session (const Glib::ustring& path, const Glib::ustring& snapshot, Glib::ustring mix_template = Glib::ustring()); bool session_loaded; int build_session (const Glib::ustring& path, const Glib::ustring& snapshot, uint32_t ctl_chns, @@ -249,6 +251,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI void toggle_clocking (); void toggle_auto_play (); void toggle_auto_input (); + void toggle_punch (); + void unset_dual_punch (); + bool ignore_dual_punch; void toggle_punch_in (); void toggle_punch_out (); void toggle_auto_return (); diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index ca0615cbef..959d5fc128 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -881,6 +881,7 @@ ARDOUR_UI::editor_realized () set_size_request_to_display_given_text (speed_display_box, _("-0.55"), 2, 2); const guint32 FUDGE = 25; // Combo's are stupid - they steal space from the entry for the button set_size_request_to_display_given_text (shuttle_style_button, _("sprung"), 2+FUDGE, 10); + reset_dpi(); } void diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 0d410cd526..32b9f5adc7 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -80,7 +80,6 @@ ARDOUR_UI::connect_to_session (Session *s) /* there are never any selections on startup */ - ActionManager::set_sensitive (ActionManager::region_selection_sensitive_actions, false); ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false); ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false); ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false); @@ -182,6 +181,7 @@ ARDOUR_UI::unload_session (bool hide_stuff) if (hide_stuff) { editor->hide (); mixer->hide (); + theme_manager->hide (); } second_connection.disconnect (); diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 6f2ead2b79..65457068d2 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -86,7 +86,6 @@ ARDOUR_UI::install_actions () ActionManager::register_action (main_actions, X_("Session"), _("Session")); ActionManager::register_action (main_actions, X_("Files"), _("Import/Export")); - ActionManager::register_action (main_actions, X_("Regions"), _("Regions")); ActionManager::register_action (main_actions, X_("Cleanup"), _("Cleanup")); ActionManager::register_action (main_actions, X_("Sync"), _("Sync")); ActionManager::register_action (main_actions, X_("Options"), _("Options")); @@ -189,7 +188,7 @@ ARDOUR_UI::install_actions () /* these actions are intended to be shared across all windows */ common_actions = ActionGroup::create (X_("Common")); - ActionManager::register_action (main_actions, X_("Windows"), _("Windows")); + ActionManager::register_action (main_actions, X_("WindowMenu"), _("Window")); ActionManager::register_action (common_actions, X_("Quit"), _("Quit"), (mem_fun(*this, &ARDOUR_UI::finish))); /* windows visibility actions */ @@ -332,6 +331,9 @@ ARDOUR_UI::install_actions () act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("Punch Out"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); + act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunch"), _("Punch In/Out"), mem_fun(*this, &ARDOUR_UI::toggle_punch)); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::transport_sensitive_actions.push_back (act); act = ActionManager::register_toggle_action (transport_actions, X_("ToggleClick"), _("Click"), mem_fun(*this, &ARDOUR_UI::toggle_click)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc index 6b1eb3e299..4b75e59614 100644 --- a/gtk2_ardour/ardour_ui_options.cc +++ b/gtk2_ardour/ardour_ui_options.cc @@ -392,6 +392,52 @@ ARDOUR_UI::toggle_session_auto_loop () } void +ARDOUR_UI::unset_dual_punch () +{ + Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch"); + + if (action) { + Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action); + if (tact) { + ignore_dual_punch = true; + tact->set_active (false); + ignore_dual_punch = false; + } + } +} + +void +ARDOUR_UI::toggle_punch () +{ + if (ignore_dual_punch) { + return; + } + + Glib::RefPtr<Action> action = ActionManager::get_action ("Transport", "TogglePunch"); + + if (action) { + + Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(action); + + if (!tact) { + return; + } + + /* drive the other two actions from this one */ + + Glib::RefPtr<Action> in_action = ActionManager::get_action ("Transport", "TogglePunchIn"); + Glib::RefPtr<Action> out_action = ActionManager::get_action ("Transport", "TogglePunchOut"); + + if (in_action && out_action) { + Glib::RefPtr<ToggleAction> tiact = Glib::RefPtr<ToggleAction>::cast_dynamic(in_action); + Glib::RefPtr<ToggleAction> toact = Glib::RefPtr<ToggleAction>::cast_dynamic(out_action); + tiact->set_active (tact->get_active()); + toact->set_active (tact->get_active()); + } + } +} + +void ARDOUR_UI::toggle_punch_in () { ActionManager::toggle_config_state ("Transport", "TogglePunchIn", &Configuration::set_punch_in, &Configuration::get_punch_in); @@ -1015,10 +1061,13 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) } else if (PARAM_IS ("send-mtc")) { ActionManager::map_some_state ("options", "SendMTC", &Configuration::get_send_mtc); + cerr << "Send MMC = " << Config->get_send_mmc() << endl; } else if (PARAM_IS ("send-mmc")) { + ActionManager::map_some_state ("options", "SendMMC", &Configuration::get_send_mmc); + cerr << "Send MMC = " << Config->get_send_mmc() << endl; } else if (PARAM_IS ("use-osc")) { @@ -1034,6 +1083,8 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) } else if (PARAM_IS ("mmc-control")) { ActionManager::map_some_state ("options", "UseMMC", &Configuration::get_mmc_control); + cerr << "Use MMC = " << Config->get_mmc_control() << endl; + } else if (PARAM_IS ("midi-feedback")) { ActionManager::map_some_state ("options", "SendMIDIfeedback", &Configuration::get_midi_feedback); } else if (PARAM_IS ("do-not-record-plugins")) { @@ -1056,8 +1107,14 @@ ARDOUR_UI::parameter_changed (const char* parameter_name) ActionManager::map_some_state ("options", "ToggleTapeMachineMode", &Configuration::get_tape_machine_mode); } else if (PARAM_IS ("punch-out")) { ActionManager::map_some_state ("Transport", "TogglePunchOut", &Configuration::get_punch_out); + if (!Config->get_punch_out()) { + unset_dual_punch (); + } } else if (PARAM_IS ("punch-in")) { ActionManager::map_some_state ("Transport", "TogglePunchIn", &Configuration::get_punch_in); + if (!Config->get_punch_in()) { + unset_dual_punch (); + } } else if (PARAM_IS ("clicking")) { ActionManager::map_some_state ("Transport", "ToggleClick", &Configuration::get_clicking); } else if (PARAM_IS ("jack-time-master")) { diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index 4dfa62275a..3f71f126f5 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -341,8 +341,6 @@ AUPluginUI::get_nswindow () void AUPluginUI::activate () { - cerr << "AUPluginUI:: activate!\n"; - return; if (carbon_window && cocoa_parent) { cerr << "APP activated, activate carbon window " << insert->name() << endl; _activating_from_app = true; @@ -392,7 +390,7 @@ AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event) break; case kEventWindowHandleDeactivate: - cerr << "carbon window for " << insert->name() << " deactivated\n"; + cerr << "carbon window for " << insert->name() << " would have been deactivated\n"; // never deactivate the carbon window return noErr; break; diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc index 787f70a993..e1b80cc073 100644 --- a/gtk2_ardour/audio_clock.cc +++ b/gtk2_ardour/audio_clock.cc @@ -500,15 +500,21 @@ AudioClock::set_frames (nframes_t when, bool force) sprintf (buf, "%.3fK", rate/1000.0f); } - frames_upper_info_label->set_text (buf); + if (frames_upper_info_label->get_text() != buf) { + frames_upper_info_label->set_text (buf); + } float vid_pullup = Config->get_video_pullup(); if (vid_pullup == 0.0) { - frames_lower_info_label->set_text(_("none")); + if (frames_lower_info_label->get_text () != _("none")) { + frames_lower_info_label->set_text(_("none")); + } } else { sprintf (buf, "%-6.4f", vid_pullup); - frames_lower_info_label->set_text (buf); + if (frames_lower_info_label->get_text() != buf) { + frames_lower_info_label->set_text (buf); + } } } } @@ -598,7 +604,9 @@ AudioClock::set_smpte (nframes_t when, bool force) sprintf (buf, "%.2f", smpte_frames); } - smpte_upper_info_label->set_text (buf); + if (smpte_upper_info_label->get_text() != buf) { + smpte_upper_info_label->set_text (buf); + } if ((fabs(smpte_frames - 29.97) < 0.0001) || smpte_frames == 30) { if (session->smpte_drop_frames()) { @@ -611,7 +619,9 @@ AudioClock::set_smpte (nframes_t when, bool force) buf[0] = '\0'; } - smpte_lower_info_label->set_text (buf); + if (smpte_lower_info_label->get_text() != buf) { + smpte_lower_info_label->set_text (buf); + } } } @@ -632,9 +642,13 @@ AudioClock::set_bbt (nframes_t when, bool force) if (bbt_upper_info_label) { TempoMap::Metric m (session->tempo_map().metric_at (when)); sprintf (buf, "%-5.2f", m.tempo().beats_per_minute()); - bbt_lower_info_label->set_text (buf); + if (bbt_lower_info_label->get_text() != buf) { + bbt_lower_info_label->set_text (buf); + } sprintf (buf, "%g|%g", m.meter().beats_per_bar(), m.meter().note_divisor()); - bbt_upper_info_label->set_text (buf); + if (bbt_upper_info_label->get_text() != buf) { + bbt_upper_info_label->set_text (buf); + } } } diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index a98958f8a8..c9943e1e96 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -143,7 +143,7 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd) } compute_colors (basic_color); - + create_waves (); fade_in_shape = new ArdourCanvas::Polygon (*group); @@ -800,7 +800,7 @@ AudioRegionView::set_envelope_visible (bool yn) void AudioRegionView::create_waves () { - //cerr << "AudioRegionView::create_waves() called on " << this << endl;//DEBUG + // cerr << "AudioRegionView::create_waves() called on " << this << endl;//DEBUG RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick if (!atv.get_diskstream()) { diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h index 01ec7c95ce..10b0254337 100644 --- a/gtk2_ardour/audio_region_view.h +++ b/gtk2_ardour/audio_region_view.h @@ -63,6 +63,8 @@ class AudioRegionView : public RegionView boost::shared_ptr<ARDOUR::AudioRegion> audio_region() const; void set_y_position_and_height (double, double); + void create_waves (); + void set_samples_per_unit (double); void set_amplitude_above_axis (gdouble spp); @@ -72,8 +74,8 @@ class AudioRegionView : public RegionView void set_envelope_visible (bool); void set_waveform_visible (bool yn); - void set_waveform_shape (WaveformShape); - void set_waveform_scale (WaveformScale); + void set_waveform_shape (Editing::WaveformShape); + void set_waveform_scale (Editing::WaveformScale); bool waveform_rectified() const { return _flags & WaveformRectified; } bool waveform_logscaled() const { return _flags & WaveformLogScaled; } @@ -150,7 +152,6 @@ class AudioRegionView : public RegionView void region_scale_amplitude_changed (); void region_renamed (); - void create_waves (); void create_one_wave (uint32_t, bool); void manage_zero_line (); void peaks_ready_handler (uint32_t); diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc index a21de27b46..08ac532319 100644 --- a/gtk2_ardour/audio_streamview.cc +++ b/gtk2_ardour/audio_streamview.cc @@ -466,8 +466,9 @@ AudioStreamView::set_show_waveforms (bool yn) { for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); - if (arv) + if (arv) { arv->set_waveform_visible (yn); + } } } diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h index bd56b371a3..326a05f240 100644 --- a/gtk2_ardour/audio_streamview.h +++ b/gtk2_ardour/audio_streamview.h @@ -26,7 +26,7 @@ #include <boost/weak_ptr.hpp> #include <ardour/location.h> -#include "enums.h" +#include "editing.h" #include "simplerect.h" #include "streamview.h" @@ -57,10 +57,10 @@ class AudioStreamView : public StreamView AudioStreamView (AudioTimeAxisView&); ~AudioStreamView (); - void set_waveform_shape (WaveformShape); - WaveformShape get_waveform_shape () const { return _waveform_shape; } - void set_waveform_scale (WaveformScale); - WaveformScale get_waveform_scale () const { return _waveform_scale; } + void set_waveform_shape (Editing::WaveformShape); + Editing::WaveformShape get_waveform_shape () const { return _waveform_shape; } + void set_waveform_scale (Editing::WaveformScale); + Editing::WaveformScale get_waveform_scale () const { return _waveform_scale; } int set_samples_per_unit (gdouble spp); @@ -106,8 +106,8 @@ class AudioStreamView : public StreamView CrossfadeViewList crossfade_views; bool crossfades_visible; - WaveformShape _waveform_shape; - WaveformScale _waveform_scale; + Editing::WaveformShape _waveform_shape; + Editing::WaveformScale _waveform_scale; map<boost::shared_ptr<ARDOUR::Source>, bool> rec_data_ready_map; }; diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 34566d4de2..8eea568b7b 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -73,7 +73,6 @@ using namespace PBD; using namespace Gtk; using namespace Editing; - AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas) : AxisView(sess) , RouteTimeAxisView(ed, sess, rt, canvas) @@ -115,16 +114,29 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh /* ask for notifications of any new RegionViews */ _view->RegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added)); - _view->attach (); - } - post_construct (); + if (!editor.have_idled()) { + /* first idle will do what we need */ + } else { + first_idle (); + } + + } else { + post_construct (); + } } AudioTimeAxisView::~AudioTimeAxisView () { } +void +AudioTimeAxisView::first_idle () +{ + _view->attach (); + post_construct (); +} + AudioStreamView* AudioTimeAxisView::audio_view() { @@ -457,24 +469,26 @@ AudioTimeAxisView::update_control_names () { if (is_audio_track()) { if (_route->active()) { - controls_ebox.set_name ("AudioTrackControlsBaseUnselected"); controls_base_selected_name = "AudioTrackControlsBaseSelected"; controls_base_unselected_name = "AudioTrackControlsBaseUnselected"; } else { - controls_ebox.set_name ("AudioTrackControlsBaseInactiveUnselected"); controls_base_selected_name = "AudioTrackControlsBaseInactiveSelected"; controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected"; } } else { if (_route->active()) { - controls_ebox.set_name ("BusControlsBaseUnselected"); controls_base_selected_name = "BusControlsBaseSelected"; controls_base_unselected_name = "BusControlsBaseUnselected"; } else { - controls_ebox.set_name ("BusControlsBaseInactiveUnselected"); controls_base_selected_name = "BusControlsBaseInactiveSelected"; controls_base_unselected_name = "BusControlsBaseInactiveUnselected"; } } + + if (get_selected()) { + controls_ebox.set_name (controls_base_selected_name); + } else { + controls_ebox.set_name (controls_base_unselected_name); + } } diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h index cb19be0b75..565d7cda9f 100644 --- a/gtk2_ardour/audio_time_axis.h +++ b/gtk2_ardour/audio_time_axis.h @@ -36,6 +36,7 @@ #include "ardour_dialog.h" #include "route_ui.h" #include "enums.h" +#include "editing.h" #include "route_time_axis.h" #include "canvas.h" @@ -83,6 +84,11 @@ class AudioTimeAxisView : public RouteTimeAxisView void create_automation_child (ARDOUR::Parameter param, bool show); + void first_idle (); + + void set_waveform_shape (Editing::WaveformShape); + void set_waveform_scale (Editing::WaveformScale); + private: friend class AudioStreamView; friend class AudioRegionView; @@ -93,9 +99,7 @@ class AudioTimeAxisView : public RouteTimeAxisView Gtk::Menu* build_mode_menu(); void toggle_show_waveforms (); - void set_waveform_shape (WaveformShape); void toggle_waveforms (); - void set_waveform_scale (WaveformScale); void show_all_automation (); void show_existing_automation (); diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index d5805aa3af..81e4d34989 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -462,6 +462,12 @@ AutomationLine::determine_visible_control_points (ALPoints& points) double tx = points[pi].x; double ty = points[pi].y; + + if (isnan (tx) || isnan (ty)) { + warning << string_compose (_("Ignoring illegal points on AutomationLine \"%1\""), + _name) << endmsg; + continue; + } /* now ensure that the control_points vector reflects the current curve state, but don't plot control points too close together. also, don't @@ -1059,7 +1065,7 @@ AutomationLine::reset_callback (const AutomationList& events) AutomationList::const_iterator ai; for (ai = events.const_begin(); ai != events.const_end(); ++ai) { - + double translated_y = (*ai)->value; model_to_view_y (translated_y); diff --git a/gtk2_ardour/canvas-imageframe.c b/gtk2_ardour/canvas-imageframe.c index e0f0f2f743..1f0e7e877b 100644 --- a/gtk2_ardour/canvas-imageframe.c +++ b/gtk2_ardour/canvas-imageframe.c @@ -456,8 +456,6 @@ static void gnome_canvas_imageframe_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) { - fprintf(stderr, "please don't use the CanvasImageFrame item in a non-aa Canvas\n") ; - abort() ; } static double diff --git a/gtk2_ardour/canvas-simpleline.c b/gtk2_ardour/canvas-simpleline.c index b65693a548..576eedc369 100644 --- a/gtk2_ardour/canvas-simpleline.c +++ b/gtk2_ardour/canvas-simpleline.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <math.h> +#include <cairo.h> #include <libgnomecanvas/libgnomecanvas.h> #include "canvas-simpleline.h" @@ -400,15 +401,54 @@ gnome_canvas_simpleline_draw (GnomeCanvasItem *item, int width, int height) { GnomeCanvasSimpleLine *simpleline; + cairo_t* cr; + double ulx; + double uly; + double lrx; + double lry; simpleline = GNOME_CANVAS_SIMPLELINE (item); - if (parent_class->draw) { - (* parent_class->draw) (item, drawable, x, y, width, height); + cr = gdk_cairo_create (drawable); + + if (x > simpleline->bbox_ulx) { + ulx = x; + } else { + ulx = simpleline->bbox_ulx; + } + + if (y > simpleline->bbox_uly) { + uly = y; + } else { + uly = simpleline->bbox_uly; + } + + if (x + width > simpleline->bbox_lrx) { + lrx = simpleline->bbox_lrx; + } else { + lrx = x + width; + } + + if (y + height > simpleline->bbox_lry) { + lry = simpleline->bbox_lry; + } else { + lry = y + height; } - fprintf (stderr, "please don't use the CanvasSimpleLine item in a non-aa Canvas\n"); - abort (); + ulx -= x; + uly -= y; + lrx -= x; + lry -= y; + + cairo_set_source_rgba (cr, + simpleline->r/255.0, + simpleline->g/255.0, + simpleline->b/255.0, + simpleline->a/255.0); + cairo_set_line_width (cr, 1); + cairo_move_to (cr, ulx+0.5, uly+0.5); + cairo_line_to (cr, lrx+0.5, lry+0.5); + cairo_stroke (cr); } static void @@ -433,17 +473,17 @@ gnome_canvas_simpleline_point (GnomeCanvasItem *item, double x, double y, int cx *actual_item = item; - /* Find the bounds for the rectangle plus its outline width */ + /* Find the bounds for the line plus its outline width */ gnome_canvas_simpleline_bounds (item, &x1, &y1, &x2, &y2); - /* Is point inside rectangle */ + /* Is point inside line */ if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { return 0.0; } - /* Point is outside rectangle */ + /* Point is outside line */ if (x < x1) dx = x1 - x; diff --git a/gtk2_ardour/canvas-simplerect.c b/gtk2_ardour/canvas-simplerect.c index d50943f0c3..91649b64bb 100644 --- a/gtk2_ardour/canvas-simplerect.c +++ b/gtk2_ardour/canvas-simplerect.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <math.h> +#include <cairo.h> #include <libgnomecanvas/libgnomecanvas.h> #include "canvas-simplerect.h" @@ -287,7 +288,7 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x1, y1, &simplerect->bbox_ulx, &simplerect->bbox_uly); gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x2, y2, &simplerect->bbox_lrx, &simplerect->bbox_lry); - /* now queue redraws for changed areas */ + /* now queue redraws for changed areas */ if (item->x1 == old_x1 && item->x2 == old_x2) { @@ -714,12 +715,111 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, static void gnome_canvas_simplerect_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height) + GdkDrawable *drawable, + int x, int y, + int width, int height) { - fprintf (stderr, "please don't use the CanvasSimpleRect item in a non-aa Canvas\n"); - abort (); + GnomeCanvasSimpleRect *simplerect; + cairo_t* cr; + double ulx; + double uly; + double lrx; + double lry; + + simplerect = GNOME_CANVAS_SIMPLERECT (item); + + cr = gdk_cairo_create (drawable); + + if (x > simplerect->bbox_ulx) { + ulx = x; + } else { + ulx = simplerect->bbox_ulx; + } + + if (y > simplerect->bbox_uly) { + uly = y; + } else { + uly = simplerect->bbox_uly; + } + + if (x + width > simplerect->bbox_lrx) { + lrx = simplerect->bbox_lrx; + } else { + lrx = x + width; + } + + if (y + height > simplerect->bbox_lry) { + lry = simplerect->bbox_lry; + } else { + lry = y + height; + } + + ulx -= x; + uly -= y; + lrx -= x; + lry -= y; + + cairo_rectangle (cr, ulx, uly, lrx - ulx, lry - uly); + + if (simplerect->fill) { + cairo_set_source_rgba (cr, + simplerect->fill_r/255.0, + simplerect->fill_g/255.0, + simplerect->fill_b/255.0, + simplerect->fill_a/255.0); + cairo_fill (cr); + } + + if (simplerect->outline_what && simplerect->outline_pixels) { + +#define x_in_range(a) (x <= (a) && (a) < x + width) +#define y_in_range(a) (y <= (a) && (a) < y + height) + + cairo_set_line_width (cr, simplerect->outline_pixels); + + cairo_set_source_rgb (cr, + simplerect->outline_r/255.0, + simplerect->outline_g/255.0, + simplerect->outline_b/255.0); + + if (simplerect->outline_what & 0x1) { + /* left edge, if visible */ + if (x_in_range (simplerect->bbox_ulx)) { + cairo_move_to (cr, ulx+0.5, uly+0.5); + cairo_line_to (cr, ulx+0.5, lry+0.5); + cairo_stroke (cr); + } + } + + if (simplerect->outline_what & 0x2) { + /* right edge, if visible */ + if (x_in_range (simplerect->bbox_lrx)) { + cairo_move_to (cr, lrx+0.5, uly+0.5); + cairo_line_to (cr, lrx+0.5, lry+0.5); + cairo_stroke (cr); + } + } + + if (simplerect->outline_what & 0x4) { + /* top edge */ + if (y_in_range (simplerect->bbox_uly)) { + cairo_move_to (cr, ulx+0.5, uly+0.5); + cairo_line_to (cr, lrx+0.5, uly+0.5); + cairo_stroke (cr); + } + } + + if (simplerect->outline_what & 0x8) { + /* bottom edge */ + if (y_in_range (simplerect->bbox_lry)) { + cairo_move_to (cr, ulx+0.5, lry+0.5); + cairo_line_to (cr, lrx+0.5, lry+0.5); + cairo_stroke (cr); + } + } + } + + cairo_destroy (cr); } static double diff --git a/gtk2_ardour/canvas-waveview.c b/gtk2_ardour/canvas-waveview.c index 2f721dc8d6..dee5706c51 100644 --- a/gtk2_ardour/canvas-waveview.c +++ b/gtk2_ardour/canvas-waveview.c @@ -21,6 +21,7 @@ #include <stdio.h> #include <math.h> #include <libgnomecanvas/libgnomecanvas.h> +#include <cairo.h> #include <string.h> #include <limits.h> @@ -1600,22 +1601,228 @@ gnome_canvas_waveview_render (GnomeCanvasItem *item, static void gnome_canvas_waveview_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height) + GdkDrawable *drawable, + int x, int y, + int width, int height) { GnomeCanvasWaveView *waveview; + cairo_t* cr; + gulong s1, s2; + int cache_index; + double zbegin, zend; + gboolean rectify; + double n; + double origin; + double clip_length; + double xoff; + double yoff; + double ulx; + double uly; + double lrx; + double lry; waveview = GNOME_CANVAS_WAVEVIEW (item); - if (parent_class->draw) { - (* parent_class->draw) (item, drawable, x, y, width, height); + /* compute intersection of Drawable area and waveview, + in canvas coordinate space + */ + + if (x > waveview->bbox_ulx) { + ulx = x; + zbegin = ulx; + } else { + ulx = waveview->bbox_ulx; + zbegin = ulx + 1; + } + + if (y > waveview->bbox_uly) { + uly = y; + } else { + uly = waveview->bbox_uly; + } + + if (x + width > waveview->bbox_lrx) { + lrx = waveview->bbox_lrx; + zend = lrx - 1; + } else { + lrx = x + width; + zend = lrx; + } + + if (y + height > waveview->bbox_lry) { + lry = waveview->bbox_lry; + } else { + lry = y + height; + } + + /* figure out which samples we need for the resulting intersection */ + + s1 = floor ((ulx - waveview->bbox_ulx) * waveview->samples_per_unit) ; + + if (lrx == waveview->bbox_lrx) { + /* This avoids minor rounding errors when we have the + entire region visible. + */ + s2 = waveview->samples; + } else { + s2 = s1 + floor ((lrx - ulx) * waveview->samples_per_unit); + } + + /* translate back to buffer coordinate space */ + + ulx -= x; + uly -= y; + lrx -= x; + lry -= y; + zbegin -= x; + zend -= x; + + /* don't rectify at single-sample zoom */ + if(waveview->rectified && waveview->samples_per_unit > 1.0) { + rectify = TRUE; + } else { + rectify = FALSE; + } + + clip_length = MIN(5,(waveview->height/4)); + + cr = gdk_cairo_create (drawable); + cairo_set_line_width (cr, 0.5); + + origin = waveview->bbox_uly - y + waveview->half_height; + + cairo_rectangle (cr, ulx, uly, lrx - ulx, lry - uly); + cairo_clip (cr); + + if (waveview->cache_updater && waveview->reload_cache_in_render) { + waveview->cache->start = 0; + waveview->cache->end = 0; + waveview->reload_cache_in_render = FALSE; + } + + cache_index = gnome_canvas_waveview_ensure_cache (waveview, s1, s2); + +#if 0 + printf ("%p r (%d,%d)(%d,%d)[%d x %d] bbox (%d,%d)(%d,%d)[%d x %d]" + " draw (%.1f,%.1f)(%.1f,%.1f)[%.1f x %.1f] s= %lu..%lu\n", + waveview, + x, y, + x + width, + y + height, + width, + height, + waveview->bbox_ulx, + waveview->bbox_uly, + waveview->bbox_lrx, + waveview->bbox_lry, + waveview->bbox_lrx - waveview->bbox_ulx, + waveview->bbox_lry - waveview->bbox_uly, + ulx, uly, + lrx, lry, + lrx - ulx, + lry - uly, + s1, s2); +#endif + + /* draw the top half */ + + for (xoff = ulx; xoff < lrx; xoff++) { + double max, min; + + max = waveview->cache->data[cache_index].max; + min = waveview->cache->data[cache_index].min; + + if (min <= -1.0) { + min = -1.0; + } + + if (max >= 1.0) { + max = 1.0; + } + + if (rectify) { + if (fabs (min) > fabs (max)) { + max = fabs (min); + } + } + + yoff = origin - (waveview->half_height * max) + 0.5; + + if (n == ulx) { + cairo_move_to (cr, xoff+0.5, yoff); + } else { + cairo_line_to (cr, xoff+0.5, yoff); + } + + cache_index++; } - fprintf (stderr, "please don't use the CanvasWaveView item in a non-aa Canvas\n"); - abort (); + /* from the final top point, move out of the clip zone */ + + cairo_line_to (cr, xoff + 10, yoff); + + /* now draw the bottom half */ + + for (--xoff, --cache_index; xoff >= ulx; --xoff) { + double min; + + min = waveview->cache->data[cache_index].min; + + if (min <= -1.0) { + min = -1.0; + } + + yoff = origin - (waveview->half_height * min) + 0.5; + + cairo_line_to (cr, xoff+0.5, yoff); + cache_index--; + } + + /* from the final lower point, move out of the clip zone */ + + cairo_line_to (cr, xoff - 10, yoff); + + /* close path to fill */ + + cairo_close_path (cr); + + /* fill and stroke */ + + cairo_set_source_rgba (cr, + (waveview->fill_r/255.0), + (waveview->fill_g/255.0), + (waveview->fill_b/255.0), + (waveview->fill_a/255.0)); + cairo_fill_preserve (cr); + cairo_set_source_rgba (cr, + (waveview->wave_r/255.0), + (waveview->wave_g/255.0), + (waveview->wave_b/255.0), + (waveview->wave_a/255.0)); + cairo_stroke (cr); + + cairo_destroy (cr); } +#if 0 + if (clip_max || clip_min) { + cairo_set_source_rgba (cr, waveview->clip_r, waveview->clip_g, waveview->clip_b, waveview->clip_a); + } + + if (clip_max) { + cairo_move_to (cr, xoff, yoff1); + cairo_line_to (cr, xoff, yoff1 + clip_length); + cairo_stroke (cr); + } + + if (clip_min) { + cairo_move_to (cr, xoff, yoff2); + cairo_line_to (cr, xoff, yoff2 - clip_length); + cairo_stroke (cr); + } + +#endif + static void gnome_canvas_waveview_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) { diff --git a/gtk2_ardour/canvas.h b/gtk2_ardour/canvas.h index 9fa737258c..8df2674db7 100644 --- a/gtk2_ardour/canvas.h +++ b/gtk2_ardour/canvas.h @@ -25,6 +25,7 @@ namespace Gnome { class Item; class Group; class Canvas; + class Rect; class SimpleRect; class SimpleLine; class Polygon; diff --git a/gtk2_ardour/cocoacarbon.mm b/gtk2_ardour/cocoacarbon.mm index 75141d34f6..75df481186 100644 --- a/gtk2_ardour/cocoacarbon.mm +++ b/gtk2_ardour/cocoacarbon.mm @@ -27,6 +27,7 @@ #include <gtkmm2ext/sync-menu.h> #include <Appkit/Appkit.h> +#include <gdk/gdkquartz.h> sigc::signal<void,bool> ApplicationActivationChanged; static EventHandlerRef application_event_handler_ref; @@ -40,18 +41,51 @@ handle_reopen_application (const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon) { - cerr << "reopen app\n"; return noErr; } + static OSErr -handle_quit_application (const AppleEvent *inAppleEvent, +handle_print_documents (const AppleEvent *inAppleEvent, + AppleEvent *outAppleEvent, + long inHandlerRefcon) +{ + return noErr; +} + + +static OSErr +handle_open_documents (const AppleEvent *inAppleEvent, + AppleEvent *outAppleEvent, + long inHandlerRefcon) +{ + AEDescList docs; + + if (AEGetParamDesc(inAppleEvent, keyDirectObject, typeAEList, &docs) == noErr) { + long n = 0; + AECountItems(&docs, &n); + UInt8 strBuffer[PATH_MAX+1]; + + /* ardour only opens 1 session at a time */ + + FSRef ref; + + if (AEGetNthPtr(&docs, 1, typeFSRef, 0, 0, &ref, sizeof(ref), 0) == noErr) { + if (FSRefMakePath(&ref, strBuffer, sizeof(strBuffer)) == noErr) { + Glib::ustring utf8_path ((const char*) strBuffer); + ARDOUR_UI::instance()->idle_load (utf8_path); + } + } + } + + return noErr; +} + +static OSErr +handle_open_application (const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon) { - cerr << "quit app\n"; - ARDOUR_UI::instance()->quit (); - return noErr; } @@ -79,12 +113,6 @@ application_event_handler (EventHandlerCallRef nextHandlerRef, EventRef event, v void ARDOUR_UI::platform_specific () { - AEInstallEventHandler (kCoreEventClass, kAEReopenApplication, - handle_reopen_application, 0, true); - - AEInstallEventHandler (kCoreEventClass, kAEQuitApplication, - handle_quit_application, 0, true); - Gtk::Widget* widget = ActionManager::get_widget ("/ui/Main/Session/Quit"); if (widget) { ige_mac_menu_set_quit_menu_item ((GtkMenuItem*) widget->gobj()); @@ -97,9 +125,26 @@ ARDOUR_UI::platform_specific () ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0); } widget = ActionManager::get_widget ("/ui/Main/Session/ToggleOptionsEditor"); + if (widget) { ige_mac_menu_add_app_menu_item (group, (GtkMenuItem*) widget->gobj(), 0); } +} + +void +ARDOUR_UI::platform_setup () +{ + AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments, + handle_open_documents, 0, true); + + AEInstallEventHandler (kCoreEventClass, kAEOpenApplication, + handle_open_application, 0, true); + + AEInstallEventHandler (kCoreEventClass, kAEReopenApplication, + handle_reopen_application, 0, true); + + AEInstallEventHandler (kCoreEventClass, kAEPrintDocuments, + handle_print_documents, 0, true); EventTypeSpec applicationEventTypes[] = { {kEventClassApplication, kEventAppActivated }, @@ -110,11 +155,6 @@ ARDOUR_UI::platform_specific () InstallApplicationEventHandler (ehUPP, sizeof(applicationEventTypes) / sizeof(EventTypeSpec), applicationEventTypes, 0, &application_event_handler_ref); -} - -void -ARDOUR_UI::platform_setup () -{ if (!ARDOUR_COMMAND_LINE::finder_invoked_ardour) { /* if invoked from the command line, make sure we're visible */ @@ -122,3 +162,4 @@ ARDOUR_UI::platform_setup () [NSApp activateIgnoringOtherApps:1]; } } + diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc index 03d03c3d10..a4e7281870 100644 --- a/gtk2_ardour/crossfade_edit.cc +++ b/gtk2_ardour/crossfade_edit.cc @@ -925,17 +925,6 @@ CrossfadeEditor::build_presets () p->push_back (PresetPoint (1, 0)); fade_out_presets->push_back (p); - // p = new Preset ("regout.xpm"); - p = new Preset ("crossfade_out_constant"); - p->push_back (PresetPoint (0, 1)); - p->push_back (PresetPoint (0.228111, 0.988889)); - p->push_back (PresetPoint (0.347926, 0.972222)); - p->push_back (PresetPoint (0.529954, 0.886111)); - p->push_back (PresetPoint (0.753456, 0.658333)); - p->push_back (PresetPoint (0.9262673, 0.308333)); - p->push_back (PresetPoint (1, 0)); - fade_out_presets->push_back (p); - // p = new Preset ("loout.xpm"); p = new Preset ("crossfade_out_transition"); p->push_back (PresetPoint (0, 1)); @@ -947,6 +936,17 @@ CrossfadeEditor::build_presets () p->push_back (PresetPoint (1, 0)); fade_out_presets->push_back (p); + // p = new Preset ("regout.xpm"); + p = new Preset ("crossfade_out_constant"); + p->push_back (PresetPoint (0, 1)); + p->push_back (PresetPoint (0.228111, 0.988889)); + p->push_back (PresetPoint (0.347926, 0.972222)); + p->push_back (PresetPoint (0.529954, 0.886111)); + p->push_back (PresetPoint (0.753456, 0.658333)); + p->push_back (PresetPoint (0.9262673, 0.308333)); + p->push_back (PresetPoint (1, 0)); + fade_out_presets->push_back (p); + // p = new Preset ("regout2.xpm"); p = new Preset ("crossfade_out_slow-fade"); p->push_back (PresetPoint (0, 1)); diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h index 2b4519ec9c..64ced895db 100644 --- a/gtk2_ardour/editing.h +++ b/gtk2_ardour/editing.h @@ -37,6 +37,8 @@ #define IMPORTPOSITION(a) #define IMPORTDISPOSITION(a) #define EDITPOINT(a) /*empty*/ +#define WAVEFORMSCALE(a) /*empty*/ +#define WAVEFORMSHAPE(a) /*empty*/ namespace Editing { @@ -179,6 +181,27 @@ enum EditPoint { #undef EDITPOINT #define EDITPOINT(a) /*empty*/ +// WAVEFORMSCALE +#undef WAVEFORMSCALE +#define WAVEFORMSCALE(a) a, +enum WaveformScale { + #include "editing_syms.h" +}; + +#undef WAVEFORMSCALE +#define WAVEFORMSCALE(a) /*empty*/ + + +// WAVEFORMSHAPE +#undef WAVEFORMSHAPE +#define WAVEFORMSHAPE(a) a, +enum WaveformShape { + #include "editing_syms.h" +}; + +#undef WAVEFORMSHAPE +#define WAVEFORMSHAPE(a) /*empty*/ + ///////////////////// // These don't need their state saved. yet... enum CutCopyOp { diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h index 1cbb2decd8..71a7747b47 100644 --- a/gtk2_ardour/editing_syms.h +++ b/gtk2_ardour/editing_syms.h @@ -100,3 +100,11 @@ IMPORTDISPOSITION(ImportDistinctChannels=3) EDITPOINT(EditAtPlayhead) EDITPOINT(EditAtSelectedMarker) EDITPOINT(EditAtMouse) + +WAVEFORMSCALE(LinearWaveform) +WAVEFORMSCALE(LogWaveform) + +WAVEFORMSHAPE(Traditional) +WAVEFORMSHAPE(Rectified) + + diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index fa44862191..4f36865905 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -247,6 +247,7 @@ Editor::Editor () PublicEditor::_instance = this; session = 0; + _have_idled = false; selection = new Selection (this); cut_buffer = new Selection (this); @@ -382,12 +383,12 @@ Editor::Editor () horizontal_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::canvas_horizontally_scrolled), false); vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true); - track_canvas.set_hadjustment (horizontal_adjustment); - track_canvas.set_vadjustment (vertical_adjustment); - time_canvas.set_hadjustment (horizontal_adjustment); + track_canvas->set_hadjustment (horizontal_adjustment); + track_canvas->set_vadjustment (vertical_adjustment); + time_canvas->set_hadjustment (horizontal_adjustment); - track_canvas.signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler)); - time_canvas.signal_map_event().connect (mem_fun (*this, &Editor::time_canvas_map_handler)); + track_canvas->signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler)); + time_canvas->signal_map_event().connect (mem_fun (*this, &Editor::time_canvas_map_handler)); controls_layout.add (edit_controls_vbox); controls_layout.set_name ("EditControlsBase"); @@ -425,7 +426,7 @@ Editor::Editor () time_canvas_vbox.pack_start (*smpte_ruler, false, false); time_canvas_vbox.pack_start (*frames_ruler, false, false); time_canvas_vbox.pack_start (*bbt_ruler, false, false); - time_canvas_vbox.pack_start (time_canvas, true, true); + time_canvas_vbox.pack_start (*time_canvas, true, true); time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars) + 5); bbt_label.set_name ("EditorTimeButton"); @@ -492,7 +493,7 @@ Editor::Editor () for the canvas areas. */ - track_canvas_event_box.add (track_canvas); + track_canvas_event_box.add (*track_canvas); time_canvas_event_box.add (time_canvas_vbox); time_canvas_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK); @@ -613,6 +614,10 @@ Editor::Editor () region_list_display.set_size_request (100, -1); region_list_display.set_name ("RegionListDisplay"); + /* Try to prevent single mouse presses from initiating edits. + This relies on a hack in gtktreeview.c:gtk_treeview_button_press() + */ + region_list_display.set_data ("mouse-edits-require-mod1", (gpointer) 0x1); region_list_model = TreeStore::create (region_list_columns); region_list_model->set_sort_func (0, mem_fun (*this, &Editor::region_list_sorter)); @@ -748,8 +753,7 @@ Editor::Editor () set_snap_to (snap_type); snap_mode = SnapOff; set_snap_mode (snap_mode); - _edit_point = EditAtMouse; - set_edit_point_preference (_edit_point); + set_edit_point_preference (EditAtMouse, true); XMLNode* node = ARDOUR_UI::instance()->editor_settings(); set_state (*node); @@ -833,6 +837,16 @@ Editor::~Editor() image_socket_listener = 0 ; } #endif + + if (track_canvas) { + delete track_canvas; + track_canvas = 0; + } + + if (time_canvas) { + delete time_canvas; + time_canvas = 0; + } } void @@ -1150,6 +1164,10 @@ Editor::connect_to_session (Session *t) { session = t; + /* there are never any selected regions at startup */ + + sensitize_the_right_region_actions (false); + XMLNode* node = ARDOUR_UI::instance()->editor_settings(); set_state (*node); @@ -2229,9 +2247,9 @@ Editor::set_snap_mode (SnapMode mode) instant_save (); } void -Editor::set_edit_point_preference (EditPoint ep) +Editor::set_edit_point_preference (EditPoint ep, bool force) { - bool changed = _edit_point != ep; + bool changed = (_edit_point != ep); _edit_point = ep; string str = edit_point_strings[(int)ep]; @@ -2242,7 +2260,7 @@ Editor::set_edit_point_preference (EditPoint ep) set_canvas_cursor (); - if (!changed) { + if (!force && !changed) { return; } @@ -2266,6 +2284,25 @@ Editor::set_edit_point_preference (EditPoint ep) break; } + const char* action; + + switch (_edit_point) { + case EditAtPlayhead: + action = "edit-at-playhead"; + break; + case EditAtSelectedMarker: + action = "edit-at-marker"; + break; + case EditAtMouse: + action = "edit-at-mouse"; + break; + } + + Glib::RefPtr<Action> act = ActionManager::get_action ("Editor", action); + if (act) { + Glib::RefPtr<RadioAction>::cast_dynamic(act)->set_active (true); + } + instant_save (); } @@ -2339,7 +2376,7 @@ Editor::set_state (const XMLNode& node) } if ((prop = node.property ("edit-point"))) { - set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point)); + set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point), true); } if ((prop = node.property ("mouse-mode"))) { @@ -2354,7 +2391,7 @@ Editor::set_state (const XMLNode& node) if ((prop = node.property ("show-waveforms"))) { bool yn = (prop->value() == "yes"); _show_waveforms = !yn; - RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility")); + RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-waveform-visible")); if (act) { RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act); /* do it twice to force the change */ @@ -4506,8 +4543,7 @@ Editor::set_loop_range (nframes_t start, nframes_t end, string cmd) session->set_auto_loop_location (loc); XMLNode &after = session->locations()->get_state(); session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after)); - } - else { + } else { XMLNode &before = tll->get_state(); tll->set_hidden (false, this); tll->set (start, end); @@ -4629,15 +4665,20 @@ Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) if (selection->tracks.empty()) { - /* no regions or tracks selected, but entered regionview is valid - and we're in object mode - just use entered regionview + /* no regions or tracks selected */ - if (entered_regionview && (mouse_mode == Editing::MouseObject)) { + if (entered_regionview && mouse_mode == Editing::MouseObject) { + + /* entered regionview is valid and we're in object mode - + just use entered regionview + */ + rs.add (entered_regionview); - return; } + return; + } else { /* no regions selected, so get all regions at the edit point across @@ -4720,3 +4761,29 @@ Editor::show_rhythm_ferret () rhythm_ferret->show (); rhythm_ferret->present (); } + +void +Editor::first_idle () +{ + MessageDialog* dialog = 0; + + if (track_views.size() > 1) { + dialog = new MessageDialog (*this, + _("Please wait while Ardour loads visual data"), + true, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_NONE); + dialog->present (); + ARDOUR_UI::instance()->flush_pending (); + } + + for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) { + (*t)->first_idle(); + } + + if (dialog) { + delete dialog; + } + + _have_idled = true; +} diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 62d62a330f..6fe6d0207a 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -61,6 +61,7 @@ #include "editor_items.h" #include "region_selection.h" #include "canvas.h" +#include "time_axis_view.h" #include "draginfo.h" #include "tempo_lines.h" @@ -132,6 +133,8 @@ class Editor : public PublicEditor void connect_to_session (ARDOUR::Session *); ARDOUR::Session* current_session() const { return session; } + void first_idle (); + virtual bool have_idled() const { return _have_idled; } nframes_t leftmost_position() const { return leftmost_frame; } nframes_t current_page_frames() const { @@ -163,9 +166,11 @@ class Editor : public PublicEditor void add_imageframe_marker_time_axis(const std::string & track_name, TimeAxisView* marked_track, void*) ; void connect_to_image_compositor() ; void scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item) ; - TimeAxisView* get_named_time_axis(const std::string & name) ; #endif + TimeAxisView* get_named_time_axis(const std::string & name) ; + void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>); + RouteTimeAxisView* get_route_view_by_id (PBD::ID& id); void consider_auditioning (boost::shared_ptr<ARDOUR::Region>); @@ -181,6 +186,8 @@ class Editor : public PublicEditor void set_show_waveforms (bool yn); bool show_waveforms() const { return _show_waveforms; } + void set_waveform_scale (Editing::WaveformScale); + void set_show_waveforms_recording (bool yn); bool show_waveforms_recording() const { return _show_waveforms_recording; } @@ -225,14 +232,14 @@ class Editor : public PublicEditor */ if (pixel >= 0) { - return (nframes_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas.gobj())->pixels_per_unit); + return (nframes_t) rint (pixel * frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit); } else { return 0; } } gulong frame_to_pixel (nframes64_t frame) const { - return (gulong) rint ((frame / (frames_per_unit * GNOME_CANVAS(track_canvas.gobj())->pixels_per_unit))); + return (gulong) rint ((frame / (frames_per_unit * GNOME_CANVAS(track_canvas->gobj())->pixels_per_unit))); } void flush_canvas (); @@ -561,8 +568,8 @@ class Editor : public PublicEditor void set_canvas_cursor (); Gdk::Cursor* which_grabber_cursor (); - ArdourCanvas::CanvasAA track_canvas; - ArdourCanvas::CanvasAA time_canvas; + ArdourCanvas::Canvas* track_canvas; + ArdourCanvas::Canvas* time_canvas; ArdourCanvas::Text* first_action_message; ArdourCanvas::Text* verbose_canvas_cursor; @@ -596,7 +603,7 @@ class Editor : public PublicEditor ArdourCanvas::Group *transport_marker_group; ArdourCanvas::Group* cd_marker_group; - enum { + enum RulerType { ruler_metric_smpte = 0, ruler_metric_bbt = 1, ruler_metric_frames = 2, @@ -611,7 +618,16 @@ class Editor : public PublicEditor }; static GtkCustomMetric ruler_metrics[4]; - bool ruler_shown[10]; + Glib::RefPtr<Gtk::ToggleAction> ruler_timecode_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_bbt_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_samples_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_minsec_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_tempo_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_meter_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_marker_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_range_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_loop_punch_action; + Glib::RefPtr<Gtk::ToggleAction> ruler_cd_marker_action; bool no_ruler_shown_update; gint ruler_button_press (GdkEventButton*); @@ -629,6 +645,8 @@ class Editor : public PublicEditor void update_tempo_based_rulers (); void popup_ruler_menu (nframes_t where = 0, ItemType type = RegionItem); void update_ruler_visibility (); + void set_ruler_visible (RulerType, bool); + void toggle_ruler_visibility (RulerType rt); void ruler_toggled (int); gint ruler_label_button_release (GdkEventButton*); void store_ruler_visibility (); @@ -1018,7 +1036,7 @@ class Editor : public PublicEditor void cut_copy (Editing::CutCopyOp); bool can_cut_copy () const; void cut_copy_points (Editing::CutCopyOp); - void cut_copy_regions (Editing::CutCopyOp); + void cut_copy_regions (Editing::CutCopyOp, RegionSelection&); void cut_copy_ranges (Editing::CutCopyOp); void mouse_paste (); @@ -1135,7 +1153,10 @@ class Editor : public PublicEditor SoundFileOmega* sfbrowser; void bring_in_external_audio (Editing::ImportMode mode, nframes64_t& pos); + + void _do_import (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, ARDOUR::SrcQuality, nframes64_t&); void do_import (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, ARDOUR::SrcQuality, nframes64_t&); + bool idle_do_import (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, ARDOUR::SrcQuality, nframes64_t&); void _do_embed (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, nframes64_t&); void do_embed (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, nframes64_t&); @@ -1641,6 +1662,7 @@ public: void time_selection_changed (); void track_selection_changed (); void region_selection_changed (); + void sensitize_the_right_region_actions (bool have_selected_regions); void point_selection_changed (); void marker_selection_changed (); @@ -2172,7 +2194,7 @@ public: Gtk::ComboBoxText edit_point_selector; - void set_edit_point_preference (Editing::EditPoint ep); + void set_edit_point_preference (Editing::EditPoint ep, bool force = false); void cycle_edit_point (bool with_marker); void set_edit_point (); void edit_point_selection_done (); @@ -2203,6 +2225,20 @@ public: void snap_to_internal (nframes64_t& first, int32_t direction = 0, bool for_mark = false); RhythmFerret* rhythm_ferret; + + void set_track_height (TimeAxisView::TrackHeight h); + void set_track_height_largest (); + void set_track_height_large (); + void set_track_height_larger (); + void set_track_height_normal (); + void set_track_height_smaller (); + void set_track_height_small (); + + void remove_tracks (); + void toggle_tracks_active (); + void waveform_scale_chosen (Editing::WaveformScale); + + bool _have_idled; }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index d6e4a5a214..f1539757fb 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -18,6 +18,7 @@ */ #include <ardour/ardour.h> +#include <ardour/profile.h> #include "utils.h" #include "editor.h" @@ -67,6 +68,7 @@ Editor::register_actions () ActionManager::register_action (editor_actions, X_("PlayMenu"), _("Play")); ActionManager::register_action (editor_actions, X_("PrimaryClockMenu"), _("Primary Clock")); ActionManager::register_action (editor_actions, X_("Pullup"), _("Pullup / Pulldown")); + ActionManager::register_action (editor_actions, X_("RegionMenu"), _("Region")); ActionManager::register_action (editor_actions, X_("RegionEditOps"), _("Region operations")); ActionManager::register_action (editor_actions, X_("RegionGainMenu"), _("Gain")); ActionManager::register_action (editor_actions, X_("RulerMenu"), _("Rulers")); @@ -79,11 +81,15 @@ Editor::register_actions () ActionManager::register_action (editor_actions, X_("SetPunchMenu"), _("Punch")); ActionManager::register_action (editor_actions, X_("Solo"), _("Solo")); ActionManager::register_action (editor_actions, X_("Subframes"), _("Subframes")); + ActionManager::register_action (editor_actions, X_("SyncMenu"), _("Sync")); ActionManager::register_action (editor_actions, X_("TempoMenu"), _("Tempo")); ActionManager::register_action (editor_actions, X_("Timecode"), _("Timecode fps")); + ActionManager::register_action (editor_actions, X_("TrackHeightMenu"), _("Height")); + ActionManager::register_action (editor_actions, X_("TrackMenu"), _("Track")); ActionManager::register_action (editor_actions, X_("Tools"), _("Tools")); ActionManager::register_action (editor_actions, X_("TrimMenu"), _("Trim")); ActionManager::register_action (editor_actions, X_("View"), _("View")); + ActionManager::register_action (editor_actions, X_("WaveformMenu"), _("Waveforms")); ActionManager::register_action (editor_actions, X_("ZoomFocus"), _("Zoom")); ActionManager::register_action (editor_actions, X_("ZoomMenu"), _("Zoom")); ActionManager::register_action (editor_actions, X_("ZoomFocusMenu"), _("Zoom Focus")); @@ -265,32 +271,32 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "goto", _("goto"), mem_fun(*this, &Editor::goto_frame)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "center-playhead", _("to Center"), mem_fun(*this, &Editor::center_playhead)); + act = ActionManager::register_action (editor_actions, "center-playhead", _("Center Playhead"), mem_fun(*this, &Editor::center_playhead)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("to Center"), mem_fun(*this, &Editor::center_edit_point)); + act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("Center Active Marker"), mem_fun(*this, &Editor::center_edit_point)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "scroll-playhead-forward", _("Playhead forward"), bind (mem_fun(*this, &Editor::scroll_playhead), true));; + act = ActionManager::register_action (editor_actions, "scroll-playhead-forward", _("Playhead Forward"), bind (mem_fun(*this, &Editor::scroll_playhead), true));; ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "scroll-playhead-backward", _("Playhead Backward"), bind (mem_fun(*this, &Editor::scroll_playhead), false)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "playhead-to-edit", _("to Edit"), bind (mem_fun(*this, &Editor::cursor_align), true)); + act = ActionManager::register_action (editor_actions, "playhead-to-edit", _("Playhead To Active Mark"), bind (mem_fun(*this, &Editor::cursor_align), true)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("to Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false)); + act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("Active Mark To Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "trim-front", _("Trim start at edit point"), mem_fun(*this, &Editor::trim_region_front)); + act = ActionManager::register_action (editor_actions, "trim-front", _("Trim Start At Edit Point"), mem_fun(*this, &Editor::trim_region_front)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::region_selection_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "trim-back", _("Trim end at edit point"), mem_fun(*this, &Editor::trim_region_back)); + act = ActionManager::register_action (editor_actions, "trim-back", _("Trim End At Edit Point"), mem_fun(*this, &Editor::trim_region_back)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::region_selection_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "trim-from-start", _("Start to edit point"), mem_fun(*this, &Editor::trim_region_from_edit_point)); + act = ActionManager::register_action (editor_actions, "trim-from-start", _("Start To Edit Point"), mem_fun(*this, &Editor::trim_region_from_edit_point)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::region_selection_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "trim-to-end", _("Edit point to end"), mem_fun(*this, &Editor::trim_region_to_edit_point)); + act = ActionManager::register_action (editor_actions, "trim-to-end", _("Edit Point To End"), mem_fun(*this, &Editor::trim_region_to_edit_point)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::region_selection_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "trim-region-to-loop", _("Trim To Loop"), mem_fun(*this, &Editor::trim_region_to_loop)); @@ -357,9 +363,9 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "brush-at-mouse", _("Brush at Mouse"), mem_fun(*this, &Editor::kbd_brush)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "set-playhead", _("Set Playhead"), mem_fun(*this, &Editor::set_playhead_cursor)); + act = ActionManager::register_action (editor_actions, "set-playhead", _("Playhead to Mouse"), mem_fun(*this, &Editor::set_playhead_cursor)); ActionManager::session_sensitive_actions.push_back (act); - act = ActionManager::register_action (editor_actions, "set-edit-point", _("Set Edit Point"), mem_fun(*this, &Editor::set_edit_point)); + act = ActionManager::register_action (editor_actions, "set-edit-point", _("Edit Point to Mouse"), mem_fun(*this, &Editor::set_edit_point)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "duplicate-region", _("Duplicate Region"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)); @@ -505,6 +511,33 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "remove-last-capture", _("Remove Last Capture"), (mem_fun(*this, &Editor::remove_last_capture))); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "toggle-track-active", _("Toggle Active"), (mem_fun(*this, &Editor::toggle_tracks_active))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "remove-track", _("Remove"), (mem_fun(*this, &Editor::remove_tracks))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "track-height-largest", _("Largest"), (mem_fun(*this, &Editor::set_track_height_largest))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "track-height-larger", _("Larger"), (mem_fun(*this, &Editor::set_track_height_large))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "track-height-large", _("Large"), (mem_fun(*this, &Editor::set_track_height_larger))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "track-height-normal", _("Normal"), (mem_fun(*this, &Editor::set_track_height_normal))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "track-height-small", _("Small"), (mem_fun(*this, &Editor::set_track_height_smaller))); + ActionManager::track_selection_sensitive_actions.push_back (act); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "track-height-smaller", _("Smaller"), (mem_fun(*this, &Editor::set_track_height_small))); + ActionManager::session_sensitive_actions.push_back (act); + ActionManager::track_selection_sensitive_actions.push_back (act); + Glib::RefPtr<ActionGroup> zoom_actions = ActionGroup::create (X_("Zoom")); RadioAction::Group zoom_group; @@ -536,10 +569,6 @@ Editor::register_actions () ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-mouse"), _("Mouse"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead))); ActionManager::register_radio_action (editor_actions, edit_point_group, X_("edit-at-selected-marker"), _("Marker"), (bind (mem_fun(*this, &Editor::edit_point_chosen), Editing::EditAtPlayhead))); - ActionManager::register_action (editor_actions, "edit-point-marker", _("Marker"), bind (mem_fun (*this, &Editor::set_edit_point_preference), EditAtSelectedMarker)); - ActionManager::register_action (editor_actions, "edit-point-playhead", _("Playhead"), bind (mem_fun (*this, &Editor::set_edit_point_preference), EditAtPlayhead)); - ActionManager::register_action (editor_actions, "edit-point-mouse", _("Mouse"), bind (mem_fun (*this, &Editor::set_edit_point_preference), EditAtMouse)); - ActionManager::register_action (editor_actions, "cycle-edit-point", _("Change edit point"), bind (mem_fun (*this, &Editor::cycle_edit_point), false)); ActionManager::register_action (editor_actions, "cycle-edit-point-with-marker", _("Change edit point (w/Marker)"), bind (mem_fun (*this, &Editor::cycle_edit_point), true)); @@ -584,17 +613,36 @@ Editor::register_actions () /* RULERS */ Glib::RefPtr<ActionGroup> ruler_actions = ActionGroup::create (X_("Rulers")); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-tempo-ruler"), _("Tempo"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_tempo)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-meter-ruler"), _("Meter"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_meter)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-range-ruler"), _("Ranges"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_range_marker)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-marker-ruler"), _("Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_marker)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-cd-marker-ruler"), _("CD Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_cd_marker)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-loop-punch-ruler"), _("Loop/Punch"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_transport_marker)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-bbt-ruler"), _("Bars & Beats"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_frames)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-samples-ruler"), _("Samples"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_bbt)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-timecode-ruler"), _("Timecode"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_smpte)); - ActionManager::register_toggle_action (ruler_actions, X_("toggle-minsec-ruler"), _("Timecode"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_minsec)); - + ruler_tempo_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-tempo-ruler"), _("Tempo"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_tempo))); + ruler_meter_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-meter-ruler"), _("Meter"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_meter))); + ruler_range_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-range-ruler"), _("Ranges"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_range_marker))); + ruler_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-marker-ruler"), _("Markers"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_marker))); + ruler_cd_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-cd-marker-ruler"), _("CD Markers"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_cd_marker))); + ruler_loop_punch_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-loop-punch-ruler"), _("Loop/Punch"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_time_transport_marker))); + ruler_bbt_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-bbt-ruler"), _("Bars & Beats"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_frames))); + ruler_samples_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-samples-ruler"), _("Samples"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_bbt))); + ruler_timecode_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-timecode-ruler"), _("Timecode"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_smpte))); + ruler_minsec_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-minsec-ruler"), _("Min:Sec"), bind (mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_minsec))); + + /* set defaults here */ + + no_ruler_shown_update = true; + ruler_meter_action->set_active (true); + ruler_tempo_action->set_active (true); + ruler_marker_action->set_active (true); + ruler_range_action->set_active (true); + if (Profile->get_sae()) { + ruler_cd_marker_action->set_active (false); + ruler_timecode_action->set_active (false); + ruler_minsec_action->set_active (true); + } else { + ruler_cd_marker_action->set_active (true); + ruler_timecode_action->set_active (true); + ruler_minsec_action->set_active (false); + } + ruler_samples_action->set_active (false); + no_ruler_shown_update = false; + /* REGION LIST */ Glib::RefPtr<ActionGroup> rl_actions = ActionGroup::create (X_("RegionList")); @@ -647,10 +695,18 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Add External Media"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion)); ActionManager::session_sensitive_actions.push_back (act); - ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformVisibility"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility)); + ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility)); + ActionManager::track_selection_sensitive_actions.push_back (act); ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformsWhileRecording"), _("Show Waveforms While Recording"), mem_fun (*this, &Editor::toggle_waveforms_while_recording)); act = ActionManager::register_toggle_action (editor_actions, X_("ToggleMeasureVisibility"), _("Show Measures"), mem_fun (*this, &Editor::toggle_measure_visibility)); + + RadioAction::Group waveform_scale_group; + act = ActionManager::register_radio_action (editor_actions, waveform_scale_group, X_("linear-waveforms"), _("Linear"), bind (mem_fun (*this, &Editor::waveform_scale_chosen), Editing::LinearWaveform)); + ActionManager::track_selection_sensitive_actions.push_back (act); + act = ActionManager::register_radio_action (editor_actions, waveform_scale_group, X_("logarithmic-waveforms"), _("Logarithmic"), bind (mem_fun (*this, &Editor::waveform_scale_chosen), Editing::LogWaveform)); + ActionManager::track_selection_sensitive_actions.push_back (act); + /* if there is a logo in the editor canvas, its always visible at startup */ act = ActionManager::register_toggle_action (editor_actions, X_("ToggleLogoVisibility"), _("Show Logo"), mem_fun (*this, &Editor::toggle_logo_visibility)); @@ -704,9 +760,59 @@ Editor::register_actions () } void +Editor::toggle_ruler_visibility (RulerType rt) +{ + const char* action = 0; + + if (no_ruler_shown_update) { + return; + } + + switch (rt) { + case ruler_metric_smpte: + action = "toggle-timecode-ruler"; + break; + case ruler_metric_bbt: + action = "toggle-bbt-ruler"; + break; + case ruler_metric_frames: + action = "toggle-samples-ruler"; + break; + case ruler_metric_minsec: + action = "toggle-minsec-ruler"; + break; + case ruler_time_tempo: + action = "toggle-tempo-ruler"; + break; + case ruler_time_meter: + action = "toggle-meter-ruler"; + break; + case ruler_time_marker: + action = "toggle-marker-ruler"; + break; + case ruler_time_range_marker: + action = "toggle-range-ruler"; + break; + case ruler_time_transport_marker: + action = "toggle-loop-punch-ruler"; + break; + case ruler_time_cd_marker: + action = "toggle-cd-marker-ruler"; + break; + } + + Glib::RefPtr<Action> act = ActionManager::get_action (X_("Rulers"), action); + if (act) { + Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act); + update_ruler_visibility (); + store_ruler_visibility (); + } +} + +void Editor::toggle_waveform_visibility () { - Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility")); + Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-waveform-visible")); if (act) { Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act); set_show_waveforms (tact->get_active()); @@ -751,6 +857,33 @@ Editor::toggle_logo_visibility () } void +Editor::waveform_scale_chosen (Editing::WaveformScale ws) +{ + RefPtr<Action> act; + + /* this is driven by a toggle on a radio group, and so is invoked twice, + once for the item that became inactive and once for the one that became + active. + */ + + switch (ws) { + case LinearWaveform: + act = ActionManager::get_action (X_("Editor"), X_("linear-waveforms")); + break; + case LogWaveform: + act = ActionManager::get_action (X_("Editor"), X_("logarithmic-waveforms")); + break; + } + + if (act) { + RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act); + if (ract && ract->get_active()) { + set_waveform_scale (ws); + } + } +} + +void Editor::set_crossfade_model (CrossfadeModel model) { RefPtr<Action> act; @@ -1523,7 +1656,6 @@ Editor::parameter_changed (const char* parameter_name) update_just_smpte (); } else if (PARAM_IS ("show-track-meters")) { toggle_meter_updating(); - track_canvas_allocate(track_canvas.get_allocation()); } else if (PARAM_IS ("link-region-and-track-selection")) { ActionManager::map_some_state ("Editor", "link-region-and-track-selection", &Configuration::get_link_region_and_track_selection); } @@ -1534,5 +1666,5 @@ Editor::parameter_changed (const char* parameter_name) void Editor::reset_focus () { - track_canvas.grab_focus(); + track_canvas->grab_focus(); } diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index e13eb81181..fb6e2c8673 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -22,6 +22,7 @@ #include <sys/time.h> #include <errno.h> #include <unistd.h> +#include <algorithm> #include <sndfile.h> @@ -312,9 +313,26 @@ Editor::get_nth_selected_midi_track (int nth) const return mtv->midi_track(); } +bool +Editor::idle_do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos) +{ + _do_import (paths, chns, mode, quality, pos); + return false; +} + void Editor::do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos) { +#ifdef GTKOSX + Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_import), paths, chns, mode, quality, pos)); +#else + _do_import (paths, chns, mode, quality, pos); +#endif +} + +void +Editor::_do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos) +{ boost::shared_ptr<Track> track; vector<ustring> to_import; bool ok = true; @@ -324,7 +342,6 @@ Editor::do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mod build_interthread_progress_window (); } - if (chns == Editing::ImportMergeFiles) { /* create 1 region from all paths, add to 1 track, ignore "track" @@ -511,7 +528,6 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality qual interthread_progress_window->set_title (title.get_string()); interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE); - interthread_progress_window->show_all (); interthread_progress_bar.set_fraction (0.0f); interthread_cancel_label.set_text (_("Cancel Import")); current_interthread_info = &import_status; @@ -525,9 +541,9 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality qual import_status.replace_existing_source = replace; interthread_progress_connection = Glib::signal_timeout().connect - (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100); + (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 500); - track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); + track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); ARDOUR_UI::instance()->flush_pending (); /* start import thread for this spec. this will ultimately call Session::import_audiofiles() @@ -559,7 +575,7 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality qual } out: - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); return 0; } @@ -574,7 +590,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile, SoundFileInfo finfo; int ret = 0; - track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); + track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); ARDOUR_UI::instance()->flush_pending (); for (vector<Glib::ustring>::iterator p = paths.begin(); p != paths.end(); ++p) { @@ -674,7 +690,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile, } } - track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); + track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); for (int n = 0; n < finfo.channels; ++n) { try { @@ -684,6 +700,9 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile, boost::shared_ptr<Source> s; if ((s = session->source_by_path_and_channel (path, n)) == 0) { + + cerr << "add embed/import source with defer_peaks = true\n"; + source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *session, path, n, (mode == ImportAsTapeTrack ? @@ -713,7 +732,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile, ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track, true); out: - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); return ret; } @@ -915,6 +934,13 @@ Editor::import_thread () gint Editor::import_progress_timeout (void *arg) { + bool reset = false; + + if (!interthread_progress_window->is_visible()) { + interthread_progress_window->show_all (); + reset = true; + } + interthread_progress_label.set_text (import_status.doing_what); if (import_status.freeze) { @@ -927,9 +953,20 @@ Editor::import_progress_timeout (void *arg) interthread_progress_bar.pulse (); return FALSE; } else { - interthread_progress_bar.set_fraction (import_status.progress); + float val = import_status.progress; + interthread_progress_bar.set_fraction (min (max (0.0f, val), 1.0f)); } - return !(import_status.done || import_status.cancel); + if (reset) { + + /* the window is now visible, speed up the updates */ + + interthread_progress_connection.disconnect (); + interthread_progress_connection = Glib::signal_timeout().connect + (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100); + return false; + } else { + return !(import_status.done || import_status.cancel); + } } diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index e54109c7d6..1331ce8759 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -98,28 +98,36 @@ static void ardour_canvas_type_init() void Editor::initialize_canvas () { + if (getenv ("ARDOUR_NON_AA_CANVAS")) { + track_canvas = new ArdourCanvas::Canvas (); + time_canvas = new ArdourCanvas::Canvas (); + } else { + track_canvas = new ArdourCanvas::CanvasAA (); + time_canvas = new ArdourCanvas::CanvasAA (); + } + ArdourCanvas::init (); ardour_canvas_type_init (); /* don't try to center the canvas */ - track_canvas.set_center_scroll_region (false); - track_canvas.set_dither (Gdk::RGB_DITHER_NONE); + track_canvas->set_center_scroll_region (false); + track_canvas->set_dither (Gdk::RGB_DITHER_NONE); /* need to handle 4 specific types of events as catch-alls */ - track_canvas.signal_scroll_event().connect (mem_fun (*this, &Editor::track_canvas_scroll_event)); - track_canvas.signal_motion_notify_event().connect (mem_fun (*this, &Editor::track_canvas_motion_notify_event)); - track_canvas.signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event)); - track_canvas.signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event)); + track_canvas->signal_scroll_event().connect (mem_fun (*this, &Editor::track_canvas_scroll_event)); + track_canvas->signal_motion_notify_event().connect (mem_fun (*this, &Editor::track_canvas_motion_notify_event)); + track_canvas->signal_button_press_event().connect (mem_fun (*this, &Editor::track_canvas_button_press_event)); + track_canvas->signal_button_release_event().connect (mem_fun (*this, &Editor::track_canvas_button_release_event)); /* just scroll stuff for the timecanvas */ - time_canvas.signal_scroll_event().connect (mem_fun (*this, &Editor::time_canvas_scroll_event)); + time_canvas->signal_scroll_event().connect (mem_fun (*this, &Editor::time_canvas_scroll_event)); - track_canvas.set_name ("EditorMainCanvas"); - track_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); - track_canvas.signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas)); - track_canvas.set_flags (CAN_FOCUS); + track_canvas->set_name ("EditorMainCanvas"); + track_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK|Gdk::SCROLL_MASK); + track_canvas->signal_leave_notify_event().connect (mem_fun(*this, &Editor::left_track_canvas)); + track_canvas->set_flags (CAN_FOCUS); /* set up drag-n-drop */ @@ -133,14 +141,14 @@ Editor::initialize_canvas () target_table.push_back (TargetEntry ("text/uri-list")); target_table.push_back (TargetEntry ("application/x-rootwin-drop")); - track_canvas.drag_dest_set (target_table); - track_canvas.signal_drag_data_received().connect (mem_fun(*this, &Editor::track_canvas_drag_data_received)); + track_canvas->drag_dest_set (target_table); + track_canvas->signal_drag_data_received().connect (mem_fun(*this, &Editor::track_canvas_drag_data_received)); /* stuff for the verbose canvas cursor */ Pango::FontDescription* font = get_font_for_style (N_("VerboseCanvasCursor")); - verbose_canvas_cursor = new ArdourCanvas::Text (*track_canvas.root()); + verbose_canvas_cursor = new ArdourCanvas::Text (*track_canvas->root()); verbose_canvas_cursor->property_font_desc() = *font; verbose_canvas_cursor->property_anchor() = ANCHOR_NW; @@ -150,7 +158,7 @@ Editor::initialize_canvas () if (Profile->get_sae()) { Image img (::get_icon (X_("saelogo"))); - logo_item = new ArdourCanvas::Pixbuf (*track_canvas.root(), 0.0, 0.0, img.get_pixbuf()); + logo_item = new ArdourCanvas::Pixbuf (*track_canvas->root(), 0.0, 0.0, img.get_pixbuf()); // logo_item->property_height_in_pixels() = true; // logo_item->property_width_in_pixels() = true; // logo_item->property_height_set() = true; @@ -160,34 +168,38 @@ Editor::initialize_canvas () /* a group to hold time (measure) lines */ - time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0); - tempo_lines = new TempoLines(track_canvas, time_line_group); - cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0); - time_canvas.set_name ("EditorTimeCanvas"); - time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK); - time_canvas.set_flags (CAN_FOCUS); - time_canvas.set_center_scroll_region (false); - time_canvas.set_dither (Gdk::RGB_DITHER_NONE); - - marker_time_line_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0); - marker_tempo_lines = new TempoLines(time_canvas, marker_time_line_group); - - meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0); - tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height); - range_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0); - transport_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 3.0); - marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 4.0); - cd_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 5.0); + time_line_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0); + tempo_lines = new TempoLines(*track_canvas, time_line_group); + cursor_group = new ArdourCanvas::Group (*track_canvas->root(), 0.0, 0.0); + + time_canvas->set_name ("EditorTimeCanvas"); + time_canvas->add_events (Gdk::POINTER_MOTION_HINT_MASK); + time_canvas->set_flags (CAN_FOCUS); + time_canvas->set_center_scroll_region (false); + time_canvas->set_dither (Gdk::RGB_DITHER_NONE); + + marker_time_line_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0); + marker_tempo_lines = new TempoLines(*time_canvas, marker_time_line_group); + + meter_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, 0.0); + tempo_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height); + range_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 2.0); + transport_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 3.0); + marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 4.0); + cd_marker_group = new ArdourCanvas::Group (*time_canvas->root(), 0.0, timebar_height * 5.0); tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + tempo_bar->property_outline_what() = (0x1 | 0x8); tempo_bar->property_outline_pixels() = 1; meter_bar = new ArdourCanvas::SimpleRect (*meter_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + meter_bar->property_outline_what() = (0x1 | 0x8); meter_bar->property_outline_pixels() = 1; marker_bar = new ArdourCanvas::SimpleRect (*marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + marker_bar->property_outline_what() = (0x1 | 0x8); marker_bar->property_outline_pixels() = 1; @@ -200,11 +212,12 @@ Editor::initialize_canvas () range_marker_bar->property_outline_pixels() = 1; transport_marker_bar = new ArdourCanvas::SimpleRect (*transport_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); + transport_marker_bar->property_outline_what() = (0x1 | 0x8); transport_marker_bar->property_outline_pixels() = 1; - + cd_marker_bar_drag_rect = new ArdourCanvas::SimpleRect (*cd_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); - cd_marker_bar_drag_rect->property_outline_pixels() = 0; + // cd_marker_bar_drag_rect->property_outline_pixels() = 0; cd_marker_bar_drag_rect->hide (); range_bar_drag_rect = new ArdourCanvas::SimpleRect (*range_marker_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0); @@ -218,12 +231,12 @@ Editor::initialize_canvas () marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0)); marker_drag_line_points.push_back(Gnome::Art::Point(0.0, 0.0)); - marker_drag_line = new ArdourCanvas::Line (*track_canvas.root()); + marker_drag_line = new ArdourCanvas::Line (*track_canvas->root()); marker_drag_line->property_width_pixels() = 1; marker_drag_line->property_points() = marker_drag_line_points; marker_drag_line->hide(); - range_marker_drag_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0); + range_marker_drag_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); range_marker_drag_rect->hide (); transport_loop_range_rect = new ArdourCanvas::SimpleRect (*time_line_group, 0.0, 0.0, 0.0, 0.0); @@ -251,14 +264,14 @@ Editor::initialize_canvas () transport_punchout_line->hide(); // used to show zoom mode active zooming - zoom_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0); + zoom_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); zoom_rect->property_outline_pixels() = 1; zoom_rect->hide(); zoom_rect->signal_event().connect (bind (mem_fun (*this, &Editor::canvas_zoom_rect_event), (ArdourCanvas::Item*) 0)); // used as rubberband rect - rubberband_rect = new ArdourCanvas::SimpleRect (*track_canvas.root(), 0.0, 0.0, 0.0, 0.0); + rubberband_rect = new ArdourCanvas::SimpleRect (*track_canvas->root(), 0.0, 0.0, 0.0, 0.0); rubberband_rect->property_outline_pixels() = 1; rubberband_rect->hide(); @@ -274,12 +287,12 @@ Editor::initialize_canvas () double time_height = timebar_height * 5; double time_width = FLT_MAX/frames_per_unit; - time_canvas.set_scroll_region(0.0, 0.0, time_width, time_height); + time_canvas->set_scroll_region(0.0, 0.0, time_width, time_height); playhead_cursor = new Cursor (*this, &Editor::canvas_playhead_cursor_event); initial_ruler_update_required = true; - track_canvas.signal_size_allocate().connect (mem_fun(*this, &Editor::track_canvas_allocate)); + track_canvas->signal_size_allocate().connect (mem_fun(*this, &Editor::track_canvas_allocate)); if (logo_item) { logo_item->lower_to_bottom (); @@ -382,10 +395,10 @@ Editor::reset_scrolling_region (Gtk::Allocation* alloc) double last_canvas_unit = max ((last_canvas_frame / frames_per_unit), canvas_width); - track_canvas.set_scroll_region (0.0, 0.0, last_canvas_unit, pos); + track_canvas->set_scroll_region (0.0, 0.0, last_canvas_unit, pos); // XXX what is the correct height value for the time canvas ? this overstates it - time_canvas.set_scroll_region ( 0.0, 0.0, last_canvas_unit, canvas_height); + time_canvas->set_scroll_region ( 0.0, 0.0, last_canvas_unit, canvas_height); range_marker_drag_rect->property_y2() = canvas_height; transport_loop_range_rect->property_y2() = canvas_height; @@ -441,14 +454,14 @@ Editor::controls_layout_size_request (Requisition* req) bool Editor::track_canvas_map_handler (GdkEventAny* ev) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); return false; } bool Editor::time_canvas_map_handler (GdkEventAny* ev) { - time_canvas.get_window()->set_cursor (*timebar_cursor); + time_canvas->get_window()->set_cursor (*timebar_cursor); return false; } @@ -495,7 +508,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, double wx; double wy; - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->window_to_world (x, y, wx, wy); wx += horizontal_adjustment.get_value(); wy += vertical_adjustment.get_value(); @@ -511,7 +524,11 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, /* drop onto canvas background: create new tracks */ - do_embed (paths, Editing::ImportDistinctFiles, ImportAsTrack, frame); + if (Profile->get_sae() || Config->get_only_copy_imported_files()) { + do_import (paths, Editing::ImportDistinctFiles, Editing::ImportAsTrack, SrcBest, frame); + } else { + do_embed (paths, Editing::ImportDistinctFiles, ImportAsTrack, frame); + } } else if ((tv = dynamic_cast<RouteTimeAxisView*>(tvp)) != 0) { @@ -522,7 +539,12 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, if (tv->get_diskstream()) { /* select the track, then embed */ selection->set (tv); - do_embed (paths, Editing::ImportDistinctFiles, ImportToTrack, frame); + + if (Profile->get_sae() || Config->get_only_copy_imported_files()) { + do_import (paths, Editing::ImportDistinctFiles, Editing::ImportToTrack, SrcBest, frame); + } else { + do_embed (paths, Editing::ImportDistinctFiles, ImportToTrack, frame); + } } } @@ -855,3 +877,12 @@ Editor::color_handler() session->tempo_map().apply_with_metrics (*this, &Editor::draw_metric_marks); // redraw metric markers } + +void +Editor::flush_canvas () +{ + if (is_mapped()) { + track_canvas->update_now (); + // gdk_window_process_updates (GTK_LAYOUT(track_canvas->gobj())->bin_window, true); + } +} diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 3de7dc5c21..d5c1305f66 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -67,8 +67,8 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) if we're in mid zoom, so we have to get the damn mouse pointer again */ - track_canvas.get_pointer (x, y); - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->get_pointer (x, y); + track_canvas->window_to_world (x, y, wx, wy); wx += horizontal_adjustment.get_value(); wy += vertical_adjustment.get_value(); @@ -102,8 +102,8 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) case GDK_SCROLL_DOWN: if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { //if (ev->state == GDK_CONTROL_MASK) { - track_canvas.get_pointer (x, y); - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->get_pointer (x, y); + track_canvas->window_to_world (x, y, wx, wy); wx += horizontal_adjustment.get_value(); wy += vertical_adjustment.get_value(); @@ -163,7 +163,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) bool Editor::track_canvas_scroll_event (GdkEventScroll *event) { - track_canvas.grab_focus(); + track_canvas->grab_focus(); track_canvas_scroll (event); return false; } @@ -212,7 +212,7 @@ Editor::time_canvas_scroll (GdkEventScroll* ev) bool Editor::time_canvas_scroll_event (GdkEventScroll *event) { - time_canvas.grab_focus(); + time_canvas->grab_focus(); time_canvas_scroll (event); return false; } @@ -221,7 +221,7 @@ bool Editor::track_canvas_button_press_event (GdkEventButton *event) { selection->clear (); - track_canvas.grab_focus(); + track_canvas->grab_focus(); return false; } @@ -239,7 +239,7 @@ Editor::track_canvas_motion_notify_event (GdkEventMotion *event) { int x, y; /* keep those motion events coming */ - track_canvas.get_pointer (x, y); + track_canvas->get_pointer (x, y); return false; } diff --git a/gtk2_ardour/editor_imageframe.cc b/gtk2_ardour/editor_imageframe.cc index eb78fb5c7f..68d061696e 100644 --- a/gtk2_ardour/editor_imageframe.cc +++ b/gtk2_ardour/editor_imageframe.cc @@ -1080,7 +1080,7 @@ void Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src) { ImageFrameTimeAxis* iftav ; - iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ; + iftav = new ImageFrameTimeAxis(track_name, *this, *session, *track_canvas) ; iftav->set_time_axis_name(track_name, this) ; track_views.push_back(iftav) ; @@ -1097,7 +1097,7 @@ Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* sr void Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track) { - MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ; + MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), *track_canvas, track_name, marked_track) ; ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ; track_views.push_back(mta) ; diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc index 4a5d55d879..6d8bbda6fd 100644 --- a/gtk2_ardour/editor_keyboard.cc +++ b/gtk2_ardour/editor_keyboard.cc @@ -39,7 +39,7 @@ Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, b double worldx, worldy; GdkEvent ev; Gdk::ModifierType mask; - Glib::RefPtr<Gdk::Window> evw = track_canvas.get_window()->get_pointer (x, y, mask); + Glib::RefPtr<Gdk::Window> evw = track_canvas->get_window()->get_pointer (x, y, mask); bool doit = false; if (use_track_canvas && track_canvas_event_box.get_window()->get_pointer(x, y, mask) != 0) { @@ -62,7 +62,7 @@ Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, b selection->set (entered_regionview); } - track_canvas.window_to_world (x, y, worldx, worldy); + track_canvas->window_to_world (x, y, worldx, worldy); worldx += horizontal_adjustment.get_value(); worldy += vertical_adjustment.get_value(); diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 084f75124d..4b0ba07b77 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -79,7 +79,7 @@ Editor::add_new_location (Location *location) if (location->is_mark()) { - if (location->is_cd_marker() && ruler_shown[ruler_time_cd_marker]) { + if (location->is_cd_marker() && ruler_cd_marker_action->get_active()) { lam->start = new Marker (*this, *cd_marker_group, color, location->name(), Marker::Mark, location->start()); } else { @@ -103,7 +103,7 @@ Editor::add_new_location (Location *location) } else { // range marker - if (location->is_cd_marker() && ruler_shown[ruler_time_cd_marker]) { + if (location->is_cd_marker() && ruler_cd_marker_action->get_active()) { lam->start = new Marker (*this, *cd_marker_group, color, location->name(), Marker::Start, location->start()); lam->end = new Marker (*this, *cd_marker_group, color, @@ -212,7 +212,7 @@ void Editor::update_cd_marker_display () void Editor::ensure_cd_marker_updated (LocationMarkers * lam, Location * location) { if (location->is_cd_marker() - && (ruler_shown[ruler_time_cd_marker] && lam->start->get_parent() != cd_marker_group)) + && (ruler_cd_marker_action->get_active() && lam->start->get_parent() != cd_marker_group)) { //cerr << "reparenting non-cd marker so it can be relocated: " << location->name() << endl; if (lam->start) { @@ -222,7 +222,7 @@ void Editor::ensure_cd_marker_updated (LocationMarkers * lam, Location * locatio lam->end->reparent (*cd_marker_group); } } - else if ( (!location->is_cd_marker() || !ruler_shown[ruler_time_cd_marker]) + else if ( (!location->is_cd_marker() || !ruler_cd_marker_action->get_active()) && (lam->start->get_parent() == cd_marker_group)) { //cerr << "reparenting non-cd marker so it can be relocated: " << location->name() << endl; @@ -1113,7 +1113,7 @@ Editor::update_punch_range_view (bool visibility) double x2 = frame_to_pixel (tpl->end()); guint track_canvas_width,track_canvas_height; - track_canvas.get_size(track_canvas_width,track_canvas_height); + track_canvas->get_size(track_canvas_width,track_canvas_height); transport_punch_range_rect->property_x1() = x1; transport_punch_range_rect->property_x2() = x2; diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index dfa617d082..b732487740 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -305,6 +305,8 @@ Editor::current_mixer_strip_hidden () void Editor::session_going_away () { + _have_idled = false; + for (vector<sigc::connection>::iterator i = session_connections.begin(); i != session_connections.end(); ++i) { (*i).disconnect (); } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index eef83e819e..22215ecb62 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -82,21 +82,21 @@ Editor::mouse_frame (nframes64_t& where, bool& in_track_canvas) const int x, y; double wx, wy; Gdk::ModifierType mask; - Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas.get_window(); + Glib::RefPtr<Gdk::Window> canvas_window = const_cast<Editor*>(this)->track_canvas->get_window(); Glib::RefPtr<const Gdk::Window> pointer_window; pointer_window = canvas_window->get_pointer (x, y, mask); - if (pointer_window == track_canvas.get_bin_window()) { + if (pointer_window == track_canvas->get_bin_window()) { - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->window_to_world (x, y, wx, wy); in_track_canvas = true; } else { in_track_canvas = false; - if (pointer_window == time_canvas.get_bin_window()) { - time_canvas.window_to_world (x, y, wx, wy); + if (pointer_window == time_canvas->get_bin_window()) { + time_canvas->window_to_world (x, y, wx, wy); } else { return false; } @@ -134,18 +134,18 @@ Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) const case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: - track_canvas.w2c(event->button.x, event->button.y, *pcx, *pcy); + track_canvas->w2c(event->button.x, event->button.y, *pcx, *pcy); break; case GDK_MOTION_NOTIFY: - track_canvas.w2c(event->motion.x, event->motion.y, *pcx, *pcy); + track_canvas->w2c(event->motion.x, event->motion.y, *pcx, *pcy); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: - track_canvas.w2c(event->crossing.x, event->crossing.y, *pcx, *pcy); + track_canvas->w2c(event->crossing.x, event->crossing.y, *pcx, *pcy); break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: - // track_canvas.w2c(event->key.x, event->key.y, *pcx, *pcy); + // track_canvas->w2c(event->key.x, event->key.y, *pcx, *pcy); break; default: warning << string_compose (_("Editor::event_frame() used on unhandled event type %1"), event->type) << endmsg; @@ -262,7 +262,7 @@ Editor::set_canvas_cursor () } if (is_drawable()) { - track_canvas.get_window()->set_cursor(*current_canvas_cursor); + track_canvas->get_window()->set_cursor(*current_canvas_cursor); } } @@ -463,7 +463,7 @@ Editor::set_midi_edit_mode (MidiEditMode m, bool force) set_midi_edit_cursor (current_midi_edit_mode()); if (is_drawable()) { - track_canvas.get_window()->set_cursor(*current_canvas_cursor); + track_canvas->get_window()->set_cursor(*current_canvas_cursor); } } @@ -581,7 +581,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it bool Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { - track_canvas.grab_focus(); + track_canvas->grab_focus(); if (session && session->actively_recording()) { return true; @@ -851,7 +851,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp scrub_reverse_distance = 0; last_scrub_x = event->button.x; scrubbing_direction = 0; - track_canvas.get_window()->set_cursor (*transparent_cursor); + track_canvas->get_window()->set_cursor (*transparent_cursor); /* rest handled in motion & release */ break; @@ -1197,7 +1197,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MouseAudition: _scrubbing = false; - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); if (scrubbing_direction == 0) { /* no drag, just a click */ switch (item_type) { @@ -1293,7 +1293,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ fraction = 1.0 - (cp->get_y() / cp->line().height()); if (is_drawable() && !_scrubbing) { - track_canvas.get_window()->set_cursor (*fader_cursor); + track_canvas->get_window()->set_cursor (*fader_cursor); } last_item_entered_n++; @@ -1310,7 +1310,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ if (line) line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EnteredGainLine.get(); if (is_drawable()) { - track_canvas.get_window()->set_cursor (*fader_cursor); + track_canvas->get_window()->set_cursor (*fader_cursor); } } break; @@ -1323,14 +1323,14 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EnteredAutomationLine.get(); } if (is_drawable()) { - track_canvas.get_window()->set_cursor (*fader_cursor); + track_canvas->get_window()->set_cursor (*fader_cursor); } } break; case RegionViewNameHighlight: if (is_drawable() && mouse_mode == MouseObject) { - track_canvas.get_window()->set_cursor (*trimmer_cursor); + track_canvas->get_window()->set_cursor (*trimmer_cursor); } break; @@ -1345,7 +1345,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ #endif if (is_drawable()) { - track_canvas.get_window()->set_cursor (*trimmer_cursor); + track_canvas->get_window()->set_cursor (*trimmer_cursor); } break; @@ -1353,10 +1353,10 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ if (is_drawable()) { switch (_edit_point) { case EditAtMouse: - track_canvas.get_window()->set_cursor (*grabber_edit_point_cursor); + track_canvas->get_window()->set_cursor (*grabber_edit_point_cursor); break; default: - track_canvas.get_window()->set_cursor (*grabber_cursor); + track_canvas->get_window()->set_cursor (*grabber_cursor); break; } } @@ -1368,7 +1368,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) { if (mouse_mode == MouseObject && is_drawable()) { - track_canvas.get_window()->set_cursor (*trimmer_cursor); + track_canvas->get_window()->set_cursor (*trimmer_cursor); } } break; @@ -1389,7 +1389,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; } - track_canvas.get_window()->set_cursor (*cursor); + track_canvas->get_window()->set_cursor (*cursor); AutomationTimeAxisView* atv; if ((atv = static_cast<AutomationTimeAxisView*>(item->get_data ("trackview"))) != 0) { @@ -1406,7 +1406,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case MeterBarItem: case TempoBarItem: if (is_drawable()) { - time_canvas.get_window()->set_cursor (*timebar_cursor); + time_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1420,7 +1420,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case MeterMarkerItem: case TempoMarkerItem: if (is_drawable()) { - time_canvas.get_window()->set_cursor (*timebar_cursor); + time_canvas->get_window()->set_cursor (*timebar_cursor); } break; case FadeInHandleItem: @@ -1481,7 +1481,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ } if (is_drawable()) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } hide_verbose_canvas_cursor (); @@ -1500,7 +1500,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ #endif if (is_drawable()) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } break; @@ -1513,7 +1513,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ line->property_fill_color_rgba() = al->get_line_color(); } if (is_drawable()) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } break; @@ -1521,7 +1521,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ /* see enter_handler() for notes */ if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) { if (is_drawable() && mouse_mode == MouseObject) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } } break; @@ -1533,7 +1533,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case TempoBarItem: case MarkerBarItem: if (is_drawable()) { - time_canvas.get_window()->set_cursor (*timebar_cursor); + time_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1550,7 +1550,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case TempoMarkerItem: if (is_drawable()) { - time_canvas.get_window()->set_cursor (*timebar_cursor); + time_canvas->get_window()->set_cursor (*timebar_cursor); } break; @@ -1569,7 +1569,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case AutomationTrackItem: if (is_drawable()) { - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); clear_entered_track = true; Glib::signal_idle().connect (mem_fun(*this, &Editor::left_automation_track)); } @@ -1607,7 +1607,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item event might do, its a good tradeoff. */ - track_canvas.get_pointer (x, y); + track_canvas->get_pointer (x, y); } if (current_stepping_trackview) { @@ -2750,8 +2750,9 @@ Editor::start_control_point_grab (ArdourCanvas::Item* item, GdkEvent* event) // the point doesn't 'jump' to the mouse after the first drag drag_info.grab_x = control_point->get_x(); drag_info.grab_y = control_point->get_y(); + control_point->line().parent_group().i2w(drag_info.grab_x, drag_info.grab_y); - track_canvas.w2c(drag_info.grab_x, drag_info.grab_y, drag_info.grab_x, drag_info.grab_y); + track_canvas->w2c(drag_info.grab_x, drag_info.grab_y, drag_info.grab_x, drag_info.grab_y); drag_info.grab_frame = pixel_to_frame(drag_info.grab_x); @@ -4080,7 +4081,15 @@ Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, d return; } - switch (Profile->get_small_screen() ? ARDOUR_UI::instance()->primary_clock.mode () : ARDOUR_UI::instance()->secondary_clock.mode ()) { + AudioClock::Mode m; + + if (Profile->get_sae() || Profile->get_small_screen()) { + m = ARDOUR_UI::instance()->primary_clock.mode(); + } else { + m = ARDOUR_UI::instance()->secondary_clock.mode(); + } + + switch (m) { case AudioClock::BBT: session->bbt_time (frame, bbt); snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, bbt.bars, bbt.beats, bbt.ticks); @@ -4132,7 +4141,15 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off return; } - switch (ARDOUR_UI::instance()->secondary_clock.mode ()) { + AudioClock::Mode m; + + if (Profile->get_sae() || Profile->get_small_screen()) { + m = ARDOUR_UI::instance()->primary_clock.mode (); + } else { + m = ARDOUR_UI::instance()->secondary_clock.mode (); + } + + switch (m) { case AudioClock::BBT: session->bbt_time (start, sbbt); session->bbt_time (end, ebbt); @@ -4187,6 +4204,7 @@ Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double off else { set_verbose_canvas_cursor (buf, drag_info.current_pointer_x + offset, drag_info.current_pointer_y + offset); } + show_verbose_canvas_cursor (); } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 0be6221be5..2614dab71e 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2093,7 +2093,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y) RouteTimeAxisView *rtv = 0; boost::shared_ptr<Playlist> playlist; - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->window_to_world (x, y, wx, wy); wx += horizontal_adjustment.get_value(); wy += vertical_adjustment.get_value(); @@ -2139,7 +2139,7 @@ Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y) { RouteTimeAxisView *dest_rtv = 0; RouteTimeAxisView *source_rtv = 0; - track_canvas.window_to_world (x, y, wx, wy); + track_canvas->window_to_world (x, y, wx, wy); wx += horizontal_adjustment.get_value(); wy += vertical_adjustment.get_value(); @@ -2310,14 +2310,19 @@ Editor::play_from_edit_point_and_return () nframes64_t start_frame; nframes64_t return_frame; + start_frame = get_preferred_edit_position (true); + + if (session->transport_rolling()) { + session->request_locate (start_frame, false); + return; + } + /* don't reset the return frame if its already set */ if ((return_frame = session->requested_return_frame()) < 0) { return_frame = session->audible_frame(); } - start_frame = get_preferred_edit_position (true); - if (start_frame >= 0) { session->request_roll_at_and_return (start_frame, return_frame); } @@ -2710,8 +2715,8 @@ Editor::separate_regions_between (const TimeSelection& ts) } if (tmptracks.empty()) { - /* no regions selected: use all tracks */ - tmptracks = track_views; + /* no regions selected: do nothing */ + return; } } else { @@ -3119,7 +3124,7 @@ Editor::align (RegionPoint what) { RegionSelection rs; - get_regions_for_action (rs, false); + get_regions_for_action (rs); nframes64_t where = get_preferred_edit_position(); if (!rs.empty()) { @@ -3138,7 +3143,7 @@ Editor::align_relative (RegionPoint what) nframes64_t where = get_preferred_edit_position(); RegionSelection rs; - get_regions_for_action (rs, false); + get_regions_for_action (rs); if (!rs.empty()) { align_selection_relative (what, where, rs); @@ -3518,7 +3523,7 @@ Editor::freeze_route () pthread_attr_destroy(&attr); - track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); + track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); while (!itt.done && !itt.cancel) { gtk_main_iteration (); @@ -3527,7 +3532,7 @@ Editor::freeze_route () interthread_progress_connection.disconnect (); interthread_progress_window->hide_all (); current_interthread_info = 0; - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } void @@ -3655,7 +3660,11 @@ Editor::cut_copy (CutCopyOp op) RegionSelection rs; - get_regions_for_action (rs); + /* we only want to cut regions if some are selected */ + + if (!selection->regions.empty()) { + get_regions_for_action (rs); + } switch (current_mouse_mode()) { case MouseObject: @@ -3664,7 +3673,7 @@ Editor::cut_copy (CutCopyOp op) begin_reversible_command (opname + _(" objects")); if (!rs.empty()) { - cut_copy_regions (op); + cut_copy_regions (op, rs); if (op == Cut) { selection->clear_regions (); @@ -3751,7 +3760,7 @@ struct PlaylistMapping { * @param op Operation (Cut, Copy or Clear) */ void -Editor::cut_copy_regions (CutCopyOp op) +Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs) { /* we can't use a std::map here because the ordering is important, and we can't trivially sort a map when we want ordered access to both elements. i think. @@ -3766,9 +3775,6 @@ Editor::cut_copy_regions (CutCopyOp op) /* get ordering correct before we cut/copy */ - RegionSelection rs; - - get_regions_for_action (rs); rs.sort_by_position_and_track (); for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) { @@ -3889,9 +3895,14 @@ void Editor::cut_copy_ranges (CutCopyOp op) { TrackSelection* ts; + TrackSelection entered; if (selection->tracks.empty()) { - ts = &track_views; + if (!entered_track) { + return; + } + entered.push_back (entered_track); + ts = &entered; } else { ts = &selection->tracks; } @@ -4220,7 +4231,7 @@ Editor::normalize_region () begin_reversible_command (_("normalize")); - track_canvas.get_window()->set_cursor (*wait_cursor); + track_canvas->get_window()->set_cursor (*wait_cursor); gdk_flush (); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { @@ -4233,7 +4244,7 @@ Editor::normalize_region () } commit_reversible_command (); - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } @@ -4356,7 +4367,7 @@ Editor::apply_filter (Filter& filter, string command) begin_reversible_command (command); - track_canvas.get_window()->set_cursor (*wait_cursor); + track_canvas->get_window()->set_cursor (*wait_cursor); gdk_flush (); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { @@ -4392,7 +4403,7 @@ Editor::apply_filter (Filter& filter, string command) rs.clear (); out: - track_canvas.get_window()->set_cursor (*current_canvas_cursor); + track_canvas->get_window()->set_cursor (*current_canvas_cursor); } void @@ -5531,3 +5542,169 @@ Editor::playhead_backward_to_grid () } } +void +Editor::set_track_height (TimeAxisView::TrackHeight h) +{ + TrackSelection& ts (selection->tracks); + + if (ts.empty()) { + return; + } + + for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { + (*x)->set_height (h); + } +} + +void +Editor::set_track_height_largest () +{ + set_track_height (TimeAxisView::Largest); +} +void +Editor::set_track_height_large () +{ + set_track_height (TimeAxisView::Large); +} +void +Editor::set_track_height_larger () +{ + set_track_height (TimeAxisView::Larger); +} +void +Editor::set_track_height_normal () +{ + set_track_height (TimeAxisView::Normal); +} +void +Editor::set_track_height_smaller () +{ + set_track_height (TimeAxisView::Smaller); +} +void +Editor::set_track_height_small () +{ + set_track_height (TimeAxisView::Small); +} + +void +Editor::toggle_tracks_active () +{ + TrackSelection& ts (selection->tracks); + bool first = true; + bool target = false; + + if (ts.empty()) { + return; + } + + for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*x); + + if (rtv) { + if (first) { + target = !rtv->_route->active(); + first = false; + } + rtv->_route->set_active (target); + } + } +} + +void +Editor::remove_tracks () +{ + TrackSelection& ts (selection->tracks); + + if (ts.empty()) { + return; + } + + vector<string> choices; + string prompt; + int ntracks = 0; + int nbusses = 0; + const char* trackstr; + const char* busstr; + vector<boost::shared_ptr<Route> > routes; + + for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*x); + if (rtv) { + if (rtv->is_track()) { + ntracks++; + } else { + nbusses++; + } + } + routes.push_back (rtv->_route); + } + + if (ntracks + nbusses == 0) { + return; + } + + if (ntracks > 1) { + trackstr = _("tracks"); + } else { + trackstr = _("track"); + } + + if (nbusses > 1) { + busstr = _("busses"); + } else { + busstr = _("bus"); + } + + if (ntracks) { + if (nbusses) { + prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?\n" + "(You may also lose the playlists associated with the %2)\n\n" + "This action cannot be undone!"), + ntracks, trackstr, nbusses, busstr); + } else { + prompt = string_compose (_("Do you really want to remove %1 %2?\n" + "(You may also lose the playlists associated with the %2)\n\n" + "This action cannot be undone!"), + ntracks, trackstr); + } + } else if (nbusses) { + prompt = string_compose (_("Do you really want to remove %1 %2?"), + nbusses, busstr); + } + + choices.push_back (_("No, do nothing.")); + if (ntracks + nbusses > 1) { + choices.push_back (_("Yes, remove them.")); + } else { + choices.push_back (_("Yes, remove it.")); + } + + Choice prompter (prompt, choices); + + if (prompter.run () != 1) { + return; + } + + for (vector<boost::shared_ptr<Route> >::iterator x = routes.begin(); x != routes.end(); ++x) { + session->remove_route (*x); + } +} + +void +Editor::set_waveform_scale (WaveformScale ws) +{ + TrackSelection& ts (selection->tracks); + + if (ts.empty()) { + return; + } + + for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (*x); + if (atv) { + atv->set_waveform_scale (ws); + } + } +} + diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index ee15602f34..c9067cacfe 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -75,8 +75,6 @@ Editor::region_hidden (boost::shared_ptr<Region> r) void Editor::add_regions_to_region_display (vector<boost::weak_ptr<Region> >& regions) { - cerr << "Adding " << regions.size() << " to region list\n"; - region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0)); for (vector<boost::weak_ptr<Region> >::iterator x = regions.begin(); x != regions.end(); ++x) { boost::shared_ptr<Region> region ((*x).lock()); @@ -414,7 +412,7 @@ Editor::region_list_display_button_press (GdkEventButton *ev) int cellx; int celly; - cerr << "Button press release, button = " << ev->button << endl; + // cerr << "Button press release, button = " << ev->button << endl; if (region_list_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { if ((iter = region_list_model->get_iter (path))) { diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index d7611d7cdf..65202cb0db 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -66,11 +66,12 @@ Editor::handle_new_route (Session::RouteList& routes) } if (route->default_type() == ARDOUR::DataType::AUDIO) - tv = new AudioTimeAxisView (*this, *session, route, track_canvas); + tv = new AudioTimeAxisView (*this, *session, route, *track_canvas); else if (route->default_type() == ARDOUR::DataType::MIDI) - tv = new MidiTimeAxisView (*this, *session, route, track_canvas); + tv = new MidiTimeAxisView (*this, *session, route, *track_canvas); else throw unknown_type(); + //cerr << "Editor::handle_new_route() called on " << route->name() << endl;//DEBUG #if 0 if (route_display_model->children().size() == 0) { @@ -631,3 +632,11 @@ Editor::get_route_view_by_id (PBD::ID& id) return 0; } + +void +Editor::foreach_time_axis_view (sigc::slot<void,TimeAxisView&> theslot) +{ + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + theslot (**i); + } +} diff --git a/gtk2_ardour/editor_rulers.cc b/gtk2_ardour/editor_rulers.cc index cb3ef7d45e..8ed6ea9a53 100644 --- a/gtk2_ardour/editor_rulers.cc +++ b/gtk2_ardour/editor_rulers.cc @@ -22,12 +22,15 @@ #include <string> +#include <gtk/gtkaction.h> + #include <ardour/tempo.h> #include <ardour/profile.h> #include <gtkmm2ext/gtk_ui.h> #include "editor.h" #include "editing.h" +#include "actions.h" #include "gtk-custom-hruler.h" #include "gui_thread.h" @@ -66,14 +69,12 @@ Editor::initialize_rulers () smpte_ruler->set_name ("SMPTERuler"); smpte_ruler->set_size_request (-1, (int)timebar_height); gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_smpte_ruler), &ruler_metrics[ruler_metric_smpte]); - ruler_shown[ruler_metric_smpte] = true; _bbt_ruler = gtk_custom_hruler_new (); bbt_ruler = Glib::wrap (_bbt_ruler); bbt_ruler->set_name ("BBTRuler"); bbt_ruler->set_size_request (-1, (int)timebar_height); gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_bbt_ruler), &ruler_metrics[ruler_metric_bbt]); - ruler_shown[ruler_metric_bbt] = true; _frames_ruler = gtk_custom_hruler_new (); frames_ruler = Glib::wrap (_frames_ruler); @@ -87,19 +88,6 @@ Editor::initialize_rulers () minsec_ruler->set_size_request (-1, (int)timebar_height); gtk_custom_ruler_set_metric (GTK_CUSTOM_RULER(_minsec_ruler), &ruler_metrics[ruler_metric_minsec]); - ruler_shown[ruler_time_meter] = true; - ruler_shown[ruler_time_tempo] = true; - ruler_shown[ruler_time_marker] = true; - ruler_shown[ruler_time_range_marker] = true; - ruler_shown[ruler_time_transport_marker] = true; - if (Profile->get_sae()) { - ruler_shown[ruler_time_cd_marker] = false; - } else { - ruler_shown[ruler_time_cd_marker] = true; - } - ruler_shown[ruler_metric_frames] = false; - ruler_shown[ruler_metric_minsec] = false; - visible_timebars = 7; /* 4 here, 3 in time_canvas */ ruler_pressed_button = 0; } @@ -261,9 +249,11 @@ Editor::ruler_button_release (GdkEventButton* ev) gint Editor::ruler_label_button_release (GdkEventButton* ev) { - if (ev->button == 3) - { - popup_ruler_menu(); + if (ev->button == 3) { + Gtk::Menu* m= dynamic_cast<Gtk::Menu*> (ActionManager::get_widget (X_("/RulerMenuPopup"))); + if (m) { + m->popup (1, ev->time); + } } return TRUE; @@ -287,8 +277,8 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev) time_canvas_event_box.get_window()->get_pointer (x, y, state); - track_canvas.c2w (x, y, wcx, wcy); - track_canvas.w2c (wcx, wcy, cx, cy); + track_canvas->c2w (x, y, wcx, wcy); + track_canvas->w2c (wcx, wcy, cx, cy); nframes_t where = leftmost_frame + pixel_to_frame (x); @@ -360,10 +350,6 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) editor_ruler_menu->set_name ("ArdourContextMenu"); ruler_items.clear(); - CheckMenuItem * mitem; - - no_ruler_shown_update = true; - switch (t) { case MarkerBarItem: ruler_items.push_back (MenuElem (_("New location marker"), bind ( mem_fun(*this, &Editor::mouse_add_new_marker), where, false, false))); @@ -403,114 +389,74 @@ Editor::popup_ruler_menu (nframes_t where, ItemType t) default: break; } - - ruler_items.push_back (CheckMenuElem (_("Min:Secs"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_minsec))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_metric_minsec]) { - mitem->set_active(true); - } - ruler_items.push_back (CheckMenuElem (_("Timecode"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_smpte))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_metric_smpte]) { - mitem->set_active(true); - } + Glib::RefPtr<Action> action; - ruler_items.push_back (CheckMenuElem (_("Samples"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_frames))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_metric_frames]) { - mitem->set_active(true); + action = ActionManager::get_action ("Rulers", "toggle-minsec-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); } - - ruler_items.push_back (CheckMenuElem (_("Bars:Beats"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_metric_bbt))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_metric_bbt]) { - mitem->set_active(true); + if (!Profile->get_sae()) { + action = ActionManager::get_action ("Rulers", "toggle-timecode-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); + } } - - ruler_items.push_back (SeparatorElem ()); - - ruler_items.push_back (CheckMenuElem (_("Meter"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_meter))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_meter]) { - mitem->set_active(true); + action = ActionManager::get_action ("Rulers", "toggle-samples-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); } - - ruler_items.push_back (CheckMenuElem (_("Tempo"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_tempo))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_tempo]) { - mitem->set_active(true); + action = ActionManager::get_action ("Rulers", "toggle-bbt-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); } - - ruler_items.push_back (CheckMenuElem (_("Location Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_marker))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_marker]) { - mitem->set_active(true); + action = ActionManager::get_action ("Rulers", "toggle-meter-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); + } + action = ActionManager::get_action ("Rulers", "toggle-tempo-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); } - if (!Profile->get_sae()) { - ruler_items.push_back (CheckMenuElem (_("Range Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_range_marker))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_range_marker]) { - mitem->set_active(true); + action = ActionManager::get_action ("Rulers", "toggle-range-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); } } + action = ActionManager::get_action ("Rulers", "toggle-loop-punch-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); + } + action = ActionManager::get_action ("Rulers", "toggle-cd-marker-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); + } + action = ActionManager::get_action ("Rulers", "toggle-marker-ruler"); + if (action) { + ruler_items.push_back (MenuElem (*action->create_menu_item())); + } - ruler_items.push_back (CheckMenuElem (_("CD Markers"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_cd_marker))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_cd_marker]) { - mitem->set_active(true); - } - - ruler_items.push_back (CheckMenuElem (_("Loop/Punch Ranges"), bind (mem_fun(*this, &Editor::ruler_toggled), (int)ruler_time_transport_marker))); - mitem = (CheckMenuItem *) &ruler_items.back(); - if (ruler_shown[ruler_time_transport_marker]) { - mitem->set_active(true); - } - editor_ruler_menu->popup (1, gtk_get_current_event_time()); no_ruler_shown_update = false; } void -Editor::ruler_toggled (int ruler) -{ - if (!session) return; - if (ruler < 0 || ruler >= (int) sizeof(ruler_shown)) return; - - if (no_ruler_shown_update) return; - - if (ruler_shown[ruler]) { - if (visible_timebars <= 1) { - // must always have 1 visible - return; - } - } - - ruler_shown[ruler] = !ruler_shown[ruler]; - - update_ruler_visibility (); - - // update session extra RulerVisibility - store_ruler_visibility (); -} - -void Editor::store_ruler_visibility () { XMLNode* node = new XMLNode(X_("RulerVisibility")); - node->add_property (X_("smpte"), ruler_shown[ruler_metric_smpte] ? "yes": "no"); - node->add_property (X_("bbt"), ruler_shown[ruler_metric_bbt] ? "yes": "no"); - node->add_property (X_("frames"), ruler_shown[ruler_metric_frames] ? "yes": "no"); - node->add_property (X_("minsec"), ruler_shown[ruler_metric_minsec] ? "yes": "no"); - node->add_property (X_("tempo"), ruler_shown[ruler_time_tempo] ? "yes": "no"); - node->add_property (X_("meter"), ruler_shown[ruler_time_meter] ? "yes": "no"); - node->add_property (X_("marker"), ruler_shown[ruler_time_marker] ? "yes": "no"); - node->add_property (X_("rangemarker"), ruler_shown[ruler_time_range_marker] ? "yes": "no"); - node->add_property (X_("transportmarker"), ruler_shown[ruler_time_transport_marker] ? "yes": "no"); - node->add_property (X_("cdmarker"), ruler_shown[ruler_time_cd_marker] ? "yes": "no"); + node->add_property (X_("smpte"), ruler_timecode_action->get_active() ? "yes": "no"); + node->add_property (X_("bbt"), ruler_bbt_action->get_active() ? "yes": "no"); + node->add_property (X_("frames"), ruler_samples_action->get_active() ? "yes": "no"); + node->add_property (X_("minsec"), ruler_minsec_action->get_active() ? "yes": "no"); + node->add_property (X_("tempo"), ruler_tempo_action->get_active() ? "yes": "no"); + node->add_property (X_("meter"), ruler_meter_action->get_active() ? "yes": "no"); + node->add_property (X_("marker"), ruler_marker_action->get_active() ? "yes": "no"); + node->add_property (X_("rangemarker"), ruler_range_action->get_active() ? "yes": "no"); + node->add_property (X_("transportmarker"), ruler_loop_punch_action->get_active() ? "yes": "no"); + node->add_property (X_("cdmarker"), ruler_cd_marker_action->get_active() ? "yes": "no"); session->add_extra_xml (*node); session->set_dirty (); @@ -522,92 +468,92 @@ Editor::restore_ruler_visibility () XMLProperty* prop; XMLNode * node = session->extra_xml (X_("RulerVisibility")); + no_ruler_shown_update = true; + if (node) { if ((prop = node->property ("smpte")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_metric_smpte] = true; + ruler_timecode_action->set_active (true); else - ruler_shown[ruler_metric_smpte] = false; + ruler_timecode_action->set_active (false); } if ((prop = node->property ("bbt")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_metric_bbt] = true; + ruler_bbt_action->set_active (true); else - ruler_shown[ruler_metric_bbt] = false; + ruler_bbt_action->set_active (false); } if ((prop = node->property ("frames")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_metric_frames] = true; + ruler_samples_action->set_active (true); else - ruler_shown[ruler_metric_frames] = false; + ruler_samples_action->set_active (false); } if ((prop = node->property ("minsec")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_metric_minsec] = true; + ruler_minsec_action->set_active (true); else - ruler_shown[ruler_metric_minsec] = false; + ruler_minsec_action->set_active (false); } if ((prop = node->property ("tempo")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_tempo] = true; + ruler_tempo_action->set_active (true); else - ruler_shown[ruler_time_tempo] = false; + ruler_tempo_action->set_active (false); } if ((prop = node->property ("meter")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_meter] = true; + ruler_meter_action->set_active (true); else - ruler_shown[ruler_time_meter] = false; + ruler_meter_action->set_active (false); } if ((prop = node->property ("marker")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_marker] = true; + ruler_marker_action->set_active (true); else - ruler_shown[ruler_time_marker] = false; + ruler_marker_action->set_active (false); } if ((prop = node->property ("rangemarker")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_range_marker] = true; + ruler_range_action->set_active (true); else - ruler_shown[ruler_time_range_marker] = false; + ruler_range_action->set_active (false); } if ((prop = node->property ("transportmarker")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_transport_marker] = true; + ruler_loop_punch_action->set_active (true); else - ruler_shown[ruler_time_transport_marker] = false; + ruler_loop_punch_action->set_active (false); } if ((prop = node->property ("cdmarker")) != 0) { if (prop->value() == "yes") - ruler_shown[ruler_time_cd_marker] = true; + ruler_cd_marker_action->set_active (true); else - ruler_shown[ruler_time_cd_marker] = false; - - cerr << "cd marker ruler set to " << ruler_shown[ruler_time_cd_marker] << endl; + ruler_cd_marker_action->set_active (false); } else { // this session doesn't yet know about the cdmarker ruler // as a benefit to the user who doesn't know the feature exists, show the ruler if // any cd marks exist - ruler_shown[ruler_time_cd_marker] = false; + ruler_cd_marker_action->set_active (false); const Locations::LocationList & locs = session->locations()->list(); for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) { if ((*i)->is_cd_marker()) { - ruler_shown[ruler_time_cd_marker] = true; + ruler_cd_marker_action->set_active (true); break; } } - cerr << "cd marker ruler default to " << ruler_shown[ruler_time_cd_marker] << endl; } } + no_ruler_shown_update = false; + update_ruler_visibility (); } - void Editor::update_ruler_visibility () { @@ -615,6 +561,10 @@ Editor::update_ruler_visibility () BoxList & lab_children = time_button_vbox.children(); BoxList & ruler_children = time_canvas_vbox.children(); + if (no_ruler_shown_update) { + return; + } + visible_timebars = 0; lab_children.clear(); @@ -679,25 +629,25 @@ Editor::update_ruler_visibility () ruler_children.insert (canvaspos, Element(*_ruler_separator, PACK_SHRINK, PACK_START)); - if (ruler_shown[ruler_metric_minsec]) { + if (ruler_minsec_action->get_active()) { lab_children.push_back (Element(minsec_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*minsec_ruler, PACK_SHRINK, PACK_START)); visible_timebars++; } - if (ruler_shown[ruler_metric_smpte]) { + if (ruler_timecode_action->get_active()) { lab_children.push_back (Element(smpte_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*smpte_ruler, PACK_SHRINK, PACK_START)); visible_timebars++; } - if (ruler_shown[ruler_metric_frames]) { + if (ruler_samples_action->get_active()) { lab_children.push_back (Element(frame_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*frames_ruler, PACK_SHRINK, PACK_START)); visible_timebars++; } - if (ruler_shown[ruler_metric_bbt]) { + if (ruler_bbt_action->get_active()) { lab_children.push_back (Element(bbt_label, PACK_SHRINK, PACK_START)); ruler_children.insert (canvaspos, Element(*bbt_ruler, PACK_SHRINK, PACK_START)); visible_timebars++; @@ -706,7 +656,7 @@ Editor::update_ruler_visibility () double tbpos = 1.0; double old_unit_pos ; - if (ruler_shown[ruler_time_meter]) { + if (ruler_meter_action->get_active()) { lab_children.push_back (Element(meter_label, PACK_SHRINK, PACK_START)); old_unit_pos = meter_group->property_y(); @@ -721,7 +671,7 @@ Editor::update_ruler_visibility () meter_group->hide(); } - if (ruler_shown[ruler_time_tempo]) { + if (ruler_tempo_action->get_active()) { lab_children.push_back (Element(tempo_label, PACK_SHRINK, PACK_START)); old_unit_pos = tempo_group->property_y(); if (tbpos != old_unit_pos) { @@ -735,20 +685,21 @@ Editor::update_ruler_visibility () tempo_group->hide(); } - if (!Profile->get_sae() && ruler_shown[ruler_time_range_marker]) { + if (!Profile->get_sae() && ruler_range_action->get_active()) { lab_children.push_back (Element(range_mark_label, PACK_SHRINK, PACK_START)); old_unit_pos = range_marker_group->property_y(); if (tbpos != old_unit_pos) { range_marker_group->move (0.0, tbpos - old_unit_pos); } range_marker_group->show(); + cerr << "range_marker_group now at " << range_marker_group->property_y() << endl; tbpos += timebar_height; visible_timebars++; } else { range_marker_group->hide(); } - if (ruler_shown[ruler_time_transport_marker]) { + if (ruler_loop_punch_action->get_active()) { lab_children.push_back (Element(transport_mark_label, PACK_SHRINK, PACK_START)); old_unit_pos = transport_marker_group->property_y(); if (tbpos != old_unit_pos) { @@ -762,7 +713,7 @@ Editor::update_ruler_visibility () transport_marker_group->hide(); } - if (ruler_shown[ruler_time_cd_marker]) { + if (ruler_cd_marker_action->get_active()) { lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START)); old_unit_pos = cd_marker_group->property_y(); if (tbpos != old_unit_pos) { @@ -780,7 +731,7 @@ Editor::update_ruler_visibility () update_cd_marker_display(); } - if (ruler_shown[ruler_time_marker]) { + if (ruler_marker_action->get_active()) { lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START)); old_unit_pos = marker_group->property_y(); if (tbpos != old_unit_pos) { @@ -819,7 +770,7 @@ Editor::update_just_smpte () nframes_t rightmost_frame = leftmost_frame + current_page_frames(); - if (ruler_shown[ruler_metric_smpte]) { + if (ruler_timecode_action->get_active()) { gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_smpte_ruler), leftmost_frame, rightmost_frame, leftmost_frame, session->current_end_frame()); } @@ -832,11 +783,11 @@ Editor::compute_fixed_ruler_scale () return; } - if (ruler_shown[ruler_metric_smpte]) { + if (ruler_timecode_action->get_active()) { set_smpte_ruler_scale (leftmost_frame, leftmost_frame + (edit_packer.get_width() * frames_per_unit) ); } - if (ruler_shown[ruler_metric_minsec]) { + if (ruler_minsec_action->get_active()) { set_minsec_ruler_scale (leftmost_frame, leftmost_frame + (edit_packer.get_width() * frames_per_unit) ); } } @@ -860,17 +811,17 @@ Editor::update_fixed_rulers () to compute the relevant ticks to display. */ - if (ruler_shown[ruler_metric_smpte]) { + if (ruler_timecode_action->get_active()) { gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_smpte_ruler), leftmost_frame, rightmost_frame, leftmost_frame, session->current_end_frame()); } - if (ruler_shown[ruler_metric_frames]) { + if (ruler_samples_action->get_active()) { gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_frames_ruler), leftmost_frame, rightmost_frame, leftmost_frame, session->current_end_frame()); } - if (ruler_shown[ruler_metric_minsec]) { + if (ruler_minsec_action->get_active()) { gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_minsec_ruler), leftmost_frame, rightmost_frame, leftmost_frame, session->current_end_frame()); } @@ -885,7 +836,7 @@ Editor::update_tempo_based_rulers () ruler_metrics[ruler_metric_bbt].units_per_pixel = frames_per_unit; - if (ruler_shown[ruler_metric_bbt]) { + if (ruler_bbt_action->get_active()) { gtk_custom_ruler_set_range (GTK_CUSTOM_RULER(_bbt_ruler), leftmost_frame, leftmost_frame+current_page_frames(), leftmost_frame, session->current_end_frame()); } diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 1408351d47..7c36384e30 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -25,6 +25,7 @@ #include <ardour/diskstream.h> #include <ardour/playlist.h> #include <ardour/route_group.h> +#include <ardour/profile.h> #include "editor.h" #include "actions.h" @@ -761,11 +762,17 @@ Editor::track_selection_changed () (*i)->set_selected (false); } } + + ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty()); } void Editor::time_selection_changed () { + if (Profile->get_sae()) { + return; + } + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (*i)->hide_selection (); } @@ -789,14 +796,8 @@ Editor::time_selection_changed () } void -Editor::region_selection_changed () +Editor::sensitize_the_right_region_actions (bool have_selected_regions) { - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - (*i)->set_selected_regionviews (selection->regions); - } - - bool have_selected_regions = !selection->regions.empty(); - for (vector<Glib::RefPtr<Action> >::iterator x = ActionManager::region_selection_sensitive_actions.begin(); x != ActionManager::region_selection_sensitive_actions.end(); ++x) { @@ -815,6 +816,17 @@ Editor::region_selection_changed () (*x)->set_sensitive (have_selected_regions); } } +} + + +void +Editor::region_selection_changed () +{ + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + (*i)->set_selected_regionviews (selection->regions); + } + + sensitize_the_right_region_actions (!selection->regions.empty()); zoomed_to_region = false; } @@ -982,7 +994,9 @@ Editor::set_selection_from_region () } selection->set (0, selection->regions.start(), selection->regions.end_frame()); - set_mouse_mode (Editing::MouseRange, false); + if (!Profile->get_sae()) { + set_mouse_mode (Editing::MouseRange, false); + } } void @@ -1015,7 +1029,9 @@ Editor::set_selection_from_range (Location& loc) selection->set (0, loc.start(), loc.end()); commit_reversible_command (); - set_mouse_mode (Editing::MouseRange, false); + if (!Profile->get_sae()) { + set_mouse_mode (Editing::MouseRange, false); + } } void @@ -1328,6 +1344,12 @@ Editor::get_edit_op_range (nframes64_t& start, nframes64_t& end) const swap (start, end); } + /* turn range into one delimited by start...end, + not start...end-1 + */ + + end++; + return true; } diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index e94bb9f642..c9bd50607b 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -190,8 +190,8 @@ Editor::redraw_measures () void Editor::draw_measures () { - if (session == 0 || _show_measures == false - || !current_bbt_points || current_bbt_points->empty()) { + if (session == 0 || _show_measures == false || + !current_bbt_points || current_bbt_points->empty()) { return; } @@ -202,7 +202,7 @@ Editor::draw_measures () time_line_group->lower(1);*/ marker_time_line_group->raise_to_top(); //marker_time_line_group->lower(1); - + /* the cursors are always on top of everything */ cursor_group->raise_to_top(); diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc index f626bfb968..9ed5bdfd8c 100644 --- a/gtk2_ardour/enums.cc +++ b/gtk2_ardour/enums.cc @@ -39,6 +39,8 @@ setup_gtk_ardour_enums () Width width; ImportMode import_mode; EditPoint edit_point; + WaveformScale waveform_scale; + WaveformShape waveform_shape; #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear() @@ -66,4 +68,12 @@ setup_gtk_ardour_enums () REGISTER_ENUM (EditAtMouse); REGISTER_ENUM (EditAtSelectedMarker); REGISTER (edit_point); + + REGISTER_ENUM (LinearWaveform); + REGISTER_ENUM (LogWaveform); + REGISTER (waveform_scale); + + REGISTER_ENUM (Traditional); + REGISTER_ENUM (Rectified); + REGISTER (waveform_shape); } diff --git a/gtk2_ardour/enums.h b/gtk2_ardour/enums.h index fcb675fd46..ebd061cc40 100644 --- a/gtk2_ardour/enums.h +++ b/gtk2_ardour/enums.h @@ -22,17 +22,6 @@ #include <ardour/types.h> -enum WaveformShape { - Traditional, - Rectified -}; - -enum WaveformScale { - LinearWaveform=0, - LogWaveform, -}; - - enum Width { Wide, Narrow, diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc index 62f43f37fd..db741d66ed 100644 --- a/gtk2_ardour/export_dialog.cc +++ b/gtk2_ardour/export_dialog.cc @@ -129,7 +129,7 @@ ExportDialog::ExportDialog(PublicEditor& e) set_wmclass (X_("ardour_export"), "Ardour"); set_name ("ExportWindow"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK); - + spec.running = false; file_entry.set_name ("ExportFileNameEntry"); @@ -143,7 +143,7 @@ ExportDialog::ExportDialog(PublicEditor& e) master_selector.append_column_editable(_("Left"), exp_cols.left); master_selector.append_column_editable(_("Right"), exp_cols.right); master_selector.get_column(0)->set_min_width(100); - + master_selector.get_column(1)->set_min_width(40); master_selector.get_column(1)->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE); master_selector.get_column(2)->set_min_width(40); diff --git a/gtk2_ardour/fft_graph.cc b/gtk2_ardour/fft_graph.cc index e7a0fd75b6..077c1e162c 100644 --- a/gtk2_ardour/fft_graph.cc +++ b/gtk2_ardour/fft_graph.cc @@ -51,6 +51,9 @@ FFTGraph::FFTGraph(int windowSize) _a_window = 0; + _show_minmax = false; + _show_normalized = false; + setWindowSize(windowSize); } @@ -151,23 +154,6 @@ FFTGraph::prepareResult(Gdk::Color color, string trackname) return res; } -void -FFTGraph::analyze(float *window, float *composite) -{ - int i; - // Copy the data and apply the hanning window - for (i = 0; i < _windowSize; i++) { - _in[i] = window[ i ] * _hanning[ i ]; - } - - fftwf_execute(_plan); - - composite[0] += (_out[0] * _out[0]); - - for (i=1; i < _dataSize - 1; i++) { // TODO: check with Jesse whether this is really correct - composite[i] += (_out[i] * _out[i]) + (_out[_windowSize-i] * _out[_windowSize-i]); - } -} void FFTGraph::set_analysis_window(AnalysisWindow *a_window) @@ -198,17 +184,18 @@ FFTGraph::draw_scales(Glib::RefPtr<Gdk::Window> window) window->draw_line(white, h_margin, v_margin, h_margin, height - v_margin ); // Line 2 - window->draw_line(white, width - h_margin, v_margin, width - h_margin, height - v_margin ); + window->draw_line(white, width - h_margin + 1, v_margin, width - h_margin + 1, height - v_margin ); // Line 3 window->draw_line(white, h_margin, height - v_margin, width - h_margin, height - v_margin ); #define DB_METRIC_LENGTH 8 - // Line 5 + // Line 4 window->draw_line(white, h_margin - DB_METRIC_LENGTH, v_margin, h_margin, v_margin ); - // Line 6 - window->draw_line(white, width - h_margin, v_margin, width - h_margin + DB_METRIC_LENGTH, v_margin ); + // Line 5 + window->draw_line(white, width - h_margin + 1, v_margin, width - h_margin + DB_METRIC_LENGTH, v_margin ); + if (graph_gc == 0) { @@ -229,8 +216,24 @@ FFTGraph::draw_scales(Glib::RefPtr<Gdk::Window> window) // Draw logscale int logscale_pos = 0; int position_on_scale; + + +/* TODO, write better scales and change the log function so that octaves are of equal pixel length + float scale_points[10] = { 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0, 7040.0, 14080.0, 28160.0 }; + + for (int x = 0; x < 10; x++) { + + // i = 0.. _dataSize-1 + float freq_at_bin = (SR/2.0) * ((double)i / (double)_dataSize); + + + + freq_at_pixel = FFT_START * exp( FFT_RANGE * pixel / (double)(currentScaleWidth - 1) ); + } + */ + for (int x = 1; x < 8; x++) { - position_on_scale = (int)floor( (double)scaleWidth*(double)x/8.0); + position_on_scale = (int)floor( (double)currentScaleWidth*(double)x/8.0); while (_logScale[logscale_pos] < position_on_scale) logscale_pos++; @@ -251,7 +254,7 @@ FFTGraph::draw_scales(Glib::RefPtr<Gdk::Window> window) layout->set_text(label); - window->draw_line(graph_gc, coord, v_margin, coord, height - v_margin); + window->draw_line(graph_gc, coord, v_margin, coord, height - v_margin - 1); int width, height; layout->get_pixel_size (width, height); @@ -268,12 +271,19 @@ FFTGraph::redraw() Glib::Mutex::Lock lm (_a_window->track_list_lock); draw_scales(get_window()); + if (_a_window == 0) return; if (!_a_window->track_list_ready) return; + + cairo_t *cr; + cr = gdk_cairo_create(GDK_DRAWABLE(get_window()->gobj())); + cairo_set_line_width(cr, 1.5); + cairo_translate(cr, (float)v_margin + 1.0, (float)h_margin); + // Find "session wide" min & max @@ -300,17 +310,24 @@ FFTGraph::redraw() max = res->maximum(); } } - - int graph_height = height - 2 * h_margin; - if (graph_gc == 0) { - graph_gc = GC::create( get_window() ); + if (!_show_normalized) { + min = -150.0f; + max = 0.0f; } - - double pixels_per_db = (double)graph_height / (double)(max - min); + //int graph_height = height - 2 * h_margin; + + float fft_pane_size_w = (float)(width - 2*v_margin) - 1.0; + float fft_pane_size_h = (float)(height - 2*h_margin); + + double pixels_per_db = (double)fft_pane_size_h / (double)(max - min); + + cairo_rectangle(cr, 0.0, 0.0, fft_pane_size_w, fft_pane_size_h); + cairo_clip(cr); + for (TreeIter i = track_rows.begin(); i != track_rows.end(); i++) { TreeModel::Row row = *i; @@ -326,72 +343,104 @@ FFTGraph::redraw() if (res->minimum() == res->maximum()) { continue; } + + float mpp; - std::string name = row[_a_window->tlcols.trackname]; + if (_show_minmax) { + mpp = -1000000.0; + + cairo_set_source_rgba(cr, res->get_color().get_red_p(), res->get_color().get_green_p(), res->get_color().get_blue_p(), 0.30); + cairo_move_to(cr, 0.5f + (float)_logScale[0], 0.5f + (float)( fft_pane_size_h - (int)floor( (res->maxAt(0) - min) * pixels_per_db) )); + + // Draw the line of maximum values + for (int x = 1; x < res->length(); x++) { + if (res->maxAt(x) > mpp) + mpp = res->maxAt(x); + mpp = fmax(mpp, min); + mpp = fmin(mpp, max); + + // If the next point on the log scale is at the same location, + // don't draw yet + if (x + 1 < res->length() && _logScale[x] == _logScale[x + 1]) { + continue; + } + + float X = 0.5f + (float)_logScale[x]; + float Y = 0.5f + (float)( fft_pane_size_h - (int)floor( (mpp - min) * pixels_per_db) ); + + cairo_line_to(cr, X, Y); + + mpp = -1000000.0; + } + + mpp = +10000000.0; + // Draw back to the start using the minimum value + for (int x = res->length()-1; x >= 0; x--) { + if (res->minAt(x) < mpp) + mpp = res->minAt(x); + mpp = fmax(mpp, min); + mpp = fmin(mpp, max); + + // If the next point on the log scale is at the same location, + // don't draw yet + if (x - 1 > 0 && _logScale[x] == _logScale[x - 1]) { + continue; + } + + float X = 0.5f + (float)_logScale[x]; + float Y = 0.5f + (float)( fft_pane_size_h - (int)floor( (mpp - min) * pixels_per_db) ); + + cairo_line_to(cr, X, Y ); + + mpp = +10000000.0; + } + + cairo_close_path(cr); + + cairo_fill(cr); + } + + // Set color from track - graph_gc->set_rgb_fg_color( res->get_color() ); + cairo_set_source_rgb(cr, res->get_color().get_red_p(), res->get_color().get_green_p(), res->get_color().get_blue_p()); - float mpp = -1000000.0; - int prevx = 0; - float prevSample = min; - - for (int x = 0; x < res->length() - 1; x++) { + mpp = -1000000.0; + + cairo_move_to(cr, 0.5, fft_pane_size_h-0.5); + + for (int x = 0; x < res->length(); x++) { - if (res->sampleAt(x) > mpp) - mpp = res->sampleAt(x); + + if (res->avgAt(x) > mpp) + mpp = res->avgAt(x); + mpp = fmax(mpp, min); + mpp = fmin(mpp, max); // If the next point on the log scale is at the same location, // don't draw yet - if (x + 1 < res->length() && - _logScale[x] == _logScale[x + 1]) { + if (x + 1 < res->length() && _logScale[x] == _logScale[x + 1]) { continue; } - get_window()->draw_line( - graph_gc, - v_margin + 1 + prevx, - graph_height - (int)floor( (prevSample - min) * pixels_per_db) + h_margin - 1, - v_margin + 1 + _logScale[x], - graph_height - (int)floor( (mpp - min) * pixels_per_db) + h_margin - 1); - - prevx = _logScale[x]; - prevSample = mpp; - + cairo_line_to(cr, 0.5f + (float)_logScale[x], 0.5f + (float)( fft_pane_size_h - (int)floor( (mpp - min) * pixels_per_db) )); mpp = -1000000.0; - } + + cairo_stroke(cr); } + cairo_destroy(cr); } void FFTGraph::on_size_request(Gtk::Requisition* requisition) { - width = scaleWidth + h_margin * 2; - height = scaleHeight + 2 + v_margin * 2; + width = max(requisition->width, minScaleWidth + h_margin * 2); + height = max(requisition->height, minScaleHeight + 2 + v_margin * 2); - if (_logScale != 0) { - free(_logScale); - } - _logScale = (int *) malloc(sizeof(int) * _dataSize); - - float SR = 44100; - float FFT_START = SR/(double)_dataSize; - float FFT_END = SR/2.0; - float FFT_RANGE = log( FFT_END / FFT_START); - float pixel = 0; - for (int i = 0; i < _dataSize; i++) { - float freq_at_bin = (SR/2.0) * ((double)i / (double)_dataSize); - float freq_at_pixel = FFT_START * exp( FFT_RANGE * pixel / (double)scaleWidth ); - while (freq_at_bin > freq_at_pixel) { - pixel++; - freq_at_pixel = FFT_START * exp( FFT_RANGE * pixel / (double)scaleWidth ); - } - _logScale[i] = (int)floor(pixel); -//printf("logscale at %d = %3.3f, freq_at_pixel %3.3f, freq_at_bin %3.3f, scaleWidth %d\n", i, pixel, freq_at_pixel, freq_at_bin, scaleWidth); - } + update_size(); requisition->width = width;; requisition->height = height; @@ -403,7 +452,32 @@ FFTGraph::on_size_allocate(Gtk::Allocation & alloc) width = alloc.get_width(); height = alloc.get_height(); + update_size(); + DrawingArea::on_size_allocate (alloc); +} + +void +FFTGraph::update_size() +{ + currentScaleWidth = width - h_margin*2; + currentScaleHeight = height - 2 - v_margin*2; + float SR = 44100; + float FFT_START = SR/(double)_dataSize; + float FFT_END = SR/2.0; + float FFT_RANGE = log( FFT_END / FFT_START); + float pixel = 0; + for (int i = 0; i < _dataSize; i++) { + float freq_at_bin = (SR/2.0) * ((double)i / (double)_dataSize); + float freq_at_pixel; + pixel--; + do { + pixel++; + freq_at_pixel = FFT_START * exp( FFT_RANGE * pixel / (double)(currentScaleWidth - 1) ); + } while (freq_at_bin > freq_at_pixel); + + _logScale[i] = (int)floor(pixel); + } } diff --git a/gtk2_ardour/fft_graph.h b/gtk2_ardour/fft_graph.h index 73636b989d..bbf7774741 100644 --- a/gtk2_ardour/fft_graph.h +++ b/gtk2_ardour/fft_graph.h @@ -54,27 +54,34 @@ class FFTGraph : public Gtk::DrawingArea void on_size_allocate(Gtk::Allocation & alloc); FFTResult *prepareResult(Gdk::Color color, std::string trackname); + const void set_show_minmax (bool v) { _show_minmax = v; redraw(); }; + const void set_show_normalized (bool v) { _show_normalized = v; redraw(); }; + private: + void update_size(); + void setWindowSize_internal(int windowSize); void draw_scales(Glib::RefPtr<Gdk::Window> window); - static const int scaleWidth = 512; - static const int scaleHeight = 420; + static const int minScaleWidth = 512; + static const int minScaleHeight = 420; + + int currentScaleWidth; + int currentScaleHeight; static const int h_margin = 20; static const int v_margin = 20; + Glib::RefPtr<Gdk::GC> graph_gc; int width; int height; - void analyze(float *window, float *composite); int _windowSize; int _dataSize; Glib::RefPtr<Pango::Layout> layout; - Glib::RefPtr<Gdk::GC> graph_gc; AnalysisWindow *_a_window; fftwf_plan _plan; @@ -84,6 +91,9 @@ class FFTGraph : public Gtk::DrawingArea float *_hanning; int *_logScale; + bool _show_minmax; + bool _show_normalized; + friend class FFTResult; }; diff --git a/gtk2_ardour/fft_result.cc b/gtk2_ardour/fft_result.cc index f5acef92ed..d692b9152b 100644 --- a/gtk2_ardour/fft_result.cc +++ b/gtk2_ardour/fft_result.cc @@ -37,8 +37,16 @@ FFTResult::FFTResult(FFTGraph *graph, Gdk::Color color, string trackname) _averages = 0; - _data = (float *) malloc(sizeof(float) * _dataSize); - memset(_data,0,sizeof(float) * _dataSize); + _data_avg = (float *) malloc(sizeof(float) * _dataSize); + memset(_data_avg,0,sizeof(float) * _dataSize); + + _data_min = (float *) malloc(sizeof(float) * _dataSize); + _data_max = (float *) malloc(sizeof(float) * _dataSize); + + for (int i = 0; i < _dataSize; i++) { + _data_min[i] = FLT_MAX; + _data_max[i] = FLT_MIN; + } _color = color; _trackname = trackname; @@ -47,7 +55,34 @@ FFTResult::FFTResult(FFTGraph *graph, Gdk::Color color, string trackname) void FFTResult::analyzeWindow(float *window) { - _graph->analyze(window, _data); + float *_hanning = _graph->_hanning; + float *_in = _graph->_in; + float *_out = _graph->_out; + + int i; + // Copy the data and apply the hanning window + for (i = 0; i < _windowSize; i++) { + _in[i] = window[ i ] * _hanning[ i ]; + } + + fftwf_execute(_graph->_plan); + + float b = _out[0] * _out[0]; + + _data_avg[0] += b; + if (b < _data_min[0]) _data_min[0] = b; + if (b > _data_max[0]) _data_max[0] = b; + + for (i=1; i < _dataSize - 1; i++) { // TODO: check with Jesse whether this is really correct + b = (_out[i] * _out[i]); + + _data_avg[i] += b; // + (_out[_windowSize-i] * _out[_windowSize-i]);, TODO: thanks to Stefan Kost + + if (_data_min[i] > b) _data_min[i] = b; + if (_data_max[i] < b ) _data_max[i] = b; + } + + _averages++; } @@ -59,21 +94,27 @@ FFTResult::finalize() _maximum = 0.0; return; } - + // Average & scale for (int i = 0; i < _dataSize; i++) { - _data[i] /= _averages; - _data[i] = 10.0f * log10f(_data[i]); + _data_avg[i] /= _averages; + _data_avg[i] = 10.0f * log10f(_data_avg[i]); + + _data_min[i] = 10.0f * log10f(_data_min[i]); + if (_data_min[i] < -10000.0f) { + _data_min[i] = -10000.0f; + } + _data_max[i] = 10.0f * log10f(_data_max[i]); } // find min & max - _minimum = _maximum = _data[0]; + _minimum = _maximum = _data_avg[0]; for (int i = 1; i < _dataSize; i++) { - if (_data[i] < _minimum && !isinf(_data[i])) { - _minimum = _data[i]; - } else if (_data[i] > _maximum && !isinf(_data[i])) { - _maximum = _data[i]; + if (_data_avg[i] < _minimum && !isinf(_data_avg[i])) { + _minimum = _data_avg[i]; + } else if (_data_avg[i] > _maximum && !isinf(_data_avg[i])) { + _maximum = _data_avg[i]; } } @@ -82,16 +123,36 @@ FFTResult::finalize() FFTResult::~FFTResult() { - free(_data); + free(_data_avg); + free(_data_min); + free(_data_max); } float -FFTResult::sampleAt(int x) +FFTResult::avgAt(int x) +{ + if (x < 0 || x>= _dataSize) + return 0.0f; + + return _data_avg[x]; +} + +float +FFTResult::minAt(int x) +{ + if (x < 0 || x>= _dataSize) + return 0.0f; + + return _data_min[x]; +} + +float +FFTResult::maxAt(int x) { if (x < 0 || x>= _dataSize) return 0.0f; - return _data[x]; + return _data_max[x]; } diff --git a/gtk2_ardour/fft_result.h b/gtk2_ardour/fft_result.h index c8f17dc01c..c6c952db1c 100644 --- a/gtk2_ardour/fft_result.h +++ b/gtk2_ardour/fft_result.h @@ -41,7 +41,9 @@ class FFTResult const int length() { return _dataSize; } - float sampleAt(int x); + float avgAt(int x); + float maxAt(int x); + float minAt(int x); const float minimum() { return _minimum; } const float maximum() { return _maximum; } @@ -53,10 +55,13 @@ class FFTResult int _averages; - float* _data; + float* _data_avg; + float* _data_max; + float* _data_min; + float* _work; - int _windowSize; + int _windowSize; int _dataSize; float _minimum; diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index 8406e21aa3..0a6046309a 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -217,8 +217,10 @@ GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s) ResetGroupPeakDisplays.connect (mem_fun(*this, &GainMeter::reset_group_peak_display)); UI::instance()->theme_changed.connect (mem_fun(*this, &GainMeter::on_theme_changed)); - - ColorsChanged.connect (mem_fun (*this, &GainMeter::color_handler)); + + ColorsChanged.connect (bind (mem_fun (*this, &GainMeter::color_handler), false)); + DPIReset.connect (bind (mem_fun (*this, &GainMeter::color_handler), true)); + //hide_all(); } @@ -302,7 +304,7 @@ GainMeter::meter_metrics_expose (GdkEventExpose *ev) Glib::RefPtr<Gdk::Pixmap> pixmap; std::map<string,Glib::RefPtr<Gdk::Pixmap> >::iterator i = metric_pixmaps.find (meter_metric_area.get_name()); - if (i == metric_pixmaps.end() || style_changed) { + if (i == metric_pixmaps.end() || style_changed || dpi_changed) { pixmap = render_metrics (meter_metric_area); } else { pixmap = i->second; @@ -978,8 +980,9 @@ void GainMeter::clear_meters () } } -void GainMeter::color_handler() +void GainMeter::color_handler (bool dpi) { color_changed = true; + dpi_changed = (dpi) ? true : false; setup_meters(); } diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h index af4f55709c..d15d8dfd59 100644 --- a/gtk2_ardour/gain_meter.h +++ b/gtk2_ardour/gain_meter.h @@ -118,7 +118,7 @@ class GainMeter : public Gtk::VBox std::string short_astyle_string (ARDOUR::AutoStyle); std::string _astyle_string (ARDOUR::AutoStyle, bool); - Width _width; + Width _width; static std::map<std::string,Glib::RefPtr<Gdk::Pixmap> > metric_pixmaps; static Glib::RefPtr<Gdk::Pixmap> render_metrics (Gtk::Widget&); @@ -193,8 +193,9 @@ class GainMeter : public Gtk::VBox void on_theme_changed (); bool style_changed; + bool dpi_changed; bool color_changed; - void color_handler(); + void color_handler(bool); }; #endif /* __ardour_gtk_gain_meter_h__ */ diff --git a/gtk2_ardour/icons/application-x-ardour2.png b/gtk2_ardour/icons/application-x-ardour2.png Binary files differnew file mode 100644 index 0000000000..536b90fe82 --- /dev/null +++ b/gtk2_ardour/icons/application-x-ardour2.png diff --git a/gtk2_ardour/keyboard.cc b/gtk2_ardour/keyboard.cc index b7706556ed..22dd274306 100644 --- a/gtk2_ardour/keyboard.cc +++ b/gtk2_ardour/keyboard.cc @@ -57,12 +57,14 @@ guint Keyboard::snap_mod = GDK_MOD3_MASK; guint Keyboard::PrimaryModifier = GDK_META_MASK; // Command guint Keyboard::SecondaryModifier = GDK_MOD1_MASK; // Alt/Option guint Keyboard::TertiaryModifier = GDK_SHIFT_MASK; // Shift +guint Keyboard::Level4Modifier = GDK_CONTROL_MASK; // Control guint Keyboard::CopyModifier = GDK_MOD1_MASK; // Alt/Option guint Keyboard::RangeSelectModifier = GDK_SHIFT_MASK; #else guint Keyboard::PrimaryModifier = GDK_CONTROL_MASK; // Control guint Keyboard::SecondaryModifier = GDK_MOD1_MASK; // Alt/Option guint Keyboard::TertiaryModifier = GDK_SHIFT_MASK; // Shift +guint Keyboard::Level4Modifier = GDK_MOD4_MASK; // Mod4/Windows guint Keyboard::CopyModifier = GDK_CONTROL_MASK; guint Keyboard::RangeSelectModifier = GDK_SHIFT_MASK; #endif @@ -109,9 +111,12 @@ Keyboard::Keyboard () RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | PrimaryModifier); RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | SecondaryModifier); RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | TertiaryModifier); + RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | Level4Modifier); RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | CopyModifier); RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | RangeSelectModifier); + gtk_accelerator_set_default_mod_mask (RelevantModifierKeyMask); + snooper_id = gtk_key_snooper_install (_snooper, (gpointer) this); XMLNode* node = ARDOUR_UI::instance()->keyboard_settings(); diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h index 9042dc4f6b..de2a0929ed 100644 --- a/gtk2_ardour/keyboard.h +++ b/gtk2_ardour/keyboard.h @@ -49,6 +49,7 @@ class Keyboard : public sigc::trackable, PBD::Stateful static uint32_t PrimaryModifier; static uint32_t SecondaryModifier; static uint32_t TertiaryModifier; + static uint32_t Level4Modifier; static uint32_t CopyModifier; static uint32_t RangeSelectModifier; @@ -61,6 +62,9 @@ class Keyboard : public sigc::trackable, PBD::Stateful static void set_tertiary_modifier (uint32_t newval) { set_modifier (newval, TertiaryModifier); } + static void set_level4_modifier (uint32_t newval) { + set_modifier (newval, Level4Modifier); + } static void set_copy_modifier (uint32_t newval) { set_modifier (newval, CopyModifier); } diff --git a/gtk2_ardour/level_meter.h b/gtk2_ardour/level_meter.h index dfae72a576..240cc4b785 100644 --- a/gtk2_ardour/level_meter.h +++ b/gtk2_ardour/level_meter.h @@ -73,7 +73,7 @@ class LevelMeter : public Gtk::HBox boost::shared_ptr<ARDOUR::IO> _io; ARDOUR::Session& _session; - Width _width; + Width _width; struct MeterInfo { Gtkmm2ext::FastMeter *meter; diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 809e654838..c935e091f2 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -197,21 +197,32 @@ fixup_bundle_environment () localedir = strdup (path.c_str()); - /* write a pango.rc file and tell pango to use it */ + /* write a pango.rc file and tell pango to use it. we'd love + to put this into the Ardour.app bundle and leave it there, + but the user may not have write permission. so ... - path = dir_path; - path += "/../Resources/pango.rc"; + we also have to make sure that the user ardour directory + actually exists ... + */ + + sys::path pangopath = user_config_directory(); + pangopath /= "pango.rc"; + path = pangopath.to_string(); std::ofstream pangorc (path.c_str()); if (!pangorc) { error << string_compose (_("cannot open pango.rc file %1") , path) << endmsg; } else { pangorc << "[Pango]\nModuleFiles="; - Glib::ustring mpath = dir_path; - mpath += "/../Resources/pango.modules"; - pangorc << mpath << endl; - + + pangopath = dir_path; + pangopath /= '..'; + pangopath /= 'Resources'; + pangopath /= 'pango.modules'; + + pangorc << pangopath.to_string() << endl; pangorc.close (); + setenv ("PANGO_RC_FILE", path.c_str(), 1); } @@ -257,7 +268,7 @@ int main (int argc, char *argv[]) #endif { vector<Glib::ustring> null_file_list; - + #ifdef __APPLE__ fixup_bundle_environment (); #endif @@ -305,7 +316,7 @@ int main (int argc, char *argv[]) } if (no_splash) { - cerr << _("Copyright (C) 1999-2007 Paul Davis") << endl + cerr << _("Copyright (C) 1999-2008 Paul Davis") << endl << _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl << endl << _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 771683d80e..dd5a70bb7d 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -245,7 +245,7 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con mark->property_outline_color_rgba() = rgba; mark->property_width_pixels() = 1; Pango::FontDescription* font = get_font_for_style (N_("MarkerText")); - + text = new Text (*group); text->property_text() = annotation.c_str(); text->property_font_desc() = *font; @@ -285,6 +285,7 @@ Marker::~Marker () if (line) { delete line; + line = 0; } } diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 8024fbabd4..9ca93e8f03 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -1206,6 +1206,14 @@ MixerStrip::map_frozen () break; } } + + + hide_redirect_editors (); +} + +void +MixerStrip::hide_redirect_editors () +{ _route->foreach_processor (this, &MixerStrip::hide_processor_editor); } diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index cfe350e514..63a47974cc 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -240,6 +240,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox void update_speed_display (); void map_frozen (); void hide_processor_editor (boost::shared_ptr<ARDOUR::Processor> processor); + void hide_redirect_editors (); bool ignore_speed_adjustment; diff --git a/gtk2_ardour/new_session_dialog.cc b/gtk2_ardour/new_session_dialog.cc index 79f6d5e8ee..22ddfa395d 100644 --- a/gtk2_ardour/new_session_dialog.cc +++ b/gtk2_ardour/new_session_dialog.cc @@ -39,6 +39,7 @@ #include <gtkmm2ext/window_title.h> +using namespace Gtk; using namespace Gtkmm2ext; using namespace PBD; using namespace ARDOUR; @@ -50,14 +51,14 @@ NewSessionDialog::NewSessionDialog() : ArdourDialog ("session control") { in_destructor = false; - session_name_label = Gtk::manage(new class Gtk::Label(_("Name :"))); - m_name = Gtk::manage(new class Gtk::Entry()); + session_name_label = new Gtk::Label(_("Name :")); + m_name = new Gtk::Entry(); m_name->set_text(ARDOUR_COMMAND_LINE::session_name); - chan_count_label_1 = Gtk::manage(new class Gtk::Label(_("channels"))); - chan_count_label_2 = Gtk::manage(new class Gtk::Label(_("channels"))); - chan_count_label_3 = Gtk::manage(new class Gtk::Label(_("channels"))); - chan_count_label_4 = Gtk::manage(new class Gtk::Label(_("channels"))); + chan_count_label_1 = new Gtk::Label(_("channels")); + chan_count_label_2 = new Gtk::Label(_("channels")); + chan_count_label_3 = new Gtk::Label(_("channels")); + chan_count_label_4 = new Gtk::Label(_("channels")); chan_count_label_1->set_alignment(0,0.5); chan_count_label_1->set_padding(0,0); @@ -75,64 +76,64 @@ NewSessionDialog::NewSessionDialog() chan_count_label_4->set_padding(0,0); chan_count_label_4->set_line_wrap(false); - bus_label = Gtk::manage(new class Gtk::Label(_("<b>Busses</b>"))); - input_label = Gtk::manage(new class Gtk::Label(_("<b>Inputs</b>"))); - output_label = Gtk::manage(new class Gtk::Label(_("<b>Outputs</b>"))); + bus_label = new Gtk::Label(_("<b>Busses</b>")); + input_label = new Gtk::Label(_("<b>Inputs</b>")); + output_label = new Gtk::Label(_("<b>Outputs</b>")); - session_location_label = Gtk::manage(new class Gtk::Label(_("Create Folder In :"))); - m_folder = Gtk::manage(new class Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); - session_template_label = Gtk::manage(new class Gtk::Label(_("Template :"))); - m_template = Gtk::manage(new class Gtk::FileChooserButton()); - m_create_control_bus = Gtk::manage(new class Gtk::CheckButton(_("Create Monitor Bus"))); + session_location_label = new Gtk::Label(_("Create Folder In :")); + m_folder = new Gtk::FileChooserButton(Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + session_template_label = new Gtk::Label(_("Template :")); + m_template = new Gtk::FileChooserButton(); + m_create_control_bus = new Gtk::CheckButton(_("Create Monitor Bus")); - Gtk::Adjustment *m_control_bus_channel_count_adj = Gtk::manage(new class Gtk::Adjustment(2, 0, 100, 1, 10, 10)); - m_control_bus_channel_count = Gtk::manage(new class Gtk::SpinButton(*m_control_bus_channel_count_adj, 1, 0)); + Gtk::Adjustment *m_control_bus_channel_count_adj = Gtk::manage(new Gtk::Adjustment(2, 0, 100, 1, 10, 10)); + m_control_bus_channel_count = new Gtk::SpinButton(*m_control_bus_channel_count_adj, 1, 0); - Gtk::Adjustment *m_master_bus_channel_count_adj = Gtk::manage(new class Gtk::Adjustment(2, 0, 100, 1, 10, 10)); - m_master_bus_channel_count = Gtk::manage(new class Gtk::SpinButton(*m_master_bus_channel_count_adj, 1, 0)); - m_create_master_bus = Gtk::manage(new class Gtk::CheckButton(_("Create Master Bus"))); - advanced_table = Gtk::manage(new class Gtk::Table(2, 2, true)); - m_connect_inputs = Gtk::manage(new class Gtk::CheckButton(_("Automatically Connect to Physical Inputs"))); - m_limit_input_ports = Gtk::manage(new class Gtk::CheckButton(_("Use only"))); + Gtk::Adjustment *m_master_bus_channel_count_adj = Gtk::manage(new Gtk::Adjustment(2, 0, 100, 1, 10, 10)); + m_master_bus_channel_count = new Gtk::SpinButton(*m_master_bus_channel_count_adj, 1, 0); + m_create_master_bus = new Gtk::CheckButton(_("Create Master Bus")); + advanced_table = new Gtk::Table(2, 2, true); + m_connect_inputs = new Gtk::CheckButton(_("Automatically Connect to Physical Inputs")); + m_limit_input_ports = new Gtk::CheckButton(_("Use only")); - Gtk::Adjustment *m_input_limit_count_adj = Gtk::manage(new class Gtk::Adjustment(1, 0, 100, 1, 10, 10)); - m_input_limit_count = Gtk::manage(new class Gtk::SpinButton(*m_input_limit_count_adj, 1, 0)); - input_port_limit_hbox = Gtk::manage(new class Gtk::HBox(false, 0)); - input_port_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); - input_table = Gtk::manage(new class Gtk::Table(2, 2, false)); - - bus_frame = Gtk::manage(new class Gtk::Frame()); - bus_table = Gtk::manage (new Gtk::Table (2, 3, false)); - - input_frame = Gtk::manage(new class Gtk::Frame()); - m_connect_outputs = Gtk::manage(new class Gtk::CheckButton(_("Automatically Connect Outputs"))); - m_limit_output_ports = Gtk::manage(new class Gtk::CheckButton(_("Use only"))); + Gtk::Adjustment *m_input_limit_count_adj = Gtk::manage(new Gtk::Adjustment(1, 0, 100, 1, 10, 10)); + m_input_limit_count = new Gtk::SpinButton(*m_input_limit_count_adj, 1, 0); + input_port_limit_hbox = new Gtk::HBox(false, 0); + input_port_vbox = new Gtk::VBox(false, 0); + input_table = new Gtk::Table(2, 2, false); + + bus_frame = new Gtk::Frame(); + bus_table = new Gtk::Table (2, 3, false); - Gtk::Adjustment *m_output_limit_count_adj = Gtk::manage(new class Gtk::Adjustment(1, 0, 100, 1, 10, 10)); - m_output_limit_count = Gtk::manage(new class Gtk::SpinButton(*m_output_limit_count_adj, 1, 0)); - output_port_limit_hbox = Gtk::manage(new class Gtk::HBox(false, 0)); - output_port_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); + input_frame = new Gtk::Frame(); + m_connect_outputs = new Gtk::CheckButton(_("Automatically Connect Outputs")); + m_limit_output_ports = new Gtk::CheckButton(_("Use only")); + + Gtk::Adjustment *m_output_limit_count_adj = Gtk::manage(new Gtk::Adjustment(1, 0, 100, 1, 10, 10)); + m_output_limit_count = new Gtk::SpinButton(*m_output_limit_count_adj, 1, 0); + output_port_limit_hbox = new Gtk::HBox(false, 0); + output_port_vbox = new Gtk::VBox(false, 0); Gtk::RadioButton::Group _RadioBGroup_m_connect_outputs_to_master; - m_connect_outputs_to_master = Gtk::manage(new class Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Master Bus"))); - m_connect_outputs_to_physical = Gtk::manage(new class Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Physical Outputs"))); - output_conn_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); - output_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); - - output_frame = Gtk::manage(new class Gtk::Frame()); - advanced_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); - advanced_label = Gtk::manage(new class Gtk::Label(_("Advanced Options"))); - advanced_expander = Gtk::manage(new class Gtk::Expander()); - new_session_table = Gtk::manage(new class Gtk::Table(2, 2, false)); - m_open_filechooser = Gtk::manage(new class Gtk::FileChooserButton()); - open_session_hbox = Gtk::manage(new class Gtk::HBox(false, 0)); - m_treeview = Gtk::manage(new class Gtk::TreeView()); - recent_scrolledwindow = Gtk::manage(new class Gtk::ScrolledWindow()); - - recent_sesion_label = Gtk::manage(new class Gtk::Label(_("Recent:"))); - recent_frame = Gtk::manage(new class Gtk::Frame()); - open_session_vbox = Gtk::manage(new class Gtk::VBox(false, 0)); - m_notebook = Gtk::manage(new class Gtk::Notebook()); + m_connect_outputs_to_master = new Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Master Bus")); + m_connect_outputs_to_physical = new Gtk::RadioButton(_RadioBGroup_m_connect_outputs_to_master, _("... to Physical Outputs")); + output_conn_vbox = new Gtk::VBox(false, 0); + output_vbox = new Gtk::VBox(false, 0); + + output_frame = new Gtk::Frame(); + advanced_vbox = new Gtk::VBox(false, 0); + advanced_label = new Gtk::Label(_("Advanced Options")); + advanced_expander = new Gtk::Expander(); + new_session_table = new Gtk::Table(2, 2, false); + m_open_filechooser = new Gtk::FileChooserButton(); + open_session_hbox = new Gtk::HBox(false, 0); + m_treeview = new Gtk::TreeView(); + recent_scrolledwindow = new Gtk::ScrolledWindow(); + + recent_sesion_label = new Gtk::Label(_("Recent:")); + recent_frame = new Gtk::Frame(); + open_session_vbox = new Gtk::VBox(false, 0); + m_notebook = new Gtk::Notebook(); session_name_label->set_alignment(0, 0.5); session_name_label->set_padding(6,0); session_name_label->set_line_wrap(false); @@ -166,7 +167,7 @@ NewSessionDialog::NewSessionDialog() m_master_bus_channel_count->set_numeric(true); m_master_bus_channel_count->set_digits(0); m_master_bus_channel_count->set_wrap(false); - open_session_file_label = Gtk::manage(new class Gtk::Label(_("Browse:"))); + open_session_file_label = new Gtk::Label(_("Browse:")); open_session_file_label->set_alignment(0, 0.5); m_create_master_bus->set_flags(Gtk::CAN_FOCUS); m_create_master_bus->set_relief(Gtk::RELIEF_NORMAL); @@ -175,7 +176,7 @@ NewSessionDialog::NewSessionDialog() m_create_master_bus->set_border_width(0); advanced_table->set_row_spacings(0); advanced_table->set_col_spacings(0); - + m_connect_inputs->set_flags(Gtk::CAN_FOCUS); m_connect_inputs->set_relief(Gtk::RELIEF_NORMAL); m_connect_inputs->set_mode(true); @@ -194,7 +195,7 @@ NewSessionDialog::NewSessionDialog() m_input_limit_count->set_wrap(false); m_input_limit_count->set_sensitive(false); - bus_hbox = Gtk::manage (new Gtk::HBox (false, 0)); + bus_hbox = new Gtk::HBox (false, 0); bus_hbox->pack_start (*bus_table, Gtk::PACK_SHRINK, 18); bus_label->set_alignment(0, 0.5); @@ -225,7 +226,7 @@ NewSessionDialog::NewSessionDialog() input_table->set_col_spacings(0); input_table->attach(*input_port_vbox, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 6, 6); - input_hbox = Gtk::manage (new Gtk::HBox (false, 0)); + input_hbox = new Gtk::HBox (false, 0); input_hbox->pack_start (*input_table, Gtk::PACK_SHRINK, 18); input_label->set_alignment(0, 0.5); @@ -285,7 +286,7 @@ NewSessionDialog::NewSessionDialog() output_frame->set_shadow_type(Gtk::SHADOW_NONE); output_frame->set_label_align(0,0.5); - output_hbox = Gtk::manage (new Gtk::HBox (false, 0)); + output_hbox = new Gtk::HBox (false, 0); output_hbox->pack_start (*output_vbox, Gtk::PACK_SHRINK, 18); output_frame->add(*output_hbox); diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index 988aa92e45..fd5c35e186 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -16,6 +16,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <pango/pangoft2.h> // for fontmap resolution control for GnomeCanvas +#include <pango/pangocairo.h> // for fontmap resolution control for GnomeCanvas #include <pbd/whitespace.h> @@ -44,6 +46,7 @@ #include "option_editor.h" #include "midi_port_dialog.h" #include "gui_thread.h" +#include "utils.h" #include "i18n.h" @@ -250,12 +253,40 @@ OptionEditor::add_session_paths () session_raid_entry.set_text(session->raid_path()); } +static void +font_scale_changed (Gtk::Adjustment* adj) +{ + Config->set_font_scale((long)floor (adj->get_value() * 1024)); + reset_dpi(); +} + void OptionEditor::setup_misc_options () { Gtk::HBox* hbox; - - Label* label = manage (new Label (_("Short crossfade length (msecs)"))); + Label* label; + +#ifndef GTKOSX + /* font scaling does nothing with GDK/Quartz */ + + Gtk::Adjustment* dpi_adj = new Gtk::Adjustment ((double)Config->get_font_scale() / 1024, 50, 250, 1, 10); + Gtk::HScale * dpi_range = new Gtk::HScale (*dpi_adj); + + label = manage (new Label (_("Font Scaling"))); + label->set_name ("OptionsLabel"); + + dpi_range->set_update_policy (Gtk::UPDATE_DISCONTINUOUS); + dpi_adj->signal_value_changed().connect (bind (sigc::ptr_fun (font_scale_changed), dpi_adj)); + + hbox = manage (new HBox); + hbox->set_border_width (5); + hbox->set_spacing (10); + hbox->pack_start (*label, false, false); + hbox->pack_start (*dpi_range, true, true); + misc_packer.pack_start (*hbox, false, false); +#endif + + label = manage (new Label (_("Short crossfade length (msecs)"))); label->set_name ("OptionsLabel"); hbox = manage (new HBox); @@ -1345,5 +1376,7 @@ OptionEditor::parameter_changed (const char* parameter_name) save_history_button.set_active (x); saved_history_depth_spinner.set_sensitive (x); + } else if (PARAM_IS ("font-scale")) { + reset_dpi(); } } diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index c76c5dcf78..aa269be577 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -435,3 +435,9 @@ PluginSelector::filter_mode_changed () refill (); } +void +PluginSelector::on_show () +{ + ArdourDialog::on_show (); + filter_entry.grab_focus (); +} diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index e8e8927829..fe797588de 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -41,6 +41,7 @@ class PluginSelector : public ArdourDialog int run (); // XXX should we try not to overload the non-virtual Gtk::Dialog::run() ? void set_session (ARDOUR::Session*); + void on_show (); private: ARDOUR::Session* session; diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 7f2955dfda..5813c644fb 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -61,7 +61,8 @@ using namespace Gtkmm2ext; using namespace Gtk; using namespace sigc; -PluginUIWindow::PluginUIWindow (boost::shared_ptr<PluginInsert> insert, nframes64_t sr, nframes64_t period, bool scrollable) +PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert> insert, bool scrollable) + : parent (win) { bool have_gui = false; non_gtk_gui = false; @@ -136,17 +137,36 @@ PluginUIWindow::~PluginUIWindow () } void +PluginUIWindow::set_parent (Gtk::Window* win) +{ + parent = win; +} + +void +PluginUIWindow::on_map () +{ + Window::on_map (); + set_keep_above (true); +} + +void PluginUIWindow::on_show () { - cerr << "PluginWindow shown\n"; - + if (_pluginui) { + _pluginui->update_presets (); + } + Window::on_show (); + + if (parent) { + cerr << "plugin becomes transient for " << parent << endl; + // set_transient_for (*parent); + } } void PluginUIWindow::on_hide () { - cerr << "PluginWindow hidden\n"; Window::on_hide (); } @@ -329,3 +349,9 @@ PlugUIBase::bypass_toggled () } } } + +void +PlugUIBase::update_presets () +{ + set_popdown_strings (preset_combo, plugin->get_presets()); +} diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index 72cfc465e6..2214b4aa50 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -79,6 +79,8 @@ class PlugUIBase : public virtual sigc::trackable virtual void activate () {} virtual void deactivate () {} + virtual void update_presets (); + protected: boost::shared_ptr<ARDOUR::PluginInsert> insert; boost::shared_ptr<ARDOUR::Plugin> plugin; @@ -204,20 +206,22 @@ class GenericPluginUI : public PlugUIBase, public Gtk::VBox class PluginUIWindow : public Gtk::Window { public: - PluginUIWindow (boost::shared_ptr<ARDOUR::PluginInsert> insert, nframes64_t sample_rate, nframes64_t period_size, bool scrollable = false); + PluginUIWindow (Gtk::Window*, boost::shared_ptr<ARDOUR::PluginInsert> insert, bool scrollable=false); ~PluginUIWindow (); PlugUIBase& pluginui() { return *_pluginui; } void resize_preferred(); + void set_parent (Gtk::Window*); bool on_key_press_event (GdkEventKey*); bool on_key_release_event (GdkEventKey*); void on_show (); void on_hide (); - + void on_map (); private: PlugUIBase* _pluginui; + Gtk::Window* parent; Gtk::VBox vbox; bool non_gtk_gui; void app_activated (bool); @@ -231,7 +235,7 @@ class PluginUIWindow : public Gtk::Window class VSTPluginUI : public PlugUIBase, public Gtk::VBox { public: - VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::VSTPlugin>, nframes64_t sample_rate, nframes64_t period_size); + VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::VSTPlugin>); ~VSTPluginUI (); gint get_preferred_height (); diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 9f6dff823b..b2b1c3b538 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -1097,17 +1097,17 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor) ARDOUR::PluginType type = plugin_processor->type(); if (type == ARDOUR::LADSPA || type == ARDOUR::VST) { + PluginUIWindow *plugin_ui; + /* these are both allowed to be null */ + + Container* toplevel = get_toplevel(); + Window* win = dynamic_cast<Gtk::Window*>(toplevel); + if (plugin_processor->get_gui() == 0) { - plugin_ui = new PluginUIWindow (plugin_processor, _session.frame_rate(), _session.engine().frames_per_cycle()); - - if (_owner_is_mixer) { - ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui); - } else { - ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui); - } + plugin_ui = new PluginUIWindow (win, plugin_processor); WindowTitle title(Glib::get_application_name()); title += generate_processor_title (plugin_processor); @@ -1117,7 +1117,6 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor) // change window title when route name is changed _route->NameChanged.connect (bind (mem_fun(*this, &ProcessorBox::route_name_changed), plugin_ui, boost::weak_ptr<PluginInsert> (plugin_processor))); - } else { plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_processor->get_gui()); diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 6adaf07186..e6f576352a 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -90,6 +90,9 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway /** @return Singleton PublicEditor instance */ static PublicEditor& instance () { return *_instance; } + virtual bool have_idled() const = 0; + virtual void first_idle() = 0; + /** Attach this editor to a Session. * @param s Session to connect to. */ @@ -256,6 +259,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway virtual void toggle_meter_updating() = 0; virtual void split_region_at_points (boost::shared_ptr<ARDOUR::Region>, ARDOUR::AnalysisFeatureList&, bool can_ferret) = 0; virtual void mouse_add_new_marker (nframes_t where, bool is_cd=false, bool is_xrun=false) = 0; + virtual void foreach_time_axis_view (sigc::slot<void,TimeAxisView&>) = 0; #ifdef WITH_CMT virtual void add_imageframe_time_axis(const std::string & track_name, void*) = 0; diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index ffe64e6451..4251df344c 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -147,7 +147,7 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) set_colors (); ColorsChanged.connect (mem_fun (*this, &RegionView::color_handler)); - + // set_pango_fontsize(); /* XXX sync mark drag? */ } diff --git a/gtk2_ardour/rhythm_ferret.cc b/gtk2_ardour/rhythm_ferret.cc index 83852b33b3..63440e7ab1 100644 --- a/gtk2_ardour/rhythm_ferret.cc +++ b/gtk2_ardour/rhythm_ferret.cc @@ -191,7 +191,7 @@ RhythmFerret::run_analysis () } for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { - (*i)->get_time_axis_view().show_temporary_lines (current_results); + (*i)->get_time_axis_view().show_feature_lines (current_results); } } @@ -269,7 +269,7 @@ RhythmFerret::do_split_action () tmp = i; ++tmp; - (*i)->get_time_axis_view().hide_temporary_lines (); + (*i)->get_time_axis_view().hide_feature_lines (); editor.split_region_at_points ((*i)->region(), current_results, false); @@ -286,3 +286,16 @@ RhythmFerret::set_session (Session* s) ArdourDialog::set_session (s); current_results.clear (); } + +static void hide_time_axis_features (TimeAxisView& tav) +{ + tav.hide_feature_lines (); +} + +void +RhythmFerret::on_hide () +{ + editor.foreach_time_axis_view (sigc::ptr_fun (hide_time_axis_features)); + ArdourDialog::on_hide (); +} + diff --git a/gtk2_ardour/rhythm_ferret.h b/gtk2_ardour/rhythm_ferret.h index 891b447a11..2ddb2a4ffd 100644 --- a/gtk2_ardour/rhythm_ferret.h +++ b/gtk2_ardour/rhythm_ferret.h @@ -41,6 +41,9 @@ class RhythmFerret : public ArdourDialog { ~RhythmFerret (); void set_session (ARDOUR::Session*); + + protected: + void on_hide (); private: PublicEditor& editor; diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 0104daea7c..6f7f655d8e 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -874,10 +874,10 @@ SoundFileOmega::bad_file_message() bool SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& src_needed, bool& multichannel) { - SNDFILE* sf; - SF_INFO info; + SoundFileInfo info; nframes64_t sz = 0; bool err = false; + string errmsg; same_size = true; src_needed = false; @@ -885,19 +885,16 @@ SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& for (vector<ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) { - info.format = 0; // libsndfile says to clear this before sf_open(). + if (AudioFileSource::get_soundfile_info (*i, info, errmsg)) { - if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) { - sf_close (sf); - if (info.channels > 1) { multichannel = true; } - + if (sz == 0) { - sz = info.frames; + sz = info.length; } else { - if (sz != info.frames) { + if (sz != info.length) { same_size = false; } } @@ -907,10 +904,16 @@ SoundFileOmega::check_info (const vector<ustring>& paths, bool& same_size, bool& } } else if (SMFSource::safe_file_extension (*i)) { + SMFReader reader(*i); if (reader.num_tracks() > 1) { multichannel = true; // "channel" == track here... } + + /* XXX we need err = true handling here in case + we can't check the file + */ + } else { err = true; } diff --git a/gtk2_ardour/splash.cc b/gtk2_ardour/splash.cc index 7ffca37fc1..8846c9f4e6 100644 --- a/gtk2_ardour/splash.cc +++ b/gtk2_ardour/splash.cc @@ -118,10 +118,11 @@ Splash::message (const string& msg) str += "</b>"; layout->set_markup (str); - darea.queue_draw (); - Glib::RefPtr<Gdk::Window> win = darea.get_window(); + if (win) { + win->invalidate_rect (Gdk::Rectangle (0, darea.get_height() - 30, + darea.get_width(), 30), true); win->process_updates (true); gdk_flush (); } diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index cb335882e2..e5205069a3 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -183,6 +183,10 @@ TimeAxisView::~TimeAxisView() delete (*i)->end_trim; } + for (list<SimpleLine*>::iterator i = feature_lines.begin(); i != feature_lines.end(); ++i) { + delete (*i); + } + if (selection_group) { delete selection_group; selection_group = 0; @@ -637,6 +641,14 @@ TimeAxisView::set_samples_per_unit (double spu) for (Children::iterator i = children.begin(); i != children.end(); ++i) { (*i)->set_samples_per_unit (spu); } + + AnalysisFeatureList::const_iterator i; + list<ArdourCanvas::SimpleLine*>::iterator l; + + for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) { + (*l)->property_x1() = editor.frame_to_pixel (*i); + (*l)->property_x2() = editor.frame_to_pixel (*i); + } } void @@ -1166,35 +1178,47 @@ TimeAxisView::covers_y_position (double y) } void -TimeAxisView::show_temporary_lines (const AnalysisFeatureList& pos) +TimeAxisView::show_feature_lines (const AnalysisFeatureList& pos) { - while (temp_lines.size()< pos.size()) { + analysis_features = pos; + reshow_feature_lines (); +} + + +void +TimeAxisView::hide_feature_lines () +{ + list<ArdourCanvas::SimpleLine*>::iterator l; + + for (l = feature_lines.begin(); l != feature_lines.end(); ++l) { + (*l)->hide(); + } +} + +void +TimeAxisView::reshow_feature_lines () +{ + while (feature_lines.size()< analysis_features.size()) { ArdourCanvas::SimpleLine* l = new ArdourCanvas::SimpleLine (*canvas_display); l->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get(); l->property_y1() = 0; l->property_y2() = height; - temp_lines.push_back (l); + feature_lines.push_back (l); } - while (temp_lines.size() > pos.size()) { - ArdourCanvas::SimpleLine *line = temp_lines.back(); - temp_lines.pop_back (); + while (feature_lines.size() > analysis_features.size()) { + ArdourCanvas::SimpleLine *line = feature_lines.back(); + feature_lines.pop_back (); delete line; } AnalysisFeatureList::const_iterator i; list<ArdourCanvas::SimpleLine*>::iterator l; - for (i = pos.begin(), l = temp_lines.begin(); i != pos.end() && l != temp_lines.end(); ++i, ++l) { + for (i = analysis_features.begin(), l = feature_lines.begin(); i != analysis_features.end() && l != feature_lines.end(); ++i, ++l) { (*l)->property_x1() = editor.frame_to_pixel (*i); (*l)->property_x2() = editor.frame_to_pixel (*i); + (*l)->show (); } } -void -TimeAxisView::hide_temporary_lines () -{ - for (list<ArdourCanvas::SimpleLine*>::iterator l = temp_lines.begin(); l != temp_lines.end(); ++l) { - (*l)->hide (); - } -} diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index ee03585992..5649c0150a 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -174,8 +174,8 @@ class TimeAxisView : public virtual AxisView virtual ARDOUR::RouteGroup* edit_group() const { return 0; } virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); } - virtual void show_temporary_lines (const ARDOUR::AnalysisFeatureList&); - virtual void hide_temporary_lines (); + virtual void show_feature_lines (const ARDOUR::AnalysisFeatureList&); + virtual void hide_feature_lines (); virtual void set_samples_per_unit (double); virtual void show_selection (TimeSelection&); @@ -210,6 +210,12 @@ class TimeAxisView : public virtual AxisView void remove_ghost (RegionView*); void erase_ghost (GhostRegion*); + /* called at load time when first GUI idle occurs. put + expensive data loading/redisplay code in here. + */ + + virtual void first_idle () {} + /* state/serialization management */ TimeAxisView* get_parent () { return parent; } @@ -324,7 +330,9 @@ class TimeAxisView : public virtual AxisView void set_heights (TrackHeight); void set_height_pixels (uint32_t h); void color_handler (); - list<ArdourCanvas::SimpleLine*> temp_lines; + list<ArdourCanvas::SimpleLine*> feature_lines; + ARDOUR::AnalysisFeatureList analysis_features; + void reshow_feature_lines (); }; /* class TimeAxisView */ diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 5b67022ee0..a52969268a 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -17,6 +17,9 @@ */ +#include <pango/pangoft2.h> // for fontmap resolution control for GnomeCanvas +#include <pango/pangocairo.h> // for fontmap resolution control for GnomeCanvas + #include <cstdlib> #include <cctype> #include <fstream> @@ -32,6 +35,7 @@ #include <pbd/file_utils.h> #include <gtkmm2ext/utils.h> +#include <ardour/configuration.h> #include <ardour/filesystem_paths.h> @@ -48,6 +52,8 @@ using namespace sigc; using namespace Glib; using namespace PBD; +sigc::signal<void> DPIReset; + int pixel_width (const ustring& str, Pango::FontDescription& font) { @@ -706,6 +712,29 @@ key_is_legal_for_numeric_entry (guint keyval) return false; } +void +set_pango_fontsize () +{ + long val = ARDOUR::Config->get_font_scale(); + + /* FT2 rendering */ + + pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_for_display(), val/1024, val/1024); + + /* Cairo rendering, in case there is any */ + + pango_cairo_font_map_set_resolution ((PangoCairoFontMap*) pango_cairo_font_map_get_default(), val/1024); +} +void +reset_dpi () +{ + long val = ARDOUR::Config->get_font_scale(); + set_pango_fontsize (); + /* Xft rendering */ + gtk_settings_set_long_property (gtk_settings_get_default(), + "gtk-xft-dpi", val, "ardour"); + DPIReset();//Emit Signal +} diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h index 74a6eebd21..4cf8fc371b 100644 --- a/gtk2_ardour/utils.h +++ b/gtk2_ardour/utils.h @@ -83,5 +83,7 @@ static std::map<std::string, Glib::RefPtr<Gdk::Pixbuf> > xpm_map; const char* const *get_xpm_data (std::string path); std::string longest (std::vector<std::string>&); bool key_is_legal_for_numeric_entry (guint keyval); +void reset_dpi (); +void set_pango_fontsize (); #endif /* __ardour_gtk_utils_h__ */ |