From 2a2677d7ca58a10897ff17e34463b4ba9c9876d6 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Thu, 15 Sep 2011 11:31:34 +0100 Subject: [PATCH] Fix for incredibly subtle windows popupmenu problem. --- modules/juce_core/text/juce_String.cpp | 6 +-- .../menus/juce_MenuBarComponent.cpp | 45 +++++++++---------- .../menus/juce_MenuBarComponent.h | 8 ++-- .../juce_gui_basics/menus/juce_PopupMenu.cpp | 38 ++++++++-------- .../juce_gui_basics/menus/juce_PopupMenu.h | 12 ++--- .../juce_gui_basics/widgets/juce_Slider.cpp | 4 +- 6 files changed, 55 insertions(+), 58 deletions(-) diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 669005db08..2f55c15d86 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -324,17 +324,17 @@ String::String (const char* const t, const size_t maxChars) } String::String (const wchar_t* const t) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t))) {} -String::String (const CharPointer_UTF8& t) : text (StringHolder::createFromCharPointer (t)) {} +String::String (const CharPointer_UTF8& t) : text (StringHolder::createFromCharPointer (t)) {} String::String (const CharPointer_UTF16& t) : text (StringHolder::createFromCharPointer (t)) {} String::String (const CharPointer_UTF32& t) : text (StringHolder::createFromCharPointer (t)) {} String::String (const CharPointer_ASCII& t) : text (StringHolder::createFromCharPointer (t)) {} -String::String (const CharPointer_UTF8& t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} +String::String (const CharPointer_UTF8& t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} String::String (const CharPointer_UTF16& t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} String::String (const CharPointer_UTF32& t, const size_t maxChars) : text (StringHolder::createFromCharPointer (t, maxChars)) {} String::String (const wchar_t* const t, size_t maxChars) : text (StringHolder::createFromCharPointer (castToCharPointer_wchar_t (t), maxChars)) {} -String::String (const CharPointer_UTF8& start, const CharPointer_UTF8& end) : text (StringHolder::createFromCharPointer (start, end)) {} +String::String (const CharPointer_UTF8& start, const CharPointer_UTF8& end) : text (StringHolder::createFromCharPointer (start, end)) {} String::String (const CharPointer_UTF16& start, const CharPointer_UTF16& end) : text (StringHolder::createFromCharPointer (start, end)) {} String::String (const CharPointer_UTF32& start, const CharPointer_UTF32& end) : text (StringHolder::createFromCharPointer (start, end)) {} diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp index 3ea2571d8c..a1f660d565 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp @@ -30,9 +30,7 @@ MenuBarComponent::MenuBarComponent (MenuBarModel* model_) : model (nullptr), itemUnderMouse (-1), currentPopupIndex (-1), - topLevelIndexClicked (0), - lastMouseX (0), - lastMouseY (0) + topLevelIndexClicked (0) { setRepaintsOnMouseActivity (true); setWantsKeyboardFocus (false); @@ -115,11 +113,11 @@ void MenuBarComponent::resized() } } -int MenuBarComponent::getItemAt (const int x, const int y) +int MenuBarComponent::getItemAt (const Point& p) { for (int i = 0; i < xPositions.size(); ++i) - if (x >= xPositions[i] && x < xPositions[i + 1]) - return reallyContains (Point (x, y), true) ? i : -1; + if (p.getX() >= xPositions[i] && p.getX() < xPositions[i + 1]) + return reallyContains (p, true) ? i : -1; return -1; } @@ -153,16 +151,18 @@ void MenuBarComponent::setOpenItem (int index) currentPopupIndex = index; repaintMenuItem (currentPopupIndex); + Desktop& desktop = Desktop::getInstance(); + if (index >= 0) - Desktop::getInstance().addGlobalMouseListener (this); + desktop.addGlobalMouseListener (this); else - Desktop::getInstance().removeGlobalMouseListener (this); + desktop.removeGlobalMouseListener (this); } } -void MenuBarComponent::updateItemUnderMouse (int x, int y) +void MenuBarComponent::updateItemUnderMouse (const Point& p) { - setItemUnderMouse (getItemAt (x, y)); + setItemUnderMouse (getItemAt (p)); } void MenuBarComponent::showMenu (int index) @@ -208,7 +208,7 @@ void MenuBarComponent::menuDismissed (int topLevelIndex, int itemId) void MenuBarComponent::handleCommandMessage (int commandId) { const Point mousePos (getMouseXYRelative()); - updateItemUnderMouse (mousePos.getX(), mousePos.getY()); + updateItemUnderMouse (mousePos); if (currentPopupIndex == topLevelIndexClicked) setOpenItem (-1); @@ -221,13 +221,13 @@ void MenuBarComponent::handleCommandMessage (int commandId) void MenuBarComponent::mouseEnter (const MouseEvent& e) { if (e.eventComponent == this) - updateItemUnderMouse (e.x, e.y); + updateItemUnderMouse (e.getPosition()); } void MenuBarComponent::mouseExit (const MouseEvent& e) { if (e.eventComponent == this) - updateItemUnderMouse (e.x, e.y); + updateItemUnderMouse (e.getPosition()); } void MenuBarComponent::mouseDown (const MouseEvent& e) @@ -235,7 +235,7 @@ void MenuBarComponent::mouseDown (const MouseEvent& e) if (currentPopupIndex < 0) { const MouseEvent e2 (e.getEventRelativeTo (this)); - updateItemUnderMouse (e2.x, e2.y); + updateItemUnderMouse (e2.getPosition()); currentPopupIndex = -2; showMenu (itemUnderMouse); @@ -245,7 +245,7 @@ void MenuBarComponent::mouseDown (const MouseEvent& e) void MenuBarComponent::mouseDrag (const MouseEvent& e) { const MouseEvent e2 (e.getEventRelativeTo (this)); - const int item = getItemAt (e2.x, e2.y); + const int item = getItemAt (e2.getPosition()); if (item >= 0) showMenu (item); @@ -255,7 +255,7 @@ void MenuBarComponent::mouseUp (const MouseEvent& e) { const MouseEvent e2 (e.getEventRelativeTo (this)); - updateItemUnderMouse (e2.x, e2.y); + updateItemUnderMouse (e2.getPosition()); if (itemUnderMouse < 0 && getLocalBounds().contains (e2.x, e2.y)) { @@ -268,22 +268,21 @@ void MenuBarComponent::mouseMove (const MouseEvent& e) { const MouseEvent e2 (e.getEventRelativeTo (this)); - if (lastMouseX != e2.x || lastMouseY != e2.y) + if (lastMousePos != e2.getPosition()) { if (currentPopupIndex >= 0) { - const int item = getItemAt (e2.x, e2.y); + const int item = getItemAt (e2.getPosition()); if (item >= 0) showMenu (item); } else { - updateItemUnderMouse (e2.x, e2.y); + updateItemUnderMouse (e2.getPosition()); } - lastMouseX = e2.x; - lastMouseY = e2.y; + lastMousePos = e2.getPosition(); } } @@ -344,9 +343,7 @@ void MenuBarComponent::menuCommandInvoked (MenuBarModel* /*menuBarModel*/, void MenuBarComponent::timerCallback() { stopTimer(); - - const Point mousePos (getMouseXYRelative()); - updateItemUnderMouse (mousePos.getX(), mousePos.getY()); + updateItemUnderMouse (getMouseXYRelative()); } diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h index b3743325ab..53edc8d785 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h @@ -104,14 +104,14 @@ private: MenuBarModel* model; StringArray menuNames; - Array xPositions; + Array xPositions; + Point lastMousePos; int itemUnderMouse, currentPopupIndex, topLevelIndexClicked; - int lastMouseX, lastMouseY; - int getItemAt (int x, int y); + int getItemAt (const Point&); void setItemUnderMouse (int index); void setOpenItem (int index); - void updateItemUnderMouse (int x, int y); + void updateItemUnderMouse (const Point&); void timerCallback(); void repaintMenuItem (int index); void menuDismissed (int topLevelIndex, int itemId); diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index 6a1d20cd06..b0e96ffc03 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -229,7 +229,6 @@ class PopupMenu::Window : public Component, private Timer { public: - //============================================================================== Window (const PopupMenu& menu, Window* const owner_, const Rectangle& target, const bool alignToRectangle, const int itemIdThatMustBeVisible, const int minimumWidth_, const int maximumNumColumns_, @@ -400,7 +399,7 @@ public: } else { - hide (0, false); + hide (nullptr, false); } } } @@ -466,7 +465,7 @@ public: } else if (key.isKeyCode (KeyPress::escapeKey)) { - dismissMenu (0); + dismissMenu (nullptr); } else { @@ -501,7 +500,7 @@ public: } } - dismissMenu (0); + dismissMenu (nullptr); } } @@ -510,7 +509,7 @@ public: Component::handleCommandMessage (commandId); if (commandId == PopupMenuSettings::dismissCommandId) - dismissMenu (0); + dismissMenu (nullptr); } //============================================================================== @@ -521,7 +520,7 @@ public: if (componentAttachedTo != componentAttachedToOriginal) { - dismissMenu (0); + dismissMenu (nullptr); return; } @@ -623,7 +622,7 @@ public: if (now > lastFocused + 10) { PopupMenuSettings::menuWasHiddenBecauseOfAppChange = true; - dismissMenu (0); + dismissMenu (nullptr); return; // may have been deleted by the previous call.. } @@ -639,7 +638,7 @@ public: } else if ((hasBeenOver || ! dismissOnMouseUp) && ! isOverAny) { - dismissMenu (0); + dismissMenu (nullptr); } return; // may have been deleted by the previous calls.. @@ -1034,7 +1033,7 @@ private: if (activeSubMenu != nullptr) { - activeSubMenu->setVisible (true); + activeSubMenu->setVisible (true); // (must be called before enterModalState on Windows to avoid DropShadower confusion) activeSubMenu->enterModalState (false); activeSubMenu->toFront (false); return true; @@ -1386,7 +1385,7 @@ PopupMenu::Options::Options() targetArea.setPosition (Desktop::getMousePosition()); } -const PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) const +PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) const { Options o (*this); o.targetComponent = comp; @@ -1397,35 +1396,35 @@ const PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* com return o; } -const PopupMenu::Options PopupMenu::Options::withTargetScreenArea (const Rectangle& area) const +PopupMenu::Options PopupMenu::Options::withTargetScreenArea (const Rectangle& area) const { Options o (*this); o.targetArea = area; return o; } -const PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const +PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const { Options o (*this); o.minWidth = w; return o; } -const PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const +PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const { Options o (*this); o.maxColumns = cols; return o; } -const PopupMenu::Options PopupMenu::Options::withStandardItemHeight (int height) const +PopupMenu::Options PopupMenu::Options::withStandardItemHeight (int height) const { Options o (*this); o.standardHeight = height; return o; } -const PopupMenu::Options PopupMenu::Options::withItemThatMustBeVisible (int idOfItemToBeVisible) const +PopupMenu::Options PopupMenu::Options::withItemThatMustBeVisible (int idOfItemToBeVisible) const { Options o (*this); o.visibleItemID = idOfItemToBeVisible; @@ -1497,6 +1496,7 @@ int PopupMenu::showWithOptionalCallback (const Options& options, ModalComponentM callback->component = window; + window->setVisible (true); // (must be called before enterModalState on Windows to avoid DropShadower confusion) window->enterModalState (false, userCallbackDeleter.release()); ModalComponentManager::getInstance()->attachCallback (window, callback.release()); @@ -1576,13 +1576,15 @@ int PopupMenu::showAt (Component* componentToAttachTo, bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() { - const int numWindows = Window::getActiveWindows().size(); + Array& windows = Window::getActiveWindows(); + + const int numWindows = windows.size(); for (int i = numWindows; --i >= 0;) { - Window* const pmw = Window::getActiveWindows()[i]; + Window* const pmw = windows[i]; if (pmw != nullptr) - pmw->dismissMenu (0); + pmw->dismissMenu (nullptr); } return numWindows > 0; diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.h b/modules/juce_gui_basics/menus/juce_PopupMenu.h index ae09843ade..482ef7ddbf 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.h +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.h @@ -223,12 +223,12 @@ public: public: Options(); - const Options withTargetComponent (Component* targetComponent) const; - const Options withTargetScreenArea (const Rectangle& targetArea) const; - const Options withMinimumWidth (int minWidth) const; - const Options withMaximumNumColumns (int maxNumColumns) const; - const Options withStandardItemHeight (int standardHeight) const; - const Options withItemThatMustBeVisible (int idOfItemToBeVisible) const; + Options withTargetComponent (Component* targetComponent) const; + Options withTargetScreenArea (const Rectangle& targetArea) const; + Options withMinimumWidth (int minWidth) const; + Options withMaximumNumColumns (int maxNumColumns) const; + Options withStandardItemHeight (int standardHeight) const; + Options withItemThatMustBeVisible (int idOfItemToBeVisible) const; private: friend class PopupMenu; diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp index 68f11b5ead..cfbcac8a54 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -1345,10 +1345,8 @@ void Slider::mouseDrag (const MouseEvent& e) else minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue(); } - else + else if (sliderBeingDragged == 2) { - jassert (sliderBeingDragged == 2); - setMaxValue (snapValue (valueWhenLastDragged, true), ! sendChangeOnlyOnRelease, false, true);