#pragma once #include #include "LcdPanel.h" #include "PluginProcessor.h" #include "BinaryData.h" class RackEditor : public juce::AudioProcessorEditor, private juce::Timer { public: explicit RackEditor (RMX19AudioProcessor&); ~RackEditor() override; void paint (juce::Graphics&) override; void resized() override; bool keyPressed (const juce::KeyPress&) override; private: RMX19AudioProcessor& proc; // one of the four wedge-shaped keys of the circular joystick ring. every wedge // component covers the whole ring bounding box and paints only its own sector, // so the ring centre is always at (outerR, outerR) in local coordinates. class DirWedge : public juce::Button { public: DirWedge (const juce::String& label, double centreAngleRad) : juce::Button (label), angle (centreAngleRad) { setWantsKeyboardFocus (true); setRepeatSpeed (320, 80); } void paintButton (juce::Graphics&, bool, bool) override; // all four wedges share the ring's bounding box, so the box alone would let the // topmost one swallow every click in the ring. restrict hits to this wedge's sector. bool hitTest (int x, int y) override; static constexpr float outerR = 66.0f; static constexpr float innerR = 24.0f; // half of a quadrant, minus a gap so neighbouring wedges read as separate keys static constexpr double halfSpan = 0.7156; double angle; // radians clockwise from 12 o'clock }; // the OK key sitting in the middle of the ring class CentreOkButton : public juce::Button { public: explicit CentreOkButton (const juce::String& label) : juce::Button (label) { setWantsKeyboardFocus (true); } void paintButton (juce::Graphics&, bool, bool) override; // the key paints as a disc, so hit only the disc rather than its square bounds bool hitTest (int x, int y) override; static constexpr float radius = 21.0f; }; // the separate ESC key, outside the ring at the bottom left class EscButton : public juce::Button { public: explicit EscButton (const juce::String& label) : juce::Button (label) { setWantsKeyboardFocus (true); } void paintButton (juce::Graphics&, bool, bool) override; bool hitTest (int x, int y) override; static constexpr float diameter = 30.0f; }; DirWedge* up = nullptr; DirWedge* down = nullptr; DirWedge* left = nullptr; DirWedge* right = nullptr; CentreOkButton* okB = nullptr; EscButton* escB = nullptr; juce::ComboBox scaleBox; LcdPanel display; juce::Colour face; juce::Image backgroundImage; float powerPulse = 0.0f; float uiScale = 1.5f; static constexpr int baseW = 656, baseH = 248; void setScale (float s); void timerCallback() override; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RackEditor) };