diff --git a/gtk2_ardour/audio_clip_editor.cc b/gtk2_ardour/audio_clip_editor.cc index d828d8cd1d..cbbad24d2d 100644 --- a/gtk2_ardour/audio_clip_editor.cc +++ b/gtk2_ardour/audio_clip_editor.cc @@ -86,18 +86,22 @@ ClipEditorBox::register_clip_editor_actions (Bindings* clip_editor_bindings) void AudioClipEditor::ClipBBTMetric::get_marks (std::vector& marks, int64_t lower, int64_t upper, int maxchars) const { - TriggerPtr trigger = tref.trigger(); - + TriggerPtr trigger (tref.trigger()); if (!trigger) { std::cerr << "No trigger\n"; return; } + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (!at) { + return; + } + ArdourCanvas::Ruler::Mark mark; - assert (trigger->segment_tempo() > 0.); + assert (at->segment_tempo() > 0.); - Temporal::Tempo tempo (trigger->segment_tempo(), trigger->meter().divisions_per_bar()); + Temporal::Tempo tempo (at->segment_tempo(), at->meter().divisions_per_bar()); std::cerr << "get marks between " << lower << " .. " << upper << " with tempo " << tempo << " upp = " << units_per_pixel << std::endl; @@ -439,10 +443,10 @@ AudioClipEditor::set_region (boost::shared_ptr r, TriggerReference waves.push_back (wv); } - TriggerPtr t (tr.trigger()); - - if (t) { - if (t->segment_tempo() == 0.) { + TriggerPtr trigger (tr.trigger()); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + if (at->segment_tempo() == 0.) { /* tempo unknown, hide ruler */ ruler->hide (); } else { diff --git a/gtk2_ardour/audio_trigger_properties_box.cc b/gtk2_ardour/audio_trigger_properties_box.cc index 41aa16fb5d..1ee305e390 100644 --- a/gtk2_ardour/audio_trigger_properties_box.cc +++ b/gtk2_ardour/audio_trigger_properties_box.cc @@ -53,12 +53,17 @@ using std::min; AudioTriggerPropertiesBox::AudioTriggerPropertiesBox () : _length_clock (X_("regionlength"), true, "", true, false, true) , _start_clock (X_("regionstart"), true, "", false, false) + , _bar_adjustment( 1, 0.001, 1000.0, 1.0, 4.0, 0) + , _bar_spinner (_bar_adjustment) , _stretch_toggle (ArdourButton::led_default_elements) , _abpm_label (ArdourButton::Text) + , _ignore_changes (false) { Gtk::Label* label; int row = 0; + _abpm_label.set_sizing_text("200.00"); + /* ------- Stretching and Tempo stuff ----------------------------- */ Gtk::Table* bpm_table = manage (new Gtk::Table ()); bpm_table->set_homogeneous (false); @@ -66,8 +71,8 @@ AudioTriggerPropertiesBox::AudioTriggerPropertiesBox () bpm_table->set_border_width (8); _stretch_toggle.set_text (_("Stretch")); - bpm_table->attach (_stretch_toggle, 0, 1, row, row + 1, Gtk::SHRINK, Gtk::SHRINK); - bpm_table->attach (_stretch_selector, 1, 2, row, row + 1, Gtk::SHRINK, Gtk::SHRINK); row++; + bpm_table->attach (_stretch_toggle, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK); + bpm_table->attach (_stretch_selector, 1, 4, row, row + 1, Gtk::FILL, Gtk::SHRINK); row++; label = manage (new Gtk::Label (_("BPM:"))); label->set_alignment (1.0, 0.5); @@ -83,10 +88,20 @@ AudioTriggerPropertiesBox::AudioTriggerPropertiesBox () row++; - label = manage (new Gtk::Label (_("Time Sig:"))); + label = manage (new Gtk::Label (_("Meter:"))); label->set_alignment (1.0, 0.5); bpm_table->attach (*label, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK); - bpm_table->attach (_metrum_button, 1, 2, row, row + 1, Gtk::FILL, Gtk::SHRINK); + bpm_table->attach (_meter_selector, 1, 4, row, row + 1, Gtk::FILL, Gtk::SHRINK); + + row++; + + label = manage (new Gtk::Label (_("Clip Length:"))); + label->set_alignment (1.0, 0.5); + Gtk::Label *bar_label = manage (new Gtk::Label (_("(bars)"))); + bar_label->set_alignment (0.0, 0.5); + bpm_table->attach (*label, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK); + bpm_table->attach (_bar_spinner, 1, 2, row, row + 1, Gtk::FILL, Gtk::SHRINK); + bpm_table->attach (*bar_label, 2, 4, row, row + 1, Gtk::FILL, Gtk::SHRINK); ArdourWidgets::Frame* eTempoBox = manage (new ArdourWidgets::Frame); eTempoBox->set_label("Stretch Options"); @@ -118,8 +133,18 @@ AudioTriggerPropertiesBox::AudioTriggerPropertiesBox () attach (_table, 0,1, 1,2, Gtk::FILL, Gtk::SHRINK); #endif + _start_clock.ValueChanged.connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::start_clock_changed)); + _length_clock.ValueChanged.connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::length_clock_changed)); + using namespace Menu_Helpers; + _meter_selector.set_text ("??"); + _meter_selector.set_name ("generic button"); + _meter_selector.set_sizing_text ("4/4"); + _meter_selector.AddMenuElem (MenuElem ("3/4", sigc::bind (sigc::mem_fun(*this, &AudioTriggerPropertiesBox::meter_changed), Temporal::Meter(3,4)))); + _meter_selector.AddMenuElem (MenuElem ("4/4", sigc::bind (sigc::mem_fun(*this, &AudioTriggerPropertiesBox::meter_changed), Temporal::Meter(4,4)))); + _meter_selector.AddMenuElem (MenuElem ("5/4", sigc::bind (sigc::mem_fun(*this, &AudioTriggerPropertiesBox::meter_changed), Temporal::Meter(5,4)))); + _stretch_selector.set_text ("??"); _stretch_selector.set_name ("generic button"); _stretch_selector.set_sizing_text (TriggerUI::longest_stretch_mode); @@ -128,6 +153,9 @@ AudioTriggerPropertiesBox::AudioTriggerPropertiesBox () _stretch_selector.AddMenuElem (MenuElem (TriggerUI::stretch_mode_to_string(Trigger::Smooth), sigc::bind (sigc::mem_fun(*this, &AudioTriggerPropertiesBox::set_stretch_mode), Trigger::Smooth))); _stretch_toggle.signal_clicked.connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::toggle_stretch)); + + _bar_spinner.set_can_focus(false); + _bar_spinner.signal_changed ().connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::bars_changed)); } AudioTriggerPropertiesBox::~AudioTriggerPropertiesBox () @@ -138,8 +166,9 @@ void AudioTriggerPropertiesBox::MultiplyTempo(float mult) { TriggerPtr trigger (tref.trigger()); - if (trigger) { - trigger->set_segment_tempo (trigger->segment_tempo () * mult); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + at->set_segment_tempo (at->segment_tempo () * mult); } } @@ -147,8 +176,9 @@ void AudioTriggerPropertiesBox::toggle_stretch () { TriggerPtr trigger (tref.trigger()); - if (trigger) { - trigger->set_stretchable (!trigger->stretchable ()); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + at->set_stretchable (!at->stretchable ()); } } @@ -156,8 +186,9 @@ void AudioTriggerPropertiesBox::set_stretch_mode (Trigger::StretchMode sm) { TriggerPtr trigger (tref.trigger()); - if (trigger) { - trigger->set_stretch_mode (sm); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + at->set_stretch_mode (sm); } } @@ -171,33 +202,71 @@ AudioTriggerPropertiesBox::set_session (Session* s) } void -AudioTriggerPropertiesBox::on_trigger_changed (const PBD::PropertyChange& what_changed) +AudioTriggerPropertiesBox::on_trigger_changed (const PBD::PropertyChange& pc) { TriggerPtr trigger (tref.trigger()); - if (!trigger) { + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (!at) { return; } - AudioClock::Mode mode = trigger->box ().data_type () == ARDOUR::DataType::AUDIO ? AudioClock::Samples : AudioClock::BBT; + _ignore_changes = true; - _start_clock.set_mode (mode); - _length_clock.set_mode (mode); + if (pc.contains (Properties::start) || pc.contains (Properties::length)) { /* NOT REACHED from current code */ + AudioClock::Mode mode = at->box ().data_type () == ARDOUR::DataType::AUDIO ? AudioClock::Samples : AudioClock::BBT; - _start_clock.set (trigger->start_offset ()); - _length_clock.set (trigger->current_length ()); // set_duration() ? + _start_clock.set_mode (mode); + _length_clock.set_mode (mode); - _start_clock.ValueChanged.connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::start_clock_changed)); - _length_clock.ValueChanged.connect (sigc::mem_fun (*this, &AudioTriggerPropertiesBox::length_clock_changed)); + _start_clock.set (at->start_offset ()); + _length_clock.set (at->current_length ()); // set_duration() ? + } - _abpm_label.set_text (string_compose ("%1", trigger->segment_tempo ())); - ArdourWidgets::set_tooltip (_abpm_label, string_compose ("Clip Tempo, used for stretching. Estimated tempo (from file) was: %1", trigger->estimated_tempo ())); + if (pc.contains (Properties::tempo_meter) || pc.contains (Properties::follow_length)) { - _metrum_button.set_text (string_compose ("%1/%2", trigger->meter().divisions_per_bar(), trigger->meter().note_value())); + char buf[32]; + sprintf(buf, "%3.2f", at->segment_tempo ()); + _abpm_label.set_text (buf); - _stretch_toggle.set_active (trigger->stretchable () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + ArdourWidgets::set_tooltip (_abpm_label, string_compose ("Clip Tempo, used for stretching. Estimated tempo (from file) was: %1", trigger->estimated_tempo ())); - _stretch_selector.set_sensitive(trigger->stretchable ()); - _stretch_selector.set_text(stretch_mode_to_string(trigger->stretch_mode ())); + _meter_selector.set_text (string_compose ("%1/%2", at->meter().divisions_per_bar(), at->meter().note_value())); + + _bar_adjustment.set_value(at->segment_barcnt()); + } + + if (pc.contains (Properties::stretch_mode) || pc.contains (Properties::stretchable)) { + _stretch_toggle.set_active (at->stretchable () ? Gtkmm2ext::ExplicitActive : Gtkmm2ext::Off); + + _stretch_selector.set_sensitive(at->stretchable ()); + _stretch_selector.set_text(stretch_mode_to_string(at->stretch_mode ())); + } + + _ignore_changes = false; +} + +void +AudioTriggerPropertiesBox::meter_changed (Temporal::Meter m) +{ + TriggerPtr trigger (tref.trigger()); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + at->set_segment_meter(m); + } +} + +void +AudioTriggerPropertiesBox::bars_changed () +{ + if (_ignore_changes) { + return; + } + + TriggerPtr trigger (tref.trigger()); + boost::shared_ptr at = boost::dynamic_pointer_cast (trigger); + if (at) { + at->set_segment_barcnt (_bar_adjustment.get_value()); + } } void diff --git a/gtk2_ardour/audio_trigger_properties_box.h b/gtk2_ardour/audio_trigger_properties_box.h index b8b51763ab..859760daa3 100644 --- a/gtk2_ardour/audio_trigger_properties_box.h +++ b/gtk2_ardour/audio_trigger_properties_box.h @@ -63,7 +63,9 @@ protected: void start_clock_changed(); void length_clock_changed(); - void follow_clock_changed(); + void meter_changed (Temporal::Meter m); + + void bars_changed(); private: @@ -74,7 +76,10 @@ private: AudioClock _length_clock; AudioClock _start_clock; - ArdourWidgets::ArdourButton _metrum_button; + ArdourWidgets::ArdourDropdown _meter_selector; + + Gtk::Adjustment _bar_adjustment; + Gtk::SpinButton _bar_spinner; ArdourWidgets::ArdourButton _stretch_toggle; @@ -82,6 +87,7 @@ private: ArdourWidgets::ArdourButton _abpm_label; + bool _ignore_changes; }; #endif diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 4e3d130f17..19e03334ec 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -677,10 +677,9 @@ Editor::Editor () Location::end_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context()); Location::changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context()); -#if 0 +#if SELECTION_PROPERTIES_BOX_TODO add_notebook_page (_("Selection"), *_properties_box); -#else -#warning @Ben Fix Properties Sidebar Layout to fit < 720px height +#warning Fix Properties Sidebar Layout to fit < 720px height #endif add_notebook_page (_("Tracks & Busses"), _routes->widget ()); add_notebook_page (_("Sources"), _sources->widget ()); @@ -738,8 +737,8 @@ Editor::Editor () editor_summary_pane.add (_summary_hbox); edit_pane.set_check_divider_position (true); edit_pane.add (editor_summary_pane); + _editor_list_vbox.pack_start (*_properties_box, false, false, 0); _editor_list_vbox.pack_start (_the_notebook); -// _editor_list_vbox.pack_start (*_properties_box, false, false, 0); edit_pane.add (_editor_list_vbox); edit_pane.set_child_minsize (_editor_list_vbox, 30); /* rough guess at width of notebook tabs */ diff --git a/gtk2_ardour/selection_properties_box.cc b/gtk2_ardour/selection_properties_box.cc index eab1c97f5b..792e9fde81 100644 --- a/gtk2_ardour/selection_properties_box.cc +++ b/gtk2_ardour/selection_properties_box.cc @@ -65,6 +65,7 @@ SelectionPropertiesBox::SelectionPropertiesBox () _time_info_box = new TimeInfoBox ("EditorTimeInfo", true); pack_start(*_time_info_box, false, false, 0); +#if SELECTION_PROPERTIES_BOX_TODO /* Region ops (mute/unmute), for multiple-Region selections */ _mregions_prop_box = new MultiRegionPropertiesBox (); pack_start(*_mregions_prop_box, false, false, 0); @@ -91,7 +92,7 @@ SelectionPropertiesBox::SelectionPropertiesBox () /* SLOT properties, for Trigger slot selections */ _slot_prop_box = new SlotPropertiesBox (); pack_start(*_slot_prop_box, false, false, 0); - +#endif /* watch for any change in our selection, so we can show an appropriate property editor */ Editor::instance().get_selection().TracksChanged.connect (sigc::mem_fun (*this, &SelectionPropertiesBox::selection_changed)); @@ -114,6 +115,7 @@ SelectionPropertiesBox::~SelectionPropertiesBox () { delete _time_info_box; +#if SELECTION_PROPERTIES_BOX_TODO delete _mregions_prop_box; delete _slot_prop_box; @@ -123,6 +125,7 @@ SelectionPropertiesBox::~SelectionPropertiesBox () delete _midi_prop_box; delete _audio_prop_box; +#endif } void @@ -131,6 +134,8 @@ SelectionPropertiesBox::set_session (Session* s) SessionHandlePtr::set_session (s); _time_info_box->set_session(s); + +#if SELECTION_PROPERTIES_BOX_TODO _mregions_prop_box->set_session(s); _midi_prop_box->set_session(s); @@ -140,6 +145,7 @@ SelectionPropertiesBox::set_session (Session* s) _audio_ops_box->set_session(s); _slot_prop_box->set_session(s); +#endif } void @@ -155,6 +161,7 @@ SelectionPropertiesBox::selection_changed () _time_info_box->hide(); +#if SELECTION_PROPERTIES_BOX_TODO _mregions_prop_box->hide(); _midi_ops_box->hide(); @@ -164,17 +171,20 @@ SelectionPropertiesBox::selection_changed () _audio_prop_box->hide(); _slot_prop_box->hide(); +#endif if (selection.empty()) { - _header_label.set_text(_("Nothing Selected")); + _header_label.hide(); } else { - _header_label.set_text(_("Selection Properties (ESC = Deselect All)")); + _header_label.set_text(_("Range Properties (Press ESC to Deselect All)")); + _header_label.show(); } if (!selection.time.empty()) { _time_info_box->show(); } +#if SELECTION_PROPERTIES_BOX_TODO /* one or more regions, show the multi-region operations box (just MUTE? kinda boring) */ if (!selection.regions.empty()) { _mregions_prop_box->show(); @@ -233,4 +243,5 @@ SelectionPropertiesBox::selection_changed () _audio_ops_box->show(); } } +#endif } diff --git a/gtk2_ardour/slot_properties_box.cc b/gtk2_ardour/slot_properties_box.cc index f7a196d2fa..036f095864 100644 --- a/gtk2_ardour/slot_properties_box.cc +++ b/gtk2_ardour/slot_properties_box.cc @@ -201,7 +201,7 @@ SlotPropertyTable::SlotPropertyTable () _name_label.set_name (X_("TrackNameEditor")); _name_label.set_alignment (0.0, 0.5); _name_label.set_padding (4, 0); - _name_label.set_width_chars (12); + _name_label.set_width_chars (24); _namebox.add (_name_label); _namebox.add_events (Gdk::BUTTON_PRESS_MASK); @@ -233,7 +233,8 @@ SlotPropertyTable::SlotPropertyTable () _follow_size_group->add_widget(_velocity_slider); _follow_size_group->add_widget(_follow_count_spinner); - set_spacings (4); + set_spacings (8); //match to TriggerPage:: table->set_spacings + set_border_width (0); //change TriggerPage:: table->set_border_width instead set_homogeneous (false); int row=0; @@ -241,14 +242,15 @@ SlotPropertyTable::SlotPropertyTable () /* ---- Basic trigger properties (name, color) ----- */ _trigger_table.set_spacings (4); + _trigger_table.set_border_width (8); _trigger_table.set_homogeneous (false); - _trigger_table.attach(_name_frame, 0, 2, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK ); - _trigger_table.attach(_load_button, 2, 3, row, row+1, Gtk::SHRINK, Gtk::SHRINK ); - _trigger_table.attach(_color_label, 3, 4, row, row + 1, Gtk::FILL, Gtk::SHRINK); - _trigger_table.attach(_color_button, 4, 5, row, row+1, Gtk::SHRINK, Gtk::SHRINK ); - _trigger_table.attach(_gain_label, 5, 6, row, row + 1, Gtk::FILL, Gtk::SHRINK); - _trigger_table.attach(_gain_spinner, 6, 7, row, row + 1, Gtk::FILL, Gtk::SHRINK); + _trigger_table.attach(_name_frame, 0, 5, row, row+1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK ); row++; + _trigger_table.attach(_load_button, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK ); + _trigger_table.attach(_color_label, 1, 2, row, row + 1, Gtk::FILL, Gtk::SHRINK); + _trigger_table.attach(_color_button, 2, 3, row, row+1, Gtk::SHRINK, Gtk::SHRINK ); + _trigger_table.attach(_gain_label, 3, 4, row, row + 1, Gtk::FILL, Gtk::SHRINK); + _trigger_table.attach(_gain_spinner, 4, 5, row, row + 1, Gtk::FILL, Gtk::SHRINK); /* ---- Launch settings ----- */ @@ -318,6 +320,12 @@ SlotPropertyTable::SlotPropertyTable () _follow_table.attach( *prob_table, 0, 2, row, row+1, Gtk::FILL, Gtk::SHRINK ); row++; _follow_table.attach( *fol_table, 0, 2, row, row+1, Gtk::FILL, Gtk::SHRINK ); row++; + ArdourWidgets::Frame* trigBox = manage (new ArdourWidgets::Frame); + trigBox->set_label("Clip Properties"); + trigBox->set_name("EditorDark"); + trigBox->set_edge_color (0x000000ff); // black + trigBox->add (_trigger_table); + ArdourWidgets::Frame* eFollowBox = manage (new ArdourWidgets::Frame); eFollowBox->set_label("Follow Options"); eFollowBox->set_name("EditorDark"); @@ -330,9 +338,9 @@ SlotPropertyTable::SlotPropertyTable () eLaunchBox->set_edge_color (0x000000ff); // black eLaunchBox->add (_launch_table); - attach(_trigger_table, 0,2, 0,1, Gtk::FILL, Gtk::SHRINK ); - attach(*eLaunchBox, 0,1, 1,2, Gtk::FILL, Gtk::SHRINK ); - attach(*eFollowBox, 1,2, 1,2, Gtk::FILL, Gtk::SHRINK ); + attach(*trigBox, 0,1, 0,1, Gtk::FILL, Gtk::SHRINK ); + attach(*eLaunchBox, 1,2, 0,1, Gtk::FILL, Gtk::SHRINK ); + attach(*eFollowBox, 2,3, 0,1, Gtk::FILL, Gtk::SHRINK ); } SlotPropertyTable::~SlotPropertyTable () diff --git a/gtk2_ardour/trigger_clip_picker.cc b/gtk2_ardour/trigger_clip_picker.cc index 156b164160..19c5625ea2 100644 --- a/gtk2_ardour/trigger_clip_picker.cc +++ b/gtk2_ardour/trigger_clip_picker.cc @@ -135,6 +135,7 @@ TriggerClipPicker::TriggerClipPicker () _view.signal_row_collapsed ().connect (sigc::mem_fun (*this, &TriggerClipPicker::row_collapsed)); _view.signal_drag_data_get ().connect (sigc::mem_fun (*this, &TriggerClipPicker::drag_data_get)); _view.signal_cursor_changed ().connect (sigc::mem_fun (*this, &TriggerClipPicker::cursor_changed)); + _view.signal_drag_end ().connect (sigc::mem_fun (*this, &TriggerClipPicker::drag_end)); Config->ParameterChanged.connect (_config_connection, invalidator (*this), boost::bind (&TriggerClipPicker::parameter_changed, this, _1), gui_context ()); @@ -316,6 +317,12 @@ TriggerClipPicker::maybe_add_dir (std::string const& dir) * Treeview Callbacks */ +void +TriggerClipPicker::drag_end (Glib::RefPtr const&) +{ + _session->cancel_audition (); +} + void TriggerClipPicker::cursor_changed () { diff --git a/gtk2_ardour/trigger_clip_picker.h b/gtk2_ardour/trigger_clip_picker.h index 0402850115..cf69fd856b 100644 --- a/gtk2_ardour/trigger_clip_picker.h +++ b/gtk2_ardour/trigger_clip_picker.h @@ -56,6 +56,7 @@ private: bool test_expand (Gtk::TreeModel::iterator const&, Gtk::TreeModel::Path const&); void row_collapsed (Gtk::TreeModel::iterator const&, Gtk::TreeModel::Path const&); void drag_data_get (Glib::RefPtr const&, Gtk::SelectionData&, guint, guint); + void drag_end (Glib::RefPtr const&); void maybe_add_dir (std::string const&); void audition_selected (); void audition (std::string const&); diff --git a/gtk2_ardour/trigger_page.cc b/gtk2_ardour/trigger_page.cc index 6f4a657d25..f22afaec75 100644 --- a/gtk2_ardour/trigger_page.cc +++ b/gtk2_ardour/trigger_page.cc @@ -118,33 +118,34 @@ TriggerPage::TriggerPage () _strip_group_box.pack_start (_cue_area_frame, false, false); _strip_group_box.pack_start (_strip_scroller, true, true); + /* sidebar */ + _sidebar_notebook.set_show_tabs (true); + _sidebar_notebook.set_scrollable (true); + _sidebar_notebook.popup_disable (); + _sidebar_notebook.set_tab_pos (Gtk::POS_RIGHT); + + _sidebar_vbox.pack_start (_sidebar_notebook); + add_sidebar_page (_("Clips"), _trigger_clip_picker); + /* Upper pane ([slot | strips] | file browser) */ _pane_upper.add (_strip_group_box); - _pane_upper.add (_trigger_clip_picker); + _pane_upper.add (_sidebar_vbox); /* Bottom -- Properties of selected Slot/Region */ Gtk::Table* table = manage (new Gtk::Table); table->set_homogeneous (false); - table->set_spacings (8); + table->set_spacings (8); //match to slot_properties_box::set_spacings table->set_border_width (8); int col = 0; - table->attach (_slot_prop_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); + table->attach (_slot_prop_box, col, col + 1, 0, 1, Gtk::FILL, Gtk::SHRINK); - col = 1; /* audio and midi boxen share the same table locations; shown and hidden depending on region type */ - table->attach (_audio_trig_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); - ++col; - table->attach (_audio_trim_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); - ++col; - table->attach (_audio_ops_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); + col = 1; + table->attach (_audio_trig_box, col, col + 1, 0, 1, Gtk::FILL, Gtk::SHRINK); ++col; - col = 1; /* audio and midi boxen share the same table locations; shown and hidden depending on region type */ - table->attach (_midi_trig_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); - ++col; - table->attach (_midi_trim_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); - ++col; - table->attach (_midi_ops_box, col, col + 1, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::SHRINK); + col = 2; + table->attach (_midi_trig_box, col, col + 1, 0, 1, Gtk::FILL, Gtk::SHRINK); ++col; _parameter_box.pack_start (*table); @@ -165,6 +166,7 @@ TriggerPage::TriggerPage () _cue_area_frame.show_all (); _trigger_clip_picker.show (); _no_strips.show (); + _sidebar_notebook.show_all (); /* setup keybidings */ _content.set_data ("ardour-bindings", bindings); @@ -226,12 +228,18 @@ TriggerPage::get_state () node->set_property (X_("triggerpage-vpane-pos"), _pane.get_divider ()); node->set_property (X_("triggerpage-hpane-pos"), _pane_upper.get_divider ()); + node->set_property (X_("triggerpage-sidebar-page"), _sidebar_notebook.get_current_page ()); + return *node; } int TriggerPage::set_state (const XMLNode& node, int version) { + int32_t sidebar_page; + if (node.get_property (X_("triggerpage-sidebar-page"), sidebar_page)) { + _sidebar_notebook.set_current_page (sidebar_page); + } return Tabbable::set_state (node, version); } @@ -278,12 +286,8 @@ TriggerPage::set_session (Session* s) _slot_prop_box.set_session (s); _audio_trig_box.set_session (s); - _audio_ops_box.set_session (s); - _audio_trim_box.set_session (s); _midi_trig_box.set_session (s); - _midi_ops_box.set_session (s); - _midi_trim_box.set_session (s); update_title (); start_updating (); @@ -341,6 +345,17 @@ TriggerPage::update_title () } } +void +TriggerPage::add_sidebar_page (string const & name, Gtk::Widget& widget) +{ + EventBox* b = manage (new EventBox); + Label* l = manage (new Label (name)); + l->set_angle (-90); + b->add (*l); + b->show_all (); + _sidebar_notebook.append_page (widget, *b); +} + void TriggerPage::initial_track_display () { @@ -358,12 +373,8 @@ TriggerPage::selection_changed () _slot_prop_box.hide (); _audio_trig_box.hide (); - _audio_ops_box.hide (); - _audio_trim_box.hide (); _midi_trig_box.hide (); - _midi_ops_box.hide (); - _midi_trim_box.hide (); _parameter_box.hide (); @@ -378,18 +389,10 @@ TriggerPage::selection_changed () if (trigger->region ()) { if (trigger->region ()->data_type () == DataType::AUDIO) { _audio_trig_box.set_trigger (ref); - _audio_trim_box.set_region (trigger->region (), ref); - _audio_trig_box.show (); - _audio_trim_box.show (); - _audio_ops_box.show (); } else { _midi_trig_box.set_trigger (ref); - _midi_trim_box.set_region (trigger->region (), ref); - _midi_trig_box.show (); - _midi_trim_box.show (); - _midi_ops_box.show (); } } _parameter_box.show (); @@ -600,8 +603,8 @@ TriggerPage::drop_paths_part_two (std::vector paths) bool TriggerPage::idle_drop_paths (std::vector paths) { - drop_paths_part_two (paths); - return false; + drop_paths_part_two (paths); + return false; } gint diff --git a/gtk2_ardour/trigger_page.h b/gtk2_ardour/trigger_page.h index 0c26f5d1a3..0ce68064d0 100644 --- a/gtk2_ardour/trigger_page.h +++ b/gtk2_ardour/trigger_page.h @@ -72,6 +72,8 @@ private: void pi_property_changed (PBD::PropertyChange const&); void stripable_property_changed (PBD::PropertyChange const&, boost::weak_ptr); + void add_sidebar_page (std::string const&, Gtk::Widget&); + bool no_strip_button_event (GdkEventButton*); bool no_strip_drag_motion (Glib::RefPtr const&, int, int, guint); void no_strip_drag_data_received (Glib::RefPtr const&, int, int, Gtk::SelectionData const&, guint, guint); @@ -98,8 +100,9 @@ private: Gtk::Alignment _cue_area_frame; Gtk::VBox _cue_area_box; Gtk::HBox _parameter_box; - - TriggerClipPicker _trigger_clip_picker; + Gtk::VBox _sidebar_vbox; + Gtk::Notebook _sidebar_notebook; + TriggerClipPicker _trigger_clip_picker; CueBoxWidget _cue_box; FittedCanvasWidget _master_widget; @@ -108,12 +111,15 @@ private: SlotPropertiesBox _slot_prop_box; AudioTriggerPropertiesBox _audio_trig_box; + MidiTriggerPropertiesBox _midi_trig_box; + +#if REGION_PROPERTIES_BOX_TODO AudioRegionOperationsBox _audio_ops_box; AudioClipEditorBox _audio_trim_box; - MidiTriggerPropertiesBox _midi_trig_box; MidiRegionOperationsBox _midi_ops_box; MidiClipEditorBox _midi_trim_box; +#endif std::list _strips; sigc::connection _fast_screen_update_connection; diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index cc979780e7..b6cedf6ac8 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -252,6 +252,10 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { TriggerBox& box() const { return _box; } + double estimated_tempo() const { return _estimated_tempo; } + + Temporal::Meter meter() const { return _meter; } + gain_t gain() const { return _gain; } void set_gain (gain_t); @@ -266,16 +270,6 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { Smooth, }; - StretchMode stretch_mode() const { return _stretch_mode; } - void set_stretch_mode (StretchMode); - - double estimated_tempo() const { return _estimated_tempo; } - double segment_tempo() const { return _segment_tempo; } - void set_segment_tempo (double t); - - Temporal::Meter meter() const { return _meter; } - void set_tempo (Temporal::Meter const &); - void set_pending (Trigger*); Trigger* swap_pending (Trigger*); @@ -354,6 +348,18 @@ class LIBARDOUR_API AudioTrigger : public Trigger { pframes_t run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes, pframes_t offset, bool first, double bpm, bool); + StretchMode stretch_mode() const { return _stretch_mode; } + void set_stretch_mode (StretchMode); + + double segment_tempo() const { return _segment_tempo; } + void set_segment_tempo (double t); + + Temporal::Meter segment_meter() const { return _meter; } //TODO: might be different? + void set_segment_meter(Temporal::Meter const &); //TODO: disambiguated from a future midi::metrum + + double segment_barcnt () { return _barcnt; } + void set_segment_barcnt (double count); + void set_start (timepos_t const &); void set_end (timepos_t const &); void set_legato_offset (timepos_t const &); diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index b03cc1ce1d..ca6076d4d4 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -200,16 +200,6 @@ Trigger::set_stretchable (bool s) _box.session().set_dirty(); } -void -Trigger::set_segment_tempo (double t) -{ - if (_segment_tempo != t) { - _segment_tempo = t; //TODO : this data will likely get stored in the SegmentDescriptor, not the trigger itself - PropertyChanged (ARDOUR::Properties::tempo_meter); - _box.session().set_dirty(); - } -} - void Trigger::set_ui (void* p) { @@ -248,18 +238,6 @@ Trigger::set_gain (gain_t g) _box.session().set_dirty(); } -void -Trigger::set_stretch_mode (Trigger::StretchMode sm) -{ - if (_stretch_mode == sm) { - return; - } - - _stretch_mode = sm; - PropertyChanged (Properties::stretch_mode); - _box.session().set_dirty(); -} - void Trigger::set_midi_velocity_effect (float mve) { @@ -367,6 +345,7 @@ Trigger::set_state (const XMLNode& node, int version) node.get_property (X_("estimated-tempo"), _estimated_tempo); //TODO: for now: if we know the bpm, overwrite the value that estimate_tempo() found node.get_property (X_("segment-tempo"), _segment_tempo); + node.get_property (X_("barcnt"), _barcnt); node.get_property (X_("index"), _index); set_values (node); @@ -861,6 +840,59 @@ AudioTrigger::~AudioTrigger () delete _stretcher; } +void +AudioTrigger::set_stretch_mode (Trigger::StretchMode sm) +{ + if (_stretch_mode == sm) { + return; + } + + _stretch_mode = sm; + PropertyChanged (Properties::stretch_mode); + _box.session().set_dirty(); +} + +void +AudioTrigger::set_segment_tempo (double t) +{ + if (_segment_tempo != t) { + _segment_tempo = t; //TODO : this data will likely get stored in the SegmentDescriptor, not the trigger itself + PropertyChanged (ARDOUR::Properties::tempo_meter); + _box.session().set_dirty(); + } +} + +void +AudioTrigger::set_segment_meter (Temporal::Meter const &m) +{ + if (_meter != m) { + _meter = m; + + //given a meter from the user, tempo is assumed constant and we re-calc barcnt internally + const double seconds = (double) data.length / _box.session().sample_rate(); + const double quarters = (seconds / 60.) * _segment_tempo; + _barcnt = quarters / _meter.divisions_per_bar(); + + PropertyChanged (ARDOUR::Properties::tempo_meter); + _box.session().set_dirty(); + } +} + +void +AudioTrigger::set_segment_barcnt (double count) +{ + if (_barcnt != count) { + _barcnt = count; + + //given a barcnt from the user, meter is assumed constant and we re-calc tempo internally + const double seconds = (double) data.length / _box.session().sample_rate(); + const double quarters = _barcnt * _meter.divisions_per_bar(); //TODO: this assumes note_value=quarter + _estimated_tempo = quarters / (seconds/60.0); + + set_segment_tempo(_estimated_tempo); + } +} + bool AudioTrigger::stretching() const {