Browse Source

Added some PopupMenu::addItem overloads which let you attach a lambda callback to be invoked for a menu item.

tags/2021-05-28
jules 6 years ago
parent
commit
0367d5c3a9
7 changed files with 214 additions and 138 deletions
  1. +1
    -1
      modules/juce_core/maths/juce_NormalisableRange.h
  2. +13
    -1
      modules/juce_events/messages/juce_MessageManager.cpp
  3. +1
    -15
      modules/juce_events/messages/juce_MessageManager.h
  4. +137
    -73
      modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  5. +41
    -27
      modules/juce_gui_basics/menus/juce_PopupMenu.h
  6. +1
    -1
      modules/juce_gui_basics/widgets/juce_Toolbar.cpp
  7. +20
    -20
      modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp

+ 1
- 1
modules/juce_core/maths/juce_NormalisableRange.h View File

@@ -195,7 +195,7 @@ public:
}
/** Takes a non-normalised value and snaps it based on either the interval property of
this NormalisedRange or the lambda function supplied to the constructor.
this NormalisableRange or the lambda function supplied to the constructor.
*/
ValueType snapToLegalValue (ValueType v) const noexcept
{


+ 13
- 1
modules/juce_events/messages/juce_MessageManager.cpp View File

@@ -164,7 +164,7 @@ private:
JUCE_DECLARE_NON_COPYABLE (AsyncFunctionCallback)
};
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* const func, void* const parameter)
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func, void* parameter)
{
if (isThisTheMessageThread())
return func (parameter);
@@ -184,6 +184,18 @@ void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* cons
return nullptr;
}
void MessageManager::callAsync (std::function<void()> fn)
{
struct AsyncCallInvoker : public MessageBase
{
AsyncCallInvoker (std::function<void()> f) : callback (std::move (f)) { post(); }
void messageCallback() override { callback(); }
std::function<void()> callback;
};
new AsyncCallInvoker (std::move (fn));
}
//==============================================================================
void MessageManager::deliverBroadcastMessage (const String& value)
{


+ 1
- 15
modules/juce_events/messages/juce_MessageManager.h View File

@@ -95,11 +95,7 @@ public:
//==============================================================================
/** Asynchronously invokes a function or C++11 lambda on the message thread. */
template <typename FunctionType>
static void callAsync (FunctionType&& functionToCall)
{
new AsyncCallInvoker<FunctionType> (std::forward<FunctionType> (functionToCall));
}
static void callAsync (std::function<void()> functionToCall);
/** Calls a function using the message-thread.
@@ -340,16 +336,6 @@ private:
static void doPlatformSpecificShutdown();
static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages);
template <typename FunctionType>
struct AsyncCallInvoker : public MessageBase
{
AsyncCallInvoker (FunctionType&& f) : callback (std::forward<FunctionType> (f)) { post(); }
void messageCallback() override { callback(); }
FunctionType callback;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncCallInvoker)
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager)
};


+ 137
- 73
modules/juce_gui_basics/menus/juce_PopupMenu.cpp View File

@@ -223,12 +223,12 @@ struct MenuWindow : public Component
setOpaque (lf.findColour (PopupMenu::backgroundColourId).isOpaque()
|| ! Desktop::canUseSemiTransparentWindows());
for (int i = 0; i < menu.items.size(); ++i)
for (size_t i = 0; i < menu.items.size(); ++i)
{
auto item = menu.items.getUnchecked (i);
auto& item = menu.items[i];
if (i < menu.items.size() - 1 || ! item->isSeparator)
items.add (new ItemComponent (*item, options.getStandardItemHeight(), *this));
if (i + 1 < menu.items.size() || ! item.isSeparator)
items.add (new ItemComponent (item, options.getStandardItemHeight(), *this));
}
auto targetArea = options.getTargetScreenArea() / scaleFactor;
@@ -323,10 +323,15 @@ struct MenuWindow : public Component
*managerOfChosenCommand = item->commandManager;
}
exitModalState (getResultItemID (item));
auto resultID = getResultItemID (item);
if (makeInvisible && (deletionChecker != nullptr))
exitModalState (resultID);
if (makeInvisible && deletionChecker != nullptr)
setVisible (false);
if (resultID != 0 && item != nullptr && item->action != nullptr)
MessageManager::callAsync (item->action);
}
}
@@ -1262,42 +1267,36 @@ PopupMenu::PopupMenu()
}
PopupMenu::PopupMenu (const PopupMenu& other)
: lookAndFeel (other.lookAndFeel)
: items (other.items),
lookAndFeel (other.lookAndFeel)
{
items.addCopiesOf (other.items);
}
PopupMenu& PopupMenu::operator= (const PopupMenu& other)
{
if (this != &other)
{
items = other.items;
lookAndFeel = other.lookAndFeel;
clear();
items.addCopiesOf (other.items);
}
return *this;
}
PopupMenu::PopupMenu (PopupMenu&& other) noexcept
: lookAndFeel (other.lookAndFeel)
: items (std::move (other.items)),
lookAndFeel (std::move (other.lookAndFeel))
{
items.swapWith (other.items);
}
PopupMenu& PopupMenu::operator= (PopupMenu&& other) noexcept
{
jassert (this != &other); // hopefully the compiler should make this situation impossible!
items.swapWith (other.items);
items = std::move (other.items);
lookAndFeel = other.lookAndFeel;
return *this;
}
PopupMenu::~PopupMenu()
{
}
PopupMenu::~PopupMenu() = default;
void PopupMenu::clear()
{
@@ -1305,13 +1304,54 @@ void PopupMenu::clear()
}
//==============================================================================
PopupMenu::Item::Item() noexcept
PopupMenu::Item::Item() = default;
#if JUCE_MSVC && _MSC_VER < 1900 // tedious VC2013 workaround
PopupMenu::Item::Item (Item&& other)
: text (std::move (other.text)),
itemID (other.itemID),
action (std::move (other.action)),
subMenu (std::move (other.subMenu)),
image (std::move (other.image)),
customComponent (std::move (other.customComponent)),
customCallback (std::move (other.customCallback)),
commandManager (other.commandManager),
shortcutKeyDescription (std::move (other.shortcutKeyDescription)),
colour (other.colour),
isEnabled (other.isEnabled),
isTicked (other.isTicked),
isSeparator (other.isSeparator),
isSectionHeader (other.isSectionHeader)
{
}
PopupMenu::Item& PopupMenu::Item::operator= (Item&& other)
{
text = std::move (other.text);
itemID = other.itemID;
action = std::move (other.action);
subMenu = std::move (other.subMenu);
image = std::move (other.image);
customComponent = std::move (other.customComponent);
customCallback = std::move (other.customCallback);
commandManager = other.commandManager;
shortcutKeyDescription = std::move (other.shortcutKeyDescription);
colour = other.colour;
isEnabled = other.isEnabled;
isTicked = other.isTicked;
isSeparator = other.isSeparator;
isSectionHeader = other.isSectionHeader;
return *this;
}
#else
PopupMenu::Item::Item (Item&&) = default;
PopupMenu::Item& PopupMenu::Item::operator= (Item&&) = default;
#endif
PopupMenu::Item::Item (const Item& other)
: text (other.text),
itemID (other.itemID),
action (other.action),
subMenu (createCopyIfNotNull (other.subMenu.get())),
image (other.image != nullptr ? other.image->createCopy() : nullptr),
customComponent (other.customComponent),
@@ -1330,6 +1370,7 @@ PopupMenu::Item& PopupMenu::Item::operator= (const Item& other)
{
text = other.text;
itemID = other.itemID;
action = other.action;
subMenu.reset (createCopyIfNotNull (other.subMenu.get()));
image = other.image != nullptr ? other.image->createCopy() : std::unique_ptr<Drawable>();
customComponent = other.customComponent;
@@ -1344,7 +1385,7 @@ PopupMenu::Item& PopupMenu::Item::operator= (const Item& other)
return *this;
}
void PopupMenu::addItem (const Item& newItem)
void PopupMenu::addItem (Item newItem)
{
// An ID of 0 is used as a return value to indicate that the user
// didn't pick anything, so you shouldn't use it as the ID for an item..
@@ -1352,17 +1393,33 @@ void PopupMenu::addItem (const Item& newItem)
|| newItem.isSeparator || newItem.isSectionHeader
|| newItem.subMenu != nullptr);
items.add (new Item (newItem));
items.push_back (std::move (newItem));
}
void PopupMenu::addItem (String itemText, std::function<void()> action)
{
addItem (std::move (itemText), true, false, std::move (action));
}
void PopupMenu::addItem (int itemResultID, const String& itemText, bool isActive, bool isTicked)
void PopupMenu::addItem (String itemText, bool isActive, bool isTicked, std::function<void()> action)
{
Item i;
i.text = itemText;
i.text = std::move (itemText);
i.action = std::move (action);
i.itemID = -1;
i.isEnabled = isActive;
i.isTicked = isTicked;
addItem (std::move (i));
}
void PopupMenu::addItem (int itemResultID, String itemText, bool isActive, bool isTicked)
{
Item i;
i.text = std::move (itemText);
i.itemID = itemResultID;
i.isEnabled = isActive;
i.isTicked = isTicked;
addItem (i);
addItem (std::move (i));
}
static std::unique_ptr<Drawable> createDrawableFromImage (const Image& im)
@@ -1377,26 +1434,26 @@ static std::unique_ptr<Drawable> createDrawableFromImage (const Image& im)
return {};
}
void PopupMenu::addItem (int itemResultID, const String& itemText, bool isActive, bool isTicked, const Image& iconToUse)
void PopupMenu::addItem (int itemResultID, String itemText, bool isActive, bool isTicked, const Image& iconToUse)
{
addItem (itemResultID, itemText, isActive, isTicked, createDrawableFromImage (iconToUse));
addItem (itemResultID, std::move (itemText), isActive, isTicked, createDrawableFromImage (iconToUse));
}
void PopupMenu::addItem (int itemResultID, const String& itemText, bool isActive,
void PopupMenu::addItem (int itemResultID, String itemText, bool isActive,
bool isTicked, std::unique_ptr<Drawable> iconToUse)
{
Item i;
i.text = itemText;
i.text = std::move (itemText);
i.itemID = itemResultID;
i.isEnabled = isActive;
i.isTicked = isTicked;
i.image = std::move (iconToUse);
addItem (i);
addItem (std::move (i));
}
void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager,
const CommandID commandID,
const String& displayName,
String displayName,
std::unique_ptr<Drawable> iconToUse)
{
jassert (commandManager != nullptr && commandID != 0);
@@ -1407,40 +1464,40 @@ void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager,
auto* target = commandManager->getTargetForCommand (commandID, info);
Item i;
i.text = displayName.isNotEmpty() ? displayName : info.shortName;
i.text = displayName.isNotEmpty() ? std::move (displayName) : info.shortName;
i.itemID = (int) commandID;
i.commandManager = commandManager;
i.isEnabled = target != nullptr && (info.flags & ApplicationCommandInfo::isDisabled) == 0;
i.isTicked = (info.flags & ApplicationCommandInfo::isTicked) != 0;
i.image = std::move (iconToUse);
addItem (i);
addItem (std::move (i));
}
}
void PopupMenu::addColouredItem (int itemResultID, const String& itemText, Colour itemTextColour,
void PopupMenu::addColouredItem (int itemResultID, String itemText, Colour itemTextColour,
bool isActive, bool isTicked, std::unique_ptr<Drawable> iconToUse)
{
Item i;
i.text = itemText;
i.text = std::move (itemText);
i.itemID = itemResultID;
i.colour = itemTextColour;
i.isEnabled = isActive;
i.isTicked = isTicked;
i.image = std::move (iconToUse);
addItem (i);
addItem (std::move (i));
}
void PopupMenu::addColouredItem (int itemResultID, const String& itemText, Colour itemTextColour,
void PopupMenu::addColouredItem (int itemResultID, String itemText, Colour itemTextColour,
bool isActive, bool isTicked, const Image& iconToUse)
{
Item i;
i.text = itemText;
i.text = std::move (itemText);
i.itemID = itemResultID;
i.colour = itemTextColour;
i.isEnabled = isActive;
i.isTicked = isTicked;
i.image = createDrawableFromImage (iconToUse);
addItem (i);
addItem (std::move (i));
}
void PopupMenu::addCustomItem (int itemResultID, CustomComponent* cc, const PopupMenu* subMenu)
@@ -1449,7 +1506,7 @@ void PopupMenu::addCustomItem (int itemResultID, CustomComponent* cc, const Popu
i.itemID = itemResultID;
i.customComponent = cc;
i.subMenu.reset (createCopyIfNotNull (subMenu));
addItem (i);
addItem (std::move (i));
}
void PopupMenu::addCustomItem (int itemResultID, Component* customComponent, int idealWidth, int idealHeight,
@@ -1461,46 +1518,47 @@ void PopupMenu::addCustomItem (int itemResultID, Component* customComponent, int
subMenu);
}
void PopupMenu::addSubMenu (const String& subMenuName, const PopupMenu& subMenu, bool isActive)
void PopupMenu::addSubMenu (String subMenuName, PopupMenu subMenu, bool isActive)
{
addSubMenu (subMenuName, subMenu, isActive, nullptr, false, 0);
addSubMenu (std::move (subMenuName), std::move (subMenu), isActive, nullptr, false, 0);
}
void PopupMenu::addSubMenu (const String& subMenuName, const PopupMenu& subMenu, bool isActive,
void PopupMenu::addSubMenu (String subMenuName, PopupMenu subMenu, bool isActive,
const Image& iconToUse, bool isTicked, int itemResultID)
{
addSubMenu (subMenuName, subMenu, isActive, createDrawableFromImage (iconToUse), isTicked, itemResultID);
addSubMenu (std::move (subMenuName), std::move (subMenu), isActive,
createDrawableFromImage (iconToUse), isTicked, itemResultID);
}
void PopupMenu::addSubMenu (const String& subMenuName, const PopupMenu& subMenu, bool isActive,
void PopupMenu::addSubMenu (String subMenuName, PopupMenu subMenu, bool isActive,
std::unique_ptr<Drawable> iconToUse, bool isTicked, int itemResultID)
{
Item i;
i.text = subMenuName;
i.text = std::move (subMenuName);
i.itemID = itemResultID;
i.subMenu.reset (new PopupMenu (subMenu));
i.isEnabled = isActive && (itemResultID != 0 || subMenu.getNumItems() > 0);
i.subMenu.reset (new PopupMenu (std::move (subMenu)));
i.isTicked = isTicked;
i.image = std::move (iconToUse);
addItem (i);
addItem (std::move (i));
}
void PopupMenu::addSeparator()
{
if (items.size() > 0 && ! items.getLast()->isSeparator)
if (items.size() > 0 && ! items.back().isSeparator)
{
Item i;
i.isSeparator = true;
addItem (i);
addItem (std::move (i));
}
}
void PopupMenu::addSectionHeader (const String& title)
void PopupMenu::addSectionHeader (String title)
{
Item i;
i.text = title;
i.text = std::move (title);
i.isSectionHeader = true;
addItem (i);
addItem (std::move (i));
}
//==============================================================================
@@ -1579,11 +1637,11 @@ PopupMenu::Options PopupMenu::Options::withPreferredPopupDirection (PopupDirecti
Component* PopupMenu::createWindow (const Options& options,
ApplicationCommandManager** managerOfChosenCommand) const
{
return items.isEmpty() ? nullptr
: new HelperClasses::MenuWindow (*this, nullptr, options,
! options.getTargetScreenArea().isEmpty(),
ModifierKeys::currentModifiers.isAnyMouseButtonDown(),
managerOfChosenCommand);
return items.empty() ? nullptr
: new HelperClasses::MenuWindow (*this, nullptr, options,
! options.getTargetScreenArea().isEmpty(),
ModifierKeys::currentModifiers.isAnyMouseButtonDown(),
managerOfChosenCommand);
}
//==============================================================================
@@ -1627,8 +1685,9 @@ struct PopupMenuCompletionCallback : public ModalComponentManager::Callback
JUCE_DECLARE_NON_COPYABLE (PopupMenuCompletionCallback)
};
int PopupMenu::showWithOptionalCallback (const Options& options, ModalComponentManager::Callback* const userCallback,
const bool canBeModal)
int PopupMenu::showWithOptionalCallback (const Options& options,
ModalComponentManager::Callback* userCallback,
bool canBeModal)
{
std::unique_ptr<ModalComponentManager::Callback> userCallbackDeleter (userCallback);
std::unique_ptr<PopupMenuCompletionCallback> callback (new PopupMenuCompletionCallback());
@@ -1664,6 +1723,11 @@ int PopupMenu::showMenu (const Options& options)
}
#endif
void PopupMenu::showMenuAsync (const Options& options)
{
showWithOptionalCallback (options, nullptr, false);
}
void PopupMenu::showMenuAsync (const Options& options, ModalComponentManager::Callback* userCallback)
{
#if ! JUCE_MODAL_LOOPS_PERMITTED
@@ -1743,8 +1807,8 @@ int PopupMenu::getNumItems() const noexcept
{
int num = 0;
for (auto* mi : items)
if (! mi->isSeparator)
for (auto& mi : items)
if (! mi.isSeparator)
++num;
return num;
@@ -1752,9 +1816,9 @@ int PopupMenu::getNumItems() const noexcept
bool PopupMenu::containsCommandItem (const int commandID) const
{
for (auto* mi : items)
if ((mi->itemID == commandID && mi->commandManager != nullptr)
|| (mi->subMenu != nullptr && mi->subMenu->containsCommandItem (commandID)))
for (auto& mi : items)
if ((mi.itemID == commandID && mi.commandManager != nullptr)
|| (mi.subMenu != nullptr && mi.subMenu->containsCommandItem (commandID)))
return true;
return false;
@@ -1762,14 +1826,14 @@ bool PopupMenu::containsCommandItem (const int commandID) const
bool PopupMenu::containsAnyActiveItems() const noexcept
{
for (auto* mi : items)
for (auto& mi : items)
{
if (mi->subMenu != nullptr)
if (mi.subMenu != nullptr)
{
if (mi->subMenu->containsAnyActiveItems())
if (mi.subMenu->containsAnyActiveItems())
return true;
}
else if (mi->isEnabled)
else if (mi.isEnabled)
{
return true;
}
@@ -1832,14 +1896,14 @@ PopupMenu::MenuItemIterator::MenuItemIterator (const PopupMenu& m, bool recurse)
menus.add (&m);
}
PopupMenu::MenuItemIterator::~MenuItemIterator() {}
PopupMenu::MenuItemIterator::~MenuItemIterator() = default;
bool PopupMenu::MenuItemIterator::next()
{
if (index.size() == 0 || menus.getLast()->items.size() == 0)
return false;
currentItem = menus.getLast()->items.getUnchecked (index.getLast());
currentItem = const_cast<PopupMenu::Item*> (&(menus.getLast()->items[(size_t) index.getLast()]));
if (searchRecursively && currentItem->subMenu != nullptr)
{
@@ -1851,7 +1915,7 @@ bool PopupMenu::MenuItemIterator::next()
index.setUnchecked (index.size() - 1, index.getLast() + 1);
}
while (index.size() > 0 && index.getLast() >= menus.getLast()->items.size())
while (index.size() > 0 && index.getLast() >= (int) menus.getLast()->items.size())
{
index.removeLast();
menus.removeLast();
@@ -1863,7 +1927,7 @@ bool PopupMenu::MenuItemIterator::next()
return true;
}
PopupMenu::Item& PopupMenu::MenuItemIterator::getItem() const noexcept
PopupMenu::Item& PopupMenu::MenuItemIterator::getItem() const
{
jassert (currentItem != nullptr);
return *(currentItem);


+ 41
- 27
modules/juce_gui_basics/menus/juce_PopupMenu.h View File

@@ -79,13 +79,7 @@ namespace juce
*/
class JUCE_API PopupMenu
{
private:
class Window;
public:
class CustomComponent;
class CustomCallback;
//==============================================================================
/** Creates an empty popup menu. */
PopupMenu();
@@ -105,6 +99,10 @@ public:
/** Move assignment operator */
PopupMenu& operator= (PopupMenu&&) noexcept;
//==============================================================================
class CustomComponent;
class CustomCallback;
//==============================================================================
/** Resets the menu, removing all its items. */
void clear();
@@ -116,13 +114,12 @@ public:
You'll need to set some fields after creating an Item before you
can add it to a PopupMenu
*/
Item() noexcept;
Item();
/** Creates a copy of an item. */
Item (const Item&);
/** Creates a copy of an item. */
Item& operator= (const Item&);
Item (Item&&);
Item& operator= (Item&&);
/** The menu item's name. */
String text;
@@ -130,6 +127,9 @@ public:
/** The menu item's ID. This must not be 0 if you want the item to be triggerable! */
int itemID = 0;
/** An optional function which should be invoked when this menu item is triggered. */
std::function<void()> action;
/** A sub-menu, or nullptr if there isn't one. */
std::unique_ptr<PopupMenu> subMenu;
@@ -175,7 +175,17 @@ public:
You can call this method for full control over the item that is added, or use the other
addItem helper methods if you want to pass arguments rather than creating an Item object.
*/
void addItem (const Item& newItem);
void addItem (Item newItem);
/** Adds an item to the menu with an action callback. */
void addItem (String itemText,
std::function<void()> action);
/** Adds an item to the menu with an action callback. */
void addItem (String itemText,
bool isEnabled,
bool isTicked,
std::function<void()> action);
/** Appends a new text item for this menu to show.
@@ -190,7 +200,7 @@ public:
@see addSeparator, addColouredItem, addCustomItem, addSubMenu
*/
void addItem (int itemResultID,
const String& itemText,
String itemText,
bool isEnabled = true,
bool isTicked = false);
@@ -208,7 +218,7 @@ public:
@see addSeparator, addColouredItem, addCustomItem, addSubMenu
*/
void addItem (int itemResultID,
const String& itemText,
String itemText,
bool isEnabled,
bool isTicked,
const Image& iconToUse);
@@ -228,7 +238,7 @@ public:
@see addSeparator, addColouredItem, addCustomItem, addSubMenu
*/
void addItem (int itemResultID,
const String& itemText,
String itemText,
bool isEnabled,
bool isTicked,
std::unique_ptr<Drawable> iconToUse);
@@ -246,7 +256,7 @@ public:
*/
void addCommandItem (ApplicationCommandManager* commandManager,
CommandID commandID,
const String& displayName = String(),
String displayName = {},
std::unique_ptr<Drawable> iconToUse = {});
/** Appends a text item with a special colour.
@@ -256,11 +266,11 @@ public:
current look-and-feel. See addItem() for a description of the parameters.
*/
void addColouredItem (int itemResultID,
const String& itemText,
String itemText,
Colour itemTextColour,
bool isEnabled = true,
bool isTicked = false,
const Image& iconToUse = Image());
const Image& iconToUse = {});
/** Appends a text item with a special colour.
@@ -269,7 +279,7 @@ public:
current look-and-feel. See addItem() for a description of the parameters.
*/
void addColouredItem (int itemResultID,
const String& itemText,
String itemText,
Colour itemTextColour,
bool isEnabled,
bool isTicked,
@@ -314,8 +324,8 @@ public:
If the itemResultID argument is non-zero, then the sub-menu item itself can be
clicked to trigger it as a command.
*/
void addSubMenu (const String& subMenuName,
const PopupMenu& subMenu,
void addSubMenu (String subMenuName,
PopupMenu subMenu,
bool isEnabled = true);
/** Appends a sub-menu with an icon.
@@ -324,8 +334,8 @@ public:
If the itemResultID argument is non-zero, then the sub-menu item itself can be
clicked to trigger it as a command.
*/
void addSubMenu (const String& subMenuName,
const PopupMenu& subMenu,
void addSubMenu (String subMenuName,
PopupMenu subMenu,
bool isEnabled,
const Image& iconToUse,
bool isTicked = false,
@@ -341,8 +351,8 @@ public:
the item. The menu will take ownership of this drawable object and will delete it
later when no longer needed
*/
void addSubMenu (const String& subMenuName,
const PopupMenu& subMenu,
void addSubMenu (String subMenuName,
PopupMenu subMenu,
bool isEnabled,
std::unique_ptr<Drawable> iconToUse,
bool isTicked = false,
@@ -360,7 +370,7 @@ public:
This is a bold-font items which can be used as a header to separate the items
into named groups.
*/
void addSectionHeader (const String& title);
void addSectionHeader (String title);
/** Returns the number of items that the menu currently contains.
(This doesn't count separators).
@@ -509,6 +519,9 @@ public:
int showMenu (const Options& options);
#endif
/** Runs the menu asynchronously. */
void showMenuAsync (const Options& options);
/** Runs the menu asynchronously, with a user-provided callback that will receive the result. */
void showMenuAsync (const Options& options,
ModalComponentManager::Callback* callback);
@@ -594,7 +607,7 @@ public:
/** Returns a reference to the description of the current item.
It is only valid to call this after next() has returned true!
*/
Item& getItem() const noexcept;
Item& getItem() const;
private:
//==============================================================================
@@ -749,10 +762,11 @@ public:
private:
//==============================================================================
JUCE_PUBLIC_IN_DLL_BUILD (struct HelperClasses)
class Window;
friend struct HelperClasses;
friend class MenuBarComponent;
OwnedArray<Item> items;
std::vector<Item> items;
WeakReference<LookAndFeel> lookAndFeel;
Component* createWindow (const Options&, ApplicationCommandManager**) const;


+ 1
- 1
modules/juce_gui_basics/widgets/juce_Toolbar.cpp View File

@@ -543,7 +543,7 @@ void Toolbar::showMissingItems()
{
PopupMenu m;
m.addCustomItem (1, new MissingItemsComponent (*this, getThickness()));
m.showMenuAsync (PopupMenu::Options().withTargetComponent (missingItemsButton.get()), [] (int) {});
m.showMenuAsync (PopupMenu::Options().withTargetComponent (missingItemsButton.get()));
}
}


+ 20
- 20
modules/juce_gui_extra/misc/juce_KeyMappingEditorComponent.cpp View File

@@ -30,8 +30,8 @@ namespace juce
class KeyMappingEditorComponent::ChangeKeyButton : public Button
{
public:
ChangeKeyButton (KeyMappingEditorComponent& kec, const CommandID command,
const String& keyName, const int keyIndex)
ChangeKeyButton (KeyMappingEditorComponent& kec, CommandID command,
const String& keyName, int keyIndex)
: Button (keyName),
owner (kec),
commandID (command),
@@ -50,31 +50,31 @@ public:
keyNum >= 0 ? getName() : String());
}
static void menuCallback (int result, ChangeKeyButton* button)
{
if (button != nullptr)
{
switch (result)
{
case 1: button->assignNewKey(); break;
case 2: button->owner.getMappings().removeKeyPress (button->commandID, button->keyNum); break;
default: break;
}
}
}
void clicked() override
{
if (keyNum >= 0)
{
// existing key clicked..
Component::SafePointer<ChangeKeyButton> button (this);
PopupMenu m;
m.addItem (1, TRANS("Change this key-mapping"));
m.addItem (TRANS("Change this key-mapping"),
[button]
{
if (button != nullptr)
button.getComponent()->assignNewKey();
});
m.addSeparator();
m.addItem (2, TRANS("Remove this key-mapping"));
m.showMenuAsync (PopupMenu::Options(),
ModalCallbackFunction::forComponent (menuCallback, this));
m.addItem (TRANS("Remove this key-mapping"),
[button]
{
if (button != nullptr)
button->owner.getMappings().removeKeyPress (button->commandID,
button->keyNum);
});
m.showMenuAsync (PopupMenu::Options().withTargetComponent (this));
}
else
{


Loading…
Cancel
Save