diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index edddd1a7e1..7ee7863c03 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -146,6 +146,8 @@ public: virtual void set_selected_midi_region_view (MidiRegionView&); + samplecnt_t get_current_zoom () const { return samples_per_pixel; } + /* NOTE: these functions assume that the "pixel" coordinate is in canvas coordinates. These coordinates already take into account any scrolling offsets. @@ -244,7 +246,6 @@ public: virtual void set_zoom_focus (Editing::ZoomFocus) = 0; virtual Editing::ZoomFocus get_zoom_focus () const = 0; - virtual samplecnt_t get_current_zoom () const = 0; virtual void reset_zoom (samplecnt_t) = 0; virtual void reposition_and_zoom (samplepos_t, double) = 0; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 578f93efb2..0b8786db62 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -281,7 +281,6 @@ public: void set_zoom_focus (Editing::ZoomFocus); Editing::ZoomFocus get_zoom_focus () const { return zoom_focus; } - samplecnt_t get_current_zoom () const { return samples_per_pixel; } void cycle_zoom_focus (); void temporal_zoom_step (bool zoom_out); void temporal_zoom_step_scale (bool zoom_out, double scale); diff --git a/gtk2_ardour/ghostregion.cc b/gtk2_ardour/ghostregion.cc index 5718e2ed05..a92dd3f748 100644 --- a/gtk2_ardour/ghostregion.cc +++ b/gtk2_ardour/ghostregion.cc @@ -452,8 +452,8 @@ MidiGhostRegion::model_changed () std::shared_ptr note = i->first; GhostEvent* cne = i->second; - const bool visible = (note->note() >= parent_mrv._current_range_min) && - (note->note() <= parent_mrv._current_range_max); + const bool visible = (note->note() >= parent_mrv.midi_context().lowest_note()) && + (note->note() <= parent_mrv.midi_context().highest_note()); if (visible) { if (cne->is_hit) { diff --git a/gtk2_ardour/midi_cue_background.cc b/gtk2_ardour/midi_cue_background.cc index 2156b6c073..3243451d55 100644 --- a/gtk2_ardour/midi_cue_background.cc +++ b/gtk2_ardour/midi_cue_background.cc @@ -50,6 +50,12 @@ CueMidiBackground::contents_height() const return _height; } +double +CueMidiBackground::height() const +{ + return _height; +} + uint8_t CueMidiBackground::get_preferred_midi_channel () const { diff --git a/gtk2_ardour/midi_cue_background.h b/gtk2_ardour/midi_cue_background.h index 9040db4592..76346c421e 100644 --- a/gtk2_ardour/midi_cue_background.h +++ b/gtk2_ardour/midi_cue_background.h @@ -37,6 +37,7 @@ class CueMidiBackground : public MidiViewBackground CueMidiBackground (ArdourCanvas::Item* parent); ~CueMidiBackground (); + double height() const; double contents_height() const; uint8_t get_preferred_midi_channel () const; diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 20e545bcec..220e710a2a 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -96,13 +96,7 @@ MidiCueEditor::build_canvas () rubberband_rect = new ArdourCanvas::Rectangle (hv_scroll_group, ArdourCanvas::Rect (0.0, 0.0, 0.0, 0.0)); rubberband_rect->hide(); - ArdourCanvas::Text* hw = new ArdourCanvas::Text (hv_scroll_group); - hw->set ("hello, world"); - hw->set_fill_color (Gtkmm2ext::Color (0xff0000ff)); - - std::cerr << "New CMB\n"; bg = new CueMidiBackground (hv_scroll_group); - _canvas_viewport->signal_size_allocate().connect (sigc::mem_fun(*this, &MidiCueEditor::canvas_allocate)); } @@ -119,7 +113,6 @@ MidiCueEditor::snap_to_grid (timepos_t const & presnap, Temporal::RoundMode dire return snap_to_bbt (presnap, direction, gpref); } - void MidiCueEditor::snap_to_internal (timepos_t& start, Temporal::RoundMode direction, SnapPref pref, bool ensure_snap) const { @@ -198,7 +191,7 @@ MidiCueEditor::viewport() } void -MidiCueEditor::set_region (std::shared_ptr t, std::shared_ptr r) +MidiCueEditor::set_region (std::shared_ptr t, std::shared_ptr r) { // delete view; // view = nullptr; @@ -207,5 +200,6 @@ MidiCueEditor::set_region (std::shared_ptr t, std::shared_ptr return; } - // view = new MidiView (t, hv_scroll_group, *this, *bg, 0xff0000ff); + view = new MidiView (t, *hv_scroll_group, *this, *bg, 0xff0000ff); + view->set_region (r); } diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 01caf475c0..e36e20ab95 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -62,7 +62,7 @@ class MidiCueEditor : public CueEditor void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const RegionSelection& rs); PBD::Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiRegionView& mrv); - void set_region (std::shared_ptr, std::shared_ptr); + void set_region (std::shared_ptr, std::shared_ptr); protected: Temporal::timepos_t snap_to_grid (Temporal::timepos_t const & start, diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc index ae52ecb2ee..272dd3aa30 100644 --- a/gtk2_ardour/midi_streamview.cc +++ b/gtk2_ardour/midi_streamview.cc @@ -207,7 +207,6 @@ MidiStreamView::display_track (std::shared_ptr tr) { StreamView::display_track (tr); - std::cerr << "MSV @ " << this << " dnl\n"; draw_note_lines(); NoteRangeChanged(); /* EMIT SIGNAL*/ diff --git a/gtk2_ardour/midi_view.cc b/gtk2_ardour/midi_view.cc index 052f6e0867..c86c488ab5 100644 --- a/gtk2_ardour/midi_view.cc +++ b/gtk2_ardour/midi_view.cc @@ -120,8 +120,6 @@ MidiView::MidiView (std::shared_ptr mt, , _step_edit_cursor (0) , _step_edit_cursor_width (1, 0) , _channel_selection_scoped_note (0) - , _current_range_min(0) - , _current_range_max(0) , _mouse_state(None) , _pressed_button(0) , _optimization_iterator (_events.end()) @@ -153,8 +151,6 @@ MidiView::MidiView (MidiView const & other) , _step_edit_cursor (0) , _step_edit_cursor_width (1, 0) , _channel_selection_scoped_note (0) - , _current_range_min(0) - , _current_range_max(0) , _mouse_state(None) , _pressed_button(0) , _optimization_iterator (_events.end()) @@ -233,6 +229,8 @@ MidiView::set_model (std::shared_ptr m) _editing_context.MouseModeChanged.connect (connections_requiring_model, invalidator (*this), boost::bind (&MidiView::mouse_mode_changed, this), gui_context ()); + + model_changed (); } bool @@ -1005,6 +1003,8 @@ MidiView::redisplay (bool view_only) void MidiView::model_changed() { + std::cerr << "MC!\n"; + if (!display_is_enabled()) { return; } @@ -1045,6 +1045,22 @@ MidiView::model_changed() NoteBase* cne; + std::cerr << "drawing " << notes.size() << " notes\n"; + + uint8_t low_note = std::numeric_limits::max(); + uint8_t hi_note = std::numeric_limits::min(); + + for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) { + if ((*n)->note() < low_note) { + low_note = (*n)->note(); + } + if ((*n)->note() > hi_note) { + hi_note = (*n)->note(); + } + } + + _midi_context.apply_note_range (low_note, hi_note, true); + for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) { std::shared_ptr note (*n); @@ -1445,13 +1461,10 @@ MidiView::set_height (double ht) void MidiView::apply_note_range (uint8_t min, uint8_t max, bool force) { - if (!force && _current_range_min == min && _current_range_max == max) { + if (!force && _midi_context.lowest_note() == min && _midi_context.highest_note() == max) { return; } - _current_range_min = min; - _current_range_max = max; - view_changed (); } @@ -1548,7 +1561,7 @@ MidiView::note_in_region_range (const std::shared_ptr note, bool& visi const bool outside = !note_in_region_time_range (note); - visible = (note->note() >= _current_range_min) && (note->note() <= _current_range_max); + visible = (note->note() >= _midi_context.lowest_note()) && (note->note() <= _midi_context.highest_note()); return !outside; } @@ -1600,6 +1613,11 @@ MidiView::update_sustained (Note* ev, bool update_ghost_regions) const double y0 = 1 + floor(note_to_y(note->note())); double y1; + std::cerr << "Note: " << *note << std::endl; + std::cerr << "SSS " << session_source_start << std::endl; + std::cerr << "nh " << note_height() << std::endl; + std::cerr << "vs. " << (int) _midi_context.lowest_note() << " .. " << (int) _midi_context.highest_note() << std::endl; + if (note->length() == Temporal::Beats()) { /* special case actual zero-length notes */ @@ -1618,6 +1636,8 @@ MidiView::update_sustained (Note* ev, bool update_ghost_regions) const samplepos_t note_end_samples = _midi_region->position().distance ((session_source_start + note_end)).samples(); + std::cerr << "nes: " << note_end_samples << " Z " << _editing_context.get_current_zoom() << std::endl; + x1 = std::max(1., _editing_context.sample_to_pixel (note_end_samples)); } else { @@ -1629,6 +1649,7 @@ MidiView::update_sustained (Note* ev, bool update_ghost_regions) y1 = y0 + std::max(1., floor(note_height()) - 1); + std::cerr << "note rect " << ArdourCanvas::Rect (x0, y0, x1, y1) << std::endl; ev->set (ArdourCanvas::Rect (x0, y0, x1, y1)); ev->set_velocity (note->velocity()/127.0); @@ -4174,10 +4195,10 @@ MidiView::data_recorded (std::weak_ptr w) nb->item()->set_outline_color (UIConfiguration::instance().color ("recording note")); /* fix up our note range */ - if (ev.note() < _current_range_min) { - apply_note_range (ev.note(), _current_range_max, true); - } else if (ev.note() > _current_range_max) { - apply_note_range (_current_range_min, ev.note(), true); + if (ev.note() < _midi_context.lowest_note()) { + apply_note_range (ev.note(), _midi_context.highest_note(), true); + } else if (ev.note() > _midi_context.highest_note()) { + apply_note_range (_midi_context.lowest_note(), ev.note(), true); } } else if (ev.type() == MIDI_CMD_NOTE_OFF) { @@ -4415,28 +4436,6 @@ MidiView::get_draw_length_beats (timepos_t const & pos) const return beats; } -uint8_t -MidiView::y_to_note (double y) const -{ - int const n = ((contents_height() - y) / contents_height() * (double)(_current_range_max - _current_range_min + 1)) - + _current_range_min; - - if (n < 0) { - return 0; - } else if (n > 127) { - return 127; - } - - /* min due to rounding and/or off-by-one errors */ - return min ((uint8_t) n, _current_range_max); -} - -double -MidiView::note_to_y(uint8_t note) const -{ - return contents_height() - (note + 1 - _current_range_min) * note_height() + 1; -} - void MidiView::quantize_selected_notes () { @@ -4677,3 +4676,9 @@ MidiView::drag_group () const { return _note_group->parent(); } + +double +MidiView::height() const +{ + return _midi_context.height(); +} diff --git a/gtk2_ardour/midi_view.h b/gtk2_ardour/midi_view.h index 98b3fde675..842711bc7e 100644 --- a/gtk2_ardour/midi_view.h +++ b/gtk2_ardour/midi_view.h @@ -483,9 +483,6 @@ class MidiView : public virtual sigc::trackable Temporal::Beats _step_edit_cursor_position; NoteBase* _channel_selection_scoped_note; - uint8_t _current_range_min; - uint8_t _current_range_max; - MouseState _mouse_state; int _pressed_button; @@ -577,14 +574,13 @@ class MidiView : public virtual sigc::trackable ARDOUR::ChannelMode get_channel_mode() const; uint16_t get_selected_channels () const; - virtual double height() const = 0; + virtual double height() const; virtual double contents_height() const { return height() - 2; } - inline double contents_note_range () const { return (double)(_current_range_max - _current_range_min + 1); } - inline double note_height() const { return contents_height() / contents_note_range(); } + inline double note_height() const { return contents_height() / _midi_context.contents_note_range(); } - double note_to_y (uint8_t note) const; - uint8_t y_to_note (double y) const; + double note_to_y (uint8_t note) const { return _midi_context.note_to_y (note); } + uint8_t y_to_note (double y) const { return _midi_context.y_to_note (y); } void update_patch_changes (); void update_sysexes (); diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 076b6da25a..3482c172e4 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -115,7 +115,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer) , processor_box (sess, boost::bind (&MixerStrip::plugin_selector, this), mx.selection(), this, in_mixer) , gpm (sess, 250) , panners (sess) - , trigger_display (-1., TriggerBox::default_triggers_per_box*16.) , button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL)) , rec_mon_table (2, 2) , solo_iso_table (1, 2) @@ -153,7 +152,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, std::shared_ptr rt, , processor_box (sess, boost::bind (&MixerStrip::plugin_selector, this), mx.selection(), this, in_mixer) , gpm (sess, 250) , panners (sess) - , trigger_display (-1., 8*16.) , button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_HORIZONTAL)) , rec_mon_table (2, 2) , solo_iso_table (1, 2) @@ -335,7 +333,6 @@ MixerStrip::init () global_vpacker.pack_start (name_button, Gtk::PACK_SHRINK); global_vpacker.pack_start (input_button_box, Gtk::PACK_SHRINK); global_vpacker.pack_start (invert_button_box, Gtk::PACK_SHRINK); - global_vpacker.pack_start (trigger_display, Gtk::PACK_SHRINK); global_vpacker.pack_start (_tmaster_widget, Gtk::PACK_SHRINK); global_vpacker.pack_start (processor_box, true, true); global_vpacker.pack_start (panners, Gtk::PACK_SHRINK); @@ -425,7 +422,6 @@ MixerStrip::init () _visibility.add (&output_button, X_("Output"), _("Output"), false); _visibility.add (&_comment_button, X_("Comments"), _("Comments"), false); _visibility.add (&control_slave_ui, X_("VCA"), _("VCA Assigns"), false); - _visibility.add (&trigger_display, X_("TriggerGrid"), _("Trigger Grid"), false); _visibility.add (&_tmaster_widget, X_("TriggerMaster"), _("Trigger Master"), false); parameter_changed (X_("mixer-element-visibility")); @@ -542,8 +538,6 @@ MixerStrip::set_route (std::shared_ptr rt) RouteUI::set_route (rt); - set_trigger_display (rt->triggerbox()); - control_slave_ui.set_stripable (std::dynamic_pointer_cast (rt)); /* ProcessorBox needs access to _route so that it can read @@ -1683,8 +1677,6 @@ MixerStrip::revert_to_default_display () } reset_strip_style (); - - set_trigger_display (_route->triggerbox()); } void @@ -2140,9 +2132,3 @@ MixerStrip::hide_master_spacer (bool yn) } } -void -MixerStrip::set_trigger_display (std::shared_ptr tb) -{ - _tmaster->set_triggerbox (tb); - trigger_display.set_triggerbox (tb.get()); -} diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index 3df6071b6d..203ad3919a 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -192,7 +192,6 @@ private: ProcessorBox processor_box; GainMeter gpm; PannerUI panners; - TriggerBoxWidget trigger_display; Glib::RefPtr button_size_group; diff --git a/gtk2_ardour/slot_properties_box.cc b/gtk2_ardour/slot_properties_box.cc index c081c7720b..0eb618e0bd 100644 --- a/gtk2_ardour/slot_properties_box.cc +++ b/gtk2_ardour/slot_properties_box.cc @@ -756,7 +756,6 @@ SlotPropertyWindow::SlotPropertyWindow (TriggerReference tref) _trig_box->set_trigger (tref); _midi_editor = new MidiCueEditor; - _midi_editor->set_region (std::shared_ptr(), trigger->region()); table->attach(*_trig_box, col, col+1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); col++; table->attach(_midi_editor->viewport(), col, col+1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); col++; diff --git a/gtk2_ardour/trigger_page.cc b/gtk2_ardour/trigger_page.cc index 37e4aed22b..09e585d902 100644 --- a/gtk2_ardour/trigger_page.cc +++ b/gtk2_ardour/trigger_page.cc @@ -39,6 +39,7 @@ #include "ardour/region_factory.h" #include "ardour/profile.h" #include "ardour/smf_source.h" +#include "ardour/stripable.h" #include "actions.h" #include "ardour_ui.h" @@ -410,8 +411,12 @@ TriggerPage::selection_changed () _midi_trig_box.set_trigger (ref); _midi_trig_box.show (); - // _midi_trim_box.set_trigger (ref); - _midi_editor->viewport().show (); + std::shared_ptr mr = std::dynamic_pointer_cast (trigger->region()); + if (mr) { + std::shared_ptr mt = std::dynamic_pointer_cast (entry->strip().stripable()); + _midi_editor->set_region (mt, mr); + _midi_editor->viewport().show (); + } } } _parameter_box.show (); diff --git a/gtk2_ardour/trigger_strip.cc b/gtk2_ardour/trigger_strip.cc index 67e5f91d57..f246215cfd 100644 --- a/gtk2_ardour/trigger_strip.cc +++ b/gtk2_ardour/trigger_strip.cc @@ -65,7 +65,7 @@ TriggerStrip::TriggerStrip (Session* s, std::shared_ptr rt) , _pb_selection () , _tmaster_widget (-1, 16) , _processor_box (s, boost::bind (&TriggerStrip::plugin_selector, this), _pb_selection, 0) - , _trigger_display (-1., TriggerBox::default_triggers_per_box * 16.) + , _trigger_display (*this, -1., TriggerBox::default_triggers_per_box * 16.) , _panners (s) , _level_meter (s) { diff --git a/gtk2_ardour/triggerbox_ui.cc b/gtk2_ardour/triggerbox_ui.cc index db7a552303..ca424f7a4b 100644 --- a/gtk2_ardour/triggerbox_ui.cc +++ b/gtk2_ardour/triggerbox_ui.cc @@ -65,8 +65,9 @@ using namespace ArdourCanvas; using namespace Gtkmm2ext; using namespace PBD; -TriggerEntry::TriggerEntry (Item* item, TriggerReference tr) +TriggerEntry::TriggerEntry (Item* item, TriggerStrip& s, TriggerReference tr) : ArdourCanvas::Rectangle (item) + , _strip (s) , _grabbed (false) , _drag_active (false) { @@ -826,9 +827,10 @@ TriggerEntry::drag_data_get (Glib::RefPtr const&, Gtk::Selecti Glib::RefPtr TriggerBoxUI::_dnd_src; -TriggerBoxUI::TriggerBoxUI (ArdourCanvas::Item* parent, TriggerBox& tb) +TriggerBoxUI::TriggerBoxUI (ArdourCanvas::Item* parent, TriggerStrip& s, TriggerBox& tb) : Rectangle (parent) , _triggerbox (tb) + , _strip (s) { set_layout_sensitive (true); // why??? @@ -894,7 +896,7 @@ TriggerBoxUI::build () if (!t) { break; } - TriggerEntry* te = new TriggerEntry (this, TriggerReference (_triggerbox, n)); + TriggerEntry* te = new TriggerEntry (this, _strip, TriggerReference (_triggerbox, n)); _slots.push_back (te); @@ -1031,9 +1033,10 @@ TriggerBoxUI::drag_data_received (Glib::RefPtr const& context, /* ********************************************** */ -TriggerBoxWidget::TriggerBoxWidget (float w, float h) +TriggerBoxWidget::TriggerBoxWidget (TriggerStrip& s, float w, float h) : FittedCanvasWidget (w, h) - , ui (0) + , ui (nullptr) + , _strip (s) { set_background_color (UIConfiguration::instance ().color (X_("theme:bg"))); } @@ -1044,13 +1047,13 @@ TriggerBoxWidget::set_triggerbox (TriggerBox* tb) if (ui) { root ()->remove (ui); delete ui; - ui = 0; + ui = nullptr; } if (!tb) { return; } - ui = new TriggerBoxUI (root (), *tb); + ui = new TriggerBoxUI (root (), _strip, *tb); repeat_size_allocation (); } diff --git a/gtk2_ardour/triggerbox_ui.h b/gtk2_ardour/triggerbox_ui.h index 6faec16137..6d28f84595 100644 --- a/gtk2_ardour/triggerbox_ui.h +++ b/gtk2_ardour/triggerbox_ui.h @@ -43,10 +43,12 @@ namespace ArdourCanvas class Polygon; } +class TriggerStrip; + class TriggerEntry : public ArdourCanvas::Rectangle, public TriggerUI { public: - TriggerEntry (ArdourCanvas::Item* item, ARDOUR::TriggerReference rf); + TriggerEntry (ArdourCanvas::Item* item, TriggerStrip&, ARDOUR::TriggerReference rf); ~TriggerEntry (); ArdourCanvas::Rectangle* play_button; @@ -76,7 +78,10 @@ public: bool name_button_event (GdkEvent*); + TriggerStrip& strip() const { return _strip; } + private: + TriggerStrip& _strip; bool _grabbed; double _poly_size; double _poly_margin; @@ -104,11 +109,13 @@ private: class TriggerBoxUI : public ArdourCanvas::Rectangle { public: - TriggerBoxUI (ArdourCanvas::Item* parent, ARDOUR::TriggerBox&); + TriggerBoxUI (ArdourCanvas::Item* parent, TriggerStrip&, ARDOUR::TriggerBox&); ~TriggerBoxUI (); void _size_allocate (ArdourCanvas::Rect const&); + TriggerStrip& strip() const { return _strip; } + static Glib::RefPtr dnd_src () { return _dnd_src; @@ -119,6 +126,7 @@ private: ARDOUR::TriggerBox& _triggerbox; Slots _slots; + TriggerStrip& _strip; static Glib::RefPtr _dnd_src; @@ -140,12 +148,14 @@ private: class TriggerBoxWidget : public FittedCanvasWidget { public: - TriggerBoxWidget (float w, float h); + TriggerBoxWidget (TriggerStrip&, float w, float h); void set_triggerbox (ARDOUR::TriggerBox* tb); + TriggerStrip& strip() const { return _strip; } private: TriggerBoxUI* ui; + TriggerStrip& _strip; }; #endif diff --git a/gtk2_ardour/view_background.h b/gtk2_ardour/view_background.h index 27783d415b..80d59d84e5 100644 --- a/gtk2_ardour/view_background.h +++ b/gtk2_ardour/view_background.h @@ -40,6 +40,7 @@ class ViewBackground ViewBackground (); virtual ~ViewBackground (); + virtual double height() const { return 0.; } virtual double contents_height() const { return 0.; } /** @return y position, or -1 if hidden */