From 673a527212f6008d27fe90f9fb5824ec9340aac5 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Wed, 20 Oct 2021 18:32:32 -0400 Subject: [PATCH] Fix TearOut objections Closes #5247 - Center initial position - Handle close and reskin and swap type closes - Pink line in mseg gone - Mouse drag at correct speed - Positions remember as defaults keys --- src/common/UserDefaults.cpp | 9 +++ src/common/UserDefaults.h | 4 ++ src/surge-xt/gui/SurgeGUIEditor.cpp | 40 ++++++++++++ src/surge-xt/gui/SurgeGUIEditorOverlays.cpp | 12 ++-- src/surge-xt/gui/overlays/MSEGEditor.cpp | 2 +- src/surge-xt/gui/overlays/OverlayComponent.h | 6 +- src/surge-xt/gui/overlays/OverlayWrapper.cpp | 64 ++++++++++++++------ src/surge-xt/gui/overlays/OverlayWrapper.h | 13 +++- 8 files changed, 121 insertions(+), 29 deletions(-) diff --git a/src/common/UserDefaults.cpp b/src/common/UserDefaults.cpp index b9d353e0882..e7884ac3fc8 100644 --- a/src/common/UserDefaults.cpp +++ b/src/common/UserDefaults.cpp @@ -168,6 +168,15 @@ void initMaps() case WSAnalysisOverlayLocation: r = "wsAnalysisOverlayLocation"; break; + case TuningOverlayLocationTearOut: + r = "tuningOverlayLocationTearOut"; + break; + case ModlistOverlayLocationTearOut: + r = "modlistOverlayLocationTearOut"; + break; + case MSEGFormulaOverlayLocationTearOut: + r = "msegFormulaOverlayLocationTearOut"; + break; case nKeys: break; } diff --git a/src/common/UserDefaults.h b/src/common/UserDefaults.h index df371869ccf..2ff8938922d 100644 --- a/src/common/UserDefaults.h +++ b/src/common/UserDefaults.h @@ -69,6 +69,10 @@ enum DefaultKey // streamed as strings so feel free to change the order to whate MSEGFormulaOverlayLocation, WSAnalysisOverlayLocation, + TuningOverlayLocationTearOut, + ModlistOverlayLocationTearOut, + MSEGFormulaOverlayLocationTearOut, + nKeys }; /** diff --git a/src/surge-xt/gui/SurgeGUIEditor.cpp b/src/surge-xt/gui/SurgeGUIEditor.cpp index 3b4c331f746..43408ec5b62 100644 --- a/src/surge-xt/gui/SurgeGUIEditor.cpp +++ b/src/surge-xt/gui/SurgeGUIEditor.cpp @@ -3649,7 +3649,21 @@ void SurgeGUIEditor::reloadFromSkin() // update overlays, if opened if (isAnyOverlayPresent(MSEG_EDITOR)) { + bool tornOut = false; + juce::Point tearOutPos; + auto olw = getOverlayWrapperIfOpen(MSEG_EDITOR); + if (olw && olw->isTornOut()) + { + tornOut = true; + tearOutPos = olw->currentTearOutLocation(); + } showOverlay(SurgeGUIEditor::MSEG_EDITOR); + if (tornOut) + { + auto olw = getOverlayWrapperIfOpen(MSEG_EDITOR); + if (olw) + olw->doTearOut(tearOutPos); + } } // update waveshaper analyzer if opened @@ -5243,13 +5257,27 @@ void SurgeGUIEditor::lfoShapeChanged(int prior, int curr) } bool hadExtendedEditor = false; + bool isTornOut = false; + juce::Point tearOutPos; if (isAnyOverlayPresent(MSEG_EDITOR)) { + auto olw = getOverlayWrapperIfOpen(MSEG_EDITOR); + if (olw && olw->isTornOut()) + { + isTornOut = true; + tearOutPos = olw->currentTearOutLocation(); + } closeOverlay(SurgeGUIEditor::MSEG_EDITOR); hadExtendedEditor = true; } if (isAnyOverlayPresent(FORMULA_EDITOR)) { + auto olw = getOverlayWrapperIfOpen(FORMULA_EDITOR); + if (olw && olw->isTornOut()) + { + isTornOut = true; + tearOutPos = olw->currentTearOutLocation(); + } closeOverlay(FORMULA_EDITOR); hadExtendedEditor = true; } @@ -5259,10 +5287,22 @@ void SurgeGUIEditor::lfoShapeChanged(int prior, int curr) if (curr == lt_mseg) { showOverlay(SurgeGUIEditor::MSEG_EDITOR); + if (isTornOut) + { + auto olw = getOverlayWrapperIfOpen(MSEG_EDITOR); + if (olw) + olw->doTearOut(tearOutPos); + } } if (curr == lt_formula) { showOverlay(FORMULA_EDITOR); + if (isTornOut) + { + auto olw = getOverlayWrapperIfOpen(FORMULA_EDITOR); + if (olw) + olw->doTearOut(tearOutPos); + } } } diff --git a/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp b/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp index b88a4166d92..b8039ad8907 100644 --- a/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp +++ b/src/surge-xt/gui/SurgeGUIEditorOverlays.cpp @@ -24,6 +24,7 @@ #include "overlays/OverlayWrapper.h" #include "widgets/MainFrame.h" #include "widgets/WaveShaperSelector.h" +#include "UserDefaults.h" std::unique_ptr SurgeGUIEditor::makeStorePatchDialog() { @@ -138,7 +139,8 @@ std::unique_ptr SurgeGUIEditor::createOverlay auto h = getWindowSizeY() - yPos - xBuf; pt->setEnclosingParentPosition(juce::Rectangle(xBuf, yPos, w, h)); pt->setEnclosingParentTitle("Patch Database"); - pt->setCanTearOut(true); + jassert(false); // Make a key for me please! + pt->setCanTearOut({true, Surge::Storage::nKeys}); return pt; } break; @@ -187,7 +189,7 @@ std::unique_ptr SurgeGUIEditor::createOverlay Surge::Storage::findReplaceSubstring(title, std::string("LFO"), std::string("MSEG")); mse->setEnclosingParentTitle(title); - mse->setCanTearOut(true); + mse->setCanTearOut({true, Surge::Storage::MSEGFormulaOverlayLocationTearOut}); locationForMSFR(mse.get()); return mse; } @@ -230,7 +232,7 @@ std::unique_ptr SurgeGUIEditor::createOverlay Surge::Storage::findReplaceSubstring(title, std::string("LFO"), std::string("Formula")); pt->setEnclosingParentTitle(title); - pt->setCanTearOut(true); + pt->setCanTearOut({true, Surge::Storage::MSEGFormulaOverlayLocationTearOut}); locationForMSFR(pt.get()); return pt; } @@ -263,7 +265,7 @@ std::unique_ptr SurgeGUIEditor::createOverlay pt->setTuning(synth->storage.currentTuning); pt->setEnclosingParentPosition(juce::Rectangle(px, py, w, h)); pt->setEnclosingParentTitle("Tuning Editor"); - pt->setCanTearOut(true); + pt->setCanTearOut({true, Surge::Storage::TuningOverlayLocationTearOut}); pt->defaultLocation = dl; pt->setCanMoveAround(std::make_pair(true, Surge::Storage::TuningOverlayLocation)); return pt; @@ -346,7 +348,7 @@ std::unique_ptr SurgeGUIEditor::createOverlay pt->setEnclosingParentTitle("Modulation List"); pt->setEnclosingParentPosition(r); pt->setCanMoveAround(std::make_pair(true, Surge::Storage::ModlistOverlayLocation)); - pt->setCanTearOut(true); + pt->setCanTearOut({true, Surge::Storage::ModlistOverlayLocationTearOut}); pt->defaultLocation = dl; return pt; } diff --git a/src/surge-xt/gui/overlays/MSEGEditor.cpp b/src/surge-xt/gui/overlays/MSEGEditor.cpp index cba9828c232..4bc84c0749d 100644 --- a/src/surge-xt/gui/overlays/MSEGEditor.cpp +++ b/src/surge-xt/gui/overlays/MSEGEditor.cpp @@ -3259,7 +3259,7 @@ void MSEGEditor::forceRefresh() } } -void MSEGEditor::paint(juce::Graphics &g) { g.fillAll(juce::Colours::orchid); } +void MSEGEditor::paint(juce::Graphics &g) { g.fillAll(juce::Colours::black); } void MSEGEditor::resized() { diff --git a/src/surge-xt/gui/overlays/OverlayComponent.h b/src/surge-xt/gui/overlays/OverlayComponent.h index 5c19da367ef..177903b6346 100644 --- a/src/surge-xt/gui/overlays/OverlayComponent.h +++ b/src/surge-xt/gui/overlays/OverlayComponent.h @@ -39,9 +39,9 @@ struct OverlayComponent : juce::Component void setHasIndependentClose(bool b) { hasIndependentClose = b; } bool getHasIndependentClose() { return hasIndependentClose; } - bool canTearOut{false}; - void setCanTearOut(bool b) { canTearOut = b; } - bool getCanTearOut() { return canTearOut; } + std::pair canTearOut{false, Surge::Storage::nKeys}; + void setCanTearOut(std::pair b) { canTearOut = b; } + std::pair getCanTearOut() { return canTearOut; } virtual void onTearOutChanged(bool isTornOut) {} std::pair canMoveAround{false, Surge::Storage::nKeys}; diff --git a/src/surge-xt/gui/overlays/OverlayWrapper.cpp b/src/surge-xt/gui/overlays/OverlayWrapper.cpp index 10e94a8f627..082fc1338cc 100644 --- a/src/surge-xt/gui/overlays/OverlayWrapper.cpp +++ b/src/surge-xt/gui/overlays/OverlayWrapper.cpp @@ -18,6 +18,7 @@ #include "SurgeImage.h" #include "SurgeGUIEditor.h" #include "OverlayComponent.h" +#include "widgets/MainFrame.h" namespace Surge { @@ -133,20 +134,38 @@ struct TearOutWindow : public juce::DocumentWindow } OverlayWrapper *wrapping{nullptr}; - void closeButtonPressed() + void closeButtonPressed() override { if (wrapping) { wrapping->onClose(); } } - void minimiseButtonPressed() + void minimiseButtonPressed() override { if (wrapping) { wrapping->doTearIn(); } } + + int outstandingMoves = 0; + void moved() override + { + outstandingMoves++; + // writing every move would be "bad". Add a 1 second delay. + juce::Timer::callAfterDelay(1000, [this]() { this->moveUpdate(); }); + } + void moveUpdate() + { + outstandingMoves--; + if (outstandingMoves == 0 && wrapping->storage) + { + auto tl = getBounds().getTopLeft(); + Surge::Storage::updateUserDefaultValue( + wrapping->storage, wrapping->canTearOutPair.second, std::make_pair(tl.x, tl.y)); + } + } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TearOutWindow); }; @@ -190,6 +209,24 @@ void OverlayWrapper::doTearOut(const juce::Point &showAt) dw->setVisible(true); if (showAt.x >= 0 && showAt.y >= 0) dw->setTopLeftPosition(showAt.x, showAt.y); + else + { + auto pt = std::make_pair(-1, -1); + if (storage) + pt = Surge::Storage::getUserDefaultValue(storage, canTearOutPair.second, pt); + auto dt = juce::Desktop::getInstance() + .getDisplays() + .getDisplayForPoint(editor->frame->getBounds().getTopLeft()) + ->userArea; + auto dtp = juce::Point((dt.getWidth() - w) / 2, (dt.getHeight() - h) / 2); + if (pt.first > 0 && pt.second > 0 && pt.first < dt.getWidth() - w / 2 && + pt.second < dt.getHeight() - h / 2) + { + dtp.x = pt.first; + dtp.y = pt.second; + } + dw->setTopLeftPosition(dtp); + } dw->toFront(true); dw->wrapping = this; supressInteriorDecoration(); @@ -236,8 +273,9 @@ void OverlayWrapper::mouseDown(const juce::MouseEvent &e) if (c && c->getCanMoveAround()) { isDragging = true; - distanceFromCornerToMouseDown = - localPointToGlobal(e.position) - getBounds().getTopLeft().toFloat(); + + // This is borrowed from juce::ComponentDragger + mouseDownWithinTarget = e.getEventRelativeTo(this).getMouseDownPosition(); repaint(); } } @@ -283,19 +321,11 @@ void OverlayWrapper::mouseDrag(const juce::MouseEvent &e) auto c = getPrimaryChildAsOverlayComponent(); if (c && c->getCanMoveAround()) { - auto gp = localPointToGlobal(e.position); - auto newTopLeft = gp - distanceFromCornerToMouseDown; - newTopLeft.x = std::max(0.f, newTopLeft.x); - newTopLeft.y = std::max(0.f, newTopLeft.y); - - auto pw = 1.f * getParentComponent()->getWidth(); - auto ph = 1.f * getParentComponent()->getHeight(); - newTopLeft.x = std::min(newTopLeft.x, pw - getWidth()); - newTopLeft.y = std::min(newTopLeft.y, ph - getHeight()); - - auto b = getBounds(); - auto q = juce::Rectangle(newTopLeft.x, newTopLeft.y, b.getWidth(), b.getHeight()); - setBounds(q); + // Borrowed from juce::ComponentDragger + auto bounds = getBounds(); + bounds += getLocalPoint(nullptr, e.source.getScreenPosition()).roundToInt() - + mouseDownWithinTarget; + setBounds(bounds); } } diff --git a/src/surge-xt/gui/overlays/OverlayWrapper.h b/src/surge-xt/gui/overlays/OverlayWrapper.h index b16f8824c18..546ce24733b 100644 --- a/src/surge-xt/gui/overlays/OverlayWrapper.h +++ b/src/surge-xt/gui/overlays/OverlayWrapper.h @@ -17,6 +17,7 @@ #define SURGE_XT_OVERLAYWRAPPER_H #include "SkinSupport.h" +#include "UserDefaults.h" #include "juce_gui_basics/juce_gui_basics.h" @@ -55,7 +56,8 @@ struct OverlayWrapper : public juce::Component, std::unique_ptr closeButton, tearOutButton; void buttonClicked(juce::Button *button) override; - juce::Point distanceFromCornerToMouseDown; + juce::Point mouseDownWithinTarget; + bool isDragging{false}; bool allowDrag{true}; void mouseDown(const juce::MouseEvent &) override; @@ -66,8 +68,13 @@ struct OverlayWrapper : public juce::Component, SurgeImage *icon{nullptr}; void setIcon(SurgeImage *d) { icon = d; } - bool canTearOut{false}; - void setCanTearOut(bool b) { canTearOut = b; } + std::pair canTearOutPair{false, Surge::Storage::nKeys}; + bool canTearOut; + void setCanTearOut(std::pair b) + { + canTearOutPair = b; + canTearOut = b.first; + } void doTearOut(const juce::Point &showAt = juce::Point(-1, -1)); void doTearIn(); bool isTornOut();