Make click & drag in the left-hand half of a region with the Timestretch
tool stretch the region on its left, leaving the end position of the new
time-stretched region in the same place as the end of the original.
Editor::motion_handler() only updates the snap-cursor
when no drags are active. While dragging, Drag::motion is
responsible to set the cursor accordingly.
In many cases the snap-cursor simply remained stuck at
the most recent position. Since in many cases
(e.g. RubberbandSelectDrag) it makes no sense to show the
cursor, so Drag::start_grab now hides the cursor by default.
This also fixes cases where the cursor is shown, but
was displayed in the wrong location.
* the process of tempo mapping requires/encourages you to click on the
last-known good marker, before continuing to make tempo tweaks
* this conflicts with the idea that clicking in a ruler should start a
playhead-drag. TBD. but tempo-mapping is a special and rare operation.
* correctly handle clicks on the immediate right or left of a beat line
* prefer Mid-Twist and End-Stretch terminology over Twist and Linear
* static-tempo vs ramped-tempo is orthogonal to mid- and end- drags (TODO)
* in the 'fake_drag' case (dragging the playhead from the ruler), the
mouse events are delivered to the playhead during the drag so we need
to temporarily sensitize the playhead during that operation, then reset
the sensitivity via config
This is mostly a simple lexical search+replace but the absence of operator< for
std::weak_ptr<T> leads to some complications, particularly with Evoral::Sequence
and ExportPortChannel.
* during drag and trim operations, we use "dragging region" transparency
so you can see the audio data beneath your region(s)
* we already do this for region-end-trim fade drags, which is a special
kind of trim operation, accessed from the 'lower' drag handle
* now we also trigger transparency for regular fade trims.
see discussion at:
https://discourse.ardour.org/t/regions-transparency-in-7-2/108060/31
* HitCreateDrag::start_grab does not need to do anything
a hit cannot be past end of region. Drawing at or past
the end of a region will create a new region (not an event)
* HitCreateDrag::finished now calculates the position like
NoteCreateDrag::finished.
* the selection does not need to be cleared. Creating new
notes/hits selectes the newly created ones.
The old code could not snap to the grid, because it had a lot of confusion about pixels vs. time,
and between line-origin-relative time and absolute time
When copying regions from multiple tracks, use the same
time domain for each region (depends on grid).
The primary region position is set the time-domain from
RegionMotionDrag::_last_position replacing the region's
prior time-domain. Other regions should follow suit and not
retain their time-domain.
Fixes: Enable snap-to-grid, select regions on multiple tracks,
ctrl+drag copy them.
This fixes rendering of opaque MIDI regions (previously
MIDI regions were always transparent). This change provides a
way to "flatten" layered MIDI regions, while still allowing
to show the note-line and grid behind the regions.
Double-clicking on a line in internal edit mode adds
a new point in the line. In this case LineDrag need not
manage automation events because the "add" functions already
do. see AutomationTimeAxisView::add_automation_event and
AudioRegionView::add_gain_point_event
a drag on a segment without adjacent points would crash because we never
set the _grab_button for the Drag, so the LineDrag object never gets deleted
on mouse-up. This leaves a dangling reversible command, which will then
cause an assert(false) crash in the next Editor::begin_reversible_command()
In the presence of tempo-changes distinguishing between offsets and
absolute positions is signficant. It is only valid to convert absolute
times using the tempo-map
Furthermore since GUI zoom-factor is time-invariant (samples per pixel),
all GUI operations must explictly use samples (or timecnt). It is not
valid (and problematic) to use use a location dependent timepos.
The class now has two separate methods for setting a duration or a point
value. They MUST be used appropriately, because their behavior is different.
When ::set_duration() is used in timecode mode, an extent (inclusive-end
length) is shown rather than a length.
Some objects, such as the TimeInfoBox, now deliberately shown an inclusive end
for their "end" clock, but this not universally followed, pending more feedback
from users and investigating of conventions in other DAWs.
Confusion caused during nutempo development when a boolean related to nick_m's old
"for music" concept ended up becoming the "auto_partition" argument instead
In case of auto-scroll it is apparently possible that the
move_threshold_passed, but ::motion() is not called.
There already is an explicit _starting_point_passed variable
that is set when first_move occurred. So far it was just unused.
when dragging their location
* it should be possible to launch an arbitrary (non-quantized) sound
'anytime' on the timeline
* this was already possible anyway, by switching the Grid to None
When no movement has occurred, TrimDrag::motion was never called
and `begin_reversible_command()` was not called. There is nothing
to undo. This fixes
`commit_reversible_command(Command*): Assertion `_current_trans' failed`
When a tempo map change originates from a drag, we know the required redraws have
already been done. Use a new bool member, ignore_map_change, to tell the Editor
to ignore the map change signal. For all other map changes, do the full reset.
We now simply move markers during drags, and do not seek to create/delete markers.
When the map is changed, we rebuild the markers from scratch. This might need optimization to avoid doing
when the editor itself changed the map.
This used to be a distinct kind of drag, but ended up being refactored into
something that happens during a regular drag. Has not been used in quite some time.
The design ignored the ratio computed by the drag interaction, and relied on getting the stretch
ratio from the dialog. This truncated the actual ratio, leading to (relatively) small errors
in the length of the generated region.
Now, if the ratio provided by the drag is not (1/1) (i.e. a single click while in timefx mode)
then the percentage stretch spinner is marked insensitive and the stretch ratio is taken from
the given ratio. For single clicks, the user can still adjust the percentage as they wish
* in the case where there are no existing automation points, then
initiating an automation range drag (select range, switch to Draw)
should initialize the line at the current knob position
this prevents the case where have enabled snap, and you add a note that
appears to be on a bar line. but actually it is {some Grid value} off,
it just looks right because of pixel rounding.
This fixes the issue where you click to create a note, but move the mouse
just a little, resulting in a note of invisibly small length
Do the calculation in ::motion so it displays the final
size while you are dragging. "what you see is what you will get"