X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fmidi_region_view.cc;h=4ef7c014bb82c53e8b6fe2984c8cd61765053f48;hb=2c72f58aa19c169752e6c09310c7d7917b63c3eb;hp=af79a4f2b8f892b9d29121f7ab1b24357bff992e;hpb=f784343e0770af311d7c5d61f48fe745936012bf;p=ardour.git diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index af79a4f2b8..4ef7c014bb 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -49,6 +49,7 @@ #include "canvas-hit.h" #include "canvas-note.h" #include "canvas_patch_change.h" +#include "debug.h" #include "editor.h" #include "ghostregion.h" #include "gui_thread.h" @@ -293,10 +294,6 @@ MidiRegionView::canvas_event(GdkEvent* ev) return false; } - /* XXX: note that until version 2.30, the GnomeCanvas did not propagate scroll events - to its items, which means that ev->type == GDK_SCROLL will never be seen - */ - switch (ev->type) { case GDK_SCROLL: return scroll (&ev->scroll); @@ -924,7 +921,7 @@ MidiRegionView::note_diff_add_change (ArdourCanvas::CanvasNoteEvent* ev, } void -MidiRegionView::apply_diff () +MidiRegionView::apply_diff (bool as_subcommand) { bool add_or_remove; @@ -939,7 +936,12 @@ MidiRegionView::apply_diff () } } - _model->apply_command(*trackview.session(), _note_diff_command); + if (as_subcommand) { + _model->apply_command_as_subcommand (*trackview.session(), _note_diff_command); + } else { + _model->apply_command (*trackview.session(), _note_diff_command); + } + _note_diff_command = 0; midi_view()->midi_track()->playlist_modified(); @@ -950,33 +952,6 @@ MidiRegionView::apply_diff () _marked_for_velocity.clear(); } -void -MidiRegionView::apply_diff_as_subcommand () -{ - bool add_or_remove; - - if (!_note_diff_command) { - return; - } - - if ((add_or_remove = _note_diff_command->adds_or_removes())) { - // Mark all selected notes for selection when model reloads - for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { - _marked_for_selection.insert((*i)->note()); - } - } - - _model->apply_command_as_subcommand(*trackview.session(), _note_diff_command); - _note_diff_command = 0; - midi_view()->midi_track()->playlist_modified(); - - if (add_or_remove) { - _marked_for_selection.clear(); - } - _marked_for_velocity.clear(); -} - - void MidiRegionView::abort_command() { @@ -1327,16 +1302,16 @@ MidiRegionView::add_ghost (TimeAxisView& tv) ghost = new MidiGhostRegion (tv, trackview, unit_position); } - ghost->set_height (); - ghost->set_duration (_region->length() / samples_per_unit); - ghosts.push_back (ghost); - for (Events::iterator i = _events.begin(); i != _events.end(); ++i) { if ((note = dynamic_cast(*i)) != 0) { ghost->add_note(note); } } + ghost->set_height (); + ghost->set_duration (_region->length() / samples_per_unit); + ghosts.push_back (ghost); + GhostRegion::CatchDeletion.connect (*this, invalidator (*this), ui_bind (&RegionView::remove_ghost, this, _1), gui_context()); return ghost; @@ -1460,8 +1435,12 @@ MidiRegionView::note_in_region_range(const boost::shared_ptr note, boo return !outside; } +/** Update a canvas note's size from its model note. + * @param ev Canvas note to update. + * @param update_ghost_regions true to update the note in any ghost regions that we have, otherwise false. + */ void -MidiRegionView::update_note (CanvasNote* ev) +MidiRegionView::update_note (CanvasNote* ev, bool update_ghost_regions) { boost::shared_ptr note = ev->note(); @@ -1504,6 +1483,15 @@ MidiRegionView::update_note (CanvasNote* ev) /* outline all edges */ ev->property_outline_what() = (guint32) 0xF; } + + if (update_ghost_regions) { + for (std::vector::iterator i = ghosts.begin(); i != ghosts.end(); ++i) { + MidiGhostRegion* gr = dynamic_cast (*i); + if (gr) { + gr->update_note (ev); + } + } + } } double @@ -2868,13 +2856,33 @@ MidiRegionView::note_mouse_position (float x_fraction, float /*y_fraction*/, boo void MidiRegionView::set_frame_color() { - if (frame) { - if (_selected && should_show_selection) { - frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(); - } else { - frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiFrameBase.get(); - } + uint32_t f; + + if (!frame) { + return; + } + + if (_selected) { + f = ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(); + } else if (high_enough_for_name) { + f= ARDOUR_UI::config()->canvasvar_MidiFrameBase.get(); + } else { + f = fill_color; } + + if (!rect_visible) { + f = UINT_RGBA_CHANGE_A (f, 0); + } + + frame->property_fill_color_rgba() = f; + + f = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get(); + + if (!rect_visible) { + f = UINT_RGBA_CHANGE_A (f, 0); + } + + frame->property_outline_color_rgba() = f; } void @@ -2962,6 +2970,7 @@ MidiRegionView::selection_as_cut_buffer () const return cb; } +/** This method handles undo */ void MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) { @@ -2969,6 +2978,10 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) return; } + DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("MIDI paste @ %1 times %2\n", pos, times)); + + trackview.session()->begin_reversible_command (_("paste")); + start_note_diff_command (_("paste")); Evoral::MusicalTime beat_delta; @@ -2981,6 +2994,12 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) beat_delta = (*mcb.notes().begin())->time() - paste_pos_beats; paste_pos_beats = 0; + DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste data spans from %1 to %2 (%3) ; paste pos beats = %4 (based on %5 - %6 ; beat delta = %7\n", + (*mcb.notes().begin())->time(), + (*mcb.notes().rbegin())->end_time(), + duration, pos, _region->position(), + paste_pos_beats, beat_delta)); + clear_selection (); for (int n = 0; n < (int) times; ++n) { @@ -3006,14 +3025,16 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) if (end_frame > region_end) { - trackview.session()->begin_reversible_command (_("paste")); + DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste extended region from %1 to %2\n", region_end, end_frame)); _region->clear_changes (); _region->set_length (end_frame, this); trackview.session()->add_command (new StatefulDiffCommand (_region)); } - apply_diff (); + apply_diff (true); + + trackview.session()->commit_reversible_command (); } struct EventNoteTimeEarlyFirstComparator { @@ -3137,7 +3158,8 @@ MidiRegionView::update_ghost_note (double x, double y) _ghost_note->note()->set_length (length); _ghost_note->note()->set_note (midi_stream_view()->y_to_note (y)); - update_note (_ghost_note); + /* the ghost note does not appear in ghost regions, so pass false in here */ + update_note (_ghost_note, false); show_verbose_canvas_cursor (_ghost_note->note ()); }