From 95ccbacc4286fdf62f7adafe3b0b12d328e4ac23 Mon Sep 17 00:00:00 2001 From: James Ball Date: Fri, 29 Dec 2023 13:01:09 +0000 Subject: [PATCH] Double-click visualiser to make fullscreen --- Source/MainComponent.cpp | 40 +++++++++++++++++++---- Source/MainComponent.h | 1 - Source/PluginEditor.cpp | 23 ++++++++----- Source/PluginEditor.h | 13 +++++--- Source/components/VisualiserComponent.cpp | 25 ++++++++++++++ Source/components/VisualiserComponent.h | 12 +++++++ osci-render.jucer | 2 +- 7 files changed, 95 insertions(+), 21 deletions(-) diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 7595c216..90c65b28 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -90,7 +90,30 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess createFile.triggerClick(); }; - addAndMakeVisible(visualiser); + if (!pluginEditor.visualiserFullScreen) { + addAndMakeVisible(pluginEditor.visualiser); + } + pluginEditor.visualiser.setFullScreenCallback([this](FullScreenMode mode) { + if (mode == FullScreenMode::TOGGLE) { + pluginEditor.visualiserFullScreen = !pluginEditor.visualiserFullScreen; + } else if (mode == FullScreenMode::FULL_SCREEN) { + pluginEditor.visualiserFullScreen = true; + } else if (mode == FullScreenMode::MAIN_COMPONENT) { + pluginEditor.visualiserFullScreen = false; + } + + if (pluginEditor.visualiserFullScreen) { + removeChildComponent(&pluginEditor.visualiser); + pluginEditor.addAndMakeVisible(pluginEditor.visualiser); + } else { + pluginEditor.removeChildComponent(&pluginEditor.visualiser); + addAndMakeVisible(pluginEditor.visualiser); + } + pluginEditor.resized(); + pluginEditor.repaint(); + resized(); + repaint(); + }); addAndMakeVisible(openOscilloscope); openOscilloscope.onClick = [this] { @@ -151,15 +174,18 @@ void MainComponent::resized() { frequencyLabel.setBounds(bounds.removeFromTop(20)); bounds.removeFromTop(padding); - // openOscilloscope.setBounds(bounds.removeFromBottom(buttonHeight).withSizeKeepingCentre(160, buttonHeight)); - auto minDim = juce::jmin(bounds.getWidth(), bounds.getHeight()); - visualiser.setBounds(bounds.withSizeKeepingCentre(minDim, minDim)); + if (!pluginEditor.visualiserFullScreen) { + auto minDim = juce::jmin(bounds.getWidth(), bounds.getHeight()); + pluginEditor.visualiser.setBounds(bounds.withSizeKeepingCentre(minDim, minDim)); + } } void MainComponent::paint(juce::Graphics& g) { juce::GroupComponent::paint(g); - // add drop shadow to the visualiser - auto dc = juce::DropShadow(juce::Colours::black, 30, juce::Point(0, 0)); - dc.drawForRectangle(g, visualiser.getBounds()); + if (!pluginEditor.visualiserFullScreen) { + // add drop shadow to the visualiser + auto dc = juce::DropShadow(juce::Colours::black, 30, juce::Point(0, 0)); + dc.drawForRectangle(g, pluginEditor.visualiser.getBounds()); + } } diff --git a/Source/MainComponent.h b/Source/MainComponent.h index 57f0f051..99bd2edc 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -32,7 +32,6 @@ private: juce::ComboBox fileType; juce::TextButton createFile{"Create File"}; - VisualiserComponent visualiser{2, audioProcessor}; juce::TextButton openOscilloscope{"Open Oscilloscope"}; juce::Label frequencyLabel; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 47d6fecc..7e503ca6 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -80,6 +80,10 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr addAndMakeVisible(settings); addAndMakeVisible(resizerBar); + + if (visualiserFullScreen) { + addAndMakeVisible(visualiser); + } } OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() { @@ -130,6 +134,12 @@ void OscirenderAudioProcessorEditor::paint(juce::Graphics& g) { void OscirenderAudioProcessorEditor::resized() { auto area = getLocalBounds(); + + if (visualiserFullScreen) { + visualiser.setBounds(area); + return; + } + if (!usingNativeMenuBar) { menuBar.setBounds(area.removeFromTop(25)); } @@ -327,7 +337,7 @@ void OscirenderAudioProcessorEditor::updateCodeDocument() { } bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { - bool consumeKey1 = true; + bool consumeKey = false; { juce::SpinLock::ScopedLockType parserLock(audioProcessor.parsersLock); juce::SpinLock::ScopedLockType effectsLock(audioProcessor.effectsLock); @@ -344,6 +354,7 @@ bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { } changedFile = true; } + consumeKey = true; } else if (key.getTextCharacter() == 'k') { if (numFiles > 1) { currentFile--; @@ -352,8 +363,7 @@ bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { } changedFile = true; } - } else { - consumeKey1 = false; + consumeKey = true; } if (changedFile) { @@ -362,7 +372,6 @@ bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { } } - bool consumeKey2 = true; if (key.isKeyCode(juce::KeyPress::escapeKey)) { settings.disableMouseRotation(); } else if (key.getModifiers().isCommandDown() && key.getModifiers().isShiftDown() && key.getKeyCode() == 'S') { @@ -371,11 +380,9 @@ bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { saveProject(); } else if (key.getModifiers().isCommandDown() && key.getKeyCode() == 'O') { openProject(); - } else { - consumeKey2 = false; - } + } - return consumeKey1 || consumeKey2; + return consumeKey; } void OscirenderAudioProcessorEditor::newProject() { diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 7a80092f..e0b44102 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -35,14 +35,19 @@ public: void openAudioSettings(); void resetToDefault(); - std::atomic editingPerspective = false; - - OscirenderLookAndFeel lookAndFeel; private: OscirenderAudioProcessor& audioProcessor; - +public: + + OscirenderLookAndFeel lookAndFeel; + + std::atomic editingPerspective = false; + + VisualiserComponent visualiser{2, audioProcessor}; + std::atomic visualiserFullScreen = false; SettingsComponent settings{audioProcessor, *this}; VolumeComponent volume{audioProcessor}; + std::vector> codeDocuments; std::vector> codeEditors; juce::CodeEditorComponent::ColourScheme colourScheme; diff --git a/Source/components/VisualiserComponent.cpp b/Source/components/VisualiserComponent.cpp index eaba9ccf..3d6687a2 100644 --- a/Source/components/VisualiserComponent.cpp +++ b/Source/components/VisualiserComponent.cpp @@ -8,6 +8,9 @@ VisualiserComponent::VisualiserComponent(int numChannels, OscirenderAudioProcess roughness.textBox.setValue(4); intensity.textBox.setValue(1.0); + + setMouseCursor(juce::MouseCursor::PointingHandCursor); + setWantsKeyboardFocus(true); } VisualiserComponent::~VisualiserComponent() { @@ -15,6 +18,17 @@ VisualiserComponent::~VisualiserComponent() { stopThread(1000); } +void VisualiserComponent::setFullScreenCallback(std::function callback) { + fullScreenCallback = callback; +} + +void VisualiserComponent::mouseDoubleClick(const juce::MouseEvent& event) { + if (fullScreenCallback) { + fullScreenCallback(FullScreenMode::TOGGLE); + } + grabKeyboardFocus(); +} + void VisualiserComponent::setBuffer(std::vector& newBuffer) { juce::CriticalSection::ScopedLockType scope(lock); buffer.clear(); @@ -94,6 +108,17 @@ void VisualiserComponent::mouseDown(const juce::MouseEvent& event) { } } +bool VisualiserComponent::keyPressed(const juce::KeyPress& key) { + if (key.isKeyCode(juce::KeyPress::escapeKey)) { + if (fullScreenCallback) { + fullScreenCallback(FullScreenMode::MAIN_COMPONENT); + } + return true; + } + + return false; +} + void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle area, int channel) { juce::Path path; diff --git a/Source/components/VisualiserComponent.h b/Source/components/VisualiserComponent.h index 0e73b0d0..960a95e0 100644 --- a/Source/components/VisualiserComponent.h +++ b/Source/components/VisualiserComponent.h @@ -7,11 +7,19 @@ #include "../PluginProcessor.h" #include "LabelledTextBox.h" +enum class FullScreenMode { + TOGGLE, + FULL_SCREEN, + MAIN_COMPONENT, +}; + class VisualiserComponent : public juce::Component, public juce::Timer, public juce::Thread, public juce::MouseListener { public: VisualiserComponent(int numChannels, OscirenderAudioProcessor& p); ~VisualiserComponent() override; + void setFullScreenCallback(std::function callback); + void mouseDoubleClick(const juce::MouseEvent& event) override; void setBuffer(std::vector& buffer); void setColours(juce::Colour backgroundColour, juce::Colour waveformColour); void paintChannel(juce::Graphics&, juce::Rectangle bounds, int channel); @@ -20,6 +28,8 @@ public: void timerCallback() override; void run() override; void mouseDown(const juce::MouseEvent& event) override; + bool keyPressed(const juce::KeyPress& key) override; + private: const double BUFFER_LENGTH_SECS = 0.02; @@ -41,6 +51,8 @@ private: std::atomic active = true; std::shared_ptr consumer; + + std::function fullScreenCallback; void resetBuffer(); diff --git a/osci-render.jucer b/osci-render.jucer index f3d76000..0505817c 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -5,7 +5,7 @@ pluginCharacteristicsValue="pluginProducesMidiOut,pluginWantsMidiIn" pluginManufacturer="jameshball" aaxIdentifier="sh.ball.oscirender" cppLanguageStandard="20" projectLineFeed=" " headerPath="./include" - version="2.0.3" companyName="James H Ball" companyWebsite="https://osci-render.com" + version="2.0.4" companyName="James H Ball" companyWebsite="https://osci-render.com" companyEmail="james@ball.sh">