mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
mostly fix region- and note-create drags
This commit is contained in:
parent
b757756e92
commit
dee71c0a97
4 changed files with 85 additions and 68 deletions
|
|
@ -2597,7 +2597,6 @@ RegionCreateDrag::RegionCreateDrag (Editor* e, ArdourCanvas::Item* i, TimeAxisVi
|
||||||
void
|
void
|
||||||
RegionCreateDrag::motion (GdkEvent* event, bool first_move)
|
RegionCreateDrag::motion (GdkEvent* event, bool first_move)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (first_move) {
|
if (first_move) {
|
||||||
_editor->begin_reversible_command (_("create region"));
|
_editor->begin_reversible_command (_("create region"));
|
||||||
_region = add_midi_region (_view, false);
|
_region = add_midi_region (_view, false);
|
||||||
|
|
@ -2605,13 +2604,14 @@ RegionCreateDrag::motion (GdkEvent* event, bool first_move)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (_region) {
|
if (_region) {
|
||||||
timepos_t const pos = adjusted_current_time (event);
|
timepos_t const pos (adjusted_current_time (event).beats());
|
||||||
if (pos <= grab_time()) {
|
if (pos <= grab_time()) {
|
||||||
_region->set_initial_position (pos);
|
_region->set_initial_position (pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != grab_time()) {
|
if (pos != grab_time()) {
|
||||||
timecnt_t const len = grab_time().distance (pos).abs();
|
/* Force MIDI regions to use Beats ... for now */
|
||||||
|
timecnt_t const len (grab_time().distance (pos).abs().beats());
|
||||||
_region->set_length (len);
|
_region->set_length (len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3526,7 +3526,6 @@ TempoMarkerDrag::TempoMarkerDrag (Editor* e, ArdourCanvas::Item* i, bool c)
|
||||||
: Drag (e, i)
|
: Drag (e, i)
|
||||||
, _copy (c)
|
, _copy (c)
|
||||||
, _grab_bpm (120.0, 4.0)
|
, _grab_bpm (120.0, 4.0)
|
||||||
, _grab_qn (0.0)
|
|
||||||
, _before_state (0)
|
, _before_state (0)
|
||||||
{
|
{
|
||||||
DEBUG_TRACE (DEBUG::Drags, "New TempoMarkerDrag\n");
|
DEBUG_TRACE (DEBUG::Drags, "New TempoMarkerDrag\n");
|
||||||
|
|
@ -3730,7 +3729,6 @@ TempoMarkerDrag::aborted (bool moved)
|
||||||
|
|
||||||
BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i)
|
BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i)
|
||||||
: Drag (e, i)
|
: Drag (e, i)
|
||||||
, _grab_qn (0.0)
|
|
||||||
, _tempo (0)
|
, _tempo (0)
|
||||||
, _before_state (0)
|
, _before_state (0)
|
||||||
, _drag_valid (true)
|
, _drag_valid (true)
|
||||||
|
|
@ -6925,7 +6923,7 @@ NoteCreateDrag::grid_aligned_beats (timepos_t const & pos, GdkEvent const * even
|
||||||
beats = map->quarters_at (map->metric_at (pos).meter().round_to_bar (map->bbt_at (pos)));
|
beats = map->quarters_at (map->metric_at (pos).meter().round_to_bar (map->bbt_at (pos)));
|
||||||
break;
|
break;
|
||||||
default: /* round to some beat subdivision */
|
default: /* round to some beat subdivision */
|
||||||
beats = (pos).beats().round_to_subdivision (divisions, Temporal::RoundNearest);
|
beats = pos.beats().round_to_subdivision (divisions, Temporal::RoundNearest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6940,27 +6938,19 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
_drag_rect = new ArdourCanvas::Rectangle (_region_view->get_canvas_group ());
|
_drag_rect = new ArdourCanvas::Rectangle (_region_view->get_canvas_group ());
|
||||||
|
|
||||||
const timepos_t pos = _drags->current_pointer_time ();
|
const timepos_t pos = _drags->current_pointer_time ();
|
||||||
Temporal::Beats grid_beats = grid_aligned_beats (pos, event);
|
timepos_t aligned_start (grid_aligned_beats (pos, event));
|
||||||
const int32_t divisions = _editor->get_grid_music_divisions (event->button.state);
|
const timepos_t grid_beats (_region_view->get_grid_beats (aligned_start));
|
||||||
|
|
||||||
if (divisions != 0) {
|
_note[0] = aligned_start;
|
||||||
|
|
||||||
const Temporal::Beats unaligned_beats = pos.beats ();
|
|
||||||
|
|
||||||
/* Hack so that we always snap to the note that we are over, instead of snapping
|
|
||||||
to the next one if we're more than halfway through the one we're over.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const Temporal::Beats rem = grid_beats - unaligned_beats;
|
|
||||||
|
|
||||||
if (rem >= std::numeric_limits<Temporal::Beats>::lowest ()) {
|
|
||||||
grid_beats = rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_note[0] = timepos_t (grid_beats);
|
|
||||||
/* minimum initial length is grid beats */
|
/* minimum initial length is grid beats */
|
||||||
_note[1] = timepos_t (grid_beats + grid_beats);
|
_note[1] = aligned_start + grid_beats;
|
||||||
|
|
||||||
|
/* Note: at this point we are drawing a rect for the dragging note in
|
||||||
|
* absolute coordinates (it's not real note, there's no particular
|
||||||
|
* connection to the position/start of the regionview/region. So we
|
||||||
|
* just translate directly from absolute time (_note[0], _note[1]) to
|
||||||
|
* pixels.
|
||||||
|
*/
|
||||||
|
|
||||||
double const x0 = _editor->time_to_pixel (_note[0]);
|
double const x0 = _editor->time_to_pixel (_note[0]);
|
||||||
double const x1 = _editor->time_to_pixel (_note[1]);
|
double const x1 = _editor->time_to_pixel (_note[1]);
|
||||||
|
|
@ -6997,7 +6987,9 @@ NoteCreateDrag::motion (GdkEvent* event, bool)
|
||||||
aligned_beats += grid_beats;
|
aligned_beats += grid_beats;
|
||||||
}
|
}
|
||||||
|
|
||||||
_note[1] = timepos_t (max (Temporal::Beats(), aligned_beats - _region_view->region()->position ().beats()));
|
_note[1] = timepos_t (max (Temporal::Beats(), aligned_beats));
|
||||||
|
|
||||||
|
/* We continue to draw the dragging rect with absolute time/pixel coordinates */
|
||||||
|
|
||||||
double const x0 = _editor->time_to_pixel (_note[0]);
|
double const x0 = _editor->time_to_pixel (_note[0]);
|
||||||
double const x1 = _editor->time_to_pixel (_note[1]);
|
double const x1 = _editor->time_to_pixel (_note[1]);
|
||||||
|
|
@ -7009,8 +7001,11 @@ void
|
||||||
NoteCreateDrag::finished (GdkEvent* ev, bool had_movement)
|
NoteCreateDrag::finished (GdkEvent* ev, bool had_movement)
|
||||||
{
|
{
|
||||||
/* we create a note even if there was no movement */
|
/* we create a note even if there was no movement */
|
||||||
Beats const start = (min (_note[0], _note[1])).beats ();
|
|
||||||
Beats length = max (Beats (1, 0), (_note[1].distance (_note[0]).abs().beats()));
|
/* Compute start within region, rather than absolute time start */
|
||||||
|
|
||||||
|
Beats const start = _region_view->region()->absolute_time_to_region_beats (min (_note[0], _note[1]));
|
||||||
|
Beats length = max (Beats (0, 1), (_note[0].distance (_note[1]).abs().beats()));
|
||||||
|
|
||||||
int32_t div = _editor->get_grid_music_divisions (ev->button.state);
|
int32_t div = _editor->get_grid_music_divisions (ev->button.state);
|
||||||
|
|
||||||
|
|
@ -7019,7 +7014,7 @@ NoteCreateDrag::finished (GdkEvent* ev, bool had_movement)
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor->begin_reversible_command (_("Create Note"));
|
_editor->begin_reversible_command (_("Create Note"));
|
||||||
_region_view->create_note_at (start, _drag_rect->y0(), length, ev->button.state, false);
|
_region_view->create_note_at (timepos_t (start), _drag_rect->y0(), length, ev->button.state, false);
|
||||||
_editor->commit_reversible_command ();
|
_editor->commit_reversible_command ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7040,7 +7035,7 @@ NoteCreateDrag::aborted (bool)
|
||||||
HitCreateDrag::HitCreateDrag (Editor* e, ArdourCanvas::Item* i, MidiRegionView* rv)
|
HitCreateDrag::HitCreateDrag (Editor* e, ArdourCanvas::Item* i, MidiRegionView* rv)
|
||||||
: Drag (e, i)
|
: Drag (e, i)
|
||||||
, _region_view (rv)
|
, _region_view (rv)
|
||||||
, _last_pos (0)
|
, _last_pos (Temporal::Beats())
|
||||||
, _y (0.0)
|
, _y (0.0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -7072,9 +7067,9 @@ HitCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
|
|
||||||
_editor->begin_reversible_command (_("Create Hit"));
|
_editor->begin_reversible_command (_("Create Hit"));
|
||||||
_region_view->clear_note_selection();
|
_region_view->clear_note_selection();
|
||||||
_region_view->create_note_at (start, _y, length, event->button.state, false);
|
_region_view->create_note_at (timepos_t (start), _y, length, event->button.state, false);
|
||||||
|
|
||||||
_last_pos = start;
|
_last_pos = timepos_t (start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -7102,9 +7097,9 @@ HitCreateDrag::motion (GdkEvent* event, bool)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_region_view->create_note_at (start, _y, length, event->button.state, false);
|
_region_view->create_note_at (timepos_t (start), _y, length, event->button.state, false);
|
||||||
|
|
||||||
_last_pos = start;
|
_last_pos = timepos_t (start);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -713,7 +713,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiRegionView* _region_view;
|
MidiRegionView* _region_view;
|
||||||
samplepos_t _last_pos;
|
Temporal::timepos_t _last_pos;
|
||||||
double _y;
|
double _y;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -876,7 +876,7 @@ private:
|
||||||
bool _copy;
|
bool _copy;
|
||||||
bool _movable;
|
bool _movable;
|
||||||
Temporal::Tempo _grab_bpm;
|
Temporal::Tempo _grab_bpm;
|
||||||
double _grab_qn;
|
Temporal::Beats _grab_qn;
|
||||||
XMLNode* _before_state;
|
XMLNode* _before_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -902,7 +902,7 @@ public:
|
||||||
void setup_pointer_offset ();
|
void setup_pointer_offset ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double _grab_qn;
|
Temporal::Beats _grab_qn;
|
||||||
Temporal::TempoPoint* _tempo;
|
Temporal::TempoPoint* _tempo;
|
||||||
XMLNode* _before_state;
|
XMLNode* _before_state;
|
||||||
bool _drag_valid;
|
bool _drag_valid;
|
||||||
|
|
@ -932,7 +932,7 @@ public:
|
||||||
void setup_pointer_offset ();
|
void setup_pointer_offset ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double _grab_qn;
|
Temporal::Beats _grab_qn;
|
||||||
Temporal::Tempo _grab_tempo;
|
Temporal::Tempo _grab_tempo;
|
||||||
Temporal::TempoPoint* _tempo;
|
Temporal::TempoPoint* _tempo;
|
||||||
Temporal::TempoPoint* _next_tempo;
|
Temporal::TempoPoint* _next_tempo;
|
||||||
|
|
@ -963,7 +963,7 @@ public:
|
||||||
void setup_pointer_offset ();
|
void setup_pointer_offset ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double _grab_qn;
|
Temporal::Beats _grab_qn;
|
||||||
Temporal::TempoPoint* _tempo;
|
Temporal::TempoPoint* _tempo;
|
||||||
XMLNode* _before_state;
|
XMLNode* _before_state;
|
||||||
bool _drag_valid;
|
bool _drag_valid;
|
||||||
|
|
|
||||||
|
|
@ -837,9 +837,9 @@ MidiRegionView::show_list_editor ()
|
||||||
* \param snap_t true to snap t to the grid, otherwise false.
|
* \param snap_t true to snap t to the grid, otherwise false.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
MidiRegionView::create_note_at (samplepos_t t, double y, Temporal::Beats length, uint32_t state, bool shift_snap)
|
MidiRegionView::create_note_at (timepos_t const & t, double y, Temporal::Beats length, uint32_t state, bool shift_snap)
|
||||||
{
|
{
|
||||||
if (length < 2 * DBL_EPSILON) {
|
if (length < Temporal::Beats::one_tick()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -851,16 +851,15 @@ MidiRegionView::create_note_at (samplepos_t t, double y, Temporal::Beats length,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start of note in samples relative to region start
|
/* assume time is already region-relative and snapped */
|
||||||
const int32_t divisions = trackview.editor().get_grid_music_divisions (state);
|
|
||||||
Temporal::Beats beat_time = snap_sample_to_grid_underneath (t, divisions, shift_snap);
|
Temporal::Beats region_start = t.beats();
|
||||||
|
|
||||||
const double note = view->y_to_note(y);
|
const double note = view->y_to_note(y);
|
||||||
const uint8_t chan = mtv->get_channel_for_add();
|
const uint8_t chan = mtv->get_channel_for_add();
|
||||||
const uint8_t velocity = get_velocity_for_add(beat_time);
|
const uint8_t velocity = get_velocity_for_add (region_start);
|
||||||
|
|
||||||
const boost::shared_ptr<NoteType> new_note(
|
const boost::shared_ptr<NoteType> new_note (new NoteType (chan, region_start, length, (uint8_t)note, velocity));
|
||||||
new NoteType (chan, beat_time, length, (uint8_t)note, velocity));
|
|
||||||
|
|
||||||
if (_model->contains (new_note)) {
|
if (_model->contains (new_note)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1644,10 +1643,30 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
|
||||||
{
|
{
|
||||||
const boost::shared_ptr<ARDOUR::MidiRegion> mr = midi_region();
|
const boost::shared_ptr<ARDOUR::MidiRegion> mr = midi_region();
|
||||||
boost::shared_ptr<NoteType> note = ev->note();
|
boost::shared_ptr<NoteType> note = ev->note();
|
||||||
const timepos_t note_start = _region->source_beats_to_absolute_time (note->time());
|
const timepos_t note_start (note->time());
|
||||||
|
timepos_t note_end (note->end_time());
|
||||||
|
|
||||||
const double x0 = trackview.editor().time_to_pixel (note_start);
|
/* The note is drawn as a child item of this region view, so its
|
||||||
|
* coordinate system is relative to the region view. This means that x0
|
||||||
|
* and x1 are pixel offsets relative to beginning of the region (view)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* compute absolute time where the start of the source is
|
||||||
|
*/
|
||||||
|
|
||||||
|
const timepos_t session_source_start = _region->source_position();
|
||||||
|
|
||||||
|
/* this computes the number of samples from the start of the region of the start of the
|
||||||
|
* note. We add the source start to get to the absolute time of the
|
||||||
|
* note, then subtract the start of the region
|
||||||
|
*/
|
||||||
|
|
||||||
|
const samplepos_t note_start_samples = (note_start + session_source_start).earlier ( _region->position()).samples();
|
||||||
|
|
||||||
|
const double x0 = trackview.editor().sample_to_pixel (note_start_samples);
|
||||||
double x1;
|
double x1;
|
||||||
|
|
||||||
|
|
||||||
const double y0 = 1 + floor(note_to_y(note->note()));
|
const double y0 = 1 + floor(note_to_y(note->note()));
|
||||||
double y1;
|
double y1;
|
||||||
|
|
||||||
|
|
@ -1661,13 +1680,15 @@ MidiRegionView::update_sustained (Note* ev, bool update_ghost_regions)
|
||||||
|
|
||||||
/* normal note */
|
/* normal note */
|
||||||
|
|
||||||
timepos_t note_end (note->end_time());
|
const Temporal::Beats source_end ((_region->start() + _region->length()).beats());
|
||||||
|
|
||||||
if (note_end > mr->start() + mr->length()) {
|
if (note->end_time() > source_end) {
|
||||||
note_end = mr->start() + mr->length();
|
note_end = timepos_t (source_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 = std::max(1., trackview.editor().time_to_pixel (note_end)) - 1;
|
const samplepos_t note_end_samples = _region->position().distance ((note_end + session_source_start)).samples();
|
||||||
|
|
||||||
|
x1 = std::max(1., trackview.editor().sample_to_pixel (note_end_samples)) - 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -2912,16 +2933,16 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
|
||||||
|
|
||||||
if (!cursor_set) {
|
if (!cursor_set) {
|
||||||
/* Convert snap delta from pixels to beats. */
|
/* Convert snap delta from pixels to beats. */
|
||||||
samplepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
|
timepos_t snap_delta_time = timepos_t (trackview.editor().pixel_to_sample (snap_delta));
|
||||||
double snap_delta_beats = 0.0;
|
Beats snap_delta_beats;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
|
|
||||||
|
|
||||||
/* negative beat offsets aren't allowed */
|
/* negative beat offsets aren't allowed */
|
||||||
if (snap_delta_samps > 0) {
|
if (snap_delta_time > 0) {
|
||||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_samps, _region->position()));
|
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_time, _region->position()));
|
||||||
} else if (snap_delta_samps < 0) {
|
} else if (snap_delta_time < 0) {
|
||||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_samps, _region->position()));
|
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_time, _region->position()));
|
||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3009,14 +3030,14 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert snap delta from pixels to beats with sign. */
|
/* Convert snap delta from pixels to beats with sign. */
|
||||||
samplepos_t snap_delta_samps = trackview.editor().pixel_to_sample (snap_delta);
|
timepos_t snap_delta_time (trackview.editor().pixel_to_sample (snap_delta));
|
||||||
Temporal::Beats snap_delta_beats;
|
Temporal::Beats snap_delta_beats;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
|
|
||||||
if (snap_delta_samps > 0) {
|
if (snap_delta_time.positive()) {
|
||||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_samps, _region->position()));
|
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (snap_delta_time, _region->position()));
|
||||||
} else if (snap_delta_samps < 0) {
|
} else if (snap_delta_time.negative()) {
|
||||||
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_samps, _region->position()));
|
snap_delta_beats = _region->region_distance_to_region_beats (timecnt_t (-snap_delta_time, _region->position()));
|
||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3905,6 +3926,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
|
||||||
_ghost_note->note()->set_note (y_to_note (y));
|
_ghost_note->note()->set_note (y_to_note (y));
|
||||||
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
|
_ghost_note->note()->set_channel (mtv->get_channel_for_add ());
|
||||||
_ghost_note->note()->set_velocity (get_velocity_for_add (snapped_beats));
|
_ghost_note->note()->set_velocity (get_velocity_for_add (snapped_beats));
|
||||||
|
|
||||||
update_note (_ghost_note, false);
|
update_note (_ghost_note, false);
|
||||||
|
|
||||||
show_verbose_cursor (_ghost_note->note ());
|
show_verbose_cursor (_ghost_note->note ());
|
||||||
|
|
@ -4271,6 +4293,7 @@ MidiRegionView::snap_sample_to_grid_underneath (samplepos_t p, int32_t divisions
|
||||||
|
|
||||||
TempoMap::SharedPtr tmap (TempoMap::use());
|
TempoMap::SharedPtr tmap (TempoMap::use());
|
||||||
timepos_t pos (_region->position() + timecnt_t (p));
|
timepos_t pos (_region->position() + timecnt_t (p));
|
||||||
|
|
||||||
Beats snapped_beats = tmap->quarters_at (pos).round_to_subdivision (divisions, RoundNearest);
|
Beats snapped_beats = tmap->quarters_at (pos).round_to_subdivision (divisions, RoundNearest);
|
||||||
|
|
||||||
if (shift_snap) {
|
if (shift_snap) {
|
||||||
|
|
@ -4338,4 +4361,3 @@ MidiRegionView::note_to_y(uint8_t note) const
|
||||||
{
|
{
|
||||||
return contents_height() - (note + 1 - _current_range_min) * note_height() + 1;
|
return contents_height() - (note + 1 - _current_range_min) * note_height() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -260,8 +260,8 @@ public:
|
||||||
MouseState mouse_state() const { return _mouse_state; }
|
MouseState mouse_state() const { return _mouse_state; }
|
||||||
|
|
||||||
struct NoteResizeData {
|
struct NoteResizeData {
|
||||||
Note *note;
|
::Note *note;
|
||||||
ArdourCanvas::Rectangle *resize_rect;
|
ArdourCanvas::Rectangle *resize_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Snap a region relative pixel coordinate to pixel units.
|
/** Snap a region relative pixel coordinate to pixel units.
|
||||||
|
|
@ -312,7 +312,7 @@ public:
|
||||||
* \param state the keyboard modifier mask for the canvas event (click).
|
* \param state the keyboard modifier mask for the canvas event (click).
|
||||||
* \param shift_snap true alters snap behavior to round down always (false if the gui has already done that).
|
* \param shift_snap true alters snap behavior to round down always (false if the gui has already done that).
|
||||||
*/
|
*/
|
||||||
void create_note_at (samplepos_t t, double y, Temporal::Beats length, uint32_t state, bool shift_snap);
|
void create_note_at (Temporal::timepos_t const & t, double y, Temporal::Beats length, uint32_t state, bool shift_snap);
|
||||||
|
|
||||||
/** An external request to clear the note selection, remove MRV from editor
|
/** An external request to clear the note selection, remove MRV from editor
|
||||||
* selection.
|
* selection.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue