summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-12-29 16:34:51 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-12-29 16:34:51 +0000
commitd16bb0b8bc007e805b1c3b386d3595ba0e69938a (patch)
treef3fbd3c5b0e2c6a351fc97f7bd030f02a1fef338
parentb690cac96178810ea2f73fdce7d2403a246a8f03 (diff)
rest of lincoln's MIDI note edit via click outside of MIDI edit mode patch
git-svn-id: svn://localhost/ardour2/branches/3.0@8366 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/canvas-note-event.cc16
-rw-r--r--gtk2_ardour/midi_region_view.cc156
-rw-r--r--gtk2_ardour/midi_region_view.h5
-rw-r--r--gtk2_ardour/rc_option_editor.cc63
4 files changed, 201 insertions, 39 deletions
diff --git a/gtk2_ardour/canvas-note-event.cc b/gtk2_ardour/canvas-note-event.cc
index 1aa5ddda1b..0e1afcc017 100644
--- a/gtk2_ardour/canvas-note-event.cc
+++ b/gtk2_ardour/canvas-note-event.cc
@@ -138,6 +138,12 @@ void
CanvasNoteEvent::show_channel_selector(void)
{
if (_channel_selector_widget == 0) {
+
+ if(_region.channel_selector_scoped_note() != 0){
+ _region.channel_selector_scoped_note()->hide_channel_selector();
+ _region.set_channel_selector_scoped_note(0);
+ }
+
SingleMidiChannelSelector* _channel_selector = new SingleMidiChannelSelector(_note->channel());
_channel_selector->show_all();
_channel_selector->channel_selected.connect(
@@ -156,6 +162,8 @@ CanvasNoteEvent::show_channel_selector(void)
_channel_selector_widget->property_width() = 100;
_channel_selector_widget->raise_to_top();
_channel_selector_widget->show();
+
+ _region.set_channel_selector_scoped_note(this);
} else {
hide_channel_selector();
}
@@ -183,8 +191,14 @@ CanvasNoteEvent::set_selected(bool selected)
if (_selected) {
set_outline_color(calculate_outline(ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get()));
+
+ if(_region.channel_selector_scoped_note() != 0){
+ _region.channel_selector_scoped_note()->hide_channel_selector();
+ _region.set_channel_selector_scoped_note(0);
+ }
} else {
set_outline_color(calculate_outline(base_color()));
+ hide_channel_selector();
}
}
@@ -306,7 +320,7 @@ CanvasNoteEvent::on_event(GdkEvent* ev)
case GDK_BUTTON_PRESS:
set_mouse_fractions (ev);
- if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state)) {
+ if (ev->button.button == 3 && Keyboard::no_modifiers_active (ev->button.state) && _selected) {
show_channel_selector();
return true;
}
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 3cf59eed2c..fd2d629a09 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -94,6 +94,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _temporary_note_group (0)
, _mouse_state(None)
, _pressed_button(0)
@@ -127,6 +128,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _temporary_note_group (0)
, _mouse_state(None)
, _pressed_button(0)
@@ -158,6 +160,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _temporary_note_group (0)
, _mouse_state(None)
, _pressed_button(0)
@@ -191,6 +194,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _temporary_note_group (0)
, _mouse_state(None)
, _pressed_button(0)
@@ -378,11 +382,14 @@ MidiRegionView::button_press (GdkEventButton* ev)
{
_last_x = ev->x;
_last_y = ev->y;
+
group->w2i (_last_x, _last_y);
- if (_mouse_state != SelectTouchDragging && ev->button == 1) {
+ if (_mouse_state != SelectTouchDragging) {
+
_pressed_button = ev->button;
_mouse_state = Pressed;
+
return true;
}
@@ -399,61 +406,88 @@ MidiRegionView::button_release (GdkEventButton* ev)
event_x = ev->x;
event_y = ev->y;
+
group->w2i(event_x, event_y);
group->ungrab(ev->time);
- event_frame = trackview.editor().pixel_to_frame(event_x);
-
- if (ev->button == 3) {
- return false;
- } else if (_pressed_button != 1) {
- return false;
- }
+
+ event_frame = trackview.editor().pixel_to_frame(event_x);
switch (_mouse_state) {
- case Pressed: // Clicked
+ case Pressed: // Clicked
+
switch (trackview.editor().current_mouse_mode()) {
case MouseObject:
case MouseTimeFX:
+ {
clear_selection();
- maybe_select_by_position (ev, event_x, event_y);
- break;
+
+ if (Keyboard::is_insert_note_event(ev)){
+
+ double event_x, event_y;
+
+ event_x = ev->x;
+ event_y = ev->y;
+ group->w2i(event_x, event_y);
+ bool success;
+ Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x));
+
+ if (!success) {
+ beats = 1;
+ }
+
+ create_note_at (event_x, event_y, beats, true);
+ }
+
+ break;
+ }
case MouseRange:
{
bool success;
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x));
- if (!success) {
+
+ if (!success) {
beats = 1;
}
+
create_note_at (event_x, event_y, beats, true);
- break;
+
+ break;
}
default:
break;
}
+
_mouse_state = None;
break;
+
case SelectRectDragging: // Select drag done
+
_mouse_state = None;
delete _drag_rect;
_drag_rect = 0;
break;
case AddDragging: // Add drag done
+
_mouse_state = None;
- if (_drag_rect->property_x2() > _drag_rect->property_x1() + 2) {
- const double x = _drag_rect->property_x1();
- const double length = trackview.editor().pixel_to_frame
- (_drag_rect->property_x2() - _drag_rect->property_x1());
+
+ if (Keyboard::is_insert_note_event(ev) || trackview.editor().current_mouse_mode() == MouseRange){
+
+ if (_drag_rect->property_x2() > _drag_rect->property_x1() + 2) {
+
+ const double x = _drag_rect->property_x1();
+ const double length = trackview.editor().pixel_to_frame (_drag_rect->property_x2() - _drag_rect->property_x1());
- create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), true);
+ create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), true);
+ }
}
delete _drag_rect;
_drag_rect = 0;
create_ghost_note (ev->x, ev->y);
-
+
default:
break;
}
@@ -474,10 +508,29 @@ MidiRegionView::motion (GdkEventMotion* ev)
// convert event_x to global frame
event_frame = trackview.editor().pixel_to_frame(event_x) + _region->position();
trackview.editor().snap_to(event_frame);
- // convert event_frame back to local coordinates relative to position
+
+ // convert event_frame back to local coordinates relative to position
event_frame -= _region->position();
- if (_ghost_note) {
+ if (!_ghost_note && trackview.editor().current_mouse_mode() != MouseRange
+ && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())
+ && _mouse_state != AddDragging){
+
+ create_ghost_note (ev->x, ev->y);
+ }
+ else if (_ghost_note && trackview.editor().current_mouse_mode() != MouseRange
+ && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())){
+
+ update_ghost_note (ev->x, ev->y);
+ }
+ else if (_ghost_note && trackview.editor().current_mouse_mode() != MouseRange){
+
+ delete _ghost_note;
+ _ghost_note = 0;
+
+ trackview.editor().hide_verbose_canvas_cursor ();
+ }
+ else if (_ghost_note && trackview.editor().current_mouse_mode() == MouseRange) {
update_ghost_note (ev->x, ev->y);
}
@@ -489,16 +542,19 @@ MidiRegionView::motion (GdkEventMotion* ev)
switch (_mouse_state) {
case Pressed: // Maybe start a drag, if we've moved a bit
-
+
if (fabs (event_x - _last_x) < 1 && fabs (event_y - _last_y) < 1) {
/* no appreciable movement since the button was pressed */
return false;
}
// Select drag start
- if (_pressed_button == 1 && trackview.editor().current_mouse_mode() == MouseObject) {
- group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+ if (_pressed_button == 1 && trackview.editor().current_mouse_mode() == MouseObject
+ && !Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
+
+ group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
Gdk::Cursor(Gdk::FLEUR), ev->time);
+
_last_x = event_x;
_last_y = event_y;
_drag_start_x = event_x;
@@ -526,6 +582,7 @@ MidiRegionView::motion (GdkEventMotion* ev)
group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
Gdk::Cursor(Gdk::FLEUR), ev->time);
+
_last_x = event_x;
_last_y = event_y;
_drag_start_x = event_x;
@@ -544,6 +601,15 @@ MidiRegionView::motion (GdkEventMotion* ev)
_drag_rect->property_fill_color_rgba() = 0xFFFFFF66;
_mouse_state = AddDragging;
+
+ if (_ghost_note){
+
+ delete _ghost_note;
+ _ghost_note = 0;
+
+ trackview.editor().hide_verbose_canvas_cursor ();
+ }
+
return true;
}
@@ -551,6 +617,7 @@ MidiRegionView::motion (GdkEventMotion* ev)
case SelectRectDragging: // Select drag motion
case AddDragging: // Add note drag motion
+
if (ev->is_hint) {
int t_x;
int t_y;
@@ -560,23 +627,30 @@ MidiRegionView::motion (GdkEventMotion* ev)
event_y = t_y;
}
- if (_mouse_state == AddDragging)
+ if (_mouse_state == AddDragging){
event_x = trackview.editor().frame_to_pixel(event_frame);
+ }
if (_drag_rect) {
- if (event_x > _drag_start_x)
+
+ if (event_x > _drag_start_x){
_drag_rect->property_x2() = event_x;
- else
+ }
+ else {
_drag_rect->property_x1() = event_x;
+ }
}
if (_drag_rect && _mouse_state == SelectRectDragging) {
- if (event_y > _drag_start_y)
+
+ if (event_y > _drag_start_y){
_drag_rect->property_y2() = event_y;
- else
+ }
+ else {
_drag_rect->property_y1() = event_y;
+ }
- update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y);
+ update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y);
}
_last_x = event_x;
@@ -1304,7 +1378,9 @@ MidiRegionView::resolve_note(uint8_t note, double end_time)
}
if (_active_notes && _active_notes[note]) {
- const framepos_t end_time_frames = beats_to_frames(end_time) - _region->start();
+
+ const framepos_t end_time_frames = beats_to_frames(end_time);
+
_active_notes[note]->property_x2() = trackview.editor().frame_to_pixel(end_time_frames);
_active_notes[note]->property_outline_what() = (guint32) 0xF; // all edges
_active_notes[note] = 0;
@@ -1400,11 +1476,13 @@ MidiRegionView::update_note (CanvasNote* ev)
ev->property_x1() = x;
ev->property_y1() = y1;
+
if (note->length() > 0) {
ev->property_x2() = note_endpixel;
} else {
ev->property_x2() = trackview.editor().frame_to_pixel(_region->length());
}
+
ev->property_y2() = y1 + floor(midi_stream_view()->note_height());
if (note->length() == 0) {
@@ -1457,6 +1535,8 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible)
assert(note->time() >= 0);
assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive);
+ //ArdourCanvas::Group* const group = (ArdourCanvas::Group*) get_canvas_group();
+
if (midi_view()->note_mode() == Sustained) {
CanvasNote* ev_rect = new CanvasNote(*this, *_note_group, note);
@@ -1495,6 +1575,7 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible)
if (_marked_for_velocity.find(note) != _marked_for_velocity.end()) {
event->show_velocity();
}
+
event->on_channel_selection_change(_last_channel_selection);
_events.push_back(event);
@@ -1504,6 +1585,11 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible)
event->hide ();
}
}
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ view->update_note_range(note->note());
}
void
@@ -1520,6 +1606,11 @@ MidiRegionView::step_add_note (uint8_t channel, uint8_t number, uint8_t velocity
if (end_frame > region_end) {
_region->set_length (end_frame - _region->position(), this);
}
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ view->update_note_range(new_note->note());
_marked_for_selection.clear ();
clear_selection ();
@@ -3025,6 +3116,7 @@ MidiRegionView::update_ghost_note (double x, double y)
bool success;
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, f);
+
if (!success) {
beats = 1;
}
@@ -3090,8 +3182,6 @@ MidiRegionView::maybe_select_by_position (GdkEventButton* ev, double /*x*/, doub
double note = midi_stream_view()->y_to_note(y);
Events e;
MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
-
- cerr << "Selecting by position\n";
uint16_t chn_mask = mtv->channel_selector().get_selected_channels();
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 42b544b97d..846b1651a1 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -274,6 +274,9 @@ class MidiRegionView : public RegionView
void selection_as_notelist (Notes& selected, bool allow_all_if_none_selected = false);
void enable_display (bool);
+
+ void set_channel_selector_scoped_note(ArdourCanvas::CanvasNoteEvent* note){ _channel_selection_scoped_note = note; }
+ ArdourCanvas::CanvasNoteEvent* channel_selector_scoped_note(){ return _channel_selection_scoped_note; }
void trim_front_starting ();
void trim_front_ending ();
@@ -369,6 +372,8 @@ class MidiRegionView : public RegionView
ArdourCanvas::SimpleRect* _step_edit_cursor;
Evoral::MusicalTime _step_edit_cursor_width;
Evoral::MusicalTime _step_edit_cursor_position;
+ ArdourCanvas::CanvasNoteEvent* _channel_selection_scoped_note;
+
/** A group used to temporarily reparent _note_group to during start trims, so
* that the notes don't move with the parent region view.
diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc
index c1d8f10156..0c3d4f2562 100644
--- a/gtk2_ardour/rc_option_editor.cc
+++ b/gtk2_ardour/rc_option_editor.cc
@@ -260,7 +260,10 @@ public:
_delete_button_adjustment (3, 1, 12),
_delete_button_spin (_delete_button_adjustment),
_edit_button_adjustment (3, 1, 5),
- _edit_button_spin (_edit_button_adjustment)
+ _edit_button_spin (_edit_button_adjustment),
+ _insert_note_button_adjustment (3, 1, 5),
+ _insert_note_button_spin (_insert_note_button_adjustment)
+
{
/* internationalize and prepare for use with combos */
@@ -327,6 +330,35 @@ public:
_delete_button_adjustment.set_value (Keyboard::delete_button());
_delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
+
+ set_popdown_strings (_insert_note_modifier_combo, dumb);
+ _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
+
+ for (int x = 0; modifiers[x].name; ++x) {
+ if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
+ _insert_note_modifier_combo.set_active_text (_(modifiers[x].name));
+ break;
+ }
+ }
+
+ l = manage (new Label (_("Insert note using:")));
+ l->set_name ("OptionsLabel");
+ l->set_alignment (0, 0.5);
+
+ t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
+ t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
+
+ l = manage (new Label (_("+ button")));
+ l->set_name ("OptionsLabel");
+
+ t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
+ t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
+
+ _insert_note_button_spin.set_name ("OptionsEntry");
+ _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
+ _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
+
+
set_popdown_strings (_snap_modifier_combo, dumb);
_snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
@@ -341,8 +373,8 @@ public:
l->set_name ("OptionsLabel");
l->set_alignment (0, 0.5);
- t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
- t->attach (_snap_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
+ t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
+ t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
vector<string> strs;
@@ -358,8 +390,8 @@ public:
l->set_name ("OptionsLabel");
l->set_alignment (0, 0.5);
- t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
- t->attach (_keyboard_layout_selector, 1, 2, 3, 4, FILL | EXPAND, FILL);
+ t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
+ t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
_box->pack_start (*t, false, false);
}
@@ -415,6 +447,18 @@ private:
}
}
+ void insert_note_modifier_chosen ()
+ {
+ string const txt = _insert_note_modifier_combo.get_active_text();
+
+ for (int i = 0; modifiers[i].name; ++i) {
+ if (txt == _(modifiers[i].name)) {
+ Keyboard::set_insert_note_modifier (modifiers[i].modifier);
+ break;
+ }
+ }
+ }
+
void snap_modifier_chosen ()
{
string const txt = _snap_modifier_combo.get_active_text();
@@ -437,14 +481,23 @@ private:
Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
}
+ void insert_note_button_changed ()
+ {
+ Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
+ }
+
ComboBoxText _keyboard_layout_selector;
ComboBoxText _edit_modifier_combo;
ComboBoxText _delete_modifier_combo;
+ ComboBoxText _insert_note_modifier_combo;
ComboBoxText _snap_modifier_combo;
Adjustment _delete_button_adjustment;
SpinButton _delete_button_spin;
Adjustment _edit_button_adjustment;
SpinButton _edit_button_spin;
+ Adjustment _insert_note_button_adjustment;
+ SpinButton _insert_note_button_spin;
+
};
class FontScalingOptions : public OptionEditorBox