View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0003492 | ardour | features | public | 2010-10-06 22:08 | 2020-04-19 20:14 |
| Reporter | lincoln | Assigned To | lincoln | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | closed | Resolution | fixed | ||
| Target Version | 3.0-beta1 | ||||
| Summary | 0003492: Ctl+Click to add notes in internal region edit mode | ||||
| Description | A3 requires you to change the edit mode in order to place new notes in a region. The attached patch adds 2 modifiers to help make the midi editing work flow quicker when in object mode: By pressing ctl+click the user can add new notes to a midi region. shift+ right click over a note will delete the note. Additive selection should not be affected by this patch. | ||||
| Tags | No tags attached. | ||||
|
2010-10-06 22:08
|
ctl-click-to-add-note-in-internal-region-edit.patch (9,417 bytes)
Index: gtk2_ardour/midi_region_view.cc
===================================================================
--- gtk2_ardour/midi_region_view.cc (revision 7877)
+++ gtk2_ardour/midi_region_view.cc (working copy)
@@ -312,8 +312,10 @@
group->w2i (_last_x, _last_y);
if (_mouse_state != SelectTouchDragging && ev->button == 1) {
+
_pressed_button = ev->button;
_mouse_state = Pressed;
+
return true;
}
@@ -330,9 +332,11 @@
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);
+
+ event_frame = trackview.editor().pixel_to_frame(event_x);
if (ev->button == 3) {
return false;
@@ -345,25 +349,50 @@
switch (trackview.editor().current_mouse_mode()) {
case MouseObject:
case MouseTimeFX:
+ {
clear_selection();
maybe_select_by_position (ev, event_x, event_y);
+
+ if (Keyboard::modifier_state_contains (ev->state, Keyboard::PrimaryModifier)){
+
+ 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;
@@ -372,6 +401,7 @@
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
@@ -405,10 +435,29 @@
// 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::PrimaryModifier) &&
+ _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::PrimaryModifier)){
+
+ 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);
}
@@ -420,15 +469,17 @@
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::PrimaryModifier)) {
+
+ group->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
Gdk::Cursor(Gdk::FLEUR), ev->time);
_last_x = event_x;
_last_y = event_y;
@@ -457,6 +508,7 @@
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;
@@ -475,6 +527,15 @@
_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;
}
@@ -482,6 +543,7 @@
case SelectRectDragging: // Select drag motion
case AddDragging: // Add note drag motion
+
if (ev->is_hint) {
int t_x;
int t_y;
@@ -491,23 +553,30 @@
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;
@@ -1287,7 +1356,9 @@
}
if (_active_notes && _active_notes[note]) {
+
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;
@@ -1383,11 +1454,13 @@
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) {
@@ -1438,7 +1511,7 @@
assert(note->time() >= 0);
assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive);
- ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
+ ArdourCanvas::Group* const group = (ArdourCanvas::Group*) get_canvas_group();
if (midi_view()->note_mode() == Sustained) {
@@ -1478,6 +1551,7 @@
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);
@@ -1487,6 +1561,11 @@
event->hide ();
}
}
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ view->update_note_range(note->note());
}
void
@@ -1503,7 +1582,12 @@
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 ();
@@ -2950,6 +3034,7 @@
bool success;
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, f);
+
if (!success) {
beats = 1;
}
|
|
2010-11-12 08:32
|
midi-region-view-edit-tweaks.patch (22,739 bytes)
Index: gtk2_ardour/canvas-note-event.cc
===================================================================
--- gtk2_ardour/canvas-note-event.cc (revision 8011)
+++ gtk2_ardour/canvas-note-event.cc (working copy)
@@ -138,6 +138,12 @@
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 @@
_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 @@
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 @@
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;
}
Index: gtk2_ardour/midi_region_view.h
===================================================================
--- gtk2_ardour/midi_region_view.h (revision 8011)
+++ gtk2_ardour/midi_region_view.h (working copy)
@@ -282,6 +282,9 @@
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; }
protected:
/** Allows derived types to specify their visibility requirements
@@ -372,6 +375,8 @@
ArdourCanvas::SimpleRect* _step_edit_cursor;
Evoral::MusicalTime _step_edit_cursor_width;
Evoral::MusicalTime _step_edit_cursor_position;
+ ArdourCanvas::CanvasNoteEvent* _channel_selection_scoped_note;
+
MouseState _mouse_state;
int _pressed_button;
Index: gtk2_ardour/rc_option_editor.cc
===================================================================
--- gtk2_ardour/rc_option_editor.cc (revision 8011)
+++ gtk2_ardour/rc_option_editor.cc (working copy)
@@ -256,8 +256,11 @@
_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 */
@@ -323,6 +326,35 @@
_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));
@@ -337,8 +369,8 @@
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;
@@ -354,8 +386,8 @@
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);
}
@@ -411,6 +443,18 @@
}
}
+ 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();
@@ -433,14 +477,23 @@
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
Index: libs/gtkmm2ext/gtkmm2ext/keyboard.h
===================================================================
--- libs/gtkmm2ext/gtkmm2ext/keyboard.h (revision 8011)
+++ libs/gtkmm2ext/gtkmm2ext/keyboard.h (working copy)
@@ -110,8 +110,14 @@
static guint delete_modifier() { return delete_mod; }
static void set_delete_modifier(guint);
+ static guint insert_note_button() { return insert_note_but; }
+ static void set_insert_note_button (guint);
+ static guint insert_note_modifier() { return insert_note_mod; }
+ static void set_insert_note_modifier(guint);
+
static bool is_edit_event (GdkEventButton*);
static bool is_delete_event (GdkEventButton*);
+ static bool is_insert_note_event (GdkEventButton*);
static bool is_context_menu_event (GdkEventButton*);
static bool is_button2_event (GdkEventButton*);
@@ -148,6 +154,8 @@
static guint edit_mod;
static guint delete_but;
static guint delete_mod;
+ static guint insert_note_but;
+ static guint insert_note_mod;
static guint snap_mod;
static guint button2_modifiers;
static Gtk::Window* current_window;
Index: libs/gtkmm2ext/keyboard.cc
===================================================================
--- libs/gtkmm2ext/keyboard.cc (revision 8011)
+++ libs/gtkmm2ext/keyboard.cc (working copy)
@@ -52,6 +52,8 @@
guint Keyboard::edit_mod = GDK_CONTROL_MASK;
guint Keyboard::delete_but = 3;
guint Keyboard::delete_mod = GDK_SHIFT_MASK;
+guint Keyboard::insert_note_but = 3;
+guint Keyboard::insert_note_mod = GDK_CONTROL_MASK;
guint Keyboard::snap_mod = GDK_MOD3_MASK;
#ifdef GTKOSX
@@ -148,6 +150,10 @@
node->add_property ("delete-modifier", buf);
snprintf (buf, sizeof (buf), "%d", snap_mod);
node->add_property ("snap-modifier", buf);
+ snprintf (buf, sizeof (buf), "%d", insert_note_but);
+ node->add_property ("insert-note-button", buf);
+ snprintf (buf, sizeof (buf), "%d", insert_note_mod);
+ node->add_property ("insert-note-modifier", buf);
return *node;
}
@@ -177,6 +183,14 @@
sscanf (prop->value().c_str(), "%d", &snap_mod);
}
+ if ((prop = node.property ("insert-note-button")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &insert_note_but);
+ }
+
+ if ((prop = node.property ("insert-note-modifier")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &insert_note_mod);
+ }
+
return 0;
}
@@ -360,6 +374,21 @@
}
void
+Keyboard::set_insert_note_button (guint but)
+{
+ insert_note_but = but;
+}
+
+void
+Keyboard::set_insert_note_modifier (guint mod)
+{
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~insert_note_mod);
+ insert_note_mod = mod;
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | insert_note_mod);
+}
+
+
+void
Keyboard::set_modifier (uint32_t newval, uint32_t& var)
{
RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~var);
@@ -384,6 +413,14 @@
}
bool
+Keyboard::is_insert_note_event (GdkEventButton *ev)
+{
+ return (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE) &&
+ (ev->button == Keyboard::insert_note_button()) &&
+ ((ev->state & RelevantModifierKeyMask) == Keyboard::insert_note_modifier());
+}
+
+bool
Keyboard::is_button2_event (GdkEventButton* ev)
{
#ifdef GTKOSX
Index: gtk2_ardour/midi_region_view.cc
===================================================================
--- gtk2_ardour/midi_region_view.cc (revision 8011)
+++ gtk2_ardour/midi_region_view.cc (working copy)
@@ -93,6 +93,7 @@
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _mouse_state(None)
, _pressed_button(0)
, _sort_needed (true)
@@ -123,6 +124,7 @@
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _mouse_state(None)
, _pressed_button(0)
, _sort_needed (true)
@@ -151,6 +153,7 @@
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _mouse_state(None)
, _pressed_button(0)
, _sort_needed (true)
@@ -181,6 +184,7 @@
, _step_edit_cursor (0)
, _step_edit_cursor_width (1.0)
, _step_edit_cursor_position (0.0)
+ , _channel_selection_scoped_note (0)
, _mouse_state(None)
, _pressed_button(0)
, _sort_needed (true)
@@ -330,11 +334,14 @@
{
_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;
}
@@ -351,61 +358,88 @@
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);
+
+ event_frame = trackview.editor().pixel_to_frame(event_x);
- if (ev->button == 3) {
- return false;
- } else if (_pressed_button != 1) {
- return false;
- }
+ switch (_mouse_state) {
+ case Pressed: // Clicked
- switch (_mouse_state) {
- case Pressed: // Clicked
switch (trackview.editor().current_mouse_mode()) {
case MouseObject:
case MouseTimeFX:
+ {
clear_selection();
- maybe_select_by_position (ev, event_x, event_y);
+
+ 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), false);
- }
-
+ create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), false);
+ }
+ }
+
delete _drag_rect;
_drag_rect = 0;
create_ghost_note (ev->x, ev->y);
-
+
default:
break;
}
@@ -426,10 +460,29 @@
// 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);
}
@@ -441,16 +494,19 @@
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;
@@ -478,6 +534,7 @@
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;
@@ -496,6 +553,15 @@
_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;
}
@@ -503,6 +569,7 @@
case SelectRectDragging: // Select drag motion
case AddDragging: // Add note drag motion
+
if (ev->is_hint) {
int t_x;
int t_y;
@@ -512,23 +579,30 @@
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;
@@ -1042,6 +1116,7 @@
Evoral::Parameter bank_select_msb(MidiCCAutomation, channel, MIDI_CTL_MSB_BANK);
boost::shared_ptr<Evoral::Control> msb_control = _model->control(bank_select_msb);
uint8_t msb = 0;
+
if (msb_control != 0) {
msb = uint8_t(floor(msb_control->get_double(true, event_time) + 0.5));
}
@@ -1050,6 +1125,7 @@
Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK);
boost::shared_ptr<Evoral::Control> lsb_control = _model->control(bank_select_lsb);
uint8_t lsb = 0;
+
if (lsb_control != 0) {
lsb = uint8_t(floor(lsb_control->get_double(true, event_time) + 0.5));
}
@@ -1302,7 +1378,9 @@
}
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;
@@ -1398,11 +1476,13 @@
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) {
@@ -1455,7 +1535,7 @@
assert(note->time() >= 0);
assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive);
- ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
+ ArdourCanvas::Group* const group = (ArdourCanvas::Group*) get_canvas_group();
if (midi_view()->note_mode() == Sustained) {
@@ -1495,6 +1575,7 @@
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 @@
event->hide ();
}
}
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ view->update_note_range(note->note());
}
void
@@ -1520,7 +1606,12 @@
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 ();
@@ -2967,6 +3058,7 @@
bool success;
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, f);
+
if (!success) {
beats = 1;
}
@@ -3032,8 +3124,6 @@
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();
|
|
|
I Attached a second version of the patch that does the following: 1. Add a 'Insert note using' option in Edit->Preferences->Keyboard 2. Allows the user to use key + modifier specified in 1. to insert new notes into a midi region without having to switch to the Draw/Edit mode. 3. Note channel selector is displayed with a 'select note and right click' sequence. Channel selector was previously directly available with a right click on the note. 4. Allow only one note to have the channel selector visible. 5. Hide a visible channel selector upon selection of a new note. 6. Auto range midi region view when a new note is added. This is nice feedback when entering notes via a midi keyboard. Can be improved by testing present range before calling for range update similar to the auto ranging in the step editor. Needs some testing to ensure that the modifier key edit keeps things working consistently. |
|
2010-12-08 12:53
|
midi-region-view-edit-tweaks-2.patch (22,761 bytes)
Index: gtk2_ardour/canvas-note-event.cc
===================================================================
--- gtk2_ardour/canvas-note-event.cc (revision 8218)
+++ gtk2_ardour/canvas-note-event.cc (working copy)
@@ -138,6 +138,12 @@
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 @@
_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 @@
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 @@
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;
}
Index: gtk2_ardour/midi_region_view.h
===================================================================
--- gtk2_ardour/midi_region_view.h (revision 8218)
+++ gtk2_ardour/midi_region_view.h (working copy)
@@ -282,6 +282,9 @@
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 ();
@@ -375,6 +378,8 @@
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.
Index: gtk2_ardour/rc_option_editor.cc
===================================================================
--- gtk2_ardour/rc_option_editor.cc (revision 8218)
+++ gtk2_ardour/rc_option_editor.cc (working copy)
@@ -260,8 +260,11 @@
_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 @@
_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 @@
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 @@
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 @@
}
}
+ 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 @@
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
Index: gtk2_ardour/midi_region_view.cc
===================================================================
--- gtk2_ardour/midi_region_view.cc (revision 8218)
+++ gtk2_ardour/midi_region_view.cc (working copy)
@@ -94,6 +94,7 @@
, _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 @@
, _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 @@
, _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 @@
, _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 @@
{
_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 @@
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);
+
+ event_frame = trackview.editor().pixel_to_frame(event_x);
- if (ev->button == 3) {
- return false;
- } else if (_pressed_button != 1) {
- return false;
- }
+ switch (_mouse_state) {
+ case Pressed: // Clicked
- switch (_mouse_state) {
- case Pressed: // Clicked
switch (trackview.editor().current_mouse_mode()) {
case MouseObject:
case MouseTimeFX:
+ {
clear_selection();
- maybe_select_by_position (ev, event_x, event_y);
+
+ 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) {
- create_note_at (x, _drag_rect->property_y1(), frames_to_beats(length), true);
+ 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);
+ }
}
delete _drag_rect;
_drag_rect = 0;
create_ghost_note (ev->x, ev->y);
-
+
default:
break;
}
@@ -474,10 +508,29 @@
// 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 @@
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 @@
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 @@
_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 @@
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 @@
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;
@@ -1090,6 +1164,7 @@
Evoral::Parameter bank_select_msb(MidiCCAutomation, channel, MIDI_CTL_MSB_BANK);
boost::shared_ptr<Evoral::Control> msb_control = _model->control(bank_select_msb);
uint8_t msb = 0;
+
if (msb_control != 0) {
msb = uint8_t(floor(msb_control->get_double(true, event_time) + 0.5));
}
@@ -1098,6 +1173,7 @@
Evoral::Parameter bank_select_lsb(MidiCCAutomation, channel, MIDI_CTL_LSB_BANK);
boost::shared_ptr<Evoral::Control> lsb_control = _model->control(bank_select_lsb);
uint8_t lsb = 0;
+
if (lsb_control != 0) {
lsb = uint8_t(floor(lsb_control->get_double(true, event_time) + 0.5));
}
@@ -1349,7 +1425,9 @@
}
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;
@@ -1445,11 +1523,13 @@
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) {
@@ -1502,6 +1582,8 @@
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);
@@ -1540,6 +1622,7 @@
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);
@@ -1549,6 +1632,11 @@
event->hide ();
}
}
+
+ MidiTimeAxisView* const mtv = dynamic_cast<MidiTimeAxisView*>(&trackview);
+ MidiStreamView* const view = mtv->midi_view();
+
+ view->update_note_range(note->note());
}
void
@@ -1565,7 +1653,12 @@
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 ();
@@ -3011,6 +3104,7 @@
bool success;
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, f);
+
if (!success) {
beats = 1;
}
@@ -3076,8 +3170,6 @@
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();
Index: libs/gtkmm2ext/gtkmm2ext/keyboard.h
===================================================================
--- libs/gtkmm2ext/gtkmm2ext/keyboard.h (revision 8218)
+++ libs/gtkmm2ext/gtkmm2ext/keyboard.h (working copy)
@@ -110,8 +110,14 @@
static guint delete_modifier() { return delete_mod; }
static void set_delete_modifier(guint);
+ static guint insert_note_button() { return insert_note_but; }
+ static void set_insert_note_button (guint);
+ static guint insert_note_modifier() { return insert_note_mod; }
+ static void set_insert_note_modifier(guint);
+
static bool is_edit_event (GdkEventButton*);
static bool is_delete_event (GdkEventButton*);
+ static bool is_insert_note_event (GdkEventButton*);
static bool is_context_menu_event (GdkEventButton*);
static bool is_button2_event (GdkEventButton*);
@@ -148,6 +154,8 @@
static guint edit_mod;
static guint delete_but;
static guint delete_mod;
+ static guint insert_note_but;
+ static guint insert_note_mod;
static guint snap_mod;
static guint button2_modifiers;
static Gtk::Window* current_window;
Index: libs/gtkmm2ext/keyboard.cc
===================================================================
--- libs/gtkmm2ext/keyboard.cc (revision 8218)
+++ libs/gtkmm2ext/keyboard.cc (working copy)
@@ -52,6 +52,8 @@
guint Keyboard::edit_mod = GDK_CONTROL_MASK;
guint Keyboard::delete_but = 3;
guint Keyboard::delete_mod = GDK_SHIFT_MASK;
+guint Keyboard::insert_note_but = 3;
+guint Keyboard::insert_note_mod = GDK_CONTROL_MASK;
guint Keyboard::snap_mod = GDK_MOD3_MASK;
#ifdef GTKOSX
@@ -148,6 +150,10 @@
node->add_property ("delete-modifier", buf);
snprintf (buf, sizeof (buf), "%d", snap_mod);
node->add_property ("snap-modifier", buf);
+ snprintf (buf, sizeof (buf), "%d", insert_note_but);
+ node->add_property ("insert-note-button", buf);
+ snprintf (buf, sizeof (buf), "%d", insert_note_mod);
+ node->add_property ("insert-note-modifier", buf);
return *node;
}
@@ -177,6 +183,14 @@
sscanf (prop->value().c_str(), "%d", &snap_mod);
}
+ if ((prop = node.property ("insert-note-button")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &insert_note_but);
+ }
+
+ if ((prop = node.property ("insert-note-modifier")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &insert_note_mod);
+ }
+
return 0;
}
@@ -360,6 +374,21 @@
}
void
+Keyboard::set_insert_note_button (guint but)
+{
+ insert_note_but = but;
+}
+
+void
+Keyboard::set_insert_note_modifier (guint mod)
+{
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~insert_note_mod);
+ insert_note_mod = mod;
+ RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask | insert_note_mod);
+}
+
+
+void
Keyboard::set_modifier (uint32_t newval, uint32_t& var)
{
RelevantModifierKeyMask = GdkModifierType (RelevantModifierKeyMask & ~var);
@@ -384,6 +413,14 @@
}
bool
+Keyboard::is_insert_note_event (GdkEventButton *ev)
+{
+ return (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_BUTTON_RELEASE) &&
+ (ev->button == Keyboard::insert_note_button()) &&
+ ((ev->state & RelevantModifierKeyMask) == Keyboard::insert_note_modifier());
+}
+
+bool
Keyboard::is_button2_event (GdkEventButton* ev)
{
#ifdef GTKOSX
|
|
|
If I have insert note set to Control + button 3, and I click & drag with Control + button 1 I appear to get a ghost note which is then not turned into a real one. |
|
|
As far as I can tell this behaviour is consistent with the A3 without this patch applied. What do you expect to see when doing Ctl+ button 1? |
|
|
This patch has been applied in SVN. |
|
|
Issue has been closed automatically, by Trigger Close Plugin. Feel free to re-open with additional information if you think the issue is not resolved. |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2010-10-06 22:08 | lincoln | New Issue | |
| 2010-10-06 22:08 | lincoln | File Added: ctl-click-to-add-note-in-internal-region-edit.patch | |
| 2010-11-12 08:32 | lincoln | File Added: midi-region-view-edit-tweaks.patch | |
| 2010-11-12 08:50 | lincoln | Note Added: 0009395 | |
| 2010-11-12 17:17 | cth103 | cost | => 0.00 |
| 2010-11-12 17:17 | cth103 | Target Version | => 3.0-beta1 |
| 2010-12-08 12:53 | lincoln | File Added: midi-region-view-edit-tweaks-2.patch | |
| 2010-12-08 13:18 | lincoln | Note Edited: 0009395 | |
| 2010-12-09 22:35 | cth103 | Note Added: 0009590 | |
| 2010-12-09 23:23 | lincoln | Note Added: 0009591 | |
| 2011-01-10 12:06 | lincoln | Note Added: 0009900 | |
| 2011-01-10 12:06 | lincoln | Status | new => resolved |
| 2011-01-10 12:06 | lincoln | Resolution | open => fixed |
| 2011-01-10 12:06 | lincoln | Assigned To | => lincoln |
| 2020-04-19 20:14 | system | Note Added: 0022246 | |
| 2020-04-19 20:14 | system | Status | resolved => closed |