From: David Robillard Date: Thu, 9 Aug 2007 20:50:56 +0000 (+0000) Subject: Make MIDI tools actually do something. Sorta. Sometimes. X-Git-Tag: 3.0-alpha5~4608 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=8eded9b7bcabc08083413139ac3a89812483881f;p=ardour.git Make MIDI tools actually do something. Sorta. Sometimes. When the moon is right. Cosmic radiation may be a factor. Prayer may not be an entirely bad idea, just in case. git-svn-id: svn://localhost/ardour2/trunk@2283 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/canvas-midi-event.cc b/gtk2_ardour/canvas-midi-event.cc index 1e8e313684..625d16ffd5 100644 --- a/gtk2_ardour/canvas-midi-event.cc +++ b/gtk2_ardour/canvas-midi-event.cc @@ -73,7 +73,9 @@ CanvasMidiEvent::on_event(GdkEvent* ev) switch (ev->type) { case GDK_KEY_PRESS: + cerr << "EV KEY\n"; if (_note && ev->key.keyval == GDK_Delete) { + cerr << "EV DELETE KEY\n"; selected(true); _region.start_remove_command(); _region.command_remove_note(this); @@ -92,8 +94,8 @@ CanvasMidiEvent::on_event(GdkEvent* ev) if (select_mod) { _region.note_selected(this, true); } - Keyboard::magic_widget_grab_focus(); _item->grab_focus(); + Keyboard::magic_widget_grab_focus(); _region.note_entered(this); break; @@ -123,6 +125,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev) last_y = event_y; drag_delta_x = 0; drag_delta_note = 0; + _region.note_selected(this, true); } return true; @@ -178,14 +181,20 @@ CanvasMidiEvent::on_event(GdkEvent* ev) switch (_state) { case Pressed: // Clicked - _state = None; - - if (_selected && !select_mod && _region.selection_size() > 1) - _region.unique_select(this); - else if (_selected) - _region.note_deselected(this, select_mod); - else - _region.note_selected(this, select_mod); + if (_region.midi_view()->editor.current_midi_edit_mode() == Editing::MidiEditSelect) { + _state = None; + + if (_selected && !select_mod && _region.selection_size() > 1) + _region.unique_select(this); + else if (_selected) + _region.note_deselected(this, select_mod); + else + _region.note_selected(this, select_mod); + } else if (_region.midi_view()->editor.current_midi_edit_mode() == Editing::MidiEditErase) { + _region.start_remove_command(); + _region.command_remove_note(this); + _region.apply_command(); + } return true; case Dragging: // Dropped diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 952e5b098a..bc9e38418a 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -301,6 +301,7 @@ Editor::Editor () temp_location = 0; leftmost_frame = 0; ignore_mouse_mode_toggle = false; + ignore_midi_edit_mode_toggle = false; current_stepping_trackview = 0; entered_track = 0; entered_regionview = 0; @@ -326,6 +327,7 @@ Editor::Editor () marker_drag_line = 0; set_mouse_mode (MouseObject, true); + set_midi_edit_mode (MidiEditSelect, true); frames_per_unit = 2048; /* too early to use reset_zoom () */ reset_hscrollbar_stepping (); @@ -2621,6 +2623,12 @@ Editor::setup_midi_toolbar () midi_tool_pencil_button.unset_flags (CAN_FOCUS); midi_tool_erase_button.unset_flags (CAN_FOCUS); + midi_tool_select_button.signal_toggled().connect (bind (mem_fun(*this, + &Editor::midi_edit_mode_toggled), Editing::MidiEditSelect)); + midi_tool_pencil_button.signal_toggled().connect (bind (mem_fun(*this, + &Editor::midi_edit_mode_toggled), Editing::MidiEditPencil)); + midi_tool_erase_button.signal_toggled().connect (bind (mem_fun(*this, + &Editor::midi_edit_mode_toggled), Editing::MidiEditErase)); /* Pack everything in... */ diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index cae4da5a04..685d56db70 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1388,8 +1388,8 @@ class Editor : public PublicEditor Gtk::ToggleButton midi_tool_pencil_button; Gtk::ToggleButton midi_tool_erase_button; GroupedButtons *midi_tool_button_set; - //void midi_tool_toggled (Editing::MouseMode m); - //bool ignore_midi_tool_toggle; + void midi_edit_mode_toggled (Editing::MidiEditMode m); + bool ignore_midi_edit_mode_toggle; Gtkmm2ext::TearOff* midi_tools_tearoff; Gtk::HBox midi_toolbar_hbox; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 0423e1aab3..4ba1213d62 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -310,6 +310,38 @@ Editor::step_mouse_mode (bool next) } } +void +Editor::midi_edit_mode_toggled (MidiEditMode m) +{ + if (ignore_midi_edit_mode_toggle) { + return; + } + + switch (m) { + case MidiEditSelect: + if (midi_tool_select_button.get_active()) { + set_midi_edit_mode (m); + } + break; + + case MidiEditPencil: + if (midi_tool_pencil_button.get_active()) { + set_midi_edit_mode (m); + } + break; + + case MidiEditErase: + if (midi_tool_erase_button.get_active()) { + set_midi_edit_mode (m); + } + break; + + default: + break; + } +} + + void Editor::set_midi_edit_mode (MidiEditMode m, bool force) { @@ -325,7 +357,7 @@ Editor::set_midi_edit_mode (MidiEditMode m, bool force) instant_save (); - //ignore_midi_edit_mode_toggle = true; + ignore_midi_edit_mode_toggle = true; switch (midi_edit_mode) { case MidiEditSelect: @@ -349,7 +381,7 @@ Editor::set_midi_edit_mode (MidiEditMode m, bool force) else midi_toolbar_frame.hide(); - //ignore_midi_edit_mode_toggle = false; + ignore_midi_edit_mode_toggle = false; /*if (is_drawable()) { track_canvas.get_window()->set_cursor(*current_canvas_cursor); diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 8e90087697..c58a92e9b7 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -63,9 +63,12 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & : RegionView (parent, tv, r, spu, basic_color) , _default_note_length(0.0) , _active_notes(0) + , _note_group(new ArdourCanvas::Group(*parent)) , _delta_command(NULL) - , _command_mode(None) + , _mouse_state(None) + , _pressed_button(0) { + _note_group->raise_to_top(); } MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr r, double spu, @@ -73,9 +76,12 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView & : RegionView (parent, tv, r, spu, basic_color, visibility) , _default_note_length(0.0) , _active_notes(0) + , _note_group(new ArdourCanvas::Group(*parent)) , _delta_command(NULL) - , _command_mode(None) + , _mouse_state(None) + , _pressed_button(0) { + _note_group->raise_to_top(); } void @@ -124,39 +130,49 @@ MidiRegionView::init (Gdk::Color& basic_color, bool wfd) bool MidiRegionView::canvas_event(GdkEvent* ev) { - enum State { None, Pressed, SelectDragging, AddDragging }; - static int press_button = 0; - static State _state; + static bool delete_mod = false; + static Editing::MidiEditMode original_mode; static double drag_start_x, drag_start_y; static double last_x, last_y; double event_x, event_y; + nframes_t event_frame = 0; static ArdourCanvas::SimpleRect* drag_rect = NULL; if (trackview.editor.current_mouse_mode() != MouseNote) return false; + // Mmmm, spaghetti + switch (ev->type) { case GDK_KEY_PRESS: - if (ev->key.keyval == GDK_Delete) { + if (ev->key.keyval == GDK_Delete && !delete_mod) { + delete_mod = true; + original_mode = trackview.editor.current_midi_edit_mode(); trackview.editor.set_midi_edit_mode(MidiEditErase); start_remove_command(); + _mouse_state = EraseDragging; } break; case GDK_KEY_RELEASE: - if (_command_mode == Remove && ev->key.keyval == GDK_Delete) { - delete_selection(); - apply_command(); - trackview.editor.set_midi_edit_mode(MidiEditSelect); + if (ev->key.keyval == GDK_Delete) { + if (_mouse_state == EraseDragging) { + delete_selection(); + apply_command(); + } + if (delete_mod) { + trackview.editor.set_midi_edit_mode(original_mode); + delete_mod = false; + } } break; case GDK_BUTTON_PRESS: //group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, ev->button.time); - _state = Pressed; - press_button = ev->button.button; + _mouse_state = Pressed; + _pressed_button = ev->button.button; //cerr << "PRESSED: " << press_button << endl; return true; @@ -170,11 +186,16 @@ MidiRegionView::canvas_event(GdkEvent* ev) event_x = ev->motion.x; event_y = ev->motion.y; group->w2i(event_x, event_y); + + event_frame = trackview.editor.pixel_to_frame(event_x); + trackview.editor.snap_to(event_frame); - switch (_state) { + switch (_mouse_state) { case Pressed: // Drag start - if (press_button == 1 && _command_mode != Remove) { // Select rect start + // Select rect start + if (_pressed_button == 1 && trackview.editor.current_midi_edit_mode() == MidiEditSelect) { + cerr << "SELECT START\n"; group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->motion.time); last_x = event_x; @@ -193,22 +214,21 @@ MidiRegionView::canvas_event(GdkEvent* ev) drag_rect->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiSelectRectFill.get(); - _state = SelectDragging; + _mouse_state = SelectDragging; return true; - } else if (press_button == 3) { // Add note drag start + // Add note drag start + } else if (trackview.editor.current_midi_edit_mode() == MidiEditPencil) { + cerr << "PENCIL START\n"; group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, Gdk::Cursor(Gdk::FLEUR), ev->motion.time); last_x = event_x; last_y = event_y; drag_start_x = event_x; drag_start_y = event_y; - - nframes_t event_frame = midi_view()->editor.pixel_to_frame(event_x); - midi_view()->editor.snap_to(event_frame); drag_rect = new ArdourCanvas::SimpleRect(*group); - drag_rect->property_x1() = midi_view()->editor.frame_to_pixel(event_frame); + drag_rect->property_x1() = trackview.editor.frame_to_pixel(event_frame); drag_rect->property_y1() = midi_stream_view()->note_to_y(midi_stream_view()->y_to_note(event_y)); drag_rect->property_x2() = event_x; @@ -218,8 +238,14 @@ MidiRegionView::canvas_event(GdkEvent* ev) drag_rect->property_fill_color_rgba() = 0xFFFFFF66; - _state = AddDragging; + _mouse_state = AddDragging; return true; + + // Eraser drag start + } else if (trackview.editor.current_midi_edit_mode() == MidiEditErase) { + cerr << "ERASE DRAGGING\n"; + _mouse_state = EraseDragging; + return false; // ? } break; @@ -235,16 +261,13 @@ MidiRegionView::canvas_event(GdkEvent* ev) event_y = t_y; } - if (_state == AddDragging) { - nframes_t event_frame = midi_view()->editor.pixel_to_frame(event_x); - midi_view()->editor.snap_to(event_frame); - event_x = midi_view()->editor.frame_to_pixel(event_frame); - } + if (_mouse_state == AddDragging) + event_x = trackview.editor.frame_to_pixel(event_frame); if (drag_rect) drag_rect->property_x2() = event_x; - if (drag_rect && _state == SelectDragging) { + if (drag_rect && _mouse_state == SelectDragging) { drag_rect->property_y2() = event_y; update_drag_selection(drag_start_x, event_x, drag_start_y, event_y); @@ -253,9 +276,11 @@ MidiRegionView::canvas_event(GdkEvent* ev) last_x = event_x; last_y = event_y; + case EraseDragging: return true; + default: - _state = None; + _mouse_state = None; break; } break; @@ -265,25 +290,30 @@ MidiRegionView::canvas_event(GdkEvent* ev) event_y = ev->motion.y; group->w2i(event_x, event_y); group->ungrab(ev->button.time); - switch (_state) { + event_frame = trackview.editor.pixel_to_frame(event_x); + + switch (_mouse_state) { case Pressed: // Clicked - if (ev->button.button == 1) { + switch (trackview.editor.current_midi_edit_mode()) { + case MidiEditSelect: clear_selection(); - } else if (ev->button.button == 3) { - nframes_t event_frame = midi_view()->editor.pixel_to_frame(event_x); - midi_view()->editor.snap_to(event_frame); - event_x = midi_view()->editor.frame_to_pixel(event_frame); + break; + case MidiEditPencil: + trackview.editor.snap_to(event_frame); + event_x = trackview.editor.frame_to_pixel(event_frame); create_note_at(event_x, event_y, _default_note_length); + default: + break; } - _state = None; + _mouse_state = None; return true; case SelectDragging: // Select drag done - _state = None; + _mouse_state = None; delete drag_rect; drag_rect = NULL; return true; case AddDragging: // Add drag done - _state = None; + _mouse_state = None; if (drag_rect->property_x2() > drag_rect->property_x1() + 2) { create_note_at(drag_rect->property_x1(), drag_rect->property_y1(), trackview.editor.pixel_to_frame( @@ -483,7 +513,8 @@ MidiRegionView::add_event (const MidiEvent& ev) } printf("\n\n");*/ - ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); + //ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group(); + ArdourCanvas::Group* const group = _note_group; if (midi_view()->note_mode() == Sustained) { if ((ev.buffer()[0] & 0xF0) == MIDI_CMD_NOTE_ON) { @@ -666,6 +697,7 @@ MidiRegionView::update_drag_selection(double last_x, double x, double last_y, do void MidiRegionView::move_selection(double dx, double dy) { + cerr << "MOVE SELECTION: " << dx << ", " << dy << endl; for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) (*i)->item()->move(dx, dy); } diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 38d61703fa..fb3e4d3449 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -89,13 +89,11 @@ class MidiRegionView : public RegionView /* This stuff is a bit boilerplatey ATM. Work in progress. */ inline void start_remove_command() { - _command_mode = Remove; if (!_delta_command) _delta_command = _model->new_delta_command(); } inline void start_delta_command() { - _command_mode = Delta; if (!_delta_command) _delta_command = _model->new_delta_command(); } @@ -114,7 +112,9 @@ class MidiRegionView : public RegionView } void note_entered(ArdourCanvas::CanvasMidiEvent* ev) { - if (_command_mode == Remove && _delta_command && ev->note()) { + cerr << "ENTERED, STATE = " << _mouse_state << endl; + if (_mouse_state == EraseDragging) { + start_delta_command(); ev->selected(true); _delta_command->remove(*ev->note()); } @@ -123,7 +123,6 @@ class MidiRegionView : public RegionView void abort_command() { delete _delta_command; _delta_command = NULL; - _command_mode = None; clear_selection(); } @@ -132,7 +131,6 @@ class MidiRegionView : public RegionView _model->apply_command(_delta_command); _delta_command = NULL; } - _command_mode = None; midi_view()->midi_track()->diskstream()->playlist_modified(); } @@ -182,13 +180,15 @@ class MidiRegionView : public RegionView boost::shared_ptr _model; std::vector _events; ArdourCanvas::CanvasNote** _active_notes; + ArdourCanvas::Group* _note_group; ARDOUR::MidiModel::DeltaCommand* _delta_command; + + enum MouseState { None, Pressed, SelectDragging, AddDragging, EraseDragging }; + MouseState _mouse_state; + int _pressed_button; typedef std::set Selection; Selection _selection; - - enum CommandMode { None, Remove, Delta }; - CommandMode _command_mode; }; #endif /* __gtk_ardour_midi_region_view_h__ */