Upload files to "DrawWavesAndRevisedAudio"
This commit is contained in:
172
DrawWavesAndRevisedAudio/PluginEditor.h
Normal file
172
DrawWavesAndRevisedAudio/PluginEditor.h
Normal file
@@ -0,0 +1,172 @@
|
||||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include <functional>
|
||||
#include "PluginProcessor.h"
|
||||
|
||||
// === Small waveform thumbnail =================================================
|
||||
class WaveThumbnail : public juce::Component
|
||||
{
|
||||
public:
|
||||
WaveThumbnail (const std::vector<float>* tbl = nullptr) : table (tbl) {}
|
||||
|
||||
void setTable (const std::vector<float>* tbl) { table = tbl; repaint(); }
|
||||
|
||||
void setHighlight (bool shouldHighlight)
|
||||
{
|
||||
if (highlight == shouldHighlight) return;
|
||||
highlight = shouldHighlight;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void setOnClick (std::function<void()> handler) { onClick = std::move (handler); }
|
||||
|
||||
void paint (juce::Graphics& g) override;
|
||||
|
||||
void mouseDown (const juce::MouseEvent& e) override
|
||||
{
|
||||
juce::ignoreUnused (e);
|
||||
if (onClick) onClick();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<float>* table { nullptr };
|
||||
bool highlight { false };
|
||||
std::function<void()> onClick;
|
||||
};
|
||||
|
||||
// === Draw-your-own wave pad ===================================================
|
||||
// (Grid + thicker antialiased stroke + smooth “ink” interpolation while dragging)
|
||||
class DrawWaveComponent : public juce::Component
|
||||
{
|
||||
public:
|
||||
DrawWaveComponent();
|
||||
|
||||
void clear();
|
||||
void paint (juce::Graphics& g) override;
|
||||
void mouseDown (const juce::MouseEvent& e) override;
|
||||
void mouseDrag (const juce::MouseEvent& e) override;
|
||||
|
||||
const std::vector<float>& getTable() const { return samples; }
|
||||
|
||||
private:
|
||||
void drawAt (const juce::MouseEvent& e);
|
||||
void setSampleAt (int idx, float value);
|
||||
|
||||
std::vector<float> samples;
|
||||
int lastDrawIndex { -1 };
|
||||
};
|
||||
|
||||
// === Custom looks =============================================================
|
||||
class MetalKnobLookAndFeel : public juce::LookAndFeel_V4
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider (juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPosProportional, float rotaryStartAngle,
|
||||
float rotaryEndAngle, juce::Slider& slider) override;
|
||||
};
|
||||
|
||||
class FlatButtonLookAndFeel : public juce::LookAndFeel_V4
|
||||
{
|
||||
public:
|
||||
void drawButtonBackground (juce::Graphics& g, juce::Button& b, const juce::Colour& bg,
|
||||
bool isHighlighted, bool isDown) override
|
||||
{
|
||||
auto r = b.getLocalBounds().toFloat();
|
||||
auto base = bg; if (isDown) base = base.darker (0.15f); else if (isHighlighted) base = base.brighter (0.08f);
|
||||
g.setColour (base);
|
||||
g.fillRoundedRectangle (r, 4.0f);
|
||||
g.setColour (juce::Colours::black.withAlpha (0.5f));
|
||||
g.drawRoundedRectangle (r.reduced (0.5f), 4.0f, 1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
// === Editor ===================================================================
|
||||
class WavetableSynthAudioProcessorEditor : public juce::AudioProcessorEditor,
|
||||
private juce::Timer
|
||||
{
|
||||
public:
|
||||
explicit WavetableSynthAudioProcessorEditor (WavetableSynthAudioProcessor&);
|
||||
~WavetableSynthAudioProcessorEditor() override = default;
|
||||
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
void mouseDown (const juce::MouseEvent& e) override;
|
||||
|
||||
private:
|
||||
WavetableSynthAudioProcessor& audioProcessor;
|
||||
|
||||
// Morph
|
||||
juce::Slider morphSlider;
|
||||
juce::ToggleButton morphLoopToggle { "Loop Morph" };
|
||||
juce::ComboBox morphLoopMode; // Forward / Ping-Pong / Half Trip
|
||||
|
||||
// Master
|
||||
juce::Slider master;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> morphAttach, masterAttach;
|
||||
|
||||
// A/B/C thumbnails
|
||||
WaveThumbnail slotABox, slotBBox, slotCBox;
|
||||
|
||||
// Synth knobs
|
||||
juce::Slider cutoffSlider, attack, decay, sustain, release;
|
||||
juce::Slider lfoRate, lfoDepth, fenvA, fenvD, fenvS, fenvR, fenvAmt;
|
||||
|
||||
// FX knobs
|
||||
juce::Slider chRate, chDepth, chDelay, chFb, chMix;
|
||||
juce::Slider rvRoom, rvDamp, rvWidth, rvWet;
|
||||
|
||||
// Attachments
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>
|
||||
cutoffAttach, attAttach, decAttach, susAttach, relAttach,
|
||||
lfoRateAttach, lfoDepthAttach, fenvAAttach, fenvDAttach, fenvSAttach, fenvRAttach, fenvAmtAttach,
|
||||
chRateAttach, chDepthAttach, chDelayAttach, chFbAttach, chMixAttach,
|
||||
rvRoomAttach, rvDampAttach, rvWidthAttach, rvWetAttach;
|
||||
|
||||
// Hidden slot params
|
||||
juce::Slider slotAParam, slotBParam, slotCParam;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>
|
||||
slotAAttach, slotBAttach, slotCAttach;
|
||||
|
||||
// Toggles
|
||||
juce::ToggleButton chorusOn { "Chorus" }, reverbOn { "Reverb" }, osc2Mute { "Deactivate Osc2" };
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::ButtonAttachment> chOnAttach, rvOnAttach, osc2MuteAttach;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::ButtonAttachment> morphLoopToggleAttach;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::ComboBoxAttachment> morphLoopModeAttach;
|
||||
|
||||
// Browser grid cells
|
||||
std::vector<juce::Rectangle<int>> browserCells; // 4 x 10 = 40
|
||||
|
||||
// Draw pad + buttons
|
||||
DrawWaveComponent userDraw;
|
||||
juce::TextButton addToBrowser { "Add to Browser" }, clearDraw { "Clear" }, presetButton { "Presets" };
|
||||
|
||||
// Labels
|
||||
juce::Label lblCutoff, lblAttack, lblDecay, lblSustain, lblRelease;
|
||||
juce::Label lblLfoRate, lblLfoDepth, lblFenvA, lblFenvD, lblFenvS, lblFenvR, lblFenvAmt;
|
||||
juce::Label lblChRate, lblChDepth, lblChDelay, lblChFb, lblChMix;
|
||||
juce::Label lblRvRoom, lblRvDamp, lblRvWidth, lblRvWet;
|
||||
juce::Label lblMaster, lblDrawWave;
|
||||
|
||||
// L&F
|
||||
MetalKnobLookAndFeel metalKnobLNF;
|
||||
FlatButtonLookAndFeel flatBtnLNF;
|
||||
|
||||
// Layout helpers
|
||||
juce::Rectangle<int> getTopPanelBounds() const;
|
||||
juce::Rectangle<int> getBottomPanelBounds() const;
|
||||
|
||||
// Logic
|
||||
void timerCallback() override;
|
||||
void handleBrowserClick (juce::Point<int> pos);
|
||||
void showPresetMenu();
|
||||
void setActiveSlot (int slotIndex);
|
||||
|
||||
// Helpers
|
||||
static void labelAbove (juce::Label& L, const juce::String& text);
|
||||
int activeSlot { 0 };
|
||||
|
||||
// Local morph animation (fallback)
|
||||
double lastTimerMs { juce::Time::getMillisecondCounterHiRes() };
|
||||
float localMorphPhase { 0.0f }; // 0..1
|
||||
};
|
||||
Reference in New Issue
Block a user