View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002148 | ardour | features | public | 2008-03-28 05:21 | 2008-04-14 12:40 |
Reporter | hansfbaier | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | Linux Ubuntu studio gutsy | OS | Linux | OS Version | 2.6.22-14-rt |
Summary | 0002148: Implemented Editing velocities, please apply patch | ||||
Description | Editing velocities of single notes or groups of notes is now possible by using the mouse wheel over the notes or selections. Contained in the patch are several bugfixes in MidiRegionView and an improvement of its selection model. | ||||
Tags | No tags attached. | ||||
2008-03-28 05:21
|
implemented_editing_velocities_and_improved_selection_model_and_bugfixes_midi_region_view.diff (10,001 bytes)
Index: gtk2_ardour/editor_canvas_events.cc =================================================================== --- gtk2_ardour/editor_canvas_events.cc (Revision 3194) +++ gtk2_ardour/editor_canvas_events.cc (Arbeitskopie) @@ -40,6 +40,7 @@ #include "control_point.h" #include "canvas_impl.h" #include "simplerect.h" +#include "canvas-midi-event.h" #include "i18n.h" @@ -48,6 +49,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; +using namespace ArdourCanvas; bool Editor::track_canvas_scroll (GdkEventScroll* ev) @@ -56,6 +58,7 @@ double wx, wy; nframes_t xdelta; int direction = ev->direction; + CanvasMidiEvent *midi_event = dynamic_cast<CanvasMidiEvent *>(track_canvas->get_item_at(ev->x, ev->y)); retry: switch (direction) { @@ -94,6 +97,9 @@ current_stepping_trackview->step_height (true); return true; } else { + if(midi_event) { + return midi_event->on_event(reinterpret_cast<GdkEvent *>(ev)); + } scroll_tracks_up_line (); return true; } @@ -129,6 +135,9 @@ current_stepping_trackview->step_height (false); return true; } else { + if(midi_event) { + return midi_event->on_event(reinterpret_cast<GdkEvent *>(ev)); + } scroll_tracks_down_line (); return true; } Index: gtk2_ardour/midi_util.h =================================================================== --- gtk2_ardour/midi_util.h (Revision 3194) +++ gtk2_ardour/midi_util.h (Arbeitskopie) @@ -54,5 +54,14 @@ } } +inline static void clamp_0_to_127(uint8_t &val) +{ + if( (127 < val) && (val < 192) ) { + val = 127; + } else if( (192 <= val) && (val < 255) ) { + val = 0; + } +} + #endif /* __gtk_ardour_midi_util_h__ */ Index: gtk2_ardour/canvas-midi-event.cc =================================================================== --- gtk2_ardour/canvas-midi-event.cc (Revision 3194) +++ gtk2_ardour/canvas-midi-event.cc (Arbeitskopie) @@ -49,7 +49,7 @@ return; } else if (yn) { set_fill_color(UINT_INTERPOLATE(note_fill_color(_note->velocity()), - ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(), 0.85)); + ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(), 0.1)); set_outline_color(ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get()); } else { set_fill_color(note_fill_color(_note->velocity())); @@ -75,6 +75,27 @@ return false; switch (ev->type) { + case GDK_SCROLL: + if(ev->scroll.direction == GDK_SCROLL_UP) { + _region.note_selected(this, true); + if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) { + // TODO: absolute velocity + } else { + _region.change_velocity(10, true); + } + return true; + } else if(ev->scroll.direction == GDK_SCROLL_DOWN) { + _region.note_selected(this, true); + if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) { + // TODO: absolute velocity + } else { + _region.change_velocity(-10, true); + } + return true; + } else { + return false; + } + case GDK_KEY_PRESS: if (_note && ev->key.keyval == GDK_Delete) { selected(true); Index: gtk2_ardour/midi_region_view.h =================================================================== --- gtk2_ardour/midi_region_view.h (Revision 3194) +++ gtk2_ardour/midi_region_view.h (Arbeitskopie) @@ -103,6 +103,7 @@ void command_remove_note(ArdourCanvas::CanvasMidiEvent* ev) { if (_delta_command && ev->note()) { + _selection.erase(ev); _delta_command->remove(ev->note()); ev->selected(true); } @@ -162,6 +163,14 @@ */ void commit_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double event_x, bool relative); + /** + * This function is called while the user adjusts the velocity on a selection of notes + * @param velocity the relative or absolute velocity, dependin on the value of relative + * @param relative true if the given velocity represents a delta to be applied to all notes, false + * if the absolute value of the note shoud be set + */ + void change_velocity(uint8_t velocity, bool relative=false); + enum MouseState { None, Pressed, SelectTouchDragging, SelectRectDragging, AddDragging, EraseTouchDragging }; MouseState mouse_state() const { return _mouse_state; } @@ -221,9 +230,17 @@ MouseState _mouse_state; int _pressed_button; + /// currently selected CanvasMidiEvents typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection; Selection _selection; + /** + * this enables vanilla notes to be marked for selection + * they are added to _selection when redisplay_model is called + * this is necessary for selecting notes during/after model manipulations + */ + std::set<ARDOUR::Note *> _marked_for_selection; + std::vector<NoteResizeData *> _resize_data; }; Index: gtk2_ardour/midi_region_view.cc =================================================================== --- gtk2_ardour/midi_region_view.cc (Revision 3194) +++ gtk2_ardour/midi_region_view.cc (Arbeitskopie) @@ -423,8 +423,22 @@ _model->read_lock(); - for (size_t i=0; i < _model->n_notes(); ++i) + /* + MidiModel::Notes notes = _model->notes(); + cerr << endl << "Model contains " << notes.size() << " Notes:" << endl; + for(MidiModel::Notes::iterator i = notes.begin(); i != notes.end(); ++i) { + Note note = *(*i).get(); + cerr << "MODEL: Note time: " << note.time() << " duration: " << note.duration() + << " end-time: " << note.end_time() + << " velocity: " << int(note.velocity()) + //<< " Note-on: " << note.on_event(). + //<< " Note-off: " << note.off_event() + << endl; + }*/ + + for (size_t i=0; i < _model->n_notes(); ++i) { add_note(_model->note_at(i)); + } end_write(); @@ -609,6 +623,7 @@ { delete[] _active_notes; _active_notes = NULL; + _marked_for_selection.clear(); } @@ -657,6 +672,8 @@ ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); + CanvasMidiEvent *event = 0; + if (midi_view()->note_mode() == Sustained) { //cerr << "MRV::add_note sustained " << note->note() << " @ " << note->time() @@ -687,6 +704,7 @@ ev_rect->show(); _events.push_back(ev_rect); + event = ev_rect; MidiGhostRegion* gr; @@ -711,9 +729,19 @@ ev_diamond->property_fill_color_rgba() = note_fill_color(note->velocity()); ev_diamond->property_outline_color_rgba() = note_outline_color(note->velocity()); _events.push_back(ev_diamond); + event = ev_diamond; + } else { + event = 0; + } + if(event) { + Note *note = event->note().get(); + + if(_marked_for_selection.find(note) != _marked_for_selection.end()) { + note_selected(event, true); } } +} void MidiRegionView::delete_selection() @@ -851,7 +879,6 @@ // Make sure the note pitch does not exceed the MIDI standard range if (dnote <= 127 && (highest_note_in_selection + dnote > 127)) { highest_note_difference = highest_note_in_selection - 127; - cerr << "Highest note difference: " << (int) highest_note_difference; } start_delta_command(); @@ -868,9 +895,15 @@ copy->set_time(0); } - uint8_t new_pitch = (*i)->note()->note() + dnote - highest_note_difference; - if(new_pitch > 127) { - new_pitch = 127; + uint8_t original_pitch = (*i)->note()->note(); + uint8_t new_pitch = original_pitch + dnote - highest_note_difference; + + // keep notes in standard midi range + clamp_0_to_127(new_pitch); + + //notes which are dragged beyond the standard midi range snap back to their original place + if((original_pitch != 0 && new_pitch == 0) || (original_pitch != 127 && new_pitch == 127)) { + new_pitch = original_pitch; } lowest_note_in_selection = std::min(lowest_note_in_selection, new_pitch); @@ -880,19 +913,16 @@ command_add_note(copy); - _selection.erase(i); + _marked_for_selection.insert(copy.get()); i = next; } apply_command(); - //cerr << "new lowest note (selection): " << int(lowest_note_in_selection) << " new highest note(selection): " << int(highest_note_in_selection) << endl; - // care about notes being moved beyond the upper/lower bounds on the canvas if(lowest_note_in_selection < midi_stream_view()->lowest_note() || highest_note_in_selection > midi_stream_view()->highest_note() ) { - //cerr << "resetting note range" << endl; midi_stream_view()->set_note_range(MidiStreamView::ContentsRange); } } @@ -1031,12 +1061,15 @@ command_remove_note(canvas_note); copy->on_event().time() = current_frame; command_add_note(copy); + _marked_for_selection.insert(copy.get()); } // resize end of note if (note_end == CanvasNote::NOTE_OFF && current_frame > copy->time()) { command_remove_note(canvas_note); + command_remove_note(canvas_note); copy->off_event().time() = current_frame; command_add_note(copy); + _marked_for_selection.insert(copy.get()); } delete resize_rect; @@ -1045,10 +1078,46 @@ _resize_data.clear(); apply_command(); - clear_selection(); } + void +MidiRegionView::change_velocity(uint8_t velocity, bool relative) +{ + start_delta_command(); + for (Selection::iterator i = _selection.begin(); i != _selection.end();) { + Selection::iterator next = i; + ++next; + + CanvasMidiEvent *event = *i; + const boost::shared_ptr<Note> copy(new Note(*(event->note().get()))); + + if(relative) { + uint8_t new_velocity = copy->velocity() + velocity; + clamp_0_to_127(new_velocity); + + copy->set_velocity(new_velocity); + } else { // absolute + copy->set_velocity(velocity); + } + + command_remove_note(event); + command_add_note(copy); + + _marked_for_selection.insert(copy.get()); + i = next; + } + + // dont keep notes selected if tweaking a single note + if(_marked_for_selection.size() == 1) { + _marked_for_selection.clear(); + } + + apply_command(); +} + + +void MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev) { if (ev->note() && _mouse_state == EraseTouchDragging) { |
2008-03-31 00:51
|
implemented_editing_velocities_and_bugfixes_midi_region_view.diff (13,676 bytes)
Index: gtk2_ardour/editor_canvas_events.cc =================================================================== --- gtk2_ardour/editor_canvas_events.cc (Revision 3197) +++ gtk2_ardour/editor_canvas_events.cc (Arbeitskopie) @@ -40,6 +40,7 @@ #include "control_point.h" #include "canvas_impl.h" #include "simplerect.h" +#include "canvas-midi-event.h" #include "i18n.h" @@ -48,6 +49,7 @@ using namespace ARDOUR; using namespace PBD; using namespace Gtk; +using namespace ArdourCanvas; bool Editor::track_canvas_scroll (GdkEventScroll* ev) @@ -56,6 +58,7 @@ double wx, wy; nframes_t xdelta; int direction = ev->direction; + CanvasMidiEvent *midi_event = dynamic_cast<CanvasMidiEvent *>(track_canvas->get_item_at(ev->x, ev->y)); retry: switch (direction) { @@ -94,6 +97,9 @@ current_stepping_trackview->step_height (true); return true; } else { + if(midi_event) { + return midi_event->on_event(reinterpret_cast<GdkEvent *>(ev)); + } scroll_tracks_up_line (); return true; } @@ -129,6 +135,9 @@ current_stepping_trackview->step_height (false); return true; } else { + if(midi_event) { + return midi_event->on_event(reinterpret_cast<GdkEvent *>(ev)); + } scroll_tracks_down_line (); return true; } Index: gtk2_ardour/midi_util.h =================================================================== --- gtk2_ardour/midi_util.h (Revision 3197) +++ gtk2_ardour/midi_util.h (Arbeitskopie) @@ -54,5 +54,14 @@ } } +inline static void clamp_0_to_127(uint8_t &val) +{ + if( (127 < val) && (val < 192) ) { + val = 127; + } else if( (192 <= val) && (val < 255) ) { + val = 0; + } +} + #endif /* __gtk_ardour_midi_util_h__ */ Index: gtk2_ardour/canvas-midi-event.cc =================================================================== --- gtk2_ardour/canvas-midi-event.cc (Revision 3197) +++ gtk2_ardour/canvas-midi-event.cc (Arbeitskopie) @@ -35,25 +35,56 @@ const boost::shared_ptr<ARDOUR::Note> note) : _region(region) , _item(item) + , _text(0) , _state(None) , _note(note) , _selected(false) { + _text = new Text(*(item->property_parent())); } +void +CanvasMidiEvent::move_event(double dx, double dy) +{ + _item->move(dx, dy); + _text->move(dx, dy); +} void +CanvasMidiEvent::show_velocity(void) +{ + _text->property_x() = (x1() + x2()) /2; + _text->property_y() = (y1() + y2()) /2; + ostringstream velo(ios::ate); + velo << int(_note->velocity()); + _text->property_text() = velo.str(); + _text->property_justification() = Gtk::JUSTIFY_CENTER; + _text->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(); + _text->show(); + _text->lower_to_bottom(); + _text->raise(2); +} + +void +CanvasMidiEvent::hide_velocity(void) +{ + _text->hide(); +} + +void CanvasMidiEvent::selected(bool yn) { if (!_note) { return; } else if (yn) { set_fill_color(UINT_INTERPOLATE(note_fill_color(_note->velocity()), - ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(), 0.85)); + ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(), 0.1)); set_outline_color(ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get()); + show_velocity(); } else { set_fill_color(note_fill_color(_note->velocity())); set_outline_color(note_outline_color(_note->velocity())); + hide_velocity(); } _selected = yn; @@ -70,11 +101,38 @@ double event_x, event_y, dx, dy; nframes_t event_frame; bool select_mod; + uint8_t d_velocity = 10; if (_region.get_time_axis_view().editor.current_mouse_mode() != Editing::MouseNote) return false; switch (ev->type) { + case GDK_SCROLL: + if (Keyboard::modifier_state_equals (ev->scroll.state, Keyboard::Level4Modifier)) { + d_velocity = 1; + } + + if(ev->scroll.direction == GDK_SCROLL_UP) { + _region.note_selected(this, true); + if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) { + // TODO: absolute velocity + } else { + _region.change_velocity(d_velocity, true); + } + return true; + } else if(ev->scroll.direction == GDK_SCROLL_DOWN) { + + _region.note_selected(this, true); + if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) { + // TODO: absolute velocity + } else { + _region.change_velocity(-d_velocity, true); + } + return true; + } else { + return false; + } + case GDK_KEY_PRESS: if (_note && ev->key.keyval == GDK_Delete) { selected(true); @@ -92,11 +150,15 @@ case GDK_ENTER_NOTIFY: _region.note_entered(this); _item->grab_focus(); + show_velocity(); Keyboard::magic_widget_grab_focus(); break; case GDK_LEAVE_NOTIFY: Keyboard::magic_widget_drop_focus(); + if(! selected()) { + hide_velocity(); + } _region.get_canvas_group()->grab_focus(); break; Index: gtk2_ardour/midi_region_view.h =================================================================== --- gtk2_ardour/midi_region_view.h (Revision 3197) +++ gtk2_ardour/midi_region_view.h (Arbeitskopie) @@ -103,6 +103,7 @@ void command_remove_note(ArdourCanvas::CanvasMidiEvent* ev) { if (_delta_command && ev->note()) { + _selection.erase(ev); _delta_command->remove(ev->note()); ev->selected(true); } @@ -162,6 +163,14 @@ */ void commit_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double event_x, bool relative); + /** + * This function is called while the user adjusts the velocity on a selection of notes + * @param velocity the relative or absolute velocity, dependin on the value of relative + * @param relative true if the given velocity represents a delta to be applied to all notes, false + * if the absolute value of the note shoud be set + */ + void change_velocity(uint8_t velocity, bool relative=false); + enum MouseState { None, Pressed, SelectTouchDragging, SelectRectDragging, AddDragging, EraseTouchDragging }; MouseState mouse_state() const { return _mouse_state; } @@ -221,9 +230,17 @@ MouseState _mouse_state; int _pressed_button; + /// currently selected CanvasMidiEvents typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection; Selection _selection; + /** + * this enables vanilla notes to be marked for selection + * they are added to _selection when redisplay_model is called + * this is necessary for selecting notes during/after model manipulations + */ + std::set<ARDOUR::Note *> _marked_for_selection; + std::vector<NoteResizeData *> _resize_data; }; Index: gtk2_ardour/canvas-midi-event.h =================================================================== --- gtk2_ardour/canvas-midi-event.h (Revision 3197) +++ gtk2_ardour/canvas-midi-event.h (Arbeitskopie) @@ -21,6 +21,7 @@ #define __gtk_ardour_canvas_midi_event_h__ #include "simplerect.h" +#include <libgnomecanvasmm/text.h> #include <ardour/midi_model.h> class Editor; @@ -48,13 +49,18 @@ Item* item, const boost::shared_ptr<ARDOUR::Note> note = boost::shared_ptr<ARDOUR::Note>()); - virtual ~CanvasMidiEvent() {} + virtual ~CanvasMidiEvent() { if(_text) delete _text; } bool on_event(GdkEvent* ev); bool selected() const { return _selected; } void selected(bool yn); + void move_event(double dx, double dy); + + void show_velocity(); + void hide_velocity(); + virtual void set_outline_color(uint32_t c) = 0; virtual void set_fill_color(uint32_t c) = 0; @@ -63,9 +69,6 @@ virtual double x2() = 0; virtual double y2() = 0; - const Item* item() const { return _item; } - Item* item() { return _item; } - const boost::shared_ptr<ARDOUR::Note> note() { return _note; } protected: @@ -73,6 +76,7 @@ MidiRegionView& _region; Item* const _item; + Text* _text; State _state; const boost::shared_ptr<ARDOUR::Note> _note; bool _own_note; Index: gtk2_ardour/midi_region_view.cc =================================================================== --- gtk2_ardour/midi_region_view.cc (Revision 3197) +++ gtk2_ardour/midi_region_view.cc (Arbeitskopie) @@ -423,8 +423,22 @@ _model->read_lock(); - for (size_t i=0; i < _model->n_notes(); ++i) + /* + MidiModel::Notes notes = _model->notes(); + cerr << endl << "Model contains " << notes.size() << " Notes:" << endl; + for(MidiModel::Notes::iterator i = notes.begin(); i != notes.end(); ++i) { + Note note = *(*i).get(); + cerr << "MODEL: Note time: " << note.time() << " duration: " << note.duration() + << " end-time: " << note.end_time() + << " velocity: " << int(note.velocity()) + //<< " Note-on: " << note.on_event(). + //<< " Note-off: " << note.off_event() + << endl; + }*/ + + for (size_t i=0; i < _model->n_notes(); ++i) { add_note(_model->note_at(i)); + } end_write(); @@ -538,11 +552,15 @@ note->show(); } + note->hide_velocity(); note->property_y1() = y1; note->property_y2() = y2; + if(note->selected()) { + note->show_velocity(); } } } + } _model->read_unlock(); } @@ -609,6 +627,7 @@ { delete[] _active_notes; _active_notes = NULL; + _marked_for_selection.clear(); } @@ -657,6 +676,8 @@ ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); + CanvasMidiEvent *event = 0; + if (midi_view()->note_mode() == Sustained) { //cerr << "MRV::add_note sustained " << note->note() << " @ " << note->time() @@ -687,6 +708,7 @@ ev_rect->show(); _events.push_back(ev_rect); + event = ev_rect; MidiGhostRegion* gr; @@ -711,9 +733,19 @@ ev_diamond->property_fill_color_rgba() = note_fill_color(note->velocity()); ev_diamond->property_outline_color_rgba() = note_outline_color(note->velocity()); _events.push_back(ev_diamond); + event = ev_diamond; + } else { + event = 0; + } + if(event) { + Note *note = event->note().get(); + + if(_marked_for_selection.find(note) != _marked_for_selection.end()) { + note_selected(event, true); } } +} void MidiRegionView::delete_selection() @@ -813,7 +845,7 @@ MidiRegionView::move_selection(double dx, double dy) { for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) - (*i)->item()->move(dx, dy); + (*i)->move_event(dx, dy); } @@ -851,7 +883,6 @@ // Make sure the note pitch does not exceed the MIDI standard range if (dnote <= 127 && (highest_note_in_selection + dnote > 127)) { highest_note_difference = highest_note_in_selection - 127; - cerr << "Highest note difference: " << (int) highest_note_difference; } start_delta_command(); @@ -868,9 +899,15 @@ copy->set_time(0); } - uint8_t new_pitch = (*i)->note()->note() + dnote - highest_note_difference; - if(new_pitch > 127) { - new_pitch = 127; + uint8_t original_pitch = (*i)->note()->note(); + uint8_t new_pitch = original_pitch + dnote - highest_note_difference; + + // keep notes in standard midi range + clamp_0_to_127(new_pitch); + + //notes which are dragged beyond the standard midi range snap back to their original place + if((original_pitch != 0 && new_pitch == 0) || (original_pitch != 127 && new_pitch == 127)) { + new_pitch = original_pitch; } lowest_note_in_selection = std::min(lowest_note_in_selection, new_pitch); @@ -880,19 +917,16 @@ command_add_note(copy); - _selection.erase(i); + _marked_for_selection.insert(copy.get()); i = next; } apply_command(); - //cerr << "new lowest note (selection): " << int(lowest_note_in_selection) << " new highest note(selection): " << int(highest_note_in_selection) << endl; - // care about notes being moved beyond the upper/lower bounds on the canvas if(lowest_note_in_selection < midi_stream_view()->lowest_note() || highest_note_in_selection > midi_stream_view()->highest_note() ) { - //cerr << "resetting note range" << endl; midi_stream_view()->set_note_range(MidiStreamView::ContentsRange); } } @@ -1031,12 +1065,15 @@ command_remove_note(canvas_note); copy->on_event().time() = current_frame; command_add_note(copy); + _marked_for_selection.insert(copy.get()); } // resize end of note if (note_end == CanvasNote::NOTE_OFF && current_frame > copy->time()) { command_remove_note(canvas_note); + command_remove_note(canvas_note); copy->off_event().time() = current_frame; command_add_note(copy); + _marked_for_selection.insert(copy.get()); } delete resize_rect; @@ -1045,10 +1082,46 @@ _resize_data.clear(); apply_command(); - clear_selection(); } + void +MidiRegionView::change_velocity(uint8_t velocity, bool relative) +{ + start_delta_command(); + for (Selection::iterator i = _selection.begin(); i != _selection.end();) { + Selection::iterator next = i; + ++next; + + CanvasMidiEvent *event = *i; + const boost::shared_ptr<Note> copy(new Note(*(event->note().get()))); + + if(relative) { + uint8_t new_velocity = copy->velocity() + velocity; + clamp_0_to_127(new_velocity); + + copy->set_velocity(new_velocity); + } else { // absolute + copy->set_velocity(velocity); + } + + command_remove_note(event); + command_add_note(copy); + + _marked_for_selection.insert(copy.get()); + i = next; + } + + // dont keep notes selected if tweaking a single note + if(_marked_for_selection.size() == 1) { + _marked_for_selection.clear(); + } + + apply_command(); +} + + +void MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev) { if (ev->note() && _mouse_state == EraseTouchDragging) { |
|
please use the latest diff: It has the feature of note velocities shown when hovered on or selected. |
|
have you committed this patch now that you have commit access? |
|
This patch was committed in rev branches/3.0@3211 |
Date Modified | Username | Field | Change |
---|---|---|---|
2008-03-28 05:21 | hansfbaier | New Issue | |
2008-03-28 05:21 | hansfbaier | File Added: implemented_editing_velocities_and_improved_selection_model_and_bugfixes_midi_region_view.diff | |
2008-03-31 00:51 | hansfbaier | File Added: implemented_editing_velocities_and_bugfixes_midi_region_view.diff | |
2008-03-31 00:52 | hansfbaier | Note Added: 0004819 | |
2008-04-09 01:25 | timbyr | Note Added: 0004846 | |
2008-04-14 12:40 | timbyr | Status | new => closed |
2008-04-14 12:40 | timbyr | Note Added: 0004863 | |
2008-04-14 12:40 | timbyr | Resolution | open => fixed |