This just uses the old Evoral BeatTest. Some of the tests needed amending
because temporal uses rint() to convert between float and int, not just
a cast.
Until we have a trimmer, the clip length spinner sets integer beats (beatcnt)
This allows the user some minimal ability to fix a clip of the wrong bpm.
We assumed that 'clips' are already be pre-trimmed to a beat length.
Our internal heuristic always forced tempo to match an integer beatcnt
However: when bouncing a Range to a Trigger Clip, you can know the tempo, and also have a non-integer beat length.
In those cases, the clip-length spinner could behave oddly.
While it's arguably wrong to show integer beats when the internal value is something else,
we still want to show the spinner in integer beats, so it remains usable for its main purpose
This will need some refinement, we should only copy the settings
if the file in question was previously auditioned, and perhaps
only if GMsynth.lv2 is used.
Previously there were two signals for a ::set()
1. Clear Selection -> Emit Signal
2. Select TriggerEntry -> Emit Signal
As result the Trigger Patch Selector was reset and hidden at (1),
only to be set and presented again at (2).
This should perhaps be done for other ::set() calls as well.
This keeps the plugin in sync with any changes made to the
Plugin UI. In particular General MIDI Synth will send
notifications once patch/program changes are processed.
ACE Fluidsynth can load sf2 files, etc.
TriggerEntry has 3 child items:
* play-button, follow-button, name-button.
On mouse-down the TriggerEntry is grab()bed in preparation
to start a drag. From then on all events are directly sent to
TriggerEntry, which can only pass it up to parent items.
Mouse-release hence reaches the TriggerStrip and selects it.
This also changes TriggerBox Selection to act on release
(like all other selection). Otherwise strip selection will
de-select the TriggerBox on mouse-release.
* when a menu uses RadioActions, their initial state must be synced
* we use various methods to 'fix' this throughout the program
-> I'm forcing internal state to match in the case the Action is already active
* question: we tend to use RadioActions for all these menu items,
because they represent a choice between many options;
but do we really need to use RadioActions here?
This properly updates the display if the preference changes.
Even with FILE_CHOOSER_ACTION_SELECT_FOLDER the API is
is get/set_filename -- set_current_folder() sets the parent folder.
This should not be needed, however Editor::idle_remove_tracks()
has the same priority as Editor::redisplay_track_views() and this
might save us another redisplay call.
There is probably a good reason why _vca.reset() is called
immediately, and 6dc66ea78f is a better solution to the issue
This reverts commit 83719fba1a.
Session::remove_routes() first calls IO::disconnect()
before eventually calling route->drop_references().
RouteTimeAxisView::io_changed() is called while the route still
exists and requests a redraw which in turn emits
_stripable->gui_changed ("track_height").
Since the RTAV is deleted later during an idle-callback, there
was another redraw performed just before the RTAV is actually deleted.
VCATimeAxisView::self_delete () resets _vca and queues delete_when_idle.
From now on STAV::strippable () will return 0.
Editor::idle_remove_tracks() returns, and before the VCATimeAxisView
is destroyed. Editor::redisplay_track_views() may be called.
The VCATimeAxisView still exists at this point and is in
Editor::track_views, but has no valid stripable.
This causes a crash in TrackViewStripableSorter which depends
on STAV::stripable();
THe length of a Source(File) is always measured from its start. In this sense,
the length is like a position on the timeline, which is a duration with an
implicit origin, or a Region start, also a duration with an implicit origin (in
that case the start of the Source). There is no good reason for using
a timecnt_t for this value, because the position component of a timecnt_t
(the origin for the duration) is implicit and always zero. So we make
this property into a timepos_t, and include a number of asserts() to check
for common possible coding errors related to the time domain
The track-height change needs to be applied so that
vertical_adjustment max range is set correctly.
Otherwise vertical_adjustment.set_value() may fail
or scroll to the wrong position.
In 5b3eacd421 `redisplay_track_views()` was moved from
EditorRoutes to Editor. The call was delegated to the idle
thread, potentially collecting multiple calls before performing
the update.
This resulted in "Fit selection" to set the y-offset before the
height-change was applied.