Skip to content

Commit

Permalink
Merge pull request #6193 from SKefalidis/smooth3x
Browse files Browse the repository at this point in the history
fix #306234: added teleportation to smooth scrolling, for dealing with repeats + improved comments and default value
  • Loading branch information
anatoly-os committed Jun 10, 2020
1 parent 017910b commit ff4e34c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 19 deletions.
2 changes: 2 additions & 0 deletions global/settings/types/preferencekeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@
#define PREF_PAN_MODIFIER_MAX "smoothPan/modifier/maxSpeed"
#define PREF_PAN_CURSOR_POS "smoothPan/cursor/position"
#define PREF_PAN_CURSOR_VISIBLE "smoothPan/cursor/visible"
#define PREF_PAN_TELEPORT_RIGHT "smoothPan/cursor/teleportRight"
#define PREF_PAN_TELEPORT_LEFT "smoothPan/cursor/teleportLeft"
//#define PREF_PAN_DISTANCE_LEFT "smoothPan/distance/left"
//#define PREF_PAN_DISTANCE_LEFT1 "smoothPan/distance/left1"
//#define PREF_PAN_DISTANCE_LEFT2 "smoothPan/distance/left2"
Expand Down
4 changes: 3 additions & 1 deletion mscore/preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,13 @@ void Preferences::init(bool storeInMemoryOnly)
{PREF_UI_INSPECTOR_STYLED_TEXT_COLOR_DARK, new ColorPreference(QColor("#36B2FF"))},
{PREF_PAN_MODIFIER_BASE, new DoublePreference(1, true)},
{PREF_PAN_MODIFIER_STEP, new DoublePreference(0.01, true)},
{PREF_PAN_MODIFIER_MIN, new DoublePreference(0, true)},
{PREF_PAN_MODIFIER_MIN, new DoublePreference(0.2, true)},
{PREF_PAN_MODIFIER_MAX, new DoublePreference(5, true)},
{PREF_PAN_CURSOR_VISIBLE, new BoolPreference(false, true)},
{PREF_PAN_CURSOR_POS, new DoublePreference(0.3, true)},
{PREF_PAN_SMOOTHLY_ENABLED, new BoolPreference(false, true)},
{PREF_PAN_TELEPORT_LEFT, new BoolPreference(true, true) },
{PREF_PAN_TELEPORT_RIGHT, new BoolPreference(false, true) },
// {PREF_PAN_DISTANCE_LEFT, new DoublePreference(-250, false)},
// {PREF_PAN_DISTANCE_LEFT1, new DoublePreference(-125, false)},
// {PREF_PAN_DISTANCE_LEFT2, new DoublePreference(-50, false)},
Expand Down
36 changes: 31 additions & 5 deletions mscore/scoreview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,8 @@ void ScoreView::moveControlCursor(const Fraction& tick)
int controlX = _controlCursor->rect().x();
double distance = realX - controlX;

if (seq->isPlaying()) {
//playbackCursor in front of the controlCursor
if (seq->isPlaying() && isCursorDistanceReasonable()) {
// playbackCursor in front of the controlCursor
if (distance > _panSettings.rightDistance)
_controlModifier += _panSettings.controlModifierSteps;
else if (distance > _panSettings.rightDistance1 && _controlModifier < _panSettings.rightMod1)
Expand All @@ -697,7 +697,7 @@ void ScoreView::moveControlCursor(const Fraction& tick)
_controlModifier -= _panSettings.controlModifierSteps;
else if (_controlModifier > _panSettings.rightMod3 && distance < _panSettings.rightDistance3)
_controlModifier = _panSettings.controlModifierBase;
//playbackCursor behind the controlCursor
// playbackCursor behind the controlCursor
else if (distance < _panSettings.leftDistance)
_controlModifier -= _panSettings.controlModifierSteps;
else if (_controlModifier < _panSettings.leftMod1 && distance > _panSettings.leftDistance1)
Expand All @@ -707,7 +707,7 @@ void ScoreView::moveControlCursor(const Fraction& tick)
else if (_controlModifier < _panSettings.leftMod3 && distance > _panSettings.leftDistance3)
_controlModifier = _panSettings.controlModifierBase;

//enforce limits
// enforce limits
if (_controlModifier < _panSettings.minContinuousModifier)
_controlModifier = _panSettings.minContinuousModifier;
else if (_controlModifier > _panSettings.maxContinuousModifier)
Expand Down Expand Up @@ -749,13 +749,37 @@ void ScoreView::moveControlCursor(const Fraction& tick)
}


//Calculate the position of the controlCursor based on the timeElapsed (which is not the real time that has passed)
// Calculate the position of the controlCursor based on the timeElapsed (which is not the real time that has passed)
qreal x = score()->firstMeasure()->pos().x() + (score()->lastMeasure()->pos().x() - score()->firstMeasure()->pos().x()) * (_timeElapsed / (score()->duration() * 1000));
x -= score()->spatium();
_controlCursor->setRect(QRectF(x, _cursor->rect().y(), _cursor->rect().width(), _cursor->rect().height()));
update(_matrix.mapRect(_controlCursor->rect()).toRect().adjusted(-1,-1,1,1));
}

//---------------------------------------------------------
// isCursorDistanceReasonable
// check if the control cursor needs to be teleported
// to catch up with the playback cursor (for smooth panning)
//---------------------------------------------------------

bool ScoreView::isCursorDistanceReasonable()
{
qreal viewWidth = canvasViewport().width();
qreal controlX = _controlCursor->rect().x();
qreal playbackX = _cursor->rect().x();
qreal cursorDistance = abs(controlX - playbackX);
double maxLeftDistance = viewWidth * (_panSettings.controlCursorScreenPos + 0.07); // 0.05 left margin + 0.02 for making this less sensitive
double maxRightDistance = viewWidth * (1 - _panSettings.controlCursorScreenPos + 0.15); // teleporting to the right is harder to trigger (we don't want to overdo it)

if (controlX < playbackX && _panSettings.teleportRightEnabled)
return cursorDistance < maxRightDistance;

if (playbackX < controlX && _panSettings.teleportLeftEnabled)
return cursorDistance < maxLeftDistance;

return true;
}

//---------------------------------------------------------
// moveCursor
// move cursor in note input mode
Expand Down Expand Up @@ -5401,5 +5425,7 @@ void SmoothPanSettings::loadFromPreferences()
// advancedWeighting = preferences.getBool(PREF_PAN_WEIGHT_ADVANCED);
// cursorTimerDuration = preferences.getInt(PREF_PAN_SMART_TIMER_DURATION);
controlCursorScreenPos = preferences.getDouble(PREF_PAN_CURSOR_POS);
teleportLeftEnabled = preferences.getBool(PREF_PAN_TELEPORT_LEFT);
teleportRightEnabled = preferences.getBool(PREF_PAN_TELEPORT_RIGHT);
}
} // namespace Ms
33 changes: 20 additions & 13 deletions mscore/scoreview.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,34 @@ enum class ZoomIndex : char;
//---------------------------------------------------------

struct SmoothPanSettings {
double controlModifierBase { 1 };
double controlModifierSteps { 0.01 };
double minContinuousModifier { 0.2 };
double maxContinuousModifier { 5 };

// Changing the distance will change the sensitivity/accuracy/jitter of the algorithm. Larger absolut values are generally smoother.
double leftDistance { -250 };
// these are all actually loaded from the loadFromPreferences fuction so don't change these to change the default values,
// change the corresponding preferences
double controlModifierBase { 1 }; // initial speed modifier
double controlModifierSteps { 0.01 }; // modification steps for the modifier
double minContinuousModifier { 0.2 }; // minimum speed, 0.2 was chosen instead of 0 to remove stuttering
double maxContinuousModifier { 5 }; // maximum speed

// Changing the distance will change the sensitivity/accuracy/jitter of the algorithm. Larger absolute values are generally smoother.
double leftDistance { -250 }; // decelarate
double leftDistance1 { -125 };
double leftDistance2 { -50 };
double leftDistance3 { -25 };
double rightDistance { 500 };
double rightDistance { 500 }; // accelerate
double rightDistance1 { 250 };
double rightDistance2 { 125 };
double rightDistance3 { 50 };
double leftMod1 { 0.8 };
double leftMod2 { 0.9 };
// used to smoothly go back to normal speed when the playback cursor is getting closer
double leftMod1 { 0.8 }; // minimum speed at the first level
double leftMod2 { 0.9 }; // etc
double leftMod3 { 0.95 };
double rightMod1 { 1.2 };
double rightMod2 { 1.1 };
// used to smoothly go back to normal speed when the control cursor is getting closer to the playback cursor
double rightMod1 { 1.2 }; // maximum speed at the first level
double rightMod2 { 1.1 }; // etc
double rightMod3 { 1.05 };

double controlCursorScreenPos { 0.3 };
double controlCursorScreenPos { 0.3 };
bool teleportLeftEnabled { true };
bool teleportRightEnabled { false };

bool advancedWeighting { false }; // enables the 'smart weight'
double normalWeight { 1 };
Expand Down Expand Up @@ -358,6 +364,7 @@ class ScoreView : public QWidget, public MuseScoreView {

void moveCursor(const Fraction& tick);
void moveControlCursor(const Fraction& tick);
bool isCursorDistanceReasonable();
Fraction cursorTick() const;
void setCursorOn(bool);
void setBackground(QPixmap*);
Expand Down

0 comments on commit ff4e34c

Please sign in to comment.