Merge pull request #81 from jameshball/interface-refresh

Interface refresh
pull/170/head
James H Ball 2023-12-19 12:20:36 +00:00 zatwierdzone przez GitHub
commit 90fcd085be
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
20 zmienionych plików z 510 dodań i 302 usunięć

Wyświetl plik

@ -1,6 +1,7 @@
#include "LookAndFeel.h" #include "LookAndFeel.h"
OscirenderLookAndFeel::OscirenderLookAndFeel() { OscirenderLookAndFeel::OscirenderLookAndFeel() {
// slider
setColour(juce::Slider::thumbColourId, Colours::veryDark); setColour(juce::Slider::thumbColourId, Colours::veryDark);
setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::white); setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::white);
setColour(juce::Slider::textBoxBackgroundColourId, Colours::veryDark); setColour(juce::Slider::textBoxBackgroundColourId, Colours::veryDark);
@ -8,38 +9,72 @@ OscirenderLookAndFeel::OscirenderLookAndFeel() {
setColour(juce::Slider::trackColourId, juce::Colours::grey); setColour(juce::Slider::trackColourId, juce::Colours::grey);
setColour(juce::Slider::backgroundColourId, Colours::dark); setColour(juce::Slider::backgroundColourId, Colours::dark);
setColour(sliderThumbOutlineColourId, juce::Colours::white); setColour(sliderThumbOutlineColourId, juce::Colours::white);
// buttons
setColour(juce::ToggleButton::tickDisabledColourId, juce::Colours::white); setColour(juce::ToggleButton::tickDisabledColourId, juce::Colours::white);
setColour(juce::ResizableWindow::backgroundColourId, Colours::dark); setColour(juce::TextButton::buttonColourId, Colours::veryDark);
// windows & menus
setColour(juce::ResizableWindow::backgroundColourId, Colours::grey);
setColour(groupComponentBackgroundColourId, Colours::darker); setColour(groupComponentBackgroundColourId, Colours::darker);
setColour(groupComponentHeaderColourId, Colours::veryDark); setColour(groupComponentHeaderColourId, Colours::veryDark);
setColour(juce::PopupMenu::backgroundColourId, Colours::veryDark); setColour(juce::PopupMenu::backgroundColourId, Colours::veryDark);
setColour(juce::PopupMenu::highlightedBackgroundColourId, Colours::darker); setColour(juce::PopupMenu::highlightedBackgroundColourId, Colours::darker);
setColour(juce::TooltipWindow::backgroundColourId, Colours::veryDark);
setColour(juce::TooltipWindow::outlineColourId, juce::Colours::white);
// combo box
setColour(juce::ComboBox::backgroundColourId, Colours::veryDark); setColour(juce::ComboBox::backgroundColourId, Colours::veryDark);
setColour(juce::ComboBox::outlineColourId, juce::Colours::white); setColour(juce::ComboBox::outlineColourId, juce::Colours::white);
setColour(juce::ComboBox::arrowColourId, juce::Colours::white); setColour(juce::ComboBox::arrowColourId, juce::Colours::white);
setColour(juce::TextButton::buttonColourId, Colours::veryDark);
// text box
setColour(juce::TextEditor::backgroundColourId, Colours::veryDark); setColour(juce::TextEditor::backgroundColourId, Colours::veryDark);
setColour(juce::TextEditor::outlineColourId, juce::Colours::white); setColour(juce::TextEditor::outlineColourId, juce::Colours::white);
setColour(juce::CaretComponent::caretColourId, Dracula::foreground);
setColour(juce::TextEditor::highlightColourId, Colours::grey);
// list box
setColour(juce::ListBox::backgroundColourId, Colours::darker); setColour(juce::ListBox::backgroundColourId, Colours::darker);
// scroll bar
setColour(juce::ScrollBar::thumbColourId, juce::Colours::white); setColour(juce::ScrollBar::thumbColourId, juce::Colours::white);
setColour(juce::ScrollBar::trackColourId, Colours::veryDark); setColour(juce::ScrollBar::trackColourId, Colours::veryDark);
setColour(juce::ScrollBar::backgroundColourId, Colours::veryDark); setColour(juce::ScrollBar::backgroundColourId, Colours::veryDark);
// custom components
setColour(effectComponentBackgroundColourId, juce::Colours::transparentBlack); setColour(effectComponentBackgroundColourId, juce::Colours::transparentBlack);
setColour(effectComponentHandleColourId, Colours::veryDark); setColour(effectComponentHandleColourId, Colours::veryDark);
// code editor
setColour(juce::CodeEditorComponent::backgroundColourId, Colours::darker); setColour(juce::CodeEditorComponent::backgroundColourId, Colours::darker);
setColour(juce::CodeEditorComponent::defaultTextColourId, Dracula::foreground); setColour(juce::CodeEditorComponent::defaultTextColourId, Dracula::foreground);
setColour(juce::CodeEditorComponent::lineNumberBackgroundId, Colours::veryDark); setColour(juce::CodeEditorComponent::lineNumberBackgroundId, Colours::veryDark);
setColour(juce::CodeEditorComponent::lineNumberTextId, Dracula::foreground); setColour(juce::CodeEditorComponent::lineNumberTextId, Dracula::foreground);
setColour(juce::CodeEditorComponent::highlightColourId, Colours::grey); setColour(juce::CodeEditorComponent::highlightColourId, Colours::grey);
setColour(juce::CaretComponent::caretColourId, Dracula::foreground);
setColour(juce::TextEditor::highlightColourId, Colours::grey);
setColour(juce::TabbedButtonBar::tabOutlineColourId, Colours::veryDark);
setColour(juce::TabbedButtonBar::frontOutlineColourId, Colours::veryDark);
setColour(juce::TabbedButtonBar::tabTextColourId, juce::Colours::white);
setColour(juce::TabbedButtonBar::frontTextColourId, juce::Colours::white);
setColour(juce::TabbedComponent::outlineColourId, Colours::veryDark);
setColour(tabbedComponentBackgroundColourId, Colours::veryDark);
// envelope
setColour(EnvelopeComponent::Node, Colours::veryDark);
setColour(EnvelopeComponent::ReleaseNode, Colours::veryDark);
setColour(EnvelopeComponent::LoopNode, Colours::veryDark);
setColour(EnvelopeComponent::NodeOutline, juce::Colours::white);
setColour(EnvelopeComponent::Line, juce::Colours::white);
setColour(EnvelopeComponent::LoopLine, juce::Colours::white);
setColour(EnvelopeComponent::Background, Colours::veryDark);
setColour(EnvelopeComponent::GridLine, Colours::dark);
setColour(EnvelopeComponent::LegendText, juce::Colours::white);
setColour(EnvelopeComponent::LegendBackground, Colours::veryDark);
// midi keyboard
setColour(juce::MidiKeyboardComponent::blackNoteColourId, Colours::veryDark);
setColour(juce::MidiKeyboardComponent::whiteNoteColourId, juce::Colours::white);
setColour(juce::MidiKeyboardComponent::mouseOverKeyOverlayColourId, Colours::accentColor.withAlpha(0.3f));
setColour(juce::MidiKeyboardComponent::keyDownOverlayColourId, Colours::accentColor.withAlpha(0.7f));
setColour(juce::MidiKeyboardComponent::shadowColourId, juce::Colours::transparentBlack);
setColour(juce::MidiKeyboardComponent::upDownButtonBackgroundColourId, Colours::veryDark);
setColour(juce::MidiKeyboardComponent::upDownButtonArrowColourId, juce::Colours::white);
// UI colours
getCurrentColourScheme().setUIColour(ColourScheme::widgetBackground, Colours::veryDark); getCurrentColourScheme().setUIColour(ColourScheme::widgetBackground, Colours::veryDark);
getCurrentColourScheme().setUIColour(ColourScheme::UIColour::defaultFill, Colours::accentColor); getCurrentColourScheme().setUIColour(ColourScheme::UIColour::defaultFill, Colours::accentColor);
} }
@ -175,6 +210,20 @@ void OscirenderLookAndFeel::drawMenuBarBackground(juce::Graphics& g, int width,
g.fillRect(r); g.fillRect(r);
} }
void OscirenderLookAndFeel::drawTooltip(juce::Graphics& g, const juce::String& text, int width, int height) {
juce::Rectangle<int> bounds (width, height);
auto cornerSize = 5.0f;
g.setColour(findColour(juce::TooltipWindow::backgroundColourId));
g.fillRect(bounds.toFloat());
g.setColour(findColour(juce::TooltipWindow::outlineColourId));
g.drawRect(bounds.toFloat().reduced(0.5f, 0.5f), 1.0f);
LookAndFeelHelpers::layoutTooltipText (text, findColour (juce::TooltipWindow::textColourId))
.draw (g, { static_cast<float> (width), static_cast<float> (height) });
}
juce::CodeEditorComponent::ColourScheme OscirenderLookAndFeel::getDefaultColourScheme() { juce::CodeEditorComponent::ColourScheme OscirenderLookAndFeel::getDefaultColourScheme() {
juce::CodeEditorComponent::ColourScheme cs; juce::CodeEditorComponent::ColourScheme cs;

Wyświetl plik

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <JuceHeader.h> #include <JuceHeader.h>
#include "UGen/ugen_JuceEnvelopeComponent.h"
enum ColourIds { enum ColourIds {
groupComponentBackgroundColourId, groupComponentBackgroundColourId,
@ -8,11 +9,10 @@ enum ColourIds {
effectComponentBackgroundColourId, effectComponentBackgroundColourId,
effectComponentHandleColourId, effectComponentHandleColourId,
sliderThumbOutlineColourId, sliderThumbOutlineColourId,
tabbedComponentBackgroundColourId,
}; };
namespace Colours { namespace Colours {
const juce::Colour dark{0xff424242}; const juce::Colour dark{0xff353535};
const juce::Colour darker{0xff212121}; const juce::Colour darker{0xff212121};
const juce::Colour veryDark{0xff111111}; const juce::Colour veryDark{0xff111111};
const juce::Colour grey{0xff555555}; const juce::Colour grey{0xff555555};
@ -34,6 +34,37 @@ namespace Dracula {
const juce::Colour yellow{0xfff1fa8c}; const juce::Colour yellow{0xfff1fa8c};
} }
namespace LookAndFeelHelpers
{
static juce::Colour createBaseColour (juce::Colour buttonColour,
bool hasKeyboardFocus,
bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown) noexcept
{
const float sat = hasKeyboardFocus ? 1.3f : 0.9f;
const juce::Colour baseColour (buttonColour.withMultipliedSaturation (sat));
if (shouldDrawButtonAsDown) return baseColour.contrasting (0.2f);
if (shouldDrawButtonAsHighlighted) return baseColour.contrasting (0.1f);
return baseColour;
}
static juce::TextLayout layoutTooltipText (const juce::String& text, juce::Colour colour) noexcept
{
const float tooltipFontSize = 13.0f;
const int maxToolTipWidth = 400;
juce::AttributedString s;
s.setJustification (juce::Justification::centred);
s.append (text, juce::Font (tooltipFontSize, juce::Font::bold), colour);
juce::TextLayout tl;
tl.createLayoutWithBalancedLineLengths (s, (float) maxToolTipWidth);
return tl;
}
}
class OscirenderLookAndFeel : public juce::LookAndFeel_V4 { class OscirenderLookAndFeel : public juce::LookAndFeel_V4 {
public: public:
OscirenderLookAndFeel(); OscirenderLookAndFeel();
@ -58,6 +89,6 @@ public:
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown) override; bool shouldDrawButtonAsDown) override;
void drawMenuBarBackground(juce::Graphics& g, int width, int height, bool, juce::MenuBarComponent& menuBar) override; void drawMenuBarBackground(juce::Graphics& g, int width, int height, bool, juce::MenuBarComponent& menuBar) override;
juce::CodeEditorComponent::ColourScheme getDefaultColourScheme(); juce::CodeEditorComponent::ColourScheme getDefaultColourScheme();
void drawTooltip(juce::Graphics& g, const juce::String& text, int width, int height) override;
}; };

Wyświetl plik

@ -83,6 +83,9 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
pluginEditor.fileUpdated(fileName); pluginEditor.fileUpdated(fileName);
}; };
fileName.setFont(juce::Font(16.0f, juce::Font::plain));
fileName.setText("filename");
fileName.onReturnKey = [this] { fileName.onReturnKey = [this] {
createFile.triggerClick(); createFile.triggerClick();
}; };

Wyświetl plik

@ -2,6 +2,8 @@
#include "PluginEditor.h" #include "PluginEditor.h"
MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) {
setText("MIDI Settings");
addAndMakeVisible(midiToggle); addAndMakeVisible(midiToggle);
addAndMakeVisible(keyboard); addAndMakeVisible(keyboard);
@ -15,6 +17,7 @@ MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
envelope.setAdsrMode(true); envelope.setAdsrMode(true);
envelope.setEnv(audioProcessor.adsrEnv); envelope.setEnv(audioProcessor.adsrEnv);
envelope.addListener(&audioProcessor); envelope.addListener(&audioProcessor);
envelope.setGrid(EnvelopeComponent::GridBoth, EnvelopeComponent::GridNone, 0.1, 0.25);
audioProcessor.attackTime->addListener(this); audioProcessor.attackTime->addListener(this);
audioProcessor.attackLevel->addListener(this); audioProcessor.attackLevel->addListener(this);
@ -45,7 +48,6 @@ void MidiComponent::parameterValueChanged(int parameterIndex, float newValue) {
void MidiComponent::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {} void MidiComponent::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {}
void MidiComponent::handleAsyncUpdate() { void MidiComponent::handleAsyncUpdate() {
DBG("MidiComponent::handleAsyncUpdate");
Env newEnv = Env( Env newEnv = Env(
{ {
0.0, 0.0,
@ -71,14 +73,13 @@ void MidiComponent::handleAsyncUpdate() {
} }
void MidiComponent::resized() { void MidiComponent::resized() {
auto area = getLocalBounds().reduced(5); auto area = getLocalBounds().withTrimmedTop(20).reduced(20);
midiToggle.setBounds(area.removeFromTop(50)); midiToggle.setBounds(area.removeFromTop(30));
envelope.setBounds(area.removeFromTop(200)); area.removeFromTop(5);
keyboard.setBounds(area.removeFromBottom(100)); keyboard.setBounds(area.removeFromBottom(50));
envelope.setBounds(area);
} }
void MidiComponent::paint(juce::Graphics& g) { void MidiComponent::paint(juce::Graphics& g) {
auto rect = getLocalBounds().reduced(5); juce::GroupComponent::paint(g);
g.setColour(getLookAndFeel().findColour(groupComponentBackgroundColourId));
g.fillRect(rect);
} }

Wyświetl plik

@ -4,7 +4,7 @@
#include "PluginProcessor.h" #include "PluginProcessor.h"
class OscirenderAudioProcessorEditor; class OscirenderAudioProcessorEditor;
class MidiComponent : public juce::Component, public juce::AudioProcessorParameter::Listener, public juce::AsyncUpdater { class MidiComponent : public juce::GroupComponent, public juce::AudioProcessorParameter::Listener, public juce::AsyncUpdater {
public: public:
MidiComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&); MidiComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&);
~MidiComponent() override; ~MidiComponent() override;
@ -20,8 +20,7 @@ private:
OscirenderAudioProcessorEditor& pluginEditor; OscirenderAudioProcessorEditor& pluginEditor;
juce::ToggleButton midiToggle{"Enable MIDI"}; juce::ToggleButton midiToggle{"Enable MIDI"};
juce::MidiKeyboardState keyboardState; juce::MidiKeyboardComponent keyboard{audioProcessor.keyboardState, juce::MidiKeyboardComponent::horizontalKeyboard};
juce::MidiKeyboardComponent keyboard{keyboardState, juce::MidiKeyboardComponent::horizontalKeyboard};
EnvelopeContainerComponent envelope; EnvelopeContainerComponent envelope;

Wyświetl plik

@ -73,6 +73,11 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor
rotateX.setComponent(fixedRotateX); rotateX.setComponent(fixedRotateX);
rotateY.setComponent(fixedRotateY); rotateY.setComponent(fixedRotateY);
rotateZ.setComponent(fixedRotateZ); rotateZ.setComponent(fixedRotateZ);
juce::String tooltip = "Toggles whether the rotation around this axis is fixed, or changes according to the rotation speed.";
fixedRotateX->setTooltip(tooltip);
fixedRotateY->setTooltip(tooltip);
fixedRotateZ->setTooltip(tooltip);
} }
ObjComponent::~ObjComponent() { ObjComponent::~ObjComponent() {

Wyświetl plik

@ -6,10 +6,6 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
{ {
juce::Desktop::getInstance().setDefaultLookAndFeel(&lookAndFeel); juce::Desktop::getInstance().setDefaultLookAndFeel(&lookAndFeel);
setLookAndFeel(&lookAndFeel); setLookAndFeel(&lookAndFeel);
addAndMakeVisible(tabs);
tabs.addTab("Main", getLookAndFeel().findColour(tabbedComponentBackgroundColourId), &settings, false);
tabs.addTab("MIDI", getLookAndFeel().findColour(tabbedComponentBackgroundColourId), &midi, false);
addAndMakeVisible(volume); addAndMakeVisible(volume);
menuBar.setModel(&menuBarModel); menuBar.setModel(&menuBarModel);
@ -33,6 +29,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
juce::Path path; juce::Path path;
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f); path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
collapseButton.setShape(path, false, true, true); collapseButton.setShape(path, false, true, true);
collapseButton.setMouseCursor(juce::MouseCursor::PointingHandCursor);
colourScheme = lookAndFeel.getDefaultColourScheme(); colourScheme = lookAndFeel.getDefaultColourScheme();
@ -62,6 +59,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
layout.setItemLayout(1, 7, 7, 7); layout.setItemLayout(1, 7, 7, 7);
layout.setItemLayout(2, -0.1, -1.0, -0.3); layout.setItemLayout(2, -0.1, -1.0, -0.3);
addAndMakeVisible(settings);
addAndMakeVisible(resizerBar); addAndMakeVisible(resizerBar);
} }
@ -115,6 +113,8 @@ void OscirenderAudioProcessorEditor::resized() {
juce::Component* columns[] = { &dummy, &resizerBar, codeEditors[index].get() }; juce::Component* columns[] = { &dummy, &resizerBar, codeEditors[index].get() };
DBG("area: " << area.toString());
layout.layOutComponents(columns, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), false, true); layout.layOutComponents(columns, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), false, true);
auto dummyBounds = dummy.getBounds(); auto dummyBounds = dummy.getBounds();
collapseButton.setBounds(dummyBounds.removeFromRight(20)); collapseButton.setBounds(dummyBounds.removeFromRight(20));
@ -123,6 +123,7 @@ void OscirenderAudioProcessorEditor::resized() {
} else { } else {
codeEditors[index]->setBounds(0, 0, 0, 0); codeEditors[index]->setBounds(0, 0, 0, 0);
resizerBar.setBounds(0, 0, 0, 0);
collapseButton.setBounds(area.removeFromRight(20)); collapseButton.setBounds(area.removeFromRight(20));
} }
} else { } else {
@ -139,9 +140,8 @@ void OscirenderAudioProcessorEditor::resized() {
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f); path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
collapseButton.setShape(path, false, true, true); collapseButton.setShape(path, false, true, true);
} }
tabs.setBounds(area);
settings.setBounds(area);
repaint(); repaint();
} }

Wyświetl plik

@ -38,8 +38,6 @@ public:
private: private:
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
juce::TabbedComponent tabs{juce::TabbedButtonBar::TabsAtTop};
MidiComponent midi{audioProcessor, *this};
SettingsComponent settings{audioProcessor, *this}; SettingsComponent settings{audioProcessor, *this};
VolumeComponent volume{audioProcessor}; VolumeComponent volume{audioProcessor};
std::vector<std::shared_ptr<juce::CodeDocument>> codeDocuments; std::vector<std::shared_ptr<juce::CodeDocument>> codeDocuments;
@ -58,7 +56,7 @@ private:
juce::StretchableLayoutManager layout; juce::StretchableLayoutManager layout;
juce::StretchableLayoutResizerBar resizerBar{&layout, 1, true}; juce::StretchableLayoutResizerBar resizerBar{&layout, 1, true};
juce::TooltipWindow tooltipWindow{this}; juce::TooltipWindow tooltipWindow{this, 0};
std::atomic<bool> updatingDocumentsWithParserLock = false; std::atomic<bool> updatingDocumentsWithParserLock = false;

Wyświetl plik

@ -36,68 +36,63 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<BitCrushEffect>(), std::make_shared<BitCrushEffect>(),
new EffectParameter("Bit Crush", "bitCrush", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Bit Crush", "Limits the resolution of points drawn to the screen, making the image look pixelated, and making the audio sound more 'digital' and distorted.", "bitCrush", VERSION_HINT, 0.0, 0.0, 1.0)
"bitCrush"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<BulgeEffect>(), std::make_shared<BulgeEffect>(),
new EffectParameter("Bulge", "bulge", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Bulge", "Applies a bulge that makes the centre of the image larger, and squishes the edges of the image. This applies a distortion to the audio.", "bulge", VERSION_HINT, 0.0, 0.0, 1.0)
"bulge"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<RotateEffect>(), std::make_shared<RotateEffect>(),
new EffectParameter("2D Rotate", "2DRotateSpeed", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("2D Rotate", "Rotates the image, and pans the audio.", "2DRotateSpeed", VERSION_HINT, 0.0, 0.0, 1.0)
"2DRotate"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<VectorCancellingEffect>(), std::make_shared<VectorCancellingEffect>(),
new EffectParameter("Vector Cancelling", "vectorCancelling", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Vector Cancelling", "Inverts the audio and image every few samples to 'cancel out' the audio, making the audio quiet, and distorting the image.", "vectorCancelling", VERSION_HINT, 0.0, 0.0, 1.0)
"vectorCancelling"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<DistortEffect>(false), std::make_shared<DistortEffect>(false),
new EffectParameter("Distort X", "distortX", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Distort X", "Distorts the image in the horizontal direction by jittering the audio sample being drawn.", "distortX", VERSION_HINT, 0.0, 0.0, 1.0)
"distortX"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<DistortEffect>(true), std::make_shared<DistortEffect>(true),
new EffectParameter("Distort Y", "distortY", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Distort Y", "Distorts the image in the vertical direction by jittering the audio sample being drawn.", "distortY", VERSION_HINT, 0.0, 0.0, 1.0)
"distortY"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
input.x += values[0]; input.x += values[0];
input.y += values[1]; input.y += values[1];
return input; return input;
}, std::vector<EffectParameter*>{new EffectParameter("Translate X", "translateX", VERSION_HINT, 0.0, -1.0, 1.0), new EffectParameter("Translate Y", "translateY", VERSION_HINT, 0.0, -1.0, 1.0)}, }, std::vector<EffectParameter*>{
"translate" new EffectParameter("Translate X", "Moves the image horizontally.", "translateX", VERSION_HINT, 0.0, -1.0, 1.0),
new EffectParameter("Translate Y", "Moves the image vertically.", "translateY", VERSION_HINT, 0.0, -1.0, 1.0)
}
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<SmoothEffect>(), std::make_shared<SmoothEffect>(),
new EffectParameter("Smoothing", "smoothing", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Smoothing", "This works as a low-pass frequency filter that removes high frequencies, making the image look smoother, and audio sound less harsh.", "smoothing", VERSION_HINT, 0.0, 0.0, 1.0)
"smoothing"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
wobbleEffect, wobbleEffect,
new EffectParameter("Wobble", "wobble", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Wobble", "Adds a sine wave of the prominent frequency in the audio currently playing. The sine wave's frequency is slightly offset to create a subtle 'wobble' in the image. Increasing the slider increases the strength of the wobble.", "wobble", VERSION_HINT, 0.0, 0.0, 1.0)
"wobble"
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
delayEffect, delayEffect,
std::vector<EffectParameter*>{new EffectParameter("Delay Decay", "delayDecay", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("Delay Length", "delayLength", VERSION_HINT, 0.5, 0.0, 1.0)}, std::vector<EffectParameter*>{
"delay" new EffectParameter("Delay Decay", "Adds repetitions, delays, or echos to the audio. This slider controls the volume of the echo.", "delayDecay", VERSION_HINT, 0.0, 0.0, 1.0),
new EffectParameter("Delay Length", "Controls the time in seconds between echos.", "delayLength", VERSION_HINT, 0.5, 0.0, 1.0)
}
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
perspectiveEffect, perspectiveEffect,
std::vector<EffectParameter*>{ std::vector<EffectParameter*>{
new EffectParameter("3D Perspective", "perspectiveStrength", VERSION_HINT, 0.0, 0.0, 1.0), new EffectParameter("3D Perspective", "Controls the strength of the 3D perspective effect which treats the image as a 3D object that can be rotated.", "perspectiveStrength", VERSION_HINT, 0.0, 0.0, 1.0),
new EffectParameter("Depth (z)", "perspectiveZPos", VERSION_HINT, 0.1, 0.0, 1.0), new EffectParameter("Depth (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", "perspectiveRotateSpeed", VERSION_HINT, 0.0, -1.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", "perspectiveRotateX", VERSION_HINT, 1.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),
new EffectParameter("Rotate Y", "perspectiveRotateY", VERSION_HINT, 1.0, -1.0, 1.0), new EffectParameter("Rotate Y", "Controls the rotation of the object in the Y axis.", "perspectiveRotateY", VERSION_HINT, 1.0, -1.0, 1.0),
new EffectParameter("Rotate Z", "perspectiveRotateZ", VERSION_HINT, 0.0, -1.0, 1.0), new EffectParameter("Rotate Z", "Controls the rotation of the object in the Z axis.", "perspectiveRotateZ", VERSION_HINT, 0.0, -1.0, 1.0),
}, }
"perspective"
)); ));
toggleableEffects.push_back(traceMax); toggleableEffects.push_back(traceMax);
toggleableEffects.push_back(traceMin); toggleableEffects.push_back(traceMin);
@ -275,8 +270,12 @@ void OscirenderAudioProcessor::addLuaSlider() {
luaEffects.push_back(std::make_shared<Effect>( luaEffects.push_back(std::make_shared<Effect>(
std::make_shared<LuaEffect>(sliderName, *this), std::make_shared<LuaEffect>(sliderName, *this),
new EffectParameter("Lua " + sliderName, "lua" + sliderName, VERSION_HINT, 0.0, 0.0, 1.0, 0.001, false), new EffectParameter(
"lua" + sliderName "Lua Slider " + sliderName,
"Controls the value of the Lua variable called slider_" + sliderName + ".",
"lua" + sliderName,
VERSION_HINT, 0.0, 0.0, 1.0, 0.001, false
)
)); ));
auto& effect = luaEffects.back(); auto& effect = luaEffects.back();
@ -480,6 +479,9 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
buffer.clear(i, 0, buffer.getNumSamples()); buffer.clear(i, 0, buffer.getNumSamples());
} }
// merge keyboard state and midi messages
keyboardState.processNextMidiBuffer(midiMessages, 0, buffer.getNumSamples(), true);
bool usingInput = inputEnabled->getBoolValue(); bool usingInput = inputEnabled->getBoolValue();
bool usingMidi = midiEnabled->getBoolValue(); bool usingMidi = midiEnabled->getBoolValue();

Wyświetl plik

@ -81,24 +81,36 @@ public:
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
frequency = values[0]; frequency = values[0];
return input; return input;
}, new EffectParameter("Frequency", "frequency", VERSION_HINT, 440.0, 0.0, 12000.0, 0.1), }, new EffectParameter(
"Controls how many times per second the image is drawn, thereby controlling the pitch of the sound. Lower frequencies result in more-accurately drawn images, but more flickering, and vice versa." "Frequency",
"Controls how many times per second the image is drawn, thereby controlling the pitch of the sound. Lower frequencies result in more-accurately drawn images, but more flickering, and vice versa.",
"frequency",
VERSION_HINT, 440.0, 0.0, 12000.0, 0.1
)
); );
std::shared_ptr<Effect> volumeEffect = std::make_shared<Effect>( std::shared_ptr<Effect> volumeEffect = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
volume = values[0]; volume = values[0];
return input; return input;
}, new EffectParameter("Volume", "volume", VERSION_HINT, 1.0, 0.0, 3.0), }, new EffectParameter(
"Controls the volume of the sound. Works by scaling the image and sound by a factor." "Volume",
"Controls the volume of the sound. Works by scaling the image and sound by a factor.",
"volume",
VERSION_HINT, 1.0, 0.0, 3.0
)
); );
std::shared_ptr<Effect> thresholdEffect = std::make_shared<Effect>( std::shared_ptr<Effect> thresholdEffect = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
threshold = values[0]; threshold = values[0];
return input; return input;
}, new EffectParameter("Threshold", "threshold", VERSION_HINT, 1.0, 0.0, 1.0), }, new EffectParameter(
"Clips the sound and image to a maximum value. Applying a harsher threshold results in a more distorted sound." "Threshold",
"Clips the sound and image to a maximum value. Applying a harsher threshold results in a more distorted sound.",
"threshold",
VERSION_HINT, 1.0, 0.0, 1.0
)
); );
std::shared_ptr<Effect> focalLength = std::make_shared<Effect>( std::shared_ptr<Effect> focalLength = std::make_shared<Effect>(
@ -109,8 +121,12 @@ public:
camera->setFocalLength(values[0]); camera->setFocalLength(values[0]);
} }
return input; return input;
}, new EffectParameter("Focal length", "objFocalLength", VERSION_HINT, 1.0, 0.0, 2.0), }, new EffectParameter(
"Controls the focal length of the camera being used to render the 3D object. A lower focal length results in a wider field of view, distorting the image, and making the image smaller." "Focal length",
"Controls the focal length of the camera being used to render the 3D object. A lower focal length results in a wider field of view, distorting the image, and making the image smaller.",
"objFocalLength",
VERSION_HINT, 1.0, 0.0, 2.0
)
); );
BooleanParameter* fixedRotateX = new BooleanParameter("Object Fixed Rotate X", "objFixedRotateX", VERSION_HINT, false); BooleanParameter* fixedRotateX = new BooleanParameter("Object Fixed Rotate X", "objFixedRotateX", VERSION_HINT, false);
@ -129,8 +145,12 @@ public:
} }
} }
return input; return input;
}, new EffectParameter("Object Rotate X", "objRotateX", VERSION_HINT, 1.0, -1.0, 1.0), }, new EffectParameter(
"Controls the rotation of the 3D object around the X axis. When Object Fixed Rotate X is enabled, the object is unaffected by the rotation speed, and remains in a fixed position." "Object Rotate X",
"Controls the rotation of the 3D object around the X axis. When Object Fixed Rotate X is enabled, the object is unaffected by the rotation speed, and remains in a fixed position.",
"objRotateX",
VERSION_HINT, 1.0, -1.0, 1.0
)
); );
std::shared_ptr<Effect> rotateY = std::make_shared<Effect>( std::shared_ptr<Effect> rotateY = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
@ -145,8 +165,12 @@ public:
} }
} }
return input; return input;
}, new EffectParameter("Object Rotate Y", "objRotateY", VERSION_HINT, 1.0, -1.0, 1.0), }, new EffectParameter(
"Controls the rotation of the 3D object around the Y axis. When Object Fixed Rotate Y is enabled, the object is unaffected by the rotation speed, and remains in a fixed position." "Object Rotate Y",
"Controls the rotation of the 3D object around the Y axis. When Object Fixed Rotate Y is enabled, the object is unaffected by the rotation speed, and remains in a fixed position.",
"objRotateY",
VERSION_HINT, 1.0, -1.0, 1.0
)
); );
std::shared_ptr<Effect> rotateZ = std::make_shared<Effect>( std::shared_ptr<Effect> rotateZ = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
@ -161,8 +185,12 @@ public:
} }
} }
return input; return input;
}, new EffectParameter("Object Rotate Z", "objRotateZ", VERSION_HINT, 0.0, -1.0, 1.0), }, new EffectParameter(
"Controls the rotation of the 3D object around the Z axis. When Object Fixed Rotate Z is enabled, the object is unaffected by the rotation speed, and remains in a fixed position." "Object Rotate Z",
"Controls the rotation of the 3D object around the Z axis. When Object Fixed Rotate Z is enabled, the object is unaffected by the rotation speed, and remains in a fixed position.",
"objRotateZ",
VERSION_HINT, 0.0, -1.0, 1.0
)
); );
std::shared_ptr<Effect> rotateSpeed = std::make_shared<Effect>( std::shared_ptr<Effect> rotateSpeed = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
@ -172,27 +200,39 @@ public:
obj->setRotationSpeed(values[0]); obj->setRotationSpeed(values[0]);
} }
return input; return input;
}, new EffectParameter("Rotate Speed", "objRotateSpeed", VERSION_HINT, 0.0, -1.0, 1.0), }, new EffectParameter(
"Controls the speed at which the 3D object rotates. A negative value results in the object rotating in the opposite direction. The rotate speed is scaled by the different Object Rotate Axis values to rotate the object." "Rotate Speed",
"Controls the speed at which the 3D object rotates. A negative value results in the object rotating in the opposite direction. The rotate speed is scaled by the different Object Rotate Axis values to rotate the object.",
"objRotateSpeed",
VERSION_HINT, 0.0, -1.0, 1.0
)
); );
std::shared_ptr<Effect> traceMax = std::make_shared<Effect>( std::shared_ptr<Effect> traceMax = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
return input; return input;
}, new EffectParameter("Trace max", "traceMax", VERSION_HINT, 1.0, 0.0, 1.0), }, new EffectParameter(
"Defines the maximum proportion of the image that is drawn before skipping to the next frame. This has the effect of 'tracing' out the image from a single dot when animated. By default, we draw until the end of the frame, so this value is 1.0." "Trace max",
"Defines the maximum proportion of the image that is drawn before skipping to the next frame. This has the effect of 'tracing' out the image from a single dot when animated. By default, we draw until the end of the frame, so this value is 1.0.",
"traceMax",
VERSION_HINT, 1.0, 0.0, 1.0
)
); );
std::shared_ptr<Effect> traceMin = std::make_shared<Effect>( std::shared_ptr<Effect> traceMin = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
return input; return input;
}, new EffectParameter("Trace min", "traceMin", VERSION_HINT, 0.0, 0.0, 1.0), }, new EffectParameter(
"Defines the proportion of the image that drawing starts from. This has the effect of 'tracing' out the image from a single dot when animated. By default, we start drawing from the beginning of the frame, so this value is 0.0." "Trace min",
"Defines the proportion of the image that drawing starts from. This has the effect of 'tracing' out the image from a single dot when animated. By default, we start drawing from the beginning of the frame, so this value is 0.0.",
"traceMin",
VERSION_HINT, 0.0, 0.0, 1.0
)
); );
std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>(); std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>();
std::shared_ptr<PerspectiveEffect> perspectiveEffect = std::make_shared<PerspectiveEffect>(VERSION_HINT); std::shared_ptr<PerspectiveEffect> perspectiveEffect = std::make_shared<PerspectiveEffect>(VERSION_HINT);
BooleanParameter* midiEnabled = new BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, !juce::JUCEApplicationBase::isStandaloneApp()); BooleanParameter* midiEnabled = new BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, false);
BooleanParameter* inputEnabled = new BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false); BooleanParameter* inputEnabled = new BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false);
std::atomic<float> frequency = 440.0f; std::atomic<float> frequency = 440.0f;
@ -207,14 +247,14 @@ public:
std::atomic<bool> objectServerRendering = false; std::atomic<bool> objectServerRendering = false;
juce::ChangeBroadcaster fileChangeBroadcaster; juce::ChangeBroadcaster fileChangeBroadcaster;
FloatParameter* attackTime = new FloatParameter("Attack Time", "attackTime", VERSION_HINT, 0.05, 0.0, 1.0); FloatParameter* attackTime = new FloatParameter("Attack Time", "attackTime", VERSION_HINT, 0.005, 0.0, 1.0);
FloatParameter* attackLevel = new FloatParameter("Attack Level", "attackLevel", VERSION_HINT, 1.0, 0.0, 1.0); FloatParameter* attackLevel = new FloatParameter("Attack Level", "attackLevel", VERSION_HINT, 1.0, 0.0, 1.0);
FloatParameter* decayTime = new FloatParameter("Decay Time", "decayTime", VERSION_HINT, 0.05, 0.0, 1.0); FloatParameter* decayTime = new FloatParameter("Decay Time", "decayTime", VERSION_HINT, 0.095, 0.0, 1.0);
FloatParameter* sustainLevel = new FloatParameter("Sustain Level", "sustainLevel", VERSION_HINT, 0.8, 0.0, 1.0); FloatParameter* sustainLevel = new FloatParameter("Sustain Level", "sustainLevel", VERSION_HINT, 0.6, 0.0, 1.0);
FloatParameter* releaseTime = new FloatParameter("Release Time", "releaseTime", VERSION_HINT, 0.2, 0.0, 1.0); FloatParameter* releaseTime = new FloatParameter("Release Time", "releaseTime", VERSION_HINT, 0.4, 0.0, 1.0);
FloatParameter* attackShape = new FloatParameter("Attack Shape", "attackShape", VERSION_HINT, 5, -50, 50); FloatParameter* attackShape = new FloatParameter("Attack Shape", "attackShape", VERSION_HINT, 5, -50, 50);
FloatParameter* decayShape = new FloatParameter("Decay Shape", "decayShape", VERSION_HINT, -20, -50, 50); FloatParameter* decayShape = new FloatParameter("Decay Shape", "decayShape", VERSION_HINT, -20, -50, 50);
FloatParameter* releaseShape = new FloatParameter("Release Shape", "releaseShape", VERSION_HINT, 5,-50, 50); FloatParameter* releaseShape = new FloatParameter("Release Shape", "releaseShape", VERSION_HINT, -5,-50, 50);
Env adsrEnv = Env::adsr( Env adsrEnv = Env::adsr(
attackTime->getValueUnnormalised(), attackTime->getValueUnnormalised(),
@ -225,6 +265,8 @@ public:
std::vector<EnvCurve>{ attackShape->getValueUnnormalised(), decayShape->getValueUnnormalised(), releaseShape->getValueUnnormalised() } std::vector<EnvCurve>{ attackShape->getValueUnnormalised(), decayShape->getValueUnnormalised(), releaseShape->getValueUnnormalised() }
); );
juce::MidiKeyboardState keyboardState;
private: private:
juce::SpinLock consumerLock; juce::SpinLock consumerLock;
std::vector<std::shared_ptr<BufferConsumer>> consumers; std::vector<std::shared_ptr<BufferConsumer>> consumers;

Wyświetl plik

@ -4,19 +4,25 @@
SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) {
addAndMakeVisible(effects); addAndMakeVisible(effects);
addAndMakeVisible(main); addAndMakeVisible(main);
addAndMakeVisible(columnResizerBar); addAndMakeVisible(midiResizerBar);
addAndMakeVisible(rowResizerBar); addAndMakeVisible(mainResizerBar);
addAndMakeVisible(effectResizerBar);
addAndMakeVisible(midi);
addChildComponent(lua); addChildComponent(lua);
addChildComponent(obj); addChildComponent(obj);
addChildComponent(txt); addChildComponent(txt);
columnLayout.setItemLayout(0, -0.1, -0.9, -0.4); midiLayout.setItemLayout(0, -0.1, -1.0, -1.0);
columnLayout.setItemLayout(1, 7, 7, 7); midiLayout.setItemLayout(1, 7, 7, 7);
columnLayout.setItemLayout(2, -0.1, -0.9, -0.6); midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, CLOSED_PREF_SIZE);
rowLayout.setItemLayout(0, -0.1, -1.0, -0.63); mainLayout.setItemLayout(0, -0.1, -0.9, -0.4);
rowLayout.setItemLayout(1, 7, 7, 7); mainLayout.setItemLayout(1, 7, 7, 7);
rowLayout.setItemLayout(2, -0.1, -0.9, -0.37); 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);
} }
@ -29,8 +35,11 @@ void SettingsComponent::resized() {
juce::Component dummy; juce::Component dummy;
juce::Component* columns[] = { &main, &columnResizerBar, &dummy }; juce::Component* midiComponents[] = { &dummy, &midiResizerBar, &midi };
columnLayout.layOutComponents(columns, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), false, true); midiLayout.layOutComponents(midiComponents, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), true, true);
juce::Component* columns[] = { &main, &mainResizerBar, &dummy };
mainLayout.layOutComponents(columns, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), false, true);
juce::Component* effectSettings = nullptr; juce::Component* effectSettings = nullptr;
@ -42,14 +51,16 @@ void SettingsComponent::resized() {
effectSettings = &txt; effectSettings = &txt;
} }
juce::Component* rows[] = { &effects, &rowResizerBar, effectSettings }; juce::Component* rows[] = { &effects, &effectResizerBar, effectSettings };
// use the dummy component to work out the bounds of the rows // use the dummy component to work out the bounds of the rows
if (effectSettings != nullptr) { if (effectSettings != nullptr) {
rowLayout.layOutComponents(rows, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), true, true); effectLayout.layOutComponents(rows, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), true, true);
} else { } else {
effects.setBounds(dummy.getBounds()); effects.setBounds(dummy.getBounds());
} }
repaint();
} }
void SettingsComponent::fileUpdated(juce::String fileName) { void SettingsComponent::fileUpdated(juce::String fileName) {
@ -77,3 +88,49 @@ void SettingsComponent::update() {
void SettingsComponent::disableMouseRotation() { void SettingsComponent::disableMouseRotation() {
obj.disableMouseRotation(); obj.disableMouseRotation();
} }
void SettingsComponent::toggleMidiComponent() {
double minSize, maxSize, preferredSize;
midiLayout.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);
} else {
midiLayout.setItemLayout(0, -0.1, -1.0, -1.0);
midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, CLOSED_PREF_SIZE);
}
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);
}
}
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();
}
}
void SettingsComponent::paint(juce::Graphics& g) {
// add drop shadow to each component
auto dc = juce::DropShadow(juce::Colours::black, 5, juce::Point<int>(0, 0));
dc.drawForRectangle(g, main.getBounds());
dc.drawForRectangle(g, effects.getBounds());
dc.drawForRectangle(g, midi.getBounds());
if (lua.isVisible()) {
dc.drawForRectangle(g, lua.getBounds());
} else if (obj.isVisible()) {
dc.drawForRectangle(g, obj.getBounds());
} else if (txt.isVisible()) {
dc.drawForRectangle(g, txt.getBounds());
}
}

Wyświetl plik

@ -7,6 +7,7 @@
#include "ObjComponent.h" #include "ObjComponent.h"
#include "TxtComponent.h" #include "TxtComponent.h"
#include "EffectsComponent.h" #include "EffectsComponent.h"
#include "MidiComponent.h"
class OscirenderAudioProcessorEditor; class OscirenderAudioProcessorEditor;
class SettingsComponent : public juce::Component { class SettingsComponent : public juce::Component {
@ -17,6 +18,10 @@ public:
void fileUpdated(juce::String fileName); void fileUpdated(juce::String fileName);
void update(); void update();
void disableMouseRotation(); void disableMouseRotation();
void toggleMidiComponent();
void mouseMove(const juce::MouseEvent& event) override;
void mouseDown(const juce::MouseEvent& event) override;
void paint(juce::Graphics& g) override;
private: private:
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
@ -27,11 +32,16 @@ private:
ObjComponent obj{audioProcessor, pluginEditor}; ObjComponent obj{audioProcessor, pluginEditor};
TxtComponent txt{audioProcessor, pluginEditor}; TxtComponent txt{audioProcessor, pluginEditor};
EffectsComponent effects{audioProcessor, pluginEditor}; EffectsComponent effects{audioProcessor, pluginEditor};
MidiComponent midi{audioProcessor, pluginEditor};
juce::StretchableLayoutManager columnLayout; const double CLOSED_PREF_SIZE = 30.0;
juce::StretchableLayoutResizerBar columnResizerBar{&columnLayout, 1, true};
juce::StretchableLayoutManager rowLayout; juce::StretchableLayoutManager midiLayout;
juce::StretchableLayoutResizerBar rowResizerBar{&rowLayout, 1, false}; juce::StretchableLayoutResizerBar midiResizerBar{&midiLayout, 1, false};
juce::StretchableLayoutManager mainLayout;
juce::StretchableLayoutResizerBar mainResizerBar{&mainLayout, 1, true};
juce::StretchableLayoutManager effectLayout;
juce::StretchableLayoutResizerBar effectResizerBar{&effectLayout, 1, false};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SettingsComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SettingsComponent)
}; };

Wyświetl plik

@ -13,6 +13,7 @@
UGEN++ can be redistributed and/or modified under the terms of the UGEN++ can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation; GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version. either version 2 of the License, or (at your option) any later version.
either version 2 of the License, or (at your option) any later version.
UGEN++ is distributed in the hope that it will be useful, UGEN++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -88,15 +89,19 @@ void EnvelopeHandleComponentConstrainer::setAdjacentHandleLimits(int setLeftLimi
} }
EnvelopeHandleComponent::EnvelopeHandleComponent() EnvelopeHandleComponent::EnvelopeHandleComponent()
: dontUpdateTimeAndValue(false), : dontUpdateTimeAndValue(false),
lastX(-1), lastX(-1),
lastY(-1), lastY(-1),
resizeLimits(this), resizeLimits(this),
shouldLockTime(false), shouldLockTime(false),
shouldLockValue(false), shouldLockValue(false),
ignoreDrag(false) shouldDraw(!shouldLockTime || !shouldLockValue),
ignoreDrag(false)
{ {
setMouseCursor(juce::MouseCursor::CrosshairCursor);
if (shouldDraw) {
setMouseCursor(juce::MouseCursor::DraggingHandCursor);
}
resetOffsets(); resetOffsets();
} }
@ -149,70 +154,88 @@ void EnvelopeHandleComponent::updateLegend()
int width = getParentWidth(); int width = getParentWidth();
int places; int places;
if(width >= 165) { if (width >= 115) {
if(env && env->isLoopNode(this))
text << "(Loop) ";
else if(env && env->isReleaseNode(this))
text << "(Release) ";
else
text << "Point ";
places = 3; places = 3;
} else if (width >= 100) {
places = 2;
} else {
places = 1;
} }
else if(width >= 140) {
text << "Point "; if (env->getAdsrMode()) {
places = 3; int index = env->getHandleIndex(this);
} else if(width >= 115) { Env envelope = env->getEnv();
text << "Pt ";
places = 3; double envTime = envelope.getTimes()[index - 1];
} else if(width >= 100) {
text << "Pt "; if (index == 1) {
places = 2; text = "Attack time (s): " + juce::String(legend->mapTime(envTime), places);
} else if(width >= 85) { text << ", Attack level: " << juce::String(legend->mapValue(value), places);
text << "Pt "; } else if (index == 2) {
places = 1; text = "Decay time (s): " + juce::String(legend->mapTime(envTime), places);
} else if(width >= 65) { text << ", Sustain level: " << juce::String(legend->mapValue(value), places);
text << "P "; } else {
places = 1; text = "Release time (s): " + juce::String(legend->mapTime(envTime), places);
}
} else { } else {
places = 1; if (width >= 165) {
if (env && env->isLoopNode(this))
text << "(Loop) ";
else if (env && env->isReleaseNode(this))
text << "(Release) ";
else
text << "Point ";
} else if (width >= 140) {
text << "Point ";
} else if (width >= 115) {
text << "Pt ";
} else if (width >= 100) {
text << "Pt ";
} else if (width >= 85) {
text << "Pt ";
} else if (width >= 65) {
text << "P ";
}
text << (getHandleIndex())
<< ": "
<< juce::String(legend->mapTime(time), places) << legend->getTimeUnits()
<< ", "
<< juce::String(legend->mapValue(value), places) << legend->getValueUnits();
} }
text << (getHandleIndex())
<< ": "
<< juce::String(legend->mapTime(time), places) << legend->getTimeUnits()
<< ", "
<< juce::String(legend->mapValue(value), places) << legend->getValueUnits();
getParentComponent()->setLegendText(text); getParentComponent()->setLegendText(text);
} }
void EnvelopeHandleComponent::paint(juce::Graphics& g) void EnvelopeHandleComponent::paint(juce::Graphics& g)
{ {
EnvelopeComponent *env = getParentComponent(); if (shouldDraw) {
juce::Colour handleColour; EnvelopeComponent *env = getParentComponent();
juce::Colour handleColour;
if(env == 0)
{ if(env == 0)
handleColour = juce::Colour(0xFF69B4FF); {
handleColour = juce::Colour(0xFF69B4FF);
}
else if(env->isReleaseNode(this))
{
handleColour = findColour(EnvelopeComponent::ReleaseNode);
}
else if(env->isLoopNode(this))
{
handleColour = findColour(EnvelopeComponent::LoopNode);
}
else
{
handleColour = findColour(EnvelopeComponent::Node);
}
g.setColour(handleColour);
g.fillEllipse(1, 1, getWidth() - 2, getHeight() - 2);
g.setColour(findColour(EnvelopeComponent::NodeOutline));
g.drawEllipse(1, 1, getWidth() - 2, getHeight() - 2, 1.0f);
} }
else if(env->isReleaseNode(this))
{
handleColour = env->getEnvColour(EnvelopeComponent::ReleaseNode);
}
else if(env->isLoopNode(this))
{
handleColour = env->getEnvColour(EnvelopeComponent::LoopNode);
}
else
{
handleColour = env->getEnvColour(EnvelopeComponent::Node);
}
g.setColour(handleColour);
g.fillRect(1, 1, getWidth()-2, getHeight()-2);
} }
void EnvelopeHandleComponent::moved() void EnvelopeHandleComponent::moved()
@ -236,8 +259,12 @@ void EnvelopeHandleComponent::mouseEnter(const juce::MouseEvent& e)
printf("MyEnvelopeHandleComponent::mouseEnter\n"); printf("MyEnvelopeHandleComponent::mouseEnter\n");
#endif #endif
setMouseCursor(juce::MouseCursor::CrosshairCursor); if (shouldDraw) {
updateLegend(); setMouseCursor(juce::MouseCursor::DraggingHandCursor);
updateLegend();
} else {
setMouseCursor(juce::MouseCursor::NormalCursor);
}
} }
void EnvelopeHandleComponent::mouseExit(const juce::MouseEvent& e) void EnvelopeHandleComponent::mouseExit(const juce::MouseEvent& e)
@ -256,60 +283,62 @@ void EnvelopeHandleComponent::mouseDown(const juce::MouseEvent& e)
printf("MyEnvelopeHandleComponent::mouseDown (%d, %d)\n", e.x, e.y); printf("MyEnvelopeHandleComponent::mouseDown (%d, %d)\n", e.x, e.y);
#endif #endif
setMouseCursor(juce::MouseCursor::NoCursor); if (shouldDraw) {
setMouseCursor(juce::MouseCursor::NoCursor);
if(e.mods.isShiftDown()) {
if(e.mods.isShiftDown()) {
if(!shouldLockTime && !shouldLockValue)
{ if(!shouldLockTime && !shouldLockValue)
getParentComponent()->setLegendTextToDefault(); {
removeThisHandle(); getParentComponent()->setLegendTextToDefault();
removeThisHandle();
}
return; // dont send drag msg
}
//else if(e.mods.isCtrlDown())
//{
// if(getParentComponent()->getAllowNodeEditing())
// {
// ignoreDrag = true;
//
// if(PopupComponent::getActivePopups() < 1)
// {
// EnvelopeNodePopup::create(this, getScreenX()+e.x, getScreenY()+e.y);
// }
// }
//}
else
{
offsetX = e.x;
offsetY = e.y;
resizeLimits.setMinimumOnscreenAmounts(HANDLESIZE,HANDLESIZE,HANDLESIZE,HANDLESIZE);
EnvelopeHandleComponent* previousHandle = getPreviousHandle();
EnvelopeHandleComponent* nextHandle = getNextHandle();
int leftLimit = previousHandle == 0 ? 0 : previousHandle->getX()+2;
int rightLimit = nextHandle == 0 ? getParentWidth()-HANDLESIZE : nextHandle->getX()-2;
// int leftLimit = previousHandle == 0 ? 0 : previousHandle->getX();
// int rightLimit = nextHandle == 0 ? getParentWidth()-HANDLESIZE : nextHandle->getX();
resizeLimits.setAdjacentHandleLimits(leftLimit, rightLimit);
dragger.startDraggingComponent(this, e);//&resizeLimits);
} }
return; // dont send drag msg
}
//else if(e.mods.isCtrlDown())
//{
// if(getParentComponent()->getAllowNodeEditing())
// {
// ignoreDrag = true;
//
// if(PopupComponent::getActivePopups() < 1)
// {
// EnvelopeNodePopup::create(this, getScreenX()+e.x, getScreenY()+e.y);
// }
// }
//}
else
{
offsetX = e.x;
offsetY = e.y;
resizeLimits.setMinimumOnscreenAmounts(HANDLESIZE,HANDLESIZE,HANDLESIZE,HANDLESIZE);
EnvelopeHandleComponent* previousHandle = getPreviousHandle();
EnvelopeHandleComponent* nextHandle = getNextHandle();
int leftLimit = previousHandle == 0 ? 0 : previousHandle->getX()+2;
int rightLimit = nextHandle == 0 ? getParentWidth()-HANDLESIZE : nextHandle->getX()-2;
// int leftLimit = previousHandle == 0 ? 0 : previousHandle->getX();
// int rightLimit = nextHandle == 0 ? getParentWidth()-HANDLESIZE : nextHandle->getX();
getParentComponent()->sendStartDrag();
resizeLimits.setAdjacentHandleLimits(leftLimit, rightLimit);
dragger.startDraggingComponent(this, e);//&resizeLimits);
} }
getParentComponent()->sendStartDrag();
} }
void EnvelopeHandleComponent::mouseDrag(const juce::MouseEvent& e) void EnvelopeHandleComponent::mouseDrag(const juce::MouseEvent& e)
{ {
if(ignoreDrag == true) return; if(ignoreDrag || !shouldDraw) return;
dragger.dragComponent(this, e, &resizeLimits); dragger.dragComponent(this, e, &resizeLimits);
@ -350,7 +379,11 @@ void EnvelopeHandleComponent::mouseUp(const juce::MouseEvent& e)
printf("MyEnvelopeHandleComponent::mouseUp\n"); printf("MyEnvelopeHandleComponent::mouseUp\n");
#endif #endif
if(ignoreDrag == true) if (!shouldDraw) {
goto exit;
}
if(ignoreDrag)
{ {
ignoreDrag = false; ignoreDrag = false;
goto exit; goto exit;
@ -361,7 +394,7 @@ void EnvelopeHandleComponent::mouseUp(const juce::MouseEvent& e)
env->quantiseHandle(this); env->quantiseHandle(this);
// } // }
setMouseCursor(juce::MouseCursor::CrosshairCursor); setMouseCursor(juce::MouseCursor::DraggingHandCursor);
setMousePositionToThisHandle(); setMousePositionToThisHandle();
offsetX = 0; offsetX = 0;
@ -504,22 +537,26 @@ void EnvelopeHandleComponent::lockTime(double timeToLock)
{ {
setTime(timeToLock); setTime(timeToLock);
shouldLockTime = true; shouldLockTime = true;
recalculateShouldDraw();
} }
void EnvelopeHandleComponent::lockValue(double valueToLock) void EnvelopeHandleComponent::lockValue(double valueToLock)
{ {
setValue(valueToLock); setValue(valueToLock);
shouldLockValue = true; shouldLockValue = true;
recalculateShouldDraw();
} }
void EnvelopeHandleComponent::unlockTime() void EnvelopeHandleComponent::unlockTime()
{ {
shouldLockTime = false; shouldLockTime = false;
recalculateShouldDraw();
} }
void EnvelopeHandleComponent::unlockValue() void EnvelopeHandleComponent::unlockValue()
{ {
shouldLockValue = false; shouldLockValue = false;
recalculateShouldDraw();
} }
void EnvelopeHandleComponent::recalculatePosition() void EnvelopeHandleComponent::recalculatePosition()
@ -532,6 +569,10 @@ void EnvelopeHandleComponent::recalculatePosition()
getParentComponent()->repaint(); getParentComponent()->repaint();
} }
void EnvelopeHandleComponent::recalculateShouldDraw() {
shouldDraw = !shouldLockTime || !shouldLockValue;
}
EnvelopeComponent::EnvelopeComponent() EnvelopeComponent::EnvelopeComponent()
: minNumHandles(0), : minNumHandles(0),
@ -554,16 +595,6 @@ EnvelopeComponent::EnvelopeComponent()
{ {
setMouseCursor(juce::MouseCursor::NormalCursor); setMouseCursor(juce::MouseCursor::NormalCursor);
setBounds(0, 0, 200, 200); // non-zero size to start with setBounds(0, 0, 200, 200); // non-zero size to start with
colours[Node] = juce::Colour(0xFF69B4FF);
colours[ReleaseNode] = juce::Colour(0xFFB469FF);
colours[LoopNode] = juce::Colour(0xFF69FFB4);
colours[Line] = juce::Colour(0xFFFFFFFF);
colours[LoopLine] = juce::Colour(0xFFB469FF);
colours[Background] = juce::Colour(0xFF555555);
colours[GridLine] = juce::Colour(0xFF888888);
colours[LegendText] = juce::Colour(0xFF000000);
colours[LegendBackground] = juce::Colour(0xFF696969);
} }
EnvelopeComponent::~EnvelopeComponent() EnvelopeComponent::~EnvelopeComponent()
@ -719,8 +750,8 @@ void EnvelopeComponent::paint(juce::Graphics& g)
time = nextTime; time = nextTime;
} }
g.setColour(colours[Line]); g.setColour(findColour(Line));
g.strokePath (path, juce::PathStrokeType(1.0f)); g.strokePath (path, juce::PathStrokeType(2.0f));
if((loopNode >= 0) && (releaseNode >= 0) && (releaseNode > loopNode)) if((loopNode >= 0) && (releaseNode >= 0) && (releaseNode > loopNode))
{ {
@ -730,7 +761,7 @@ void EnvelopeComponent::paint(juce::Graphics& g)
if((releaseHandle != 0) && (loopHandle != 0)) if((releaseHandle != 0) && (loopHandle != 0))
{ {
// draw a horizontal line from release // draw a horizontal line from release
g.setColour(colours[LoopLine]); g.setColour(findColour(LoopLine));
const float loopY = (loopHandle->getY() + loopHandle->getBottom()) * 0.5f; const float loopY = (loopHandle->getY() + loopHandle->getBottom()) * 0.5f;
const float releaseY = (releaseHandle->getY() + releaseHandle->getBottom()) * 0.5f; const float releaseY = (releaseHandle->getY() + releaseHandle->getBottom()) * 0.5f;
@ -748,7 +779,7 @@ void EnvelopeComponent::paint(juce::Graphics& g)
0.5f); 0.5f);
if(loopY == releaseY) if(loopY == releaseY)
g.setColour(colours[LoopNode]); g.setColour(findColour(LoopNode));
// g.drawArrow(loopX + arrowLength, releaseY, // g.drawArrow(loopX + arrowLength, releaseY,
// loopX, releaseY, // loopX, releaseY,
@ -770,10 +801,10 @@ inline double round(double a, double b) throw()
void EnvelopeComponent::paintBackground(juce::Graphics& g) void EnvelopeComponent::paintBackground(juce::Graphics& g)
{ {
g.setColour(colours[Background]); g.setColour(findColour(Background));
g.fillRect(0, 0, getWidth(), getHeight()); g.fillRect(0, 0, getWidth(), getHeight());
g.setColour(colours[GridLine]); g.setColour(findColour(GridLine));
if((gridDisplayMode & GridValue) && (valueGrid > 0.0)) if((gridDisplayMode & GridValue) && (valueGrid > 0.0))
{ {
@ -904,7 +935,7 @@ void EnvelopeComponent::mouseUp(const juce::MouseEvent& e)
if(e.mods.isCtrlDown() == false) if(e.mods.isCtrlDown() == false)
quantiseHandle(draggingHandle); quantiseHandle(draggingHandle);
setMouseCursor(juce::MouseCursor::CrosshairCursor); setMouseCursor(juce::MouseCursor::DraggingHandCursor);
draggingHandle->setMousePositionToThisHandle(); draggingHandle->setMousePositionToThisHandle();
draggingHandle->resetOffsets(); draggingHandle->resetOffsets();
draggingHandle = 0; draggingHandle = 0;
@ -1389,28 +1420,6 @@ double EnvelopeComponent::constrainValue(double valueToConstrain) const
// return value; // return value;
//} //}
void EnvelopeComponent::setEnvColour(const EnvColours which, juce::Colour colour) throw()
{
if((which >= 0) && (which < NumEnvColours))
{
//lock();
colours[which] = colour;
//unlock();
//updateGUI();
getParentComponent()->repaint();
repaint();
}
}
const juce::Colour EnvelopeComponent::getEnvColour(const EnvColours which) const throw()
{
if ((which < 0) || (which >= NumEnvColours))
return juce::Colour();
else
return colours[which];
}
EnvelopeLegendComponent::EnvelopeLegendComponent(juce::String _defaultText) EnvelopeLegendComponent::EnvelopeLegendComponent(juce::String _defaultText)
: defaultText(_defaultText) : defaultText(_defaultText)
{ {
@ -1440,12 +1449,12 @@ void EnvelopeLegendComponent::resized()
void EnvelopeLegendComponent::paint(juce::Graphics& g) void EnvelopeLegendComponent::paint(juce::Graphics& g)
{ {
EnvelopeComponent *env = getEnvelopeComponent(); EnvelopeComponent *env = getEnvelopeComponent();
juce::Colour backColour = env ? env->getEnvColour(EnvelopeComponent::LegendBackground) : juce::Colour(0xFF696969); juce::Colour backColour = findColour(EnvelopeComponent::LegendBackground);
g.setColour(backColour); g.setColour(backColour);
g.fillRect(0, 0, getWidth(), getHeight()); g.fillRect(0, 0, getWidth(), getHeight());
juce::Colour textColour = env ? env->getEnvColour(EnvelopeComponent::LegendText) : juce::Colour(0xFF0000); juce::Colour textColour = findColour(EnvelopeComponent::LegendText);
text->setColour(juce::Label::textColourId, textColour); text->setColour(juce::Label::textColourId, textColour);
} }

Wyświetl plik

@ -46,7 +46,7 @@
#include "EnvCurve.h" #include "EnvCurve.h"
#define HANDLESIZE 7 #define HANDLESIZE 11
#define FINETUNE 0.001 #define FINETUNE 0.001
//#define MYDEBUG 1 // get rid of this later //#define MYDEBUG 1 // get rid of this later
@ -121,6 +121,7 @@ public:
private: private:
bool dontUpdateTimeAndValue; bool dontUpdateTimeAndValue;
void recalculatePosition(); void recalculatePosition();
void recalculateShouldDraw();
juce::ComponentDragger dragger; juce::ComponentDragger dragger;
int lastX, lastY; int lastX, lastY;
@ -128,7 +129,7 @@ private:
EnvelopeHandleComponentConstrainer resizeLimits; EnvelopeHandleComponentConstrainer resizeLimits;
double time, value; double time, value;
bool shouldLockTime, shouldLockValue; bool shouldLockTime, shouldLockValue, shouldDraw;
EnvCurve curve; EnvCurve curve;
bool ignoreDrag; bool ignoreDrag;
}; };
@ -235,9 +236,21 @@ public:
// double quantiseDomain(double value); // double quantiseDomain(double value);
// double quantiseValue(double value); // double quantiseValue(double value);
enum EnvColours { Node, ReleaseNode, LoopNode, Line, LoopLine, Background, GridLine, LegendText, LegendBackground, NumEnvColours }; const static int COLOUR_OFFSET = 0x6082100;
void setEnvColour(const EnvColours which, juce::Colour colour) throw();
const juce::Colour getEnvColour(const EnvColours which) const throw(); enum EnvColours {
Node = COLOUR_OFFSET,
ReleaseNode = COLOUR_OFFSET + 1,
LoopNode = COLOUR_OFFSET + 2,
NodeOutline = COLOUR_OFFSET + 3,
Line = COLOUR_OFFSET + 4,
LoopLine = COLOUR_OFFSET + 5,
Background = COLOUR_OFFSET + 6,
GridLine = COLOUR_OFFSET + 7,
LegendText = COLOUR_OFFSET + 8,
LegendBackground = COLOUR_OFFSET + 9,
NumEnvColours = 10,
};
enum MoveMode { MoveClip, MoveSlide, NumMoveModes }; enum MoveMode { MoveClip, MoveSlide, NumMoveModes };
@ -262,8 +275,6 @@ private:
bool allowCurveEditing = false; bool allowCurveEditing = false;
bool allowNodeEditing = false; bool allowNodeEditing = false;
bool adsrMode = false; bool adsrMode = false;
juce::Colour colours[NumEnvColours];
}; };
class EnvelopeLegendComponent : public juce::Component class EnvelopeLegendComponent : public juce::Component
@ -311,16 +322,7 @@ public:
Env getEnv() const { return getEnvelopeComponent()->getEnv(); } Env getEnv() const { return getEnvelopeComponent()->getEnv(); }
void setEnv(Env const& env) { return getEnvelopeComponent()->setEnv(env); } void setEnv(Env const& env) { return getEnvelopeComponent()->setEnv(env); }
float lookup(const float time) const { return getEnvelopeComponent()->lookup(time); } float lookup(const float time) const { return getEnvelopeComponent()->lookup(time); }
void setEnvColour(const EnvelopeComponent::EnvColours which, juce::Colour const& colour) throw()
{
envelope->setEnvColour(which, colour);
}
const juce::Colour getEnvColour(const EnvelopeComponent::EnvColours which) const throw()
{
return envelope->getEnvColour(which);
}
void setDomainRange(const double min, const double max) { envelope->setDomainRange(min, max); } void setDomainRange(const double min, const double max) { envelope->setDomainRange(min, max); }
void setDomainRange(const double max) { setDomainRange(0.0, max); } void setDomainRange(const double max) { setDomainRange(0.0, max); }

Wyświetl plik

@ -1,23 +1,21 @@
#include "Effect.h" #include "Effect.h"
#include <numbers> #include <numbers>
Effect::Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters, juce::String description) : Effect::Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters) :
effectApplication(effectApplication), effectApplication(effectApplication),
parameters(parameters), parameters(parameters),
enabled(nullptr), enabled(nullptr),
actualValues(std::vector<double>(parameters.size(), 0.0)), actualValues(std::vector<double>(parameters.size(), 0.0)) {}
description(description) {}
Effect::Effect(std::shared_ptr<EffectApplication> effectApplication, EffectParameter* parameter, juce::String description) : Effect(effectApplication, std::vector<EffectParameter*>{parameter}, description) {} Effect::Effect(std::shared_ptr<EffectApplication> effectApplication, EffectParameter* parameter) : Effect(effectApplication, std::vector<EffectParameter*>{parameter}) {}
Effect::Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, const std::vector<EffectParameter*>& parameters, juce::String description) : Effect::Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, const std::vector<EffectParameter*>& parameters) :
application(application), application(application),
parameters(parameters), parameters(parameters),
enabled(nullptr), enabled(nullptr),
actualValues(std::vector<double>(parameters.size(), 0.0)), actualValues(std::vector<double>(parameters.size(), 0.0)) {}
description(description) {}
Effect::Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, EffectParameter* parameter, juce::String description) : Effect(application, std::vector<EffectParameter*>{parameter}, description) {} Effect::Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, EffectParameter* parameter) : Effect(application, std::vector<EffectParameter*>{parameter}) {}
Vector2 Effect::apply(int index, Vector2 input) { Vector2 Effect::apply(int index, Vector2 input) {
animateValues(); animateValues();
@ -203,7 +201,3 @@ EffectParameter* Effect::getParameter(juce::String id) {
} }
return nullptr; return nullptr;
} }
juce::String Effect::getDescription() {
return description;
}

Wyświetl plik

@ -8,10 +8,10 @@
class Effect { class Effect {
public: public:
Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters, juce::String description); Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters);
Effect(std::shared_ptr<EffectApplication> effectApplication, EffectParameter* parameter, juce::String description); Effect(std::shared_ptr<EffectApplication> effectApplication, EffectParameter* parameter);
Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, const std::vector<EffectParameter*>& parameters, juce::String description); Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, const std::vector<EffectParameter*>& parameters);
Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, EffectParameter* parameter, juce::String description); Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, EffectParameter* parameter);
Vector2 apply(int index, Vector2 input); Vector2 apply(int index, Vector2 input);
@ -32,7 +32,6 @@ public:
void save(juce::XmlElement* xml); void save(juce::XmlElement* xml);
void load(juce::XmlElement* xml); void load(juce::XmlElement* xml);
EffectParameter* getParameter(juce::String id); EffectParameter* getParameter(juce::String id);
juce::String getDescription();
std::vector<EffectParameter*> parameters; std::vector<EffectParameter*> parameters;
BooleanParameter* enabled; BooleanParameter* enabled;
@ -44,7 +43,6 @@ private:
int precedence = -1; int precedence = -1;
int sampleRate = 192000; int sampleRate = 192000;
std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application; std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application;
juce::String description;
std::shared_ptr<EffectApplication> effectApplication; std::shared_ptr<EffectApplication> effectApplication;

Wyświetl plik

@ -309,6 +309,7 @@ public:
LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", paramID + "Lfo", getVersionHint(), 1); LfoTypeParameter* lfo = new LfoTypeParameter(name + " LFO", paramID + "Lfo", getVersionHint(), 1);
FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", paramID + "LfoRate", getVersionHint(), 1.0f, 0.0f, 100.0f, 0.1f, "Hz"); FloatParameter* lfoRate = new FloatParameter(name + " LFO Rate", paramID + "LfoRate", getVersionHint(), 1.0f, 0.0f, 100.0f, 0.1f, "Hz");
std::atomic<float> phase = 0.0f; std::atomic<float> phase = 0.0f;
juce::String description;
std::vector<juce::AudioProcessorParameter*> getParameters() { std::vector<juce::AudioProcessorParameter*> getParameters() {
std::vector<juce::AudioProcessorParameter*> parameters; std::vector<juce::AudioProcessorParameter*> parameters;
@ -349,5 +350,5 @@ public:
} }
} }
EffectParameter(juce::String name, juce::String id, int versionHint, float value, float min, float max, float step = 0.01, bool smoothValueChange = true) : FloatParameter(name, id, versionHint, value, min, max, step), smoothValueChange(smoothValueChange) {} EffectParameter(juce::String name, juce::String description, juce::String id, int versionHint, float value, float min, float max, float step = 0.01, bool smoothValueChange = true) : FloatParameter(name, id, versionHint, value, min, max, step), smoothValueChange(smoothValueChange), description(description) {}
}; };

Wyświetl plik

@ -5,6 +5,9 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, in
addAndMakeVisible(slider); addAndMakeVisible(slider);
addChildComponent(lfoSlider); addChildComponent(lfoSlider);
addAndMakeVisible(lfo); addAndMakeVisible(lfo);
addAndMakeVisible(label);
label.setFont(juce::Font(13.0f));
lfo.addItem("Static", static_cast<int>(LfoType::Static)); lfo.addItem("Static", static_cast<int>(LfoType::Static));
lfo.addItem("Sine", static_cast<int>(LfoType::Sine)); lfo.addItem("Sine", static_cast<int>(LfoType::Sine));
@ -15,9 +18,6 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, in
lfo.addItem("Reverse Sawtooth", static_cast<int>(LfoType::ReverseSawtooth)); lfo.addItem("Reverse Sawtooth", static_cast<int>(LfoType::ReverseSawtooth));
lfo.addItem("Noise", static_cast<int>(LfoType::Noise)); lfo.addItem("Noise", static_cast<int>(LfoType::Noise));
// temporarily disabling tooltips
// setTooltip(effect.getDescription());
effect.addListener(index, this); effect.addListener(index, this);
setupComponent(); setupComponent();
} }
@ -27,6 +27,9 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect) :
void EffectComponent::setupComponent() { void EffectComponent::setupComponent() {
EffectParameter* parameter = effect.parameters[index]; EffectParameter* parameter = effect.parameters[index];
label.setTooltip(parameter->description);
label.setText(parameter->name, juce::dontSendNotification);
slider.setRange(parameter->min, parameter->max, parameter->step); slider.setRange(parameter->min, parameter->max, parameter->step);
slider.setValue(parameter->getValueUnnormalised(), juce::dontSendNotification); slider.setValue(parameter->getValueUnnormalised(), juce::dontSendNotification);
@ -118,16 +121,14 @@ void EffectComponent::resized() {
lfo.setBounds(bounds.removeFromRight(100).reduced(5)); lfo.setBounds(bounds.removeFromRight(100).reduced(5));
} }
textBounds = bounds.removeFromLeft(120); bounds.removeFromLeft(5);
textBounds.removeFromLeft(5); label.setBounds(bounds.removeFromLeft(120));
slider.setBounds(bounds); slider.setBounds(bounds);
lfoSlider.setBounds(bounds); lfoSlider.setBounds(bounds);
} }
void EffectComponent::paint(juce::Graphics& g) { void EffectComponent::paint(juce::Graphics& g) {
g.fillAll(findColour(effectComponentBackgroundColourId)); g.fillAll(findColour(effectComponentBackgroundColourId));
g.setColour(juce::Colours::white);
g.drawText(effect.parameters[index]->name, textBounds, juce::Justification::left);
} }
void EffectComponent::mouseDown(const juce::MouseEvent& event) { void EffectComponent::mouseDown(const juce::MouseEvent& event) {

Wyświetl plik

@ -28,11 +28,11 @@ public:
private: private:
void setupComponent(); void setupComponent();
bool lfoEnabled = true; bool lfoEnabled = true;
juce::Rectangle<int> textBounds;
std::shared_ptr<juce::Component> component; std::shared_ptr<juce::Component> component;
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
juce::Label popupLabel; juce::Label popupLabel;
juce::Label label;
LabelledTextBox min{"Min"}; LabelledTextBox min{"Min"};
LabelledTextBox max{"Max"}; LabelledTextBox max{"Max"};

Wyświetl plik

@ -86,14 +86,19 @@ void EffectsListComponent::resized() {
std::shared_ptr<juce::Component> EffectsListComponent::createComponent(EffectParameter* parameter) { std::shared_ptr<juce::Component> EffectsListComponent::createComponent(EffectParameter* parameter) {
if (parameter->paramID == "perspectiveRotateX" || parameter->paramID == "perspectiveRotateY" || parameter->paramID == "perspectiveRotateZ") { if (parameter->paramID == "perspectiveRotateX" || parameter->paramID == "perspectiveRotateY" || parameter->paramID == "perspectiveRotateZ") {
BooleanParameter* toggle; BooleanParameter* toggle;
juce::String axis;
if (parameter->paramID == "perspectiveRotateX") { if (parameter->paramID == "perspectiveRotateX") {
toggle = audioProcessor.perspectiveEffect->fixedRotateX; toggle = audioProcessor.perspectiveEffect->fixedRotateX;
axis = "X";
} else if (parameter->paramID == "perspectiveRotateY") { } else if (parameter->paramID == "perspectiveRotateY") {
toggle = audioProcessor.perspectiveEffect->fixedRotateY; toggle = audioProcessor.perspectiveEffect->fixedRotateY;
axis = "Y";
} else if (parameter->paramID == "perspectiveRotateZ") { } else if (parameter->paramID == "perspectiveRotateZ") {
toggle = audioProcessor.perspectiveEffect->fixedRotateZ; toggle = audioProcessor.perspectiveEffect->fixedRotateZ;
axis = "Z";
} }
std::shared_ptr<SvgButton> button = std::make_shared<SvgButton>(parameter->name, BinaryData::fixed_rotate_svg, "white", "red", toggle); std::shared_ptr<SvgButton> button = std::make_shared<SvgButton>(parameter->name, BinaryData::fixed_rotate_svg, "white", "red", toggle);
button->setTooltip("Toggles whether the rotation around the " + axis + " axis is fixed, or changes according to the rotation speed.");
button->onClick = [this, toggle] { button->onClick = [this, toggle] {
toggle->setBoolValueNotifyingHost(!toggle->getBoolValue()); toggle->setBoolValueNotifyingHost(!toggle->getBoolValue());
}; };
@ -103,6 +108,7 @@ std::shared_ptr<juce::Component> EffectsListComponent::createComponent(EffectPar
std::weak_ptr<SvgButton> weakButton = button; std::weak_ptr<SvgButton> weakButton = button;
button->setEdgeIndent(5); button->setEdgeIndent(5);
button->setToggleState(editor.editingPerspective, juce::dontSendNotification); button->setToggleState(editor.editingPerspective, juce::dontSendNotification);
button->setTooltip("Toggles whether the text editor is editing the currently open file, or the Lua 3D perspective function.");
button->onClick = [this, weakButton] { button->onClick = [this, weakButton] {
if (auto button = weakButton.lock()) { if (auto button = weakButton.lock()) {
editor.editPerspectiveFunction(button->getToggleState()); editor.editPerspectiveFunction(button->getToggleState());