sm-26/Source/JoystickPad.h

70 lines
2.4 KiB
C
Raw Permalink Normal View History

#pragma once
#include <JuceHeader.h>
// Small flat circular button matching the joystick pad's dark style.
class RoundNavButton : public juce::Button
{
public:
explicit RoundNavButton (const juce::String& label) : juce::Button (label) {}
void paintButton (juce::Graphics& g, bool isDown, bool isOver) override
{
const float w = (float) getWidth();
const float h = (float) getHeight();
const float cx = w * 0.5f;
const float cy = h * 0.5f;
const float r = juce::jmin (w, h) * 0.5f - 1.0f;
g.fillAll (juce::Colour (0xFF000000));
g.setColour (isDown ? juce::Colour (0xFFECECEC) : juce::Colour (0xFF151515));
g.fillEllipse (cx - r, cy - r, r * 2.0f, r * 2.0f);
g.setColour (isDown ? juce::Colour (0xFFECECEC) : juce::Colour (0xFF242424));
g.drawEllipse (cx - r, cy - r, r * 2.0f, r * 2.0f, 1.0f);
g.setFont (juce::Font (juce::FontOptions { juce::Font::getDefaultMonospacedFontName(),
12.0f, isDown ? juce::Font::bold : juce::Font::plain }));
g.setColour (isDown ? juce::Colour (0xFF0A0A0A) : juce::Colour (0xFF9A9A9A));
g.drawText (getButtonText(), juce::Rectangle<float> (0, 0, w, h), juce::Justification::centred);
}
};
// A flat dark virtual-analog joystick pad. A circular well holds four
// quarter-circle buttons (up/down/left/right). Holding a direction glows
// the matching quarter and emits repeat actions like a gamepad D-pad.
class JoystickPad : public juce::Component, private juce::Timer
{
public:
enum Direction : int { None = -1, Up = 0, Down = 1, Left = 2, Right = 3 };
JoystickPad();
~JoystickPad() override = default;
void paint (juce::Graphics&) override;
void mouseDown (const juce::MouseEvent&) override;
void mouseDrag (const juce::MouseEvent&) override;
void mouseUp (const juce::MouseEvent&) override;
// Called on press (immediately) and then on repeat while held.
std::function<void (int direction)> onAction;
void setRepeatSpeed (int initialDelayMs, int repeatMs);
private:
void timerCallback() override;
void beginHold (int direction);
void endHold();
int directionFrom (const juce::MouseEvent&) const;
Direction active = None;
int initialDelayMs = 250;
int repeatMs = 50;
int64 holdStartMs = 0;
int64 lastFireMs = 0;
bool repeatsStarted = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JoystickPad)
};