13
0

changes to deal with region/note selection when changing into/out of internal edit mode

Also, activate MIDI editing actions so that they are effective in internal edit mode
This commit is contained in:
Paul Davis 2020-04-16 12:16:45 -06:00
parent 921e3e75b5
commit 65f7a6a938
9 changed files with 123 additions and 13 deletions

View File

@ -1883,6 +1883,7 @@ private:
void update_time_selection_display ();
void presentation_info_changed (PBD::PropertyChange const &);
void region_selection_changed ();
void catch_up_on_midi_selection ();
sigc::connection editor_regions_selection_changed_connection;
void sensitize_all_region_actions (bool);
void sensitize_the_right_region_actions (bool because_canvas_crossing);

View File

@ -347,6 +347,38 @@ Editor::mouse_mode_toggled (MouseMode m)
update_time_selection_display ();
if (internal_editing()) {
/* reinstate any existing MIDI note (and by extension, MIDI
* region) selection for internal edit mode. This allows a user
* to enter/exit/enter this mode without losing a selection of
* notes.
*/
catch_up_on_midi_selection ();
/* ensure that the track canvas has focus, so that key events
will get directed to the correct place.
*/
_track_canvas->grab_focus ();
/* enable MIDI editing actions, which in turns enables their
bindings
*/
ActionManager::set_sensitive (_midi_actions, true);
/* mark "magic widget focus" so that we handle key events
* correctly
*/
Keyboard::magic_widget_grab_focus ();
} else {
/* undo some of the above actions, since we're not in internal
edit mode.
*/
ActionManager::set_sensitive (_midi_actions, false);
Keyboard::magic_widget_drop_focus ();
}
update_all_enter_cursors ();
MouseModeChanged (); /* EMIT SIGNAL */
@ -2627,6 +2659,9 @@ Editor::escape ()
if (_drags->active ()) {
_drags->abort ();
} else if (_session) {
midi_action (&MidiRegionView::clear_note_selection);
selection->clear ();
/* if session is playing a range, cancel that */

View File

@ -4437,17 +4437,21 @@ void
Editor::cut_copy_midi (CutCopyOp op)
{
Temporal::Beats earliest = std::numeric_limits<Temporal::Beats>::max();
for (MidiRegionSelection::iterator i = selection->midi_regions.begin(); i != selection->midi_regions.end(); ++i) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*i);
if (mrv) {
if (!mrv->selection().empty()) {
earliest = std::min(earliest, (*mrv->selection().begin())->note()->time());
}
mrv->cut_copy_clear (op);
/* XXX: not ideal, as there may be more than one track involved in the selection */
_last_cut_copy_source_track = &mrv->get_time_axis_view();
MidiRegionSelection ms = selection->midi_regions ();
cerr << "CCM, mrv = " << ms.size() << endl;
for (MidiRegionSelection::iterator i = ms.begin(); i != ms.end(); ++i) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
if (!mrv->selection().empty()) {
earliest = std::min(earliest, (*mrv->selection().begin())->note()->time());
}
mrv->cut_copy_clear (op);
/* XXX: not ideal, as there may be more than one track involved in the selection */
_last_cut_copy_source_track = &mrv->get_time_axis_view();
}
if (!selection->points.empty()) {
@ -8562,3 +8566,22 @@ Editor::toggle_layer_display ()
}
}
void
Editor::midi_action (void (MidiRegionView::*method)())
{
MidiRegionSelection ms = selection->midi_regions();
cerr << "MIDI action with " << ms.size() << " midi regions\n";
for (MidiRegionSelection::iterator i = ms.begin(); i != ms.end(); ++i) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
if (!mrv) {
continue;
}
(mrv->*method) ();
}
}

View File

@ -49,6 +49,7 @@
#include "control_point.h"
#include "editor_regions.h"
#include "editor_cursors.h"
#include "keyboard.h"
#include "midi_region_view.h"
#include "sfdb_ui.h"
@ -1618,8 +1619,8 @@ Editor::region_selection_changed ()
//there are a few global Editor->Select actions which select regions even if you aren't in Object mode.
//if regions are selected, we must always force the mouse mode to Object...
//... otherwise the user is confusingly left with selected regions that can't be manipulated.
if (!selection->regions.empty()) {
set_mouse_mode( MouseObject, false );
if (!selection->regions.empty() && !internal_editing()) {
set_mouse_mode (MouseObject, false);
}
}
@ -1746,7 +1747,8 @@ Editor::invert_selection ()
{
if (internal_editing()) {
for (MidiRegionSelection::iterator i = selection->midi_regions.begin(); i != selection->midi_regions.end(); ++i) {
MidiRegionSelection ms = selection->midi_regions();
for (MidiRegionSelection::iterator i = ms.begin(); i != ms.end(); ++i) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*i);
if (mrv) {
mrv->invert_selection ();
@ -2217,3 +2219,26 @@ Editor::select_range (samplepos_t s, samplepos_t e)
commit_reversible_selection_op ();
return ret;
}
void
Editor::catch_up_on_midi_selection ()
{
RegionSelection regions;
for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
if ((*iter)->hidden()) {
continue;
}
MidiTimeAxisView* matv = dynamic_cast<MidiTimeAxisView*> (*iter);
if (!matv) {
continue;
}
matv->get_regions_with_selected_data (regions);
}
if (!regions.empty()) {
selection->set (regions);
}
}

View File

@ -711,3 +711,20 @@ MidiStreamView::paste (ARDOUR::samplepos_t pos, const Selection& selection, Past
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*prev);
return mrv ? mrv->paste(pos, selection, ctx, sub_num) : false;
}
void
MidiStreamView::get_regions_with_selected_data (RegionSelection& rs)
{
for (list<RegionView*>::const_iterator i = region_views.begin(); i != region_views.end(); ++i) {
MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
if (!mrv) {
continue;
}
if (!mrv->selection().empty()) {
rs.add (*i);
cerr << "added region " << mrv->get_item_name() << " to RwSD\n";
}
}
}

View File

@ -63,8 +63,8 @@ public:
MidiStreamView (MidiTimeAxisView&);
~MidiStreamView ();
void set_selected_regionviews (RegionSelection&);
void get_inverted_selectables (Selection&, std::list<Selectable* >& results);
void get_regions_with_selected_data (RegionSelection&);
enum VisibleNoteRange {
FullRange,

View File

@ -1700,3 +1700,9 @@ MidiTimeAxisView::paste (samplepos_t pos, const Selection& selection, PasteConte
return midi_view()->paste(pos, selection, ctx, sub_num);
}
void
MidiTimeAxisView::get_regions_with_selected_data (RegionSelection& rs)
{
midi_view()->get_regions_with_selected_data (rs);
}

View File

@ -93,6 +93,8 @@ public:
void show_existing_automation (bool apply_to_selection = false);
void create_automation_child (const Evoral::Parameter& param, bool show);
void get_regions_with_selected_data (RegionSelection&);
bool paste (ARDOUR::samplepos_t, const Selection&, PasteContext& ctx, const int32_t sub_num);
ARDOUR::NoteMode note_mode() const { return _note_mode; }

View File

@ -390,6 +390,7 @@ public:
Glib::RefPtr<Gtk::ActionGroup> editor_actions;
Glib::RefPtr<Gtk::ActionGroup> editor_menu_actions;
Glib::RefPtr<Gtk::ActionGroup> _region_actions;
Glib::RefPtr<Gtk::ActionGroup> _midi_actions;
virtual bool canvas_scroll_event (GdkEventScroll* event, bool from_canvas) = 0;
virtual bool canvas_control_point_event (GdkEvent* event, ArdourCanvas::Item*, ControlPoint*) = 0;