#include "pbd/memento_command.h"
#include "pbd/stateful_diff_command.h"
-#include "ardour/midi_region.h"
-#include "ardour/midi_source.h"
#include "ardour/midi_model.h"
#include "ardour/midi_patch_manager.h"
+#include "ardour/midi_region.h"
+#include "ardour/midi_source.h"
+#include "ardour/midi_track.h"
#include "ardour/session.h"
#include "evoral/Parameter.hpp"
#include "mouse_cursors.h"
#include "note_player.h"
#include "public_editor.h"
+#include "route_time_axis.h"
#include "rgb_macros.h"
#include "selection.h"
#include "simpleline.h"
MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color const & basic_color)
: RegionView (parent, tv, r, spu, basic_color)
- , _last_channel_selection(0xFFFF)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
_note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
-
- MidiTimeAxisView *time_axis = dynamic_cast<MidiTimeAxisView *>(&tv);
- if (time_axis) {
- _last_channel_mode = time_axis->channel_selector().get_channel_mode();
- _last_channel_selection = time_axis->channel_selector().get_selected_channels();
- }
-
Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&MidiRegionView::parameter_changed, this, _1), gui_context());
connect_to_diskstream ();
boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color,
TimeAxisViewItem::Visibility visibility)
: RegionView (parent, tv, r, spu, basic_color, false, visibility)
- , _last_channel_selection(0xFFFF)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
_note_group->raise_to_top();
PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
- MidiTimeAxisView *time_axis = dynamic_cast<MidiTimeAxisView *>(&tv);
- if (time_axis) {
- _last_channel_mode = time_axis->channel_selector().get_channel_mode();
- _last_channel_selection = time_axis->channel_selector().get_selected_channels();
- }
-
connect_to_diskstream ();
SelectionCleared.connect (_selection_cleared_connection, invalidator (*this), boost::bind (&MidiRegionView::selection_cleared, this, _1), gui_context ());
MidiRegionView::MidiRegionView (const MidiRegionView& other)
: sigc::trackable(other)
, RegionView (other)
- , _last_channel_selection(0xFFFF)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<MidiRegion> region)
: RegionView (other, boost::shared_ptr<Region> (region))
- , _last_channel_selection(0xFFFF)
, _current_range_min(0)
, _current_range_max(0)
, _active_notes(0)
group->raise_to_top();
group->signal_event().connect (sigc::mem_fun (this, &MidiRegionView::canvas_event), false);
- midi_view()->signal_channel_mode_changed().connect(
- sigc::mem_fun(this, &MidiRegionView::midi_channel_mode_changed));
+
+ midi_view()->midi_track()->PlaybackChannelModeChanged.connect (_channel_mode_changed_connection, invalidator (*this),
+ boost::bind (&MidiRegionView::midi_channel_mode_changed, this),
+ gui_context ());
instrument_info().Changed.connect (_instrument_changed_connection, invalidator (*this),
boost::bind (&MidiRegionView::instrument_settings_changed, this), gui_context());
MidiRegionView::display_patch_changes ()
{
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
- uint16_t chn_mask = mtv->channel_selector().get_selected_channels();
+ uint16_t chn_mask = mtv->midi_track()->get_playback_channel_mask();
for (uint8_t i = 0; i < 16; ++i) {
display_patch_changes_on_channel (i, chn_mask & (1 << i));
/* outline all edges */
ev->property_outline_what() = (guint32) 0xF;
}
-
+
if (update_ghost_regions) {
for (std::vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*i);
event->show_velocity();
}
- event->on_channel_selection_change(_last_channel_selection);
+ event->on_channel_selection_change (get_selected_channels());
_events.push_back(event);
if (visible) {
void
MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2, bool extend)
{
- if (x1 > x2) {
- swap (x1, x2);
- }
-
- if (y1 > y2) {
- swap (y1, y2);
- }
-
// TODO: Make this faster by storing the last updated selection rect, and only
// adjusting things that are in the area that appears/disappeared.
// We probably need a tree to be able to find events in O(log(n)) time.
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
-
- /* check if any corner of the note is inside the rect
-
- Notes:
- 1) this is computing "touched by", not "contained by" the rect.
- 2) this does not require that events be sorted in time.
- */
-
- const double ix1 = (*i)->x1();
- const double ix2 = (*i)->x2();
- const double iy1 = (*i)->y1();
- const double iy2 = (*i)->y2();
-
- if ((ix1 >= x1 && ix1 <= x2 && iy1 >= y1 && iy1 <= y2) ||
- (ix1 >= x1 && ix1 <= x2 && iy2 >= y1 && iy2 <= y2) ||
- (ix2 >= x1 && ix2 <= x2 && iy1 >= y1 && iy1 <= y2) ||
- (ix2 >= x1 && ix2 <= x2 && iy2 >= y1 && iy2 <= y2)) {
-
- // Inside rectangle
+ if ((*i)->x1() < x2 && (*i)->x2() > x1 && (*i)->y1() < y2 && (*i)->y2() > y1) {
+ // Rectangles intersect
if (!(*i)->selected()) {
add_to_selection (*i);
}
} else if ((*i)->selected() && !extend) {
- // Not inside rectangle
+ // Rectangles do not intersect
remove_from_selection (*i);
}
}
// We probably need a tree to be able to find events in O(log(n)) time.
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
-
- /* check if any corner of the note is inside the rect
-
- Notes:
- 1) this is computing "touched by", not "contained by" the rect.
- 2) this does not require that events be sorted in time.
- */
-
if (((*i)->y1() >= y1 && (*i)->y1() <= y2)) {
// within y- (note-) range
if (!(*i)->selected()) {
add_to_selection (*i);
}
} else if ((*i)->selected() && !extend) {
- // Not inside rectangle
remove_from_selection (*i);
}
}
}
void
-MidiRegionView::midi_channel_mode_changed(ChannelMode mode, uint16_t mask)
+MidiRegionView::midi_channel_mode_changed ()
{
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ uint16_t mask = mtv->midi_track()->get_playback_channel_mask();
+ ChannelMode mode = mtv->midi_track()->get_playback_channel_mode ();
+
if (mode == ForceChannel) {
mask = 0xFFFF; // Show all notes as active (below)
}
// Update notes for selection
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
- (*i)->on_channel_selection_change(mask);
+ (*i)->on_channel_selection_change (mask);
}
- _last_channel_selection = mask;
- _last_channel_mode = mode;
-
_patch_changes.clear ();
display_patch_changes ();
}
time_sort_events ();
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
- uint16_t const channel_mask = mtv->channel_selector().get_selected_channels ();
+ uint16_t const channel_mask = mtv->midi_track()->get_playback_channel_mask();
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
if ((*i)->selected()) {
time_sort_events ();
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
- uint16_t const channel_mask = mtv->channel_selector().get_selected_channels ();
+ uint16_t const channel_mask = mtv->midi_track()->get_playback_channel_mask ();
for (Events::reverse_iterator i = _events.rbegin(); i != _events.rend(); ++i) {
if ((*i)->selected()) {
Events e;
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
- uint16_t chn_mask = mtv->channel_selector().get_selected_channels();
+ uint16_t chn_mask = mtv->midi_track()->get_playback_channel_mask();
if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
get_events (e, Evoral::Sequence<Evoral::MusicalTime>::PitchGreaterThanOrEqual, (uint8_t) floor (note), chn_mask);
Evoral::MIDIEvent<MidiBuffer::TimeType> const ev (*i, false);
if (ev.is_channel_event()) {
- if (_last_channel_mode == FilterChannels) {
- if (((uint16_t(1) << ev.channel()) & _last_channel_selection) == 0) {
+ if (get_channel_mode() == FilterChannels) {
+ if (((uint16_t(1) << ev.channel()) & get_selected_channels()) == 0) {
continue;
}
}
Evoral::MusicalTime const time_beats = converter.from (ev.time () - converter.origin_b ());
if (ev.type() == MIDI_CMD_NOTE_ON) {
-
boost::shared_ptr<NoteType> note (
- new NoteType (ev.channel(), time_beats, 0, ev.note(), ev.velocity())
- );
+ new NoteType (ev.channel(), time_beats, 0, ev.note(), ev.velocity()));
add_note (note, true);
{
PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY, true);
- d.set_position (Gtk::WIN_POS_MOUSE);
-
int response = d.run();
switch (response) {
delete _note_player;
_note_player = 0;
}
+
+ChannelMode
+MidiRegionView::get_channel_mode () const
+{
+ RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (&trackview);
+ return rtav->midi_track()->get_playback_channel_mode();
+}
+
+uint16_t
+MidiRegionView::get_selected_channels () const
+{
+ RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (&trackview);
+ return rtav->midi_track()->get_playback_channel_mask();
+}
+