2026-07-19 11:40:36 +02:00
|
|
|
#pragma once
|
|
|
|
|
#include "PluginProcessor.h"
|
|
|
|
|
#include <juce_gui_basics/juce_gui_basics.h>
|
|
|
|
|
|
|
|
|
|
class TrommelkisteLookAndFeel : public juce::LookAndFeel_V4
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
juce::Colour bg{0xFF1A1A1A};
|
|
|
|
|
juce::Colour rowAlt{0xFF222222};
|
|
|
|
|
juce::Colour accent{0xFFE8600A};
|
|
|
|
|
float fontScale = 1.5f;
|
|
|
|
|
|
|
|
|
|
void drawRotarySlider(juce::Graphics&, int x, int y, int w, int h,
|
|
|
|
|
float pos, float start, float end, juce::Slider&) override;
|
2026-07-19 18:53:17 +02:00
|
|
|
void drawToggleButton(juce::Graphics&, juce::ToggleButton&, bool, bool) override;
|
2026-07-19 11:40:36 +02:00
|
|
|
void drawButtonBackground(juce::Graphics&, juce::Button&, const juce::Colour&,
|
|
|
|
|
bool, bool) override;
|
|
|
|
|
void drawComboBox(juce::Graphics&, int w, int h, bool down,
|
|
|
|
|
int bx, int by, int bw, int bh, juce::ComboBox&) override;
|
|
|
|
|
void positionComboBoxText(juce::ComboBox&, juce::Label&) override;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct KnobSlider : juce::Slider
|
|
|
|
|
{
|
|
|
|
|
std::function<juce::String(double)> formatFn;
|
|
|
|
|
juce::String getTextFromValue(double v) override
|
|
|
|
|
{
|
|
|
|
|
if (formatFn) return formatFn(v);
|
|
|
|
|
return Slider::getTextFromValue(v);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class TrommelkisteEditor : public juce::AudioProcessorEditor, private juce::Timer
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TrommelkisteEditor(TrommelkisteProcessor&);
|
|
|
|
|
~TrommelkisteEditor() override;
|
|
|
|
|
|
|
|
|
|
void paint(juce::Graphics&) override;
|
|
|
|
|
void resized() override;
|
|
|
|
|
void mouseDown(const juce::MouseEvent&) override;
|
2026-07-19 18:53:17 +02:00
|
|
|
void timerCallback() override;
|
2026-07-19 11:40:36 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
TrommelkisteProcessor& proc;
|
|
|
|
|
TrommelkisteLookAndFeel lnf;
|
|
|
|
|
|
|
|
|
|
juce::ComboBox scaleCombo;
|
|
|
|
|
float uiScale = 1.5f;
|
|
|
|
|
|
|
|
|
|
int scaled(int v) const { return (int)(v * uiScale + 0.5f); }
|
|
|
|
|
void scaleChanged();
|
|
|
|
|
|
|
|
|
|
struct TrackUI
|
|
|
|
|
{
|
|
|
|
|
using SliderAtt = juce::AudioProcessorValueTreeState::SliderAttachment;
|
2026-07-19 18:53:17 +02:00
|
|
|
using ButtonAtt = juce::AudioProcessorValueTreeState::ButtonAttachment;
|
2026-07-19 11:40:36 +02:00
|
|
|
|
|
|
|
|
juce::TextButton prevBtn{"<"};
|
|
|
|
|
juce::TextButton nextBtn{">"};
|
|
|
|
|
KnobSlider level, length, velocity, pitch, tone, pan;
|
2026-07-19 18:53:17 +02:00
|
|
|
KnobSlider delaySend, reverbSend, ringMod, destruction, shuffle;
|
|
|
|
|
juce::ToggleButton decay;
|
2026-07-19 11:40:36 +02:00
|
|
|
juce::Label fileLabel;
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<SliderAtt> levelAtt, lengthAtt, velAtt, pitchAtt, toneAtt, panAtt;
|
2026-07-19 18:53:17 +02:00
|
|
|
std::unique_ptr<SliderAtt> delaySendAtt, reverbSendAtt;
|
|
|
|
|
std::unique_ptr<SliderAtt> ringModAtt, destructionAtt, shuffleAtt;
|
|
|
|
|
std::unique_ptr<ButtonAtt> decayAtt;
|
2026-07-19 11:40:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TrackUI ui[NUM_TRACKS];
|
|
|
|
|
juce::FileChooser chooser{"Load Sample", juce::File{}, "*.wav;*.aif;*.aiff;*.flac"};
|
2026-07-19 18:53:17 +02:00
|
|
|
double trackActivatedTime[NUM_TRACKS] = {};
|
2026-07-19 11:40:36 +02:00
|
|
|
|
|
|
|
|
// Preset selector
|
|
|
|
|
juce::ComboBox presetCombo;
|
|
|
|
|
juce::TextButton presetPrevBtn{"<"};
|
|
|
|
|
juce::TextButton presetNextBtn{">"};
|
|
|
|
|
|
2026-07-19 18:53:17 +02:00
|
|
|
// Global effect controls in header
|
|
|
|
|
KnobSlider globalRingFreq, globalDestruction;
|
|
|
|
|
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> globalRingFreqAtt, globalDestructionAtt;
|
|
|
|
|
|
|
|
|
|
// Master controls in header
|
|
|
|
|
KnobSlider masterVolume, masterPan, masterDelay, masterReverb;
|
|
|
|
|
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> masterVolumeAtt, masterPanAtt, masterDelayAtt, masterReverbAtt;
|
|
|
|
|
|
|
|
|
|
// Global shuffle controls in header
|
|
|
|
|
KnobSlider globalShuffleDiv, globalShuffleAmt, globalGroove;
|
|
|
|
|
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> globalShuffleDivAtt, globalShuffleAmtAtt, globalGrooveAtt;
|
|
|
|
|
|
|
|
|
|
// Delay sync control in header
|
|
|
|
|
KnobSlider delaySyncDiv;
|
|
|
|
|
std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> delaySyncDivAtt;
|
|
|
|
|
|
2026-07-19 11:40:36 +02:00
|
|
|
void loadForTrack(int idx);
|
|
|
|
|
void updateFileLabel(int idx);
|
|
|
|
|
void refreshPresetCombo();
|
|
|
|
|
|
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TrommelkisteEditor)
|
|
|
|
|
};
|