1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-02-07 04:10:08 +00:00

Added ListenerList class and changed some components to use it for their listener dispatching. Sorted out bug in popup menus and win32 mouse wheel.

This commit is contained in:
Julian Storer 2010-03-07 17:45:10 +00:00
parent b974203d0f
commit 2676bb02f2
42 changed files with 1815 additions and 1867 deletions

View file

@ -52,7 +52,6 @@ private:
//==============================================================================
Button::Button (const String& name)
: Component (name),
keySource (0),
text (name),
buttonPressTime (0),
lastTimeCallbackTime (0),
@ -352,23 +351,17 @@ void Button::handleCommandMessage (int commandId)
//==============================================================================
void Button::addButtonListener (ButtonListener* const newListener)
{
jassert (newListener != 0);
jassert (! buttonListeners.contains (newListener)); // trying to add a listener to the list twice!
if (newListener != 0)
buttonListeners.add (newListener);
buttonListeners.add (newListener);
}
void Button::removeButtonListener (ButtonListener* const listener)
{
jassert (buttonListeners.contains (listener)); // trying to remove a listener that isn't on the list!
buttonListeners.removeValue (listener);
buttonListeners.remove (listener);
}
void Button::sendClickMessage (const ModifierKeys& modifiers)
{
Component::SafePointer<Component> deletionWatcher (this);
Component::BailOutChecker checker (this);
if (commandManagerToUse != 0 && commandID != 0)
{
@ -381,44 +374,18 @@ void Button::sendClickMessage (const ModifierKeys& modifiers)
clicked (modifiers);
if (deletionWatcher != 0)
{
for (int i = buttonListeners.size(); --i >= 0;)
{
ButtonListener* const bl = (ButtonListener*) buttonListeners[i];
if (bl != 0)
{
bl->buttonClicked (this);
if (deletionWatcher == 0)
return;
}
}
}
if (! checker.shouldBailOut())
buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this);
}
void Button::sendStateMessage()
{
Component::SafePointer<Component> deletionWatcher (this);
Component::BailOutChecker checker (this);
buttonStateChanged();
if (deletionWatcher == 0)
return;
for (int i = buttonListeners.size(); --i >= 0;)
{
ButtonListener* const bl = (ButtonListener*) buttonListeners[i];
if (bl != 0)
{
bl->buttonStateChanged (this);
if (deletionWatcher == 0)
return;
}
}
if (! checker.shouldBailOut())
buttonListeners.callChecked (checker, &ButtonListener::buttonStateChanged, this);
}
//==============================================================================
@ -512,12 +479,12 @@ void Button::parentHierarchyChanged()
if (newKeySource != keySource)
{
if (keySource->isValidComponent())
if (keySource != 0)
keySource->removeKeyListener (this);
keySource = newKeySource;
if (keySource->isValidComponent())
if (keySource != 0)
keySource->addKeyListener (this);
}
}

View file

@ -469,9 +469,9 @@ protected:
private:
//==============================================================================
Array <KeyPress> shortcuts;
Component* keySource;
Component::SafePointer<Component> keySource;
String text;
SortedSet <void*> buttonListeners;
ListenerList <ButtonListener> buttonListeners;
class RepeatTimer;
friend class RepeatTimer;

View file

@ -605,23 +605,18 @@ void ComboBox::mouseUp (const MouseEvent& e2)
//==============================================================================
void ComboBox::addListener (ComboBoxListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void ComboBox::removeListener (ComboBoxListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
void ComboBox::handleAsyncUpdate()
{
for (int i = listeners.size(); --i >= 0;)
{
((ComboBoxListener*) listeners.getUnchecked (i))->comboBoxChanged (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &ComboBoxListener::comboBoxChanged, this);
}

View file

@ -392,7 +392,7 @@ private:
Value currentId;
int lastCurrentId;
bool isButtonDown, separatorPending, menuActive, textIsCustom;
SortedSet <void*> listeners;
ListenerList <ComboBoxListener> listeners;
ScopedPointer<Label> label;
String textWhenNothingSelected, noChoicesMessage;

View file

@ -140,7 +140,7 @@ void Label::setBorderSize (int h, int v)
//==============================================================================
Component* Label::getAttachedComponent() const
{
return const_cast <Component*> (static_cast <const Component*> (ownerComponent));
return static_cast<Component*> (ownerComponent);
}
void Label::attachToComponent (Component* owner,
@ -257,6 +257,8 @@ void Label::hideEditor (const bool discardCurrentEditorContents)
{
if (editor != 0)
{
Component::SafePointer<Component> deletionChecker (this);
editorAboutToBeHidden (editor);
const bool changed = (! discardCurrentEditorContents)
@ -268,9 +270,10 @@ void Label::hideEditor (const bool discardCurrentEditorContents)
if (changed)
textWasEdited();
exitModalState (0);
if (deletionChecker != 0)
exitModalState (0);
if (changed && isValidComponent())
if (changed && deletionChecker != 0)
callChangeListeners();
}
}
@ -395,23 +398,18 @@ KeyboardFocusTraverser* Label::createFocusTraverser()
//==============================================================================
void Label::addListener (LabelListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void Label::removeListener (LabelListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
void Label::callChangeListeners()
{
for (int i = listeners.size(); --i >= 0;)
{
((LabelListener*) listeners.getUnchecked (i))->labelTextChanged (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &LabelListener::labelTextChanged, this);
}
//==============================================================================
@ -443,9 +441,10 @@ void Label::textEditorReturnKeyPressed (TextEditor& ed)
if (changed)
{
Component::SafePointer<Component> deletionChecker (this);
textWasEdited();
if (isValidComponent())
if (deletionChecker != 0)
callChangeListeners();
}
}

View file

@ -327,7 +327,7 @@ private:
Font font;
Justification justification;
ScopedPointer <TextEditor> editor;
SortedSet <void*> listeners;
ListenerList <LabelListener> listeners;
Component::SafePointer<Component> ownerComponent;
int horizontalBorderSize, verticalBorderSize;
float minimumHorizontalScale;

View file

@ -158,22 +158,16 @@ void Slider::handleAsyncUpdate()
{
cancelPendingUpdate();
for (int i = listeners.size(); --i >= 0;)
{
((SliderListener*) listeners.getUnchecked (i))->sliderValueChanged (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &SliderListener::sliderValueChanged, this);
}
void Slider::sendDragStart()
{
startedDragging();
for (int i = listeners.size(); --i >= 0;)
{
((SliderListener*) listeners.getUnchecked (i))->sliderDragStarted (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &SliderListener::sliderDragStarted, this);
}
void Slider::sendDragEnd()
@ -182,23 +176,18 @@ void Slider::sendDragEnd()
sliderBeingDragged = -1;
for (int i = listeners.size(); --i >= 0;)
{
((SliderListener*) listeners.getUnchecked (i))->sliderDragEnded (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &SliderListener::sliderDragEnded, this);
}
void Slider::addListener (SliderListener* const listener)
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void Slider::removeListener (SliderListener* const listener)
{
listeners.removeValue (listener);
listeners.remove (listener);
}
//==============================================================================

View file

@ -30,7 +30,6 @@
#include "juce_Label.h"
#include "../buttons/juce_Button.h"
#include "../../../events/juce_AsyncUpdater.h"
#include "../../../containers/juce_SortedSet.h"
#include "../../../containers/juce_Value.h"
@ -750,7 +749,7 @@ protected:
void valueChanged (Value& value);
private:
SortedSet <void*> listeners;
ListenerList <SliderListener> listeners;
Value currentValue, valueMin, valueMax;
double lastCurrentValue, lastValueMin, lastValueMax;
double minimum, maximum, interval, doubleClickReturnValue;

View file

@ -1258,15 +1258,12 @@ void TextEditor::escapePressed()
void TextEditor::addListener (TextEditorListener* const newListener)
{
jassert (newListener != 0)
if (newListener != 0)
listeners.add (newListener);
listeners.add (newListener);
}
void TextEditor::removeListener (TextEditorListener* const listenerToRemove)
{
listeners.removeValue (listenerToRemove);
listeners.remove (listenerToRemove);
}
//==============================================================================
@ -2166,47 +2163,36 @@ void TextEditor::resized()
void TextEditor::handleCommandMessage (const int commandId)
{
Component::SafePointer<Component> deletionChecker (this);
Component::BailOutChecker checker (this);
for (int i = listeners.size(); --i >= 0;)
switch (commandId)
{
TextEditorListener* const tl = (TextEditorListener*) listeners [i];
case TextEditorDefs::textChangeMessageId:
listeners.callChecked (checker, &TextEditorListener::textEditorTextChanged, (TextEditor&) *this);
break;
if (tl != 0)
{
switch (commandId)
{
case TextEditorDefs::textChangeMessageId:
tl->textEditorTextChanged (*this);
break;
case TextEditorDefs::returnKeyMessageId:
listeners.callChecked (checker, &TextEditorListener::textEditorReturnKeyPressed, (TextEditor&) *this);
break;
case TextEditorDefs::returnKeyMessageId:
tl->textEditorReturnKeyPressed (*this);
break;
case TextEditorDefs::escapeKeyMessageId:
listeners.callChecked (checker, &TextEditorListener::textEditorEscapeKeyPressed, (TextEditor&) *this);
break;
case TextEditorDefs::escapeKeyMessageId:
tl->textEditorEscapeKeyPressed (*this);
break;
case TextEditorDefs::focusLossMessageId:
listeners.callChecked (checker, &TextEditorListener::textEditorFocusLost, (TextEditor&) *this);
break;
case TextEditorDefs::focusLossMessageId:
tl->textEditorFocusLost (*this);
break;
default:
jassertfalse
break;
}
if (deletionChecker == 0)
return;
}
default:
jassertfalse
break;
}
}
void TextEditor::enablementChanged()
{
setMouseCursor (MouseCursor (isReadOnly() ? MouseCursor::NormalCursor
: MouseCursor::IBeamCursor));
setMouseCursor (isReadOnly() ? MouseCursor::NormalCursor
: MouseCursor::IBeamCursor);
repaint();
}

View file

@ -652,7 +652,7 @@ private:
} dragType;
String allowedCharacters;
SortedSet <void*> listeners;
ListenerList <TextEditorListener> listeners;
friend class TextEditorInsertAction;
friend class TextEditorRemoveAction;

View file

@ -47,47 +47,26 @@ FileBrowserListener::~FileBrowserListener()
void DirectoryContentsDisplayComponent::addListener (FileBrowserListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void DirectoryContentsDisplayComponent::removeListener (FileBrowserListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
void DirectoryContentsDisplayComponent::sendSelectionChangeMessage()
{
Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this));
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged();
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
Component::BailOutChecker checker (dynamic_cast <Component*> (this));
listeners.callChecked (checker, &FileBrowserListener::selectionChanged);
}
void DirectoryContentsDisplayComponent::sendMouseClickMessage (const File& file, const MouseEvent& e)
{
if (fileList.getDirectory().exists())
{
Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this));
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (file, e);
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
Component::BailOutChecker checker (dynamic_cast <Component*> (this));
listeners.callChecked (checker, &FileBrowserListener::fileClicked, file, e);
}
}
@ -95,17 +74,8 @@ void DirectoryContentsDisplayComponent::sendDoubleClickMessage (const File& file
{
if (fileList.getDirectory().exists())
{
Component::SafePointer<Component> deletionWatcher (dynamic_cast <Component*> (this));
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (file);
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
Component::BailOutChecker checker (dynamic_cast <Component*> (this));
listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, file);
}
}

View file

@ -104,7 +104,7 @@ public:
protected:
DirectoryContentsList& fileList;
SortedSet <void*> listeners;
ListenerList <FileBrowserListener> listeners;
DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&);
DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&);

View file

@ -152,15 +152,12 @@ FileBrowserComponent::~FileBrowserComponent()
//==============================================================================
void FileBrowserComponent::addListener (FileBrowserListener* const newListener) throw()
{
jassert (newListener != 0)
if (newListener != 0)
listeners.add (newListener);
listeners.add (newListener);
}
void FileBrowserComponent::removeListener (FileBrowserListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
//==============================================================================
@ -302,23 +299,15 @@ void FileBrowserComponent::resized()
//==============================================================================
void FileBrowserComponent::sendListenerChangeMessage()
{
Component::SafePointer<Component> deletionWatcher (this);
Component::BailOutChecker checker (this);
if (previewComp != 0)
previewComp->selectedFileChanged (getSelectedFile (0));
// You shouldn't delete the browser when the file gets changed!
jassert (deletionWatcher != 0);
jassert (! checker.shouldBailOut());
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->selectionChanged();
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
listeners.callChecked (checker, &FileBrowserListener::selectionChanged);
}
void FileBrowserComponent::selectionChanged()
@ -351,17 +340,8 @@ void FileBrowserComponent::selectionChanged()
void FileBrowserComponent::fileClicked (const File& f, const MouseEvent& e)
{
Component::SafePointer<Component> deletionWatcher (this);
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->fileClicked (f, e);
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &FileBrowserListener::fileClicked, f, e);
}
void FileBrowserComponent::fileDoubleClicked (const File& f)
@ -372,17 +352,8 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
}
else
{
Component::SafePointer<Component> deletionWatcher (this);
for (int i = listeners.size(); --i >= 0;)
{
((FileBrowserListener*) listeners.getUnchecked (i))->fileDoubleClicked (f);
if (deletionWatcher == 0)
return;
i = jmin (i, listeners.size() - 1);
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &FileBrowserListener::fileDoubleClicked, f);
}
}

View file

@ -213,7 +213,7 @@ private:
int flags;
File currentRoot;
Array<File> chosenFiles;
SortedSet <void*> listeners;
ListenerList <FileBrowserListener> listeners;
DirectoryContentsDisplayComponent* fileListComponent;
FilePreviewComponent* previewComp;

View file

@ -239,24 +239,18 @@ void FilenameComponent::addRecentlyUsedFile (const File& file)
//==============================================================================
void FilenameComponent::addListener (FilenameComponentListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void FilenameComponent::removeListener (FilenameComponentListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
void FilenameComponent::handleAsyncUpdate()
{
for (int i = listeners.size(); --i >= 0;)
{
((FilenameComponentListener*) listeners.getUnchecked (i))->filenameComponentChanged (this);
i = jmin (i, listeners.size());
}
Component::BailOutChecker checker (this);
listeners.callChecked (checker, &FilenameComponentListener::filenameComponentChanged, this);
}
END_JUCE_NAMESPACE

View file

@ -209,7 +209,7 @@ private:
int maxRecentFiles;
bool isDir, isSaving, isFileDragOver;
String wildcard, enforcedSuffix, browseButtonText;
SortedSet <void*> listeners;
ListenerList <FilenameComponentListener> listeners;
File defaultBrowseFile;
void comboBoxChanged (ComboBox*);

View file

@ -50,9 +50,11 @@ Component* Component::currentlyFocusedComponent = 0;
static Array <Component*> modalComponentStack, modalComponentReturnValueKeys;
static Array <int> modalReturnValues;
static const int customCommandMessage = 0x7fff0001;
static const int exitModalStateMessage = 0x7fff0002;
enum ComponentMessageNumbers
{
customCommandMessage = 0x7fff0001,
exitModalStateMessage = 0x7fff0002
};
//==============================================================================
#define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
@ -70,7 +72,6 @@ Component::Component() throw()
bufferedImage_ (0),
mouseListeners_ (0),
keyListeners_ (0),
componentListeners_ (0),
componentFlags_ (0)
{
}
@ -85,23 +86,13 @@ Component::Component (const String& name) throw()
bufferedImage_ (0),
mouseListeners_ (0),
keyListeners_ (0),
componentListeners_ (0),
componentFlags_ (0)
{
}
Component::~Component()
{
if (componentListeners_ != 0)
{
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentBeingDeleted (*this);
i = jmin (i, componentListeners_->size());
}
}
componentListeners.call (&ComponentListener::componentBeingDeleted, *this);
if (parentComponent_ != 0)
{
@ -124,7 +115,6 @@ Component::~Component()
delete bufferedImage_;
delete mouseListeners_;
delete keyListeners_;
delete componentListeners_;
}
//==============================================================================
@ -147,22 +137,8 @@ void Component::setName (const String& name)
peer->setTitle (name);
}
if (componentListeners_ != 0)
{
SafePointer<Component> safePointer (this);
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentNameChanged (*this);
if (safePointer == 0)
return;
i = jmin (i, componentListeners_->size());
}
}
BailOutChecker checker (this);
componentListeners.callChecked (checker, &ComponentListener::componentNameChanged, *this);
}
}
@ -216,23 +192,12 @@ void Component::visibilityChanged()
void Component::sendVisibilityChangeMessage()
{
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
visibilityChanged();
if (safePointer != 0 && componentListeners_ != 0)
{
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentVisibilityChanged (*this);
if (safePointer == 0)
return;
i = jmin (i, componentListeners_->size());
}
}
if (! checker.shouldBailOut())
componentListeners.callChecked (checker, &ComponentListener::componentVisibilityChanged, *this);
}
bool Component::isShowing() const throw()
@ -903,24 +868,14 @@ void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasRes
}
}
BailOutChecker checker (this);
if (parentComponent_ != 0)
parentComponent_->childBoundsChanged (this);
if (componentListeners_ != 0)
{
SafePointer<Component> safePointer (this);
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentMovedOrResized (*this, wasMoved, wasResized);
if (safePointer == 0)
return;
i = jmin (i, componentListeners_->size());
}
}
if (! checker.shouldBailOut())
componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized,
*this, wasMoved, wasResized);
}
JUCE_CATCH_EXCEPTION
}
@ -1288,7 +1243,13 @@ Component* Component::getTopLevelComponent() const throw()
bool Component::isParentOf (const Component* possibleChild) const throw()
{
while (possibleChild->isValidComponent())
if (! possibleChild->isValidComponent())
{
jassert (possibleChild == 0);
return false;
}
while (possibleChild != 0)
{
possibleChild = possibleChild->parentComponent_;
@ -1310,58 +1271,46 @@ void Component::childrenChanged()
void Component::internalChildrenChanged()
{
SafePointer<Component> safePointer (this);
const bool hasListeners = componentListeners_ != 0;
childrenChanged();
if (hasListeners)
if (componentListeners.isEmpty())
{
if (safePointer == 0)
return;
childrenChanged();
}
else
{
BailOutChecker checker (this);
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentChildrenChanged (*this);
childrenChanged();
if (safePointer == 0)
return;
i = jmin (i, componentListeners_->size());
}
if (! checker.shouldBailOut())
componentListeners.callChecked (checker, &ComponentListener::componentChildrenChanged, *this);
}
}
void Component::internalHierarchyChanged()
{
BailOutChecker checker (this);
parentHierarchyChanged();
SafePointer<Component> safePointer (this);
if (checker.shouldBailOut())
return;
if (componentListeners_ != 0)
{
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentParentHierarchyChanged (*this);
componentListeners.callChecked (checker, &ComponentListener::componentParentHierarchyChanged, *this);
if (safePointer == 0)
return;
i = jmin (i, componentListeners_->size());
}
}
if (checker.shouldBailOut())
return;
for (int i = childComponentList_.size(); --i >= 0;)
{
childComponentList_.getUnchecked (i)->internalHierarchyChanged();
// you really shouldn't delete the parent component during a callback telling you
// that it's changed..
jassert (safePointer != 0);
if (safePointer == 0)
if (checker.shouldBailOut())
{
// you really shouldn't delete the parent component during a callback telling you
// that it's changed..
jassertfalse;
return;
}
i = jmin (i, childComponentList_.size());
}
@ -2077,18 +2026,14 @@ void Component::parentSizeChanged()
void Component::addComponentListener (ComponentListener* const newListener) throw()
{
if (componentListeners_ == 0)
componentListeners_ = new VoidArray();
componentListeners_->addIfNotAlreadyThere (newListener);
componentListeners.add (newListener);
}
void Component::removeComponentListener (ComponentListener* const listenerToRemove) throw()
{
jassert (isValidComponent());
if (componentListeners_ != 0)
componentListeners_->removeValue (listenerToRemove);
componentListeners.remove (listenerToRemove);
}
//==============================================================================
@ -2204,13 +2149,13 @@ void Component::internalMouseEnter (MouseInputSource& source, const Point<int>&
return;
}
if (isValidComponent() && ! flags.mouseInsideFlag)
if (! flags.mouseInsideFlag)
{
flags.mouseInsideFlag = true;
flags.mouseOverFlag = true;
flags.draggingFlag = false;
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
if (flags.repaintOnMouseActivityFlag)
repaint();
@ -2221,20 +2166,14 @@ void Component::internalMouseEnter (MouseInputSource& source, const Point<int>&
mouseEnter (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
Desktop::getInstance().resetTimer();
Desktop::getInstance().mouseListeners.callChecked (checker, &MouseListener::mouseEnter, me);
for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
{
((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseEnter (me);
if (safePointer == 0)
return;
i = jmin (i, Desktop::getInstance().mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2242,7 +2181,7 @@ void Component::internalMouseEnter (MouseInputSource& source, const Point<int>&
{
((MouseListener*) mouseListeners_->getUnchecked(i))->mouseEnter (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2253,16 +2192,19 @@ void Component::internalMouseEnter (MouseInputSource& source, const Point<int>&
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked(i)))->mouseEnter (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked(i)))->mouseEnter (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2272,13 +2214,13 @@ void Component::internalMouseEnter (MouseInputSource& source, const Point<int>&
void Component::internalMouseExit (MouseInputSource& source, const Point<int>& relativePos, const Time& time)
{
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
if (flags.draggingFlag)
{
internalMouseUp (source, relativePos, time, source.getCurrentModifiers().getRawFlags());
if (safePointer == 0)
if (checker.shouldBailOut())
return;
}
@ -2296,20 +2238,14 @@ void Component::internalMouseExit (MouseInputSource& source, const Point<int>& r
time, 0, false);
mouseExit (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
Desktop::getInstance().resetTimer();
Desktop::getInstance().mouseListeners.callChecked (checker, &MouseListener::mouseExit, me);
for (int i = Desktop::getInstance().mouseListeners.size(); --i >= 0;)
{
((MouseListener*) Desktop::getInstance().mouseListeners[i])->mouseExit (me);
if (safePointer == 0)
return;
i = jmin (i, Desktop::getInstance().mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2317,7 +2253,7 @@ void Component::internalMouseExit (MouseInputSource& source, const Point<int>& r
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseExit (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2328,16 +2264,19 @@ void Component::internalMouseExit (MouseInputSource& source, const Point<int>& r
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseExit (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseExit (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2406,13 +2345,13 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
{
Desktop& desktop = Desktop::getInstance();
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
if (isCurrentlyBlockedByAnotherModalComponent())
{
internalModalInputAttempt();
if (safePointer == 0)
if (checker.shouldBailOut())
return;
// If processing the input attempt has exited the modal loop, we'll allow the event
@ -2425,17 +2364,7 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
source.getNumberOfMultipleClicks(), false);
desktop.resetTimer();
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseDown (me);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseDown, me);
return;
}
}
@ -2449,7 +2378,7 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
{
c->toFront (true);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
}
@ -2461,7 +2390,7 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
{
grabFocusInternal (focusChangedByMouseClick);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
}
@ -2476,20 +2405,14 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
source.getNumberOfMultipleClicks(), false);
mouseDown (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
desktop.resetTimer();
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseDown, me);
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseDown (me);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2497,7 +2420,7 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseDown (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2508,16 +2431,19 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDown (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDown (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2527,13 +2453,13 @@ void Component::internalMouseDown (MouseInputSource& source, const Point<int>& r
//==============================================================================
void Component::internalMouseUp (MouseInputSource& source, const Point<int>& relativePos, const Time& time, const ModifierKeys& oldModifiers)
{
if (isValidComponent() && flags.draggingFlag)
if (flags.draggingFlag)
{
Desktop& desktop = Desktop::getInstance();
flags.draggingFlag = false;
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
if (flags.repaintOnMouseActivityFlag)
repaint();
@ -2547,20 +2473,14 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
mouseUp (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
desktop.resetTimer();
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseUp, me);
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseUp (me);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2568,7 +2488,7 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseUp (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2580,16 +2500,19 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseUp (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseUp (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2603,20 +2526,17 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
mouseDoubleClick (me);
int i;
for (i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseDoubleClick (me);
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseDoubleClick, me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
for (int i = numListeners; --i >= 0;)
{
if (checker.shouldBailOut())
return;
i = jmin (i, desktop.mouseListeners.size());
}
for (i = numListeners; --i >= 0;)
{
if (safePointer == 0 || mouseListeners_ == 0)
if (mouseListeners_ == 0)
return;
MouseListener* const ml = (MouseListener*)((*mouseListeners_)[i]);
@ -2624,23 +2544,26 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
ml->mouseDoubleClick (me);
}
if (safePointer == 0)
if (checker.shouldBailOut())
return;
Component* p = parentComponent_;
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDoubleClick (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDoubleClick (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2651,13 +2574,13 @@ void Component::internalMouseUp (MouseInputSource& source, const Point<int>& rel
void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& relativePos, const Time& time)
{
if (isValidComponent() && flags.draggingFlag)
if (flags.draggingFlag)
{
Desktop& desktop = Desktop::getInstance();
flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false);
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
const MouseEvent me (source, relativePos,
source.getCurrentModifiers(), this, time,
@ -2668,20 +2591,14 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
mouseDrag (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
desktop.resetTimer();
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me);
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseDrag (me);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2689,7 +2606,7 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseDrag (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2700,16 +2617,19 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDrag (me);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseDrag (me);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2719,73 +2639,66 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
void Component::internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time)
{
SafePointer<Component> safePointer (this);
Desktop& desktop = Desktop::getInstance();
BailOutChecker checker (this);
if (isValidComponent())
const MouseEvent me (source, relativePos, source.getCurrentModifiers(),
this, time, relativePos,
time, 0, false);
if (isCurrentlyBlockedByAnotherModalComponent())
{
Desktop& desktop = Desktop::getInstance();
// allow blocked mouse-events to go to global listeners..
desktop.sendMouseMove();
}
else
{
flags.mouseOverFlag = true;
const MouseEvent me (source, relativePos, source.getCurrentModifiers(),
this, time, relativePos,
time, 0, false);
mouseMove (me);
if (isCurrentlyBlockedByAnotherModalComponent())
if (checker.shouldBailOut())
return;
desktop.resetTimer();
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseMove, me);
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
// allow blocked mouse-events to go to global listeners..
desktop.sendMouseMove();
}
else
{
flags.mouseOverFlag = true;
mouseMove (me);
if (safePointer == 0)
return;
desktop.resetTimer();
for (int i = desktop.mouseListeners.size(); --i >= 0;)
for (int i = mouseListeners_->size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseMove (me);
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseMove (me);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, desktop.mouseListeners.size());
i = jmin (i, mouseListeners_->size());
}
}
if (mouseListeners_ != 0)
Component* p = parentComponent_;
while (p != 0)
{
if (p->numDeepMouseListeners > 0)
{
for (int i = mouseListeners_->size(); --i >= 0;)
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseMove (me);
if (safePointer == 0)
return;
i = jmin (i, mouseListeners_->size());
}
}
Component* p = parentComponent_;
while (p != 0)
{
SafePointer<Component> parentPointer (p);
BailOutChecker checker (this, p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseMove (me);
if (safePointer == 0 || parentPointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
p = p->parentComponent_;
}
p = p->parentComponent_;
}
}
}
@ -2794,7 +2707,7 @@ void Component::internalMouseWheel (MouseInputSource& source, const Point<int>&
const Time& time, const float amountX, const float amountY)
{
Desktop& desktop = Desktop::getInstance();
SafePointer<Component> safePointer (this);
BailOutChecker checker (this);
const float wheelIncrementX = amountX * (1.0f / 256.0f);
const float wheelIncrementY = amountY * (1.0f / 256.0f);
@ -2805,32 +2718,19 @@ void Component::internalMouseWheel (MouseInputSource& source, const Point<int>&
if (isCurrentlyBlockedByAnotherModalComponent())
{
// allow blocked mouse-events to go to global listeners..
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheelIncrementX, wheelIncrementY);
}
else
{
mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
for (int i = desktop.mouseListeners.size(); --i >= 0;)
{
((MouseListener*) desktop.mouseListeners[i])->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
desktop.mouseListeners.callChecked (checker, &MouseListener::mouseWheelMove, me, wheelIncrementX, wheelIncrementY);
if (safePointer == 0)
return;
i = jmin (i, desktop.mouseListeners.size());
}
if (checker.shouldBailOut())
return;
if (mouseListeners_ != 0)
{
@ -2838,7 +2738,7 @@ void Component::internalMouseWheel (MouseInputSource& source, const Point<int>&
{
((MouseListener*) mouseListeners_->getUnchecked (i))->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
if (safePointer == 0)
if (checker.shouldBailOut())
return;
i = jmin (i, mouseListeners_->size());
@ -2849,16 +2749,19 @@ void Component::internalMouseWheel (MouseInputSource& source, const Point<int>&
while (p != 0)
{
SafePointer<Component> parentPointer (p);
for (int i = p->numDeepMouseListeners; --i >= 0;)
if (p->numDeepMouseListeners > 0)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
BailOutChecker checker (this, p);
if (safePointer == 0 || parentPointer == 0)
return;
for (int i = p->numDeepMouseListeners; --i >= 0;)
{
((MouseListener*) (p->mouseListeners_->getUnchecked (i)))->mouseWheelMove (me, wheelIncrementX, wheelIncrementY);
i = jmin (i, p->numDeepMouseListeners);
if (checker.shouldBailOut())
return;
i = jmin (i, p->numDeepMouseListeners);
}
}
p = p->parentComponent_;
@ -2877,39 +2780,29 @@ void Component::broughtToFront()
void Component::internalBroughtToFront()
{
if (isValidComponent())
{
if (flags.hasHeavyweightPeerFlag)
Desktop::getInstance().componentBroughtToFront (this);
if (! isValidComponent())
return;
SafePointer<Component> safePointer (this);
broughtToFront();
if (flags.hasHeavyweightPeerFlag)
Desktop::getInstance().componentBroughtToFront (this);
if (safePointer == 0)
return;
BailOutChecker checker (this);
broughtToFront();
if (componentListeners_ != 0)
{
for (int i = componentListeners_->size(); --i >= 0;)
{
((ComponentListener*) componentListeners_->getUnchecked (i))
->componentBroughtToFront (*this);
if (checker.shouldBailOut())
return;
if (safePointer == 0)
return;
componentListeners.callChecked (checker, &ComponentListener::componentBroughtToFront, *this);
i = jmin (i, componentListeners_->size());
}
}
if (checker.shouldBailOut())
return;
// when brought to the front and there's a modal component blocking this one,
// we need to bring the modal one to the front instead..
// When brought to the front and there's a modal component blocking this one,
// we need to bring the modal one to the front instead..
Component* const cm = getCurrentlyModalComponent();
Component* const cm = getCurrentlyModalComponent();
if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent())
bringModalComponentToFront();
}
if (cm != 0 && cm->getTopLevelComponent() != getTopLevelComponent())
bringModalComponentToFront();
}
void Component::focusGained (FocusChangeType)
@ -3311,6 +3204,18 @@ ComponentPeer* Component::getPeer() const throw()
return 0;
}
//==============================================================================
Component::BailOutChecker::BailOutChecker (Component* const component1, Component* const component2_)
: safePointer1 (component1), safePointer2 (component2_), component2 (component2_)
{
jassert (component1 != 0);
}
bool Component::BailOutChecker::shouldBailOut() const throw()
{
return safePointer1 == 0 || safePointer2 != component2;
}
//==============================================================================
ComponentDeletionWatcher::ComponentDeletionWatcher (const Component* const componentToWatch_) throw()
: componentToWatch (componentToWatch_),

View file

@ -36,6 +36,7 @@
#include "../graphics/geometry/juce_RectangleList.h"
#include "../graphics/geometry/juce_BorderSize.h"
#include "../../events/juce_MessageListener.h"
#include "../../events/juce_ListenerList.h"
#include "../../text/juce_StringArray.h"
#include "../../containers/juce_VoidArray.h"
#include "../../containers/juce_NamedValueSet.h"
@ -1931,10 +1932,7 @@ public:
}
/** Returns the component that this pointer refers to, or null if the component no longer exists. */
operator ComponentType*() throw() { return comp; }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */
operator const ComponentType*() const throw() { return comp; }
operator ComponentType*() const throw() { return comp; }
/** Returns the component that this pointer refers to, or null if the component no longer exists. */
ComponentType* operator->() throw() { jassert (comp != 0); return comp; }
@ -1953,6 +1951,35 @@ public:
void componentBeingDeleted (Component&) { comp = 0; }
};
//==============================================================================
/** A class to keep an eye on one or two components and check for them being deleted.
This is designed for use with the ListenerList::callChecked() methods, to allow
the list iterator to stop cleanly if the component is deleted by a listener callback
while the list is still being iterated.
*/
class BailOutChecker
{
public:
/** Creates a checker that watches either one or two components.
component1 must be a valid component; component2 can be null if you only need
to check on one component.
*/
BailOutChecker (Component* const component1,
Component* const component2 = 0);
/** Returns true if either of the two components have been deleted since this
object was created. */
bool shouldBailOut() const throw();
private:
Component::SafePointer<Component> safePointer1, safePointer2;
Component* const component2;
BailOutChecker (const BailOutChecker&);
BailOutChecker& operator= (const BailOutChecker&);
};
//==============================================================================
juce_UseDebuggingNewOperator
@ -1978,7 +2005,7 @@ private:
Image* bufferedImage_;
VoidArray* mouseListeners_;
VoidArray* keyListeners_;
VoidArray* componentListeners_;
ListenerList <ComponentListener> componentListeners;
NamedValueSet properties;
struct ComponentFlags

View file

@ -36,6 +36,6 @@ void ComponentListener::componentVisibilityChanged (Component&) {}
void ComponentListener::componentChildrenChanged (Component&) {}
void ComponentListener::componentParentHierarchyChanged (Component&) {}
void ComponentListener::componentNameChanged (Component&) {}
void ComponentListener::componentBeingDeleted (Component& component) {}
void ComponentListener::componentBeingDeleted (Component&) {}
END_JUCE_NAMESPACE

View file

@ -36,7 +36,7 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
Desktop::Desktop() throw()
Desktop::Desktop()
: mouseClickCounter (0),
kioskModeComponent (0)
{
@ -44,7 +44,7 @@ Desktop::Desktop() throw()
refreshMonitorSizes();
}
Desktop::~Desktop() throw()
Desktop::~Desktop()
{
jassert (instance == this);
instance = 0;
@ -54,7 +54,7 @@ Desktop::~Desktop() throw()
jassert (desktopComponents.size() == 0);
}
Desktop& JUCE_CALLTYPE Desktop::getInstance() throw()
Desktop& JUCE_CALLTYPE Desktop::getInstance()
{
if (instance == 0)
instance = new Desktop();
@ -68,7 +68,7 @@ Desktop* Desktop::instance = 0;
extern void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords,
const bool clipToWorkArea);
void Desktop::refreshMonitorSizes() throw()
void Desktop::refreshMonitorSizes()
{
const Array <Rectangle<int> > oldClipped (monitorCoordsClipped);
const Array <Rectangle<int> > oldUnclipped (monitorCoordsUnclipped);
@ -118,7 +118,7 @@ const Rectangle<int> Desktop::getMainMonitorArea (const bool clippedToWorkArea)
return getDisplayMonitorCoordinates (0, clippedToWorkArea);
}
const Rectangle<int> Desktop::getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea) const throw()
const Rectangle<int> Desktop::getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea) const
{
Rectangle<int> best (getMainMonitorArea (clippedToWorkArea));
double bestDistance = 1.0e10;
@ -168,19 +168,19 @@ Component* Desktop::findComponentAt (const Point<int>& screenPosition) const
}
//==============================================================================
void Desktop::addDesktopComponent (Component* const c) throw()
void Desktop::addDesktopComponent (Component* const c)
{
jassert (c != 0);
jassert (! desktopComponents.contains (c));
desktopComponents.addIfNotAlreadyThere (c);
}
void Desktop::removeDesktopComponent (Component* const c) throw()
void Desktop::removeDesktopComponent (Component* const c)
{
desktopComponents.removeValue (c);
}
void Desktop::componentBroughtToFront (Component* const c) throw()
void Desktop::componentBroughtToFront (Component* const c)
{
const int index = desktopComponents.indexOf (c);
jassert (index >= 0);
@ -249,52 +249,40 @@ MouseInputSource* Desktop::getDraggingMouseSource (int index) const throw()
}
//==============================================================================
void Desktop::addGlobalMouseListener (MouseListener* const listener) throw()
void Desktop::addFocusChangeListener (FocusChangeListener* const listener)
{
jassert (listener != 0);
if (listener != 0)
{
mouseListeners.add (listener);
resetTimer();
}
focusListeners.add (listener);
}
void Desktop::removeGlobalMouseListener (MouseListener* const listener) throw()
void Desktop::removeFocusChangeListener (FocusChangeListener* const listener)
{
mouseListeners.removeValue (listener);
resetTimer();
focusListeners.remove (listener);
}
//==============================================================================
void Desktop::addFocusChangeListener (FocusChangeListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
focusListeners.add (listener);
}
void Desktop::removeFocusChangeListener (FocusChangeListener* const listener) throw()
{
focusListeners.removeValue (listener);
}
void Desktop::triggerFocusCallback() throw()
void Desktop::triggerFocusCallback()
{
triggerAsyncUpdate();
}
void Desktop::handleAsyncUpdate()
{
for (int i = focusListeners.size(); --i >= 0;)
{
((FocusChangeListener*) focusListeners.getUnchecked (i))->globalFocusChanged (Component::getCurrentlyFocusedComponent());
i = jmin (i, focusListeners.size());
}
Component* currentFocus = Component::getCurrentlyFocusedComponent();
focusListeners.call (&FocusChangeListener::globalFocusChanged, currentFocus);
}
//==============================================================================
void Desktop::addGlobalMouseListener (MouseListener* const listener)
{
mouseListeners.add (listener);
resetTimer();
}
void Desktop::removeGlobalMouseListener (MouseListener* const listener)
{
mouseListeners.remove (listener);
resetTimer();
}
void Desktop::timerCallback()
{
if (lastFakeMouseMove != getMousePosition())
@ -303,7 +291,7 @@ void Desktop::timerCallback()
void Desktop::sendMouseMove()
{
if (mouseListeners.size() > 0)
if (! mouseListeners.isEmpty())
{
startTimer (20);
@ -313,30 +301,22 @@ void Desktop::sendMouseMove()
if (target != 0)
{
Component::SafePointer<Component> deletionChecker (target);
Component::BailOutChecker checker (target);
const Point<int> pos (target->globalPositionToRelative (lastFakeMouseMove));
const Time now (Time::getCurrentTime());
const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(),
target, now, pos, now, 0, false);
for (int i = mouseListeners.size(); --i >= 0;)
{
if (ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown())
((MouseListener*) mouseListeners[i])->mouseDrag (me);
else
((MouseListener*) mouseListeners[i])->mouseMove (me);
if (deletionChecker == 0)
return;
i = jmin (i, mouseListeners.size());
}
if (me.mods.isAnyMouseButtonDown())
mouseListeners.callChecked (checker, &MouseListener::mouseDrag, me);
else
mouseListeners.callChecked (checker, &MouseListener::mouseMove, me);
}
}
}
void Desktop::resetTimer() throw()
void Desktop::resetTimer()
{
if (mouseListeners.size() == 0)
stopTimer();

View file

@ -31,7 +31,6 @@
#include "../../utilities/juce_DeletedAtShutdown.h"
#include "../../events/juce_Timer.h"
#include "../../events/juce_AsyncUpdater.h"
#include "../../containers/juce_SortedSet.h"
#include "../../containers/juce_OwnedArray.h"
#include "../graphics/geometry/juce_RectangleList.h"
class MouseInputSource;
@ -70,7 +69,7 @@ public:
//==============================================================================
/** There's only one dektop object, and this method will return it.
*/
static Desktop& JUCE_CALLTYPE getInstance() throw();
static Desktop& JUCE_CALLTYPE getInstance();
//==============================================================================
/** Returns a list of the positions of all the monitors available.
@ -97,7 +96,7 @@ public:
If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
*/
const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const throw();
const Rectangle<int> getMonitorAreaContaining (const Point<int>& position, const bool clippedToWorkArea = true) const;
//==============================================================================
@ -157,23 +156,23 @@ public:
@see removeGlobalMouseListener
*/
void addGlobalMouseListener (MouseListener* const listener) throw();
void addGlobalMouseListener (MouseListener* const listener);
/** Unregisters a MouseListener that was added with the addGlobalMouseListener()
method.
@see addGlobalMouseListener
*/
void removeGlobalMouseListener (MouseListener* const listener) throw();
void removeGlobalMouseListener (MouseListener* const listener);
//==============================================================================
/** Registers a MouseListener that will receive a callback whenever the focused
component changes.
*/
void addFocusChangeListener (FocusChangeListener* const listener) throw();
void addFocusChangeListener (FocusChangeListener* const listener);
/** Unregisters a listener that was added with addFocusChangeListener(). */
void removeFocusChangeListener (FocusChangeListener* const listener) throw();
void removeFocusChangeListener (FocusChangeListener* const listener);
//==============================================================================
/** Takes a component and makes it full-screen, removing the taskbar, dock, etc.
@ -198,7 +197,7 @@ public:
This is the component that was last set by setKioskModeComponent(). If none
has been set, this returns 0.
*/
Component* getKioskModeComponent() const { return kioskModeComponent; }
Component* getKioskModeComponent() const throw() { return kioskModeComponent; }
//==============================================================================
/** Returns the number of components that are currently active as top-level
@ -269,7 +268,7 @@ public:
(Called internally by the native code).
*/
void refreshMonitorSizes() throw();
void refreshMonitorSizes();
/** True if the OS supports semitransparent windows */
static bool canUseSemiTransparentWindows() throw();
@ -282,42 +281,43 @@ private:
friend class ComponentPeer;
friend class MouseInputSource;
friend class MouseInputSourceInternal;
SortedSet <void*> mouseListeners, focusListeners;
Array <Component*> desktopComponents;
friend class DeletedAtShutdown;
friend class TopLevelWindowManager;
Desktop() throw();
~Desktop() throw();
Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped;
OwnedArray <MouseInputSource> mouseSources;
void createMouseInputSources();
ListenerList <MouseListener> mouseListeners;
ListenerList <FocusChangeListener> focusListeners;
Array <Component*> desktopComponents;
Array <Rectangle<int> > monitorCoordsClipped, monitorCoordsUnclipped;
Point<int> lastFakeMouseMove;
int mouseClickCounter;
void sendMouseMove();
int mouseClickCounter;
void incrementMouseClickCounter() throw();
Component* kioskModeComponent;
Rectangle<int> kioskComponentOriginalBounds;
void createMouseInputSources();
void timerCallback();
void sendMouseMove();
void resetTimer() throw();
void resetTimer();
int getNumDisplayMonitors() const throw();
const Rectangle<int> getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw();
void addDesktopComponent (Component* const c) throw();
void removeDesktopComponent (Component* const c) throw();
void componentBroughtToFront (Component* const c) throw();
void addDesktopComponent (Component* const c);
void removeDesktopComponent (Component* const c);
void componentBroughtToFront (Component* const c);
void triggerFocusCallback() throw();
void triggerFocusCallback();
void handleAsyncUpdate();
Desktop();
~Desktop();
Desktop (const Desktop&);
Desktop& operator= (const Desktop&);
};

View file

@ -189,25 +189,17 @@ void ScrollBar::setButtonRepeatSpeed (const int initialDelayInMillisecs_,
//==============================================================================
void ScrollBar::addListener (ScrollBarListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
listeners.add (listener);
}
void ScrollBar::removeListener (ScrollBarListener* const listener) throw()
{
listeners.removeValue (listener);
listeners.remove (listener);
}
void ScrollBar::handleAsyncUpdate()
{
const double value = getCurrentRangeStart();
for (int i = listeners.size(); --i >= 0;)
{
((ScrollBarListener*) listeners.getUnchecked (i))->scrollBarMoved (this, value);
i = jmin (i, listeners.size());
}
listeners.call (&ScrollBarListener::scrollBarMoved, this, rangeStart);
}
//==============================================================================

View file

@ -293,7 +293,7 @@ private:
bool vertical, isDraggingThumb, alwaysVisible;
Button* upButton;
Button* downButton;
SortedSet <void*> listeners;
ListenerList <ScrollBarListener> listeners;
void updateThumbPosition() throw();
void timerCallback();

View file

@ -63,11 +63,7 @@ void MenuBarModel::setApplicationCommandManagerToWatch (ApplicationCommandManage
void MenuBarModel::addListener (MenuBarModelListener* const newListener) throw()
{
jassert (newListener != 0);
jassert (! listeners.contains (newListener)); // trying to add a listener to the list twice!
if (newListener != 0)
listeners.add (newListener);
listeners.add (newListener);
}
void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove) throw()
@ -77,26 +73,18 @@ void MenuBarModel::removeListener (MenuBarModelListener* const listenerToRemove)
// deleted this menu model while it's still being used by something (e.g. by a MenuBarComponent)
jassert (listeners.contains (listenerToRemove));
listeners.removeValue (listenerToRemove);
}
void MenuBarModel::handleAsyncUpdate()
{
for (int i = listeners.size(); --i >= 0;)
{
((MenuBarModelListener*) listeners.getUnchecked (i))->menuBarItemsChanged (this);
i = jmin (i, listeners.size());
}
listeners.remove (listenerToRemove);
}
//==============================================================================
void MenuBarModel::handleAsyncUpdate()
{
listeners.call (&MenuBarModelListener::menuBarItemsChanged, this);
}
void MenuBarModel::applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info)
{
for (int i = listeners.size(); --i >= 0;)
{
((MenuBarModelListener*) listeners.getUnchecked (i))->menuCommandInvoked (this, info);
i = jmin (i, listeners.size());
}
listeners.call (&MenuBarModelListener::menuCommandInvoked, this, info);
}
void MenuBarModel::applicationCommandListChanged()

View file

@ -172,7 +172,7 @@ public:
private:
ApplicationCommandManager* manager;
SortedSet <void*> listeners;
ListenerList <MenuBarModelListener> listeners;
MenuBarModel (const MenuBarModel&);
MenuBarModel& operator= (const MenuBarModel&);

View file

@ -351,6 +351,7 @@ public:
mw->menuBarComponent = menuBarComponent;
mw->managerOfChosenCommand = managerOfChosenCommand;
mw->componentAttachedTo = componentAttachedTo;
mw->componentAttachedToOriginal = componentAttachedTo;
mw->calculateWindowPos (minX, maxX, minY, maxY, alignToRectangle);
mw->setTopLeftPosition (mw->windowPos.getX(),
@ -502,16 +503,14 @@ public:
}
else if (key.isKeyCode (KeyPress::leftKey))
{
Window* parentWindow = owner;
if (parentWindow != 0)
if (owner != 0)
{
PopupMenu::ItemComponent* currentChildOfParent
= (parentWindow != 0) ? parentWindow->currentChild : 0;
Component::SafePointer<Window> parentWindow (owner);
PopupMenu::ItemComponent* currentChildOfParent = parentWindow->currentChild;
hide (0);
if (parentWindow->isValidComponent())
if (parentWindow != 0)
parentWindow->setCurrentlyHighlightedChild (currentChildOfParent);
disableTimerUntilMouseMoves();
@ -594,7 +593,7 @@ public:
if (! isVisible())
return;
if (componentAttachedTo == 0)
if (componentAttachedTo != componentAttachedToOriginal)
{
dismissMenu (0);
return;
@ -748,6 +747,7 @@ private:
Component* menuBarComponent;
ApplicationCommandManager** managerOfChosenCommand;
Component::SafePointer<Component> componentAttachedTo;
Component* componentAttachedToOriginal;
Rectangle<int> windowPos;
Point<int> lastMouse;
int minimumWidth, maximumNumColumns, standardItemHeight;