Skip to content

Commit c5aa567

Browse files
committed
ensure BPM is set on tempo points before moving them
1 parent a3693ad commit c5aa567

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

Breeder/BR_Tempo.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,8 @@ static bool MoveGridInit (COMMAND_T* ct, bool init)
284284
if (init)
285285
{
286286
const int projgridframe = ConfigVar<int>("projgridframe").value_or(0);
287-
if (((int)ct->user == 1 || (int)ct->user == 2) && projgridframe&1) // frames grid line spacing
287+
MoveGridToMouseCommand cmd = (MoveGridToMouseCommand)ct->user;
288+
if ((cmd == MOVE_GRID_TO_MOUSE || cmd == MOVE_M_GRID_TO_MOUSE) && projgridframe&1) // frames grid line spacing
288289
{
289290
initSuccessful = false;
290291
static bool s_warnUser = true;
@@ -332,25 +333,59 @@ static HCURSOR MoveGridCursor (COMMAND_T* ct, int window)
332333
return NULL;
333334
}
334335

336+
/**
337+
* Explicitly set a tempo envelope point's tempo to its calculated tempo.
338+
*
339+
* Must call this on a point before creating a BR_Envelope that will change its bpm,
340+
* otherwise tempo updates via BR_Envelope will be ignored.
341+
*
342+
* @param id The tempo envelope point id to ensure has tempo set. It must exist.
343+
* @return whether a point was mutated
344+
*/
345+
static bool EnsureTempoSet(int id)
346+
{
347+
double timeposOut, beat, bpm;
348+
int measure, num, den;
349+
bool linear;
350+
GetTempoTimeSigMarker(NULL, id, &timeposOut, &measure, &beat, &bpm, &num, &den, &linear);
351+
//TODO is there any way to tell whether bpm has already been explicitly set by this point?
352+
SetTempoTimeSigMarker(NULL, id, timeposOut, measure, beat, bpm, num, den, linear);
353+
return true;
354+
}
355+
335356
static void MoveGridToMouse (COMMAND_T* ct)
336357
{
337358
static int s_lockedId = -1;
338359
static double s_lastPosition = 0;
339360

361+
MoveGridToMouseCommand cmd = (MoveGridToMouseCommand)ct->user;
362+
340363
// Action called for the first time: reset variables and cache tempo map for future calls
341364
if (!g_moveGridTempoMap)
342365
{
343366
s_lockedId = -1;
344367
s_lastPosition = 0;
345368

346369
// Make sure tempo map already has at least one point created (for some reason it won't work if creating it directly in chunk)
347-
if ((int)ct->user != 0 && CountTempoTimeSigMarkers(NULL) == 0) // do it only if not moving tempo marker
370+
if (cmd != MOVE_CLOSEST_TEMPO_MOUSE)
348371
{
349372
InitTempoMap();
350373
g_didTempoMapInit = true;
351374
}
352375

353376
g_moveGridTempoMap = new (nothrow) BR_Envelope(GetTempoEnv());
377+
378+
// Make sure previous point is editable via g_moveGridTempoMap.
379+
if (g_moveGridTempoMap && cmd != MOVE_CLOSEST_TEMPO_MOUSE)
380+
{
381+
// ensure previous point's bpm is explicitly set, otherwise changes won't register in BR_Envelope.
382+
if(EnsureTempoSet(g_moveGridTempoMap->FindPrevious(PositionAtMouseCursor(true))))
383+
{
384+
delete g_moveGridTempoMap;
385+
g_moveGridTempoMap = new (nothrow) BR_Envelope(GetTempoEnv());
386+
}
387+
}
388+
354389
if (!g_moveGridTempoMap || !g_moveGridTempoMap->CountPoints() || g_moveGridTempoMap->IsLocked())
355390
{
356391
ContinuousActionStopAll();
@@ -380,9 +415,9 @@ static void MoveGridToMouse (COMMAND_T* ct)
380415
int targetId;
381416

382417
// Find closest grid tempo marker
383-
if ((int)ct->user == 1 || (int)ct->user == 2)
418+
if (cmd == MOVE_GRID_TO_MOUSE || cmd == MOVE_M_GRID_TO_MOUSE)
384419
{
385-
grid = ((int)ct->user == 1) ? (GetClosestGridLine(mousePosition)) : (GetClosestMeasureGridLine(mousePosition));
420+
grid = (cmd == MOVE_GRID_TO_MOUSE) ? (GetClosestGridLine(mousePosition)) : (GetClosestMeasureGridLine(mousePosition));
386421
targetId = g_moveGridTempoMap->Find(grid, MIN_TEMPO_DIST);
387422
}
388423
// Find closest tempo marker
@@ -445,9 +480,9 @@ void MoveGridToMouseInit ()
445480
//!WANT_LOCALIZE_1ST_STRING_BEGIN:sws_actions
446481
static COMMAND_T s_commandTable[] =
447482
{
448-
{ { DEFACCEL, "SWS/BR: Move closest tempo marker to mouse cursor (perform until shortcut released)" }, "BR_MOVE_CLOSEST_TEMPO_MOUSE", MoveGridToMouse, NULL, 0},
449-
{ { DEFACCEL, "SWS/BR: Move closest grid line to mouse cursor (perform until shortcut released)" }, "BR_MOVE_GRID_TO_MOUSE", MoveGridToMouse, NULL, 1},
450-
{ { DEFACCEL, "SWS/BR: Move closest measure grid line to mouse cursor (perform until shortcut released)" }, "BR_MOVE_M_GRID_TO_MOUSE", MoveGridToMouse, NULL, 2},
483+
{ { DEFACCEL, "SWS/BR: Move closest tempo marker to mouse cursor (perform until shortcut released)" }, "BR_MOVE_CLOSEST_TEMPO_MOUSE", MoveGridToMouse, NULL, MOVE_CLOSEST_TEMPO_MOUSE},
484+
{ { DEFACCEL, "SWS/BR: Move closest grid line to mouse cursor (perform until shortcut released)" }, "BR_MOVE_GRID_TO_MOUSE", MoveGridToMouse, NULL, MOVE_GRID_TO_MOUSE},
485+
{ { DEFACCEL, "SWS/BR: Move closest measure grid line to mouse cursor (perform until shortcut released)" }, "BR_MOVE_M_GRID_TO_MOUSE", MoveGridToMouse, NULL, MOVE_M_GRID_TO_MOUSE},
451486
{ {}, LAST_COMMAND}
452487
};
453488
//!WANT_LOCALIZE_1ST_STRING_END

Breeder/BR_Tempo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
/******************************************************************************
3131
* Commands: Tempo continuous actions *
3232
******************************************************************************/
33+
enum MoveGridToMouseCommand
34+
{
35+
MOVE_CLOSEST_TEMPO_MOUSE = 0,
36+
MOVE_GRID_TO_MOUSE,
37+
MOVE_M_GRID_TO_MOUSE
38+
};
3339
void MoveGridToMouseInit ();
3440

3541
/******************************************************************************

0 commit comments

Comments
 (0)