diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-12-29 16:34:51 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-12-29 16:34:51 +0000 |
commit | d16bb0b8bc007e805b1c3b386d3595ba0e69938a (patch) | |
tree | f3fbd3c5b0e2c6a351fc97f7bd030f02a1fef338 | |
parent | b690cac96178810ea2f73fdce7d2403a246a8f03 (diff) |
rest of lincoln's MIDI note edit via click outside of MIDI edit mode patch
git-svn-id: svn://localhost/ardour2/branches/3.0@8366 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/canvas-note-event.cc | 16 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 156 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 5 | ||||
-rw-r--r-- | gtk2_ardour/rc_option_editor.cc | 63 |
4 files changed, 201 insertions, 39 deletions
diff --git a/gtk2_ardour/canvas-note-event.cc b/gtk2_ardour/canvas-note-event.cc index 1aa5ddda1b..0e1afcc017 100644 --- a/gtk2_ardour/canvas-note-event.cc +++ b/gtk2_ardour/canvas-note-event.cc @@ -138,6 +138,12 @@ void CanvasNoteEvent::show_channel_selector(void) { if (_channel_selector_widget == 0) { + + if(_region.channel_selector_scoped_note() != 0){ + _region.channel_selector_scoped_note()->hide_channel_selector(); + _region.set_channel_selector_scoped_note(0); + } + SingleMidiChannelSelector* _channel_selector = new SingleMidiChannelSelector(_note->channel()); _channel_selector->show_all(); _channel_selector->channel_selected.connect( @@ -156,6 +162,8 @@ CanvasNoteEvent::show_channel_selector(void) _channel_selector_widget->property_width() = 100; _channel_selector_widget->raise_to_top(); _channel_selector_widget->show(); + + _region.set_channel_selector_scoped_note(this); } else { hide_channel_selector(); } @@ -183,8 +191,14 @@ CanvasNoteEvent::set_selected(bool selected) if (_selected) { set_outline_color(calculate_outline(ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get())); + + if(_region.channel_selector_scoped_note() != 0){ + _region.channel_selector_scoped_note()->hide_channel_selector(); + _region.set_channel_selector_scoped_note(0); + } } else { set_outline_color(calculate_outline(base_color())); + hide_channel_selector(); } } @@ -306,7 +320,7 @@ CanvasNoteEvent::on_event(GdkEvent* ev) case GDK_BUTTON_PRESS: set_mouse_fractions (ev); - if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) { + if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state) && _selected) { show_channel_selector(); return true; } diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 3cf59eed2c..fd2d629a09 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -94,6 +94,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _channel_selection_scoped_note (0) , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) @@ -127,6 +128,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _channel_selection_scoped_note (0) , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) @@ -158,6 +160,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other) , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _channel_selection_scoped_note (0) , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) @@ -191,6 +194,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M , _step_edit_cursor (0) , _step_edit_cursor_width (1.0) , _step_edit_cursor_position (0.0) + , _channel_selection_scoped_note (0) , _temporary_note_group (0) , _mouse_state(None) , _pressed_button(0) @@ -378,11 +382,14 @@ MidiRegionView::button_press (GdkEventButton* ev) { _last_x = ev->x; _last_y = ev->y; + group->w2i (_last_x, _last_y); - if (_mouse_state != SelectTouchDragging && ev->button == 1) { + if (_mouse_state != SelectTouchDragging) { + _pressed_button = ev->button; _mouse_state = Pressed; + return true; } @@ -399,61 +406,88 @@ MidiRegionView::button_release (GdkEventButton* ev) event_x = ev->x; event_y = ev->y; + group->w2i(event_x, event_y); group->ungrab(ev->time); - event_frame = trackview.editor().pixel_to_frame(event_x); - - if (ev->button == 3) { - return false; - } else if (_pressed_button != 1) { - return false; - } + + event_frame = trackview.editor().pixel_to_frame(event_x); switch (_mouse_state) { - case Pressed: // Clicked + case Pressed: // Clicked + switch (trackview.editor().current_mouse_mode()) { case MouseObject: case MouseTimeFX: + { clear_selection(); - maybe_select_by_position (ev, event_x, event_y); - break; + + if (Keyboard::is_insert_note_event(ev)){ + + double event_x, event_y; + + event_x = ev->x; + event_y = ev->y; + group->w2i(event_x, event_y); + bool success; + Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x)); + + if (!success) { + beats = 1; + } + + create_note_at (event_x, event_y, beats, true); + } + + break; + } case MouseRange: { bool success; Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x)); - if (!success) { + + if (!success) { beats = 1; } + create_note_at (event_x, event_y, beats, true); - break; + + break; } default: break; } + _mouse_state = None; break; + case SelectRectDragging: // Select drag done + _mouse_state = None; delete _drag_rect; _drag_rect = 0; break; case AddDragging: // Add drag done + _mouse_state = None; - if (_drag_rect->property_x2() > _drag_rect->property_x1() + 2) { - const double x = _drag_rect->property_x1(); - const double length = trackview.editor().pixel_to_frame - (_drag_rect->property_x2() - _drag_rect->property_x1()); + + if (Keyboard::is_insert_note_event(ev) || trackview.editor().current_mouse_mode() == MouseRange){ + + if (_drag_rect->property_x2() > _drag_rect->property_x1() + 2) { + + const double x = _drag_rect->property_x1(); + const double length = trackview.editor().pixel_to_frame (_drag_rect->property_x2() - _drag_rect->property_x1()); - create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), true); + create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), true); + } } delete _drag_rect; _drag_rect = 0; create_ghost_note (ev->x, ev->y); - + default: break; } @@ -474,10 +508,29 @@ MidiRegionView::motion (GdkEventMotion* ev) // convert event_x to global frame event_frame = trackview.editor().pixel_to_frame(event_x) + _region->position(); trackview.editor().snap_to(event_frame); - // convert event_frame back to local coordinates relative to position + + // convert event_frame back to local coordinates relative to position event_frame -= _region->position(); - if (_ghost_note) { + if (!_ghost_note && trackview.editor().current_mouse_mode() != MouseRange + && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()) + && _mouse_state != AddDragging){ + + create_ghost_note (ev->x, ev->y); + } + else if (_ghost_note && trackview.editor().current_mouse_mode() != MouseRange + && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())){ + + update_ghost_note (ev->x, ev->y); + } + else if (_ghost_note && trackview.editor().current_mouse_mode() != MouseRange){ + + delete _ghost_note; + _ghost_note = 0; + + trackview.editor().hide_verbose_canvas_cursor (); + } + else if (_ghost_note && trackview.editor().current_mouse_mode() == MouseRange) { update_ghost_note (ev->x, ev->y); } @@ -489,16 +542,19 @@ MidiRegionView::motion (GdkEventMotion* ev) switch (_mouse_state) { case Pressed: // Maybe start a drag, if we've moved a bit - + if (fabs (event_x - _last_x) < 1 && fabs (event_y - _last_y) < 1) { /* no appreciable movement since the button was pressed */ return false; } // Select drag start - if (_pressed_button == 1 && trackview.editor().current_mouse_mode() == MouseObject) { - group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, + if (_pressed_button == 1 && trackview.editor().current_mouse_mode() == MouseObject + && !Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) { + + group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->time); + _last_x = event_x; _last_y = event_y; _drag_start_x = event_x; @@ -526,6 +582,7 @@ MidiRegionView::motion (GdkEventMotion* ev) group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->time); + _last_x = event_x; _last_y = event_y; _drag_start_x = event_x; @@ -544,6 +601,15 @@ MidiRegionView::motion (GdkEventMotion* ev) _drag_rect->property_fill_color_rgba() = 0xFFFFFF66; _mouse_state = AddDragging; + + if (_ghost_note){ + + delete _ghost_note; + _ghost_note = 0; + + trackview.editor().hide_verbose_canvas_cursor (); + } + return true; } @@ -551,6 +617,7 @@ MidiRegionView::motion (GdkEventMotion* ev) case SelectRectDragging: // Select drag motion case AddDragging: // Add note drag motion + if (ev->is_hint) { int t_x; int t_y; @@ -560,23 +627,30 @@ MidiRegionView::motion (GdkEventMotion* ev) event_y = t_y; } - if (_mouse_state == AddDragging) + if (_mouse_state == AddDragging){ event_x = trackview.editor().frame_to_pixel(event_frame); + } if (_drag_rect) { - if (event_x > _drag_start_x) + + if (event_x > _drag_start_x){ _drag_rect->property_x2() = event_x; - else + } + else { _drag_rect->property_x1() = event_x; + } } if (_drag_rect && _mouse_state == SelectRectDragging) { - if (event_y > _drag_start_y) + + if (event_y > _drag_start_y){ _drag_rect->property_y2() = event_y; - else + } + else { _drag_rect->property_y1() = event_y; + } - update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y); + update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y); } _last_x = event_x; @@ -1304,7 +1378,9 @@ MidiRegionView::resolve_note(uint8_t note, double end_time) } if (_active_notes && _active_notes[note]) { - const framepos_t end_time_frames = beats_to_frames(end_time) - _region->start(); + + const framepos_t end_time_frames = beats_to_frames(end_time); + _active_notes[note]->property_x2() = trackview.editor().frame_to_pixel(end_time_frames); _active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges _active_notes[note] = 0; @@ -1400,11 +1476,13 @@ MidiRegionView::update_note (CanvasNote* ev) ev->property_x1() = x; ev->property_y1() = y1; + if (note->length() > 0) { ev->property_x2() = note_endpixel; } else { ev->property_x2() = trackview.editor().frame_to_pixel(_region->length()); } + ev->property_y2() = y1 + floor(midi_stream_view()->note_height()); if (note->length() == 0) { @@ -1457,6 +1535,8 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible) assert(note->time() >= 0); assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive); + //ArdourCanvas::Group* const group = (ArdourCanvas::Group*) get_canvas_group(); + if (midi_view()->note_mode() == Sustained) { CanvasNote* ev_rect = new CanvasNote(*this, *_note_group, note); @@ -1495,6 +1575,7 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible) if (_marked_for_velocity.find(note) != _marked_for_velocity.end()) { event->show_velocity(); } + event->on_channel_selection_change(_last_channel_selection); _events.push_back(event); @@ -1504,6 +1585,11 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible) event->hide (); } } + + MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview); + MidiStreamView* const view = mtv->midi_view(); + + view->update_note_range(note->note()); } void @@ -1520,6 +1606,11 @@ MidiRegionView::step_add_note (uint8_t channel, uint8_t number, uint8_t velocity if (end_frame > region_end) { _region->set_length (end_frame - _region->position(), this); } + + MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview); + MidiStreamView* const view = mtv->midi_view(); + + view->update_note_range(new_note->note()); _marked_for_selection.clear (); clear_selection (); @@ -3025,6 +3116,7 @@ MidiRegionView::update_ghost_note (double x, double y) bool success; Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, f); + if (!success) { beats = 1; } @@ -3090,8 +3182,6 @@ MidiRegionView::maybe_select_by_position (GdkEventButton* ev, double /*x*/, doub double note = midi_stream_view()->y_to_note(y); Events e; MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview); - - cerr << "Selecting by position\n"; uint16_t chn_mask = mtv->channel_selector().get_selected_channels(); diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 42b544b97d..846b1651a1 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -274,6 +274,9 @@ class MidiRegionView : public RegionView void selection_as_notelist (Notes& selected, bool allow_all_if_none_selected = false); void enable_display (bool); + + void set_channel_selector_scoped_note(ArdourCanvas::CanvasNoteEvent* note){ _channel_selection_scoped_note = note; } + ArdourCanvas::CanvasNoteEvent* channel_selector_scoped_note(){ return _channel_selection_scoped_note; } void trim_front_starting (); void trim_front_ending (); @@ -369,6 +372,8 @@ class MidiRegionView : public RegionView ArdourCanvas::SimpleRect* _step_edit_cursor; Evoral::MusicalTime _step_edit_cursor_width; Evoral::MusicalTime _step_edit_cursor_position; + ArdourCanvas::CanvasNoteEvent* _channel_selection_scoped_note; + /** A group used to temporarily reparent _note_group to during start trims, so * that the notes don't move with the parent region view. diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index c1d8f10156..0c3d4f2562 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -260,7 +260,10 @@ public: _delete_button_adjustment (3, 1, 12), _delete_button_spin (_delete_button_adjustment), _edit_button_adjustment (3, 1, 5), - _edit_button_spin (_edit_button_adjustment) + _edit_button_spin (_edit_button_adjustment), + _insert_note_button_adjustment (3, 1, 5), + _insert_note_button_spin (_insert_note_button_adjustment) + { /* internationalize and prepare for use with combos */ @@ -327,6 +330,35 @@ public: _delete_button_adjustment.set_value (Keyboard::delete_button()); _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed)); + + set_popdown_strings (_insert_note_modifier_combo, dumb); + _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen)); + + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) { + _insert_note_modifier_combo.set_active_text (_(modifiers[x].name)); + break; + } + } + + l = manage (new Label (_("Insert note using:"))); + l->set_name ("OptionsLabel"); + l->set_alignment (0, 0.5); + + t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL); + t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL); + + l = manage (new Label (_("+ button"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL); + t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL); + + _insert_note_button_spin.set_name ("OptionsEntry"); + _insert_note_button_adjustment.set_value (Keyboard::insert_note_button()); + _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed)); + + set_popdown_strings (_snap_modifier_combo, dumb); _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen)); @@ -341,8 +373,8 @@ public: l->set_name ("OptionsLabel"); l->set_alignment (0, 0.5); - t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL); - t->attach (_snap_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL); + t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL); + t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL); vector<string> strs; @@ -358,8 +390,8 @@ public: l->set_name ("OptionsLabel"); l->set_alignment (0, 0.5); - t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL); - t->attach (_keyboard_layout_selector, 1, 2, 3, 4, FILL | EXPAND, FILL); + t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL); + t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL); _box->pack_start (*t, false, false); } @@ -415,6 +447,18 @@ private: } } + void insert_note_modifier_chosen () + { + string const txt = _insert_note_modifier_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + Keyboard::set_insert_note_modifier (modifiers[i].modifier); + break; + } + } + } + void snap_modifier_chosen () { string const txt = _snap_modifier_combo.get_active_text(); @@ -437,14 +481,23 @@ private: Keyboard::set_edit_button (_edit_button_spin.get_value_as_int()); } + void insert_note_button_changed () + { + Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int()); + } + ComboBoxText _keyboard_layout_selector; ComboBoxText _edit_modifier_combo; ComboBoxText _delete_modifier_combo; + ComboBoxText _insert_note_modifier_combo; ComboBoxText _snap_modifier_combo; Adjustment _delete_button_adjustment; SpinButton _delete_button_spin; Adjustment _edit_button_adjustment; SpinButton _edit_button_spin; + Adjustment _insert_note_button_adjustment; + SpinButton _insert_note_button_spin; + }; class FontScalingOptions : public OptionEditorBox |