AnalogTapeModel

Physical modelling signal processing for analog tape recording
Log | Files | Refs | Submodules | README | LICENSE

commit 6f364d77c6c593f44c86bb77b337eb0e8c6aac69
parent 74f606a0d1eaf443356ed781afc0858ca419a543
Author: jatinchowdhury18 <[email protected]>
Date:   Mon, 12 Apr 2021 17:30:39 -0700

Allow for two-finger scroll on iOS (#182)

* Allow for two-finger scroll

* {Apply clang-format}

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Diffstat:
MPlugin/Source/GUI/Assets/gui_ios.xml | 3+++
MPlugin/Source/GUI/CMakeLists.txt | 2++
APlugin/Source/GUI/DragToScrollListener.cpp | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
APlugin/Source/GUI/DragToScrollListener.h | 31+++++++++++++++++++++++++++++++
MPlugin/Source/GUI/MyLNF.cpp | 1+
APlugin/Source/GUI/ScrollView.cpp | 40++++++++++++++++++++++++++++++++++++++++
MPlugin/Source/GUI/ScrollView.h | 43++++++++++---------------------------------
7 files changed, 184 insertions(+), 33 deletions(-)

diff --git a/Plugin/Source/GUI/Assets/gui_ios.xml b/Plugin/Source/GUI/Assets/gui_ios.xml @@ -70,6 +70,7 @@ parameter="ifilt_onoff" name="Filters On/Off" tooltip="Turns the pre-processing filters on or off."/> </View> </View> + <View margin="0" padding="0" flex-grow="0.07" background-color="00000000"/> <View display="tabbed" padding="0" background-color="FF31323A" lookAndFeel="MyLNF"> <View flex-direction="column" tab-color="" background-color="FF31323A" padding="0" tab-caption="Tape" margin="0"> @@ -98,6 +99,7 @@ name="Tone On/Off" tooltip="Turns the tone control processing on or off."/> </View> </View> + <View margin="0" padding="0" flex-grow="0.07" background-color="00000000"/> <View display="tabbed" padding="0" background-color="FF31323A" flex-grow="1.5" lookAndFeel="MyLNF"> <View flex-direction="column" tab-caption="Loss" tab-color="" background-color="FF31323A" @@ -188,6 +190,7 @@ parameter="chew_onoff" name="Chew On/Off" tooltip="Turns the chew processing on or off."/> </View> </View> + <View margin="0" padding="0" flex-grow="0.07" background-color="00000000"/> <View display="tabbed" padding="0" margin="2" background-color="FF31323A" lookAndFeel="MyLNF"> <View tab-caption="Flutter" flex-direction="column" background-color="FF31323A"> <FlutterMenu margin="0" padding="0" background-color="00000000" diff --git a/Plugin/Source/GUI/CMakeLists.txt b/Plugin/Source/GUI/CMakeLists.txt @@ -1,6 +1,8 @@ target_sources(CHOWTapeModel PRIVATE AutoUpdating.cpp + DragToScrollListener.cpp MyLNF.cpp + ScrollView.cpp TitleComp.cpp TooltipComp.cpp WowFlutterMenu.cpp diff --git a/Plugin/Source/GUI/DragToScrollListener.cpp b/Plugin/Source/GUI/DragToScrollListener.cpp @@ -0,0 +1,97 @@ +#include "DragToScrollListener.h" + +DragToScrollListener::DragToScrollListener (Viewport& v) : viewport (v) +{ + viewport.getViewedComponent()->addMouseListener (this, true); + offsetX.addListener (this); + offsetY.addListener (this); + offsetX.behaviour.setMinimumVelocity (100); + offsetY.behaviour.setMinimumVelocity (100); +} + +DragToScrollListener::~DragToScrollListener() +{ + viewport.getViewedComponent()->removeMouseListener (this); + Desktop::getInstance().removeGlobalMouseListener (this); +} + +void DragToScrollListener::positionChanged (ViewportDragPosition&, double) +{ + if (! isDragging) + return; + + viewport.setViewPosition (originalViewPos - Point<int> ((int) offsetX.getPosition(), (int) offsetY.getPosition())); +} + +static int getNumSources() +{ + return Desktop::getInstance().getNumDraggingMouseSources(); +} + +void DragToScrollListener::mouseDown (const MouseEvent&) +{ + if (! isGlobalMouseListener && getNumSources() >= 2) + { + offsetX.setPosition (offsetX.getPosition()); + offsetY.setPosition (offsetY.getPosition()); + + // switch to a global mouse listener so we still receive mouseUp events + // if the original event component is deleted + viewport.getViewedComponent()->removeMouseListener (this); + Desktop::getInstance().addGlobalMouseListener (this); + + isGlobalMouseListener = true; + } +} + +void DragToScrollListener::mouseDrag (const MouseEvent& e) +{ + if (getNumSources() >= 2 && ! doesMouseEventComponentBlockViewportDrag (e.eventComponent)) + { + auto totalOffset = e.getOffsetFromDragStart().toFloat(); + + if (! isDragging && totalOffset.getDistanceFromOrigin() > 8.0f) + { + isDragging = true; + + originalViewPos = viewport.getViewPosition(); + offsetX.setPosition (0.0); + offsetX.beginDrag(); + offsetY.setPosition (0.0); + offsetY.beginDrag(); + } + + if (isDragging) + { + offsetX.drag (totalOffset.x); + offsetY.drag (totalOffset.y); + } + } +} + +void DragToScrollListener::mouseUp (const MouseEvent&) +{ + if (isGlobalMouseListener && getNumSources() < 2) + endDragAndClearGlobalMouseListener(); +} + +void DragToScrollListener::endDragAndClearGlobalMouseListener() +{ + offsetX.endDrag(); + offsetY.endDrag(); + isDragging = false; + + viewport.getViewedComponent()->addMouseListener (this, true); + Desktop::getInstance().removeGlobalMouseListener (this); + + isGlobalMouseListener = false; +} + +bool DragToScrollListener::doesMouseEventComponentBlockViewportDrag (const Component* eventComp) +{ + for (auto c = eventComp; c != nullptr && c != &viewport; c = c->getParentComponent()) + if (c->getViewportIgnoreDragFlag()) + return true; + + return false; +} diff --git a/Plugin/Source/GUI/DragToScrollListener.h b/Plugin/Source/GUI/DragToScrollListener.h @@ -0,0 +1,31 @@ +#pragma once + +#include <JuceHeader.h> + +using ViewportDragPosition = AnimatedPosition<AnimatedPositionBehaviours::ContinuousWithMomentum>; + +class DragToScrollListener : private MouseListener, + private ViewportDragPosition::Listener +{ +public: + DragToScrollListener (Viewport& v); + ~DragToScrollListener() override; + + void positionChanged (ViewportDragPosition&, double) override; + + void mouseDown (const MouseEvent&) override; + void mouseDrag (const MouseEvent& e) override; + void mouseUp (const MouseEvent&) override; + + void endDragAndClearGlobalMouseListener(); + bool doesMouseEventComponentBlockViewportDrag (const Component* eventComp); + +private: + Viewport& viewport; + ViewportDragPosition offsetX, offsetY; + Point<int> originalViewPos; + bool isDragging = false; + bool isGlobalMouseListener = false; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragToScrollListener) +}; diff --git a/Plugin/Source/GUI/MyLNF.cpp b/Plugin/Source/GUI/MyLNF.cpp @@ -88,6 +88,7 @@ void MyLNF::createTabTextLayout (const TabBarButton& button, float length, float void MyLNF::drawTabButton (TabBarButton& button, Graphics& g, bool /*isMouseOver*/, bool /*isMouseDown*/) { + button.setViewportIgnoreDragFlag (true); const Rectangle<int> activeArea (button.getActiveArea()); const TabbedButtonBar::Orientation o = button.getTabbedButtonBar().getOrientation(); diff --git a/Plugin/Source/GUI/ScrollView.cpp b/Plugin/Source/GUI/ScrollView.cpp @@ -0,0 +1,40 @@ +#include "ScrollView.h" + +ScrollView::ScrollView (foleys::MagicGUIBuilder& builder, ValueTree node) + : foleys::GuiItem (builder, node), + baseView (builder, node) +{ + addAndMakeVisible (viewport); + addAndMakeVisible (baseView); + viewport.setViewedComponent (&baseView, false); + + viewport.setScrollBarsShown (true, false); + viewport.getVerticalScrollBar().setColour (ScrollBar::thumbColourId, Colour (0xFFEAA92C).withAlpha (0.7f)); + viewport.setScrollBarThickness (10); + viewport.setScrollOnDragEnabled (false); + + dragToScrollListener = std::make_unique<DragToScrollListener> (viewport); +} + +void ScrollView::resized() +{ + viewport.setBounds (getLocalBounds()); + baseView.setSize (getWidth() - viewport.getScrollBarThickness(), jmax (420, getHeight())); +} + +void ScrollView::update() +{ + baseView.getConfigNode() = configNode.createCopy(); + baseView.update(); +} + +void ScrollView::createSubComponents() +{ + baseView.getConfigNode() = configNode.createCopy(); + baseView.createSubComponents(); +} + +foleys::GuiItem* ScrollView::findGuiItemWithId (const String& name) +{ + return baseView.findGuiItemWithId (name); +} diff --git a/Plugin/Source/GUI/ScrollView.h b/Plugin/Source/GUI/ScrollView.h @@ -1,50 +1,27 @@ #pragma once +#include "DragToScrollListener.h" + class ScrollView : public foleys::GuiItem { public: FOLEYS_DECLARE_GUI_FACTORY (ScrollView) - ScrollView (foleys::MagicGUIBuilder& builder, ValueTree node) - : foleys::GuiItem (builder, node), - baseView (builder, node) - { - addAndMakeVisible (viewport); - addAndMakeVisible (baseView); - viewport.setViewedComponent (&baseView, false); - - viewport.setScrollBarsShown (true, false); - viewport.getVerticalScrollBar().setColour (ScrollBar::thumbColourId, Colour (0xFFEAA92C).withAlpha (0.7f)); - viewport.setScrollBarThickness (10); - } - - void resized() override - { - viewport.setBounds (getLocalBounds()); - baseView.setSize (getWidth() - viewport.getScrollBarThickness(), jmax (420, getHeight())); - } - - void update() override - { - baseView.getConfigNode() = configNode.createCopy(); - baseView.update(); - } - - bool isContainer() const override { return true; } + ScrollView (foleys::MagicGUIBuilder& builder, ValueTree node); - void createSubComponents() override - { - baseView.getConfigNode() = configNode.createCopy(); - baseView.createSubComponents(); - } + void resized() override; + void update() override; Component* getWrappedComponent() override { return &viewport; } - - foleys::GuiItem* findGuiItemWithId (const String& name) override { return baseView.findGuiItemWithId (name); } + bool isContainer() const override { return true; } + void createSubComponents() override; + foleys::GuiItem* findGuiItemWithId (const String& name) override; private: Viewport viewport; foleys::Container baseView; + std::unique_ptr<DragToScrollListener> dragToScrollListener; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScrollView) };