mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
add HitBrushDrag, to allow brushing notes on the grid
This commit is contained in:
parent
dcb482e74d
commit
88bf459a61
4 changed files with 152 additions and 3 deletions
|
|
@ -443,7 +443,7 @@ Drag::end_grab (GdkEvent* event)
|
||||||
_item->ungrab ();
|
_item->ungrab ();
|
||||||
|
|
||||||
finished (event, _starting_point_passed);
|
finished (event, _starting_point_passed);
|
||||||
|
|
||||||
editing_context.verbose_cursor().hide ();
|
editing_context.verbose_cursor().hide ();
|
||||||
|
|
||||||
return _starting_point_passed;
|
return _starting_point_passed;
|
||||||
|
|
@ -6903,7 +6903,6 @@ NoteCreateDrag::aborted (bool)
|
||||||
HitCreateDrag::HitCreateDrag (EditingContext& ec, ArdourCanvas::Item* i, MidiView* mv)
|
HitCreateDrag::HitCreateDrag (EditingContext& ec, ArdourCanvas::Item* i, MidiView* mv)
|
||||||
: Drag (ec, i, Temporal::BeatTime, ec.get_trackview_group())
|
: Drag (ec, i, Temporal::BeatTime, ec.get_trackview_group())
|
||||||
, _midi_view (mv)
|
, _midi_view (mv)
|
||||||
, _last_pos (Temporal::Beats ())
|
|
||||||
, _y (0)
|
, _y (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -6962,6 +6961,120 @@ HitCreateDrag::y_to_region (double y) const
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------*/
|
||||||
|
|
||||||
|
HitBrushDrag::HitBrushDrag (EditingContext& ec, ArdourCanvas::Item* i, MidiView* mv)
|
||||||
|
: Drag (ec, i, Temporal::BeatTime, ec.get_trackview_group())
|
||||||
|
, _midi_view (mv)
|
||||||
|
, _last_pos (Temporal::Beats ())
|
||||||
|
, _y (0)
|
||||||
|
, added_notes (false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HitBrushDrag::~HitBrushDrag ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HitBrushDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
|
||||||
|
{
|
||||||
|
Drag::start_grab (event, cursor);
|
||||||
|
|
||||||
|
_y = _midi_view->note_to_y (_midi_view->y_to_note (y_to_region (event->button.y)));
|
||||||
|
|
||||||
|
timepos_t pos (_drags->current_pointer_time ());
|
||||||
|
assert (Config->get_default_quantization().type == AnyTime::BBT_Offset);
|
||||||
|
stride = get_stride (pos.beats(), Config->get_default_quantization().bbt_offset);
|
||||||
|
Temporal::Beats dl = _midi_view->get_draw_length_beats (pos);
|
||||||
|
|
||||||
|
if (dl > stride) {
|
||||||
|
stride = dl;
|
||||||
|
}
|
||||||
|
|
||||||
|
editing_context.snap_to (pos, RoundNearest, SnapToGrid_Scaled);
|
||||||
|
next_grid = pos.beats ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Temporal::Beats
|
||||||
|
HitBrushDrag::get_stride (Temporal::Beats const & pos, Temporal::BBT_Offset const & q)
|
||||||
|
{
|
||||||
|
if (q < Temporal::BBT_Offset (0, 0, 0)) {
|
||||||
|
/* negative quantization == do not quantize */
|
||||||
|
return Temporal::Beats ();
|
||||||
|
|
||||||
|
} else if (q.bars == 0) {
|
||||||
|
|
||||||
|
return Temporal::Beats (q.beats, q.ticks);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
||||||
|
return tmap->meter_at (pos).to_quarters (q); /* Quantization as beats */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HitBrushDrag::motion (GdkEvent* event, bool first_move)
|
||||||
|
{
|
||||||
|
Beats length;
|
||||||
|
|
||||||
|
if (last_pointer_x() >= current_pointer_x()) {
|
||||||
|
/* nothing to if we move earlier in time */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_move) {
|
||||||
|
_midi_view->start_note_diff_command (_("brush notes"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const timepos_t pos = _drags->current_pointer_time ();
|
||||||
|
|
||||||
|
while (pos.beats() >= next_grid) {
|
||||||
|
|
||||||
|
if (!_midi_view->midi_region()) {
|
||||||
|
editing_context.make_a_region ();
|
||||||
|
assert (_midi_view->midi_region());
|
||||||
|
}
|
||||||
|
|
||||||
|
length = _midi_view->get_draw_length_beats (timepos_t (next_grid));
|
||||||
|
|
||||||
|
Beats start;
|
||||||
|
|
||||||
|
if (!_midi_view->on_timeline()) {
|
||||||
|
Beats spos = _midi_view->midi_region()->source_position().beats() + next_grid;
|
||||||
|
start = _midi_view->midi_region ()->absolute_time_to_source_beats (timepos_t (spos));
|
||||||
|
} else {
|
||||||
|
start = _midi_view->midi_region ()->absolute_time_to_source_beats (timepos_t (next_grid));
|
||||||
|
}
|
||||||
|
|
||||||
|
_midi_view->create_note_at (timepos_t (start), _y, length, event->button.state, false, false);
|
||||||
|
added_notes = true;
|
||||||
|
|
||||||
|
next_grid += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HitBrushDrag::finished (GdkEvent* event, bool had_movement)
|
||||||
|
{
|
||||||
|
if (added_notes) {
|
||||||
|
_midi_view->end_note_diff_command ();
|
||||||
|
} else {
|
||||||
|
_midi_view->abort_note_diff ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
HitBrushDrag::y_to_region (double y) const
|
||||||
|
{
|
||||||
|
double x = 0;
|
||||||
|
_midi_view->drag_group ()->canvas_to_item (x, y);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------------------*/
|
||||||
|
|
||||||
CrossfadeEdgeDrag::CrossfadeEdgeDrag (Editor& e, AudioRegionView* rv, ArdourCanvas::Item* i, bool start_yn)
|
CrossfadeEdgeDrag::CrossfadeEdgeDrag (Editor& e, AudioRegionView* rv, ArdourCanvas::Item* i, bool start_yn)
|
||||||
: Drag (e, i, Temporal::AudioTime, e.get_trackview_group())
|
: Drag (e, i, Temporal::AudioTime, e.get_trackview_group())
|
||||||
, arv (rv)
|
, arv (rv)
|
||||||
|
|
|
||||||
|
|
@ -708,9 +708,40 @@ public:
|
||||||
private:
|
private:
|
||||||
double y_to_region (double) const;
|
double y_to_region (double) const;
|
||||||
|
|
||||||
|
MidiView* _midi_view;
|
||||||
|
int _y;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class HitBrushDrag : public Drag
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HitBrushDrag (EditingContext&, ArdourCanvas::Item *, MidiView *);
|
||||||
|
~HitBrushDrag ();
|
||||||
|
|
||||||
|
void start_grab (GdkEvent *, Gdk::Cursor* c = 0);
|
||||||
|
void motion (GdkEvent *, bool);
|
||||||
|
void finished (GdkEvent *, bool);
|
||||||
|
void aborted (bool) {}
|
||||||
|
|
||||||
|
bool active (Editing::MouseMode mode) {
|
||||||
|
return mode == Editing::MouseDraw || mode == Editing::MouseContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool y_movement_matters () const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double y_to_region (double) const;
|
||||||
|
Temporal::Beats get_stride (Temporal::Beats const & pos, Temporal::BBT_Offset const & quantization);
|
||||||
|
|
||||||
MidiView* _midi_view;
|
MidiView* _midi_view;
|
||||||
Temporal::timepos_t _last_pos;
|
Temporal::timepos_t _last_pos;
|
||||||
int _y;
|
int _y;
|
||||||
|
Temporal::Beats stride;
|
||||||
|
Temporal::Beats next_grid;
|
||||||
|
bool added_notes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -568,7 +568,11 @@ MidiView::button_press (GdkEventButton* ev)
|
||||||
draw_drag = new HitCreateDrag (_editing_context, drag_group(), this);
|
draw_drag = new HitCreateDrag (_editing_context, drag_group(), this);
|
||||||
_editing_context.drags()->set (draw_drag, (GdkEvent *) ev);
|
_editing_context.drags()->set (draw_drag, (GdkEvent *) ev);
|
||||||
} else {
|
} else {
|
||||||
draw_drag = new NoteCreateDrag (_editing_context, drag_group(), this);
|
if (Keyboard::modifier_state_contains (ev->state, Keyboard::TertiaryModifier)) {
|
||||||
|
draw_drag = new HitBrushDrag (_editing_context, drag_group(), this);
|
||||||
|
} else {
|
||||||
|
draw_drag = new NoteCreateDrag (_editing_context, drag_group(), this);
|
||||||
|
}
|
||||||
_editing_context.drags()->set (draw_drag, (GdkEvent *) ev);
|
_editing_context.drags()->set (draw_drag, (GdkEvent *) ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ class MidiView : public virtual sigc::trackable, public LineMerger
|
||||||
friend class NoteDrag;
|
friend class NoteDrag;
|
||||||
friend class NoteCreateDrag;
|
friend class NoteCreateDrag;
|
||||||
friend class HitCreateDrag;
|
friend class HitCreateDrag;
|
||||||
|
friend class HitBrushDrag;
|
||||||
friend class MidiGhostRegion;
|
friend class MidiGhostRegion;
|
||||||
|
|
||||||
friend class EditNoteDialog;
|
friend class EditNoteDialog;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue