diff --git a/Source/ObjComponent.cpp b/Source/PerspectiveComponent.cpp similarity index 86% rename from Source/ObjComponent.cpp rename to Source/PerspectiveComponent.cpp index 3c48cf9..11dad36 100644 --- a/Source/ObjComponent.cpp +++ b/Source/PerspectiveComponent.cpp @@ -1,8 +1,8 @@ -#include "ObjComponent.h" +#include "PerspectiveComponent.h" #include "PluginEditor.h" #include -ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { +PerspectiveComponent::PerspectiveComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { setText("3D Settings"); juce::Desktop::getInstance().addGlobalMouseListener(this); @@ -50,12 +50,12 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor fixedRotateZ->setTooltip(tooltip); } -ObjComponent::~ObjComponent() { +PerspectiveComponent::~PerspectiveComponent() { juce::Desktop::getInstance().removeGlobalMouseListener(this); } // listen for mouse movement and rotate the object if mouseRotate is enabled -void ObjComponent::mouseMove(const juce::MouseEvent& e) { +void PerspectiveComponent::mouseMove(const juce::MouseEvent& e) { if (mouseRotate.getToggleState()) { auto globalEvent = e.getEventRelativeTo(&pluginEditor); auto width = pluginEditor.getWidth(); @@ -68,11 +68,11 @@ void ObjComponent::mouseMove(const juce::MouseEvent& e) { } } -void ObjComponent::disableMouseRotation() { +void PerspectiveComponent::disableMouseRotation() { mouseRotate.setToggleState(false, juce::NotificationType::dontSendNotification); } -void ObjComponent::resized() { +void PerspectiveComponent::resized() { auto area = getLocalBounds().withTrimmedTop(20).reduced(20); double rowHeight = 30; perspective.setBounds(area.removeFromTop(rowHeight)); diff --git a/Source/ObjComponent.h b/Source/PerspectiveComponent.h similarity index 85% rename from Source/ObjComponent.h rename to Source/PerspectiveComponent.h index 52c8f64..3840716 100644 --- a/Source/ObjComponent.h +++ b/Source/PerspectiveComponent.h @@ -6,10 +6,10 @@ #include "components/SvgButton.h" class OscirenderAudioProcessorEditor; -class ObjComponent : public juce::GroupComponent { +class PerspectiveComponent : public juce::GroupComponent { public: - ObjComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&); - ~ObjComponent(); + PerspectiveComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&); + ~PerspectiveComponent(); void resized() override; void mouseMove(const juce::MouseEvent& event) override; @@ -33,5 +33,5 @@ private: std::shared_ptr fixedRotateY = std::make_shared("fixedRotateY", juce::String(BinaryData::fixed_rotate_svg), "white", "red", audioProcessor.perspectiveEffect->fixedRotateY); std::shared_ptr fixedRotateZ = std::make_shared("fixedRotateZ", juce::String(BinaryData::fixed_rotate_svg), "white", "red", audioProcessor.perspectiveEffect->fixedRotateZ); - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ObjComponent) + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PerspectiveComponent) }; diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 486d9d5..a013a01 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -145,7 +145,7 @@ public: perspectiveEffect, std::vector{ new EffectParameter("3D Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0), - new EffectParameter("Focal Length", "Controls the focal length of the 3D perspective effect. A higher focal length makes the image look more flat, and a lower focal length makes the image look more 3D.", "perspectiveFocalLength", VERSION_HINT, 1.0, 0.1, 10.0), + new EffectParameter("Focal Length", "Controls the focal length of the 3D perspective effect. A higher focal length makes the image look more flat, and a lower focal length makes the image look more 3D.", "perspectiveFocalLength", VERSION_HINT, 1.0, 0.0, 10.0), new EffectParameter("Distance (z)", "Controls how far away the 3D object is drawn away from the camera (the Z position).", "perspectiveZPos", VERSION_HINT, 0.1, 0.0, 1.0), new EffectParameter("Rotate Speed", "Controls how fast the 3D object rotates in the direction determined by the rotation sliders below.", "perspectiveRotateSpeed", VERSION_HINT, 0.0, -1.0, 1.0), new EffectParameter("Rotate X", "Controls the rotation of the object in the X axis.", "perspectiveRotateX", VERSION_HINT, 1.0, -1.0, 1.0), diff --git a/Source/SettingsComponent.cpp b/Source/SettingsComponent.cpp index bcabdf7..c115ed1 100644 --- a/Source/SettingsComponent.cpp +++ b/Source/SettingsComponent.cpp @@ -4,25 +4,30 @@ SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { addAndMakeVisible(effects); addAndMakeVisible(main); + addAndMakeVisible(perspective); addAndMakeVisible(midiResizerBar); addAndMakeVisible(mainResizerBar); + addAndMakeVisible(mainPerspectiveResizerBar); addAndMakeVisible(effectResizerBar); addAndMakeVisible(midi); addChildComponent(lua); - addChildComponent(obj); addChildComponent(txt); midiLayout.setItemLayout(0, -0.1, -1.0, -1.0); - midiLayout.setItemLayout(1, 7, 7, 7); + midiLayout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE); midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, CLOSED_PREF_SIZE); mainLayout.setItemLayout(0, -0.1, -0.9, -0.4); - mainLayout.setItemLayout(1, 7, 7, 7); + mainLayout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE); mainLayout.setItemLayout(2, -0.1, -0.9, -0.6); - effectLayout.setItemLayout(0, -0.1, -1.0, -0.63); - effectLayout.setItemLayout(1, 7, 7, 7); - effectLayout.setItemLayout(2, -0.1, -0.9, -0.37); + mainPerspectiveLayout.setItemLayout(0, RESIZER_BAR_SIZE, -1.0, -1.0); + mainPerspectiveLayout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE); + mainPerspectiveLayout.setItemLayout(2, CLOSED_PREF_SIZE, -1.0, CLOSED_PREF_SIZE); + + effectLayout.setItemLayout(0, CLOSED_PREF_SIZE, -1.0, -0.6); + effectLayout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE); + effectLayout.setItemLayout(2, CLOSED_PREF_SIZE, -1.0, -0.4); } @@ -34,28 +39,30 @@ void SettingsComponent::resized() { area.removeFromBottom(5); juce::Component dummy; + juce::Component dummy2; juce::Component* midiComponents[] = { &dummy, &midiResizerBar, &midi }; midiLayout.layOutComponents(midiComponents, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), true, true); - juce::Component* columns[] = { &main, &mainResizerBar, &dummy }; + juce::Component* columns[] = { &dummy2, &mainResizerBar, &dummy }; mainLayout.layOutComponents(columns, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), false, true); + juce::Component* rows1[] = { &main, &mainPerspectiveResizerBar, &perspective }; + mainPerspectiveLayout.layOutComponents(rows1, 3, dummy2.getX(), dummy2.getY(), dummy2.getWidth(), dummy2.getHeight(), true, true); + juce::Component* effectSettings = nullptr; if (lua.isVisible()) { effectSettings = &lua; - } else if (obj.isVisible()) { - effectSettings = &obj; } else if (txt.isVisible()) { effectSettings = &txt; } - juce::Component* rows[] = { &effects, &effectResizerBar, effectSettings }; + juce::Component* rows2[] = {&effects, &effectResizerBar, effectSettings}; // use the dummy component to work out the bounds of the rows if (effectSettings != nullptr) { - effectLayout.layOutComponents(rows, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), true, true); + effectLayout.layOutComponents(rows2, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), true, true); } else { effects.setBounds(dummy.getBounds()); } @@ -66,14 +73,11 @@ void SettingsComponent::resized() { void SettingsComponent::fileUpdated(juce::String fileName) { juce::String extension = fileName.fromLastOccurrenceOf(".", true, false); lua.setVisible(false); - obj.setVisible(false); txt.setVisible(false); if (fileName.isEmpty() || audioProcessor.objectServerRendering) { // do nothing } else if (extension == ".lua") { lua.setVisible(true); - } else if (extension == ".obj") { - obj.setVisible(true); } else if (extension == ".txt") { txt.setVisible(true); } @@ -86,36 +90,40 @@ void SettingsComponent::update() { } void SettingsComponent::disableMouseRotation() { - obj.disableMouseRotation(); + perspective.disableMouseRotation(); } -void SettingsComponent::toggleMidiComponent() { +void SettingsComponent::toggleLayout(juce::StretchableLayoutManager& layout, double prefSize) { double minSize, maxSize, preferredSize; - midiLayout.getItemLayout(2, minSize, maxSize, preferredSize); + layout.getItemLayout(2, minSize, maxSize, preferredSize); + if (preferredSize == CLOSED_PREF_SIZE) { - midiLayout.setItemLayout(0, -0.1, -1.0, -0.7); - midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, -0.3); + double otherPrefSize = -(1 + prefSize); + layout.setItemLayout(2, CLOSED_PREF_SIZE, -1.0, prefSize); + layout.setItemLayout(0, CLOSED_PREF_SIZE, -1.0, otherPrefSize); } else { - midiLayout.setItemLayout(0, -0.1, -1.0, -1.0); - midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, CLOSED_PREF_SIZE); + layout.setItemLayout(2, CLOSED_PREF_SIZE, -1.0, CLOSED_PREF_SIZE); + layout.setItemLayout(0, CLOSED_PREF_SIZE, -1.0, -1.0); } resized(); } void SettingsComponent::mouseMove(const juce::MouseEvent& event) { - // if mouse over midi component, change cursor to link cursor - if (midi.getBounds().removeFromTop(CLOSED_PREF_SIZE).contains(event.getPosition())) { - setMouseCursor(juce::MouseCursor::PointingHandCursor); - } else { - setMouseCursor(juce::MouseCursor::NormalCursor); + for (int i = 0; i < 4; i++) { + if (toggleComponents[i]->getBounds().removeFromTop(CLOSED_PREF_SIZE).contains(event.getPosition())) { + setMouseCursor(juce::MouseCursor::PointingHandCursor); + return; + } } + setMouseCursor(juce::MouseCursor::NormalCursor); } void SettingsComponent::mouseDown(const juce::MouseEvent& event) { - // if mouse over midi component, toggle midi component - if (midi.getBounds().removeFromTop(CLOSED_PREF_SIZE).contains(event.getPosition())) { - toggleMidiComponent(); + for (int i = 0; i < 4; i++) { + if (toggleComponents[i]->getBounds().removeFromTop(CLOSED_PREF_SIZE).contains(event.getPosition())) { + toggleLayout(*toggleLayouts[i], prefSizes[i]); + } } } @@ -128,8 +136,8 @@ void SettingsComponent::paint(juce::Graphics& g) { if (lua.isVisible()) { dc.drawForRectangle(g, lua.getBounds()); - } else if (obj.isVisible()) { - dc.drawForRectangle(g, obj.getBounds()); + } else if (perspective.isVisible()) { + dc.drawForRectangle(g, perspective.getBounds()); } else if (txt.isVisible()) { dc.drawForRectangle(g, txt.getBounds()); } diff --git a/Source/SettingsComponent.h b/Source/SettingsComponent.h index 37caa04..1f8ccb1 100644 --- a/Source/SettingsComponent.h +++ b/Source/SettingsComponent.h @@ -4,7 +4,7 @@ #include "PluginProcessor.h" #include "MainComponent.h" #include "LuaComponent.h" -#include "ObjComponent.h" +#include "PerspectiveComponent.h" #include "TxtComponent.h" #include "EffectsComponent.h" #include "MidiComponent.h" @@ -18,7 +18,7 @@ public: void fileUpdated(juce::String fileName); void update(); void disableMouseRotation(); - void toggleMidiComponent(); + void toggleLayout(juce::StretchableLayoutManager& layout, double prefSize); void mouseMove(const juce::MouseEvent& event) override; void mouseDown(const juce::MouseEvent& event) override; void paint(juce::Graphics& g) override; @@ -29,19 +29,26 @@ private: MainComponent main{audioProcessor, pluginEditor}; LuaComponent lua{audioProcessor, pluginEditor}; - ObjComponent obj{audioProcessor, pluginEditor}; + PerspectiveComponent perspective{audioProcessor, pluginEditor}; TxtComponent txt{audioProcessor, pluginEditor}; EffectsComponent effects{audioProcessor, pluginEditor}; MidiComponent midi{audioProcessor, pluginEditor}; const double CLOSED_PREF_SIZE = 30.0; + const double RESIZER_BAR_SIZE = 7.0; juce::StretchableLayoutManager midiLayout; juce::StretchableLayoutResizerBar midiResizerBar{&midiLayout, 1, false}; juce::StretchableLayoutManager mainLayout; juce::StretchableLayoutResizerBar mainResizerBar{&mainLayout, 1, true}; + juce::StretchableLayoutManager mainPerspectiveLayout; + juce::StretchableLayoutResizerBar mainPerspectiveResizerBar{&mainPerspectiveLayout, 1, false}; juce::StretchableLayoutManager effectLayout; juce::StretchableLayoutResizerBar effectResizerBar{&effectLayout, 1, false}; + juce::Component* toggleComponents[4] = { &midi, &perspective, &lua, &txt }; + juce::StretchableLayoutManager* toggleLayouts[4] = { &midiLayout, &mainPerspectiveLayout, &effectLayout, &effectLayout }; + double prefSizes[4] = { -0.3, -0.5, -0.4, -0.4 }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SettingsComponent) }; \ No newline at end of file diff --git a/Source/audio/CustomEffect.cpp b/Source/audio/CustomEffect.cpp index 19a4f24..cf8b79a 100644 --- a/Source/audio/CustomEffect.cpp +++ b/Source/audio/CustomEffect.cpp @@ -12,7 +12,6 @@ CustomEffect::~CustomEffect() { Point CustomEffect::apply(int index, Point input, const std::vector& values, double sampleRate) { auto effectScale = values[0]; - auto depth = 1.0 + (values[1] - 0.1) * 3; auto x = input.x; auto y = input.y; diff --git a/Source/audio/PerspectiveEffect.cpp b/Source/audio/PerspectiveEffect.cpp index f002ff9..c5380c3 100644 --- a/Source/audio/PerspectiveEffect.cpp +++ b/Source/audio/PerspectiveEffect.cpp @@ -12,7 +12,7 @@ PerspectiveEffect::~PerspectiveEffect() {} Point PerspectiveEffect::apply(int index, Point input, const std::vector& values, double sampleRate) { auto effectScale = values[0]; - auto focalLength = values[1]; + auto focalLength = juce::jmax(values[1], 0.001); auto depth = 1.0 + (values[2] - 0.1) * 3; auto rotateSpeed = linearSpeedToActualSpeed(values[3]); double baseRotateX, baseRotateY, baseRotateZ; diff --git a/osci-render.jucer b/osci-render.jucer index 2ca6d73..2553709 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -403,9 +403,10 @@ - - + +