Browse Source

Fix for incredibly subtle windows popupmenu problem.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
2a2677d7ca
6 changed files with 55 additions and 58 deletions
  1. +3
    -3
      modules/juce_core/text/juce_String.cpp
  2. +21
    -24
      modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp
  3. +4
    -4
      modules/juce_gui_basics/menus/juce_MenuBarComponent.h
  4. +20
    -18
      modules/juce_gui_basics/menus/juce_PopupMenu.cpp
  5. +6
    -6
      modules/juce_gui_basics/menus/juce_PopupMenu.h
  6. +1
    -3
      modules/juce_gui_basics/widgets/juce_Slider.cpp

+ 3
- 3
modules/juce_core/text/juce_String.cpp View File

@@ -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 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_UTF16& t) : text (StringHolder::createFromCharPointer (t)) {}
String::String (const CharPointer_UTF32& 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_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_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 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 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_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)) {} String::String (const CharPointer_UTF32& start, const CharPointer_UTF32& end) : text (StringHolder::createFromCharPointer (start, end)) {}


+ 21
- 24
modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp View File

@@ -30,9 +30,7 @@ MenuBarComponent::MenuBarComponent (MenuBarModel* model_)
: model (nullptr), : model (nullptr),
itemUnderMouse (-1), itemUnderMouse (-1),
currentPopupIndex (-1), currentPopupIndex (-1),
topLevelIndexClicked (0),
lastMouseX (0),
lastMouseY (0)
topLevelIndexClicked (0)
{ {
setRepaintsOnMouseActivity (true); setRepaintsOnMouseActivity (true);
setWantsKeyboardFocus (false); setWantsKeyboardFocus (false);
@@ -115,11 +113,11 @@ void MenuBarComponent::resized()
} }
} }
int MenuBarComponent::getItemAt (const int x, const int y)
int MenuBarComponent::getItemAt (const Point<int>& p)
{ {
for (int i = 0; i < xPositions.size(); ++i) for (int i = 0; i < xPositions.size(); ++i)
if (x >= xPositions[i] && x < xPositions[i + 1])
return reallyContains (Point<int> (x, y), true) ? i : -1;
if (p.getX() >= xPositions[i] && p.getX() < xPositions[i + 1])
return reallyContains (p, true) ? i : -1;
return -1; return -1;
} }
@@ -153,16 +151,18 @@ void MenuBarComponent::setOpenItem (int index)
currentPopupIndex = index; currentPopupIndex = index;
repaintMenuItem (currentPopupIndex); repaintMenuItem (currentPopupIndex);
Desktop& desktop = Desktop::getInstance();
if (index >= 0) if (index >= 0)
Desktop::getInstance().addGlobalMouseListener (this);
desktop.addGlobalMouseListener (this);
else else
Desktop::getInstance().removeGlobalMouseListener (this);
desktop.removeGlobalMouseListener (this);
} }
} }
void MenuBarComponent::updateItemUnderMouse (int x, int y)
void MenuBarComponent::updateItemUnderMouse (const Point<int>& p)
{ {
setItemUnderMouse (getItemAt (x, y));
setItemUnderMouse (getItemAt (p));
} }
void MenuBarComponent::showMenu (int index) void MenuBarComponent::showMenu (int index)
@@ -208,7 +208,7 @@ void MenuBarComponent::menuDismissed (int topLevelIndex, int itemId)
void MenuBarComponent::handleCommandMessage (int commandId) void MenuBarComponent::handleCommandMessage (int commandId)
{ {
const Point<int> mousePos (getMouseXYRelative()); const Point<int> mousePos (getMouseXYRelative());
updateItemUnderMouse (mousePos.getX(), mousePos.getY());
updateItemUnderMouse (mousePos);
if (currentPopupIndex == topLevelIndexClicked) if (currentPopupIndex == topLevelIndexClicked)
setOpenItem (-1); setOpenItem (-1);
@@ -221,13 +221,13 @@ void MenuBarComponent::handleCommandMessage (int commandId)
void MenuBarComponent::mouseEnter (const MouseEvent& e) void MenuBarComponent::mouseEnter (const MouseEvent& e)
{ {
if (e.eventComponent == this) if (e.eventComponent == this)
updateItemUnderMouse (e.x, e.y);
updateItemUnderMouse (e.getPosition());
} }
void MenuBarComponent::mouseExit (const MouseEvent& e) void MenuBarComponent::mouseExit (const MouseEvent& e)
{ {
if (e.eventComponent == this) if (e.eventComponent == this)
updateItemUnderMouse (e.x, e.y);
updateItemUnderMouse (e.getPosition());
} }
void MenuBarComponent::mouseDown (const MouseEvent& e) void MenuBarComponent::mouseDown (const MouseEvent& e)
@@ -235,7 +235,7 @@ void MenuBarComponent::mouseDown (const MouseEvent& e)
if (currentPopupIndex < 0) if (currentPopupIndex < 0)
{ {
const MouseEvent e2 (e.getEventRelativeTo (this)); const MouseEvent e2 (e.getEventRelativeTo (this));
updateItemUnderMouse (e2.x, e2.y);
updateItemUnderMouse (e2.getPosition());
currentPopupIndex = -2; currentPopupIndex = -2;
showMenu (itemUnderMouse); showMenu (itemUnderMouse);
@@ -245,7 +245,7 @@ void MenuBarComponent::mouseDown (const MouseEvent& e)
void MenuBarComponent::mouseDrag (const MouseEvent& e) void MenuBarComponent::mouseDrag (const MouseEvent& e)
{ {
const MouseEvent e2 (e.getEventRelativeTo (this)); const MouseEvent e2 (e.getEventRelativeTo (this));
const int item = getItemAt (e2.x, e2.y);
const int item = getItemAt (e2.getPosition());
if (item >= 0) if (item >= 0)
showMenu (item); showMenu (item);
@@ -255,7 +255,7 @@ void MenuBarComponent::mouseUp (const MouseEvent& e)
{ {
const MouseEvent e2 (e.getEventRelativeTo (this)); const MouseEvent e2 (e.getEventRelativeTo (this));
updateItemUnderMouse (e2.x, e2.y);
updateItemUnderMouse (e2.getPosition());
if (itemUnderMouse < 0 && getLocalBounds().contains (e2.x, e2.y)) 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)); const MouseEvent e2 (e.getEventRelativeTo (this));
if (lastMouseX != e2.x || lastMouseY != e2.y)
if (lastMousePos != e2.getPosition())
{ {
if (currentPopupIndex >= 0) if (currentPopupIndex >= 0)
{ {
const int item = getItemAt (e2.x, e2.y);
const int item = getItemAt (e2.getPosition());
if (item >= 0) if (item >= 0)
showMenu (item); showMenu (item);
} }
else 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() void MenuBarComponent::timerCallback()
{ {
stopTimer(); stopTimer();
const Point<int> mousePos (getMouseXYRelative());
updateItemUnderMouse (mousePos.getX(), mousePos.getY());
updateItemUnderMouse (getMouseXYRelative());
} }


+ 4
- 4
modules/juce_gui_basics/menus/juce_MenuBarComponent.h View File

@@ -104,14 +104,14 @@ private:
MenuBarModel* model; MenuBarModel* model;
StringArray menuNames; StringArray menuNames;
Array <int> xPositions;
Array<int> xPositions;
Point<int> lastMousePos;
int itemUnderMouse, currentPopupIndex, topLevelIndexClicked; int itemUnderMouse, currentPopupIndex, topLevelIndexClicked;
int lastMouseX, lastMouseY;
int getItemAt (int x, int y);
int getItemAt (const Point<int>&);
void setItemUnderMouse (int index); void setItemUnderMouse (int index);
void setOpenItem (int index); void setOpenItem (int index);
void updateItemUnderMouse (int x, int y);
void updateItemUnderMouse (const Point<int>&);
void timerCallback(); void timerCallback();
void repaintMenuItem (int index); void repaintMenuItem (int index);
void menuDismissed (int topLevelIndex, int itemId); void menuDismissed (int topLevelIndex, int itemId);


+ 20
- 18
modules/juce_gui_basics/menus/juce_PopupMenu.cpp View File

@@ -229,7 +229,6 @@ class PopupMenu::Window : public Component,
private Timer private Timer
{ {
public: public:
//==============================================================================
Window (const PopupMenu& menu, Window* const owner_, const Rectangle<int>& target, Window (const PopupMenu& menu, Window* const owner_, const Rectangle<int>& target,
const bool alignToRectangle, const int itemIdThatMustBeVisible, const bool alignToRectangle, const int itemIdThatMustBeVisible,
const int minimumWidth_, const int maximumNumColumns_, const int minimumWidth_, const int maximumNumColumns_,
@@ -400,7 +399,7 @@ public:
} }
else else
{ {
hide (0, false);
hide (nullptr, false);
} }
} }
} }
@@ -466,7 +465,7 @@ public:
} }
else if (key.isKeyCode (KeyPress::escapeKey)) else if (key.isKeyCode (KeyPress::escapeKey))
{ {
dismissMenu (0);
dismissMenu (nullptr);
} }
else else
{ {
@@ -501,7 +500,7 @@ public:
} }
} }
dismissMenu (0);
dismissMenu (nullptr);
} }
} }
@@ -510,7 +509,7 @@ public:
Component::handleCommandMessage (commandId); Component::handleCommandMessage (commandId);
if (commandId == PopupMenuSettings::dismissCommandId) if (commandId == PopupMenuSettings::dismissCommandId)
dismissMenu (0);
dismissMenu (nullptr);
} }
//============================================================================== //==============================================================================
@@ -521,7 +520,7 @@ public:
if (componentAttachedTo != componentAttachedToOriginal) if (componentAttachedTo != componentAttachedToOriginal)
{ {
dismissMenu (0);
dismissMenu (nullptr);
return; return;
} }
@@ -623,7 +622,7 @@ public:
if (now > lastFocused + 10) if (now > lastFocused + 10)
{ {
PopupMenuSettings::menuWasHiddenBecauseOfAppChange = true; PopupMenuSettings::menuWasHiddenBecauseOfAppChange = true;
dismissMenu (0);
dismissMenu (nullptr);
return; // may have been deleted by the previous call.. return; // may have been deleted by the previous call..
} }
@@ -639,7 +638,7 @@ public:
} }
else if ((hasBeenOver || ! dismissOnMouseUp) && ! isOverAny) else if ((hasBeenOver || ! dismissOnMouseUp) && ! isOverAny)
{ {
dismissMenu (0);
dismissMenu (nullptr);
} }
return; // may have been deleted by the previous calls.. return; // may have been deleted by the previous calls..
@@ -1034,7 +1033,7 @@ private:
if (activeSubMenu != nullptr) if (activeSubMenu != nullptr)
{ {
activeSubMenu->setVisible (true);
activeSubMenu->setVisible (true); // (must be called before enterModalState on Windows to avoid DropShadower confusion)
activeSubMenu->enterModalState (false); activeSubMenu->enterModalState (false);
activeSubMenu->toFront (false); activeSubMenu->toFront (false);
return true; return true;
@@ -1386,7 +1385,7 @@ PopupMenu::Options::Options()
targetArea.setPosition (Desktop::getMousePosition()); targetArea.setPosition (Desktop::getMousePosition());
} }
const PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) const
PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* comp) const
{ {
Options o (*this); Options o (*this);
o.targetComponent = comp; o.targetComponent = comp;
@@ -1397,35 +1396,35 @@ const PopupMenu::Options PopupMenu::Options::withTargetComponent (Component* com
return o; return o;
} }
const PopupMenu::Options PopupMenu::Options::withTargetScreenArea (const Rectangle<int>& area) const
PopupMenu::Options PopupMenu::Options::withTargetScreenArea (const Rectangle<int>& area) const
{ {
Options o (*this); Options o (*this);
o.targetArea = area; o.targetArea = area;
return o; return o;
} }
const PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const
PopupMenu::Options PopupMenu::Options::withMinimumWidth (int w) const
{ {
Options o (*this); Options o (*this);
o.minWidth = w; o.minWidth = w;
return o; return o;
} }
const PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const
PopupMenu::Options PopupMenu::Options::withMaximumNumColumns (int cols) const
{ {
Options o (*this); Options o (*this);
o.maxColumns = cols; o.maxColumns = cols;
return o; return o;
} }
const PopupMenu::Options PopupMenu::Options::withStandardItemHeight (int height) const
PopupMenu::Options PopupMenu::Options::withStandardItemHeight (int height) const
{ {
Options o (*this); Options o (*this);
o.standardHeight = height; o.standardHeight = height;
return o; return o;
} }
const PopupMenu::Options PopupMenu::Options::withItemThatMustBeVisible (int idOfItemToBeVisible) const
PopupMenu::Options PopupMenu::Options::withItemThatMustBeVisible (int idOfItemToBeVisible) const
{ {
Options o (*this); Options o (*this);
o.visibleItemID = idOfItemToBeVisible; o.visibleItemID = idOfItemToBeVisible;
@@ -1497,6 +1496,7 @@ int PopupMenu::showWithOptionalCallback (const Options& options, ModalComponentM
callback->component = window; callback->component = window;
window->setVisible (true); // (must be called before enterModalState on Windows to avoid DropShadower confusion)
window->enterModalState (false, userCallbackDeleter.release()); window->enterModalState (false, userCallbackDeleter.release());
ModalComponentManager::getInstance()->attachCallback (window, callback.release()); ModalComponentManager::getInstance()->attachCallback (window, callback.release());
@@ -1576,13 +1576,15 @@ int PopupMenu::showAt (Component* componentToAttachTo,
bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus() bool JUCE_CALLTYPE PopupMenu::dismissAllActiveMenus()
{ {
const int numWindows = Window::getActiveWindows().size();
Array<Window*>& windows = Window::getActiveWindows();
const int numWindows = windows.size();
for (int i = numWindows; --i >= 0;) for (int i = numWindows; --i >= 0;)
{ {
Window* const pmw = Window::getActiveWindows()[i];
Window* const pmw = windows[i];
if (pmw != nullptr) if (pmw != nullptr)
pmw->dismissMenu (0);
pmw->dismissMenu (nullptr);
} }
return numWindows > 0; return numWindows > 0;


+ 6
- 6
modules/juce_gui_basics/menus/juce_PopupMenu.h View File

@@ -223,12 +223,12 @@ public:
public: public:
Options(); Options();
const Options withTargetComponent (Component* targetComponent) const;
const Options withTargetScreenArea (const Rectangle<int>& 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<int>& targetArea) const;
Options withMinimumWidth (int minWidth) const;
Options withMaximumNumColumns (int maxNumColumns) const;
Options withStandardItemHeight (int standardHeight) const;
Options withItemThatMustBeVisible (int idOfItemToBeVisible) const;
private: private:
friend class PopupMenu; friend class PopupMenu;


+ 1
- 3
modules/juce_gui_basics/widgets/juce_Slider.cpp View File

@@ -1345,10 +1345,8 @@ void Slider::mouseDrag (const MouseEvent& e)
else else
minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue(); minMaxDiff = (double) valueMax.getValue() - (double) valueMin.getValue();
} }
else
else if (sliderBeingDragged == 2)
{ {
jassert (sliderBeingDragged == 2);
setMaxValue (snapValue (valueWhenLastDragged, true), setMaxValue (snapValue (valueWhenLastDragged, true),
! sendChangeOnlyOnRelease, false, true); ! sendChangeOnlyOnRelease, false, true);


Loading…
Cancel
Save