mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 23:05:04 +01:00
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
8 changed files with 120 additions and 37 deletions
|
|
@ -83,15 +83,15 @@
|
||||||
<Option name="TrimHandle" value="1900ff44"/>
|
<Option name="TrimHandle" value="1900ff44"/>
|
||||||
<Option name="EditCursor" value="0000ffff"/>
|
<Option name="EditCursor" value="0000ffff"/>
|
||||||
<Option name="PlayHead" value="ff0000ff"/>
|
<Option name="PlayHead" value="ff0000ff"/>
|
||||||
<Option name="MidiSelectRectOutline" value="ff000099"/>
|
<Option name="MidiSelectRectOutline" value="5555ffff"/>
|
||||||
<Option name="MidiSelectRectFill" value="ffdddd33"/>
|
<Option name="MidiSelectRectFill" value="8888ff88"/>
|
||||||
<Option name="MidiNoteOutlineMin" value="44ff4466"/>
|
<Option name="MidiNoteOutlineMin" value="22ff22b0"/>
|
||||||
<Option name="MidiNoteOutlineMid" value="ffff4466"/>
|
<Option name="MidiNoteOutlineMid" value="ffff22b0"/>
|
||||||
<Option name="MidiNoteOutlineMax" value="ff4444ee"/>
|
<Option name="MidiNoteOutlineMax" value="ff2222b0"/>
|
||||||
<Option name="MidiNoteFillMin" value="44ee4433"/>
|
<Option name="MidiNoteFillMin" value="33ee338a"/>
|
||||||
<Option name="MidiNoteFillMid" value="eeee4444"/>
|
<Option name="MidiNoteFillMid" value="eeee338a"/>
|
||||||
<Option name="MidiNoteFillMax" value="dd999955"/>
|
<Option name="MidiNoteFillMax" value="ee33338a"/>
|
||||||
<Option name="MidiNoteSelectedOutline" value="ff000099"/>
|
<Option name="MidiNoteSelectedOutline" value="5566ffee"/>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</Ardour>
|
</Ardour>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,8 @@ public:
|
||||||
CanvasHit(MidiRegionView& region, Group& group, double size, const ARDOUR::MidiModel::Note* note=NULL)
|
CanvasHit(MidiRegionView& region, Group& group, double size, const ARDOUR::MidiModel::Note* note=NULL)
|
||||||
: Diamond(group, size), CanvasMidiEvent(region, this, note) {}
|
: Diamond(group, size), CanvasMidiEvent(region, this, note) {}
|
||||||
|
|
||||||
virtual void selected(bool yn) {
|
void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; }
|
||||||
// Temporary hack, no reversal for now
|
void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; }
|
||||||
if (yn)
|
|
||||||
property_outline_color_rgba() = 0xFF000099;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
|
bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,26 @@ CanvasMidiEvent::CanvasMidiEvent(MidiRegionView& region, Item* item, const ARDOU
|
||||||
, _item(item)
|
, _item(item)
|
||||||
, _state(None)
|
, _state(None)
|
||||||
, _note(note)
|
, _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
|
bool
|
||||||
|
|
@ -48,6 +66,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
static double last_x, last_y;
|
static double last_x, last_y;
|
||||||
double event_x, event_y, dx, dy;
|
double event_x, event_y, dx, dy;
|
||||||
nframes_t event_frame;
|
nframes_t event_frame;
|
||||||
|
bool select_mod = false;
|
||||||
|
|
||||||
if (_region.get_time_axis_view().editor.current_mouse_mode() != Editing::MouseNote)
|
if (_region.get_time_axis_view().editor.current_mouse_mode() != Editing::MouseNote)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -67,6 +86,11 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_ENTER_NOTIFY:
|
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();
|
Keyboard::magic_widget_grab_focus();
|
||||||
_item->grab_focus();
|
_item->grab_focus();
|
||||||
_region.note_entered(this);
|
_region.note_entered(this);
|
||||||
|
|
@ -82,6 +106,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case GDK_MOTION_NOTIFY:
|
case GDK_MOTION_NOTIFY:
|
||||||
|
select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK));
|
||||||
event_x = ev->motion.x;
|
event_x = ev->motion.x;
|
||||||
event_y = ev->motion.y;
|
event_y = ev->motion.y;
|
||||||
//cerr << "MOTION @ " << event_x << ", " << event_y << endl;
|
//cerr << "MOTION @ " << event_x << ", " << event_y << endl;
|
||||||
|
|
@ -89,13 +114,15 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case Pressed: // Drag begin
|
case Pressed: // Drag begin
|
||||||
_item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
if (!select_mod) {
|
||||||
Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
|
_item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
|
||||||
_state = Dragging;
|
Gdk::Cursor(Gdk::FLEUR), ev->motion.time);
|
||||||
last_x = event_x;
|
_state = Dragging;
|
||||||
last_y = event_y;
|
last_x = event_x;
|
||||||
drag_delta_x = 0;
|
last_y = event_y;
|
||||||
drag_delta_note = 0;
|
drag_delta_x = 0;
|
||||||
|
drag_delta_note = 0;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Dragging: // Drag motion
|
case Dragging: // Drag motion
|
||||||
|
|
@ -143,6 +170,7 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
|
select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK));
|
||||||
event_x = ev->button.x;
|
event_x = ev->button.x;
|
||||||
event_y = ev->button.y;
|
event_y = ev->button.y;
|
||||||
_item->property_parent().get_value()->w2i(event_x, event_y);
|
_item->property_parent().get_value()->w2i(event_x, event_y);
|
||||||
|
|
@ -150,6 +178,14 @@ CanvasMidiEvent::on_event(GdkEvent* ev)
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case Pressed: // Clicked
|
case Pressed: // Clicked
|
||||||
_state = None;
|
_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;
|
return true;
|
||||||
case Dragging: // Dropped
|
case Dragging: // Dropped
|
||||||
_item->ungrab(ev->button.time);
|
_item->ungrab(ev->button.time);
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,13 @@ public:
|
||||||
CanvasMidiEvent(MidiRegionView& region, Item* item, const ARDOUR::MidiModel::Note* note = NULL);
|
CanvasMidiEvent(MidiRegionView& region, Item* item, const ARDOUR::MidiModel::Note* note = NULL);
|
||||||
virtual ~CanvasMidiEvent() {}
|
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; }
|
const ARDOUR::MidiModel::Note* note() { return _note; }
|
||||||
|
|
||||||
|
|
@ -57,6 +61,7 @@ protected:
|
||||||
Item* const _item;
|
Item* const _item;
|
||||||
State _state;
|
State _state;
|
||||||
const ARDOUR::MidiModel::Note* _note;
|
const ARDOUR::MidiModel::Note* _note;
|
||||||
|
bool _selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Gnome
|
} // namespace Gnome
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,8 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void selected(bool yn) {
|
void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; }
|
||||||
if (!_note)
|
void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; }
|
||||||
return;
|
|
||||||
else if (yn)
|
|
||||||
property_outline_color_rgba()
|
|
||||||
= ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get();
|
|
||||||
else
|
|
||||||
property_outline_color_rgba() = note_outline_color(_note->velocity());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
|
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;
|
_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:
|
protected:
|
||||||
|
|
||||||
/* this constructor allows derived types
|
/* this constructor allows derived types
|
||||||
|
|
@ -160,6 +165,8 @@ class MidiRegionView : public RegionView
|
||||||
|
|
||||||
bool canvas_event(GdkEvent* ev);
|
bool canvas_event(GdkEvent* ev);
|
||||||
bool note_canvas_event(GdkEvent* ev);
|
bool note_canvas_event(GdkEvent* ev);
|
||||||
|
|
||||||
|
void clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev);
|
||||||
|
|
||||||
double _default_note_length;
|
double _default_note_length;
|
||||||
|
|
||||||
|
|
@ -167,10 +174,12 @@ class MidiRegionView : public RegionView
|
||||||
std::vector<ArdourCanvas::Item*> _events;
|
std::vector<ArdourCanvas::Item*> _events;
|
||||||
ArdourCanvas::CanvasNote** _active_notes;
|
ArdourCanvas::CanvasNote** _active_notes;
|
||||||
ARDOUR::MidiModel::DeltaCommand* _delta_command;
|
ARDOUR::MidiModel::DeltaCommand* _delta_command;
|
||||||
|
|
||||||
|
typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection;
|
||||||
|
Selection _selection;
|
||||||
|
|
||||||
enum CommandMode { None, Remove, Delta };
|
enum CommandMode { None, Remove, Delta };
|
||||||
CommandMode _command_mode;
|
CommandMode _command_mode;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __gtk_ardour_midi_region_view_h__ */
|
#endif /* __gtk_ardour_midi_region_view_h__ */
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,13 @@ inline static uint32_t note_fill_color(uint8_t vel)
|
||||||
{
|
{
|
||||||
if (vel < 64) {
|
if (vel < 64) {
|
||||||
return UINT_INTERPOLATE(
|
return UINT_INTERPOLATE(
|
||||||
ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMin.get(),
|
ARDOUR_UI::config()->canvasvar_MidiNoteFillMin.get(),
|
||||||
ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMid.get(),
|
ARDOUR_UI::config()->canvasvar_MidiNoteFillMid.get(),
|
||||||
(vel / (double)63.0));
|
(vel / (double)63.0));
|
||||||
} else {
|
} else {
|
||||||
return UINT_INTERPOLATE(
|
return UINT_INTERPOLATE(
|
||||||
ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMid.get(),
|
ARDOUR_UI::config()->canvasvar_MidiNoteFillMid.get(),
|
||||||
ARDOUR_UI::config()->canvasvar_MidiNoteOutlineMax.get(),
|
ARDOUR_UI::config()->canvasvar_MidiNoteFillMax.get(),
|
||||||
((vel-64) / (double)63.0));
|
((vel-64) / (double)63.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue