diff --git a/Resources/svg/close.svg b/Resources/svg/close.svg
index ba9d8f7..096198c 100644
--- a/Resources/svg/close.svg
+++ b/Resources/svg/close.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
index c369d51..50b144b 100644
--- a/Source/PluginEditor.cpp
+++ b/Source/PluginEditor.cpp
@@ -17,7 +17,7 @@ void OscirenderAudioProcessorEditor::registerFileRemovedCallback() {
});
}
-OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioProcessor& p) : CommonPluginEditor(p, "osci-render", "osci", 1100, 750), audioProcessor(p), collapseButton("Collapse", juce::Colours::white, juce::Colours::white, juce::Colours::white) {
+OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioProcessor& p) : CommonPluginEditor(p, "osci-render", "osci", 1100, 770), audioProcessor(p), collapseButton("Collapse", juce::Colours::white, juce::Colours::white, juce::Colours::white) {
// Register the file removal callback
registerFileRemovedCallback();
diff --git a/Source/SettingsComponent.cpp b/Source/SettingsComponent.cpp
index a5c3bcf..87cf493 100644
--- a/Source/SettingsComponent.cpp
+++ b/Source/SettingsComponent.cpp
@@ -13,7 +13,7 @@ SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudi
addChildComponent(frame);
double midiLayoutPreferredSize = std::any_cast(audioProcessor.getProperty("midiLayoutPreferredSize", pluginEditor.CLOSED_PREF_SIZE));
- double mainLayoutPreferredSize = std::any_cast(audioProcessor.getProperty("mainLayoutPreferredSize", -0.4));
+ double mainLayoutPreferredSize = std::any_cast(audioProcessor.getProperty("mainLayoutPreferredSize", -0.5));
midiLayout.setItemLayout(0, -0.1, -1.0, -(1.0 + midiLayoutPreferredSize));
midiLayout.setItemLayout(1, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE);
@@ -46,8 +46,6 @@ void SettingsComponent::resized() {
mainLayout.layOutComponents(columns, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), false, true);
auto bounds = dummy2.getBounds();
- perspective.setBounds(bounds.removeFromBottom(120));
- bounds.removeFromBottom(pluginEditor.RESIZER_BAR_SIZE);
main.setBounds(bounds);
juce::Component* effectSettings = nullptr;
@@ -65,6 +63,9 @@ void SettingsComponent::resized() {
dummyBounds.removeFromBottom(pluginEditor.RESIZER_BAR_SIZE);
}
+ perspective.setBounds(dummyBounds.removeFromBottom(120));
+ dummyBounds.removeFromBottom(pluginEditor.RESIZER_BAR_SIZE);
+
effects.setBounds(dummyBounds);
if (isVisible() && getWidth() > 0 && getHeight() > 0) {
diff --git a/Source/components/EffectTypeGridComponent.cpp b/Source/components/EffectTypeGridComponent.cpp
index 2ef77f3..134dda5 100644
--- a/Source/components/EffectTypeGridComponent.cpp
+++ b/Source/components/EffectTypeGridComponent.cpp
@@ -1,6 +1,8 @@
#include "EffectTypeGridComponent.h"
#include "../LookAndFeel.h"
#include
+#include
+#include
EffectTypeGridComponent::EffectTypeGridComponent(OscirenderAudioProcessor& processor)
: audioProcessor(processor)
@@ -31,14 +33,28 @@ void EffectTypeGridComponent::setupEffectItems()
// Get effect types directly from the audio processor's toggleableEffects
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
- for (const auto& effect : audioProcessor.toggleableEffects)
+ const int n = (int) audioProcessor.toggleableEffects.size();
+ std::vector order(n);
+ std::iota(order.begin(), order.end(), 0);
+ std::sort(order.begin(), order.end(), [this](int a, int b) {
+ auto ea = audioProcessor.toggleableEffects[a];
+ auto eb = audioProcessor.toggleableEffects[b];
+ const int cmp = ea->getName().compareIgnoreCase(eb->getName());
+ if (cmp != 0)
+ return cmp < 0; // ascending alphabetical, case-insensitive
+ // Stable tie-breaker to ensure deterministic layout
+ return ea->getId().compare(eb->getId()) < 0;
+ });
+
+ for (int idx : order)
{
- // Extract effect name from the effect ID or first parameter name
+ auto effect = audioProcessor.toggleableEffects[idx];
+ // Extract effect name from the effect
juce::String effectName = effect->getName();
-
+
// Create new item component
auto* item = new EffectTypeItemComponent(effectName, effect->getIcon(), effect->getId());
-
+
// Set up callback to forward effect selection
item->onEffectSelected = [this](const juce::String& effectId) {
if (onEffectSelected)
@@ -53,9 +69,9 @@ void EffectTypeGridComponent::setupEffectItems()
juce::SpinLock::ScopedLockType lock(audioProcessor.effectsLock);
audioProcessor.clearPreviewEffect();
};
-
- effectItems.add(item);
- content.addAndMakeVisible(item);
+
+ effectItems.add(item);
+ content.addAndMakeVisible(item);
}
}
diff --git a/osci-bitcrush.jucer b/osci-bitcrush.jucer
index 4cb31bc..22f901c 100644
--- a/osci-bitcrush.jucer
+++ b/osci-bitcrush.jucer
@@ -51,14 +51,23 @@
file="Resources/sosci/vector_display.sosci"/>
+
+
+
+
+
+
+
+
+
@@ -70,11 +79,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/sosci.jucer b/sosci.jucer
index f46a379..87bab75 100644
--- a/sosci.jucer
+++ b/sosci.jucer
@@ -50,15 +50,23 @@
file="Resources/sosci/vector_display.sosci"/>
+
+
+
+
+
+
+
+
@@ -70,11 +78,21 @@
+
+
+
+
+
+
+
+
+