diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index 6c92b07e02..530a49f7ee 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -74,9 +74,7 @@ struct HeaderItemComponent : public PopupMenu::CustomComponent struct ItemComponent : public Component { ItemComponent (const PopupMenu::Item& i, int standardItemHeight, MenuWindow& parent) - : item (i), - customComp (i.customComponent), - isHighlighted (false) + : item (i), customComp (i.customComponent) { if (item.isSectionHeader) customComp = new HeaderItemComponent (item.text); @@ -152,7 +150,7 @@ struct ItemComponent : public Component private: // NB: we use a copy of the one from the item info in case we're using our own section comp ReferenceCountedObjectPtr customComp; - bool isHighlighted; + bool isHighlighted = false; void updateShortcutKeyDescription() { @@ -200,7 +198,7 @@ public: parent (parentWindow), options (opts), managerOfChosenCommand (manager), - componentAttachedTo (options.targetComponent), + componentAttachedTo (options.getTargetComponent()), dismissOnMouseUp (shouldDismissOnMouseUp), windowCreationTime (Time::getMillisecondCounter()), lastFocusedTime (windowCreationTime), @@ -230,23 +228,22 @@ public: auto item = menu.items.getUnchecked (i); if (i < menu.items.size() - 1 || ! item->isSeparator) - items.add (new ItemComponent (*item, options.standardHeight, *this)); + items.add (new ItemComponent (*item, options.getStandardItemHeight(), *this)); } - Rectangle targetArea = options.targetArea / scaleFactor; + auto targetArea = options.getTargetScreenArea() / scaleFactor; calculateWindowPos (targetArea, alignToRectangle); setTopLeftPosition (windowPos.getPosition()); updateYPositions(); - if (options.visibleItemID != 0) + if (auto visibleID = options.getItemThatMustBeVisible()) { auto targetPosition = parentComponent != nullptr ? parentComponent->getLocalPoint (nullptr, targetArea.getTopLeft()) : targetArea.getTopLeft(); auto y = targetPosition.getY() - windowPos.getY(); - ensureItemIsVisible (options.visibleItemID, - isPositiveAndBelow (y, windowPos.getHeight()) ? y : -1); + ensureItemIsVisible (visibleID, isPositiveAndBelow (y, windowPos.getHeight()) ? y : -1); } resizeToBestWindowPos(); @@ -492,7 +489,7 @@ public: if (! isVisible()) return false; - if (componentAttachedTo != options.targetComponent) + if (componentAttachedTo != options.getTargetComponent()) { dismissMenu (nullptr); return false; @@ -629,8 +626,8 @@ public: { x = target.getX(); - const int spaceUnder = parentArea.getHeight() - (target.getBottom() - parentArea.getY()); - const int spaceOver = target.getY() - parentArea.getY(); + auto spaceUnder = parentArea.getHeight() - (target.getBottom() - parentArea.getY()); + auto spaceOver = target.getY() - parentArea.getY(); if (heightToUse < spaceUnder - 30 || spaceUnder >= spaceOver) y = target.getBottom(); @@ -697,15 +694,14 @@ public: void layoutMenuItems (const int maxMenuW, const int maxMenuH, int& width, int& height) { - numColumns = 0; + numColumns = options.getMinimumNumColumns(); contentHeight = 0; int totalW; - const int maximumNumColumns = options.maxColumns > 0 ? options.maxColumns : 7; + auto maximumNumColumns = options.getMaximumNumColumns() > 0 ? options.getMaximumNumColumns() : 7; - do + for (;;) { - ++numColumns; totalW = workOutBestSize (maxMenuW); if (totalW > maxMenuW) @@ -715,12 +711,15 @@ public: break; } - if (totalW > maxMenuW / 2 || contentHeight < maxMenuH) + if (totalW > maxMenuW / 2 + || contentHeight < maxMenuH + || numColumns >= maximumNumColumns) break; - } while (numColumns < maximumNumColumns); + ++numColumns; + } - const int actualH = jmin (contentHeight, maxMenuH); + auto actualH = jmin (contentHeight, maxMenuH); needsToScroll = contentHeight > actualH; @@ -736,7 +735,7 @@ public: for (int col = 0; col < numColumns; ++col) { - int colW = options.standardHeight, colH = 0; + int colW = options.getStandardItemHeight(), colH = 0; const int numChildren = jmin (items.size() - childNum, (items.size() + numColumns - 1) / numColumns); @@ -757,7 +756,7 @@ public: } // width must never be larger than the screen - const int minWidth = jmin (maxMenuW, options.minWidth); + auto minWidth = jmin (maxMenuW, options.getMinimumWidth()); if (totalW < minWidth) { @@ -1321,13 +1320,6 @@ void PopupMenu::clear() //============================================================================== PopupMenu::Item::Item() noexcept - : itemID (0), - commandManager (nullptr), - colour (0x00000000), - isEnabled (true), - isTicked (false), - isSeparator (false), - isSectionHeader (false) { } @@ -1526,12 +1518,6 @@ void PopupMenu::addSectionHeader (const String& title) //============================================================================== PopupMenu::Options::Options() - : targetComponent (nullptr), - parentComponent (nullptr), - visibleItemID (0), - minWidth (0), - maxColumns (0), - standardHeight (0) { targetArea.setPosition (Desktop::getMousePosition()); } @@ -1547,7 +1533,7 @@ PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) con return o; } -PopupMenu::Options PopupMenu::Options::withTargetScreenArea (const Rectangle& area) const noexcept +PopupMenu::Options PopupMenu::Options::withTargetScreenArea (Rectangle area) const noexcept { Options o (*this); o.targetArea = area; @@ -1561,6 +1547,13 @@ PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const noexcept return o; } +PopupMenu::Options PopupMenu::Options::withMinimumNumColumns (int cols) const noexcept +{ + Options o (*this); + o.minColumns = cols; + return o; +} + PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const noexcept { Options o (*this); @@ -1592,13 +1585,11 @@ PopupMenu::Options PopupMenu::Options::withParentComponent (Component* parent) c Component* PopupMenu::createWindow (const Options& options, ApplicationCommandManager** managerOfChosenCommand) const { - if (items.size() > 0) - return new HelperClasses::MenuWindow (*this, nullptr, options, - ! options.targetArea.isEmpty(), - ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), - managerOfChosenCommand); - - return nullptr; + return items.isEmpty() ? nullptr + : new HelperClasses::MenuWindow (*this, nullptr, options, + ! options.getTargetScreenArea().isEmpty(), + ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), + managerOfChosenCommand); } //============================================================================== @@ -1690,9 +1681,8 @@ void PopupMenu::showMenuAsync (const Options& options, ModalComponentManager::Ca //============================================================================== #if JUCE_MODAL_LOOPS_PERMITTED -int PopupMenu::show (const int itemIDThatMustBeVisible, - const int minimumWidth, const int maximumNumColumns, - const int standardItemHeight, +int PopupMenu::show (int itemIDThatMustBeVisible, int minimumWidth, + int maximumNumColumns, int standardItemHeight, ModalComponentManager::Callback* callback) { return showWithOptionalCallback (Options().withItemThatMustBeVisible (itemIDThatMustBeVisible) @@ -1702,10 +1692,9 @@ int PopupMenu::show (const int itemIDThatMustBeVisible, callback, true); } -int PopupMenu::showAt (const Rectangle& screenAreaToAttachTo, - const int itemIDThatMustBeVisible, - const int minimumWidth, const int maximumNumColumns, - const int standardItemHeight, +int PopupMenu::showAt (Rectangle screenAreaToAttachTo, + int itemIDThatMustBeVisible, int minimumWidth, + int maximumNumColumns, int standardItemHeight, ModalComponentManager::Callback* callback) { return showWithOptionalCallback (Options().withTargetScreenArea (screenAreaToAttachTo) @@ -1717,15 +1706,14 @@ int PopupMenu::showAt (const Rectangle& screenAreaToAttachTo, } int PopupMenu::showAt (Component* componentToAttachTo, - const int itemIDThatMustBeVisible, - const int minimumWidth, const int maximumNumColumns, - const int standardItemHeight, + int itemIDThatMustBeVisible, int minimumWidth, + int maximumNumColumns, int standardItemHeight, ModalComponentManager::Callback* callback) { - Options options (Options().withItemThatMustBeVisible (itemIDThatMustBeVisible) - .withMinimumWidth (minimumWidth) - .withMaximumNumColumns (maximumNumColumns) - .withStandardItemHeight (standardItemHeight)); + auto options = Options().withItemThatMustBeVisible (itemIDThatMustBeVisible) + .withMinimumWidth (minimumWidth) + .withMaximumNumColumns (maximumNumColumns) + .withStandardItemHeight (standardItemHeight); if (componentToAttachTo != nullptr) options = options.withTargetComponent (componentToAttachTo); @@ -1793,8 +1781,7 @@ void PopupMenu::setLookAndFeel (LookAndFeel* const newLookAndFeel) //============================================================================== PopupMenu::CustomComponent::CustomComponent (bool autoTrigger) - : isHighlighted (false), - triggeredAutomatically (autoTrigger) + : triggeredAutomatically (autoTrigger) { } @@ -1835,9 +1822,8 @@ PopupMenu::CustomCallback::CustomCallback() {} PopupMenu::CustomCallback::~CustomCallback() {} //============================================================================== -PopupMenu::MenuItemIterator::MenuItemIterator (const PopupMenu& m, bool searchR) : searchRecursively (searchR) +PopupMenu::MenuItemIterator::MenuItemIterator (const PopupMenu& m, bool recurse) : searchRecursively (recurse) { - currentItem = nullptr; index.add (0); menus.add (&m); } diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.h b/modules/juce_gui_basics/menus/juce_PopupMenu.h index 10ecd898fc..d3a91b94ce 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -89,19 +89,19 @@ public: PopupMenu(); /** Creates a copy of another menu. */ - PopupMenu (const PopupMenu& other); + PopupMenu (const PopupMenu&); /** Destructor. */ ~PopupMenu(); /** Copies this menu from another one. */ - PopupMenu& operator= (const PopupMenu& other); + PopupMenu& operator= (const PopupMenu&); /** Move constructor */ - PopupMenu (PopupMenu&& other) noexcept; + PopupMenu (PopupMenu&&) noexcept; /** Move assignment operator */ - PopupMenu& operator= (PopupMenu&& other) noexcept; + PopupMenu& operator= (PopupMenu&&) noexcept; //============================================================================== /** Resets the menu, removing all its items. */ @@ -125,8 +125,8 @@ public: /** The menu item's name. */ String text; - /** The menu item's ID. This can not be 0 if you want the item to be triggerable! */ - int itemID; + /** The menu item's ID. This must not be 0 if you want the item to be triggerable! */ + int itemID = 0; /** A sub-menu, or nullptr if there isn't one. */ ScopedPointer subMenu; @@ -141,7 +141,7 @@ public: ReferenceCountedObjectPtr customCallback; /** A command manager to use to automatically invoke the command, or nullptr if none is specified. */ - ApplicationCommandManager* commandManager; + ApplicationCommandManager* commandManager = nullptr; /** An optional string describing the shortcut key for this item. This is only used for displaying at the right-hand edge of a menu item - the @@ -157,16 +157,16 @@ public: Colour colour; /** True if this menu item is enabled. */ - bool isEnabled; + bool isEnabled = true; /** True if this menu item should have a tick mark next to it. */ - bool isTicked; + bool isTicked = false; /** True if this menu item is a separator line. */ - bool isSeparator; + bool isSeparator = false; /** True if this menu item is a section header. */ - bool isSectionHeader; + bool isSectionHeader = false; }; /** Adds an item to the menu. @@ -247,8 +247,6 @@ public: const String& displayName = String(), Drawable* iconToUse = nullptr); - - /** Appends a text item with a special colour. This is the same as addItem(), but specifies a colour to use for the @@ -389,11 +387,14 @@ public: { public: Options(); + Options (const Options&) = default; + Options& operator= (const Options&) = default; //============================================================================== Options withTargetComponent (Component* targetComponent) const noexcept; - Options withTargetScreenArea (const Rectangle& targetArea) const noexcept; + Options withTargetScreenArea (Rectangle targetArea) const noexcept; Options withMinimumWidth (int minWidth) const noexcept; + Options withMinimumNumColumns (int minNumColumns) const noexcept; Options withMaximumNumColumns (int maxNumColumns) const noexcept; Options withStandardItemHeight (int standardHeight) const noexcept; Options withItemThatMustBeVisible (int idOfItemToBeVisible) const noexcept; @@ -405,17 +406,16 @@ public: Rectangle getTargetScreenArea() const noexcept { return targetArea; } int getMinimumWidth() const noexcept { return minWidth; } int getMaximumNumColumns() const noexcept { return maxColumns; } + int getMinimumNumColumns() const noexcept { return minColumns; } int getStandardItemHeight() const noexcept { return standardHeight; } int getItemThatMustBeVisible() const noexcept { return visibleItemID; } private: //============================================================================== - friend class PopupMenu; - friend class PopupMenu::Window; Rectangle targetArea; - Component* targetComponent; - Component* parentComponent; - int visibleItemID, minWidth, maxColumns, standardHeight; + Component* targetComponent = nullptr; + Component* parentComponent = nullptr; + int visibleItemID = 0, minWidth = 0, minColumns = 1, maxColumns = 0, standardHeight = 0; }; //============================================================================== @@ -473,7 +473,7 @@ public: @see show() */ - int showAt (const Rectangle& screenAreaToAttachTo, + int showAt (Rectangle screenAreaToAttachTo, int itemIDThatMustBeVisible = 0, int minimumWidth = 0, int maximumNumColumns = 0, @@ -585,9 +585,9 @@ public: //============================================================================== bool searchRecursively; - Array index; - Array menus; - PopupMenu::Item *currentItem; + Array index; + Array menus; + PopupMenu::Item* currentItem = nullptr; MenuItemIterator& operator= (const MenuItemIterator&); JUCE_LEAK_DETECTOR (MenuItemIterator) @@ -638,7 +638,7 @@ public: private: //============================================================================== - bool isHighlighted, triggeredAutomatically; + bool isHighlighted = false, triggeredAutomatically; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComponent) };