move assignments out of assert() in editor_drag (thanks lincoln); change mouse mode...
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 17 Aug 2009 15:58:47 +0000 (15:58 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 17 Aug 2009 15:58:47 +0000 (15:58 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5539 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/canvas-note-event.cc
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
libs/ardour/session_state.cc
libs/evoral/src/Note.cpp

index 52e7ac5eef396a5caaef1cb1a5684a0444bea002..20e0880f05476c8aa793a4f4124be27670505daf 100644 (file)
@@ -224,24 +224,8 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
        static double last_x, last_y;
        double event_x, event_y, dx, dy;
        bool select_mod;
-       uint8_t d_velocity = 10;
 
        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.change_velocity(this, d_velocity, true);
-                       return true;
-               } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
-                       _region.change_velocity(this, -d_velocity, true);
-                       return true;
-               } else {
-                       return false;
-               }
-               
        case GDK_ENTER_NOTIFY:
                _region.note_entered(this);
                //_item->grab_focus();
index 1f7447ca0ed00166b0e2def9edf1f456f3ab9774..70f5f4d692b5a33a82cfc9aca8295187f642629d 100644 (file)
@@ -891,10 +891,14 @@ RegionMoveDrag::finished (GdkEvent* /*event*/, bool movement_occurred)
                        /* get the playlist where this drag started. we can't use rv->region()->playlist()
                           because we may have copied the region and it has not been attached to a playlist.
                        */
+                       
+                       source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
+                       ds = source_tv->get_diskstream();
+                       from_playlist = ds->playlist();
 
-                       assert ((source_tv = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view())));
-                       assert ((ds = source_tv->get_diskstream()));
-                       assert ((from_playlist = ds->playlist()));
+                       assert (source_tv);
+                       assert (ds);
+                       assert (from_playlist);
 
                        /* moved to a different audio track, without copying */
 
index 02c13fb2516f3bfca7c29b93e740181ef4519f33..41d14c4f1eb89797b8e70580c4ed959f736500c4 100644 (file)
@@ -2558,5 +2558,14 @@ void
 Editor::set_internal_edit (bool yn)
 {
        _internal_editing = yn;
+
+       if (yn) {
+               mouse_select_button.set_image (*(manage (new Image (::get_icon("midi_tool_select")))));
+               mouse_move_button.set_image (*(manage (new Image (::get_icon("midi_tool_pencil")))));
+       } else {
+               mouse_select_button.set_image (*(manage (new Image (::get_xpm("tool_range.xpm")))));
+               mouse_move_button.set_image (*(manage (new Image (::get_icon("tool_object")))));
+       }
+
        set_canvas_cursor ();
 }
index 4967886b7cdc7b948054665b650cd85bf4068c8b..248b2cfb9e40f3d41db9aef44e6950684dc7e428 100644 (file)
@@ -210,10 +210,27 @@ MidiRegionView::canvas_event(GdkEvent* ev)
        static double last_x, last_y;
        double event_x, event_y;
        nframes64_t event_frame = 0;
+       uint8_t d_velocity = 10;
 
        static ArdourCanvas::SimpleRect* drag_rect = NULL;
 
        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) {
+                       change_velocities (d_velocity, true);
+                       return true;
+               } else if (ev->scroll.direction == GDK_SCROLL_DOWN) {
+                       change_velocities(-d_velocity, true);
+                       return true;
+               } else {
+                       return false;
+               }
+               break;
+
        case GDK_KEY_PRESS:
                if (ev->key.keyval == GDK_Shift_L || ev->key.keyval == GDK_Control_L) {
                        _mouse_state = SelectTouchDragging;
@@ -232,6 +249,36 @@ MidiRegionView::canvas_event(GdkEvent* ev)
                } else if (ev->key.keyval == GDK_Shift_L || ev->key.keyval == GDK_Control_L) {
                        _mouse_state = None;
                        return true;
+               } else if (ev->key.keyval == GDK_Tab) {
+                       if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
+                               goto_previous_note ();
+                       } else {
+                               goto_next_note ();
+                       }
+                       return true;
+               } else if (ev->key.keyval == GDK_Up) {
+
+                       if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
+                               change_velocities (1, true);
+                       } else {
+                               transpose (true, false);
+                       }
+
+               } else if (ev->key.keyval == GDK_Down) {
+
+                       if (Keyboard::modifier_state_equals (ev->key.state, Keyboard::PrimaryModifier)) {
+                               change_velocities (-1, true);
+                       } else {
+                               transpose (false, false);
+                       }
+               } else if (ev->key.keyval == GDK_Left) {
+
+                       nudge_notes (-1.0);
+
+               } else if (ev->key.keyval == GDK_Right) {
+
+                       nudge_notes (1.0);
+
                }
                return false;
 
@@ -468,7 +515,6 @@ MidiRegionView::clear_events()
 void
 MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
 {
-       cerr << "MRV: display mode, enable = " << _enable_display << endl;
        _model = model;
        content_connection.disconnect ();
        content_connection = _model->ContentsChanged.connect(sigc::mem_fun(this, &MidiRegionView::redisplay_model));
@@ -542,7 +588,6 @@ MidiRegionView::abort_command()
 void
 MidiRegionView::redisplay_model()
 {
-       cerr << "MRV: display mode, active notes = " << _active_notes << endl;
        // Don't redisplay the model if we're currently recording and displaying that
        if (_active_notes) {
                return;
@@ -1569,6 +1614,46 @@ MidiRegionView::change_note_velocity(CanvasNoteEvent* event, int8_t velocity, bo
        command_add_note(copy, event->selected(), true);
 }
 
+void
+MidiRegionView::change_note_note (CanvasNoteEvent* event, int8_t note, bool relative)
+{
+       const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get())));
+
+       if (relative) {
+               uint8_t new_note = copy->note() + note;
+               clamp_to_0_127(new_note);
+               copy->set_note(new_note);
+       } else {
+               copy->set_note(note);                   
+       }
+
+       command_remove_note(event);
+       command_add_note(copy, event->selected(), false);
+}
+
+void
+MidiRegionView::change_note_time (CanvasNoteEvent* event, MidiModel::TimeType delta, bool relative)
+{
+       const boost::shared_ptr<NoteType> copy(new NoteType(*(event->note().get())));
+
+       if (relative) {
+               if (delta < 0.0) {
+                       if (copy->time() < -delta) {
+                               copy->set_time (0);
+                       } else {
+                               copy->set_time (copy->time() + delta);
+                       } 
+               } else {
+                       copy->set_time (copy->time() + delta);
+               }
+       } else {
+               copy->set_time (delta);
+       }
+
+       command_remove_note(event);
+       command_add_note(copy, event->selected(), false);
+}
+
 void
 MidiRegionView::change_velocity(CanvasNoteEvent* ev, int8_t velocity, bool relative)
 {
@@ -1588,6 +1673,66 @@ MidiRegionView::change_velocity(CanvasNoteEvent* ev, int8_t velocity, bool relat
        apply_command();
 }
 
+
+void
+MidiRegionView::change_velocities (int8_t velocity, bool relative)
+{
+       start_delta_command(_("change velocities"));
+       
+       for (Selection::iterator i = _selection.begin(); i != _selection.end();) {
+               Selection::iterator next = i;
+               ++next;
+               change_note_velocity (*i, velocity, relative);
+               i = next;
+       }
+       
+       apply_command();
+}
+
+
+void
+MidiRegionView::transpose (bool up, bool fine)
+{
+       int8_t delta;
+       
+       if (fine) {
+               delta = 1;
+       } else {
+               delta = 12;
+       }
+
+       if (!up) {
+               delta = -delta;
+       }
+
+       start_delta_command (_("transpose"));
+
+       for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
+               Selection::iterator next = i;
+               ++next;
+               change_note_note (*i, delta, true);
+               i = next;
+       }
+
+       apply_command ();
+}
+
+void
+MidiRegionView::nudge_notes (MidiModel::TimeType delta)
+{
+       start_delta_command (_("nudge"));
+
+       for (Selection::iterator i = _selection.begin(); i != _selection.end(); ) {
+               Selection::iterator next = i;
+               ++next;
+               change_note_time (*i, delta, true);
+               i = next;
+       }
+
+       apply_command ();
+}
+
+
 void
 MidiRegionView::change_channel(uint8_t channel)
 {
@@ -1752,6 +1897,7 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
                        copied_note->set_time (paste_pos_beats + copied_note->time() - beat_delta);
 
                        /* make all newly added notes selected */
+                       cerr << "\tadd @ " << copied_note->time() << endl;
 
                        command_add_note (copied_note, true);
                        end_point = copied_note->end_time();
@@ -1762,14 +1908,51 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
 
        /* if we pasted past the current end of the region, extend the region */
 
-       nframes64_t end_frame = beats_to_frames (end_point);
+       nframes64_t end_frame = _region->position() + beats_to_frames (end_point);
        nframes64_t region_end = _region->position() + _region->length() - 1;
 
+       cerr << "\tEnd frame = " << end_frame << " from " << end_point << " region end = " << region_end << endl;
+
        if (end_frame > region_end) {
+
+               trackview.session().begin_reversible_command (_("paste"));
+
                XMLNode& before (_region->get_state());
                _region->set_length (end_frame, this);
+               cerr << "\textended to " << end_frame << endl;
                trackview.session().add_command (new MementoCommand<Region>(*_region, &before, &_region->get_state()));
        }
        
        apply_command ();
 }
+
+void
+MidiRegionView::goto_next_note ()
+{
+       nframes64_t pos = trackview.session().transport_frame();
+
+       for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
+               nframes64_t npos = _region->position() + beats_to_frames ((*i)->note()->time());
+
+               if (npos >= pos && !(*i)->selected()) {
+                       unique_select (*i);
+                       trackview.session().request_locate (npos);
+                       return;
+               }
+       }
+}
+
+void
+MidiRegionView::goto_previous_note ()
+{
+       nframes64_t pos = trackview.session().transport_frame();
+
+       for (Events::reverse_iterator i = _events.rbegin(); i != _events.rend(); ++i) {
+               nframes64_t npos = _region->position() + beats_to_frames ((*i)->note()->time());
+               if (npos <= pos && !(*i)->selected()) {
+                       unique_select (*i);
+                       trackview.session().request_locate (npos);
+                       return;
+               }
+       }
+}
index d759b7c411f59c7840993011d3c2b17fcccae2f7..83cbbc1d7791c41983f6b063024c7deb657cec14 100644 (file)
@@ -260,7 +260,13 @@ class MidiRegionView : public RegionView
 
        /** Return the current selection as a MidiModel or null if there is no selection */
        ARDOUR::MidiModel* selection_as_model () const;
-       
+
+       void goto_previous_note ();
+       void goto_next_note ();
+       void change_velocities (int8_t velocity, bool relative);
+       void transpose (bool up, bool fine);
+       void nudge_notes (ARDOUR::MidiModel::TimeType delta);
+
   protected:
        /** Allows derived types to specify their visibility requirements
         * to the TimeAxisViewItem parent class.
@@ -300,6 +306,8 @@ class MidiRegionView : public RegionView
        void midi_patch_settings_changed(std::string model, std::string custom_device_mode);
        
        void change_note_velocity(ArdourCanvas::CanvasNoteEvent* ev, int8_t vel, bool relative=false);
+       void change_note_note(ArdourCanvas::CanvasNoteEvent* ev, int8_t note, bool relative=false);
+       void change_note_time(ArdourCanvas::CanvasNoteEvent* ev, ARDOUR::MidiModel::TimeType, bool relative=false);
 
        void clear_selection_except(ArdourCanvas::CanvasNoteEvent* ev);
        void clear_selection() { clear_selection_except(NULL); }
index 32ef8f58c5cd5298edad65099c8c6250a2a97cbc..c782882c0f737a0ac2cd1e98cccf7fa9bf5205ca 100644 (file)
@@ -2151,10 +2151,12 @@ Session::begin_reversible_command(const string& name)
 {
        UndoTransaction* trans = new UndoTransaction();
        trans->set_name(name);
+
        if (!_current_trans.empty()) {
-               _current_trans.top()->add_command(trans);
+               _current_trans.top()->add_command (trans);
+       } else {
+               _current_trans.push(trans);
        }
-       _current_trans.push(trans);
 }
 
 void
index 51aee00958a77010979db437511b35a50774b7e1..d86f7b894824d866c4440871d0fe00435b8d02e2 100644 (file)
@@ -39,7 +39,7 @@ Note<Time>::Note(uint8_t chan, Time t, Time l, uint8_t n, uint8_t v)
        _off_event.buffer()[2] = 0x40;
        
        assert(time() == t);
-       assert(length() - l <= std::numeric_limits<Time>::epsilon());
+       assert(length() - l <= 1.0/1920.0); /* acceptable tolerance is 1/ppqn. Nice if there was no magic number here */
        assert(note() == n);
        assert(velocity() == v);
        assert(_on_event.channel() == _off_event.channel());