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
This commit is contained in:
parent
c1b73d4a41
commit
c0e916d4da
|
@ -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>
|
||||
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue