Use a Drag class for midi note selection, so that it
gets autoscroll (#4474). git-svn-id: svn://localhost/ardour2/branches/3.0@10650 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
86d927b4dd
commit
ec90b0ceb0
@ -104,7 +104,7 @@ AutomationRegionView::canvas_event (GdkEvent* ev)
|
||||
if (ev->type == GDK_BUTTON_PRESS && e.current_mouse_mode() == Editing::MouseObject) {
|
||||
|
||||
/* XXX: icky dcast to Editor */
|
||||
e.drags()->set (new RubberbandSelectDrag (dynamic_cast<Editor*> (&e), group), ev);
|
||||
e.drags()->set (new EditorRubberbandSelectDrag (dynamic_cast<Editor*> (&e), group), ev);
|
||||
|
||||
} else if (ev->type == GDK_BUTTON_RELEASE) {
|
||||
|
||||
|
@ -2084,6 +2084,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
|
||||
friend class ControlPointDrag;
|
||||
friend class LineDrag;
|
||||
friend class RubberbandSelectDrag;
|
||||
friend class EditorRubberbandSelectDrag;
|
||||
friend class TimeFXDrag;
|
||||
friend class ScrubDrag;
|
||||
friend class SelectionDrag;
|
||||
|
@ -3100,45 +3100,51 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
|
||||
_editor->rubberband_rect->raise_to_top();
|
||||
|
||||
show_verbose_cursor_time (pf);
|
||||
|
||||
do_select_things (event, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RubberbandSelectDrag::do_select_things (GdkEvent* event, bool drag_in_progress)
|
||||
{
|
||||
framepos_t x1;
|
||||
framepos_t x2;
|
||||
|
||||
if (grab_frame() < last_pointer_frame()) {
|
||||
x1 = grab_frame ();
|
||||
x2 = last_pointer_frame ();
|
||||
} else {
|
||||
x2 = grab_frame ();
|
||||
x1 = last_pointer_frame ();
|
||||
}
|
||||
|
||||
double y1;
|
||||
double y2;
|
||||
|
||||
if (_drags->current_pointer_y() < grab_y()) {
|
||||
y1 = _drags->current_pointer_y();
|
||||
y2 = grab_y();
|
||||
} else {
|
||||
y2 = _drags->current_pointer_y();
|
||||
y1 = grab_y();
|
||||
}
|
||||
|
||||
select_things (event->button.state, x1, x2, y1, y2, drag_in_progress);
|
||||
}
|
||||
|
||||
void
|
||||
RubberbandSelectDrag::finished (GdkEvent* event, bool movement_occurred)
|
||||
{
|
||||
if (movement_occurred) {
|
||||
|
||||
motion (event, false);
|
||||
|
||||
double y1,y2;
|
||||
if (_drags->current_pointer_y() < grab_y()) {
|
||||
y1 = _drags->current_pointer_y();
|
||||
y2 = grab_y();
|
||||
} else {
|
||||
y2 = _drags->current_pointer_y();
|
||||
y1 = grab_y();
|
||||
}
|
||||
|
||||
|
||||
Selection::Operation op = ArdourKeyboard::selection_type (event->button.state);
|
||||
|
||||
_editor->begin_reversible_command (_("rubberband selection"));
|
||||
|
||||
if (grab_frame() < last_pointer_frame()) {
|
||||
_editor->select_all_within (grab_frame(), last_pointer_frame() - 1, y1, y2, _editor->track_views, op, false);
|
||||
} else {
|
||||
_editor->select_all_within (last_pointer_frame(), grab_frame() - 1, y1, y2, _editor->track_views, op, false);
|
||||
}
|
||||
|
||||
_editor->commit_reversible_command ();
|
||||
do_select_things (event, false);
|
||||
|
||||
} else {
|
||||
if (!getenv("ARDOUR_SAE")) {
|
||||
_editor->selection->clear_tracks();
|
||||
}
|
||||
_editor->selection->clear_regions();
|
||||
_editor->selection->clear_points ();
|
||||
_editor->selection->clear_lines ();
|
||||
|
||||
deselect_things ();
|
||||
|
||||
}
|
||||
|
||||
_editor->rubberband_rect->hide();
|
||||
@ -4227,3 +4233,67 @@ PatchChangeDrag::setup_pointer_frame_offset ()
|
||||
_pointer_frame_offset = raw_grab_frame() - _region_view->source_beats_to_absolute_frames (_patch_change->patch()->time());
|
||||
}
|
||||
|
||||
MidiRubberbandSelectDrag::MidiRubberbandSelectDrag (Editor* e, MidiRegionView* rv)
|
||||
: RubberbandSelectDrag (e, rv->get_canvas_frame ())
|
||||
, _region_view (rv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MidiRubberbandSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress)
|
||||
{
|
||||
framepos_t const p = _region_view->region()->position ();
|
||||
double const y = _region_view->midi_view()->y_position ();
|
||||
|
||||
x1 = max ((framepos_t) 0, x1 - p);
|
||||
x2 = max ((framepos_t) 0, x2 - p);
|
||||
y1 = max (0.0, y1 - y);
|
||||
y2 = max (0.0, y2 - y);
|
||||
|
||||
_region_view->update_drag_selection (
|
||||
_editor->frame_to_pixel (x1),
|
||||
_editor->frame_to_pixel (x2),
|
||||
y1,
|
||||
y2,
|
||||
Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier)
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
MidiRubberbandSelectDrag::deselect_things ()
|
||||
{
|
||||
/* XXX */
|
||||
}
|
||||
|
||||
EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
|
||||
: RubberbandSelectDrag (e, i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
EditorRubberbandSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress)
|
||||
{
|
||||
if (drag_in_progress) {
|
||||
/* We just want to select things at the end of the drag, not during it */
|
||||
return;
|
||||
}
|
||||
|
||||
Selection::Operation op = ArdourKeyboard::selection_type (button_state);
|
||||
|
||||
_editor->begin_reversible_command (_("rubberband selection"));
|
||||
_editor->select_all_within (x1, x2 - 1, y1, y2, _editor->track_views, op, false);
|
||||
_editor->commit_reversible_command ();
|
||||
}
|
||||
|
||||
void
|
||||
EditorRubberbandSelectDrag::deselect_things ()
|
||||
{
|
||||
if (!getenv("ARDOUR_SAE")) {
|
||||
_editor->selection->clear_tracks();
|
||||
}
|
||||
_editor->selection->clear_regions();
|
||||
_editor->selection->clear_points ();
|
||||
_editor->selection->clear_lines ();
|
||||
}
|
||||
|
@ -761,6 +761,43 @@ public:
|
||||
std::pair<ARDOUR::framecnt_t, int> move_threshold () const {
|
||||
return std::make_pair (8, 1);
|
||||
}
|
||||
|
||||
void do_select_things (GdkEvent *, bool);
|
||||
|
||||
/** Select some things within a rectangle.
|
||||
* @param button_state The button state from the GdkEvent.
|
||||
* @param x1 The left-hand side of the rectangle in session frames.
|
||||
* @param x2 The right-hand side of the rectangle in session frames.
|
||||
* @param y1 The top of the rectangle in trackview coordinates.
|
||||
* @param y2 The bottom of the rectangle in trackview coordinates.
|
||||
* @param drag_in_progress true if the drag is currently happening.
|
||||
*/
|
||||
virtual void select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) = 0;
|
||||
|
||||
virtual void deselect_things () = 0;
|
||||
};
|
||||
|
||||
/** A general editor RubberbandSelectDrag (for regions, automation points etc.) */
|
||||
class EditorRubberbandSelectDrag : public RubberbandSelectDrag
|
||||
{
|
||||
public:
|
||||
EditorRubberbandSelectDrag (Editor *, ArdourCanvas::Item *);
|
||||
|
||||
void select_things (int, framepos_t, framepos_t, double, double, bool);
|
||||
void deselect_things ();
|
||||
};
|
||||
|
||||
/** A RubberbandSelectDrag for selecting MIDI notes */
|
||||
class MidiRubberbandSelectDrag : public RubberbandSelectDrag
|
||||
{
|
||||
public:
|
||||
MidiRubberbandSelectDrag (Editor *, MidiRegionView *);
|
||||
|
||||
void select_things (int, framepos_t, framepos_t, double, double, bool);
|
||||
void deselect_things ();
|
||||
|
||||
private:
|
||||
MidiRegionView* _region_view;
|
||||
};
|
||||
|
||||
/** Region drag in time-FX mode */
|
||||
|
@ -792,7 +792,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::PrimaryModifier|Keyboard::SecondaryModifier)) &&
|
||||
event->type == GDK_BUTTON_PRESS) {
|
||||
|
||||
_drags->set (new RubberbandSelectDrag (this, item), event);
|
||||
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
||||
|
||||
} else if (event->type == GDK_BUTTON_PRESS) {
|
||||
|
||||
@ -888,7 +888,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
_drags->set (new RubberbandSelectDrag (this, item), event);
|
||||
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -902,7 +902,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
|
||||
_drags->set (new RegionCreateDrag (this, item, parent), event);
|
||||
} else {
|
||||
/* rubberband drag to select automation points */
|
||||
_drags->set (new RubberbandSelectDrag (this, item), event);
|
||||
_drags->set (new EditorRubberbandSelectDrag (this, item), event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "canvas_patch_change.h"
|
||||
#include "debug.h"
|
||||
#include "editor.h"
|
||||
#include "editor_drag.h"
|
||||
#include "ghostregion.h"
|
||||
#include "gui_thread.h"
|
||||
#include "keyboard.h"
|
||||
@ -462,10 +463,12 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||
group->w2i(event_x, event_y);
|
||||
group->ungrab(ev->time);
|
||||
|
||||
PublicEditor& editor = trackview.editor ();
|
||||
|
||||
switch (_mouse_state) {
|
||||
case Pressed: // Clicked
|
||||
|
||||
switch (trackview.editor().current_mouse_mode()) {
|
||||
switch (editor.current_mouse_mode()) {
|
||||
case MouseObject:
|
||||
case MouseTimeFX:
|
||||
{
|
||||
@ -480,7 +483,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||
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));
|
||||
Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_frame (event_x));
|
||||
|
||||
if (!success) {
|
||||
beats = 1;
|
||||
@ -494,7 +497,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||
case MouseRange:
|
||||
{
|
||||
bool success;
|
||||
Evoral::MusicalTime beats = trackview.editor().get_grid_type_as_beats (success, trackview.editor().pixel_to_frame (event_x));
|
||||
Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_frame (event_x));
|
||||
|
||||
if (!success) {
|
||||
beats = 1;
|
||||
@ -512,10 +515,8 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||
break;
|
||||
|
||||
case SelectRectDragging: // Select drag done
|
||||
|
||||
editor.drags()->end_grab ((GdkEvent *) ev);
|
||||
_mouse_state = None;
|
||||
delete _drag_rect;
|
||||
_drag_rect = 0;
|
||||
break;
|
||||
|
||||
case AddDragging: // Add drag done
|
||||
@ -596,27 +597,8 @@ MidiRegionView::motion (GdkEventMotion* ev)
|
||||
|
||||
if (_pressed_button == 1 && editor.current_mouse_mode() == MouseObject
|
||||
&& !Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier())) {
|
||||
// Select drag start
|
||||
|
||||
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;
|
||||
_drag_start_y = event_y;
|
||||
|
||||
_drag_rect = new ArdourCanvas::SimpleRect(*group);
|
||||
_drag_rect->property_x1() = event_x;
|
||||
_drag_rect->property_y1() = event_y;
|
||||
_drag_rect->property_x2() = event_x;
|
||||
_drag_rect->property_y2() = event_y;
|
||||
_drag_rect->property_outline_what() = 0xFF;
|
||||
_drag_rect->property_outline_color_rgba()
|
||||
= ARDOUR_UI::config()->canvasvar_MidiSelectRectOutline.get();
|
||||
_drag_rect->property_fill_color_rgba()
|
||||
= ARDOUR_UI::config()->canvasvar_MidiSelectRectFill.get();
|
||||
|
||||
editor.drags()->set (new MidiRubberbandSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
|
||||
_mouse_state = SelectRectDragging;
|
||||
return true;
|
||||
|
||||
@ -656,7 +638,10 @@ MidiRegionView::motion (GdkEventMotion* ev)
|
||||
|
||||
return false;
|
||||
|
||||
case SelectRectDragging: // Select drag motion
|
||||
case SelectRectDragging:
|
||||
editor.drags()->motion_handler ((GdkEvent *) ev, false);
|
||||
break;
|
||||
|
||||
case AddDragging: // Add note drag motion
|
||||
|
||||
if (ev->is_hint) {
|
||||
@ -692,18 +677,6 @@ MidiRegionView::motion (GdkEventMotion* ev)
|
||||
}
|
||||
}
|
||||
|
||||
if (_drag_rect && _mouse_state == SelectRectDragging) {
|
||||
|
||||
if (event_y > _drag_start_y) {
|
||||
_drag_rect->property_y2() = event_y;
|
||||
}
|
||||
else {
|
||||
_drag_rect->property_y1() = event_y;
|
||||
}
|
||||
|
||||
update_drag_selection(_drag_start_x, event_x, _drag_start_y, event_y, Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier));
|
||||
}
|
||||
|
||||
_last_x = event_x;
|
||||
_last_y = event_y;
|
||||
|
||||
|
@ -311,6 +311,8 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
friend class MidiRubberbandSelectDrag;
|
||||
|
||||
/** Emitted when the selection has been cleared in one MidiRegionView */
|
||||
static PBD::Signal1<void, MidiRegionView*> SelectionCleared;
|
||||
PBD::ScopedConnection _selection_cleared_connection;
|
||||
|
@ -389,7 +389,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible {
|
||||
virtual Marker* find_marker_from_location_id (PBD::ID const &, bool) const = 0;
|
||||
|
||||
virtual void snap_to_with_modifier (framepos_t &, GdkEvent const *, int32_t direction = 0, bool for_mark = false) = 0;
|
||||
|
||||
|
||||
/// Singleton instance, set up by Editor::Editor()
|
||||
|
||||
static PublicEditor* _instance;
|
||||
|
Loading…
Reference in New Issue
Block a user