From b46339e7d91963cd11d6dc821ef13bd5a1fdd77d Mon Sep 17 00:00:00 2001 From: rghvdberg Date: Sun, 24 Feb 2019 16:31:44 +0100 Subject: [PATCH] Scrollwheel 607 - Add scrollwheel support to various controls (#650) Scrollwheel support for most of the UI elements, but most importantly, for sliders when moused over allows quick editing with scroll gestures. Closes #605 flashing popups Closes #607 scroll wheel support --- src/common/gui/CHSwitch2.cpp | 23 +++++++++++++++++++++ src/common/gui/CHSwitch2.h | 2 ++ src/common/gui/CNumberField.cpp | 16 ++++++++++++++- src/common/gui/CNumberField.h | 2 +- src/common/gui/CSurgeSlider.cpp | 33 +++++++++++++++++++++++++++++++ src/common/gui/CSurgeSlider.h | 2 ++ src/common/gui/SurgeGUIEditor.cpp | 12 +++++++++++ 7 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/common/gui/CHSwitch2.cpp b/src/common/gui/CHSwitch2.cpp index 6489088189d..f11c265c07f 100644 --- a/src/common/gui/CHSwitch2.cpp +++ b/src/common/gui/CHSwitch2.cpp @@ -107,3 +107,26 @@ CMouseEventResult CHSwitch2::onMouseMoved(CPoint& where, const CButtonState& but } return kMouseEventNotHandled; } +bool CHSwitch2::onWheel(const CPoint& where, const float& distance, const CButtonState& buttons) +{ + float newVal=value; + float rate = 1.0f; + float range = getRange(); + if (columns >1) + { + rate = range / (float)columns; + newVal += rate * distance; + } + else + { + rate = range / (float)rows; + newVal += rate * -distance; // flip distance (==direction) because it makes more sense when wheeling + } + beginEdit(); + value = newVal; + bounceValue(); + if (listener) + listener->valueChanged(this); + setValue(value); + return true; +} \ No newline at end of file diff --git a/src/common/gui/CHSwitch2.h b/src/common/gui/CHSwitch2.h index d933d3944e2..12fd8bedca2 100644 --- a/src/common/gui/CHSwitch2.h +++ b/src/common/gui/CHSwitch2.h @@ -39,5 +39,7 @@ class CHSwitch2 : public VSTGUI::CHorizontalSwitch virtual VSTGUI::CMouseEventResult onMouseMoved(VSTGUI::CPoint& where, const VSTGUI::CButtonState& buttons); ///< called when a mouse move event occurs + virtual bool + onWheel (const VSTGUI::CPoint& where, const float& distance, const VSTGUI::CButtonState& buttons); ///< called when scrollwheel events occurs CLASS_METHODS(CHSwitch2, VSTGUI::CControl) }; diff --git a/src/common/gui/CNumberField.cpp b/src/common/gui/CNumberField.cpp index bce10161e3b..e7576affe88 100644 --- a/src/common/gui/CNumberField.cpp +++ b/src/common/gui/CNumberField.cpp @@ -657,7 +657,21 @@ CMouseEventResult CNumberField::onMouseMoved(CPoint& where, const CButtonState& } return kMouseEventHandled; } - +bool CNumberField::onWheel(const CPoint& where, const float& distance, const CButtonState& buttons) +{ + beginEdit(); + i_value += int(distance); + int steps = i_max - i_min; + int offset = i_value - i_min; + float multiplier = 1.0f / (float) steps; + value = (float) offset * multiplier; + setIntValue(i_value); // also does bounceValue for i_value and value ..and setDirty + setValue(value); + if (isDirty() && listener) + listener->valueChanged(this); + endEdit(); + return true; +} //------------------------------------------------------------------------ /*void CParamEdit::mouse (CDrawContext *pContext, CPoint &where, long buttons) { diff --git a/src/common/gui/CNumberField.h b/src/common/gui/CNumberField.h index 0e8e66b5984..d016129a479 100644 --- a/src/common/gui/CNumberField.h +++ b/src/common/gui/CNumberField.h @@ -223,7 +223,7 @@ class CNumberField : public VSTGUI::CControl virtual VSTGUI::CMouseEventResult onMouseDown(VSTGUI::CPoint& where, const VSTGUI::CButtonState& buttons); virtual VSTGUI::CMouseEventResult onMouseUp(VSTGUI::CPoint& where, const VSTGUI::CButtonState& buttons); virtual VSTGUI::CMouseEventResult onMouseMoved(VSTGUI::CPoint& where, const VSTGUI::CButtonState& buttons); - // virtual bool onWheel (VSTGUI::CDrawContext *pContext, const VSTGUI::CPoint &where, float distance); + virtual bool onWheel(const VSTGUI::CPoint& where, const float& distance, const VSTGUI::CButtonState& buttons); bool altlook; private: diff --git a/src/common/gui/CSurgeSlider.cpp b/src/common/gui/CSurgeSlider.cpp index c7a9b9b0369..e4e7d99a165 100644 --- a/src/common/gui/CSurgeSlider.cpp +++ b/src/common/gui/CSurgeSlider.cpp @@ -435,3 +435,36 @@ void CSurgeSlider::setBipolar(bool b) setDirty(); } +bool CSurgeSlider::onWheel(const VSTGUI::CPoint& where, const float &distance, const VSTGUI::CButtonState& buttons) +{ + // shift + scrollwheel for fine control + double rate = 0.1 * moverate; + if (buttons & kShift) + rate *= 0.05; + + edit_value = modmode ? &modval : &value; + oldVal = *edit_value; + + beginEdit(); + *edit_value += rate * distance; + bounceValue(); + if (modmode) + { + setModValue(*edit_value); + } + else + { + setValue(value); + } + setDirty(); + if (isDirty() && listener) + listener->valueChanged(this); + //endEdit(); + /* + ** No need to call endEdit since the timer in SurgeGUIEditor will close the + ** info window, and SurgeGUIEditor will make sure a window + ** doesn't appear twice + */ + edit_value = nullptr; + return true; +} \ No newline at end of file diff --git a/src/common/gui/CSurgeSlider.h b/src/common/gui/CSurgeSlider.h index 228af53e706..c0b5caeb836 100644 --- a/src/common/gui/CSurgeSlider.h +++ b/src/common/gui/CSurgeSlider.h @@ -28,6 +28,8 @@ class CSurgeSlider : public CCursorHidingControl virtual void draw(VSTGUI::CDrawContext*); // virtual void mouse (VSTGUI::CDrawContext *pContext, VSTGUI::CPoint &where, long buttons = -1); // virtual bool onWheel (VSTGUI::CDrawContext *pContext, const VSTGUI::CPoint &where, float distance); + virtual bool + onWheel(const VSTGUI::CPoint& where, const float &distane, const VSTGUI::CButtonState& buttons); virtual VSTGUI::CMouseEventResult onMouseDown(VSTGUI::CPoint& where, diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp index b05ece6f322..b6280a3b6f7 100644 --- a/src/common/gui/SurgeGUIEditor.cpp +++ b/src/common/gui/SurgeGUIEditor.cpp @@ -2426,10 +2426,22 @@ void SurgeGUIEditor::draw_infowindow(int ptag, CControl* control, bool modulate, if (buttons || forceMB) { + // make sure an infowindow doesn't appear twice + if (((CParameterTooltip*)infowindow)->isVisible()) + { + ((CParameterTooltip*)infowindow)->Hide(); + ((CParameterTooltip*)infowindow)->invalid(); + } + ((CParameterTooltip*)infowindow)->setViewSize(r); ((CParameterTooltip*)infowindow)->Show(); infowindow->invalid(); + // on Linux the infoview closes too soon + #if LINUX + clear_infoview_countdown = 100; + #else clear_infoview_countdown = 40; + #endif } else {