Hello, thank you for your help.
Not sure if I’m doing this right, but I think this is what you’re asking for:
class JUCE_API Button : public Component,
public SettableTooltipClient
{
protected:
//==============================================================================
explicit Button (const String& buttonName);
public:
/** Destructor. */
~Button() override;
//==============================================================================
void setButtonText (const String& newText);
const String& getButtonText() const { return text; }
//==============================================================================
bool isDown() const noexcept;
bool isOver() const noexcept;
//==============================================================================
void setToggleState (bool shouldBeOn, NotificationType notification);
bool getToggleState() const noexcept { return isOn.getValue(); }
Value& getToggleStateValue() noexcept { return isOn; }
void setClickingTogglesState (bool shouldAutoToggleOnClick) noexcept;
bool getClickingTogglesState() const noexcept;
//==============================================================================
void setRadioGroupId (int newGroupId, NotificationType notification = sendNotification);
/** Returns the ID of the group to which this button belongs.
(See setRadioGroupId() for an explanation of this).
*/
int getRadioGroupId() const noexcept { return radioGroupId; }
//==============================================================================
class JUCE_API Listener
{
public:
/** Destructor. */
virtual ~Listener() = default;
/** Called when the button is clicked. */
virtual void buttonClicked (Button*) = 0;
/** Called when the button's state changes. */
virtual void buttonStateChanged (Button*) {}
};
void addListener (Listener* newListener);
/** Removes a previously-registered button listener
@see addListener
*/
void removeListener (Listener* listener);
//==============================================================================
/** You can assign a lambda to this callback object to have it called when the button is clicked. */
std::function<void()> onClick;
/** You can assign a lambda to this callback object to have it called when the button's state changes. */
std::function<void()> onStateChange;
//==============================================================================
virtual void triggerClick();
//==============================================================================
void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse,
CommandID commandID,
bool generateTooltip);
/** Returns the command ID that was set by setCommandToTrigger(). */
CommandID getCommandID() const noexcept { return commandID; }
//==============================================================================
void addShortcut (const KeyPress&);
void clearShortcuts();
bool isRegisteredForShortcut (const KeyPress&) const;
//==============================================================================
void setRepeatSpeed (int initialDelayInMillisecs,
int repeatDelayInMillisecs,
int minimumDelayInMillisecs = -1) noexcept;
void setTriggeredOnMouseDown (bool isTriggeredOnMouseDown) noexcept;
bool getTriggeredOnMouseDown() const noexcept;
uint32 getMillisecondsSinceButtonDown() const noexcept;
//==============================================================================
void setTooltip (const String& newTooltip) override;
//==============================================================================
/** A combination of these flags are used by setConnectedEdges(). */
enum ConnectedEdgeFlags
{
ConnectedOnLeft = 1,
ConnectedOnRight = 2,
ConnectedOnTop = 4,
ConnectedOnBottom = 8
};
void setConnectedEdges (int connectedEdgeFlags);
/** Returns the set of flags passed into setConnectedEdges(). */
int getConnectedEdgeFlags() const noexcept { return connectedEdgeFlags; }
bool isConnectedOnLeft() const noexcept { return (connectedEdgeFlags & ConnectedOnLeft) != 0; }
bool isConnectedOnRight() const noexcept { return (connectedEdgeFlags & ConnectedOnRight) != 0; }
bool isConnectedOnTop() const noexcept { return (connectedEdgeFlags & ConnectedOnTop) != 0; }
/** Indicates whether the button adjoins another one on its bottom edge.
@see setConnectedEdges
*/
bool isConnectedOnBottom() const noexcept { return (connectedEdgeFlags & ConnectedOnBottom) != 0; }
//==============================================================================
/** Used by setState(). */
enum ButtonState
{
buttonNormal,
buttonOver,
buttonDown
};
void setState (ButtonState newState);
/** Returns the button's current over/down/up state. */
ButtonState getState() const noexcept { return buttonState; }
//==============================================================================
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() = default;
virtual void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
virtual Font getTextButtonFont (TextButton&, int buttonHeight) = 0;
virtual int getTextButtonWidthToFitText (TextButton&, int buttonHeight) = 0;
/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics&, TextButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
/** Draws the contents of a standard ToggleButton. */
virtual void drawToggleButton (Graphics&, ToggleButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
virtual void changeToggleButtonWidthToFitText (ToggleButton&) = 0;
virtual void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
bool ticked, bool isEnabled,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
virtual void drawDrawableButton (Graphics&, DrawableButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) = 0;
};
// This method's parameters have changed - see the new version.
JUCE_DEPRECATED (void setToggleState (bool, bool));
protected:
//==============================================================================
/** This method is called when the button has been clicked.
Subclasses can override this to perform whatever actions they need to do.
In general, you wouldn't use this method to receive clicks, but should get your callbacks
by attaching a std::function to the onClick callback, or adding a Button::Listener.
@see triggerClick, onClick
*/
virtual void clicked();
/** This method is called when the button has been clicked.
By default it just calls clicked(), but you might want to override it to handle
things like clicking when a modifier key is pressed, etc.
@see ModifierKeys
*/
virtual void clicked (const ModifierKeys& modifiers);
/** Subclasses should override this to actually paint the button's contents.
It's better to use this than the paint method, because it gives you information
about the over/down state of the button.
@param g the graphics context to use
@param shouldDrawButtonAsHighlighted true if the button is either in the 'over' or 'down' state
@param shouldDrawButtonAsDown true if the button should be drawn in the 'down' position
*/
virtual void paintButton (Graphics& g,
bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown) = 0;
/** Called when the button's up/down/over state changes.
Subclasses can override this if they need to do something special when the button
goes up or down.
@see isDown, isOver
*/
virtual void buttonStateChanged();
//==============================================================================
/** @internal */
virtual void internalClickCallback (const ModifierKeys&);
/** @internal */
void handleCommandMessage (int commandId) override;
/** @internal */
void mouseEnter (const MouseEvent&) override;
/** @internal */
void mouseExit (const MouseEvent&) override;
/** @internal */
void mouseDown (const MouseEvent&) override;
/** @internal */
void mouseDrag (const MouseEvent&) override;
/** @internal */
void mouseUp (const MouseEvent&) override;
/** @internal */
bool keyPressed (const KeyPress&) override;
/** @internal */
using Component::keyStateChanged;
/** @internal */
void paint (Graphics&) override;
/** @internal */
void parentHierarchyChanged() override;
/** @internal */
void visibilityChanged() override;
/** @internal */
void focusGained (FocusChangeType) override;
/** @internal */
void focusLost (FocusChangeType) override;
/** @internal */
void enablementChanged() override;
private:
//==============================================================================
Array<KeyPress> shortcuts;
WeakReference<Component> keySource;
String text;
ListenerList<Listener> buttonListeners;
struct CallbackHelper;
std::unique_ptr<CallbackHelper> callbackHelper;
uint32 buttonPressTime = 0, lastRepeatTime = 0;
ApplicationCommandManager* commandManagerToUse = nullptr;
int autoRepeatDelay = -1, autoRepeatSpeed = 0, autoRepeatMinimumDelay = -1;
int radioGroupId = 0, connectedEdgeFlags = 0;
CommandID commandID = {};
ButtonState buttonState = buttonNormal, lastStatePainted = buttonNormal;
Value isOn;
bool lastToggleState = false;
bool clickTogglesState = false;
bool needsToRelease = false;
bool needsRepainting = false;
bool isKeyDown = false;
bool triggerOnMouseDown = false;
bool generateTooltip = false;
void repeatTimerCallback();
bool keyStateChangedCallback();
void applicationCommandListChangeCallback();
void updateAutomaticTooltip (const ApplicationCommandInfo&);
ButtonState updateState();
ButtonState updateState (bool isOver, bool isDown);
bool isShortcutPressed() const;
void turnOffOtherButtonsInGroup (NotificationType click, NotificationType state);
void flashButtonState();
void sendClickMessage (const ModifierKeys&);
void sendStateMessage();
void setToggleState (bool shouldBeOn, NotificationType click, NotificationType state);
bool isMouseSourceOver (const MouseEvent& e);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Button)
};
} // namespace juce
Thank you.