mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 23:05:04 +01:00
make mouse range mode do something interesting when in internal/note edit mode. not entirely finished because the usual modifiers to add/extend the selection don't work correctly. note that this works both on the scroomer (where the modifiers do work correctly) and in the track (where they do not)
git-svn-id: svn://localhost/ardour2/branches/3.0@11273 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c2a93a9b38
commit
5de9a8f38b
8 changed files with 177 additions and 30 deletions
|
|
@ -3112,6 +3112,7 @@ FeatureLineDrag::aborted (bool)
|
||||||
|
|
||||||
RubberbandSelectDrag::RubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
|
RubberbandSelectDrag::RubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
: Drag (e, i)
|
: Drag (e, i)
|
||||||
|
, _vertical_only (false)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New RubberbandSelectDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New RubberbandSelectDrag\n");
|
||||||
}
|
}
|
||||||
|
|
@ -3163,8 +3164,14 @@ RubberbandSelectDrag::motion (GdkEvent* event, bool)
|
||||||
double x2 = _editor->frame_to_pixel (end);
|
double x2 = _editor->frame_to_pixel (end);
|
||||||
|
|
||||||
_editor->rubberband_rect->property_x1() = x1;
|
_editor->rubberband_rect->property_x1() = x1;
|
||||||
_editor->rubberband_rect->property_y1() = y1;
|
if (_vertical_only) {
|
||||||
|
/* fixed 10 pixel width */
|
||||||
|
_editor->rubberband_rect->property_x2() = x1 + 10;
|
||||||
|
} else {
|
||||||
_editor->rubberband_rect->property_x2() = x2;
|
_editor->rubberband_rect->property_x2() = x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
_editor->rubberband_rect->property_y1() = y1;
|
||||||
_editor->rubberband_rect->property_y2() = y2;
|
_editor->rubberband_rect->property_y2() = y2;
|
||||||
|
|
||||||
_editor->rubberband_rect->show();
|
_editor->rubberband_rect->show();
|
||||||
|
|
@ -4337,6 +4344,34 @@ MidiRubberbandSelectDrag::deselect_things ()
|
||||||
/* XXX */
|
/* XXX */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MidiVerticalSelectDrag::MidiVerticalSelectDrag (Editor* e, MidiRegionView* rv)
|
||||||
|
: RubberbandSelectDrag (e, rv->get_canvas_frame ())
|
||||||
|
, _region_view (rv)
|
||||||
|
{
|
||||||
|
_vertical_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiVerticalSelectDrag::select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress)
|
||||||
|
{
|
||||||
|
double const y = _region_view->midi_view()->y_position ();
|
||||||
|
|
||||||
|
y1 = max (0.0, y1 - y);
|
||||||
|
y2 = max (0.0, y2 - y);
|
||||||
|
|
||||||
|
_region_view->update_vertical_drag_selection (
|
||||||
|
y1,
|
||||||
|
y2,
|
||||||
|
Keyboard::modifier_state_contains (button_state, Keyboard::TertiaryModifier)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiVerticalSelectDrag::deselect_things ()
|
||||||
|
{
|
||||||
|
/* XXX */
|
||||||
|
}
|
||||||
|
|
||||||
EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
|
EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
: RubberbandSelectDrag (e, i)
|
: RubberbandSelectDrag (e, i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -800,6 +800,9 @@ public:
|
||||||
virtual void select_things (int button_state, framepos_t x1, framepos_t x2, double y1, double y2, bool drag_in_progress) = 0;
|
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;
|
virtual void deselect_things () = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _vertical_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A general editor RubberbandSelectDrag (for regions, automation points etc.) */
|
/** A general editor RubberbandSelectDrag (for regions, automation points etc.) */
|
||||||
|
|
@ -825,6 +828,19 @@ private:
|
||||||
MidiRegionView* _region_view;
|
MidiRegionView* _region_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** A RubberbandSelectDrag for selecting MIDI notes but with no horizonal component */
|
||||||
|
class MidiVerticalSelectDrag : public RubberbandSelectDrag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MidiVerticalSelectDrag (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 */
|
/** Region drag in time-FX mode */
|
||||||
class TimeFXDrag : public RegionDrag
|
class TimeFXDrag : public RegionDrag
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -480,6 +480,11 @@ MidiRegionView::button_release (GdkEventButton* ev)
|
||||||
case Pressed: // Clicked
|
case Pressed: // Clicked
|
||||||
|
|
||||||
switch (editor.current_mouse_mode()) {
|
switch (editor.current_mouse_mode()) {
|
||||||
|
case MouseRange:
|
||||||
|
/* no motion occured - simple click */
|
||||||
|
clear_selection ();
|
||||||
|
break;
|
||||||
|
|
||||||
case MouseObject:
|
case MouseObject:
|
||||||
case MouseTimeFX:
|
case MouseTimeFX:
|
||||||
{
|
{
|
||||||
|
|
@ -595,20 +600,23 @@ MidiRegionView::motion (GdkEventMotion* ev)
|
||||||
_mouse_state = AddDragging;
|
_mouse_state = AddDragging;
|
||||||
remove_ghost_note ();
|
remove_ghost_note ();
|
||||||
editor.verbose_cursor()->hide ();
|
editor.verbose_cursor()->hide ();
|
||||||
cerr << "starting note create drag\n";
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else if (m == MouseObject) {
|
||||||
|
|
||||||
editor.drags()->set (new MidiRubberbandSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
|
editor.drags()->set (new MidiRubberbandSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
|
||||||
_mouse_state = SelectRectDragging;
|
_mouse_state = SelectRectDragging;
|
||||||
return true;
|
return true;
|
||||||
|
} else if (m == MouseRange) {
|
||||||
|
editor.drags()->set (new MidiVerticalSelectDrag (dynamic_cast<Editor *> (&editor), this), (GdkEvent *) ev);
|
||||||
|
_mouse_state = SelectVerticalDragging;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case SelectRectDragging:
|
case SelectRectDragging:
|
||||||
|
case SelectVerticalDragging:
|
||||||
case AddDragging:
|
case AddDragging:
|
||||||
editor.drags()->motion_handler ((GdkEvent *) ev, false);
|
editor.drags()->motion_handler ((GdkEvent *) ev, false);
|
||||||
break;
|
break;
|
||||||
|
|
@ -2208,6 +2216,38 @@ MidiRegionView::update_drag_selection(double x1, double x2, double y1, double y2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiRegionView::update_vertical_drag_selection (double y1, double y2, bool extend)
|
||||||
|
{
|
||||||
|
if (y1 > y2) {
|
||||||
|
swap (y1, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Make this faster by storing the last updated selection rect, and only
|
||||||
|
// adjusting things that are in the area that appears/disappeared.
|
||||||
|
// We probably need a tree to be able to find events in O(log(n)) time.
|
||||||
|
|
||||||
|
for (Events::iterator i = _events.begin(); i != _events.end(); ++i) {
|
||||||
|
|
||||||
|
/* check if any corner of the note is inside the rect
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
1) this is computing "touched by", not "contained by" the rect.
|
||||||
|
2) this does not require that events be sorted in time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (((*i)->y1() >= y1 && (*i)->y1() <= y2)) {
|
||||||
|
// within y- (note-) range
|
||||||
|
if (!(*i)->selected()) {
|
||||||
|
add_to_selection (*i);
|
||||||
|
}
|
||||||
|
} else if ((*i)->selected() && !extend) {
|
||||||
|
// Not inside rectangle
|
||||||
|
remove_from_selection (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiRegionView::remove_from_selection (CanvasNoteEvent* ev)
|
MidiRegionView::remove_from_selection (CanvasNoteEvent* ev)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ public:
|
||||||
Pressed,
|
Pressed,
|
||||||
SelectTouchDragging,
|
SelectTouchDragging,
|
||||||
SelectRectDragging,
|
SelectRectDragging,
|
||||||
|
SelectVerticalDragging,
|
||||||
AddDragging
|
AddDragging
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -315,6 +316,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class MidiRubberbandSelectDrag;
|
friend class MidiRubberbandSelectDrag;
|
||||||
|
friend class MidiVerticalSelectDrag;
|
||||||
|
|
||||||
/** Emitted when the selection has been cleared in one MidiRegionView */
|
/** Emitted when the selection has been cleared in one MidiRegionView */
|
||||||
static PBD::Signal1<void, MidiRegionView*> SelectionCleared;
|
static PBD::Signal1<void, MidiRegionView*> SelectionCleared;
|
||||||
|
|
@ -353,6 +355,7 @@ private:
|
||||||
void clear_selection_except (ArdourCanvas::CanvasNoteEvent* ev, bool signal = true);
|
void clear_selection_except (ArdourCanvas::CanvasNoteEvent* ev, bool signal = true);
|
||||||
void clear_selection (bool signal = true) { clear_selection_except (0, signal); }
|
void clear_selection (bool signal = true) { clear_selection_except (0, signal); }
|
||||||
void update_drag_selection (double last_x, double x, double last_y, double y, bool extend);
|
void update_drag_selection (double last_x, double x, double last_y, double y, bool extend);
|
||||||
|
void update_vertical_drag_selection (double last_y, double y, bool extend);
|
||||||
|
|
||||||
void add_to_selection (ArdourCanvas::CanvasNoteEvent*);
|
void add_to_selection (ArdourCanvas::CanvasNoteEvent*);
|
||||||
void remove_from_selection (ArdourCanvas::CanvasNoteEvent*);
|
void remove_from_selection (ArdourCanvas::CanvasNoteEvent*);
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ MidiTimeAxisView::set_route (boost::shared_ptr<Route> rt)
|
||||||
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
|
_route->processors_changed.connect (*this, invalidator (*this), ui_bind (&MidiTimeAxisView::processors_changed, this, _1), gui_context());
|
||||||
|
|
||||||
if (is_track()) {
|
if (is_track()) {
|
||||||
|
_piano_roll_header->SetNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::set_note_selection));
|
||||||
_piano_roll_header->AddNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::add_note_selection));
|
_piano_roll_header->AddNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::add_note_selection));
|
||||||
_piano_roll_header->ExtendNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::extend_note_selection));
|
_piano_roll_header->ExtendNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::extend_note_selection));
|
||||||
_piano_roll_header->ToggleNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_note_selection));
|
_piano_roll_header->ToggleNoteSelection.connect (sigc::mem_fun (*this, &MidiTimeAxisView::toggle_note_selection));
|
||||||
|
|
@ -964,7 +965,21 @@ MidiTimeAxisView::route_active_changed ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiTimeAxisView::set_note_selection (uint8_t note)
|
||||||
|
{
|
||||||
|
if (!_editor.internal_editing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t chn_mask = _channel_selector.get_selected_channels();
|
||||||
|
|
||||||
|
if (_view->num_selected_regionviews() == 0) {
|
||||||
|
_view->foreach_regionview (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::set_note_selection_region_view), note, chn_mask));
|
||||||
|
} else {
|
||||||
|
_view->foreach_selected_regionview (sigc::bind (sigc::mem_fun (*this, &MidiTimeAxisView::set_note_selection_region_view), note, chn_mask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTimeAxisView::add_note_selection (uint8_t note)
|
MidiTimeAxisView::add_note_selection (uint8_t note)
|
||||||
|
|
@ -1015,11 +1030,17 @@ MidiTimeAxisView::toggle_note_selection (uint8_t note)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTimeAxisView::add_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask)
|
MidiTimeAxisView::set_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask)
|
||||||
{
|
{
|
||||||
dynamic_cast<MidiRegionView*>(rv)->select_matching_notes (note, chn_mask, false, false);
|
dynamic_cast<MidiRegionView*>(rv)->select_matching_notes (note, chn_mask, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MidiTimeAxisView::add_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask)
|
||||||
|
{
|
||||||
|
dynamic_cast<MidiRegionView*>(rv)->select_matching_notes (note, chn_mask, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiTimeAxisView::extend_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask)
|
MidiTimeAxisView::extend_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,11 @@ class MidiTimeAxisView : public RouteTimeAxisView
|
||||||
void build_controller_menu ();
|
void build_controller_menu ();
|
||||||
void set_channel_mode (ARDOUR::ChannelMode, uint16_t);
|
void set_channel_mode (ARDOUR::ChannelMode, uint16_t);
|
||||||
|
|
||||||
|
void set_note_selection (uint8_t note);
|
||||||
void add_note_selection (uint8_t note);
|
void add_note_selection (uint8_t note);
|
||||||
void extend_note_selection (uint8_t note);
|
void extend_note_selection (uint8_t note);
|
||||||
void toggle_note_selection (uint8_t note);
|
void toggle_note_selection (uint8_t note);
|
||||||
|
void set_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask);
|
||||||
void add_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask);
|
void add_note_selection_region_view (RegionView* rv, uint8_t note, uint16_t chn_mask);
|
||||||
void extend_note_selection_region_view (RegionView*, uint8_t note, uint16_t chn_mask);
|
void extend_note_selection_region_view (RegionView*, uint8_t note, uint16_t chn_mask);
|
||||||
void toggle_note_selection_region_view (RegionView*, uint8_t note, uint16_t chn_mask);
|
void toggle_note_selection_region_view (RegionView*, uint8_t note, uint16_t chn_mask);
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@
|
||||||
|
|
||||||
#include "gtkmm2ext/keyboard.h"
|
#include "gtkmm2ext/keyboard.h"
|
||||||
|
|
||||||
|
#include "editing.h"
|
||||||
#include "piano_roll_header.h"
|
#include "piano_roll_header.h"
|
||||||
#include "midi_time_axis.h"
|
#include "midi_time_axis.h"
|
||||||
#include "midi_streamview.h"
|
#include "midi_streamview.h"
|
||||||
|
#include "public_editor.h"
|
||||||
|
|
||||||
const int no_note = 0xff;
|
const int no_note = 0xff;
|
||||||
|
|
||||||
|
|
@ -465,6 +467,18 @@ PianoRollHeader::on_motion_notify_event (GdkEventMotion* ev)
|
||||||
|
|
||||||
int note = _view.y_to_note(ev->y);
|
int note = _view.y_to_note(ev->y);
|
||||||
|
|
||||||
|
if (editor().current_mouse_mode() == Editing::MouseRange) {
|
||||||
|
|
||||||
|
/* select note range */
|
||||||
|
|
||||||
|
if (Keyboard::no_modifiers_active (ev->state)) {
|
||||||
|
AddNoteSelection (note); // EMIT SIGNAL
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* play notes */
|
||||||
|
|
||||||
if (_highlighted_note != no_note) {
|
if (_highlighted_note != no_note) {
|
||||||
if (note > _highlighted_note) {
|
if (note > _highlighted_note) {
|
||||||
invalidate_note_range(_highlighted_note, note);
|
invalidate_note_range(_highlighted_note, note);
|
||||||
|
|
@ -488,6 +502,7 @@ PianoRollHeader::on_motion_notify_event (GdkEventMotion* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//win->process_updates(false);
|
//win->process_updates(false);
|
||||||
|
|
||||||
|
|
@ -499,9 +514,15 @@ PianoRollHeader::on_button_press_event (GdkEventButton* ev)
|
||||||
{
|
{
|
||||||
int note = _view.y_to_note(ev->y);
|
int note = _view.y_to_note(ev->y);
|
||||||
|
|
||||||
if (ev->button == 2) {
|
if (ev->button != 1) {
|
||||||
send_note_on (note);
|
return false;
|
||||||
/* relax till release */
|
}
|
||||||
|
|
||||||
|
if (editor().current_mouse_mode() == Editing::MouseRange) {
|
||||||
|
if (Keyboard::no_modifiers_active (ev->state)) {
|
||||||
|
SetNoteSelection (note); // EMIT SIGNAL
|
||||||
|
}
|
||||||
|
_dragging = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (ev->type == GDK_BUTTON_PRESS && note >= 0 && note < 128) {
|
if (ev->type == GDK_BUTTON_PRESS && note >= 0 && note < 128) {
|
||||||
|
|
@ -529,8 +550,7 @@ PianoRollHeader::on_button_release_event (GdkEventButton* ev)
|
||||||
{
|
{
|
||||||
int note = _view.y_to_note(ev->y);
|
int note = _view.y_to_note(ev->y);
|
||||||
|
|
||||||
if (ev->button == 2) {
|
if (editor().current_mouse_mode() == Editing::MouseRange) {
|
||||||
send_note_off (note);
|
|
||||||
|
|
||||||
if (Keyboard::no_modifiers_active (ev->state)) {
|
if (Keyboard::no_modifiers_active (ev->state)) {
|
||||||
AddNoteSelection (note); // EMIT SIGNAL
|
AddNoteSelection (note); // EMIT SIGNAL
|
||||||
|
|
@ -544,7 +564,6 @@ PianoRollHeader::on_button_release_event (GdkEventButton* ev)
|
||||||
|
|
||||||
if (_dragging) {
|
if (_dragging) {
|
||||||
remove_modal_grab();
|
remove_modal_grab();
|
||||||
_dragging = false;
|
|
||||||
|
|
||||||
if (note == _clicked_note) {
|
if (note == _clicked_note) {
|
||||||
reset_clicked_note(note);
|
reset_clicked_note(note);
|
||||||
|
|
@ -552,6 +571,7 @@ PianoRollHeader::on_button_release_event (GdkEventButton* ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_dragging = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -694,3 +714,9 @@ PianoRollHeader::reset_clicked_note (uint8_t note, bool invalidate)
|
||||||
invalidate_note_range (note, note);
|
invalidate_note_range (note, note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PublicEditor&
|
||||||
|
PianoRollHeader::editor() const
|
||||||
|
{
|
||||||
|
return _view.trackview().editor();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ namespace ARDOUR {
|
||||||
|
|
||||||
class MidiTimeAxisView;
|
class MidiTimeAxisView;
|
||||||
class MidiStreamView;
|
class MidiStreamView;
|
||||||
|
class PublicEditor;
|
||||||
|
|
||||||
class PianoRollHeader : public Gtk::DrawingArea {
|
class PianoRollHeader : public Gtk::DrawingArea {
|
||||||
public:
|
public:
|
||||||
|
|
@ -58,6 +59,7 @@ public:
|
||||||
double b;
|
double b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sigc::signal<void,uint8_t> SetNoteSelection;
|
||||||
sigc::signal<void,uint8_t> AddNoteSelection;
|
sigc::signal<void,uint8_t> AddNoteSelection;
|
||||||
sigc::signal<void,uint8_t> ToggleNoteSelection;
|
sigc::signal<void,uint8_t> ToggleNoteSelection;
|
||||||
sigc::signal<void,uint8_t> ExtendNoteSelection;
|
sigc::signal<void,uint8_t> ExtendNoteSelection;
|
||||||
|
|
@ -107,6 +109,8 @@ private:
|
||||||
|
|
||||||
double _note_height;
|
double _note_height;
|
||||||
double _black_note_width;
|
double _black_note_width;
|
||||||
|
|
||||||
|
PublicEditor& editor() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ardour_piano_roll_header_h__ */
|
#endif /* __ardour_piano_roll_header_h__ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue