summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2020-04-16 12:16:45 -0600
committerPaul Davis <paul@linuxaudiosystems.com>2020-04-16 17:48:12 -0600
commit65f7a6a9388d8462a08dd8da7a218baca099649f (patch)
treec532f3a8492dec66a9e27f423ded11982fdde16d /gtk2_ardour
parent921e3e75b5f03ff9d38e12c28167e377c1254926 (diff)
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
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_mouse.cc35
-rw-r--r--gtk2_ardour/editor_ops.cc41
-rw-r--r--gtk2_ardour/editor_selection.cc31
-rw-r--r--gtk2_ardour/midi_streamview.cc17
-rw-r--r--gtk2_ardour/midi_streamview.h2
-rw-r--r--gtk2_ardour/midi_time_axis.cc6
-rw-r--r--gtk2_ardour/midi_time_axis.h2
-rw-r--r--gtk2_ardour/public_editor.h1
9 files changed, 123 insertions, 13 deletions
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 9d2e860030..5381951ab7 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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);
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 7d63c4925d..2437dc31b8 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -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 */
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 92385e41b7..813ff303de 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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) ();
+ }
+}
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index fa67ea4ab1..e8326ae643 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -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);
+ }
+}
diff --git a/gtk2_ardour/midi_streamview.cc b/gtk2_ardour/midi_streamview.cc
index fe3ecd9685..b638a64999 100644
--- a/gtk2_ardour/midi_streamview.cc
+++ b/gtk2_ardour/midi_streamview.cc
@@ -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";
+ }
+ }
+}
diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h
index 20cf7b88fe..b333ff33e8 100644
--- a/gtk2_ardour/midi_streamview.h
+++ b/gtk2_ardour/midi_streamview.h
@@ -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,
diff --git a/gtk2_ardour/midi_time_axis.cc b/gtk2_ardour/midi_time_axis.cc
index 71732123bd..395ce6d012 100644
--- a/gtk2_ardour/midi_time_axis.cc
+++ b/gtk2_ardour/midi_time_axis.cc
@@ -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);
+}
diff --git a/gtk2_ardour/midi_time_axis.h b/gtk2_ardour/midi_time_axis.h
index 0f0724fe32..78a7f95cee 100644
--- a/gtk2_ardour/midi_time_axis.h
+++ b/gtk2_ardour/midi_time_axis.h
@@ -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; }
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 9709f88722..be6f900d3d 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -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;