migrating to the latest JUCE version
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,477 +1,463 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that lets the user choose from a drop-down list of choices.
|
||||
|
||||
The combo-box has a list of text strings, each with an associated id number,
|
||||
that will be shown in the drop-down list when the user clicks on the component.
|
||||
|
||||
The currently selected choice is displayed in the combo-box, and this can
|
||||
either be read-only text, or editable.
|
||||
|
||||
To find out when the user selects a different item or edits the text, you
|
||||
can assign a lambda to the onChange member, or register a ComboBox::Listener
|
||||
to receive callbacks.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ComboBox : public Component,
|
||||
public SettableTooltipClient,
|
||||
public Value::Listener,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a combo-box.
|
||||
|
||||
On construction, the text field will be empty, so you should call the
|
||||
setSelectedId() or setText() method to choose the initial value before
|
||||
displaying it.
|
||||
|
||||
@param componentName the name to set for the component (see Component::setName())
|
||||
*/
|
||||
explicit ComboBox (const String& componentName = {});
|
||||
|
||||
/** Destructor. */
|
||||
~ComboBox() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets whether the text in the combo-box is editable.
|
||||
|
||||
The default state for a new ComboBox is non-editable, and can only be changed
|
||||
by choosing from the drop-down list.
|
||||
*/
|
||||
void setEditableText (bool isEditable);
|
||||
|
||||
/** Returns true if the text is directly editable.
|
||||
@see setEditableText
|
||||
*/
|
||||
bool isTextEditable() const noexcept;
|
||||
|
||||
/** Sets the style of justification to be used for positioning the text.
|
||||
|
||||
The default is Justification::centredLeft. The text is displayed using a
|
||||
Label component inside the ComboBox.
|
||||
*/
|
||||
void setJustificationType (Justification justification);
|
||||
|
||||
/** Returns the current justification for the text box.
|
||||
@see setJustificationType
|
||||
*/
|
||||
Justification getJustificationType() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds an item to be shown in the drop-down list.
|
||||
|
||||
@param newItemText the text of the item to show in the list
|
||||
@param newItemId an associated ID number that can be set or retrieved - see
|
||||
getSelectedId() and setSelectedId(). Note that this value can not
|
||||
be 0!
|
||||
@see setItemEnabled, addSeparator, addSectionHeading, getNumItems, getItemText, getItemId
|
||||
*/
|
||||
void addItem (const String& newItemText, int newItemId);
|
||||
|
||||
/** Adds an item to be shown in the drop-down list.
|
||||
|
||||
@param newItemText the text of the item to show in the list
|
||||
@param newItemId an associated ID number that can be set or retrieved - see
|
||||
getSelectedId() and setSelectedId(). Note that this value can not
|
||||
be 0!
|
||||
@param newItemImage an icon image that is shown to the left of text
|
||||
@see setItemEnabled, addSeparator, addSectionHeading, getNumItems, getItemText, getItemId
|
||||
*/
|
||||
void addItem (const String& newItemText, int newItemId, const Image & newItemImage);
|
||||
|
||||
|
||||
/** Adds an array of items to the drop-down list.
|
||||
The item ID of each item will be its index in the StringArray + firstItemIdOffset.
|
||||
*/
|
||||
void addItemList (const StringArray& items, int firstItemIdOffset);
|
||||
|
||||
/** Adds a separator line to the drop-down list.
|
||||
|
||||
This is like adding a separator to a popup menu. See PopupMenu::addSeparator().
|
||||
*/
|
||||
void addSeparator();
|
||||
|
||||
/** Adds a heading to the drop-down list, so that you can group the items into
|
||||
different sections.
|
||||
|
||||
The headings are indented slightly differently to set them apart from the
|
||||
items on the list, and obviously can't be selected. You might want to add
|
||||
separators between your sections too.
|
||||
|
||||
@see addItem, addSeparator
|
||||
*/
|
||||
void addSectionHeading (const String& headingName);
|
||||
|
||||
/** This allows items in the drop-down list to be selectively disabled.
|
||||
|
||||
When you add an item, it's enabled by default, but you can call this
|
||||
method to change its status.
|
||||
|
||||
If you disable an item which is already selected, this won't change the
|
||||
current selection - it just stops the user choosing that item from the list.
|
||||
*/
|
||||
void setItemEnabled (int itemId, bool shouldBeEnabled);
|
||||
|
||||
/** Returns true if the given item is enabled. */
|
||||
bool isItemEnabled (int itemId) const noexcept;
|
||||
|
||||
/** Changes the text for an existing item.
|
||||
*/
|
||||
void changeItemText (int itemId, const String& newText);
|
||||
|
||||
/** Removes all the items from the drop-down list.
|
||||
|
||||
If this call causes the content to be cleared, and a change-message
|
||||
will be broadcast according to the notification parameter.
|
||||
|
||||
@see addItem, getNumItems
|
||||
*/
|
||||
void clear (NotificationType notification = sendNotificationAsync);
|
||||
|
||||
/** Returns the number of items that have been added to the list.
|
||||
|
||||
Note that this doesn't include headers or separators.
|
||||
*/
|
||||
int getNumItems() const noexcept;
|
||||
|
||||
/** Returns the text for one of the items in the list.
|
||||
Note that this doesn't include headers or separators.
|
||||
@param index the item's index from 0 to (getNumItems() - 1)
|
||||
*/
|
||||
String getItemText (int index) const;
|
||||
|
||||
/** Returns the ID for one of the items in the list.
|
||||
Note that this doesn't include headers or separators.
|
||||
@param index the item's index from 0 to (getNumItems() - 1)
|
||||
*/
|
||||
int getItemId (int index) const noexcept;
|
||||
|
||||
/** Returns the index in the list of a particular item ID.
|
||||
If no such ID is found, this will return -1.
|
||||
*/
|
||||
int indexOfItemId (int itemId) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the ID of the item that's currently shown in the box.
|
||||
|
||||
If no item is selected, or if the text is editable and the user
|
||||
has entered something which isn't one of the items in the list, then
|
||||
this will return 0.
|
||||
|
||||
@see setSelectedId, getSelectedItemIndex, getText
|
||||
*/
|
||||
int getSelectedId() const noexcept;
|
||||
|
||||
/** Returns a Value object that can be used to get or set the selected item's ID.
|
||||
|
||||
You can call Value::referTo() on this object to make the combo box control
|
||||
another Value object.
|
||||
*/
|
||||
Value& getSelectedIdAsValue() { return currentId; }
|
||||
|
||||
/** Sets one of the items to be the current selection.
|
||||
|
||||
This will set the ComboBox's text to that of the item that matches
|
||||
this ID.
|
||||
|
||||
@param newItemId the new item to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the value changes
|
||||
@see getSelectedId, setSelectedItemIndex, setText
|
||||
*/
|
||||
void setSelectedId (int newItemId,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the index of the item that's currently shown in the box.
|
||||
|
||||
If no item is selected, or if the text is editable and the user
|
||||
has entered something which isn't one of the items in the list, then
|
||||
this will return -1.
|
||||
|
||||
@see setSelectedItemIndex, getSelectedId, getText
|
||||
*/
|
||||
int getSelectedItemIndex() const;
|
||||
|
||||
/** Sets one of the items to be the current selection.
|
||||
|
||||
This will set the ComboBox's text to that of the item at the given
|
||||
index in the list.
|
||||
|
||||
@param newItemIndex the new item to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the value changes
|
||||
@see getSelectedItemIndex, setSelectedId, setText
|
||||
*/
|
||||
void setSelectedItemIndex (int newItemIndex,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the text that is currently shown in the combo-box's text field.
|
||||
|
||||
If the ComboBox has editable text, then this text may have been edited
|
||||
by the user; otherwise it will be one of the items from the list, or
|
||||
possibly an empty string if nothing was selected.
|
||||
|
||||
@see setText, getSelectedId, getSelectedItemIndex
|
||||
*/
|
||||
String getText() const;
|
||||
|
||||
/** Sets the contents of the combo-box's text field.
|
||||
|
||||
The text passed-in will be set as the current text regardless of whether
|
||||
it is one of the items in the list. If the current text isn't one of the
|
||||
items, then getSelectedId() will return 0, otherwise it will return
|
||||
the appropriate ID.
|
||||
|
||||
@param newText the text to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the text changes
|
||||
@see getText
|
||||
*/
|
||||
void setText (const String& newText,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
/** Programmatically opens the text editor to allow the user to edit the current item.
|
||||
|
||||
This is the same effect as when the box is clicked-on.
|
||||
@see Label::showEditor();
|
||||
*/
|
||||
void showEditor();
|
||||
|
||||
/** Pops up the combo box's list.
|
||||
This is virtual so that you can override it with your own custom popup
|
||||
mechanism if you need some really unusual behaviour.
|
||||
*/
|
||||
virtual void showPopup();
|
||||
|
||||
/** Hides the combo box's popup list, if it's currently visible. */
|
||||
void hidePopup();
|
||||
|
||||
/** Returns true if the popup menu is currently being shown. */
|
||||
bool isPopupActive() const noexcept { return menuActive; }
|
||||
|
||||
/** Returns the PopupMenu object associated with the ComboBox.
|
||||
Can be useful for adding sub-menus to the ComboBox standard PopupMenu
|
||||
*/
|
||||
PopupMenu* getRootMenu() noexcept { return ¤tMenu; }
|
||||
|
||||
/** Returns the PopupMenu object associated with the ComboBox. */
|
||||
const PopupMenu* getRootMenu() const noexcept { return ¤tMenu; }
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for receiving events from a ComboBox.
|
||||
|
||||
You can register a ComboBox::Listener with a ComboBox using the ComboBox::addListener()
|
||||
method, and it will be called when the selected item in the box changes.
|
||||
|
||||
@see ComboBox::addListener, ComboBox::removeListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Called when a ComboBox has its selected item changed. */
|
||||
virtual void comboBoxChanged (ComboBox* comboBoxThatHasChanged) = 0;
|
||||
};
|
||||
|
||||
/** Registers a listener that will be called when the box's content changes. */
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a previously-registered listener. */
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** You can assign a lambda to this callback object to have it called when the selected ID is changed. */
|
||||
std::function<void()> onChange;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a message to display when there is no item currently selected.
|
||||
@see getTextWhenNothingSelected
|
||||
*/
|
||||
void setTextWhenNothingSelected (const String& newMessage);
|
||||
|
||||
/** Returns the text that is shown when no item is selected.
|
||||
@see setTextWhenNothingSelected
|
||||
*/
|
||||
String getTextWhenNothingSelected() const;
|
||||
|
||||
/** Sets the message to show when there are no items in the list, and the user clicks
|
||||
on the drop-down box.
|
||||
|
||||
By default it just says "no choices", but this lets you change it to something more
|
||||
meaningful.
|
||||
*/
|
||||
void setTextWhenNoChoicesAvailable (const String& newMessage);
|
||||
|
||||
/** Returns the text shown when no items have been added to the list.
|
||||
@see setTextWhenNoChoicesAvailable
|
||||
*/
|
||||
String getTextWhenNoChoicesAvailable() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Gives the ComboBox a tooltip. */
|
||||
void setTooltip (const String& newTooltip) override;
|
||||
|
||||
/** This can be used to allow the scroll-wheel to nudge the chosen item.
|
||||
By default it's disabled, and I'd recommend leaving it disabled if there's any
|
||||
chance that the control might be inside a scrollable list or viewport.
|
||||
*/
|
||||
void setScrollWheelEnabled (bool enabled) noexcept;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the combo box.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
To change the colours of the menu that pops up, you can set the colour IDs in PopupMenu::ColourIDs.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1000b00, /**< The background colour to fill the box with. */
|
||||
textColourId = 0x1000a00, /**< The colour for the text in the box. */
|
||||
outlineColourId = 0x1000c00, /**< The colour for an outline around the box. */
|
||||
buttonColourId = 0x1000d00, /**< The base colour for the button (a LookAndFeel class will probably use variations on this). */
|
||||
arrowColourId = 0x1000e00, /**< The colour for the arrow shape that pops up the menu */
|
||||
focusedOutlineColourId = 0x1000f00 /**< The colour that will be used to draw a box around the edge of the component when it has focus. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes to provide
|
||||
ComboBox functionality.
|
||||
*/
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
|
||||
int buttonX, int buttonY, int buttonW, int buttonH,
|
||||
ComboBox&) = 0;
|
||||
|
||||
virtual Font getComboBoxFont (ComboBox&) = 0;
|
||||
|
||||
virtual Label* createComboBoxTextBox (ComboBox&) = 0;
|
||||
|
||||
virtual void positionComboBoxText (ComboBox&, Label& labelToPosition, Drawable * image = nullptr) = 0;
|
||||
|
||||
virtual PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox&, Label&) = 0;
|
||||
|
||||
virtual void drawComboBoxTextWhenNothingSelected (Graphics&, ComboBox&, Label&) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void enablementChanged() override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
/** @internal */
|
||||
void focusGained (Component::FocusChangeType) override;
|
||||
/** @internal */
|
||||
void focusLost (Component::FocusChangeType) override;
|
||||
/** @internal */
|
||||
void handleAsyncUpdate() override;
|
||||
/** @internal */
|
||||
String getTooltip() override { return label->getTooltip(); }
|
||||
/** @internal */
|
||||
void mouseDown (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseDrag (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseUp (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
bool keyStateChanged (bool) override;
|
||||
/** @internal */
|
||||
bool keyPressed (const KeyPress&) override;
|
||||
/** @internal */
|
||||
void valueChanged (Value&) override;
|
||||
/** @internal */
|
||||
void parentHierarchyChanged() override;
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// These methods' bool parameters have changed: see their new method signatures.
|
||||
[[deprecated]] void clear (bool);
|
||||
[[deprecated]] void setSelectedId (int, bool);
|
||||
[[deprecated]] void setSelectedItemIndex (int, bool);
|
||||
[[deprecated]] void setText (const String&, bool);
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
enum EditableState
|
||||
{
|
||||
editableUnknown,
|
||||
labelIsNotEditable,
|
||||
labelIsEditable
|
||||
};
|
||||
|
||||
PopupMenu currentMenu;
|
||||
Value currentId;
|
||||
int lastCurrentId = 0;
|
||||
bool isButtonDown = false, menuActive = false, scrollWheelEnabled = false;
|
||||
float mouseWheelAccumulator = 0;
|
||||
ListenerList<Listener> listeners;
|
||||
std::unique_ptr<Label> label;
|
||||
String textWhenNothingSelected, noChoicesMessage;
|
||||
EditableState labelEditableState = editableUnknown;
|
||||
|
||||
std::unique_ptr<Drawable> image;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
PopupMenu::Item* getItemForId (int) const noexcept;
|
||||
PopupMenu::Item* getItemForIndex (int) const noexcept;
|
||||
bool selectIfEnabled (int index);
|
||||
bool nudgeSelectedItem (int delta);
|
||||
void sendChange (NotificationType);
|
||||
void showPopupIfNotActive();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBox)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that lets the user choose from a drop-down list of choices.
|
||||
|
||||
The combo-box has a list of text strings, each with an associated id number,
|
||||
that will be shown in the drop-down list when the user clicks on the component.
|
||||
|
||||
The currently selected choice is displayed in the combo-box, and this can
|
||||
either be read-only text, or editable.
|
||||
|
||||
To find out when the user selects a different item or edits the text, you
|
||||
can assign a lambda to the onChange member, or register a ComboBox::Listener
|
||||
to receive callbacks.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ComboBox : public Component,
|
||||
public SettableTooltipClient,
|
||||
public Value::Listener,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a combo-box.
|
||||
|
||||
On construction, the text field will be empty, so you should call the
|
||||
setSelectedId() or setText() method to choose the initial value before
|
||||
displaying it.
|
||||
|
||||
@param componentName the name to set for the component (see Component::setName())
|
||||
*/
|
||||
explicit ComboBox (const String& componentName = {});
|
||||
|
||||
/** Destructor. */
|
||||
~ComboBox() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets whether the text in the combo-box is editable.
|
||||
|
||||
The default state for a new ComboBox is non-editable, and can only be changed
|
||||
by choosing from the drop-down list.
|
||||
*/
|
||||
void setEditableText (bool isEditable);
|
||||
|
||||
/** Returns true if the text is directly editable.
|
||||
@see setEditableText
|
||||
*/
|
||||
bool isTextEditable() const noexcept;
|
||||
|
||||
/** Sets the style of justification to be used for positioning the text.
|
||||
|
||||
The default is Justification::centredLeft. The text is displayed using a
|
||||
Label component inside the ComboBox.
|
||||
*/
|
||||
void setJustificationType (Justification justification);
|
||||
|
||||
/** Returns the current justification for the text box.
|
||||
@see setJustificationType
|
||||
*/
|
||||
Justification getJustificationType() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds an item to be shown in the drop-down list.
|
||||
|
||||
@param newItemText the text of the item to show in the list
|
||||
@param newItemId an associated ID number that can be set or retrieved - see
|
||||
getSelectedId() and setSelectedId(). Note that this value can not
|
||||
be 0!
|
||||
@see setItemEnabled, addSeparator, addSectionHeading, getNumItems, getItemText, getItemId
|
||||
*/
|
||||
void addItem (const String& newItemText, int newItemId);
|
||||
|
||||
/** Adds an array of items to the drop-down list.
|
||||
The item ID of each item will be its index in the StringArray + firstItemIdOffset.
|
||||
*/
|
||||
void addItemList (const StringArray& items, int firstItemIdOffset);
|
||||
|
||||
/** Adds a separator line to the drop-down list.
|
||||
|
||||
This is like adding a separator to a popup menu. See PopupMenu::addSeparator().
|
||||
*/
|
||||
void addSeparator();
|
||||
|
||||
/** Adds a heading to the drop-down list, so that you can group the items into
|
||||
different sections.
|
||||
|
||||
The headings are indented slightly differently to set them apart from the
|
||||
items on the list, and obviously can't be selected. You might want to add
|
||||
separators between your sections too.
|
||||
|
||||
@see addItem, addSeparator
|
||||
*/
|
||||
void addSectionHeading (const String& headingName);
|
||||
|
||||
/** This allows items in the drop-down list to be selectively disabled.
|
||||
|
||||
When you add an item, it's enabled by default, but you can call this
|
||||
method to change its status.
|
||||
|
||||
If you disable an item which is already selected, this won't change the
|
||||
current selection - it just stops the user choosing that item from the list.
|
||||
*/
|
||||
void setItemEnabled (int itemId, bool shouldBeEnabled);
|
||||
|
||||
/** Returns true if the given item is enabled. */
|
||||
bool isItemEnabled (int itemId) const noexcept;
|
||||
|
||||
/** Changes the text for an existing item.
|
||||
*/
|
||||
void changeItemText (int itemId, const String& newText);
|
||||
|
||||
/** Removes all the items from the drop-down list.
|
||||
|
||||
If this call causes the content to be cleared, and a change-message
|
||||
will be broadcast according to the notification parameter.
|
||||
|
||||
@see addItem, getNumItems
|
||||
*/
|
||||
void clear (NotificationType notification = sendNotificationAsync);
|
||||
|
||||
/** Returns the number of items that have been added to the list.
|
||||
|
||||
Note that this doesn't include headers or separators.
|
||||
*/
|
||||
int getNumItems() const noexcept;
|
||||
|
||||
/** Returns the text for one of the items in the list.
|
||||
Note that this doesn't include headers or separators.
|
||||
@param index the item's index from 0 to (getNumItems() - 1)
|
||||
*/
|
||||
String getItemText (int index) const;
|
||||
|
||||
/** Returns the ID for one of the items in the list.
|
||||
Note that this doesn't include headers or separators.
|
||||
@param index the item's index from 0 to (getNumItems() - 1)
|
||||
*/
|
||||
int getItemId (int index) const noexcept;
|
||||
|
||||
/** Returns the index in the list of a particular item ID.
|
||||
If no such ID is found, this will return -1.
|
||||
*/
|
||||
int indexOfItemId (int itemId) const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the ID of the item that's currently shown in the box.
|
||||
|
||||
If no item is selected, or if the text is editable and the user
|
||||
has entered something which isn't one of the items in the list, then
|
||||
this will return 0.
|
||||
|
||||
@see setSelectedId, getSelectedItemIndex, getText
|
||||
*/
|
||||
int getSelectedId() const noexcept;
|
||||
|
||||
/** Returns a Value object that can be used to get or set the selected item's ID.
|
||||
|
||||
You can call Value::referTo() on this object to make the combo box control
|
||||
another Value object.
|
||||
*/
|
||||
Value& getSelectedIdAsValue() { return currentId; }
|
||||
|
||||
/** Sets one of the items to be the current selection.
|
||||
|
||||
This will set the ComboBox's text to that of the item that matches
|
||||
this ID.
|
||||
|
||||
@param newItemId the new item to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the value changes
|
||||
@see getSelectedId, setSelectedItemIndex, setText
|
||||
*/
|
||||
void setSelectedId (int newItemId,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the index of the item that's currently shown in the box.
|
||||
|
||||
If no item is selected, or if the text is editable and the user
|
||||
has entered something which isn't one of the items in the list, then
|
||||
this will return -1.
|
||||
|
||||
@see setSelectedItemIndex, getSelectedId, getText
|
||||
*/
|
||||
int getSelectedItemIndex() const;
|
||||
|
||||
/** Sets one of the items to be the current selection.
|
||||
|
||||
This will set the ComboBox's text to that of the item at the given
|
||||
index in the list.
|
||||
|
||||
@param newItemIndex the new item to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the value changes
|
||||
@see getSelectedItemIndex, setSelectedId, setText
|
||||
*/
|
||||
void setSelectedItemIndex (int newItemIndex,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the text that is currently shown in the combo-box's text field.
|
||||
|
||||
If the ComboBox has editable text, then this text may have been edited
|
||||
by the user; otherwise it will be one of the items from the list, or
|
||||
possibly an empty string if nothing was selected.
|
||||
|
||||
@see setText, getSelectedId, getSelectedItemIndex
|
||||
*/
|
||||
String getText() const;
|
||||
|
||||
/** Sets the contents of the combo-box's text field.
|
||||
|
||||
The text passed-in will be set as the current text regardless of whether
|
||||
it is one of the items in the list. If the current text isn't one of the
|
||||
items, then getSelectedId() will return 0, otherwise it will return
|
||||
the appropriate ID.
|
||||
|
||||
@param newText the text to select
|
||||
@param notification determines the type of change notification that will
|
||||
be sent to listeners if the text changes
|
||||
@see getText
|
||||
*/
|
||||
void setText (const String& newText,
|
||||
NotificationType notification = sendNotificationAsync);
|
||||
|
||||
/** Programmatically opens the text editor to allow the user to edit the current item.
|
||||
|
||||
This is the same effect as when the box is clicked-on.
|
||||
@see Label::showEditor();
|
||||
*/
|
||||
void showEditor();
|
||||
|
||||
/** Pops up the combo box's list.
|
||||
This is virtual so that you can override it with your own custom popup
|
||||
mechanism if you need some really unusual behaviour.
|
||||
*/
|
||||
virtual void showPopup();
|
||||
|
||||
/** Hides the combo box's popup list, if it's currently visible. */
|
||||
void hidePopup();
|
||||
|
||||
/** Returns true if the popup menu is currently being shown. */
|
||||
bool isPopupActive() const noexcept { return menuActive; }
|
||||
|
||||
/** Returns the PopupMenu object associated with the ComboBox.
|
||||
Can be useful for adding sub-menus to the ComboBox standard PopupMenu
|
||||
*/
|
||||
PopupMenu* getRootMenu() noexcept { return ¤tMenu; }
|
||||
|
||||
/** Returns the PopupMenu object associated with the ComboBox. */
|
||||
const PopupMenu* getRootMenu() const noexcept { return ¤tMenu; }
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for receiving events from a ComboBox.
|
||||
|
||||
You can register a ComboBox::Listener with a ComboBox using the ComboBox::addListener()
|
||||
method, and it will be called when the selected item in the box changes.
|
||||
|
||||
@see ComboBox::addListener, ComboBox::removeListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Called when a ComboBox has its selected item changed. */
|
||||
virtual void comboBoxChanged (ComboBox* comboBoxThatHasChanged) = 0;
|
||||
};
|
||||
|
||||
/** Registers a listener that will be called when the box's content changes. */
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a previously-registered listener. */
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** You can assign a lambda to this callback object to have it called when the selected ID is changed. */
|
||||
std::function<void()> onChange;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a message to display when there is no item currently selected.
|
||||
@see getTextWhenNothingSelected
|
||||
*/
|
||||
void setTextWhenNothingSelected (const String& newMessage);
|
||||
|
||||
/** Returns the text that is shown when no item is selected.
|
||||
@see setTextWhenNothingSelected
|
||||
*/
|
||||
String getTextWhenNothingSelected() const;
|
||||
|
||||
/** Sets the message to show when there are no items in the list, and the user clicks
|
||||
on the drop-down box.
|
||||
|
||||
By default it just says "no choices", but this lets you change it to something more
|
||||
meaningful.
|
||||
*/
|
||||
void setTextWhenNoChoicesAvailable (const String& newMessage);
|
||||
|
||||
/** Returns the text shown when no items have been added to the list.
|
||||
@see setTextWhenNoChoicesAvailable
|
||||
*/
|
||||
String getTextWhenNoChoicesAvailable() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Gives the ComboBox a tooltip. */
|
||||
void setTooltip (const String& newTooltip) override;
|
||||
|
||||
/** This can be used to allow the scroll-wheel to nudge the chosen item.
|
||||
By default it's disabled, and I'd recommend leaving it disabled if there's any
|
||||
chance that the control might be inside a scrollable list or viewport.
|
||||
*/
|
||||
void setScrollWheelEnabled (bool enabled) noexcept;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the combo box.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
To change the colours of the menu that pops up, you can set the colour IDs in PopupMenu::ColourIDs.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1000b00, /**< The background colour to fill the box with. */
|
||||
textColourId = 0x1000a00, /**< The colour for the text in the box. */
|
||||
outlineColourId = 0x1000c00, /**< The colour for an outline around the box. */
|
||||
buttonColourId = 0x1000d00, /**< The base colour for the button (a LookAndFeel class will probably use variations on this). */
|
||||
arrowColourId = 0x1000e00, /**< The colour for the arrow shape that pops up the menu */
|
||||
focusedOutlineColourId = 0x1000f00 /**< The colour that will be used to draw a box around the edge of the component when it has focus. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes to provide
|
||||
ComboBox functionality.
|
||||
*/
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
|
||||
int buttonX, int buttonY, int buttonW, int buttonH,
|
||||
ComboBox&) = 0;
|
||||
|
||||
virtual Font getComboBoxFont (ComboBox&) = 0;
|
||||
|
||||
virtual Label* createComboBoxTextBox (ComboBox&) = 0;
|
||||
|
||||
virtual void positionComboBoxText (ComboBox&, Label& labelToPosition) = 0;
|
||||
|
||||
virtual PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox&, Label&) = 0;
|
||||
|
||||
virtual void drawComboBoxTextWhenNothingSelected (Graphics&, ComboBox&, Label&) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void enablementChanged() override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
/** @internal */
|
||||
void focusGained (Component::FocusChangeType) override;
|
||||
/** @internal */
|
||||
void focusLost (Component::FocusChangeType) override;
|
||||
/** @internal */
|
||||
void handleAsyncUpdate() override;
|
||||
/** @internal */
|
||||
String getTooltip() override { return label->getTooltip(); }
|
||||
/** @internal */
|
||||
void mouseDown (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseDrag (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseUp (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
bool keyStateChanged (bool) override;
|
||||
/** @internal */
|
||||
bool keyPressed (const KeyPress&) override;
|
||||
/** @internal */
|
||||
void valueChanged (Value&) override;
|
||||
/** @internal */
|
||||
void parentHierarchyChanged() override;
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// These methods' bool parameters have changed: see their new method signatures.
|
||||
[[deprecated]] void clear (bool);
|
||||
[[deprecated]] void setSelectedId (int, bool);
|
||||
[[deprecated]] void setSelectedItemIndex (int, bool);
|
||||
[[deprecated]] void setText (const String&, bool);
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
enum EditableState
|
||||
{
|
||||
editableUnknown,
|
||||
labelIsNotEditable,
|
||||
labelIsEditable
|
||||
};
|
||||
|
||||
PopupMenu currentMenu;
|
||||
Value currentId;
|
||||
int lastCurrentId = 0;
|
||||
bool isButtonDown = false, menuActive = false, scrollWheelEnabled = false;
|
||||
float mouseWheelAccumulator = 0;
|
||||
ListenerList<Listener> listeners;
|
||||
std::unique_ptr<Label> label;
|
||||
String textWhenNothingSelected, noChoicesMessage;
|
||||
EditableState labelEditableState = editableUnknown;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
PopupMenu::Item* getItemForId (int) const noexcept;
|
||||
PopupMenu::Item* getItemForIndex (int) const noexcept;
|
||||
bool selectIfEnabled (int index);
|
||||
bool nudgeSelectedItem (int delta);
|
||||
void sendChange (NotificationType);
|
||||
void showPopupIfNotActive();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBox)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,107 +1,107 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ImageComponent::ImageComponent (const String& name)
|
||||
: Component (name),
|
||||
placement (RectanglePlacement::centred)
|
||||
{
|
||||
}
|
||||
|
||||
ImageComponent::~ImageComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageComponent::setImage (const Image& newImage)
|
||||
{
|
||||
if (image != newImage)
|
||||
{
|
||||
image = newImage;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::setImage (const Image& newImage, RectanglePlacement placementToUse)
|
||||
{
|
||||
if (image != newImage || placement != placementToUse)
|
||||
{
|
||||
image = newImage;
|
||||
placement = placementToUse;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::setImagePlacement (RectanglePlacement newPlacement)
|
||||
{
|
||||
if (placement != newPlacement)
|
||||
{
|
||||
placement = newPlacement;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
const Image& ImageComponent::getImage() const
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
RectanglePlacement ImageComponent::getImagePlacement() const
|
||||
{
|
||||
return placement;
|
||||
}
|
||||
|
||||
void ImageComponent::paint (Graphics& g)
|
||||
{
|
||||
g.setOpacity (1.0f);
|
||||
g.drawImage (image, getLocalBounds().toFloat(), placement);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ImageComponent::createAccessibilityHandler()
|
||||
{
|
||||
class ImageComponentAccessibilityHandler : public AccessibilityHandler
|
||||
{
|
||||
public:
|
||||
explicit ImageComponentAccessibilityHandler (ImageComponent& imageComponentToWrap)
|
||||
: AccessibilityHandler (imageComponentToWrap, AccessibilityRole::image),
|
||||
imageComponent (imageComponentToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
String getHelp() const override { return imageComponent.getTooltip(); }
|
||||
|
||||
private:
|
||||
ImageComponent& imageComponent;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageComponentAccessibilityHandler)
|
||||
};
|
||||
|
||||
return std::make_unique<ImageComponentAccessibilityHandler> (*this);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ImageComponent::ImageComponent (const String& name)
|
||||
: Component (name),
|
||||
placement (RectanglePlacement::centred)
|
||||
{
|
||||
}
|
||||
|
||||
ImageComponent::~ImageComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageComponent::setImage (const Image& newImage)
|
||||
{
|
||||
if (image != newImage)
|
||||
{
|
||||
image = newImage;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::setImage (const Image& newImage, RectanglePlacement placementToUse)
|
||||
{
|
||||
if (image != newImage || placement != placementToUse)
|
||||
{
|
||||
image = newImage;
|
||||
placement = placementToUse;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageComponent::setImagePlacement (RectanglePlacement newPlacement)
|
||||
{
|
||||
if (placement != newPlacement)
|
||||
{
|
||||
placement = newPlacement;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
const Image& ImageComponent::getImage() const
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
RectanglePlacement ImageComponent::getImagePlacement() const
|
||||
{
|
||||
return placement;
|
||||
}
|
||||
|
||||
void ImageComponent::paint (Graphics& g)
|
||||
{
|
||||
g.setOpacity (1.0f);
|
||||
g.drawImage (image, getLocalBounds().toFloat(), placement);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ImageComponent::createAccessibilityHandler()
|
||||
{
|
||||
class ImageComponentAccessibilityHandler : public AccessibilityHandler
|
||||
{
|
||||
public:
|
||||
explicit ImageComponentAccessibilityHandler (ImageComponent& imageComponentToWrap)
|
||||
: AccessibilityHandler (imageComponentToWrap, AccessibilityRole::image),
|
||||
imageComponent (imageComponentToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
String getHelp() const override { return imageComponent.getTooltip(); }
|
||||
|
||||
private:
|
||||
ImageComponent& imageComponent;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageComponentAccessibilityHandler)
|
||||
};
|
||||
|
||||
return std::make_unique<ImageComponentAccessibilityHandler> (*this);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,81 +1,81 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that simply displays an image.
|
||||
|
||||
Use setImage to give it an image, and it'll display it - simple as that!
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ImageComponent : public Component,
|
||||
public SettableTooltipClient
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an ImageComponent. */
|
||||
ImageComponent (const String& componentName = String());
|
||||
|
||||
/** Destructor. */
|
||||
~ImageComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the image that should be displayed. */
|
||||
void setImage (const Image& newImage);
|
||||
|
||||
/** Sets the image that should be displayed, and its placement within the component. */
|
||||
void setImage (const Image& newImage,
|
||||
RectanglePlacement placementToUse);
|
||||
|
||||
/** Returns the current image. */
|
||||
const Image& getImage() const;
|
||||
|
||||
/** Sets the method of positioning that will be used to fit the image within the component's bounds.
|
||||
By default the positioning is centred, and will fit the image inside the component's bounds
|
||||
whilst keeping its aspect ratio correct, but you can change it to whatever layout you need.
|
||||
*/
|
||||
void setImagePlacement (RectanglePlacement newPlacement);
|
||||
|
||||
/** Returns the current image placement. */
|
||||
RectanglePlacement getImagePlacement() const;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
|
||||
Image image;
|
||||
RectanglePlacement placement;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that simply displays an image.
|
||||
|
||||
Use setImage to give it an image, and it'll display it - simple as that!
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ImageComponent : public Component,
|
||||
public SettableTooltipClient
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an ImageComponent. */
|
||||
ImageComponent (const String& componentName = String());
|
||||
|
||||
/** Destructor. */
|
||||
~ImageComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the image that should be displayed. */
|
||||
void setImage (const Image& newImage);
|
||||
|
||||
/** Sets the image that should be displayed, and its placement within the component. */
|
||||
void setImage (const Image& newImage,
|
||||
RectanglePlacement placementToUse);
|
||||
|
||||
/** Returns the current image. */
|
||||
const Image& getImage() const;
|
||||
|
||||
/** Sets the method of positioning that will be used to fit the image within the component's bounds.
|
||||
By default the positioning is centred, and will fit the image inside the component's bounds
|
||||
whilst keeping its aspect ratio correct, but you can change it to whatever layout you need.
|
||||
*/
|
||||
void setImagePlacement (RectanglePlacement newPlacement);
|
||||
|
||||
/** Returns the current image placement. */
|
||||
RectanglePlacement getImagePlacement() const;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
|
||||
Image image;
|
||||
RectanglePlacement placement;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
1169
deps/juce/modules/juce_gui_basics/widgets/juce_Label.cpp
vendored
1169
deps/juce/modules/juce_gui_basics/widgets/juce_Label.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,366 +1,366 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that displays a text string, and can optionally become a text
|
||||
editor when clicked.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API Label : public Component,
|
||||
public SettableTooltipClient,
|
||||
protected TextEditor::Listener,
|
||||
private ComponentListener,
|
||||
private Value::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a Label.
|
||||
|
||||
@param componentName the name to give the component
|
||||
@param labelText the text to show in the label
|
||||
*/
|
||||
Label (const String& componentName = String(),
|
||||
const String& labelText = String());
|
||||
|
||||
/** Destructor. */
|
||||
~Label() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the label text.
|
||||
|
||||
The NotificationType parameter indicates whether to send a change message to
|
||||
any Label::Listener objects if the new text is different.
|
||||
*/
|
||||
void setText (const String& newText,
|
||||
NotificationType notification);
|
||||
|
||||
/** Returns the label's current text.
|
||||
|
||||
@param returnActiveEditorContents if this is true and the label is currently
|
||||
being edited, then this method will return the
|
||||
text as it's being shown in the editor. If false,
|
||||
then the value returned here won't be updated until
|
||||
the user has finished typing and pressed the return
|
||||
key.
|
||||
*/
|
||||
String getText (bool returnActiveEditorContents = false) const;
|
||||
|
||||
/** Returns the text content as a Value object.
|
||||
You can call Value::referTo() on this object to make the label read and control
|
||||
a Value object that you supply.
|
||||
*/
|
||||
Value& getTextValue() noexcept { return textValue; }
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the font to use to draw the text.
|
||||
@see getFont
|
||||
*/
|
||||
void setFont (const Font& newFont);
|
||||
|
||||
/** Returns the font currently being used.
|
||||
This may be the one set by setFont(), unless it has been overridden by the current LookAndFeel
|
||||
@see setFont
|
||||
*/
|
||||
Font getFont() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
Note that you can also use the constants from TextEditor::ColourIds to change the
|
||||
colour of the text editor that is opened when a label is editable.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */
|
||||
textColourId = 0x1000281, /**< The colour for the text. */
|
||||
outlineColourId = 0x1000282, /**< An optional colour to use to draw a border around the label.
|
||||
Leave this transparent to not have an outline. */
|
||||
backgroundWhenEditingColourId = 0x1000283, /**< The background colour when the label is being edited. */
|
||||
textWhenEditingColourId = 0x1000284, /**< The colour for the text when the label is being edited. */
|
||||
outlineWhenEditingColourId = 0x1000285 /**< An optional border colour when the label is being edited. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the style of justification to be used for positioning the text.
|
||||
(The default is Justification::centredLeft)
|
||||
*/
|
||||
void setJustificationType (Justification justification);
|
||||
|
||||
/** Returns the type of justification, as set in setJustificationType(). */
|
||||
Justification getJustificationType() const noexcept { return justification; }
|
||||
|
||||
/** Changes the border that is left between the edge of the component and the text.
|
||||
By default there's a small gap left at the sides of the component to allow for
|
||||
the drawing of the border, but you can change this if necessary.
|
||||
*/
|
||||
void setBorderSize (BorderSize<int> newBorderSize);
|
||||
|
||||
/** Returns the size of the border to be left around the text. */
|
||||
BorderSize<int> getBorderSize() const noexcept { return border; }
|
||||
|
||||
/** Makes this label "stick to" another component.
|
||||
|
||||
This will cause the label to follow another component around, staying
|
||||
either to its left or above it.
|
||||
|
||||
@param owner the component to follow
|
||||
@param onLeft if true, the label will stay on the left of its component; if
|
||||
false, it will stay above it.
|
||||
*/
|
||||
void attachToComponent (Component* owner, bool onLeft);
|
||||
|
||||
/** If this label has been attached to another component using attachToComponent, this
|
||||
returns the other component.
|
||||
|
||||
Returns nullptr if the label is not attached.
|
||||
*/
|
||||
Component* getAttachedComponent() const;
|
||||
|
||||
/** If the label is attached to the left of another component, this returns true.
|
||||
|
||||
Returns false if the label is above the other component. This is only relevant if
|
||||
attachToComponent() has been called.
|
||||
*/
|
||||
bool isAttachedOnLeft() const noexcept { return leftOfOwnerComp; }
|
||||
|
||||
/** Specifies the minimum amount that the font can be squashed horizontally before it starts
|
||||
using ellipsis. Use a value of 0 for a default value.
|
||||
|
||||
@see Graphics::drawFittedText
|
||||
*/
|
||||
void setMinimumHorizontalScale (float newScale);
|
||||
|
||||
/** Specifies the amount that the font can be squashed horizontally. */
|
||||
float getMinimumHorizontalScale() const noexcept { return minimumHorizontalScale; }
|
||||
|
||||
/** Set a keyboard type for use when the text editor is shown. */
|
||||
void setKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { keyboardType = type; }
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for receiving events from a Label.
|
||||
|
||||
You can register a Label::Listener with a Label using the Label::addListener()
|
||||
method, and it will be called when the text of the label changes, either because
|
||||
of a call to Label::setText() or by the user editing the text (if the label is
|
||||
editable).
|
||||
|
||||
@see Label::addListener, Label::removeListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Called when a Label's text has changed. */
|
||||
virtual void labelTextChanged (Label* labelThatHasChanged) = 0;
|
||||
|
||||
/** Called when a Label goes into editing mode and displays a TextEditor. */
|
||||
virtual void editorShown (Label*, TextEditor&) {}
|
||||
|
||||
/** Called when a Label is about to delete its TextEditor and exit editing mode. */
|
||||
virtual void editorHidden (Label*, TextEditor&) {}
|
||||
};
|
||||
|
||||
/** Registers a listener that will be called when the label's text changes. */
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a previously-registered listener. */
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** You can assign a lambda to this callback object to have it called when the label text is changed. */
|
||||
std::function<void()> onTextChange;
|
||||
|
||||
/** You can assign a lambda to this callback object to have it called when the label's editor is shown. */
|
||||
std::function<void()> onEditorShow;
|
||||
|
||||
/** You can assign a lambda to this callback object to have it called when the label's editor is hidden. */
|
||||
std::function<void()> onEditorHide;
|
||||
|
||||
//==============================================================================
|
||||
/** Makes the label turn into a TextEditor when clicked.
|
||||
|
||||
By default this is turned off.
|
||||
|
||||
If turned on, then single- or double-clicking will turn the label into
|
||||
an editor. If the user then changes the text, then the ChangeBroadcaster
|
||||
base class will be used to send change messages to any listeners that
|
||||
have registered.
|
||||
|
||||
If the user changes the text, the textWasEdited() method will be called
|
||||
afterwards, and subclasses can override this if they need to do anything
|
||||
special.
|
||||
|
||||
@param editOnSingleClick if true, just clicking once on the label will start editing the text
|
||||
@param editOnDoubleClick if true, a double-click is needed to start editing
|
||||
@param lossOfFocusDiscardsChanges if true, clicking somewhere else while the text is being
|
||||
edited will discard any changes; if false, then this will
|
||||
commit the changes.
|
||||
@see showEditor, setEditorColours, TextEditor
|
||||
*/
|
||||
void setEditable (bool editOnSingleClick,
|
||||
bool editOnDoubleClick = false,
|
||||
bool lossOfFocusDiscardsChanges = false);
|
||||
|
||||
/** Returns true if this option was set using setEditable(). */
|
||||
bool isEditableOnSingleClick() const noexcept { return editSingleClick; }
|
||||
|
||||
/** Returns true if this option was set using setEditable(). */
|
||||
bool isEditableOnDoubleClick() const noexcept { return editDoubleClick; }
|
||||
|
||||
/** Returns true if this option has been set in a call to setEditable(). */
|
||||
bool doesLossOfFocusDiscardChanges() const noexcept { return lossOfFocusDiscardsChanges; }
|
||||
|
||||
/** Returns true if the user can edit this label's text. */
|
||||
bool isEditable() const noexcept { return editSingleClick || editDoubleClick; }
|
||||
|
||||
/** Makes the editor appear as if the label had been clicked by the user.
|
||||
@see textWasEdited, setEditable
|
||||
*/
|
||||
void showEditor();
|
||||
|
||||
/** Hides the editor if it was being shown.
|
||||
|
||||
@param discardCurrentEditorContents if true, the label's text will be
|
||||
reset to whatever it was before the editor
|
||||
was shown; if false, the current contents of the
|
||||
editor will be used to set the label's text
|
||||
before it is hidden.
|
||||
*/
|
||||
void hideEditor (bool discardCurrentEditorContents);
|
||||
|
||||
/** Returns true if the editor is currently focused and active. */
|
||||
bool isBeingEdited() const noexcept;
|
||||
|
||||
/** Returns the currently-visible text editor, or nullptr if none is open. */
|
||||
TextEditor* getCurrentTextEditor() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes to provide
|
||||
label drawing functionality.
|
||||
*/
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawLabel (Graphics&, Label&) = 0;
|
||||
virtual Font getLabelFont (Label&) = 0;
|
||||
virtual BorderSize<int> getLabelBorderSize (Label&) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the TextEditor component that will be used when the user has clicked on the label.
|
||||
Subclasses can override this if they need to customise this component in some way.
|
||||
*/
|
||||
virtual TextEditor* createEditorComponent();
|
||||
|
||||
/** Called after the user changes the text. */
|
||||
virtual void textWasEdited();
|
||||
|
||||
/** Called when the text has been altered. */
|
||||
virtual void textWasChanged();
|
||||
|
||||
/** Called when the text editor has just appeared, due to a user click or other focus change. */
|
||||
virtual void editorShown (TextEditor*);
|
||||
|
||||
/** Called when the text editor is going to be deleted, after editing has finished. */
|
||||
virtual void editorAboutToBeHidden (TextEditor*);
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
void mouseUp (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseDoubleClick (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
|
||||
/** @internal */
|
||||
void componentParentHierarchyChanged (Component&) override;
|
||||
/** @internal */
|
||||
void componentVisibilityChanged (Component&) override;
|
||||
/** @internal */
|
||||
void inputAttemptWhenModal() override;
|
||||
/** @internal */
|
||||
void focusGained (FocusChangeType) override;
|
||||
/** @internal */
|
||||
void enablementChanged() override;
|
||||
/** @internal */
|
||||
std::unique_ptr<ComponentTraverser> createKeyboardFocusTraverser() override;
|
||||
/** @internal */
|
||||
void textEditorTextChanged (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorReturnKeyPressed (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorEscapeKeyPressed (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorFocusLost (TextEditor&) override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
/** @internal */
|
||||
void valueChanged (Value&) override;
|
||||
/** @internal */
|
||||
void callChangeListeners();
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Value textValue;
|
||||
String lastTextValue;
|
||||
Font font { 15.0f };
|
||||
Justification justification = Justification::centredLeft;
|
||||
std::unique_ptr<TextEditor> editor;
|
||||
ListenerList<Listener> listeners;
|
||||
WeakReference<Component> ownerComponent;
|
||||
BorderSize<int> border { 1, 5, 1, 5 };
|
||||
float minimumHorizontalScale = 0;
|
||||
TextInputTarget::VirtualKeyboardType keyboardType = TextInputTarget::textKeyboard;
|
||||
bool editSingleClick = false;
|
||||
bool editDoubleClick = false;
|
||||
bool lossOfFocusDiscardsChanges = false;
|
||||
bool leftOfOwnerComp = false;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
bool updateFromTextEditorContents (TextEditor&);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Label)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that displays a text string, and can optionally become a text
|
||||
editor when clicked.
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API Label : public Component,
|
||||
public SettableTooltipClient,
|
||||
protected TextEditor::Listener,
|
||||
private ComponentListener,
|
||||
private Value::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a Label.
|
||||
|
||||
@param componentName the name to give the component
|
||||
@param labelText the text to show in the label
|
||||
*/
|
||||
Label (const String& componentName = String(),
|
||||
const String& labelText = String());
|
||||
|
||||
/** Destructor. */
|
||||
~Label() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the label text.
|
||||
|
||||
The NotificationType parameter indicates whether to send a change message to
|
||||
any Label::Listener objects if the new text is different.
|
||||
*/
|
||||
void setText (const String& newText,
|
||||
NotificationType notification);
|
||||
|
||||
/** Returns the label's current text.
|
||||
|
||||
@param returnActiveEditorContents if this is true and the label is currently
|
||||
being edited, then this method will return the
|
||||
text as it's being shown in the editor. If false,
|
||||
then the value returned here won't be updated until
|
||||
the user has finished typing and pressed the return
|
||||
key.
|
||||
*/
|
||||
String getText (bool returnActiveEditorContents = false) const;
|
||||
|
||||
/** Returns the text content as a Value object.
|
||||
You can call Value::referTo() on this object to make the label read and control
|
||||
a Value object that you supply.
|
||||
*/
|
||||
Value& getTextValue() noexcept { return textValue; }
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the font to use to draw the text.
|
||||
@see getFont
|
||||
*/
|
||||
void setFont (const Font& newFont);
|
||||
|
||||
/** Returns the font currently being used.
|
||||
This may be the one set by setFont(), unless it has been overridden by the current LookAndFeel
|
||||
@see setFont
|
||||
*/
|
||||
Font getFont() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
Note that you can also use the constants from TextEditor::ColourIds to change the
|
||||
colour of the text editor that is opened when a label is editable.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */
|
||||
textColourId = 0x1000281, /**< The colour for the text. */
|
||||
outlineColourId = 0x1000282, /**< An optional colour to use to draw a border around the label.
|
||||
Leave this transparent to not have an outline. */
|
||||
backgroundWhenEditingColourId = 0x1000283, /**< The background colour when the label is being edited. */
|
||||
textWhenEditingColourId = 0x1000284, /**< The colour for the text when the label is being edited. */
|
||||
outlineWhenEditingColourId = 0x1000285 /**< An optional border colour when the label is being edited. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Sets the style of justification to be used for positioning the text.
|
||||
(The default is Justification::centredLeft)
|
||||
*/
|
||||
void setJustificationType (Justification justification);
|
||||
|
||||
/** Returns the type of justification, as set in setJustificationType(). */
|
||||
Justification getJustificationType() const noexcept { return justification; }
|
||||
|
||||
/** Changes the border that is left between the edge of the component and the text.
|
||||
By default there's a small gap left at the sides of the component to allow for
|
||||
the drawing of the border, but you can change this if necessary.
|
||||
*/
|
||||
void setBorderSize (BorderSize<int> newBorderSize);
|
||||
|
||||
/** Returns the size of the border to be left around the text. */
|
||||
BorderSize<int> getBorderSize() const noexcept { return border; }
|
||||
|
||||
/** Makes this label "stick to" another component.
|
||||
|
||||
This will cause the label to follow another component around, staying
|
||||
either to its left or above it.
|
||||
|
||||
@param owner the component to follow
|
||||
@param onLeft if true, the label will stay on the left of its component; if
|
||||
false, it will stay above it.
|
||||
*/
|
||||
void attachToComponent (Component* owner, bool onLeft);
|
||||
|
||||
/** If this label has been attached to another component using attachToComponent, this
|
||||
returns the other component.
|
||||
|
||||
Returns nullptr if the label is not attached.
|
||||
*/
|
||||
Component* getAttachedComponent() const;
|
||||
|
||||
/** If the label is attached to the left of another component, this returns true.
|
||||
|
||||
Returns false if the label is above the other component. This is only relevant if
|
||||
attachToComponent() has been called.
|
||||
*/
|
||||
bool isAttachedOnLeft() const noexcept { return leftOfOwnerComp; }
|
||||
|
||||
/** Specifies the minimum amount that the font can be squashed horizontally before it starts
|
||||
using ellipsis. Use a value of 0 for a default value.
|
||||
|
||||
@see Graphics::drawFittedText
|
||||
*/
|
||||
void setMinimumHorizontalScale (float newScale);
|
||||
|
||||
/** Specifies the amount that the font can be squashed horizontally. */
|
||||
float getMinimumHorizontalScale() const noexcept { return minimumHorizontalScale; }
|
||||
|
||||
/** Set a keyboard type for use when the text editor is shown. */
|
||||
void setKeyboardType (TextInputTarget::VirtualKeyboardType type) noexcept { keyboardType = type; }
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A class for receiving events from a Label.
|
||||
|
||||
You can register a Label::Listener with a Label using the Label::addListener()
|
||||
method, and it will be called when the text of the label changes, either because
|
||||
of a call to Label::setText() or by the user editing the text (if the label is
|
||||
editable).
|
||||
|
||||
@see Label::addListener, Label::removeListener
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Called when a Label's text has changed. */
|
||||
virtual void labelTextChanged (Label* labelThatHasChanged) = 0;
|
||||
|
||||
/** Called when a Label goes into editing mode and displays a TextEditor. */
|
||||
virtual void editorShown (Label*, TextEditor&) {}
|
||||
|
||||
/** Called when a Label is about to delete its TextEditor and exit editing mode. */
|
||||
virtual void editorHidden (Label*, TextEditor&) {}
|
||||
};
|
||||
|
||||
/** Registers a listener that will be called when the label's text changes. */
|
||||
void addListener (Listener* listener);
|
||||
|
||||
/** Deregisters a previously-registered listener. */
|
||||
void removeListener (Listener* listener);
|
||||
|
||||
//==============================================================================
|
||||
/** You can assign a lambda to this callback object to have it called when the label text is changed. */
|
||||
std::function<void()> onTextChange;
|
||||
|
||||
/** You can assign a lambda to this callback object to have it called when the label's editor is shown. */
|
||||
std::function<void()> onEditorShow;
|
||||
|
||||
/** You can assign a lambda to this callback object to have it called when the label's editor is hidden. */
|
||||
std::function<void()> onEditorHide;
|
||||
|
||||
//==============================================================================
|
||||
/** Makes the label turn into a TextEditor when clicked.
|
||||
|
||||
By default this is turned off.
|
||||
|
||||
If turned on, then single- or double-clicking will turn the label into
|
||||
an editor. If the user then changes the text, then the ChangeBroadcaster
|
||||
base class will be used to send change messages to any listeners that
|
||||
have registered.
|
||||
|
||||
If the user changes the text, the textWasEdited() method will be called
|
||||
afterwards, and subclasses can override this if they need to do anything
|
||||
special.
|
||||
|
||||
@param editOnSingleClick if true, just clicking once on the label will start editing the text
|
||||
@param editOnDoubleClick if true, a double-click is needed to start editing
|
||||
@param lossOfFocusDiscardsChanges if true, clicking somewhere else while the text is being
|
||||
edited will discard any changes; if false, then this will
|
||||
commit the changes.
|
||||
@see showEditor, setEditorColours, TextEditor
|
||||
*/
|
||||
void setEditable (bool editOnSingleClick,
|
||||
bool editOnDoubleClick = false,
|
||||
bool lossOfFocusDiscardsChanges = false);
|
||||
|
||||
/** Returns true if this option was set using setEditable(). */
|
||||
bool isEditableOnSingleClick() const noexcept { return editSingleClick; }
|
||||
|
||||
/** Returns true if this option was set using setEditable(). */
|
||||
bool isEditableOnDoubleClick() const noexcept { return editDoubleClick; }
|
||||
|
||||
/** Returns true if this option has been set in a call to setEditable(). */
|
||||
bool doesLossOfFocusDiscardChanges() const noexcept { return lossOfFocusDiscardsChanges; }
|
||||
|
||||
/** Returns true if the user can edit this label's text. */
|
||||
bool isEditable() const noexcept { return editSingleClick || editDoubleClick; }
|
||||
|
||||
/** Makes the editor appear as if the label had been clicked by the user.
|
||||
@see textWasEdited, setEditable
|
||||
*/
|
||||
void showEditor();
|
||||
|
||||
/** Hides the editor if it was being shown.
|
||||
|
||||
@param discardCurrentEditorContents if true, the label's text will be
|
||||
reset to whatever it was before the editor
|
||||
was shown; if false, the current contents of the
|
||||
editor will be used to set the label's text
|
||||
before it is hidden.
|
||||
*/
|
||||
void hideEditor (bool discardCurrentEditorContents);
|
||||
|
||||
/** Returns true if the editor is currently focused and active. */
|
||||
bool isBeingEdited() const noexcept;
|
||||
|
||||
/** Returns the currently-visible text editor, or nullptr if none is open. */
|
||||
TextEditor* getCurrentTextEditor() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes to provide
|
||||
label drawing functionality.
|
||||
*/
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawLabel (Graphics&, Label&) = 0;
|
||||
virtual Font getLabelFont (Label&) = 0;
|
||||
virtual BorderSize<int> getLabelBorderSize (Label&) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** Creates the TextEditor component that will be used when the user has clicked on the label.
|
||||
Subclasses can override this if they need to customise this component in some way.
|
||||
*/
|
||||
virtual TextEditor* createEditorComponent();
|
||||
|
||||
/** Called after the user changes the text. */
|
||||
virtual void textWasEdited();
|
||||
|
||||
/** Called when the text has been altered. */
|
||||
virtual void textWasChanged();
|
||||
|
||||
/** Called when the text editor has just appeared, due to a user click or other focus change. */
|
||||
virtual void editorShown (TextEditor*);
|
||||
|
||||
/** Called when the text editor is going to be deleted, after editing has finished. */
|
||||
virtual void editorAboutToBeHidden (TextEditor*);
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
void mouseUp (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void mouseDoubleClick (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
|
||||
/** @internal */
|
||||
void componentParentHierarchyChanged (Component&) override;
|
||||
/** @internal */
|
||||
void componentVisibilityChanged (Component&) override;
|
||||
/** @internal */
|
||||
void inputAttemptWhenModal() override;
|
||||
/** @internal */
|
||||
void focusGained (FocusChangeType) override;
|
||||
/** @internal */
|
||||
void enablementChanged() override;
|
||||
/** @internal */
|
||||
std::unique_ptr<ComponentTraverser> createKeyboardFocusTraverser() override;
|
||||
/** @internal */
|
||||
void textEditorTextChanged (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorReturnKeyPressed (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorEscapeKeyPressed (TextEditor&) override;
|
||||
/** @internal */
|
||||
void textEditorFocusLost (TextEditor&) override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
/** @internal */
|
||||
void valueChanged (Value&) override;
|
||||
/** @internal */
|
||||
void callChangeListeners();
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Value textValue;
|
||||
String lastTextValue;
|
||||
Font font { 15.0f };
|
||||
Justification justification = Justification::centredLeft;
|
||||
std::unique_ptr<TextEditor> editor;
|
||||
ListenerList<Listener> listeners;
|
||||
WeakReference<Component> ownerComponent;
|
||||
BorderSize<int> border { 1, 5, 1, 5 };
|
||||
float minimumHorizontalScale = 0;
|
||||
TextInputTarget::VirtualKeyboardType keyboardType = TextInputTarget::textKeyboard;
|
||||
bool editSingleClick = false;
|
||||
bool editDoubleClick = false;
|
||||
bool lossOfFocusDiscardsChanges = false;
|
||||
bool leftOfOwnerComp = false;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
bool updateFromTextEditorContents (TextEditor&);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Label)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,60 +0,0 @@
|
||||
diff a/modules/juce_gui_basics/widgets/juce_ListBox.cpp b/modules/juce_gui_basics/widgets/juce_ListBox.cpp (rejected hunks)
|
||||
@@ -63,12 +63,15 @@ public:
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
+ DBG("Listbox row mousedown");
|
||||
isDragging = false;
|
||||
selectRowOnMouseUp = false;
|
||||
|
||||
+ owner.stopInertialScroll();
|
||||
+
|
||||
if (isEnabled())
|
||||
{
|
||||
- if (owner.selectOnMouseDown && ! selected)
|
||||
+ if (! selected && owner.selectOnMouseDown && !owner.getTouchScrollEnabled())
|
||||
{
|
||||
owner.selectRowsBasedOnModifierKeys (row, e.mods, false);
|
||||
|
||||
@@ -84,7 +87,16 @@ public:
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
{
|
||||
- if (isEnabled() && selectRowOnMouseUp && ! isDragging)
|
||||
+ bool wasTouchScrolling = false;
|
||||
+ if (owner.isTouchScrollActive()) {
|
||||
+ wasTouchScrolling = true;
|
||||
+ if (owner.getTouchScrollInertia() > 0.0f) {
|
||||
+ owner.startInertialScroll();
|
||||
+ }
|
||||
+ owner.touchScrollDone();
|
||||
+ }
|
||||
+
|
||||
+ if (isEnabled() && !wasTouchScrolling && selectRowOnMouseUp && !isDragging)
|
||||
{
|
||||
owner.selectRowsBasedOnModifierKeys (row, e.mods, true);
|
||||
|
||||
@@ -102,9 +114,10 @@ public:
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
+ bool touchdrag = owner.touchScrollDrag(e);
|
||||
if (ListBoxModel* m = owner.getModel())
|
||||
{
|
||||
- if (isEnabled() && e.mouseWasDraggedSinceMouseDown() && ! isDragging)
|
||||
+ if (!touchdrag && isEnabled() && e.mouseWasDraggedSinceMouseDown() && ! isDragging)
|
||||
{
|
||||
SparseSet<int> rowsToDrag;
|
||||
|
||||
@@ -367,6 +380,11 @@ private:
|
||||
//==============================================================================
|
||||
ListBox::ListBox (const String& name, ListBoxModel* const m)
|
||||
: Component (name),
|
||||
+ touchScrollEnabled(false),
|
||||
+ touchScrolling(false),
|
||||
+ scrollRate(0.0f),
|
||||
+ touchScrollInertia(0.25f),
|
||||
+ touchScrollScale(1.0f),
|
||||
model (m),
|
||||
totalItems (0),
|
||||
rowHeight (22),
|
1248
deps/juce/modules/juce_gui_basics/widgets/juce_ListBox.h
vendored
1248
deps/juce/modules/juce_gui_basics/widgets/juce_ListBox.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,172 +1,167 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ProgressBar::ProgressBar (double& progress_)
|
||||
: progress (progress_),
|
||||
displayPercentage (true),
|
||||
lastCallbackTime (0)
|
||||
{
|
||||
currentValue = jlimit (0.0, 1.0, progress);
|
||||
}
|
||||
|
||||
ProgressBar::~ProgressBar()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ProgressBar::setPercentageDisplay (const bool shouldDisplayPercentage)
|
||||
{
|
||||
displayPercentage = shouldDisplayPercentage;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void ProgressBar::setTextToDisplay (const String& text)
|
||||
{
|
||||
displayPercentage = false;
|
||||
displayedMessage = text;
|
||||
}
|
||||
|
||||
void ProgressBar::lookAndFeelChanged()
|
||||
{
|
||||
setOpaque (getLookAndFeel().isProgressBarOpaque (*this));
|
||||
}
|
||||
|
||||
void ProgressBar::colourChanged()
|
||||
{
|
||||
lookAndFeelChanged();
|
||||
}
|
||||
|
||||
void ProgressBar::paint (Graphics& g)
|
||||
{
|
||||
String text;
|
||||
|
||||
if (displayPercentage)
|
||||
{
|
||||
if (currentValue >= 0 && currentValue <= 1.0)
|
||||
text << roundToInt (currentValue * 100.0) << '%';
|
||||
}
|
||||
else
|
||||
{
|
||||
text = displayedMessage;
|
||||
}
|
||||
|
||||
getLookAndFeel().drawProgressBar (g, *this,
|
||||
getWidth(), getHeight(),
|
||||
currentValue, text);
|
||||
}
|
||||
|
||||
void ProgressBar::visibilityChanged()
|
||||
{
|
||||
if (isVisible()) {
|
||||
lastCallbackTime = Time::getMillisecondCounter();
|
||||
currentValue = progress;
|
||||
currentMessage = displayedMessage;
|
||||
startTimer (30);
|
||||
}
|
||||
else {
|
||||
stopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::timerCallback()
|
||||
{
|
||||
double newProgress = progress;
|
||||
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
const int timeSinceLastCallback = (int) (now - lastCallbackTime);
|
||||
lastCallbackTime = now;
|
||||
|
||||
if (currentValue != newProgress
|
||||
|| newProgress < 0 || newProgress >= 1.0
|
||||
|| currentMessage != displayedMessage)
|
||||
{
|
||||
if (currentValue < newProgress
|
||||
&& newProgress >= 0 && newProgress < 1.0
|
||||
&& currentValue >= 0 && currentValue < 1.0)
|
||||
{
|
||||
newProgress = jmin (currentValue + 0.004 * timeSinceLastCallback,
|
||||
newProgress);
|
||||
}
|
||||
|
||||
currentValue = newProgress;
|
||||
currentMessage = displayedMessage;
|
||||
repaint();
|
||||
|
||||
if (auto* handler = getAccessibilityHandler())
|
||||
handler->notifyAccessibilityEvent (AccessibilityEvent::valueChanged);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ProgressBar::createAccessibilityHandler()
|
||||
{
|
||||
class ProgressBarAccessibilityHandler : public AccessibilityHandler
|
||||
{
|
||||
public:
|
||||
explicit ProgressBarAccessibilityHandler (ProgressBar& progressBarToWrap)
|
||||
: AccessibilityHandler (progressBarToWrap,
|
||||
AccessibilityRole::progressBar,
|
||||
AccessibilityActions{},
|
||||
AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (progressBarToWrap) }),
|
||||
progressBar (progressBarToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
String getHelp() const override { return progressBar.getTooltip(); }
|
||||
|
||||
private:
|
||||
class ValueInterface : public AccessibilityRangedNumericValueInterface
|
||||
{
|
||||
public:
|
||||
explicit ValueInterface (ProgressBar& progressBarToWrap)
|
||||
: progressBar (progressBarToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
bool isReadOnly() const override { return true; }
|
||||
void setValue (double) override { jassertfalse; }
|
||||
double getCurrentValue() const override { return progressBar.progress; }
|
||||
AccessibleValueRange getRange() const override { return { { 0.0, 1.0 }, 0.001 }; }
|
||||
|
||||
private:
|
||||
ProgressBar& progressBar;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface)
|
||||
};
|
||||
|
||||
ProgressBar& progressBar;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgressBarAccessibilityHandler)
|
||||
};
|
||||
|
||||
return std::make_unique<ProgressBarAccessibilityHandler> (*this);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ProgressBar::ProgressBar (double& progress_)
|
||||
: progress (progress_),
|
||||
displayPercentage (true),
|
||||
lastCallbackTime (0)
|
||||
{
|
||||
currentValue = jlimit (0.0, 1.0, progress);
|
||||
}
|
||||
|
||||
ProgressBar::~ProgressBar()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ProgressBar::setPercentageDisplay (const bool shouldDisplayPercentage)
|
||||
{
|
||||
displayPercentage = shouldDisplayPercentage;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void ProgressBar::setTextToDisplay (const String& text)
|
||||
{
|
||||
displayPercentage = false;
|
||||
displayedMessage = text;
|
||||
}
|
||||
|
||||
void ProgressBar::lookAndFeelChanged()
|
||||
{
|
||||
setOpaque (getLookAndFeel().isProgressBarOpaque (*this));
|
||||
}
|
||||
|
||||
void ProgressBar::colourChanged()
|
||||
{
|
||||
lookAndFeelChanged();
|
||||
}
|
||||
|
||||
void ProgressBar::paint (Graphics& g)
|
||||
{
|
||||
String text;
|
||||
|
||||
if (displayPercentage)
|
||||
{
|
||||
if (currentValue >= 0 && currentValue <= 1.0)
|
||||
text << roundToInt (currentValue * 100.0) << '%';
|
||||
}
|
||||
else
|
||||
{
|
||||
text = displayedMessage;
|
||||
}
|
||||
|
||||
getLookAndFeel().drawProgressBar (g, *this,
|
||||
getWidth(), getHeight(),
|
||||
currentValue, text);
|
||||
}
|
||||
|
||||
void ProgressBar::visibilityChanged()
|
||||
{
|
||||
if (isVisible())
|
||||
startTimer (30);
|
||||
else
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
void ProgressBar::timerCallback()
|
||||
{
|
||||
double newProgress = progress;
|
||||
|
||||
const uint32 now = Time::getMillisecondCounter();
|
||||
const int timeSinceLastCallback = (int) (now - lastCallbackTime);
|
||||
lastCallbackTime = now;
|
||||
|
||||
if (currentValue != newProgress
|
||||
|| newProgress < 0 || newProgress >= 1.0
|
||||
|| currentMessage != displayedMessage)
|
||||
{
|
||||
if (currentValue < newProgress
|
||||
&& newProgress >= 0 && newProgress < 1.0
|
||||
&& currentValue >= 0 && currentValue < 1.0)
|
||||
{
|
||||
newProgress = jmin (currentValue + 0.0008 * timeSinceLastCallback,
|
||||
newProgress);
|
||||
}
|
||||
|
||||
currentValue = newProgress;
|
||||
currentMessage = displayedMessage;
|
||||
repaint();
|
||||
|
||||
if (auto* handler = getAccessibilityHandler())
|
||||
handler->notifyAccessibilityEvent (AccessibilityEvent::valueChanged);
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ProgressBar::createAccessibilityHandler()
|
||||
{
|
||||
class ProgressBarAccessibilityHandler : public AccessibilityHandler
|
||||
{
|
||||
public:
|
||||
explicit ProgressBarAccessibilityHandler (ProgressBar& progressBarToWrap)
|
||||
: AccessibilityHandler (progressBarToWrap,
|
||||
AccessibilityRole::progressBar,
|
||||
AccessibilityActions{},
|
||||
AccessibilityHandler::Interfaces { std::make_unique<ValueInterface> (progressBarToWrap) }),
|
||||
progressBar (progressBarToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
String getHelp() const override { return progressBar.getTooltip(); }
|
||||
|
||||
private:
|
||||
class ValueInterface : public AccessibilityRangedNumericValueInterface
|
||||
{
|
||||
public:
|
||||
explicit ValueInterface (ProgressBar& progressBarToWrap)
|
||||
: progressBar (progressBarToWrap)
|
||||
{
|
||||
}
|
||||
|
||||
bool isReadOnly() const override { return true; }
|
||||
void setValue (double) override { jassertfalse; }
|
||||
double getCurrentValue() const override { return progressBar.progress; }
|
||||
AccessibleValueRange getRange() const override { return { { 0.0, 1.0 }, 0.001 }; }
|
||||
|
||||
private:
|
||||
ProgressBar& progressBar;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueInterface)
|
||||
};
|
||||
|
||||
ProgressBar& progressBar;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgressBarAccessibilityHandler)
|
||||
};
|
||||
|
||||
return std::make_unique<ProgressBarAccessibilityHandler> (*this);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,144 +1,144 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A progress bar component.
|
||||
|
||||
To use this, just create one and make it visible. It'll run its own timer
|
||||
to keep an eye on a variable that you give it, and will automatically
|
||||
redraw itself when the variable changes.
|
||||
|
||||
If using LookAndFeel_V4 a circular spinning progress bar will be drawn if
|
||||
the width and height of the ProgressBar are equal, otherwise the standard,
|
||||
linear ProgressBar will be drawn.
|
||||
|
||||
For an easy way of running a background task with a dialog box showing its
|
||||
progress, see the ThreadWithProgressWindow class.
|
||||
|
||||
@see ThreadWithProgressWindow
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ProgressBar : public Component,
|
||||
public SettableTooltipClient,
|
||||
private Timer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a ProgressBar.
|
||||
|
||||
@param progress pass in a reference to a double that you're going to
|
||||
update with your task's progress. The ProgressBar will
|
||||
monitor the value of this variable and will redraw itself
|
||||
when the value changes. The range is from 0 to 1.0 and JUCE
|
||||
LookAndFeel classes will draw a spinning animation for values
|
||||
outside this range. Obviously you'd better be careful not to
|
||||
delete this variable while the ProgressBar still exists!
|
||||
*/
|
||||
explicit ProgressBar (double& progress);
|
||||
|
||||
/** Destructor. */
|
||||
~ProgressBar() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Turns the percentage display on or off.
|
||||
|
||||
By default this is on, and the progress bar will display a text string showing
|
||||
its current percentage.
|
||||
*/
|
||||
void setPercentageDisplay (bool shouldDisplayPercentage);
|
||||
|
||||
/** Gives the progress bar a string to display inside it.
|
||||
|
||||
If you call this, it will turn off the percentage display.
|
||||
@see setPercentageDisplay
|
||||
*/
|
||||
void setTextToDisplay (const String& text);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the bar.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1001900, /**< The background colour, behind the bar. */
|
||||
foregroundColourId = 0x1001a00, /**< The colour to use to draw the bar itself. LookAndFeel
|
||||
classes will probably use variations on this colour. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
/** Draws a progress bar.
|
||||
|
||||
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
|
||||
bar that fills the whole space (i.e. to say that the app is still busy but the progress
|
||||
isn't known). It can use the current time as a basis for playing an animation.
|
||||
|
||||
(Used by progress bars in AlertWindow).
|
||||
*/
|
||||
virtual void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
|
||||
double progress, const String& textToShow) = 0;
|
||||
|
||||
virtual bool isProgressBarOpaque (ProgressBar&) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void visibilityChanged() override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
|
||||
private:
|
||||
double& progress;
|
||||
double currentValue;
|
||||
bool displayPercentage;
|
||||
String displayedMessage, currentMessage;
|
||||
uint32 lastCallbackTime;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void timerCallback() override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgressBar)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A progress bar component.
|
||||
|
||||
To use this, just create one and make it visible. It'll run its own timer
|
||||
to keep an eye on a variable that you give it, and will automatically
|
||||
redraw itself when the variable changes.
|
||||
|
||||
If using LookAndFeel_V4 a circular spinning progress bar will be drawn if
|
||||
the width and height of the ProgressBar are equal, otherwise the standard,
|
||||
linear ProgressBar will be drawn.
|
||||
|
||||
For an easy way of running a background task with a dialog box showing its
|
||||
progress, see the ThreadWithProgressWindow class.
|
||||
|
||||
@see ThreadWithProgressWindow
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ProgressBar : public Component,
|
||||
public SettableTooltipClient,
|
||||
private Timer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a ProgressBar.
|
||||
|
||||
@param progress pass in a reference to a double that you're going to
|
||||
update with your task's progress. The ProgressBar will
|
||||
monitor the value of this variable and will redraw itself
|
||||
when the value changes. The range is from 0 to 1.0 and JUCE
|
||||
LookAndFeel classes will draw a spinning animation for values
|
||||
outside this range. Obviously you'd better be careful not to
|
||||
delete this variable while the ProgressBar still exists!
|
||||
*/
|
||||
explicit ProgressBar (double& progress);
|
||||
|
||||
/** Destructor. */
|
||||
~ProgressBar() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Turns the percentage display on or off.
|
||||
|
||||
By default this is on, and the progress bar will display a text string showing
|
||||
its current percentage.
|
||||
*/
|
||||
void setPercentageDisplay (bool shouldDisplayPercentage);
|
||||
|
||||
/** Gives the progress bar a string to display inside it.
|
||||
|
||||
If you call this, it will turn off the percentage display.
|
||||
@see setPercentageDisplay
|
||||
*/
|
||||
void setTextToDisplay (const String& text);
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the bar.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1001900, /**< The background colour, behind the bar. */
|
||||
foregroundColourId = 0x1001a00, /**< The colour to use to draw the bar itself. LookAndFeel
|
||||
classes will probably use variations on this colour. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
/** Draws a progress bar.
|
||||
|
||||
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
|
||||
bar that fills the whole space (i.e. to say that the app is still busy but the progress
|
||||
isn't known). It can use the current time as a basis for playing an animation.
|
||||
|
||||
(Used by progress bars in AlertWindow).
|
||||
*/
|
||||
virtual void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
|
||||
double progress, const String& textToShow) = 0;
|
||||
|
||||
virtual bool isProgressBarOpaque (ProgressBar&) = 0;
|
||||
};
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void visibilityChanged() override;
|
||||
/** @internal */
|
||||
void colourChanged() override;
|
||||
|
||||
private:
|
||||
double& progress;
|
||||
double currentValue;
|
||||
bool displayPercentage;
|
||||
String displayedMessage, currentMessage;
|
||||
uint32 lastCallbackTime;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void timerCallback() override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgressBar)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
2049
deps/juce/modules/juce_gui_basics/widgets/juce_Slider.h
vendored
2049
deps/juce/modules/juce_gui_basics/widgets/juce_Slider.h
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,459 +1,461 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that displays a strip of column headings for a table, and allows these
|
||||
to be resized, dragged around, etc.
|
||||
|
||||
This is just the component that goes at the top of a table. You can use it
|
||||
directly for custom components, or to create a simple table, use the
|
||||
TableListBox class.
|
||||
|
||||
To use one of these, create it and use addColumn() to add all the columns that you need.
|
||||
Each column must be given a unique ID number that's used to refer to it.
|
||||
|
||||
@see TableListBox, TableHeaderComponent::Listener
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableHeaderComponent : public Component,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty table header.
|
||||
*/
|
||||
TableHeaderComponent();
|
||||
|
||||
/** Destructor. */
|
||||
~TableHeaderComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** A combination of these flags are passed into the addColumn() method to specify
|
||||
the properties of a column.
|
||||
*/
|
||||
enum ColumnPropertyFlags
|
||||
{
|
||||
visible = 1, /**< If this is set, the column will be shown; if not, it will be hidden until the user enables it with the pop-up menu. */
|
||||
resizable = 2, /**< If this is set, the column can be resized by dragging it. */
|
||||
draggable = 4, /**< If this is set, the column can be dragged around to change its order in the table. */
|
||||
appearsOnColumnMenu = 8, /**< If this is set, the column will be shown on the pop-up menu allowing it to be hidden/shown. */
|
||||
sortable = 16, /**< If this is set, then clicking on the column header will set it to be the sort column, and clicking again will reverse the order. */
|
||||
sortedForwards = 32, /**< If this is set, the column is currently the one by which the table is sorted (forwards). */
|
||||
sortedBackwards = 64, /**< If this is set, the column is currently the one by which the table is sorted (backwards). */
|
||||
|
||||
/** This set of default flags is used as the default parameter value in addColumn(). */
|
||||
defaultFlags = (visible | resizable | draggable | appearsOnColumnMenu | sortable),
|
||||
|
||||
/** A quick way of combining flags for a column that's not resizable. */
|
||||
notResizable = (visible | draggable | appearsOnColumnMenu | sortable),
|
||||
|
||||
/** A quick way of combining flags for a column that's not resizable or sortable. */
|
||||
notResizableOrSortable = (visible | draggable | appearsOnColumnMenu),
|
||||
|
||||
/** A quick way of combining flags for a column that's not sortable. */
|
||||
notSortable = (visible | resizable | draggable | appearsOnColumnMenu)
|
||||
};
|
||||
|
||||
/** Adds a column to the table.
|
||||
|
||||
This will add a column, and asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
|
||||
@param columnName the name of the new column. It's ok to have two or more columns with the same name
|
||||
@param columnId an ID for this column. The ID can be any number apart from 0, but every column must have
|
||||
a unique ID. This is used to identify the column later on, after the user may have
|
||||
changed the order that they appear in
|
||||
@param width the initial width of the column, in pixels
|
||||
@param maximumWidth a maximum width that the column can take when the user is resizing it. This only applies
|
||||
if the 'resizable' flag is specified for this column
|
||||
@param minimumWidth a minimum width that the column can take when the user is resizing it. This only applies
|
||||
if the 'resizable' flag is specified for this column
|
||||
@param propertyFlags a combination of some of the values from the ColumnPropertyFlags enum, to define the
|
||||
properties of this column
|
||||
@param insertIndex the index at which the column should be added. A value of 0 puts it at the start (left-hand side)
|
||||
and -1 puts it at the end (right-hand size) of the table. Note that the index the index within
|
||||
all columns, not just the index amongst those that are currently visible
|
||||
*/
|
||||
void addColumn (const String& columnName,
|
||||
int columnId,
|
||||
int width,
|
||||
int minimumWidth = 30,
|
||||
int maximumWidth = -1,
|
||||
int propertyFlags = defaultFlags,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Removes a column with the given ID.
|
||||
|
||||
If there is such a column, this will asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
*/
|
||||
void removeColumn (int columnIdToRemove);
|
||||
|
||||
/** Deletes all columns from the table.
|
||||
|
||||
If there are any columns to remove, this will asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
*/
|
||||
void removeAllColumns();
|
||||
|
||||
/** Returns the number of columns in the table.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will return the number of visible columns; otherwise it'll
|
||||
return the total number of columns, including hidden ones.
|
||||
|
||||
@see isColumnVisible
|
||||
*/
|
||||
int getNumColumns (bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the name for a column.
|
||||
@see setColumnName
|
||||
*/
|
||||
String getColumnName (int columnId) const;
|
||||
|
||||
/** Changes the name of a column. */
|
||||
void setColumnName (int columnId, const String& newName);
|
||||
|
||||
/** Moves a column to a different index in the table.
|
||||
|
||||
@param columnId the column to move
|
||||
@param newVisibleIndex the target index for it, from 0 to the number of columns currently visible.
|
||||
*/
|
||||
void moveColumn (int columnId, int newVisibleIndex);
|
||||
|
||||
/** Returns the width of one of the columns.
|
||||
*/
|
||||
int getColumnWidth (int columnId) const;
|
||||
|
||||
/** Changes the width of a column.
|
||||
|
||||
This will cause an asynchronous callback to the tableColumnsResized() method of any registered listeners.
|
||||
*/
|
||||
void setColumnWidth (int columnId, int newWidth);
|
||||
|
||||
/** Shows or hides a column.
|
||||
|
||||
This can cause an asynchronous callback to the tableColumnsChanged() method of any registered listeners.
|
||||
@see isColumnVisible
|
||||
*/
|
||||
void setColumnVisible (int columnId, bool shouldBeVisible);
|
||||
|
||||
/** Returns true if this column is currently visible.
|
||||
@see setColumnVisible
|
||||
*/
|
||||
bool isColumnVisible (int columnId) const;
|
||||
|
||||
/** Changes the column which is the sort column.
|
||||
|
||||
This can cause an asynchronous callback to the tableSortOrderChanged() method of any registered listeners.
|
||||
|
||||
If this method doesn't actually change the column ID, then no re-sort will take place (you can
|
||||
call reSortTable() to force a re-sort to happen if you've modified the table's contents).
|
||||
|
||||
@see getSortColumnId, isSortedForwards, reSortTable
|
||||
*/
|
||||
void setSortColumnId (int columnId, bool sortForwards);
|
||||
|
||||
/** Returns the column ID by which the table is currently sorted, or 0 if it is unsorted.
|
||||
|
||||
@see setSortColumnId, isSortedForwards
|
||||
*/
|
||||
int getSortColumnId() const;
|
||||
|
||||
/** Returns true if the table is currently sorted forwards, or false if it's backwards.
|
||||
@see setSortColumnId
|
||||
*/
|
||||
bool isSortedForwards() const;
|
||||
|
||||
/** Triggers a re-sort of the table according to the current sort-column.
|
||||
|
||||
If you modify the table's contents, you can call this to signal that the table needs
|
||||
to be re-sorted.
|
||||
|
||||
(This doesn't do any sorting synchronously - it just asynchronously sends a call to the
|
||||
tableSortOrderChanged() method of any listeners).
|
||||
*/
|
||||
void reSortTable();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total width of all the visible columns in the table.
|
||||
*/
|
||||
int getTotalWidth() const;
|
||||
|
||||
/** Returns the index of a given column.
|
||||
|
||||
If there's no such column ID, this will return -1.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will return the index amongst the visible columns;
|
||||
otherwise it'll return the index amongst all the columns, including any hidden ones.
|
||||
*/
|
||||
int getIndexOfColumnId (int columnId, bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the ID of the column at a given index.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will count the index amongst the visible columns;
|
||||
otherwise it'll count it amongst all the columns, including any hidden ones.
|
||||
|
||||
If the index is out-of-range, it'll return 0.
|
||||
*/
|
||||
int getColumnIdOfIndex (int index, bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the rectangle containing of one of the columns.
|
||||
|
||||
The index is an index from 0 to the number of columns that are currently visible (hidden
|
||||
ones are not counted). It returns a rectangle showing the position of the column relative
|
||||
to this component's top-left. If the index is out-of-range, an empty rectangle is returned.
|
||||
*/
|
||||
Rectangle<int> getColumnPosition (int index) const;
|
||||
|
||||
/** Finds the column ID at a given x-position in the component.
|
||||
If there is a column at this point this returns its ID, or if not, it will return 0.
|
||||
*/
|
||||
int getColumnIdAtX (int xToFind) const;
|
||||
|
||||
/** If set to true, this indicates that the columns should be expanded or shrunk to fill the
|
||||
entire width of the component.
|
||||
|
||||
By default this is disabled. Turning it on also means that when resizing a column, those
|
||||
on the right will be squashed to fit.
|
||||
*/
|
||||
void setStretchToFitActive (bool shouldStretchToFit);
|
||||
|
||||
/** Returns true if stretch-to-fit has been enabled.
|
||||
@see setStretchToFitActive
|
||||
*/
|
||||
bool isStretchToFitActive() const;
|
||||
|
||||
/** If stretch-to-fit is enabled, this will resize all the columns to make them fit into the
|
||||
specified width, keeping their relative proportions the same.
|
||||
|
||||
If the minimum widths of the columns are too wide to fit into this space, it may
|
||||
actually end up wider.
|
||||
*/
|
||||
void resizeAllColumnsToFit (int targetTotalWidth);
|
||||
|
||||
//==============================================================================
|
||||
/** Enables or disables the pop-up menu.
|
||||
|
||||
The default menu allows the user to show or hide columns. You can add custom
|
||||
items to this menu by overloading the addMenuItems() and reactToMenuItem() methods.
|
||||
|
||||
By default the menu is enabled.
|
||||
|
||||
@see isPopupMenuActive, addMenuItems, reactToMenuItem
|
||||
*/
|
||||
void setPopupMenuActive (bool hasMenu);
|
||||
|
||||
/** Returns true if the pop-up menu is enabled.
|
||||
@see setPopupMenuActive
|
||||
*/
|
||||
bool isPopupMenuActive() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string that encapsulates the table's current layout.
|
||||
|
||||
This can be restored later using restoreFromString(). It saves the order of
|
||||
the columns, the currently-sorted column, and the widths.
|
||||
|
||||
@see restoreFromString
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Restores the state of the table, based on a string previously created with
|
||||
toString().
|
||||
|
||||
@see toString
|
||||
*/
|
||||
void restoreFromString (const String& storedVersion);
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Receives events from a TableHeaderComponent when columns are resized, moved, etc.
|
||||
|
||||
You can register one of these objects for table events using TableHeaderComponent::addListener()
|
||||
and TableHeaderComponent::removeListener().
|
||||
|
||||
@see TableHeaderComponent
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
Listener() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** This is called when some of the table's columns are added, removed, hidden,
|
||||
or rearranged.
|
||||
*/
|
||||
virtual void tableColumnsChanged (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when one or more of the table's columns are resized. */
|
||||
virtual void tableColumnsResized (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when the column by which the table should be sorted is changed. */
|
||||
virtual void tableSortOrderChanged (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when the user begins or ends dragging one of the columns around.
|
||||
|
||||
When the user starts dragging a column, this is called with the ID of that
|
||||
column. When they finish dragging, it is called again with 0 as the ID.
|
||||
*/
|
||||
virtual void tableColumnDraggingChanged (TableHeaderComponent* tableHeader,
|
||||
int columnIdNowBeingDragged);
|
||||
};
|
||||
|
||||
/** Adds a listener to be informed about things that happen to the header. */
|
||||
void addListener (Listener* newListener);
|
||||
|
||||
/** Removes a previously-registered listener. */
|
||||
void removeListener (Listener* listenerToRemove);
|
||||
|
||||
//==============================================================================
|
||||
/** This can be overridden to handle a mouse-click on one of the column headers.
|
||||
|
||||
The default implementation will use this click to call getSortColumnId() and
|
||||
change the sort order.
|
||||
*/
|
||||
virtual void columnClicked (int columnId, const ModifierKeys& mods);
|
||||
|
||||
/** This can be overridden to add custom items to the pop-up menu.
|
||||
|
||||
If you override this, you should call the superclass's method to add its
|
||||
column show/hide items, if you want them on the menu as well.
|
||||
|
||||
Then to handle the result, override reactToMenuItem().
|
||||
|
||||
@see reactToMenuItem
|
||||
*/
|
||||
virtual void addMenuItems (PopupMenu& menu, int columnIdClicked);
|
||||
|
||||
/** Override this to handle any custom items that you have added to the
|
||||
pop-up menu with an addMenuItems() override.
|
||||
|
||||
If the menuReturnId isn't one of your own custom menu items, you'll need to
|
||||
call TableHeaderComponent::reactToMenuItem() to allow the base class to
|
||||
handle the items that it had added.
|
||||
|
||||
@see addMenuItems
|
||||
*/
|
||||
virtual void reactToMenuItem (int menuReturnId, int columnIdClicked);
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the TableHeaderComponent.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
textColourId = 0x1003800, /**< The colour for the text in the header. */
|
||||
backgroundColourId = 0x1003810, /**< The colour of the table header background.
|
||||
It's up to the LookAndFeel how this is used. */
|
||||
outlineColourId = 0x1003820, /**< The colour of the table header's outline. */
|
||||
highlightColourId = 0x1003830, /**< The colour of the table header background when
|
||||
the mouse is over or down above the the table
|
||||
header. It's up to the LookAndFeel to use a
|
||||
variant of this colour to distinguish between
|
||||
the down and hover state. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) = 0;
|
||||
|
||||
virtual void drawTableHeaderColumn (Graphics&, TableHeaderComponent&,
|
||||
const String& columnName, int columnId,
|
||||
int width, int height,
|
||||
bool isMouseOver, bool isMouseDown, int columnFlags) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void mouseMove (const MouseEvent&) 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 */
|
||||
MouseCursor getMouseCursor() override;
|
||||
|
||||
/** Can be overridden for more control over the pop-up menu behaviour. */
|
||||
virtual void showColumnChooserMenu (int columnIdClicked);
|
||||
|
||||
private:
|
||||
struct ColumnInfo
|
||||
{
|
||||
String name;
|
||||
int id, propertyFlags, width, minimumWidth, maximumWidth;
|
||||
double lastDeliberateWidth;
|
||||
|
||||
bool isVisible() const;
|
||||
};
|
||||
|
||||
OwnedArray<ColumnInfo> columns;
|
||||
Array<Listener*> listeners;
|
||||
std::unique_ptr<Component> dragOverlayComp;
|
||||
class DragOverlayComp;
|
||||
|
||||
bool columnsChanged = false, columnsResized = false, sortChanged = false;
|
||||
bool menuActive = true, stretchToFit = false;
|
||||
int columnIdBeingResized = 0, columnIdBeingDragged = 0, initialColumnWidth = 0;
|
||||
int columnIdUnderMouse = 0, draggingColumnOffset = 0, draggingColumnOriginalIndex = 0, lastDeliberateWidth = 0;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
ColumnInfo* getInfoForId (int columnId) const;
|
||||
int visibleIndexToTotalIndex (int visibleIndex) const;
|
||||
void sendColumnsChanged();
|
||||
void handleAsyncUpdate() override;
|
||||
void beginDrag (const MouseEvent&);
|
||||
void endDrag (int finalIndex);
|
||||
int getResizeDraggerAt (int mouseX) const;
|
||||
void updateColumnUnderMouse (const MouseEvent&);
|
||||
void setColumnUnderMouse (int columnId);
|
||||
void resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableHeaderComponent)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that displays a strip of column headings for a table, and allows these
|
||||
to be resized, dragged around, etc.
|
||||
|
||||
This is just the component that goes at the top of a table. You can use it
|
||||
directly for custom components, or to create a simple table, use the
|
||||
TableListBox class.
|
||||
|
||||
To use one of these, create it and use addColumn() to add all the columns that you need.
|
||||
Each column must be given a unique ID number that's used to refer to it.
|
||||
|
||||
@see TableListBox, TableHeaderComponent::Listener
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableHeaderComponent : public Component,
|
||||
private AsyncUpdater
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty table header.
|
||||
*/
|
||||
TableHeaderComponent();
|
||||
|
||||
/** Destructor. */
|
||||
~TableHeaderComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** A combination of these flags are passed into the addColumn() method to specify
|
||||
the properties of a column.
|
||||
*/
|
||||
enum ColumnPropertyFlags
|
||||
{
|
||||
visible = 1, /**< If this is set, the column will be shown; if not, it will be hidden until the user enables it with the pop-up menu. */
|
||||
resizable = 2, /**< If this is set, the column can be resized by dragging it. */
|
||||
draggable = 4, /**< If this is set, the column can be dragged around to change its order in the table. */
|
||||
appearsOnColumnMenu = 8, /**< If this is set, the column will be shown on the pop-up menu allowing it to be hidden/shown. */
|
||||
sortable = 16, /**< If this is set, then clicking on the column header will set it to be the sort column, and clicking again will reverse the order. */
|
||||
sortedForwards = 32, /**< If this is set, the column is currently the one by which the table is sorted (forwards). */
|
||||
sortedBackwards = 64, /**< If this is set, the column is currently the one by which the table is sorted (backwards). */
|
||||
|
||||
/** This set of default flags is used as the default parameter value in addColumn(). */
|
||||
defaultFlags = (visible | resizable | draggable | appearsOnColumnMenu | sortable),
|
||||
|
||||
/** A quick way of combining flags for a column that's not resizable. */
|
||||
notResizable = (visible | draggable | appearsOnColumnMenu | sortable),
|
||||
|
||||
/** A quick way of combining flags for a column that's not resizable or sortable. */
|
||||
notResizableOrSortable = (visible | draggable | appearsOnColumnMenu),
|
||||
|
||||
/** A quick way of combining flags for a column that's not sortable. */
|
||||
notSortable = (visible | resizable | draggable | appearsOnColumnMenu)
|
||||
};
|
||||
|
||||
/** Adds a column to the table.
|
||||
|
||||
This will add a column, and asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
|
||||
@param columnName the name of the new column. It's ok to have two or more columns with the same name
|
||||
@param columnId an ID for this column. The ID can be any number apart from 0, but every column must have
|
||||
a unique ID. This is used to identify the column later on, after the user may have
|
||||
changed the order that they appear in
|
||||
@param width the initial width of the column, in pixels
|
||||
@param maximumWidth a maximum width that the column can take when the user is resizing it. This only applies
|
||||
if the 'resizable' flag is specified for this column
|
||||
@param minimumWidth a minimum width that the column can take when the user is resizing it. This only applies
|
||||
if the 'resizable' flag is specified for this column
|
||||
@param propertyFlags a combination of some of the values from the ColumnPropertyFlags enum, to define the
|
||||
properties of this column
|
||||
@param insertIndex the index at which the column should be added. A value of 0 puts it at the start (left-hand side)
|
||||
and -1 puts it at the end (right-hand size) of the table. Note that the index the index within
|
||||
all columns, not just the index amongst those that are currently visible
|
||||
*/
|
||||
void addColumn (const String& columnName,
|
||||
int columnId,
|
||||
int width,
|
||||
int minimumWidth = 30,
|
||||
int maximumWidth = -1,
|
||||
int propertyFlags = defaultFlags,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Removes a column with the given ID.
|
||||
|
||||
If there is such a column, this will asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
*/
|
||||
void removeColumn (int columnIdToRemove);
|
||||
|
||||
/** Deletes all columns from the table.
|
||||
|
||||
If there are any columns to remove, this will asynchronously call the tableColumnsChanged() method of any
|
||||
registered listeners.
|
||||
*/
|
||||
void removeAllColumns();
|
||||
|
||||
/** Returns the number of columns in the table.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will return the number of visible columns; otherwise it'll
|
||||
return the total number of columns, including hidden ones.
|
||||
|
||||
@see isColumnVisible
|
||||
*/
|
||||
int getNumColumns (bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the name for a column.
|
||||
@see setColumnName
|
||||
*/
|
||||
String getColumnName (int columnId) const;
|
||||
|
||||
/** Changes the name of a column. */
|
||||
void setColumnName (int columnId, const String& newName);
|
||||
|
||||
/** Moves a column to a different index in the table.
|
||||
|
||||
@param columnId the column to move
|
||||
@param newVisibleIndex the target index for it, from 0 to the number of columns currently visible.
|
||||
*/
|
||||
void moveColumn (int columnId, int newVisibleIndex);
|
||||
|
||||
/** Returns the width of one of the columns.
|
||||
*/
|
||||
int getColumnWidth (int columnId) const;
|
||||
|
||||
/** Changes the width of a column.
|
||||
|
||||
This will cause an asynchronous callback to the tableColumnsResized() method of any registered listeners.
|
||||
*/
|
||||
void setColumnWidth (int columnId, int newWidth);
|
||||
|
||||
/** Shows or hides a column.
|
||||
|
||||
This can cause an asynchronous callback to the tableColumnsChanged() method of any registered listeners.
|
||||
@see isColumnVisible
|
||||
*/
|
||||
void setColumnVisible (int columnId, bool shouldBeVisible);
|
||||
|
||||
/** Returns true if this column is currently visible.
|
||||
@see setColumnVisible
|
||||
*/
|
||||
bool isColumnVisible (int columnId) const;
|
||||
|
||||
/** Changes the column which is the sort column.
|
||||
|
||||
This can cause an asynchronous callback to the tableSortOrderChanged() method of any registered listeners.
|
||||
|
||||
If this method doesn't actually change the column ID, then no re-sort will take place (you can
|
||||
call reSortTable() to force a re-sort to happen if you've modified the table's contents).
|
||||
|
||||
@see getSortColumnId, isSortedForwards, reSortTable
|
||||
*/
|
||||
void setSortColumnId (int columnId, bool sortForwards);
|
||||
|
||||
/** Returns the column ID by which the table is currently sorted, or 0 if it is unsorted.
|
||||
|
||||
@see setSortColumnId, isSortedForwards
|
||||
*/
|
||||
int getSortColumnId() const;
|
||||
|
||||
/** Returns true if the table is currently sorted forwards, or false if it's backwards.
|
||||
@see setSortColumnId
|
||||
*/
|
||||
bool isSortedForwards() const;
|
||||
|
||||
/** Triggers a re-sort of the table according to the current sort-column.
|
||||
|
||||
If you modify the table's contents, you can call this to signal that the table needs
|
||||
to be re-sorted.
|
||||
|
||||
(This doesn't do any sorting synchronously - it just asynchronously sends a call to the
|
||||
tableSortOrderChanged() method of any listeners).
|
||||
*/
|
||||
void reSortTable();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the total width of all the visible columns in the table.
|
||||
*/
|
||||
int getTotalWidth() const;
|
||||
|
||||
/** Returns the index of a given column.
|
||||
|
||||
If there's no such column ID, this will return -1.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will return the index amongst the visible columns;
|
||||
otherwise it'll return the index amongst all the columns, including any hidden ones.
|
||||
*/
|
||||
int getIndexOfColumnId (int columnId, bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the ID of the column at a given index.
|
||||
|
||||
If onlyCountVisibleColumns is true, this will count the index amongst the visible columns;
|
||||
otherwise it'll count it amongst all the columns, including any hidden ones.
|
||||
|
||||
If the index is out-of-range, it'll return 0.
|
||||
*/
|
||||
int getColumnIdOfIndex (int index, bool onlyCountVisibleColumns) const;
|
||||
|
||||
/** Returns the rectangle containing of one of the columns.
|
||||
|
||||
The index is an index from 0 to the number of columns that are currently visible (hidden
|
||||
ones are not counted). It returns a rectangle showing the position of the column relative
|
||||
to this component's top-left. If the index is out-of-range, an empty rectangle is returned.
|
||||
*/
|
||||
Rectangle<int> getColumnPosition (int index) const;
|
||||
|
||||
/** Finds the column ID at a given x-position in the component.
|
||||
If there is a column at this point this returns its ID, or if not, it will return 0.
|
||||
*/
|
||||
int getColumnIdAtX (int xToFind) const;
|
||||
|
||||
/** If set to true, this indicates that the columns should be expanded or shrunk to fill the
|
||||
entire width of the component.
|
||||
|
||||
By default this is disabled. Turning it on also means that when resizing a column, those
|
||||
on the right will be squashed to fit.
|
||||
*/
|
||||
void setStretchToFitActive (bool shouldStretchToFit);
|
||||
|
||||
/** Returns true if stretch-to-fit has been enabled.
|
||||
@see setStretchToFitActive
|
||||
*/
|
||||
bool isStretchToFitActive() const;
|
||||
|
||||
/** If stretch-to-fit is enabled, this will resize all the columns to make them fit into the
|
||||
specified width, keeping their relative proportions the same.
|
||||
|
||||
If the minimum widths of the columns are too wide to fit into this space, it may
|
||||
actually end up wider.
|
||||
*/
|
||||
void resizeAllColumnsToFit (int targetTotalWidth);
|
||||
|
||||
//==============================================================================
|
||||
/** Enables or disables the pop-up menu.
|
||||
|
||||
The default menu allows the user to show or hide columns. You can add custom
|
||||
items to this menu by overloading the addMenuItems() and reactToMenuItem() methods.
|
||||
|
||||
By default the menu is enabled.
|
||||
|
||||
@see isPopupMenuActive, addMenuItems, reactToMenuItem
|
||||
*/
|
||||
void setPopupMenuActive (bool hasMenu);
|
||||
|
||||
/** Returns true if the pop-up menu is enabled.
|
||||
@see setPopupMenuActive
|
||||
*/
|
||||
bool isPopupMenuActive() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string that encapsulates the table's current layout.
|
||||
|
||||
This can be restored later using restoreFromString(). It saves the order of
|
||||
the columns, the currently-sorted column, and the widths.
|
||||
|
||||
@see restoreFromString
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Restores the state of the table, based on a string previously created with
|
||||
toString().
|
||||
|
||||
@see toString
|
||||
*/
|
||||
void restoreFromString (const String& storedVersion);
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Receives events from a TableHeaderComponent when columns are resized, moved, etc.
|
||||
|
||||
You can register one of these objects for table events using TableHeaderComponent::addListener()
|
||||
and TableHeaderComponent::removeListener().
|
||||
|
||||
@see TableHeaderComponent
|
||||
*/
|
||||
class JUCE_API Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
Listener() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** This is called when some of the table's columns are added, removed, hidden,
|
||||
or rearranged.
|
||||
*/
|
||||
virtual void tableColumnsChanged (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when one or more of the table's columns are resized. */
|
||||
virtual void tableColumnsResized (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when the column by which the table should be sorted is changed. */
|
||||
virtual void tableSortOrderChanged (TableHeaderComponent* tableHeader) = 0;
|
||||
|
||||
/** This is called when the user begins or ends dragging one of the columns around.
|
||||
|
||||
When the user starts dragging a column, this is called with the ID of that
|
||||
column. When they finish dragging, it is called again with 0 as the ID.
|
||||
*/
|
||||
virtual void tableColumnDraggingChanged (TableHeaderComponent* tableHeader,
|
||||
int columnIdNowBeingDragged);
|
||||
};
|
||||
|
||||
/** Adds a listener to be informed about things that happen to the header. */
|
||||
void addListener (Listener* newListener);
|
||||
|
||||
/** Removes a previously-registered listener. */
|
||||
void removeListener (Listener* listenerToRemove);
|
||||
|
||||
//==============================================================================
|
||||
/** This can be overridden to handle a mouse-click on one of the column headers.
|
||||
|
||||
The default implementation will use this click to call getSortColumnId() and
|
||||
change the sort order.
|
||||
*/
|
||||
virtual void columnClicked (int columnId, const ModifierKeys& mods);
|
||||
|
||||
/** This can be overridden to add custom items to the pop-up menu.
|
||||
|
||||
If you override this, you should call the superclass's method to add its
|
||||
column show/hide items, if you want them on the menu as well.
|
||||
|
||||
Then to handle the result, override reactToMenuItem().
|
||||
|
||||
@see reactToMenuItem
|
||||
*/
|
||||
virtual void addMenuItems (PopupMenu& menu, int columnIdClicked);
|
||||
|
||||
/** Override this to handle any custom items that you have added to the
|
||||
pop-up menu with an addMenuItems() override.
|
||||
|
||||
If the menuReturnId isn't one of your own custom menu items, you'll need to
|
||||
call TableHeaderComponent::reactToMenuItem() to allow the base class to
|
||||
handle the items that it had added.
|
||||
|
||||
@see addMenuItems
|
||||
*/
|
||||
virtual void reactToMenuItem (int menuReturnId, int columnIdClicked);
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the TableHeaderComponent.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
textColourId = 0x1003800, /**< The colour for the text in the header. */
|
||||
backgroundColourId = 0x1003810, /**< The colour of the table header background.
|
||||
It's up to the LookAndFeel how this is used. */
|
||||
outlineColourId = 0x1003820, /**< The colour of the table header's outline. */
|
||||
highlightColourId = 0x1003830, /**< The colour of the table header background when
|
||||
the mouse is over or down above the the table
|
||||
header. It's up to the LookAndFeel to use a
|
||||
variant of this colour to distinguish between
|
||||
the down and hover state. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) = 0;
|
||||
|
||||
virtual void drawTableHeaderColumn (Graphics&, TableHeaderComponent&,
|
||||
const String& columnName, int columnId,
|
||||
int width, int height,
|
||||
bool isMouseOver, bool isMouseDown, int columnFlags) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
void mouseMove (const MouseEvent&) 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 */
|
||||
MouseCursor getMouseCursor() override;
|
||||
|
||||
/** Can be overridden for more control over the pop-up menu behaviour. */
|
||||
virtual void showColumnChooserMenu (int columnIdClicked);
|
||||
|
||||
private:
|
||||
struct ColumnInfo : public Component
|
||||
{
|
||||
ColumnInfo() { setInterceptsMouseClicks (false, false); }
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
|
||||
int id, propertyFlags, width, minimumWidth, maximumWidth;
|
||||
double lastDeliberateWidth;
|
||||
};
|
||||
|
||||
OwnedArray<ColumnInfo> columns;
|
||||
Array<Listener*> listeners;
|
||||
std::unique_ptr<Component> dragOverlayComp;
|
||||
class DragOverlayComp;
|
||||
|
||||
bool columnsChanged = false, columnsResized = false, sortChanged = false;
|
||||
bool menuActive = true, stretchToFit = false;
|
||||
int columnIdBeingResized = 0, columnIdBeingDragged = 0, initialColumnWidth = 0;
|
||||
int columnIdUnderMouse = 0, draggingColumnOffset = 0, draggingColumnOriginalIndex = 0, lastDeliberateWidth = 0;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
ColumnInfo* getInfoForId (int columnId) const;
|
||||
int visibleIndexToTotalIndex (int visibleIndex) const;
|
||||
void sendColumnsChanged();
|
||||
void handleAsyncUpdate() override;
|
||||
void beginDrag (const MouseEvent&);
|
||||
void endDrag (int finalIndex);
|
||||
int getResizeDraggerAt (int mouseX) const;
|
||||
void updateColumnUnderMouse (const MouseEvent&);
|
||||
void setColumnUnderMouse (int columnId);
|
||||
void resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableHeaderComponent)
|
||||
};
|
||||
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,346 +1,346 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
One of these is used by a TableListBox as the data model for the table's contents.
|
||||
|
||||
The virtual methods that you override in this class take care of drawing the
|
||||
table cells, and reacting to events.
|
||||
|
||||
@see TableListBox
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableListBoxModel
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
TableListBoxModel() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~TableListBoxModel() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** This must return the number of rows currently in the table.
|
||||
|
||||
If the number of rows changes, you must call TableListBox::updateContent() to
|
||||
cause it to refresh the list.
|
||||
*/
|
||||
virtual int getNumRows() = 0;
|
||||
|
||||
/** This must draw the background behind one of the rows in the table.
|
||||
|
||||
The graphics context has its origin at the row's top-left, and your method
|
||||
should fill the area specified by the width and height parameters.
|
||||
|
||||
Note that the rowNumber value may be greater than the number of rows in your
|
||||
list, so be careful that you don't assume it's less than getNumRows().
|
||||
*/
|
||||
virtual void paintRowBackground (Graphics&,
|
||||
int rowNumber,
|
||||
int width, int height,
|
||||
bool rowIsSelected) = 0;
|
||||
|
||||
/** This must draw one of the cells.
|
||||
|
||||
The graphics context's origin will already be set to the top-left of the cell,
|
||||
whose size is specified by (width, height).
|
||||
|
||||
Note that the rowNumber value may be greater than the number of rows in your
|
||||
list, so be careful that you don't assume it's less than getNumRows().
|
||||
*/
|
||||
virtual void paintCell (Graphics&,
|
||||
int rowNumber,
|
||||
int columnId,
|
||||
int width, int height,
|
||||
bool rowIsSelected) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** This is used to create or update a custom component to go in a cell.
|
||||
|
||||
Any cell may contain a custom component, or can just be drawn with the paintCell() method
|
||||
and handle mouse clicks with cellClicked().
|
||||
|
||||
This method will be called whenever a custom component might need to be updated - e.g.
|
||||
when the table is changed, or TableListBox::updateContent() is called.
|
||||
|
||||
If you don't need a custom component for the specified cell, then return nullptr.
|
||||
(Bear in mind that even if you're not creating a new component, you may still need to
|
||||
delete existingComponentToUpdate if it's non-null).
|
||||
|
||||
If you do want a custom component, and the existingComponentToUpdate is null, then
|
||||
this method must create a new component suitable for the cell, and return it.
|
||||
|
||||
If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
|
||||
by this method. In this case, the method must either update it to make sure it's correctly representing
|
||||
the given cell (which may be different from the one that the component was created for), or it can
|
||||
delete this component and return a new one.
|
||||
*/
|
||||
virtual Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected,
|
||||
Component* existingComponentToUpdate);
|
||||
|
||||
//==============================================================================
|
||||
/** This callback is made when the user clicks on one of the cells in the table.
|
||||
|
||||
The mouse event's coordinates will be relative to the entire table row.
|
||||
@see cellDoubleClicked, backgroundClicked
|
||||
*/
|
||||
virtual void cellClicked (int rowNumber, int columnId, const MouseEvent&);
|
||||
|
||||
/** This callback is made when the user clicks on one of the cells in the table.
|
||||
|
||||
The mouse event's coordinates will be relative to the entire table row.
|
||||
@see cellClicked, backgroundClicked
|
||||
*/
|
||||
virtual void cellDoubleClicked (int rowNumber, int columnId, const MouseEvent&);
|
||||
|
||||
/** This can be overridden to react to the user double-clicking on a part of the list where
|
||||
there are no rows.
|
||||
|
||||
@see cellClicked
|
||||
*/
|
||||
virtual void backgroundClicked (const MouseEvent&);
|
||||
|
||||
//==============================================================================
|
||||
/** This callback is made when the table's sort order is changed.
|
||||
|
||||
This could be because the user has clicked a column header, or because the
|
||||
TableHeaderComponent::setSortColumnId() method was called.
|
||||
|
||||
If you implement this, your method should re-sort the table using the given
|
||||
column as the key.
|
||||
*/
|
||||
virtual void sortOrderChanged (int newSortColumnId, bool isForwards);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the best width for one of the columns.
|
||||
|
||||
If you implement this method, you should measure the width of all the items
|
||||
in this column, and return the best size.
|
||||
|
||||
Returning 0 means that the column shouldn't be changed.
|
||||
|
||||
This is used by TableListBox::autoSizeColumn() and TableListBox::autoSizeAllColumns().
|
||||
*/
|
||||
virtual int getColumnAutoSizeWidth (int columnId);
|
||||
|
||||
/** Returns a tooltip for a particular cell in the table. */
|
||||
virtual String getCellTooltip (int rowNumber, int columnId);
|
||||
|
||||
//==============================================================================
|
||||
/** Override this to be informed when rows are selected or deselected.
|
||||
@see ListBox::selectedRowsChanged()
|
||||
*/
|
||||
virtual void selectedRowsChanged (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the delete key is pressed.
|
||||
@see ListBox::deleteKeyPressed()
|
||||
*/
|
||||
virtual void deleteKeyPressed (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the return key is pressed.
|
||||
@see ListBox::returnKeyPressed()
|
||||
*/
|
||||
virtual void returnKeyPressed (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the list is scrolled.
|
||||
|
||||
This might be caused by the user moving the scrollbar, or by programmatic changes
|
||||
to the list position.
|
||||
*/
|
||||
virtual void listWasScrolled();
|
||||
|
||||
/** To allow rows from your table to be dragged-and-dropped, implement this method.
|
||||
|
||||
If this returns a non-null variant then when the user drags a row, the table will try to
|
||||
find a DragAndDropContainer in its parent hierarchy, and will use it to trigger a
|
||||
drag-and-drop operation, using this string as the source description, and the listbox
|
||||
itself as the source component.
|
||||
|
||||
@see getDragSourceCustomData, DragAndDropContainer::startDragging
|
||||
*/
|
||||
virtual var getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A table of cells, using a TableHeaderComponent as its header.
|
||||
|
||||
This component makes it easy to create a table by providing a TableListBoxModel as
|
||||
the data source.
|
||||
|
||||
|
||||
@see TableListBoxModel, TableHeaderComponent
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableListBox : public ListBox,
|
||||
private ListBoxModel,
|
||||
private TableHeaderComponent::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a TableListBox.
|
||||
|
||||
The model pointer passed-in can be null, in which case you can set it later
|
||||
with setModel(). The TableListBox does not take ownership of the model - it's
|
||||
the caller's responsibility to manage its lifetime and make sure it
|
||||
doesn't get deleted while still being used.
|
||||
*/
|
||||
TableListBox (const String& componentName = String(),
|
||||
TableListBoxModel* model = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~TableListBox() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the TableListBoxModel that is being used for this table.
|
||||
The TableListBox does not take ownership of the model - it's the caller's responsibility
|
||||
to manage its lifetime and make sure it doesn't get deleted while still being used.
|
||||
*/
|
||||
void setModel (TableListBoxModel* newModel);
|
||||
|
||||
/** Returns the model currently in use. */
|
||||
TableListBoxModel* getModel() const noexcept { return model; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the header component being used in this table. */
|
||||
TableHeaderComponent& getHeader() const noexcept { return *header; }
|
||||
|
||||
/** Sets the header component to use for the table.
|
||||
The table will take ownership of the component that you pass in, and will delete it
|
||||
when it's no longer needed.
|
||||
The pointer passed in may not be null.
|
||||
*/
|
||||
void setHeader (std::unique_ptr<TableHeaderComponent> newHeader);
|
||||
|
||||
/** Changes the height of the table header component.
|
||||
@see getHeaderHeight
|
||||
*/
|
||||
void setHeaderHeight (int newHeight);
|
||||
|
||||
/** Returns the height of the table header.
|
||||
@see setHeaderHeight
|
||||
*/
|
||||
int getHeaderHeight() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Resizes a column to fit its contents.
|
||||
|
||||
This uses TableListBoxModel::getColumnAutoSizeWidth() to find the best width,
|
||||
and applies that to the column.
|
||||
|
||||
@see autoSizeAllColumns, TableHeaderComponent::setColumnWidth
|
||||
*/
|
||||
void autoSizeColumn (int columnId);
|
||||
|
||||
/** Calls autoSizeColumn() for all columns in the table. */
|
||||
void autoSizeAllColumns();
|
||||
|
||||
/** Enables or disables the auto size options on the popup menu.
|
||||
By default, these are enabled.
|
||||
*/
|
||||
void setAutoSizeMenuOptionShown (bool shouldBeShown) noexcept;
|
||||
|
||||
/** True if the auto-size options should be shown on the menu.
|
||||
@see setAutoSizeMenuOptionShown
|
||||
*/
|
||||
bool isAutoSizeMenuOptionShown() const noexcept { return autoSizeOptionsShown; }
|
||||
|
||||
/** Returns the position of one of the cells in the table.
|
||||
|
||||
If relativeToComponentTopLeft is true, the coordinates are relative to
|
||||
the table component's top-left. The row number isn't checked to see if it's
|
||||
in-range, but the column ID must exist or this will return an empty rectangle.
|
||||
|
||||
If relativeToComponentTopLeft is false, the coordinates are relative to the
|
||||
top-left of the table's top-left cell.
|
||||
*/
|
||||
Rectangle<int> getCellPosition (int columnId, int rowNumber,
|
||||
bool relativeToComponentTopLeft) const;
|
||||
|
||||
/** Returns the component that currently represents a given cell.
|
||||
If the component for this cell is off-screen or if the position is out-of-range,
|
||||
this may return nullptr.
|
||||
@see getCellPosition
|
||||
*/
|
||||
Component* getCellComponent (int columnId, int rowNumber) const;
|
||||
|
||||
/** Scrolls horizontally if necessary to make sure that a particular column is visible.
|
||||
|
||||
@see ListBox::scrollToEnsureRowIsOnscreen
|
||||
*/
|
||||
void scrollToEnsureColumnIsOnscreen (int columnId);
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
int getNumRows() override;
|
||||
/** @internal */
|
||||
void paintListBoxItem (int, Graphics&, int, int, bool) override;
|
||||
/** @internal */
|
||||
Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate) override;
|
||||
/** @internal */
|
||||
void selectedRowsChanged (int row) override;
|
||||
/** @internal */
|
||||
void deleteKeyPressed (int currentSelectedRow) override;
|
||||
/** @internal */
|
||||
void returnKeyPressed (int currentSelectedRow) override;
|
||||
/** @internal */
|
||||
void backgroundClicked (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void listWasScrolled() override;
|
||||
/** @internal */
|
||||
void tableColumnsChanged (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableColumnsResized (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableSortOrderChanged (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableColumnDraggingChanged (TableHeaderComponent*, int) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class Header;
|
||||
class RowComp;
|
||||
|
||||
TableHeaderComponent* header = nullptr;
|
||||
TableListBoxModel* model;
|
||||
int columnIdNowBeingDragged = 0;
|
||||
bool autoSizeOptionsShown = true;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void updateColumnComponents() const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableListBox)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
One of these is used by a TableListBox as the data model for the table's contents.
|
||||
|
||||
The virtual methods that you override in this class take care of drawing the
|
||||
table cells, and reacting to events.
|
||||
|
||||
@see TableListBox
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableListBoxModel
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
TableListBoxModel() = default;
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~TableListBoxModel() = default;
|
||||
|
||||
//==============================================================================
|
||||
/** This must return the number of rows currently in the table.
|
||||
|
||||
If the number of rows changes, you must call TableListBox::updateContent() to
|
||||
cause it to refresh the list.
|
||||
*/
|
||||
virtual int getNumRows() = 0;
|
||||
|
||||
/** This must draw the background behind one of the rows in the table.
|
||||
|
||||
The graphics context has its origin at the row's top-left, and your method
|
||||
should fill the area specified by the width and height parameters.
|
||||
|
||||
Note that the rowNumber value may be greater than the number of rows in your
|
||||
list, so be careful that you don't assume it's less than getNumRows().
|
||||
*/
|
||||
virtual void paintRowBackground (Graphics&,
|
||||
int rowNumber,
|
||||
int width, int height,
|
||||
bool rowIsSelected) = 0;
|
||||
|
||||
/** This must draw one of the cells.
|
||||
|
||||
The graphics context's origin will already be set to the top-left of the cell,
|
||||
whose size is specified by (width, height).
|
||||
|
||||
Note that the rowNumber value may be greater than the number of rows in your
|
||||
list, so be careful that you don't assume it's less than getNumRows().
|
||||
*/
|
||||
virtual void paintCell (Graphics&,
|
||||
int rowNumber,
|
||||
int columnId,
|
||||
int width, int height,
|
||||
bool rowIsSelected) = 0;
|
||||
|
||||
//==============================================================================
|
||||
/** This is used to create or update a custom component to go in a cell.
|
||||
|
||||
Any cell may contain a custom component, or can just be drawn with the paintCell() method
|
||||
and handle mouse clicks with cellClicked().
|
||||
|
||||
This method will be called whenever a custom component might need to be updated - e.g.
|
||||
when the table is changed, or TableListBox::updateContent() is called.
|
||||
|
||||
If you don't need a custom component for the specified cell, then return nullptr.
|
||||
(Bear in mind that even if you're not creating a new component, you may still need to
|
||||
delete existingComponentToUpdate if it's non-null).
|
||||
|
||||
If you do want a custom component, and the existingComponentToUpdate is null, then
|
||||
this method must create a new component suitable for the cell, and return it.
|
||||
|
||||
If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
|
||||
by this method. In this case, the method must either update it to make sure it's correctly representing
|
||||
the given cell (which may be different from the one that the component was created for), or it can
|
||||
delete this component and return a new one.
|
||||
*/
|
||||
virtual Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected,
|
||||
Component* existingComponentToUpdate);
|
||||
|
||||
//==============================================================================
|
||||
/** This callback is made when the user clicks on one of the cells in the table.
|
||||
|
||||
The mouse event's coordinates will be relative to the entire table row.
|
||||
@see cellDoubleClicked, backgroundClicked
|
||||
*/
|
||||
virtual void cellClicked (int rowNumber, int columnId, const MouseEvent&);
|
||||
|
||||
/** This callback is made when the user clicks on one of the cells in the table.
|
||||
|
||||
The mouse event's coordinates will be relative to the entire table row.
|
||||
@see cellClicked, backgroundClicked
|
||||
*/
|
||||
virtual void cellDoubleClicked (int rowNumber, int columnId, const MouseEvent&);
|
||||
|
||||
/** This can be overridden to react to the user double-clicking on a part of the list where
|
||||
there are no rows.
|
||||
|
||||
@see cellClicked
|
||||
*/
|
||||
virtual void backgroundClicked (const MouseEvent&);
|
||||
|
||||
//==============================================================================
|
||||
/** This callback is made when the table's sort order is changed.
|
||||
|
||||
This could be because the user has clicked a column header, or because the
|
||||
TableHeaderComponent::setSortColumnId() method was called.
|
||||
|
||||
If you implement this, your method should re-sort the table using the given
|
||||
column as the key.
|
||||
*/
|
||||
virtual void sortOrderChanged (int newSortColumnId, bool isForwards);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the best width for one of the columns.
|
||||
|
||||
If you implement this method, you should measure the width of all the items
|
||||
in this column, and return the best size.
|
||||
|
||||
Returning 0 means that the column shouldn't be changed.
|
||||
|
||||
This is used by TableListBox::autoSizeColumn() and TableListBox::autoSizeAllColumns().
|
||||
*/
|
||||
virtual int getColumnAutoSizeWidth (int columnId);
|
||||
|
||||
/** Returns a tooltip for a particular cell in the table. */
|
||||
virtual String getCellTooltip (int rowNumber, int columnId);
|
||||
|
||||
//==============================================================================
|
||||
/** Override this to be informed when rows are selected or deselected.
|
||||
@see ListBox::selectedRowsChanged()
|
||||
*/
|
||||
virtual void selectedRowsChanged (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the delete key is pressed.
|
||||
@see ListBox::deleteKeyPressed()
|
||||
*/
|
||||
virtual void deleteKeyPressed (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the return key is pressed.
|
||||
@see ListBox::returnKeyPressed()
|
||||
*/
|
||||
virtual void returnKeyPressed (int lastRowSelected);
|
||||
|
||||
/** Override this to be informed when the list is scrolled.
|
||||
|
||||
This might be caused by the user moving the scrollbar, or by programmatic changes
|
||||
to the list position.
|
||||
*/
|
||||
virtual void listWasScrolled();
|
||||
|
||||
/** To allow rows from your table to be dragged-and-dropped, implement this method.
|
||||
|
||||
If this returns a non-null variant then when the user drags a row, the table will try to
|
||||
find a DragAndDropContainer in its parent hierarchy, and will use it to trigger a
|
||||
drag-and-drop operation, using this string as the source description, and the listbox
|
||||
itself as the source component.
|
||||
|
||||
@see getDragSourceCustomData, DragAndDropContainer::startDragging
|
||||
*/
|
||||
virtual var getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A table of cells, using a TableHeaderComponent as its header.
|
||||
|
||||
This component makes it easy to create a table by providing a TableListBoxModel as
|
||||
the data source.
|
||||
|
||||
|
||||
@see TableListBoxModel, TableHeaderComponent
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API TableListBox : public ListBox,
|
||||
private ListBoxModel,
|
||||
private TableHeaderComponent::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a TableListBox.
|
||||
|
||||
The model pointer passed-in can be null, in which case you can set it later
|
||||
with setModel(). The TableListBox does not take ownership of the model - it's
|
||||
the caller's responsibility to manage its lifetime and make sure it
|
||||
doesn't get deleted while still being used.
|
||||
*/
|
||||
TableListBox (const String& componentName = String(),
|
||||
TableListBoxModel* model = nullptr);
|
||||
|
||||
/** Destructor. */
|
||||
~TableListBox() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the TableListBoxModel that is being used for this table.
|
||||
The TableListBox does not take ownership of the model - it's the caller's responsibility
|
||||
to manage its lifetime and make sure it doesn't get deleted while still being used.
|
||||
*/
|
||||
void setModel (TableListBoxModel* newModel);
|
||||
|
||||
/** Returns the model currently in use. */
|
||||
TableListBoxModel* getModel() const noexcept { return model; }
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the header component being used in this table. */
|
||||
TableHeaderComponent& getHeader() const noexcept { return *header; }
|
||||
|
||||
/** Sets the header component to use for the table.
|
||||
The table will take ownership of the component that you pass in, and will delete it
|
||||
when it's no longer needed.
|
||||
The pointer passed in may not be null.
|
||||
*/
|
||||
void setHeader (std::unique_ptr<TableHeaderComponent> newHeader);
|
||||
|
||||
/** Changes the height of the table header component.
|
||||
@see getHeaderHeight
|
||||
*/
|
||||
void setHeaderHeight (int newHeight);
|
||||
|
||||
/** Returns the height of the table header.
|
||||
@see setHeaderHeight
|
||||
*/
|
||||
int getHeaderHeight() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Resizes a column to fit its contents.
|
||||
|
||||
This uses TableListBoxModel::getColumnAutoSizeWidth() to find the best width,
|
||||
and applies that to the column.
|
||||
|
||||
@see autoSizeAllColumns, TableHeaderComponent::setColumnWidth
|
||||
*/
|
||||
void autoSizeColumn (int columnId);
|
||||
|
||||
/** Calls autoSizeColumn() for all columns in the table. */
|
||||
void autoSizeAllColumns();
|
||||
|
||||
/** Enables or disables the auto size options on the popup menu.
|
||||
By default, these are enabled.
|
||||
*/
|
||||
void setAutoSizeMenuOptionShown (bool shouldBeShown) noexcept;
|
||||
|
||||
/** True if the auto-size options should be shown on the menu.
|
||||
@see setAutoSizeMenuOptionShown
|
||||
*/
|
||||
bool isAutoSizeMenuOptionShown() const noexcept { return autoSizeOptionsShown; }
|
||||
|
||||
/** Returns the position of one of the cells in the table.
|
||||
|
||||
If relativeToComponentTopLeft is true, the coordinates are relative to
|
||||
the table component's top-left. The row number isn't checked to see if it's
|
||||
in-range, but the column ID must exist or this will return an empty rectangle.
|
||||
|
||||
If relativeToComponentTopLeft is false, the coordinates are relative to the
|
||||
top-left of the table's top-left cell.
|
||||
*/
|
||||
Rectangle<int> getCellPosition (int columnId, int rowNumber,
|
||||
bool relativeToComponentTopLeft) const;
|
||||
|
||||
/** Returns the component that currently represents a given cell.
|
||||
If the component for this cell is off-screen or if the position is out-of-range,
|
||||
this may return nullptr.
|
||||
@see getCellPosition
|
||||
*/
|
||||
Component* getCellComponent (int columnId, int rowNumber) const;
|
||||
|
||||
/** Scrolls horizontally if necessary to make sure that a particular column is visible.
|
||||
|
||||
@see ListBox::scrollToEnsureRowIsOnscreen
|
||||
*/
|
||||
void scrollToEnsureColumnIsOnscreen (int columnId);
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
int getNumRows() override;
|
||||
/** @internal */
|
||||
void paintListBoxItem (int, Graphics&, int, int, bool) override;
|
||||
/** @internal */
|
||||
Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate) override;
|
||||
/** @internal */
|
||||
void selectedRowsChanged (int row) override;
|
||||
/** @internal */
|
||||
void deleteKeyPressed (int currentSelectedRow) override;
|
||||
/** @internal */
|
||||
void returnKeyPressed (int currentSelectedRow) override;
|
||||
/** @internal */
|
||||
void backgroundClicked (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
void listWasScrolled() override;
|
||||
/** @internal */
|
||||
void tableColumnsChanged (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableColumnsResized (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableSortOrderChanged (TableHeaderComponent*) override;
|
||||
/** @internal */
|
||||
void tableColumnDraggingChanged (TableHeaderComponent*, int) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
class Header;
|
||||
class RowComp;
|
||||
|
||||
TableHeaderComponent* header = nullptr;
|
||||
TableListBoxModel* model;
|
||||
int columnIdNowBeingDragged = 0;
|
||||
bool autoSizeOptionsShown = true;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void updateColumnComponents() const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableListBox)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,334 +1,335 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ToolbarItemComponent;
|
||||
class ToolbarItemFactory;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A toolbar component.
|
||||
|
||||
A toolbar contains a horizontal or vertical strip of ToolbarItemComponents,
|
||||
and looks after their order and layout.
|
||||
|
||||
Items (icon buttons or other custom components) are added to a toolbar using a
|
||||
ToolbarItemFactory - each type of item is given a unique ID number, and a
|
||||
toolbar might contain more than one instance of a particular item type.
|
||||
|
||||
Toolbars can be interactively customised, allowing the user to drag the items
|
||||
around, and to drag items onto or off the toolbar, using the ToolbarItemPalette
|
||||
component as a source of new items.
|
||||
|
||||
@see ToolbarItemFactory, ToolbarItemComponent, ToolbarItemPalette
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API Toolbar : public Component,
|
||||
public DragAndDropContainer,
|
||||
public DragAndDropTarget
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty toolbar component.
|
||||
|
||||
To add some icons or other components to your toolbar, you'll need to
|
||||
create a ToolbarItemFactory class that can create a suitable set of
|
||||
ToolbarItemComponents.
|
||||
|
||||
@see ToolbarItemFactory, ToolbarItemComponents
|
||||
*/
|
||||
Toolbar();
|
||||
|
||||
/** Destructor.
|
||||
|
||||
Any items on the bar will be deleted when the toolbar is deleted.
|
||||
*/
|
||||
~Toolbar() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the bar's orientation.
|
||||
@see isVertical
|
||||
*/
|
||||
void setVertical (bool shouldBeVertical);
|
||||
|
||||
/** Returns true if the bar is set to be vertical, or false if it's horizontal.
|
||||
|
||||
You can change the bar's orientation with setVertical().
|
||||
*/
|
||||
bool isVertical() const noexcept { return vertical; }
|
||||
|
||||
/** Returns the depth of the bar.
|
||||
|
||||
If the bar is horizontal, this will return its height; if it's vertical, it
|
||||
will return its width.
|
||||
|
||||
@see getLength
|
||||
*/
|
||||
int getThickness() const noexcept;
|
||||
|
||||
/** Returns the length of the bar.
|
||||
|
||||
If the bar is horizontal, this will return its width; if it's vertical, it
|
||||
will return its height.
|
||||
|
||||
@see getThickness
|
||||
*/
|
||||
int getLength() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Deletes all items from the bar.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/** Adds an item to the toolbar.
|
||||
|
||||
The factory's ToolbarItemFactory::createItem() will be called by this method
|
||||
to create the component that will actually be added to the bar.
|
||||
|
||||
The new item will be inserted at the specified index (if the index is -1, it
|
||||
will be added to the right-hand or bottom end of the bar).
|
||||
|
||||
Once added, the component will be automatically deleted by this object when it
|
||||
is no longer needed.
|
||||
|
||||
@see ToolbarItemFactory
|
||||
*/
|
||||
void addItem (ToolbarItemFactory& factory,
|
||||
int itemId,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Deletes one of the items from the bar. */
|
||||
void removeToolbarItem (int itemIndex);
|
||||
|
||||
/** Removes an item from the bar and returns it. */
|
||||
ToolbarItemComponent* removeAndReturnItem (int itemIndex);
|
||||
|
||||
/** Returns the number of items currently on the toolbar.
|
||||
|
||||
@see getItemId, getItemComponent
|
||||
*/
|
||||
int getNumItems() const noexcept;
|
||||
|
||||
/** Returns the ID of the item with the given index.
|
||||
|
||||
If the index is less than zero or greater than the number of items,
|
||||
this will return nullptr.
|
||||
|
||||
@see getNumItems
|
||||
*/
|
||||
int getItemId (int itemIndex) const noexcept;
|
||||
|
||||
/** Returns the component being used for the item with the given index.
|
||||
|
||||
If the index is less than zero or greater than the number of items,
|
||||
this will return nullptr.
|
||||
|
||||
@see getNumItems
|
||||
*/
|
||||
ToolbarItemComponent* getItemComponent (int itemIndex) const noexcept;
|
||||
|
||||
/** Clears this toolbar and adds to it the default set of items that the specified
|
||||
factory creates.
|
||||
|
||||
@see ToolbarItemFactory::getDefaultItemSet
|
||||
*/
|
||||
void addDefaultItems (ToolbarItemFactory& factoryToUse);
|
||||
|
||||
//==============================================================================
|
||||
/** Options for the way items should be displayed.
|
||||
@see setStyle, getStyle
|
||||
*/
|
||||
enum ToolbarItemStyle
|
||||
{
|
||||
iconsOnly, /**< Means that the toolbar should just contain icons. */
|
||||
iconsWithText, /**< Means that the toolbar should have text labels under each icon. */
|
||||
textOnly /**< Means that the toolbar only display text labels for each item. */
|
||||
};
|
||||
|
||||
/** Returns the toolbar's current style.
|
||||
@see ToolbarItemStyle, setStyle
|
||||
*/
|
||||
ToolbarItemStyle getStyle() const noexcept { return toolbarStyle; }
|
||||
|
||||
/** Changes the toolbar's current style.
|
||||
@see ToolbarItemStyle, getStyle, ToolbarItemComponent::setStyle
|
||||
*/
|
||||
void setStyle (const ToolbarItemStyle& newStyle);
|
||||
|
||||
//==============================================================================
|
||||
/** Flags used by the showCustomisationDialog() method. */
|
||||
enum CustomisationFlags
|
||||
{
|
||||
allowIconsOnlyChoice = 1, /**< If this flag is specified, the customisation dialog can
|
||||
show the "icons only" option on its choice of toolbar styles. */
|
||||
allowIconsWithTextChoice = 2, /**< If this flag is specified, the customisation dialog can
|
||||
show the "icons with text" option on its choice of toolbar styles. */
|
||||
allowTextOnlyChoice = 4, /**< If this flag is specified, the customisation dialog can
|
||||
show the "text only" option on its choice of toolbar styles. */
|
||||
showResetToDefaultsButton = 8, /**< If this flag is specified, the customisation dialog can
|
||||
show a button to reset the toolbar to its default set of items. */
|
||||
|
||||
allCustomisationOptionsEnabled = (allowIconsOnlyChoice | allowIconsWithTextChoice | allowTextOnlyChoice | showResetToDefaultsButton)
|
||||
};
|
||||
|
||||
/** Pops up a modal dialog box that allows this toolbar to be customised by the user.
|
||||
|
||||
The dialog contains a ToolbarItemPalette and various controls for editing other
|
||||
aspects of the toolbar. The dialog box will be opened modally, but the method will
|
||||
return immediately.
|
||||
|
||||
The factory is used to determine the set of items that will be shown on the
|
||||
palette.
|
||||
|
||||
The optionFlags parameter is a bitwise-or of values from the CustomisationFlags
|
||||
enum.
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
void showCustomisationDialog (ToolbarItemFactory& factory,
|
||||
int optionFlags = allCustomisationOptionsEnabled);
|
||||
|
||||
/** Turns on or off the toolbar's editing mode, in which its items can be
|
||||
rearranged by the user.
|
||||
|
||||
(In most cases it's easier just to use showCustomisationDialog() instead of
|
||||
trying to enable editing directly).
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
void setEditingActive (bool editingEnabled);
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the toolbar.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1003200, /**< A colour to use to fill the toolbar's background. For
|
||||
more control over this, override LookAndFeel::paintToolbarBackground(). */
|
||||
separatorColourId = 0x1003210, /**< A colour to use to draw the separator lines. */
|
||||
|
||||
buttonMouseOverBackgroundColourId = 0x1003220, /**< A colour used to paint the background of buttons when the mouse is
|
||||
over them. */
|
||||
buttonMouseDownBackgroundColourId = 0x1003230, /**< A colour used to paint the background of buttons when the mouse is
|
||||
held down on them. */
|
||||
|
||||
labelTextColourId = 0x1003240, /**< A colour to use for drawing the text under buttons
|
||||
when the style is set to iconsWithText or textOnly. */
|
||||
|
||||
editingModeOutlineColourId = 0x1003250 /**< A colour to use for an outline around buttons when
|
||||
the customisation dialog is active and the mouse moves over them. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string that represents the toolbar's current set of items.
|
||||
|
||||
This lets you later restore the same item layout using restoreFromString().
|
||||
|
||||
@see restoreFromString
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Restores a set of items that was previously stored in a string by the toString()
|
||||
method.
|
||||
|
||||
The factory object is used to create any item components that are needed.
|
||||
|
||||
@see toString
|
||||
*/
|
||||
bool restoreFromString (ToolbarItemFactory& factoryToUse,
|
||||
const String& savedVersion);
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) = 0;
|
||||
|
||||
virtual Button* createToolbarMissingItemsButton (Toolbar&) = 0;
|
||||
|
||||
virtual void paintToolbarButtonBackground (Graphics&, int width, int height,
|
||||
bool isMouseOver, bool isMouseDown,
|
||||
ToolbarItemComponent&) = 0;
|
||||
|
||||
virtual void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
|
||||
const String& text, ToolbarItemComponent&) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
void mouseDown (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
bool isInterestedInDragSource (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDragMove (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDragExit (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDropped (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void updateAllItemPositions (bool animate);
|
||||
/** @internal */
|
||||
static ToolbarItemComponent* createItem (ToolbarItemFactory&, int itemId);
|
||||
/** @internal */
|
||||
static const char* const toolbarDragDescriptor;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::unique_ptr<Button> missingItemsButton;
|
||||
bool vertical = false, isEditingActive = false;
|
||||
ToolbarItemStyle toolbarStyle = iconsOnly;
|
||||
class MissingItemsComponent;
|
||||
friend class MissingItemsComponent;
|
||||
OwnedArray<ToolbarItemComponent> items;
|
||||
class Spacer;
|
||||
class CustomisationDialog;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void showMissingItems();
|
||||
void addItemInternal (ToolbarItemFactory& factory, int itemId, int insertIndex);
|
||||
|
||||
ToolbarItemComponent* getNextActiveComponent (int index, int delta) const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Toolbar)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
class ToolbarItemComponent;
|
||||
class ToolbarItemFactory;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A toolbar component.
|
||||
|
||||
A toolbar contains a horizontal or vertical strip of ToolbarItemComponents,
|
||||
and looks after their order and layout.
|
||||
|
||||
Items (icon buttons or other custom components) are added to a toolbar using a
|
||||
ToolbarItemFactory - each type of item is given a unique ID number, and a
|
||||
toolbar might contain more than one instance of a particular item type.
|
||||
|
||||
Toolbars can be interactively customised, allowing the user to drag the items
|
||||
around, and to drag items onto or off the toolbar, using the ToolbarItemPalette
|
||||
component as a source of new items.
|
||||
|
||||
@see ToolbarItemFactory, ToolbarItemComponent, ToolbarItemPalette
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API Toolbar : public Component,
|
||||
public DragAndDropContainer,
|
||||
public DragAndDropTarget
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty toolbar component.
|
||||
|
||||
To add some icons or other components to your toolbar, you'll need to
|
||||
create a ToolbarItemFactory class that can create a suitable set of
|
||||
ToolbarItemComponents.
|
||||
|
||||
@see ToolbarItemFactory, ToolbarItemComponents
|
||||
*/
|
||||
Toolbar();
|
||||
|
||||
/** Destructor.
|
||||
|
||||
Any items on the bar will be deleted when the toolbar is deleted.
|
||||
*/
|
||||
~Toolbar() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Changes the bar's orientation.
|
||||
@see isVertical
|
||||
*/
|
||||
void setVertical (bool shouldBeVertical);
|
||||
|
||||
/** Returns true if the bar is set to be vertical, or false if it's horizontal.
|
||||
|
||||
You can change the bar's orientation with setVertical().
|
||||
*/
|
||||
bool isVertical() const noexcept { return vertical; }
|
||||
|
||||
/** Returns the depth of the bar.
|
||||
|
||||
If the bar is horizontal, this will return its height; if it's vertical, it
|
||||
will return its width.
|
||||
|
||||
@see getLength
|
||||
*/
|
||||
int getThickness() const noexcept;
|
||||
|
||||
/** Returns the length of the bar.
|
||||
|
||||
If the bar is horizontal, this will return its width; if it's vertical, it
|
||||
will return its height.
|
||||
|
||||
@see getThickness
|
||||
*/
|
||||
int getLength() const noexcept;
|
||||
|
||||
//==============================================================================
|
||||
/** Deletes all items from the bar.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/** Adds an item to the toolbar.
|
||||
|
||||
The factory's ToolbarItemFactory::createItem() will be called by this method
|
||||
to create the component that will actually be added to the bar.
|
||||
|
||||
The new item will be inserted at the specified index (if the index is -1, it
|
||||
will be added to the right-hand or bottom end of the bar).
|
||||
|
||||
Once added, the component will be automatically deleted by this object when it
|
||||
is no longer needed.
|
||||
|
||||
@see ToolbarItemFactory
|
||||
*/
|
||||
void addItem (ToolbarItemFactory& factory,
|
||||
int itemId,
|
||||
int insertIndex = -1);
|
||||
|
||||
/** Deletes one of the items from the bar. */
|
||||
void removeToolbarItem (int itemIndex);
|
||||
|
||||
/** Removes an item from the bar and returns it. */
|
||||
ToolbarItemComponent* removeAndReturnItem (int itemIndex);
|
||||
|
||||
/** Returns the number of items currently on the toolbar.
|
||||
|
||||
@see getItemId, getItemComponent
|
||||
*/
|
||||
int getNumItems() const noexcept;
|
||||
|
||||
/** Returns the ID of the item with the given index.
|
||||
|
||||
If the index is less than zero or greater than the number of items,
|
||||
this will return nullptr.
|
||||
|
||||
@see getNumItems
|
||||
*/
|
||||
int getItemId (int itemIndex) const noexcept;
|
||||
|
||||
/** Returns the component being used for the item with the given index.
|
||||
|
||||
If the index is less than zero or greater than the number of items,
|
||||
this will return nullptr.
|
||||
|
||||
@see getNumItems
|
||||
*/
|
||||
ToolbarItemComponent* getItemComponent (int itemIndex) const noexcept;
|
||||
|
||||
/** Clears this toolbar and adds to it the default set of items that the specified
|
||||
factory creates.
|
||||
|
||||
@see ToolbarItemFactory::getDefaultItemSet
|
||||
*/
|
||||
void addDefaultItems (ToolbarItemFactory& factoryToUse);
|
||||
|
||||
//==============================================================================
|
||||
/** Options for the way items should be displayed.
|
||||
@see setStyle, getStyle
|
||||
*/
|
||||
enum ToolbarItemStyle
|
||||
{
|
||||
iconsOnly, /**< Means that the toolbar should just contain icons. */
|
||||
iconsWithText, /**< Means that the toolbar should have text labels under each icon. */
|
||||
textOnly /**< Means that the toolbar only display text labels for each item. */
|
||||
};
|
||||
|
||||
/** Returns the toolbar's current style.
|
||||
@see ToolbarItemStyle, setStyle
|
||||
*/
|
||||
ToolbarItemStyle getStyle() const noexcept { return toolbarStyle; }
|
||||
|
||||
/** Changes the toolbar's current style.
|
||||
@see ToolbarItemStyle, getStyle, ToolbarItemComponent::setStyle
|
||||
*/
|
||||
void setStyle (const ToolbarItemStyle& newStyle);
|
||||
|
||||
//==============================================================================
|
||||
/** Flags used by the showCustomisationDialog() method. */
|
||||
enum CustomisationFlags
|
||||
{
|
||||
allowIconsOnlyChoice = 1, /**< If this flag is specified, the customisation dialog can
|
||||
show the "icons only" option on its choice of toolbar styles. */
|
||||
allowIconsWithTextChoice = 2, /**< If this flag is specified, the customisation dialog can
|
||||
show the "icons with text" option on its choice of toolbar styles. */
|
||||
allowTextOnlyChoice = 4, /**< If this flag is specified, the customisation dialog can
|
||||
show the "text only" option on its choice of toolbar styles. */
|
||||
showResetToDefaultsButton = 8, /**< If this flag is specified, the customisation dialog can
|
||||
show a button to reset the toolbar to its default set of items. */
|
||||
|
||||
allCustomisationOptionsEnabled = (allowIconsOnlyChoice | allowIconsWithTextChoice | allowTextOnlyChoice | showResetToDefaultsButton)
|
||||
};
|
||||
|
||||
/** Pops up a modal dialog box that allows this toolbar to be customised by the user.
|
||||
|
||||
The dialog contains a ToolbarItemPalette and various controls for editing other
|
||||
aspects of the toolbar. The dialog box will be opened modally, but the method will
|
||||
return immediately.
|
||||
|
||||
The factory is used to determine the set of items that will be shown on the
|
||||
palette.
|
||||
|
||||
The optionFlags parameter is a bitwise-or of values from the CustomisationFlags
|
||||
enum.
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
void showCustomisationDialog (ToolbarItemFactory& factory,
|
||||
int optionFlags = allCustomisationOptionsEnabled);
|
||||
|
||||
/** Turns on or off the toolbar's editing mode, in which its items can be
|
||||
rearranged by the user.
|
||||
|
||||
(In most cases it's easier just to use showCustomisationDialog() instead of
|
||||
trying to enable editing directly).
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
void setEditingActive (bool editingEnabled);
|
||||
|
||||
//==============================================================================
|
||||
/** A set of colour IDs to use to change the colour of various aspects of the toolbar.
|
||||
|
||||
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
||||
methods.
|
||||
|
||||
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
||||
*/
|
||||
enum ColourIds
|
||||
{
|
||||
backgroundColourId = 0x1003200, /**< A colour to use to fill the toolbar's background. For
|
||||
more control over this, override LookAndFeel::paintToolbarBackground(). */
|
||||
separatorColourId = 0x1003210, /**< A colour to use to draw the separator lines. */
|
||||
|
||||
buttonMouseOverBackgroundColourId = 0x1003220, /**< A colour used to paint the background of buttons when the mouse is
|
||||
over them. */
|
||||
buttonMouseDownBackgroundColourId = 0x1003230, /**< A colour used to paint the background of buttons when the mouse is
|
||||
held down on them. */
|
||||
|
||||
labelTextColourId = 0x1003240, /**< A colour to use for drawing the text under buttons
|
||||
when the style is set to iconsWithText or textOnly. */
|
||||
|
||||
editingModeOutlineColourId = 0x1003250 /**< A colour to use for an outline around buttons when
|
||||
the customisation dialog is active and the mouse moves over them. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a string that represents the toolbar's current set of items.
|
||||
|
||||
This lets you later restore the same item layout using restoreFromString().
|
||||
|
||||
@see restoreFromString
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/** Restores a set of items that was previously stored in a string by the toString()
|
||||
method.
|
||||
|
||||
The factory object is used to create any item components that are needed.
|
||||
|
||||
@see toString
|
||||
*/
|
||||
bool restoreFromString (ToolbarItemFactory& factoryToUse,
|
||||
const String& savedVersion);
|
||||
|
||||
//==============================================================================
|
||||
/** This abstract base class is implemented by LookAndFeel classes. */
|
||||
struct JUCE_API LookAndFeelMethods
|
||||
{
|
||||
virtual ~LookAndFeelMethods() = default;
|
||||
|
||||
virtual void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) = 0;
|
||||
|
||||
virtual Button* createToolbarMissingItemsButton (Toolbar&) = 0;
|
||||
|
||||
virtual void paintToolbarButtonBackground (Graphics&, int width, int height,
|
||||
bool isMouseOver, bool isMouseDown,
|
||||
ToolbarItemComponent&) = 0;
|
||||
|
||||
virtual void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
|
||||
const String& text, ToolbarItemComponent&) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paint (Graphics&) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
/** @internal */
|
||||
void mouseDown (const MouseEvent&) override;
|
||||
/** @internal */
|
||||
bool isInterestedInDragSource (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDragMove (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDragExit (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void itemDropped (const SourceDetails&) override;
|
||||
/** @internal */
|
||||
void lookAndFeelChanged() override;
|
||||
/** @internal */
|
||||
void updateAllItemPositions (bool animate);
|
||||
/** @internal */
|
||||
static ToolbarItemComponent* createItem (ToolbarItemFactory&, int itemId);
|
||||
/** @internal */
|
||||
static const char* const toolbarDragDescriptor;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
std::unique_ptr<Button> missingItemsButton;
|
||||
bool vertical = false, isEditingActive = false;
|
||||
ToolbarItemStyle toolbarStyle = iconsOnly;
|
||||
class MissingItemsComponent;
|
||||
friend class MissingItemsComponent;
|
||||
OwnedArray<ToolbarItemComponent> items;
|
||||
class Spacer;
|
||||
class CustomisationDialog;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void initMissingItemButton();
|
||||
void showMissingItems();
|
||||
void addItemInternal (ToolbarItemFactory& factory, int itemId, int insertIndex);
|
||||
|
||||
ToolbarItemComponent* getNextActiveComponent (int index, int delta) const;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Toolbar)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,255 +1,255 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ToolbarItemFactory::ToolbarItemFactory() {}
|
||||
ToolbarItemFactory::~ToolbarItemFactory() {}
|
||||
|
||||
//==============================================================================
|
||||
class ToolbarItemComponent::ItemDragAndDropOverlayComponent : public Component
|
||||
{
|
||||
public:
|
||||
ItemDragAndDropOverlayComponent()
|
||||
: isDragging (false)
|
||||
{
|
||||
setAlwaysOnTop (true);
|
||||
setRepaintsOnMouseActivity (true);
|
||||
setMouseCursor (MouseCursor::DraggingHandCursor);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
if (isMouseOverOrDragging()
|
||||
&& tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
{
|
||||
g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
|
||||
g.drawRect (getLocalBounds(), jmin (2, (getWidth() - 1) / 2,
|
||||
(getHeight() - 1) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
isDragging = false;
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->dragOffsetX = e.x;
|
||||
tc->dragOffsetY = e.y;
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
if (e.mouseWasDraggedSinceMouseDown() && ! isDragging)
|
||||
{
|
||||
isDragging = true;
|
||||
|
||||
if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
|
||||
{
|
||||
dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image(), true, nullptr, &e.source);
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->isBeingDragged = true;
|
||||
|
||||
if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
tc->setVisible (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent&) override
|
||||
{
|
||||
isDragging = false;
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->isBeingDragged = false;
|
||||
|
||||
if (Toolbar* const tb = tc->getToolbar())
|
||||
tb->updateAllItemPositions (true);
|
||||
else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
delete tc;
|
||||
}
|
||||
}
|
||||
|
||||
void parentSizeChanged() override
|
||||
{
|
||||
setBounds (0, 0, getParentWidth(), getParentHeight());
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
bool isDragging;
|
||||
|
||||
ToolbarItemComponent* getToolbarItemComponent() const noexcept
|
||||
{
|
||||
return dynamic_cast<ToolbarItemComponent*> (getParentComponent());
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
|
||||
const String& labelText,
|
||||
const bool isBeingUsedAsAButton_)
|
||||
: Button (labelText),
|
||||
itemId (itemId_),
|
||||
mode (normalMode),
|
||||
toolbarStyle (Toolbar::iconsOnly),
|
||||
dragOffsetX (0),
|
||||
dragOffsetY (0),
|
||||
isActive (true),
|
||||
isBeingDragged (false),
|
||||
isBeingUsedAsAButton (isBeingUsedAsAButton_)
|
||||
{
|
||||
// Your item ID can't be 0!
|
||||
jassert (itemId_ != 0);
|
||||
}
|
||||
|
||||
ToolbarItemComponent::~ToolbarItemComponent()
|
||||
{
|
||||
overlayComp.reset();
|
||||
}
|
||||
|
||||
Toolbar* ToolbarItemComponent::getToolbar() const
|
||||
{
|
||||
return dynamic_cast<Toolbar*> (getParentComponent());
|
||||
}
|
||||
|
||||
bool ToolbarItemComponent::isToolbarVertical() const
|
||||
{
|
||||
const Toolbar* const t = getToolbar();
|
||||
return t != nullptr && t->isVertical();
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
|
||||
{
|
||||
if (toolbarStyle != newStyle)
|
||||
{
|
||||
toolbarStyle = newStyle;
|
||||
repaint();
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
|
||||
{
|
||||
if (isBeingUsedAsAButton)
|
||||
getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
|
||||
over, down, *this);
|
||||
|
||||
if (toolbarStyle != Toolbar::iconsOnly)
|
||||
{
|
||||
auto indent = contentArea.getX();
|
||||
auto y = indent;
|
||||
auto h = getHeight() - indent * 2;
|
||||
|
||||
if (toolbarStyle == Toolbar::iconsWithText)
|
||||
{
|
||||
y = contentArea.getBottom() + indent / 2;
|
||||
h -= contentArea.getHeight();
|
||||
}
|
||||
|
||||
getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
|
||||
getButtonText(), *this);
|
||||
}
|
||||
|
||||
if (! contentArea.isEmpty())
|
||||
{
|
||||
Graphics::ScopedSaveState ss (g);
|
||||
|
||||
g.reduceClipRegion (contentArea);
|
||||
g.setOrigin (contentArea.getPosition());
|
||||
|
||||
paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::resized()
|
||||
{
|
||||
if (toolbarStyle != Toolbar::textOnly)
|
||||
{
|
||||
const int indent = jmin (proportionOfWidth (0.08f),
|
||||
proportionOfHeight (0.08f));
|
||||
|
||||
contentArea = Rectangle<int> (indent, indent,
|
||||
getWidth() - indent * 2,
|
||||
toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
|
||||
: (getHeight() - indent * 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
contentArea = {};
|
||||
}
|
||||
|
||||
contentAreaChanged (contentArea);
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
|
||||
{
|
||||
if (mode != newMode)
|
||||
{
|
||||
mode = newMode;
|
||||
repaint();
|
||||
|
||||
if (mode == normalMode)
|
||||
{
|
||||
overlayComp.reset();
|
||||
}
|
||||
else if (overlayComp == nullptr)
|
||||
{
|
||||
overlayComp.reset (new ItemDragAndDropOverlayComponent());
|
||||
addAndMakeVisible (overlayComp.get());
|
||||
overlayComp->parentSizeChanged();
|
||||
}
|
||||
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ToolbarItemComponent::createAccessibilityHandler()
|
||||
{
|
||||
const auto shouldItemBeAccessible = (itemId != ToolbarItemFactory::separatorBarId
|
||||
&& itemId != ToolbarItemFactory::spacerId
|
||||
&& itemId != ToolbarItemFactory::flexibleSpacerId);
|
||||
|
||||
if (! shouldItemBeAccessible)
|
||||
return nullptr;
|
||||
|
||||
return std::make_unique<ButtonAccessibilityHandler> (*this, AccessibilityRole::button);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ToolbarItemFactory::ToolbarItemFactory() {}
|
||||
ToolbarItemFactory::~ToolbarItemFactory() {}
|
||||
|
||||
//==============================================================================
|
||||
class ToolbarItemComponent::ItemDragAndDropOverlayComponent : public Component
|
||||
{
|
||||
public:
|
||||
ItemDragAndDropOverlayComponent()
|
||||
: isDragging (false)
|
||||
{
|
||||
setAlwaysOnTop (true);
|
||||
setRepaintsOnMouseActivity (true);
|
||||
setMouseCursor (MouseCursor::DraggingHandCursor);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
if (isMouseOverOrDragging()
|
||||
&& tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
{
|
||||
g.setColour (findColour (Toolbar::editingModeOutlineColourId, true));
|
||||
g.drawRect (getLocalBounds(), jmin (2, (getWidth() - 1) / 2,
|
||||
(getHeight() - 1) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDown (const MouseEvent& e) override
|
||||
{
|
||||
isDragging = false;
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->dragOffsetX = e.x;
|
||||
tc->dragOffsetY = e.y;
|
||||
}
|
||||
}
|
||||
|
||||
void mouseDrag (const MouseEvent& e) override
|
||||
{
|
||||
if (e.mouseWasDraggedSinceMouseDown() && ! isDragging)
|
||||
{
|
||||
isDragging = true;
|
||||
|
||||
if (DragAndDropContainer* const dnd = DragAndDropContainer::findParentDragContainerFor (this))
|
||||
{
|
||||
dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), ScaledImage(), true, nullptr, &e.source);
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->isBeingDragged = true;
|
||||
|
||||
if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
tc->setVisible (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent&) override
|
||||
{
|
||||
isDragging = false;
|
||||
|
||||
if (ToolbarItemComponent* const tc = getToolbarItemComponent())
|
||||
{
|
||||
tc->isBeingDragged = false;
|
||||
|
||||
if (Toolbar* const tb = tc->getToolbar())
|
||||
tb->updateAllItemPositions (true);
|
||||
else if (tc->getEditingMode() == ToolbarItemComponent::editableOnToolbar)
|
||||
delete tc;
|
||||
}
|
||||
}
|
||||
|
||||
void parentSizeChanged() override
|
||||
{
|
||||
setBounds (0, 0, getParentWidth(), getParentHeight());
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
bool isDragging;
|
||||
|
||||
ToolbarItemComponent* getToolbarItemComponent() const noexcept
|
||||
{
|
||||
return dynamic_cast<ToolbarItemComponent*> (getParentComponent());
|
||||
}
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent)
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
ToolbarItemComponent::ToolbarItemComponent (const int itemId_,
|
||||
const String& labelText,
|
||||
const bool isBeingUsedAsAButton_)
|
||||
: Button (labelText),
|
||||
itemId (itemId_),
|
||||
mode (normalMode),
|
||||
toolbarStyle (Toolbar::iconsOnly),
|
||||
dragOffsetX (0),
|
||||
dragOffsetY (0),
|
||||
isActive (true),
|
||||
isBeingDragged (false),
|
||||
isBeingUsedAsAButton (isBeingUsedAsAButton_)
|
||||
{
|
||||
// Your item ID can't be 0!
|
||||
jassert (itemId_ != 0);
|
||||
}
|
||||
|
||||
ToolbarItemComponent::~ToolbarItemComponent()
|
||||
{
|
||||
overlayComp.reset();
|
||||
}
|
||||
|
||||
Toolbar* ToolbarItemComponent::getToolbar() const
|
||||
{
|
||||
return dynamic_cast<Toolbar*> (getParentComponent());
|
||||
}
|
||||
|
||||
bool ToolbarItemComponent::isToolbarVertical() const
|
||||
{
|
||||
const Toolbar* const t = getToolbar();
|
||||
return t != nullptr && t->isVertical();
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::setStyle (const Toolbar::ToolbarItemStyle& newStyle)
|
||||
{
|
||||
if (toolbarStyle != newStyle)
|
||||
{
|
||||
toolbarStyle = newStyle;
|
||||
repaint();
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::paintButton (Graphics& g, const bool over, const bool down)
|
||||
{
|
||||
if (isBeingUsedAsAButton)
|
||||
getLookAndFeel().paintToolbarButtonBackground (g, getWidth(), getHeight(),
|
||||
over, down, *this);
|
||||
|
||||
if (toolbarStyle != Toolbar::iconsOnly)
|
||||
{
|
||||
auto indent = contentArea.getX();
|
||||
auto y = indent;
|
||||
auto h = getHeight() - indent * 2;
|
||||
|
||||
if (toolbarStyle == Toolbar::iconsWithText)
|
||||
{
|
||||
y = contentArea.getBottom() + indent / 2;
|
||||
h -= contentArea.getHeight();
|
||||
}
|
||||
|
||||
getLookAndFeel().paintToolbarButtonLabel (g, indent, y, getWidth() - indent * 2, h,
|
||||
getButtonText(), *this);
|
||||
}
|
||||
|
||||
if (! contentArea.isEmpty())
|
||||
{
|
||||
Graphics::ScopedSaveState ss (g);
|
||||
|
||||
g.reduceClipRegion (contentArea);
|
||||
g.setOrigin (contentArea.getPosition());
|
||||
|
||||
paintButtonArea (g, contentArea.getWidth(), contentArea.getHeight(), over, down);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::resized()
|
||||
{
|
||||
if (toolbarStyle != Toolbar::textOnly)
|
||||
{
|
||||
const int indent = jmin (proportionOfWidth (0.08f),
|
||||
proportionOfHeight (0.08f));
|
||||
|
||||
contentArea = Rectangle<int> (indent, indent,
|
||||
getWidth() - indent * 2,
|
||||
toolbarStyle == Toolbar::iconsWithText ? proportionOfHeight (0.55f)
|
||||
: (getHeight() - indent * 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
contentArea = {};
|
||||
}
|
||||
|
||||
contentAreaChanged (contentArea);
|
||||
}
|
||||
|
||||
void ToolbarItemComponent::setEditingMode (const ToolbarEditingMode newMode)
|
||||
{
|
||||
if (mode != newMode)
|
||||
{
|
||||
mode = newMode;
|
||||
repaint();
|
||||
|
||||
if (mode == normalMode)
|
||||
{
|
||||
overlayComp.reset();
|
||||
}
|
||||
else if (overlayComp == nullptr)
|
||||
{
|
||||
overlayComp.reset (new ItemDragAndDropOverlayComponent());
|
||||
addAndMakeVisible (overlayComp.get());
|
||||
overlayComp->parentSizeChanged();
|
||||
}
|
||||
|
||||
resized();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ToolbarItemComponent::createAccessibilityHandler()
|
||||
{
|
||||
const auto shouldItemBeAccessible = (itemId != ToolbarItemFactory::separatorBarId
|
||||
&& itemId != ToolbarItemFactory::spacerId
|
||||
&& itemId != ToolbarItemFactory::flexibleSpacerId);
|
||||
|
||||
if (! shouldItemBeAccessible)
|
||||
return createIgnoredAccessibilityHandler (*this);
|
||||
|
||||
return std::make_unique<ButtonAccessibilityHandler> (*this, AccessibilityRole::button);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,209 +1,209 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that can be used as one of the items in a Toolbar.
|
||||
|
||||
Each of the items on a toolbar must be a component derived from ToolbarItemComponent,
|
||||
and these objects are always created by a ToolbarItemFactory - see the ToolbarItemFactory
|
||||
class for further info about creating them.
|
||||
|
||||
The ToolbarItemComponent class is actually a button, but can be used to hold non-button
|
||||
components too. To do this, set the value of isBeingUsedAsAButton to false when
|
||||
calling the constructor, and override contentAreaChanged(), in which you can position
|
||||
any sub-components you need to add.
|
||||
|
||||
To add basic buttons without writing a special subclass, have a look at the
|
||||
ToolbarButton class.
|
||||
|
||||
@see ToolbarButton, Toolbar, ToolbarItemFactory
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemComponent : public Button
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructor.
|
||||
|
||||
@param itemId the ID of the type of toolbar item which this represents
|
||||
@param labelText the text to display if the toolbar's style is set to
|
||||
Toolbar::iconsWithText or Toolbar::textOnly
|
||||
@param isBeingUsedAsAButton set this to false if you don't want the button
|
||||
to draw itself with button over/down states when the mouse
|
||||
moves over it or clicks
|
||||
*/
|
||||
ToolbarItemComponent (int itemId,
|
||||
const String& labelText,
|
||||
bool isBeingUsedAsAButton);
|
||||
|
||||
/** Destructor. */
|
||||
~ToolbarItemComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the item type ID that this component represents.
|
||||
This value is in the constructor.
|
||||
*/
|
||||
int getItemId() const noexcept { return itemId; }
|
||||
|
||||
/** Returns the toolbar that contains this component, or nullptr if it's not currently
|
||||
inside one.
|
||||
*/
|
||||
Toolbar* getToolbar() const;
|
||||
|
||||
/** Returns true if this component is currently inside a toolbar which is vertical.
|
||||
@see Toolbar::isVertical
|
||||
*/
|
||||
bool isToolbarVertical() const;
|
||||
|
||||
/** Returns the current style setting of this item.
|
||||
|
||||
Styles are listed in the Toolbar::ToolbarItemStyle enum.
|
||||
@see setStyle, Toolbar::getStyle
|
||||
*/
|
||||
Toolbar::ToolbarItemStyle getStyle() const noexcept { return toolbarStyle; }
|
||||
|
||||
/** Changes the current style setting of this item.
|
||||
|
||||
Styles are listed in the Toolbar::ToolbarItemStyle enum, and are automatically updated
|
||||
by the toolbar that holds this item.
|
||||
|
||||
@see setStyle, Toolbar::setStyle
|
||||
*/
|
||||
virtual void setStyle (const Toolbar::ToolbarItemStyle& newStyle);
|
||||
|
||||
/** Returns the area of the component that should be used to display the button image or
|
||||
other contents of the item.
|
||||
|
||||
This content area may change when the item's style changes, and may leave a space around the
|
||||
edge of the component where the text label can be shown.
|
||||
|
||||
@see contentAreaChanged
|
||||
*/
|
||||
Rectangle<int> getContentArea() const noexcept { return contentArea; }
|
||||
|
||||
//==============================================================================
|
||||
/** This method must return the size criteria for this item, based on a given toolbar
|
||||
size and orientation.
|
||||
|
||||
The preferredSize, minSize and maxSize values must all be set by your implementation
|
||||
method. If the toolbar is horizontal, these will be the width of the item; for a vertical
|
||||
toolbar, they refer to the item's height.
|
||||
|
||||
The preferredSize is the size that the component would like to be, and this must be
|
||||
between the min and max sizes. For a fixed-size item, simply set all three variables to
|
||||
the same value.
|
||||
|
||||
The toolbarThickness parameter tells you the depth of the toolbar - the same as calling
|
||||
Toolbar::getThickness().
|
||||
|
||||
The isToolbarVertical parameter tells you whether the bar is oriented horizontally or
|
||||
vertically.
|
||||
*/
|
||||
virtual bool getToolbarItemSizes (int toolbarThickness,
|
||||
bool isToolbarVertical,
|
||||
int& preferredSize,
|
||||
int& minSize,
|
||||
int& maxSize) = 0;
|
||||
|
||||
/** Your subclass should use this method to draw its content area.
|
||||
|
||||
The graphics object that is passed-in will have been clipped and had its origin
|
||||
moved to fit the content area as specified get getContentArea(). The width and height
|
||||
parameters are the width and height of the content area.
|
||||
|
||||
If the component you're writing isn't a button, you can just do nothing in this method.
|
||||
*/
|
||||
virtual void paintButtonArea (Graphics& g,
|
||||
int width, int height,
|
||||
bool isMouseOver, bool isMouseDown) = 0;
|
||||
|
||||
/** Callback to indicate that the content area of this item has changed.
|
||||
|
||||
This might be because the component was resized, or because the style changed and
|
||||
the space needed for the text label is different.
|
||||
|
||||
See getContentArea() for a description of what the area is.
|
||||
*/
|
||||
virtual void contentAreaChanged (const Rectangle<int>& newBounds) = 0;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Editing modes.
|
||||
These are used by setEditingMode(), but will be rarely needed in user code.
|
||||
*/
|
||||
enum ToolbarEditingMode
|
||||
{
|
||||
normalMode = 0, /**< Means that the component is active, inside a toolbar. */
|
||||
editableOnToolbar, /**< Means that the component is on a toolbar, but the toolbar is in
|
||||
customisation mode, and the items can be dragged around. */
|
||||
editableOnPalette /**< Means that the component is on an new-item palette, so it can be
|
||||
dragged onto a toolbar to add it to that bar.*/
|
||||
};
|
||||
|
||||
/** Changes the editing mode of this component.
|
||||
|
||||
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
||||
and is unlikely to be of much use in end-user-code.
|
||||
*/
|
||||
void setEditingMode (const ToolbarEditingMode newMode);
|
||||
|
||||
/** Returns the current editing mode of this component.
|
||||
|
||||
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
||||
and is unlikely to be of much use in end-user-code.
|
||||
*/
|
||||
ToolbarEditingMode getEditingMode() const noexcept { return mode; }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paintButton (Graphics&, bool isMouseOver, bool isMouseDown) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
friend class Toolbar;
|
||||
class ItemDragAndDropOverlayComponent;
|
||||
friend class ItemDragAndDropOverlayComponent;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
|
||||
const int itemId;
|
||||
ToolbarEditingMode mode;
|
||||
Toolbar::ToolbarItemStyle toolbarStyle;
|
||||
std::unique_ptr<Component> overlayComp;
|
||||
int dragOffsetX, dragOffsetY;
|
||||
bool isActive, isBeingDragged, isBeingUsedAsAButton;
|
||||
Rectangle<int> contentArea;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component that can be used as one of the items in a Toolbar.
|
||||
|
||||
Each of the items on a toolbar must be a component derived from ToolbarItemComponent,
|
||||
and these objects are always created by a ToolbarItemFactory - see the ToolbarItemFactory
|
||||
class for further info about creating them.
|
||||
|
||||
The ToolbarItemComponent class is actually a button, but can be used to hold non-button
|
||||
components too. To do this, set the value of isBeingUsedAsAButton to false when
|
||||
calling the constructor, and override contentAreaChanged(), in which you can position
|
||||
any sub-components you need to add.
|
||||
|
||||
To add basic buttons without writing a special subclass, have a look at the
|
||||
ToolbarButton class.
|
||||
|
||||
@see ToolbarButton, Toolbar, ToolbarItemFactory
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemComponent : public Button
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Constructor.
|
||||
|
||||
@param itemId the ID of the type of toolbar item which this represents
|
||||
@param labelText the text to display if the toolbar's style is set to
|
||||
Toolbar::iconsWithText or Toolbar::textOnly
|
||||
@param isBeingUsedAsAButton set this to false if you don't want the button
|
||||
to draw itself with button over/down states when the mouse
|
||||
moves over it or clicks
|
||||
*/
|
||||
ToolbarItemComponent (int itemId,
|
||||
const String& labelText,
|
||||
bool isBeingUsedAsAButton);
|
||||
|
||||
/** Destructor. */
|
||||
~ToolbarItemComponent() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the item type ID that this component represents.
|
||||
This value is in the constructor.
|
||||
*/
|
||||
int getItemId() const noexcept { return itemId; }
|
||||
|
||||
/** Returns the toolbar that contains this component, or nullptr if it's not currently
|
||||
inside one.
|
||||
*/
|
||||
Toolbar* getToolbar() const;
|
||||
|
||||
/** Returns true if this component is currently inside a toolbar which is vertical.
|
||||
@see Toolbar::isVertical
|
||||
*/
|
||||
bool isToolbarVertical() const;
|
||||
|
||||
/** Returns the current style setting of this item.
|
||||
|
||||
Styles are listed in the Toolbar::ToolbarItemStyle enum.
|
||||
@see setStyle, Toolbar::getStyle
|
||||
*/
|
||||
Toolbar::ToolbarItemStyle getStyle() const noexcept { return toolbarStyle; }
|
||||
|
||||
/** Changes the current style setting of this item.
|
||||
|
||||
Styles are listed in the Toolbar::ToolbarItemStyle enum, and are automatically updated
|
||||
by the toolbar that holds this item.
|
||||
|
||||
@see setStyle, Toolbar::setStyle
|
||||
*/
|
||||
virtual void setStyle (const Toolbar::ToolbarItemStyle& newStyle);
|
||||
|
||||
/** Returns the area of the component that should be used to display the button image or
|
||||
other contents of the item.
|
||||
|
||||
This content area may change when the item's style changes, and may leave a space around the
|
||||
edge of the component where the text label can be shown.
|
||||
|
||||
@see contentAreaChanged
|
||||
*/
|
||||
Rectangle<int> getContentArea() const noexcept { return contentArea; }
|
||||
|
||||
//==============================================================================
|
||||
/** This method must return the size criteria for this item, based on a given toolbar
|
||||
size and orientation.
|
||||
|
||||
The preferredSize, minSize and maxSize values must all be set by your implementation
|
||||
method. If the toolbar is horizontal, these will be the width of the item; for a vertical
|
||||
toolbar, they refer to the item's height.
|
||||
|
||||
The preferredSize is the size that the component would like to be, and this must be
|
||||
between the min and max sizes. For a fixed-size item, simply set all three variables to
|
||||
the same value.
|
||||
|
||||
The toolbarThickness parameter tells you the depth of the toolbar - the same as calling
|
||||
Toolbar::getThickness().
|
||||
|
||||
The isToolbarVertical parameter tells you whether the bar is oriented horizontally or
|
||||
vertically.
|
||||
*/
|
||||
virtual bool getToolbarItemSizes (int toolbarThickness,
|
||||
bool isToolbarVertical,
|
||||
int& preferredSize,
|
||||
int& minSize,
|
||||
int& maxSize) = 0;
|
||||
|
||||
/** Your subclass should use this method to draw its content area.
|
||||
|
||||
The graphics object that is passed-in will have been clipped and had its origin
|
||||
moved to fit the content area as specified get getContentArea(). The width and height
|
||||
parameters are the width and height of the content area.
|
||||
|
||||
If the component you're writing isn't a button, you can just do nothing in this method.
|
||||
*/
|
||||
virtual void paintButtonArea (Graphics& g,
|
||||
int width, int height,
|
||||
bool isMouseOver, bool isMouseDown) = 0;
|
||||
|
||||
/** Callback to indicate that the content area of this item has changed.
|
||||
|
||||
This might be because the component was resized, or because the style changed and
|
||||
the space needed for the text label is different.
|
||||
|
||||
See getContentArea() for a description of what the area is.
|
||||
*/
|
||||
virtual void contentAreaChanged (const Rectangle<int>& newBounds) = 0;
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** Editing modes.
|
||||
These are used by setEditingMode(), but will be rarely needed in user code.
|
||||
*/
|
||||
enum ToolbarEditingMode
|
||||
{
|
||||
normalMode = 0, /**< Means that the component is active, inside a toolbar. */
|
||||
editableOnToolbar, /**< Means that the component is on a toolbar, but the toolbar is in
|
||||
customisation mode, and the items can be dragged around. */
|
||||
editableOnPalette /**< Means that the component is on an new-item palette, so it can be
|
||||
dragged onto a toolbar to add it to that bar.*/
|
||||
};
|
||||
|
||||
/** Changes the editing mode of this component.
|
||||
|
||||
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
||||
and is unlikely to be of much use in end-user-code.
|
||||
*/
|
||||
void setEditingMode (const ToolbarEditingMode newMode);
|
||||
|
||||
/** Returns the current editing mode of this component.
|
||||
|
||||
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
||||
and is unlikely to be of much use in end-user-code.
|
||||
*/
|
||||
ToolbarEditingMode getEditingMode() const noexcept { return mode; }
|
||||
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void paintButton (Graphics&, bool isMouseOver, bool isMouseDown) override;
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
friend class Toolbar;
|
||||
class ItemDragAndDropOverlayComponent;
|
||||
friend class ItemDragAndDropOverlayComponent;
|
||||
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
|
||||
const int itemId;
|
||||
ToolbarEditingMode mode;
|
||||
Toolbar::ToolbarItemStyle toolbarStyle;
|
||||
std::unique_ptr<Component> overlayComp;
|
||||
int dragOffsetX, dragOffsetY;
|
||||
bool isActive, isBeingDragged, isBeingUsedAsAButton;
|
||||
Rectangle<int> contentArea;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,109 +1,109 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A factory object which can create ToolbarItemComponent objects.
|
||||
|
||||
A subclass of ToolbarItemFactory publishes a set of types of toolbar item
|
||||
that it can create.
|
||||
|
||||
Each type of item is identified by a unique ID, and multiple instances of an
|
||||
item type can exist at once (even on the same toolbar, e.g. spacers or separator
|
||||
bars).
|
||||
|
||||
@see Toolbar, ToolbarItemComponent, ToolbarButton
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemFactory
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ToolbarItemFactory();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ToolbarItemFactory();
|
||||
|
||||
//==============================================================================
|
||||
/** A set of reserved item ID values, used for the built-in item types.
|
||||
*/
|
||||
enum SpecialItemIds
|
||||
{
|
||||
separatorBarId = -1, /**< The item ID for a vertical (or horizontal) separator bar that
|
||||
can be placed between sets of items to break them into groups. */
|
||||
spacerId = -2, /**< The item ID for a fixed-width space that can be placed between
|
||||
items.*/
|
||||
flexibleSpacerId = -3 /**< The item ID for a gap that pushes outwards against the things on
|
||||
either side of it, filling any available space. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Must return a list of the IDs for all the item types that this factory can create.
|
||||
|
||||
The ids should be added to the array that is passed-in.
|
||||
|
||||
An item ID can be any integer you choose, except for 0, which is considered a null ID,
|
||||
and the predefined IDs in the SpecialItemIds enum.
|
||||
|
||||
You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId)
|
||||
to this list if you want your toolbar to be able to contain those items.
|
||||
|
||||
The list returned here is used by the ToolbarItemPalette class to obtain its list
|
||||
of available items, and their order on the palette will reflect the order in which
|
||||
they appear on this list.
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
virtual void getAllToolbarItemIds (Array <int>& ids) = 0;
|
||||
|
||||
/** Must return the set of items that should be added to a toolbar as its default set.
|
||||
|
||||
This method is used by Toolbar::addDefaultItems() to determine which items to
|
||||
create.
|
||||
|
||||
The items that your method adds to the array that is passed-in will be added to the
|
||||
toolbar in the same order. Items can appear in the list more than once.
|
||||
*/
|
||||
virtual void getDefaultItemSet (Array <int>& ids) = 0;
|
||||
|
||||
/** Must create an instance of one of the items that the factory lists in its
|
||||
getAllToolbarItemIds() method.
|
||||
|
||||
The itemId parameter can be any of the values listed by your getAllToolbarItemIds()
|
||||
method, except for the built-in item types from the SpecialItemIds enum, which
|
||||
are created internally by the toolbar code.
|
||||
|
||||
Try not to keep a pointer to the object that is returned, as it will be deleted
|
||||
automatically by the toolbar, and remember that multiple instances of the same
|
||||
item type are likely to exist at the same time.
|
||||
*/
|
||||
virtual ToolbarItemComponent* createItem (int itemId) = 0;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A factory object which can create ToolbarItemComponent objects.
|
||||
|
||||
A subclass of ToolbarItemFactory publishes a set of types of toolbar item
|
||||
that it can create.
|
||||
|
||||
Each type of item is identified by a unique ID, and multiple instances of an
|
||||
item type can exist at once (even on the same toolbar, e.g. spacers or separator
|
||||
bars).
|
||||
|
||||
@see Toolbar, ToolbarItemComponent, ToolbarButton
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemFactory
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ToolbarItemFactory();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~ToolbarItemFactory();
|
||||
|
||||
//==============================================================================
|
||||
/** A set of reserved item ID values, used for the built-in item types.
|
||||
*/
|
||||
enum SpecialItemIds
|
||||
{
|
||||
separatorBarId = -1, /**< The item ID for a vertical (or horizontal) separator bar that
|
||||
can be placed between sets of items to break them into groups. */
|
||||
spacerId = -2, /**< The item ID for a fixed-width space that can be placed between
|
||||
items.*/
|
||||
flexibleSpacerId = -3 /**< The item ID for a gap that pushes outwards against the things on
|
||||
either side of it, filling any available space. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Must return a list of the IDs for all the item types that this factory can create.
|
||||
|
||||
The ids should be added to the array that is passed-in.
|
||||
|
||||
An item ID can be any integer you choose, except for 0, which is considered a null ID,
|
||||
and the predefined IDs in the SpecialItemIds enum.
|
||||
|
||||
You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId)
|
||||
to this list if you want your toolbar to be able to contain those items.
|
||||
|
||||
The list returned here is used by the ToolbarItemPalette class to obtain its list
|
||||
of available items, and their order on the palette will reflect the order in which
|
||||
they appear on this list.
|
||||
|
||||
@see ToolbarItemPalette
|
||||
*/
|
||||
virtual void getAllToolbarItemIds (Array <int>& ids) = 0;
|
||||
|
||||
/** Must return the set of items that should be added to a toolbar as its default set.
|
||||
|
||||
This method is used by Toolbar::addDefaultItems() to determine which items to
|
||||
create.
|
||||
|
||||
The items that your method adds to the array that is passed-in will be added to the
|
||||
toolbar in the same order. Items can appear in the list more than once.
|
||||
*/
|
||||
virtual void getDefaultItemSet (Array <int>& ids) = 0;
|
||||
|
||||
/** Must create an instance of one of the items that the factory lists in its
|
||||
getAllToolbarItemIds() method.
|
||||
|
||||
The itemId parameter can be any of the values listed by your getAllToolbarItemIds()
|
||||
method, except for the built-in item types from the SpecialItemIds enum, which
|
||||
are created internally by the toolbar code.
|
||||
|
||||
Try not to keep a pointer to the object that is returned, as it will be deleted
|
||||
automatically by the toolbar, and remember that multiple instances of the same
|
||||
item type are likely to exist at the same time.
|
||||
*/
|
||||
virtual ToolbarItemComponent* createItem (int itemId) = 0;
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,116 +1,116 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ToolbarItemPalette::ToolbarItemPalette (ToolbarItemFactory& tbf, Toolbar& bar)
|
||||
: factory (tbf), toolbar (bar)
|
||||
{
|
||||
auto* itemHolder = new Component();
|
||||
viewport.setViewedComponent (itemHolder);
|
||||
|
||||
Array<int> allIds;
|
||||
factory.getAllToolbarItemIds (allIds);
|
||||
|
||||
for (auto& i : allIds)
|
||||
addComponent (i, -1);
|
||||
|
||||
addAndMakeVisible (viewport);
|
||||
}
|
||||
|
||||
ToolbarItemPalette::~ToolbarItemPalette()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ToolbarItemPalette::addComponent (const int itemId, const int index)
|
||||
{
|
||||
if (auto* tc = Toolbar::createItem (factory, itemId))
|
||||
{
|
||||
items.insert (index, tc);
|
||||
viewport.getViewedComponent()->addAndMakeVisible (tc, index);
|
||||
tc->setEditingMode (ToolbarItemComponent::editableOnPalette);
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemPalette::replaceComponent (ToolbarItemComponent& comp)
|
||||
{
|
||||
auto index = items.indexOf (&comp);
|
||||
jassert (index >= 0);
|
||||
items.removeObject (&comp, false);
|
||||
|
||||
addComponent (comp.getItemId(), index);
|
||||
resized();
|
||||
}
|
||||
|
||||
void ToolbarItemPalette::resized()
|
||||
{
|
||||
viewport.setBoundsInset (BorderSize<int> (1));
|
||||
|
||||
auto* itemHolder = viewport.getViewedComponent();
|
||||
|
||||
const int indent = 8;
|
||||
const int preferredWidth = viewport.getWidth() - viewport.getScrollBarThickness() - indent;
|
||||
const int height = toolbar.getThickness();
|
||||
auto x = indent;
|
||||
auto y = indent;
|
||||
int maxX = 0;
|
||||
|
||||
for (auto* tc : items)
|
||||
{
|
||||
tc->setStyle (toolbar.getStyle());
|
||||
|
||||
int preferredSize = 1, minSize = 1, maxSize = 1;
|
||||
|
||||
if (tc->getToolbarItemSizes (height, false, preferredSize, minSize, maxSize))
|
||||
{
|
||||
if (x + preferredSize > preferredWidth && x > indent)
|
||||
{
|
||||
x = indent;
|
||||
y += height;
|
||||
}
|
||||
|
||||
tc->setBounds (x, y, preferredSize, height);
|
||||
|
||||
x += preferredSize + 8;
|
||||
maxX = jmax (maxX, x);
|
||||
}
|
||||
}
|
||||
|
||||
itemHolder->setSize (maxX, y + height + 8);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ToolbarItemPalette::createAccessibilityHandler()
|
||||
{
|
||||
return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::group);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
ToolbarItemPalette::ToolbarItemPalette (ToolbarItemFactory& tbf, Toolbar& bar)
|
||||
: factory (tbf), toolbar (bar)
|
||||
{
|
||||
auto* itemHolder = new Component();
|
||||
viewport.setViewedComponent (itemHolder);
|
||||
|
||||
Array<int> allIds;
|
||||
factory.getAllToolbarItemIds (allIds);
|
||||
|
||||
for (auto& i : allIds)
|
||||
addComponent (i, -1);
|
||||
|
||||
addAndMakeVisible (viewport);
|
||||
}
|
||||
|
||||
ToolbarItemPalette::~ToolbarItemPalette()
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void ToolbarItemPalette::addComponent (const int itemId, const int index)
|
||||
{
|
||||
if (auto* tc = Toolbar::createItem (factory, itemId))
|
||||
{
|
||||
items.insert (index, tc);
|
||||
viewport.getViewedComponent()->addAndMakeVisible (tc, index);
|
||||
tc->setEditingMode (ToolbarItemComponent::editableOnPalette);
|
||||
}
|
||||
else
|
||||
{
|
||||
jassertfalse;
|
||||
}
|
||||
}
|
||||
|
||||
void ToolbarItemPalette::replaceComponent (ToolbarItemComponent& comp)
|
||||
{
|
||||
auto index = items.indexOf (&comp);
|
||||
jassert (index >= 0);
|
||||
items.removeObject (&comp, false);
|
||||
|
||||
addComponent (comp.getItemId(), index);
|
||||
resized();
|
||||
}
|
||||
|
||||
void ToolbarItemPalette::resized()
|
||||
{
|
||||
viewport.setBoundsInset (BorderSize<int> (1));
|
||||
|
||||
auto* itemHolder = viewport.getViewedComponent();
|
||||
|
||||
const int indent = 8;
|
||||
const int preferredWidth = viewport.getWidth() - viewport.getScrollBarThickness() - indent;
|
||||
const int height = toolbar.getThickness();
|
||||
auto x = indent;
|
||||
auto y = indent;
|
||||
int maxX = 0;
|
||||
|
||||
for (auto* tc : items)
|
||||
{
|
||||
tc->setStyle (toolbar.getStyle());
|
||||
|
||||
int preferredSize = 1, minSize = 1, maxSize = 1;
|
||||
|
||||
if (tc->getToolbarItemSizes (height, false, preferredSize, minSize, maxSize))
|
||||
{
|
||||
if (x + preferredSize > preferredWidth && x > indent)
|
||||
{
|
||||
x = indent;
|
||||
y += height;
|
||||
}
|
||||
|
||||
tc->setBounds (x, y, preferredSize, height);
|
||||
|
||||
x += preferredSize + 8;
|
||||
maxX = jmax (maxX, x);
|
||||
}
|
||||
}
|
||||
|
||||
itemHolder->setSize (maxX, y + height + 8);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
std::unique_ptr<AccessibilityHandler> ToolbarItemPalette::createAccessibilityHandler()
|
||||
{
|
||||
return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::group);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@@ -1,78 +1,78 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component containing a list of toolbar items, which the user can drag onto
|
||||
a toolbar to add them.
|
||||
|
||||
You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(),
|
||||
which automatically shows one of these in a dialog box with lots of extra controls.
|
||||
|
||||
@see Toolbar
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemPalette : public Component,
|
||||
public DragAndDropContainer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a palette of items for a given factory, with the aim of adding them
|
||||
to the specified toolbar.
|
||||
|
||||
The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the
|
||||
set of items that are shown in this palette.
|
||||
|
||||
The toolbar and factory must not be deleted while this object exists.
|
||||
*/
|
||||
ToolbarItemPalette (ToolbarItemFactory& factory,
|
||||
Toolbar& toolbar);
|
||||
|
||||
/** Destructor. */
|
||||
~ToolbarItemPalette() override;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
ToolbarItemFactory& factory;
|
||||
Toolbar& toolbar;
|
||||
Viewport viewport;
|
||||
OwnedArray<ToolbarItemComponent> items;
|
||||
|
||||
friend class Toolbar;
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void replaceComponent (ToolbarItemComponent&);
|
||||
void addComponent (int itemId, int index);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemPalette)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component containing a list of toolbar items, which the user can drag onto
|
||||
a toolbar to add them.
|
||||
|
||||
You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(),
|
||||
which automatically shows one of these in a dialog box with lots of extra controls.
|
||||
|
||||
@see Toolbar
|
||||
|
||||
@tags{GUI}
|
||||
*/
|
||||
class JUCE_API ToolbarItemPalette : public Component,
|
||||
public DragAndDropContainer
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates a palette of items for a given factory, with the aim of adding them
|
||||
to the specified toolbar.
|
||||
|
||||
The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the
|
||||
set of items that are shown in this palette.
|
||||
|
||||
The toolbar and factory must not be deleted while this object exists.
|
||||
*/
|
||||
ToolbarItemPalette (ToolbarItemFactory& factory,
|
||||
Toolbar& toolbar);
|
||||
|
||||
/** Destructor. */
|
||||
~ToolbarItemPalette() override;
|
||||
|
||||
//==============================================================================
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
ToolbarItemFactory& factory;
|
||||
Toolbar& toolbar;
|
||||
Viewport viewport;
|
||||
OwnedArray<ToolbarItemComponent> items;
|
||||
|
||||
friend class Toolbar;
|
||||
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override;
|
||||
void replaceComponent (ToolbarItemComponent&);
|
||||
void addComponent (int itemId, int index);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToolbarItemPalette)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user