From 8542f5e8ac6e656d27fe18040edfc66c5f9a3311 Mon Sep 17 00:00:00 2001 From: Geert Bevin Date: Sun, 12 Nov 2023 15:48:26 -0500 Subject: [PATCH] Properly handle pausing anywhere in the UI. Fix for plugins initializing the portlist needlessly. --- .../MacOSX/showmidi.xcodeproj/project.pbxproj | 2 + .../ShowMIDI_SharedCode.vcxproj | 1 + .../ShowMIDI_SharedCode.vcxproj.filters | 3 ++ Builds/iOS/ShowMIDI.xcodeproj/project.pbxproj | 2 + Source/MainLayoutComponent.cpp | 31 +++++++++++--- Source/MainLayoutComponent.h | 3 +- Source/PauseManager.h | 31 ++++++++++++++ Source/PluginEditor.cpp | 17 ++------ Source/SidebarComponent.cpp | 40 ++++++++++++------- Source/StandaloneDevicesComponent.cpp | 23 +++-------- Source/StandaloneDevicesComponent.h | 5 ++- Source/StandaloneWindow.cpp | 2 +- showmidi.jucer | 1 + 13 files changed, 108 insertions(+), 53 deletions(-) create mode 100644 Source/PauseManager.h diff --git a/Builds/MacOSX/showmidi.xcodeproj/project.pbxproj b/Builds/MacOSX/showmidi.xcodeproj/project.pbxproj index d1b40ea..7c28249 100644 --- a/Builds/MacOSX/showmidi.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/showmidi.xcodeproj/project.pbxproj @@ -127,6 +127,7 @@ 174103AD3F224D30061D8C33 /* JetBrainsMono-Italic.ttf */ /* JetBrainsMono-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file.ttf; name = "JetBrainsMono-Italic.ttf"; path = "../../Fonts/JetBrainsMono-Italic.ttf"; sourceTree = SOURCE_ROOT; }; 17ACFE7C6558A3BFE6DE79C9 /* CoreMIDI.framework */ /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; 18E89D52FCDF34385983843E /* AUv3 AppExtension */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShowMIDI.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 1E8AF652B5355FF40C9CC3C2 /* PauseManager.h */ /* PauseManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PauseManager.h; path = ../../Source/PauseManager.h; sourceTree = SOURCE_ROOT; }; 1F9AA665E4E0435365DA2D52 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../JuceLibraryCode/modules/juce_data_structures; sourceTree = SOURCE_ROOT; }; 226AF0455917BA09A7EFD367 /* StandaloneWindow.h */ /* StandaloneWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StandaloneWindow.h; path = ../../Source/StandaloneWindow.h; sourceTree = SOURCE_ROOT; }; 2343ECC7F67FA6AD9E72214D /* PluginProcessor.cpp */ /* PluginProcessor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginProcessor.cpp; path = ../../Source/PluginProcessor.cpp; sourceTree = SOURCE_ROOT; }; @@ -548,6 +549,7 @@ BB0B90FF903B2C484336242E, E071CD1AE979F36DF9BCBCCF, 88AAC6E05E409AD97864C094, + 1E8AF652B5355FF40C9CC3C2, 5E8212E205DE721CE55589C7, A7D51DA4FAC7916144DC9C37, 2343ECC7F67FA6AD9E72214D, diff --git a/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj b/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj index 9bc6899..d8a268d 100644 --- a/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj +++ b/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj @@ -2429,6 +2429,7 @@ + diff --git a/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj.filters b/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj.filters index 35e44ba..16b56a0 100644 --- a/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj.filters +++ b/Builds/VisualStudio2022/ShowMIDI_SharedCode.vcxproj.filters @@ -3108,6 +3108,9 @@ ShowMIDI\Source + + ShowMIDI\Source + ShowMIDI\Source diff --git a/Builds/iOS/ShowMIDI.xcodeproj/project.pbxproj b/Builds/iOS/ShowMIDI.xcodeproj/project.pbxproj index 7cf8c5d..1f74bff 100644 --- a/Builds/iOS/ShowMIDI.xcodeproj/project.pbxproj +++ b/Builds/iOS/ShowMIDI.xcodeproj/project.pbxproj @@ -108,6 +108,7 @@ 17ACFE7C6558A3BFE6DE79C9 /* CoreMIDI.framework */ /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; 18E89D52FCDF34385983843E /* AUv3 AppExtension */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShowMIDI.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 1C6731403A5CDD50BA00A1BF /* Images.xcassets */ /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ShowMIDI/Images.xcassets; sourceTree = SOURCE_ROOT; }; + 1E8AF652B5355FF40C9CC3C2 /* PauseManager.h */ /* PauseManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PauseManager.h; path = ../../Source/PauseManager.h; sourceTree = SOURCE_ROOT; }; 1F9AA665E4E0435365DA2D52 /* juce_data_structures */ /* juce_data_structures */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_data_structures; path = ../../JuceLibraryCode/modules/juce_data_structures; sourceTree = SOURCE_ROOT; }; 226AF0455917BA09A7EFD367 /* StandaloneWindow.h */ /* StandaloneWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StandaloneWindow.h; path = ../../Source/StandaloneWindow.h; sourceTree = SOURCE_ROOT; }; 2343ECC7F67FA6AD9E72214D /* PluginProcessor.cpp */ /* PluginProcessor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginProcessor.cpp; path = ../../Source/PluginProcessor.cpp; sourceTree = SOURCE_ROOT; }; @@ -390,6 +391,7 @@ BB0B90FF903B2C484336242E, E071CD1AE979F36DF9BCBCCF, 88AAC6E05E409AD97864C094, + 1E8AF652B5355FF40C9CC3C2, 5E8212E205DE721CE55589C7, A7D51DA4FAC7916144DC9C37, 2343ECC7F67FA6AD9E72214D, diff --git a/Source/MainLayoutComponent.cpp b/Source/MainLayoutComponent.cpp index 40599f3..4fb455d 100644 --- a/Source/MainLayoutComponent.cpp +++ b/Source/MainLayoutComponent.cpp @@ -23,15 +23,19 @@ namespace showmidi { - struct MainLayoutComponent::Pimpl : public SidebarListener + struct MainLayoutComponent::Pimpl : public SidebarListener, public KeyListener { static constexpr int DEFAULT_WINDOW_HEIGHT = 600; - Pimpl(MainLayoutComponent* owner, SettingsManager& manager, MainLayoutType type, Component* content) : + Pimpl(MainLayoutComponent* owner, SettingsManager& settings, PauseManager& pause, MainLayoutType type, Component* content) : owner_(owner), - settingsManager_(manager), + settingsManager_(settings), + pauseManager_(pause), layoutType_(type) { + owner_->setWantsKeyboardFocus(true); + owner_->addKeyListener(this); + sidebar_.setBounds(0, 0, getSidebarWidth(), DEFAULT_WINDOW_HEIGHT); owner_->addAndMakeVisible(sidebar_); @@ -47,6 +51,22 @@ namespace showmidi viewport_.setBounds(sidebar_.getWidth(), 0, default_width, DEFAULT_WINDOW_HEIGHT); owner_->addAndMakeVisible(viewport_); } + + ~Pimpl() + { + owner_->removeKeyListener(this); + } + + bool keyPressed(const KeyPress& key, Component*) override + { + if (key.getKeyCode() == KeyPress::spaceKey) + { + pauseManager_.togglePaused(); + return true; + } + + return false; + } bool isInterestedInFileDrag(const StringArray& files) { @@ -84,7 +104,7 @@ namespace showmidi return sidebar_.getActiveWidth(); } - void sidebarChangedWidth() + void sidebarChangedWidth() override { if (layoutType_ == MainLayoutType::layoutStandalone) { @@ -94,6 +114,7 @@ namespace showmidi MainLayoutComponent* const owner_; SettingsManager& settingsManager_; + PauseManager& pauseManager_; const MainLayoutType layoutType_; SidebarComponent sidebar_ { settingsManager_, @@ -104,7 +125,7 @@ namespace showmidi JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; - MainLayoutComponent::MainLayoutComponent(SettingsManager& m, MainLayoutType t, Component* c) : pimpl_(new Pimpl(this, m, t, c)) + MainLayoutComponent::MainLayoutComponent(SettingsManager& s, PauseManager& p, MainLayoutType t, Component* c) : pimpl_(new Pimpl(this, s, p, t, c)) { setSize(pimpl_->sidebar_.getWidth() + pimpl_->viewport_.getWidth(), Pimpl::DEFAULT_WINDOW_HEIGHT); } diff --git a/Source/MainLayoutComponent.h b/Source/MainLayoutComponent.h index 679deb1..e0335f0 100644 --- a/Source/MainLayoutComponent.h +++ b/Source/MainLayoutComponent.h @@ -19,6 +19,7 @@ #include +#include "PauseManager.h" #include "SettingsManager.h" namespace showmidi @@ -32,7 +33,7 @@ namespace showmidi class MainLayoutComponent : public Component, public FileDragAndDropTarget { public: - MainLayoutComponent(SettingsManager&, MainLayoutType, Component*); + MainLayoutComponent(SettingsManager&, PauseManager&, MainLayoutType, Component*); virtual ~MainLayoutComponent(); bool isInterestedInFileDrag(const StringArray&); diff --git a/Source/PauseManager.h b/Source/PauseManager.h new file mode 100644 index 0000000..ff80079 --- /dev/null +++ b/Source/PauseManager.h @@ -0,0 +1,31 @@ +/* + * This file is part of ShowMIDI. + * Copyright (command) 2023 Uwyn LLC. https://www.uwyn.com + * + * ShowMIDI is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ShowMIDI is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +namespace showmidi +{ + class PauseManager + { + public: + virtual ~PauseManager() {}; + + virtual void togglePaused() = 0; + }; +} diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 4b78526..5eaaa5d 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -27,7 +27,7 @@ namespace showmidi { - struct ShowMIDIPluginAudioProcessorEditor::Pimpl : public MultiTimer, public KeyListener, public SettingsManager + struct ShowMIDIPluginAudioProcessorEditor::Pimpl : public MultiTimer, public SettingsManager, public PauseManager { static constexpr int DEFAULT_EDITOR_HEIGHT = 600; @@ -55,7 +55,6 @@ namespace showmidi owner_->setSize(layout_.getWidth(), DEFAULT_EDITOR_HEIGHT); owner_->setWantsKeyboardFocus(true); - owner_->addKeyListener(this); // 30Hz startTimer(RenderDevices, 1000 / 30); @@ -65,8 +64,6 @@ namespace showmidi ~Pimpl() { - owner_->removeKeyListener(this); - stopTimer(RenderDevices); } @@ -75,15 +72,9 @@ namespace showmidi midiDevice_.handleIncomingMidiMessage(msg); } - bool keyPressed(const KeyPress& key, Component*) override + void togglePaused() override { - if (key.getKeyCode() == KeyPress::spaceKey) - { - setPaused(!paused_); - return true; - } - - return false; + setPaused(!paused_); } void setPaused(bool paused) @@ -160,7 +151,7 @@ namespace showmidi ShowMIDIPluginAudioProcessor& audioProcessor_; MidiDeviceComponent midiDevice_; - MainLayoutComponent layout_ { *this, MainLayoutType::layoutPlugin, &midiDevice_ }; + MainLayoutComponent layout_ { *this, *this, MainLayoutType::layoutPlugin, &midiDevice_ }; MidiDevicesListeners midiDevicesListeners_; diff --git a/Source/SidebarComponent.cpp b/Source/SidebarComponent.cpp index 6b1533f..926494f 100644 --- a/Source/SidebarComponent.cpp +++ b/Source/SidebarComponent.cpp @@ -39,7 +39,6 @@ namespace showmidi manager_(manager), sidebarType_(type), listener_(listener), - portList_(manager), settings_(manager), about_(manager.getSettings().getTheme()) { @@ -57,16 +56,19 @@ namespace showmidi owner_->addChildComponent(expandedButton_); owner_->addAndMakeVisible(helpButton_); owner_->addChildComponent(settingsButton_); - - portViewport_.setScrollOnDragMode(Viewport::ScrollOnDragMode::all); - portViewport_.setScrollBarsShown(true, false); - portViewport_.setScrollBarThickness(Theme::SCROLLBAR_THICKNESS); - portViewport_.setViewedComponent(&portList_, false); - owner_->addChildComponent(portViewport_); - + if (sidebarType_ == SidebarType::sidebarExpandable) { collapsedButton_.setVisible(true); + + portList_ = std::make_unique(manager_); + + portViewport_ = std::make_unique(); + portViewport_->setScrollOnDragMode(Viewport::ScrollOnDragMode::all); + portViewport_->setScrollBarsShown(true, false); + portViewport_->setScrollBarThickness(Theme::SCROLLBAR_THICKNESS); + portViewport_->setViewedComponent(portList_.get(), false); + owner_->addChildComponent(portViewport_.get()); } else { @@ -85,7 +87,10 @@ namespace showmidi collapsedButton_.setVisible(false); expandedButton_.setVisible(true); settingsButton_.setVisible(true); - portViewport_.setVisible(true); + if (portViewport_.get()) + { + portViewport_->setVisible(true); + } settings_.setVisible(false); about_.setVisible(false); @@ -98,7 +103,10 @@ namespace showmidi collapsedButton_.setVisible(true); expandedButton_.setVisible(false); settingsButton_.setVisible(false); - portViewport_.setVisible(false); + if (portViewport_.get()) + { + portViewport_->setVisible(false); + } settings_.setVisible(false); about_.setVisible(false); @@ -163,9 +171,11 @@ namespace showmidi settingsButton_.setBoundsForTouch(owner_->getWidth() - expandedSvg_->getWidth() - X_SETTINGS, Y_SETTINGS, settingsSvg_->getWidth(), settingsSvg_->getHeight()); - - portViewport_.setBounds(0, Y_PORTLIST, owner_->getWidth(), owner_->getHeight() - Y_PORTLIST - PORTLIST_BOTTOM_MARGIN); - portList_.setSize(owner_->getWidth() - portViewport_.getScrollBarThickness(), std::max(portViewport_.getHeight(), portList_.getVisibleHeight())); + if (portViewport_.get()) + { + portViewport_->setBounds(0, Y_PORTLIST, owner_->getWidth(), owner_->getHeight() - Y_PORTLIST - PORTLIST_BOTTOM_MARGIN); + portList_->setSize(owner_->getWidth() - portViewport_->getScrollBarThickness(), std::max(portViewport_->getHeight(), portList_->getVisibleHeight())); + } about_.setTopLeftPosition(owner_->getWidth() + X_SETTINGS, owner_->getHeight() - Y_SETTINGS - about_.getHeight()); settings_.setTopLeftPosition(owner_->getWidth() + X_SETTINGS, Y_SETTINGS); } @@ -196,8 +206,8 @@ namespace showmidi PaintedButton expandedButton_; PaintedButton helpButton_; PaintedButton settingsButton_; - Viewport portViewport_; - PortListComponent portList_; + std::unique_ptr portViewport_; + std::unique_ptr portList_; SettingsComponent settings_; AboutComponent about_; diff --git a/Source/StandaloneDevicesComponent.cpp b/Source/StandaloneDevicesComponent.cpp index 2f5ca58..799b0ff 100644 --- a/Source/StandaloneDevicesComponent.cpp +++ b/Source/StandaloneDevicesComponent.cpp @@ -24,7 +24,7 @@ namespace showmidi { - struct StandaloneDevicesComponent::Pimpl : public MultiTimer, public KeyListener, public MidiDevicesListener + struct StandaloneDevicesComponent::Pimpl : public MultiTimer, public MidiDevicesListener { static constexpr int MIN_MIDI_DEVICES_AUTO_SHOWN = 1; static constexpr int MAX_MIDI_DEVICES_AUTO_SHOWN = 6; @@ -37,9 +37,6 @@ namespace showmidi Pimpl(StandaloneDevicesComponent* owner) : owner_(owner) { - owner_->setWantsKeyboardFocus(true); - owner_->addKeyListener(this); - SMApp.getMidiDevicesListeners().add(this); refreshMidiDevices(); @@ -53,7 +50,6 @@ namespace showmidi ~Pimpl() { SMApp.getMidiDevicesListeners().remove(this); - owner_->removeKeyListener(this); stopTimer(RenderDevices); @@ -88,26 +84,19 @@ namespace showmidi } } - bool keyPressed(const KeyPress& key, Component*) override + void togglePaused() { - if (key.getKeyCode() == KeyPress::spaceKey) - { - setPaused(!paused_); - return true; - } - - return false; + setPaused(!paused_); } void setPaused(bool paused) { SMApp.setWindowTitle(String("ShowMIDI") + (paused ? " (paused)" : "")); + paused_ = paused; ScopedLock g(midiDevicesLock_); for (HashMap::Iterator i(midiDevices_); i.next();) { - paused_ = paused; - i.getValue()->setPaused(paused); } } @@ -201,8 +190,6 @@ namespace showmidi if (devices_to_remove.size() > 0 || new_devices_preset) { - setPaused(false); - owner_->removeAllChildren(); // remove the devices that disappeared @@ -227,6 +214,7 @@ namespace showmidi if (component == nullptr) { component = new MidiDeviceComponent(SMApp, info); + component->setPaused(paused_); midiDevices_.set(info.identifier, component); } @@ -262,4 +250,5 @@ namespace showmidi StandaloneDevicesComponent::~StandaloneDevicesComponent() = default; void StandaloneDevicesComponent::paint(Graphics& g) { pimpl_->paint(g); } + void StandaloneDevicesComponent::togglePaused() { pimpl_->togglePaused(); } } diff --git a/Source/StandaloneDevicesComponent.h b/Source/StandaloneDevicesComponent.h index 80a9b84..4b9bda1 100644 --- a/Source/StandaloneDevicesComponent.h +++ b/Source/StandaloneDevicesComponent.h @@ -19,11 +19,12 @@ #include +#include "PauseManager.h" #include "Theme.h" namespace showmidi { - class StandaloneDevicesComponent : public Component + class StandaloneDevicesComponent : public Component, public PauseManager { public: StandaloneDevicesComponent(); @@ -31,6 +32,8 @@ namespace showmidi void paint(Graphics&) override; + void togglePaused() override; + struct Pimpl; private: std::unique_ptr pimpl_; diff --git a/Source/StandaloneWindow.cpp b/Source/StandaloneWindow.cpp index 8058b53..e2d56ae 100644 --- a/Source/StandaloneWindow.cpp +++ b/Source/StandaloneWindow.cpp @@ -53,7 +53,7 @@ namespace showmidi StandaloneWindow* const owner_; StandaloneDevicesComponent main_; - MainLayoutComponent layout_ { SMApp, MainLayoutType::layoutStandalone, &main_ }; + MainLayoutComponent layout_ { SMApp, main_, MainLayoutType::layoutStandalone, &main_ }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl) }; diff --git a/showmidi.jucer b/showmidi.jucer index f6a5a2b..118ae04 100644 --- a/showmidi.jucer +++ b/showmidi.jucer @@ -54,6 +54,7 @@ +