diff options
author | Hans Fugal <hans@fugal.net> | 2006-08-04 02:18:45 +0000 |
---|---|---|
committer | Hans Fugal <hans@fugal.net> | 2006-08-04 02:18:45 +0000 |
commit | 79986643c0c904f6574bb5323e2233a43a9e622e (patch) | |
tree | 859323dbb096ac1658359881e7d11415b6588caa /gtk2_ardour | |
parent | b0b723445816bc968a6a183c6619fccc61e82859 (diff) |
r269@gandalf: fugalh | 2006-08-03 20:18:05 -0600
Trunk merge conflicts resolved
git-svn-id: svn://localhost/ardour2/branches/undo@756 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
127 files changed, 7450 insertions, 4925 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript index 65f8dfca73..d004c9c4c6 100644 --- a/gtk2_ardour/SConscript +++ b/gtk2_ardour/SConscript @@ -27,7 +27,7 @@ gtkardour.Merge ([ libraries['ardour_cp'], libraries['gtkmm2ext'], libraries['midi++2'], - libraries['pbd3'], + libraries['pbd'], libraries['gtkmm2'], libraries['glib2'], libraries['libgnomecanvas2'], @@ -57,6 +57,10 @@ if gtkardour['FFT_ANALYSIS']: gtkardour.Merge ([libraries['fftw3f']]) gtkardour.Append(CCFLAGS='-DFFT_ANALYSIS') +if gtkardour['COREAUDIO']: + gtkardour.Append(CCFLAGS='-DHAVE_COREAUDIO') + gtkardour.Merge([libraries['appleutility']]) + skipped_files=Split(""" connection_editor.cc """) @@ -75,6 +79,7 @@ ardour_ui_ed.cc ardour_ui_mixer.cc ardour_ui_options.cc audio_clock.cc +route_time_axis.cc audio_time_axis.cc automation_gain_line.cc automation_line.cc @@ -141,8 +146,6 @@ marker.cc marker_time_axis.cc marker_time_axis_view.cc marker_view.cc -meter_bridge.cc -meter_bridge_strip.cc mixer_strip.cc mixer_ui.cc new_session_dialog.cc @@ -159,10 +162,11 @@ public_editor.cc redirect_automation_line.cc redirect_automation_time_axis.cc redirect_box.cc -region_editor.cc +audio_region_editor.cc region_gain_line.cc region_selection.cc -regionview.cc +region_view.cc +audio_region_view.cc route_params_ui.cc route_redirect_selection.cc route_ui.cc @@ -170,7 +174,8 @@ selection.cc sfdb_ui.cc send_ui.cc streamview.cc -taperegionview.cc +audio_streamview.cc +tape_region_view.cc tempo_dialog.cc time_axis_view.cc time_axis_view_item.cc @@ -255,8 +260,7 @@ else: env.Alias('install', env.InstallAs(os.path.join(install_prefix, 'bin')+'/ardour2', ardoursh)) if env['NLS']: - Export('gtkardour', 'intl_files') - SConscript ('po/SConscript') + i18n (gtkardour, gtkardour_files+skipped_files+fft_analysis_files, env) # configuration files env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour2_ui.rc')) diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc index ee688c3660..2197d4dc00 100644 --- a/gtk2_ardour/actions.cc +++ b/gtk2_ardour/actions.cc @@ -19,7 +19,7 @@ */ #include <vector> -#include <string.h> +#include <string> #include <gtk/gtkaccelmap.h> #include <gtk/gtkuimanager.h> diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc index b8318f45fe..f742afd727 100644 --- a/gtk2_ardour/analysis_window.cc +++ b/gtk2_ardour/analysis_window.cc @@ -26,7 +26,7 @@ #include <gtkmm/treeiter.h> #include <ardour/audioregion.h> -#include <ardour/playlist.h> +#include <ardour/audioplaylist.h> #include <ardour/types.h> #include "analysis_window.h" @@ -35,7 +35,7 @@ #include "time_axis_view.h" #include "public_editor.h" #include "selection.h" -#include "regionview.h" +#include "audio_region_view.h" #include "i18n.h" @@ -45,16 +45,15 @@ using namespace PBD; AnalysisWindow::AnalysisWindow() : ArdourDialog(_("analysis window")), - fft_graph (2048), - source_selection_label (_("Signal source")), source_selection_ranges_rb (_("Selected ranges")), source_selection_regions_rb (_("Selected regions")), - + 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")) + display_model_composite_all_tracks_rb (_("Composite graph of all tracks")), + fft_graph (2048) { track_list_ready = false; @@ -226,18 +225,23 @@ AnalysisWindow::analyze_data (Gtk::Button *button) Selection s = PublicEditor::instance().get_selection(); TimeSelection ts = s.time; - AudioRegionSelection ars = s.audio_regions; + RegionSelection ars = s.regions; for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) { - ARDOUR::Playlist *pl = (*i)->playlist(); + ARDOUR::AudioPlaylist *pl + = dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist()); + + if (!pl) + continue; + RouteUI *rui = dynamic_cast<RouteUI *>(*i); // Busses don't have playlists, so we need to check that we actually are working with a playlist if (!pl || !rui) continue; - FFTResult *res = fft_graph.prepareResult(*&rui->color(), *&rui->route().name()); + FFTResult *res = fft_graph.prepareResult(rui->color(), rui->route()->name()); // if timeSelection if (source_selection_ranges_rb.get_active()) { @@ -275,24 +279,29 @@ AnalysisWindow::analyze_data (Gtk::Button *button) TimeAxisView *current_axis = (*i); - for (std::set<AudioRegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) { + for (std::set<RegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) { + // Check that the region is actually audio (so we can analyze it) + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*j); + if (!arv) + continue; + // Check that the region really is selected on _this_ track/solo - if ( &(*j)->get_time_axis_view() != current_axis) + if ( &arv->get_time_axis_view() != current_axis) continue; -// cerr << " - " << (*j)->region.name() << ": " << (*j)->region.length() << " samples starting at " << (*j)->region.position() << endl; +// cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl; jack_nframes_t i = 0; int n; - while ( i < (*j)->region.length() ) { + while ( i < arv->region().length() ) { // TODO: What about stereo+ channels? composite all to one, I guess n = fft_graph.windowSize(); - if (i + n >= (*j)->region.length() ) { - n = (*j)->region.length() - i; + if (i + n >= arv->region().length() ) { + n = arv->region().length() - i; } - - n = (*j)->region.read_at(buf, mixbuf, gain, work, (*j)->region.position() + i, n); + + n = arv->audio_region().read_at(buf, mixbuf, gain, work, arv->region().position() + i, n); if ( n < fft_graph.windowSize()) { for (int j = n; j < fft_graph.windowSize(); j++) { @@ -313,9 +322,9 @@ AnalysisWindow::analyze_data (Gtk::Button *button) Gtk::TreeModel::Row newrow = *(tlmodel)->append(); - newrow[tlcols.trackname] = rui->route().name(); + newrow[tlcols.trackname] = rui->route()->name(); newrow[tlcols.visible] = true; - newrow[tlcols.color] = *&rui->color(); + newrow[tlcols.color] = rui->color(); newrow[tlcols.graph] = res; } diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh index 5c68933a96..bf644f3e84 100755 --- a/gtk2_ardour/ardev_common.sh +++ b/gtk2_ardour/ardev_common.sh @@ -2,7 +2,10 @@ export ARDOUR_PATH=./glade:./pixmaps:. -export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:../libs/appleutility:$LD_LIBRARY_PATH # DYLD_LIBRARY_PATH is for darwin. export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH + +# LADSPA_PATH for OSX +export LADSPA_PATH=$LADSPA_PATH:/Library/Audio/Plug-Ins/LADSPA diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 9293883067..b1064b8e87 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -15,8 +15,10 @@ <separator/> <menu action='addExistingAudioFiles'> <menuitem action='addExternalAudioAsRegion'/> - <menuitem action='addExternalAudioAsTrack'/> <menuitem action='addExternalAudioToTrack'/> + <separator/> + <menuitem action='addExternalAudioAsTrack'/> + <menuitem action='addExternalAudioAsTapeTrack'/> </menu> <separator/> <menu name='Export' action='Export'> diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc index ac4f055df6..5422a63b8b 100644 --- a/gtk2_ardour/ardour2_ui.rc +++ b/gtk2_ardour/ardour2_ui.rc @@ -219,6 +219,14 @@ style "mute_button" = "small_button" fg[PRELIGHT] = { 0, 0, 0 } } + +style "multiline_combo" = "small_button" +{ + font_name = "sans 8" + xthickness = 0 + ythickness = 0 +} + style "mixer_mute_button" = "mute_button" { font_name = "sans 7" @@ -936,6 +944,7 @@ widget "*TrackRecordEnableButton" style "track_rec_enable_button" widget "*TrackRecordEnableButton*" style "track_rec_enable_button" widget "*TrackMuteButton*" style "mute_button" widget "*TrackLoopButton*" style "track_loop_button" +widget "*PanAutomationLineSelector*" style "multiline_combo" widget "*EditorTimeButton*" style "time_button" widget "*EditorMixerButton*" style "default_buttons_menus" widget "*SoloButton*" style "solo_button" diff --git a/gtk2_ardour/ardour_dialog.h b/gtk2_ardour/ardour_dialog.h index a23dcda9e0..069768c143 100644 --- a/gtk2_ardour/ardour_dialog.h +++ b/gtk2_ardour/ardour_dialog.h @@ -26,7 +26,7 @@ namespace ARDOUR { class Session; -}; +} /* * This virtual parent class is so that each dialog box uses the @@ -55,3 +55,4 @@ class ArdourDialog : public Gtk::Dialog }; #endif // __ardour_dialog_h__ + diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index f452ec9c7e..e5367d6280 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -46,6 +46,7 @@ #include <midi++/mmc.h> #include <ardour/ardour.h> +#include <ardour/session_route.h> #include <ardour/port.h> #include <ardour/audioengine.h> #include <ardour/playlist.h> @@ -53,7 +54,6 @@ #include <ardour/audio_diskstream.h> #include <ardour/audiofilesource.h> #include <ardour/recent_sessions.h> -#include <ardour/session_diskstream.h> #include <ardour/port.h> #include <ardour/audio_track.h> @@ -116,16 +116,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile) shuttle_units_button (_("% ")), - punch_in_button (_("punch\nin")), - punch_out_button (_("punch\nout")), - auto_return_button (_("auto\nreturn")), - auto_play_button (_("auto\nplay")), - auto_input_button (_("auto\ninput")), - click_button (_("click")), - auditioning_alert_button (_("AUDITIONING")), + punch_in_button (_("Punch In")), + punch_out_button (_("Punch Out")), + auto_return_button (_("Auto Return")), + auto_play_button (_("Autuo Play")), + auto_input_button (_("Auto Input")), + click_button (_("Click")), + auditioning_alert_button (_("AUDITION")), solo_alert_button (_("SOLO")), shown_flag (false) - { using namespace Gtk::Menu_Helpers; @@ -186,8 +185,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile) gettimeofday (&last_shuttle_request, 0); ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread)); - ARDOUR::AudioDiskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler)); - ARDOUR::AudioDiskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler)); + ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler)); + ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler)); /* handle pending state with a dialog */ @@ -339,15 +338,15 @@ ARDOUR_UI::save_ardour_state () Config->add_extra_xml (*node); Config->save_state(); - XMLNode& enode (static_cast<Stateful*>(editor)->get_state()); - XMLNode& mnode (mixer->get_state()); + XMLNode enode(static_cast<Stateful*>(editor)->get_state()); + XMLNode mnode(mixer->get_state()); if (session) { - session->add_instant_xml(enode, session->path()); - session->add_instant_xml(mnode, session->path()); + session->add_instant_xml (enode, session->path()); + session->add_instant_xml (mnode, session->path()); } else { - Config->add_instant_xml(enode, get_user_ardour_path()); - Config->add_instant_xml(mnode, get_user_ardour_path()); + Config->add_instant_xml (enode, get_user_ardour_path()); + Config->add_instant_xml (mnode, get_user_ardour_path()); } /* keybindings */ @@ -507,11 +506,11 @@ ARDOUR_UI::update_sample_rate (jack_nframes_t ignored) jack_nframes_t rate = engine->frame_rate(); if (fmod (rate, 1000.0) != 0.0) { - snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), + snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"), (float) rate/1000.0f, (engine->frames_per_cycle() / (float) rate) * 1000.0f); } else { - snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), + snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"), rate/1000, (engine->frames_per_cycle() / (float) rate) * 1000.0f); } @@ -524,7 +523,7 @@ void ARDOUR_UI::update_cpu_load () { char buf[32]; - snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load()); + snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load()); cpu_load_label.set_text (buf); } @@ -543,9 +542,10 @@ ARDOUR_UI::update_buffer_load () } void -ARDOUR_UI::count_recenabled_diskstreams (AudioDiskstream& ds) +ARDOUR_UI::count_recenabled_diskstreams (Route& route) { - if (ds.record_enabled()) { + Track* track = dynamic_cast<Track*>(&route); + if (track && track->diskstream().record_enabled()) { rec_enabled_diskstreams++; } } @@ -561,7 +561,7 @@ ARDOUR_UI::update_disk_space() char buf[64]; if (frames == max_frames) { - strcpy (buf, _("space: 24hrs+")); + strcpy (buf, _("Disk: 24hrs+")); } else { int hrs; int mins; @@ -571,7 +571,7 @@ ARDOUR_UI::update_disk_space() if (session->actively_recording()){ rec_enabled_diskstreams = 0; - session->foreach_audio_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams); + session->foreach_route (this, &ARDOUR_UI::count_recenabled_diskstreams); if (rec_enabled_diskstreams) { frames /= rec_enabled_diskstreams; @@ -591,7 +591,7 @@ ARDOUR_UI::update_disk_space() frames -= mins * fr * 60; secs = frames / fr; - snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs); + snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs); } disk_space_label.set_text (buf); @@ -876,7 +876,7 @@ ARDOUR_UI::session_add_midi_track () void ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode) { - Route* route; + boost::shared_ptr<Route> route; if (session == 0) { warning << _("You cannot add a track without a session already loaded.") << endmsg; @@ -918,7 +918,7 @@ restart JACK with more ports.")); } void -ARDOUR_UI::diskstream_added (AudioDiskstream* ds) +ARDOUR_UI::diskstream_added (Diskstream* ds) { } @@ -1159,32 +1159,25 @@ ARDOUR_UI::transport_forward (int option) } void -ARDOUR_UI::toggle_monitor_enable (guint32 dstream) +ARDOUR_UI::toggle_record_enable (uint32_t dstream) { if (session == 0) { return; } - AudioDiskstream *ds; + boost::shared_ptr<Route> r; + + if ((r = session->route_by_remote_id (dstream)) != 0) { - if ((ds = session->diskstream_by_id (dstream)) != 0) { - Port *port = ds->io()->input (0); - port->request_monitor_input (!port->monitoring_input()); - } -} + Track* t; -void -ARDOUR_UI::toggle_record_enable (guint32 dstream) -{ + if ((t = dynamic_cast<Track*>(r.get())) != 0) { + t->diskstream().set_record_enabled (!t->diskstream().record_enabled()); + } + } if (session == 0) { return; } - - AudioDiskstream *ds; - - if ((ds = session->diskstream_by_id (dstream)) != 0) { - ds->set_record_enabled (!ds->record_enabled(), this); - } } void @@ -1385,63 +1378,6 @@ ARDOUR_UI::stop_blinking () } } - -void -ARDOUR_UI::add_diskstream_to_menu (AudioDiskstream& dstream) -{ - using namespace Gtk; - using namespace Menu_Helpers; - - if (dstream.hidden()) { - return; - } - - MenuList& items = diskstream_menu->items(); - items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id()))); -} - -void -ARDOUR_UI::diskstream_selected (gint32 id) -{ - selected_dstream = id; - Main::quit (); -} - -gint32 -ARDOUR_UI::select_diskstream (GdkEventButton *ev) -{ - using namespace Gtk; - using namespace Menu_Helpers; - - if (session == 0) { - return -1; - } - - diskstream_menu = new Menu(); - diskstream_menu->set_name ("ArdourContextMenu"); - using namespace Gtk; - using namespace Menu_Helpers; - - MenuList& items = diskstream_menu->items(); - items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1)))); - - session->foreach_audio_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu); - - if (ev) { - diskstream_menu->popup (ev->button, ev->time); - } else { - diskstream_menu->popup (0, 0); - } - - selected_dstream = -1; - - Main::run (); - - delete diskstream_menu; - - return selected_dstream; -} - void ARDOUR_UI::name_io_setup (AudioEngine& engine, string& buf, @@ -2217,11 +2153,11 @@ ARDOUR_UI::halt_on_xrun_message () } void -ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>* deletion_list) +ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list)); - for (list<AudioFileSource*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) { + for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) { delete *i; } diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 678342f32b..297c9c3c65 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -79,7 +79,7 @@ class ColorManager; namespace Gtkmm2ext { class TearOff; -}; +} namespace ARDOUR { class AudioEngine; @@ -87,11 +87,11 @@ namespace ARDOUR { class Port; class IO; class ControlProtocolInfo; -}; +} namespace ALSA { class MultiChannelDevice; -}; +} #define FRAME_NAME "BaseFrame" @@ -154,8 +154,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI void toggle_tempo_window (); void toggle_editing_space(); - gint32 select_diskstream (GdkEventButton *ev); - Gtk::Tooltips& tooltips() { return _tooltips; } static sigc::signal<void,bool> Blink; @@ -522,7 +520,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI sigc::connection point_one_second_connection; sigc::connection point_zero_one_second_connection; - void diskstream_added (ARDOUR::AudioDiskstream*); + void diskstream_added (ARDOUR::Diskstream*); gint session_menu (GdkEventButton *); @@ -536,14 +534,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI void save_template (); - void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode); - void add_diskstream_to_menu (ARDOUR::AudioDiskstream&); - void diskstream_selected (gint32); - Gtk::Menu *diskstream_menu; - gint32 selected_dstream; - void set_transport_sensitivity (bool); void remove_last_capture (); @@ -626,11 +618,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI void test_binding_action (const char *); void start_keyboard_prefix(); - void toggle_record_enable (guint32); - void toggle_monitor_enable (guint32); + void toggle_record_enable (uint32_t); uint32_t rec_enabled_diskstreams; - void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&); + void count_recenabled_diskstreams (ARDOUR::Route&); About* about; bool shown_flag; @@ -649,7 +640,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI struct timeval last_peak_grab; struct timeval last_shuttle_request; - void delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>*); + void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*); void editor_display_control_changed (Editing::DisplayControl c); @@ -716,5 +707,5 @@ class ARDOUR_UI : public Gtkmm2ext::UI void toggle_control_protocol (ARDOUR::ControlProtocolInfo*); }; - #endif /* __ardour_gui_h__ */ + diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc index f92201e36c..44287fe61e 100644 --- a/gtk2_ardour/ardour_ui2.cc +++ b/gtk2_ardour/ardour_ui2.cc @@ -359,10 +359,10 @@ ARDOUR_UI::setup_transport () auditioning_alert_button.set_name ("TransportAuditioningAlert"); auditioning_alert_button.signal_pressed().connect (mem_fun(*this,&ARDOUR_UI::audition_alert_toggle)); - alert_box.pack_start (solo_alert_button); - alert_box.pack_start (auditioning_alert_button); + alert_box.pack_start (solo_alert_button, false, false); + alert_box.pack_start (auditioning_alert_button, false, false); - transport_tearoff_hbox.set_border_width (5); + transport_tearoff_hbox.set_border_width (3); transport_tearoff_hbox.pack_start (goto_start_button, false, false); transport_tearoff_hbox.pack_start (goto_end_button, false, false); @@ -398,6 +398,7 @@ ARDOUR_UI::setup_transport () mtc_port_changed (); sync_option_combo.set_active_text (positional_sync_strings.front()); sync_option_combo.signal_changed().connect (mem_fun (*this, &ARDOUR_UI::sync_option_changed)); + Gtkmm2ext::set_size_request_to_display_given_text (sync_option_combo, "Internal", 22, 10); shbox->pack_start (*sdframe, false, false); shbox->pack_start (shuttle_units_button, true, true); @@ -406,37 +407,52 @@ ARDOUR_UI::setup_transport () svbox->pack_start (*sframe, false, false); svbox->pack_start (*shbox, false, false); - transport_tearoff_hbox.pack_start (*svbox, false, false, 5); + transport_tearoff_hbox.pack_start (*svbox, false, false, 3); transport_tearoff_hbox.pack_start (auto_loop_button, false, false); transport_tearoff_hbox.pack_start (play_selection_button, false, false); transport_tearoff_hbox.pack_start (roll_button, false, false); transport_tearoff_hbox.pack_start (stop_button, false, false); - transport_tearoff_hbox.pack_start (rec_button, false, false, 10); - - transport_tearoff_hbox.pack_start (primary_clock, false, false, 5); - transport_tearoff_hbox.pack_start (secondary_clock, false, false, 5); - - transport_tearoff_hbox.pack_start (sync_option_combo, false, false); - transport_tearoff_hbox.pack_start (time_master_button, false, false); - transport_tearoff_hbox.pack_start (punch_in_button, false, false); - transport_tearoff_hbox.pack_start (punch_out_button, false, false); - transport_tearoff_hbox.pack_start (auto_input_button, false, false); - transport_tearoff_hbox.pack_start (auto_return_button, false, false); - transport_tearoff_hbox.pack_start (auto_play_button, false, false); - transport_tearoff_hbox.pack_start (click_button, false, false); + transport_tearoff_hbox.pack_start (rec_button, false, false, 6); + + HBox* clock_box = manage (new HBox); + clock_box->pack_start (primary_clock, false, false); + clock_box->pack_start (secondary_clock, false, false); + VBox* time_controls_box = manage (new VBox); + time_controls_box->pack_start (sync_option_combo, false, false); + time_controls_box->pack_start (time_master_button, false, false); + clock_box->pack_start (*time_controls_box, false, false, 1); + transport_tearoff_hbox.pack_start (*clock_box, false, false, 0); + + HBox* toggle_box = manage(new HBox); + + VBox* punch_box = manage (new VBox); + punch_box->pack_start (punch_in_button, false, false); + punch_box->pack_start (punch_out_button, false, false); + toggle_box->pack_start (*punch_box, false, false); + + VBox* auto_box = manage (new VBox); + auto_box->pack_start (auto_play_button, false, false); + auto_box->pack_start (auto_return_button, false, false); + toggle_box->pack_start (*auto_box, false, false); + + VBox* io_box = manage (new VBox); + io_box->pack_start (auto_input_button, false, false); + io_box->pack_start (click_button, false, false); + toggle_box->pack_start (*io_box, false, false); /* desensitize */ set_transport_sensitivity (false); -// transport_tearoff_hbox.pack_start (preroll_button, false, false); -// transport_tearoff_hbox.pack_start (preroll_clock, false, false); +// toggle_box->pack_start (preroll_button, false, false); +// toggle_box->pack_start (preroll_clock, false, false); -// transport_tearoff_hbox.pack_start (postroll_button, false, false); -// transport_tearoff_hbox.pack_start (postroll_clock, false, false); +// toggle_box->pack_start (postroll_button, false, false); +// toggle_box->pack_start (postroll_clock, false, false); - transport_tearoff_hbox.pack_start (alert_box, false, false, 5); + transport_tearoff_hbox.pack_start (*toggle_box, false, false, 4); + transport_tearoff_hbox.pack_start (alert_box, false, false); } void @@ -820,7 +836,7 @@ ARDOUR_UI::set_shuttle_units (ShuttleUnits u) shuttle_units_button.set_label("% "); break; case Semitones: - shuttle_units_button.set_label(_("st")); + shuttle_units_button.set_label(_("ST")); break; } } @@ -864,7 +880,7 @@ ARDOUR_UI::update_speed_display () { if (!session) { if (last_speed_displayed != 0) { - speed_display_label.set_text (_("stopped")); + speed_display_label.set_text (_("stop")); last_speed_displayed = 0; } return; @@ -877,7 +893,7 @@ ARDOUR_UI::update_speed_display () if (x != 0) { if (shuttle_units == Percentage) { - snprintf (buf, sizeof (buf), "%.4f", x); + snprintf (buf, sizeof (buf), "%.2f", x); } else { if (x < 0) { snprintf (buf, sizeof (buf), "< %.1f", 12.0 * fast_log2 (-x)); @@ -887,7 +903,7 @@ ARDOUR_UI::update_speed_display () } speed_display_label.set_text (buf); } else { - speed_display_label.set_text (_("stopped")); + speed_display_label.set_text (_("stop")); } last_speed_displayed = x; @@ -904,7 +920,7 @@ ARDOUR_UI::set_transport_sensitivity (bool yn) void ARDOUR_UI::editor_realized () { - set_size_request_to_display_given_text (speed_display_box, _("stopped"), 2, 2); + set_size_request_to_display_given_text (speed_display_box, _("-0.55"), 2, 2); /* XXX: this should really be saved in instant.xml or something similar and restored from there */ shuttle_style_button.set_active_text (_("sprung")); const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index 202fa88b59..25f3068a81 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -76,8 +76,8 @@ ARDOUR_UI::connect_to_session (Session *s) rec_button.set_sensitive (true); shuttle_box.set_sensitive (true); - if (session->n_audio_diskstreams() == 0) { - session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added)); + if (session->n_diskstreams() == 0) { + session->DiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added)); } if (connection_editor) { diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 1bc2de26d1..238f81dd4f 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -264,31 +264,26 @@ ARDOUR_UI::install_actions () ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - /* XXX the newline in the displayed names of these action is really wrong, but its because we want the button - that proxies for these action to be more compact. It would be nice to find a way to override the action - name appearance on the buttons. - */ - - act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("Punch\nin"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in)); + act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("Punch In"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("Punch\nout"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out)); + 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_("ToggleClick"), _("Click"), mem_fun(*this, &ARDOUR_UI::toggle_click)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoInput"), _("Auto\ninput"), mem_fun(*this, &ARDOUR_UI::toggle_auto_input)); + act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoInput"), _("Auto Input"), mem_fun(*this, &ARDOUR_UI::toggle_auto_input)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoPlay"), _("Auto\nplay"), mem_fun(*this, &ARDOUR_UI::toggle_auto_play)); + act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoPlay"), _("Auto Play"), mem_fun(*this, &ARDOUR_UI::toggle_auto_play)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoReturn"), _("Auto\nreturn"), mem_fun(*this, &ARDOUR_UI::toggle_auto_return)); + act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoReturn"), _("Auto Return"), mem_fun(*this, &ARDOUR_UI::toggle_auto_return)); ActionManager::session_sensitive_actions.push_back (act); ActionManager::transport_sensitive_actions.push_back (act); - act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Time\nmaster"), mem_fun(*this, &ARDOUR_UI::toggle_time_master)); + act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Master"), mem_fun(*this, &ARDOUR_UI::toggle_time_master)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack1"), _("Toggle Record Enable Track1"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 0U)); diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h index 14dc6ba673..9ff5f45ddf 100644 --- a/gtk2_ardour/audio_clock.h +++ b/gtk2_ardour/audio_clock.h @@ -30,7 +30,7 @@ namespace ARDOUR { class Session; -}; +} class AudioClock : public Gtk::HBox { @@ -40,7 +40,7 @@ class AudioClock : public Gtk::HBox BBT, MinSec, Frames, - Off, + Off }; AudioClock (const string& name, bool editable, bool is_duration = false, bool with_tempo_meter = false); @@ -87,7 +87,7 @@ class AudioClock : public Gtk::HBox Bars, Beats, Ticks, - AudioFrames, + AudioFrames }; Gtk::EventBox audio_frames_ebox; diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/audio_region_editor.cc index 413ff01753..194f358b42 100644 --- a/gtk2_ardour/region_editor.cc +++ b/gtk2_ardour/audio_region_editor.cc @@ -24,8 +24,8 @@ #include <gtkmm2ext/stop_signal.h> #include <cmath> -#include "region_editor.h" -#include "regionview.h" +#include "audio_region_editor.h" +#include "audio_region_view.h" #include "ardour_ui.h" #include "utils.h" #include "gui_thread.h" @@ -37,9 +37,8 @@ using namespace PBD; using namespace sigc; using namespace std; -AudioRegionEditor::AudioRegionEditor (Session&s, AudioRegion& r, AudioRegionView& rv) - : ArdourDialog ("audio region editor"), - _session (s), +AudioRegionEditor::AudioRegionEditor (Session& s, AudioRegion& r, AudioRegionView& rv) + : RegionEditor (s), _region (r), _region_view (rv), name_label (_("NAME:")), diff --git a/gtk2_ardour/audio_region_editor.h b/gtk2_ardour/audio_region_editor.h new file mode 100644 index 0000000000..38cd920e5e --- /dev/null +++ b/gtk2_ardour/audio_region_editor.h @@ -0,0 +1,186 @@ +/* + Copyright (C) 2001 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __gtk_ardour_audio_region_edit_h__ +#define __gtk_ardour_audio_region_edit_h__ + +#include <map> + +#include <gtkmm/label.h> +#include <gtkmm/entry.h> +#include <gtkmm/box.h> +#include <gtkmm/togglebutton.h> +#include <gtkmm/button.h> +#include <gtkmm/arrow.h> +#include <gtkmm/frame.h> +#include <gtkmm/table.h> +#include <gtkmm/alignment.h> +#include <gtkmm/adjustment.h> +#include <gtkmm/separator.h> +#include <gtkmm/spinbutton.h> + +#include <libgnomecanvas/libgnomecanvas.h> +#include <sigc++/signal.h> + +#include "audio_clock.h" +#include "ardour_dialog.h" +#include "region_editor.h" + +namespace ARDOUR { + class AudioRegion; + class Session; +} + +class AudioRegionView; + +class AudioRegionEditor : public RegionEditor +{ + public: + AudioRegionEditor (ARDOUR::Session&, ARDOUR::AudioRegion&, AudioRegionView& rv); + ~AudioRegionEditor (); + + private: + ARDOUR::AudioRegion& _region; + AudioRegionView& _region_view; + + void connect_editor_events (); + + Gtk::Label name_label; + Gtk::Entry name_entry; + Gtk::HBox name_hbox; + + Gtk::HBox top_row_hbox; + Gtk::HBox top_row_button_hbox; + + Gtk::ToggleButton lock_button; + Gtk::ToggleButton mute_button; + Gtk::ToggleButton opaque_button; + Gtk::ToggleButton envelope_active_button; + Gtk::ToggleButton envelope_view_button; + + Gtk::Button raise_button; + Gtk::Arrow raise_arrow; + Gtk::Button lower_button; + Gtk::Arrow lower_arrow; + Gtk::Frame layer_frame; + Gtk::Label layer_value_label; + Gtk::Label layer_label; + Gtk::HBox layer_hbox; + + Gtk::ToggleButton audition_button; + + Gtk::HBox lower_hbox; + + Gtk::Table time_table; + + Gtk::Label start_label; + Gtk::Label end_label; + Gtk::Label length_label; + Gtk::Alignment start_alignment; + Gtk::Alignment end_alignment; + Gtk::Alignment length_alignment; + + AudioClock start_clock; + AudioClock end_clock; + AudioClock length_clock; + AudioClock sync_offset_clock; + + Gtk::Table envelope_loop_table; + Gtk::Button loop_button; + Gtk::Label loop_label; + Gtk::Label envelope_label; + + Gtk::Table fade_in_table; + Gtk::Label fade_in_label; + Gtk::Alignment fade_in_label_align; + Gtk::Label fade_in_active_button_label; + Gtk::ToggleButton fade_in_active_button; + Gtk::Label fade_in_length_label; + + Gtk::Adjustment fade_in_length_adjustment; + Gtk::SpinButton fade_in_length_spinner; + + Gtk::Table fade_out_table; + Gtk::Label fade_out_label; + Gtk::Alignment fade_out_label_align; + Gtk::Label fade_out_active_button_label; + Gtk::ToggleButton fade_out_active_button; + Gtk::Label fade_out_length_label; + + Gtk::Adjustment fade_out_length_adjustment; + Gtk::SpinButton fade_out_length_spinner; + + Gtk::HSeparator sep3; + Gtk::VSeparator sep1; + Gtk::VSeparator sep2; + + void region_changed (ARDOUR::Change); + void bounds_changed (ARDOUR::Change); + void name_changed (); + void opacity_changed (); + void mute_changed (); + void envelope_active_changed (); + void lock_changed (); + void layer_changed (); + + void fade_in_length_adjustment_changed (); + void fade_out_length_adjustment_changed (); + void fade_in_changed (); + void fade_out_changed (); + void audition_state_changed (bool); + + void activation (); + + void name_entry_changed (); + void start_clock_changed (); + void end_clock_changed (); + void length_clock_changed (); + + gint envelope_active_button_press (GdkEventButton *); + gint envelope_active_button_release (GdkEventButton *); + + void audition_button_toggled (); + void envelope_view_button_toggled (); + void lock_button_clicked (); + void mute_button_clicked (); + void opaque_button_clicked (); + void raise_button_clicked (); + void lower_button_clicked (); + + void fade_in_active_toggled (); + void fade_out_active_toggled (); + void fade_in_active_changed (); + void fade_out_active_changed (); + + void fade_in_realized (); + void fade_out_realized (); + + void start_editing_fade_in (); + void start_editing_fade_out (); + void stop_editing_fade_in (); + void stop_editing_fade_out (); + + gint bpressed (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)()); + gint breleased (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)()); + + bool spin_arrow_grab; +}; + +#endif /* __gtk_ardour_audio_region_edit_h__ */ diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc new file mode 100644 index 0000000000..feb8f4fd0b --- /dev/null +++ b/gtk2_ardour/audio_region_view.cc @@ -0,0 +1,1127 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include <cmath> +#include <cassert> +#include <algorithm> + +#include <gtkmm.h> + +#include <gtkmm2ext/gtk_ui.h> + +#include <ardour/playlist.h> +#include <ardour/audioregion.h> +#include <ardour/audiosource.h> +#include <ardour/audio_diskstream.h> + +#include "streamview.h" +#include "audio_region_view.h" +#include "audio_time_axis.h" +#include "simplerect.h" +#include "simpleline.h" +#include "waveview.h" +#include "public_editor.h" +#include "audio_region_editor.h" +#include "region_gain_line.h" +#include "ghostregion.h" +#include "audio_time_axis.h" +#include "utils.h" +#include "rgb_macros.h" +#include "gui_thread.h" + +#include "i18n.h" + +using namespace sigc; +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; +using namespace ArdourCanvas; + +static const int32_t sync_mark_width = 9; + +AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, + Gdk::Color& basic_color) + : RegionView (parent, tv, r, spu, basic_color) + , sync_mark(0) + , zero_line(0) + , fade_in_shape(0) + , fade_out_shape(0) + , fade_in_handle(0) + , fade_out_handle(0) + , gain_line(0) + , _amplitude_above_axis(1.0) + , _flags(0) + , fade_color(0) +{ +} + +AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, + Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility) + : RegionView (parent, tv, r, spu, basic_color, visibility) + , sync_mark(0) + , zero_line(0) + , fade_in_shape(0) + , fade_out_shape(0) + , fade_in_handle(0) + , fade_out_handle(0) + , gain_line(0) + , _amplitude_above_axis(1.0) + , _flags(0) + , fade_color(0) +{ +} + +void +AudioRegionView::init (Gdk::Color& basic_color, bool wfd) +{ + // FIXME: Some redundancy here with RegionView::init. Need to figure out + // where order is important and where it isn't... + + RegionView::init(basic_color, wfd); + + XMLNode *node; + + _amplitude_above_axis = 1.0; + zero_line = 0; + _flags = 0; + + if ((node = _region.extra_xml ("GUI")) != 0) { + set_flags (node); + } else { + _flags = WaveformVisible; + store_flags (); + } + + if (trackview.editor.new_regionviews_display_gain()) { + _flags |= EnvelopeVisible; + } + + compute_colors (basic_color); + + create_waves (); + + fade_in_shape = new ArdourCanvas::Polygon (*group); + fade_in_shape->property_fill_color_rgba() = fade_color; + fade_in_shape->set_data ("regionview", this); + + fade_out_shape = new ArdourCanvas::Polygon (*group); + fade_out_shape->property_fill_color_rgba() = fade_color; + fade_out_shape->set_data ("regionview", this); + + + { + uint32_t r,g,b,a; + UINT_TO_RGBA(fill_color,&r,&g,&b,&a); + + + fade_in_handle = new ArdourCanvas::SimpleRect (*group); + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); + fade_in_handle->property_outline_pixels() = 0; + fade_in_handle->property_y1() = 2.0; + fade_in_handle->property_y2() = 7.0; + + fade_in_handle->set_data ("regionview", this); + + fade_out_handle = new ArdourCanvas::SimpleRect (*group); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0); + fade_out_handle->property_outline_pixels() = 0; + fade_out_handle->property_y1() = 2.0; + fade_out_handle->property_y2() = 7.0; + + fade_out_handle->set_data ("regionview", this); + } + + string foo = _region.name(); + foo += ':'; + foo += "gain"; + + gain_line = new AudioRegionGainLine (foo, trackview.session(), *this, *group, audio_region().envelope()); + + if (!(_flags & EnvelopeVisible)) { + gain_line->hide (); + } else { + gain_line->show (); + } + + reset_width_dependent_items ((double) _region.length() / samples_per_unit); + + gain_line->reset (); + + set_height (trackview.height); + + region_muted (); + region_sync_changed (); + region_resized (BoundsChanged); + set_waveview_data_src(); + region_locked (); + envelope_active_changed (); + fade_in_active_changed (); + fade_out_active_changed (); + + _region.StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed)); + + fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this)); + fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this)); + fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this)); + fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this)); + + set_colors (); + + /* XXX sync mark drag? */ +} + +AudioRegionView::~AudioRegionView () +{ + in_destructor = true; + + RegionViewGoingAway (this); /* EMIT_SIGNAL */ + + for (vector<GnomeCanvasWaveViewCache *>::iterator cache = wave_caches.begin(); cache != wave_caches.end() ; ++cache) { + gnome_canvas_waveview_cache_destroy (*cache); + } + + /* all waveviews etc will be destroyed when the group is destroyed */ + + if (gain_line) { + delete gain_line; + } +} + +ARDOUR::AudioRegion& +AudioRegionView::audio_region() const +{ + // "Guaranteed" to succeed... + return dynamic_cast<AudioRegion&>(_region); +} + +void +AudioRegionView::region_changed (Change what_changed) +{ + ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed)); + + RegionView::region_changed(what_changed); + + if (what_changed & AudioRegion::ScaleAmplitudeChanged) { + region_scale_amplitude_changed (); + } + if (what_changed & AudioRegion::FadeInChanged) { + fade_in_changed (); + } + if (what_changed & AudioRegion::FadeOutChanged) { + fade_out_changed (); + } + if (what_changed & AudioRegion::FadeInActiveChanged) { + fade_in_active_changed (); + } + if (what_changed & AudioRegion::FadeOutActiveChanged) { + fade_out_active_changed (); + } + if (what_changed & AudioRegion::EnvelopeActiveChanged) { + envelope_active_changed (); + } +} + +void +AudioRegionView::fade_in_changed () +{ + reset_fade_in_shape (); +} + +void +AudioRegionView::fade_out_changed () +{ + reset_fade_out_shape (); +} + +void +AudioRegionView::set_fade_in_active (bool yn) +{ + audio_region().set_fade_in_active (yn); +} + +void +AudioRegionView::set_fade_out_active (bool yn) +{ + audio_region().set_fade_out_active (yn); +} + +void +AudioRegionView::fade_in_active_changed () +{ + uint32_t r,g,b,a; + uint32_t col; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + + if (audio_region().fade_in_active()) { + col = RGBA_TO_UINT(r,g,b,120); + fade_in_shape->property_fill_color_rgba() = col; + fade_in_shape->property_width_pixels() = 0; + fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); + } else { + col = RGBA_TO_UINT(r,g,b,0); + fade_in_shape->property_fill_color_rgba() = col; + fade_in_shape->property_width_pixels() = 1; + fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); + } +} + +void +AudioRegionView::fade_out_active_changed () +{ + uint32_t r,g,b,a; + uint32_t col; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + + if (audio_region().fade_out_active()) { + col = RGBA_TO_UINT(r,g,b,120); + fade_out_shape->property_fill_color_rgba() = col; + fade_out_shape->property_width_pixels() = 0; + fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0); + } else { + col = RGBA_TO_UINT(r,g,b,0); + fade_out_shape->property_fill_color_rgba() = col; + fade_out_shape->property_width_pixels() = 1; + fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255); + } +} + + +void +AudioRegionView::region_scale_amplitude_changed () +{ + ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed)); + + for (uint32_t n = 0; n < waves.size(); ++n) { + // force a reload of the cache + waves[n]->property_data_src() = &_region; + } +} + +void +AudioRegionView::region_resized (Change what_changed) +{ + RegionView::region_resized(what_changed); + + if (what_changed & Change (StartChanged|LengthChanged)) { + + for (uint32_t n = 0; n < waves.size(); ++n) { + waves[n]->property_region_start() = _region.start(); + } + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { + (*w)->property_region_start() = _region.start(); + } + } + } +} + +void +AudioRegionView::reset_width_dependent_items (double pixel_width) +{ + RegionView::reset_width_dependent_items(pixel_width); + assert(_pixel_width == pixel_width); + + if (zero_line) { + zero_line->property_x2() = pixel_width - 1.0; + } + + if (fade_in_handle) { + if (pixel_width <= 6.0) { + fade_in_handle->hide(); + fade_out_handle->hide(); + } else { + if (_height < 5.0) { + fade_in_handle->hide(); + fade_out_handle->hide(); + } else { + fade_in_handle->show(); + fade_out_handle->show(); + } + } + } + + reset_fade_shapes (); +} + +void +AudioRegionView::region_muted () +{ + RegionView::region_muted(); + + for (uint32_t n=0; n < waves.size(); ++n) { + if (_region.muted()) { + waves[n]->property_wave_color() = color_map[cMutedWaveForm]; + } else { + waves[n]->property_wave_color() = color_map[cWaveForm]; + } + } +} + + +void +AudioRegionView::set_height (gdouble height) +{ + uint32_t wcnt = waves.size(); + + // FIXME: ick + TimeAxisViewItem::set_height (height - 2); + + _height = height; + + for (uint32_t n=0; n < wcnt; ++n) { + gdouble ht; + + if ((height) <= NAME_HIGHLIGHT_THRESH) { + ht = ((height-2*wcnt) / (double) wcnt); + } else { + ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt); + } + + gdouble yoff = n * (ht+1); + + waves[n]->property_height() = ht; + waves[n]->property_y() = yoff + 2; + } + + if (gain_line) { + if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) { + gain_line->hide (); + } else { + if (_flags & EnvelopeVisible) { + gain_line->show (); + } + } + gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE)); + } + + manage_zero_line (); + reset_fade_shapes (); + + if (name_text) { + name_text->raise_to_top(); + } +} + +void +AudioRegionView::manage_zero_line () +{ + if (!zero_line) { + return; + } + + if (_height >= 100) { + gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0; + zero_line->property_y1() = wave_midpoint; + zero_line->property_y2() = wave_midpoint; + zero_line->show(); + } else { + zero_line->hide(); + } +} + +void +AudioRegionView::reset_fade_shapes () +{ + reset_fade_in_shape (); + reset_fade_out_shape (); +} + +void +AudioRegionView::reset_fade_in_shape () +{ + reset_fade_in_shape_width ((jack_nframes_t) audio_region().fade_in().back()->when); +} + +void +AudioRegionView::reset_fade_in_shape_width (jack_nframes_t width) +{ + if (fade_in_handle == 0) { + return; + } + + /* smallest size for a fade is 64 frames */ + + width = std::max ((jack_nframes_t) 64, width); + + Points* points; + double pwidth = width / samples_per_unit; + uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); + double h; + + if (_height < 5) { + fade_in_shape->hide(); + fade_in_handle->hide(); + return; + } + + double handle_center; + handle_center = pwidth; + + if (handle_center > 7.0) { + handle_center -= 3.0; + } else { + handle_center = 3.0; + } + + fade_in_handle->property_x1() = handle_center - 3.0; + fade_in_handle->property_x2() = handle_center + 3.0; + + if (pwidth < 5) { + fade_in_shape->hide(); + return; + } + + fade_in_shape->show(); + + float curve[npoints]; + audio_region().fade_in().get_vector (0, audio_region().fade_in().back()->when, curve, npoints); + + points = get_canvas_points ("fade in shape", npoints+3); + + if (_height > NAME_HIGHLIGHT_THRESH) { + h = _height - NAME_HIGHLIGHT_SIZE; + } else { + h = _height; + } + + /* points *MUST* be in anti-clockwise order */ + + uint32_t pi, pc; + double xdelta = pwidth/npoints; + + for (pi = 0, pc = 0; pc < npoints; ++pc) { + (*points)[pi].set_x(1 + (pc * xdelta)); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); + } + + /* fold back */ + + (*points)[pi].set_x(pwidth); + (*points)[pi++].set_y(2); + + (*points)[pi].set_x(1); + (*points)[pi++].set_y(2); + + /* connect the dots ... */ + + (*points)[pi] = (*points)[0]; + + fade_in_shape->property_points() = *points; + delete points; +} + +void +AudioRegionView::reset_fade_out_shape () +{ + reset_fade_out_shape_width ((jack_nframes_t) audio_region().fade_out().back()->when); +} + +void +AudioRegionView::reset_fade_out_shape_width (jack_nframes_t width) +{ + if (fade_out_handle == 0) { + return; + } + + /* smallest size for a fade is 64 frames */ + + width = std::max ((jack_nframes_t) 64, width); + + Points* points; + double pwidth = width / samples_per_unit; + uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth); + double h; + + if (_height < 5) { + fade_out_shape->hide(); + fade_out_handle->hide(); + return; + } + + double handle_center; + handle_center = (_region.length() - width) / samples_per_unit; + + if (handle_center > 7.0) { + handle_center -= 3.0; + } else { + handle_center = 3.0; + } + + fade_out_handle->property_x1() = handle_center - 3.0; + fade_out_handle->property_x2() = handle_center + 3.0; + + /* don't show shape if its too small */ + + if (pwidth < 5) { + fade_out_shape->hide(); + return; + } + + fade_out_shape->show(); + + float curve[npoints]; + audio_region().fade_out().get_vector (0, audio_region().fade_out().back()->when, curve, npoints); + + if (_height > NAME_HIGHLIGHT_THRESH) { + h = _height - NAME_HIGHLIGHT_SIZE; + } else { + h = _height; + } + + /* points *MUST* be in anti-clockwise order */ + + points = get_canvas_points ("fade out shape", npoints+3); + + uint32_t pi, pc; + double xdelta = pwidth/npoints; + + for (pi = 0, pc = 0; pc < npoints; ++pc) { + (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta)); + (*points)[pi++].set_y(2 + (h - (curve[pc] * h))); + } + + /* fold back */ + + (*points)[pi].set_x(_pixel_width); + (*points)[pi++].set_y(h); + + (*points)[pi].set_x(_pixel_width); + (*points)[pi++].set_y(2); + + /* connect the dots ... */ + + (*points)[pi] = (*points)[0]; + + fade_out_shape->property_points() = *points; + delete points; +} + +void +AudioRegionView::set_samples_per_unit (gdouble spu) +{ + RegionView::set_samples_per_unit (spu); + + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->property_samples_per_unit() = spu; + } + + if (gain_line) { + gain_line->reset (); + } + reset_fade_shapes (); +} + +void +AudioRegionView::set_amplitude_above_axis (gdouble spp) +{ + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->property_amplitude_above_axis() = spp; + } +} + +void +AudioRegionView::compute_colors (Gdk::Color& basic_color) +{ + RegionView::compute_colors(basic_color); + + uint32_t r, g, b, a; + + /* gain color computed in envelope_active_changed() */ + + UINT_TO_RGBA (fill_color, &r, &g, &b, &a); + fade_color = RGBA_TO_UINT(r,g,b,120); +} + +void +AudioRegionView::set_colors () +{ + RegionView::set_colors(); + + if (gain_line) { + gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); + } + + for (uint32_t n=0; n < waves.size(); ++n) { + if (_region.muted()) { + waves[n]->property_wave_color() = color_map[cMutedWaveForm]; + } else { + waves[n]->property_wave_color() = color_map[cWaveForm]; + } + } +} + +void +AudioRegionView::show_region_editor () +{ + if (editor == 0) { + editor = new AudioRegionEditor (trackview.session(), audio_region(), *this); + // GTK2FIX : how to ensure float without realizing + // editor->realize (); + // trackview.editor.ensure_float (*editor); + } + + editor->show_all (); + editor->get_window()->raise(); +} + +void +AudioRegionView::set_waveform_visible (bool yn) +{ + if (((_flags & WaveformVisible) != yn)) { + if (yn) { + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->show(); + } + _flags |= WaveformVisible; + } else { + for (uint32_t n=0; n < waves.size(); ++n) { + waves[n]->hide(); + } + _flags &= ~WaveformVisible; + } + store_flags (); + } +} + +void +AudioRegionView::temporarily_hide_envelope () +{ + if (gain_line) { + gain_line->hide (); + } +} + +void +AudioRegionView::unhide_envelope () +{ + if (gain_line && (_flags & EnvelopeVisible)) { + gain_line->show (); + } +} + +void +AudioRegionView::set_envelope_visible (bool yn) +{ + if (gain_line && ((_flags & EnvelopeVisible) != yn)) { + if (yn) { + gain_line->show (); + _flags |= EnvelopeVisible; + } else { + gain_line->hide (); + _flags &= ~EnvelopeVisible; + } + store_flags (); + } +} + +void +AudioRegionView::create_waves () +{ + bool create_zero_line = true; + + RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick + + if (!atv.get_diskstream()) { + return; + } + + uint32_t nchans = atv.get_diskstream()->n_channels(); + + /* in tmp_waves, set up null pointers for each channel so the vector is allocated */ + for (uint32_t n = 0; n < nchans; ++n) { + tmp_waves.push_back (0); + } + + for (uint32_t n = 0; n < nchans; ++n) { + + if (n >= audio_region().n_channels()) { + break; + } + + wave_caches.push_back (WaveView::create_cache ()); + + if (wait_for_data) { + if (audio_region().source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) { + create_one_wave (n, true); + } else { + create_zero_line = false; + } + } else { + create_one_wave (n, true); + } + } + + if (create_zero_line) { + zero_line = new ArdourCanvas::SimpleLine (*group); + zero_line->property_x1() = (gdouble) 1.0; + zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + manage_zero_line (); + } +} + +void +AudioRegionView::create_one_wave (uint32_t which, bool direct) +{ + RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick + uint32_t nchans = atv.get_diskstream()->n_channels(); + uint32_t n; + uint32_t nwaves = std::min (nchans, audio_region().n_channels()); + gdouble ht; + + if (trackview.height < NAME_HIGHLIGHT_SIZE) { + ht = ((trackview.height) / (double) nchans); + } else { + ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans); + } + + gdouble yoff = which * ht; + + WaveView *wave = new WaveView(*group); + + wave->property_data_src() = (gpointer) &_region; + wave->property_cache() = wave_caches[which]; + wave->property_cache_updater() = true; + wave->property_channel() = which; + wave->property_length_function() = (gpointer) region_length_from_c; + wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; + wave->property_peak_function() = (gpointer) region_read_peaks_from_c; + wave->property_x() = 0.0; + wave->property_y() = yoff; + wave->property_height() = (double) ht; + wave->property_samples_per_unit() = samples_per_unit; + wave->property_amplitude_above_axis() = _amplitude_above_axis; + wave->property_wave_color() = _region.muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm]; + wave->property_region_start() = _region.start(); + + if (!(_flags & WaveformVisible)) { + wave->hide(); + } + + /* note: calling this function is serialized by the lock + held in the peak building thread that signals that + peaks are ready for use *or* by the fact that it is + called one by one from the GUI thread. + */ + + if (which < nchans) { + tmp_waves[which] = wave; + } else { + /* n-channel track, >n-channel source */ + } + + /* see if we're all ready */ + + for (n = 0; n < nchans; ++n) { + if (tmp_waves[n] == 0) { + break; + } + } + + if (n == nwaves && waves.empty()) { + /* all waves are ready */ + tmp_waves.resize(nwaves); + + waves = tmp_waves; + tmp_waves.clear (); + + if (!zero_line) { + zero_line = new ArdourCanvas::SimpleLine (*group); + zero_line->property_x1() = (gdouble) 1.0; + zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0; + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + manage_zero_line (); + } + } +} + +void +AudioRegionView::peaks_ready_handler (uint32_t which) +{ + Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false)); + + if (!waves.empty()) { + /* all waves created, don't hook into peaks ready anymore */ + data_ready_connection.disconnect (); + } +} + +void +AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) +{ + if (gain_line == 0) { + return; + } + + double x, y; + + /* don't create points that can't be seen */ + + set_envelope_visible (true); + + x = ev->button.x; + y = ev->button.y; + + item->w2i (x, y); + + jack_nframes_t fx = trackview.editor.pixel_to_frame (x); + + if (fx > _region.length()) { + return; + } + + /* compute vertical fractional position */ + + y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE)); + + /* map using gain line */ + + gain_line->view_to_model_y (y); + + trackview.session().begin_reversible_command (_("add gain control point")); + trackview.session().add_undo (audio_region().envelope().get_memento()); + + + if (!audio_region().envelope_active()) { + trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) ); + audio_region().set_envelope_active(true); + trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) ); + } + + audio_region().envelope().add (fx, y); + + trackview.session().add_redo_no_execute (audio_region().envelope().get_memento()); + trackview.session().commit_reversible_command (); +} + +void +AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) +{ + ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point")); + audio_region().envelope().erase (cp->model); +} + +void +AudioRegionView::store_flags() +{ + XMLNode *node = new XMLNode ("GUI"); + + node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no"); + node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no"); + + _region.add_extra_xml (*node); +} + +void +AudioRegionView::set_flags (XMLNode* node) +{ + XMLProperty *prop; + + if ((prop = node->property ("waveform-visible")) != 0) { + if (prop->value() == "yes") { + _flags |= WaveformVisible; + } + } + + if ((prop = node->property ("envelope-visible")) != 0) { + if (prop->value() == "yes") { + _flags |= EnvelopeVisible; + } + } +} + +void +AudioRegionView::set_waveform_shape (WaveformShape shape) +{ + bool yn; + + /* this slightly odd approach is to leave the door open to + other "shapes" such as spectral displays, etc. + */ + + switch (shape) { + case Rectified: + yn = true; + break; + + default: + yn = false; + break; + } + + if (yn != (bool) (_flags & WaveformRectified)) { + for (vector<WaveView *>::iterator wave = waves.begin(); wave != waves.end() ; ++wave) { + (*wave)->property_rectified() = yn; + } + + if (zero_line) { + if (yn) { + zero_line->hide(); + } else { + zero_line->show(); + } + } + + if (yn) { + _flags |= WaveformRectified; + } else { + _flags &= ~WaveformRectified; + } + } +} + +GhostRegion* +AudioRegionView::add_ghost (AutomationTimeAxisView& atv) +{ + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&trackview); + assert(rtv); + + double unit_position = _region.position () / samples_per_unit; + GhostRegion* ghost = new GhostRegion (atv, unit_position); + uint32_t nchans; + + nchans = rtv->get_diskstream()->n_channels(); + + for (uint32_t n = 0; n < nchans; ++n) { + + if (n >= audio_region().n_channels()) { + break; + } + + WaveView *wave = new WaveView(*ghost->group); + + wave->property_data_src() = &_region; + wave->property_cache() = wave_caches[n]; + wave->property_cache_updater() = false; + wave->property_channel() = n; + wave->property_length_function() = (gpointer)region_length_from_c; + wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c; + wave->property_peak_function() = (gpointer) region_read_peaks_from_c; + wave->property_x() = 0.0; + wave->property_samples_per_unit() = samples_per_unit; + wave->property_amplitude_above_axis() = _amplitude_above_axis; + wave->property_wave_color() = color_map[cGhostTrackWave]; + wave->property_region_start() = _region.start(); + + ghost->waves.push_back(wave); + } + + ghost->set_height (); + ghost->set_duration (_region.length() / samples_per_unit); + ghosts.push_back (ghost); + + ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost)); + + return ghost; +} + +void +AudioRegionView::entered () +{ + if (gain_line && _flags & EnvelopeVisible) { + gain_line->show_all_control_points (); + } + + uint32_t r,g,b,a; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + a=255; + + if (fade_in_handle) { + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + } +} + +void +AudioRegionView::exited () +{ + if (gain_line) { + gain_line->hide_all_but_selected_control_points (); + } + + uint32_t r,g,b,a; + UINT_TO_RGBA(fade_color,&r,&g,&b,&a); + a=0; + + if (fade_in_handle) { + fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a); + } +} + +void +AudioRegionView::envelope_active_changed () +{ + if (gain_line) { + gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]); + } +} + +void +AudioRegionView::set_waveview_data_src() +{ + + double unit_length= _region.length() / samples_per_unit; + + for (uint32_t n = 0; n < waves.size(); ++n) { + // TODO: something else to let it know the channel + waves[n]->property_data_src() = &_region; + } + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + (*i)->set_duration (unit_length); + + for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) { + (*w)->property_data_src() = &_region; + } + } + +} + +void +AudioRegionView::color_handler (ColorID id, uint32_t val) +{ + switch (id) { + case cMutedWaveForm: + case cWaveForm: + set_colors (); + break; + + case cGainLineInactive: + case cGainLine: + envelope_active_changed(); + break; + + case cZeroLine: + if (zero_line) { + zero_line->property_color_rgba() = (guint) color_map[cZeroLine]; + } + break; + + case cGhostTrackWave: + break; + + default: + break; + } +} diff --git a/gtk2_ardour/regionview.h b/gtk2_ardour/audio_region_view.h index f49b46aea4..ec3ea6c4c5 100644 --- a/gtk2_ardour/regionview.h +++ b/gtk2_ardour/audio_region_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2004 Paul Davis + Copyright (C) 2001-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,12 +14,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ */ -#ifndef __gtk_ardour_region_view_h__ -#define __gtk_ardour_region_view_h__ +#ifndef __gtk_ardour_audio_region_view_h__ +#define __gtk_ardour_audio_region_view_h__ #include <vector> @@ -28,6 +26,8 @@ #include <sigc++/signal.h> #include <ardour/region.h> +#include "region_view.h" +#include "route_time_axis.h" #include "time_axis_view_item.h" #include "automation_line.h" #include "enums.h" @@ -46,51 +46,38 @@ class AudioRegionEditor; class GhostRegion; class AutomationTimeAxisView; -class AudioRegionView : public TimeAxisViewItem +class AudioRegionView : public RegionView { public: AudioRegionView (ArdourCanvas::Group *, - AudioTimeAxisView&, + RouteTimeAxisView&, ARDOUR::AudioRegion&, double initial_samples_per_unit, Gdk::Color& basic_color); ~AudioRegionView (); - virtual void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves); + virtual void init (Gdk::Color& base_color, bool wait_for_data = false); + + ARDOUR::AudioRegion& audio_region() const; - ARDOUR::AudioRegion& region; // ok, let 'em have it - bool is_valid() const { return valid; } - void set_valid (bool yn) { valid = yn; } - void set_height (double); void set_samples_per_unit (double); - bool set_duration (jack_nframes_t, void*); void set_amplitude_above_axis (gdouble spp); - void move (double xdelta, double ydelta); - - void raise (); - void raise_to_top (); - void lower (); - void lower_to_bottom (); - - bool set_position(jack_nframes_t pos, void* src, double* delta = 0); - - void temporarily_hide_envelope (); // dangerous - void unhide_envelope (); // dangerous + void temporarily_hide_envelope (); ///< Dangerous! + void unhide_envelope (); ///< Dangerous! void set_envelope_visible (bool); void set_waveform_visible (bool yn); void set_waveform_shape (WaveformShape); bool waveform_rectified() const { return _flags & WaveformRectified; } - bool waveform_visible() const { return _flags & WaveformVisible; } - bool envelope_visible() const { return _flags & EnvelopeVisible; } + bool waveform_visible() const { return _flags & WaveformVisible; } + bool envelope_visible() const { return _flags & EnvelopeVisible; } void show_region_editor (); - void hide_region_editor(); void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event); @@ -100,19 +87,13 @@ class AudioRegionView : public TimeAxisViewItem void region_changed (ARDOUR::Change); void envelope_active_changed (); - static sigc::signal<void,AudioRegionView*> AudioRegionViewGoingAway; - sigc::signal<void> GoingAway; - GhostRegion* add_ghost (AutomationTimeAxisView&); - void remove_ghost (GhostRegion*); void reset_fade_in_shape_width (jack_nframes_t); void reset_fade_out_shape_width (jack_nframes_t); void set_fade_in_active (bool); void set_fade_out_active (bool); - uint32_t get_fill_color (); - virtual void entered (); virtual void exited (); @@ -124,44 +105,18 @@ class AudioRegionView : public TimeAxisViewItem */ AudioRegionView (ArdourCanvas::Group *, - AudioTimeAxisView&, - ARDOUR::AudioRegion&, - double initial_samples_per_unit, - Gdk::Color& basic_color, - TimeAxisViewItem::Visibility); + RouteTimeAxisView&, + ARDOUR::AudioRegion&, + double samples_per_unit, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility); enum Flags { EnvelopeVisible = 0x1, WaveformVisible = 0x4, WaveformRectified = 0x8 }; - - vector<ArdourCanvas::WaveView *> waves; /* waveviews */ - vector<ArdourCanvas::WaveView *> tmp_waves; /* see ::create_waves()*/ - ArdourCanvas::Polygon* sync_mark; /* polgyon for sync position */ - ArdourCanvas::Text* no_wave_msg; /* text */ - ArdourCanvas::SimpleLine* zero_line; /* simpleline */ - ArdourCanvas::Polygon* fade_in_shape; /* polygon */ - ArdourCanvas::Polygon* fade_out_shape; /* polygon */ - ArdourCanvas::SimpleRect* fade_in_handle; /* simplerect */ - ArdourCanvas::SimpleRect* fade_out_handle; /* simplerect */ - - AudioRegionGainLine* gain_line; - AudioRegionEditor *editor; - - vector<ControlPoint *> control_points; - double _amplitude_above_axis; - double current_visible_sync_position; - - uint32_t _flags; - uint32_t fade_color; - bool valid; /* see StreamView::redisplay_diskstream() */ - double _pixel_width; - double _height; - bool in_destructor; - bool wait_for_waves; - sigc::connection peaks_ready_connection; - + void reset_fade_shapes (); void reset_fade_in_shape (); void reset_fade_out_shape (); @@ -173,34 +128,37 @@ class AudioRegionView : public TimeAxisViewItem void region_resized (ARDOUR::Change); void region_moved (void *); void region_muted (); - void region_locked (); - void region_opacity (); - void region_layered (); - void region_renamed (); - void region_sync_changed (); void region_scale_amplitude_changed (); - static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*); - void lock_toggle (); - void create_waves (); void create_one_wave (uint32_t, bool); void manage_zero_line (); void peaks_ready_handler (uint32_t); - void reset_name (gdouble width); void set_flags (XMLNode *); void store_flags (); void set_colors (); void compute_colors (Gdk::Color&); - virtual void set_frame_color (); void reset_width_dependent_items (double pixel_width); void set_waveview_data_src(); + + void color_handler (ColorID, uint32_t); vector<GnomeCanvasWaveViewCache*> wave_caches; - vector<GhostRegion*> ghosts; - - void color_handler (ColorID, uint32_t); + vector<ArdourCanvas::WaveView *> waves; + vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves() + ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position + ArdourCanvas::SimpleLine* zero_line; + ArdourCanvas::Polygon* fade_in_shape; + ArdourCanvas::Polygon* fade_out_shape; + ArdourCanvas::SimpleRect* fade_in_handle; + ArdourCanvas::SimpleRect* fade_out_handle; + AudioRegionGainLine* gain_line; + + double _amplitude_above_axis; + + uint32_t _flags; + uint32_t fade_color; }; -#endif /* __gtk_ardour_region_view_h__ */ +#endif /* __gtk_ardour_audio_region_view_h__ */ diff --git a/gtk2_ardour/regionview.cc b/gtk2_ardour/audio_regionview.cc index dcc71a03c4..e2d20c0cc0 100644 --- a/gtk2_ardour/regionview.cc +++ b/gtk2_ardour/audio_regionview.cc @@ -15,7 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ + $Id: regionview.cc 678 2006-07-11 15:45:19Z paul $ */ #include <cmath> @@ -29,10 +29,9 @@ #include <ardour/audioregion.h> #include <ardour/audiosource.h> #include <ardour/audio_diskstream.h> -#include <pbd/memento_command.h> #include "streamview.h" -#include "regionview.h" +#include "region_view.h" #include "audio_time_axis.h" #include "simplerect.h" #include "simpleline.h" @@ -519,7 +518,7 @@ AudioRegionView::set_height (gdouble height) for (uint32_t n=0; n < wcnt; ++n) { gdouble ht; - if ((height) < NAME_HIGHLIGHT_THRESH) { + if ((height) <= NAME_HIGHLIGHT_THRESH) { ht = ((height-2*wcnt) / (double) wcnt); } else { ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt); @@ -1145,20 +1144,18 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev) gain_line->view_to_model_y (y); trackview.session().begin_reversible_command (_("add gain control point")); - XMLNode &before = region.envelope().get_state(); + trackview.session().add_undo (region.envelope().get_memento()); if (!region.envelope_active()) { - XMLNode &before = region.get_state(); + trackview.session().add_undo( bind( mem_fun(region, &AudioRegion::set_envelope_active), false) ); region.set_envelope_active(true); - XMLNode &after = region.get_state(); - trackview.session().add_command(new MementoCommand<AudioRegion>(region, before, after)); + trackview.session().add_redo( bind( mem_fun(region, &AudioRegion::set_envelope_active), true) ); } region.envelope().add (fx, y); - XMLNode &after = region.envelope().get_state(); - trackview.session().add_command(new MementoCommand<Curve>(region.envelope(), before, after)); + trackview.session().add_redo_no_execute (region.envelope().get_memento()); trackview.session().commit_reversible_command (); } diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc new file mode 100644 index 0000000000..82349947c6 --- /dev/null +++ b/gtk2_ardour/audio_streamview.cc @@ -0,0 +1,700 @@ +/* + Copyright (C) 2001, 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <cmath> +#include <cassert> + +#include <gtkmm.h> + +#include <gtkmm2ext/gtk_ui.h> + +#include <ardour/audioplaylist.h> +#include <ardour/audioregion.h> +#include <ardour/audiosource.h> +#include <ardour/audio_diskstream.h> +#include <ardour/audio_track.h> +#include <ardour/playlist_templates.h> +#include <ardour/source.h> + +#include "audio_streamview.h" +#include "audio_region_view.h" +#include "tape_region_view.h" +#include "audio_time_axis.h" +#include "canvas-waveview.h" +#include "canvas-simplerect.h" +#include "region_selection.h" +#include "selection.h" +#include "public_editor.h" +#include "ardour_ui.h" +#include "crossfade_view.h" +#include "rgb_macros.h" +#include "gui_thread.h" +#include "utils.h" +#include "color.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; + +AudioStreamView::AudioStreamView (AudioTimeAxisView& tv) + : StreamView (tv) +{ + crossfades_visible = true; + + if (tv.is_audio_track()) + stream_base_color = color_map[cAudioTrackBase]; + else + stream_base_color = color_map[cAudioBusBase]; + + canvas_rect->property_fill_color_rgba() = stream_base_color; + canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline]; + + _amplitude_above_axis = 1.0; + + use_rec_regions = tv.editor.show_waveforms_recording (); + last_rec_peak_frame = 0; +} + +AudioStreamView::~AudioStreamView () +{ +} + +int +AudioStreamView::set_height (gdouble h) +{ + /* limit the values to something sane-ish */ + if (h < 10.0 || h > 1000.0) { + return -1; + } + + StreamView::set_height(h); + + for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + (*i)->set_height (h); + } + + return 0; +} + +int +AudioStreamView::set_samples_per_unit (gdouble spp) +{ + StreamView::set_samples_per_unit(spp); + + for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) { + (*xi)->set_samples_per_unit (spp); + } + + return 0; +} + +int +AudioStreamView::set_amplitude_above_axis (gdouble app) +{ + RegionViewList::iterator i; + + if (app < 1.0) { + return -1; + } + + _amplitude_above_axis = app; + + for (i = region_views.begin(); i != region_views.end(); ++i) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + arv->set_amplitude_above_axis (app); + } + + return 0; +} + +void +AudioStreamView::add_region_view_internal (Region *r, bool wait_for_waves) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r)); + + AudioRegion* region = dynamic_cast<AudioRegion*> (r); + + if (region == 0) { + return; + } + + AudioRegionView *region_view; + list<RegionView *>::iterator i; + + for (i = region_views.begin(); i != region_views.end(); ++i) { + if (&(*i)->region() == r) { + + /* great. we already have a AudioRegionView for this Region. use it again. */ + + (*i)->set_valid (true); + return; + } + } + + switch (_trackview.audio_track()->mode()) { + case Normal: + region_view = new AudioRegionView (canvas_group, _trackview, *region, + _samples_per_unit, region_color); + break; + case Destructive: + region_view = new TapeAudioRegionView (canvas_group, _trackview, *region, + _samples_per_unit, region_color); + break; + } + + region_view->init (region_color, wait_for_waves); + region_view->set_amplitude_above_axis(_amplitude_above_axis); + region_views.push_front (region_view); + + /* follow global waveform setting */ + + region_view->set_waveform_visible(_trackview.editor.show_waveforms()); + + /* catch regionview going away */ + + region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_region_view)); + + RegionViewAdded (region_view); +} + +void +AudioStreamView::remove_region_view (Region *r) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), r)); + + for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) { + list<CrossfadeView*>::iterator tmp; + + tmp = i; + ++tmp; + + AudioRegion* ar = dynamic_cast<AudioRegion*>(r); + if (ar && (*i)->crossfade.involves (*ar)) { + delete *i; + crossfade_views.erase (i); + } + + i = tmp; + } + + StreamView::remove_region_view(r); +} + +void +AudioStreamView::undisplay_diskstream () +{ + StreamView::undisplay_diskstream(); + + for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + delete *i; + } + + crossfade_views.clear (); +} + +void +AudioStreamView::playlist_modified () +{ + ENSURE_GUI_THREAD (mem_fun (*this, &AudioStreamView::playlist_modified)); + + StreamView::playlist_modified(); + + /* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked + correctly. + */ + + for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + (*i)->get_canvas_group()->raise_to_top(); + } +} + +void +AudioStreamView::playlist_changed (Diskstream *ds) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::playlist_changed), ds)); + + StreamView::playlist_changed(ds); + + AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist()); + if (apl) + playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade))); +} + +void +AudioStreamView::add_crossfade (Crossfade *crossfade) +{ + AudioRegionView* lview = 0; + AudioRegionView* rview = 0; + + ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade)); + + /* first see if we already have a CrossfadeView for this Crossfade */ + + for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + if (&(*i)->crossfade == crossfade) { + if (!crossfades_visible) { + (*i)->hide(); + } else { + (*i)->show (); + } + (*i)->set_valid (true); + return; + } + } + + /* create a new one */ + + for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i); + + if (!lview && arv && &(arv->region()) == &crossfade->out()) { + lview = arv; + } + if (!rview && arv && &(arv->region()) == &crossfade->in()) { + rview = arv; + } + } + + CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display, + _trackview, + *crossfade, + _samples_per_unit, + region_color, + *lview, *rview); + + crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade)); + crossfade_views.push_back (cv); + + if (!crossfades_visible) { + cv->hide (); + } +} + +void +AudioStreamView::remove_crossfade (Crossfade *xfade) +{ + ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade)); + + for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + if (&(*i)->crossfade == xfade) { + delete *i; + crossfade_views.erase (i); + break; + } + } +} + +void +AudioStreamView::redisplay_diskstream () +{ + list<RegionView *>::iterator i, tmp; + list<CrossfadeView*>::iterator xi, tmpx; + + + for (i = region_views.begin(); i != region_views.end(); ++i) { + (*i)->set_valid (false); + } + + for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) { + (*xi)->set_valid (false); + if ((*xi)->visible()) { + (*xi)->show (); + } + } + + if (_trackview.is_audio_track()) { + _trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view); + AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist()); + if (apl) + apl->foreach_crossfade (this, &AudioStreamView::add_crossfade); + } + + for (i = region_views.begin(); i != region_views.end(); ) { + tmp = i; + tmp++; + + if (!(*i)->is_valid()) { + delete *i; + region_views.erase (i); + } + + i = tmp; + } + + for (xi = crossfade_views.begin(); xi != crossfade_views.end();) { + tmpx = xi; + tmpx++; + + if (!(*xi)->valid()) { + delete *xi; + crossfade_views.erase (xi); + } + + xi = tmpx; + } + + /* now fix layering */ + + playlist_modified (); +} + +void +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) + arv->set_waveform_visible (yn); + } +} + +void +AudioStreamView::set_waveform_shape (WaveformShape shape) +{ + for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + arv->set_waveform_shape (shape); + } +} + +void +AudioStreamView::setup_rec_box () +{ + // cerr << _trackview.name() << " streamview SRB\n"; + + if (_trackview.session().transport_rolling()) { + + // cerr << "\trolling\n"; + + if (!rec_active && + _trackview.session().record_status() == Session::Recording && + _trackview.get_diskstream()->record_enabled()) { + + if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) { + + /* add a new region, but don't bother if they set use_rec_regions mid-record */ + + AudioRegion::SourceList sources; + + for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { + (*prc).disconnect(); + } + peak_ready_connections.clear(); + + // FIXME + AudioDiskstream* ads = dynamic_cast<AudioDiskstream*>(_trackview.get_diskstream()); + assert(ads); + + for (uint32_t n=0; n < ads->n_channels(); ++n) { + AudioSource *src = (AudioSource *) ads->write_source (n); + if (src) { + sources.push_back (src); + peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src))); + } + } + + // handle multi + + jack_nframes_t start = 0; + if (rec_regions.size() > 0) { + start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1); + } + + AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false); + region->set_position (_trackview.session().transport_frame(), this); + rec_regions.push_back (region); + /* catch it if it goes away */ + region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_rec_region)); + + /* we add the region later */ + } + + /* start a new rec box */ + + AudioTrack* at; + + at = _trackview.audio_track(); /* we know what it is already */ + AudioDiskstream& ds = at->audio_diskstream(); + jack_nframes_t frame_pos = ds.current_capture_start (); + gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); + gdouble xend; + uint32_t fill_color; + + switch (_trackview.audio_track()->mode()) { + case Normal: + xend = xstart; + fill_color = color_map[cRecordingRectFill]; + break; + + case Destructive: + xend = xstart + 2; + fill_color = color_map[cRecordingRectFill]; + /* make the recording rect translucent to allow + the user to see the peak data coming in, etc. + */ + fill_color = UINT_RGBA_CHANGE_A (fill_color, 120); + break; + } + + ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group); + rec_rect->property_x1() = xstart; + rec_rect->property_y1() = 1.0; + rec_rect->property_x2() = xend; + rec_rect->property_y2() = (double) _trackview.height - 1; + rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline]; + rec_rect->property_fill_color_rgba() = fill_color; + + RecBoxInfo recbox; + recbox.rectangle = rec_rect; + recbox.start = _trackview.session().transport_frame(); + recbox.length = 0; + + rec_rects.push_back (recbox); + + screen_update_connection.disconnect(); + screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &AudioStreamView::update_rec_box)); + rec_updating = true; + rec_active = true; + + } else if (rec_active && + (_trackview.session().record_status() != Session::Recording || + !_trackview.get_diskstream()->record_enabled())) { + + screen_update_connection.disconnect(); + rec_active = false; + rec_updating = false; + + } + + } else { + + // cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl; + + if (!rec_rects.empty() || !rec_regions.empty()) { + + /* disconnect rapid update */ + screen_update_connection.disconnect(); + + for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { + (*prc).disconnect(); + } + peak_ready_connections.clear(); + + rec_updating = false; + rec_active = false; + last_rec_peak_frame = 0; + + /* remove temp regions */ + for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); ) + { + list<Region*>::iterator tmp; + + tmp = iter; + ++tmp; + + /* this will trigger the remove_region_view */ + delete *iter; + + iter = tmp; + } + + rec_regions.clear(); + + // cerr << "\tclear " << rec_rects.size() << " rec rects\n"; + + + /* transport stopped, clear boxes */ + for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) { + RecBoxInfo &rect = (*iter); + delete rect.rectangle; + } + + rec_rects.clear(); + + } + } +} + +void +AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void)) +{ + for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + ((*i)->*pmf) (); + } +} + +void +AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src) +{ + // this is called from the peak building thread + + ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src)); + + if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) { + last_rec_peak_frame = start + cnt; + } + + rec_peak_ready_map[src] = true; + + if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) { + this->update_rec_regions (); + rec_peak_ready_map.clear(); + } +} + +void +AudioStreamView::update_rec_regions () +{ + if (use_rec_regions) { + + uint32_t n = 0; + + for (list<Region*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) { + + list<Region*>::iterator tmp; + + tmp = iter; + ++tmp; + + if (!canvas_item_visible (rec_rects[n].rectangle)) { + /* rect already hidden, this region is done */ + iter = tmp; + continue; + } + + // FIXME + AudioRegion * region = dynamic_cast<AudioRegion*>(*iter); + assert(region); + + jack_nframes_t origlen = region->length(); + + if (region == rec_regions.back() && rec_active) { + + if (last_rec_peak_frame > region->start()) { + + jack_nframes_t nlen = last_rec_peak_frame - region->start(); + + if (nlen != region->length()) { + + region->freeze (); + region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this); + region->set_length (nlen, this); + region->thaw ("updated"); + + if (origlen == 1) { + /* our special initial length */ + add_region_view_internal (region, false); + } + + /* also update rect */ + ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle; + gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length()); + rect->property_x2() = xend; + } + } + + } else { + + jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n); + + if (nlen != region->length()) { + + if (region->source(0).length() >= region->start() + nlen) { + + region->freeze (); + region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this); + region->set_length (nlen, this); + region->thaw ("updated"); + + if (origlen == 1) { + /* our special initial length */ + add_region_view_internal (region, false); + } + + /* also hide rect */ + ArdourCanvas::Item * rect = rec_rects[n].rectangle; + rect->hide(); + + } + } + } + + iter = tmp; + } + } +} + +void +AudioStreamView::show_all_xfades () +{ + foreach_crossfadeview (&CrossfadeView::show); + crossfades_visible = true; +} + +void +AudioStreamView::hide_all_xfades () +{ + foreach_crossfadeview (&CrossfadeView::hide); + crossfades_visible = false; +} + +void +AudioStreamView::hide_xfades_involving (AudioRegionView& rv) +{ + for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + if ((*i)->crossfade.involves (rv.audio_region())) { + (*i)->fake_hide (); + } + } +} + +void +AudioStreamView::reveal_xfades_involving (AudioRegionView& rv) +{ + for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) { + (*i)->show (); + } + } +} + +void +AudioStreamView::color_handler (ColorID id, uint32_t val) +{ + switch (id) { + case cAudioTrackBase: + if (_trackview.is_track()) { + canvas_rect->property_fill_color_rgba() = val; + } + break; + case cAudioBusBase: + if (!_trackview.is_track()) { + canvas_rect->property_fill_color_rgba() = val; + } + break; + case cAudioTrackOutline: + canvas_rect->property_outline_color_rgba() = val; + break; + + default: + break; + } +} + diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h new file mode 100644 index 0000000000..05ce8125f6 --- /dev/null +++ b/gtk2_ardour/audio_streamview.h @@ -0,0 +1,110 @@ +/* + Copyright (C) 2001, 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __ardour_audio_streamview_h__ +#define __ardour_audio_streamview_h__ + +#include <list> +#include <map> +#include <cmath> + +#include <ardour/location.h> +#include "enums.h" +#include "simplerect.h" +#include "color.h" +#include "streamview.h" + +namespace Gdk { + class Color; +} + +namespace ARDOUR { + class Route; + class Diskstream; + class Crossfade; + class PeakData; + class AudioRegion; + class Source; +} + +class PublicEditor; +class Selectable; +class AudioTimeAxisView; +class AudioRegionView; +class RegionSelection; +class CrossfadeView; +class Selection; + +class AudioStreamView : public StreamView +{ + public: + AudioStreamView (AudioTimeAxisView&); + ~AudioStreamView (); + + void set_waveform_shape (WaveformShape); + + int set_height (gdouble h); + int set_samples_per_unit (gdouble spp); + + int set_amplitude_above_axis (gdouble app); + gdouble get_amplitude_above_axis () { return _amplitude_above_axis; } + + void set_show_waveforms (bool yn); + void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; } + + void foreach_crossfadeview (void (CrossfadeView::*pmf)(void)); + + void show_all_xfades (); + void hide_all_xfades (); + void hide_xfades_involving (AudioRegionView&); + void reveal_xfades_involving (AudioRegionView&); + + private: + void setup_rec_box (); + void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src); + void update_rec_regions (); + + void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves); + void remove_region_view (ARDOUR::Region* ); + void remove_audio_region_view (ARDOUR::AudioRegion* ); + void remove_audio_rec_region (ARDOUR::AudioRegion*); + + void undisplay_diskstream (); + void redisplay_diskstream (); + void playlist_modified (); + void playlist_changed (ARDOUR::Diskstream *ds); + + void add_crossfade (ARDOUR::Crossfade*); + void remove_crossfade (ARDOUR::Crossfade*); + + void color_handler (ColorID id, uint32_t val); + + + double _amplitude_above_axis; + + typedef list<CrossfadeView*> CrossfadeViewList; + CrossfadeViewList crossfade_views; + bool crossfades_visible; + + list<sigc::connection> peak_ready_connections; + jack_nframes_t last_rec_peak_frame; + map<ARDOUR::Source*, bool> rec_peak_ready_map; + +}; + +#endif /* __ardour_audio_streamview_h__ */ diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc index 857adff6b9..9ae94d1fe0 100644 --- a/gtk2_ardour/audio_time_axis.cc +++ b/gtk2_ardour/audio_time_axis.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include <cstdlib> #include <cmath> +#include <cassert> #include <algorithm> #include <string> @@ -32,16 +33,15 @@ #include <pbd/whitespace.h> #include <pbd/memento_command.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/selector.h> #include <gtkmm2ext/stop_signal.h> +#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/utils.h> #include <ardour/audioplaylist.h> #include <ardour/audio_diskstream.h> #include <ardour/insert.h> -#include <ardour/ladspa_plugin.h> #include <ardour/location.h> #include <ardour/panner.h> #include <ardour/playlist.h> @@ -53,27 +53,20 @@ #include "audio_time_axis.h" #include "automation_gain_line.h" #include "automation_pan_line.h" -#include "automation_time_axis.h" #include "canvas_impl.h" #include "crossfade_view.h" #include "enums.h" #include "gain_automation_time_axis.h" -#include "gui_thread.h" #include "keyboard.h" #include "pan_automation_time_axis.h" #include "playlist_selector.h" #include "plugin_selector.h" #include "plugin_ui.h" -#include "point_selection.h" #include "prompter.h" #include "public_editor.h" -#include "redirect_automation_line.h" -#include "redirect_automation_time_axis.h" -#include "regionview.h" -#include "rgb_macros.h" -#include "selection.h" +#include "audio_region_view.h" #include "simplerect.h" -#include "streamview.h" +#include "audio_streamview.h" #include "utils.h" #include <ardour/audio_track.h> @@ -82,202 +75,76 @@ using namespace ARDOUR; using namespace PBD; -using namespace LADSPA; using namespace Gtk; using namespace Editing; -AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, Canvas& canvas) - : AxisView(sess), - RouteUI(rt, sess, _("m"), _("s"), _("r")), // mute, solo, and record - TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas), - parent_canvas (canvas), - button_table (3, 3), - edit_group_button (_("g")), // group - playlist_button (_("p")), - size_button (_("h")), // height - automation_button (_("a")), - visual_button (_("v")) - +AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas) + : AxisView(sess) + , RouteTimeAxisView(ed, sess, rt, canvas) { - _has_state = true; + // Make sure things are sane... + assert(!is_track() || is_audio_track()); + subplugin_menu.set_name ("ArdourContextMenu"); - playlist_menu = 0; - playlist_action_menu = 0; - automation_action_menu = 0; gain_track = 0; pan_track = 0; - view = 0; - timestretch_rect = 0; waveform_item = 0; pan_automation_item = 0; gain_automation_item = 0; - no_redraw = false; - view = new StreamView (*this); + _view = new AudioStreamView (*this); add_gain_automation_child (); add_pan_automation_child (); ignore_toggle = false; - rec_enable_button->set_active (false); mute_button->set_active (false); solo_button->set_active (false); - rec_enable_button->set_name ("TrackRecordEnableButton"); - mute_button->set_name ("TrackMuteButton"); - solo_button->set_name ("SoloButton"); - edit_group_button.set_name ("TrackGroupButton"); - playlist_button.set_name ("TrackPlaylistButton"); - automation_button.set_name ("TrackAutomationButton"); - size_button.set_name ("TrackSizeButton"); - visual_button.set_name ("TrackVisualButton"); - hide_button.set_name ("TrackRemoveButton"); - - hide_button.add (*(manage (new Image (get_xpm("small_x.xpm"))))); - - solo_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - mute_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - playlist_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - automation_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - size_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - visual_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - hide_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false); - - solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false); - solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); - mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); - mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false); - rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); - edit_group_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::edit_click), false); - playlist_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::playlist_click)); - automation_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::automation_click)); - size_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::size_click), false); - visual_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::visual_click)); - hide_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::hide_click)); - - if (is_audio_track()) { - controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); - } - controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); - controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0); - - controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); - - ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); - ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo")); - ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute")); - ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group")); - ARDOUR_UI::instance()->tooltips().set_tip(size_button,_("Display Height")); - ARDOUR_UI::instance()->tooltips().set_tip(playlist_button,_("Playlist")); - ARDOUR_UI::instance()->tooltips().set_tip(automation_button, _("Automation")); - ARDOUR_UI::instance()->tooltips().set_tip(visual_button, _("Visual options")); - ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("Hide this track")); - - label_view (); - - controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - - if (is_audio_track() && audio_track()->mode() == ARDOUR::Normal) { - controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } - - /* remove focus from the buttons */ - - automation_button.unset_flags (Gtk::CAN_FOCUS); - solo_button->unset_flags (Gtk::CAN_FOCUS); - mute_button->unset_flags (Gtk::CAN_FOCUS); - edit_group_button.unset_flags (Gtk::CAN_FOCUS); - size_button.unset_flags (Gtk::CAN_FOCUS); - playlist_button.unset_flags (Gtk::CAN_FOCUS); - hide_button.unset_flags (Gtk::CAN_FOCUS); - visual_button.unset_flags (Gtk::CAN_FOCUS); + if (is_audio_track()) + controls_ebox.set_name ("AudioTimeAxisViewControlsBaseUnselected"); + else // bus + controls_ebox.set_name ("AudioBusControlsBaseUnselected"); /* map current state of the route */ - update_diskstream_display (); - solo_changed(0); - mute_changed(0); redirects_changed (0); reset_redirect_automation_curves (); - y_position = -1; ensure_xml_node (); set_state (*xml_node); - _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)); - _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); - _route.redirects_changed.connect (mem_fun(*this, &AudioTimeAxisView::redirects_changed)); - _route.name_changed.connect (mem_fun(*this, &AudioTimeAxisView::route_name_changed)); - _route.solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); - _route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans)); + _route->panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans)); if (is_audio_track()) { - /* track */ - - audio_track()->FreezeChange.connect (mem_fun(*this, &AudioTimeAxisView::map_frozen)); - - audio_track()->diskstream_changed.connect (mem_fun(*this, &AudioTimeAxisView::diskstream_changed)); - get_diskstream()->speed_changed.connect (mem_fun(*this, &AudioTimeAxisView::speed_changed)); - controls_ebox.set_name ("AudioTrackControlsBaseUnselected"); controls_base_selected_name = "AudioTrackControlsBaseSelected"; controls_base_unselected_name = "AudioTrackControlsBaseUnselected"; /* ask for notifications of any new RegionViews */ + _view->RegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added)); + _view->attach (); - view->AudioRegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added)); - - view->attach (); - - /* pick up the correct freeze state */ - - map_frozen (); + } else { /* bus */ - } else { - - /* bus */ - - controls_ebox.set_name ("BusControlsBaseUnselected"); - controls_base_selected_name = "BusControlsBaseSelected"; - controls_base_unselected_name = "BusControlsBaseUnselected"; + controls_ebox.set_name ("AudioBusControlsBaseUnselected"); + controls_base_selected_name = "AudioBusControlsBaseSelected"; + controls_base_unselected_name = "AudioBusControlsBaseUnselected"; } - - editor.ZoomChanged.connect (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit)); - ColorChanged.connect (mem_fun (*this, &AudioTimeAxisView::color_handler)); } AudioTimeAxisView::~AudioTimeAxisView () { - GoingAway (); /* EMIT_SIGNAL */ - - if (playlist_menu) { - delete playlist_menu; - playlist_menu = 0; - } - - if (playlist_action_menu) { - delete playlist_action_menu; - playlist_action_menu = 0; - } - - vector_delete (&redirect_automation_curves); - - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - delete *i; - } +} - if (view) { - delete view; - view = 0; - } +AudioStreamView* +AudioTimeAxisView::audio_view() +{ + return dynamic_cast<AudioStreamView*>(_view); } guint32 @@ -299,233 +166,6 @@ AudioTimeAxisView::hide () } void -AudioTimeAxisView::set_playlist (AudioPlaylist *newplaylist) -{ - AudioPlaylist *pl; - - modified_connection.disconnect (); - state_changed_connection.disconnect (); - - if ((pl = dynamic_cast<AudioPlaylist*> (playlist())) != 0) { - state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed)); - modified_connection = pl->Modified.connect (mem_fun(*this, &AudioTimeAxisView::playlist_modified)); - } -} - -void -AudioTimeAxisView::playlist_modified () -{ -} - -gint -AudioTimeAxisView::edit_click (GdkEventButton *ev) -{ - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { - _route.set_edit_group (0, this); - return FALSE; - } - - using namespace Menu_Helpers; - - MenuList& items = edit_group_menu.items (); - RadioMenuItem::Group group; - - items.clear (); - items.push_back (RadioMenuElem (group, _("No group"), - bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0))); - - if (_route.edit_group() == 0) { - static_cast<RadioMenuItem*>(&items.back())->set_active (); - } - - _session.foreach_edit_group (bind (mem_fun (*this, &AudioTimeAxisView::add_edit_group_menu_item), &group)); - edit_group_menu.popup (ev->button, ev->time); - - return FALSE; -} - -void -AudioTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Group* group) -{ - using namespace Menu_Helpers; - - MenuList &items = edit_group_menu.items(); - - cerr << "adding edit group called " << eg->name() << endl; - - items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), eg))); - if (_route.edit_group() == eg) { - static_cast<RadioMenuItem*>(&items.back())->set_active (); - } -} - -void -AudioTimeAxisView::set_edit_group_from_menu (RouteGroup *eg) - -{ - _route.set_edit_group (eg, this); -} - -void -AudioTimeAxisView::playlist_state_changed (Change ignored) -{ - // ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed), ignored)); - // why are we here ? -} - -void -AudioTimeAxisView::playlist_changed () - -{ - label_view (); - - if (is_audio_track()) { - set_playlist (get_diskstream()->playlist()); - } -} - -void -AudioTimeAxisView::label_view () -{ - string x = _route.name(); - - if (x != name_entry.get_text()) { - name_entry.set_text (x); - } - - ARDOUR_UI::instance()->tooltips().set_tip (name_entry, x); -} - -void -AudioTimeAxisView::route_name_changed (void *src) -{ - editor.route_name_changed (this); - label_view (); -} - -void -AudioTimeAxisView::take_name_changed (void *src) - -{ - if (src != this) { - label_view (); - } -} - -void -AudioTimeAxisView::playlist_click () -{ - // always build a new action menu - - if (playlist_action_menu == 0) { - playlist_action_menu = new Menu; - playlist_action_menu->set_name ("ArdourContextMenu"); - } - - build_playlist_menu(playlist_action_menu); - - playlist_action_menu->popup (1, 0); -} - -void -AudioTimeAxisView::automation_click () -{ - if (automation_action_menu == 0) { - /* this seems odd, but the automation action - menu is built as part of the display menu. - */ - build_display_menu (); - } - automation_action_menu->popup (1, 0); -} - -void -AudioTimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end) -{ - double x1; - double x2; - double y2; - - TimeAxisView::show_timestretch (start, end); - - hide_timestretch (); - -#if 0 - if (ts.empty()) { - return; - } - - - /* check that the time selection was made in our route, or our edit group. - remember that edit_group() == 0 implies the route is *not* in a edit group. - */ - - if (!(ts.track == this || (ts.group != 0 && ts.group == _route.edit_group()))) { - /* this doesn't apply to us */ - return; - } - - /* ignore it if our edit group is not active */ - - if ((ts.track != this) && _route.edit_group() && !_route.edit_group()->is_active()) { - return; - } -#endif - - if (timestretch_rect == 0) { - timestretch_rect = new SimpleRect (*canvas_display); - timestretch_rect->property_x1() = 0.0; - timestretch_rect->property_y1() = 0.0; - timestretch_rect->property_x2() = 0.0; - timestretch_rect->property_y2() = 0.0; - timestretch_rect->property_fill_color_rgba() = color_map[cTimeStretchFill]; - timestretch_rect->property_outline_color_rgba() = color_map[cTimeStretchOutline]; - } - - timestretch_rect->show (); - timestretch_rect->raise_to_top (); - - x1 = start / editor.get_current_zoom(); - x2 = (end - 1) / editor.get_current_zoom(); - y2 = height - 2; - - timestretch_rect->property_x1() = x1; - timestretch_rect->property_y1() = 1.0; - timestretch_rect->property_x2() = x2; - timestretch_rect->property_y2() = y2; -} - -void -AudioTimeAxisView::hide_timestretch () -{ - TimeAxisView::hide_timestretch (); - - if (timestretch_rect) { - timestretch_rect->hide (); - } -} - -void -AudioTimeAxisView::show_selection (TimeSelection& ts) -{ - -#if 0 - /* ignore it if our edit group is not active or if the selection was started - in some other track or edit group (remember that edit_group() == 0 means - that the track is not in an edit group). - */ - - if (((ts.track != this && !is_child (ts.track)) && _route.edit_group() && !_route.edit_group()->is_active()) || - (!(ts.track == this || is_child (ts.track) || (ts.group != 0 && ts.group == _route.edit_group())))) { - hide_selection (); - return; - } -#endif - - TimeAxisView::show_selection (ts); -} - -void AudioTimeAxisView::set_state (const XMLNode& node) { const XMLProperty *prop; @@ -578,153 +218,14 @@ AudioTimeAxisView::set_state (const XMLNode& node) } void -AudioTimeAxisView::set_height (TrackHeight h) -{ - bool height_changed = (height == 0) || (h != height_style); - - TimeAxisView::set_height (h); - - ensure_xml_node (); - - view->set_height ((double) height); - - switch (height_style) { - case Largest: - xml_node->add_property ("track_height", "largest"); - show_name_entry (); - hide_name_label (); - controls_table.show_all(); - break; - case Large: - xml_node->add_property ("track_height", "large"); - show_name_entry (); - hide_name_label (); - controls_table.show_all(); - break; - case Larger: - xml_node->add_property ("track_height", "larger"); - show_name_entry (); - hide_name_label (); - controls_table.show_all(); - break; - case Normal: - xml_node->add_property ("track_height", "normal"); - show_name_entry (); - hide_name_label (); - controls_table.show_all(); - break; - case Smaller: - xml_node->add_property ("track_height", "smaller"); - controls_table.show_all (); - show_name_entry (); - hide_name_label (); - edit_group_button.hide (); - hide_button.hide (); - visual_button.hide (); - size_button.hide (); - automation_button.hide (); - playlist_button.hide (); - break; - case Small: - xml_node->add_property ("track_height", "small"); - controls_table.hide_all (); - controls_table.show (); - hide_name_entry (); - show_name_label (); - name_label.set_text (_route.name()); - break; - } - - if (height_changed) { - /* only emit the signal if the height really changed */ - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ - } -} - -void -AudioTimeAxisView::select_track_color () -{ - if (RouteUI::choose_color ()) { - - if (view) { - view->apply_color (_color, StreamView::RegionColor); - } - } -} - -void -AudioTimeAxisView::reset_redirect_automation_curves () -{ - for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) { - (*i)->reset(); - } -} - -void -AudioTimeAxisView::reset_samples_per_unit () -{ - set_samples_per_unit (editor.get_current_zoom()); -} - -void -AudioTimeAxisView::set_samples_per_unit (double spu) -{ - double speed = 1.0; - - if (get_diskstream() != 0) { - speed = get_diskstream()->speed(); - } - - if (view) { - view->set_samples_per_unit (spu * speed); - } - - TimeAxisView::set_samples_per_unit (spu * speed); -} - -void -AudioTimeAxisView::build_display_menu () +AudioTimeAxisView::build_automation_action_menu () { using namespace Menu_Helpers; - /* get the size menu ready */ - - build_size_menu (); - - /* prepare it */ - - TimeAxisView::build_display_menu (); - - /* now fill it with our stuff */ - - MenuList& items = display_menu->items(); - display_menu->set_name ("ArdourContextMenu"); - - items.push_back (MenuElem (_("Height"), *size_menu)); - items.push_back (MenuElem (_("Color"), mem_fun(*this, &AudioTimeAxisView::select_track_color))); - - - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades))); - items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades))); - items.push_back (SeparatorElem()); - - build_remote_control_menu (); - items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + RouteTimeAxisView::build_automation_action_menu (); - automation_action_menu = manage (new Menu); MenuList& automation_items = automation_action_menu->items(); - automation_action_menu->set_name ("ArdourContextMenu"); - automation_items.push_back (MenuElem (_("Show all automation"), - mem_fun(*this, &AudioTimeAxisView::show_all_automation))); - - automation_items.push_back (MenuElem (_("Show existing automation"), - mem_fun(*this, &AudioTimeAxisView::show_existing_automation))); - - automation_items.push_back (MenuElem (_("Hide all automation"), - mem_fun(*this, &AudioTimeAxisView::hide_all_automation))); - automation_items.push_back (SeparatorElem()); automation_items.push_back (CheckMenuElem (_("Fader"), @@ -736,11 +237,21 @@ AudioTimeAxisView::build_display_menu () mem_fun(*this, &AudioTimeAxisView::toggle_pan_track))); pan_automation_item = static_cast<CheckMenuItem*> (&automation_items.back()); pan_automation_item->set_active(show_pan_automation); + +} + +void +AudioTimeAxisView::append_extra_display_menu_items () +{ + using namespace Menu_Helpers; - automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu)); + MenuList& items = display_menu->items(); - items.push_back (MenuElem (_("Automation"), *automation_action_menu)); + // crossfade stuff + items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades))); + items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades))); + // waveform menu Menu *waveform_menu = manage(new Menu); MenuList& waveform_items = waveform_menu->items(); waveform_menu->set_name ("ArdourContextMenu"); @@ -760,401 +271,55 @@ AudioTimeAxisView::build_display_menu () rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back()); items.push_back (MenuElem (_("Waveform"), *waveform_menu)); - - if (is_audio_track()) { - - Menu* alignment_menu = manage (new Menu); - MenuList& alignment_items = alignment_menu->items(); - alignment_menu->set_name ("ArdourContextMenu"); - - RadioMenuItem::Group align_group; - - alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), ExistingMaterial))); - align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); - if (get_diskstream()->alignment_style() == ExistingMaterial) { - align_existing_item->set_active(); - } - alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), CaptureTime))); - align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); - if (get_diskstream()->alignment_style() == CaptureTime) { - align_capture_item->set_active(); - } - - items.push_back (MenuElem (_("Alignment"), *alignment_menu)); - - get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &AudioTimeAxisView::align_style_changed)); - } - - items.push_back (SeparatorElem()); - items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active))); - route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); - route_active_menu_item->set_active (_route.active()); - - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route))); - -} - -void -AudioTimeAxisView::align_style_changed () -{ - switch (get_diskstream()->alignment_style()) { - case ExistingMaterial: - if (!align_existing_item->get_active()) { - align_existing_item->set_active(); - } - break; - case CaptureTime: - if (!align_capture_item->get_active()) { - align_capture_item->set_active(); - } - break; - } -} - -void -AudioTimeAxisView::set_align_style (AlignStyle style) -{ - get_diskstream()->set_align_style (style); -} - -void -AudioTimeAxisView::rename_current_playlist () -{ - ArdourPrompter prompter (true); - string name; - - AudioPlaylist *pl; - AudioDiskstream *ds; - - if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { - return; - } - - prompter.set_prompt (_("Name for playlist")); - prompter.set_initial_text (pl->name()); - prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT); - prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); - - switch (prompter.run ()) { - case Gtk::RESPONSE_ACCEPT: - prompter.get_result (name); - if (name.length()) { - pl->set_name (name); - } - break; - - default: - break; - } -} - -void -AudioTimeAxisView::use_copy_playlist (bool prompt) -{ - AudioPlaylist *pl; - AudioDiskstream *ds; - string name; - - if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { - return; - } - - name = Playlist::bump_name (pl->name(), _session); - - if (prompt) { - - ArdourPrompter prompter (true); - - prompter.set_prompt (_("Name for Playlist")); - prompter.set_initial_text (name); - prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT); - prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); - prompter.show_all (); - - switch (prompter.run ()) { - case Gtk::RESPONSE_ACCEPT: - prompter.get_result (name); - break; - - default: - return; - } - } - - if (name.length()) { - ds->use_copy_playlist (); - pl = ds->playlist(); - pl->set_name (name); - } -} - -void -AudioTimeAxisView::use_new_playlist (bool prompt) -{ - AudioPlaylist *pl; - AudioDiskstream *ds; - string name; - - if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) { - return; - } - - name = Playlist::bump_name (pl->name(), _session); - - if (prompt) { - - ArdourPrompter prompter (true); - - prompter.set_prompt (_("Name for Playlist")); - prompter.set_initial_text (name); - prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT); - prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); - - switch (prompter.run ()) { - case Gtk::RESPONSE_ACCEPT: - prompter.get_result (name); - break; - - default: - return; - } - } - - if (name.length()) { - ds->use_new_playlist (); - pl = ds->playlist(); - pl->set_name (name); - } -} - -void -AudioTimeAxisView::clear_playlist () -{ - AudioPlaylist *pl; - AudioDiskstream *ds; - - if ((ds = get_diskstream()) != 0) { - if ((pl = ds->playlist()) != 0) { - editor.clear_playlist (*pl); - } - } } void AudioTimeAxisView::toggle_waveforms () { - if (view && waveform_item && !ignore_toggle) { - view->set_show_waveforms (waveform_item->get_active()); + AudioStreamView* asv = audio_view(); + assert(asv); + + if (asv && waveform_item && !ignore_toggle) { + asv->set_show_waveforms (waveform_item->get_active()); } } void AudioTimeAxisView::set_show_waveforms (bool yn) { + AudioStreamView* asv = audio_view(); + assert(asv); + if (waveform_item) { waveform_item->set_active (yn); } else { - view->set_show_waveforms (yn); + asv->set_show_waveforms (yn); } } void AudioTimeAxisView::set_show_waveforms_recording (bool yn) { - if (view) { - view->set_show_waveforms_recording (yn); - } -} + AudioStreamView* asv = audio_view(); -void -AudioTimeAxisView::set_waveform_shape (WaveformShape shape) -{ - if (view) { - view->set_waveform_shape (shape); + if (asv) { + asv->set_show_waveforms_recording (yn); } } void -AudioTimeAxisView::speed_changed () -{ - Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit)); -} - -void -AudioTimeAxisView::diskstream_changed (void *src) -{ - Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::update_diskstream_display)); -} - -void -AudioTimeAxisView::update_diskstream_display () +AudioTimeAxisView::set_waveform_shape (WaveformShape shape) { - AudioDiskstream *ds; + AudioStreamView* asv = audio_view(); - if ((ds = get_diskstream()) != 0) { - set_playlist (ds->playlist ()); + if (asv) { + asv->set_waveform_shape (shape); } map_frozen (); } void -AudioTimeAxisView::selection_click (GdkEventButton* ev) -{ - PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route.edit_group()); - - switch (Keyboard::selection_type (ev->state)) { - case Selection::Toggle: - /* XXX this is not right */ - editor.get_selection().add (*tracks); - break; - - case Selection::Set: - editor.get_selection().set (*tracks); - break; - - case Selection::Extend: - /* not defined yet */ - break; - } - - delete tracks; -} - -void -AudioTimeAxisView::set_selected_regionviews (AudioRegionSelection& regions) -{ - if (view) { - view->set_selected_regionviews (regions); - } -} - -void -AudioTimeAxisView::set_selected_points (PointSelection& points) -{ - for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - (*i)->set_selected_points (points); - } -} - -void -AudioTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results) -{ - double speed = 1.0; - - if (get_diskstream() != 0) { - speed = get_diskstream()->speed(); - } - - jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed); - jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed); - - if (view && ((top < 0.0 && bot < 0.0)) || touched (top, bot)) { - view->get_selectables (start_adjusted, end_adjusted, results); - } - - /* pick up visible automation tracks */ - - for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - if (!(*i)->hidden()) { - (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results); - } - } -} - -void -AudioTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results) -{ - if (view) { - view->get_inverted_selectables (sel, results); - } - - for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - if (!(*i)->hidden()) { - (*i)->get_inverted_selectables (sel, results); - } - } - - return; -} - -RouteGroup* -AudioTimeAxisView::edit_group() const -{ - return _route.edit_group(); -} - -string -AudioTimeAxisView::name() const -{ - return _route.name(); -} - -Playlist * -AudioTimeAxisView::playlist () const -{ - AudioDiskstream *ds; - - if ((ds = get_diskstream()) != 0) { - return ds->playlist(); - } else { - return 0; - } -} - -void -AudioTimeAxisView::name_entry_changed () -{ - string x; - - x = name_entry.get_text (); - - if (x == _route.name()) { - return; - } - - if (x.length() == 0) { - name_entry.set_text (_route.name()); - return; - } - - strip_whitespace_edges(x); - - if (_session.route_name_unique (x)) { - _route.set_name (x, this); - } else { - ARDOUR_UI::instance()->popup_error (_("a track already exists with that name")); - name_entry.set_text (_route.name()); - } -} - -void -AudioTimeAxisView::visual_click () -{ - popup_display_menu (0); -} - -void -AudioTimeAxisView::hide_click () -{ - editor.hide_track_in_display (*this); -} - -Region* -AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir) -{ - AudioDiskstream *stream; - AudioPlaylist *playlist; - - if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) { - return playlist->find_next_region (pos, point, dir); - } - - return 0; -} - -void AudioTimeAxisView::add_gain_automation_child () { XMLProperty* prop; @@ -1166,13 +331,13 @@ AudioTimeAxisView::add_gain_automation_child () *this, parent_canvas, _("gain"), - _route.gain_automation_curve()); + _route->gain_automation_curve()); line = new AutomationGainLine ("automation gain", _session, *gain_track, *gain_track->canvas_display, - _route.gain_automation_curve()); + _route->gain_automation_curve()); line->set_line_color (color_map[cAutomationLine]); @@ -1241,11 +406,11 @@ AudioTimeAxisView::update_pans () /* we don't draw lines for "greater than stereo" panning. */ - if (_route.n_outputs() > 2) { + if (_route->n_outputs() > 2) { return; } - for (p = _route.panner().begin(); p != _route.panner().end(); ++p) { + for (p = _route->panner().begin(); p != _route->panner().end(); ++p) { AutomationLine* line; @@ -1253,7 +418,7 @@ AudioTimeAxisView::update_pans () *pan_track->canvas_display, (*p)->automation()); - if (p == _route.panner().begin()) { + if (p == _route->panner().begin()) { /* first line is a nice orange */ line->set_line_color (color_map[cLeftPanAutomationLine]); } else { @@ -1285,7 +450,7 @@ AudioTimeAxisView::toggle_gain_track () /* now trigger a redisplay */ if (!no_redraw) { - _route.gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */ } } } @@ -1299,7 +464,7 @@ AudioTimeAxisView::gain_hidden () gain_automation_item->set_active (false); } - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } void @@ -1321,7 +486,7 @@ AudioTimeAxisView::toggle_pan_track () /* now trigger a redisplay */ if (!no_redraw) { - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } } } @@ -1335,322 +500,7 @@ AudioTimeAxisView::pan_hidden () pan_automation_item->set_active (false); } - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ -} - -AudioTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo () -{ - for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) { - delete *i; - } -} - - -AudioTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode () -{ - parent.remove_ran (this); - - if (view) { - delete view; - } -} - -void -AudioTimeAxisView::remove_ran (RedirectAutomationNode* ran) -{ - if (ran->view) { - remove_child (ran->view); - } -} - -AudioTimeAxisView::RedirectAutomationNode* -AudioTimeAxisView::find_redirect_automation_node (Redirect *redirect, uint32_t what) -{ - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - - if ((*i)->redirect == redirect) { - - for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { - if ((*ii)->what == what) { - return *ii; - } - } - } - } - - return 0; -} - -static string -legalize_for_xml_node (string str) -{ - string::size_type pos; - string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:"; - string legal; - - legal = str; - pos = 0; - - while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { - legal.replace (pos, 1, "_"); - pos += 1; - } - - return legal; -} - - -void -AudioTimeAxisView::add_redirect_automation_curve (Redirect *redirect, uint32_t what) -{ - RedirectAutomationLine* ral; - string name; - RedirectAutomationNode* ran; - - if ((ran = find_redirect_automation_node (redirect, what)) == 0) { - fatal << _("programming error: ") - << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"), - redirect->name(), what) - << endmsg; - /*NOTREACHED*/ - return; - } - - if (ran->view) { - return; - } - - name = redirect->describe_parameter (what); - - /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */ - - char state_name[256]; - snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what); - - ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name); - - ral = new RedirectAutomationLine (name, - *redirect, what, _session, *ran->view, - *ran->view->canvas_display, redirect->automation_list (what)); - - ral->set_line_color (color_map[cRedirectAutomationLine]); - ral->queue_reset (); - - ran->view->add_line (*ral); - - ran->view->Hiding.connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_automation_track_hidden), ran, redirect)); - - if (!ran->view->marked_for_display()) { - ran->view->hide (); - } else { - ran->menu_item->set_active (true); - } - - add_child (ran->view); - - view->foreach_regionview (bind (mem_fun(*this, &AudioTimeAxisView::add_ghost_to_redirect), ran->view)); - - redirect->mark_automation_visible (what, true); -} - -void -AudioTimeAxisView::redirect_automation_track_hidden (AudioTimeAxisView::RedirectAutomationNode* ran, Redirect* r) -{ - if (!_hidden) { - ran->menu_item->set_active (false); - } - - r->mark_automation_visible (ran->what, false); - - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ -} - -void -AudioTimeAxisView::add_existing_redirect_automation_curves (Redirect *redirect) -{ - set<uint32_t> s; - RedirectAutomationLine *ral; - - redirect->what_has_visible_automation (s); - - for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) { - - if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) { - ral->queue_reset (); - } else { - add_redirect_automation_curve (redirect, (*i)); - } - } -} - -void -AudioTimeAxisView::add_redirect_to_subplugin_menu (Redirect* r) -{ - using namespace Menu_Helpers; - RedirectAutomationInfo *rai; - list<RedirectAutomationInfo*>::iterator x; - - const std::set<uint32_t>& automatable = r->what_can_be_automated (); - std::set<uint32_t> has_visible_automation; - - r->what_has_visible_automation(has_visible_automation); - - if (automatable.empty()) { - return; - } - - for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) { - if ((*x)->redirect == r) { - break; - } - } - - if (x == redirect_automation.end()) { - - rai = new RedirectAutomationInfo (r); - redirect_automation.push_back (rai); - - } else { - - rai = *x; - - } - - /* any older menu was deleted at the top of redirects_changed() - when we cleared the subplugin menu. - */ - - rai->menu = manage (new Menu); - MenuList& items = rai->menu->items(); - rai->menu->set_name ("ArdourContextMenu"); - - items.clear (); - - for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) { - - RedirectAutomationNode* ran; - CheckMenuItem* mitem; - - string name = r->describe_parameter (*i); - - items.push_back (CheckMenuElem (name)); - mitem = dynamic_cast<CheckMenuItem*> (&items.back()); - - if (has_visible_automation.find((*i)) != has_visible_automation.end()) { - mitem->set_active(true); - } - - if ((ran = find_redirect_automation_node (r, *i)) == 0) { - - /* new item */ - - ran = new RedirectAutomationNode (*i, mitem, *this); - - rai->lines.push_back (ran); - - } else { - - ran->menu_item = mitem; - - } - - mitem->signal_toggled().connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_menu_item_toggled), rai, ran)); - } - - /* add the menu for this redirect, because the subplugin - menu is always cleared at the top of redirects_changed(). - this is the result of some poor design in gtkmm and/or - GTK+. - */ - - subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu)); - rai->valid = true; -} - -void -AudioTimeAxisView::redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo* rai, - AudioTimeAxisView::RedirectAutomationNode* ran) -{ - bool showit = ran->menu_item->get_active(); - bool redraw = false; - - if (ran->view == 0 && showit) { - add_redirect_automation_curve (rai->redirect, ran->what); - redraw = true; - } - - if (showit != ran->view->marked_for_display()) { - - if (showit) { - ran->view->set_marked_for_display (true); - ran->view->canvas_display->show(); - } else { - rai->redirect->mark_automation_visible (ran->what, true); - ran->view->set_marked_for_display (false); - ran->view->hide (); - } - - redraw = true; - - } - - if (redraw && !no_redraw) { - - /* now trigger a redisplay */ - - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ - - } -} - -void -AudioTimeAxisView::redirects_changed (void *src) -{ - using namespace Menu_Helpers; - - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - (*i)->valid = false; - } - - subplugin_menu.items().clear (); - - _route.foreach_redirect (this, &AudioTimeAxisView::add_redirect_to_subplugin_menu); - _route.foreach_redirect (this, &AudioTimeAxisView::add_existing_redirect_automation_curves); - - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) { - - list<RedirectAutomationInfo*>::iterator tmp; - - tmp = i; - ++tmp; - - if (!(*i)->valid) { - - delete *i; - redirect_automation.erase (i); - - } - - i = tmp; - } - - /* change in visibility was possible */ - - _route.gui_changed ("track_height", this); -} - -RedirectAutomationLine * -AudioTimeAxisView::find_redirect_automation_curve (Redirect *redirect, uint32_t what) -{ - RedirectAutomationNode* ran; - - if ((ran = find_redirect_automation_node (redirect, what)) != 0) { - if (ran->view) { - return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front()); - } - } - - return 0; + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } void @@ -1661,19 +511,11 @@ AudioTimeAxisView::show_all_automation () pan_automation_item->set_active (true); gain_automation_item->set_active (true); - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { - if ((*ii)->view == 0) { - add_redirect_automation_curve ((*i)->redirect, (*ii)->what); - } - - (*ii)->menu_item->set_active (true); - } - } + RouteTimeAxisView::show_all_automation (); no_redraw = false; - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } void @@ -1684,17 +526,11 @@ AudioTimeAxisView::show_existing_automation () pan_automation_item->set_active (true); gain_automation_item->set_active (true); - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { - if ((*ii)->view != 0) { - (*ii)->menu_item->set_active (true); - } - } - } + RouteTimeAxisView::show_existing_automation (); no_redraw = false; - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } void @@ -1705,236 +541,61 @@ AudioTimeAxisView::hide_all_automation () pan_automation_item->set_active (false); gain_automation_item->set_active (false); - for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { - for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { - (*ii)->menu_item->set_active (false); - } - } + RouteTimeAxisView::hide_all_automation(); no_redraw = false; - _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ -} - -bool -AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) -{ - Playlist* what_we_got; - AudioDiskstream* ds = get_diskstream(); - Playlist* playlist; - bool ret = false; - - if (ds == 0) { - /* route is a bus, not a track */ - return false; - } - - playlist = ds->playlist(); - - - TimeSelection time (selection.time); - float speed = ds->speed(); - if (speed != 1.0f) { - for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) { - (*i).start = session_frame_to_track_frame((*i).start, speed); - (*i).end = session_frame_to_track_frame((*i).end, speed); - } - } - - XMLNode &before = playlist->get_state(); - switch (op) { - case Cut: - if ((what_we_got = playlist->cut (time)) != 0) { - editor.get_cut_buffer().add (what_we_got); - XMLNode &after = playlist->get_state(); - _session.add_command (new MementoCommand<Playlist>(*playlist, before, after)); - ret = true; - } - break; - case Copy: - if ((what_we_got = playlist->copy (time)) != 0) { - editor.get_cut_buffer().add (what_we_got); - } - break; - - case Clear: - if ((what_we_got = playlist->cut (time)) != 0) { - XMLNode &after = playlist->get_state(); - _session.add_command(new MementoCommand<Playlist>(*playlist, before, after)); - what_we_got->unref (); - ret = true; - } - break; - } - - return ret; -} - -bool -AudioTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth) -{ - if (!is_audio_track()) { - return false; - } - - Playlist* playlist = get_diskstream()->playlist(); - PlaylistSelection::iterator p; - - for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth); - - if (p == selection.playlists.end()) { - return false; - } - - if (get_diskstream()->speed() != 1.0f) - pos = session_frame_to_track_frame(pos, get_diskstream()->speed() ); - - XMLNode &before = playlist->get_state(); - playlist->paste (**p, pos, times); - _session.add_command(new MementoCommand<Playlist>(*playlist, before, - playlist->get_state())); - - return true; -} - -void -AudioTimeAxisView::region_view_added (AudioRegionView* arv) -{ - for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - AutomationTimeAxisView* atv; - - if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) { - arv->add_ghost (*atv); - } - } -} - -void -AudioTimeAxisView::add_ghost_to_redirect (AudioRegionView* arv, AutomationTimeAxisView* atv) -{ - arv->add_ghost (*atv); -} - -list<TimeAxisView*> -AudioTimeAxisView::get_child_list() -{ - - list<TimeAxisView*>redirect_children; - - for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - if (!(*i)->hidden()) { - redirect_children.push_back(*i); - } - } - return redirect_children; -} - - -void -AudioTimeAxisView::build_playlist_menu (Gtk::Menu * menu) -{ - using namespace Menu_Helpers; - - if (!menu || !is_audio_track()) { - return; - } - - MenuList& playlist_items = menu->items(); - menu->set_name ("ArdourContextMenu"); - playlist_items.clear(); - - if (playlist_menu) { - delete playlist_menu; - } - playlist_menu = new Menu; - playlist_menu->set_name ("ArdourContextMenu"); - - playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name()))); - playlist_items.push_back (SeparatorElem()); - - playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &AudioTimeAxisView::rename_current_playlist))); - playlist_items.push_back (SeparatorElem()); - - playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists))); - playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists))); - playlist_items.push_back (SeparatorElem()); - playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists))); - playlist_items.push_back (SeparatorElem()); - playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &AudioTimeAxisView::show_playlist_selector))); - -} - -void -AudioTimeAxisView::show_playlist_selector () -{ - editor.playlist_selector().show_for (this); -} - - -void -AudioTimeAxisView::map_frozen () -{ - if (!is_audio_track()) { - return; - } - - ENSURE_GUI_THREAD (mem_fun(*this, &AudioTimeAxisView::map_frozen)); - - - switch (audio_track()->freeze_state()) { - case AudioTrack::Frozen: - playlist_button.set_sensitive (false); - rec_enable_button->set_sensitive (false); - break; - default: - playlist_button.set_sensitive (true); - rec_enable_button->set_sensitive (true); - break; - } + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } void AudioTimeAxisView::show_all_xfades () { - if (view) { - view->show_all_xfades (); + AudioStreamView* asv = audio_view(); + + if (asv) { + asv->show_all_xfades (); } } void AudioTimeAxisView::hide_all_xfades () { - if (view) { - view->hide_all_xfades (); + AudioStreamView* asv = audio_view(); + + if (asv) { + asv->hide_all_xfades (); } } void AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi) { + AudioStreamView* asv = audio_view(); AudioRegionView* rv; - if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) { - view->hide_xfades_involving (*rv); + if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) { + asv->hide_xfades_involving (*rv); } } void AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi) { + AudioStreamView* asv = audio_view(); AudioRegionView* rv; - if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) { - view->reveal_xfades_involving (*rv); + if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) { + asv->reveal_xfades_involving (*rv); } } void AudioTimeAxisView::route_active_changed () { - RouteUI::route_active_changed (); + RouteTimeAxisView::route_active_changed (); if (is_audio_track()) { - if (_route.active()) { + if (_route->active()) { controls_ebox.set_name ("AudioTrackControlsBaseUnselected"); controls_base_selected_name = "AudioTrackControlsBaseSelected"; controls_base_unselected_name = "AudioTrackControlsBaseUnselected"; @@ -1944,7 +605,7 @@ AudioTimeAxisView::route_active_changed () controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected"; } } else { - if (_route.active()) { + if (_route->active()) { controls_ebox.set_name ("BusControlsBaseUnselected"); controls_base_selected_name = "BusControlsBaseSelected"; controls_base_unselected_name = "BusControlsBaseUnselected"; @@ -1962,24 +623,3 @@ AudioTimeAxisView::get_child_xml_node (const string & childname) return RouteUI::get_child_xml_node (childname); } -void -AudioTimeAxisView::color_handler (ColorID id, uint32_t val) -{ - switch (id) { - case cTimeStretchOutline: - timestretch_rect->property_outline_color_rgba() = val; - break; - case cTimeStretchFill: - timestretch_rect->property_fill_color_rgba() = val; - break; - default: - break; - } -} - -bool -AudioTimeAxisView::select_me (GdkEventButton* ev) -{ - editor.get_selection().add (this); - return false; -} diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h index b319d0ea99..2162771285 100644 --- a/gtk2_ardour/audio_time_axis.h +++ b/gtk2_ardour/audio_time_axis.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,8 +18,8 @@ $Id$ */ -#ifndef __ardour_trackview_h__ -#define __ardour_trackview_h__ +#ifndef __ardour_audio_time_axis_h__ +#define __ardour_audio_time_axis_h__ #include <gtkmm/table.h> #include <gtkmm/button.h> @@ -33,19 +33,14 @@ #include <list> #include <ardour/types.h> -#include <ardour/region.h> #include "ardour_dialog.h" #include "route_ui.h" #include "enums.h" -#include "time_axis_view.h" +#include "route_time_axis.h" #include "canvas.h" #include "color.h" -namespace ALSA { - class MultiChannelDevice; -} - namespace ARDOUR { class Session; class AudioDiskstream; @@ -56,247 +51,58 @@ namespace ARDOUR { class AudioPlaylist; } -namespace LADSPA { - class Manager; - class Plugin; -} - class PublicEditor; class AudioThing; -class StreamView; +class AudioStreamView; class Selection; class Selectable; +class RegionView; class AudioRegionView; class AutomationLine; class AutomationGainLine; class AutomationPanLine; -class RedirectAutomationLine; class TimeSelection; class AutomationTimeAxisView; -class AudioTimeAxisView : public RouteUI, public TimeAxisView +class AudioTimeAxisView : public RouteTimeAxisView { public: - AudioTimeAxisView (PublicEditor&, ARDOUR::Session&, ARDOUR::Route&, ArdourCanvas::Canvas& canvas); + AudioTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas); virtual ~AudioTimeAxisView (); + + AudioStreamView* audio_view(); - void show_selection (TimeSelection&); - void automation_control_point_changed (ARDOUR::AutomationType); - - void set_samples_per_unit (double); - void set_height (TimeAxisView::TrackHeight); void set_show_waveforms (bool yn); void set_show_waveforms_recording (bool yn); - void show_timestretch (jack_nframes_t start, jack_nframes_t end); - void hide_timestretch (); - void selection_click (GdkEventButton*); - void set_selected_regionviews (AudioRegionSelection&); - void set_selected_points (PointSelection&); - void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&); - void get_inverted_selectables (Selection&, list<Selectable*>&); void show_all_xfades (); void hide_all_xfades (); void hide_dependent_views (TimeAxisViewItem&); void reveal_dependent_views (TimeAxisViewItem&); - ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir); - - string name() const; - - ARDOUR::RouteGroup* edit_group() const; - - void build_playlist_menu (Gtk::Menu *); - ARDOUR::Playlist* playlist() const; - - /* overridden from parent to store display state */ + /* Overridden from parent to store display state */ guint32 show_at (double y, int& nth, Gtk::VBox *parent); void hide (); - /* need accessors/mutators */ - - StreamView *view; - - /* editing operations */ - - bool cut_copy_clear (Selection&, Editing::CutCopyOp); - bool paste (jack_nframes_t, float times, Selection&, size_t nth); - - list<TimeAxisView*>get_child_list(); - void set_state (const XMLNode&); XMLNode* get_child_xml_node (const string & childname); - /* the editor calls these when mapping an operation across multiple tracks */ - - void use_new_playlist (bool prompt); - void use_copy_playlist (bool prompt); - void clear_playlist (); - private: - friend class StreamView; + friend class AudioStreamView; friend class AudioRegionView; - - ArdourCanvas::Canvas& parent_canvas; - - bool no_redraw; - - AutomationTimeAxisView *gain_track; - AutomationTimeAxisView *pan_track; - - void update_automation_view (ARDOUR::AutomationType); - void reset_redirect_automation_curves (); - - Gtk::HBox other_button_hbox; - - Gtk::Table button_table; - - Gtk::Button redirect_button; - Gtk::Button edit_group_button; - Gtk::Button playlist_button; - Gtk::Button size_button; - Gtk::Button automation_button; - Gtk::Button hide_button; - Gtk::Button visual_button; - - void route_active_changed (); - - void diskstream_changed (void *src); - void update_diskstream_display (); - gint edit_click (GdkEventButton *); - - // variables to get the context menu - // automation buttons correctly initialized - bool show_gain_automation; - bool show_pan_automation; - - void build_redirect_window (); - void redirect_click (); - void redirect_add (); - void redirect_remove (); - void redirect_edit (); - void redirect_relist (); - void redirect_row_selected (gint row, gint col, GdkEvent *ev); - void add_to_redirect_display (ARDOUR::Redirect *); - void redirects_changed (void *); - - sigc::connection modified_connection; - sigc::connection state_changed_connection; - - void take_name_changed (void *); - void route_name_changed (void *); - void name_entry_changed (); - - void on_area_realize (); - - virtual void label_view (); - - Gtk::Menu edit_group_menu; - - void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*); - void set_edit_group_from_menu (ARDOUR::RouteGroup *); - - void reset_samples_per_unit (); + void route_active_changed (); - void select_track_color(); + void build_automation_action_menu (); + void append_extra_display_menu_items (); - virtual void build_display_menu (); - - Gtk::CheckMenuItem* waveform_item; - Gtk::RadioMenuItem* traditional_item; - Gtk::RadioMenuItem* rectified_item; - - Gtk::RadioMenuItem* align_existing_item; - Gtk::RadioMenuItem* align_capture_item; - - void align_style_changed (); - void set_align_style (ARDOUR::AlignStyle); - void toggle_show_waveforms (); - void set_waveform_shape (WaveformShape); void toggle_waveforms (); - Gtk::Menu *playlist_menu; - Gtk::Menu *playlist_action_menu; - Gtk::MenuItem *playlist_item; - - /* playlist */ - - void set_playlist (ARDOUR::AudioPlaylist *); - void playlist_click (); - void show_playlist_selector (); - - void playlist_changed (); - void playlist_state_changed (ARDOUR::Change); - void playlist_modified (); - - void add_playlist_to_playlist_menu (ARDOUR::Playlist*); - void rename_current_playlist (); - - /* automation stuff */ - - Gtk::Menu* automation_action_menu; - Gtk::CheckMenuItem* gain_automation_item; - Gtk::CheckMenuItem* pan_automation_item; - - void automation_click (); - void clear_automation (); - void hide_all_automation (); void show_all_automation (); void show_existing_automation (); + void hide_all_automation (); - struct RedirectAutomationNode { - uint32_t what; - Gtk::CheckMenuItem* menu_item; - AutomationTimeAxisView* view; - AudioTimeAxisView& parent; - - RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, AudioTimeAxisView& p) - : what (w), menu_item (mitem), view (0), parent (p) {} - - ~RedirectAutomationNode (); - }; - - struct RedirectAutomationInfo { - ARDOUR::Redirect* redirect; - bool valid; - Gtk::Menu* menu; - vector<RedirectAutomationNode*> lines; - - RedirectAutomationInfo (ARDOUR::Redirect* r) - : redirect (r), valid (true) {} - - ~RedirectAutomationInfo (); - }; - - list<RedirectAutomationInfo*> redirect_automation; - RedirectAutomationNode* find_redirect_automation_node (ARDOUR::Redirect *redirect, uint32_t what); - - Gtk::Menu subplugin_menu; - void add_redirect_to_subplugin_menu (ARDOUR::Redirect *); - - void remove_ran (RedirectAutomationNode* ran); - - void redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo*, - AudioTimeAxisView::RedirectAutomationNode*); - void redirect_automation_track_hidden (RedirectAutomationNode*, ARDOUR::Redirect*); - - vector<RedirectAutomationLine*> redirect_automation_curves; - RedirectAutomationLine *find_redirect_automation_curve (ARDOUR::Redirect*,uint32_t); - void add_redirect_automation_curve (ARDOUR::Redirect*, uint32_t); - void add_existing_redirect_automation_curves (ARDOUR::Redirect*); - - ArdourCanvas::SimpleRect *timestretch_rect; - - void timestretch (jack_nframes_t start, jack_nframes_t end); - - void visual_click (); - void hide_click (); - gint when_displayed (GdkEventAny*); - - void speed_changed (); - void add_gain_automation_child (); void add_pan_automation_child (); void add_parameter_automation_child (); @@ -309,14 +115,19 @@ class AudioTimeAxisView : public RouteUI, public TimeAxisView void update_pans (); - void region_view_added (AudioRegionView*); - void add_ghost_to_redirect (AudioRegionView*, AutomationTimeAxisView*); - - void map_frozen (); + AutomationTimeAxisView* gain_track; + AutomationTimeAxisView* pan_track; - void color_handler (ColorID, uint32_t); - bool select_me (GdkEventButton*); + // Set from XML so context menu automation buttons can be correctly initialized + bool show_gain_automation; + bool show_pan_automation; + + Gtk::CheckMenuItem* waveform_item; + Gtk::RadioMenuItem* traditional_item; + Gtk::RadioMenuItem* rectified_item; + Gtk::CheckMenuItem* gain_automation_item; + Gtk::CheckMenuItem* pan_automation_item; }; -#endif /* __ardour_trackview_h__ */ +#endif /* __ardour_audio_time_axis_h__ */ diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 080a440bc9..6e2a93889f 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -21,7 +21,7 @@ using namespace PBD; using namespace Gtk; using namespace Editing; -AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& rent, +AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e, TimeAxisView& rent, ArdourCanvas::Canvas& canvas, const string & nom, const string & state_name, const string & nomparent) @@ -41,6 +41,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit auto_write_item = 0; auto_play_item = 0; ignore_state_request = false; + first_call_to_set_height = true; // base_rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP(canvas_display), // gnome_canvas_simplerect_get_type(), @@ -73,6 +74,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit clear_button.set_name ("TrackVisualButton"); hide_button.set_name ("TrackRemoveButton"); + controls_table.set_no_show_all(); + ARDOUR_UI::instance()->tooltips().set_tip(height_button, _("track height")); ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state")); ARDOUR_UI::instance()->tooltips().set_tip(clear_button, _("clear track")); @@ -116,6 +119,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit plugname = new Label (pname); plugname->set_name (X_("TrackPlugName")); plugname->set_alignment (1.0, 0.5); + plugname->show(); name_label.set_name (X_("TrackParameterName")); controls_table.remove (name_hbox); controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); @@ -139,9 +143,9 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); controls_table.attach (height_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (auto_button, 6, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.attach (clear_button, 6, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - + controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (clear_button, 5, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.show_all (); height_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::height_clicked)); @@ -282,11 +286,11 @@ AutomationTimeAxisView::set_height (TrackHeight ht) uint32_t h = height_to_pixels (ht); bool changed = (height != (uint32_t) h); + bool changed_between_small_and_normal = ( (ht == Small || ht == Smaller) ^ (height_style == Small || height_style == Smaller) ); + TimeAxisView* state_parent = get_parent_with_state (); XMLNode* xml_node = state_parent->get_child_xml_node (_state_name); - controls_table.show_all (); - TimeAxisView::set_height (ht); base_rect->property_y2() = h; @@ -298,119 +302,91 @@ AutomationTimeAxisView::set_height (TrackHeight ht) (*i)->set_height (); } - switch (height) { + + switch (ht) { case Largest: xml_node->add_property ("track_height", "largest"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - plugname_packed = true; - controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } else { - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } - controls_table.show_all (); - hide_name_entry (); - show_name_label (); break; case Large: xml_node->add_property ("track_height", "large"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - plugname_packed = true; - } else { - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } - controls_table.show_all (); - hide_name_entry (); - show_name_label (); break; case Larger: xml_node->add_property ("track_height", "larger"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - plugname_packed = true; - } else { - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } - controls_table.show_all (); - hide_name_entry (); - show_name_label (); break; case Normal: xml_node->add_property ("track_height", "normal"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - plugname_packed = true; - controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } else { - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - } - controls_table.show_all (); - hide_name_entry (); - show_name_label (); break; case Smaller: xml_node->add_property ("track_height", "smaller"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - } - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.hide_all (); - hide_name_entry (); - show_name_label (); - name_hbox.show_all (); - controls_table.show (); break; case Small: xml_node->add_property ("track_height", "small"); - controls_table.remove (name_hbox); - if (plugname) { - if (plugname_packed) { - controls_table.remove (*plugname); - plugname_packed = false; - } - } - controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); - controls_table.hide_all (); - hide_name_entry (); - show_name_label (); - name_hbox.show_all (); - controls_table.show (); break; } + if (changed_between_small_and_normal || first_call_to_set_height) { + first_call_to_set_height = false; + switch (ht) { + case Largest: + case Large: + case Larger: + case Normal: + + controls_table.remove (name_hbox); + + if (plugname) { + if (plugname_packed) { + controls_table.remove (*plugname); + plugname_packed = false; + } + controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + plugname_packed = true; + controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + } else { + controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + } + hide_name_entry (); + show_name_label (); + name_hbox.show_all (); + + auto_button.show(); + height_button.show(); + clear_button.show(); + hide_button.show_all(); + break; + + case Smaller: + case Small: + + controls_table.remove (name_hbox); + if (plugname) { + if (plugname_packed) { + controls_table.remove (*plugname); + plugname_packed = false; + } + } + controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.hide_all (); + hide_name_entry (); + show_name_label (); + name_hbox.show_all (); + + auto_button.hide(); + height_button.hide(); + clear_button.hide(); + hide_button.hide(); + break; + } + } + if (changed) { /* only emit the signal if the height really changed */ - route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ } } diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h index deb08b41f0..0cd9acc034 100644 --- a/gtk2_ardour/automation_time_axis.h +++ b/gtk2_ardour/automation_time_axis.h @@ -4,6 +4,9 @@ #include <vector> #include <list> #include <string> + +#include <boost/shared_ptr.hpp> + #include <ardour/types.h> #include "canvas.h" @@ -21,7 +24,7 @@ namespace ARDOUR { class PublicEditor; class TimeSelection; -class AudioRegionSelection; +class RegionSelection; class PointSelection; class AutomationLine; class GhostRegion; @@ -31,7 +34,7 @@ class Selectable; class AutomationTimeAxisView : public TimeAxisView { public: AutomationTimeAxisView (ARDOUR::Session&, - ARDOUR::Route&, + boost::shared_ptr<ARDOUR::Route>, PublicEditor&, TimeAxisView& parent, ArdourCanvas::Canvas& canvas, @@ -41,14 +44,14 @@ class AutomationTimeAxisView : public TimeAxisView { ~AutomationTimeAxisView(); - void set_height (TimeAxisView::TrackHeight); + virtual void set_height (TimeAxisView::TrackHeight); void set_samples_per_unit (double); std::string name() const { return _name; } virtual void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double) = 0; - void clear_lines (); - void add_line (AutomationLine&); + virtual void clear_lines (); + virtual void add_line (AutomationLine&); vector<AutomationLine*> lines; @@ -75,12 +78,14 @@ class AutomationTimeAxisView : public TimeAxisView { XMLNode* get_state_node (); protected: - ARDOUR::Route& route; + boost::shared_ptr<ARDOUR::Route> route; ArdourCanvas::SimpleRect* base_rect; string _name; string _state_name; bool in_destructor; + bool first_call_to_set_height; + Gtk::Button hide_button; Gtk::Button height_button; Gtk::Button clear_button; diff --git a/gtk2_ardour/canvas-waveview.h b/gtk2_ardour/canvas-waveview.h index 97ac91f622..75281f69eb 100644 --- a/gtk2_ardour/canvas-waveview.h +++ b/gtk2_ardour/canvas-waveview.h @@ -80,10 +80,10 @@ struct _GnomeCanvasWaveView void (*gain_curve_function)(void *arg, double start, double end, float* vector, guint32 veclen); void *gain_src; - /* x-axis: samples per canvas unit. */ + /** x-axis: samples per canvas unit. */ double samples_per_unit; - /* y-axis: amplitude_above_axis. + /** y-axis: amplitude_above_axis. * * the default is that an (scaled, normalized -1.0 ... +1.0) amplitude of 1.0 * corresponds to the top of the area assigned to the waveview. @@ -92,8 +92,8 @@ struct _GnomeCanvasWaveView * smaller values will decrease the vertical scale, moving peaks/troughs toward * the middle of the area assigned to the waveview. */ - double amplitude_above_axis; + double x; double y; double height; diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc index 5b587594de..b2967dc4a9 100644 --- a/gtk2_ardour/crossfade_edit.cc +++ b/gtk2_ardour/crossfade_edit.cc @@ -1077,7 +1077,7 @@ CrossfadeEditor::peaks_ready (AudioRegion* r, WhichFade which) void CrossfadeEditor::audition_both () { - AudioPlaylist& pl (session.the_auditioner().prepare_playlist()); + AudioPlaylist& pl (session.the_auditioner()->prepare_playlist()); jack_nframes_t preroll; jack_nframes_t postroll; jack_nframes_t length; @@ -1140,7 +1140,7 @@ CrossfadeEditor::audition_left_dry () void CrossfadeEditor::audition_left () { - AudioPlaylist& pl (session.the_auditioner().prepare_playlist()); + AudioPlaylist& pl (session.the_auditioner()->prepare_playlist()); AudioRegion* left = new AudioRegion (xfade.out(), xfade.out().length() - xfade.length(), xfade.length(), "xfade left", 0, Region::DefaultFlags, false); @@ -1172,7 +1172,7 @@ CrossfadeEditor::audition_right_dry () void CrossfadeEditor::audition_right () { - AudioPlaylist& pl (session.the_auditioner().prepare_playlist()); + AudioPlaylist& pl (session.the_auditioner()->prepare_playlist()); AudioRegion* left = new AudioRegion (xfade.out(), xfade.out().length() - xfade.length(), xfade.length(), "xfade out", 0, Region::DefaultFlags, false); diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc index 350698ec48..087af25e73 100644 --- a/gtk2_ardour/crossfade_view.cc +++ b/gtk2_ardour/crossfade_view.cc @@ -29,7 +29,7 @@ #include "rgb_macros.h" #include "audio_time_axis.h" #include "public_editor.h" -#include "regionview.h" +#include "audio_region_view.h" #include "utils.h" #include "canvas_impl.h" @@ -43,7 +43,7 @@ using namespace Canvas; sigc::signal<void,CrossfadeView*> CrossfadeView::GoingAway; CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent, - AudioTimeAxisView &tv, + RouteTimeAxisView &tv, Crossfade& xf, double spu, Gdk::Color& basic_color, @@ -227,7 +227,7 @@ CrossfadeView::set_valid (bool yn) AudioRegionView& CrossfadeView::upper_regionview () const { - if (left_view.region.layer() > right_view.region.layer()) { + if (left_view.region().layer() > right_view.region().layer()) { return left_view; } else { return right_view; diff --git a/gtk2_ardour/crossfade_view.h b/gtk2_ardour/crossfade_view.h index 403edfe297..adbd74b420 100644 --- a/gtk2_ardour/crossfade_view.h +++ b/gtk2_ardour/crossfade_view.h @@ -28,13 +28,13 @@ #include "time_axis_view_item.h" -class AudioTimeAxisView; +class RouteTimeAxisView; class AudioRegionView; struct CrossfadeView : public TimeAxisViewItem { CrossfadeView (ArdourCanvas::Group*, - AudioTimeAxisView&, + RouteTimeAxisView&, ARDOUR::Crossfade&, double initial_samples_per_unit, Gdk::Color& basic_color, diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h index cf36550fb4..654ddc8852 100644 --- a/gtk2_ardour/editing_syms.h +++ b/gtk2_ardour/editing_syms.h @@ -56,4 +56,5 @@ DISPLAYCONTROL(ShowWaveformsRecording) IMPORTMODE(ImportAsRegion) IMPORTMODE(ImportAsTrack) +IMPORTMODE(ImportAsTapeTrack) IMPORTMODE(ImportToTrack) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 6472974093..513251085c 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -57,10 +57,10 @@ #include "keyboard.h" #include "marker.h" #include "playlist_selector.h" -#include "regionview.h" +#include "audio_region_view.h" #include "rgb_macros.h" #include "selection.h" -#include "streamview.h" +#include "audio_streamview.h" #include "time_axis_view.h" #include "utils.h" #include "crossfade_view.h" @@ -102,8 +102,8 @@ static const int32_t slide_index = 0; static const int32_t splice_index = 1; static const gchar *edit_mode_strings[] = { - N_("Slide"), - N_("Splice"), + N_("Slide Edit"), + N_("Splice Edit"), 0 }; @@ -132,17 +132,17 @@ static const gchar *snap_type_strings[] = { }; static const gchar *snap_mode_strings[] = { - N_("Normal"), - N_("Magnetic"), + N_("Normal Snap"), + N_("Magnetic Snap"), 0 }; static const gchar *zoom_focus_strings[] = { - N_("Left"), - N_("Right"), - N_("Center"), - N_("Playhead"), - N_("Edit Cursor"), + N_("Focus Left"), + N_("Focus Right"), + N_("Focus Center"), + N_("Focus Play"), + N_("Focus Edit"), 0 }; @@ -205,37 +205,20 @@ Editor::Editor (AudioEngine& eng) /* tool bar related */ - selection_start_clock (X_("SelectionStartClock"), true), - selection_end_clock (X_("SelectionEndClock"), true), edit_cursor_clock (X_("EditCursorClock"), true), zoom_range_clock (X_("ZoomRangeClock"), true, true), toolbar_selection_clock_table (2,3), - mouse_mode_button_table (2, 3), - - mouse_select_button (_("range")), - mouse_move_button (_("object")), - mouse_gain_button (_("gain")), - mouse_zoom_button (_("zoom")), - mouse_timefx_button (_("timefx")), - mouse_audition_button (_("listen")), - automation_mode_button (_("mode")), global_automation_button (_("automation")), - edit_mode_label (_("Edit Mode")), - snap_type_label (_("Snap To")), - snap_mode_label(_("Snap Mode")), - zoom_focus_label (_("Zoom Focus")), - /* <CMT Additions> */ image_socket_listener(0), /* </CMT Additions> */ /* nudge */ - nudge_label (_("Nudge")), nudge_clock (X_("NudgeClock"), true, true) { @@ -346,6 +329,7 @@ Editor::Editor (AudioEngine& eng) reset_hscrollbar_stepping (); zoom_focus = ZoomFocusLeft; + set_zoom_focus (ZoomFocusLeft); zoom_range_clock.ValueChanged.connect (mem_fun(*this, &Editor::zoom_adjustment_changed)); initialize_rulers (); @@ -466,36 +450,7 @@ Editor::Editor (AudioEngine& eng) edit_packer.attach (edit_hscrollbar, 2, 3, 2, 3, FILL|EXPAND, FILL, 0, 0); - zoom_in_button.set_name ("EditorTimeButton"); - zoom_out_button.set_name ("EditorTimeButton"); - ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom in")); - ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom out")); - - zoom_out_full_button.set_name ("EditorTimeButton"); - ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to session")); - - zoom_in_button.add (*(manage (new Image (Stock::ZOOM_IN, ICON_SIZE_BUTTON)))); - zoom_out_button.add (*(manage (new Image (Stock::ZOOM_OUT, ICON_SIZE_BUTTON)))); - zoom_out_full_button.add (*(manage (new Image (Stock::ZOOM_FIT, ICON_SIZE_BUTTON)))); - - zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false)); - zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true)); - zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session)); - - zoom_indicator_box.pack_start (zoom_out_button, false, false); - zoom_indicator_box.pack_start (zoom_in_button, false, false); - zoom_indicator_box.pack_start (zoom_range_clock, false, false); - zoom_indicator_box.pack_start (zoom_out_full_button, false, false); - - zoom_indicator_label.set_text (_("Zoom Span")); - zoom_indicator_label.set_name ("ToolBarLabel"); - - zoom_indicator_vbox.set_spacing (3); - zoom_indicator_vbox.set_border_width (3); - zoom_indicator_vbox.pack_start (zoom_indicator_label, false, false); - zoom_indicator_vbox.pack_start (zoom_indicator_box, false, false); - - bottom_hbox.set_border_width (3); + bottom_hbox.set_border_width (2); bottom_hbox.set_spacing (3); route_display_model = ListStore::create(route_display_columns); @@ -718,15 +673,15 @@ Editor::Editor (AudioEngine& eng) _playlist_selector = new PlaylistSelector(); _playlist_selector->signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector))); - AudioRegionView::AudioRegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_audio_regionview)); + RegionView::RegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_regionview)); /* nudge stuff */ nudge_forward_button.add (*(manage (new Image (get_xpm("right_arrow.xpm"))))); nudge_backward_button.add (*(manage (new Image (get_xpm("left_arrow.xpm"))))); - ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge region/selection forwards")); - ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge region/selection backwards")); + ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge Region/Selection Forwards")); + ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge Region/Selection Backwards")); nudge_forward_button.set_name ("TransportButton"); nudge_backward_button.set_name ("TransportButton"); @@ -776,7 +731,7 @@ Editor::add_toplevel_controls (Container& cont) } void -Editor::catch_vanishing_audio_regionview (AudioRegionView *rv) +Editor::catch_vanishing_regionview (RegionView *rv) { /* note: the selection will take care of the vanishing audioregionview by itself. @@ -792,7 +747,7 @@ Editor::catch_vanishing_audio_regionview (AudioRegionView *rv) } void -Editor::set_entered_regionview (AudioRegionView* rv) +Editor::set_entered_regionview (RegionView* rv) { if (rv == entered_regionview) { return; @@ -914,7 +869,7 @@ Editor::set_frames_per_unit (double fpu) void Editor::instant_save () { - if (!constructed || !ARDOUR_UI::instance()->session_loaded) { + if (!constructed || !ARDOUR_UI::instance()->session_loaded) { return; } @@ -1222,7 +1177,7 @@ Editor::connect_to_session (Session *t) session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state))); session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change))); - session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route_p))); + session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route))); session_connections.push_back (session->AudioRegionAdded.connect (mem_fun(*this, &Editor::handle_new_audio_region))); session_connections.push_back (session->AudioRegionRemoved.connect (mem_fun(*this, &Editor::handle_audio_region_removed))); session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration))); @@ -1243,8 +1198,6 @@ Editor::connect_to_session (Session *t) edit_groups_changed (); edit_cursor_clock.set_session (session); - selection_start_clock.set_session (session); - selection_end_clock.set_session (session); zoom_range_clock.set_session (session); _playlist_selector->set_session (session); nudge_clock.set_session (session); @@ -1377,7 +1330,7 @@ Editor::connect_to_session (Session *t) AudioTimeAxisView *atv; if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) { - if (atv->route().master()) { + if (atv->route()->master()) { route_list_display.get_selection()->unselect (i); } } @@ -1448,7 +1401,7 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i switch (item_type) { case FadeInItem: case FadeInHandleItem: - if (arv->region.fade_in_active()) { + if (arv->audio_region().fade_in_active()) { items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), false))); } else { items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), true))); @@ -1456,16 +1409,16 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Linear))); - items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogB))); - items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Fast))); - items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogA))); - items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Slow))); + items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Linear))); + items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogB))); + items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Fast))); + items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogA))); + items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Slow))); break; case FadeOutItem: case FadeOutHandleItem: - if (arv->region.fade_out_active()) { + if (arv->audio_region().fade_out_active()) { items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), false))); } else { items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), true))); @@ -1473,11 +1426,11 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Linear))); - items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Fast))); - items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogB))); - items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogA))); - items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Slow))); + items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Linear))); + items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Fast))); + items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogB))); + items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogA))); + items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Slow))); break; default: @@ -1499,8 +1452,8 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, switch (item_type) { case RegionItem: - case AudioRegionViewName: - case AudioRegionViewNameHighlight: + case RegionViewName: + case RegionViewNameHighlight: if (with_selection) { build_menu_function = &Editor::build_track_selection_context_menu; } else { @@ -1540,25 +1493,26 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, switch (item_type) { case RegionItem: - case AudioRegionViewName: - case AudioRegionViewNameHighlight: + case RegionViewName: + case RegionViewNameHighlight: if (!with_selection) { if (region_edit_menu_split_item) { - if (clicked_regionview && clicked_regionview->region.covers (edit_cursor->current_frame)) { + if (clicked_regionview && clicked_regionview->region().covers (edit_cursor->current_frame)) { ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true); } else { ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false); } } + /* if (region_edit_menu_split_multichannel_item) { - if (clicked_regionview && clicked_regionview->region.n_channels() > 1) { + if (clicked_regionview && clicked_regionview->region().n_channels() > 1) { // GTK2FIX find the action, change its sensitivity // region_edit_menu_split_multichannel_item->set_sensitive (true); } else { // GTK2FIX see above // region_edit_menu_split_multichannel_item->set_sensitive (false); } - } + }*/ } break; @@ -1638,13 +1592,13 @@ Editor::build_track_region_context_menu (jack_nframes_t frame) AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview); if (atv) { - AudioDiskstream* ds; + Diskstream* ds; Playlist* pl; if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) { Playlist::RegionList* regions = pl->regions_at ((jack_nframes_t) floor ( (double)frame * ds->speed())); for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) { - add_region_context_items (atv->view, (*i), edit_items); + add_region_context_items (atv->audio_view(), (*i), edit_items); } delete regions; } @@ -1665,7 +1619,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame) AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview); if (atv) { - AudioDiskstream* ds; + Diskstream* ds; Playlist* pl; AudioPlaylist* apl; @@ -1679,11 +1633,11 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame) bool many = xfades.size() > 1; for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) { - add_crossfade_context_items (atv->view, (*i), edit_items, many); + add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many); } for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) { - add_region_context_items (atv->view, (*i), edit_items); + add_region_context_items (atv->audio_view(), (*i), edit_items); } delete regions; @@ -1749,7 +1703,7 @@ Editor::build_track_selection_context_menu (jack_nframes_t ignored) } void -Editor::add_crossfade_context_items (StreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many) +Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many) { using namespace Menu_Helpers; Menu *xfade_menu = manage (new Menu); @@ -1806,7 +1760,7 @@ Editor::xfade_edit_right_region () } void -Editor::add_region_context_items (StreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items) +Editor::add_region_context_items (AudioStreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items) { using namespace Menu_Helpers; Menu *region_menu = manage (new Menu); @@ -2185,7 +2139,6 @@ Editor::set_state (const XMLNode& node) yoff = atoi(geometry->property("y_off")->value()); } - set_geometry_hints (vpacker, g, Gdk::HINT_BASE_SIZE); set_default_size (g.base_width, g.base_height); move (x, y); @@ -2297,7 +2250,7 @@ Editor::get_state () char buf[32]; if (is_realized()) { - Glib::RefPtr<Gdk::Window> win = get_window(); + Glib::RefPtr<Gdk::Window> win = get_window(); int x, y, xoff, yoff, width, height; win->get_root_origin(x, y); @@ -2586,30 +2539,56 @@ void Editor::setup_toolbar () { string pixmap_path; + + const guint32 FUDGE = 18; // Combo's are stupid - they steal space from the entry for the button + + + /* Mode Buttons (tool selection) */ + vector<ToggleButton *> mouse_mode_buttons; + mouse_move_button.add (*(manage (new Image (get_xpm("tool_object.xpm"))))); + mouse_move_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_move_button); + mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm"))))); + mouse_select_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_select_button); + mouse_gain_button.add (*(manage (new Image (get_xpm("tool_gain.xpm"))))); + mouse_gain_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_gain_button); + mouse_zoom_button.add (*(manage (new Image (get_xpm("tool_zoom.xpm"))))); + mouse_zoom_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_zoom_button); + mouse_timefx_button.add (*(manage (new Image (get_xpm("tool_stretch.xpm"))))); + mouse_timefx_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_timefx_button); + mouse_audition_button.add (*(manage (new Image (get_xpm("tool_audition.xpm"))))); + mouse_audition_button.set_relief(Gtk::RELIEF_NONE); mouse_mode_buttons.push_back (&mouse_audition_button); + mouse_mode_button_set = new GroupedButtons (mouse_mode_buttons); - mouse_mode_button_table.set_homogeneous (true); - mouse_mode_button_table.set_col_spacings (2); - mouse_mode_button_table.set_row_spacings (2); - mouse_mode_button_table.set_border_width (5); + HBox* mode_box = manage(new HBox); + mode_box->set_border_width (2); + mode_box->set_spacing(4); + mouse_mode_button_box.set_spacing(1); + mouse_mode_button_box.pack_start(mouse_move_button, true, true); + mouse_mode_button_box.pack_start(mouse_select_button, true, true); + mouse_mode_button_box.pack_start(mouse_zoom_button, true, true); + mouse_mode_button_box.pack_start(mouse_gain_button, true, true); + mouse_mode_button_box.pack_start(mouse_timefx_button, true, true); + mouse_mode_button_box.pack_start(mouse_audition_button, true, true); + mouse_mode_button_box.set_homogeneous(true); - mouse_mode_button_table.attach (mouse_move_button, 0, 1, 0, 1); - mouse_mode_button_table.attach (mouse_select_button, 1, 2, 0, 1); - mouse_mode_button_table.attach (mouse_zoom_button, 2, 3, 0, 1); - - mouse_mode_button_table.attach (mouse_gain_button, 0, 1, 1, 2); - mouse_mode_button_table.attach (mouse_timefx_button, 1, 2, 1, 2); - mouse_mode_button_table.attach (mouse_audition_button, 2, 3, 1, 2); + edit_mode_selector.set_name ("EditModeSelector"); + Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "Splice Edit", 2+FUDGE, 10); + set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings)); + edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done)); - mouse_mode_tearoff = manage (new TearOff (mouse_mode_button_table)); + mode_box->pack_start(edit_mode_selector); + mode_box->pack_start(mouse_mode_button_box); + + mouse_mode_tearoff = manage (new TearOff (*mode_box)); mouse_mode_tearoff->set_name ("MouseModeBase"); mouse_mode_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox), @@ -2628,12 +2607,12 @@ Editor::setup_toolbar () mouse_timefx_button.set_name ("MouseModeButton"); mouse_audition_button.set_name ("MouseModeButton"); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("select/move objects")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("select/move ranges")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("draw gain automation")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("select zoom range")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("stretch/shrink regions")); - ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("listen to specific regions")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("Select/Move Objects")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("Draw Gain Automation")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("Select Zoom Range")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("Stretch/Shrink Regions")); + ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("Listen to Specific Regions")); mouse_move_button.unset_flags (CAN_FOCUS); mouse_select_button.unset_flags (CAN_FOCUS); @@ -2652,160 +2631,82 @@ Editor::setup_toolbar () mouse_audition_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition)); // mouse_move_button.set_active (true); + - /* automation control */ - - global_automation_button.set_name ("MouseModeButton"); - automation_mode_button.set_name ("MouseModeButton"); - - automation_box.set_spacing (2); - automation_box.set_border_width (2); - automation_box.pack_start (global_automation_button, false, false); - automation_box.pack_start (automation_mode_button, false, false); - - /* Edit mode */ - - edit_mode_label.set_name ("ToolBarLabel"); - - edit_mode_selector.set_name ("EditModeSelector"); + /* Zoom */ + + zoom_box.set_spacing (1); + zoom_box.set_border_width (2); - edit_mode_box.set_spacing (3); - edit_mode_box.set_border_width (3); + zoom_in_button.set_name ("EditorTimeButton"); + zoom_in_button.add (*(manage (new Image (get_xpm("zoom_in.xpm"))))); + zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false)); + ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In")); + + zoom_out_button.set_name ("EditorTimeButton"); + zoom_out_button.add (*(manage (new Image (get_xpm("zoom_out.xpm"))))); + zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true)); + ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out")); - /* XXX another disgusting hack because of the way combo boxes size themselves */ + zoom_out_full_button.set_name ("EditorTimeButton"); + zoom_out_full_button.add (*(manage (new Image (get_xpm("zoom_full.xpm"))))); + zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session)); + ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session")); + + zoom_box.pack_start (zoom_out_button, false, false); + zoom_box.pack_start (zoom_in_button, false, false); + zoom_box.pack_start (zoom_range_clock, false, false); + zoom_box.pack_start (zoom_out_full_button, false, false); + + ARDOUR_UI::instance()->tooltips().set_tip (zoom_range_clock, _("Current Zoom Range\n(Width of visible area)")); + + zoom_focus_selector.set_name ("ZoomFocusSelector"); + Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Focus Center", 2+FUDGE, 0); + set_popdown_strings (zoom_focus_selector, internationalize (zoom_focus_strings)); + zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done)); - const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button - Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "EdgtMode", 2+FUDGE, 10); - set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings)); - edit_mode_box.pack_start (edit_mode_label, false, false); - edit_mode_box.pack_start (edit_mode_selector, false, false); + zoom_box.pack_start (zoom_focus_selector, false, false); - edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done)); - /* Snap Type */ + /* Edit Cursor / Snap */ - snap_type_label.set_name ("ToolBarLabel"); + snap_box.set_spacing (1); + snap_box.set_border_width (2); snap_type_selector.set_name ("SnapTypeSelector"); - - snap_type_box.set_spacing (3); - snap_type_box.set_border_width (3); - - /* XXX another disgusting hack because of the way combo boxes size themselves */ - Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10); set_popdown_strings (snap_type_selector, internationalize (snap_type_strings)); - - snap_type_box.pack_start (snap_type_label, false, false); - snap_type_box.pack_start (snap_type_selector, false, false); - snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done)); - - /* Snap mode, not snap type */ - - snap_mode_label.set_name ("ToolBarLabel"); + ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Unit to snap cursors and ranges to")); snap_mode_selector.set_name ("SnapModeSelector"); - - snap_mode_box.set_spacing (3); - snap_mode_box.set_border_width (3); - - Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "SngpMode", 2+FUDGE, 10); + Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10); set_popdown_strings (snap_mode_selector, internationalize (snap_mode_strings)); - - snap_mode_box.pack_start (snap_mode_label, false, false); - snap_mode_box.pack_start (snap_mode_selector, false, false); - snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done)); - /* Zoom focus mode */ - - zoom_focus_label.set_name ("ToolBarLabel"); - - zoom_focus_selector.set_name ("ZoomFocusSelector"); - - zoom_focus_box.set_spacing (3); - zoom_focus_box.set_border_width (3); - - /* XXX another disgusting hack because of the way combo boxes size themselves */ - - Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edgt Cursor", 2+FUDGE, 10); - set_popdown_strings (zoom_focus_selector, internationalize (zoom_focus_strings)); - - zoom_focus_box.pack_start (zoom_focus_label, false, false); - zoom_focus_box.pack_start (zoom_focus_selector, false, false); - - zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done)); - - /* selection/cursor clocks */ - - toolbar_selection_cursor_label.set_name ("ToolBarLabel"); - selection_start_clock_label.set_name ("ToolBarLabel"); - selection_end_clock_label.set_name ("ToolBarLabel"); - edit_cursor_clock_label.set_name ("ToolBarLabel"); - - selection_start_clock_label.set_text (_("Start:")); - selection_end_clock_label.set_text (_("End:")); - edit_cursor_clock_label.set_text (_("Edit")); - - /* the zoom in/out buttons are generally taller than the clocks, so - put all the toolbar clocks into a size group with one of the - buttons to make them all equal height. + snap_box.pack_start (edit_cursor_clock, false, false); + snap_box.pack_start (snap_mode_selector, false, false); + snap_box.pack_start (snap_type_selector, false, false); - this also applies to the various toolbar combos - */ - - RefPtr<SizeGroup> toolbar_clock_size_group = SizeGroup::create (SIZE_GROUP_VERTICAL); - toolbar_clock_size_group->add_widget (zoom_out_button); - toolbar_clock_size_group->add_widget (edit_cursor_clock); - toolbar_clock_size_group->add_widget (zoom_range_clock); - toolbar_clock_size_group->add_widget (nudge_clock); - toolbar_clock_size_group->add_widget (edit_mode_selector); - toolbar_clock_size_group->add_widget (snap_type_selector); - toolbar_clock_size_group->add_widget (snap_mode_selector); - toolbar_clock_size_group->add_widget (zoom_focus_selector); - - HBox* edit_clock_hbox = manage (new HBox()); - VBox* edit_clock_vbox = manage (new VBox()); - - edit_clock_hbox->pack_start (edit_cursor_clock, false, false); - - edit_clock_vbox->set_spacing (3); - edit_clock_vbox->set_border_width (3); - edit_clock_vbox->pack_start (edit_cursor_clock_label, false, false); - edit_clock_vbox->pack_start (*edit_clock_hbox, false, false); - - HBox* hbox = new HBox; - hbox->pack_start (*edit_clock_vbox, false, false); - hbox->pack_start (zoom_indicator_vbox, false, false); - hbox->pack_start (zoom_focus_box, false, false); - hbox->pack_start (snap_type_box, false, false); - hbox->pack_start (snap_mode_box, false, false); - hbox->pack_start (edit_mode_box, false, false); + /* Nudge */ - VBox *vbox = manage (new VBox); + HBox *nudge_box = manage (new HBox); + nudge_box->set_spacing(1); + nudge_box->set_border_width (2); - vbox->set_spacing (3); - vbox->set_border_width (3); - - HBox *nbox = manage (new HBox); - nudge_forward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_forward), false)); nudge_backward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_backward), false)); - nbox->pack_start (nudge_backward_button, false, false); - nbox->pack_start (nudge_forward_button, false, false); - nbox->pack_start (nudge_clock, false, false, 5); - - nudge_label.set_name ("ToolBarLabel"); + nudge_box->pack_start (nudge_backward_button, false, false); + nudge_box->pack_start (nudge_forward_button, false, false); + nudge_box->pack_start (nudge_clock, false, false); - vbox->pack_start (nudge_label, false, false); - vbox->pack_start (*nbox, false, false); - hbox->pack_start (*vbox, false, false); + /* Pack everything in... */ - hbox->show_all (); + HBox* hbox = new HBox; + hbox->set_spacing(10); tools_tearoff = new TearOff (*hbox); tools_tearoff->set_name ("MouseModeBase"); @@ -2819,11 +2720,18 @@ Editor::setup_toolbar () tools_tearoff->Visible.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox), &tools_tearoff->tearoff_window(), 0)); - toolbar_hbox.set_spacing (8); - toolbar_hbox.set_border_width (2); + toolbar_hbox.set_spacing (10); + toolbar_hbox.set_border_width (1); - toolbar_hbox.pack_start (*tools_tearoff, false, false); toolbar_hbox.pack_start (*mouse_mode_tearoff, false, false); + toolbar_hbox.pack_start (*tools_tearoff, false, false); + + + hbox->pack_start (snap_box, false, false); + hbox->pack_start (zoom_box, false, false); + hbox->pack_start (*nudge_box, false, false); + + hbox->show_all (); toolbar_base.set_name ("ToolBarBase"); toolbar_base.add (toolbar_hbox); @@ -3055,7 +2963,7 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie continue; } - RouteGroup* group = atv->route().edit_group(); + RouteGroup* group = atv->route()->edit_group(); if (group && group->is_active()) { @@ -3067,7 +2975,7 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie if ((tatv = dynamic_cast<AudioTimeAxisView*> (*i)) != 0) { - if (tatv->route().edit_group() == group) { + if (tatv->route()->edit_group() == group) { relevant_tracks.insert (tatv); } } @@ -3102,31 +3010,31 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl) } void -Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint32_t ignored, - AudioRegionView* basis, vector<AudioRegionView*>* all_equivs) +Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored, + RegionView* basis, vector<RegionView*>* all_equivs) { - AudioPlaylist* pl; - vector<AudioRegion*> results; - AudioRegionView* marv; - AudioDiskstream* ds; + Playlist* pl; + vector<Region*> results; + RegionView* marv; + Diskstream* ds; - if ((ds = atv.get_diskstream()) == 0) { + if ((ds = tv.get_diskstream()) == 0) { /* bus */ return; } - if (&atv == &basis->get_time_axis_view()) { + if (&tv == &basis->get_time_axis_view()) { /* looking in same track as the original */ return; } - if ((pl = ds->playlist()) != 0) { - pl->get_equivalent_regions (basis->region, results); + if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) { + pl->get_equivalent_regions (basis->region(), results); } - for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) { - if ((marv = atv.view->find_view (**ir)) != 0) { + for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) { + if ((marv = tv.view()->find_view (**ir)) != 0) { all_equivs->push_back (marv); } } @@ -3135,7 +3043,7 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3 bool Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove) { - vector<AudioRegionView*> all_equivalent_regions; + vector<RegionView*> all_equivalent_regions; bool commit = false; if (!clicked_regionview || !clicked_audio_trackview) { @@ -3190,7 +3098,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, commit = true; } - for (vector<AudioRegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) { + for (vector<RegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) { selection->add (*i); } } @@ -3223,58 +3131,58 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, last_frame = 0; first_frame = max_frames; - for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) { + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) { - if ((*x)->region.last_frame() > last_frame) { - last_frame = (*x)->region.last_frame(); + if ((*x)->region().last_frame() > last_frame) { + last_frame = (*x)->region().last_frame(); } - if ((*x)->region.first_frame() < first_frame) { - first_frame = (*x)->region.first_frame(); + if ((*x)->region().first_frame() < first_frame) { + first_frame = (*x)->region().first_frame(); } } } /* 2. figure out the boundaries for our search for new objects */ - switch (clicked_regionview->region.coverage (first_frame, last_frame)) { + switch (clicked_regionview->region().coverage (first_frame, last_frame)) { case OverlapNone: cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = " - << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl; + << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl; - if (last_frame < clicked_regionview->region.first_frame()) { + if (last_frame < clicked_regionview->region().first_frame()) { first_frame = last_frame; - last_frame = clicked_regionview->region.last_frame(); + last_frame = clicked_regionview->region().last_frame(); } else { last_frame = first_frame; - first_frame = clicked_regionview->region.first_frame(); + first_frame = clicked_regionview->region().first_frame(); } break; case OverlapExternal: cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = " - << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl; + << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl; - if (last_frame < clicked_regionview->region.first_frame()) { + if (last_frame < clicked_regionview->region().first_frame()) { first_frame = last_frame; - last_frame = clicked_regionview->region.last_frame(); + last_frame = clicked_regionview->region().last_frame(); } else { last_frame = first_frame; - first_frame = clicked_regionview->region.first_frame(); + first_frame = clicked_regionview->region().first_frame(); } break; case OverlapInternal: cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = " - << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl; + << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl; - if (last_frame < clicked_regionview->region.first_frame()) { + if (last_frame < clicked_regionview->region().first_frame()) { first_frame = last_frame; - last_frame = clicked_regionview->region.last_frame(); + last_frame = clicked_regionview->region().last_frame(); } else { last_frame = first_frame; - first_frame = clicked_regionview->region.first_frame(); + first_frame = clicked_regionview->region().first_frame(); } break; @@ -3300,18 +3208,18 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, /* 3. convert to a vector of audio regions */ - vector<AudioRegionView*> audio_regions; + vector<RegionView*> regions; for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) { - AudioRegionView* arv; + RegionView* arv; - if ((arv = dynamic_cast<AudioRegionView*>(*x)) != 0) { - audio_regions.push_back (arv); + if ((arv = dynamic_cast<RegionView*>(*x)) != 0) { + regions.push_back (arv); } } - if (!audio_regions.empty()) { - selection->add (audio_regions); + if (!regions.empty()) { + selection->add (regions); commit = true; } } @@ -3321,37 +3229,32 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, } void -Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operation op) +Editor::set_selected_regionview_from_region_list (Region& region, Selection::Operation op) { - vector<AudioRegionView*> all_equivalent_regions; - AudioRegion* region; - - if ((region = dynamic_cast<AudioRegion*>(&r)) == 0) { - return; - } + vector<RegionView*> all_equivalent_regions; for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - AudioTimeAxisView* tatv; + RouteTimeAxisView* tatv; - if ((tatv = dynamic_cast<AudioTimeAxisView*> (*i)) != 0) { + if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) { - AudioPlaylist* pl; - vector<AudioRegion*> results; - AudioRegionView* marv; - AudioDiskstream* ds; + Playlist* pl; + vector<Region*> results; + RegionView* marv; + Diskstream* ds; if ((ds = tatv->get_diskstream()) == 0) { /* bus */ continue; } - if ((pl = ds->playlist()) != 0) { - pl->get_region_list_equivalent_regions (*region, results); + if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) { + pl->get_region_list_equivalent_regions (region, results); } - for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) { - if ((marv = tatv->view->find_view (**ir)) != 0) { + for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) { + if ((marv = tatv->view()->find_view (**ir)) != 0) { all_equivalent_regions.push_back (marv); } } @@ -3380,10 +3283,10 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio bool Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, Region* r) { - AudioRegionView* rv; - AudioRegion* ar; + RegionView* rv; + Region* ar; - if ((ar = dynamic_cast<AudioRegion*> (r)) == 0) { + if ((ar = dynamic_cast<Region*> (r)) == 0) { return TRUE; } @@ -3395,7 +3298,7 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, a single other region. */ - if (selection->audio_regions.size() > 1) { + if (selection->regions.size() > 1) { return TRUE; } @@ -3560,7 +3463,7 @@ Editor::duplicate_dialog (bool dup_region) if (sscanf (text.c_str(), "%f", ×) == 1) { if (dup_region) { - AudioRegionSelection regions; + RegionSelection regions; regions.add (clicked_regionview); duplicate_some_regions (regions, times); } else { @@ -3611,9 +3514,9 @@ Editor::edit_mode_selection_done () string choice = edit_mode_selector.get_active_text(); EditMode mode = Slide; - if (choice == _("Splice")) { + if (choice == _("Splice Edit")) { mode = Splice; - } else if (choice == _("Slide")) { + } else if (choice == _("Slide Edit")) { mode = Slide; } @@ -3629,18 +3532,18 @@ Editor::snap_type_selection_done () string choice = snap_type_selector.get_active_text(); SnapType snaptype = SnapToFrame; - + if (choice == _("Beats/3")) { - snaptype = SnapToAThirdBeat; - } else if (choice == _("Beats/4")) { - snaptype = SnapToAQuarterBeat; - } else if (choice == _("Beats/8")) { - snaptype = SnapToAEighthBeat; - } else if (choice == _("Beats/16")) { - snaptype = SnapToASixteenthBeat; - } else if (choice == _("Beats/32")) { - snaptype = SnapToAThirtysecondBeat; - } else if (choice == _("Beats")) { + snaptype = SnapToAThirdBeat; + } else if (choice == _("Beats/4")) { + snaptype = SnapToAQuarterBeat; + } else if (choice == _("Beats/8")) { + snaptype = SnapToAEighthBeat; + } else if (choice == _("Beats/16")) { + snaptype = SnapToASixteenthBeat; + } else if (choice == _("Beats/32")) { + snaptype = SnapToAThirtysecondBeat; + } else if (choice == _("Beats")) { snaptype = SnapToBeat; } else if (choice == _("Bars")) { snaptype = SnapToBar; @@ -3668,10 +3571,10 @@ Editor::snap_type_selection_done () snaptype = SnapToSeconds; } else if (choice == _("Minutes")) { snaptype = SnapToMinutes; - } else if (choice == _("None")) { + } else if (choice == _("None")) { snaptype = SnapToFrame; } - + set_snap_to (snaptype); } @@ -3685,9 +3588,9 @@ Editor::snap_mode_selection_done () string choice = snap_mode_selector.get_active_text(); SnapMode mode = SnapNormal; - if (choice == _("Normal")) { + if (choice == _("Normal Snap")) { mode = SnapNormal; - } else if (choice == _("Magnetic")) { + } else if (choice == _("Magnetic Snap")) { mode = SnapMagnetic; } @@ -3704,15 +3607,15 @@ Editor::zoom_focus_selection_done () string choice = zoom_focus_selector.get_active_text(); ZoomFocus focus_type = ZoomFocusLeft; - if (choice == _("Left")) { + if (choice == _("Focus Left")) { focus_type = ZoomFocusLeft; - } else if (choice == _("Right")) { + } else if (choice == _("Focus Right")) { focus_type = ZoomFocusRight; - } else if (choice == _("Center")) { + } else if (choice == _("Focus Center")) { focus_type = ZoomFocusCenter; - } else if (choice == _("Playhead")) { + } else if (choice == _("Focus Playhead")) { focus_type = ZoomFocusPlayhead; - } else if (choice == _("Edit Cursor")) { + } else if (choice == _("Focus Edit Cursor")) { focus_type = ZoomFocusEdit; } @@ -3782,7 +3685,7 @@ void Editor::region_selection_changed () { for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - (*i)->set_selected_regionviews (selection->audio_regions); + (*i)->set_selected_regionviews (selection->regions); } } @@ -4052,8 +3955,8 @@ Editor::playlist_deletion_dialog (Playlist* pl) bool Editor::audio_region_selection_covers (jack_nframes_t where) { - for (AudioRegionSelection::iterator a = selection->audio_regions.begin(); a != selection->audio_regions.end(); ++a) { - if ((*a)->region.covers (where)) { + for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) { + if ((*a)->region().covers (where)) { return true; } } @@ -4064,10 +3967,10 @@ Editor::audio_region_selection_covers (jack_nframes_t where) void Editor::prepare_for_cleanup () { - cut_buffer->clear_audio_regions (); + cut_buffer->clear_regions (); cut_buffer->clear_playlists (); - selection->clear_audio_regions (); + selection->clear_regions (); selection->clear_playlists (); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 478a8c96ab..c31dfd5ede 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -40,7 +40,7 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/dndtreeview.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include <ardour/session.h> #include <ardour/tempo.h> #include <ardour/location.h> @@ -69,6 +69,7 @@ namespace ARDOUR { class AudioDiskstream; class RouteGroup; class Playlist; + class AudioPlaylist; class Region; class Location; class TempoSection; @@ -83,6 +84,7 @@ namespace LADSPA { } class TimeAxisView; +class RouteTimeAxisView; class AudioTimeAxisView; class AutomationTimeAxisView; class AudioRegionView; @@ -100,6 +102,7 @@ class TrackSelection; class AutomationSelection; class MixerStrip; class StreamView; +class AudioStreamView; class ControlPoint; #ifdef FFT_ANALYSIS class AnalysisWindow; @@ -405,8 +408,8 @@ class Editor : public PublicEditor TimeAxisView* clicked_trackview; AudioTimeAxisView* clicked_audio_trackview; - AudioRegionView* clicked_regionview; - AudioRegionView* latest_regionview; + RegionView* clicked_regionview; + RegionView* latest_regionview; uint32_t clicked_selection; CrossfadeView* clicked_crossfadeview; ControlPoint* clicked_control_point; @@ -416,7 +419,7 @@ class Editor : public PublicEditor /* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */ - void mapped_set_selected_regionview_from_click (AudioTimeAxisView&, uint32_t, AudioRegionView*, vector<AudioRegionView*>*); + void mapped_set_selected_regionview_from_click (RouteTimeAxisView&, uint32_t, RegionView*, vector<RegionView*>*); void mapped_use_new_playlist (AudioTimeAxisView&, uint32_t); void mapped_use_copy_playlist (AudioTimeAxisView&, uint32_t); void mapped_clear_playlist (AudioTimeAxisView&, uint32_t); @@ -426,7 +429,7 @@ class Editor : public PublicEditor void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type); bool button_release_can_deselect; - void catch_vanishing_audio_regionview (AudioRegionView *); + void catch_vanishing_regionview (RegionView *); bool set_selected_control_point_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false); bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false); @@ -434,7 +437,7 @@ class Editor : public PublicEditor void set_selected_regionview_from_region_list (ARDOUR::Region& region, Selection::Operation op = Selection::Set); bool set_selected_regionview_from_map_event (GdkEventAny*, StreamView*, ARDOUR::Region*); - void collect_new_region_view (AudioRegionView *); + void collect_new_region_view (RegionView *); Gtk::Menu track_context_menu; Gtk::Menu track_region_context_menu; @@ -455,12 +458,11 @@ class Editor : public PublicEditor Gtk::Menu* build_track_selection_context_menu (jack_nframes_t); void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&); void add_bus_context_items (Gtk::Menu_Helpers::MenuList&); - void add_region_context_items (StreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&); - void add_crossfade_context_items (StreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many); + void add_region_context_items (AudioStreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&); + void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many); void add_selection_context_items (Gtk::Menu_Helpers::MenuList&); - void handle_new_route (ARDOUR::Route&); - void handle_new_route_p (ARDOUR::Route*); + void handle_new_route (boost::shared_ptr<ARDOUR::Route>); void remove_route (TimeAxisView *); bool route_removal; @@ -854,7 +856,7 @@ class Editor : public PublicEditor void lower_region_to_bottom (); void split_region (); void split_region_at (jack_nframes_t); - void split_regions_at (jack_nframes_t, AudioRegionSelection&); + void split_regions_at (jack_nframes_t, RegionSelection&); void crop_region_to_selection (); void set_a_regions_sync_position (ARDOUR::Region&, jack_nframes_t); void set_region_sync_from_edit_cursor (); @@ -867,13 +869,13 @@ class Editor : public PublicEditor void remove_clicked_region (); void destroy_clicked_region (); void edit_region (); - void duplicate_some_regions (AudioRegionSelection&, float times); + void duplicate_some_regions (RegionSelection&, float times); void duplicate_selection (float times); void region_fill_selection (); void region_fill_track (); - void audition_playlist_region_standalone (ARDOUR::AudioRegion&); - void audition_playlist_region_via_route (ARDOUR::AudioRegion&, ARDOUR::Route&); + void audition_playlist_region_standalone (ARDOUR::Region&); + void audition_playlist_region_via_route (ARDOUR::Region&, ARDOUR::Route&); void split_multichannel_region(); void reverse_region (); void normalize_region (); @@ -1020,7 +1022,7 @@ class Editor : public PublicEditor bool have_pending_keyboard_selection; jack_nframes_t pending_keyboard_selection_start; - ARDOUR::AudioRegion* select_region_for_operation (int dir, TimeAxisView **tv); + ARDOUR::Region* select_region_for_operation (int dir, TimeAxisView **tv); void extend_selection_to_end_of_region (bool next); void extend_selection_to_start_of_region (bool previous); @@ -1094,7 +1096,7 @@ class Editor : public PublicEditor void remove_gain_control_point (ArdourCanvas::Item*, GdkEvent*); void remove_control_point (ArdourCanvas::Item*, GdkEvent*); - void mouse_brush_insert_region (AudioRegionView*, jack_nframes_t pos); + void mouse_brush_insert_region (RegionView*, jack_nframes_t pos); void brush (jack_nframes_t); void show_verbose_time_cursor (jack_nframes_t frame, double offset = 0, double xpos=-1, double ypos=-1); @@ -1112,10 +1114,10 @@ class Editor : public PublicEditor bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); - bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); - bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); - bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*); - bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*); + bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); + bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); + bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*); + bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*); bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*); bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*); bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*); @@ -1263,12 +1265,7 @@ class Editor : public PublicEditor void editor_mixer_button_toggled (); - AudioClock selection_start_clock; - Gtk::Label selection_start_clock_label; - AudioClock selection_end_clock; - Gtk::Label selection_end_clock_label; AudioClock edit_cursor_clock; - Gtk::Label edit_cursor_clock_label; AudioClock zoom_range_clock; Gtk::Button zoom_in_button; Gtk::Button zoom_out_button; @@ -1280,8 +1277,8 @@ class Editor : public PublicEditor Gtk::Table toolbar_selection_clock_table; Gtk::Label toolbar_selection_cursor_label; - Gtk::Table mouse_mode_button_table; - Gtkmm2ext::TearOff* mouse_mode_tearoff; + Gtk::HBox mouse_mode_button_box; + Gtkmm2ext::TearOff* mouse_mode_tearoff; Gtk::ToggleButton mouse_select_button; Gtk::ToggleButton mouse_move_button; Gtk::ToggleButton mouse_gain_button; @@ -1299,32 +1296,23 @@ class Editor : public PublicEditor Gtk::ToggleButton global_automation_button; Gtk::ComboBoxText edit_mode_selector; - Gtk::Label edit_mode_label; - Gtk::VBox edit_mode_box; + Gtk::VBox edit_mode_box; void edit_mode_selection_done (); Gtk::ComboBoxText snap_type_selector; - Gtk::Label snap_type_label; - Gtk::VBox snap_type_box; + Gtk::ComboBoxText snap_mode_selector; + Gtk::HBox snap_box; void snap_type_selection_done (); - - Gtk::ComboBoxText snap_mode_selector; - Gtk::Label snap_mode_label; - Gtk::VBox snap_mode_box; - void snap_mode_selection_done (); Gtk::ComboBoxText zoom_focus_selector; - Gtk::Label zoom_focus_label; Gtk::VBox zoom_focus_box; void zoom_focus_selection_done (); - Gtk::Label zoom_indicator_label; - Gtk::HBox zoom_indicator_box; - Gtk::VBox zoom_indicator_vbox; + Gtk::HBox zoom_box; void update_zoom_indicator (); void zoom_adjustment_changed(); @@ -1533,12 +1521,12 @@ class Editor : public PublicEditor void start_trim (ArdourCanvas::Item*, GdkEvent*); void point_trim (GdkEvent*); void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*); - void single_contents_trim (AudioRegionView&, jack_nframes_t, bool, bool, bool); - void single_start_trim (AudioRegionView&, jack_nframes_t, bool, bool); - void single_end_trim (AudioRegionView&, jack_nframes_t, bool, bool); + void single_contents_trim (RegionView&, jack_nframes_t, bool, bool, bool); + void single_start_trim (RegionView&, jack_nframes_t, bool, bool); + void single_end_trim (RegionView&, jack_nframes_t, bool, bool); void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*); - void thaw_region_after_trim (AudioRegionView& rv); + void thaw_region_after_trim (RegionView& rv); void trim_region_to_edit_cursor (); void trim_region_from_edit_cursor (); @@ -1592,7 +1580,7 @@ class Editor : public PublicEditor void export_range (jack_nframes_t start, jack_nframes_t end); void export_range_markers (); - int write_region_selection(AudioRegionSelection&); + int write_region_selection(RegionSelection&); bool write_region (string path, ARDOUR::AudioRegion&); void export_region (); void bounce_region_selection (); @@ -1600,7 +1588,7 @@ class Editor : public PublicEditor void external_edit_region (); int write_audio_selection (TimeSelection&); - bool write_audio_range (ARDOUR::Playlist&, uint32_t channels, list<ARDOUR::AudioRange>&); + bool write_audio_range (ARDOUR::AudioPlaylist&, uint32_t channels, list<ARDOUR::AudioRange>&); void write_selection (); @@ -1671,7 +1659,7 @@ class Editor : public PublicEditor struct TimeStretchDialog : public ArdourDialog { ARDOUR::Session::TimeStretchRequest request; Editor& editor; - AudioRegionSelection regions; + RegionSelection regions; Gtk::ProgressBar progress_bar; Gtk::ToggleButton quick_button; Gtk::ToggleButton antialias_button; @@ -1697,7 +1685,7 @@ class Editor : public PublicEditor TimeStretchDialog* current_timestretch; static void* timestretch_thread (void *arg); - int run_timestretch (AudioRegionSelection&, float fraction); + int run_timestretch (RegionSelection&, float fraction); void do_timestretch (TimeStretchDialog&); /* editor-mixer strip */ @@ -1776,7 +1764,6 @@ class Editor : public PublicEditor Gtk::Button nudge_backward_button; Gtk::HBox nudge_hbox; Gtk::VBox nudge_vbox; - Gtk::Label nudge_label; AudioClock nudge_clock; jack_nframes_t get_nudge_distance (jack_nframes_t pos, jack_nframes_t& next); @@ -1799,11 +1786,11 @@ class Editor : public PublicEditor sigc::connection step_timeout; TimeAxisView* entered_track; - AudioRegionView* entered_regionview; + RegionView* entered_regionview; bool clear_entered_track; gint left_track_canvas (GdkEventCrossing*); void set_entered_track (TimeAxisView*); - void set_entered_regionview (AudioRegionView*); + void set_entered_regionview (RegionView*); gint left_automation_track (); bool _new_regionviews_show_envelope; diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index e20e6ee8eb..65195ca822 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -357,6 +357,8 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsTrack"), _("as Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTrack)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsTapeTrack"), _("as Tape Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTapeTrack)); + ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, X_("addExternalAudioToTrack"), _("to Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack)); ActionManager::session_sensitive_actions.push_back (act); diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 2c64f2cf15..7524f9605c 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -268,7 +268,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool idspec += string_compose(":%1", n); try { - source = AudioFileSource::create (idspec.c_str()); + source = AudioFileSource::create (idspec.c_str(), (mode == ImportAsTrack ? AudioFileSource::Destructive : AudioFileSource::Flag (0))); sources.push_back(source); } @@ -306,16 +306,18 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool } int - Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, jack_nframes_t& pos, ImportMode mode) - { - switch (mode) { - case ImportAsRegion: - /* relax, its been done */ - break; +Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, jack_nframes_t& pos, ImportMode mode) +{ + AudioRegion* copy; + + switch (mode) { + case ImportAsRegion: + /* relax, its been done */ + break; case ImportToTrack: if (track) { - Playlist* playlist = track->disk_stream().playlist(); + Playlist* playlist = track->diskstream().playlist(); AudioRegion* copy = new AudioRegion (region); begin_reversible_command (_("insert sndfile")); @@ -329,11 +331,21 @@ int break; case ImportAsTrack: - AudioTrack* at = session->new_audio_track (in_chans, out_chans); - AudioRegion* copy = new AudioRegion (region); - at->disk_stream().playlist()->add_region (*copy, pos); + { + boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Normal)); + copy = new AudioRegion (region); + at->diskstream().playlist()->add_region (*copy, pos); + break; + } + + case ImportAsTapeTrack: + { + boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Destructive)); + copy = new AudioRegion (region); + at->diskstream().playlist()->add_region (*copy, pos); break; } + } return 0; } diff --git a/gtk2_ardour/editor_audiotrack.cc b/gtk2_ardour/editor_audiotrack.cc index acad3371a0..5b575b4814 100644 --- a/gtk2_ardour/editor_audiotrack.cc +++ b/gtk2_ardour/editor_audiotrack.cc @@ -4,7 +4,7 @@ #include "editor.h" #include "editing.h" #include "audio_time_axis.h" -#include "regionview.h" +#include "region_view.h" #include "selection.h" using namespace ARDOUR; diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 41350a1da4..e8ba2b8a60 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -128,7 +128,7 @@ Editor::initialize_canvas () time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0); 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); diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 43114534c5..8e635bbe13 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -26,8 +26,8 @@ #include "editor.h" #include "public_editor.h" -#include "regionview.h" -#include "streamview.h" +#include "audio_region_view.h" +#include "audio_streamview.h" #include "crossfade_view.h" #include "audio_time_axis.h" #include "region_gain_line.h" @@ -212,7 +212,7 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) } bool -Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) +Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv) { gint ret = FALSE; @@ -251,7 +251,7 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud } bool -Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv) +Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv) { bool ret = FALSE; @@ -262,7 +262,7 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud clicked_regionview = 0; clicked_control_point = 0; clicked_trackview = tv; - clicked_audio_trackview = tv; + clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(tv); ret = button_press_handler (item, event, StreamItem); break; @@ -512,22 +512,25 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) { if (atv->is_audio_track()) { - - AudioPlaylist* pl = atv->get_diskstream()->playlist(); - Playlist::RegionList* rl = pl->regions_at (event_frame (event)); - if (!rl->empty()) { - DescendingRegionLayerSorter cmp; - rl->sort (cmp); + AudioPlaylist* pl; + if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) { + + Playlist::RegionList* rl = pl->regions_at (event_frame (event)); + + if (!rl->empty()) { + DescendingRegionLayerSorter cmp; + rl->sort (cmp); - AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front()))); + RegionView* rv = atv->view()->find_view (*rl->front()); - /* proxy */ - - delete rl; + /* proxy */ - return canvas_region_view_event (event, arv->get_canvas_group(), arv); - } + delete rl; + + return canvas_region_view_event (event, rv->get_canvas_group(), rv); + } + } } } @@ -696,7 +699,7 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it bool -Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv) +Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv) { bool ret = false; @@ -708,20 +711,20 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas:: clicked_control_point = 0; clicked_trackview = &clicked_regionview->get_time_axis_view(); clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview); - ret = button_press_handler (item, event, AudioRegionViewNameHighlight); + ret = button_press_handler (item, event, RegionViewNameHighlight); break; case GDK_BUTTON_RELEASE: - ret = button_release_handler (item, event, AudioRegionViewNameHighlight); + ret = button_release_handler (item, event, RegionViewNameHighlight); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, AudioRegionViewNameHighlight); + ret = motion_handler (item, event, RegionViewNameHighlight); break; case GDK_ENTER_NOTIFY: - ret = enter_handler (item, event, AudioRegionViewNameHighlight); + ret = enter_handler (item, event, RegionViewNameHighlight); break; case GDK_LEAVE_NOTIFY: - ret = leave_handler (item, event, AudioRegionViewNameHighlight); + ret = leave_handler (item, event, RegionViewNameHighlight); break; default: @@ -732,7 +735,7 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas:: } bool -Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv) +Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv) { bool ret = false; @@ -744,20 +747,20 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item clicked_control_point = 0; clicked_trackview = &clicked_regionview->get_time_axis_view(); clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview); - ret = button_press_handler (item, event, AudioRegionViewName); + ret = button_press_handler (item, event, RegionViewName); break; case GDK_BUTTON_RELEASE: - ret = button_release_handler (item, event, AudioRegionViewName); + ret = button_release_handler (item, event, RegionViewName); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, AudioRegionViewName); + ret = motion_handler (item, event, RegionViewName); break; case GDK_ENTER_NOTIFY: - ret = enter_handler (item, event, AudioRegionViewName); + ret = enter_handler (item, event, RegionViewName); break; case GDK_LEAVE_NOTIFY: - ret = leave_handler (item, event, AudioRegionViewName); + ret = leave_handler (item, event, RegionViewName); break; default: diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc index 7339536e42..46a704b435 100644 --- a/gtk2_ardour/editor_export_audio.cc +++ b/gtk2_ardour/editor_export_audio.cc @@ -31,7 +31,7 @@ #include "selection.h" #include "time_axis_view.h" #include "audio_time_axis.h" -#include "regionview.h" +#include "audio_region_view.h" #include <pbd/pthread_utils.h> #include <ardour/types.h> @@ -92,12 +92,12 @@ Editor::export_region () return; } - ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region); + ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region()); dialog->connect_to_session (session); dialog->set_range ( - clicked_regionview->region.first_frame(), - clicked_regionview->region.last_frame()); + clicked_regionview->region().first_frame(), + clicked_regionview->region().last_frame()); dialog->start_export(); } @@ -123,24 +123,26 @@ Editor::export_range_markers () } int -Editor::write_region_selection (AudioRegionSelection& regions) +Editor::write_region_selection (RegionSelection& regions) { - for (AudioRegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { - if (write_region ("", (*i)->region) == false) { - return -1; - } + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + if (write_region ("", arv->audio_region()) == false) + return -1; } + return 0; } void Editor::bounce_region_selection () { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - AudioRegion& region ((*i)->region); - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&(*i)->get_time_axis_view()); - AudioTrack* track = dynamic_cast<AudioTrack*>(&(atv->route())); + Region& region ((*i)->region()); + RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view()); + Track* track = dynamic_cast<Track*>(rtv->route().get()); InterThreadInfo itt; @@ -287,7 +289,7 @@ Editor::write_audio_selection (TimeSelection& ts) if (atv->is_audio_track()) { - Playlist* playlist = atv->get_diskstream()->playlist(); + AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist()); if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) { ret = -1; @@ -300,7 +302,7 @@ Editor::write_audio_selection (TimeSelection& ts) } bool -Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range) +Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<AudioRange>& range) { AudioFileSource* fs; const jack_nframes_t chunk_size = 4096; @@ -435,7 +437,7 @@ Editor::write_selection () { if (!selection->time.empty()) { write_audio_selection (selection->time); - } else if (!selection->audio_regions.empty()) { - write_region_selection (selection->audio_regions); + } else if (!selection->regions.empty()) { + write_region_selection (selection->regions); } } diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h index 4f6010ec2c..7f3a0d3fcc 100644 --- a/gtk2_ardour/editor_items.h +++ b/gtk2_ardour/editor_items.h @@ -23,8 +23,8 @@ enum ItemType { TempoMarkerItem, MeterBarItem, TempoBarItem, - AudioRegionViewNameHighlight, - AudioRegionViewName, + RegionViewNameHighlight, + RegionViewName, StartSelectionTrimItem, EndSelectionTrimItem, AutomationTrackItem, diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc index b665f8b0a6..a0368b23b0 100644 --- a/gtk2_ardour/editor_keyboard.cc +++ b/gtk2_ardour/editor_keyboard.cc @@ -23,7 +23,7 @@ #include <pbd/memento_command.h> #include "editor.h" -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "i18n.h" @@ -82,10 +82,10 @@ Editor::kbd_do_split (GdkEvent* ev) jack_nframes_t where = event_frame (ev); if (entered_regionview) { - if (selection->audio_regions.find (entered_regionview) != selection->audio_regions.end()) { - split_regions_at (where, selection->audio_regions); + if (selection->regions.find (entered_regionview) != selection->regions.end()) { + split_regions_at (where, selection->regions); } else { - AudioRegionSelection s; + RegionSelection s; s.add (entered_regionview); split_regions_at (where, s); } @@ -103,11 +103,11 @@ Editor::kbd_mute_unmute_region () { if (entered_regionview) { begin_reversible_command (_("mute region")); - XMLNode &before = entered_regionview->region.playlist()->get_state(); + XMLNode &before = entered_regionview->region().playlist()->get_state(); - entered_regionview->region.set_muted (!entered_regionview->region.muted()); + entered_regionview->region().set_muted (!entered_regionview->region().muted()); - XMLNode &after = entered_regionview->region.playlist()->get_state(); + XMLNode &after = entered_regionview->region().playlist()->get_state(); session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region.playlist()), before, after)); commit_reversible_command(); } @@ -126,7 +126,7 @@ Editor::kbd_do_set_sync_position (GdkEvent* ev) snap_to (where); if (entered_regionview) { - set_a_regions_sync_position (entered_regionview->region, where); + set_a_regions_sync_position (entered_regionview->region(), where); } } diff --git a/gtk2_ardour/editor_keys.cc b/gtk2_ardour/editor_keys.cc index baa158cbf8..1bcaafd279 100644 --- a/gtk2_ardour/editor_keys.cc +++ b/gtk2_ardour/editor_keys.cc @@ -30,7 +30,7 @@ #include "ardour_ui.h" #include "editor.h" #include "time_axis_view.h" -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "i18n.h" @@ -66,7 +66,7 @@ Editor::keyboard_selection_begin () void Editor::keyboard_duplicate_region () { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } @@ -74,9 +74,9 @@ Editor::keyboard_duplicate_region () bool was_floating; if (get_prefix (prefix, was_floating) == 0) { - duplicate_some_regions (selection->audio_regions, prefix); + duplicate_some_regions (selection->regions, prefix); } else { - duplicate_some_regions (selection->audio_regions, 1); + duplicate_some_regions (selection->regions, 1); } } diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index c4d8f3143f..ccc1415888 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -717,9 +717,9 @@ Editor::marker_menu_set_from_selection () } } else { - if (!selection->audio_regions.empty()) { - l->set_start (selection->audio_regions.start()); - l->set_end (selection->audio_regions.end_frame()); + if (!selection->regions.empty()) { + l->set_start (selection->regions.start()); + l->set_end (selection->regions.end_frame()); } } } diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index a55b6f2066..246dbdc647 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -131,7 +131,7 @@ Editor::set_selected_mixer_strip (TimeAxisView& view) /* might be nothing to do */ - if (¤t_mixer_strip->route() == &at->route()) { + if (current_mixer_strip->route() == at->route()) { return; } @@ -221,7 +221,7 @@ Editor::current_mixer_strip_hidden () AudioTimeAxisView* tmp; if ((tmp = dynamic_cast<AudioTimeAxisView*>(*i)) != 0) { - if (&(tmp->route()) == &(current_mixer_strip->route())) { + if (tmp->route() == current_mixer_strip->route()) { (*i)->set_selected (false); break; } @@ -270,8 +270,6 @@ Editor::session_going_away () group_model->clear (); edit_cursor_clock.set_session (0); - selection_start_clock.set_session (0); - selection_end_clock.set_session (0); zoom_range_clock.set_session (0); nudge_clock.set_session (0); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index c7199984a8..f7abe7fdea 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -18,6 +18,7 @@ $Id$ */ +#include <cassert> #include <cstdlib> #include <stdint.h> #include <cmath> @@ -33,7 +34,7 @@ #include "editor.h" #include "time_axis_view.h" #include "audio_time_axis.h" -#include "regionview.h" +#include "audio_region_view.h" #include "marker.h" #include "streamview.h" #include "region_gain_line.h" @@ -183,7 +184,7 @@ Editor::set_mouse_mode (MouseMode m, bool force) show the object (region) selection. */ - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { (*i)->set_should_show_selection (true); } for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { @@ -320,8 +321,8 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it commit = (c1 || c2); break; - case AudioRegionViewNameHighlight: - case AudioRegionViewName: + case RegionViewNameHighlight: + case RegionViewName: c1 = set_selected_track_from_click (press, op, true, true); c2 = set_selected_regionview_from_click (press, op, true); commit = (c1 || c2); @@ -522,12 +523,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp } break; - case AudioRegionViewNameHighlight: + case RegionViewNameHighlight: start_trim (item, event); return true; break; - case AudioRegionViewName: + case RegionViewName: /* rename happens on edit clicks */ start_trim (clicked_regionview->get_name_highlight(), event); return true; @@ -693,12 +694,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp switch (item_type) { - case AudioRegionViewNameHighlight: + case RegionViewNameHighlight: start_trim (item, event); return true; break; - case AudioRegionViewName: + case RegionViewName: start_trim (clicked_regionview->get_name_highlight(), event); return true; break; @@ -854,7 +855,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT edit_meter_marker (item); break; - case AudioRegionViewName: + case RegionViewName: if (clicked_regionview->name_active()) { return mouse_rename_region (item, event); } @@ -889,8 +890,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case RegionItem: - case AudioRegionViewNameHighlight: - case AudioRegionViewName: + case RegionViewNameHighlight: + case RegionViewName: popup_track_context_menu (1, event->button.time, item_type, false, where); break; @@ -1048,9 +1049,13 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case MouseGain: + // Gain only makes sense for audio regions + if ( ! dynamic_cast<AudioRegionView*>(clicked_regionview)) + break; + switch (item_type) { case RegionItem: - clicked_regionview->add_gain_point_event (item, event); + dynamic_cast<AudioRegionView*>(clicked_regionview)->add_gain_point_event (item, event); return true; break; @@ -1204,7 +1209,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ } break; - case AudioRegionViewNameHighlight: + case RegionViewNameHighlight: if (is_drawable() && mouse_mode == MouseObject) { track_canvas.get_window()->set_cursor (*trimmer_cursor); } @@ -1231,11 +1236,11 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ } break; - case AudioRegionViewName: + case RegionViewName: /* when the name is not an active item, the entire name highlight is for trimming */ - if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) { + if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) { if (mouse_mode == MouseObject && is_drawable()) { track_canvas.get_window()->set_cursor (*trimmer_cursor); } @@ -1340,7 +1345,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ ControlPoint* cp; Marker *marker; Location *loc; - AudioRegionView* rv; + RegionView* rv; bool is_start; switch (item_type) { @@ -1362,7 +1367,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ hide_verbose_canvas_cursor (); break; - case AudioRegionViewNameHighlight: + case RegionViewNameHighlight: case StartSelectionTrimItem: case EndSelectionTrimItem: case EditCursorItem: @@ -1393,9 +1398,9 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ } break; - case AudioRegionViewName: + case RegionViewName: /* see enter_handler() for notes */ - if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) { + 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); } @@ -1430,7 +1435,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case FadeInHandleItem: case FadeOutHandleItem: - rv = static_cast<AudioRegionView*>(item->get_data ("regionview")); + rv = static_cast<RegionView*>(item->get_data ("regionview")); { ArdourCanvas::SimpleRect *rect = dynamic_cast<ArdourCanvas::SimpleRect *> (item); if (rect) { @@ -1525,7 +1530,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item case PanAutomationControlPointItem: case TempoMarkerItem: case MeterMarkerItem: - case AudioRegionViewNameHighlight: + case RegionViewNameHighlight: case StartSelectionTrimItem: case EndSelectionTrimItem: case SelectionItem: @@ -1746,7 +1751,7 @@ Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event) AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data); - drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->region.fade_in().back()->when + arv->region.position()); + drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->audio_region().fade_in().back()->when + arv->region().position()); } void @@ -1767,17 +1772,17 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) snap_to (pos); } - if (pos < (arv->region.position() + 64)) { + if (pos < (arv->region().position() + 64)) { fade_length = 64; // this should be a minimum defined somewhere - } else if (pos > arv->region.last_frame()) { - fade_length = arv->region.length(); + } else if (pos > arv->region().last_frame()) { + fade_length = arv->region().length(); } else { - fade_length = pos - arv->region.position(); + fade_length = pos - arv->region().position(); } arv->reset_fade_in_shape_width (fade_length); - show_verbose_duration_cursor (arv->region.position(), arv->region.position() + fade_length, 10); + show_verbose_duration_cursor (arv->region().position(), arv->region().position() + fade_length, 10); drag_info.first_move = false; } @@ -1802,23 +1807,23 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even snap_to (pos); } - if (pos < (arv->region.position() + 64)) { + if (pos < (arv->region().position() + 64)) { fade_length = 64; // this should be a minimum defined somewhere } - else if (pos > arv->region.last_frame()) { - fade_length = arv->region.length(); + else if (pos > arv->region().last_frame()) { + fade_length = arv->region().length(); } else { - fade_length = pos - arv->region.position(); + fade_length = pos - arv->region().position(); } begin_reversible_command (_("change fade in length")); - XMLNode &before = arv->region.get_state(); + XMLNode &before = arv->audio_region().get_state(); - arv->region.set_fade_in_length (fade_length); + arv->audio_region().set_fade_in_length (fade_length); - XMLNode &after = arv->region.get_state(); - session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region, + XMLNode &after = arv->audio_region().get_state(); + session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->audio_regio(), before, after)); commit_reversible_command (); @@ -1841,7 +1846,7 @@ Editor::start_fade_out_grab (ArdourCanvas::Item* item, GdkEvent* event) AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data); - drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region.length() - (jack_nframes_t) arv->region.fade_out().back()->when + arv->region.position()); + drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region().length() - (jack_nframes_t) arv->audio_region().fade_out().back()->when + arv->region().position()); } void @@ -1862,19 +1867,19 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event snap_to (pos); } - if (pos > (arv->region.last_frame() - 64)) { + if (pos > (arv->region().last_frame() - 64)) { fade_length = 64; // this should really be a minimum fade defined somewhere } - else if (pos < arv->region.position()) { - fade_length = arv->region.length(); + else if (pos < arv->region().position()) { + fade_length = arv->region().length(); } else { - fade_length = arv->region.last_frame() - pos; + fade_length = arv->region().last_frame() - pos; } arv->reset_fade_out_shape_width (fade_length); - show_verbose_duration_cursor (arv->region.last_frame() - fade_length, arv->region.last_frame(), 10); + show_verbose_duration_cursor (arv->region().last_frame() - fade_length, arv->region().last_frame(), 10); drag_info.first_move = false; } @@ -1899,23 +1904,23 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve snap_to (pos); } - if (pos > (arv->region.last_frame() - 64)) { + if (pos > (arv->region().last_frame() - 64)) { fade_length = 64; // this should really be a minimum fade defined somewhere } - else if (pos < arv->region.position()) { - fade_length = arv->region.length(); + else if (pos < arv->region().position()) { + fade_length = arv->region().length(); } else { - fade_length = arv->region.last_frame() - pos; + fade_length = arv->region().last_frame() - pos; } begin_reversible_command (_("change fade out length")); - XMLNode &before = arv->region.get_state(); + XMLNode &before = arv->region().get_state(); - arv->region.set_fade_out_length (fade_length); + arv->audio_region().set_fade_out_length (fade_length); - XMLNode &after = arv->region.get_state(); - session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region, before, after)); + XMLNode &after = arv->region().get_state(); + session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region(), before, after)); commit_reversible_command (); fade_out_drag_motion_callback (item, event); @@ -2038,7 +2043,7 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event) drag_info.copied_location = new Location (*location); drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end()); - + update_marker_drag_item (location); if (location->is_mark()) { @@ -2097,31 +2102,39 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) move_both = true; } - if (is_start) { // start marker + if (copy_location->is_mark()) { + /* just move it */ - if (move_both) { - copy_location->set_start (newframe); - copy_location->set_end (newframe + f_delta); - } else if (newframe < copy_location->end()) { - copy_location->set_start (newframe); - } else { - snap_to (next, 1, true); - copy_location->set_end (next); - copy_location->set_start (newframe); - } + copy_location->set_start (newframe); - } else { // end marker + } else { - if (move_both) { - copy_location->set_end (newframe); - copy_location->set_start (newframe - f_delta); - } else if (newframe > copy_location->start()) { - copy_location->set_end (newframe); + if (is_start) { // start-of-range marker - } else if (newframe > 0) { - snap_to (next, -1, true); - copy_location->set_start (next); - copy_location->set_end (newframe); + if (move_both) { + copy_location->set_start (newframe); + copy_location->set_end (newframe + f_delta); + } else if (newframe < copy_location->end()) { + copy_location->set_start (newframe); + } else { + snap_to (next, 1, true); + copy_location->set_end (next); + copy_location->set_start (newframe); + } + + } else { // end marker + + if (move_both) { + copy_location->set_end (newframe); + copy_location->set_start (newframe - f_delta); + } else if (newframe > copy_location->start()) { + copy_location->set_end (newframe); + + } else if (newframe > 0) { + snap_to (next, -1, true); + copy_location->set_start (next); + copy_location->set_end (newframe); + } } } @@ -2154,7 +2167,11 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event Location * location = find_location_from_marker (marker, is_start); if (location) { - location->set (drag_info.copied_location->start(), drag_info.copied_location->end()); + if (location->is_mark()) { + location->set_start (drag_info.copied_location->start()); + } else { + location->set (drag_info.copied_location->start(), drag_info.copied_location->end()); + } } XMLNode &after = session->locations()->get_state(); @@ -2553,7 +2570,8 @@ Editor::start_line_grab_from_regionview (ArdourCanvas::Item* item, GdkEvent* eve { switch (mouse_mode) { case MouseGain: - start_line_grab (clicked_regionview->get_gain_line(), event); + assert(dynamic_cast<AudioRegionView*>(clicked_regionview)); + start_line_grab (dynamic_cast<AudioRegionView*>(clicked_regionview)->get_gain_line(), event); break; default: break; @@ -2647,7 +2665,7 @@ Editor::line_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) void Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) { - if (selection->audio_regions.empty() || clicked_regionview == 0) { + if (selection->regions.empty() || clicked_regionview == 0) { return; } @@ -2661,13 +2679,13 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); if (tv && tv->is_audio_track()) { speed = tv->get_diskstream()->speed(); } - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed); + drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); // we want a move threshold @@ -2681,7 +2699,7 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) { - if (selection->audio_regions.empty() || clicked_regionview == 0) { + if (selection->regions.empty() || clicked_regionview == 0) { return; } @@ -2692,7 +2710,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab(event); TimeAxisView* tv = &clicked_regionview->get_time_axis_view(); - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(tv); + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(tv); double speed = 1.0; if (atv && atv->is_audio_track()) { @@ -2700,7 +2718,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) } drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed); + drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; // we want a move threshold drag_info.want_move_threshold = true; @@ -2711,7 +2729,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) { - if (selection->audio_regions.empty() || clicked_regionview == 0) { + if (selection->regions.empty() || clicked_regionview == 0) { return; } @@ -2725,13 +2743,13 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); if (tv && tv->is_audio_track()) { speed = tv->get_diskstream()->speed(); } - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed); + drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); // we want a move threshold @@ -2746,7 +2764,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { double x_delta; double y_delta = 0; - AudioRegionView *rv = reinterpret_cast<AudioRegionView*> (drag_info.data); + RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data); jack_nframes_t pending_region_position = 0; int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen @@ -2766,18 +2784,18 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* duplicate the region(s) */ - vector<AudioRegionView*> new_regionviews; + vector<RegionView*> new_regionviews; set<Playlist*> affected_playlists; pair<set<Playlist*>::iterator,bool> insert_result; - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { - AudioRegionView* rv; + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { + RegionView* rv; rv = (*i); - Playlist* to_playlist = rv->region.playlist(); - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view()); + Playlist* to_playlist = rv->region().playlist(); + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view()); insert_result = affected_playlists.insert (to_playlist); if (insert_result.second) { @@ -2786,18 +2804,21 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) latest_regionview = 0; - sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); - - /* create a new region with the same name. - */ + sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); - AudioRegion* newregion = new AudioRegion (rv->region); + /* create a new region with the same name. */ + // FIXME: ew. need a (virtual) Region::duplicate() or something? + Region* newregion = NULL; + if (dynamic_cast<AudioRegion*>(&rv->region())) + newregion = new AudioRegion (dynamic_cast<AudioRegion&>(rv->region())); + assert(newregion); + /* if the original region was locked, we don't care */ newregion->set_locked (false); - to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region.position() * atv->get_diskstream()->speed())); + to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * atv->get_diskstream()->speed())); c.disconnect (); @@ -2909,16 +2930,15 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } } - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { - AudioRegionView* rv2; - rv2 = (*i); + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { + RegionView* rv2 = (*i); double ix1, ix2, iy1, iy2; int32_t n = 0; rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv2->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2); + RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2); if (atv2->order != original_pointer_order) { /* this isn't the pointer track */ @@ -3013,8 +3033,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - sync_offset = rv->region.sync_offset (sync_dir); - sync_frame = rv->region.adjust_to_sync (pending_region_position); + sync_offset = rv->region().sync_offset (sync_dir); + sync_frame = rv->region().adjust_to_sync (pending_region_position); /* we snap if the snap modifier is not enabled. */ @@ -3033,7 +3053,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) pending_region_position = 0; } - if (pending_region_position > max_frames - rv->region.length()) { + if (pending_region_position > max_frames - rv->region().length()) { pending_region_position = drag_info.last_frame_position; } @@ -3075,14 +3095,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } if (x_delta < 0) { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - AudioRegionView* rv2; - rv2 = (*i); + RegionView* rv2 = (*i); - /* if any regionview is at zero, we need to know so we can - stop further leftward motion. - */ + // If any regionview is at zero, we need to know so we can stop further leftward motion. double ix1, ix2, iy1, iy2; rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); @@ -3100,12 +3117,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) ************************************************************/ pair<set<Playlist*>::iterator,bool> insert_result; - const list<AudioRegionView*>& layered_regions = selection->audio_regions.by_layer(); + const list<RegionView*>& layered_regions = selection->regions.by_layer(); - for (list<AudioRegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) { + for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) { - AudioRegionView* rv; - rv = (*i); + RegionView* rv = (*i); double ix1, ix2, iy1, iy2; int32_t temp_pointer_y_span = pointer_y_span; @@ -3186,8 +3202,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (-x_delta > ix1) { x_delta = -ix1; } - } else if ((x_delta > 0) &&(rv->region.last_frame() > max_frames - x_delta)) { - x_delta = max_frames - rv->region.last_frame(); + } else if ((x_delta > 0) &&(rv->region().last_frame() > max_frames - x_delta)) { + x_delta = max_frames - rv->region().last_frame(); } if (drag_info.first_move) { @@ -3212,7 +3228,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view()); if (atv && atv->is_audio_track()) { - AudioPlaylist* pl = atv->get_diskstream()->playlist(); + AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist()); if (pl) { /* only freeze and capture state once */ @@ -3248,11 +3264,11 @@ void Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) { jack_nframes_t where; - AudioRegionView* rv = reinterpret_cast<AudioRegionView *> (drag_info.data); + RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data); pair<set<Playlist*>::iterator,bool> insert_result; bool nocommit = true; double speed; - AudioTimeAxisView* atv; + RouteTimeAxisView* atv; bool regionview_y_movement; bool regionview_x_movement; @@ -3286,7 +3302,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event speed = atv->get_diskstream()->speed(); } - regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region.position()/speed)); + regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region().position()/speed)); regionview_y_movement = (drag_info.last_trackview != &rv->get_time_axis_view()); //printf ("last_frame: %s position is %lu %g\n", rv->get_time_axis_view().name().c_str(), drag_info.last_frame_position, speed); @@ -3296,13 +3312,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* motion between tracks */ - list<AudioRegionView*> new_selection; + list<RegionView*> new_selection; /* moved to a different audio track. */ - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ) { + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) { - AudioRegionView* rv2 = (*i); + RegionView* rv2 = (*i); /* the region that used to be in the old playlist is not moved to the new one - we make a copy of it. as a result, @@ -3319,7 +3335,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* first, freeze the target tracks */ - for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { + for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { Playlist* from_playlist; Playlist* to_playlist; @@ -3331,7 +3347,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event TimeAxisView* tvp2 = trackview_by_y_position (iy1); AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2); - from_playlist = (*i)->region.playlist(); + from_playlist = (*i)->region().playlist(); to_playlist = atv2->playlist(); /* the from_playlist was frozen in the "first_move" case @@ -3354,7 +3370,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* now do it again with the actual operations */ - for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { + for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { Playlist* from_playlist; Playlist* to_playlist; @@ -3366,17 +3382,17 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event TimeAxisView* tvp2 = trackview_by_y_position (iy1); AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2); - from_playlist = (*i)->region.playlist(); + from_playlist = (*i)->region().playlist(); to_playlist = atv2->playlist(); latest_regionview = 0; where = (jack_nframes_t) (unit_to_frame (ix1) * speed); - Region* new_region = createRegion ((*i)->region); + Region* new_region = createRegion ((*i)->region()); - from_playlist->remove_region (&((*i)->region)); + from_playlist->remove_region (&((*i)->region())); - sigc::connection c = atv2->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + sigc::connection c = atv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); to_playlist->add_region (*new_region, where); c.disconnect (); @@ -3389,11 +3405,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event /* motion within a single track */ - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { rv = (*i); - if (rv->region.locked()) { + if (rv->region().locked()) { continue; } @@ -3415,14 +3431,14 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event } else { - where = rv->region.position(); + where = rv->region().position(); } rv->get_time_axis_view().reveal_dependent_views (*rv); /* no need to add an undo here, we did that when we added this playlist to motion_frozen playlists */ - rv->region.set_position (where, (void *) this); + rv->region().set_position (where, (void *) this); } } @@ -3456,15 +3472,15 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) { - align_region (rv.region, SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed)); } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { - align_region (rv.region, End, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), End, (jack_nframes_t) (edit_cursor->current_frame * speed)); } else { - align_region (rv.region, Start, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), Start, (jack_nframes_t) (edit_cursor->current_frame * speed)); } } } @@ -3581,7 +3597,7 @@ Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, } void -Editor::collect_new_region_view (AudioRegionView* rv) +Editor::collect_new_region_view (RegionView* rv) { latest_regionview = rv; } @@ -3614,7 +3630,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) */ latest_regionview = 0; - sigc::connection c = clicked_audio_trackview->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + sigc::connection c = clicked_audio_trackview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); /* A selection grab currently creates two undo/redo operations, one for creating the new region and another for moving it. @@ -3650,7 +3666,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event); drag_info.last_trackview = clicked_trackview; - drag_info.last_frame_position = latest_regionview->region.position(); + drag_info.last_frame_position = latest_regionview->region().position(); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; show_verbose_time_cursor (drag_info.last_frame_position, 10); @@ -3891,9 +3907,9 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event) speed = tv->get_diskstream()->speed(); } - jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region.position() / speed); - jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region.last_frame() / speed); - jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region.length() / speed); + jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region().position() / speed); + jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region().last_frame() / speed); + jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region().length() / speed); motion_frozen_playlists.clear(); @@ -3933,7 +3949,7 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event) void Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { - AudioRegionView* rv = clicked_regionview; + RegionView* rv = clicked_regionview; jack_nframes_t frame_delta = 0; bool left_direction; bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()); @@ -3945,7 +3961,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); pair<set<Playlist*>::iterator,bool> insert_result; if (tv && tv->is_audio_track()) { @@ -3984,11 +4000,14 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) begin_reversible_command (trim_type); - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { - (*i)->region.freeze (); - (*i)->temporarily_hide_envelope (); + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { + (*i)->region().freeze (); + + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + arv->temporarily_hide_envelope (); - Playlist * pl = (*i)->region.playlist(); + Playlist * pl = (*i)->region().playlist(); insert_result = motion_frozen_playlists.insert (pl); if (insert_result.second) { session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state())); @@ -4004,20 +4023,20 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) switch (trim_op) { case StartTrim: - if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region.first_frame()/speed)) { + if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region().first_frame()/speed)) { break; } else { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { single_start_trim (**i, frame_delta, left_direction, obey_snap); } break; } case EndTrim: - if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region.last_frame()/speed))) { + if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region().last_frame()/speed))) { break; } else { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) { + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { single_end_trim (**i, frame_delta, left_direction, obey_snap); } break; @@ -4031,8 +4050,8 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) swap_direction = true; } - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); - i != selection->audio_regions.by_layer().end(); ++i) + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); + i != selection->regions.by_layer().end(); ++i) { single_contents_trim (**i, frame_delta, left_direction, swap_direction, obey_snap); } @@ -4042,10 +4061,10 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) switch (trim_op) { case StartTrim: - show_verbose_time_cursor((jack_nframes_t) (rv->region.position()/speed), 10); + show_verbose_time_cursor((jack_nframes_t) (rv->region().position()/speed), 10); break; case EndTrim: - show_verbose_time_cursor((jack_nframes_t) (rv->region.last_frame()/speed), 10); + show_verbose_time_cursor((jack_nframes_t) (rv->region().last_frame()/speed), 10); break; case ContentsTrim: show_verbose_time_cursor(drag_info.current_pointer_frame, 10); @@ -4057,9 +4076,9 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap) +Editor::single_contents_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap) { - Region& region (rv.region); + Region& region (rv.region()); if (region.locked()) { return; @@ -4069,7 +4088,7 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b double speed = 1.0; TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp); + RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); if (tv && tv->is_audio_track()) { speed = tv->get_diskstream()->speed(); @@ -4097,9 +4116,9 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b } void -Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) +Editor::single_start_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) { - Region& region (rv.region); + Region& region (rv.region()); if (region.locked()) { return; @@ -4131,9 +4150,9 @@ Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool } void -Editor::single_end_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) +Editor::single_end_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) { - Region& region (rv.region); + Region& region (rv.region()); if (region.locked()) { return; @@ -4172,8 +4191,8 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) thaw_region_after_trim (*clicked_regionview); } else { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); - i != selection->audio_regions.by_layer().end(); ++i) + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); + i != selection->regions.by_layer().end(); ++i) { thaw_region_after_trim (**i); } @@ -4196,7 +4215,7 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) void Editor::point_trim (GdkEvent* event) { - AudioRegionView* rv = clicked_regionview; + RegionView* rv = clicked_regionview; jack_nframes_t new_bound = drag_info.current_pointer_frame; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { @@ -4211,13 +4230,13 @@ Editor::point_trim (GdkEvent* event) if (rv->get_selected()) { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); - i != selection->audio_regions.by_layer().end(); ++i) + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); + i != selection->regions.by_layer().end(); ++i) { - if (!(*i)->region.locked()) { + if (!(*i)->region().locked()) { Playlist *pl = (*i)->region.playlist(); XMLNode &before = pl->get_state(); - (*i)->region.trim_front (new_bound, this); + (*i)->region().trim_front (new_bound, this); XMLNode &after = pl->get_state(); session->add_command(new MementoCommand<Playlist>(*pl, before, after)); } @@ -4225,10 +4244,10 @@ Editor::point_trim (GdkEvent* event) } else { - if (!rv->region.locked()) { - Playlist *pl = rv->region.playlist(); + if (!rv->region().locked()) { + Playlist *pl = rv->region().playlist(); XMLNode &before = pl->get_state(); - rv->region.trim_front (new_bound, this); + rv->region().trim_front (new_bound, this); XMLNode &after = pl->get_state(); session->add_command(new MementoCommand<Playlist>(*pl, before, after)); } @@ -4243,12 +4262,12 @@ Editor::point_trim (GdkEvent* event) if (rv->get_selected()) { - for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) + for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - if (!(*i)->region.locked()) { - Playlist *pl = (*i)->region.playlist(); + if (!(*i)->region().locked()) { + Playlist *pl = (*i)->region().playlist(); XMLNode &before = pl->get_state(); - (*i)->region.trim_end (new_bound, this); + (*i)->region().trim_end (new_bound, this); XMLNode &after = pl->get_state(); session->add_command(new MementoCommand<Playlist>(*pl, before, after)); } @@ -4256,10 +4275,10 @@ Editor::point_trim (GdkEvent* event) } else { - if (!rv->region.locked()) { - Playlist *pl = rv->region.playlist(); + if (!rv->region().locked()) { + Playlist *pl = rv->region().playlist(); XMLNode &before = pl->get_state(); - rv->region.trim_end (new_bound, this); + rv->region().trim_end (new_bound, this); XMLNode &after = pl->get_state(); session->add_command (new MementoCommand<Playlist>(*pl, before, after)); } @@ -4274,9 +4293,9 @@ Editor::point_trim (GdkEvent* event) } void -Editor::thaw_region_after_trim (AudioRegionView& rv) +Editor::thaw_region_after_trim (RegionView& rv) { - Region& region (rv.region); + Region& region (rv.region()); if (region.locked()) { return; @@ -4286,7 +4305,9 @@ Editor::thaw_region_after_trim (AudioRegionView& rv) XMLNode &after = region.playlist()->get_state(); session->add_command (new MementoRedoCommand<Playlist>(*(region.playlist()), after)); - rv.unhide_envelope (); + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv); + if (arv) + arv->unhide_envelope (); } void @@ -4679,7 +4700,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) } } else { - selection->clear_audio_regions(); + selection->clear_regions(); selection->clear_points (); selection->clear_lines (); } @@ -4696,7 +4717,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event) ArdourPrompter prompter (false); prompter.set_prompt (_("Name for region:")); - prompter.set_initial_text (clicked_regionview->region.name()); + prompter.set_initial_text (clicked_regionview->region().name()); prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT); prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); prompter.show_all (); @@ -4705,7 +4726,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event) string str; prompter.get_result(str); if (str.length()) { - clicked_regionview->region.set_name (str); + clicked_regionview->region().set_name (str); } break; } @@ -4727,7 +4748,7 @@ Editor::start_time_fx (ArdourCanvas::Item* item, GdkEvent* event) void Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event) { - AudioRegionView* rv = clicked_regionview; + RegionView* rv = clicked_regionview; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (drag_info.current_pointer_frame); @@ -4737,8 +4758,8 @@ Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event) return; } - if (drag_info.current_pointer_frame > rv->region.position()) { - rv->get_time_axis_view().show_timestretch (rv->region.position(), drag_info.current_pointer_frame); + if (drag_info.current_pointer_frame > rv->region().position()) { + rv->get_time_axis_view().show_timestretch (rv->region().position(), drag_info.current_pointer_frame); } drag_info.last_pointer_frame = drag_info.current_pointer_frame; @@ -4756,21 +4777,25 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event) return; } - jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region.position(); - float percentage = (float) ((double) newlen - (double) clicked_regionview->region.length()) / ((double) newlen) * 100.0f; + jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region().position(); + float percentage = (float) ((double) newlen - (double) clicked_regionview->region().length()) / ((double) newlen) * 100.0f; begin_reversible_command (_("timestretch")); - if (run_timestretch (selection->audio_regions, percentage) == 0) { + if (run_timestretch (selection->regions, percentage) == 0) { session->commit_reversible_command (); } } void -Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos) +Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos) { /* no brushing without a useful snap setting */ + // FIXME + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv); + assert(arv); + switch (snap_mode) { case SnapMagnetic: return; /* can't work because it allows region to be placed anywhere */ @@ -4790,11 +4815,11 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos) /* don't brush a copy over the original */ - if (pos == rv->region.position()) { + if (pos == rv->region().position()) { return; } - AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view()); + RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&arv->get_time_axis_view()); if (atv == 0 || !atv->is_audio_track()) { return; @@ -4804,7 +4829,7 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos) double speed = atv->get_diskstream()->speed(); XMLNode &before = playlist->get_state(); - playlist->add_region (*(new AudioRegion (rv->region)), (jack_nframes_t) (pos * speed)); + playlist->add_region (*(new AudioRegion (arv->audio_region)), (jack_nframes_t) (pos * speed)); XMLNode &after = playlist->get_state(); session->add_command(new MementoCommand<Playlist>(*playlist, before, after)); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index e9fcc028e6..d98be4f088 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -52,7 +52,7 @@ #include "audio_time_axis.h" #include "automation_time_axis.h" #include "streamview.h" -#include "regionview.h" +#include "audio_region_view.h" #include "rgb_macros.h" #include "selection_templates.h" #include "selection.h" @@ -187,29 +187,31 @@ Editor::split_region () void Editor::split_region_at (jack_nframes_t where) { - split_regions_at (where, selection->audio_regions); + split_regions_at (where, selection->regions); } void -Editor::split_regions_at (jack_nframes_t where, AudioRegionSelection& regions) +Editor::split_regions_at (jack_nframes_t where, RegionSelection& regions) { begin_reversible_command (_("split")); snap_to (where); - for (AudioRegionSelection::iterator a = regions.begin(); a != regions.end(); ) { + for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) { - AudioRegionSelection::iterator tmp; + RegionSelection::iterator tmp; tmp = a; ++tmp; - Playlist* pl = (*a)->region.playlist(); + Playlist* pl = (*a)->region().playlist(); - _new_regionviews_show_envelope = (*a)->envelope_visible(); + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a); + if (arv) + _new_regionviews_show_envelope = arv->envelope_visible(); if (pl) { XMLNode &before = pl->get_state(); - pl->split_region ((*a)->region, where); + pl->split_region ((*a)->region(), where); XMLNode &after = pl->get_state(); session->add_command(new MementoCommand<Playlist>(*pl, before, after)); } @@ -232,7 +234,7 @@ Editor::remove_clicked_region () begin_reversible_command (_("remove region")); XMLNode &before = playlist->get_state(); - playlist->remove_region (&clicked_regionview->region); + playlist->remove_region (&clicked_regionview->region()); XMLNode &after = playlist->get_state(); session->add_command(new MementoCommand<Playlist>(*playlist, before, after)); commit_reversible_command (); @@ -241,7 +243,7 @@ Editor::remove_clicked_region () void Editor::destroy_clicked_region () { - int32_t selected = selection->audio_regions.size(); + int32_t selected = selection->regions.size(); if (!session || clicked_regionview == 0 && selected == 0) { return; @@ -273,29 +275,29 @@ Do you really want to destroy %1 ?"), if (selected > 0) { list<Region*> r; - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - r.push_back (&(*i)->region); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + r.push_back (&(*i)->region()); } session->destroy_regions (r); } else if (clicked_regionview) { - session->destroy_region (&clicked_regionview->region); + session->destroy_region (&clicked_regionview->region()); } } -AudioRegion * +Region * Editor::select_region_for_operation (int dir, TimeAxisView **tv) { - AudioRegionView* rv; - AudioRegion *region; + RegionView* rv; + Region *region; jack_nframes_t start = 0; if (selection->time.start () == selection->time.end_frame ()) { /* no current selection-> is there a selected regionview? */ - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return 0; } @@ -303,26 +305,26 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv) region = 0; - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { - rv = *(selection->audio_regions.begin()); + rv = *(selection->regions.begin()); (*tv) = &rv->get_time_axis_view(); - region = &rv->region; + region = &rv->region(); } else if (!selection->tracks.empty()) { (*tv) = selection->tracks.front(); - AudioTimeAxisView* atv; + RouteTimeAxisView* rtv; - if ((atv = dynamic_cast<AudioTimeAxisView*> (*tv)) != 0) { + if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) { Playlist *pl; - if ((pl = atv->playlist()) == 0) { + if ((pl = rtv->playlist()) == 0) { return 0; } - region = dynamic_cast<AudioRegion*> (pl->top_region_at (start)); + region = pl->top_region_at (start); } } @@ -394,12 +396,12 @@ Editor::nudge_forward (bool next) if (!session) return; - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { begin_reversible_command (_("nudge forward")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - AudioRegion& r ((*i)->region); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + Region& r ((*i)->region()); distance = get_nudge_distance (r.position(), next_distance); @@ -429,12 +431,12 @@ Editor::nudge_backward (bool next) if (!session) return; - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { begin_reversible_command (_("nudge forward")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - AudioRegion& r ((*i)->region); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + Region& r ((*i)->region()); distance = get_nudge_distance (r.position(), next_distance); @@ -474,14 +476,14 @@ Editor::nudge_forward_capture_offset () if (!session) return; - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { begin_reversible_command (_("nudge forward")); distance = session->worst_output_latency(); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - AudioRegion& r ((*i)->region); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + Region& r ((*i)->region()); XMLNode &before = r.playlist()->get_state(); r.set_position (r.position() + distance, this); @@ -501,14 +503,14 @@ Editor::nudge_backward_capture_offset () if (!session) return; - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { begin_reversible_command (_("nudge forward")); distance = session->worst_output_latency(); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - AudioRegion& r ((*i)->region); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + Region& r ((*i)->region()); XMLNode &before = r.playlist()->get_state(); @@ -789,8 +791,8 @@ Editor::cursor_to_selection_start (Cursor *cursor) jack_nframes_t pos = 0; switch (mouse_mode) { case MouseObject: - if (!selection->audio_regions.empty()) { - pos = selection->audio_regions.start(); + if (!selection->regions.empty()) { + pos = selection->regions.start(); } break; @@ -818,8 +820,8 @@ Editor::cursor_to_selection_end (Cursor *cursor) switch (mouse_mode) { case MouseObject: - if (!selection->audio_regions.empty()) { - pos = selection->audio_regions.end_frame(); + if (!selection->regions.empty()) { + pos = selection->regions.end_frame(); } break; @@ -1319,12 +1321,12 @@ Editor::add_location_from_playhead_cursor () void Editor::add_location_from_audio_region () { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } - AudioRegionView* rv = *(selection->audio_regions.begin()); - Region& region = rv->region; + RegionView* rv = *(selection->regions.begin()); + Region& region = rv->region(); Location *location = new Location (region.position(), region.last_frame(), region.name()); session->begin_reversible_command (_("add marker")); @@ -1452,12 +1454,12 @@ Editor::select_all_within (jack_nframes_t start, jack_nframes_t end, double top, void Editor::set_selection_from_audio_region () { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } - AudioRegionView* rv = *(selection->audio_regions.begin()); - Region& region = rv->region; + RegionView* rv = *(selection->regions.begin()); + Region& region = rv->region(); begin_reversible_command (_("set selection from region")); selection->set (0, region.position(), region.last_frame()); @@ -1840,13 +1842,13 @@ Editor::insert_region_list_drag (AudioRegion& region, int x, int y) void Editor::insert_region_list_selection (float times) { - AudioTimeAxisView *tv = 0; + RouteTimeAxisView *tv = 0; Playlist *playlist; if (clicked_audio_trackview != 0) { tv = clicked_audio_trackview; } else if (!selection->tracks.empty()) { - if ((tv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front())) == 0) { + if ((tv = dynamic_cast<RouteTimeAxisView*>(selection->tracks.front())) == 0) { return; } } else { @@ -1941,23 +1943,23 @@ Editor::play_selection () void Editor::play_selected_region () { - if (!selection->audio_regions.empty()) { - AudioRegionView *rv = *(selection->audio_regions.begin()); + if (!selection->regions.empty()) { + RegionView *rv = *(selection->regions.begin()); - session->request_bounded_roll (rv->region.position(), rv->region.last_frame()); + session->request_bounded_roll (rv->region().position(), rv->region().last_frame()); } } void Editor::loop_selected_region () { - if (!selection->audio_regions.empty()) { - AudioRegionView *rv = *(selection->audio_regions.begin()); + if (!selection->regions.empty()) { + RegionView *rv = *(selection->regions.begin()); Location* tll; if ((tll = transport_loop_location()) != 0) { - tll->set (rv->region.position(), rv->region.last_frame()); + tll->set (rv->region().position(), rv->region().last_frame()); // enable looping, reposition and start rolling @@ -2000,10 +2002,10 @@ void Editor::toggle_region_mute () { if (clicked_regionview) { - clicked_regionview->region.set_muted (!clicked_regionview->region.muted()); - } else if (!selection->audio_regions.empty()) { - bool yn = ! (*selection->audio_regions.begin())->region.muted(); - selection->foreach_audio_region (&AudioRegion::set_muted, yn); + clicked_regionview->region().set_muted (!clicked_regionview->region().muted()); + } else if (!selection->regions.empty()) { + bool yn = ! (*selection->regions.begin())->region().muted(); + selection->foreach_region (&Region::set_muted, yn); } } @@ -2011,35 +2013,35 @@ void Editor::toggle_region_opaque () { if (clicked_regionview) { - clicked_regionview->region.set_opaque (!clicked_regionview->region.opaque()); - } else if (!selection->audio_regions.empty()) { - bool yn = ! (*selection->audio_regions.begin())->region.opaque(); - selection->foreach_audio_region (&Region::set_opaque, yn); + clicked_regionview->region().set_opaque (!clicked_regionview->region().opaque()); + } else if (!selection->regions.empty()) { + bool yn = ! (*selection->regions.begin())->region().opaque(); + selection->foreach_region (&Region::set_opaque, yn); } } void Editor::raise_region () { - selection->foreach_audio_region (&Region::raise); + selection->foreach_region (&Region::raise); } void Editor::raise_region_to_top () { - selection->foreach_audio_region (&Region::raise_to_top); + selection->foreach_region (&Region::raise_to_top); } void Editor::lower_region () { - selection->foreach_audio_region (&Region::lower); + selection->foreach_region (&Region::lower); } void Editor::lower_region_to_bottom () { - selection->foreach_audio_region (&Region::lower_to_bottom); + selection->foreach_region (&Region::lower_to_bottom); } void @@ -2060,7 +2062,7 @@ Editor::rename_region () Button ok_button (_("OK")); Button cancel_button (_("Cancel")); - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } @@ -2091,7 +2093,7 @@ Editor::rename_region () Main::run (); if (region_renamed) { - (*selection->audio_regions.begin())->region.set_name (entry.get_text()); + (*selection->regions.begin())->region().set_name (entry.get_text()); redisplay_regions (); } } @@ -2105,7 +2107,7 @@ Editor::rename_region_finished (bool status) } void -Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route) +Editor::audition_playlist_region_via_route (Region& region, Route& route) { if (session->is_auditioning()) { session->cancel_audition (); @@ -2126,14 +2128,14 @@ Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route) void Editor::audition_selected_region () { - if (!selection->audio_regions.empty()) { - AudioRegionView* rv = *(selection->audio_regions.begin()); - session->audition_region (rv->region); + if (!selection->regions.empty()) { + RegionView* rv = *(selection->regions.begin()); + session->audition_region (rv->region()); } } void -Editor::audition_playlist_region_standalone (AudioRegion& region) +Editor::audition_playlist_region_standalone (Region& region) { session->audition_region (region); } @@ -2183,7 +2185,6 @@ Editor::region_from_selection () jack_nframes_t selection_cnt = end - start + 1; for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - AudioRegion *region; AudioRegion *current; Region* current_r; @@ -2200,7 +2201,9 @@ Editor::region_from_selection () continue; } - if ((current = dynamic_cast<AudioRegion*> (current_r)) != 0) { + current = dynamic_cast<AudioRegion*> (current_r); + // FIXME: audio only + if (current != 0) { internal_start = start - current->position(); session->region_name (new_name, current->name(), true); region = new AudioRegion (*current, internal_start, selection_cnt, new_name); @@ -2250,11 +2253,13 @@ Editor::split_multichannel_region () { vector<AudioRegion*> v; - if (!clicked_regionview || clicked_regionview->region.n_channels() < 2) { + AudioRegionView* clicked_arv = dynamic_cast<AudioRegionView*>(clicked_regionview); + + if (!clicked_arv || clicked_arv->audio_region().n_channels() < 2) { return; } - clicked_regionview->region.separate_by_channel (*session, v); + clicked_arv->audio_region().separate_by_channel (*session, v); /* nothing else to do, really */ } @@ -2440,7 +2445,7 @@ Editor::region_fill_track () { jack_nframes_t end; - if (!session || selection->audio_regions.empty()) { + if (!session || selection->regions.empty()) { return; } @@ -2448,9 +2453,15 @@ Editor::region_fill_track () begin_reversible_command (_("region fill")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + Region& region ((*i)->region()); + + // FIXME + AudioRegion* const ar = dynamic_cast<AudioRegion*>(®ion); + if (!ar) + continue; - AudioRegion& region ((*i)->region); Playlist* pl = region.playlist(); if (end <= region.last_frame()) { @@ -2464,7 +2475,7 @@ Editor::region_fill_track () } XMLNode &before = pl->get_state(); - pl->add_region (*(new AudioRegion (region)), region.last_frame(), times); + pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times); session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state())); } @@ -2544,12 +2555,12 @@ Editor::set_region_sync_from_edit_cursor () return; } - if (!clicked_regionview->region.covers (edit_cursor->current_frame)) { + if (!clicked_regionview->region().covers (edit_cursor->current_frame)) { error << _("Place the edit cursor at the desired sync point") << endmsg; return; } - Region& region (clicked_regionview->region); + Region& region (clicked_regionview->region()); begin_reversible_command (_("set sync from edit cursor")); XMLNode &before = region.playlist()->get_state(); region.set_sync_position (edit_cursor->current_frame); @@ -2562,7 +2573,7 @@ void Editor::remove_region_sync () { if (clicked_regionview) { - Region& region (clicked_regionview->region); + Region& region (clicked_regionview->region()); begin_reversible_command (_("remove sync")); XMLNode &before = region.playlist()->get_state(); region.clear_sync_position (); @@ -2575,15 +2586,15 @@ Editor::remove_region_sync () void Editor::naturalize () { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } begin_reversible_command (_("naturalize")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - XMLNode &before = (*i)->region.get_state(); - (*i)->region.move_to_natural_position (this); - XMLNode &after = (*i)->region.get_state(); - session->add_command (new MementoCommand<AudioRegion>((*i)->region, before, after)); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + XMLNode &before = (*i)->region().get_state(); + (*i)->region().move_to_natural_position (this); + XMLNode &after = (*i)->region().get_state(); + session->add_command (new MementoCommand<AudioRegion>((*i)->region(), before, after)); } commit_reversible_command (); } @@ -2602,14 +2613,14 @@ Editor::align_relative (RegionPoint what) struct RegionSortByTime { bool operator() (const AudioRegionView* a, const AudioRegionView* b) { - return a->region.position() < b->region.position(); + return a->region().position() < b->region().position(); } }; void Editor::align_selection_relative (RegionPoint point, jack_nframes_t position) { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } @@ -2617,9 +2628,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position) jack_nframes_t pos = 0; int dir; - list<AudioRegionView*> sorted; - selection->audio_regions.by_position (sorted); - Region& r ((*sorted.begin())->region); + list<RegionView*> sorted; + selection->regions.by_position (sorted); + Region& r ((*sorted.begin())->region()); switch (point) { case Start: @@ -2645,9 +2656,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position) begin_reversible_command (_("align selection (relative)")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - Region& region ((*i)->region); + Region& region ((*i)->region()); XMLNode &before = region.playlist()->get_state(); @@ -2668,14 +2679,14 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position) void Editor::align_selection (RegionPoint point, jack_nframes_t position) { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } begin_reversible_command (_("align selection")); - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - align_region_internal ((*i)->region, point, position); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + align_region_internal ((*i)->region(), point, position); } commit_reversible_command (); @@ -2721,7 +2732,7 @@ Editor::trim_region_to_edit_cursor () return; } - Region& region (clicked_regionview->region); + Region& region (clicked_regionview->region()); float speed = 1.0f; AudioTimeAxisView *atav; @@ -2747,7 +2758,7 @@ Editor::trim_region_from_edit_cursor () return; } - Region& region (clicked_regionview->region); + Region& region (clicked_regionview->region()); float speed = 1.0f; AudioTimeAxisView *atav; @@ -2920,16 +2931,16 @@ Editor::cut_copy (CutCopyOp op) switch (current_mouse_mode()) { case MouseObject: - if (!selection->audio_regions.empty() || !selection->points.empty()) { + if (!selection->regions.empty() || !selection->points.empty()) { begin_reversible_command (opname + _(" objects")); - if (!selection->audio_regions.empty()) { + if (!selection->regions.empty()) { cut_copy_regions (op); if (op == Cut) { - selection->clear_audio_regions (); + selection->clear_regions (); } } @@ -2986,11 +2997,11 @@ Editor::cut_copy_regions (CutCopyOp op) set<Playlist*> freezelist; pair<set<Playlist*>::iterator,bool> insert_result; - for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) { - first_position = min ((*x)->region.position(), first_position); + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + first_position = min ((*x)->region().position(), first_position); if (op == Cut || op == Clear) { - AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist()); + AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist()); if (pl) { insert_result = freezelist.insert (pl); if (insert_result.second) { @@ -3001,11 +3012,11 @@ Editor::cut_copy_regions (CutCopyOp op) } } - for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ) { + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) { - AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist()); + AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist()); AudioPlaylist* npl; - AudioRegionSelection::iterator tmp; + RegionSelection::iterator tmp; tmp = x; ++tmp; @@ -3022,18 +3033,24 @@ Editor::cut_copy_regions (CutCopyOp op) npl = pi->second; } + // FIXME + AudioRegion* const ar = dynamic_cast<AudioRegion*>(&(*x)->region()); switch (op) { case Cut: - npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position); - pl->remove_region (&((*x)->region)); + if (!ar) break; + + npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position); + pl->remove_region (&((*x)->region())); break; case Copy: - npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position); + if (!ar) break; + + npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position); break; case Clear: - pl->remove_region (&((*x)->region)); + pl->remove_region (&((*x)->region())); break; } } @@ -3179,24 +3196,24 @@ Editor::paste_named_selection (float times) } void -Editor::duplicate_some_regions (AudioRegionSelection& regions, float times) +Editor::duplicate_some_regions (RegionSelection& regions, float times) { Playlist *playlist; - AudioRegionSelection sel = regions; // clear (below) will clear the argument list + RegionSelection sel = regions; // clear (below) will clear the argument list begin_reversible_command (_("duplicate region")); - selection->clear_audio_regions (); + selection->clear_regions (); - for (AudioRegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) { + for (RegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) { - Region& r ((*i)->region); + Region& r ((*i)->region()); TimeAxisView& tv = (*i)->get_time_axis_view(); AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv); - sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); - playlist = (*i)->region.playlist(); + playlist = (*i)->region().playlist(); XMLNode &before = playlist->get_state(); playlist->duplicate (r, r.last_frame(), times); session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state())); @@ -3369,7 +3386,7 @@ Editor::normalize_region () return; } - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } @@ -3378,11 +3395,13 @@ Editor::normalize_region () track_canvas.get_window()->set_cursor (*wait_cursor); gdk_flush (); - for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) { - XMLNode &before = (*r)->region.get_state(); - (*r)->region.normalize_to (0.0f); - XMLNode &after = (*r)->region.get_state(); - session->add_command (new MementoCommand<AudioRegion>((*r)->region, before, after)); + for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r); + if (!arv) + continue; + XMLNode &before = arv->region().get_state(); + arv->audio_region().normalize_to (0.0f); + session->add_command (new MementoCommand<Region>(arv->region, arv->region().get_state()); } commit_reversible_command (); @@ -3397,17 +3416,19 @@ Editor::denormalize_region () return; } - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } begin_reversible_command ("denormalize"); - for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) { - XMLNode &before = (*r)->region.get_state(); - (*r)->region.set_scale_amplitude (1.0f); - XMLNode &after = (*r)->region.get_state(); - session->add_command (new MementoCommand<AudioRegion>((*r)->region, before, after)); + for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r); + if (!arv) + continue; + XMLNode &before = arv->region().get_state(); + arv->audio_region().set_scale_amplitude (1.0f); + session->add_command (new MementoCommand<Region>(arv->region, before, arv->region().get_state()); } commit_reversible_command (); @@ -3428,7 +3449,7 @@ Editor::reverse_region () void Editor::apply_filter (AudioFilter& filter, string command) { - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { return; } @@ -3437,20 +3458,22 @@ Editor::apply_filter (AudioFilter& filter, string command) track_canvas.get_window()->set_cursor (*wait_cursor); gdk_flush (); - for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ) { + for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r); + if (!arv) + continue; - AudioRegion& region ((*r)->region); - Playlist* playlist = region.playlist(); + Playlist* playlist = arv->region().playlist(); - AudioRegionSelection::iterator tmp; + RegionSelection::iterator tmp; tmp = r; ++tmp; - if (region.apply (filter) == 0) { + if (arv->audio_region().apply (filter) == 0) { XMLNode &before = playlist->get_state(); - playlist->replace_region (region, *(filter.results.front()), region.position()); + playlist->replace_region (arv->region(), *(filter.results.front()), arv->region()position()); XMLNode &after = playlist->get_state(); session->add_command(new MementoCommand<Playlist>(*playlist, before, after)); } else { @@ -3461,7 +3484,7 @@ Editor::apply_filter (AudioFilter& filter, string command) } commit_reversible_command (); - selection->audio_regions.clear (); + selection->regions.clear (); out: track_canvas.get_window()->set_cursor (*current_canvas_cursor); @@ -3470,8 +3493,8 @@ Editor::apply_filter (AudioFilter& filter, string command) void Editor::region_selection_op (void (Region::*pmf)(void)) { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - ((*i)->region.*pmf)(); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + ((*i)->region().*pmf)(); } } @@ -3479,16 +3502,16 @@ Editor::region_selection_op (void (Region::*pmf)(void)) void Editor::region_selection_op (void (Region::*pmf)(void*), void *arg) { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - ((*i)->region.*pmf)(arg); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + ((*i)->region().*pmf)(arg); } } void Editor::region_selection_op (void (Region::*pmf)(bool), bool yn) { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - ((*i)->region.*pmf)(yn); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + ((*i)->region().*pmf)(yn); } } @@ -3505,20 +3528,20 @@ Editor::external_edit_region () void Editor::brush (jack_nframes_t pos) { - AudioRegionSelection sel; + RegionSelection sel; snap_to (pos); - if (selection->audio_regions.empty()) { + if (selection->regions.empty()) { /* XXX get selection from region list */ } else { - sel = selection->audio_regions; + sel = selection->regions; } if (sel.empty()) { return; } - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { mouse_brush_insert_region ((*i), pos); } } @@ -3526,18 +3549,19 @@ Editor::brush (jack_nframes_t pos) void Editor::toggle_gain_envelope_visibility () { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - (*i)->set_envelope_visible (!(*i)->envelope_visible()); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + arv->set_envelope_visible (!arv->envelope_visible()); } } void Editor::toggle_gain_envelope_active () { - for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) { - AudioRegion* ar = dynamic_cast<AudioRegion*>(&(*i)->region); - if (ar) { - ar->set_envelope_active (true); - } + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i); + if (arv) + arv->audio_region().set_envelope_active (true); } } diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index 2e036f5001..c93cf9aba2 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -39,21 +39,16 @@ using namespace PBD; using namespace Gtk; void -Editor::handle_new_route_p (Route* route) -{ - ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route_p), route)); - handle_new_route (*route); -} - -void -Editor::handle_new_route (Route& route) +Editor::handle_new_route (boost::shared_ptr<Route> route) { + ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), route)); + TimeAxisView *tv; AudioTimeAxisView *atv; TreeModel::Row parent; TreeModel::Row row; - if (route.hidden()) { + if (route->hidden()) { return; } @@ -75,7 +70,7 @@ Editor::handle_new_route (Route& route) } - if (dynamic_cast<AudioTrack*>(&route) != 0) { + if (dynamic_cast<AudioTrack*>(route.get()) != 0) { TreeModel::iterator iter = route_display_model->get_iter ("1"); // audio tracks parent = *iter; } else { @@ -89,7 +84,7 @@ Editor::handle_new_route (Route& route) row = *(route_display_model->append ()); #endif - row[route_display_columns.text] = route.name(); + row[route_display_columns.text] = route->name(); row[route_display_columns.visible] = tv->marked_for_display(); row[route_display_columns.tv] = tv; @@ -99,14 +94,14 @@ Editor::handle_new_route (Route& route) if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) { /* added a new fresh one at the end */ - if (atv->route().order_key(N_("editor")) == -1) { - atv->route().set_order_key (N_("editor"), route_display_model->children().size()-1); + if (atv->route()->order_key(N_("editor")) == -1) { + atv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1); } } ignore_route_list_reorder = false; - route.gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes)); + route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes)); tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv)); @@ -188,7 +183,7 @@ Editor::hide_track_in_display (TimeAxisView& tv) AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv); - if (atv && current_mixer_strip && &(atv->route()) == &(current_mixer_strip->route())) { + if (atv && current_mixer_strip && (atv->route() == current_mixer_strip->route())) { // this will hide the mixer strip set_selected_mixer_strip (tv); } @@ -244,7 +239,7 @@ Editor::redisplay_route_list () */ if ((at = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) { - at->route().set_order_key (N_("editor"), order); + at->route()->set_order_key (N_("editor"), order); ++order; } } @@ -263,6 +258,10 @@ Editor::redisplay_route_list () } + /* make sure the cursors stay on top of every newly added track */ + + cursor_group->raise_to_top (); + reset_scrolling_region (); } @@ -473,7 +472,7 @@ Editor::route_list_selection_filter (const Glib::RefPtr<TreeModel>& model, const } struct EditorOrderRouteSorter { - bool operator() (Route* a, Route* b) { + bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { /* use of ">" forces the correct sort order */ return a->order_key ("editor") < b->order_key ("editor"); } @@ -482,17 +481,18 @@ struct EditorOrderRouteSorter { void Editor::initial_route_list_display () { - Session::RouteList routes = session->get_routes(); + boost::shared_ptr<Session::RouteList> routes = session->get_routes(); + Session::RouteList r (*routes); EditorOrderRouteSorter sorter; - routes.sort (sorter); + r.sort (sorter); no_route_list_redisplay = true; route_display_model->clear (); - for (Session::RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - handle_new_route (**i); + for (Session::RouteList::iterator i = r.begin(); i != r.end(); ++i) { + handle_new_route (*i); } no_route_list_redisplay = false; diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc index 27fa6c9651..3fe0023d07 100644 --- a/gtk2_ardour/editor_timefx.cc +++ b/gtk2_ardour/editor_timefx.cc @@ -29,7 +29,7 @@ #include "editor.h" #include "audio_time_axis.h" -#include "regionview.h" +#include "audio_region_view.h" #include "region_selection.h" #include <ardour/session.h> @@ -101,7 +101,7 @@ Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev) } int -Editor::run_timestretch (AudioRegionSelection& regions, float fraction) +Editor::run_timestretch (RegionSelection& regions, float fraction) { pthread_t thread; @@ -158,39 +158,42 @@ Editor::run_timestretch (AudioRegionSelection& regions, float fraction) void Editor::do_timestretch (TimeStretchDialog& dialog) { - AudioTrack* at; + Track* t; Playlist* playlist; - AudioRegion* new_region; + Region* new_region; - for (AudioRegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) { + for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) { + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i); + if (!arv) + continue; - AudioRegion& aregion ((*i)->region); - TimeAxisView* tv = &(*i)->get_time_axis_view(); - AudioTimeAxisView* atv; - AudioRegionSelection::iterator tmp; + AudioRegion& region (arv->audio_region()); + TimeAxisView* tv = &(arv->get_time_axis_view()); + RouteTimeAxisView* rtv; + RegionSelection::iterator tmp; - cerr << "stretch " << aregion.name() << endl; + cerr << "stretch " << region.name() << endl; tmp = i; ++tmp; - if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) == 0) { + if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) == 0) { i = tmp; continue; } - if ((at = dynamic_cast<AudioTrack*> (&atv->route())) == 0) { + if ((t = dynamic_cast<Track*> (rtv->route().get())) == 0) { i = tmp; continue; } - if ((playlist = at->disk_stream().playlist()) == 0) { + if ((playlist = t->diskstream().playlist()) == 0) { i = tmp; continue; } - dialog.request.region = &aregion; + dialog.request.region = ®ion; if (!dialog.request.running) { /* we were cancelled */ @@ -205,7 +208,7 @@ Editor::do_timestretch (TimeStretchDialog& dialog) } XMLNode &before = playlist->get_state(); - playlist->replace_region (aregion, *new_region, aregion.position()); + playlist->replace_region (region, *new_region, region.position()); XMLNode &after = playlist->get_state(); session->add_command (new MementoCommand<Playlist>(*playlist, before, after)); diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc index bcf8cd85ad..b5a4757090 100644 --- a/gtk2_ardour/export_dialog.cc +++ b/gtk2_ardour/export_dialog.cc @@ -1082,11 +1082,11 @@ ExportDialog::fill_lists () track_list->clear(); master_list->clear(); - Session::RouteList routes = session->get_routes (); + boost::shared_ptr<Session::RouteList> routes = session->get_routes (); - for (Session::RouteList::iterator ri = routes.begin(); ri != routes.end(); ++ri) { - - Route* route = (*ri); + for (Session::RouteList::iterator ri = routes->begin(); ri != routes->end(); ++ri) { + + boost::shared_ptr<Route> route = (*ri); if (route->hidden()) { continue; diff --git a/gtk2_ardour/export_region_dialog.cc b/gtk2_ardour/export_region_dialog.cc index 97bf7c22b1..1964fabbfe 100644 --- a/gtk2_ardour/export_region_dialog.cc +++ b/gtk2_ardour/export_region_dialog.cc @@ -18,6 +18,8 @@ */ +#include <cassert> + #include <pbd/pthread_utils.h> #include <ardour/audioregion.h> @@ -26,11 +28,13 @@ #include "i18n.h" -ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::AudioRegion* region) +ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::Region* region) : ExportDialog(editor) { - audio_region = region; - + // FIXME + ARDOUR::AudioRegion* audio_region = dynamic_cast<ARDOUR::AudioRegion*>(region); + assert(audio_region); + do_not_allow_track_and_master_selection(); do_not_allow_channel_count_selection(); } diff --git a/gtk2_ardour/export_region_dialog.h b/gtk2_ardour/export_region_dialog.h index 00464eb5b3..e8afe97d6b 100644 --- a/gtk2_ardour/export_region_dialog.h +++ b/gtk2_ardour/export_region_dialog.h @@ -27,7 +27,7 @@ class ExportRegionDialog : public ExportDialog { public: - ExportRegionDialog (PublicEditor&, ARDOUR::AudioRegion*); + ExportRegionDialog (PublicEditor&, ARDOUR::Region*); static void* _export_region_thread (void *); void export_region (); diff --git a/gtk2_ardour/fft_graph.cc b/gtk2_ardour/fft_graph.cc index c2d81abf3c..367dc54b7c 100644 --- a/gtk2_ardour/fft_graph.cc +++ b/gtk2_ardour/fft_graph.cc @@ -234,11 +234,11 @@ FFTGraph::draw_scales(Glib::RefPtr<Gdk::Window> window) while (_logScale[logscale_pos] < position_on_scale) logscale_pos++; - int coord = v_margin + 1.0 + position_on_scale; + int coord = (int)(v_margin + 1.0 + position_on_scale); int SR = 44100; - int rate_at_pos = (double)(SR/2) * (double)logscale_pos / (double)_dataSize; + int rate_at_pos = (int)((double)(SR/2) * (double)logscale_pos / (double)_dataSize); char buf[32]; snprintf(buf,32,"%dhz",rate_at_pos); @@ -384,7 +384,7 @@ FFTGraph::on_size_request(Gtk::Requisition* requisition) } void -FFTGraph::on_size_allocate(Gtk::Allocation alloc) +FFTGraph::on_size_allocate(Gtk::Allocation & alloc) { width = alloc.get_width(); height = alloc.get_height(); diff --git a/gtk2_ardour/fft_graph.h b/gtk2_ardour/fft_graph.h index 80c78180a6..73636b989d 100644 --- a/gtk2_ardour/fft_graph.h +++ b/gtk2_ardour/fft_graph.h @@ -51,7 +51,7 @@ class FFTGraph : public Gtk::DrawingArea bool on_expose_event (GdkEventExpose* event); void on_size_request(Gtk::Requisition* requisition); - void on_size_allocate(Gtk::Allocation alloc); + void on_size_allocate(Gtk::Allocation & alloc); FFTResult *prepareResult(Gdk::Color color, std::string trackname); private: diff --git a/gtk2_ardour/fft_result.cc b/gtk2_ardour/fft_result.cc index 9a55b59cb5..f5acef92ed 100644 --- a/gtk2_ardour/fft_result.cc +++ b/gtk2_ardour/fft_result.cc @@ -20,9 +20,9 @@ #include <fft_result.h> #include <fft_graph.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> +#include <cstdlib> +#include <string> +#include <cmath> #include <iostream> diff --git a/gtk2_ardour/gain_automation_time_axis.cc b/gtk2_ardour/gain_automation_time_axis.cc index 3e3d02bfc4..c86c1390f3 100644 --- a/gtk2_ardour/gain_automation_time_axis.cc +++ b/gtk2_ardour/gain_automation_time_axis.cc @@ -32,7 +32,9 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; -GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c) +GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, + PublicEditor& e, TimeAxisView& parent, + ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c) : AxisView (s), AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("gain"), ""), @@ -74,6 +76,6 @@ void GainAutomationTimeAxisView::set_automation_state (AutoState state) { if (!ignore_state_request) { - route.set_gain_automation_state (state); + route->set_gain_automation_state (state); } } diff --git a/gtk2_ardour/gain_automation_time_axis.h b/gtk2_ardour/gain_automation_time_axis.h index 50f1cba3f9..dc6d5bd28e 100644 --- a/gtk2_ardour/gain_automation_time_axis.h +++ b/gtk2_ardour/gain_automation_time_axis.h @@ -13,7 +13,7 @@ class GainAutomationTimeAxisView : public AutomationTimeAxisView { public: GainAutomationTimeAxisView (ARDOUR::Session&, - ARDOUR::Route&, + boost::shared_ptr<ARDOUR::Route>, PublicEditor&, TimeAxisView& parent_axis, ArdourCanvas::Canvas& canvas, diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index b7746c4b19..5fa8c462bc 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -79,7 +79,7 @@ GainMeter::setup_slider_pix () return 0; } -GainMeter::GainMeter (IO& io, Session& s) +GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s) : _io (io), _session (s), gain_slider (0), @@ -99,18 +99,13 @@ GainMeter::GainMeter (IO& io, Session& s) gain_slider = manage (new VSliderController (slider, rail, &gain_adjustment, - & _io.midi_gain_control(), + _io->gain_control(), false)); gain_slider->signal_button_press_event().connect (mem_fun(*this, &GainMeter::start_gain_touch)); gain_slider->signal_button_release_event().connect (mem_fun(*this, &GainMeter::end_gain_touch)); gain_slider->set_name ("MixerGainMeter"); - if (_session.midi_port()) { - _io.set_midi_to_gain_function (slider_position_to_gain); - _io.set_gain_to_midi_function (gain_to_slider_position); - } - gain_display.set_print_func (_gain_printer, this); gain_display_box.set_spacing (2); @@ -157,7 +152,7 @@ GainMeter::GainMeter (IO& io, Session& s) Route* r; - if ((r = dynamic_cast<Route*> (&_io)) != 0) { + if ((r = dynamic_cast<Route*> (_io.get())) != 0) { /* if we don't have a route (if we're the click), pack some route-dependent stuff. @@ -170,13 +165,13 @@ GainMeter::GainMeter (IO& io, Session& s) using namespace Menu_Helpers; gain_astate_menu.items().push_back (MenuElem (_("Off"), - bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Off))); + bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Off))); gain_astate_menu.items().push_back (MenuElem (_("Play"), - bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Play))); + bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Play))); gain_astate_menu.items().push_back (MenuElem (_("Write"), - bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Write))); + bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Write))); gain_astate_menu.items().push_back (MenuElem (_("Touch"), - bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Touch))); + bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Touch))); gain_astyle_menu.items().push_back (MenuElem (_("Trim"))); gain_astyle_menu.items().push_back (MenuElem (_("Abs"))); @@ -200,7 +195,7 @@ GainMeter::GainMeter (IO& io, Session& s) pack_start (gain_display_box, Gtk::PACK_SHRINK); pack_start (hbox, Gtk::PACK_SHRINK); - _io.gain_changed.connect (mem_fun(*this, &GainMeter::gain_changed)); + _io->gain_changed.connect (mem_fun(*this, &GainMeter::gain_changed)); meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose)); gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeter::gain_adjusted)); @@ -328,7 +323,7 @@ GainMeter::update_meters () for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) { if ((*i).packed) { - peak = _io.peak_input_power (n); + peak = _io->peak_input_power (n); (*i).meter->set (log_meter (peak), peak); @@ -387,14 +382,14 @@ GainMeter::hide_all_meters () void GainMeter::setup_meters () { - uint32_t nmeters = _io.n_outputs(); + uint32_t nmeters = _io->n_outputs(); guint16 width; hide_all_meters (); Route* r; - if ((r = dynamic_cast<Route*> (&_io)) != 0) { + if ((r = dynamic_cast<Route*> (_io.get())) != 0) { switch (r->meter_point()) { case MeterPreFader: @@ -408,7 +403,7 @@ GainMeter::setup_meters () } else { - nmeters = _io.n_outputs(); + nmeters = _io->n_outputs(); } @@ -456,7 +451,7 @@ GainMeter::peak_button_release (GdkEventButton* ev) ResetAllPeakDisplays (); } else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { Route* r; - if ((r = dynamic_cast<Route*> (&_io)) != 0) { + if ((r = dynamic_cast<Route*> (_io.get())) != 0) { ResetGroupPeakDisplays (r->mix_group()); } } else { @@ -477,7 +472,7 @@ void GainMeter::reset_group_peak_display (RouteGroup* group) { Route* r; - if ((r = dynamic_cast<Route*> (&_io)) != 0) { + if ((r = dynamic_cast<Route*> (_io.get())) != 0) { if (group == r->mix_group()) { reset_peak_display (); } @@ -546,14 +541,14 @@ void GainMeter::gain_adjusted () { if (!ignore_toggle) { - _io.set_gain (slider_position_to_gain (gain_adjustment.get_value()), this); + _io->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this); } } void GainMeter::effective_gain_display () { - gfloat value = gain_to_slider_position (_io.effective_gain()); + gfloat value = gain_to_slider_position (_io->effective_gain()); if (gain_adjustment.get_value() != value) { ignore_toggle = true; @@ -583,7 +578,7 @@ GainMeter::set_fader_name (const char * name) void GainMeter::update_gain_sensitive () { - static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io.gain_automation_state() & Play)); + static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_automation_state() & Play)); } @@ -614,7 +609,7 @@ GainMeter::meter_press(GdkEventButton* ev) wait_for_release = false; - if ((_route = dynamic_cast<Route*>(&_io)) == 0) { + if ((_route = dynamic_cast<Route*>(_io.get())) == 0) { return FALSE; } @@ -676,7 +671,7 @@ GainMeter::meter_release(GdkEventButton* ev) if(!ignore_toggle){ if (wait_for_release){ wait_for_release = false; - set_meter_point (*(dynamic_cast<Route*>(&_io)), old_meter_point); + set_meter_point (*(dynamic_cast<Route*>(_io.get())), old_meter_point); } } return true; @@ -705,7 +700,7 @@ GainMeter::meter_point_clicked () { Route* r; - if ((r = dynamic_cast<Route*> (&_io)) != 0) { + if ((r = dynamic_cast<Route*> (_io.get())) != 0) { } } @@ -713,14 +708,14 @@ GainMeter::meter_point_clicked () gint GainMeter::start_gain_touch (GdkEventButton* ev) { - _io.start_gain_touch (); + _io->start_gain_touch (); return FALSE; } gint GainMeter::end_gain_touch (GdkEventButton* ev) { - _io.end_gain_touch (); + _io->end_gain_touch (); return FALSE; } @@ -824,10 +819,10 @@ GainMeter::gain_automation_style_changed () // Route* _route = dynamic_cast<Route*>(&_io); switch (_width) { case Wide: - gain_automation_style_button.set_label (astyle_string(_io.gain_automation_curve().automation_style())); + gain_automation_style_button.set_label (astyle_string(_io->gain_automation_curve().automation_style())); break; case Narrow: - gain_automation_style_button.set_label (short_astyle_string(_io.gain_automation_curve().automation_style())); + gain_automation_style_button.set_label (short_astyle_string(_io->gain_automation_curve().automation_style())); break; } } @@ -842,14 +837,14 @@ GainMeter::gain_automation_state_changed () switch (_width) { case Wide: - gain_automation_state_button.set_label (astate_string(_io.gain_automation_curve().automation_state())); + gain_automation_state_button.set_label (astate_string(_io->gain_automation_curve().automation_state())); break; case Narrow: - gain_automation_state_button.set_label (short_astate_string(_io.gain_automation_curve().automation_state())); + gain_automation_state_button.set_label (short_astate_string(_io->gain_automation_curve().automation_state())); break; } - x = (_io.gain_automation_state() != Off); + x = (_io->gain_automation_state() != Off); if (gain_automation_state_button.get_active() != x) { ignore_toggle = true; diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h index ddf93b579f..1dfc088248 100644 --- a/gtk2_ardour/gain_meter.h +++ b/gtk2_ardour/gain_meter.h @@ -34,8 +34,8 @@ #include <ardour/types.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> #include "enums.h" @@ -56,7 +56,7 @@ namespace Gtk { class GainMeter : public Gtk::VBox { public: - GainMeter (ARDOUR::IO&, ARDOUR::Session&); + GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&); ~GainMeter (); void update_gain_sensitive (); @@ -75,7 +75,7 @@ class GainMeter : public Gtk::VBox private: friend class MixerStrip; - ARDOUR::IO& _io; + boost::shared_ptr<ARDOUR::IO> _io; ARDOUR::Session& _session; bool ignore_toggle; diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc index b0ecd05077..f754435112 100644 --- a/gtk2_ardour/io_selector.cc +++ b/gtk2_ardour/io_selector.cc @@ -52,7 +52,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtkmm2ext; -IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can_cancel) +IOSelectorWindow::IOSelectorWindow (Session& sess, boost::shared_ptr<IO> ior, bool input, bool can_cancel) : ArdourDialog ("i/o selector"), _selector (sess, ior, input), ok_button (can_cancel ? _("OK"): _("Close")), @@ -65,9 +65,9 @@ IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can string title; if (input) { - title = string_compose(_("%1 input"), ior.name()); + title = string_compose(_("%1 input"), ior->name()); } else { - title = string_compose(_("%1 output"), ior.name()); + title = string_compose(_("%1 output"), ior->name()); } ok_button.set_name ("IOSelectorButton"); @@ -135,7 +135,7 @@ IOSelectorWindow::on_map () The IO Selector "widget" *************************/ -IOSelector::IOSelector (Session& sess, IO& ior, bool input) +IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input) : session (sess), io (ior), for_input (input), @@ -184,14 +184,14 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input) port_button_box.pack_start (add_port_button, false, false); if (for_input) { - if (io.input_maximum() < 0 || io.input_maximum() > (int) io.n_inputs()) { + if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) { add_port_button.set_sensitive (true); } else { add_port_button.set_sensitive (false); } } else { - if (io.output_maximum() < 0 || io.output_maximum() > (int) io.n_outputs()) { + if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) { add_port_button.set_sensitive (true); } else { add_port_button.set_sensitive (false); @@ -202,14 +202,14 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input) port_button_box.pack_start (remove_port_button, false, false); if (for_input) { - if (io.input_minimum() < 0 || io.input_minimum() < (int) io.n_inputs()) { + if (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs()) { remove_port_button.set_sensitive (true); } else { remove_port_button.set_sensitive (false); } } else { - if (io.output_minimum() < 0 || io.output_minimum() < (int) io.n_outputs()) { + if (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs()) { remove_port_button.set_sensitive (true); } else { remove_port_button.set_sensitive (false); @@ -241,12 +241,12 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input) remove_port_button.signal_clicked().connect (mem_fun(*this, &IOSelector::remove_port)); if (for_input) { - io.input_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); + io->input_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); } else { - io.output_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); + io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed)); } - io.name_changed.connect (mem_fun(*this, &IOSelector::name_changed)); + io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed)); } IOSelector::~IOSelector () @@ -265,9 +265,9 @@ void IOSelector::clear_connections () { if (for_input) { - io.disconnect_inputs (this); + io->disconnect_inputs (this); } else { - io.disconnect_outputs (this); + io->disconnect_outputs (this); } } @@ -374,9 +374,9 @@ IOSelector::display_ports () uint32_t limit; if (for_input) { - limit = io.n_inputs(); + limit = io->n_inputs(); } else { - limit = io.n_outputs(); + limit = io->n_outputs(); } for (slist<TreeView *>::iterator i = port_displays.begin(); i != port_displays.end(); ) { @@ -401,9 +401,9 @@ IOSelector::display_ports () string really_short_name; if (for_input) { - port = io.input (n); + port = io->input (n); } else { - port = io.output (n); + port = io->output (n); } /* we know there is '/' because we put it there */ @@ -443,7 +443,7 @@ IOSelector::display_ports () if (for_input) { - if (io.input_maximum() == 1) { + if (io->input_maximum() == 1) { selected_port = port; selected_port_tview = tview; } else { @@ -454,7 +454,7 @@ IOSelector::display_ports () } else { - if (io.output_maximum() == 1) { + if (io->output_maximum() == 1) { selected_port = port; selected_port_tview = tview; } else { @@ -516,12 +516,12 @@ IOSelector::port_selection_changed (GdkEventButton *ev, TreeView* treeview) ustring other_port_name = (*i)[port_display_columns.full_name]; if (for_input) { - if ((status = io.connect_input (selected_port, other_port_name, this)) == 0) { + if ((status = io->connect_input (selected_port, other_port_name, this)) == 0) { Port *p = session.engine().get_port_by_name (other_port_name); p->enable_metering(); } } else { - status = io.connect_output (selected_port, other_port_name, this); + status = io->connect_output (selected_port, other_port_name, this); } if (status == 0) { @@ -548,7 +548,7 @@ IOSelector::add_port () if (for_input) { try { - io.add_input_port ("", this); + io->add_input_port ("", this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -556,18 +556,18 @@ IOSelector::add_port () msg.run (); } - if (io.input_maximum() >= 0 && io.input_maximum() <= (int) io.n_inputs()) { + if (io->input_maximum() >= 0 && io->input_maximum() <= (int) io->n_inputs()) { add_port_button.set_sensitive (false); } - if (io.input_minimum() < (int) io.n_inputs()) { + if (io->input_minimum() < (int) io->n_inputs()) { remove_port_button.set_sensitive (true); } } else { try { - io.add_output_port ("", this); + io->add_output_port ("", this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -575,7 +575,7 @@ IOSelector::add_port () msg.run (); } - if (io.output_maximum() >= 0 && io.output_maximum() <= (int) io.n_outputs()) { + if (io->output_maximum() >= 0 && io->output_maximum() <= (int) io->n_outputs()) { add_port_button.set_sensitive (false); } } @@ -589,15 +589,15 @@ IOSelector::remove_port () // always remove last port if (for_input) { - if ((nports = io.n_inputs()) > 0) { - io.remove_input_port (io.input(nports-1), this); + if ((nports = io->n_inputs()) > 0) { + io->remove_input_port (io->input(nports-1), this); } - if (io.input_minimum() == (int) io.n_inputs()) { + if (io->input_minimum() == (int) io->n_inputs()) { remove_port_button.set_sensitive (false); } } else { - if ((nports = io.n_outputs()) > 0) { - io.remove_output_port (io.output(nports-1), this); + if ((nports = io->n_outputs()) > 0) { + io->remove_output_port (io->output(nports-1), this); } } } @@ -606,9 +606,9 @@ gint IOSelector::remove_port_when_idle (Port *port) { if (for_input) { - io.remove_input_port (port, this); + io->remove_input_port (port, this); } else { - io.remove_output_port (port, this); + io->remove_output_port (port, this); } return FALSE; @@ -651,9 +651,9 @@ IOSelector::connection_button_release (GdkEventButton *ev, TreeView *treeview) if (for_input) { Port *p = session.engine().get_port_by_name (connected_port_name); p->disable_metering(); - io.disconnect_input (port, connected_port_name, this); + io->disconnect_input (port, connected_port_name, this); } else { - io.disconnect_output (port, connected_port_name, this); + io->disconnect_output (port, connected_port_name, this); } } @@ -749,17 +749,17 @@ IOSelector::redisplay () display_ports (); if (for_input) { - if (io.input_maximum() != 0) { + if (io->input_maximum() != 0) { rescan (); } } else { - if (io.output_maximum() != 0) { + if (io->output_maximum() != 0) { rescan(); } } } -PortInsertUI::PortInsertUI (Session& sess, PortInsert& pi) +PortInsertUI::PortInsertUI (Session& sess, boost::shared_ptr<PortInsert> pi) : input_selector (sess, pi, true), output_selector (sess, pi, false) { @@ -786,9 +786,9 @@ PortInsertUI::finished(IOSelector::Result r) } -PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_cancel) +PortInsertWindow::PortInsertWindow (Session& sess, boost::shared_ptr<PortInsert> pi, bool can_cancel) : ArdourDialog ("port insert dialog"), - _portinsertui(sess, pi), + _portinsertui (sess, pi), ok_button (can_cancel ? _("OK"): _("Close")), cancel_button (_("Cancel")), rescan_button (_("Rescan")) @@ -796,7 +796,7 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc set_name ("IOSelectorWindow"); string title = _("ardour: "); - title += pi.name(); + title += pi->name(); set_title (title); ok_button.set_name ("IOSelectorButton"); @@ -823,7 +823,7 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc rescan_button.signal_clicked().connect (mem_fun(*this, &PortInsertWindow::rescan)); signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window *> (this))); - pi.GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away)); + pi->GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away)); } void diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h index 44518e6759..993d4aa1ad 100644 --- a/gtk2_ardour/io_selector.h +++ b/gtk2_ardour/io_selector.h @@ -53,7 +53,7 @@ namespace ARDOUR { class IOSelector : public Gtk::VBox { public: - IOSelector (ARDOUR::Session&, ARDOUR::IO&, bool for_input); + IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool for_input); ~IOSelector (); void redisplay (); @@ -67,9 +67,9 @@ class IOSelector : public Gtk::VBox { protected: ARDOUR::Session& session; - + private: - ARDOUR::IO& io; + boost::shared_ptr<ARDOUR::IO> io; bool for_input; ARDOUR::Port *selected_port; @@ -135,7 +135,7 @@ class IOSelector : public Gtk::VBox { class IOSelectorWindow : public ArdourDialog { public: - IOSelectorWindow (ARDOUR::Session&, ARDOUR::IO&, bool for_input, bool can_cancel=false); + IOSelectorWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool for_input, bool can_cancel=false); ~IOSelectorWindow (); IOSelector& selector() { return _selector; } @@ -162,7 +162,7 @@ class IOSelectorWindow : public ArdourDialog class PortInsertUI : public Gtk::VBox { public: - PortInsertUI (ARDOUR::Session&, ARDOUR::PortInsert&); + PortInsertUI (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>); void redisplay (); void finished (IOSelector::Result); @@ -178,7 +178,7 @@ class PortInsertUI : public Gtk::VBox class PortInsertWindow : public ArdourDialog { public: - PortInsertWindow (ARDOUR::Session&, ARDOUR::PortInsert&, bool can_cancel=false); + PortInsertWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>, bool can_cancel=false); protected: void on_map (); diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h index 06ed4c800d..c13b06afe5 100644 --- a/gtk2_ardour/keyboard.h +++ b/gtk2_ardour/keyboard.h @@ -28,7 +28,7 @@ #include <gtk/gtk.h> #include <ardour/types.h> -#include <ardour/stateful.h> +#include <pbd/stateful.h> #include "selection.h" diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc index 778355c858..047bb130a4 100644 --- a/gtk2_ardour/main.cc +++ b/gtk2_ardour/main.cc @@ -446,7 +446,7 @@ int main (int argc, char *argv[]) try { engine = new ARDOUR::AudioEngine (jack_client_name); - ARDOUR::init (*engine, use_vst, try_hw_optimization); + ARDOUR::init (use_vst, try_hw_optimization); ui->set_engine (*engine); } catch (AudioEngine::NoBackendAvailable& err) { gui_jack_error (); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 47d884be5e..4f3dc720d9 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -27,10 +27,10 @@ #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/choice.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/stop_signal.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/slider_controller.h> +#include <gtkmm2ext/bindable_button.h> #include <ardour/ardour.h> #include <ardour/session.h> @@ -52,7 +52,6 @@ #include "keyboard.h" #include "plugin_selector.h" #include "public_editor.h" - #include "plugin_ui.h" #include "send_ui.h" #include "io_selector.h" @@ -81,7 +80,7 @@ speed_printer (char buf[32], Gtk::Adjustment& adj, void* arg) } #endif -MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) +MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt, bool in_mixer) : AxisView(sess), RouteUI (rt, sess, _("Mute"), _("Solo"), _("Record")), _mixer(mx), @@ -126,12 +125,12 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) output_button.set_name ("MixerIOButton"); output_label.set_name ("MixerIOButtonLabel"); - _route.meter_change.connect (mem_fun(*this, &MixerStrip::meter_changed)); + _route->meter_change.connect (mem_fun(*this, &MixerStrip::meter_changed)); meter_point_button.add (meter_point_label); meter_point_button.set_name ("MixerStripMeterPreButton"); meter_point_label.set_name ("MixerStripMeterPreButton"); - switch (_route.meter_point()) { + switch (_route->meter_point()) { case MeterInput: meter_point_label.set_text (_("input")); break; @@ -159,9 +158,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) /* XXX what is this meant to do? */ //meter_point_button.signal_button_release_event().connect (mem_fun (gpm, &GainMeter::meter_release), false); - rec_enable_button->set_name ("MixerRecordEnableButton"); - rec_enable_button->unset_flags (Gtk::CAN_FOCUS); - solo_button->set_name ("MixerSoloButton"); mute_button->set_name ("MixerMuteButton"); @@ -191,7 +187,11 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) if (is_audio_track()) { - AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); + rec_enable_button->set_name ("MixerRecordEnableButton"); + rec_enable_button->unset_flags (Gtk::CAN_FOCUS); + rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); + + AudioTrack* at = audio_track(); at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen)); @@ -217,10 +217,10 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2); name_label.set_name ("MixerNameButtonLabel"); - if (_route.phase_invert()) { + if (_route->phase_invert()) { name_label.set_text (X_("Ø ") + name_label.get_text()); } else { - name_label.set_text (_route.name()); + name_label.set_text (_route->name()); } group_button.add (group_label); @@ -229,9 +229,9 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) comment_button.set_name ("MixerCommentButton"); - ARDOUR_UI::instance()->tooltips().set_tip (comment_button, _route.comment()=="" ? + ARDOUR_UI::instance()->tooltips().set_tip (comment_button, _route->comment()=="" ? _("Click to Add/Edit Comments"): - _route.comment()); + _route->comment()); comment_button.signal_clicked().connect (mem_fun(*this, &MixerStrip::comment_button_clicked)); @@ -281,27 +281,26 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer) _session.engine().Stopped.connect (mem_fun(*this, &MixerStrip::engine_stopped)); _session.engine().Running.connect (mem_fun(*this, &MixerStrip::engine_running)); - _route.input_changed.connect (mem_fun(*this, &MixerStrip::input_changed)); - _route.output_changed.connect (mem_fun(*this, &MixerStrip::output_changed)); - _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)); - _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); - _route.solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); - _route.mix_group_changed.connect (mem_fun(*this, &MixerStrip::mix_group_changed)); - _route.panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan)); + _route->input_changed.connect (mem_fun(*this, &MixerStrip::input_changed)); + _route->output_changed.connect (mem_fun(*this, &MixerStrip::output_changed)); + _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)); + _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); + _route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); + _route->mix_group_changed.connect (mem_fun(*this, &MixerStrip::mix_group_changed)); + _route->panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan)); if (is_audio_track()) { - audio_track()->diskstream_changed.connect (mem_fun(*this, &MixerStrip::diskstream_changed)); - get_diskstream()->speed_changed.connect (mem_fun(*this, &MixerStrip::speed_changed)); + audio_track()->DiskstreamChanged.connect (mem_fun(*this, &MixerStrip::diskstream_changed)); + get_diskstream()->SpeedChanged.connect (mem_fun(*this, &MixerStrip::speed_changed)); } - _route.name_changed.connect (mem_fun(*this, &RouteUI::name_changed)); - _route.comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed)); - _route.gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed)); + _route->name_changed.connect (mem_fun(*this, &RouteUI::name_changed)); + _route->comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed)); + _route->gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed)); input_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::input_press), false); output_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::output_press), false); - rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false); solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); @@ -414,20 +413,22 @@ MixerStrip::set_width (Width w) set_size_request (-1, -1); xml_node->add_property ("strip_width", "wide"); - rec_enable_button->set_label (_("record")); + if (rec_enable_button) { + rec_enable_button->set_label (_("record")); + } mute_button->set_label (_("mute")); solo_button->set_label (_("solo")); - if (_route.comment() == "") { + if (_route->comment() == "") { comment_button.set_label (_("comments")); } else { comment_button.set_label (_("*comments*")); } - gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route.gain_automation_curve().automation_style())); - gpm.gain_automation_state_button.set_label (gpm.astate_string(_route.gain_automation_curve().automation_state())); - panners.pan_automation_style_button.set_label (panners.astyle_string(_route.panner().automation_style())); - panners.pan_automation_state_button.set_label (panners.astate_string(_route.panner().automation_state())); + gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route->gain_automation_curve().automation_style())); + gpm.gain_automation_state_button.set_label (gpm.astate_string(_route->gain_automation_curve().automation_state())); + panners.pan_automation_style_button.set_label (panners.astyle_string(_route->panner().automation_style())); + panners.pan_automation_state_button.set_label (panners.astate_string(_route->panner().automation_state())); Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2); break; @@ -435,20 +436,22 @@ MixerStrip::set_width (Width w) set_size_request (50, -1); xml_node->add_property ("strip_width", "narrow"); - rec_enable_button->set_label (_("Rec")); + if (rec_enable_button) { + rec_enable_button->set_label (_("Rec")); + } mute_button->set_label (_("M")); solo_button->set_label (_("S")); - if (_route.comment() == "") { + if (_route->comment() == "") { comment_button.set_label (_("Cmt")); } else { comment_button.set_label (_("*Cmt*")); } - gpm.gain_automation_style_button.set_label (gpm.short_astyle_string(_route.gain_automation_curve().automation_style())); - gpm.gain_automation_state_button.set_label (gpm.short_astate_string(_route.gain_automation_curve().automation_state())); - panners.pan_automation_style_button.set_label (panners.short_astyle_string(_route.panner().automation_style())); - panners.pan_automation_state_button.set_label (panners.short_astate_string(_route.panner().automation_state())); + gpm.gain_automation_style_button.set_label (gpm.short_astyle_string(_route->gain_automation_curve().automation_style())); + gpm.gain_automation_state_button.set_label (gpm.short_astate_string(_route->gain_automation_curve().automation_state())); + panners.pan_automation_style_button.set_label (panners.short_astyle_string(_route->panner().automation_style())); + panners.pan_automation_state_button.set_label (panners.short_astate_string(_route->panner().automation_state())); Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2); break; } @@ -555,11 +558,6 @@ MixerStrip::input_press (GdkEventButton *ev) case 1: -#if ADVANCED_ROUTE_DISKSTREAM_CONNECTIVITY - if (is_audio_track()) { - citems.push_back (MenuElem (_("Track"), mem_fun(*this, &MixerStrip::select_stream_input))); - } -#endif citems.push_back (MenuElem (_("Edit"), mem_fun(*this, &MixerStrip::edit_input_configuration))); citems.push_back (SeparatorElem()); citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_input))); @@ -581,7 +579,7 @@ MixerStrip::connection_input_chosen (ARDOUR::Connection *c) if (!ignore_toggle) { try { - _route.use_input_connection (*c, this); + _route->use_input_connection (*c, this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -597,7 +595,7 @@ MixerStrip::connection_output_chosen (ARDOUR::Connection *c) if (!ignore_toggle) { try { - _route.use_output_connection (*c, this); + _route->use_output_connection (*c, this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -618,11 +616,11 @@ MixerStrip::add_connection_to_input_menu (ARDOUR::Connection* c) MenuList& citems = input_menu.items(); - if (c->nports() == _route.n_inputs()) { + if (c->nports() == _route->n_inputs()) { citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_input_chosen), c))); - ARDOUR::Connection *current = _route.input_connection(); + ARDOUR::Connection *current = _route->input_connection(); if (current == c) { ignore_toggle = true; @@ -641,12 +639,12 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c) return; } - if (c->nports() == _route.n_outputs()) { + if (c->nports() == _route->n_outputs()) { MenuList& citems = output_menu.items(); citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_output_chosen), c))); - ARDOUR::Connection *current = _route.output_connection(); + ARDOUR::Connection *current = _route->output_connection(); if (current == c) { ignore_toggle = true; @@ -657,42 +655,6 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c) } void -MixerStrip::select_stream_input () -{ - using namespace Menu_Helpers; - - Menu *stream_menu = manage (new Menu); - MenuList& items = stream_menu->items(); - stream_menu->set_name ("ArdourContextMenu"); - - Session::AudioDiskstreamList streams = _session.audio_disk_streams(); - - for (Session::AudioDiskstreamList::iterator i = streams.begin(); i != streams.end(); ++i) { - - if (!(*i)->hidden()) { - - items.push_back (CheckMenuElem ((*i)->name(), bind (mem_fun(*this, &MixerStrip::stream_input_chosen), *i))); - - if (get_diskstream() == *i) { - ignore_toggle = true; - static_cast<CheckMenuItem *> (&items.back())->set_active (true); - ignore_toggle = false; - } - } - } - - stream_menu->popup (1, 0); -} - -void -MixerStrip::stream_input_chosen (AudioDiskstream *stream) -{ - if (is_audio_track()) { - audio_track()->set_diskstream (*stream, this); - } -} - -void MixerStrip::update_diskstream_display () { if (is_audio_track()) { @@ -724,8 +686,8 @@ MixerStrip::connect_to_pan () panstate_connection.disconnect (); panstyle_connection.disconnect (); - if (!_route.panner().empty()) { - StreamPanner* sp = _route.panner().front(); + if (!_route->panner().empty()) { + StreamPanner* sp = _route->panner().front(); panstate_connection = sp->automation().automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed)); panstyle_connection = sp->automation().automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed)); @@ -739,7 +701,7 @@ MixerStrip::update_input_display () { ARDOUR::Connection *c; - if ((c = _route.input_connection()) != 0) { + if ((c = _route->input_connection()) != 0) { input_label.set_text (c->name()); } else { switch (_width) { @@ -759,7 +721,7 @@ MixerStrip::update_output_display () { ARDOUR::Connection *c; - if ((c = _route.output_connection()) != 0) { + if ((c = _route->output_connection()) != 0) { output_label.set_text (c->name()); } else { switch (_width) { @@ -782,7 +744,7 @@ MixerStrip::fast_update () } void -MixerStrip::diskstream_changed (void *src) +MixerStrip::diskstream_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_diskstream_display)); } @@ -810,8 +772,8 @@ MixerStrip::comment_button_clicked () if (comment_window->is_visible()) { string str = comment_area->get_buffer()->get_text(); - if (_route.comment() != str) { - _route.set_comment (str, this); + if (_route->comment() != str) { + _route->set_comment (str, this); switch (_width) { @@ -855,7 +817,7 @@ void MixerStrip::setup_comment_editor () { string title; - title = _route.name(); + title = _route->name(); title += _(": comment editor"); comment_window = new ArdourDialog (title, false); @@ -867,7 +829,7 @@ MixerStrip::setup_comment_editor () comment_area->set_size_request (110, 178); comment_area->set_wrap_mode (WRAP_WORD); comment_area->set_editable (true); - comment_area->get_buffer()->set_text (_route.comment()); + comment_area->get_buffer()->set_text (_route->comment()); comment_area->show (); comment_window->get_vbox()->pack_start (*comment_area); @@ -882,7 +844,7 @@ MixerStrip::comment_changed (void *src) if (src != this) { ignore_comment_edit = true; if (comment_area) { - comment_area->get_buffer()->set_text (_route.comment()); + comment_area->get_buffer()->set_text (_route->comment()); } ignore_comment_edit = false; } @@ -891,7 +853,7 @@ MixerStrip::comment_changed (void *src) void MixerStrip::set_mix_group (RouteGroup *rg) { - _route.set_mix_group (rg, this); + _route->set_mix_group (rg, this); } void @@ -903,7 +865,7 @@ MixerStrip::add_mix_group_to_menu (RouteGroup *rg, RadioMenuItem::Group* group) items.push_back (RadioMenuElem (*group, rg->name(), bind (mem_fun(*this, &MixerStrip::set_mix_group), rg))); - if (_route.mix_group() == rg) { + if (_route->mix_group() == rg) { static_cast<RadioMenuItem*>(&items.back())->set_active (); } } @@ -943,7 +905,7 @@ MixerStrip::mix_group_changed (void *ignored) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &MixerStrip::mix_group_changed), ignored)); - RouteGroup *rg = _route.mix_group(); + RouteGroup *rg = _route->mix_group(); if (rg) { group_label.set_text (rg->name()); @@ -999,11 +961,11 @@ MixerStrip::build_route_ops_menu () items.push_back (SeparatorElem()); items.push_back (CheckMenuElem (_("Active"), mem_fun (*this, &RouteUI::toggle_route_active))); route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); - route_active_menu_item->set_active (_route.active()); + route_active_menu_item->set_active (_route->active()); items.push_back (SeparatorElem()); items.push_back (CheckMenuElem (_("Invert Polarity"), mem_fun (*this, &RouteUI::toggle_polarity))); polarity_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); - polarity_menu_item->set_active (_route.phase_invert()); + polarity_menu_item->set_active (_route->phase_invert()); build_remote_control_menu (); @@ -1093,10 +1055,10 @@ MixerStrip::name_changed (void *src) RouteUI::name_changed (src); break; case Narrow: - name_label.set_text (PBD::short_version (_route.name(), 5)); + name_label.set_text (PBD::short_version (_route->name(), 5)); break; } - if (_route.phase_invert()) { + if (_route->phase_invert()) { name_label.set_text (X_("Ø ") + name_label.get_text()); } } @@ -1135,7 +1097,7 @@ MixerStrip::map_frozen () { ENSURE_GUI_THREAD (mem_fun(*this, &MixerStrip::map_frozen)); - AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); + AudioTrack* at = audio_track(); if (at) { switch (at->freeze_state()) { @@ -1151,11 +1113,11 @@ MixerStrip::map_frozen () break; } } - _route.foreach_redirect (this, &MixerStrip::hide_redirect_editor); + _route->foreach_redirect (this, &MixerStrip::hide_redirect_editor); } void -MixerStrip::hide_redirect_editor (Redirect* redirect) +MixerStrip::hide_redirect_editor (boost::shared_ptr<Redirect> redirect) { void* gui = redirect->get_gui (); @@ -1170,7 +1132,7 @@ MixerStrip::route_active_changed () RouteUI::route_active_changed (); if (is_audio_track()) { - if (_route.active()) { + if (_route->active()) { set_name ("AudioTrackStripBase"); gpm.set_meter_strip_name ("AudioTrackStripBase"); } else { @@ -1178,8 +1140,8 @@ MixerStrip::route_active_changed () gpm.set_meter_strip_name ("AudioTrackStripBaseInactive"); } gpm.set_fader_name ("AudioTrackFader"); - } else { - if (_route.active()) { + } else { // FIXME: assumed audio bus + if (_route->active()) { set_name ("AudioBusStripBase"); gpm.set_meter_strip_name ("AudioBusStripBase"); } else { @@ -1193,14 +1155,16 @@ MixerStrip::route_active_changed () RouteGroup* MixerStrip::mix_group() const { - return _route.mix_group(); + return _route->mix_group(); } void MixerStrip::engine_stopped () { input_button.set_sensitive (false); - rec_enable_button->set_sensitive (false); + if (rec_enable_button) { + rec_enable_button->set_sensitive (false); + } output_button.set_sensitive (false); } @@ -1208,7 +1172,9 @@ void MixerStrip::engine_running () { input_button.set_sensitive (true); - rec_enable_button->set_sensitive (true); + if (rec_enable_button) { + rec_enable_button->set_sensitive (true); + } output_button.set_sensitive (true); } @@ -1218,7 +1184,7 @@ MixerStrip::meter_changed (void *src) ENSURE_GUI_THREAD (bind (mem_fun(*this, &MixerStrip::meter_changed), src)); - switch (_route.meter_point()) { + switch (_route->meter_point()) { case MeterInput: meter_point_label.set_text (_("input")); break; diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index 0cc8fed8e3..21db0d14ca 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,8 +14,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ */ #ifndef __ardour_mixer_strip__ @@ -37,14 +35,15 @@ #include <gtkmm/adjustment.h> #include <gtkmm2ext/auto_spin.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> + +#include <pbd/stateful.h> #include <ardour/types.h> #include <ardour/ardour.h> #include <ardour/io.h> #include <ardour/insert.h> -#include <ardour/stateful.h> #include <ardour/redirect.h> #include <pbd/fastlog.h> @@ -83,7 +82,7 @@ class Mixer_UI; class MixerStrip : public RouteUI, public Gtk::EventBox { public: - MixerStrip (Mixer_UI&, ARDOUR::Session&, ARDOUR::Route &, bool in_mixer = true); + MixerStrip (Mixer_UI&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, bool in_mixer = true); ~MixerStrip (); void set_width (Width); @@ -170,15 +169,13 @@ class MixerStrip : public RouteUI, public Gtk::EventBox Gtk::Menu output_menu; void add_connection_to_output_menu (ARDOUR::Connection *); - void stream_input_chosen (ARDOUR::AudioDiskstream*); - void select_stream_input (); void connection_input_chosen (ARDOUR::Connection *); void connection_output_chosen (ARDOUR::Connection *); void edit_input_configuration (); void edit_output_configuration (); - void diskstream_changed (void *src); + void diskstream_changed (); Gtk::Menu *send_action_menu; void build_send_action_menu (); @@ -238,7 +235,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox void name_changed (void *src); void update_speed_display (); void map_frozen (); - void hide_redirect_editor (ARDOUR::Redirect* redirect); + void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect> redirect); bool ignore_speed_adjustment; diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 983903d6dd..c2eb588b2f 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -251,7 +251,7 @@ Mixer_UI::show_window () } void -Mixer_UI::add_strip (Route* route) +Mixer_UI::add_strip (boost::shared_ptr<Route> route) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::add_strip), route)); @@ -261,7 +261,7 @@ Mixer_UI::add_strip (Route* route) return; } - strip = new MixerStrip (*this, *session, *route); + strip = new MixerStrip (*this, *session, route); strips.push_back (strip); strip->set_width (_strip_width); @@ -310,7 +310,7 @@ void Mixer_UI::follow_strip_selection () { for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) { - (*i)->set_selected (_selection.selected (&(*i)->route())); + (*i)->set_selected (_selection.selected ((*i)->route())); } } @@ -324,13 +324,13 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip) at the same time. */ - if (_selection.selected (&strip->route())) { - _selection.remove (&strip->route()); + if (_selection.selected (strip->route())) { + _selection.remove (strip->route()); } else { if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { - _selection.add (&strip->route()); + _selection.add (strip->route()); } else { - _selection.set (&strip->route()); + _selection.set (strip->route()); } } } @@ -444,7 +444,7 @@ Mixer_UI::set_all_strips_visibility (bool yn) continue; } - if (strip->route().master() || strip->route().control()) { + if (strip->route()->master() || strip->route()->control()) { continue; } @@ -472,11 +472,11 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn) continue; } - if (strip->route().master() || strip->route().control()) { + if (strip->route()->master() || strip->route()->control()) { continue; } - AudioTrack* at = dynamic_cast<AudioTrack*> (&strip->route()); + AudioTrack* at = strip->audio_track(); switch (tracks) { case 0: @@ -570,11 +570,11 @@ Mixer_UI::redisplay_track_list () if (visible) { strip->set_marked_for_display (true); - strip->route().set_order_key (N_("signal"), order); + strip->route()->set_order_key (N_("signal"), order); if (strip->packed()) { - if (strip->route().master() || strip->route().control()) { + if (strip->route()->master() || strip->route()->control()) { out_packer.reorder_child (*strip, -1); } else { strip_packer.reorder_child (*strip, -1); /* put at end */ @@ -582,7 +582,7 @@ Mixer_UI::redisplay_track_list () } else { - if (strip->route().master() || strip->route().control()) { + if (strip->route()->master() || strip->route()->control()) { out_packer.pack_start (*strip, false, false); } else { strip_packer.pack_start (*strip, false, false); @@ -593,7 +593,7 @@ Mixer_UI::redisplay_track_list () } else { - if (strip->route().master() || strip->route().control()) { + if (strip->route()->master() || strip->route()->control()) { /* do nothing, these cannot be hidden */ } else { strip_packer.remove (*strip); @@ -604,7 +604,7 @@ Mixer_UI::redisplay_track_list () } struct SignalOrderRouteSorter { - bool operator() (Route* a, Route* b) { + bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { /* use of ">" forces the correct sort order */ return a->order_key ("signal") < b->order_key ("signal"); } @@ -613,16 +613,17 @@ struct SignalOrderRouteSorter { void Mixer_UI::initial_track_display () { - Session::RouteList routes = session->get_routes(); + boost::shared_ptr<Session::RouteList> routes = session->get_routes(); + Session::RouteList copy (*routes); SignalOrderRouteSorter sorter; - routes.sort (sorter); + copy.sort (sorter); no_track_list_redisplay = true; track_model->clear (); - for (Session::RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (Session::RouteList::iterator i = copy.begin(); i != copy.end(); ++i) { add_strip (*i); } @@ -670,7 +671,7 @@ Mixer_UI::track_display_button_press (GdkEventButton* ev) MixerStrip* strip = (*iter)[track_columns.strip]; if (strip) { - if (!strip->route().master() && !strip->route().control()) { + if (!strip->route()->master() && !strip->route()->control()) { bool visible = (*iter)[track_columns.visible]; (*iter)[track_columns.visible] = !visible; } @@ -715,7 +716,7 @@ Mixer_UI::strip_name_changed (void* src, MixerStrip* mx) for (i = rows.begin(); i != rows.end(); ++i) { if ((*i)[track_columns.strip] == mx) { - (*i)[track_columns.text] = mx->route().name(); + (*i)[track_columns.text] = mx->route()->name(); return; } } diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 5108df6014..6fe4120427 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -33,8 +33,9 @@ #include <gtkmm/menu.h> #include <gtkmm/treeview.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/io.h> #include "keyboard_target.h" @@ -110,7 +111,7 @@ class Mixer_UI : public Gtk::Window bool strip_scroller_button_release (GdkEventButton*); - void add_strip (ARDOUR::Route*); + void add_strip (boost::shared_ptr<ARDOUR::Route>); void remove_strip (MixerStrip *); void hide_all_strips (bool with_select); @@ -193,7 +194,7 @@ class Mixer_UI : public Gtk::Window } Gtk::TreeModelColumn<bool> visible; Gtk::TreeModelColumn<Glib::ustring> text; - Gtk::TreeModelColumn<ARDOUR::Route*> route; + Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route; Gtk::TreeModelColumn<MixerStrip*> strip; }; diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc index d4c2715742..b7fc7e746e 100644 --- a/gtk2_ardour/option_editor.cc +++ b/gtk2_ardour/option_editor.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2001 Paul Davis + Copyright (C) 2001-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include <pbd/whitespace.h> +#include <ardour/audio_library.h> #include <ardour/session.h> #include <ardour/audioengine.h> #include <ardour/configuration.h> @@ -59,9 +60,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui) /* Paths */ path_table (11, 2), - sfdb_path_columns(), - sfdb_paths(ListStore::create(sfdb_path_columns)), - sfdb_path_view(sfdb_paths), + sfdb_path_view(), /* Fades */ @@ -163,7 +162,6 @@ OptionEditor::set_session (Session *s) return; } - click_path_entry.set_sensitive (true); click_emphasis_path_entry.set_sensitive (true); session_raid_entry.set_sensitive (true); @@ -251,13 +249,19 @@ OptionEditor::setup_path_options() path_table.attach(*label, 0, 1, 2, 3, FILL|EXPAND, FILL); path_table.attach(sfdb_path_view, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, FILL); - sfdb_path_view.append_column(_("Paths"), sfdb_path_columns.paths); - sfdb_path_view.set_size_request(-1, 100); + sfdb_path_view.set_paths(Library->get_paths()); + sfdb_path_view.PathsUpdated.connect (mem_fun(*this, &OptionEditor::sfdb_paths_changed)); path_table.show_all(); } void +OptionEditor::sfdb_paths_changed () +{ + Library->set_paths (sfdb_path_view.get_paths()); +} + +void OptionEditor::add_session_paths () { click_path_entry.set_sensitive (true); diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h index b9690b02e2..1331d3126e 100644 --- a/gtk2_ardour/option_editor.h +++ b/gtk2_ardour/option_editor.h @@ -33,6 +33,8 @@ #include <gtkmm/radiobutton.h> #include <gtkmm/comboboxtext.h> +#include <gtkmm2ext/pathlist.h> + #include <ardour/session.h> #include "ardour_dialog.h" @@ -70,24 +72,16 @@ class OptionEditor : public Gtk::Dialog /* paths */ - Gtk::Table path_table; - Gtk::Entry session_raid_entry; - - struct SoundFilePathColumns : public Gtk::TreeModel::ColumnRecord { - public: - SoundFilePathColumns() { add (paths); } - Gtk::TreeModelColumn<std::string> paths; - - }; + Gtk::Table path_table; + Gtk::Entry session_raid_entry; - SoundFilePathColumns sfdb_path_columns; - Glib::RefPtr<Gtk::ListStore> sfdb_paths; - Gtk::TreeView sfdb_path_view; + Gtkmm2ext::PathList sfdb_path_view; void setup_path_options(); void add_session_paths (); void remove_session_paths (); void raid_path_changed (); + void sfdb_paths_changed (); /* fades */ diff --git a/gtk2_ardour/pan_automation_time_axis.cc b/gtk2_ardour/pan_automation_time_axis.cc index 73d0f7f1aa..3169f65059 100644 --- a/gtk2_ardour/pan_automation_time_axis.cc +++ b/gtk2_ardour/pan_automation_time_axis.cc @@ -28,6 +28,7 @@ #include "pan_automation_time_axis.h" #include "automation_line.h" #include "canvas_impl.h" +#include "route_ui.h" #include "i18n.h" @@ -35,11 +36,15 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; -PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n) +PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e, + TimeAxisView& parent, Canvas& canvas, std::string n) : AxisView (s), AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("pan"), "") { + multiline_selector.set_name ("PanAutomationLineSelector"); + + controls_table.attach (multiline_selector, 1, 5, 1, 2, Gtk::EXPAND, Gtk::EXPAND); } PanAutomationTimeAxisView::~PanAutomationTimeAxisView () @@ -54,14 +59,19 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv return; } + int line_index = 0; + if (lines.size() > 1) { + line_index = multiline_selector.get_active_row_number(); - Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true); - - msg->set_text (_("You can't graphically edit panning of more than stream")); - msg->touch (); + if (line_index < 0 || line_index >= (int)lines.size()) { + Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true); - return; + msg->set_text (_("You need to select which line to edit")); + msg->touch (); + + return; + } } double x = 0; @@ -76,7 +86,7 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv lines.front()->view_to_model_y (y); - AutomationList& alist (lines.front()->the_list()); + AutomationList& alist (lines[line_index]->the_list()); _session.begin_reversible_command (_("add pan automation event")); XMLNode &before = alist.get_state(); @@ -88,9 +98,56 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv } void +PanAutomationTimeAxisView::clear_lines () +{ + AutomationTimeAxisView::clear_lines(); + multiline_selector.clear(); +} + +void +PanAutomationTimeAxisView::add_line (AutomationLine& line) +{ + char buf[32]; + snprintf(buf,32,"Line %u",lines.size()+1); + multiline_selector.append_text(buf); + + if (lines.empty()) { + multiline_selector.set_active(0); + } + + if (lines.size() + 1 > 1 && (height_style != Small && height_style != Smaller)) { + multiline_selector.show(); + } else { + multiline_selector.hide(); + + } + + AutomationTimeAxisView::add_line(line); +} + +void +PanAutomationTimeAxisView::set_height (TimeAxisView::TrackHeight th) +{ + AutomationTimeAxisView::set_height(th); + + switch (th) { + case Largest: + case Large: + case Larger: + case Normal: + if (lines.size() > 1) { + multiline_selector.show(); + break; + } + default: + multiline_selector.hide(); + } +} + +void PanAutomationTimeAxisView::set_automation_state (AutoState state) { if (!ignore_state_request) { - route.panner().set_automation_state (state); + route->panner().set_automation_state (state); } } diff --git a/gtk2_ardour/pan_automation_time_axis.h b/gtk2_ardour/pan_automation_time_axis.h index b35ee67735..ca4a4db8e7 100644 --- a/gtk2_ardour/pan_automation_time_axis.h +++ b/gtk2_ardour/pan_automation_time_axis.h @@ -4,27 +4,36 @@ #include "canvas.h" #include "automation_time_axis.h" +#include <gtkmm/comboboxtext.h> + namespace ARDOUR { class Redirect; } class PanAutomationTimeAxisView : public AutomationTimeAxisView { - public: - PanAutomationTimeAxisView (ARDOUR::Session&, - ARDOUR::Route&, - PublicEditor&, - TimeAxisView& parent_axis, - ArdourCanvas::Canvas& canvas, - std::string name); - - ~PanAutomationTimeAxisView(); - - void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double); - - private: - void automation_changed (); - void set_automation_state (ARDOUR::AutoState); + public: + PanAutomationTimeAxisView (ARDOUR::Session&, + boost::shared_ptr<ARDOUR::Route>, + PublicEditor&, + TimeAxisView& parent_axis, + ArdourCanvas::Canvas& canvas, + std::string name); + + ~PanAutomationTimeAxisView(); + + void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double); + + void clear_lines (); + void add_line (AutomationLine&); + void set_height (TimeAxisView::TrackHeight); + + protected: + Gtk::ComboBoxText multiline_selector; + + private: + void automation_changed (); + void set_automation_state (ARDOUR::AutoState); }; #endif /* __ardour_gtk_pan_automation_time_axis_h__ */ diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index 63a19867a8..ccce2ec9f1 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -14,8 +14,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ */ #include <limits.h> @@ -47,7 +45,7 @@ using namespace Gtk; using namespace sigc; -PannerUI::PannerUI (IO& io, Session& s) +PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s) : _io (io), _session (s), hAdjustment(0.0, 0.0, 0.0), @@ -87,13 +85,13 @@ PannerUI::PannerUI (IO& io, Session& s) using namespace Menu_Helpers; pan_astate_menu.items().push_back (MenuElem (_("Off"), - bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Off))); + bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Off))); pan_astate_menu.items().push_back (MenuElem (_("Play"), - bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Play))); + bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Play))); pan_astate_menu.items().push_back (MenuElem (_("Write"), - bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Write))); + bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Write))); pan_astate_menu.items().push_back (MenuElem (_("Touch"), - bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Touch))); + bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Touch))); pan_astyle_menu.items().push_back (MenuElem (_("Trim"))); pan_astyle_menu.items().push_back (MenuElem (_("Abs"))); @@ -143,9 +141,9 @@ PannerUI::PannerUI (IO& io, Session& s) set_width(Narrow); - _io.panner().Changed.connect (mem_fun(*this, &PannerUI::panner_changed)); - _io.panner().LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage)); - _io.panner().StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state)); + _io->panner().Changed.connect (mem_fun(*this, &PannerUI::panner_changed)); + _io->panner().LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage)); + _io->panner().StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state)); pan_changed (0); update_pan_sensitive (); @@ -165,7 +163,7 @@ PannerUI::panning_link_button_release (GdkEventButton* ev) { cerr << "link release\n"; if (!ignore_toggle) { - _io.panner().set_linked (!_io.panner().linked()); + _io->panner().set_linked (!_io->panner().linked()); } return true; } @@ -173,12 +171,12 @@ PannerUI::panning_link_button_release (GdkEventButton* ev) void PannerUI::panning_link_direction_clicked() { - switch (_io.panner().link_direction()) { + switch (_io->panner().link_direction()) { case Panner::SameDirection: - _io.panner().set_link_direction (Panner::OppositeDirection); + _io->panner().set_link_direction (Panner::OppositeDirection); break; default: - _io.panner().set_link_direction (Panner::SameDirection); + _io->panner().set_link_direction (Panner::SameDirection); break; } } @@ -188,7 +186,7 @@ PannerUI::update_pan_linkage () { ENSURE_GUI_THREAD(mem_fun(*this, &PannerUI::update_pan_linkage)); - bool x = _io.panner().linked(); + bool x = _io->panner().linked(); bool bx = panning_link_button.get_active(); if (x != bx) { @@ -200,7 +198,7 @@ PannerUI::update_pan_linkage () panning_link_direction_button.set_sensitive (x); - switch (_io.panner().link_direction()) { + switch (_io->panner().link_direction()) { case Panner::SameDirection: panning_link_direction_button.set_image (*(manage (new Image (get_xpm ("forwardblarrow.xpm"))))); break; @@ -278,7 +276,7 @@ PannerUI::update_pan_state () void PannerUI::setup_pan () { - uint32_t nouts = _io.n_outputs (); + uint32_t nouts = _io->n_outputs (); if (nouts == 0 || nouts == 1) { @@ -292,7 +290,7 @@ PannerUI::setup_pan () } else if (nouts == 2) { vector<Adjustment*>::size_type asz; - uint32_t npans = _io.panner().size(); + uint32_t npans = _io->panner().size(); while (!pan_adjustments.empty()) { delete pan_bars.back(); @@ -308,34 +306,26 @@ PannerUI::setup_pan () /* initialize adjustment with current value of panner */ - _io.panner()[asz]->get_position (x); + _io->panner()[asz]->get_position (x); pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1)); pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz)); - _io.panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz)); + _io->panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz)); bc = new BarController (*pan_adjustments[asz], - &_io.panner()[asz]->midi_control(), + _io->panner()[asz]->control(), bind (mem_fun(*this, &PannerUI::pan_printer), pan_adjustments[asz])); - if (_session.midi_port()) { - _io.panner()[asz]->reset_midi_control (_session.midi_port(), true); - } - bc->set_name ("PanSlider"); bc->set_shadow_type (Gtk::SHADOW_NONE); bc->set_style (BarController::Line); - bc->StartGesture.connect (bind (mem_fun (_io, &IO::start_pan_touch), (uint32_t) asz)); - bc->StopGesture.connect (bind (mem_fun (_io, &IO::end_pan_touch), (uint32_t) asz)); + bc->StartGesture.connect (bind (mem_fun (*_io, &IO::start_pan_touch), (uint32_t) asz)); + bc->StopGesture.connect (bind (mem_fun (*_io, &IO::end_pan_touch), (uint32_t) asz)); char buf[64]; -#ifdef __APPLE__ - snprintf (buf, sizeof (buf), _("panner for channel %lu"), asz + 1); -#else - snprintf (buf, sizeof (buf), _("panner for channel %u"), asz + 1); -#endif + snprintf (buf, sizeof (buf), _("panner for channel %zu"), asz + 1); ARDOUR_UI::instance()->tooltips().set_tip (bc->event_widget(), buf); bc->event_widget().signal_button_release_event().connect @@ -379,13 +369,13 @@ PannerUI::setup_pan () } if (panner == 0) { - panner = new Panner2d (_io.panner(), w, 61); + panner = new Panner2d (_io->panner(), w, 61); panner->set_name ("MixerPanZone"); panner->show (); } update_pan_sensitive (); - panner->reset (_io.n_inputs()); + panner->reset (_io->n_inputs()); panner->set_size_request (w, 61); /* and finally, add it to the panner frame */ @@ -428,7 +418,7 @@ PannerUI::build_pan_menu (uint32_t which) /* set state first, connect second */ - (dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io.panner()[which]->muted()); + (dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner()[which]->muted()); (dynamic_cast<CheckMenuItem*> (&items.back()))->signal_toggled().connect (bind (mem_fun(*this, &PannerUI::pan_mute), which)); @@ -437,7 +427,7 @@ PannerUI::build_pan_menu (uint32_t which) /* set state first, connect second */ - bypass_menu_item->set_active (_io.panner().bypassed()); + bypass_menu_item->set_active (_io->panner().bypassed()); bypass_menu_item->signal_toggled().connect (mem_fun(*this, &PannerUI::pan_bypass_toggle)); items.push_back (MenuElem (_("Reset"), mem_fun(*this, &PannerUI::pan_reset))); @@ -448,15 +438,15 @@ PannerUI::build_pan_menu (uint32_t which) void PannerUI::pan_mute (uint32_t which) { - StreamPanner* sp = _io.panner()[which]; + StreamPanner* sp = _io->panner()[which]; sp->set_muted (!sp->muted()); } void PannerUI::pan_bypass_toggle () { - if (bypass_menu_item && (_io.panner().bypassed() != bypass_menu_item->get_active())) { - _io.panner().set_bypassed (!_io.panner().bypassed()); + if (bypass_menu_item && (_io->panner().bypassed() != bypass_menu_item->get_active())) { + _io->panner().set_bypassed (!_io->panner().bypassed()); } } @@ -468,11 +458,11 @@ PannerUI::pan_reset () void PannerUI::effective_pan_display () { - if (_io.panner().empty()) { + if (_io->panner().empty()) { return; } - switch (_io.n_outputs()) { + switch (_io->n_outputs()) { case 0: case 1: /* relax */ @@ -495,7 +485,7 @@ PannerUI::pan_changed (void *src) return; } - switch (_io.panner().size()) { + switch (_io->panner().size()) { case 0: panning_link_direction_button.set_sensitive (false); panning_link_button.set_sensitive (false); @@ -509,7 +499,7 @@ PannerUI::pan_changed (void *src) panning_link_button.set_sensitive (true); } - uint32_t nouts = _io.n_outputs(); + uint32_t nouts = _io->n_outputs(); switch (nouts) { case 0: @@ -530,11 +520,11 @@ PannerUI::pan_changed (void *src) void PannerUI::pan_adjustment_changed (uint32_t which) { - if (!in_pan_update && which < _io.panner().size()) { + if (!in_pan_update && which < _io->panner().size()) { float xpos; float val = pan_adjustments[which]->get_value (); - _io.panner()[which]->get_position (xpos); + _io->panner()[which]->get_position (xpos); /* add a kinda-sorta detent for the middle */ @@ -551,7 +541,7 @@ PannerUI::pan_adjustment_changed (uint32_t which) if (!Panner::equivalent (val, xpos)) { - _io.panner()[which]->set_position (val); + _io->panner()[which]->set_position (val); /* XXX the panner objects have no access to the session, so do this here. ick. @@ -566,11 +556,11 @@ PannerUI::pan_value_changed (uint32_t which) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which)); - if (_io.n_outputs() > 1 && which < _io.panner().size()) { + if (_io->n_outputs() > 1 && which < _io->panner().size()) { float xpos; float val = pan_adjustments[which]->get_value (); - _io.panner()[which]->get_position (xpos); + _io->panner()[which]->get_position (xpos); if (!Panner::equivalent (val, xpos)) { in_pan_update = true; @@ -596,14 +586,14 @@ PannerUI::update_pan_bars (bool only_if_aplay) float xpos, val; if (only_if_aplay) { - AutomationList& alist (_io.panner()[n]->automation()); + AutomationList& alist (_io->panner()[n]->automation()); if (!alist.automation_playback()) { continue; } } - _io.panner()[n]->get_effective_position (xpos); + _io->panner()[n]->get_effective_position (xpos); val = (*i)->get_value (); if (!Panner::equivalent (val, xpos)) { @@ -634,9 +624,9 @@ PannerUI::pan_printer (char *buf, uint32_t len, Adjustment* adj) void PannerUI::update_pan_sensitive () { - bool sensitive = !(_io.panner().automation_state() & Play); + bool sensitive = !(_io->panner().automation_state() & Play); - switch (_io.n_outputs()) { + switch (_io->n_outputs()) { case 0: case 1: break; @@ -697,10 +687,10 @@ PannerUI::pan_automation_style_changed () switch (_width) { case Wide: - pan_automation_style_button.set_label (astyle_string(_io.panner().automation_style())); + pan_automation_style_button.set_label (astyle_string(_io->panner().automation_style())); break; case Narrow: - pan_automation_style_button.set_label (short_astyle_string(_io.panner().automation_style())); + pan_automation_style_button.set_label (short_astyle_string(_io->panner().automation_style())); break; } } @@ -714,10 +704,10 @@ PannerUI::pan_automation_state_changed () switch (_width) { case Wide: - pan_automation_state_button.set_label (astate_string(_io.panner().automation_state())); + pan_automation_state_button.set_label (astate_string(_io->panner().automation_state())); break; case Narrow: - pan_automation_state_button.set_label (short_astate_string(_io.panner().automation_state())); + pan_automation_state_button.set_label (short_astate_string(_io->panner().automation_state())); break; } @@ -726,11 +716,11 @@ PannerUI::pan_automation_state_changed () here. */ - if (_io.panner().empty()) { + if (_io->panner().empty()) { return; } - x = (_io.panner().front()->automation().automation_state() != Off); + x = (_io->panner().front()->automation().automation_state() != Off); if (pan_automation_state_button.get_active() != x) { ignore_toggle = true; diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index 80b14465cf..7658978233 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -31,8 +31,8 @@ #include <gtkmm/togglebutton.h> #include <gtkmm/button.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/click_box.h> +#include <gtkmm2ext/slider_controller.h> #include "enums.h" @@ -55,7 +55,7 @@ namespace Gtk { class PannerUI : public Gtk::HBox { public: - PannerUI (ARDOUR::IO&, ARDOUR::Session&); + PannerUI (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&); ~PannerUI (); void pan_changed (void *); @@ -72,7 +72,7 @@ class PannerUI : public Gtk::HBox private: friend class MixerStrip; - ARDOUR::IO& _io; + boost::shared_ptr<ARDOUR::IO> _io; ARDOUR::Session& _session; bool ignore_toggle; diff --git a/gtk2_ardour/pixmaps/tool_audition.xpm b/gtk2_ardour/pixmaps/tool_audition.xpm new file mode 100644 index 0000000000..d6f2ccd127 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_audition.xpm @@ -0,0 +1,19 @@ +/* XPM */ +static char * tool_audition_xpm[] = { +"16 12 4 1", +" c None", +". c #000000", +"+ c #ECECEC", +"@ c #FFFFFF", +" .. ", +" .+. . ", +" .++. .@. ", +"....+@+... .@. ", +".+++@@+..@. .@.", +".+@@@@+. .@. .@.", +".+@@@@+. .@. .@.", +".+++@@+..@. .@.", +"....+@+... .@. ", +" .++. .@. ", +" .+. . ", +" .. "}; diff --git a/gtk2_ardour/pixmaps/tool_gain.xpm b/gtk2_ardour/pixmaps/tool_gain.xpm new file mode 100644 index 0000000000..480426fab8 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_gain.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * tool_gain_xpm[] = { +"16 12 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"... ", +".++.. ", +"...++. ", +" ..+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+.. ", +" .++.....", +" ..++++.", +" ....."}; diff --git a/gtk2_ardour/pixmaps/tool_object.xpm b/gtk2_ardour/pixmaps/tool_object.xpm new file mode 100644 index 0000000000..3d18ab8af7 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_object.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * tool_object_xpm[] = { +"16 12 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ... ", +" .+. ", +" .+. ", +" .+. ", +" .+..... ", +" .+.+.+... ", +" ...+.+.+.+. ", +" .+.+++++++. ", +" .+++++++++. ", +" ..+++++++.. ", +" ...+++++. ", +" .+++++. "}; diff --git a/gtk2_ardour/pixmaps/tool_range.xpm b/gtk2_ardour/pixmaps/tool_range.xpm new file mode 100644 index 0000000000..75ee865ca2 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_range.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * tool_range_xpm[] = { +"16 12 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +"... ...", +".+. .. .. .+.", +".+. .+. .+. .+.", +".+..+. .+..+.", +".+.++......++.+.", +".++++++++++++++.", +".+.++......++.+.", +".+..+. .+..+.", +".+. .+. .+. .+.", +".+. .. .. .+.", +".+. .+.", +"... ..."}; diff --git a/gtk2_ardour/pixmaps/tool_stretch.xpm b/gtk2_ardour/pixmaps/tool_stretch.xpm new file mode 100644 index 0000000000..77943cd7d4 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_stretch.xpm @@ -0,0 +1,18 @@ +/* XPM */ +static char * tool_stretch_xpm[] = { +"16 12 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" .. .. ", +" .+. .+. ", +".++..........++.", +"++++++++++++++++", +".++..........++.", +" .+. .+. ", +" .. .. ", +" + + + + ", +" ++ +++ + + +++ ", +"++++++++++++++++", +" ++ + ++ + + ", +" + + + + "}; diff --git a/gtk2_ardour/pixmaps/tool_zoom.xpm b/gtk2_ardour/pixmaps/tool_zoom.xpm new file mode 100644 index 0000000000..581363f3f4 --- /dev/null +++ b/gtk2_ardour/pixmaps/tool_zoom.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * tool_zoom_xpm[] = { +"16 12 14 1", +" c None", +". c #000000", +"+ c #474747", +"@ c #E7E7E7", +"# c #F6F6F6", +"$ c #DCDCDC", +"% c #FFFFFF", +"& c #DFDFDF", +"* c #D7D7D7", +"= c #D6D6D6", +"- c #040404", +"; c #070707", +"> c #060606", +", c #050505", +" ... ", +" +.@#$.+ ", +" .%%%%%. ", +" .&%%%%%*. ", +" .#%%%%%#. ", +" .$%%%%%&. ", +" .%%%%%.+ ", +" +.*#=... ", +" ...+... ", +" -.; ", +" >.- ", +" ,. "}; diff --git a/gtk2_ardour/pixmaps/zoom_full.xpm b/gtk2_ardour/pixmaps/zoom_full.xpm new file mode 100644 index 0000000000..5564074875 --- /dev/null +++ b/gtk2_ardour/pixmaps/zoom_full.xpm @@ -0,0 +1,30 @@ +/* XPM */ +static char * zoom_full_xpm[] = { +"12 12 15 1", +" c None", +". c #000000", +"+ c #474747", +"@ c #E7E7E7", +"# c #F6F6F6", +"$ c #DCDCDC", +"% c #ACACAC", +"& c #FFFFFF", +"* c #DFDFDF", +"= c #D7D7D7", +"- c #D6D6D6", +"; c #040404", +"> c #070707", +", c #060606", +"' c #050505", +" ... ", +" +.@#$.+ ", +" .%&&&%. ", +".*..&..=. ", +".#.&&&.#. ", +".$..&..*. ", +" .%&&&%.+ ", +" +.=#-... ", +" ...+... ", +" ;.> ", +" ,.;", +" '."}; diff --git a/gtk2_ardour/pixmaps/zoom_in.xpm b/gtk2_ardour/pixmaps/zoom_in.xpm new file mode 100644 index 0000000000..1f8d4e8273 --- /dev/null +++ b/gtk2_ardour/pixmaps/zoom_in.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * zoom_in_xpm[] = { +"12 12 14 1", +" c None", +". c #000000", +"+ c #474747", +"@ c #E7E7E7", +"# c #F6F6F6", +"$ c #DCDCDC", +"% c #FFFFFF", +"& c #DFDFDF", +"* c #D7D7D7", +"= c #D6D6D6", +"- c #040404", +"; c #070707", +"> c #060606", +", c #050505", +" ... ", +" +.@#$.+ ", +" .%%.%%. ", +".&%%.%%*. ", +".#.....#. ", +".$%%.%%&. ", +" .%%.%%.+ ", +" +.*#=... ", +" ...+... ", +" -.; ", +" >.-", +" ,."}; diff --git a/gtk2_ardour/pixmaps/zoom_out.xpm b/gtk2_ardour/pixmaps/zoom_out.xpm new file mode 100644 index 0000000000..ea50d145ad --- /dev/null +++ b/gtk2_ardour/pixmaps/zoom_out.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * zoom_out_xpm[] = { +"12 12 14 1", +" c None", +". c #000000", +"+ c #474747", +"@ c #E7E7E7", +"# c #F6F6F6", +"$ c #DCDCDC", +"% c #FFFFFF", +"& c #DFDFDF", +"* c #D7D7D7", +"= c #D6D6D6", +"- c #040404", +"; c #070707", +"> c #060606", +", c #050505", +" ... ", +" +.@#$.+ ", +" .%%%%%. ", +".&%%%%%*. ", +".#.....#. ", +".$%%%%%&. ", +" .%%%%%.+ ", +" +.*#=... ", +" ...+... ", +" -.; ", +" >.-", +" ,."}; diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc index f1a975d5dc..8eaac7cb9d 100644 --- a/gtk2_ardour/playlist_selector.cc +++ b/gtk2_ardour/playlist_selector.cc @@ -90,13 +90,13 @@ void PlaylistSelector::show_for (RouteUI* ruix) { vector<const char*> item; - AudioDiskstream* this_ds; + Diskstream* this_ds; string str; rui = ruix; str = _("ardour: playlist for "); - str += rui->route().name(); + str += rui->route()->name(); set_title (str); @@ -116,7 +116,7 @@ PlaylistSelector::show_for (RouteUI* ruix) for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) { - AudioDiskstream* ds = session->diskstream_by_id (x->first); + Diskstream* ds = session->diskstream_by_id (x->first); if (ds == 0) { continue; @@ -189,7 +189,7 @@ PlaylistSelector::add_playlist_to_map (Playlist *pl) if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) { - pair<ARDOUR::id_t,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>); + pair<PBD::ID,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>); x = dspl_map.insert (dspl_map.end(), newp); } @@ -223,7 +223,7 @@ PlaylistSelector::selection_changed () TreeModel::iterator iter = tree.get_selection()->get_selected(); - if (!iter) { + if (!iter || rui == 0) { /* nothing selected */ return; } @@ -233,7 +233,7 @@ PlaylistSelector::selection_changed () AudioTrack* at; AudioPlaylist* apl; - if ((at = dynamic_cast<AudioTrack*> (&rui->route())) == 0) { + if ((at = rui->audio_track()) == 0) { /* eh? */ return; } @@ -243,7 +243,7 @@ PlaylistSelector::selection_changed () return; } - at->disk_stream().use_playlist (apl); + at->diskstream().use_playlist (apl); hide (); } diff --git a/gtk2_ardour/playlist_selector.h b/gtk2_ardour/playlist_selector.h index 863d6cc7f3..2829ba54bb 100644 --- a/gtk2_ardour/playlist_selector.h +++ b/gtk2_ardour/playlist_selector.h @@ -46,7 +46,7 @@ class PlaylistSelector : public ArdourDialog void show_for (RouteUI*); private: - typedef std::map<ARDOUR::id_t,std::list<ARDOUR::Playlist*>*> DSPL_Map; + typedef std::map<PBD::ID,std::list<ARDOUR::Playlist*>*> DSPL_Map; ARDOUR::Session* session; Gtk::ScrolledWindow scroller; diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 16796df160..e0a62b177f 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,8 +48,8 @@ PluginSelector::PluginSelector (PluginManager *mgr) manager = mgr; session = 0; - o_selected_plug = -1; - i_selected_plug = 0; + + current_selection = PluginInfo::LADSPA; lmodel = Gtk::ListStore::create(lcols); ladspa_display.set_model (lmodel); @@ -91,6 +91,25 @@ PluginSelector::PluginSelector (PluginManager *mgr) column->set_sort_column(i); } #endif + +#ifdef HAVE_COREAUDIO + aumodel = ListStore::create(aucols); + au_display.set_model (aumodel); + au_display.append_column (_("Available plugins"), aucols.name); + au_display.append_column (_("# Inputs"), aucols.ins); + au_display.append_column (_("# Outputs"), aucols.outs); + au_display.set_headers_visible (true); + au_display.set_reorderable (false); + auscroller.set_border_width(10); + auscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + auscroller.add(au_display); + + for (int i = 0; i <=2; i++) { + Gtk::TreeView::Column* column = au_display.get_column(i); + column->set_sort_column(i); + } +#endif + ascroller.set_border_width(10); ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); ascroller.add(added_list); @@ -124,35 +143,51 @@ PluginSelector::PluginSelector (PluginManager *mgr) using namespace Gtk::Notebook_Helpers; notebook.pages().push_back (TabElem (lscroller, _("LADSPA"))); + #ifdef VST_SUPPORT if (Config->get_use_vst()) { notebook.pages().push_back (TabElem (vscroller, _("VST"))); } #endif +#ifdef HAVE_COREAUDIO + notebook.pages().push_back (TabElem (auscroller, _("AudioUnit"))); +#endif + table->set_name("PluginSelectorTable"); ladspa_display.set_name("PluginSelectorDisplay"); //ladspa_display.set_name("PluginSelectorList"); added_list.set_name("PluginSelectorList"); ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); + ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed)); + #ifdef VST_SUPPORT if (Config->get_use_vst()) { vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed)); } #endif - + +#ifdef HAVE_COREAUDIO + au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked)); + au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed)); +#endif + btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked)); btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked)); btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked)); - ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed)); added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed)); input_refiller (); + #ifdef VST_SUPPORT vst_refiller (); #endif + +#ifdef HAVE_COREAUDIO + au_refiller (); +#endif } void @@ -189,13 +224,11 @@ void PluginSelector::input_refiller () { guint row; - list<PluginInfo *> &plugs = manager->ladspa_plugin_info (); - list<PluginInfo *>::iterator i; + PluginInfoList &plugs = manager->ladspa_plugin_info (); + PluginInfoList::iterator i; char ibuf[16], obuf[16]; lmodel->clear(); -#ifdef VST_SUPPORT - vmodel->clear(); -#endif + // Insert into GTK list for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); @@ -224,9 +257,10 @@ void PluginSelector::vst_refiller () { guint row; - list<PluginInfo *> &plugs = manager->vst_plugin_info (); - list<PluginInfo *>::iterator i; + PluginInfoList &plugs = manager->vst_plugin_info (); + PluginInfoList::iterator i; char ibuf[16], obuf[16]; + vmodel->clear(); // Insert into GTK list for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { @@ -242,18 +276,75 @@ PluginSelector::vst_refiller () } vmodel->set_sort_column (0, Gtk::SORT_ASCENDING); } -#endif void -PluginSelector::use_plugin (PluginInfo* pi) +PluginSelector::vst_display_selection_changed() { - list<PluginInfo *>::iterator i; + if (vst_display.get_selection()->count_selected_rows() != 0) { + btn_add->set_sensitive (true); + } else { + btn_add->set_sensitive (false); + } + + current_selection = PluginInfo::VST; +} + +#endif //VST_SUPPORT - if (pi == 0 || session == 0) { +#ifdef HAVE_COREAUDIO + +void +PluginSelector::_au_refiller (void *arg) +{ + ((PluginSelector *) arg)->au_refiller (); +} + +void +PluginSelector::au_refiller () +{ + guint row; + PluginInfoList plugs (AUPluginInfo::discover ()); + PluginInfoList::iterator i; + char ibuf[16], obuf[16]; + aumodel->clear(); + + // Insert into GTK list + for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) { + + snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs); + snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs); + + Gtk::TreeModel::Row newrow = *(aumodel->append()); + newrow[aucols.name] = (*i)->name.c_str(); + newrow[aucols.ins] = ibuf; + newrow[aucols.outs] = obuf; + newrow[aucols.plugin] = *i; + } + aumodel->set_sort_column (0, Gtk::SORT_ASCENDING); +} + +void +PluginSelector::au_display_selection_changed() +{ + if (au_display.get_selection()->count_selected_rows() != 0) { + btn_add->set_sensitive (true); + } else { + btn_add->set_sensitive (false); + } + + current_selection = PluginInfo::AudioUnit; +} + +#endif //HAVE_COREAUDIO + +void +PluginSelector::use_plugin (PluginInfoPtr pi) +{ + if (session == 0) { return; } - Plugin *plugin = manager->load (*session, pi); + PluginPtr plugin = pi->load (*session); if (plugin) { PluginCreated (plugin); @@ -263,46 +354,54 @@ PluginSelector::use_plugin (PluginInfo* pi) void PluginSelector::btn_add_clicked() { - bool vst = notebook.get_current_page(); // 0 = LADSPA, 1 = VST std::string name; - ARDOUR::PluginInfo *pi; + PluginInfoPtr pi; Gtk::TreeModel::Row newrow = *(amodel->append()); - if (vst) { + Gtk::TreeModel::Row row; + + switch (current_selection) { + case PluginInfo::LADSPA: + row = *(ladspa_display.get_selection()->get_selected()); + name = row[lcols.name]; + pi = row[lcols.plugin]; + break; + case PluginInfo::VST: #ifdef VST_SUPPORT - Gtk::TreeModel::Row row = *(vst_display.get_selection()->get_selected()); - name = row[vcols.name]; - pi = row[vcols.plugin]; - added_plugins.push_back (row[vcols.plugin]); + row = *(vst_display.get_selection()->get_selected()); + name = row[vcols.name]; + pi = row[vcols.plugin]; #endif - } else { - Gtk::TreeModel::Row row = *(ladspa_display.get_selection()->get_selected()); - name = row[lcols.name]; - pi = row[lcols.plugin]; - added_plugins.push_back (row[lcols.plugin]); + break; + case PluginInfo::AudioUnit: +#ifdef HAVE_COREAUDIO + row = *(au_display.get_selection()->get_selected()); + name = row[aucols.name]; + pi = row[aucols.plugin]; +#endif + break; + default: + error << "Programming error. Unknown plugin selected." << endmsg; + return; } + newrow[acols.text] = name; newrow[acols.plugin] = pi; if (!amodel->children().empty()) { - set_response_sensitive (RESPONSE_APPLY, true); + set_response_sensitive (RESPONSE_APPLY, true); } } void PluginSelector::btn_remove_clicked() { - list<PluginInfo*>::iterator i; Gtk::TreeModel::iterator iter = added_list.get_selection()->get_selected(); - for (i = added_plugins.begin(); (*i) != (*iter)[acols.plugin]; ++i); - - added_plugins.erase(i); + amodel->erase(iter); if (amodel->children().empty()) { - set_response_sensitive (RESPONSE_APPLY, false); + set_response_sensitive (RESPONSE_APPLY, false); } - - } void @@ -313,28 +412,21 @@ PluginSelector::btn_update_clicked() #ifdef VST_SUPPORT vst_refiller (); #endif -} - -#ifdef VST_SUPPORT -void -PluginSelector::vst_display_selection_changed() -{ - if (vst_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } -} +#ifdef HAVE_COREAUDIO + au_refiller (); #endif +} void PluginSelector::ladspa_display_selection_changed() { - if (ladspa_display.get_selection()->count_selected_rows() != 0) { - btn_add->set_sensitive (true); - } else { - btn_add->set_sensitive (false); - } + if (ladspa_display.get_selection()->count_selected_rows() != 0) { + btn_add->set_sensitive (true); + } else { + btn_add->set_sensitive (false); + } + + current_selection = PluginInfo::LADSPA; } void @@ -351,14 +443,14 @@ int PluginSelector::run () { ResponseType r; - list<PluginInfo*>::iterator i; + TreeModel::Children::iterator i; r = (ResponseType) Dialog::run (); switch (r) { case RESPONSE_APPLY: - for (i = added_plugins.begin(); i != added_plugins.end(); ++i){ - use_plugin (*i); + for (i = amodel->children().begin(); i != amodel->children().end(); ++i) { + use_plugin ((*i)[acols.plugin]); } break; @@ -375,7 +467,5 @@ void PluginSelector::cleanup () { hide(); - added_plugins.clear(); amodel->clear(); } - diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index 125ce1b80a..583506972a 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -25,17 +25,18 @@ #include <gtkmm/treeview.h> #include <gtkmm2ext/selector.h> +#include <ardour/plugin.h> + namespace ARDOUR { class Session; class PluginManager; - class Plugin; } class PluginSelector : public ArdourDialog { public: PluginSelector (ARDOUR::PluginManager *); - sigc::signal<void,ARDOUR::Plugin *> PluginCreated; + sigc::signal<void,boost::shared_ptr<ARDOUR::Plugin> > PluginCreated; int run (); // XXX should we try not to overload the non-virtual Gtk::Dialog::run() ? @@ -44,9 +45,12 @@ class PluginSelector : public ArdourDialog private: ARDOUR::Session* session; Gtk::Notebook notebook; - Gtk::ScrolledWindow lscroller; - Gtk::ScrolledWindow vscroller; - Gtk::ScrolledWindow ascroller; + Gtk::ScrolledWindow lscroller; // ladspa + Gtk::ScrolledWindow vscroller; // vst + Gtk::ScrolledWindow auscroller; // AudioUnit + Gtk::ScrolledWindow ascroller; // Added plugins + + ARDOUR::PluginInfo::Type current_selection; // page 1 struct LadspaColumns : public Gtk::TreeModel::ColumnRecord { @@ -61,7 +65,7 @@ class PluginSelector : public ArdourDialog Gtk::TreeModelColumn<std::string> type; Gtk::TreeModelColumn<std::string> ins; Gtk::TreeModelColumn<std::string> outs; - Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin; + Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; }; LadspaColumns lcols; Glib::RefPtr<Gtk::ListStore> lmodel; @@ -76,7 +80,7 @@ class PluginSelector : public ArdourDialog add (plugin); } Gtk::TreeModelColumn<std::string> text; - Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin; + Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; }; AddedColumns acols; Glib::RefPtr<Gtk::ListStore> amodel; @@ -95,7 +99,7 @@ class PluginSelector : public ArdourDialog Gtk::TreeModelColumn<std::string> name; Gtk::TreeModelColumn<std::string> ins; Gtk::TreeModelColumn<std::string> outs; - Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin; + Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; }; VstColumns vcols; Glib::RefPtr<Gtk::ListStore> vmodel; @@ -104,16 +108,32 @@ class PluginSelector : public ArdourDialog static void _vst_refiller (void *); void vst_refiller (); void vst_display_selection_changed(); -#endif - - ARDOUR::PluginInfo* i_selected_plug; +#endif // VST_SUPPORT - // We need an integer for the output side because - // the name isn't promised to be unique. - gint o_selected_plug; +#ifdef HAVE_COREAUDIO + // page 3 + struct AUColumns : public Gtk::TreeModel::ColumnRecord { + AUColumns () { + add (name); + add (ins); + add (outs); + add (plugin); + } + Gtk::TreeModelColumn<std::string> name; + Gtk::TreeModelColumn<std::string> ins; + Gtk::TreeModelColumn<std::string> outs; + Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin; + }; + AUColumns aucols; + Glib::RefPtr<Gtk::ListStore> aumodel; + Glib::RefPtr<Gtk::TreeSelection> auselection; + Gtk::TreeView au_display; + static void _au_refiller (void *); + void au_refiller (); + void au_display_selection_changed(); +#endif //HAVE_COREAUDIO ARDOUR::PluginManager *manager; - list<ARDOUR::PluginInfo*> added_plugins; static void _input_refiller (void *); @@ -125,8 +145,9 @@ class PluginSelector : public ArdourDialog void added_list_selection_changed(); void ladspa_display_selection_changed(); void btn_apply_clicked(); - void use_plugin (ARDOUR::PluginInfo*); + void use_plugin (ARDOUR::PluginInfoPtr); void cleanup (); }; #endif // __ardour_plugin_selector_h__ + diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index 749ab9d4ac..5e5263b9ad 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -29,10 +29,10 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/fastmeter.h> -#include <gtkmm2ext/slider_controller.h> #include <gtkmm2ext/barcontroller.h> #include <gtkmm2ext/utils.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/slider_controller.h> #include <midi++/manager.h> @@ -61,19 +61,19 @@ using namespace Gtkmm2ext; using namespace Gtk; using namespace sigc; -PluginUIWindow::PluginUIWindow (AudioEngine &engine, PluginInsert& insert, bool scrollable) +PluginUIWindow::PluginUIWindow (AudioEngine &engine, boost::shared_ptr<PluginInsert> insert, bool scrollable) : ArdourDialog ("plugin ui") { - if (insert.plugin().has_editor()) { + if (insert->plugin()->has_editor()) { #ifdef VST_SUPPORT - VSTPlugin* vp; + boost::shared_ptr<VSTPlugin> vp; - if ((vp = dynamic_cast<VSTPlugin*> (&insert.plugin())) != 0) { + if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (insert->plugin())) != 0) { - VSTPluginUI* vpu = new VSTPluginUI (insert, *vp); + VSTPluginUI* vpu = new VSTPluginUI (insert, vp); _pluginui = vpu; get_vbox()->add (*vpu); @@ -104,7 +104,7 @@ PluginUIWindow::PluginUIWindow (AudioEngine &engine, PluginInsert& insert, bool add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this))); - insert.GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away)); + insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away)); if (scrollable) { gint h = _pluginui->get_preferred_height (); @@ -117,7 +117,7 @@ PluginUIWindow::~PluginUIWindow () { } -PluginUI::PluginUI (AudioEngine &engine, PluginInsert& pi, bool scrollable) +PluginUI::PluginUI (AudioEngine &engine, boost::shared_ptr<PluginInsert> pi, bool scrollable) : PlugUIBase (pi), engine(engine), button_table (initial_button_rows, initial_button_cols), @@ -165,8 +165,8 @@ PluginUI::PluginUI (AudioEngine &engine, PluginInsert& pi, bool scrollable) pack_start (hpacker, false, false); } - insert.active_changed.connect (mem_fun(*this, &PluginUI::redirect_active_changed)); - bypass_button.set_active (!insert.active()); + insert->active_changed.connect (mem_fun(*this, &PluginUI::redirect_active_changed)); + bypass_button.set_active (!insert->active()); build (engine); } @@ -233,13 +233,13 @@ PluginUI::build (AudioEngine &engine) /* find all ports. build control elements for all appropriate control ports */ - for (i = 0; i < plugin.parameter_count(); ++i) { + for (i = 0; i < plugin->parameter_count(); ++i) { - if (plugin.parameter_is_control (i)) { + if (plugin->parameter_is_control (i)) { /* Don't show latency control ports */ - if (plugin.describe_parameter (i) == X_("latency")) { + if (plugin->describe_parameter (i) == X_("latency")) { continue; } @@ -263,7 +263,7 @@ PluginUI::build (AudioEngine &engine) } } - if ((cui = build_control_ui (engine, i, plugin.get_nth_midi_control (i))) == 0) { + if ((cui = build_control_ui (engine, i, plugin->get_nth_control (i))) == 0) { error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg; continue; } @@ -326,8 +326,8 @@ PluginUI::build (AudioEngine &engine) } } - n_ins = plugin.get_info().n_inputs; - n_outs = plugin.get_info().n_outputs; + n_ins = plugin->get_info()->n_inputs; + n_outs = plugin->get_info()->n_outputs; if (box->children().empty()) { hpacker.remove (*frame); @@ -387,7 +387,7 @@ PluginUI::automation_state_changed (ControlUI* cui) { /* update button label */ - switch (insert.get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) { + switch (insert->get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) { case Off: cui->automate_button.set_label (_("Off")); break; @@ -415,17 +415,17 @@ static void integer_printer (char buf[32], Adjustment &adj, void *arg) void PluginUI::print_parameter (char *buf, uint32_t len, uint32_t param) { - plugin.print_parameter (param, buf, len); + plugin->print_parameter (param, buf, len); } PluginUI::ControlUI* -PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Controllable* mcontrol) +PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Controllable* mcontrol) { ControlUI* control_ui; Plugin::ParameterDescriptor desc; - plugin.get_parameter_descriptor (port_index, desc); + plugin->get_parameter_descriptor (port_index, desc); control_ui = manage (new ControlUI ()); control_ui->adjustment = 0; @@ -439,11 +439,11 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr control_ui->set_spacing (5); - if (plugin.parameter_is_input (port_index)) { + if (plugin->parameter_is_input (port_index)) { - LadspaPlugin* lp; + boost::shared_ptr<LadspaPlugin> lp; - if ((lp = dynamic_cast<LadspaPlugin*>(&plugin)) != 0) { + if ((lp = boost::dynamic_pointer_cast<LadspaPlugin>(plugin)) != 0) { lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index); @@ -453,7 +453,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr //control_ui->combo->set_value_in_list(true, false); set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui)); control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &PluginUI::control_combo_changed), control_ui)); - plugin.ParameterChanged.connect (bind (mem_fun (*this, &PluginUI::parameter_changed), control_ui)); + plugin->ParameterChanged.connect (bind (mem_fun (*this, &PluginUI::parameter_changed), control_ui)); control_ui->pack_start(control_ui->label, true, true); control_ui->pack_start(*control_ui->combo, false, true); @@ -478,7 +478,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &PluginUI::control_port_toggled), control_ui)); - if(plugin.get_parameter (port_index) == 1){ + if(plugin->get_parameter (port_index) == 1){ control_ui->button->set_active(true); } @@ -516,7 +516,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr } else { sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &PluginUI::print_parameter), (uint32_t) port_index); - control_ui->control = new BarController (*control_ui->adjustment, mcontrol, pslot); + control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot); // should really match the height of the text in the automation button+label control_ui->control->set_size_request (200, 22); control_ui->control->set_name (X_("PluginSlider")); @@ -529,9 +529,9 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr } if (control_ui->logarithmic) { - control_ui->adjustment->set_value(log(plugin.get_parameter(port_index))); + control_ui->adjustment->set_value(log(plugin->get_parameter(port_index))); } else{ - control_ui->adjustment->set_value(plugin.get_parameter(port_index)); + control_ui->adjustment->set_value(plugin->get_parameter(port_index)); } /* XXX memory leak: SliderController not destroyed by ControlUI @@ -552,11 +552,11 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr automation_state_changed (control_ui); - plugin.ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui)); - insert.automation_list (port_index).automation_state_changed.connect + plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui)); + insert->automation_list (port_index).automation_state_changed.connect (bind (mem_fun(*this, &PluginUI::automation_state_changed), control_ui)); - } else if (plugin.parameter_is_output (port_index)) { + } else if (plugin->parameter_is_output (port_index)) { control_ui->display = manage (new EventBox); control_ui->display->set_name ("ParameterValueDisplay"); @@ -603,20 +603,20 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr output_controls.push_back (control_ui); } - plugin.ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui)); + plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui)); return control_ui; } void PluginUI::start_touch (PluginUI::ControlUI* cui) { - insert.automation_list (cui->port_index).start_touch (); + insert->automation_list (cui->port_index).start_touch (); } void PluginUI::stop_touch (PluginUI::ControlUI* cui) { - insert.automation_list (cui->port_index).stop_touch (); + insert->automation_list (cui->port_index).stop_touch (); } void @@ -647,7 +647,7 @@ PluginUI::astate_clicked (ControlUI* cui, uint32_t port) void PluginUI::set_automation_state (AutoState state, ControlUI* cui) { - insert.set_port_automation_state (cui->port_index, state); + insert->set_port_automation_state (cui->port_index, state); } void @@ -663,7 +663,7 @@ PluginUI::control_adjustment_changed (ControlUI* cui) value = exp(value); } - insert.set_parameter (cui->port_index, (float) value); + insert->set_parameter (cui->port_index, (float) value); } void @@ -684,7 +684,7 @@ PluginUI::update_control_display (ControlUI* cui) cui->update_pending = false; - float val = plugin.get_parameter (cui->port_index); + float val = plugin->get_parameter (cui->port_index); cui->ignore_change++; if (cui->combo) { @@ -718,7 +718,7 @@ void PluginUI::control_port_toggled (ControlUI* cui) { if (!cui->ignore_change) { - insert.set_parameter (cui->port_index, cui->button->get_active()); + insert->set_parameter (cui->port_index, cui->button->get_active()); } } @@ -728,7 +728,7 @@ PluginUI::control_combo_changed (ControlUI* cui) if (!cui->ignore_change) { string value = cui->combo->get_active_text(); std::map<string,float> mapping = *cui->combo_map; - insert.set_parameter (cui->port_index, mapping[value]); + insert->set_parameter (cui->port_index, mapping[value]); } } @@ -774,7 +774,7 @@ void PluginUI::output_update () { for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) { - float val = plugin.get_parameter ((*i)->port_index); + float val = plugin->get_parameter ((*i)->port_index); char buf[32]; snprintf (buf, sizeof(buf), "%.2f", val); (*i)->display_label->set_text (buf); @@ -808,7 +808,7 @@ vector<string> PluginUI::setup_scale_values(guint32 port_index, ControlUI* cui) { vector<string> enums; - LadspaPlugin* lp = dynamic_cast<LadspaPlugin*> (&plugin); + boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin); cui->combo_map = new std::map<string, float>; lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index); @@ -827,14 +827,14 @@ PluginUI::setup_scale_values(guint32 port_index, ControlUI* cui) return enums; } -PlugUIBase::PlugUIBase (PluginInsert& pi) +PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi) : insert (pi), - plugin (insert.plugin()), + plugin (insert->plugin()), save_button(_("Add")), bypass_button (_("Bypass")) { //combo.set_use_arrows_always(true); - set_popdown_strings (combo, plugin.get_presets()); + set_popdown_strings (combo, plugin->get_presets()); combo.set_size_request (100, -1); combo.set_active_text (""); combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected)); @@ -850,7 +850,7 @@ void PlugUIBase::setting_selected() { if (combo.get_active_text().length() > 0) { - if (!plugin.load_preset(combo.get_active_text())) { + if (!plugin->load_preset(combo.get_active_text())) { warning << string_compose(_("Plugin preset %1 not found"), combo.get_active_text()) << endmsg; } } @@ -875,8 +875,8 @@ PlugUIBase::save_plugin_setting () prompter.get_result(name); if (name.length()) { - if(plugin.save_preset(name)){ - set_popdown_strings (combo, plugin.get_presets()); + if(plugin->save_preset(name)){ + set_popdown_strings (combo, plugin->get_presets()); combo.set_active_text (name); } } @@ -889,8 +889,8 @@ PlugUIBase::bypass_toggled () { bool x; - if ((x = bypass_button.get_active()) == insert.active()) { - insert.set_active (!x, this); + if ((x = bypass_button.get_active()) == insert->active()) { + insert->set_active (!x, this); } } diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index e5800e8ece..570a224b66 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -52,7 +52,7 @@ namespace ARDOUR { class Redirect; } -namespace MIDI { +namespace PBD { class Controllable; } @@ -67,7 +67,7 @@ namespace Gtkmm2ext { class PlugUIBase : public virtual sigc::trackable { public: - PlugUIBase (ARDOUR::PluginInsert&); + PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>); virtual ~PlugUIBase() {} virtual gint get_preferred_height () = 0; @@ -75,8 +75,8 @@ class PlugUIBase : public virtual sigc::trackable virtual bool stop_updating(GdkEventAny*) = 0; protected: - ARDOUR::PluginInsert& insert; - ARDOUR::Plugin& plugin; + boost::shared_ptr<ARDOUR::PluginInsert> insert; + boost::shared_ptr<ARDOUR::Plugin> plugin; Gtk::ComboBoxText combo; Gtk::Button save_button; Gtk::ToggleButton bypass_button; @@ -89,7 +89,7 @@ class PlugUIBase : public virtual sigc::trackable class PluginUI : public PlugUIBase, public Gtk::VBox { public: - PluginUI (ARDOUR::AudioEngine &, ARDOUR::PluginInsert& plug, bool scrollable=false); + PluginUI (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false); ~PluginUI (); gint get_preferred_height () { return prefheight; } @@ -174,7 +174,7 @@ class PluginUI : public PlugUIBase, public Gtk::VBox void output_update(); void build (ARDOUR::AudioEngine &); - ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, MIDI::Controllable *); + ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, PBD::Controllable *); std::vector<string> setup_scale_values(guint32 port_index, ControlUI* cui); void control_adjustment_changed (ControlUI* cui); void parameter_changed (uint32_t, float, ControlUI* cui); @@ -196,7 +196,7 @@ class PluginUI : public PlugUIBase, public Gtk::VBox class PluginUIWindow : public ArdourDialog { public: - PluginUIWindow (ARDOUR::AudioEngine &, ARDOUR::PluginInsert& insert, bool scrollable=false); + PluginUIWindow (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> insert, bool scrollable=false); ~PluginUIWindow (); PlugUIBase& pluginui() { return *_pluginui; } @@ -213,7 +213,7 @@ class PluginUIWindow : public ArdourDialog class VSTPluginUI : public PlugUIBase, public Gtk::VBox { public: - VSTPluginUI (ARDOUR::PluginInsert&, ARDOUR::VSTPlugin&); + VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::VSTPlugin>); ~VSTPluginUI (); gint get_preferred_height (); @@ -223,7 +223,7 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox int package (Gtk::Window&); private: - ARDOUR::VSTPlugin& vst; + boost::shared_ptr<ARDOUR::VSTPlugin> vst; Gtk::Socket socket; Gtk::HBox preset_box; Gtk::VBox vpacker; diff --git a/gtk2_ardour/po/SConscript b/gtk2_ardour/po/SConscript index 868f123988..d7e957b3eb 100644 --- a/gtk2_ardour/po/SConscript +++ b/gtk2_ardour/po/SConscript @@ -27,7 +27,7 @@ print "Updating pot file: " domain = gtkardour['DOMAIN'] potfile = gtkardour['POTFILE'] -poaction = Action('intltool-update -p -g=' + domain) +poaction = env.Action('intltool-update -p -g=' + domain) Execute(poaction) diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 4c12b99d7c..f70e4c20bd 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -39,7 +39,7 @@ class AutomationLine; class ControlPoint; class SelectionRect; class CrossfadeView; -class AudioTimeAxisView; +class RouteTimeAxisView; class AudioRegionView; class TempoMarker; class MeterMarker; @@ -145,10 +145,10 @@ class PublicEditor : public Gtk::Window, public Stateful { virtual bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; virtual bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; virtual bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; - virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; - virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; - virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0; - virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*) = 0; + virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0; + virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0; + virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0; + virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*) = 0; virtual bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*) = 0; virtual bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*) = 0; virtual bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*) = 0; diff --git a/gtk2_ardour/redirect_automation_line.cc b/gtk2_ardour/redirect_automation_line.cc index 8971e8ff10..1ea5013295 100644 --- a/gtk2_ardour/redirect_automation_line.cc +++ b/gtk2_ardour/redirect_automation_line.cc @@ -55,7 +55,7 @@ RedirectAutomationLine::RedirectAutomationLine (const string & name, Redirect& r /*NOTREACHED*/ } - pi->plugin().get_parameter_descriptor (_port, desc); + pi->plugin()->get_parameter_descriptor (_port, desc); upper = desc.upper; lower = desc.lower; diff --git a/gtk2_ardour/redirect_automation_time_axis.cc b/gtk2_ardour/redirect_automation_time_axis.cc index e3ce4b08c6..e527fd1d5e 100644 --- a/gtk2_ardour/redirect_automation_time_axis.cc +++ b/gtk2_ardour/redirect_automation_time_axis.cc @@ -33,7 +33,8 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; -RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n, +RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, + PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n, uint32_t prt, Redirect& rd, string state_name) : AxisView (s), diff --git a/gtk2_ardour/redirect_automation_time_axis.h b/gtk2_ardour/redirect_automation_time_axis.h index b8d94b2a3e..6976dc2358 100644 --- a/gtk2_ardour/redirect_automation_time_axis.h +++ b/gtk2_ardour/redirect_automation_time_axis.h @@ -14,7 +14,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView { public: RedirectAutomationTimeAxisView (ARDOUR::Session&, - ARDOUR::Route&, + boost::shared_ptr<ARDOUR::Route>, PublicEditor&, TimeAxisView& parent, ArdourCanvas::Canvas& canvas, diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc index f5cb9522e0..74198265d9 100644 --- a/gtk2_ardour/redirect_box.cc +++ b/gtk2_ardour/redirect_box.cc @@ -76,7 +76,7 @@ bool RedirectBox::get_colors = true; Gdk::Color* RedirectBox::active_redirect_color; Gdk::Color* RedirectBox::inactive_redirect_color; -RedirectBox::RedirectBox (Placement pcmnt, Session& sess, Route& rt, PluginSelector &plugsel, +RedirectBox::RedirectBox (Placement pcmnt, Session& sess, boost::shared_ptr<Route> rt, PluginSelector &plugsel, RouteRedirectSelection & rsel, bool owner_is_mixer) : _route(rt), _session(sess), @@ -132,7 +132,7 @@ RedirectBox::RedirectBox (Placement pcmnt, Session& sess, Route& rt, PluginSelec pack_start (redirect_eventbox, true, true); - _route.redirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects)); + _route->redirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects)); redirect_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (RedirectBox::enter_box), this)); @@ -161,10 +161,10 @@ RedirectBox::object_drop (string type, uint32_t cnt, void** ptr) /* do something with the dropped redirects */ - list<Redirect*> redirects; - + list<boost::shared_ptr<Redirect> > redirects; + for (uint32_t n = 0; n < cnt; ++n) { - redirects.push_back ((Redirect*) ptr[n]); + redirects.push_back (boost::shared_ptr<Redirect> ((Redirect*) ptr[n])); } paste_redirect_list (redirects); @@ -189,21 +189,21 @@ RedirectBox::set_width (Width w) } void -RedirectBox::remove_redirect_gui (Redirect *redirect) +RedirectBox::remove_redirect_gui (boost::shared_ptr<Redirect> redirect) { - Insert *insert = 0; - Send *send = 0; - PortInsert *port_insert = 0; + boost::shared_ptr<Insert> insert; + boost::shared_ptr<Send> send; + boost::shared_ptr<PortInsert> port_insert; - if ((insert = dynamic_cast<Insert *> (redirect)) != 0) { + if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) != 0) { - if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) { + if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) { PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui()); port_insert->set_gui (0); delete io_selector; } - } else if ((send = dynamic_cast<Send *> (insert)) != 0) { + } else if ((send = boost::dynamic_pointer_cast<Send> (insert)) != 0) { SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui()); send->set_gui (0); delete sui; @@ -268,7 +268,7 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev) TreeViewColumn* column; int cellx; int celly; - Redirect* redirect = 0; + boost::shared_ptr<Redirect> redirect; int ret = false; bool selected = false; @@ -353,32 +353,32 @@ RedirectBox::choose_plugin () } void -RedirectBox::insert_plugin_chosen (Plugin *plugin) +RedirectBox::insert_plugin_chosen (boost::shared_ptr<Plugin> plugin) { if (plugin) { - Redirect *redirect = new PluginInsert (_session, *plugin, _placement); + boost::shared_ptr<Redirect> redirect (new PluginInsert (_session, plugin, _placement)); redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)); uint32_t err_streams; - if (_route.add_redirect (redirect, this, &err_streams)) { + if (_route->add_redirect (redirect, this, &err_streams)) { wierd_plugin_dialog (*plugin, err_streams, _route); - delete redirect; + // XXX SHAREDPTR delete plugin here .. do we even need to care? } } } void -RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io) +RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr<IO> io) { ArdourDialog dialog ("wierd plugin dialog"); Label label; /* i hate this kind of code */ - if (streams > p.get_info().n_inputs) { + if (streams > p.get_info()->n_inputs) { label.set_text (string_compose (_( "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -388,9 +388,9 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io) "This makes no sense - you are throwing away\n" "part of the signal."), p.name(), - p.get_info().n_inputs, + p.get_info()->n_inputs, streams)); - } else if (streams < p.get_info().n_inputs) { + } else if (streams < p.get_info()->n_inputs) { label.set_text (string_compose (_( "You attempted to add a plugin (%1).\n" "The plugin has %2 inputs\n" @@ -401,7 +401,7 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io) "side-chain inputs. A future version of Ardour will\n" "support this type of configuration."), p.name(), - p.get_info().n_inputs, + p.get_info()->n_inputs, streams)); } else { label.set_text (string_compose (_( @@ -415,10 +415,10 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io) "\n" "Ardour does not understand what to do in such situations.\n"), p.name(), - p.get_info().n_inputs, - p.get_info().n_outputs, - io.n_inputs(), - io.n_outputs(), + p.get_info()->n_inputs, + p.get_info()->n_outputs, + io->n_inputs(), + io->n_outputs(), streams)); } @@ -436,36 +436,36 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io) void RedirectBox::choose_insert () { - Redirect *redirect = new PortInsert (_session, _placement); + boost::shared_ptr<Redirect> redirect (new PortInsert (_session, _placement)); redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)); - _route.add_redirect (redirect, this); + _route->add_redirect (redirect, this); } void RedirectBox::choose_send () { - Send *send = new Send (_session, _placement); + boost::shared_ptr<Send> send (new Send (_session, _placement)); /* XXX need redirect lock on route */ - send->ensure_io (0, _route.max_redirect_outs(), false, this); + send->ensure_io (0, _route->max_redirect_outs(), false, this); - IOSelectorWindow *ios = new IOSelectorWindow (_session, *send, false, true); + IOSelectorWindow *ios = new IOSelectorWindow (_session, send, false, true); ios->show_all (); - ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), static_cast<Redirect*>(send), ios)); + ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::static_pointer_cast<Redirect>(send), ios)); } void -RedirectBox::send_io_finished (IOSelector::Result r, Redirect* redirect, IOSelectorWindow* ios) +RedirectBox::send_io_finished (IOSelector::Result r, boost::shared_ptr<Redirect> redirect, IOSelectorWindow* ios) { switch (r) { case IOSelector::Cancelled: - delete redirect; + // delete redirect; XXX SHAREDPTR HOW TO DESTROY THE REDIRECT ? do we even need to think about it? break; case IOSelector::Accepted: - _route.add_redirect (redirect, this); + _route->add_redirect (redirect, this); break; } @@ -488,7 +488,8 @@ RedirectBox::redisplay_redirects (void *src) redirect_active_connections.clear (); redirect_name_connections.clear (); - _route.foreach_redirect (this, &RedirectBox::add_redirect_to_display); + void (RedirectBox::*pmf)(boost::shared_ptr<Redirect>) = &RedirectBox::add_redirect_to_display; + _route->foreach_redirect (this, pmf); switch (_placement) { case PreFader: @@ -501,33 +502,33 @@ RedirectBox::redisplay_redirects (void *src) } void -RedirectBox::add_redirect_to_display (Redirect *redirect) +RedirectBox::add_redirect_to_display (boost::shared_ptr<Redirect> redirect) { if (redirect->placement() != _placement) { return; } Gtk::TreeModel::Row row = *(model->append()); - row[columns.text] = redirect_name (*redirect); + row[columns.text] = redirect_name (redirect); row[columns.redirect] = redirect; - show_redirect_active (redirect, this); + show_redirect_active (redirect.get(), this); redirect_active_connections.push_back (redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active))); redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), redirect))); } string -RedirectBox::redirect_name (Redirect& redirect) +RedirectBox::redirect_name (boost::shared_ptr<Redirect> redirect) { - Send *send; + boost::shared_ptr<Send> send; string name_display; - if (!redirect.active()) { + if (!redirect->active()) { name_display = " ("; } - if ((send = dynamic_cast<Send *> (&redirect)) != 0) { + if ((send = boost::dynamic_pointer_cast<Send> (redirect)) != 0) { name_display += '>'; @@ -550,16 +551,16 @@ RedirectBox::redirect_name (Redirect& redirect) switch (_width) { case Wide: - name_display += redirect.name(); + name_display += redirect->name(); break; case Narrow: - name_display += PBD::short_version (redirect.name(), 5); + name_display += PBD::short_version (redirect->name(), 5); break; } } - if (!redirect.active()) { + if (!redirect->active()) { name_display += ')'; } @@ -581,34 +582,36 @@ RedirectBox::build_redirect_tooltip (EventBox& box, string start) } void -RedirectBox::show_redirect_name (void* src, Redirect *redirect) +RedirectBox::show_redirect_name (void* src, boost::shared_ptr<Redirect> redirect) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_name), src, redirect)); - - show_redirect_active (redirect, src); + show_redirect_active (redirect.get(), src); } void -RedirectBox::show_redirect_active (Redirect *redirect, void *src) +RedirectBox::show_redirect_active (Redirect* redirect, void *src) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), redirect, src)); Gtk::TreeModel::Children children = model->children(); Gtk::TreeModel::Children::iterator iter = children.begin(); - while( iter != children.end()) - { - if ((*iter)[columns.redirect] == redirect) - break; - iter++; - } + while (iter != children.end()) { - (*iter)[columns.text] = redirect_name (*redirect); + boost::shared_ptr<Redirect> r = (*iter)[columns.redirect]; - if (redirect->active()) { - (*iter)[columns.color] = *active_redirect_color; - } else { - (*iter)[columns.color] = *inactive_redirect_color; + if (r.get() == redirect) { + (*iter)[columns.text] = redirect_name (r); + + if (redirect->active()) { + (*iter)[columns.color] = *active_redirect_color; + } else { + (*iter)[columns.color] = *inactive_redirect_color; + } + break; + } + + iter++; } } @@ -627,12 +630,12 @@ RedirectBox::compute_redirect_sort_keys () Gtk::TreeModel::Children children = model->children(); for (Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) { - Redirect *redirect = (*iter)[columns.redirect]; - redirect->set_sort_key (sort_key); + boost::shared_ptr<Redirect> r = (*iter)[columns.redirect]; + r->set_sort_key (sort_key); sort_key++; } - if (_route.sort_redirects ()) { + if (_route->sort_redirects ()) { redisplay_redirects (0); @@ -661,7 +664,7 @@ outputs do not work correctly.")); void RedirectBox::rename_redirects () { - vector<Redirect*> to_be_renamed; + vector<boost::shared_ptr<Redirect> > to_be_renamed; get_selected_redirects (to_be_renamed); @@ -669,7 +672,7 @@ RedirectBox::rename_redirects () return; } - for (vector<Redirect*>::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) { + for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) { rename_redirect (*i); } } @@ -677,7 +680,7 @@ RedirectBox::rename_redirects () void RedirectBox::cut_redirects () { - vector<Redirect*> to_be_removed; + vector<boost::shared_ptr<Redirect> > to_be_removed; get_selected_redirects (to_be_removed); @@ -692,7 +695,7 @@ RedirectBox::cut_redirects () _rr_selection.set (to_be_removed); - for (vector<Redirect*>::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) { + for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) { void* gui = (*i)->get_gui (); @@ -700,7 +703,7 @@ RedirectBox::cut_redirects () static_cast<Gtk::Widget*>(gui)->hide (); } - if (_route.remove_redirect (*i, this)) { + if (_route->remove_redirect (*i, this)) { /* removal failed */ _rr_selection.remove (*i); } @@ -711,8 +714,8 @@ RedirectBox::cut_redirects () void RedirectBox::copy_redirects () { - vector<Redirect*> to_be_copied; - vector<Redirect*> copies; + vector<boost::shared_ptr<Redirect> > to_be_copied; + vector<boost::shared_ptr<Redirect> > copies; get_selected_redirects (to_be_copied); @@ -720,29 +723,24 @@ RedirectBox::copy_redirects () return; } - for (vector<Redirect*>::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) { - copies.push_back (Redirect::clone (**i)); + for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) { + copies.push_back (Redirect::clone (*i)); } _rr_selection.set (copies); } gint -RedirectBox::idle_delete_redirect (Redirect *redirect) +RedirectBox::idle_delete_redirect (boost::shared_ptr<Redirect> redirect) { /* NOT copied to _mixer.selection() */ - if (_route.remove_redirect (redirect, this)) { - /* removal failed */ - return FALSE; - } - - delete redirect; + _route->remove_redirect (redirect, this); return FALSE; } void -RedirectBox::rename_redirect (Redirect* redirect) +RedirectBox::rename_redirect (boost::shared_ptr<Redirect> redirect) { ArdourPrompter name_prompter (true); string result; @@ -767,7 +765,7 @@ RedirectBox::rename_redirect (Redirect* redirect) } void -RedirectBox::cut_redirect (Redirect *redirect) +RedirectBox::cut_redirect (boost::shared_ptr<Redirect> redirect) { /* this essentially transfers ownership of the redirect of the redirect from the route to the mixer @@ -782,15 +780,15 @@ RedirectBox::cut_redirect (Redirect *redirect) static_cast<Gtk::Widget*>(gui)->hide (); } - if (_route.remove_redirect (redirect, this)) { + if (_route->remove_redirect (redirect, this)) { _rr_selection.remove (redirect); } } void -RedirectBox::copy_redirect (Redirect *redirect) +RedirectBox::copy_redirect (boost::shared_ptr<Redirect> redirect) { - Redirect* copy = Redirect::clone (*redirect); + boost::shared_ptr<Redirect> copy = Redirect::clone (redirect); _rr_selection.add (copy); } @@ -805,22 +803,19 @@ RedirectBox::paste_redirects () } void -RedirectBox::paste_redirect_list (list<Redirect*>& redirects) +RedirectBox::paste_redirect_list (list<boost::shared_ptr<Redirect> >& redirects) { - list<Redirect*> copies; + list<boost::shared_ptr<Redirect> > copies; - for (list<Redirect*>::iterator i = redirects.begin(); i != redirects.end(); ++i) { + for (list<boost::shared_ptr<Redirect> >::iterator i = redirects.begin(); i != redirects.end(); ++i) { - Redirect* copy = Redirect::clone (**i); + boost::shared_ptr<Redirect> copy = Redirect::clone (*i); copy->set_placement (_placement, this); copies.push_back (copy); } - if (_route.add_redirects (copies, this)) { - for (list<Redirect*>::iterator i = copies.begin(); i != copies.end(); ++i) { - delete *i; - } + if (_route->add_redirects (copies, this)) { string msg = _( "Copying the set of redirects on the clipboard failed,\n\ @@ -832,19 +827,19 @@ could not match the configuration of this track."); } void -RedirectBox::activate_redirect (Redirect *r) +RedirectBox::activate_redirect (boost::shared_ptr<Redirect> r) { r->set_active (true, 0); } void -RedirectBox::deactivate_redirect (Redirect *r) +RedirectBox::deactivate_redirect (boost::shared_ptr<Redirect> r) { r->set_active (false, 0); } void -RedirectBox::get_selected_redirects (vector<Redirect*>& redirects) +RedirectBox::get_selected_redirects (vector<boost::shared_ptr<Redirect> >& redirects) { vector<Gtk::TreeModel::Path> pathlist = redirect_display.get_selection()->get_selected_rows(); @@ -853,12 +848,12 @@ RedirectBox::get_selected_redirects (vector<Redirect*>& redirects) } void -RedirectBox::for_selected_redirects (void (RedirectBox::*pmf)(Redirect*)) +RedirectBox::for_selected_redirects (void (RedirectBox::*pmf)(boost::shared_ptr<Redirect>)) { vector<Gtk::TreeModel::Path> pathlist = redirect_display.get_selection()->get_selected_rows(); for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) { - Redirect* redirect = (*(model->get_iter(*iter)))[columns.redirect]; + boost::shared_ptr<Redirect> redirect = (*(model->get_iter(*iter)))[columns.redirect]; (this->*pmf)(redirect); } } @@ -869,7 +864,7 @@ RedirectBox::clone_redirects () RouteSelection& routes (_rr_selection.routes); if (!routes.empty()) { - if (_route.copy_redirects (*routes.front(), _placement)) { + if (_route->copy_redirects (*routes.front(), _placement)) { string msg = _( "Copying the set of redirects on the clipboard failed,\n\ probably because the I/O configuration of the plugins\n\ @@ -883,7 +878,7 @@ could not match the configuration of this track."); void RedirectBox::all_redirects_active (bool state) { - _route.all_redirects_active (state); + _route->all_redirects_active (state); } void @@ -892,7 +887,7 @@ RedirectBox::clear_redirects() string prompt; vector<string> choices; - if (dynamic_cast<AudioTrack*>(&_route) != 0) { + if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) { prompt = _("Do you really want to remove all redirects from this track?\n" "(this cannot be undone)"); } else { @@ -906,23 +901,23 @@ RedirectBox::clear_redirects() Gtkmm2ext::Choice prompter (prompt, choices); if (prompter.run () == 1) { - _route.clear_redirects (this); + _route->clear_redirects (this); } } void -RedirectBox::edit_redirect (Redirect* redirect) +RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect) { - Insert *insert; + boost::shared_ptr<Insert> insert; - if (dynamic_cast<AudioTrack*>(&_route) != 0) { + if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) { - if (dynamic_cast<AudioTrack*> (&_route)->freeze_state() == AudioTrack::Frozen) { + if (boost::dynamic_pointer_cast<AudioTrack> (_route)->freeze_state() == AudioTrack::Frozen) { return; } } - if ((insert = dynamic_cast<Insert *> (redirect)) == 0) { + if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) == 0) { /* its a send */ @@ -930,7 +925,7 @@ RedirectBox::edit_redirect (Redirect* redirect) return; } - Send *send = dynamic_cast<Send*> (redirect); + boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (redirect); SendUIWindow *send_ui; @@ -939,7 +934,7 @@ RedirectBox::edit_redirect (Redirect* redirect) string title; title = string_compose(_("ardour: %1"), send->name()); - send_ui = new SendUIWindow (*send, _session); + send_ui = new SendUIWindow (send, _session); send_ui->set_title (title); send->set_gui (send_ui); @@ -957,17 +952,17 @@ RedirectBox::edit_redirect (Redirect* redirect) /* its an insert */ - PluginInsert *plugin_insert; - PortInsert *port_insert; + boost::shared_ptr<PluginInsert> plugin_insert; + boost::shared_ptr<PortInsert> port_insert; - if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) { + if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) { PluginUIWindow *plugin_ui; if (plugin_insert->get_gui() == 0) { string title; - string maker = plugin_insert->plugin().maker(); + string maker = plugin_insert->plugin()->maker(); string::size_type email_pos; if ((email_pos = maker.find_first_of ('<')) != string::npos) { @@ -979,9 +974,9 @@ RedirectBox::edit_redirect (Redirect* redirect) maker += " ..."; } - title = string_compose(_("ardour: %1: %2 (by %3)"), _route.name(), plugin_insert->name(), maker); + title = string_compose(_("ardour: %1: %2 (by %3)"), _route->name(), plugin_insert->name(), maker); - plugin_ui = new PluginUIWindow (_session.engine(), *plugin_insert); + plugin_ui = new PluginUIWindow (_session.engine(), plugin_insert); if (_owner_is_mixer) { ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui); } else { @@ -1000,7 +995,7 @@ RedirectBox::edit_redirect (Redirect* redirect) plugin_ui->show_all (); } - } else if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) { + } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) { if (!_session.engine().connected()) { MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible")); @@ -1011,7 +1006,7 @@ RedirectBox::edit_redirect (Redirect* redirect) PortInsertWindow *io_selector; if (port_insert->get_gui() == 0) { - io_selector = new PortInsertWindow (_session, *port_insert); + io_selector = new PortInsertWindow (_session, port_insert); port_insert->set_gui (io_selector); } else { diff --git a/gtk2_ardour/redirect_box.h b/gtk2_ardour/redirect_box.h index bc162fac17..51c17cad51 100644 --- a/gtk2_ardour/redirect_box.h +++ b/gtk2_ardour/redirect_box.h @@ -33,11 +33,12 @@ #include <gtkmm2ext/click_box.h> #include <gtkmm2ext/dndtreeview.h> +#include <pbd/stateful.h> + #include <ardour/types.h> #include <ardour/ardour.h> #include <ardour/io.h> #include <ardour/insert.h> -#include <ardour/stateful.h> #include <ardour/redirect.h> #include <pbd/fastlog.h> @@ -64,7 +65,8 @@ namespace ARDOUR { class RedirectBox : public Gtk::HBox { public: - RedirectBox (ARDOUR::Placement, ARDOUR::Session&, ARDOUR::Route &, PluginSelector &, RouteRedirectSelection &, bool owner_is_mixer = false); + RedirectBox (ARDOUR::Placement, ARDOUR::Session&, + boost::shared_ptr<ARDOUR::Route>, PluginSelector &, RouteRedirectSelection &, bool owner_is_mixer = false); ~RedirectBox (); void set_width (Width); @@ -77,8 +79,8 @@ class RedirectBox : public Gtk::HBox void select_all_inserts (); void select_all_sends (); - sigc::signal<void,ARDOUR::Redirect *> RedirectSelected; - sigc::signal<void,ARDOUR::Redirect *> RedirectUnselected; + sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectSelected; + sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectUnselected; static void register_actions(); @@ -86,7 +88,7 @@ class RedirectBox : public Gtk::HBox void set_stuff_from_route (); private: - ARDOUR::Route & _route; + boost::shared_ptr<ARDOUR::Route> _route; ARDOUR::Session & _session; bool _owner_is_mixer; @@ -102,7 +104,7 @@ class RedirectBox : public Gtk::HBox add (color); } Gtk::TreeModelColumn<std::string> text; - Gtk::TreeModelColumn<ARDOUR::Redirect*> redirect; + Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Redirect> > redirect; Gtk::TreeModelColumn<Gdk::Color> color; }; @@ -137,24 +139,29 @@ class RedirectBox : public Gtk::HBox void show_redirect_menu (gint arg); void choose_send (); - void send_io_finished (IOSelector::Result, ARDOUR::Redirect*, IOSelectorWindow*); + void send_io_finished (IOSelector::Result, boost::shared_ptr<ARDOUR::Redirect>, IOSelectorWindow*); void choose_insert (); void choose_plugin (); - void insert_plugin_chosen (ARDOUR::Plugin *); + void insert_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>); bool no_redirect_redisplay; bool ignore_delete; bool redirect_button_press_event (GdkEventButton *); void redisplay_redirects (void* src); - void show_redirect_active (ARDOUR::Redirect *, void *); - void show_redirect_name (void*, ARDOUR::Redirect *); - void add_redirect_to_display (ARDOUR::Redirect *); + void add_redirect_to_display (boost::shared_ptr<ARDOUR::Redirect>); void row_deleted (const Gtk::TreeModel::Path& path); + void show_redirect_name (void*, boost::shared_ptr<ARDOUR::Redirect>); + + /* these are handlers for Redirect signals, so they take Redirect* + directly, rather than shared_ptr<Redirect> + */ + + void show_redirect_active (ARDOUR::Redirect*, void *); - string redirect_name (ARDOUR::Redirect&); + string redirect_name (boost::shared_ptr<ARDOUR::Redirect>); - void remove_redirect_gui (ARDOUR::Redirect *); + void remove_redirect_gui (boost::shared_ptr<ARDOUR::Redirect>); void redirects_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*); void compute_redirect_sort_keys (); @@ -173,23 +180,23 @@ class RedirectBox : public Gtk::HBox void clone_redirects (); void rename_redirects (); - void for_selected_redirects (void (RedirectBox::*pmf)(ARDOUR::Redirect*)); - void get_selected_redirects (vector<ARDOUR::Redirect*>&); + void for_selected_redirects (void (RedirectBox::*pmf)(boost::shared_ptr<ARDOUR::Redirect>)); + void get_selected_redirects (vector<boost::shared_ptr<ARDOUR::Redirect> >&); static Glib::RefPtr<Gtk::Action> paste_action; - void paste_redirect_list (std::list<ARDOUR::Redirect*>& redirects); + void paste_redirect_list (std::list<boost::shared_ptr<ARDOUR::Redirect> >& redirects); - void activate_redirect (ARDOUR::Redirect*); - void deactivate_redirect (ARDOUR::Redirect*); - void cut_redirect (ARDOUR::Redirect*); - void copy_redirect (ARDOUR::Redirect*); - void edit_redirect (ARDOUR::Redirect*); - void hide_redirect_editor (ARDOUR::Redirect*); - void rename_redirect (ARDOUR::Redirect*); + void activate_redirect (boost::shared_ptr<ARDOUR::Redirect>); + void deactivate_redirect (boost::shared_ptr<ARDOUR::Redirect>); + void cut_redirect (boost::shared_ptr<ARDOUR::Redirect>); + void copy_redirect (boost::shared_ptr<ARDOUR::Redirect>); + void edit_redirect (boost::shared_ptr<ARDOUR::Redirect>); + void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect>); + void rename_redirect (boost::shared_ptr<ARDOUR::Redirect>); - gint idle_delete_redirect (ARDOUR::Redirect *); + gint idle_delete_redirect (boost::shared_ptr<ARDOUR::Redirect>); - void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, ARDOUR::IO& io); + void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, boost::shared_ptr<ARDOUR::IO> io); static RedirectBox* _current_redirect_box; static bool enter_box (GdkEventCrossing*, RedirectBox*); diff --git a/gtk2_ardour/redirect_selection.h b/gtk2_ardour/redirect_selection.h index 3695f85c60..5bcd77cfe4 100644 --- a/gtk2_ardour/redirect_selection.h +++ b/gtk2_ardour/redirect_selection.h @@ -2,11 +2,12 @@ #define __ardour_gtk_redirect_selection_h__ #include <list> +#include <boost/shared_ptr.hpp> namespace ARDOUR { class Redirect; } -struct RedirectSelection : list<ARDOUR::Redirect*> {}; +struct RedirectSelection : list<boost::shared_ptr<ARDOUR::Redirect> > {}; #endif /* __ardour_gtk_redirect_selection_h__ */ diff --git a/gtk2_ardour/region_editor.h b/gtk2_ardour/region_editor.h index 65b0bbaa94..70590b0db5 100644 --- a/gtk2_ardour/region_editor.h +++ b/gtk2_ardour/region_editor.h @@ -15,172 +15,29 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ + $Id: /local/undo/gtk2_ardour/region_editor.h 5 2006-05-31T02:48:48.738745Z paul $ */ #ifndef __gtk_ardour_region_edit_h__ #define __gtk_ardour_region_edit_h__ -#include <map> - -#include <gtkmm/label.h> -#include <gtkmm/entry.h> -#include <gtkmm/box.h> -#include <gtkmm/togglebutton.h> -#include <gtkmm/button.h> -#include <gtkmm/arrow.h> -#include <gtkmm/frame.h> -#include <gtkmm/table.h> -#include <gtkmm/alignment.h> -#include <gtkmm/adjustment.h> -#include <gtkmm/separator.h> -#include <gtkmm/spinbutton.h> - -#include <libgnomecanvas/libgnomecanvas.h> -#include <sigc++/signal.h> - -#include "audio_clock.h" #include "ardour_dialog.h" -namespace ARDOUR { - class AudioRegion; - class Session; -} - -class AudioRegionView; +namespace ARDOUR { class Session; } -class AudioRegionEditor : public ArdourDialog +/** Just a useless stub for now... */ +class RegionEditor : public ArdourDialog { public: - AudioRegionEditor (ARDOUR::Session&, ARDOUR::AudioRegion&, AudioRegionView& rv); - ~AudioRegionEditor (); - - private: - ARDOUR::Session& _session; - ARDOUR::AudioRegion& _region; - AudioRegionView& _region_view; - - void connect_editor_events (); - - Gtk::Label name_label; - Gtk::Entry name_entry; - Gtk::HBox name_hbox; - - Gtk::HBox top_row_hbox; - Gtk::HBox top_row_button_hbox; - - Gtk::ToggleButton lock_button; - Gtk::ToggleButton mute_button; - Gtk::ToggleButton opaque_button; - Gtk::ToggleButton envelope_active_button; - Gtk::ToggleButton envelope_view_button; - - Gtk::Button raise_button; - Gtk::Arrow raise_arrow; - Gtk::Button lower_button; - Gtk::Arrow lower_arrow; - Gtk::Frame layer_frame; - Gtk::Label layer_value_label; - Gtk::Label layer_label; - Gtk::HBox layer_hbox; - - Gtk::ToggleButton audition_button; - - Gtk::HBox lower_hbox; - - Gtk::Table time_table; - - Gtk::Label start_label; - Gtk::Label end_label; - Gtk::Label length_label; - Gtk::Alignment start_alignment; - Gtk::Alignment end_alignment; - Gtk::Alignment length_alignment; - - AudioClock start_clock; - AudioClock end_clock; - AudioClock length_clock; - AudioClock sync_offset_clock; - - Gtk::Table envelope_loop_table; - Gtk::Button loop_button; - Gtk::Label loop_label; - Gtk::Label envelope_label; - - Gtk::Table fade_in_table; - Gtk::Label fade_in_label; - Gtk::Alignment fade_in_label_align; - Gtk::Label fade_in_active_button_label; - Gtk::ToggleButton fade_in_active_button; - Gtk::Label fade_in_length_label; - - Gtk::Adjustment fade_in_length_adjustment; - Gtk::SpinButton fade_in_length_spinner; - - Gtk::Table fade_out_table; - Gtk::Label fade_out_label; - Gtk::Alignment fade_out_label_align; - Gtk::Label fade_out_active_button_label; - Gtk::ToggleButton fade_out_active_button; - Gtk::Label fade_out_length_label; - - Gtk::Adjustment fade_out_length_adjustment; - Gtk::SpinButton fade_out_length_spinner; - - Gtk::HSeparator sep3; - Gtk::VSeparator sep1; - Gtk::VSeparator sep2; - - void region_changed (ARDOUR::Change); - void bounds_changed (ARDOUR::Change); - void name_changed (); - void opacity_changed (); - void mute_changed (); - void envelope_active_changed (); - void lock_changed (); - void layer_changed (); - - void fade_in_length_adjustment_changed (); - void fade_out_length_adjustment_changed (); - void fade_in_changed (); - void fade_out_changed (); - void audition_state_changed (bool); - - void activation (); - - void name_entry_changed (); - void start_clock_changed (); - void end_clock_changed (); - void length_clock_changed (); - - gint envelope_active_button_press (GdkEventButton *); - gint envelope_active_button_release (GdkEventButton *); - - void audition_button_toggled (); - void envelope_view_button_toggled (); - void lock_button_clicked (); - void mute_button_clicked (); - void opaque_button_clicked (); - void raise_button_clicked (); - void lower_button_clicked (); - - void fade_in_active_toggled (); - void fade_out_active_toggled (); - void fade_in_active_changed (); - void fade_out_active_changed (); - - void fade_in_realized (); - void fade_out_realized (); - - void start_editing_fade_in (); - void start_editing_fade_out (); - void stop_editing_fade_in (); - void stop_editing_fade_out (); + RegionEditor(ARDOUR::Session& s) + : ArdourDialog ("region editor") + , _session(s) + {} - gint bpressed (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)()); - gint breleased (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)()); + virtual ~RegionEditor () {} - bool spin_arrow_grab; + protected: + ARDOUR::Session& _session; }; #endif /* __gtk_ardour_region_edit_h__ */ diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc index ebcf65cedd..920d2cdca9 100644 --- a/gtk2_ardour/region_gain_line.cc +++ b/gtk2_ardour/region_gain_line.cc @@ -3,7 +3,7 @@ #include <pbd/memento_command.h> #include "region_gain_line.h" -#include "regionview.h" +#include "audio_region_view.h" #include "utils.h" #include "time_axis_view.h" @@ -47,8 +47,8 @@ void AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction) { AutomationLine::start_drag(cp,fraction); - if (!rv.region.envelope_active()) { - trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.region, rv.region.get_state())); + if (!rv.audio_region().envelope_active()) { + trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state())); rv.region.set_envelope_active(false); } } @@ -64,11 +64,11 @@ AudioRegionGainLine::remove_point (ControlPoint& cp) trackview.editor.current_session()->begin_reversible_command (_("remove control point")); XMLNode &before = get_state(); - if (!rv.region.envelope_active()) { - XMLNode &before = rv.region.get_state(); - rv.region.set_envelope_active(true); - XMLNode &after = rv.region.get_state(); - trackview.session().add_command(new MementoCommand<AudioRegion>(rv.region, before, after)); + if (!rv.audio_region().envelope_active()) { + XMLNode &before = rv.audio_region().get_state(); + rv.audio_region().set_envelope_active(true); + XMLNode &after = rv.audio_region().get_state(); + trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), before, after)); } alist.erase (mr.start, mr.end); @@ -81,9 +81,9 @@ AudioRegionGainLine::remove_point (ControlPoint& cp) void AudioRegionGainLine::end_drag (ControlPoint* cp) { - if (!rv.region.envelope_active()) { - rv.region.set_envelope_active(true); - trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.region, rv.region.get_state())); + if (!rv.audio_region().envelope_active()) { + rv.audio_region().set_envelope_active(true); + trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state())); } AutomationLine::end_drag(cp); } diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc index 751584cab7..f8c9f384a9 100644 --- a/gtk2_ardour/region_selection.cc +++ b/gtk2_ardour/region_selection.cc @@ -1,8 +1,26 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include <algorithm> -#include <ardour/audioregion.h> +#include <ardour/region.h> -#include "regionview.h" +#include "region_view.h" #include "region_selection.h" using namespace ARDOUR; @@ -11,7 +29,7 @@ using namespace sigc; bool -AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionView* b) const +RegionComparator::operator() (const RegionView* a, const RegionView* b) const { if (a == b) { return false; @@ -20,16 +38,16 @@ AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionVi } } -AudioRegionSelection::AudioRegionSelection () +RegionSelection::RegionSelection () { _current_start = 0; _current_end = 0; } -AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other) +RegionSelection::RegionSelection (const RegionSelection& other) { - for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { + for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { add (*i, false); } _current_start = other._current_start; @@ -38,14 +56,14 @@ AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other) -AudioRegionSelection& -AudioRegionSelection::operator= (const AudioRegionSelection& other) +RegionSelection& +RegionSelection::operator= (const RegionSelection& other) { if (this != &other) { clear_all(); - for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { + for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { add (*i, false); } @@ -57,13 +75,13 @@ AudioRegionSelection::operator= (const AudioRegionSelection& other) } void -AudioRegionSelection::clear_all() +RegionSelection::clear_all() { clear(); _bylayer.clear(); } -bool AudioRegionSelection::contains (AudioRegionView* rv) +bool RegionSelection::contains (RegionView* rv) { if (this->find (rv) != end()) { return true; @@ -75,21 +93,21 @@ bool AudioRegionSelection::contains (AudioRegionView* rv) } void -AudioRegionSelection::add (AudioRegionView* rv, bool dosort) +RegionSelection::add (RegionView* rv, bool dosort) { if (this->find (rv) != end()) { /* we already have it */ return; } - rv->AudioRegionViewGoingAway.connect (mem_fun(*this, &AudioRegionSelection::remove_it)); + rv->RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it)); - if (rv->region.first_frame() < _current_start || empty()) { - _current_start = rv->region.first_frame(); + if (rv->region().first_frame() < _current_start || empty()) { + _current_start = rv->region().first_frame(); } - if (rv->region.last_frame() > _current_end || empty()) { - _current_end = rv->region.last_frame(); + if (rv->region().last_frame() > _current_end || empty()) { + _current_end = rv->region().last_frame(); } insert (rv); @@ -100,15 +118,15 @@ AudioRegionSelection::add (AudioRegionView* rv, bool dosort) } void -AudioRegionSelection::remove_it (AudioRegionView *rv) +RegionSelection::remove_it (RegionView *rv) { remove (rv); } bool -AudioRegionSelection::remove (AudioRegionView* rv) +RegionSelection::remove (RegionView* rv) { - AudioRegionSelection::iterator i; + RegionSelection::iterator i; if ((i = this->find (rv)) != end()) { @@ -124,7 +142,7 @@ AudioRegionSelection::remove (AudioRegionView* rv) } else { - AudioRegion& region ((*i)->region); + Region& region ((*i)->region()); if (region.first_frame() == _current_start) { @@ -165,15 +183,15 @@ AudioRegionSelection::remove (AudioRegionView* rv) } void -AudioRegionSelection::add_to_layer (AudioRegionView * rv) +RegionSelection::add_to_layer (RegionView * rv) { // insert it into layer sorted position - list<AudioRegionView*>::iterator i; + list<RegionView*>::iterator i; for (i = _bylayer.begin(); i != _bylayer.end(); ++i) { - if (rv->region.layer() < (*i)->region.layer()) { + if (rv->region().layer() < (*i)->region().layer()) { _bylayer.insert(i, rv); return; } @@ -184,16 +202,16 @@ AudioRegionSelection::add_to_layer (AudioRegionView * rv) } struct RegionSortByTime { - bool operator() (const AudioRegionView* a, const AudioRegionView* b) { - return a->region.position() < b->region.position(); + bool operator() (const RegionView* a, const RegionView* b) { + return a->region().position() < b->region().position(); } }; void -AudioRegionSelection::by_position (list<AudioRegionView*>& foo) const +RegionSelection::by_position (list<RegionView*>& foo) const { - list<AudioRegionView*>::const_iterator i; + list<RegionView*>::const_iterator i; RegionSortByTime sorter; for (i = _bylayer.begin(); i != _bylayer.end(); ++i) { diff --git a/gtk2_ardour/region_selection.h b/gtk2_ardour/region_selection.h index 0c2b7be025..2192442cb0 100644 --- a/gtk2_ardour/region_selection.h +++ b/gtk2_ardour/region_selection.h @@ -1,3 +1,21 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #ifndef __ardour_gtk_region_selection_h__ #define __ardour_gtk_region_selection_h__ @@ -9,23 +27,23 @@ using std::list; using std::set; -class AudioRegionView; +class RegionView; -struct AudioRegionComparator { - bool operator() (const AudioRegionView* a, const AudioRegionView* b) const; +struct RegionComparator { + bool operator() (const RegionView* a, const RegionView* b) const; }; -class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator>, public sigc::trackable +class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::trackable { public: - AudioRegionSelection(); - AudioRegionSelection (const AudioRegionSelection&); + RegionSelection(); + RegionSelection (const RegionSelection&); - AudioRegionSelection& operator= (const AudioRegionSelection&); + RegionSelection& operator= (const RegionSelection&); - void add (AudioRegionView*, bool dosort = true); - bool remove (AudioRegionView*); - bool contains (AudioRegionView*); + void add (RegionView*, bool dosort = true); + bool remove (RegionView*); + bool contains (RegionView*); void clear_all(); @@ -39,18 +57,18 @@ class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator> return _current_end; } - const list<AudioRegionView *> & by_layer() const { return _bylayer; } - void by_position (list<AudioRegionView*>&) const; + const list<RegionView *> & by_layer() const { return _bylayer; } + void by_position (list<RegionView*>&) const; private: - void remove_it (AudioRegionView*); + void remove_it (RegionView*); - void add_to_layer (AudioRegionView *); + void add_to_layer (RegionView *); jack_nframes_t _current_start; jack_nframes_t _current_end; - list<AudioRegionView *> _bylayer; + list<RegionView *> _bylayer; }; #endif /* __ardour_gtk_region_selection_h__ */ diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc new file mode 100644 index 0000000000..ebec4261ac --- /dev/null +++ b/gtk2_ardour/region_view.cc @@ -0,0 +1,494 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: regionview.cc 691 2006-07-23 12:03:19Z drobilla $ +*/ + +#include <cmath> +#include <cassert> +#include <algorithm> + +#include <gtkmm.h> + +#include <gtkmm2ext/gtk_ui.h> + +#include <ardour/playlist.h> +#include <ardour/audioregion.h> +#include <ardour/audiosource.h> +#include <ardour/audio_diskstream.h> + +#include "streamview.h" +#include "region_view.h" +#include "route_time_axis.h" +#include "simplerect.h" +#include "simpleline.h" +#include "waveview.h" +#include "public_editor.h" +#include "region_editor.h" +#include "ghostregion.h" +#include "route_time_axis.h" +#include "utils.h" +#include "rgb_macros.h" +#include "gui_thread.h" + +#include "i18n.h" + +using namespace sigc; +using namespace ARDOUR; +using namespace PBD; +using namespace Editing; +using namespace ArdourCanvas; + +static const int32_t sync_mark_width = 9; + +sigc::signal<void,RegionView*> RegionView::RegionViewGoingAway; + +RegionView::RegionView (ArdourCanvas::Group* parent, + TimeAxisView& tv, + ARDOUR::Region& r, + double spu, + Gdk::Color& basic_color) + : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), + TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText| + TimeAxisViewItem::ShowNameHighlight| + TimeAxisViewItem::ShowFrame)) + , _region (r) + , sync_mark(0) + , no_wave_msg(0) + , editor(0) + , current_visible_sync_position(0.0) + , valid(false) + , _pixel_width(1.0) + , _height(1.0) + , in_destructor(false) + , wait_for_data(false) +{ +} + +RegionView::RegionView (ArdourCanvas::Group* parent, + TimeAxisView& tv, + ARDOUR::Region& r, + double spu, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility visibility) + : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), visibility) + , _region (r) + , sync_mark(0) + , no_wave_msg(0) + , editor(0) + , current_visible_sync_position(0.0) + , valid(false) + , _pixel_width(1.0) + , _height(1.0) + , in_destructor(false) + , wait_for_data(false) +{ +} + +void +RegionView::init (Gdk::Color& basic_color, bool wfd) +{ + editor = 0; + valid = true; + in_destructor = false; + _height = 0; + wait_for_data = wfd; + + compute_colors (basic_color); + + name_highlight->set_data ("regionview", this); + name_text->set_data ("regionview", this); + + /* an equilateral triangle */ + ArdourCanvas::Points shape; + shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); + shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1)); + shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1)); + shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); + + sync_mark = new ArdourCanvas::Polygon (*group); + sync_mark->property_points() = shape; + sync_mark->property_fill_color_rgba() = fill_color; + sync_mark->hide(); + + reset_width_dependent_items ((double) _region.length() / samples_per_unit); + + set_height (trackview.height); + + region_muted (); + region_sync_changed (); + region_resized (BoundsChanged); + region_locked (); + + _region.StateChanged.connect (mem_fun(*this, &RegionView::region_changed)); + + group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this)); + name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this)); + + set_colors (); + + ColorChanged.connect (mem_fun (*this, &RegionView::color_handler)); + + /* XXX sync mark drag? */ +} + +RegionView::~RegionView () +{ + in_destructor = true; + + RegionViewGoingAway (this); /* EMIT_SIGNAL */ + + for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) { + delete *g; + } + + if (editor) { + delete editor; + } +} + +gint +RegionView::_lock_toggle (ArdourCanvas::Item* item, GdkEvent* ev, void* arg) +{ + switch (ev->type) { + case GDK_BUTTON_RELEASE: + static_cast<RegionView*>(arg)->lock_toggle (); + return TRUE; + break; + default: + break; + } + return FALSE; +} + +void +RegionView::lock_toggle () +{ + _region.set_locked (!_region.locked()); +} + +void +RegionView::region_changed (Change what_changed) +{ + ENSURE_GUI_THREAD (bind (mem_fun(*this, &RegionView::region_changed), what_changed)); + + if (what_changed & BoundsChanged) { + region_resized (what_changed); + region_sync_changed (); + } + if (what_changed & Region::MuteChanged) { + region_muted (); + } + if (what_changed & Region::OpacityChanged) { + region_opacity (); + } + if (what_changed & ARDOUR::NameChanged) { + region_renamed (); + } + if (what_changed & Region::SyncOffsetChanged) { + region_sync_changed (); + } + if (what_changed & Region::LayerChanged) { + region_layered (); + } + if (what_changed & Region::LockChanged) { + region_locked (); + } +} + +void +RegionView::region_locked () +{ + /* name will show locked status */ + region_renamed (); +} + +void +RegionView::region_resized (Change what_changed) +{ + double unit_length; + + if (what_changed & ARDOUR::PositionChanged) { + set_position (_region.position(), 0); + } + + if (what_changed & Change (StartChanged|LengthChanged)) { + + set_duration (_region.length(), 0); + + unit_length = _region.length() / samples_per_unit; + + reset_width_dependent_items (unit_length); + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + + (*i)->set_duration (unit_length); + + } + } +} + +void +RegionView::reset_width_dependent_items (double pixel_width) +{ + TimeAxisViewItem::reset_width_dependent_items (pixel_width); + _pixel_width = pixel_width; +} + +void +RegionView::region_layered () +{ + RouteTimeAxisView *rtv = dynamic_cast<RouteTimeAxisView*>(&get_time_axis_view()); + assert(rtv); + rtv->view()->region_layered (this); +} + +void +RegionView::region_muted () +{ + set_frame_color (); + region_renamed (); +} + +void +RegionView::region_opacity () +{ + set_frame_color (); +} + +void +RegionView::raise () +{ + _region.raise (); +} + +void +RegionView::raise_to_top () +{ + _region.raise_to_top (); +} + +void +RegionView::lower () +{ + _region.lower (); +} + +void +RegionView::lower_to_bottom () +{ + _region.lower_to_bottom (); +} + +bool +RegionView::set_position (jack_nframes_t pos, void* src, double* ignored) +{ + double delta; + bool ret; + + if (!(ret = TimeAxisViewItem::set_position (pos, this, &delta))) { + return false; + } + + if (ignored) { + *ignored = delta; + } + + if (delta) { + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->group->move (delta, 0.0); + } + } + + return ret; +} + +void +RegionView::set_samples_per_unit (gdouble spu) +{ + TimeAxisViewItem::set_samples_per_unit (spu); + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->set_samples_per_unit (spu); + (*i)->set_duration (_region.length() / samples_per_unit); + } + + region_sync_changed (); +} + +bool +RegionView::set_duration (jack_nframes_t frames, void *src) +{ + if (!TimeAxisViewItem::set_duration (frames, src)) { + return false; + } + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->set_duration (_region.length() / samples_per_unit); + } + + return true; +} + +void +RegionView::compute_colors (Gdk::Color& basic_color) +{ + TimeAxisViewItem::compute_colors (basic_color); +} + +void +RegionView::set_colors () +{ + TimeAxisViewItem::set_colors (); + + if (sync_mark) { + sync_mark->property_fill_color_rgba() = fill_color; + } +} + +void +RegionView::set_frame_color () +{ + if (_region.opaque()) { + fill_opacity = 180; + } else { + fill_opacity = 100; + } + + TimeAxisViewItem::set_frame_color (); +} + +void +RegionView::hide_region_editor() +{ + if (editor) { + editor->hide_all (); + } +} + +void +RegionView::region_renamed () +{ + string str; + + if (_region.locked()) { + str += '>'; + str += _region.name(); + str += '<'; + } else { + str = _region.name(); + } + + if (_region.speed_mismatch (trackview.session().frame_rate())) { + str = string ("*") + str; + } + + if (_region.muted()) { + str = string ("!") + str; + } + + set_item_name (str, this); + set_name_text (str); +} + +void +RegionView::region_sync_changed () +{ + if (sync_mark == 0) { + return; + } + + int sync_dir; + jack_nframes_t sync_offset; + + sync_offset = _region.sync_offset (sync_dir); + + /* this has to handle both a genuine change of position, a change of samples_per_unit, + and a change in the bounds of the _region. + */ + + if (sync_offset == 0) { + + /* no sync mark - its the start of the region */ + + sync_mark->hide(); + + } else { + + if ((sync_dir < 0) || ((sync_dir > 0) && (sync_offset > _region.length()))) { + + /* no sync mark - its out of the bounds of the region */ + + sync_mark->hide(); + + } else { + + /* lets do it */ + + Points points; + + //points = sync_mark->property_points().get_value(); + + double offset = sync_offset / samples_per_unit; + points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); + points.push_back (Gnome::Art::Point (offset + ((sync_mark_width-1)/2), 1)); + points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1)); + points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); + sync_mark->property_points().set_value (points); + sync_mark->show(); + + } + } +} + +void +RegionView::move (double x_delta, double y_delta) +{ + if (_region.locked() || (x_delta == 0 && y_delta == 0)) { + return; + } + + get_canvas_group()->move (x_delta, y_delta); + + /* note: ghosts never leave their tracks so y_delta for them is always zero */ + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + (*i)->group->move (x_delta, 0.0); + } +} + +void +RegionView::remove_ghost (GhostRegion* ghost) +{ + if (in_destructor) { + return; + } + + for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + if (*i == ghost) { + ghosts.erase (i); + break; + } + } +} + +uint32_t +RegionView::get_fill_color () +{ + return fill_color; +} + diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h new file mode 100644 index 0000000000..fdc69ea70e --- /dev/null +++ b/gtk2_ardour/region_view.h @@ -0,0 +1,140 @@ +/* + Copyright (C) 2001-2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __gtk_ardour_region_view_h__ +#define __gtk_ardour_region_view_h__ + +#include <vector> + +#include <libgnomecanvasmm.h> +#include <libgnomecanvasmm/polygon.h> +#include <sigc++/signal.h> +#include <ardour/region.h> + +#include "time_axis_view_item.h" +#include "automation_line.h" +#include "enums.h" +#include "waveview.h" +#include "canvas.h" +#include "color.h" + +class TimeAxisView; +class RegionEditor; +class GhostRegion; +class AutomationTimeAxisView; + +class RegionView : public TimeAxisViewItem +{ + public: + RegionView (ArdourCanvas::Group* parent, + TimeAxisView& time_view, + ARDOUR::Region& region, + double samples_per_unit, + Gdk::Color& basic_color); + + ~RegionView (); + + virtual void init (Gdk::Color& base_color, bool wait_for_data); + + ARDOUR::Region& region() const { return _region; } + + bool is_valid() const { return valid; } + void set_valid (bool yn) { valid = yn; } + + virtual void set_height (double) = 0; + virtual void set_samples_per_unit (double); + virtual bool set_duration (jack_nframes_t, void*); + + void move (double xdelta, double ydelta); + + void raise (); + void raise_to_top (); + void lower (); + void lower_to_bottom (); + + bool set_position(jack_nframes_t pos, void* src, double* delta = 0); + + virtual void show_region_editor () = 0; + virtual void hide_region_editor(); + + virtual void region_changed (ARDOUR::Change); + + virtual GhostRegion* add_ghost (AutomationTimeAxisView&) = 0; + void remove_ghost (GhostRegion*); + + uint32_t get_fill_color (); + + virtual void entered () {} + virtual void exited () {} + + static sigc::signal<void,RegionView*> RegionViewGoingAway; + sigc::signal<void> GoingAway; + + protected: + + /** Allows derived types to specify their visibility requirements + * to the TimeAxisViewItem parent class + */ + RegionView (ArdourCanvas::Group *, + TimeAxisView&, + ARDOUR::Region&, + double samples_per_unit, + Gdk::Color& basic_color, + TimeAxisViewItem::Visibility); + + virtual void region_resized (ARDOUR::Change); + void region_moved (void *); + virtual void region_muted (); + void region_locked (); + void region_opacity (); + void region_layered (); + void region_renamed (); + void region_sync_changed (); + + static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*); + void lock_toggle (); + + virtual void set_colors (); + virtual void compute_colors (Gdk::Color&); + virtual void set_frame_color (); + virtual void reset_width_dependent_items (double pixel_width); + + virtual void color_handler (ColorID, uint32_t) {} + + ARDOUR::Region& _region; + + ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position + ArdourCanvas::Text* no_wave_msg; + + RegionEditor* editor; + + vector<ControlPoint *> control_points; + double current_visible_sync_position; + + bool valid; ///< see StreamView::redisplay_diskstream() + double _pixel_width; + double _height; + bool in_destructor; + + bool wait_for_data; + sigc::connection data_ready_connection; + + vector<GhostRegion*> ghosts; +}; + +#endif /* __gtk_ardour_region_view_h__ */ diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc index d6ec7eab6c..8b47a17511 100644 --- a/gtk2_ardour/route_params_ui.cc +++ b/gtk2_ardour/route_params_ui.cc @@ -59,14 +59,10 @@ using namespace sigc; RouteParams_UI::RouteParams_UI (AudioEngine& eng) : ArdourDialog ("track/bus inspector"), engine (eng), - _route(0), track_menu(0) { pre_redirect_box = 0; post_redirect_box = 0; - _route = 0; - _pre_redirect = 0; - _post_redirect = 0; _input_iosel = 0; _output_iosel = 0; _active_pre_view = 0; @@ -163,7 +159,7 @@ RouteParams_UI::~RouteParams_UI () } void -RouteParams_UI::add_route (Route* route) +RouteParams_UI::add_route (boost::shared_ptr<Route> route) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::add_route), route)); @@ -183,22 +179,22 @@ RouteParams_UI::add_route (Route* route) void -RouteParams_UI::route_name_changed (void *src, Route *route) +RouteParams_UI::route_name_changed (void *src, boost::shared_ptr<Route> route) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_name_changed), src, route)); bool found = false ; TreeModel::Children rows = route_display_model->children(); for(TreeModel::Children::iterator iter = rows.begin(); iter != rows.end(); ++iter) { - if((*iter)[route_display_columns.route] == route) { + boost::shared_ptr<Route> r =(*iter)[route_display_columns.route]; + if (r == route) { (*iter)[route_display_columns.text] = route->name() ; found = true ; break; } } - if(!found) - { + if(!found) { error << _("route display list item for renamed route not found!") << endmsg; } @@ -217,8 +213,8 @@ RouteParams_UI::setup_redirect_boxes() cleanup_redirect_boxes(); // construct new redirect boxes - pre_redirect_box = new RedirectBox(PreFader, *session, *_route, *_plugin_selector, _rr_selection); - post_redirect_box = new RedirectBox(PostFader, *session, *_route, *_plugin_selector, _rr_selection); + pre_redirect_box = new RedirectBox(PreFader, *session, _route, *_plugin_selector, _rr_selection); + post_redirect_box = new RedirectBox(PostFader, *session, _route, *_plugin_selector, _rr_selection); pre_redir_hpane.pack1 (*pre_redirect_box); post_redir_hpane.pack1 (*post_redirect_box); @@ -256,13 +252,13 @@ RouteParams_UI::setup_io_frames() cleanup_io_frames(); // input - _input_iosel = new IOSelector (*session, *_route, true); + _input_iosel = new IOSelector (*session, _route, true); _input_iosel->redisplay (); input_frame.add (*_input_iosel); input_frame.show_all(); // output - _output_iosel = new IOSelector (*session, *_route, false); + _output_iosel = new IOSelector (*session, _route, false); _output_iosel->redisplay (); output_frame.add (*_output_iosel); output_frame.show_all(); @@ -322,36 +318,31 @@ RouteParams_UI::cleanup_post_view (bool stopupdate) void -RouteParams_UI::route_removed (Route *route) +RouteParams_UI::route_removed (boost::shared_ptr<Route> route) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_removed), route)); - /* - route_select_list.freeze (); - route_select_list.clear (); - session->foreach_route (this, &RouteParams_UI::add_route); - route_select_list.thaw (); - */ TreeModel::Children rows = route_display_model->children(); TreeModel::Children::iterator ri; for(TreeModel::Children::iterator iter = rows.begin(); iter != rows.end(); ++iter) { - if((*iter)[route_display_columns.route] == route) { + boost::shared_ptr<Route> r =(*iter)[route_display_columns.route]; + + if (r == route) { route_display_model->erase(iter); break; } } - if (route == _route) - { + if (route == _route) { cleanup_io_frames(); cleanup_pre_view(); cleanup_post_view(); cleanup_redirect_boxes(); - _route = 0; - _pre_redirect = 0; - _post_redirect = 0; + _route.reset ((Route*) 0); + _pre_redirect.reset ((Redirect*) 0); + _post_redirect.reset ((Redirect*) 0); update_title(); } } @@ -390,9 +381,9 @@ RouteParams_UI::session_gone () cleanup_post_view(); cleanup_redirect_boxes(); - _route = 0; - _pre_redirect = 0; - _post_redirect = 0; + _route.reset ((Route*) 0); + _pre_redirect.reset ((Redirect*) 0); + _post_redirect.reset ((Redirect*) 0); update_title(); ArdourDialog::session_gone(); @@ -406,7 +397,7 @@ RouteParams_UI::route_selected() TreeModel::iterator iter = selection->get_selected(); // only used with Gtk::SELECTION_SINGLE if(iter) { //If anything is selected - Route* route = (*iter)[route_display_columns.route] ; + boost::shared_ptr<Route> route = (*iter)[route_display_columns.route] ; if (_route == route) { // do nothing @@ -447,9 +438,9 @@ RouteParams_UI::route_selected() cleanup_post_view(); cleanup_redirect_boxes(); - _route = 0; - _pre_redirect = 0; - _post_redirect = 0; + _route.reset ((Route*) 0); + _pre_redirect.reset ((Redirect*) 0); + _post_redirect.reset ((Redirect *) 0); track_input_label.set_text(_("NO TRACK")); update_title(); } @@ -468,7 +459,7 @@ RouteParams_UI::route_selected() // cleanup_post_view(); // cleanup_redirect_boxes(); -// _route = 0; +// _route.reset ((Route*)0); // _pre_redirect = 0; // _post_redirect = 0; // track_input_label.set_text(_("NO TRACK")); @@ -495,8 +486,8 @@ RouteParams_UI::redirects_changed (void *src) cleanup_pre_view(); cleanup_post_view(); - _pre_redirect = 0; - _post_redirect = 0; + _pre_redirect.reset ((Redirect*) 0); + _post_redirect.reset ((Redirect*) 0); //update_title(); } @@ -520,24 +511,24 @@ RouteParams_UI::show_track_menu() void -RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement place) +RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Redirect> redirect, ARDOUR::Placement place) { - Insert *insert; + boost::shared_ptr<Insert> insert; if ((place == PreFader && _pre_redirect == redirect) || (place == PostFader && _post_redirect == redirect)){ return; } - if ((insert = dynamic_cast<Insert *> (redirect)) == 0) { - - Send *send; + if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) == 0) { - if ((send = dynamic_cast<Send *> (redirect)) != 0) { + boost::shared_ptr<Send> send; + + if ((send = boost::dynamic_pointer_cast<Send> (redirect)) != 0) { /* its a send */ - SendUI *send_ui = new SendUI (*send, *session); + SendUI *send_ui = new SendUI (send, *session); if (place == PreFader) { cleanup_pre_view(); @@ -560,16 +551,16 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement } else { /* its an insert, though we don't know what kind yet. */ - PluginInsert *plugin_insert; - PortInsert *port_insert; + boost::shared_ptr<PluginInsert> plugin_insert; + boost::shared_ptr<PortInsert> port_insert; - if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) { + if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) { - PluginUI *plugin_ui = new PluginUI (session->engine(), *plugin_insert, true); + PluginUI *plugin_ui = new PluginUI (session->engine(), plugin_insert, true); if (place == PreFader) { cleanup_pre_view(); - _pre_plugin_conn = plugin_insert->plugin().GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader)); + _pre_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader)); plugin_ui->start_updating (0); _active_pre_view = plugin_ui; pre_redir_hpane.pack2 (*_active_pre_view); @@ -577,16 +568,16 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement } else { cleanup_post_view(); - _post_plugin_conn = plugin_insert->plugin().GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader)); + _post_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader)); plugin_ui->start_updating (0); _active_post_view = plugin_ui; post_redir_hpane.pack2 (*_active_post_view); post_redir_hpane.show_all(); } - } else if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) { + } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) { - PortInsertUI *portinsert_ui = new PortInsertUI (*session, *port_insert); + PortInsertUI *portinsert_ui = new PortInsertUI (*session, port_insert); if (place == PreFader) { cleanup_pre_view(); @@ -610,8 +601,7 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement if (place == PreFader) { _pre_redirect = redirect; - } - else { + } else { _post_redirect = redirect; } @@ -620,23 +610,6 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement } void -RouteParams_UI::redirect_unselected (ARDOUR::Redirect *redirect) -{ - // not called anymore - - if (redirect == _pre_redirect) { - cleanup_pre_view(); - _pre_redirect = 0; - } - else if (redirect == _post_redirect) { - cleanup_post_view(); - _post_redirect = 0; - } -} - - - -void RouteParams_UI::plugin_going_away (Plugin *plugin, Placement place) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), plugin, place)); @@ -645,11 +618,11 @@ RouteParams_UI::plugin_going_away (Plugin *plugin, Placement place) if (place == PreFader) { cleanup_pre_view (false); - _pre_redirect = 0; + _pre_redirect.reset ((Redirect*) 0); } else { cleanup_post_view (false); - _post_redirect = 0; + _post_redirect.reset ((Redirect*) 0); } } @@ -661,13 +634,13 @@ RouteParams_UI::redirect_going_away (ARDOUR::Redirect *plugin) printf ("redirect going away\n"); // delete the current view without calling finish - if (plugin == _pre_redirect) { + if (plugin == _pre_redirect.get()) { cleanup_pre_view (false); - _pre_redirect = 0; + _pre_redirect.reset ((Redirect*) 0); } - else if (plugin == _post_redirect) { + else if (plugin == _post_redirect.get()) { cleanup_post_view (false); - _post_redirect = 0; + _post_redirect.reset ((Redirect*) 0); } } diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h index 96b2041db4..5f487d6e5c 100644 --- a/gtk2_ardour/route_params_ui.h +++ b/gtk2_ardour/route_params_ui.h @@ -33,8 +33,9 @@ #include <gtkmm/togglebutton.h> #include <gtkmm/treeview.h> +#include <pbd/stateful.h> + #include <ardour/ardour.h> -#include <ardour/stateful.h> #include <ardour/io.h> #include <ardour/redirect.h> @@ -120,14 +121,14 @@ class RouteParams_UI : public ArdourDialog PluginSelector *_plugin_selector; RouteRedirectSelection _rr_selection; - ARDOUR::Route *_route; + boost::shared_ptr<ARDOUR::Route> _route; sigc::connection _route_conn; sigc::connection _route_ds_conn; - ARDOUR::Redirect * _pre_redirect; + boost::shared_ptr<ARDOUR::Redirect> _pre_redirect; sigc::connection _pre_plugin_conn; - ARDOUR::Redirect * _post_redirect; + boost::shared_ptr<ARDOUR::Redirect> _post_redirect; sigc::connection _post_plugin_conn; @@ -150,7 +151,7 @@ class RouteParams_UI : public ArdourDialog add(route); } Gtk::TreeModelColumn<Glib::ustring> text; - Gtk::TreeModelColumn<ARDOUR::Route*> route; + Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route; }; RouteDisplayModelColumns route_display_columns ; @@ -158,10 +159,10 @@ class RouteParams_UI : public ArdourDialog Glib::RefPtr<Gtk::ListStore> route_display_model; - void add_route (ARDOUR::Route*); + void add_route (boost::shared_ptr<ARDOUR::Route>); - void route_name_changed (void *src, ARDOUR::Route *route); - void route_removed (ARDOUR::Route *route); + void route_name_changed (void *src, boost::shared_ptr<ARDOUR::Route> route); + void route_removed (boost::shared_ptr<ARDOUR::Route> route); void route_selected(); @@ -179,8 +180,7 @@ class RouteParams_UI : public ArdourDialog void setup_redirect_boxes(); void cleanup_redirect_boxes(); - void redirect_selected (ARDOUR::Redirect *, ARDOUR::Placement); - void redirect_unselected (ARDOUR::Redirect *); + void redirect_selected (boost::shared_ptr<ARDOUR::Redirect>, ARDOUR::Placement); void plugin_going_away (ARDOUR::Plugin *foo, ARDOUR::Placement); void redirect_going_away (ARDOUR::Redirect *foo); diff --git a/gtk2_ardour/route_redirect_selection.cc b/gtk2_ardour/route_redirect_selection.cc index 6d315e0aae..76f202dd92 100644 --- a/gtk2_ardour/route_redirect_selection.cc +++ b/gtk2_ardour/route_redirect_selection.cc @@ -61,17 +61,6 @@ RouteRedirectSelection::clear () void RouteRedirectSelection::clear_redirects () { - for (RedirectSelection::iterator i = redirects.begin(); i != redirects.end(); ) { - RedirectSelection::iterator tmp; - - tmp = i; - ++tmp; - - delete *i; - - i = tmp; - } - redirects.clear (); RedirectsChanged (); } @@ -84,29 +73,32 @@ RouteRedirectSelection::clear_routes () } void -RouteRedirectSelection::add (Redirect* r) +RouteRedirectSelection::add (boost::shared_ptr<Redirect> r) { if (find (redirects.begin(), redirects.end(), r) == redirects.end()) { redirects.push_back (r); - - void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove; - r->GoingAway.connect (mem_fun(*this, pmf)); + + // XXX SHAREDPTR FIXME + // void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove; + // r->GoingAway.connect (mem_fun(*this, pmf)); RedirectsChanged(); } } void -RouteRedirectSelection::add (const vector<Redirect*>& rlist) +RouteRedirectSelection::add (const vector<boost::shared_ptr<Redirect> >& rlist) { bool changed = false; - for (vector<Redirect*>::const_iterator i = rlist.begin(); i != rlist.end(); ++i) { + for (vector<boost::shared_ptr<Redirect> >::const_iterator i = rlist.begin(); i != rlist.end(); ++i) { if (find (redirects.begin(), redirects.end(), *i) == redirects.end()) { redirects.push_back (*i); - void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove; - (*i)->GoingAway.connect (mem_fun(*this, pmf)); + // XXX SHAREDPTR FIXME + + //void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove; + // (*i)->GoingAway.connect (mem_fun(*this, pmf)); changed = true; } } @@ -117,9 +109,9 @@ RouteRedirectSelection::add (const vector<Redirect*>& rlist) } void -RouteRedirectSelection::remove (Redirect* r) +RouteRedirectSelection::remove (boost::shared_ptr<Redirect> r) { - list<Redirect*>::iterator i; + list<boost::shared_ptr<Redirect> >::iterator i; if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) { redirects.erase (i); RedirectsChanged (); @@ -127,36 +119,37 @@ RouteRedirectSelection::remove (Redirect* r) } void -RouteRedirectSelection::set (Redirect *r) +RouteRedirectSelection::set (boost::shared_ptr<Redirect> r) { clear_redirects (); add (r); } void -RouteRedirectSelection::set (const vector<Redirect*>& rlist) +RouteRedirectSelection::set (const vector<boost::shared_ptr<Redirect> >& rlist) { clear_redirects (); add (rlist); } void -RouteRedirectSelection::add (Route* r) +RouteRedirectSelection::add (boost::shared_ptr<Route> r) { if (find (routes.begin(), routes.end(), r) == routes.end()) { routes.push_back (r); - void (RouteRedirectSelection::*pmf)(Route*) = &RouteRedirectSelection::remove; - r->GoingAway.connect (bind (mem_fun(*this, pmf), r)); + // XXX SHAREDPTR FIXME + // void (RouteRedirectSelection::*pmf)(Route*) = &RouteRedirectSelection::remove; + // r->GoingAway.connect (bind (mem_fun(*this, pmf), r)); RoutesChanged(); } } void -RouteRedirectSelection::remove (Route* r) +RouteRedirectSelection::remove (boost::shared_ptr<Route> r) { - list<Route*>::iterator i; + list<boost::shared_ptr<Route> >::iterator i; if ((i = find (routes.begin(), routes.end(), r)) != routes.end()) { routes.erase (i); RoutesChanged (); @@ -164,16 +157,16 @@ RouteRedirectSelection::remove (Route* r) } void -RouteRedirectSelection::set (Route *r) +RouteRedirectSelection::set (boost::shared_ptr<Route> r) { clear_routes (); add (r); } bool -RouteRedirectSelection::selected (Route* ms) +RouteRedirectSelection::selected (boost::shared_ptr<Route> r) { - return find (routes.begin(), routes.end(), ms) != routes.end(); + return find (routes.begin(), routes.end(), r) != routes.end(); } bool diff --git a/gtk2_ardour/route_redirect_selection.h b/gtk2_ardour/route_redirect_selection.h index 9e2b866171..60d301e762 100644 --- a/gtk2_ardour/route_redirect_selection.h +++ b/gtk2_ardour/route_redirect_selection.h @@ -43,20 +43,20 @@ class RouteRedirectSelection : public sigc::trackable void clear (); bool empty(); - void set (ARDOUR::Redirect*); - void set (const std::vector<ARDOUR::Redirect*>&); - void add (ARDOUR::Redirect*); - void add (const std::vector<ARDOUR::Redirect*>&); - void remove (ARDOUR::Redirect*); + void set (boost::shared_ptr<ARDOUR::Redirect>); + void set (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&); + void add (boost::shared_ptr<ARDOUR::Redirect>); + void add (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&); + void remove (boost::shared_ptr<ARDOUR::Redirect>); - void set (ARDOUR::Route*); - void add (ARDOUR::Route*); - void remove (ARDOUR::Route*); + void set (boost::shared_ptr<ARDOUR::Route>); + void add (boost::shared_ptr<ARDOUR::Route>); + void remove (boost::shared_ptr<ARDOUR::Route>); void clear_redirects (); void clear_routes (); - bool selected (ARDOUR::Route*); + bool selected (boost::shared_ptr<ARDOUR::Route>); }; bool operator==(const RouteRedirectSelection& a, const RouteRedirectSelection& b); diff --git a/gtk2_ardour/route_selection.h b/gtk2_ardour/route_selection.h index 50797deed3..8d5673a2ef 100644 --- a/gtk2_ardour/route_selection.h +++ b/gtk2_ardour/route_selection.h @@ -1,12 +1,14 @@ #ifndef __ardour_gtk_route_selection_h__ #define __ardour_gtk_route_selection_h__ + +#include <boost/shared_ptr.hpp> #include <list> namespace ARDOUR { class Route; } -struct RouteSelection : list<ARDOUR::Route*> {}; +struct RouteSelection : std::list<boost::shared_ptr<ARDOUR::Route> > {}; #endif /* __ardour_gtk_route_selection_h__ */ diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc new file mode 100644 index 0000000000..8dca7be480 --- /dev/null +++ b/gtk2_ardour/route_time_axis.cc @@ -0,0 +1,1601 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include <cstdlib> +#include <cmath> +#include <cassert> + +#include <algorithm> +#include <string> +#include <vector> + +#include <sigc++/bind.h> + +#include <pbd/error.h> +#include <pbd/stl_delete.h> +#include <pbd/whitespace.h> + +#include <gtkmm/menu.h> +#include <gtkmm/menuitem.h> +#include <gtkmm2ext/gtk_ui.h> +#include <gtkmm2ext/selector.h> +#include <gtkmm2ext/stop_signal.h> +#include <gtkmm2ext/bindable_button.h> +#include <gtkmm2ext/utils.h> + +#include <ardour/playlist.h> +#include <ardour/diskstream.h> +#include <ardour/insert.h> +#include <ardour/ladspa_plugin.h> +#include <ardour/location.h> +#include <ardour/panner.h> +#include <ardour/playlist.h> +#include <ardour/session.h> +#include <ardour/session_playlist.h> +#include <ardour/utils.h> + +#include "ardour_ui.h" +#include "route_time_axis.h" +#include "automation_time_axis.h" +#include "redirect_automation_time_axis.h" +#include "redirect_automation_line.h" +#include "canvas_impl.h" +#include "crossfade_view.h" +#include "enums.h" +#include "gui_thread.h" +#include "keyboard.h" +#include "playlist_selector.h" +#include "plugin_selector.h" +#include "plugin_ui.h" +#include "point_selection.h" +#include "prompter.h" +#include "public_editor.h" +#include "region_view.h" +#include "rgb_macros.h" +#include "selection.h" +#include "simplerect.h" +#include "streamview.h" +#include "utils.h" + +#include <ardour/track.h> + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; +using namespace Gtk; +using namespace Editing; + + +RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas) + : AxisView(sess), + RouteUI(rt, sess, _("m"), _("s"), _("r")), // mute, solo, and record + TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas), + parent_canvas (canvas), + button_table (3, 3), + edit_group_button (_("g")), // group + playlist_button (_("p")), + size_button (_("h")), // height + automation_button (_("a")), + visual_button (_("v")) + +{ + _has_state = true; + playlist_menu = 0; + playlist_action_menu = 0; + automation_action_menu = 0; + _view = 0; + timestretch_rect = 0; + no_redraw = false; + + ignore_toggle = false; + + mute_button->set_active (false); + solo_button->set_active (false); + + mute_button->set_name ("TrackMuteButton"); + solo_button->set_name ("SoloButton"); + edit_group_button.set_name ("TrackGroupButton"); + playlist_button.set_name ("TrackPlaylistButton"); + automation_button.set_name ("TrackAutomationButton"); + size_button.set_name ("TrackSizeButton"); + visual_button.set_name ("TrackVisualButton"); + hide_button.set_name ("TrackRemoveButton"); + + hide_button.add (*(manage (new Image (get_xpm("small_x.xpm"))))); + + solo_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + mute_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + playlist_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + automation_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + size_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + visual_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + hide_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + + solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false); + solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false); + mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false); + mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false); + edit_group_button.signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::edit_click), false); + playlist_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::playlist_click)); + automation_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::automation_click)); + size_button.signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::size_click), false); + visual_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::visual_click)); + hide_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::hide_click)); + + if (is_track()) { + rec_enable_button->set_active (false); + rec_enable_button->set_name ("TrackRecordEnableButton"); + rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false); + rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press)); + controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); + ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record")); + } + + controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); + controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0); + + controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0); + + ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo")); + ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute")); + ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group")); + ARDOUR_UI::instance()->tooltips().set_tip(size_button,_("Display Height")); + ARDOUR_UI::instance()->tooltips().set_tip(playlist_button,_("Playlist")); + ARDOUR_UI::instance()->tooltips().set_tip(automation_button, _("Automation")); + ARDOUR_UI::instance()->tooltips().set_tip(visual_button, _("Visual options")); + ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("Hide this track")); + + label_view (); + + controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + + if (is_track() && track()->mode() == ARDOUR::Normal) { + controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + } + + /* remove focus from the buttons */ + + automation_button.unset_flags (Gtk::CAN_FOCUS); + solo_button->unset_flags (Gtk::CAN_FOCUS); + mute_button->unset_flags (Gtk::CAN_FOCUS); + edit_group_button.unset_flags (Gtk::CAN_FOCUS); + size_button.unset_flags (Gtk::CAN_FOCUS); + playlist_button.unset_flags (Gtk::CAN_FOCUS); + hide_button.unset_flags (Gtk::CAN_FOCUS); + visual_button.unset_flags (Gtk::CAN_FOCUS); + + /* map current state of the route */ + + update_diskstream_display (); + solo_changed(0); + mute_changed(0); + //redirects_changed (0); + //reset_redirect_automation_curves (); + y_position = -1; + + _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed)); + _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); + _route->redirects_changed.connect (mem_fun(*this, &RouteTimeAxisView::redirects_changed)); + _route->name_changed.connect (mem_fun(*this, &RouteTimeAxisView::route_name_changed)); + _route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed)); + + if (is_track()) { + + track()->FreezeChange.connect (mem_fun(*this, &RouteTimeAxisView::map_frozen)); + track()->DiskstreamChanged.connect (mem_fun(*this, &RouteTimeAxisView::diskstream_changed)); + get_diskstream()->SpeedChanged.connect (mem_fun(*this, &RouteTimeAxisView::speed_changed)); + + /* ask for notifications of any new RegionViews */ + // FIXME: _view is NULL, but it would be nice to attach this here :/ + //_view->RegionViewAdded.connect (mem_fun(*this, &RouteTimeAxisView::region_view_added)); + //_view->attach (); + + /* pick up the correct freeze state */ + map_frozen (); + + } + + editor.ZoomChanged.connect (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit)); + ColorChanged.connect (mem_fun (*this, &RouteTimeAxisView::color_handler)); +} + +RouteTimeAxisView::~RouteTimeAxisView () +{ + GoingAway (); /* EMIT_SIGNAL */ + + vector_delete (&redirect_automation_curves); + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + delete *i; + } + + if (playlist_menu) { + delete playlist_menu; + playlist_menu = 0; + } + + if (playlist_action_menu) { + delete playlist_action_menu; + playlist_action_menu = 0; + } + + if (_view) { + delete _view; + _view = 0; + } +} + +void +RouteTimeAxisView::set_playlist (Playlist *newplaylist) +{ + Playlist *pl = playlist(); + assert(pl); + + modified_connection.disconnect (); + state_changed_connection.disconnect (); + + state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed)); + modified_connection = pl->Modified.connect (mem_fun(*this, &RouteTimeAxisView::playlist_modified)); +} + +void +RouteTimeAxisView::playlist_modified () +{ +} + +gint +RouteTimeAxisView::edit_click (GdkEventButton *ev) +{ + if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { + _route->set_edit_group (0, this); + return FALSE; + } + + using namespace Menu_Helpers; + + MenuList& items = edit_group_menu.items (); + RadioMenuItem::Group group; + + items.clear (); + items.push_back (RadioMenuElem (group, _("No group"), + bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0))); + + if (_route->edit_group() == 0) { + static_cast<RadioMenuItem*>(&items.back())->set_active (); + } + + _session.foreach_edit_group (bind (mem_fun (*this, &RouteTimeAxisView::add_edit_group_menu_item), &group)); + edit_group_menu.popup (ev->button, ev->time); + + return FALSE; +} + +void +RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Group* group) +{ + using namespace Menu_Helpers; + + MenuList &items = edit_group_menu.items(); + + cerr << "adding edit group " << eg->name() << endl; + + items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), eg))); + if (_route->edit_group() == eg) { + static_cast<RadioMenuItem*>(&items.back())->set_active (); + } +} + +void +RouteTimeAxisView::set_edit_group_from_menu (RouteGroup *eg) + +{ + _route->set_edit_group (eg, this); +} + +void +RouteTimeAxisView::playlist_state_changed (Change ignored) +{ + // ENSURE_GUI_THREAD (bind (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed), ignored)); + // why are we here ? +} + +void +RouteTimeAxisView::playlist_changed () + +{ + label_view (); + + if (is_track()) { + set_playlist (dynamic_cast<Playlist*>(get_diskstream()->playlist())); + } +} + +void +RouteTimeAxisView::label_view () +{ + string x = _route->name(); + + if (x != name_entry.get_text()) { + name_entry.set_text (x); + } + + ARDOUR_UI::instance()->tooltips().set_tip (name_entry, x); +} + +void +RouteTimeAxisView::route_name_changed (void *src) +{ + editor.route_name_changed (this); + label_view (); +} + +void +RouteTimeAxisView::take_name_changed (void *src) + +{ + if (src != this) { + label_view (); + } +} + +void +RouteTimeAxisView::playlist_click () +{ + // always build a new action menu + + if (playlist_action_menu == 0) { + playlist_action_menu = new Menu; + playlist_action_menu->set_name ("ArdourContextMenu"); + } + + build_playlist_menu(playlist_action_menu); + + playlist_action_menu->popup (1, 0); +} + +void +RouteTimeAxisView::automation_click () +{ + if (automation_action_menu == 0) { + /* this seems odd, but the automation action + menu is built as part of the display menu. + */ + build_display_menu (); + } + automation_action_menu->popup (1, 0); +} + +void +RouteTimeAxisView::build_automation_action_menu () +{ + using namespace Menu_Helpers; + + automation_action_menu = manage (new Menu); + MenuList& automation_items = automation_action_menu->items(); + automation_action_menu->set_name ("ArdourContextMenu"); + + automation_items.push_back (MenuElem (_("Show all automation"), + mem_fun(*this, &RouteTimeAxisView::show_all_automation))); + + automation_items.push_back (MenuElem (_("Show existing automation"), + mem_fun(*this, &RouteTimeAxisView::show_existing_automation))); + + automation_items.push_back (MenuElem (_("Hide all automation"), + mem_fun(*this, &RouteTimeAxisView::hide_all_automation))); + + automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu)); +} + +void +RouteTimeAxisView::build_display_menu () +{ + using namespace Menu_Helpers; + + /* get the size menu ready */ + + build_size_menu (); + + /* prepare it */ + + TimeAxisView::build_display_menu (); + + /* now fill it with our stuff */ + + MenuList& items = display_menu->items(); + display_menu->set_name ("ArdourContextMenu"); + + items.push_back (MenuElem (_("Height"), *size_menu)); + items.push_back (MenuElem (_("Color"), mem_fun(*this, &RouteTimeAxisView::select_track_color))); + + items.push_back (SeparatorElem()); + + build_remote_control_menu (); + items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu)); + + build_automation_action_menu (); + items.push_back (MenuElem (_("Automation"), *automation_action_menu)); + + // Hook for derived classes to add type specific stuff + items.push_back (SeparatorElem()); + append_extra_display_menu_items (); + items.push_back (SeparatorElem()); + + if (is_track()) { + + Menu* alignment_menu = manage (new Menu); + MenuList& alignment_items = alignment_menu->items(); + alignment_menu->set_name ("ArdourContextMenu"); + + RadioMenuItem::Group align_group; + + alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"), + bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), ExistingMaterial))); + align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); + if (get_diskstream()->alignment_style() == ExistingMaterial) + align_existing_item->set_active(); + + alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"), + bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), CaptureTime))); + align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back()); + if (get_diskstream()->alignment_style() == CaptureTime) + align_capture_item->set_active(); + + items.push_back (MenuElem (_("Alignment"), *alignment_menu)); + + get_diskstream()->AlignmentStyleChanged.connect ( + mem_fun(*this, &RouteTimeAxisView::align_style_changed)); + } + + items.push_back (SeparatorElem()); + items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active))); + route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back()); + route_active_menu_item->set_active (_route->active()); + + items.push_back (SeparatorElem()); + items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route))); +} + + +void +RouteTimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end) +{ + double x1; + double x2; + double y2; + + TimeAxisView::show_timestretch (start, end); + + hide_timestretch (); + +#if 0 + if (ts.empty()) { + return; + } + + + /* check that the time selection was made in our route, or our edit group. + remember that edit_group() == 0 implies the route is *not* in a edit group. + */ + + if (!(ts.track == this || (ts.group != 0 && ts.group == _route->edit_group()))) { + /* this doesn't apply to us */ + return; + } + + /* ignore it if our edit group is not active */ + + if ((ts.track != this) && _route->edit_group() && !_route->edit_group()->is_active()) { + return; + } +#endif + + if (timestretch_rect == 0) { + timestretch_rect = new SimpleRect (*canvas_display); + timestretch_rect->property_x1() = 0.0; + timestretch_rect->property_y1() = 0.0; + timestretch_rect->property_x2() = 0.0; + timestretch_rect->property_y2() = 0.0; + timestretch_rect->property_fill_color_rgba() = color_map[cTimeStretchFill]; + timestretch_rect->property_outline_color_rgba() = color_map[cTimeStretchOutline]; + } + + timestretch_rect->show (); + timestretch_rect->raise_to_top (); + + x1 = start / editor.get_current_zoom(); + x2 = (end - 1) / editor.get_current_zoom(); + y2 = height - 2; + + timestretch_rect->property_x1() = x1; + timestretch_rect->property_y1() = 1.0; + timestretch_rect->property_x2() = x2; + timestretch_rect->property_y2() = y2; +} + +void +RouteTimeAxisView::hide_timestretch () +{ + TimeAxisView::hide_timestretch (); + + if (timestretch_rect) { + timestretch_rect->hide (); + } +} + +void +RouteTimeAxisView::show_selection (TimeSelection& ts) +{ + +#if 0 + /* ignore it if our edit group is not active or if the selection was started + in some other track or edit group (remember that edit_group() == 0 means + that the track is not in an edit group). + */ + + if (((ts.track != this && !is_child (ts.track)) && _route->edit_group() && !_route->edit_group()->is_active()) || + (!(ts.track == this || is_child (ts.track) || (ts.group != 0 && ts.group == _route->edit_group())))) { + hide_selection (); + return; + } +#endif + + TimeAxisView::show_selection (ts); +} + +void +RouteTimeAxisView::set_height (TrackHeight h) +{ + bool height_changed = (height == 0) || (h != height_style); + + TimeAxisView::set_height (h); + + ensure_xml_node (); + + _view->set_height ((double) height); + + switch (height_style) { + case Largest: + xml_node->add_property ("track_height", "largest"); + break; + + case Large: + xml_node->add_property ("track_height", "large"); + break; + + case Larger: + xml_node->add_property ("track_height", "larger"); + break; + + case Normal: + xml_node->add_property ("track_height", "normal"); + break; + + case Smaller: + xml_node->add_property ("track_height", "smaller"); + break; + + case Small: + xml_node->add_property ("track_height", "small"); + break; + } + + switch (height_style) { + case Largest: + case Large: + case Larger: + case Normal: + show_name_entry (); + hide_name_label (); + + mute_button->show_all(); + solo_button->show_all(); + if (rec_enable_button) + rec_enable_button->show_all(); + + edit_group_button.show_all(); + hide_button.show_all(); + visual_button.show_all(); + size_button.show_all(); + automation_button.show_all(); + + if (is_track() && track()->mode() == ARDOUR::Normal) { + playlist_button.show_all(); + } + break; + + case Smaller: + show_name_entry (); + hide_name_label (); + + mute_button->show_all(); + solo_button->show_all(); + if (rec_enable_button) + rec_enable_button->show_all(); + + edit_group_button.hide (); + hide_button.hide (); + visual_button.hide (); + size_button.hide (); + automation_button.hide (); + + if (is_track() && track()->mode() == ARDOUR::Normal) { + playlist_button.hide (); + } + break; + + case Small: + hide_name_entry (); + show_name_label (); + + mute_button->hide(); + solo_button->hide(); + if (rec_enable_button) + rec_enable_button->hide(); + + edit_group_button.hide (); + hide_button.hide (); + visual_button.hide (); + size_button.hide (); + automation_button.hide (); + playlist_button.hide (); + name_label.set_text (_route->name()); + break; + } + + if (height_changed) { + /* only emit the signal if the height really changed */ + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + } +} + +void +RouteTimeAxisView::select_track_color () +{ + if (RouteUI::choose_color ()) { + + if (_view) { + _view->apply_color (_color, StreamView::RegionColor); + } + } +} + +void +RouteTimeAxisView::reset_samples_per_unit () +{ + set_samples_per_unit (editor.get_current_zoom()); +} + +void +RouteTimeAxisView::set_samples_per_unit (double spu) +{ + double speed = 1.0; + + if (get_diskstream() != 0) { + speed = get_diskstream()->speed(); + } + + if (_view) { + _view->set_samples_per_unit (spu * speed); + } + + TimeAxisView::set_samples_per_unit (spu * speed); +} + +void +RouteTimeAxisView::align_style_changed () +{ + switch (get_diskstream()->alignment_style()) { + case ExistingMaterial: + if (!align_existing_item->get_active()) { + align_existing_item->set_active(); + } + break; + case CaptureTime: + if (!align_capture_item->get_active()) { + align_capture_item->set_active(); + } + break; + } +} + +void +RouteTimeAxisView::set_align_style (AlignStyle style) +{ + get_diskstream()->set_align_style (style); +} + +void +RouteTimeAxisView::rename_current_playlist () +{ + ArdourPrompter prompter (true); + string name; + + Diskstream *const ds = get_diskstream(); + if (!ds || ds->destructive()) + return; + + Playlist *const pl = ds->playlist(); + if (!pl) + return; + + prompter.set_prompt (_("Name for playlist")); + prompter.set_initial_text (pl->name()); + prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT); + prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); + + switch (prompter.run ()) { + case Gtk::RESPONSE_ACCEPT: + prompter.get_result (name); + if (name.length()) { + pl->set_name (name); + } + break; + + default: + break; + } +} + +void +RouteTimeAxisView::use_copy_playlist (bool prompt) +{ + string name; + + Diskstream *const ds = get_diskstream(); + if (!ds || ds->destructive()) + return; + + Playlist *const pl = ds->playlist(); + if (!pl) + return; + + name = Playlist::bump_name (pl->name(), _session); + + if (prompt) { + + ArdourPrompter prompter (true); + + prompter.set_prompt (_("Name for Playlist")); + prompter.set_initial_text (name); + prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT); + prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); + prompter.show_all (); + + switch (prompter.run ()) { + case Gtk::RESPONSE_ACCEPT: + prompter.get_result (name); + break; + + default: + return; + } + } + + if (name.length()) { + ds->use_copy_playlist (); + pl->set_name (name); + } +} + +void +RouteTimeAxisView::use_new_playlist (bool prompt) +{ + string name; + + Diskstream *const ds = get_diskstream(); + if (!ds || ds->destructive()) + return; + + Playlist *const pl = ds->playlist(); + if (!pl) + return; + + name = Playlist::bump_name (pl->name(), _session); + + if (prompt) { + + ArdourPrompter prompter (true); + + prompter.set_prompt (_("Name for Playlist")); + prompter.set_initial_text (name); + prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT); + prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); + + switch (prompter.run ()) { + case Gtk::RESPONSE_ACCEPT: + prompter.get_result (name); + break; + + default: + return; + } + } + + if (name.length()) { + ds->use_new_playlist (); + pl->set_name (name); + } +} + +void +RouteTimeAxisView::clear_playlist () +{ + Diskstream *const ds = get_diskstream(); + if (!ds || ds->destructive()) + return; + + Playlist *const pl = ds->playlist(); + if (!pl) + return; + + editor.clear_playlist (*pl); +} + +void +RouteTimeAxisView::speed_changed () +{ + Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit)); +} + +void +RouteTimeAxisView::diskstream_changed () +{ + Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::update_diskstream_display)); +} + +void +RouteTimeAxisView::update_diskstream_display () +{ + if (!get_diskstream()) // bus + return; + + set_playlist (get_diskstream()->playlist()); + map_frozen (); +} + +void +RouteTimeAxisView::selection_click (GdkEventButton* ev) +{ + PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route->edit_group()); + + switch (Keyboard::selection_type (ev->state)) { + case Selection::Toggle: + /* XXX this is not right */ + editor.get_selection().add (*tracks); + break; + + case Selection::Set: + editor.get_selection().set (*tracks); + break; + + case Selection::Extend: + /* not defined yet */ + break; + } + + delete tracks; +} + +void +RouteTimeAxisView::set_selected_points (PointSelection& points) +{ + for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { + (*i)->set_selected_points (points); + } +} + +void +RouteTimeAxisView::set_selected_regionviews (RegionSelection& regions) +{ + _view->set_selected_regionviews (regions); +} + +void +RouteTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results) +{ + double speed = 1.0; + + if (get_diskstream() != 0) { + speed = get_diskstream()->speed(); + } + + jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed); + jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed); + + if (_view && ((top < 0.0 && bot < 0.0)) || touched (top, bot)) { + _view->get_selectables (start_adjusted, end_adjusted, results); + } + + /* pick up visible automation tracks */ + + for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { + if (!(*i)->hidden()) { + (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results); + } + } +} + +void +RouteTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results) +{ + if (_view) { + _view->get_inverted_selectables (sel, results); + } + + for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { + if (!(*i)->hidden()) { + (*i)->get_inverted_selectables (sel, results); + } + } + + return; +} + +RouteGroup* +RouteTimeAxisView::edit_group() const +{ + return _route->edit_group(); +} + +string +RouteTimeAxisView::name() const +{ + return _route->name(); +} + +Playlist * +RouteTimeAxisView::playlist () const +{ + Diskstream *ds; + + if ((ds = get_diskstream()) != 0) { + return ds->playlist(); + } else { + return 0; + } +} + +void +RouteTimeAxisView::name_entry_changed () +{ + string x; + + x = name_entry.get_text (); + + if (x == _route->name()) { + return; + } + + if (x.length() == 0) { + name_entry.set_text (_route->name()); + return; + } + + strip_whitespace_edges(x); + + if (_session.route_name_unique (x)) { + _route->set_name (x, this); + } else { + ARDOUR_UI::instance()->popup_error (_("a track already exists with that name")); + name_entry.set_text (_route->name()); + } +} + +void +RouteTimeAxisView::visual_click () +{ + popup_display_menu (0); +} + +void +RouteTimeAxisView::hide_click () +{ + editor.hide_track_in_display (*this); +} + +Region* +RouteTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir) +{ + Diskstream *stream; + Playlist *playlist; + + if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) { + return playlist->find_next_region (pos, point, dir); + } + + return 0; +} + +bool +RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) +{ + Playlist* what_we_got; + Diskstream* ds = get_diskstream(); + Playlist* playlist; + bool ret = false; + + if (ds == 0) { + /* route is a bus, not a track */ + return false; + } + + playlist = ds->playlist(); + + + TimeSelection time (selection.time); + float speed = ds->speed(); + if (speed != 1.0f) { + for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) { + (*i).start = session_frame_to_track_frame((*i).start, speed); + (*i).end = session_frame_to_track_frame((*i).end, speed); + } + } + + switch (op) { + case Cut: + _session.add_undo (playlist->get_memento()); + if ((what_we_got = playlist->cut (time)) != 0) { + editor.get_cut_buffer().add (what_we_got); + _session.add_redo_no_execute (playlist->get_memento()); + ret = true; + } + break; + case Copy: + if ((what_we_got = playlist->copy (time)) != 0) { + editor.get_cut_buffer().add (what_we_got); + } + break; + + case Clear: + _session.add_undo (playlist->get_memento()); + if ((what_we_got = playlist->cut (time)) != 0) { + _session.add_redo_no_execute (playlist->get_memento()); + what_we_got->unref (); + ret = true; + } + break; + } + + return ret; +} + +bool +RouteTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth) +{ + if (!is_track()) { + return false; + } + + Playlist* playlist = get_diskstream()->playlist(); + PlaylistSelection::iterator p; + + for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth); + + if (p == selection.playlists.end()) { + return false; + } + + if (get_diskstream()->speed() != 1.0f) + pos = session_frame_to_track_frame(pos, get_diskstream()->speed() ); + + _session.add_undo (playlist->get_memento()); + playlist->paste (**p, pos, times); + _session.add_redo_no_execute (playlist->get_memento()); + + return true; +} + + +list<TimeAxisView*> +RouteTimeAxisView::get_child_list() +{ + + list<TimeAxisView*>redirect_children; + + for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { + if (!(*i)->hidden()) { + redirect_children.push_back(*i); + } + } + return redirect_children; +} + + +void +RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu) +{ + using namespace Menu_Helpers; + + if (!menu || !is_track()) { + return; + } + + MenuList& playlist_items = menu->items(); + menu->set_name ("ArdourContextMenu"); + playlist_items.clear(); + + if (playlist_menu) { + delete playlist_menu; + } + playlist_menu = new Menu; + playlist_menu->set_name ("ArdourContextMenu"); + + playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name()))); + playlist_items.push_back (SeparatorElem()); + + playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist))); + playlist_items.push_back (SeparatorElem()); + + playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists))); + playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists))); + playlist_items.push_back (SeparatorElem()); + playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists))); + playlist_items.push_back (SeparatorElem()); + playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector))); + +} + +void +RouteTimeAxisView::show_playlist_selector () +{ + editor.playlist_selector().show_for (this); +} + +void +RouteTimeAxisView::map_frozen () +{ + if (!is_track()) { + return; + } + + ENSURE_GUI_THREAD (mem_fun(*this, &RouteTimeAxisView::map_frozen)); + + switch (track()->freeze_state()) { + case Track::Frozen: + playlist_button.set_sensitive (false); + rec_enable_button->set_sensitive (false); + break; + default: + playlist_button.set_sensitive (true); + rec_enable_button->set_sensitive (true); + break; + } +} + +void +RouteTimeAxisView::color_handler (ColorID id, uint32_t val) +{ + switch (id) { + case cTimeStretchOutline: + timestretch_rect->property_outline_color_rgba() = val; + break; + case cTimeStretchFill: + timestretch_rect->property_fill_color_rgba() = val; + break; + default: + break; + } +} + +bool +RouteTimeAxisView::select_me (GdkEventButton* ev) +{ + editor.get_selection().add (this); + return false; +} + +void +RouteTimeAxisView::show_all_automation () +{ + no_redraw = true; + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { + if ((*ii)->view == 0) { + add_redirect_automation_curve ((*i)->redirect, (*ii)->what); + } + + (*ii)->menu_item->set_active (true); + } + } + + no_redraw = false; + + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ +} + +void +RouteTimeAxisView::show_existing_automation () +{ + no_redraw = true; + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { + if ((*ii)->view != 0) { + (*ii)->menu_item->set_active (true); + } + } + } + + no_redraw = false; + + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ +} + +void +RouteTimeAxisView::hide_all_automation () +{ + no_redraw = true; + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { + (*ii)->menu_item->set_active (false); + } + } + + no_redraw = false; + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ +} + + +void +RouteTimeAxisView::region_view_added (RegionView* rv) +{ + for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { + AutomationTimeAxisView* atv; + + if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) { + rv->add_ghost (*atv); + } + } +} + +void +RouteTimeAxisView::add_ghost_to_redirect (RegionView* rv, AutomationTimeAxisView* atv) +{ + rv->add_ghost (*atv); +} + +RouteTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo () +{ + for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) { + delete *i; + } +} + + +RouteTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode () +{ + parent.remove_ran (this); + + if (view) { + delete view; + } +} + +void +RouteTimeAxisView::remove_ran (RedirectAutomationNode* ran) +{ + if (ran->view) { + remove_child (ran->view); + } +} + +RouteTimeAxisView::RedirectAutomationNode* +RouteTimeAxisView::find_redirect_automation_node (boost::shared_ptr<Redirect> redirect, uint32_t what) +{ + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + + if ((*i)->redirect == redirect) { + + for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) { + if ((*ii)->what == what) { + return *ii; + } + } + } + } + + return 0; +} + +// FIXME: duplicated in midi_time_axis.cc +static string +legalize_for_xml_node (string str) +{ + string::size_type pos; + string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:"; + string legal; + + legal = str; + pos = 0; + + while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) { + legal.replace (pos, 1, "_"); + pos += 1; + } + + return legal; +} + + +void +RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what) +{ + RedirectAutomationLine* ral; + string name; + RedirectAutomationNode* ran; + + if ((ran = find_redirect_automation_node (redirect, what)) == 0) { + fatal << _("programming error: ") + << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"), + redirect->name(), what) + << endmsg; + /*NOTREACHED*/ + return; + } + + if (ran->view) { + return; + } + + name = redirect->describe_parameter (what); + + /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */ + + char state_name[256]; + snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what); + + ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name); + + ral = new RedirectAutomationLine (name, + *redirect, what, _session, *ran->view, + *ran->view->canvas_display, redirect->automation_list (what)); + + ral->set_line_color (color_map[cRedirectAutomationLine]); + ral->queue_reset (); + + ran->view->add_line (*ral); + + ran->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_automation_track_hidden), ran, redirect)); + + if (!ran->view->marked_for_display()) { + ran->view->hide (); + } else { + ran->menu_item->set_active (true); + } + + add_child (ran->view); + + _view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_redirect), ran->view)); + + redirect->mark_automation_visible (what, true); +} + +void +RouteTimeAxisView::redirect_automation_track_hidden (RouteTimeAxisView::RedirectAutomationNode* ran, boost::shared_ptr<Redirect> r) +{ + if (!_hidden) { + ran->menu_item->set_active (false); + } + + r->mark_automation_visible (ran->what, false); + + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ +} + +void +RouteTimeAxisView::add_existing_redirect_automation_curves (boost::shared_ptr<Redirect> redirect) +{ + set<uint32_t> s; + RedirectAutomationLine *ral; + + redirect->what_has_visible_automation (s); + + for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) { + + if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) { + ral->queue_reset (); + } else { + add_redirect_automation_curve (redirect, (*i)); + } + } +} + +void +RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r) +{ + using namespace Menu_Helpers; + RedirectAutomationInfo *rai; + list<RedirectAutomationInfo*>::iterator x; + + const std::set<uint32_t>& automatable = r->what_can_be_automated (); + std::set<uint32_t> has_visible_automation; + + r->what_has_visible_automation(has_visible_automation); + + if (automatable.empty()) { + return; + } + + for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) { + if ((*x)->redirect == r) { + break; + } + } + + if (x == redirect_automation.end()) { + + rai = new RedirectAutomationInfo (r); + redirect_automation.push_back (rai); + + } else { + + rai = *x; + + } + + /* any older menu was deleted at the top of redirects_changed() + when we cleared the subplugin menu. + */ + + rai->menu = manage (new Menu); + MenuList& items = rai->menu->items(); + rai->menu->set_name ("ArdourContextMenu"); + + items.clear (); + + for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) { + + RedirectAutomationNode* ran; + CheckMenuItem* mitem; + + string name = r->describe_parameter (*i); + + items.push_back (CheckMenuElem (name)); + mitem = dynamic_cast<CheckMenuItem*> (&items.back()); + + if (has_visible_automation.find((*i)) != has_visible_automation.end()) { + mitem->set_active(true); + } + + if ((ran = find_redirect_automation_node (r, *i)) == 0) { + + /* new item */ + + ran = new RedirectAutomationNode (*i, mitem, *this); + + rai->lines.push_back (ran); + + } else { + + ran->menu_item = mitem; + + } + + mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_menu_item_toggled), rai, ran)); + } + + /* add the menu for this redirect, because the subplugin + menu is always cleared at the top of redirects_changed(). + this is the result of some poor design in gtkmm and/or + GTK+. + */ + + subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu)); + rai->valid = true; +} + +void +RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo* rai, + RouteTimeAxisView::RedirectAutomationNode* ran) +{ + bool showit = ran->menu_item->get_active(); + bool redraw = false; + + if (ran->view == 0 && showit) { + add_redirect_automation_curve (rai->redirect, ran->what); + redraw = true; + } + + if (showit != ran->view->marked_for_display()) { + + if (showit) { + ran->view->set_marked_for_display (true); + ran->view->canvas_display->show(); + } else { + rai->redirect->mark_automation_visible (ran->what, true); + ran->view->set_marked_for_display (false); + ran->view->hide (); + } + + redraw = true; + + } + + if (redraw && !no_redraw) { + + /* now trigger a redisplay */ + + _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */ + + } +} + +void +RouteTimeAxisView::redirects_changed (void *src) +{ + using namespace Menu_Helpers; + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) { + (*i)->valid = false; + } + + subplugin_menu.items().clear (); + + _route->foreach_redirect (this, &RouteTimeAxisView::add_redirect_to_subplugin_menu); + _route->foreach_redirect (this, &RouteTimeAxisView::add_existing_redirect_automation_curves); + + for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) { + + list<RedirectAutomationInfo*>::iterator tmp; + + tmp = i; + ++tmp; + + if (!(*i)->valid) { + + delete *i; + redirect_automation.erase (i); + + } + + i = tmp; + } + + /* change in visibility was possible */ + + _route->gui_changed ("track_height", this); +} + +RedirectAutomationLine * +RouteTimeAxisView::find_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what) +{ + RedirectAutomationNode* ran; + + if ((ran = find_redirect_automation_node (redirect, what)) != 0) { + if (ran->view) { + return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front()); + } + } + + return 0; +} + +void +RouteTimeAxisView::reset_redirect_automation_curves () +{ + for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) { + (*i)->reset(); + } +} + diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h new file mode 100644 index 0000000000..d305fd390c --- /dev/null +++ b/gtk2_ardour/route_time_axis.h @@ -0,0 +1,256 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: audio_time_axis.h 664 2006-07-05 19:47:25Z drobilla $ +*/ + +#ifndef __ardour_route_time_axis_h__ +#define __ardour_route_time_axis_h__ + +#include <gtkmm/table.h> +#include <gtkmm/button.h> +#include <gtkmm/box.h> +#include <gtkmm/menu.h> +#include <gtkmm/menuitem.h> +#include <gtkmm/radiomenuitem.h> +#include <gtkmm/checkmenuitem.h> + +#include <gtkmm2ext/selector.h> +#include <list> + +#include <ardour/types.h> + +#include "ardour_dialog.h" +#include "route_ui.h" +#include "enums.h" +#include "time_axis_view.h" +#include "canvas.h" +#include "color.h" + +namespace ARDOUR { + class Session; + class Region; + class Diskstream; + class RouteGroup; + class Redirect; + class Insert; + class Location; + class Playlist; +} + +class PublicEditor; +class RegionView; +class StreamView; +class Selection; +class RegionSelection; +class Selectable; +class AutomationTimeAxisView; +class AutomationLine; +class RedirectAutomationLine; +class TimeSelection; + +class RouteTimeAxisView : public RouteUI, public TimeAxisView +{ +public: + RouteTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas); + virtual ~RouteTimeAxisView (); + + void show_selection (TimeSelection&); + + void set_samples_per_unit (double); + void set_height (TimeAxisView::TrackHeight); + void show_timestretch (jack_nframes_t start, jack_nframes_t end); + void hide_timestretch (); + void selection_click (GdkEventButton*); + void set_selected_points (PointSelection&); + void set_selected_regionviews (RegionSelection&); + void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&); + void get_inverted_selectables (Selection&, list<Selectable*>&); + + ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir); + + /* Editing operations */ + bool cut_copy_clear (Selection&, Editing::CutCopyOp); + bool paste (jack_nframes_t, float times, Selection&, size_t nth); + + list<TimeAxisView*> get_child_list(); + + /* The editor calls these when mapping an operation across multiple tracks */ + void use_new_playlist (bool prompt); + void use_copy_playlist (bool prompt); + void clear_playlist (); + + void build_playlist_menu (Gtk::Menu *); + + string name() const; + StreamView* view() const { return _view; } + ARDOUR::RouteGroup* edit_group() const; + ARDOUR::Playlist* playlist() const; + +protected: + friend class StreamView; + + struct RedirectAutomationNode { + uint32_t what; + Gtk::CheckMenuItem* menu_item; + AutomationTimeAxisView* view; + RouteTimeAxisView& parent; + + RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p) + : what (w), menu_item (mitem), view (0), parent (p) {} + + ~RedirectAutomationNode (); + }; + + struct RedirectAutomationInfo { + boost::shared_ptr<ARDOUR::Redirect> redirect; + bool valid; + Gtk::Menu* menu; + vector<RedirectAutomationNode*> lines; + + RedirectAutomationInfo (boost::shared_ptr<ARDOUR::Redirect> r) + : redirect (r), valid (true), menu (0) {} + + ~RedirectAutomationInfo (); + }; + + + void diskstream_changed (); + void update_diskstream_display (); + + gint edit_click (GdkEventButton *); + + void build_redirect_window (); + void redirect_click (); + void redirect_add (); + void redirect_remove (); + void redirect_edit (); + void redirect_relist (); + void redirect_row_selected (gint row, gint col, GdkEvent *ev); + void add_to_redirect_display (ARDOUR::Redirect *); + void redirects_changed (void *); + + void add_redirect_to_subplugin_menu (boost::shared_ptr<ARDOUR::Redirect>); + void remove_ran (RedirectAutomationNode* ran); + + void redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo*, + RouteTimeAxisView::RedirectAutomationNode*); + + void redirect_automation_track_hidden (RedirectAutomationNode*, + boost::shared_ptr<ARDOUR::Redirect>); + + RedirectAutomationNode* + find_redirect_automation_node (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t); + + RedirectAutomationLine* + find_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t); + + void add_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t); + void add_existing_redirect_automation_curves (boost::shared_ptr<ARDOUR::Redirect>); + + void reset_redirect_automation_curves (); + + void update_automation_view (ARDOUR::AutomationType); + + void take_name_changed (void *); + void route_name_changed (void *); + void name_entry_changed (); + + void on_area_realize (); + + virtual void label_view (); + + void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*); + void set_edit_group_from_menu (ARDOUR::RouteGroup *); + + void reset_samples_per_unit (); + + void select_track_color(); + + virtual void build_automation_action_menu (); + virtual void append_extra_display_menu_items () {} + void build_display_menu (); + + void align_style_changed (); + void set_align_style (ARDOUR::AlignStyle); + + virtual void set_playlist (ARDOUR::Playlist *); + void playlist_click (); + void show_playlist_selector (); + void playlist_changed (); + void playlist_state_changed (ARDOUR::Change); + void playlist_modified (); + + void add_playlist_to_playlist_menu (ARDOUR::Playlist*); + void rename_current_playlist (); + + void automation_click (); + virtual void show_all_automation (); + virtual void show_existing_automation (); + virtual void hide_all_automation (); + + void timestretch (jack_nframes_t start, jack_nframes_t end); + + void visual_click (); + void hide_click (); + gint when_displayed (GdkEventAny*); + + void speed_changed (); + + void map_frozen (); + + void color_handler (ColorID, uint32_t); + bool select_me (GdkEventButton*); + + void region_view_added (RegionView*); + void add_ghost_to_redirect (RegionView*, AutomationTimeAxisView*); + + + StreamView* _view; + ArdourCanvas::Canvas& parent_canvas; + bool no_redraw; + + Gtk::HBox other_button_hbox; + Gtk::Table button_table; + Gtk::Button redirect_button; + Gtk::Button edit_group_button; + Gtk::Button playlist_button; + Gtk::Button size_button; + Gtk::Button automation_button; + Gtk::Button hide_button; + Gtk::Button visual_button; + + Gtk::Menu subplugin_menu; + Gtk::Menu* automation_action_menu; + Gtk::Menu edit_group_menu; + Gtk::RadioMenuItem* align_existing_item; + Gtk::RadioMenuItem* align_capture_item; + Gtk::Menu* playlist_menu; + Gtk::Menu* playlist_action_menu; + Gtk::MenuItem* playlist_item; + + ArdourCanvas::SimpleRect* timestretch_rect; + + list<RedirectAutomationInfo*> redirect_automation; + vector<RedirectAutomationLine*> redirect_automation_curves; + + sigc::connection modified_connection; + sigc::connection state_changed_connection; +}; + +#endif /* __ardour_route_time_axis_h__ */ + diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc index 988d6c8b19..8a1fb1c21a 100644 --- a/gtk2_ardour/route_ui.cc +++ b/gtk2_ardour/route_ui.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2002 Paul Davis + Copyright (C) 2002-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,8 +21,8 @@ #include <gtkmm2ext/gtk_ui.h> #include <gtkmm2ext/stop_signal.h> #include <gtkmm2ext/choice.h> -#include <gtkmm2ext/bindable_button.h> #include <gtkmm2ext/doi.h> +#include <gtkmm2ext/bindable_button.h> #include <ardour/route_group.h> #include <pbd/memento_command.h> @@ -45,9 +45,9 @@ using namespace ARDOUR; using namespace PBD; -RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name, +RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, const char* m_name, const char* s_name, const char* r_name) - : AxisView(sess), + : AxisView(sess), _route(rt), mute_button(0), solo_button(0), @@ -65,35 +65,31 @@ RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name, set_color (unique_random_color()); } - _route.GoingAway.connect (mem_fun (*this, &RouteUI::route_removed)); - _route.active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed)); + _route->GoingAway.connect (mem_fun (*this, &RouteUI::route_removed)); + _route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed)); - mute_button = manage (new BindableToggleButton (& _route.midi_mute_control(), m_name )); - mute_button->set_bind_button_state (2, GDK_CONTROL_MASK); - solo_button = manage (new BindableToggleButton (& _route.midi_solo_control(), s_name )); - solo_button->set_bind_button_state (2, GDK_CONTROL_MASK); - - if (is_audio_track()) { - AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); + mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name )); + solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name )); + + if (is_track()) { + boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route); - get_diskstream()->record_enable_changed.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed)); + t->diskstream().RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed)); _session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed)); - rec_enable_button = manage (new BindableToggleButton (& at->midi_rec_enable_control(), r_name )); - rec_enable_button->set_bind_button_state (2, GDK_CONTROL_MASK); + rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name )); - } else { - rec_enable_button = manage (new BindableToggleButton (0, r_name )); - } + rec_enable_button->unset_flags (Gtk::CAN_FOCUS); + + update_rec_display (); + } mute_button->unset_flags (Gtk::CAN_FOCUS); solo_button->unset_flags (Gtk::CAN_FOCUS); - rec_enable_button->unset_flags (Gtk::CAN_FOCUS); /* map the current state */ - update_rec_display (); map_frozen (); } @@ -146,14 +142,14 @@ RouteUI::mute_press(GdkEventButton* ev) */ if (ev->button == 1) { - set_mix_group_mute (_route, !_route.muted()); + set_mix_group_mute (_route, !_route->muted()); } } else { /* plain click applies change to this route */ - reversibly_apply_route_boolean ("mute change", &Route::set_mute, !_route.muted(), this); + reversibly_apply_route_boolean ("mute change", &Route::set_mute, !_route->muted(), this); } } } @@ -231,7 +227,7 @@ RouteUI::solo_press(GdkEventButton* ev) // shift-click: set this route to solo safe - _route.set_solo_safe (!_route.solo_safe(), this); + _route->set_solo_safe (!_route->solo_safe(), this); wait_for_release = false; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { @@ -241,14 +237,14 @@ RouteUI::solo_press(GdkEventButton* ev) */ if (ev->button == 1) { - set_mix_group_solo (_route, !_route.soloed()); + set_mix_group_solo (_route, !_route->soloed()); } } else { /* click: solo this route */ - reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route.soloed(), this); + reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this); } } } @@ -276,7 +272,7 @@ RouteUI::solo_release(GdkEventButton* ev) gint RouteUI::rec_enable_press(GdkEventButton* ev) { - if (!ignore_toggle && is_audio_track()) { + if (!ignore_toggle && is_track() && rec_enable_button) { if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { // do nothing on midi bind event @@ -298,7 +294,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev) } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { - set_mix_group_rec_enable (_route, !_route.record_enabled()); + set_mix_group_rec_enable (_route, !_route->record_enabled()); } else { @@ -326,7 +322,7 @@ RouteUI::update_solo_display () { bool x; - if (solo_button->get_active() != (x = _route.soloed())){ + if (solo_button->get_active() != (x = _route->soloed())){ ignore_toggle = true; solo_button->set_active(x); ignore_toggle = false; @@ -334,7 +330,7 @@ RouteUI::update_solo_display () /* show solo safe */ - if (_route.solo_safe()){ + if (_route->solo_safe()){ solo_button->set_name(safe_solo_button_name()); } else { solo_button->set_name(solo_button_name()); @@ -352,7 +348,7 @@ RouteUI::update_mute_display () { bool x; - if (mute_button->get_active() != (x = _route.muted())){ + if (mute_button->get_active() != (x = _route->muted())){ ignore_toggle = true; mute_button->set_active(x); ignore_toggle = false; @@ -360,7 +356,7 @@ RouteUI::update_mute_display () } void -RouteUI::route_rec_enable_changed (void *src) +RouteUI::route_rec_enable_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display)); } @@ -374,7 +370,7 @@ RouteUI::session_rec_enable_changed () void RouteUI::update_rec_display () { - bool model = _route.record_enabled(); + bool model = _route->record_enabled(); bool view = rec_enable_button->get_active(); /* first make sure the button's "depressed" visual @@ -440,7 +436,7 @@ RouteUI::refresh_remote_control_menu () limit += 4; /* leave some breathing room */ rc_items.push_back (RadioMenuElem (rc_group, _("None"))); - if (_route.remote_control_id() == 0) { + if (_route->remote_control_id() == 0) { rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back()); rc_active->set_active (); } @@ -449,7 +445,7 @@ RouteUI::refresh_remote_control_menu () snprintf (buf, sizeof (buf), "%u", i); rc_items.push_back (RadioMenuElem (rc_group, buf)); rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back()); - if (_route.remote_control_id() == i) { + if (_route->remote_control_id() == i) { rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back()); rc_active->set_active (); } @@ -467,7 +463,7 @@ RouteUI::set_remote_control_id (uint32_t id, CheckMenuItem* item) */ if (item->get_active()) { - _route.set_remote_control_id (id); + _route->set_remote_control_id (id); } } @@ -482,14 +478,14 @@ RouteUI::build_solo_menu (void) CheckMenuItem* check; check = new CheckMenuItem(_("Solo-safe")); - check->set_active (_route.solo_safe()); + check->set_active (_route->solo_safe()); check->signal_toggled().connect (bind (mem_fun (*this, &RouteUI::toggle_solo_safe), check)); - _route.solo_safe_changed.connect(bind (mem_fun (*this, &RouteUI::solo_safe_toggle), check)); + _route->solo_safe_changed.connect(bind (mem_fun (*this, &RouteUI::solo_safe_toggle), check)); items.push_back (CheckMenuElem(*check)); check->show_all(); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); + // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); } @@ -506,39 +502,39 @@ RouteUI::build_mute_menu(void) check = new CheckMenuItem(_("Pre Fader")); init_mute_menu(PRE_FADER, check); check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), PRE_FADER, check)); - _route.pre_fader_changed.connect(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), check)); + _route->pre_fader_changed.connect(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), check)); items.push_back (CheckMenuElem(*check)); check->show_all(); check = new CheckMenuItem(_("Post Fader")); init_mute_menu(POST_FADER, check); check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), POST_FADER, check)); - _route.post_fader_changed.connect(bind (mem_fun (*this, &RouteUI::post_fader_toggle), check)); + _route->post_fader_changed.connect(bind (mem_fun (*this, &RouteUI::post_fader_toggle), check)); items.push_back (CheckMenuElem(*check)); check->show_all(); check = new CheckMenuItem(_("Control Outs")); init_mute_menu(CONTROL_OUTS, check); check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), CONTROL_OUTS, check)); - _route.control_outs_changed.connect(bind (mem_fun (*this, &RouteUI::control_outs_toggle), check)); + _route->control_outs_changed.connect(bind (mem_fun (*this, &RouteUI::control_outs_toggle), check)); items.push_back (CheckMenuElem(*check)); check->show_all(); check = new CheckMenuItem(_("Main Outs")); init_mute_menu(MAIN_OUTS, check); check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), MAIN_OUTS, check)); - _route.main_outs_changed.connect(bind (mem_fun (*this, &RouteUI::main_outs_toggle), check)); + _route->main_outs_changed.connect(bind (mem_fun (*this, &RouteUI::main_outs_toggle), check)); items.push_back (CheckMenuElem(*check)); check->show_all(); items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); + // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn))); } void RouteUI::init_mute_menu(mute_type type, CheckMenuItem* check) { - if (_route.get_mute_config (type)) { + if (_route->get_mute_config (type)) { check->set_active (true); } } @@ -546,21 +542,21 @@ RouteUI::init_mute_menu(mute_type type, CheckMenuItem* check) void RouteUI::toggle_mute_menu(mute_type type, Gtk::CheckMenuItem* check) { - _route.set_mute_config(type, check->get_active(), this); + _route->set_mute_config(type, check->get_active(), this); } void RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check) { - _route.set_solo_safe (check->get_active(), this); + _route->set_solo_safe (check->get_active(), this); } void -RouteUI::set_mix_group_solo(Route& route, bool yn) +RouteUI::set_mix_group_solo(boost::shared_ptr<Route> route, bool yn) { RouteGroup* mix_group; - if((mix_group = route.mix_group()) != 0){ + if((mix_group = route->mix_group()) != 0){ _session.begin_reversible_command (_("mix group solo change")); Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this); mix_group->apply(&Route::set_solo, yn, this); @@ -568,7 +564,7 @@ RouteUI::set_mix_group_solo(Route& route, bool yn) _session.add_command (cmd); _session.commit_reversible_command (); } else { - reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route.soloed(), this); + reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route->soloed(), this); } } @@ -595,11 +591,11 @@ RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*f } void -RouteUI::set_mix_group_mute(Route& route, bool yn) +RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn) { RouteGroup* mix_group; - if((mix_group = route.mix_group()) != 0){ + if((mix_group = route->mix_group()) != 0){ _session.begin_reversible_command (_("mix group mute change")); Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand (_session, this); mix_group->apply(&Route::set_mute, yn, this); @@ -607,16 +603,16 @@ RouteUI::set_mix_group_mute(Route& route, bool yn) _session.add_command(cmd); _session.commit_reversible_command (); } else { - reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route.muted(), this); + reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route->muted(), this); } } void -RouteUI::set_mix_group_rec_enable(Route& route, bool yn) +RouteUI::set_mix_group_rec_enable(boost::shared_ptr<Route> route, bool yn) { RouteGroup* mix_group; - if((mix_group = route.mix_group()) != 0){ + if((mix_group = route->mix_group()) != 0){ _session.begin_reversible_command (_("mix group rec-enable change")); Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this); mix_group->apply (&Route::set_record_enable, yn, this); @@ -624,7 +620,7 @@ RouteUI::set_mix_group_rec_enable(Route& route, bool yn) _session.add_command(cmd); _session.commit_reversible_command (); } else { - reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route.record_enabled(), this); + reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route->record_enabled(), this); } } @@ -655,7 +651,7 @@ RouteUI::set_color (const Gdk::Color & c) snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue()); xml_node->add_property ("color", buf); - _route.gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */ + _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */ } @@ -663,9 +659,9 @@ void RouteUI::ensure_xml_node () { if (xml_node == 0) { - if ((xml_node = _route.extra_xml ("GUI")) == 0) { + if ((xml_node = _route->extra_xml ("GUI")) == 0) { xml_node = new XMLNode ("GUI"); - _route.add_extra_xml (*xml_node); + _route->add_extra_xml (*xml_node); } } } @@ -710,10 +706,10 @@ RouteUI::remove_this_route () vector<string> choices; string prompt; - if (is_audio_track()) { - prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route.name()); + if (is_track()) { + prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route->name()); } else { - prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route.name()); + prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route->name()); } choices.push_back (_("No, do nothing.")); @@ -747,7 +743,7 @@ RouteUI::route_rename () ArdourPrompter name_prompter (true); string result; name_prompter.set_prompt (_("New Name: ")); - name_prompter.set_initial_text (_route.name()); + name_prompter.set_initial_text (_route->name()); name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT); name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); name_prompter.show_all (); @@ -757,7 +753,7 @@ RouteUI::route_rename () case Gtk::RESPONSE_ACCEPT: name_prompter.get_result (result); if (result.length()) { - _route.set_name (result, this); + _route->set_name (result, this); } break; } @@ -771,7 +767,7 @@ RouteUI::name_changed (void *src) { ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::name_changed), src)); - name_label.set_text (_route.name()); + name_label.set_text (_route->name()); } void @@ -780,8 +776,8 @@ RouteUI::toggle_route_active () bool yn; if (route_active_menu_item) { - if (route_active_menu_item->get_active() != (yn = _route.active())) { - _route.set_active (!yn); + if (route_active_menu_item->get_active() != (yn = _route->active())) { + _route->set_active (!yn); } } } @@ -790,7 +786,7 @@ void RouteUI::route_active_changed () { if (route_active_menu_item) { - Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*route_active_menu_item, &CheckMenuItem::set_active), _route.active())); + Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*route_active_menu_item, &CheckMenuItem::set_active), _route->active())); } } @@ -803,12 +799,12 @@ RouteUI::toggle_polarity () ENSURE_GUI_THREAD(mem_fun (*this, &RouteUI::toggle_polarity)); - if ((x = polarity_menu_item->get_active()) != _route.phase_invert()) { - _route.set_phase_invert (x, this); + if ((x = polarity_menu_item->get_active()) != _route->phase_invert()) { + _route->set_phase_invert (x, this); if (x) { name_label.set_text (X_("Ø ") + name_label.get_text()); } else { - name_label.set_text (_route.name()); + name_label.set_text (_route->name()); } } } @@ -823,7 +819,7 @@ RouteUI::polarity_changed () void RouteUI::solo_safe_toggle(void* src, Gtk::CheckMenuItem* check) { - bool yn = _route.solo_safe (); + bool yn = _route->solo_safe (); if (check->get_active() != yn) { check->set_active (yn); @@ -834,7 +830,7 @@ RouteUI::pre_fader_toggle(void* src, Gtk::CheckMenuItem* check) { ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), src, check)); - bool yn = _route.get_mute_config(PRE_FADER); + bool yn = _route->get_mute_config(PRE_FADER); if (check->get_active() != yn) { check->set_active (yn); } @@ -845,7 +841,7 @@ RouteUI::post_fader_toggle(void* src, Gtk::CheckMenuItem* check) { ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::post_fader_toggle), src, check)); - bool yn = _route.get_mute_config(POST_FADER); + bool yn = _route->get_mute_config(POST_FADER); if (check->get_active() != yn) { check->set_active (yn); } @@ -856,7 +852,7 @@ RouteUI::control_outs_toggle(void* src, Gtk::CheckMenuItem* check) { ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::control_outs_toggle), src, check)); - bool yn = _route.get_mute_config(CONTROL_OUTS); + bool yn = _route->get_mute_config(CONTROL_OUTS); if (check->get_active() != yn) { check->set_active (yn); } @@ -867,7 +863,7 @@ RouteUI::main_outs_toggle(void* src, Gtk::CheckMenuItem* check) { ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::main_outs_toggle), src, check)); - bool yn = _route.get_mute_config(MAIN_OUTS); + bool yn = _route->get_mute_config(MAIN_OUTS); if (check->get_active() != yn) { check->set_active (yn); } @@ -876,42 +872,55 @@ RouteUI::main_outs_toggle(void* src, Gtk::CheckMenuItem* check) void RouteUI::disconnect_input () { - _route.disconnect_inputs (this); + _route->disconnect_inputs (this); } void RouteUI::disconnect_output () { - _route.disconnect_outputs (this); + _route->disconnect_outputs (this); +} + +bool +RouteUI::is_track () const +{ + return dynamic_cast<Track*>(_route.get()) != 0; +} + +Track* +RouteUI::track() const +{ + return dynamic_cast<Track*>(_route.get()); } bool RouteUI::is_audio_track () const { - return dynamic_cast<AudioTrack*>(&_route) != 0; + return dynamic_cast<AudioTrack*>(_route.get()) != 0; +} + +AudioTrack* +RouteUI::audio_track() const +{ + return dynamic_cast<AudioTrack*>(_route.get()); } -AudioDiskstream* +Diskstream* RouteUI::get_diskstream () const { - AudioTrack *at; + boost::shared_ptr<Track> t; - if ((at = dynamic_cast<AudioTrack*>(&_route)) != 0) { - return &at->disk_stream(); + if ((t = boost::dynamic_pointer_cast<Track>(_route)) != 0) { + return &t->diskstream(); } else { return 0; } } -AudioTrack* -RouteUI::audio_track() const -{ - return dynamic_cast<AudioTrack*>(&_route); -} string RouteUI::name() const { - return _route.name(); + return _route->name(); } void @@ -919,7 +928,7 @@ RouteUI::map_frozen () { ENSURE_GUI_THREAD (mem_fun (*this, &RouteUI::map_frozen)); - AudioTrack* at = dynamic_cast<AudioTrack*>(&_route); + AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get()); if (at) { switch (at->freeze_state()) { @@ -932,3 +941,4 @@ RouteUI::map_frozen () } } } + diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h index 69c9b7f5a9..7415eddad6 100644 --- a/gtk2_ardour/route_ui.h +++ b/gtk2_ardour/route_ui.h @@ -26,13 +26,10 @@ #include <pbd/xml++.h> #include <ardour/ardour.h> #include <ardour/route.h> +#include <ardour/track.h> #include "axis_view.h" -namespace Gtkmm2ext { - class BindableToggleButton; -} - namespace ARDOUR { class AudioTrack; } @@ -43,21 +40,30 @@ namespace Gtk { class Widget; } +class BindableToggleButton; + class RouteUI : public virtual AxisView { public: - RouteUI(ARDOUR::Route&, ARDOUR::Session&, const char*, const char*, const char*); + RouteUI(boost::shared_ptr<ARDOUR::Route>, ARDOUR::Session&, const char*, const char*, const char*); virtual ~RouteUI(); + bool is_track() const; bool is_audio_track() const; - ARDOUR::AudioDiskstream* get_diskstream() const; - ARDOUR::Route& route() const { return _route; } + boost::shared_ptr<ARDOUR::Route> route() const { return _route; } + + // FIXME: make these return shared_ptr + ARDOUR::Track* track() const; ARDOUR::AudioTrack* audio_track() const; + + ARDOUR::Diskstream* get_diskstream() const; string name() const; - - ARDOUR::Route& _route; + + // protected: XXX sigh this should be here + + boost::shared_ptr<ARDOUR::Route> _route; void set_color (const Gdk::Color & c); bool choose_color (); @@ -65,9 +71,9 @@ class RouteUI : public virtual AxisView bool ignore_toggle; bool wait_for_release; - Gtkmm2ext::BindableToggleButton * mute_button; - Gtkmm2ext::BindableToggleButton * solo_button; - Gtkmm2ext::BindableToggleButton * rec_enable_button; + BindableToggleButton* mute_button; + BindableToggleButton* solo_button; + BindableToggleButton* rec_enable_button; virtual string solo_button_name () const { return "SoloButton"; } virtual string safe_solo_button_name () const { return "SafeSoloButton"; } @@ -89,7 +95,8 @@ class RouteUI : public virtual AxisView void solo_changed(void*); void mute_changed(void*); - void route_rec_enable_changed(void*); + virtual void redirects_changed (void *) {} + void route_rec_enable_changed(); void session_rec_enable_changed(); void build_solo_menu (void); @@ -108,9 +115,9 @@ class RouteUI : public virtual AxisView void build_mute_menu(void); void init_mute_menu(ARDOUR::mute_type, Gtk::CheckMenuItem*); - void set_mix_group_solo(ARDOUR::Route&, bool); - void set_mix_group_mute(ARDOUR::Route&, bool); - void set_mix_group_rec_enable(ARDOUR::Route&, bool); + void set_mix_group_solo(boost::shared_ptr<ARDOUR::Route>, bool); + void set_mix_group_mute(boost::shared_ptr<ARDOUR::Route>, bool); + void set_mix_group_rec_enable(boost::shared_ptr<ARDOUR::Route>, bool); int set_color_from_route (); diff --git a/gtk2_ardour/selectable.h b/gtk2_ardour/selectable.h index b4be7090e2..b52214c9c9 100644 --- a/gtk2_ardour/selectable.h +++ b/gtk2_ardour/selectable.h @@ -34,7 +34,7 @@ class Selectable : public virtual sigc::trackable virtual void set_selected (bool yn) { if (yn != _selected) { - _selected = true; + _selected = yn; Selected (_selected); /* EMIT_SIGNAL */ } } diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index 2e4ed8a117..086d878994 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -24,7 +24,7 @@ #include <ardour/playlist.h> -#include "regionview.h" +#include "region_view.h" #include "selection.h" #include "selection_templates.h" #include "time_axis_view.h" @@ -46,7 +46,7 @@ Selection& Selection::operator= (const Selection& other) { if (&other != this) { - audio_regions = other.audio_regions; + regions = other.regions; tracks = other.tracks; time = other.time; lines = other.lines; @@ -57,7 +57,7 @@ Selection::operator= (const Selection& other) bool operator== (const Selection& a, const Selection& b) { - return a.audio_regions == b.audio_regions && + return a.regions == b.regions && a.tracks == b.tracks && a.time.track == b.time.track && a.time.group == b.time.group && @@ -71,7 +71,7 @@ void Selection::clear () { clear_tracks (); - clear_audio_regions (); + clear_regions (); clear_points (); clear_lines(); clear_time (); @@ -83,8 +83,8 @@ void Selection::dump_region_layers() { cerr << "region selection layer dump" << endl; - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - cerr << "layer: " << (int)(*i)->region.layer() << endl; + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + cerr << "layer: " << (int)(*i)->region().layer() << endl; } } @@ -99,10 +99,10 @@ Selection::clear_redirects () } void -Selection::clear_audio_regions () +Selection::clear_regions () { - if (!audio_regions.empty()) { - audio_regions.clear_all (); + if (!regions.empty()) { + regions.clear_all (); RegionsChanged(); } } @@ -151,7 +151,7 @@ Selection::clear_lines () } void -Selection::toggle (Redirect* r) +Selection::toggle (boost::shared_ptr<Redirect> r) { RedirectSelection::iterator i; @@ -196,29 +196,29 @@ Selection::toggle (TimeAxisView* track) } void -Selection::toggle (AudioRegionView* r) +Selection::toggle (RegionView* r) { - AudioRegionSelection::iterator i; + RegionSelection::iterator i; - if ((i = find (audio_regions.begin(), audio_regions.end(), r)) == audio_regions.end()) { - audio_regions.add (r); + if ((i = find (regions.begin(), regions.end(), r)) == regions.end()) { + regions.add (r); } else { - audio_regions.erase (i); + regions.erase (i); } RegionsChanged (); } void -Selection::toggle (vector<AudioRegionView*>& r) +Selection::toggle (vector<RegionView*>& r) { - AudioRegionSelection::iterator i; + RegionSelection::iterator i; - for (vector<AudioRegionView*>::iterator x = r.begin(); x != r.end(); ++x) { - if ((i = find (audio_regions.begin(), audio_regions.end(), (*x))) == audio_regions.end()) { - audio_regions.add ((*x)); + for (vector<RegionView*>::iterator x = r.begin(); x != r.end(); ++x) { + if ((i = find (regions.begin(), regions.end(), (*x))) == regions.end()) { + regions.add ((*x)); } else { - audio_regions.erase (i); + regions.erase (i); } } @@ -243,7 +243,7 @@ Selection::toggle (jack_nframes_t start, jack_nframes_t end) void -Selection::add (Redirect* r) +Selection::add (boost::shared_ptr<Redirect> r) { if (find (redirects.begin(), redirects.end(), r) == redirects.end()) { redirects.push_back (r); @@ -310,22 +310,22 @@ Selection::add (TimeAxisView* track) } void -Selection::add (AudioRegionView* r) +Selection::add (RegionView* r) { - if (find (audio_regions.begin(), audio_regions.end(), r) == audio_regions.end()) { - audio_regions.add (r); + if (find (regions.begin(), regions.end(), r) == regions.end()) { + regions.add (r); RegionsChanged (); } } void -Selection::add (vector<AudioRegionView*>& v) +Selection::add (vector<RegionView*>& v) { bool changed = false; - for (vector<AudioRegionView*>::iterator i = v.begin(); i != v.end(); ++i) { - if (find (audio_regions.begin(), audio_regions.end(), (*i)) == audio_regions.end()) { - audio_regions.add ((*i)); + for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) { + if (find (regions.begin(), regions.end(), (*i)) == regions.end()) { + regions.add ((*i)); changed = true; } } @@ -381,9 +381,9 @@ Selection::add (AutomationList* ac) } void -Selection::remove (Redirect* r) +Selection::remove (boost::shared_ptr<Redirect> r) { - list<Redirect*>::iterator i; + RedirectSelection::iterator i; if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) { redirects.erase (i); RedirectsChanged (); @@ -451,9 +451,9 @@ Selection::remove (const list<Playlist*>& pllist) } void -Selection::remove (AudioRegionView* r) +Selection::remove (RegionView* r) { - audio_regions.remove (r); + regions.remove (r); RegionsChanged (); } @@ -491,7 +491,7 @@ Selection::remove (AutomationList *ac) } void -Selection::set (Redirect *r) +Selection::set (boost::shared_ptr<Redirect> r) { clear_redirects (); add (r); @@ -526,17 +526,16 @@ Selection::set (const list<Playlist*>& pllist) } void -Selection::set (AudioRegionView* r) +Selection::set (RegionView* r) { - clear_audio_regions (); + clear_regions (); add (r); } void -Selection::set (vector<AudioRegionView*>& v) +Selection::set (vector<RegionView*>& v) { - - clear_audio_regions (); + clear_regions (); // make sure to deselect any automation selections clear_points(); add (v); @@ -590,15 +589,15 @@ Selection::selected (TimeAxisView* tv) } bool -Selection::selected (AudioRegionView* arv) +Selection::selected (RegionView* rv) { - return find (audio_regions.begin(), audio_regions.end(), arv) != audio_regions.end(); + return find (regions.begin(), regions.end(), rv) != regions.end(); } bool Selection::empty () { - return audio_regions.empty () && + return regions.empty () && tracks.empty () && points.empty () && playlists.empty () && @@ -612,7 +611,7 @@ Selection::empty () void Selection::set (list<Selectable*>& selectables) { - clear_audio_regions(); + clear_regions(); clear_points (); add (selectables); } @@ -620,14 +619,14 @@ Selection::set (list<Selectable*>& selectables) void Selection::add (list<Selectable*>& selectables) { - AudioRegionView* arv; + RegionView* rv; AutomationSelectable* as; - vector<AudioRegionView*> arvs; + vector<RegionView*> rvs; vector<AutomationSelectable*> autos; for (std::list<Selectable*>::iterator i = selectables.begin(); i != selectables.end(); ++i) { - if ((arv = dynamic_cast<AudioRegionView*> (*i)) != 0) { - arvs.push_back (arv); + if ((rv = dynamic_cast<RegionView*> (*i)) != 0) { + rvs.push_back (rv); } else if ((as = dynamic_cast<AutomationSelectable*> (*i)) != 0) { autos.push_back (as); } else { @@ -638,8 +637,8 @@ Selection::add (list<Selectable*>& selectables) } } - if (!arvs.empty()) { - add (arvs); + if (!rvs.empty()) { + add (rvs); } if (!autos.empty()) { diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h index ebeda1aea7..7b503a5e63 100644 --- a/gtk2_ardour/selection.h +++ b/gtk2_ardour/selection.h @@ -22,6 +22,7 @@ #define __ardour_gtk_selection_h__ #include <vector> +#include <boost/shared_ptr.hpp> #include <sigc++/signal.h> @@ -34,7 +35,7 @@ #include "point_selection.h" class TimeAxisView; -class AudioRegionView; +class RegionView; class Selectable; namespace ARDOUR { @@ -60,7 +61,7 @@ class Selection : public sigc::trackable }; TrackSelection tracks; - AudioRegionSelection audio_regions; + RegionSelection regions; TimeSelection time; AutomationSelection lines; PlaylistSelection playlists; @@ -88,55 +89,55 @@ class Selection : public sigc::trackable void dump_region_layers(); bool selected (TimeAxisView*); - bool selected (AudioRegionView*); + bool selected (RegionView*); void set (list<Selectable*>&); void add (list<Selectable*>&); void set (TimeAxisView*); void set (const list<TimeAxisView*>&); - void set (AudioRegionView*); - void set (std::vector<AudioRegionView*>&); + void set (RegionView*); + void set (std::vector<RegionView*>&); long set (TimeAxisView*, jack_nframes_t, jack_nframes_t); void set (ARDOUR::AutomationList*); void set (ARDOUR::Playlist*); void set (const list<ARDOUR::Playlist*>&); - void set (ARDOUR::Redirect*); + void set (boost::shared_ptr<ARDOUR::Redirect>); void set (AutomationSelectable*); void toggle (TimeAxisView*); void toggle (const list<TimeAxisView*>&); - void toggle (AudioRegionView*); - void toggle (std::vector<AudioRegionView*>&); + void toggle (RegionView*); + void toggle (std::vector<RegionView*>&); long toggle (jack_nframes_t, jack_nframes_t); void toggle (ARDOUR::AutomationList*); void toggle (ARDOUR::Playlist*); void toggle (const list<ARDOUR::Playlist*>&); - void toggle (ARDOUR::Redirect*); + void toggle (boost::shared_ptr<ARDOUR::Redirect>); void add (TimeAxisView*); void add (const list<TimeAxisView*>&); - void add (AudioRegionView*); - void add (std::vector<AudioRegionView*>&); + void add (RegionView*); + void add (std::vector<RegionView*>&); long add (jack_nframes_t, jack_nframes_t); void add (ARDOUR::AutomationList*); void add (ARDOUR::Playlist*); void add (const list<ARDOUR::Playlist*>&); - void add (ARDOUR::Redirect*); + void add (boost::shared_ptr<ARDOUR::Redirect>); void remove (TimeAxisView*); void remove (const list<TimeAxisView*>&); - void remove (AudioRegionView*); + void remove (RegionView*); void remove (uint32_t selection_id); void remove (jack_nframes_t, jack_nframes_t); void remove (ARDOUR::AutomationList*); void remove (ARDOUR::Playlist*); void remove (const list<ARDOUR::Playlist*>&); - void remove (ARDOUR::Redirect*); + void remove (boost::shared_ptr<ARDOUR::Redirect>); void replace (uint32_t time_index, jack_nframes_t start, jack_nframes_t end); - void clear_audio_regions(); + void clear_regions(); void clear_tracks (); void clear_time(); void clear_lines (); @@ -144,10 +145,8 @@ class Selection : public sigc::trackable void clear_redirects (); void clear_points (); - void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void)); - void foreach_audio_region (void (ARDOUR::Region::*method)(void)); - template<class A> void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg); - template<class A> void foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg); + void foreach_region (void (ARDOUR::Region::*method)(void)); + template<class A> void foreach_region (void (ARDOUR::Region::*method)(A), A arg); private: uint32_t next_time_id; diff --git a/gtk2_ardour/selection_templates.h b/gtk2_ardour/selection_templates.h index c2ca70b526..9511db7d61 100644 --- a/gtk2_ardour/selection_templates.h +++ b/gtk2_ardour/selection_templates.h @@ -27,35 +27,21 @@ */ #include <ardour/region.h> -#include <ardour/audioregion.h> #include "selection.h" +#include "region_view.h" inline void -Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void)) { - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - ((*i)->region.*(method))(); - } -} - -inline void -Selection::foreach_audio_region (void (ARDOUR::Region::*method)(void)) { - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - ((*i)->region.*(method))(); - } -} - -template<class A> inline void -Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg) { - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - ((*i)->region.*(method))(arg); +Selection::foreach_region (void (ARDOUR::Region::*method)(void)) { + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + ((*i)->region().*(method))(); } } template<class A> inline void -Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) { - for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) { - ((*i)->region.*(method))(arg); +Selection::foreach_region (void (ARDOUR::Region::*method)(A), A arg) { + for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) { + ((*i)->region().*(method))(arg); } } @@ -64,14 +50,14 @@ Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) { template<class A> inline void Selection::foreach_route (void (ARDOUR::Route::*method)(A), A arg) { for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) { - ((*i)->region.*(method))(arg); + ((*i)->region().*(method))(arg); } } template<class A1, class A2> inline void Selection::foreach_route (void (ARDOUR::Route::*method)(A1,A2), A1 arg1, A2 arg2) { for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) { - ((*i)->region.*(method))(arg1, arg2); + ((*i)->region().*(method))(arg1, arg2); } } diff --git a/gtk2_ardour/send_ui.cc b/gtk2_ardour/send_ui.cc index be95f753e7..9925ff51d4 100644 --- a/gtk2_ardour/send_ui.cc +++ b/gtk2_ardour/send_ui.cc @@ -30,7 +30,7 @@ using namespace ARDOUR; using namespace PBD; -SendUI::SendUI (Send& s, Session& se) +SendUI::SendUI (boost::shared_ptr<Send> s, Session& se) : _send (s), _session (se), gpm (s, se), @@ -53,10 +53,10 @@ SendUI::SendUI (Send& s, Session& se) show_all (); - _send.set_metering (true); + _send->set_metering (true); - _send.output_changed.connect (mem_fun (*this, &SendUI::ins_changed)); - _send.output_changed.connect (mem_fun (*this, &SendUI::outs_changed)); + _send->output_changed.connect (mem_fun (*this, &SendUI::ins_changed)); + _send->output_changed.connect (mem_fun (*this, &SendUI::outs_changed)); panners.set_width (Wide); panners.setup_pan (); @@ -70,7 +70,7 @@ SendUI::SendUI (Send& s, Session& se) SendUI::~SendUI () { - _send.set_metering (false); + _send->set_metering (false); /* XXX not clear that we need to do this */ @@ -118,7 +118,7 @@ SendUI::fast_update () } } -SendUIWindow::SendUIWindow (Send& s, Session& ss) +SendUIWindow::SendUIWindow (boost::shared_ptr<Send> s, Session& ss) { ui = new SendUI (s, ss); @@ -131,7 +131,7 @@ SendUIWindow::SendUIWindow (Send& s, Session& ss) add (vpacker); set_name ("SendUIWindow"); - s.GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away)); + s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away)); signal_delete_event().connect (bind (ptr_fun (just_hide_it), reinterpret_cast<Window *> (this))); diff --git a/gtk2_ardour/send_ui.h b/gtk2_ardour/send_ui.h index d1a49930ea..1d5a74e102 100644 --- a/gtk2_ardour/send_ui.h +++ b/gtk2_ardour/send_ui.h @@ -35,7 +35,7 @@ class IOSelector; class SendUI : public Gtk::HBox { public: - SendUI (ARDOUR::Send&, ARDOUR::Session&); + SendUI (boost::shared_ptr<ARDOUR::Send>, ARDOUR::Session&); ~SendUI(); void update (); @@ -44,7 +44,7 @@ class SendUI : public Gtk::HBox IOSelector* io; private: - ARDOUR::Send& _send; + boost::shared_ptr<ARDOUR::Send> _send; ARDOUR::Session& _session; GainMeter gpm; PannerUI panners; @@ -62,7 +62,7 @@ class SendUI : public Gtk::HBox class SendUIWindow : public Gtk::Window { public: - SendUIWindow(ARDOUR::Send&, ARDOUR::Session&); + SendUIWindow(boost::shared_ptr<ARDOUR::Send>, ARDOUR::Session&); ~SendUIWindow(); SendUI* ui; diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 79546880de..d9ded04d2b 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -97,6 +97,9 @@ SoundFileBox::SoundFileBox () (mem_fun (*this, &SoundFileBox::add_field_clicked)); remove_field_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::remove_field_clicked)); + + Gtk::CellRendererText* cell(dynamic_cast<Gtk::CellRendererText*>(field_view.get_column_cell_renderer(1))); + cell->signal_edited().connect (mem_fun (*this, &SoundFileBox::field_edited)); field_view.get_selection()->signal_changed().connect (mem_fun (*this, &SoundFileBox::field_selected)); Library->fields_changed.connect (mem_fun (*this, &SoundFileBox::setup_fields)); @@ -260,6 +263,13 @@ SoundFileBox::remove_field_clicked () } void +SoundFileBox::field_edited (const Glib::ustring& str1, const Glib::ustring& str2) +{ + cout << "field_edited" << endl; + Library->save_changes (); +} + +void SoundFileBox::delete_row (const Gtk::TreeModel::iterator& iter) { Gtk::TreeModel::Row row = *iter; @@ -394,6 +404,9 @@ SoundFileOmega::set_mode (Editing::ImportMode mode) case Editing::ImportToTrack: split_check.set_sensitive (false); break; + case Editing::ImportAsTapeTrack: + split_check.set_sensitive (true); + break; } } @@ -433,5 +446,8 @@ SoundFileOmega::mode_changed () case Editing::ImportToTrack: split_check.set_sensitive (false); break; + case Editing::ImportAsTapeTrack: + split_check.set_sensitive (true); + break; } } diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h index 79c73b97ac..8ef57d7b9f 100644 --- a/gtk2_ardour/sfdb_ui.h +++ b/gtk2_ardour/sfdb_ui.h @@ -100,6 +100,7 @@ class SoundFileBox : public Gtk::VBox void stop_btn_clicked (); void add_field_clicked (); void remove_field_clicked (); + void field_edited (const Glib::ustring&, const Glib::ustring&); void delete_row (const Gtk::TreeModel::iterator& iter); void field_selected (); diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index a60e0d59e7..d1d163d7a2 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -1,28 +1,42 @@ +/* + Copyright (C) 2001, 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include <cmath> #include <gtkmm.h> #include <gtkmm2ext/gtk_ui.h> -#include <ardour/audioplaylist.h> -#include <ardour/audioregion.h> -#include <ardour/audiosource.h> -#include <ardour/audio_diskstream.h> -#include <ardour/audio_track.h> -#include <ardour/playlist_templates.h> +#include <ardour/playlist.h> +#include <ardour/region.h> #include <ardour/source.h> +#include <ardour/diskstream.h> +#include <ardour/track.h> #include "streamview.h" -#include "regionview.h" -#include "taperegionview.h" -#include "audio_time_axis.h" +#include "region_view.h" +#include "route_time_axis.h" #include "canvas-waveview.h" #include "canvas-simplerect.h" #include "region_selection.h" #include "selection.h" #include "public_editor.h" #include "ardour_ui.h" -#include "crossfade_view.h" #include "rgb_macros.h" #include "gui_thread.h" #include "utils.h" @@ -32,52 +46,36 @@ using namespace ARDOUR; using namespace PBD; using namespace Editing; -StreamView::StreamView (AudioTimeAxisView& tv) +StreamView::StreamView (RouteTimeAxisView& tv) : _trackview (tv) + , canvas_group(new ArdourCanvas::Group(*_trackview.canvas_display)) + , canvas_rect(new ArdourCanvas::SimpleRect (*canvas_group)) + , _samples_per_unit(_trackview.editor.get_current_zoom()) + , rec_updating(false) + , rec_active(false) + , use_rec_regions(tv.editor.show_waveforms_recording()) + , region_color(_trackview.color()) + , stream_base_color(0xFFFFFFFF) { - region_color = _trackview.color(); - crossfades_visible = true; - - if (tv.is_audio_track()) { - /* TRACK */ - //stream_base_color = RGBA_TO_UINT (222,223,218,255); - stream_base_color = color_map[cAudioTrackBase]; - } else { - /* BUS */ - //stream_base_color = RGBA_TO_UINT (230,226,238,255); - stream_base_color = color_map[cAudioBusBase]; - } - /* set_position() will position the group */ - canvas_group = new ArdourCanvas::Group(*_trackview.canvas_display); - canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group); canvas_rect->property_x1() = 0.0; canvas_rect->property_y1() = 0.0; canvas_rect->property_x2() = 1000000.0; canvas_rect->property_y2() = (double) tv.height; - canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline]; canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom - canvas_rect->property_fill_color_rgba() = stream_base_color; + // (Fill/Outline colours set in derived classes) canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview)); - _samples_per_unit = _trackview.editor.get_current_zoom(); - _amplitude_above_axis = 1.0; - - if (_trackview.is_audio_track()) { - _trackview.audio_track()->diskstream_changed.connect (mem_fun (*this, &StreamView::diskstream_changed)); + if (_trackview.is_track()) { + _trackview.track()->DiskstreamChanged.connect (mem_fun (*this, &StreamView::diskstream_changed)); _trackview.session().TransportStateChange.connect (mem_fun (*this, &StreamView::transport_changed)); - _trackview.get_diskstream()->record_enable_changed.connect (mem_fun (*this, &StreamView::rec_enable_changed)); + _trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &StreamView::rec_enable_changed)); _trackview.session().RecordStateChanged.connect (mem_fun (*this, &StreamView::sess_rec_enable_changed)); } - rec_updating = false; - rec_active = false; - use_rec_regions = tv.editor.show_waveforms_recording (); - last_rec_peak_frame = 0; - ColorChanged.connect (mem_fun (*this, &StreamView::color_handler)); } @@ -90,7 +88,7 @@ StreamView::~StreamView () void StreamView::attach () { - if (_trackview.is_audio_track()) { + if (_trackview.is_track()) { display_diskstream (_trackview.get_diskstream()); } } @@ -115,13 +113,13 @@ StreamView::set_height (gdouble h) canvas_rect->property_y2() = h; - for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { + for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { (*i)->set_height (h); } - for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + /*for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { (*i)->set_height (h); - } + }*/ for (vector<RecBoxInfo>::iterator i = rec_rects.begin(); i != rec_rects.end(); ++i) { RecBoxInfo &recbox = (*i); @@ -134,7 +132,7 @@ StreamView::set_height (gdouble h) int StreamView::set_samples_per_unit (gdouble spp) { - AudioRegionViewList::iterator i; + RegionViewList::iterator i; if (spp < 1.0) { return -1; @@ -146,10 +144,6 @@ StreamView::set_samples_per_unit (gdouble spp) (*i)->set_samples_per_unit (spp); } - for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) { - (*xi)->set_samples_per_unit (spp); - } - for (vector<RecBoxInfo>::iterator xi = rec_rects.begin(); xi != rec_rects.end(); ++xi) { RecBoxInfo &recbox = (*xi); @@ -163,25 +157,6 @@ StreamView::set_samples_per_unit (gdouble spp) return 0; } -int -StreamView::set_amplitude_above_axis (gdouble app) - -{ - AudioRegionViewList::iterator i; - - if (app < 1.0) { - return -1; - } - - _amplitude_above_axis = app; - - for (i = region_views.begin(); i != region_views.end(); ++i) { - (*i)->set_amplitude_above_axis (app); - } - - return 0; -} - void StreamView::add_region_view (Region *r) { @@ -189,87 +164,17 @@ StreamView::add_region_view (Region *r) } void -StreamView::add_region_view_internal (Region *r, bool wait_for_waves) -{ - ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r)); - - AudioRegion* region = dynamic_cast<AudioRegion*> (r); - - if (region == 0) { - return; - } - - AudioRegionView *region_view; - list<AudioRegionView *>::iterator i; - - for (i = region_views.begin(); i != region_views.end(); ++i) { - if (&(*i)->region == region) { - - /* great. we already have a AudioRegionView for this Region. use it again. - */ - - (*i)->set_valid (true); - return; - } - } - - switch (_trackview.audio_track()->mode()) { - case Normal: - region_view = new AudioRegionView (canvas_group, _trackview, *region, - _samples_per_unit, region_color); - break; - case Destructive: - region_view = new TapeAudioRegionView (canvas_group, _trackview, *region, - _samples_per_unit, region_color); - break; - } - - region_view->init (_amplitude_above_axis, region_color, wait_for_waves); - region_views.push_front (region_view); - - /* follow global waveform setting */ - - region_view->set_waveform_visible(_trackview.editor.show_waveforms()); - - /* catch regionview going away */ - - region->GoingAway.connect (mem_fun (*this, &StreamView::remove_region_view)); - - AudioRegionViewAdded (region_view); -} - -void StreamView::remove_region_view (Region *r) { ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), r)); - AudioRegion* ar = dynamic_cast<AudioRegion*> (r); - - if (ar == 0) { - return; - } - - for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - if (&((*i)->region) == ar) { + for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + if (&((*i)->region()) == r) { delete *i; region_views.erase (i); break; } } - - for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) { - list<CrossfadeView*>::iterator tmp; - - tmp = i; - ++tmp; - - if ((*i)->crossfade.involves (*ar)) { - delete *i; - crossfade_views.erase (i); - } - - i = tmp; - } } void @@ -282,14 +187,8 @@ StreamView::remove_rec_region (Region *r) /*NOTREACHED*/ } - AudioRegion* ar = dynamic_cast<AudioRegion*> (r); - - if (ar == 0) { - return; - } - - for (list<AudioRegion *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) { - if (*i == ar) { + for (list<Region *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) { + if (*i == r) { rec_regions.erase (i); break; } @@ -299,21 +198,15 @@ StreamView::remove_rec_region (Region *r) void StreamView::undisplay_diskstream () { - - for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { - delete *i; - } - - for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { + for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { delete *i; } region_views.clear(); - crossfade_views.clear (); } void -StreamView::display_diskstream (AudioDiskstream *ds) +StreamView::display_diskstream (Diskstream *ds) { playlist_change_connection.disconnect(); playlist_changed (ds); @@ -325,21 +218,13 @@ StreamView::playlist_modified () { ENSURE_GUI_THREAD (mem_fun (*this, &StreamView::playlist_modified)); - /* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked - correctly. - */ - - for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { + for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { region_layered (*i); } - - for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - (*i)->get_canvas_group()->raise_to_top(); - } } void -StreamView::playlist_changed (AudioDiskstream *ds) +StreamView::playlist_changed (Diskstream *ds) { ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds)); @@ -362,69 +247,6 @@ StreamView::playlist_changed (AudioDiskstream *ds) playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (mem_fun (*this, &StreamView::remove_region_view))); playlist_connections.push_back (ds->playlist()->StateChanged.connect (mem_fun (*this, &StreamView::playlist_state_changed))); playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified))); - playlist_connections.push_back (ds->playlist()->NewCrossfade.connect (mem_fun (*this, &StreamView::add_crossfade))); -} - -void -StreamView::add_crossfade (Crossfade *crossfade) -{ - AudioRegionView* lview = 0; - AudioRegionView* rview = 0; - - ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_crossfade), crossfade)); - - /* first see if we already have a CrossfadeView for this Crossfade */ - - for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - if (&(*i)->crossfade == crossfade) { - if (!crossfades_visible) { - (*i)->hide(); - } else { - (*i)->show (); - } - (*i)->set_valid (true); - return; - } - } - - /* create a new one */ - - for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - if (!lview && &((*i)->region) == &crossfade->out()) { - lview = *i; - } - if (!rview && &((*i)->region) == &crossfade->in()) { - rview = *i; - } - } - - CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display, - _trackview, - *crossfade, - _samples_per_unit, - region_color, - *lview, *rview); - - crossfade->Invalidated.connect (mem_fun (*this, &StreamView::remove_crossfade)); - crossfade_views.push_back (cv); - - if (!crossfades_visible) { - cv->hide (); - } -} - -void -StreamView::remove_crossfade (Crossfade *xfade) -{ - ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_crossfade), xfade)); - - for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - if (&(*i)->crossfade == xfade) { - delete *i; - crossfade_views.erase (i); - break; - } - } } void @@ -436,64 +258,12 @@ StreamView::playlist_state_changed (Change ignored) } void -StreamView::redisplay_diskstream () -{ - list<AudioRegionView *>::iterator i, tmp; - list<CrossfadeView*>::iterator xi, tmpx; - - - for (i = region_views.begin(); i != region_views.end(); ++i) { - (*i)->set_valid (false); - } - - for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) { - (*xi)->set_valid (false); - if ((*xi)->visible()) { - (*xi)->show (); - } - } - - if (_trackview.is_audio_track()) { - _trackview.get_diskstream()->playlist()->foreach_region (this, &StreamView::add_region_view); - _trackview.get_diskstream()->playlist()->foreach_crossfade (this, &StreamView::add_crossfade); - } - - for (i = region_views.begin(); i != region_views.end(); ) { - tmp = i; - tmp++; - - if (!(*i)->is_valid()) { - delete *i; - region_views.erase (i); - } - - i = tmp; - } - - for (xi = crossfade_views.begin(); xi != crossfade_views.end();) { - tmpx = xi; - tmpx++; - - if (!(*xi)->valid()) { - delete *xi; - crossfade_views.erase (xi); - } - - xi = tmpx; - } - - /* now fix layering */ - - playlist_modified (); -} - -void -StreamView::diskstream_changed (void *src_ignored) +StreamView::diskstream_changed () { - AudioTrack *at; + Track *t; - if ((at = _trackview.audio_track()) != 0) { - AudioDiskstream& ds = at->disk_stream(); + if ((t = _trackview.track()) != 0) { + Diskstream& ds = t->diskstream(); /* XXX grrr: when will SigC++ allow me to bind references? */ Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds)); } else { @@ -505,7 +275,7 @@ void StreamView::apply_color (Gdk::Color& color, ColorTarget target) { - list<AudioRegionView *>::iterator i; + list<RegionView *>::iterator i; switch (target) { case RegionColor: @@ -513,76 +283,18 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target) for (i = region_views.begin(); i != region_views.end(); ++i) { (*i)->set_color (region_color); } - // stream_base_color = RGBA_TO_UINT (color.red/256, color.green/256, color.blue/256, 255); - // gnome_canvas_item_set (canvas_rect, "fill_color_rgba", stream_base_color, NULL); break; case StreamBaseColor: - // stream_base_color = RGBA_TO_UINT (color.red/256, color.green/256, color.blue/256, 255); - // gnome_canvas_item_set (canvas_rect, "fill_color_rgba", stream_base_color, NULL); + stream_base_color = RGBA_TO_UINT ( + color.get_red_p(), color.get_green_p(), color.get_blue_p(), 255); + canvas_rect->property_fill_color_rgba() = stream_base_color; break; } } void -StreamView::set_show_waveforms (bool yn) -{ - for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - (*i)->set_waveform_visible (yn); - } -} - -void -StreamView::set_selected_regionviews (AudioRegionSelection& regions) -{ - bool selected; - - // cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl; - for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - - selected = false; - - for (AudioRegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) { - if (*i == *ii) { - selected = true; - } - } - - // cerr << "\tregion " << (*i)->region.name() << " selected = " << selected << endl; - (*i)->set_selected (selected); - } -} - -void -StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results) -{ - for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - if ((*i)->region.coverage(start, end) != OverlapNone) { - results.push_back (*i); - } - } -} - -void -StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results) -{ - for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - if (!sel.audio_regions.contains (*i)) { - results.push_back (*i); - } - } -} - -void -StreamView::set_waveform_shape (WaveformShape shape) -{ - for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) { - (*i)->set_waveform_shape (shape); - } -} - -void -StreamView::region_layered (AudioRegionView* rv) +StreamView::region_layered (RegionView* rv) { rv->get_canvas_group()->lower_to_bottom(); @@ -590,11 +302,14 @@ StreamView::region_layered (AudioRegionView* rv) get events - the parent group does instead ... */ - rv->get_canvas_group()->raise (rv->region.layer() + 1); + /* this used to be + 1, but regions to the left ended up below + ..something.. and couldn't receive events. why? good question. + */ + rv->get_canvas_group()->raise (rv->region().layer() + 2); } void -StreamView::rec_enable_changed (void *src) +StreamView::rec_enable_changed () { Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box)); } @@ -612,161 +327,6 @@ StreamView::transport_changed() } void -StreamView::setup_rec_box () -{ - // cerr << _trackview.name() << " streamview SRB\n"; - - if (_trackview.session().transport_rolling()) { - - // cerr << "\trolling\n"; - - if (!rec_active && - _trackview.session().record_status() == Session::Recording && - _trackview.get_diskstream()->record_enabled()) { - - if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) { - - /* add a new region, but don't bother if they set use_rec_regions mid-record */ - - AudioRegion::SourceList sources; - - for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { - (*prc).disconnect(); - } - peak_ready_connections.clear(); - - for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) { - AudioSource *src = (AudioSource *) _trackview.get_diskstream()->write_source (n); - if (src) { - sources.push_back (src); - peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src))); - } - } - - // handle multi - - jack_nframes_t start = 0; - if (rec_regions.size() > 0) { - start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1); - } - - AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false); - region->set_position (_trackview.session().transport_frame(), this); - rec_regions.push_back (region); - /* catch it if it goes away */ - region->GoingAway.connect (mem_fun (*this, &StreamView::remove_rec_region)); - - /* we add the region later */ - } - - /* start a new rec box */ - - AudioTrack* at; - - at = _trackview.audio_track(); /* we know what it is already */ - AudioDiskstream& ds = at->disk_stream(); - jack_nframes_t frame_pos = ds.current_capture_start (); - gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); - gdouble xend; - uint32_t fill_color; - - switch (_trackview.audio_track()->mode()) { - case Normal: - xend = xstart; - fill_color = color_map[cRecordingRectFill]; - break; - - case Destructive: - xend = xstart + 2; - fill_color = color_map[cRecordingRectFill]; - /* make the recording rect translucent to allow - the user to see the peak data coming in, etc. - */ - fill_color = UINT_RGBA_CHANGE_A (fill_color, 120); - break; - } - - ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group); - rec_rect->property_x1() = xstart; - rec_rect->property_y1() = 1.0; - rec_rect->property_x2() = xend; - rec_rect->property_y2() = (double) _trackview.height - 1; - rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline]; - rec_rect->property_fill_color_rgba() = fill_color; - - RecBoxInfo recbox; - recbox.rectangle = rec_rect; - recbox.start = _trackview.session().transport_frame(); - recbox.length = 0; - - rec_rects.push_back (recbox); - - screen_update_connection.disconnect(); - screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &StreamView::update_rec_box)); - rec_updating = true; - rec_active = true; - - } else if (rec_active && - (_trackview.session().record_status() != Session::Recording || - !_trackview.get_diskstream()->record_enabled())) { - - screen_update_connection.disconnect(); - rec_active = false; - rec_updating = false; - - } - - } else { - - // cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl; - - if (!rec_rects.empty() || !rec_regions.empty()) { - - /* disconnect rapid update */ - screen_update_connection.disconnect(); - - for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) { - (*prc).disconnect(); - } - peak_ready_connections.clear(); - - rec_updating = false; - rec_active = false; - last_rec_peak_frame = 0; - - /* remove temp regions */ - for (list<AudioRegion*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); ) - { - list<AudioRegion*>::iterator tmp; - - tmp = iter; - ++tmp; - - /* this will trigger the remove_region_view */ - delete *iter; - - iter = tmp; - } - - rec_regions.clear(); - - // cerr << "\tclear " << rec_rects.size() << " rec rects\n"; - - - /* transport stopped, clear boxes */ - for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) { - RecBoxInfo &rect = (*iter); - delete rect.rectangle; - } - - rec_rects.clear(); - - } - } -} - - -void StreamView::update_rec_box () { if (rec_active && rec_rects.size() > 0) { @@ -776,7 +336,7 @@ StreamView::update_rec_box () double xstart; double xend; - switch (_trackview.audio_track()->mode()) { + switch (_trackview.track()->mode()) { case Normal: rect.length = at - rect.start; xstart = _trackview.editor.frame_to_pixel (rect.start); @@ -795,12 +355,12 @@ StreamView::update_rec_box () } } -AudioRegionView* -StreamView::find_view (const AudioRegion& region) +RegionView* +StreamView::find_view (const Region& region) { - for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { - if (&(*i)->region == ®ion) { + if (&(*i)->region() == ®ion) { return *i; } } @@ -808,172 +368,51 @@ StreamView::find_view (const AudioRegion& region) } void -StreamView::foreach_regionview (sigc::slot<void,AudioRegionView*> slot) +StreamView::foreach_regionview (sigc::slot<void,RegionView*> slot) { - for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { slot (*i); } } void -StreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void)) -{ - for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - ((*i)->*pmf) (); - } -} - -void -StreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src) -{ - // this is called from the peak building thread - - ENSURE_GUI_THREAD(bind (mem_fun (*this, &StreamView::rec_peak_range_ready), start, cnt, src)); - - if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) { - last_rec_peak_frame = start + cnt; - } - - rec_peak_ready_map[src] = true; - - if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) { - this->update_rec_regions (); - rec_peak_ready_map.clear(); - } -} - -void -StreamView::update_rec_regions () +StreamView::set_selected_regionviews (RegionSelection& regions) { - if (use_rec_regions) { - - uint32_t n = 0; - - for (list<AudioRegion*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) { - - list<AudioRegion*>::iterator tmp; - - tmp = iter; - ++tmp; - - if (!canvas_item_visible (rec_rects[n].rectangle)) { - /* rect already hidden, this region is done */ - iter = tmp; - continue; - } - - AudioRegion * region = (*iter); - jack_nframes_t origlen = region->length(); - - if (region == rec_regions.back() && rec_active) { - - if (last_rec_peak_frame > region->start()) { - - jack_nframes_t nlen = last_rec_peak_frame - region->start(); - - if (nlen != region->length()) { - - region->freeze (); - region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this); - region->set_length (nlen, this); - region->thaw ("updated"); - - if (origlen == 1) { - /* our special initial length */ - add_region_view_internal (region, false); - } - - /* also update rect */ - ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle; - gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length()); - rect->property_x2() = xend; - } - } - - } else { - - jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n); - - if (nlen != region->length()) { - - if (region->source(0).length() >= region->start() + nlen) { - - region->freeze (); - region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this); - region->set_length (nlen, this); - region->thaw ("updated"); - - if (origlen == 1) { - /* our special initial length */ - add_region_view_internal (region, false); - } - - /* also hide rect */ - ArdourCanvas::Item * rect = rec_rects[n].rectangle; - rect->hide(); + bool selected; - } - } + // cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl; + for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + + selected = false; + + for (RegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) { + if (*i == *ii) { + selected = true; } - - iter = tmp; } + + // cerr << "\tregion " << (*i)->region().name() << " selected = " << selected << endl; + (*i)->set_selected (selected); } } void -StreamView::show_all_xfades () -{ - foreach_crossfadeview (&CrossfadeView::show); - crossfades_visible = true; -} - -void -StreamView::hide_all_xfades () -{ - foreach_crossfadeview (&CrossfadeView::hide); - crossfades_visible = false; -} - -void -StreamView::hide_xfades_involving (AudioRegionView& rv) +StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results) { - for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - if ((*i)->crossfade.involves (rv.region)) { - (*i)->fake_hide (); + for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + if ((*i)->region().coverage(start, end) != OverlapNone) { + results.push_back (*i); } } } void -StreamView::reveal_xfades_involving (AudioRegionView& rv) +StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results) { - for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) { - if ((*i)->crossfade.involves (rv.region) && (*i)->visible()) { - (*i)->show (); + for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) { + if (!sel.regions.contains (*i)) { + results.push_back (*i); } } } -void -StreamView::color_handler (ColorID id, uint32_t val) -{ - switch (id) { - case cAudioTrackBase: - if (_trackview.is_audio_track()) { - canvas_rect->property_fill_color_rgba() = val; - } - break; - case cAudioBusBase: - if (!_trackview.is_audio_track()) { - canvas_rect->property_fill_color_rgba() = val; - } - break; - case cAudioTrackOutline: - canvas_rect->property_outline_color_rgba() = val; - break; - - default: - break; - } -} diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index 00ec2d93f2..5a0e10974f 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2001 Paul Davis + Copyright (C) 2001, 2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,8 +14,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ */ #ifndef __ardour_streamview_h__ @@ -37,141 +35,116 @@ namespace Gdk { namespace ARDOUR { class Route; - class AudioDiskstream; + class Diskstream; class Crossfade; class PeakData; - class AudioRegion; + class Region; class Source; } struct RecBoxInfo { - ArdourCanvas::SimpleRect* rectangle; - jack_nframes_t start; - jack_nframes_t length; + ArdourCanvas::SimpleRect* rectangle; + jack_nframes_t start; + jack_nframes_t length; }; class PublicEditor; class Selectable; -class AudioTimeAxisView; -class AudioRegionView; -class AudioRegionSelection; +class RouteTimeAxisView; +class RegionView; +class RegionSelection; class CrossfadeView; class Selection; class StreamView : public sigc::trackable { - public: - StreamView (AudioTimeAxisView&); - ~StreamView (); +public: + virtual ~StreamView (); - void set_waveform_shape (WaveformShape); + RouteTimeAxisView& trackview() { return _trackview; } - AudioTimeAxisView& trackview() { return _trackview; } + void attach (); void set_zoom_all(); - int set_height (gdouble); int set_position (gdouble x, gdouble y); + virtual int set_height (gdouble); - int set_samples_per_unit (gdouble spp); - gdouble get_samples_per_unit () { return _samples_per_unit; } - - int set_amplitude_above_axis (gdouble app); - gdouble get_amplitude_above_axis () { return _amplitude_above_axis; } - - void set_show_waveforms (bool yn); - void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; } + virtual int set_samples_per_unit (gdouble spp); + gdouble get_samples_per_unit () { return _samples_per_unit; } ArdourCanvas::Item* canvas_item() { return canvas_group; } - sigc::signal<void,AudioRegionView*> AudioRegionViewAdded; - enum ColorTarget { RegionColor, StreamBaseColor }; - void apply_color (Gdk::Color&, ColorTarget t); - void set_selected_regionviews (AudioRegionSelection&); + Gdk::Color get_region_color () const { return region_color; } + void apply_color (Gdk::Color&, ColorTarget t); + + RegionView* find_view (const ARDOUR::Region&); + void foreach_regionview (sigc::slot<void,RegionView*> slot); + + void set_selected_regionviews (RegionSelection&); void get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable* >&); void get_inverted_selectables (Selection&, list<Selectable* >& results); - Gdk::Color get_region_color () const { return region_color; } - void foreach_regionview (sigc::slot<void,AudioRegionView*> slot); - void foreach_crossfadeview (void (CrossfadeView::*pmf)(void)); + void add_region_view (ARDOUR::Region*); + void region_layered (RegionView*); + + sigc::signal<void,RegionView*> RegionViewAdded; - void attach (); +protected: + StreamView (RouteTimeAxisView&); - void region_layered (AudioRegionView*); +//private: (FIXME?) + + void transport_changed(); + void rec_enable_changed(); + void sess_rec_enable_changed(); + virtual void setup_rec_box () = 0; + void update_rec_box (); + virtual void update_rec_regions () = 0; - AudioRegionView* find_view (const ARDOUR::AudioRegion&); - - void show_all_xfades (); - void hide_all_xfades (); - void hide_xfades_involving (AudioRegionView&); - void reveal_xfades_involving (AudioRegionView&); + virtual void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves) = 0; + virtual void remove_region_view (ARDOUR::Region* ); + void remove_rec_region (ARDOUR::Region*); + + void display_diskstream (ARDOUR::Diskstream* ); + virtual void undisplay_diskstream (); + virtual void redisplay_diskstream () = 0; + void diskstream_changed (); + + void playlist_state_changed (ARDOUR::Change); + virtual void playlist_changed (ARDOUR::Diskstream* ); + virtual void playlist_modified (); + + virtual void color_handler (ColorID, uint32_t) = 0; - private: - AudioTimeAxisView& _trackview; - ArdourCanvas::Group* canvas_group; + RouteTimeAxisView& _trackview; + ArdourCanvas::Group* canvas_group; ArdourCanvas::SimpleRect* canvas_rect; /* frame around the whole thing */ - typedef list<AudioRegionView* > AudioRegionViewList; - AudioRegionViewList region_views; - - typedef list<CrossfadeView*> CrossfadeViewList; - CrossfadeViewList crossfade_views; + typedef list<RegionView* > RegionViewList; + RegionViewList region_views; double _samples_per_unit; - double _amplitude_above_axis; - - sigc::connection screen_update_connection; - vector<RecBoxInfo> rec_rects; - list<ARDOUR::AudioRegion* > rec_regions; - bool rec_updating; - bool rec_active; - bool use_rec_regions; - list<sigc::connection> peak_ready_connections; - jack_nframes_t last_rec_peak_frame; - map<ARDOUR::Source*, bool> rec_peak_ready_map; - - void update_rec_box (); - void transport_changed(); - void rec_enable_changed(void* src = 0); - void sess_rec_enable_changed(); - void setup_rec_box (); - void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src); - void update_rec_regions (); - - void add_region_view (ARDOUR::Region*); - void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves); - void remove_region_view (ARDOUR::Region* ); - void remove_rec_region (ARDOUR::Region*); - void remove_audio_region_view (ARDOUR::AudioRegion* ); - void remove_audio_rec_region (ARDOUR::AudioRegion*); - - void display_diskstream (ARDOUR::AudioDiskstream* ); - void undisplay_diskstream (); - void redisplay_diskstream (); - void diskstream_changed (void* ); - void playlist_state_changed (ARDOUR::Change); - void playlist_changed (ARDOUR::AudioDiskstream* ); - void playlist_modified (); - - bool crossfades_visible; - void add_crossfade (ARDOUR::Crossfade*); - void remove_crossfade (ARDOUR::Crossfade*); - - /* XXX why are these different? */ - - Gdk::Color region_color; - uint32_t stream_base_color; - void color_handler (ColorID, uint32_t); + sigc::connection screen_update_connection; + vector<RecBoxInfo> rec_rects; + list<ARDOUR::Region* > rec_regions; + bool rec_updating; + bool rec_active; + bool use_rec_regions; + + Gdk::Color region_color; ///< Contained region color + uint32_t stream_base_color; ///< Background color vector<sigc::connection> playlist_connections; - sigc::connection playlist_change_connection; + sigc::connection playlist_change_connection; }; #endif /* __ardour_streamview_h__ */ + diff --git a/gtk2_ardour/taperegionview.cc b/gtk2_ardour/tape_region_view.cc index 641d067350..bd5ce8af02 100644 --- a/gtk2_ardour/taperegionview.cc +++ b/gtk2_ardour/tape_region_view.cc @@ -30,7 +30,7 @@ #include <ardour/audiosource.h> #include <ardour/audio_diskstream.h> -#include "taperegionview.h" +#include "tape_region_view.h" #include "audio_time_axis.h" #include "gui_thread.h" @@ -42,72 +42,33 @@ using namespace PBD; using namespace Editing; using namespace ArdourCanvas; -TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, AudioTimeAxisView &tv, +const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility + = TimeAxisViewItem::Visibility ( + TimeAxisViewItem::ShowNameHighlight | + TimeAxisViewItem::ShowFrame | + TimeAxisViewItem::HideFrameRight | + TimeAxisViewItem::FullWidthNameHighlight); + +TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu, Gdk::Color& basic_color) : AudioRegionView (parent, tv, r, spu, basic_color, - TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameHighlight| - TimeAxisViewItem::ShowFrame| - TimeAxisViewItem::HideFrameLR| - TimeAxisViewItem::FullWidthNameHighlight)) + TimeAxisViewItem::Visibility ((r.position() != 0) ? default_tape_visibility : + TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft))) { } void -TapeAudioRegionView::init (double amplitude_above_axis, Gdk::Color& basic_color, bool wfw) +TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw) { - XMLNode *node; - - editor = 0; - valid = true; - in_destructor = false; - _amplitude_above_axis = amplitude_above_axis; - zero_line = 0; - wait_for_waves = wfw; - _height = 0; - - _flags = 0; - - if ((node = region.extra_xml ("GUI")) != 0) { - set_flags (node); - } else { - _flags = WaveformVisible; - store_flags (); - } - - fade_in_handle = 0; - fade_out_handle = 0; - gain_line = 0; - sync_mark = 0; - - compute_colors (basic_color); - - create_waves (); - - name_highlight->set_data ("regionview", this); - - reset_width_dependent_items ((double) region.length() / samples_per_unit); - - set_height (trackview.height); - - region_muted (); - region_resized (BoundsChanged); - set_waveview_data_src(); - region_locked (); - - /* no events, no state changes */ - - set_colors (); - - // ColorChanged.connect (mem_fun (*this, &AudioRegionView::color_handler)); + AudioRegionView::init(basic_color, wfw); /* every time the wave data changes and peaks are ready, redraw */ - - for (uint32_t n = 0; n < region.n_channels(); ++n) { - region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); + for (uint32_t n = 0; n < audio_region().n_channels(); ++n) { + audio_region().source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); } } @@ -129,7 +90,7 @@ TapeAudioRegionView::update (uint32_t n) /* this triggers a cache invalidation and redraw in the waveview */ - waves[n]->property_data_src() = ®ion; + waves[n]->property_data_src() = &_region; } void diff --git a/gtk2_ardour/taperegionview.h b/gtk2_ardour/tape_region_view.h index 3e23e0fc19..ed3852e3a9 100644 --- a/gtk2_ardour/taperegionview.h +++ b/gtk2_ardour/tape_region_view.h @@ -23,23 +23,25 @@ #include <vector> -#include "regionview.h" +#include "audio_region_view.h" class TapeAudioRegionView : public AudioRegionView { public: TapeAudioRegionView (ArdourCanvas::Group *, - AudioTimeAxisView&, + RouteTimeAxisView&, ARDOUR::AudioRegion&, double initial_samples_per_unit, Gdk::Color& base_color); ~TapeAudioRegionView (); protected: - void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves); + void init (Gdk::Color& base_color, bool wait_for_waves); void set_frame_color (); void update (uint32_t n); + + static const TimeAxisViewItem::Visibility default_tape_visibility; }; #endif /* __gtk_ardour_tape_audio_region_view_h__ */ diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index b5ab5baa10..6261241139 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -128,6 +128,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie controls_table.attach (name_hbox, 0, 4, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); controls_table.show_all (); + controls_table.set_no_show_all (); controls_vbox.pack_start (controls_table, false, false); controls_vbox.show (); @@ -661,8 +662,6 @@ TimeAxisView::show_selection (TimeSelection& ts) void TimeAxisView::reshow_selection (TimeSelection& ts) { - cerr << name() << ": reshow selection" << endl; - show_selection (ts); for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { @@ -882,7 +881,7 @@ TimeAxisView::reset_height() set_height_pixels (height); for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) { - (*i)->set_height ((TrackHeight)(*i)->height); + (*i)->set_height_pixels ((TrackHeight)(*i)->height); } } diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index c607c78166..31ff3d84ee 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -54,7 +54,7 @@ namespace Gtk { } class PublicEditor; -class AudioRegionSelection; +class RegionSelection; class TimeSelection; class PointSelection; class TimeAxisViewItem; @@ -183,7 +183,7 @@ class TimeAxisView : public virtual AxisView virtual bool cut_copy_clear (Selection&, Editing::CutCopyOp) { return false; } virtual bool paste (jack_nframes_t, float times, Selection&, size_t nth) { return false; } - virtual void set_selected_regionviews (AudioRegionSelection&) {} + virtual void set_selected_regionviews (RegionSelection&) {} virtual void set_selected_points (PointSelection&) {} virtual ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir) { diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index abab306a84..28fafcaa09 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -137,8 +137,12 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& uint32_t outline_what = 0x1|0x2|0x4|0x8; - if (visibility & HideFrameLR) { - outline_what &= ~(0x1 | 0x2); + if (visibility & HideFrameLeft) { + outline_what &= ~(0x1); + } + + if (visibility & HideFrameRight) { + outline_what &= ~(0x2); } if (visibility & HideFrameTB) { diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index b23350eef7..9ddb06876a 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -316,9 +316,10 @@ class TimeAxisViewItem : public Selectable ShowNameHighlight = 0x2, ShowNameText = 0x4, ShowHandles = 0x8, - HideFrameLR = 0x10, - HideFrameTB = 0x20, - FullWidthNameHighlight = 0x40 + HideFrameLeft = 0x10, + HideFrameRight = 0x20, + HideFrameTB = 0x40, + FullWidthNameHighlight = 0x80 }; /** diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 91cb7ad58b..ef90c34755 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -215,7 +215,7 @@ get_font_for_style (string widgetname) { Gtk::Window window (WINDOW_TOPLEVEL); Gtk::Label foobar; - Glib::RefPtr<Style> style; + Glib::RefPtr<Gtk::Style> style; window.add (foobar); foobar.set_name (widgetname); @@ -435,12 +435,10 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) if (!special_handling_of_unmodified_accelerators || ev->state & (Gdk::MOD1_MASK| - Gdk::MOD2_MASK| Gdk::MOD3_MASK| Gdk::MOD4_MASK| Gdk::MOD5_MASK| - Gdk::CONTROL_MASK| - Gdk::LOCK_MASK)) { + Gdk::CONTROL_MASK)) { /* no special handling or modifiers in effect: accelerate first */ diff --git a/gtk2_ardour/visual_time_axis.cc b/gtk2_ardour/visual_time_axis.cc index c27ed33089..e44ea4011e 100644 --- a/gtk2_ardour/visual_time_axis.cc +++ b/gtk2_ardour/visual_time_axis.cc @@ -255,7 +255,7 @@ VisualTimeAxis::set_time_axis_color(Gdk::Color c) } void -VisualTimeAxis::set_selected_regionviews (AudioRegionSelection& regions) +VisualTimeAxis::set_selected_regionviews (RegionSelection& regions) { // Not handled by purely visual TimeAxis } diff --git a/gtk2_ardour/visual_time_axis.h b/gtk2_ardour/visual_time_axis.h index 4be2da3b9a..c68ce8da1c 100644 --- a/gtk2_ardour/visual_time_axis.h +++ b/gtk2_ardour/visual_time_axis.h @@ -42,7 +42,7 @@ class ImageFrameView; class ImageFrameTimeAxisView; class MarkersTimeAxisView; class TimeSelection; -class AudioRegionSelection; +class RegionSelection; class MarkerTimeAxis; class TimeAxisViewStrip; @@ -105,7 +105,7 @@ class VisualTimeAxis : public TimeAxisView /** * Not implemented */ - virtual void set_selected_regionviews(AudioRegionSelection&) ; + virtual void set_selected_regionviews(RegionSelection&) ; //---------------------------------------------------------------------------------// |