mirror of
https://codeberg.org/armin/monostep.git
synced 2026-09-01 04:10:46 +02:00
MonoStep: monophonic 2-oscillator step-sequencer synth
This commit is contained in:
commit
e52e5cb161
14 changed files with 2674 additions and 0 deletions
190
Source/PluginEditor.h
Normal file
190
Source/PluginEditor.h
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "ui/SequencerMatrix.h"
|
||||
|
||||
class MonoStepAudioProcessor;
|
||||
|
||||
class EditorLookAndFeel final : public juce::LookAndFeel_V4
|
||||
{
|
||||
public:
|
||||
EditorLookAndFeel();
|
||||
|
||||
void drawRotarySlider (juce::Graphics&, int x, int y, int w, int h,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider&) override;
|
||||
|
||||
void drawToggleButton (juce::Graphics&, juce::ToggleButton&,
|
||||
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
|
||||
|
||||
void drawButtonBackground (juce::Graphics&, juce::Button&,
|
||||
const juce::Colour& backgroundColour, bool shouldDrawButtonAsHighlighted,
|
||||
bool shouldDrawButtonAsDown) override;
|
||||
|
||||
void drawButtonText (juce::Graphics&, juce::TextButton&,
|
||||
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
|
||||
};
|
||||
|
||||
class Knob final : public juce::Component
|
||||
{
|
||||
public:
|
||||
explicit Knob (const juce::String& title);
|
||||
|
||||
juce::Slider& getSlider() { return slider; }
|
||||
|
||||
void attach (juce::AudioProcessorValueTreeState& apvts, const juce::String& paramId)
|
||||
{
|
||||
attachment = std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment> (apvts, paramId, slider);
|
||||
}
|
||||
|
||||
void setFormat (std::function<juce::String (float)> formatFn)
|
||||
{
|
||||
format = std::move (formatFn);
|
||||
updateValueLabel();
|
||||
}
|
||||
|
||||
void setOnValueChanged (std::function<void (float)> valueChangedFn)
|
||||
{
|
||||
customOnValueChange = std::move (valueChangedFn);
|
||||
}
|
||||
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
void updateValueLabel();
|
||||
|
||||
juce::Slider slider;
|
||||
juce::Label titleLabel;
|
||||
juce::Label valueLabel;
|
||||
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> attachment;
|
||||
std::function<juce::String (float)> format;
|
||||
std::function<void (float)> customOnValueChange;
|
||||
};
|
||||
|
||||
class ChoiceBar final : public juce::Component,
|
||||
public juce::AudioProcessorValueTreeState::Listener
|
||||
{
|
||||
public:
|
||||
ChoiceBar (juce::AudioProcessorValueTreeState& apvts,
|
||||
const juce::String& paramId,
|
||||
const juce::StringArray& choices);
|
||||
|
||||
ChoiceBar (const juce::StringArray& choices,
|
||||
std::function<void (int)> onSelected);
|
||||
|
||||
~ChoiceBar() override;
|
||||
|
||||
void parameterChanged (const juce::String&, float) override;
|
||||
|
||||
void setManualHandler (std::function<void (int)> handler) { manualHandler = std::move (handler); }
|
||||
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
void refreshFromParam();
|
||||
void setIndex (int index);
|
||||
|
||||
juce::AudioProcessorValueTreeState* apvts = nullptr;
|
||||
juce::String paramId;
|
||||
std::function<void (int)> manualHandler;
|
||||
juce::OwnedArray<juce::TextButton> buttons;
|
||||
};
|
||||
|
||||
class StepPanel final : public juce::Component
|
||||
{
|
||||
public:
|
||||
explicit StepPanel (MonoStepAudioProcessor& processor);
|
||||
|
||||
void setSelectedStep (int stepIdx);
|
||||
void refresh();
|
||||
|
||||
std::function<void (int)> onStepSelected;
|
||||
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
void clearPattern();
|
||||
|
||||
MonoStepAudioProcessor& processor;
|
||||
|
||||
int selectedStep = 0;
|
||||
bool updating = false;
|
||||
|
||||
juce::Label titleLabel;
|
||||
juce::Label noteLabel;
|
||||
juce::Label gateLabel;
|
||||
Knob fineKnob;
|
||||
juce::TextButton prevButton;
|
||||
juce::TextButton nextButton;
|
||||
juce::Label hintLabel;
|
||||
juce::TextButton clearButton;
|
||||
};
|
||||
|
||||
class MonoStepAudioProcessorEditor final : public juce::AudioProcessorEditor,
|
||||
public juce::Timer
|
||||
{
|
||||
public:
|
||||
explicit MonoStepAudioProcessorEditor (MonoStepAudioProcessor& processor);
|
||||
~MonoStepAudioProcessorEditor() override;
|
||||
|
||||
void paint (juce::Graphics&) override;
|
||||
void resized() override;
|
||||
|
||||
void timerCallback() override;
|
||||
|
||||
private:
|
||||
void paintContent (juce::Graphics&);
|
||||
|
||||
class ContentComponent final : public juce::Component
|
||||
{
|
||||
public:
|
||||
explicit ContentComponent (MonoStepAudioProcessorEditor& owner) : ownerRef (owner) {}
|
||||
|
||||
void paint (juce::Graphics& g) override { ownerRef.paintContent (g); }
|
||||
|
||||
private:
|
||||
MonoStepAudioProcessorEditor& ownerRef;
|
||||
};
|
||||
|
||||
MonoStepAudioProcessor& processorRef;
|
||||
|
||||
ContentComponent content;
|
||||
|
||||
static constexpr int baseWidth = 1060;
|
||||
static constexpr int baseHeight = 640;
|
||||
|
||||
float zoomFactor = 1.0f;
|
||||
|
||||
void setZoomFactor (float newZoom);
|
||||
|
||||
std::unique_ptr<EditorLookAndFeel> lnf;
|
||||
std::vector<std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment>> attachments;
|
||||
|
||||
Knob lengthKnob;
|
||||
Knob swingKnob;
|
||||
Knob rootKnob;
|
||||
Knob gateKnob;
|
||||
Knob masterKnob;
|
||||
Knob detuneKnob;
|
||||
Knob mixKnob;
|
||||
Knob cutoffKnob;
|
||||
Knob resKnob;
|
||||
Knob glideKnob;
|
||||
Knob attackKnob;
|
||||
Knob decayKnob;
|
||||
Knob sustainKnob;
|
||||
Knob releaseKnob;
|
||||
|
||||
ChoiceBar rateBar;
|
||||
ChoiceBar octaveBar;
|
||||
ChoiceBar zoomBar;
|
||||
ChoiceBar wave1Bar;
|
||||
ChoiceBar wave2Bar;
|
||||
|
||||
SequencerMatrix matrix;
|
||||
StepPanel stepPanel;
|
||||
|
||||
int lastPlayStep = -1;
|
||||
|
||||
void refreshEditor();
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue