#pragma once #include #include "PluginProcessor.h" #include "WaveformDisplay.h" class MonoslicerEditor : public juce::AudioProcessorEditor, private juce::FileDragAndDropTarget, private juce::Button::Listener, private juce::ComboBox::Listener, private juce::Timer { public: MonoslicerEditor(MonoslicerProcessor&); ~MonoslicerEditor() override; void paint(juce::Graphics&) override; void resized() override; bool isInterestedInFileDrag(const juce::StringArray& files) override; void filesDropped(const juce::StringArray& files, int x, int y) override; void buttonClicked(juce::Button* button) override; void comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged) override; void timerCallback() override; private: MonoslicerProcessor& processorRef; WaveformDisplay waveformDisplay; // Bottom panel buttons juce::TextButton autoSliceButton { "Auto Slice" }; juce::TextButton clearSlicesButton { "Clear Slices" }; // Title bar buttons juce::TextButton loadSampleButton { "Load" }; juce::TextButton clearSampleButton { "Clear" }; juce::TextButton prevSampleButton { "<" }; juce::TextButton nextSampleButton { ">" }; juce::TextButton undoButton { "Undo" }; juce::TextButton redoButton { "Redo" }; juce::TextButton zoomInButton { "+" }; juce::TextButton zoomOutButton { "-" }; juce::TextButton zoomResetButton { "1:1" }; juce::TextButton scrollLeftButton { "<" }; juce::TextButton scrollRightButton { ">" }; juce::ComboBox scaleComboBox; juce::ComboBox octaveComboBox; static constexpr int baseWidth = 1100; static constexpr int baseHeight = 570; // Slice knobs juce::Slider bassSlider, trebleSlider, sensitivitySlider; juce::Label bassLabel, trebleLabel, sensitivityLabel; // Amp ADSR knobs juce::Slider ampAttackSlider, ampDecaySlider, ampSustainSlider, ampReleaseSlider; juce::Label ampAttackLabel, ampDecayLabel, ampSustainLabel, ampReleaseLabel; // Filter type selector juce::ComboBox filterTypeComboBox; // Filter knobs juce::Slider filterCutoffSlider, filterResoSlider, filterEnvDepthSlider; juce::Label filterCutoffLabel, filterResoLabel, filterEnvDepthLabel; using SliderAttachment = juce::AudioProcessorValueTreeState::SliderAttachment; using ComboBoxAttachment = juce::AudioProcessorValueTreeState::ComboBoxAttachment; // Filter ADSR knobs juce::Slider filterAttackSlider, filterDecaySlider, filterSustainSlider, filterReleaseSlider; juce::Label filterAttackLabel, filterDecayLabel, filterSustainLabel, filterReleaseLabel; // Time-stretch controls juce::Slider bpmSlider; juce::ComboBox stretchBeatsComboBox; juce::TextButton stretchButton { "Match Length" }; juce::ComboBox keyShiftComboBox; juce::Label keyShiftLabel; std::unique_ptr stretchBpmAttachment; std::unique_ptr stretchBeatsAttachment; std::unique_ptr keyShiftAttachment; std::unique_ptr scaleAttachment; std::unique_ptr octaveAttachment; std::unique_ptr bassAttachment, trebleAttachment, sensitivityAttachment; std::unique_ptr ampAttackAttachment, ampDecayAttachment, ampSustainAttachment, ampReleaseAttachment; std::unique_ptr filterCutoffAttachment, filterResoAttachment, filterEnvDepthAttachment; std::unique_ptr filterAttackAttachment, filterDecayAttachment, filterSustainAttachment, filterReleaseAttachment; std::unique_ptr filterTypeAttachment; juce::FileChooser fileChooser { "Load Audio File", juce::File{}, "*.wav;*.aiff;*.flac;*.ogg" }; juce::TextButton fileInfoLabel; juce::Label buildInfoLabel; juce::File currentLoadedFile; void setupSlider(juce::Slider& slider, juce::Label& label, const juce::String& name); void attachSlider(juce::Slider& slider, juce::Label& label, const juce::String& name, const juce::String& paramId, std::unique_ptr& attachment); int keyClickNote = -1; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MonoslicerEditor) };