Skip to content

Commit

Permalink
Implement TouchScreen LongPress on Sliders
Browse files Browse the repository at this point in the history
1. Add a LongHoldMixin
2. Implement that on slider
3. In touch mode, as a result, you end up with a long hold
   opening the RMB menu

Addresses surge-synthesizer#5802
  • Loading branch information
baconpaul committed Mar 4, 2022
1 parent 0d565d2 commit df22249
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/surge-xt/gui/SurgeGUIUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ bool showCursor(SurgeStorage *storage)
return sc || tm;
};

bool isTouchMode(SurgeStorage *storage)
{
bool tm = Surge::Storage::getUserDefaultValue(storage, Surge::Storage::TouchMouseMode, false);
return tm;
}

/*
* We kinda want to know if we are standalone here, but don't have reference to the processor
* but that's a constant for a process (you can't mix standalone and not) so make it a static
Expand Down
1 change: 1 addition & 0 deletions src/surge-xt/gui/SurgeGUIUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ std::string toOSCaseForMenu(const std::string &menuName);

extern bool showCursor(SurgeStorage *storage);
extern bool allowKeyboardEdits(SurgeStorage *storage);
extern bool isTouchMode(SurgeStorage *storage);

bool get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y, float p2_x, float p2_y,
float p3_x, float p3_y, float *i_x, float *i_y);
Expand Down
6 changes: 6 additions & 0 deletions src/surge-xt/gui/widgets/ModulatableSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ void ModulatableSlider::mouseDrag(const juce::MouseEvent &event)
return;
}

mouseDragLongHold(event);

auto p = mouseDownFloatPosition;
float distance = event.position.getX() - p.getX();
if (orientation == ParamConfig::kVertical)
Expand Down Expand Up @@ -472,6 +474,7 @@ void ModulatableSlider::mouseDown(const juce::MouseEvent &event)
return;
}

mouseDownLongHold(event);
valueOnMouseDown = value;
modValueOnMouseDown = modValue;
lastDistance = 0.f;
Expand All @@ -481,6 +484,7 @@ void ModulatableSlider::mouseDown(const juce::MouseEvent &event)

void ModulatableSlider::mouseMove(const juce::MouseEvent &event)
{
mouseMoveLongHold(event);
enqueueFutureInfowindow(SurgeGUIEditor::InfoQAction::START, event.position);
}

Expand All @@ -499,6 +503,8 @@ void ModulatableSlider::mouseUp(const juce::MouseEvent &event)
hideInfowindowSoon();
}

mouseUpLongHold(event);

if (!Surge::GUI::showCursor(storage))
{
juce::Desktop::getInstance().getMainMouseSource().enableUnboundedMouseMovement(false);
Expand Down
1 change: 1 addition & 0 deletions src/surge-xt/gui/widgets/ModulatableSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ namespace Widgets
{
struct ModulatableSlider : public juce::Component,
public WidgetBaseMixin<ModulatableSlider>,
public LongHoldMixin<ModulatableSlider>,
public ModulatableControlInterface
{
ModulatableSlider();
Expand Down
70 changes: 70 additions & 0 deletions src/surge-xt/gui/widgets/WidgetBaseMixin.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "SkinSupport.h"
#include "SurgeGUICallbackInterfaces.h"
#include "SurgeGUIUtils.h"

#include "juce_gui_basics/juce_gui_basics.h"

Expand Down Expand Up @@ -185,6 +186,75 @@ struct WidgetBaseMixin : public Surge::GUI::SkinConsumingComponent,
return firstListenerOfType<SurgeGUIEditor>() && e.mods.isMiddleButtonDown();
}
};

template <typename T> struct LongHoldMixin
{
LongHoldMixin() {}
virtual ~LongHoldMixin()
{
if (timer && timer->isTimerRunning())
timer->stopTimer();
}
inline T *asT() { return static_cast<T *>(this); }

static constexpr uint32_t holdDelayTimeInMS = 1000;
void onLongHoldWrapper()
{
if (timer)
timer->stopTimer();
onLongHold();
}

virtual void onLongHold()
{
juce::ModifierKeys k{0};
asT()->notifyControlModifierClicked(k, true);
}

bool shouldLongHold()
{
// return true;
return GUI::isTouchMode(asT()->storage);
}

juce::Point<float> startingHoldPosition;
virtual void mouseDownLongHold(const juce::MouseEvent &e)
{
if (!shouldLongHold())
return;

startingHoldPosition = e.position.toFloat();
if (timer && timer->isTimerRunning())
timer->stopTimer();
timer = std::make_unique<LHCB>(this);
timer->startTimer(holdDelayTimeInMS); // ms
}
virtual void mouseMoveLongHold(const juce::MouseEvent &e)
{
if (e.position.getDistanceFrom(startingHoldPosition) > 4)
if (timer && timer->isTimerRunning())
timer->stopTimer();
}
virtual void mouseDragLongHold(const juce::MouseEvent &e)
{
if (e.position.getDistanceFrom(startingHoldPosition) > 1)
if (timer && timer->isTimerRunning())
timer->stopTimer();
}
virtual void mouseUpLongHold(const juce::MouseEvent &e)
{
if (timer && timer->isTimerRunning())
timer->stopTimer();
}

struct LHCB : public juce::Timer
{
LongHoldMixin<T> *that{nullptr};
LHCB(LongHoldMixin<T> *t) : that(t) {}
void timerCallback() override { that->onLongHoldWrapper(); }
};
std::unique_ptr<juce::Timer> timer;
};
} // namespace Widgets
} // namespace Surge
#endif // SURGE_XT_WIDGETBASEMIXIN_H

0 comments on commit df22249

Please sign in to comment.