diff options
author | David Robillard <d@drobilla.net> | 2007-08-05 00:33:14 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-08-05 00:33:14 +0000 |
commit | c0e916d4dacf544e06317862ebca5d3707f6d269 (patch) | |
tree | 268ffa15285f2534c141035ba92c2c480e8428db | |
parent | c1b73d4a41390baed56b4af352f427fde7a2826b (diff) |
Note selection via clicking (including multi-note selection via ctrl/shift clicking).
git-svn-id: svn://localhost/ardour2/trunk@2245 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/ardour2_ui_default.conf | 18 | ||||
-rw-r--r-- | gtk2_ardour/canvas-hit.h | 7 | ||||
-rw-r--r-- | gtk2_ardour/canvas-midi-event.cc | 50 | ||||
-rw-r--r-- | gtk2_ardour/canvas-midi-event.h | 9 | ||||
-rw-r--r-- | gtk2_ardour/canvas-note.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.cc | 43 | ||||
-rw-r--r-- | gtk2_ardour/midi_region_view.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/midi_util.h | 8 |
8 files changed, 120 insertions, 37 deletions
diff --git a/gtk2_ardour/ardour2_ui_default.conf b/gtk2_ardour/ardour2_ui_default.conf index c3afaaec3f..0bad41cde6 100644 --- a/gtk2_ardour/ardour2_ui_default.conf +++ b/gtk2_ardour/ardour2_ui_default.conf @@ -83,15 +83,15 @@ <Option name="TrimHandle" value="1900ff44"/> <Option name="EditCursor" value="0000ffff"/> <Option name="PlayHead" value="ff0000ff"/> - <Option name="MidiSelectRectOutline" value="ff000099"/> - <Option name="MidiSelectRectFill" value="ffdddd33"/> - <Option name="MidiNoteOutlineMin" value="44ff4466"/> - <Option name="MidiNoteOutlineMid" value="ffff4466"/> - <Option name="MidiNoteOutlineMax" value="ff4444ee"/> - <Option name="MidiNoteFillMin" value="44ee4433"/> - <Option name="MidiNoteFillMid" value="eeee4444"/> - <Option name="MidiNoteFillMax" value="dd999955"/> - <Option name="MidiNoteSelectedOutline" value="ff000099"/> + <Option name="MidiSelectRectOutline" value="5555ffff"/> + <Option name="MidiSelectRectFill" value="8888ff88"/> + <Option name="MidiNoteOutlineMin" value="22ff22b0"/> + <Option name="MidiNoteOutlineMid" value="ffff22b0"/> + <Option name="MidiNoteOutlineMax" value="ff2222b0"/> + <Option name="MidiNoteFillMin" value="33ee338a"/> + <Option name="MidiNoteFillMid" value="eeee338a"/> + <Option name="MidiNoteFillMax" value="ee33338a"/> + <Option name="MidiNoteSelectedOutline" value="5566ffee"/> </Canvas> </Ardour> diff --git a/gtk2_ardour/canvas-hit.h b/gtk2_ardour/canvas-hit.h index e3dcc452de..229d3cdd80 100644 --- a/gtk2_ardour/canvas-hit.h +++ b/gtk2_ardour/canvas-hit.h @@ -32,11 +32,8 @@ public: CanvasHit(MidiRegionView& region, Group& group, double size, const ARDOUR::MidiModel::Note* note=NULL) : Diamond(group, size), CanvasMidiEvent(region, this, note) {} - virtual void selected(bool yn) { - // Temporary hack, no reversal for now - if (yn) - property_outline_color_rgba() = 0xFF000099; - } + void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; } + void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; } bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); } }; diff --git a/gtk2_ardour/canvas-midi-event.cc b/gtk2_ardour/canvas-midi-event.cc index 63acd0fef9..7b2f993335 100644 --- a/gtk2_ardour/canvas-midi-event.cc +++ b/gtk2_ardour/canvas-midi-event.cc @@ -36,8 +36,26 @@ CanvasMidiEvent::CanvasMidiEvent(MidiRegionView& region, Item* item, const ARDOU , _item(item) , _state(None) , _note(note) + , _selected(false) { } + +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)); + set_outline_color(ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get()); + } else { + set_fill_color(note_fill_color(_note->velocity())); + set_outline_color(note_outline_color(_note->velocity())); + } + + _selected = yn; +} bool @@ -48,6 +66,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev) static double last_x, last_y; double event_x, event_y, dx, dy; nframes_t event_frame; + bool select_mod = false; if (_region.get_time_axis_view().editor.current_mouse_mode() != Editing::MouseNote) return false; @@ -67,6 +86,11 @@ CanvasMidiEvent::on_event(GdkEvent* ev) break; case GDK_ENTER_NOTIFY: + select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)); + cerr << "ENTER: " << select_mod << " - " << ev->motion.state << endl; + if (select_mod) { + _region.note_selected(this, true); + } Keyboard::magic_widget_grab_focus(); _item->grab_focus(); _region.note_entered(this); @@ -82,6 +106,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev) return true; case GDK_MOTION_NOTIFY: + select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)); event_x = ev->motion.x; event_y = ev->motion.y; //cerr << "MOTION @ " << event_x << ", " << event_y << endl; @@ -89,13 +114,15 @@ CanvasMidiEvent::on_event(GdkEvent* ev) switch (_state) { case Pressed: // Drag begin - _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, - Gdk::Cursor(Gdk::FLEUR), ev->motion.time); - _state = Dragging; - last_x = event_x; - last_y = event_y; - drag_delta_x = 0; - drag_delta_note = 0; + if (!select_mod) { + _item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, + Gdk::Cursor(Gdk::FLEUR), ev->motion.time); + _state = Dragging; + last_x = event_x; + last_y = event_y; + drag_delta_x = 0; + drag_delta_note = 0; + } return true; case Dragging: // Drag motion @@ -143,6 +170,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev) break; case GDK_BUTTON_RELEASE: + select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)); event_x = ev->button.x; event_y = ev->button.y; _item->property_parent().get_value()->w2i(event_x, event_y); @@ -150,6 +178,14 @@ 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); + return true; case Dragging: // Dropped _item->ungrab(ev->button.time); diff --git a/gtk2_ardour/canvas-midi-event.h b/gtk2_ardour/canvas-midi-event.h index 8a1454c98e..214c275bed 100644 --- a/gtk2_ardour/canvas-midi-event.h +++ b/gtk2_ardour/canvas-midi-event.h @@ -44,9 +44,13 @@ public: CanvasMidiEvent(MidiRegionView& region, Item* item, const ARDOUR::MidiModel::Note* note = NULL); virtual ~CanvasMidiEvent() {} - virtual bool on_event(GdkEvent* ev); + bool on_event(GdkEvent* ev); - virtual void selected(bool yn) = 0; + bool selected() const { return _selected; } + void selected(bool yn); + + virtual void set_outline_color(uint32_t c) = 0; + virtual void set_fill_color(uint32_t c) = 0; const ARDOUR::MidiModel::Note* note() { return _note; } @@ -57,6 +61,7 @@ protected: Item* const _item; State _state; const ARDOUR::MidiModel::Note* _note; + bool _selected; }; } // namespace Gnome diff --git a/gtk2_ardour/canvas-note.h b/gtk2_ardour/canvas-note.h index 5529c90844..cd79b6d2ff 100644 --- a/gtk2_ardour/canvas-note.h +++ b/gtk2_ardour/canvas-note.h @@ -35,15 +35,8 @@ public: { } - virtual void selected(bool yn) { - if (!_note) - return; - else if (yn) - property_outline_color_rgba() - = ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(); - else - property_outline_color_rgba() = note_outline_color(_note->velocity()); - } + void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; } + void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; } bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); } }; diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 7af8198aa8..aa032af257 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -579,4 +579,47 @@ MidiRegionView::add_note (const MidiModel::Note& note) } } +void +MidiRegionView::clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev) +{ + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) + if ((*i)->selected() && (*i) != ev) + (*i)->selected(false); + + _selection.clear(); +} + +void +MidiRegionView::unique_select(ArdourCanvas::CanvasMidiEvent* ev) +{ + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) + if ((*i) != ev) + (*i)->selected(false); + + _selection.clear(); + _selection.insert(ev); + ev->selected(true); +} + +void +MidiRegionView::note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add) +{ + if ( ! add) + clear_selection_except(ev); + + _selection.insert(ev); + ev->selected(true); +} + + +void +MidiRegionView::note_deselected(ArdourCanvas::CanvasMidiEvent* ev, bool add) +{ + if ( ! add) + clear_selection_except(ev); + + _selection.erase(ev); + ev->selected(false); +} + diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index b54707a081..fd341ffe55 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -132,6 +132,11 @@ class MidiRegionView : public RegionView _command_mode = None; } + void unique_select(ArdourCanvas::CanvasMidiEvent* ev); + void note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add); + void note_deselected(ArdourCanvas::CanvasMidiEvent* ev, bool add); + size_t selection_size() { return _selection.size(); } + protected: /* this constructor allows derived types @@ -160,6 +165,8 @@ class MidiRegionView : public RegionView bool canvas_event(GdkEvent* ev); bool note_canvas_event(GdkEvent* ev); + + void clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev); double _default_note_length; @@ -167,10 +174,12 @@ class MidiRegionView : public RegionView std::vector<ArdourCanvas::Item*> _events; ArdourCanvas::CanvasNote** _active_notes; ARDOUR::MidiModel::DeltaCommand* _delta_command; + + typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection; + Selection _selection; enum CommandMode { None, Remove, Delta }; CommandMode _command_mode; - }; #endif /* __gtk_ardour_midi_region_view_h__ */ diff --git a/gtk2_ardour/midi_util.h b/gtk2_ardour/midi_util.h index 475fbe3105..451fc55ea1 100644 --- a/gtk2_ardour/midi_util.h +++ b/gtk2_ardour/midi_util.h @@ -43,13 +43,13 @@ inline static uint32_t note_fill_color(uint8_t vel) { if (vel < 64) { return UINT_INTERPOLATE( - ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMin.get(), - ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMid.get(), + ARDOUR_UI::config()->canvasvar_MidiNoteFillMin.get(), + ARDOUR_UI::config()->canvasvar_MidiNoteFillMid.get(), (vel / (double)63.0)); } else { return UINT_INTERPOLATE( - ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMid.get(), - ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMax.get(), + ARDOUR_UI::config()->canvasvar_MidiNoteFillMid.get(), + ARDOUR_UI::config()->canvasvar_MidiNoteFillMax.get(), ((vel-64) / (double)63.0)); } } |