Context menu for applying edits to note selection.

This commit is contained in:
David Robillard 2014-12-25 15:32:10 -05:00
parent 6b1c171dc2
commit 12a7f12b0b
8 changed files with 90 additions and 64 deletions

View File

@ -107,10 +107,12 @@
#include "gui_thread.h"
#include "keyboard.h"
#include "marker.h"
#include "midi_region_view.h"
#include "midi_time_axis.h"
#include "mixer_strip.h"
#include "mixer_ui.h"
#include "mouse_cursors.h"
#include "note_base.h"
#include "playlist_selector.h"
#include "public_editor.h"
#include "region_layering_order_editor.h"
@ -5735,6 +5737,40 @@ Editor::popup_control_point_context_menu (ArdourCanvas::Item* item, GdkEvent* ev
_control_point_context_menu.popup (event->button.button, event->button.time);
}
void
Editor::popup_note_context_menu (ArdourCanvas::Item* item, GdkEvent* event)
{
using namespace Menu_Helpers;
NoteBase* note = reinterpret_cast<NoteBase*>(item->get_data("notebase"));
if (!note) {
return;
}
/* We need to get the selection here and pass it to the operations, since
popping up the menu will cause a region leave event which clears
entered_regionview. */
MidiRegionView& mrv = note->region_view();
const RegionSelection rs = get_regions_from_selection_and_entered ();
MenuList& items = _note_context_menu.items();
items.clear();
items.push_back(MenuElem(_("Delete"),
sigc::mem_fun(mrv, &MidiRegionView::delete_selection)));
items.push_back(MenuElem(_("Edit..."),
sigc::bind(sigc::mem_fun(*this, &Editor::edit_notes), &mrv)));
items.push_back(MenuElem(_("Legatize"),
sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, false)));
items.push_back(MenuElem(_("Quantize..."),
sigc::bind(sigc::mem_fun(*this, &Editor::quantize_regions), rs)));
items.push_back(MenuElem(_("Remove Overlap"),
sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, true)));
_note_context_menu.popup (event->button.button, event->button.time);
}
void
Editor::zoom_vertical_modifier_released()
{

View File

@ -740,6 +740,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void popup_control_point_context_menu (ArdourCanvas::Item *, GdkEvent *);
Gtk::Menu _control_point_context_menu;
void popup_note_context_menu (ArdourCanvas::Item *, GdkEvent *);
Gtk::Menu _note_context_menu;
void add_routes (ARDOUR::RouteList&);
void timeaxisview_deleted (TimeAxisView *);
@ -1227,7 +1230,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void reset_region_scale_amplitude ();
void adjust_region_gain (bool up);
void quantize_region ();
void quantize_regions (const RegionSelection& rs);
void legatize_region (bool shrink_only);
void legatize_regions (const RegionSelection& rs, bool shrink_only);
void insert_patch_change (bool from_context);
void fork_region ();
@ -1608,7 +1613,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void edit_tempo_marker (TempoMarker&);
void edit_meter_marker (MeterMarker&);
void edit_control_point (ArdourCanvas::Item*);
void edit_notes (TimeAxisViewItem&);
void edit_notes (MidiRegionView*);
void marker_menu_edit ();
void marker_menu_remove ();
@ -2016,7 +2021,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void apply_filter (ARDOUR::Filter&, std::string cmd, ProgressReporter* progress = 0);
Command* apply_midi_note_edit_op_to_region (ARDOUR::MidiOperator& op, MidiRegionView& mrv);
void apply_midi_note_edit_op (ARDOUR::MidiOperator& op);
void apply_midi_note_edit_op (ARDOUR::MidiOperator& op, const RegionSelection& rs);
/* handling cleanup */

View File

@ -1305,6 +1305,12 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
popup_control_point_context_menu (item, event);
break;
case NoteItem:
if (internal_editing()) {
popup_note_context_menu (item, event);
}
break;
default:
break;
}
@ -1883,21 +1889,15 @@ Editor::edit_control_point (ArdourCanvas::Item* item)
}
void
Editor::edit_notes (TimeAxisViewItem& tavi)
Editor::edit_notes (MidiRegionView* mrv)
{
MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(&tavi);
if (!mrv) {
return;
}
MidiRegionView::Selection const & s = mrv->selection();
if (s.empty ()) {
return;
}
EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s);
EditNoteDialog* d = new EditNoteDialog (mrv, s);
d->show_all ();
ensure_float (*d);

View File

@ -4909,26 +4909,22 @@ Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv
}
void
Editor::apply_midi_note_edit_op (MidiOperator& op)
Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs)
{
Command* cmd;
RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
begin_reversible_command (op.name ());
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
RegionSelection::iterator tmp = r;
for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ) {
RegionSelection::const_iterator tmp = r;
++tmp;
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
if (mrv) {
cmd = apply_midi_note_edit_op_to_region (op, *mrv);
Command* cmd = apply_midi_note_edit_op_to_region (op, *mrv);
if (cmd) {
(*cmd)();
_session->add_command (cmd);
@ -4984,26 +4980,15 @@ Editor::fork_region ()
void
Editor::quantize_region ()
{
int selected_midi_region_cnt = 0;
if (!_session) {
return;
if (_session) {
quantize_regions(get_regions_from_selection_and_entered ());
}
}
RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
if (mrv) {
selected_midi_region_cnt++;
}
}
if (selected_midi_region_cnt == 0) {
void
Editor::quantize_regions (const RegionSelection& rs)
{
if (rs.n_midi_regions() == 0) {
return;
}
@ -5018,38 +5003,27 @@ Editor::quantize_region ()
qd->start_grid_size(), qd->end_grid_size(),
qd->strength(), qd->swing(), qd->threshold());
apply_midi_note_edit_op (quant);
apply_midi_note_edit_op (quant, rs);
}
}
void
Editor::legatize_region (bool shrink_only)
{
int selected_midi_region_cnt = 0;
if (!_session) {
return;
if (_session) {
legatize_regions(get_regions_from_selection_and_entered (), shrink_only);
}
}
RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
if (mrv) {
selected_midi_region_cnt++;
}
}
if (selected_midi_region_cnt == 0) {
void
Editor::legatize_regions (const RegionSelection& rs, bool shrink_only)
{
if (rs.n_midi_regions() == 0) {
return;
}
Legatize legatize(shrink_only);
apply_midi_note_edit_op (legatize);
apply_midi_note_edit_op (legatize, rs);
}
void

View File

@ -276,17 +276,10 @@ NoteBase::event_handler (GdkEvent* ev)
case GDK_BUTTON_PRESS:
set_mouse_fractions (ev);
if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state) && _selected) {
editor.edit_notes (_region);
return true;
}
break;
case GDK_BUTTON_RELEASE:
set_mouse_fractions (ev);
if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
return true;
}
break;
default:

View File

@ -290,7 +290,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi
virtual framecnt_t get_nudge_distance (framepos_t pos, framecnt_t& next) = 0;
virtual framecnt_t get_paste_offset (framepos_t pos, unsigned paste_count, framecnt_t duration) = 0;
virtual Evoral::MusicalTime get_grid_type_as_beats (bool& success, framepos_t position) = 0;
virtual void edit_notes (TimeAxisViewItem&) = 0;
virtual void edit_notes (MidiRegionView*) = 0;
virtual void queue_visual_videotimeline_update () = 0;
virtual void set_close_video_sensitive (bool) = 0;

View File

@ -21,6 +21,7 @@
#include "ardour/region.h"
#include "gui_thread.h"
#include "midi_region_view.h"
#include "region_view.h"
#include "region_selection.h"
#include "time_axis_view.h"
@ -287,3 +288,18 @@ RegionSelection::playlists () const
return pl;
}
size_t
RegionSelection::n_midi_regions () const
{
size_t count = 0;
for (const_iterator r = begin(); r != end(); ++r) {
MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
if (mrv) {
++count;
}
}
return count;
}

View File

@ -61,6 +61,8 @@ class RegionSelection : public std::list<RegionView*>
void by_position (std::list<RegionView*>&) const;
void by_track (std::list<RegionView*>&) const;
size_t n_midi_regions() const;
std::set<boost::shared_ptr<ARDOUR::Playlist> > playlists () const;
std::list<PBD::ID> pending;