kopia lustrzana https://github.com/jameshball/osci-render
commit
90fcd085be
|
@ -1,6 +1,7 @@
|
|||
#include "LookAndFeel.h"
|
||||
|
||||
OscirenderLookAndFeel::OscirenderLookAndFeel() {
|
||||
// slider
|
||||
setColour(juce::Slider::thumbColourId, Colours::veryDark);
|
||||
setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::white);
|
||||
setColour(juce::Slider::textBoxBackgroundColourId, Colours::veryDark);
|
||||
|
@ -8,38 +9,72 @@ OscirenderLookAndFeel::OscirenderLookAndFeel() {
|
|||
setColour(juce::Slider::trackColourId, juce::Colours::grey);
|
||||
setColour(juce::Slider::backgroundColourId, Colours::dark);
|
||||
setColour(sliderThumbOutlineColourId, juce::Colours::white);
|
||||
|
||||
// buttons
|
||||
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(groupComponentHeaderColourId, Colours::veryDark);
|
||||
setColour(juce::PopupMenu::backgroundColourId, Colours::veryDark);
|
||||
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::outlineColourId, 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::outlineColourId, juce::Colours::white);
|
||||
setColour(juce::CaretComponent::caretColourId, Dracula::foreground);
|
||||
setColour(juce::TextEditor::highlightColourId, Colours::grey);
|
||||
|
||||
// list box
|
||||
setColour(juce::ListBox::backgroundColourId, Colours::darker);
|
||||
|
||||
// scroll bar
|
||||
setColour(juce::ScrollBar::thumbColourId, juce::Colours::white);
|
||||
setColour(juce::ScrollBar::trackColourId, Colours::veryDark);
|
||||
setColour(juce::ScrollBar::backgroundColourId, Colours::veryDark);
|
||||
|
||||
// custom components
|
||||
setColour(effectComponentBackgroundColourId, juce::Colours::transparentBlack);
|
||||
setColour(effectComponentHandleColourId, Colours::veryDark);
|
||||
|
||||
// code editor
|
||||
setColour(juce::CodeEditorComponent::backgroundColourId, Colours::darker);
|
||||
setColour(juce::CodeEditorComponent::defaultTextColourId, Dracula::foreground);
|
||||
setColour(juce::CodeEditorComponent::lineNumberBackgroundId, Colours::veryDark);
|
||||
setColour(juce::CodeEditorComponent::lineNumberTextId, Dracula::foreground);
|
||||
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::UIColour::defaultFill, Colours::accentColor);
|
||||
}
|
||||
|
@ -175,6 +210,20 @@ void OscirenderLookAndFeel::drawMenuBarBackground(juce::Graphics& g, int width,
|
|||
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 cs;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "UGen/ugen_JuceEnvelopeComponent.h"
|
||||
|
||||
enum ColourIds {
|
||||
groupComponentBackgroundColourId,
|
||||
|
@ -8,11 +9,10 @@ enum ColourIds {
|
|||
effectComponentBackgroundColourId,
|
||||
effectComponentHandleColourId,
|
||||
sliderThumbOutlineColourId,
|
||||
tabbedComponentBackgroundColourId,
|
||||
};
|
||||
|
||||
namespace Colours {
|
||||
const juce::Colour dark{0xff424242};
|
||||
const juce::Colour dark{0xff353535};
|
||||
const juce::Colour darker{0xff212121};
|
||||
const juce::Colour veryDark{0xff111111};
|
||||
const juce::Colour grey{0xff555555};
|
||||
|
@ -34,6 +34,37 @@ namespace Dracula {
|
|||
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 {
|
||||
public:
|
||||
OscirenderLookAndFeel();
|
||||
|
@ -58,6 +89,6 @@ public:
|
|||
bool shouldDrawButtonAsHighlighted,
|
||||
bool shouldDrawButtonAsDown) override;
|
||||
void drawMenuBarBackground(juce::Graphics& g, int width, int height, bool, juce::MenuBarComponent& menuBar) override;
|
||||
|
||||
juce::CodeEditorComponent::ColourScheme getDefaultColourScheme();
|
||||
void drawTooltip(juce::Graphics& g, const juce::String& text, int width, int height) override;
|
||||
};
|
||||
|
|
|
@ -83,6 +83,9 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
|||
pluginEditor.fileUpdated(fileName);
|
||||
};
|
||||
|
||||
fileName.setFont(juce::Font(16.0f, juce::Font::plain));
|
||||
fileName.setText("filename");
|
||||
|
||||
fileName.onReturnKey = [this] {
|
||||
createFile.triggerClick();
|
||||
};
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "PluginEditor.h"
|
||||
|
||||
MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) {
|
||||
setText("MIDI Settings");
|
||||
|
||||
addAndMakeVisible(midiToggle);
|
||||
addAndMakeVisible(keyboard);
|
||||
|
||||
|
@ -15,6 +17,7 @@ MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
|||
envelope.setAdsrMode(true);
|
||||
envelope.setEnv(audioProcessor.adsrEnv);
|
||||
envelope.addListener(&audioProcessor);
|
||||
envelope.setGrid(EnvelopeComponent::GridBoth, EnvelopeComponent::GridNone, 0.1, 0.25);
|
||||
|
||||
audioProcessor.attackTime->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::handleAsyncUpdate() {
|
||||
DBG("MidiComponent::handleAsyncUpdate");
|
||||
Env newEnv = Env(
|
||||
{
|
||||
0.0,
|
||||
|
@ -71,14 +73,13 @@ void MidiComponent::handleAsyncUpdate() {
|
|||
}
|
||||
|
||||
void MidiComponent::resized() {
|
||||
auto area = getLocalBounds().reduced(5);
|
||||
midiToggle.setBounds(area.removeFromTop(50));
|
||||
envelope.setBounds(area.removeFromTop(200));
|
||||
keyboard.setBounds(area.removeFromBottom(100));
|
||||
auto area = getLocalBounds().withTrimmedTop(20).reduced(20);
|
||||
midiToggle.setBounds(area.removeFromTop(30));
|
||||
area.removeFromTop(5);
|
||||
keyboard.setBounds(area.removeFromBottom(50));
|
||||
envelope.setBounds(area);
|
||||
}
|
||||
|
||||
void MidiComponent::paint(juce::Graphics& g) {
|
||||
auto rect = getLocalBounds().reduced(5);
|
||||
g.setColour(getLookAndFeel().findColour(groupComponentBackgroundColourId));
|
||||
g.fillRect(rect);
|
||||
juce::GroupComponent::paint(g);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "PluginProcessor.h"
|
||||
|
||||
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:
|
||||
MidiComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&);
|
||||
~MidiComponent() override;
|
||||
|
@ -20,8 +20,7 @@ private:
|
|||
OscirenderAudioProcessorEditor& pluginEditor;
|
||||
|
||||
juce::ToggleButton midiToggle{"Enable MIDI"};
|
||||
juce::MidiKeyboardState keyboardState;
|
||||
juce::MidiKeyboardComponent keyboard{keyboardState, juce::MidiKeyboardComponent::horizontalKeyboard};
|
||||
juce::MidiKeyboardComponent keyboard{audioProcessor.keyboardState, juce::MidiKeyboardComponent::horizontalKeyboard};
|
||||
|
||||
EnvelopeContainerComponent envelope;
|
||||
|
||||
|
|
|
@ -73,6 +73,11 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor
|
|||
rotateX.setComponent(fixedRotateX);
|
||||
rotateY.setComponent(fixedRotateY);
|
||||
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() {
|
||||
|
|
|
@ -6,10 +6,6 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
{
|
||||
juce::Desktop::getInstance().setDefaultLookAndFeel(&lookAndFeel);
|
||||
setLookAndFeel(&lookAndFeel);
|
||||
|
||||
addAndMakeVisible(tabs);
|
||||
tabs.addTab("Main", getLookAndFeel().findColour(tabbedComponentBackgroundColourId), &settings, false);
|
||||
tabs.addTab("MIDI", getLookAndFeel().findColour(tabbedComponentBackgroundColourId), &midi, false);
|
||||
addAndMakeVisible(volume);
|
||||
|
||||
menuBar.setModel(&menuBarModel);
|
||||
|
@ -33,6 +29,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
juce::Path path;
|
||||
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
|
||||
collapseButton.setShape(path, false, true, true);
|
||||
collapseButton.setMouseCursor(juce::MouseCursor::PointingHandCursor);
|
||||
|
||||
colourScheme = lookAndFeel.getDefaultColourScheme();
|
||||
|
||||
|
@ -62,6 +59,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
layout.setItemLayout(1, 7, 7, 7);
|
||||
layout.setItemLayout(2, -0.1, -1.0, -0.3);
|
||||
|
||||
addAndMakeVisible(settings);
|
||||
addAndMakeVisible(resizerBar);
|
||||
}
|
||||
|
||||
|
@ -115,6 +113,8 @@ void OscirenderAudioProcessorEditor::resized() {
|
|||
|
||||
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);
|
||||
auto dummyBounds = dummy.getBounds();
|
||||
collapseButton.setBounds(dummyBounds.removeFromRight(20));
|
||||
|
@ -123,6 +123,7 @@ void OscirenderAudioProcessorEditor::resized() {
|
|||
|
||||
} else {
|
||||
codeEditors[index]->setBounds(0, 0, 0, 0);
|
||||
resizerBar.setBounds(0, 0, 0, 0);
|
||||
collapseButton.setBounds(area.removeFromRight(20));
|
||||
}
|
||||
} else {
|
||||
|
@ -139,9 +140,8 @@ void OscirenderAudioProcessorEditor::resized() {
|
|||
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
|
||||
collapseButton.setShape(path, false, true, true);
|
||||
}
|
||||
|
||||
tabs.setBounds(area);
|
||||
|
||||
settings.setBounds(area);
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,6 @@ public:
|
|||
private:
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
|
||||
juce::TabbedComponent tabs{juce::TabbedButtonBar::TabsAtTop};
|
||||
MidiComponent midi{audioProcessor, *this};
|
||||
SettingsComponent settings{audioProcessor, *this};
|
||||
VolumeComponent volume{audioProcessor};
|
||||
std::vector<std::shared_ptr<juce::CodeDocument>> codeDocuments;
|
||||
|
@ -58,7 +56,7 @@ private:
|
|||
juce::StretchableLayoutManager layout;
|
||||
juce::StretchableLayoutResizerBar resizerBar{&layout, 1, true};
|
||||
|
||||
juce::TooltipWindow tooltipWindow{this};
|
||||
juce::TooltipWindow tooltipWindow{this, 0};
|
||||
|
||||
std::atomic<bool> updatingDocumentsWithParserLock = false;
|
||||
|
||||
|
|
|
@ -36,68 +36,63 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
|||
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<BitCrushEffect>(),
|
||||
new EffectParameter("Bit Crush", "bitCrush", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"bitCrush"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<BulgeEffect>(),
|
||||
new EffectParameter("Bulge", "bulge", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"bulge"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<RotateEffect>(),
|
||||
new EffectParameter("2D Rotate", "2DRotateSpeed", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"2DRotate"
|
||||
new EffectParameter("2D Rotate", "Rotates the image, and pans the audio.", "2DRotateSpeed", VERSION_HINT, 0.0, 0.0, 1.0)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<VectorCancellingEffect>(),
|
||||
new EffectParameter("Vector Cancelling", "vectorCancelling", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"vectorCancelling"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<DistortEffect>(false),
|
||||
new EffectParameter("Distort X", "distortX", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"distortX"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<DistortEffect>(true),
|
||||
new EffectParameter("Distort Y", "distortY", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"distortY"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
input.x += values[0];
|
||||
input.y += values[1];
|
||||
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)},
|
||||
"translate"
|
||||
}, std::vector<EffectParameter*>{
|
||||
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>(
|
||||
std::make_shared<SmoothEffect>(),
|
||||
new EffectParameter("Smoothing", "smoothing", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"smoothing"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
wobbleEffect,
|
||||
new EffectParameter("Wobble", "wobble", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"wobble"
|
||||
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)
|
||||
));
|
||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||
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)},
|
||||
"delay"
|
||||
std::vector<EffectParameter*>{
|
||||
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>(
|
||||
perspectiveEffect,
|
||||
std::vector<EffectParameter*>{
|
||||
new EffectParameter("3D Perspective", "perspectiveStrength", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
new EffectParameter("Depth (z)", "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 X", "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 Z", "perspectiveRotateZ", VERSION_HINT, 0.0, -1.0, 1.0),
|
||||
},
|
||||
"perspective"
|
||||
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)", "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),
|
||||
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", "Controls the rotation of the object in the Z axis.", "perspectiveRotateZ", VERSION_HINT, 0.0, -1.0, 1.0),
|
||||
}
|
||||
));
|
||||
toggleableEffects.push_back(traceMax);
|
||||
toggleableEffects.push_back(traceMin);
|
||||
|
@ -275,8 +270,12 @@ void OscirenderAudioProcessor::addLuaSlider() {
|
|||
|
||||
luaEffects.push_back(std::make_shared<Effect>(
|
||||
std::make_shared<LuaEffect>(sliderName, *this),
|
||||
new EffectParameter("Lua " + sliderName, "lua" + sliderName, VERSION_HINT, 0.0, 0.0, 1.0, 0.001, false),
|
||||
"lua" + sliderName
|
||||
new EffectParameter(
|
||||
"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();
|
||||
|
@ -480,6 +479,9 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
|
|||
buffer.clear(i, 0, buffer.getNumSamples());
|
||||
}
|
||||
|
||||
// merge keyboard state and midi messages
|
||||
keyboardState.processNextMidiBuffer(midiMessages, 0, buffer.getNumSamples(), true);
|
||||
|
||||
bool usingInput = inputEnabled->getBoolValue();
|
||||
|
||||
bool usingMidi = midiEnabled->getBoolValue();
|
||||
|
|
|
@ -81,24 +81,36 @@ public:
|
|||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
frequency = values[0];
|
||||
return input;
|
||||
}, new EffectParameter("Frequency", "frequency", VERSION_HINT, 440.0, 0.0, 12000.0, 0.1),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
volume = values[0];
|
||||
return input;
|
||||
}, new EffectParameter("Volume", "volume", VERSION_HINT, 1.0, 0.0, 3.0),
|
||||
"Controls the volume of the sound. Works by scaling the image and sound by a factor."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
threshold = values[0];
|
||||
return input;
|
||||
}, new EffectParameter("Threshold", "threshold", VERSION_HINT, 1.0, 0.0, 1.0),
|
||||
"Clips the sound and image to a maximum value. Applying a harsher threshold results in a more distorted sound."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
|
@ -109,8 +121,12 @@ public:
|
|||
camera->setFocalLength(values[0]);
|
||||
}
|
||||
return input;
|
||||
}, new EffectParameter("Focal length", "objFocalLength", VERSION_HINT, 1.0, 0.0, 2.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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);
|
||||
|
@ -129,8 +145,12 @@ public:
|
|||
}
|
||||
}
|
||||
return input;
|
||||
}, new EffectParameter("Object Rotate X", "objRotateX", VERSION_HINT, 1.0, -1.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
|
@ -145,8 +165,12 @@ public:
|
|||
}
|
||||
}
|
||||
return input;
|
||||
}, new EffectParameter("Object Rotate Y", "objRotateY", VERSION_HINT, 1.0, -1.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
|
@ -161,8 +185,12 @@ public:
|
|||
}
|
||||
}
|
||||
return input;
|
||||
}, new EffectParameter("Object Rotate Z", "objRotateZ", VERSION_HINT, 0.0, -1.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
|
@ -172,27 +200,39 @@ public:
|
|||
obj->setRotationSpeed(values[0]);
|
||||
}
|
||||
return input;
|
||||
}, new EffectParameter("Rotate Speed", "objRotateSpeed", VERSION_HINT, 0.0, -1.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
return input;
|
||||
}, new EffectParameter("Trace max", "traceMax", VERSION_HINT, 1.0, 0.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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>(
|
||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||
return input;
|
||||
}, new EffectParameter("Trace min", "traceMin", VERSION_HINT, 0.0, 0.0, 1.0),
|
||||
"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."
|
||||
}, new EffectParameter(
|
||||
"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<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);
|
||||
std::atomic<float> frequency = 440.0f;
|
||||
|
||||
|
@ -207,14 +247,14 @@ public:
|
|||
std::atomic<bool> objectServerRendering = false;
|
||||
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* decayTime = new FloatParameter("Decay Time", "decayTime", VERSION_HINT, 0.05, 0.0, 1.0);
|
||||
FloatParameter* sustainLevel = new FloatParameter("Sustain Level", "sustainLevel", VERSION_HINT, 0.8, 0.0, 1.0);
|
||||
FloatParameter* releaseTime = new FloatParameter("Release Time", "releaseTime", VERSION_HINT, 0.2, 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.6, 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* 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(
|
||||
attackTime->getValueUnnormalised(),
|
||||
|
@ -225,6 +265,8 @@ public:
|
|||
std::vector<EnvCurve>{ attackShape->getValueUnnormalised(), decayShape->getValueUnnormalised(), releaseShape->getValueUnnormalised() }
|
||||
);
|
||||
|
||||
juce::MidiKeyboardState keyboardState;
|
||||
|
||||
private:
|
||||
juce::SpinLock consumerLock;
|
||||
std::vector<std::shared_ptr<BufferConsumer>> consumers;
|
||||
|
|
|
@ -4,19 +4,25 @@
|
|||
SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) {
|
||||
addAndMakeVisible(effects);
|
||||
addAndMakeVisible(main);
|
||||
addAndMakeVisible(columnResizerBar);
|
||||
addAndMakeVisible(rowResizerBar);
|
||||
addAndMakeVisible(midiResizerBar);
|
||||
addAndMakeVisible(mainResizerBar);
|
||||
addAndMakeVisible(effectResizerBar);
|
||||
addAndMakeVisible(midi);
|
||||
addChildComponent(lua);
|
||||
addChildComponent(obj);
|
||||
addChildComponent(txt);
|
||||
|
||||
columnLayout.setItemLayout(0, -0.1, -0.9, -0.4);
|
||||
columnLayout.setItemLayout(1, 7, 7, 7);
|
||||
columnLayout.setItemLayout(2, -0.1, -0.9, -0.6);
|
||||
midiLayout.setItemLayout(0, -0.1, -1.0, -1.0);
|
||||
midiLayout.setItemLayout(1, 7, 7, 7);
|
||||
midiLayout.setItemLayout(2, CLOSED_PREF_SIZE, -0.9, CLOSED_PREF_SIZE);
|
||||
|
||||
rowLayout.setItemLayout(0, -0.1, -1.0, -0.63);
|
||||
rowLayout.setItemLayout(1, 7, 7, 7);
|
||||
rowLayout.setItemLayout(2, -0.1, -0.9, -0.37);
|
||||
mainLayout.setItemLayout(0, -0.1, -0.9, -0.4);
|
||||
mainLayout.setItemLayout(1, 7, 7, 7);
|
||||
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* columns[] = { &main, &columnResizerBar, &dummy };
|
||||
columnLayout.layOutComponents(columns, 3, area.getX(), area.getY(), area.getWidth(), area.getHeight(), false, true);
|
||||
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 };
|
||||
mainLayout.layOutComponents(columns, 3, dummy.getX(), dummy.getY(), dummy.getWidth(), dummy.getHeight(), false, true);
|
||||
|
||||
juce::Component* effectSettings = nullptr;
|
||||
|
||||
|
@ -42,14 +51,16 @@ void SettingsComponent::resized() {
|
|||
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
|
||||
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 {
|
||||
effects.setBounds(dummy.getBounds());
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void SettingsComponent::fileUpdated(juce::String fileName) {
|
||||
|
@ -77,3 +88,49 @@ void SettingsComponent::update() {
|
|||
void SettingsComponent::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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "ObjComponent.h"
|
||||
#include "TxtComponent.h"
|
||||
#include "EffectsComponent.h"
|
||||
#include "MidiComponent.h"
|
||||
|
||||
class OscirenderAudioProcessorEditor;
|
||||
class SettingsComponent : public juce::Component {
|
||||
|
@ -17,6 +18,10 @@ public:
|
|||
void fileUpdated(juce::String fileName);
|
||||
void update();
|
||||
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:
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
|
@ -27,11 +32,16 @@ private:
|
|||
ObjComponent obj{audioProcessor, pluginEditor};
|
||||
TxtComponent txt{audioProcessor, pluginEditor};
|
||||
EffectsComponent effects{audioProcessor, pluginEditor};
|
||||
MidiComponent midi{audioProcessor, pluginEditor};
|
||||
|
||||
juce::StretchableLayoutManager columnLayout;
|
||||
juce::StretchableLayoutResizerBar columnResizerBar{&columnLayout, 1, true};
|
||||
juce::StretchableLayoutManager rowLayout;
|
||||
juce::StretchableLayoutResizerBar rowResizerBar{&rowLayout, 1, false};
|
||||
const double CLOSED_PREF_SIZE = 30.0;
|
||||
|
||||
juce::StretchableLayoutManager midiLayout;
|
||||
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)
|
||||
};
|
|
@ -13,6 +13,7 @@
|
|||
UGEN++ can be redistributed and/or modified under the terms of the
|
||||
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.
|
||||
|
||||
UGEN++ is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -88,15 +89,19 @@ void EnvelopeHandleComponentConstrainer::setAdjacentHandleLimits(int setLeftLimi
|
|||
}
|
||||
|
||||
EnvelopeHandleComponent::EnvelopeHandleComponent()
|
||||
: dontUpdateTimeAndValue(false),
|
||||
lastX(-1),
|
||||
lastY(-1),
|
||||
resizeLimits(this),
|
||||
shouldLockTime(false),
|
||||
shouldLockValue(false),
|
||||
ignoreDrag(false)
|
||||
: dontUpdateTimeAndValue(false),
|
||||
lastX(-1),
|
||||
lastY(-1),
|
||||
resizeLimits(this),
|
||||
shouldLockTime(false),
|
||||
shouldLockValue(false),
|
||||
shouldDraw(!shouldLockTime || !shouldLockValue),
|
||||
ignoreDrag(false)
|
||||
{
|
||||
setMouseCursor(juce::MouseCursor::CrosshairCursor);
|
||||
|
||||
if (shouldDraw) {
|
||||
setMouseCursor(juce::MouseCursor::DraggingHandCursor);
|
||||
}
|
||||
resetOffsets();
|
||||
}
|
||||
|
||||
|
@ -149,70 +154,88 @@ void EnvelopeHandleComponent::updateLegend()
|
|||
|
||||
int width = getParentWidth();
|
||||
int places;
|
||||
|
||||
if(width >= 165) {
|
||||
|
||||
if(env && env->isLoopNode(this))
|
||||
text << "(Loop) ";
|
||||
else if(env && env->isReleaseNode(this))
|
||||
text << "(Release) ";
|
||||
else
|
||||
text << "Point ";
|
||||
|
||||
|
||||
if (width >= 115) {
|
||||
places = 3;
|
||||
} else if (width >= 100) {
|
||||
places = 2;
|
||||
} else {
|
||||
places = 1;
|
||||
}
|
||||
else if(width >= 140) {
|
||||
text << "Point ";
|
||||
places = 3;
|
||||
} else if(width >= 115) {
|
||||
text << "Pt ";
|
||||
places = 3;
|
||||
} else if(width >= 100) {
|
||||
text << "Pt ";
|
||||
places = 2;
|
||||
} else if(width >= 85) {
|
||||
text << "Pt ";
|
||||
places = 1;
|
||||
} else if(width >= 65) {
|
||||
text << "P ";
|
||||
places = 1;
|
||||
|
||||
if (env->getAdsrMode()) {
|
||||
int index = env->getHandleIndex(this);
|
||||
Env envelope = env->getEnv();
|
||||
|
||||
double envTime = envelope.getTimes()[index - 1];
|
||||
|
||||
if (index == 1) {
|
||||
text = "Attack time (s): " + juce::String(legend->mapTime(envTime), places);
|
||||
text << ", Attack level: " << juce::String(legend->mapValue(value), places);
|
||||
} else if (index == 2) {
|
||||
text = "Decay time (s): " + juce::String(legend->mapTime(envTime), places);
|
||||
text << ", Sustain level: " << juce::String(legend->mapValue(value), places);
|
||||
} else {
|
||||
text = "Release time (s): " + juce::String(legend->mapTime(envTime), places);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::paint(juce::Graphics& g)
|
||||
{
|
||||
EnvelopeComponent *env = getParentComponent();
|
||||
juce::Colour handleColour;
|
||||
|
||||
if(env == 0)
|
||||
{
|
||||
handleColour = juce::Colour(0xFF69B4FF);
|
||||
if (shouldDraw) {
|
||||
EnvelopeComponent *env = getParentComponent();
|
||||
juce::Colour handleColour;
|
||||
|
||||
if(env == 0)
|
||||
{
|
||||
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()
|
||||
|
@ -236,8 +259,12 @@ void EnvelopeHandleComponent::mouseEnter(const juce::MouseEvent& e)
|
|||
printf("MyEnvelopeHandleComponent::mouseEnter\n");
|
||||
#endif
|
||||
|
||||
setMouseCursor(juce::MouseCursor::CrosshairCursor);
|
||||
updateLegend();
|
||||
if (shouldDraw) {
|
||||
setMouseCursor(juce::MouseCursor::DraggingHandCursor);
|
||||
updateLegend();
|
||||
} else {
|
||||
setMouseCursor(juce::MouseCursor::NormalCursor);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
setMouseCursor(juce::MouseCursor::NoCursor);
|
||||
|
||||
if(e.mods.isShiftDown()) {
|
||||
|
||||
if(!shouldLockTime && !shouldLockValue)
|
||||
{
|
||||
getParentComponent()->setLegendTextToDefault();
|
||||
removeThisHandle();
|
||||
if (shouldDraw) {
|
||||
setMouseCursor(juce::MouseCursor::NoCursor);
|
||||
|
||||
if(e.mods.isShiftDown()) {
|
||||
|
||||
if(!shouldLockTime && !shouldLockValue)
|
||||
{
|
||||
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();
|
||||
|
||||
|
||||
resizeLimits.setAdjacentHandleLimits(leftLimit, rightLimit);
|
||||
|
||||
dragger.startDraggingComponent(this, e);//&resizeLimits);
|
||||
|
||||
getParentComponent()->sendStartDrag();
|
||||
}
|
||||
|
||||
getParentComponent()->sendStartDrag();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::mouseDrag(const juce::MouseEvent& e)
|
||||
{
|
||||
if(ignoreDrag == true) return;
|
||||
if(ignoreDrag || !shouldDraw) return;
|
||||
|
||||
dragger.dragComponent(this, e, &resizeLimits);
|
||||
|
||||
|
@ -350,7 +379,11 @@ void EnvelopeHandleComponent::mouseUp(const juce::MouseEvent& e)
|
|||
printf("MyEnvelopeHandleComponent::mouseUp\n");
|
||||
#endif
|
||||
|
||||
if(ignoreDrag == true)
|
||||
if (!shouldDraw) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(ignoreDrag)
|
||||
{
|
||||
ignoreDrag = false;
|
||||
goto exit;
|
||||
|
@ -361,7 +394,7 @@ void EnvelopeHandleComponent::mouseUp(const juce::MouseEvent& e)
|
|||
env->quantiseHandle(this);
|
||||
// }
|
||||
|
||||
setMouseCursor(juce::MouseCursor::CrosshairCursor);
|
||||
setMouseCursor(juce::MouseCursor::DraggingHandCursor);
|
||||
setMousePositionToThisHandle();
|
||||
|
||||
offsetX = 0;
|
||||
|
@ -504,22 +537,26 @@ void EnvelopeHandleComponent::lockTime(double timeToLock)
|
|||
{
|
||||
setTime(timeToLock);
|
||||
shouldLockTime = true;
|
||||
recalculateShouldDraw();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::lockValue(double valueToLock)
|
||||
{
|
||||
setValue(valueToLock);
|
||||
shouldLockValue = true;
|
||||
recalculateShouldDraw();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::unlockTime()
|
||||
{
|
||||
shouldLockTime = false;
|
||||
recalculateShouldDraw();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::unlockValue()
|
||||
{
|
||||
shouldLockValue = false;
|
||||
recalculateShouldDraw();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::recalculatePosition()
|
||||
|
@ -532,6 +569,10 @@ void EnvelopeHandleComponent::recalculatePosition()
|
|||
getParentComponent()->repaint();
|
||||
}
|
||||
|
||||
void EnvelopeHandleComponent::recalculateShouldDraw() {
|
||||
shouldDraw = !shouldLockTime || !shouldLockValue;
|
||||
}
|
||||
|
||||
|
||||
EnvelopeComponent::EnvelopeComponent()
|
||||
: minNumHandles(0),
|
||||
|
@ -554,16 +595,6 @@ EnvelopeComponent::EnvelopeComponent()
|
|||
{
|
||||
setMouseCursor(juce::MouseCursor::NormalCursor);
|
||||
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()
|
||||
|
@ -719,8 +750,8 @@ void EnvelopeComponent::paint(juce::Graphics& g)
|
|||
time = nextTime;
|
||||
}
|
||||
|
||||
g.setColour(colours[Line]);
|
||||
g.strokePath (path, juce::PathStrokeType(1.0f));
|
||||
g.setColour(findColour(Line));
|
||||
g.strokePath (path, juce::PathStrokeType(2.0f));
|
||||
|
||||
if((loopNode >= 0) && (releaseNode >= 0) && (releaseNode > loopNode))
|
||||
{
|
||||
|
@ -730,7 +761,7 @@ void EnvelopeComponent::paint(juce::Graphics& g)
|
|||
if((releaseHandle != 0) && (loopHandle != 0))
|
||||
{
|
||||
// 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 releaseY = (releaseHandle->getY() + releaseHandle->getBottom()) * 0.5f;
|
||||
|
@ -748,7 +779,7 @@ void EnvelopeComponent::paint(juce::Graphics& g)
|
|||
0.5f);
|
||||
|
||||
if(loopY == releaseY)
|
||||
g.setColour(colours[LoopNode]);
|
||||
g.setColour(findColour(LoopNode));
|
||||
|
||||
// g.drawArrow(loopX + arrowLength, releaseY,
|
||||
// loopX, releaseY,
|
||||
|
@ -770,10 +801,10 @@ inline double round(double a, double b) throw()
|
|||
|
||||
void EnvelopeComponent::paintBackground(juce::Graphics& g)
|
||||
{
|
||||
g.setColour(colours[Background]);
|
||||
g.setColour(findColour(Background));
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
|
||||
g.setColour(colours[GridLine]);
|
||||
g.setColour(findColour(GridLine));
|
||||
|
||||
if((gridDisplayMode & GridValue) && (valueGrid > 0.0))
|
||||
{
|
||||
|
@ -904,7 +935,7 @@ void EnvelopeComponent::mouseUp(const juce::MouseEvent& e)
|
|||
if(e.mods.isCtrlDown() == false)
|
||||
quantiseHandle(draggingHandle);
|
||||
|
||||
setMouseCursor(juce::MouseCursor::CrosshairCursor);
|
||||
setMouseCursor(juce::MouseCursor::DraggingHandCursor);
|
||||
draggingHandle->setMousePositionToThisHandle();
|
||||
draggingHandle->resetOffsets();
|
||||
draggingHandle = 0;
|
||||
|
@ -1389,28 +1420,6 @@ double EnvelopeComponent::constrainValue(double valueToConstrain) const
|
|||
// 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)
|
||||
: defaultText(_defaultText)
|
||||
{
|
||||
|
@ -1440,12 +1449,12 @@ void EnvelopeLegendComponent::resized()
|
|||
void EnvelopeLegendComponent::paint(juce::Graphics& g)
|
||||
{
|
||||
EnvelopeComponent *env = getEnvelopeComponent();
|
||||
juce::Colour backColour = env ? env->getEnvColour(EnvelopeComponent::LegendBackground) : juce::Colour(0xFF696969);
|
||||
juce::Colour backColour = findColour(EnvelopeComponent::LegendBackground);
|
||||
|
||||
g.setColour(backColour);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "EnvCurve.h"
|
||||
|
||||
|
||||
#define HANDLESIZE 7
|
||||
#define HANDLESIZE 11
|
||||
#define FINETUNE 0.001
|
||||
|
||||
//#define MYDEBUG 1 // get rid of this later
|
||||
|
@ -121,6 +121,7 @@ public:
|
|||
private:
|
||||
bool dontUpdateTimeAndValue;
|
||||
void recalculatePosition();
|
||||
void recalculateShouldDraw();
|
||||
|
||||
juce::ComponentDragger dragger;
|
||||
int lastX, lastY;
|
||||
|
@ -128,7 +129,7 @@ private:
|
|||
EnvelopeHandleComponentConstrainer resizeLimits;
|
||||
|
||||
double time, value;
|
||||
bool shouldLockTime, shouldLockValue;
|
||||
bool shouldLockTime, shouldLockValue, shouldDraw;
|
||||
EnvCurve curve;
|
||||
bool ignoreDrag;
|
||||
};
|
||||
|
@ -235,9 +236,21 @@ public:
|
|||
// double quantiseDomain(double value);
|
||||
// double quantiseValue(double value);
|
||||
|
||||
enum EnvColours { Node, ReleaseNode, LoopNode, Line, LoopLine, Background, GridLine, LegendText, LegendBackground, NumEnvColours };
|
||||
void setEnvColour(const EnvColours which, juce::Colour colour) throw();
|
||||
const juce::Colour getEnvColour(const EnvColours which) const throw();
|
||||
const static int COLOUR_OFFSET = 0x6082100;
|
||||
|
||||
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 };
|
||||
|
||||
|
@ -262,8 +275,6 @@ private:
|
|||
bool allowCurveEditing = false;
|
||||
bool allowNodeEditing = false;
|
||||
bool adsrMode = false;
|
||||
|
||||
juce::Colour colours[NumEnvColours];
|
||||
};
|
||||
|
||||
class EnvelopeLegendComponent : public juce::Component
|
||||
|
@ -311,16 +322,7 @@ public:
|
|||
Env getEnv() const { return getEnvelopeComponent()->getEnv(); }
|
||||
void setEnv(Env const& env) { return getEnvelopeComponent()->setEnv(env); }
|
||||
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 max) { setDomainRange(0.0, max); }
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
#include "Effect.h"
|
||||
#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),
|
||||
parameters(parameters),
|
||||
enabled(nullptr),
|
||||
actualValues(std::vector<double>(parameters.size(), 0.0)),
|
||||
description(description) {}
|
||||
actualValues(std::vector<double>(parameters.size(), 0.0)) {}
|
||||
|
||||
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),
|
||||
parameters(parameters),
|
||||
enabled(nullptr),
|
||||
actualValues(std::vector<double>(parameters.size(), 0.0)),
|
||||
description(description) {}
|
||||
actualValues(std::vector<double>(parameters.size(), 0.0)) {}
|
||||
|
||||
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) {
|
||||
animateValues();
|
||||
|
@ -203,7 +201,3 @@ EffectParameter* Effect::getParameter(juce::String id) {
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
juce::String Effect::getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
class Effect {
|
||||
public:
|
||||
Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters, juce::String description);
|
||||
Effect(std::shared_ptr<EffectApplication> effectApplication, EffectParameter* parameter, juce::String description);
|
||||
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, EffectParameter* parameter, juce::String description);
|
||||
Effect(std::shared_ptr<EffectApplication> effectApplication, const std::vector<EffectParameter*>& parameters);
|
||||
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);
|
||||
Effect(std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application, EffectParameter* parameter);
|
||||
|
||||
Vector2 apply(int index, Vector2 input);
|
||||
|
||||
|
@ -32,7 +32,6 @@ public:
|
|||
void save(juce::XmlElement* xml);
|
||||
void load(juce::XmlElement* xml);
|
||||
EffectParameter* getParameter(juce::String id);
|
||||
juce::String getDescription();
|
||||
|
||||
std::vector<EffectParameter*> parameters;
|
||||
BooleanParameter* enabled;
|
||||
|
@ -44,7 +43,6 @@ private:
|
|||
int precedence = -1;
|
||||
int sampleRate = 192000;
|
||||
std::function<Vector2(int, Vector2, const std::vector<double>&, double)> application;
|
||||
juce::String description;
|
||||
|
||||
std::shared_ptr<EffectApplication> effectApplication;
|
||||
|
||||
|
|
|
@ -309,6 +309,7 @@ public:
|
|||
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");
|
||||
std::atomic<float> phase = 0.0f;
|
||||
juce::String description;
|
||||
|
||||
std::vector<juce::AudioProcessorParameter*> getParameters() {
|
||||
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) {}
|
||||
};
|
||||
|
|
|
@ -5,6 +5,9 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect, in
|
|||
addAndMakeVisible(slider);
|
||||
addChildComponent(lfoSlider);
|
||||
addAndMakeVisible(lfo);
|
||||
addAndMakeVisible(label);
|
||||
|
||||
label.setFont(juce::Font(13.0f));
|
||||
|
||||
lfo.addItem("Static", static_cast<int>(LfoType::Static));
|
||||
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("Noise", static_cast<int>(LfoType::Noise));
|
||||
|
||||
// temporarily disabling tooltips
|
||||
// setTooltip(effect.getDescription());
|
||||
|
||||
effect.addListener(index, this);
|
||||
setupComponent();
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ EffectComponent::EffectComponent(OscirenderAudioProcessor& p, Effect& effect) :
|
|||
void EffectComponent::setupComponent() {
|
||||
EffectParameter* parameter = effect.parameters[index];
|
||||
|
||||
label.setTooltip(parameter->description);
|
||||
label.setText(parameter->name, juce::dontSendNotification);
|
||||
|
||||
slider.setRange(parameter->min, parameter->max, parameter->step);
|
||||
slider.setValue(parameter->getValueUnnormalised(), juce::dontSendNotification);
|
||||
|
||||
|
@ -118,16 +121,14 @@ void EffectComponent::resized() {
|
|||
lfo.setBounds(bounds.removeFromRight(100).reduced(5));
|
||||
}
|
||||
|
||||
textBounds = bounds.removeFromLeft(120);
|
||||
textBounds.removeFromLeft(5);
|
||||
bounds.removeFromLeft(5);
|
||||
label.setBounds(bounds.removeFromLeft(120));
|
||||
slider.setBounds(bounds);
|
||||
lfoSlider.setBounds(bounds);
|
||||
}
|
||||
|
||||
void EffectComponent::paint(juce::Graphics& g) {
|
||||
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) {
|
||||
|
|
|
@ -28,11 +28,11 @@ public:
|
|||
private:
|
||||
void setupComponent();
|
||||
bool lfoEnabled = true;
|
||||
juce::Rectangle<int> textBounds;
|
||||
std::shared_ptr<juce::Component> component;
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
|
||||
juce::Label popupLabel;
|
||||
juce::Label label;
|
||||
LabelledTextBox min{"Min"};
|
||||
LabelledTextBox max{"Max"};
|
||||
|
||||
|
|
|
@ -86,14 +86,19 @@ void EffectsListComponent::resized() {
|
|||
std::shared_ptr<juce::Component> EffectsListComponent::createComponent(EffectParameter* parameter) {
|
||||
if (parameter->paramID == "perspectiveRotateX" || parameter->paramID == "perspectiveRotateY" || parameter->paramID == "perspectiveRotateZ") {
|
||||
BooleanParameter* toggle;
|
||||
juce::String axis;
|
||||
if (parameter->paramID == "perspectiveRotateX") {
|
||||
toggle = audioProcessor.perspectiveEffect->fixedRotateX;
|
||||
axis = "X";
|
||||
} else if (parameter->paramID == "perspectiveRotateY") {
|
||||
toggle = audioProcessor.perspectiveEffect->fixedRotateY;
|
||||
axis = "Y";
|
||||
} else if (parameter->paramID == "perspectiveRotateZ") {
|
||||
toggle = audioProcessor.perspectiveEffect->fixedRotateZ;
|
||||
axis = "Z";
|
||||
}
|
||||
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] {
|
||||
toggle->setBoolValueNotifyingHost(!toggle->getBoolValue());
|
||||
};
|
||||
|
@ -103,6 +108,7 @@ std::shared_ptr<juce::Component> EffectsListComponent::createComponent(EffectPar
|
|||
std::weak_ptr<SvgButton> weakButton = button;
|
||||
button->setEdgeIndent(5);
|
||||
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] {
|
||||
if (auto button = weakButton.lock()) {
|
||||
editor.editPerspectiveFunction(button->getToggleState());
|
||||
|
|
Ładowanie…
Reference in New Issue