summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-08-05 00:33:14 +0000
committerDavid Robillard <d@drobilla.net>2007-08-05 00:33:14 +0000
commitc0e916d4dacf544e06317862ebca5d3707f6d269 (patch)
tree268ffa15285f2534c141035ba92c2c480e8428db
parentc1b73d4a41390baed56b4af352f427fde7a2826b (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.conf18
-rw-r--r--gtk2_ardour/canvas-hit.h7
-rw-r--r--gtk2_ardour/canvas-midi-event.cc50
-rw-r--r--gtk2_ardour/canvas-midi-event.h9
-rw-r--r--gtk2_ardour/canvas-note.h11
-rw-r--r--gtk2_ardour/midi_region_view.cc43
-rw-r--r--gtk2_ardour/midi_region_view.h11
-rw-r--r--gtk2_ardour/midi_util.h8
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));
}
}