Browse Source

Jack audio fix. New class LinkedListPointer. Couple of new menu methods in DocumentWindow. win32 window size constrainer tweak.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
cac0a7e3f8
27 changed files with 1288 additions and 990 deletions
  1. +2
    -0
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  2. +1
    -0
      Builds/VisualStudio2005/Juce.vcproj
  3. +1
    -0
      Builds/VisualStudio2008/Juce.vcproj
  4. +1
    -0
      Builds/VisualStudio2008_DLL/Juce.vcproj
  5. +1
    -0
      Builds/VisualStudio2010/Juce.vcxproj
  6. +3
    -0
      Builds/VisualStudio2010/Juce.vcxproj.filters
  7. +2
    -0
      Builds/iPhone/Juce.xcodeproj/project.pbxproj
  8. +2
    -0
      Juce.jucer
  9. +232
    -438
      juce_amalgamated.cpp
  10. +437
    -104
      juce_amalgamated.h
  11. +343
    -0
      src/containers/juce_LinkedListPointer.h
  12. +1
    -1
      src/core/juce_StandardHeader.h
  13. +9
    -1
      src/gui/components/buttons/juce_Button.cpp
  14. +51
    -64
      src/gui/components/juce_Component.cpp
  15. +2
    -1
      src/gui/components/juce_Component.h
  16. +1
    -0
      src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp
  17. +41
    -38
      src/gui/components/windows/juce_DocumentWindow.cpp
  18. +14
    -2
      src/gui/components/windows/juce_DocumentWindow.h
  19. +7
    -2
      src/gui/graphics/drawables/juce_DrawableImage.cpp
  20. +1
    -0
      src/gui/graphics/drawables/juce_DrawableShape.cpp
  21. +3
    -0
      src/juce_core_includes.h
  22. +1
    -1
      src/native/linux/juce_linux_JackAudio.cpp
  23. +1
    -1
      src/native/mac/juce_mac_ObjCSuffix.h
  24. +44
    -3
      src/native/windows/juce_win32_Windowing.cpp
  25. +15
    -52
      src/text/juce_XmlDocument.cpp
  26. +64
    -277
      src/text/juce_XmlElement.cpp
  27. +8
    -5
      src/text/juce_XmlElement.h

+ 2
- 0
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -490,6 +490,7 @@
F77C9170829579FABA5679AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DynamicObject.cpp; path = ../../src/containers/juce_DynamicObject.cpp; sourceTree = SOURCE_ROOT; };
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
9289A1E6B141F24C57FF0927 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LinkedListPointer.h; path = ../../src/containers/juce_LinkedListPointer.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
BB4A73064B0FC74ECCA19116 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NamedValueSet.h; path = ../../src/containers/juce_NamedValueSet.h; sourceTree = SOURCE_ROOT; };
C1913C90ED7BE51E823887CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_OwnedArray.h; path = ../../src/containers/juce_OwnedArray.h; sourceTree = SOURCE_ROOT; };
@@ -1217,6 +1218,7 @@
F77C9170829579FABA5679AD,
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
9289A1E6B141F24C57FF0927,
70E5409425A76782B6188B31,
BB4A73064B0FC74ECCA19116,
C1913C90ED7BE51E823887CD,


+ 1
- 0
Builds/VisualStudio2005/Juce.vcproj View File

@@ -353,6 +353,7 @@
<File RelativePath="..\..\src\containers\juce_DynamicObject.cpp"/>
<File RelativePath="..\..\src\containers\juce_DynamicObject.h"/>
<File RelativePath="..\..\src\containers\juce_ElementComparator.h"/>
<File RelativePath="..\..\src\containers\juce_LinkedListPointer.h"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.cpp"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.h"/>
<File RelativePath="..\..\src\containers\juce_OwnedArray.h"/>


+ 1
- 0
Builds/VisualStudio2008/Juce.vcproj View File

@@ -353,6 +353,7 @@
<File RelativePath="..\..\src\containers\juce_DynamicObject.cpp"/>
<File RelativePath="..\..\src\containers\juce_DynamicObject.h"/>
<File RelativePath="..\..\src\containers\juce_ElementComparator.h"/>
<File RelativePath="..\..\src\containers\juce_LinkedListPointer.h"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.cpp"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.h"/>
<File RelativePath="..\..\src\containers\juce_OwnedArray.h"/>


+ 1
- 0
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -355,6 +355,7 @@
<File RelativePath="..\..\src\containers\juce_DynamicObject.cpp"/>
<File RelativePath="..\..\src\containers\juce_DynamicObject.h"/>
<File RelativePath="..\..\src\containers\juce_ElementComparator.h"/>
<File RelativePath="..\..\src\containers\juce_LinkedListPointer.h"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.cpp"/>
<File RelativePath="..\..\src\containers\juce_NamedValueSet.h"/>
<File RelativePath="..\..\src\containers\juce_OwnedArray.h"/>


+ 1
- 0
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -509,6 +509,7 @@
<ClInclude Include="..\..\src\containers\juce_ArrayAllocationBase.h"/>
<ClInclude Include="..\..\src\containers\juce_DynamicObject.h"/>
<ClInclude Include="..\..\src\containers\juce_ElementComparator.h"/>
<ClInclude Include="..\..\src\containers\juce_LinkedListPointer.h"/>
<ClInclude Include="..\..\src\containers\juce_NamedValueSet.h"/>
<ClInclude Include="..\..\src\containers\juce_OwnedArray.h"/>
<ClInclude Include="..\..\src\containers\juce_PropertySet.h"/>


+ 3
- 0
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -1455,6 +1455,9 @@
<ClInclude Include="..\..\src\containers\juce_ElementComparator.h">
<Filter>Juce\Source\containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\containers\juce_LinkedListPointer.h">
<Filter>Juce\Source\containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\containers\juce_NamedValueSet.h">
<Filter>Juce\Source\containers</Filter>
</ClInclude>


+ 2
- 0
Builds/iPhone/Juce.xcodeproj/project.pbxproj View File

@@ -490,6 +490,7 @@
F77C9170829579FABA5679AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DynamicObject.cpp; path = ../../src/containers/juce_DynamicObject.cpp; sourceTree = SOURCE_ROOT; };
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
9289A1E6B141F24C57FF0927 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LinkedListPointer.h; path = ../../src/containers/juce_LinkedListPointer.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
BB4A73064B0FC74ECCA19116 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NamedValueSet.h; path = ../../src/containers/juce_NamedValueSet.h; sourceTree = SOURCE_ROOT; };
C1913C90ED7BE51E823887CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_OwnedArray.h; path = ../../src/containers/juce_OwnedArray.h; sourceTree = SOURCE_ROOT; };
@@ -1217,6 +1218,7 @@
F77C9170829579FABA5679AD,
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
9289A1E6B141F24C57FF0927,
70E5409425A76782B6188B31,
BB4A73064B0FC74ECCA19116,
C1913C90ED7BE51E823887CD,


+ 2
- 0
Juce.jucer View File

@@ -365,6 +365,8 @@
file="src/containers/juce_DynamicObject.h"/>
<FILE id="RNHQjBFmS" name="juce_ElementComparator.h" compile="0" resource="0"
file="src/containers/juce_ElementComparator.h"/>
<FILE id="pnNXeAf" name="juce_LinkedListPointer.h" compile="0" resource="0"
file="src/containers/juce_LinkedListPointer.h"/>
<FILE id="zy1yAvLC1" name="juce_NamedValueSet.cpp" compile="1" resource="0"
file="src/containers/juce_NamedValueSet.cpp"/>
<FILE id="YIzV0n7ns" name="juce_NamedValueSet.h" compile="0" resource="0"


+ 232
- 438
juce_amalgamated.cpp
File diff suppressed because it is too large
View File


+ 437
- 104
juce_amalgamated.h View File

@@ -64,7 +64,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 110
#define JUCE_BUILDNUMBER 111

/** Current Juce version number.

@@ -6624,6 +6624,325 @@ private:
#endif
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__

#endif
#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__

/*** Start of inlined file: juce_LinkedListPointer.h ***/
#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
#define __JUCE_LINKEDLISTPOINTER_JUCEHEADER__

/**
Helps to manipulate singly-linked lists of objects.

For objects that are designed to contain a pointer to the subsequent item in the
list, this class contains methods to deal with the list. To use it, the ObjectType
class that it points to must contain a LinkedListPointer called nextListItem, e.g.

@code
struct MyObject
{
int x, y, z;

// A linkable object must contain a member with this name and type, which must be
// accessible by the LinkedListPointer class. (This doesn't mean it has to be public -
// you could make your class a friend of a LinkedListPointer<MyObject> instead).
LinkedListPointer<MyObject> nextListItem;
};

LinkedListPointer<MyObject> myList;
myList.append (new MyObject());
myList.append (new MyObject());

int numItems = myList.size(); // returns 2
MyObject* lastInList = myList.getLast();
@endcode
*/
template <class ObjectType>
class LinkedListPointer
{
public:

/** Creates a null pointer to an empty list. */
LinkedListPointer() throw()
: item (0)
{
}

/** Creates a pointer to a list whose head is the item provided. */
explicit LinkedListPointer (ObjectType* const headItem) throw()
: item (headItem)
{
}

/** Sets this pointer to point to a new list. */
LinkedListPointer& operator= (ObjectType* const newItem) throw()
{
item = newItem;
return *this;
}

/** Returns the item which this pointer points to. */
inline operator ObjectType*() const throw()
{
return item;
}

/** Returns the item which this pointer points to. */
inline ObjectType* get() const throw()
{
return item;
}

/** Returns the last item in the list which this pointer points to.
This will iterate the list and return the last item found. Obviously the speed
of this operation will be proportional to the size of the list. If the list is
empty the return value will be this object.
If you're planning on appending a number of items to your list, it's much more
efficient to use the Appender class than to repeatedly call getLast() to find the end.
*/
LinkedListPointer& getLast() throw()
{
LinkedListPointer* l = this;

while (l->item != 0)
l = &(l->item->nextListItem);

return *l;
}

/** Returns the number of items in the list.
Obviously with a simple linked list, getting the size involves iterating the list, so
this can be a lengthy operation - be careful when using this method in your code.
*/
int size() const throw()
{
int total = 0;

for (ObjectType* i = item; i != 0; i = i->nextListItem)
++total;

return total;
}

/** Returns the item at a given index in the list.
Since the only way to find an item is to iterate the list, this operation can obviously
be slow, depending on its size, so you should be careful when using this in algorithms.
*/
LinkedListPointer& operator[] (int index) throw()
{
LinkedListPointer* l = this;

while (--index >= 0 && l->item != 0)
l = &(l->item->nextListItem);

return *l;
}

/** Returns the item at a given index in the list.
Since the only way to find an item is to iterate the list, this operation can obviously
be slow, depending on its size, so you should be careful when using this in algorithms.
*/
const LinkedListPointer& operator[] (int index) const throw()
{
const LinkedListPointer* l = this;

while (--index >= 0 && l->item != 0)
l = &(l->item->nextListItem);

return *l;
}

/** Returns true if the list contains the given item. */
bool contains (const ObjectType* const itemToLookFor) const throw()
{
for (ObjectType* i = item; i != 0; i = i->nextListItem)
if (itemToLookFor == i)
return true;

return false;
}

/** Inserts an item into the list, placing it before the item that this pointer
currently points to.
*/
void insertNext (ObjectType* const newItem)
{
jassert (newItem != 0);
jassert (newItem->nextListItem == 0);
newItem->nextListItem = item;
item = newItem;
}

/** Inserts an item at a numeric index in the list.
Obviously this will involve iterating the list to find the item at the given index,
so be careful about the impact this may have on execution time.
*/
void insertAtIndex (int index, ObjectType* newItem)
{
jassert (newItem != 0);
LinkedListPointer* l = this;

while (index != 0 && l->item != 0)
{
l = &(l->item->nextListItem);
--index;
}

l->insertNext (newItem);
}

/** Replaces the object that this pointer points to, appending the rest of the list to
the new object, and returning the old one.
*/
ObjectType* replaceNext (ObjectType* const newItem) throw()
{
jassert (newItem != 0);
jassert (newItem->nextListItem == 0);

ObjectType* const oldItem = item;
item = newItem;
item->nextListItem = oldItem->nextListItem;
oldItem->nextListItem = 0;
return oldItem;
}

/** Adds an item to the end of the list.

This operation involves iterating the whole list, so can be slow - if you need to
append a number of items to your list, it's much more efficient to use the Appender
class than to repeatedly call append().
*/
void append (ObjectType* const newItem)
{
getLast().item = newItem;
}

/** Creates copies of all the items in another list and adds them to this one.
This will use the ObjectType's copy constructor to try to create copies of each
item in the other list, and appends them to this list.
*/
void addCopyOfList (const LinkedListPointer& other)
{
LinkedListPointer* insertPoint = this;

for (ObjectType* i = other.item; i != 0; i = i->nextListItem)
{
insertPoint->insertNext (new ObjectType (*i));
insertPoint = &(insertPoint->item->nextListItem);
}
}

/** Removes the head item from the list.
This won't delete the object that is removed, but returns it, so the caller can
delete it if necessary.
*/
ObjectType* removeNext() throw()
{
if (item == 0)
return 0;

ObjectType* const oldItem = item;
oldItem->nextListItem = 0;
item = item->nextListItem;
return oldItem;
}

/** Removes a specific item from the list.
Note that this will not delete the item, it simply unlinks it from the list.
*/
void remove (ObjectType* const item)
{
LinkedListPointer* l = findPointerTo (item);

if (l != 0)
l->removeNext();
}

/** Iterates the list, calling the delete operator on all of its elements and
leaving this pointer empty.
*/
void deleteAll()
{
while (item != 0)
{
ObjectType* const oldItem = item;
item = oldItem->nextListItem;
delete oldItem;
}
}

/** Finds a pointer to a given item.
If the item is found in the list, this returns the pointer that points to it. If
the item isn't found, this returns null.
*/
LinkedListPointer* findPointerTo (ObjectType* const itemToLookFor) throw()
{
LinkedListPointer* l = this;

while (l->item != 0)
{
if (l->item == itemToLookFor)
return l;

l = &(l->item->nextListItem);
}

return 0;
}

/** Copies the items in the list to an array.
The destArray must contain enough elements to hold the entire list - no checks are
made for this!
*/
void copyToArray (ObjectType** destArray) const throw()
{
jassert (destArray != 0);

for (ObjectType* i = item; i != 0; i = i->nextListItem)
*destArray++ = i;
}

/**
Allows efficient repeated insertions into a list.

You can create an Appender object which points to the last element in your
list, and then repeatedly call Appender::append() to add items to the end
of the list in O(1) time.
*/
class Appender
{
public:
/** Creates an appender which will add items to the given list.
*/
Appender (LinkedListPointer& endOfListPointer) throw()
: endOfList (&endOfListPointer)
{
// This can only be used to add to the end of a list.
jassert (endOfListPointer.item == 0);
}

/** Appends an item to the list. */
void append (ObjectType* const newItem) throw()
{
*endOfList = newItem;
endOfList = &(newItem->nextListItem);
}

private:
LinkedListPointer* endOfList;

JUCE_DECLARE_NON_COPYABLE (Appender);
};

private:

ObjectType* item;
};

#endif // __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
/*** End of inlined file: juce_LinkedListPointer.h ***/


#endif
#ifndef __JUCE_NAMEDVALUESET_JUCEHEADER__

@@ -9835,7 +10154,7 @@ public:

@see getNextElement, isTextElement, forEachXmlChildElement
*/
inline XmlElement* getNextElement() const throw() { return nextElement; }
inline XmlElement* getNextElement() const throw() { return nextListItem; }

/** Returns the next of this element's siblings which has the specified tag
name.
@@ -10070,8 +10389,9 @@ private:
friend class XmlDocument;

String tagName;
XmlElement* firstChildElement;
XmlElement* nextElement;
friend class LinkedListPointer <XmlElement>;
LinkedListPointer <XmlElement> firstChildElement;
LinkedListPointer <XmlElement> nextListItem;

struct XmlAttributeNode
{
@@ -10079,7 +10399,7 @@ private:
XmlAttributeNode (const String& name, const String& value) throw();

String name, value;
XmlAttributeNode* next;
LinkedListPointer<XmlAttributeNode> nextListItem;

bool hasName (const String& name) const throw();

@@ -10087,7 +10407,8 @@ private:
XmlAttributeNode& operator= (const XmlAttributeNode&);
};

XmlAttributeNode* attributes;
friend class LinkedListPointer<XmlAttributeNode>;
LinkedListPointer <XmlAttributeNode> attributes;

XmlElement (int) throw();
void copyChildrenAndAttributesFrom (const XmlElement& other);
@@ -28618,9 +28939,10 @@ private:
void internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time);
void internalMouseWheel (MouseInputSource& source, const Point<int>& relativePos, const Time& time, float amountX, float amountY);
void internalBroughtToFront();
void internalFocusGain (const FocusChangeType cause, const WeakReference<Component>&);
void internalFocusGain (const FocusChangeType cause);
void internalFocusLoss (const FocusChangeType cause);
void internalChildFocusChange (FocusChangeType cause);
void internalChildFocusChange (FocusChangeType cause, const WeakReference<Component>&);
void internalModalInputAttempt();
void internalModifierKeysChanged();
void internalChildrenChanged();
@@ -53892,11 +54214,6 @@ private:
#define __JUCE_DOCUMENTWINDOW_JUCEHEADER__


/*** Start of inlined file: juce_MenuBarComponent.h ***/
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__


/*** Start of inlined file: juce_MenuBarModel.h ***/
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__
#define __JUCE_MENUBARMODEL_JUCEHEADER__
@@ -54043,97 +54360,6 @@ typedef MenuBarModel::Listener MenuBarModelListener;
#endif // __JUCE_MENUBARMODEL_JUCEHEADER__
/*** End of inlined file: juce_MenuBarModel.h ***/

/**
A menu bar component.

@see MenuBarModel
*/
class JUCE_API MenuBarComponent : public Component,
private MenuBarModel::Listener,
private Timer
{
public:

/** Creates a menu bar.

@param model the model object to use to control this bar. You can
pass 0 into this if you like, and set the model later
using the setModel() method
*/
MenuBarComponent (MenuBarModel* model);

/** Destructor. */
~MenuBarComponent();

/** Changes the model object to use to control the bar.

This can be 0, in which case the bar will be empty. Don't delete the object
that is passed-in while it's still being used by this MenuBar.
*/
void setModel (MenuBarModel* newModel);

/** Returns the current menu bar model being used.
*/
MenuBarModel* getModel() const throw();

/** Pops up one of the menu items.

This lets you manually open one of the menus - it could be triggered by a
key shortcut, for example.
*/
void showMenu (int menuIndex);

/** @internal */
void paint (Graphics& g);
/** @internal */
void resized();
/** @internal */
void mouseEnter (const MouseEvent& e);
/** @internal */
void mouseExit (const MouseEvent& e);
/** @internal */
void mouseDown (const MouseEvent& e);
/** @internal */
void mouseDrag (const MouseEvent& e);
/** @internal */
void mouseUp (const MouseEvent& e);
/** @internal */
void mouseMove (const MouseEvent& e);
/** @internal */
void handleCommandMessage (int commandId);
/** @internal */
bool keyPressed (const KeyPress& key);
/** @internal */
void menuBarItemsChanged (MenuBarModel* menuBarModel);
/** @internal */
void menuCommandInvoked (MenuBarModel* menuBarModel,
const ApplicationCommandTarget::InvocationInfo& info);

private:

class AsyncCallback;
friend class AsyncCallback;
MenuBarModel* model;

StringArray menuNames;
Array <int> xPositions;
int itemUnderMouse, currentPopupIndex, topLevelIndexClicked;
int lastMouseX, lastMouseY;

int getItemAt (int x, int y);
void setItemUnderMouse (int index);
void setOpenItem (int index);
void updateItemUnderMouse (int x, int y);
void timerCallback();
void repaintMenuItem (int index);
void menuDismissed (int topLevelIndex, int itemId);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarComponent);
};

#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__
/*** End of inlined file: juce_MenuBarComponent.h ***/

/**
A resizable window with a title bar and maximise, minimise and close buttons.

@@ -54256,6 +54482,17 @@ public:
void setMenuBar (MenuBarModel* menuBarModel,
int menuBarHeight = 0);

/** Returns the current menu bar component, or null if there isn't one.
This is probably a MenuBarComponent, unless a custom one has been set using
setMenuBarComponent().
*/
Component* getMenuBarComponent() const throw();

/** Replaces the current menu bar with a custom component.
The component will be owned and deleted by the document window.
*/
void setMenuBarComponent (Component* newMenuBarComponent);

/** This method is called when the user tries to close the window.

This is triggered by the user clicking the close button, or using some other
@@ -54344,7 +54581,7 @@ private:
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
ScopedPointer <Button> titleBarButtons [3];
Image titleBarIcon;
ScopedPointer <MenuBarComponent> menuBar;
ScopedPointer <Component> menuBar;
MenuBarModel* menuBarModel;

class ButtonListenerProxy;
@@ -56229,6 +56466,102 @@ private:
#endif
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__

/*** Start of inlined file: juce_MenuBarComponent.h ***/
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__

/**
A menu bar component.

@see MenuBarModel
*/
class JUCE_API MenuBarComponent : public Component,
private MenuBarModel::Listener,
private Timer
{
public:

/** Creates a menu bar.

@param model the model object to use to control this bar. You can
pass 0 into this if you like, and set the model later
using the setModel() method
*/
MenuBarComponent (MenuBarModel* model);

/** Destructor. */
~MenuBarComponent();

/** Changes the model object to use to control the bar.

This can be 0, in which case the bar will be empty. Don't delete the object
that is passed-in while it's still being used by this MenuBar.
*/
void setModel (MenuBarModel* newModel);

/** Returns the current menu bar model being used.
*/
MenuBarModel* getModel() const throw();

/** Pops up one of the menu items.

This lets you manually open one of the menus - it could be triggered by a
key shortcut, for example.
*/
void showMenu (int menuIndex);

/** @internal */
void paint (Graphics& g);
/** @internal */
void resized();
/** @internal */
void mouseEnter (const MouseEvent& e);
/** @internal */
void mouseExit (const MouseEvent& e);
/** @internal */
void mouseDown (const MouseEvent& e);
/** @internal */
void mouseDrag (const MouseEvent& e);
/** @internal */
void mouseUp (const MouseEvent& e);
/** @internal */
void mouseMove (const MouseEvent& e);
/** @internal */
void handleCommandMessage (int commandId);
/** @internal */
bool keyPressed (const KeyPress& key);
/** @internal */
void menuBarItemsChanged (MenuBarModel* menuBarModel);
/** @internal */
void menuCommandInvoked (MenuBarModel* menuBarModel,
const ApplicationCommandTarget::InvocationInfo& info);

private:

class AsyncCallback;
friend class AsyncCallback;
MenuBarModel* model;

StringArray menuNames;
Array <int> xPositions;
int itemUnderMouse, currentPopupIndex, topLevelIndexClicked;
int lastMouseX, lastMouseY;

int getItemAt (int x, int y);
void setItemUnderMouse (int index);
void setOpenItem (int index);
void updateItemUnderMouse (int x, int y);
void timerCallback();
void repaintMenuItem (int index);
void menuDismissed (int topLevelIndex, int itemId);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarComponent);
};

#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__
/*** End of inlined file: juce_MenuBarComponent.h ***/


#endif
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__



+ 343
- 0
src/containers/juce_LinkedListPointer.h View File

@@ -0,0 +1,343 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
#define __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
//==============================================================================
/**
Helps to manipulate singly-linked lists of objects.
For objects that are designed to contain a pointer to the subsequent item in the
list, this class contains methods to deal with the list. To use it, the ObjectType
class that it points to must contain a LinkedListPointer called nextListItem, e.g.
@code
struct MyObject
{
int x, y, z;
// A linkable object must contain a member with this name and type, which must be
// accessible by the LinkedListPointer class. (This doesn't mean it has to be public -
// you could make your class a friend of a LinkedListPointer<MyObject> instead).
LinkedListPointer<MyObject> nextListItem;
};
LinkedListPointer<MyObject> myList;
myList.append (new MyObject());
myList.append (new MyObject());
int numItems = myList.size(); // returns 2
MyObject* lastInList = myList.getLast();
@endcode
*/
template <class ObjectType>
class LinkedListPointer
{
public:
//==============================================================================
/** Creates a null pointer to an empty list. */
LinkedListPointer() throw()
: item (0)
{
}
/** Creates a pointer to a list whose head is the item provided. */
explicit LinkedListPointer (ObjectType* const headItem) throw()
: item (headItem)
{
}
/** Sets this pointer to point to a new list. */
LinkedListPointer& operator= (ObjectType* const newItem) throw()
{
item = newItem;
return *this;
}
//==============================================================================
/** Returns the item which this pointer points to. */
inline operator ObjectType*() const throw()
{
return item;
}
/** Returns the item which this pointer points to. */
inline ObjectType* get() const throw()
{
return item;
}
/** Returns the last item in the list which this pointer points to.
This will iterate the list and return the last item found. Obviously the speed
of this operation will be proportional to the size of the list. If the list is
empty the return value will be this object.
If you're planning on appending a number of items to your list, it's much more
efficient to use the Appender class than to repeatedly call getLast() to find the end.
*/
LinkedListPointer& getLast() throw()
{
LinkedListPointer* l = this;
while (l->item != 0)
l = &(l->item->nextListItem);
return *l;
}
/** Returns the number of items in the list.
Obviously with a simple linked list, getting the size involves iterating the list, so
this can be a lengthy operation - be careful when using this method in your code.
*/
int size() const throw()
{
int total = 0;
for (ObjectType* i = item; i != 0; i = i->nextListItem)
++total;
return total;
}
/** Returns the item at a given index in the list.
Since the only way to find an item is to iterate the list, this operation can obviously
be slow, depending on its size, so you should be careful when using this in algorithms.
*/
LinkedListPointer& operator[] (int index) throw()
{
LinkedListPointer* l = this;
while (--index >= 0 && l->item != 0)
l = &(l->item->nextListItem);
return *l;
}
/** Returns the item at a given index in the list.
Since the only way to find an item is to iterate the list, this operation can obviously
be slow, depending on its size, so you should be careful when using this in algorithms.
*/
const LinkedListPointer& operator[] (int index) const throw()
{
const LinkedListPointer* l = this;
while (--index >= 0 && l->item != 0)
l = &(l->item->nextListItem);
return *l;
}
/** Returns true if the list contains the given item. */
bool contains (const ObjectType* const itemToLookFor) const throw()
{
for (ObjectType* i = item; i != 0; i = i->nextListItem)
if (itemToLookFor == i)
return true;
return false;
}
//==============================================================================
/** Inserts an item into the list, placing it before the item that this pointer
currently points to.
*/
void insertNext (ObjectType* const newItem)
{
jassert (newItem != 0);
jassert (newItem->nextListItem == 0);
newItem->nextListItem = item;
item = newItem;
}
/** Inserts an item at a numeric index in the list.
Obviously this will involve iterating the list to find the item at the given index,
so be careful about the impact this may have on execution time.
*/
void insertAtIndex (int index, ObjectType* newItem)
{
jassert (newItem != 0);
LinkedListPointer* l = this;
while (index != 0 && l->item != 0)
{
l = &(l->item->nextListItem);
--index;
}
l->insertNext (newItem);
}
/** Replaces the object that this pointer points to, appending the rest of the list to
the new object, and returning the old one.
*/
ObjectType* replaceNext (ObjectType* const newItem) throw()
{
jassert (newItem != 0);
jassert (newItem->nextListItem == 0);
ObjectType* const oldItem = item;
item = newItem;
item->nextListItem = oldItem->nextListItem;
oldItem->nextListItem = 0;
return oldItem;
}
/** Adds an item to the end of the list.
This operation involves iterating the whole list, so can be slow - if you need to
append a number of items to your list, it's much more efficient to use the Appender
class than to repeatedly call append().
*/
void append (ObjectType* const newItem)
{
getLast().item = newItem;
}
/** Creates copies of all the items in another list and adds them to this one.
This will use the ObjectType's copy constructor to try to create copies of each
item in the other list, and appends them to this list.
*/
void addCopyOfList (const LinkedListPointer& other)
{
LinkedListPointer* insertPoint = this;
for (ObjectType* i = other.item; i != 0; i = i->nextListItem)
{
insertPoint->insertNext (new ObjectType (*i));
insertPoint = &(insertPoint->item->nextListItem);
}
}
/** Removes the head item from the list.
This won't delete the object that is removed, but returns it, so the caller can
delete it if necessary.
*/
ObjectType* removeNext() throw()
{
if (item == 0)
return 0;
ObjectType* const oldItem = item;
oldItem->nextListItem = 0;
item = item->nextListItem;
return oldItem;
}
/** Removes a specific item from the list.
Note that this will not delete the item, it simply unlinks it from the list.
*/
void remove (ObjectType* const item)
{
LinkedListPointer* l = findPointerTo (item);
if (l != 0)
l->removeNext();
}
/** Iterates the list, calling the delete operator on all of its elements and
leaving this pointer empty.
*/
void deleteAll()
{
while (item != 0)
{
ObjectType* const oldItem = item;
item = oldItem->nextListItem;
delete oldItem;
}
}
/** Finds a pointer to a given item.
If the item is found in the list, this returns the pointer that points to it. If
the item isn't found, this returns null.
*/
LinkedListPointer* findPointerTo (ObjectType* const itemToLookFor) throw()
{
LinkedListPointer* l = this;
while (l->item != 0)
{
if (l->item == itemToLookFor)
return l;
l = &(l->item->nextListItem);
}
return 0;
}
/** Copies the items in the list to an array.
The destArray must contain enough elements to hold the entire list - no checks are
made for this!
*/
void copyToArray (ObjectType** destArray) const throw()
{
jassert (destArray != 0);
for (ObjectType* i = item; i != 0; i = i->nextListItem)
*destArray++ = i;
}
//==============================================================================
/**
Allows efficient repeated insertions into a list.
You can create an Appender object which points to the last element in your
list, and then repeatedly call Appender::append() to add items to the end
of the list in O(1) time.
*/
class Appender
{
public:
/** Creates an appender which will add items to the given list.
*/
Appender (LinkedListPointer& endOfListPointer) throw()
: endOfList (&endOfListPointer)
{
// This can only be used to add to the end of a list.
jassert (endOfListPointer.item == 0);
}
/** Appends an item to the list. */
void append (ObjectType* const newItem) throw()
{
*endOfList = newItem;
endOfList = &(newItem->nextListItem);
}
private:
LinkedListPointer* endOfList;
JUCE_DECLARE_NON_COPYABLE (Appender);
};
private:
//==============================================================================
ObjectType* item;
};
#endif // __JUCE_LINKEDLISTPOINTER_JUCEHEADER__

+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 110
#define JUCE_BUILDNUMBER 111
/** Current Juce version number.


+ 9
- 1
src/gui/components/buttons/juce_Button.cpp View File

@@ -147,9 +147,10 @@ void Button::setToggleState (const bool shouldBeOn,
lastToggleState = shouldBeOn;
repaint();
WeakReference<Component> deletionWatcher (this);
if (sendChangeNotification)
{
WeakReference<Component> deletionWatcher (this);
sendClickMessage (ModifierKeys());
if (deletionWatcher == 0)
@@ -157,7 +158,14 @@ void Button::setToggleState (const bool shouldBeOn,
}
if (lastToggleState)
{
turnOffOtherButtonsInGroup (sendChangeNotification);
if (deletionWatcher == 0)
return;
}
sendStateMessage();
}
}


+ 51
- 64
src/gui/components/juce_Component.cpp View File

@@ -1018,33 +1018,40 @@ void Component::setBounds (const int x, const int y, int w, int h)
void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasResized)
{
JUCE_TRY
BailOutChecker checker (this);
if (wasMoved)
{
if (wasMoved)
moved();
moved();
if (wasResized)
{
resized();
if (checker.shouldBailOut())
return;
}
for (int i = childComponentList_.size(); --i >= 0;)
{
childComponentList_.getUnchecked(i)->parentSizeChanged();
if (wasResized)
{
resized();
i = jmin (i, childComponentList_.size());
}
}
if (checker.shouldBailOut())
return;
BailOutChecker checker (this);
for (int i = childComponentList_.size(); --i >= 0;)
{
childComponentList_.getUnchecked(i)->parentSizeChanged();
if (parentComponent_ != 0)
parentComponent_->childBoundsChanged (this);
if (checker.shouldBailOut())
return;
if (! checker.shouldBailOut())
componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized,
*this, wasMoved, wasResized);
i = jmin (i, childComponentList_.size());
}
}
JUCE_CATCH_EXCEPTION
if (parentComponent_ != 0)
parentComponent_->childBoundsChanged (this);
if (! checker.shouldBailOut())
componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized,
*this, wasMoved, wasResized);
}
void Component::setSize (const int w, const int h)
@@ -2561,12 +2568,15 @@ void Component::focusGained (FocusChangeType)
void Component::internalFocusGain (const FocusChangeType cause)
{
WeakReference<Component> safePointer (this);
internalFocusGain (cause, WeakReference<Component> (this));
}
void Component::internalFocusGain (const FocusChangeType cause, const WeakReference<Component>& safePointer)
{
focusGained (cause);
if (safePointer != 0)
internalChildFocusChange (cause);
internalChildFocusChange (cause, safePointer);
}
void Component::focusLost (FocusChangeType)
@@ -2581,7 +2591,7 @@ void Component::internalFocusLoss (const FocusChangeType cause)
focusLost (focusChangedDirectly);
if (safePointer != 0)
internalChildFocusChange (cause);
internalChildFocusChange (cause, safePointer);
}
void Component::focusOfChildComponentChanged (FocusChangeType /*cause*/)
@@ -2589,7 +2599,7 @@ void Component::focusOfChildComponentChanged (FocusChangeType /*cause*/)
// base class does nothing
}
void Component::internalChildFocusChange (FocusChangeType cause)
void Component::internalChildFocusChange (FocusChangeType cause, const WeakReference<Component>& safePointer)
{
const bool childIsNowFocused = hasKeyboardFocus (true);
@@ -2597,7 +2607,6 @@ void Component::internalChildFocusChange (FocusChangeType cause)
{
flags.childCompFocusedFlag = childIsNowFocused;
WeakReference<Component> safePointer (this);
focusOfChildComponentChanged (cause);
if (safePointer == 0)
@@ -2605,7 +2614,7 @@ void Component::internalChildFocusChange (FocusChangeType cause)
}
if (parentComponent_ != 0)
parentComponent_->internalChildFocusChange (cause);
parentComponent_->internalChildFocusChange (cause, WeakReference<Component> (parentComponent_));
}
//==============================================================================
@@ -2711,54 +2720,32 @@ void Component::takeKeyboardFocus (const FocusChangeType cause)
// give the focus to this component
if (currentlyFocusedComponent != this)
{
JUCE_TRY
{
// get the focus onto our desktop window
ComponentPeer* const peer = getPeer();
if (peer != 0)
{
WeakReference<Component> safePointer (this);
// get the focus onto our desktop window
ComponentPeer* const peer = getPeer();
peer->grabFocus();
if (peer != 0)
{
WeakReference<Component> safePointer (this);
if (peer->isFocused() && currentlyFocusedComponent != this)
{
WeakReference<Component> componentLosingFocus (currentlyFocusedComponent);
peer->grabFocus();
currentlyFocusedComponent = this;
if (peer->isFocused() && currentlyFocusedComponent != this)
{
WeakReference<Component> componentLosingFocus (currentlyFocusedComponent);
Desktop::getInstance().triggerFocusCallback();
currentlyFocusedComponent = this;
// call this after setting currentlyFocusedComponent so that the one that's
// losing it has a chance to see where focus is going
if (componentLosingFocus != 0)
componentLosingFocus->internalFocusLoss (cause);
Desktop::getInstance().triggerFocusCallback();
if (currentlyFocusedComponent == this)
{
focusGained (cause);
// call this after setting currentlyFocusedComponent so that the one that's
// losing it has a chance to see where focus is going
if (componentLosingFocus != 0)
componentLosingFocus->internalFocusLoss (cause);
if (safePointer != 0)
internalChildFocusChange (cause);
}
}
if (currentlyFocusedComponent == this)
internalFocusGain (cause, safePointer);
}
}
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
catch (const std::exception& e)
{
currentlyFocusedComponent = 0;
Desktop::getInstance().triggerFocusCallback();
JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__);
}
catch (...)
{
currentlyFocusedComponent = 0;
Desktop::getInstance().triggerFocusCallback();
JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__);
}
#endif
}
}


+ 2
- 1
src/gui/components/juce_Component.h View File

@@ -2180,9 +2180,10 @@ private:
void internalMouseMove (MouseInputSource& source, const Point<int>& relativePos, const Time& time);
void internalMouseWheel (MouseInputSource& source, const Point<int>& relativePos, const Time& time, float amountX, float amountY);
void internalBroughtToFront();
void internalFocusGain (const FocusChangeType cause, const WeakReference<Component>&);
void internalFocusGain (const FocusChangeType cause);
void internalFocusLoss (const FocusChangeType cause);
void internalChildFocusChange (FocusChangeType cause);
void internalChildFocusChange (FocusChangeType cause, const WeakReference<Component>&);
void internalModalInputAttempt();
void internalModifierKeysChanged();
void internalChildrenChanged();


+ 1
- 0
src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp View File

@@ -43,6 +43,7 @@ BEGIN_JUCE_NAMESPACE
#include "../juce_Desktop.h"
#include "../../graphics/drawables/juce_DrawableComposite.h"
#include "../../graphics/drawables/juce_DrawablePath.h"
#include "../menus/juce_MenuBarComponent.h"
//==============================================================================


+ 41
- 38
src/gui/components/windows/juce_DocumentWindow.cpp View File

@@ -30,6 +30,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_DocumentWindow.h"
#include "juce_ComponentPeer.h"
#include "../lookandfeel/juce_LookAndFeel.h"
#include "../menus/juce_MenuBarComponent.h"
#include "../../graphics/imaging/juce_Image.h"
@@ -67,11 +68,11 @@ DocumentWindow::DocumentWindow (const String& title,
titleBarHeight (26),
menuBarHeight (24),
requiredButtons (requiredButtons_),
#if JUCE_MAC
#if JUCE_MAC
positionTitleBarButtonsOnLeft (true),
#else
#else
positionTitleBarButtonsOnLeft (false),
#endif
#endif
drawTitleTextCentred (true),
menuBarModel (0)
{
@@ -138,28 +139,39 @@ void DocumentWindow::setTitleBarTextCentred (const bool textShouldBeCentred)
repaintTitleBar();
}
void DocumentWindow::setMenuBar (MenuBarModel* menuBarModel_,
const int menuBarHeight_)
//==============================================================================
void DocumentWindow::setMenuBar (MenuBarModel* newMenuBarModel, const int newMenuBarHeight)
{
if (menuBarModel != menuBarModel_)
if (menuBarModel != newMenuBarModel)
{
menuBar = 0;
menuBarModel = menuBarModel_;
menuBarHeight = (menuBarHeight_ > 0) ? menuBarHeight_
menuBarModel = newMenuBarModel;
menuBarHeight = newMenuBarHeight > 0 ? newMenuBarHeight
: getLookAndFeel().getDefaultMenuBarHeight();
if (menuBarModel != 0)
{
// (call the Component method directly to avoid the assertion in ResizableWindow)
Component::addAndMakeVisible (menuBar = new MenuBarComponent (menuBarModel));
menuBar->setEnabled (isActiveWindow());
}
setMenuBarComponent (new MenuBarComponent (menuBarModel));
resized();
}
}
Component* DocumentWindow::getMenuBarComponent() const throw()
{
return menuBar;
}
void DocumentWindow::setMenuBarComponent (Component* newMenuBarComponent)
{
// (call the Component method directly to avoid the assertion in ResizableWindow)
Component::addAndMakeVisible (menuBar = newMenuBarComponent);
if (menuBar != 0)
menuBar->setEnabled (isActiveWindow());
resized();
}
//==============================================================================
void DocumentWindow::closeButtonPressed()
@@ -269,8 +281,8 @@ const BorderSize DocumentWindow::getContentComponentBorder()
BorderSize border (getBorderThickness());
border.setTop (border.getTop()
+ (isUsingNativeTitleBar() ? 0 : titleBarHeight)
+ (menuBar != 0 ? menuBarHeight : 0));
+ (isUsingNativeTitleBar() ? 0 : titleBarHeight)
+ (menuBar != 0 ? menuBarHeight : 0));
return border;
}
@@ -289,20 +301,9 @@ const Rectangle<int> DocumentWindow::getTitleBarArea()
getTitleBarHeight());
}
Button* DocumentWindow::getCloseButton() const throw()
{
return titleBarButtons[2];
}
Button* DocumentWindow::getMinimiseButton() const throw()
{
return titleBarButtons[0];
}
Button* DocumentWindow::getMaximiseButton() const throw()
{
return titleBarButtons[1];
}
Button* DocumentWindow::getCloseButton() const throw() { return titleBarButtons[2]; }
Button* DocumentWindow::getMinimiseButton() const throw() { return titleBarButtons[0]; }
Button* DocumentWindow::getMaximiseButton() const throw() { return titleBarButtons[1]; }
int DocumentWindow::getDesktopWindowStyleFlags() const
{
@@ -328,14 +329,16 @@ void DocumentWindow::lookAndFeelChanged()
if (! isUsingNativeTitleBar())
{
titleBarButtons[0] = ((requiredButtons & minimiseButton) != 0)
? getLookAndFeel().createDocumentWindowButton (minimiseButton) : 0;
LookAndFeel& lf = getLookAndFeel();
if ((requiredButtons & minimiseButton) != 0)
titleBarButtons[0] = lf.createDocumentWindowButton (minimiseButton);
titleBarButtons[1] = ((requiredButtons & maximiseButton) != 0)
? getLookAndFeel().createDocumentWindowButton (maximiseButton) : 0;
if ((requiredButtons & maximiseButton) != 0)
titleBarButtons[1] = lf.createDocumentWindowButton (maximiseButton);
titleBarButtons[2] = ((requiredButtons & closeButton) != 0)
? getLookAndFeel().createDocumentWindowButton (closeButton) : 0;
if ((requiredButtons & closeButton) != 0)
titleBarButtons[2] = lf.createDocumentWindowButton (closeButton);
for (i = 0; i < 3; ++i)
{
@@ -354,11 +357,11 @@ void DocumentWindow::lookAndFeelChanged()
if (getCloseButton() != 0)
{
#if JUCE_MAC
#if JUCE_MAC
getCloseButton()->addShortcut (KeyPress ('w', ModifierKeys::commandModifier, 0));
#else
#else
getCloseButton()->addShortcut (KeyPress (KeyPress::F4Key, ModifierKeys::altModifier, 0));
#endif
#endif
}
}


+ 14
- 2
src/gui/components/windows/juce_DocumentWindow.h View File

@@ -28,7 +28,7 @@
#include "juce_ResizableWindow.h"
#include "../buttons/juce_Button.h"
#include "../menus/juce_MenuBarComponent.h"
#include "../menus/juce_MenuBarModel.h"
//==============================================================================
@@ -142,6 +142,7 @@ public:
*/
void setTitleBarTextCentred (bool textShouldBeCentred);
//==============================================================================
/** Creates a menu inside this window.
@param menuBarModel this specifies a MenuBarModel that should be used to
@@ -156,6 +157,17 @@ public:
void setMenuBar (MenuBarModel* menuBarModel,
int menuBarHeight = 0);
/** Returns the current menu bar component, or null if there isn't one.
This is probably a MenuBarComponent, unless a custom one has been set using
setMenuBarComponent().
*/
Component* getMenuBarComponent() const throw();
/** Replaces the current menu bar with a custom component.
The component will be owned and deleted by the document window.
*/
void setMenuBarComponent (Component* newMenuBarComponent);
//==============================================================================
/** This method is called when the user tries to close the window.
@@ -248,7 +260,7 @@ private:
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
ScopedPointer <Button> titleBarButtons [3];
Image titleBarIcon;
ScopedPointer <MenuBarComponent> menuBar;
ScopedPointer <Component> menuBar;
MenuBarModel* menuBarModel;
class ButtonListenerProxy;


+ 7
- 2
src/gui/graphics/drawables/juce_DrawableImage.cpp View File

@@ -244,13 +244,18 @@ void DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider*
const RelativeParallelogram newBounds (controller.getBoundingBox());
if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage)
if (bounds != newBounds || newOpacity != opacity
|| overlayColour != newOverlayColour || image != newImage)
{
repaint();
opacity = newOpacity;
overlayColour = newOverlayColour;
bounds = newBounds;
setImage (newImage);
if (image != newImage)
setImage (newImage);
else
refreshTransformFromBounds();
}
}


+ 1
- 0
src/gui/graphics/drawables/juce_DrawableShape.cpp View File

@@ -129,6 +129,7 @@ void DrawableShape::paint (Graphics& g)
void DrawableShape::pathChanged()
{
rebuildPath (path);
strokeChanged();
}


+ 3
- 0
src/juce_core_includes.h View File

@@ -41,6 +41,9 @@
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
#include "containers/juce_ElementComparator.h"
#endif
#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
#include "containers/juce_LinkedListPointer.h"
#endif
#ifndef __JUCE_NAMEDVALUESET_JUCEHEADER__
#include "containers/juce_NamedValueSet.h"
#endif


+ 1
- 1
src/native/linux/juce_linux_JackAudio.cpp View File

@@ -59,7 +59,7 @@ void* juce_load_jack_function (const char* const name)
}
//==============================================================================
JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status), (client_name, options, status));
JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status));
JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client));
JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client));
JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client));


+ 1
- 1
src/native/mac/juce_mac_ObjCSuffix.h View File

@@ -44,4 +44,4 @@
#define appendMacro1(a, b, c, d, e) a ## _ ## b ## _ ## c ## _ ## d ## _ ## e
#define appendMacro2(a, b, c, d, e) appendMacro1(a, b, c, d, e)
#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_BUILDNUMBER, JUCE_ObjCExtraSuffix)
#endif
#endif

+ 44
- 3
src/native/windows/juce_win32_Windowing.cpp View File

@@ -492,6 +492,7 @@ public:
isDragging (false),
isMouseOver (false),
hasCreatedCaret (false),
constrainerIsResizing (false),
currentWindowIcon (0),
dropTarget (0),
updateLayeredWindowAlpha (255),
@@ -1029,7 +1030,7 @@ private:
#if JUCE_DIRECT2D
ScopedPointer<Direct2DLowLevelGraphicsContext> direct2DContext;
#endif
bool fullScreen, isDragging, isMouseOver, hasCreatedCaret;
bool fullScreen, isDragging, isMouseOver, hasCreatedCaret, constrainerIsResizing;
BorderSize windowBorder;
HICON currentWindowIcon;
ScopedPointer<NOTIFYICONDATA> taskBarIcon;
@@ -1542,6 +1543,14 @@ private:
void doCaptureChanged()
{
if (constrainerIsResizing)
{
if (constrainer != 0)
constrainer->resizeEnd();
constrainerIsResizing = false;
}
if (isDragging)
doMouseUp (getCurrentMousePos(), (WPARAM) 0);
}
@@ -1764,9 +1773,15 @@ private:
return false;
}
bool isConstrainedNativeWindow() const
{
return constrainer != 0
&& (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable);
}
LRESULT handleSizeConstraining (RECT* const r, const WPARAM wParam)
{
if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
if (isConstrainedNativeWindow())
{
Rectangle<int> pos (r->left, r->top, r->right - r->left, r->bottom - r->top);
@@ -1787,7 +1802,7 @@ private:
LRESULT handlePositionChanging (WINDOWPOS* const wp)
{
if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
if (isConstrainedNativeWindow())
{
if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)
&& ! Component::isMouseButtonDownAnywhere())
@@ -2279,6 +2294,32 @@ private:
break;
case WM_NCLBUTTONDOWN:
if (! sendInputAttemptWhenModalMessage())
{
switch (wParam)
{
case HTBOTTOM:
case HTBOTTOMLEFT:
case HTBOTTOMRIGHT:
case HTGROWBOX:
case HTLEFT:
case HTRIGHT:
case HTTOP:
case HTTOPLEFT:
case HTTOPRIGHT:
if (isConstrainedNativeWindow())
{
constrainerIsResizing = true;
constrainer->resizeStart();
}
break;
default:
break;
};
}
break;
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
sendInputAttemptWhenModalMessage();


+ 15
- 52
src/text/juce_XmlDocument.cpp View File

@@ -385,7 +385,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
node = new XmlElement (String (input, tagLen));
input += tagLen;
XmlElement::XmlAttributeNode* lastAttribute = 0;
LinkedListPointer<XmlElement::XmlAttributeNode>::Appender attributeAppender (node->attributes);
// look for attributes
for (;;)
@@ -437,14 +437,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
String::empty);
readQuotedString (newAtt->value);
if (lastAttribute == 0)
node->attributes = newAtt;
else
lastAttribute->next = newAtt;
lastAttribute = newAtt;
attributeAppender.append (newAtt);
continue;
}
}
@@ -465,7 +458,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
void XmlDocument::readChildElements (XmlElement* parent)
{
XmlElement* lastChildNode = 0;
LinkedListPointer<XmlElement>::Appender childAppender (parent->firstChildElement);
for (;;)
{
@@ -521,14 +514,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
++len;
}
XmlElement* const e = XmlElement::createTextElement (String (inputStart, len));
if (lastChildNode != 0)
lastChildNode->nextElement = e;
else
parent->addChildElement (e);
lastChildNode = e;
childAppender.append (XmlElement::createTextElement (String (inputStart, len)));
}
else
{
@@ -536,18 +522,9 @@ void XmlDocument::readChildElements (XmlElement* parent)
XmlElement* const n = readNextElement (true);
if (n != 0)
{
if (lastChildNode == 0)
parent->addChildElement (n);
else
lastChildNode->nextElement = n;
lastChildNode = n;
}
childAppender.append (n);
else
{
return;
}
}
}
else // must be a character block
@@ -589,12 +566,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
if (n == 0)
break;
if (lastChildNode == 0)
parent->addChildElement (n);
else
lastChildNode->nextElement = n;
lastChildNode = n;
childAppender.append (n);
}
input = oldInput;
@@ -635,14 +607,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars())
{
XmlElement* const textElement = XmlElement::createTextElement (textElementContent);
if (lastChildNode != 0)
lastChildNode->nextElement = textElement;
else
parent->addChildElement (textElement);
lastChildNode = textElement;
childAppender.append (XmlElement::createTextElement (textElementContent));
}
}
}
@@ -870,18 +835,16 @@ const String XmlDocument::getParameterEntity (const String& entity)
{
for (int i = 0; i < tokenisedDTD.size(); ++i)
{
if (tokenisedDTD[i] == entity)
if (tokenisedDTD[i] == entity
&& tokenisedDTD [i - 1] == "%"
&& tokenisedDTD [i - 2].equalsIgnoreCase ("<!entity"))
{
if (tokenisedDTD [i - 1] == "%"
&& tokenisedDTD [i - 2].equalsIgnoreCase ("<!entity"))
{
const String ent (tokenisedDTD [i + 1].trimCharactersAtEnd (">"));
const String ent (tokenisedDTD [i + 1].trimCharactersAtEnd (">"));
if (ent.equalsIgnoreCase ("system"))
return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">"));
else
return ent.trim().unquoted();
}
if (ent.equalsIgnoreCase ("system"))
return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">"));
else
return ent.trim().unquoted();
}
}


+ 64
- 277
src/text/juce_XmlElement.cpp View File

@@ -37,15 +37,13 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
XmlElement::XmlAttributeNode::XmlAttributeNode (const XmlAttributeNode& other) throw()
: name (other.name),
value (other.value),
next (0)
value (other.value)
{
}
XmlElement::XmlAttributeNode::XmlAttributeNode (const String& name_, const String& value_) throw()
: name (name_),
value (value_),
next (0)
value (value_)
{
#if JUCE_DEBUG
// this checks whether the attribute name string contains any illegals characters..
@@ -61,10 +59,7 @@ inline bool XmlElement::XmlAttributeNode::hasName (const String& nameToMatch) co
//==============================================================================
XmlElement::XmlElement (const String& tagName_) throw()
: tagName (tagName_),
firstChildElement (0),
nextElement (0),
attributes (0)
: tagName (tagName_)
{
// the tag name mustn't be empty, or it'll look like a text element!
jassert (tagName_.containsNonWhitespaceChars())
@@ -74,17 +69,11 @@ XmlElement::XmlElement (const String& tagName_) throw()
}
XmlElement::XmlElement (int /*dummy*/) throw()
: firstChildElement (0),
nextElement (0),
attributes (0)
{
}
XmlElement::XmlElement (const XmlElement& other)
: tagName (other.tagName),
firstChildElement (0),
nextElement (0),
attributes (0)
: tagName (other.tagName)
{
copyChildrenAndAttributesFrom (other);
}
@@ -106,58 +95,17 @@ XmlElement& XmlElement::operator= (const XmlElement& other)
void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other)
{
XmlElement* child = other.firstChildElement;
XmlElement* lastChild = 0;
jassert (firstChildElement.get() == 0);
firstChildElement.addCopyOfList (other.firstChildElement);
while (child != 0)
{
XmlElement* const copiedChild = new XmlElement (*child);
if (lastChild != 0)
lastChild->nextElement = copiedChild;
else
firstChildElement = copiedChild;
lastChild = copiedChild;
child = child->nextElement;
}
const XmlAttributeNode* att = other.attributes;
XmlAttributeNode* lastAtt = 0;
while (att != 0)
{
XmlAttributeNode* const newAtt = new XmlAttributeNode (*att);
if (lastAtt != 0)
lastAtt->next = newAtt;
else
attributes = newAtt;
lastAtt = newAtt;
att = att->next;
}
jassert (attributes.get() == 0);
attributes.addCopyOfList (other.attributes);
}
XmlElement::~XmlElement() throw()
{
XmlElement* child = firstChildElement;
while (child != 0)
{
XmlElement* const nextChild = child->nextElement;
delete child;
child = nextChild;
}
XmlAttributeNode* att = attributes;
while (att != 0)
{
XmlAttributeNode* const nextAtt = att->next;
delete att;
att = nextAtt;
}
firstChildElement.deleteAll();
attributes.deleteAll();
}
//==============================================================================
@@ -279,7 +227,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream,
const int attIndent = indentationLevel + tagName.length() + 1;
int lineLen = 0;
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
{
if (lineLen > lineWrapLength && indentationLevel >= 0)
{
@@ -322,7 +270,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream,
lastWasTextNode = false;
}
child = child->nextElement;
child = child->getNextElement();
}
if (indentationLevel >= 0 && ! lastWasTextNode)
@@ -438,10 +386,10 @@ bool XmlElement::hasTagName (const String& tagNameWanted) const throw()
XmlElement* XmlElement::getNextElementWithTagName (const String& requiredTagName) const
{
XmlElement* e = nextElement;
XmlElement* e = nextListItem;
while (e != 0 && ! e->hasTagName (requiredTagName))
e = e->nextElement;
e = e->nextListItem;
return e;
}
@@ -449,47 +397,24 @@ XmlElement* XmlElement::getNextElementWithTagName (const String& requiredTagName
//==============================================================================
int XmlElement::getNumAttributes() const throw()
{
int count = 0;
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
++count;
return count;
return attributes.size();
}
const String& XmlElement::getAttributeName (const int index) const throw()
{
int count = 0;
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
{
if (count == index)
return att->name;
++count;
}
return String::empty;
const XmlAttributeNode* const att = attributes [index];
return att != 0 ? att->name : String::empty;
}
const String& XmlElement::getAttributeValue (const int index) const throw()
{
int count = 0;
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
{
if (count == index)
return att->value;
++count;
}
return String::empty;
const XmlAttributeNode* const att = attributes [index];
return att != 0 ? att->value : String::empty;
}
bool XmlElement::hasAttribute (const String& attributeName) const throw()
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return true;
@@ -499,7 +424,7 @@ bool XmlElement::hasAttribute (const String& attributeName) const throw()
//==============================================================================
const String& XmlElement::getStringAttribute (const String& attributeName) const throw()
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
@@ -508,7 +433,7 @@ const String& XmlElement::getStringAttribute (const String& attributeName) const
const String XmlElement::getStringAttribute (const String& attributeName, const String& defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
@@ -517,7 +442,7 @@ const String XmlElement::getStringAttribute (const String& attributeName, const
int XmlElement::getIntAttribute (const String& attributeName, const int defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getIntValue();
@@ -526,7 +451,7 @@ int XmlElement::getIntAttribute (const String& attributeName, const int defaultR
double XmlElement::getDoubleAttribute (const String& attributeName, const double defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getDoubleValue();
@@ -535,7 +460,7 @@ double XmlElement::getDoubleAttribute (const String& attributeName, const double
bool XmlElement::getBoolAttribute (const String& attributeName, const bool defaultReturnValue) const
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
{
if (att->hasName (attributeName))
{
@@ -559,7 +484,7 @@ bool XmlElement::compareAttribute (const String& attributeName,
const String& stringToCompareAgainst,
const bool ignoreCase) const throw()
{
for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst)
: att->value == stringToCompareAgainst;
@@ -585,13 +510,13 @@ void XmlElement::setAttribute (const String& attributeName, const String& value)
att->value = value;
break;
}
else if (att->next == 0)
else if (att->nextListItem == 0)
{
att->next = new XmlAttributeNode (attributeName, value);
att->nextListItem = new XmlAttributeNode (attributeName, value);
break;
}
att = att->next;
att = att->nextListItem;
}
}
}
@@ -608,62 +533,34 @@ void XmlElement::setAttribute (const String& attributeName, const double number)
void XmlElement::removeAttribute (const String& attributeName) throw()
{
XmlAttributeNode* lastAtt = 0;
LinkedListPointer<XmlAttributeNode>* att = &attributes;
for (XmlAttributeNode* att = attributes; att != 0; att = att->next)
while (att->get() != 0)
{
if (att->hasName (attributeName))
if (att->get()->hasName (attributeName))
{
if (lastAtt == 0)
attributes = att->next;
else
lastAtt->next = att->next;
delete att;
delete att->removeNext();
break;
}
lastAtt = att;
att = &(att->get()->nextListItem);
}
}
void XmlElement::removeAllAttributes() throw()
{
while (attributes != 0)
{
XmlAttributeNode* const nextAtt = attributes->next;
delete attributes;
attributes = nextAtt;
}
attributes.deleteAll();
}
//==============================================================================
int XmlElement::getNumChildElements() const throw()
{
int count = 0;
const XmlElement* child = firstChildElement;
while (child != 0)
{
++count;
child = child->nextElement;
}
return count;
return firstChildElement.size();
}
XmlElement* XmlElement::getChildElement (const int index) const throw()
{
int count = 0;
XmlElement* child = firstChildElement;
while (child != 0 && count < index)
{
child = child->nextElement;
++count;
}
return child;
return firstChildElement [index].get();
}
XmlElement* XmlElement::getChildByName (const String& childName) const throw()
@@ -675,7 +572,7 @@ XmlElement* XmlElement::getChildByName (const String& childName) const throw()
if (child->hasTagName (childName))
break;
child = child->nextElement;
child = child->nextListItem;
}
return child;
@@ -684,25 +581,7 @@ XmlElement* XmlElement::getChildByName (const String& childName) const throw()
void XmlElement::addChildElement (XmlElement* const newNode) throw()
{
if (newNode != 0)
{
if (firstChildElement == 0)
{
firstChildElement = newNode;
}
else
{
XmlElement* child = firstChildElement;
while (child->nextElement != 0)
child = child->nextElement;
child->nextElement = newNode;
// if this is non-zero, then something's probably
// gone wrong..
jassert (newNode->nextElement == 0);
}
}
firstChildElement.append (newNode);
}
void XmlElement::insertChildElement (XmlElement* const newNode,
@@ -711,32 +590,7 @@ void XmlElement::insertChildElement (XmlElement* const newNode,
if (newNode != 0)
{
removeChildElement (newNode, false);
if (indexToInsertAt == 0)
{
newNode->nextElement = firstChildElement;
firstChildElement = newNode;
}
else
{
if (firstChildElement == 0)
{
firstChildElement = newNode;
}
else
{
if (indexToInsertAt < 0)
indexToInsertAt = std::numeric_limits<int>::max();
XmlElement* child = firstChildElement;
while (child->nextElement != 0 && --indexToInsertAt > 0)
child = child->nextElement;
newNode->nextElement = child->nextElement;
child->nextElement = newNode;
}
}
firstChildElement.insertAtIndex (indexToInsertAt, newNode);
}
}
@@ -752,30 +606,14 @@ bool XmlElement::replaceChildElement (XmlElement* const currentChildElement,
{
if (newNode != 0)
{
XmlElement* child = firstChildElement;
XmlElement* previousNode = 0;
LinkedListPointer<XmlElement>* const p = firstChildElement.findPointerTo (currentChildElement);
while (child != 0)
if (p != 0)
{
if (child == currentChildElement)
{
if (child != newNode)
{
if (previousNode == 0)
firstChildElement = newNode;
else
previousNode->nextElement = newNode;
newNode->nextElement = child->nextElement;
delete child;
}
return true;
}
if (currentChildElement != newNode)
delete p->replaceNext (newNode);
previousNode = child;
child = child->nextElement;
return true;
}
}
@@ -787,33 +625,7 @@ void XmlElement::removeChildElement (XmlElement* const childToRemove,
{
if (childToRemove != 0)
{
if (firstChildElement == childToRemove)
{
firstChildElement = childToRemove->nextElement;
childToRemove->nextElement = 0;
}
else
{
XmlElement* child = firstChildElement;
XmlElement* last = 0;
while (child != 0)
{
if (child == childToRemove)
{
if (last == 0)
firstChildElement = child->nextElement;
else
last->nextElement = child->nextElement;
childToRemove->nextElement = 0;
break;
}
last = child;
child = child->nextElement;
}
}
firstChildElement.remove (childToRemove);
if (shouldDeleteTheChild)
delete childToRemove;
@@ -838,7 +650,7 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
if (! other->compareAttribute (att->name, att->value))
return false;
att = att->next;
att = att->nextListItem;
++totalAtts;
}
@@ -866,8 +678,8 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
return false;
}
thisAtt = thisAtt->next;
otherAtt = otherAtt->next;
thisAtt = thisAtt->nextListItem;
otherAtt = otherAtt->nextListItem;
}
}
@@ -887,8 +699,8 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
if (! thisChild->isEquivalentTo (otherChild, ignoreOrderOfAttributes))
return false;
thisChild = thisChild->nextElement;
otherChild = otherChild->nextElement;
thisChild = thisChild->nextListItem;
otherChild = otherChild->nextListItem;
}
}
@@ -897,12 +709,7 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
void XmlElement::deleteAllChildElements() throw()
{
while (firstChildElement != 0)
{
XmlElement* const nextChild = firstChildElement->nextElement;
delete firstChildElement;
firstChildElement = nextChild;
}
firstChildElement.deleteAll();
}
void XmlElement::deleteAllChildElementsWithTagName (const String& name) throw()
@@ -911,32 +718,18 @@ void XmlElement::deleteAllChildElementsWithTagName (const String& name) throw()
while (child != 0)
{
XmlElement* const nextChild = child->nextListItem;
if (child->hasTagName (name))
{
XmlElement* const nextChild = child->nextElement;
removeChildElement (child, true);
child = nextChild;
}
else
{
child = child->nextElement;
}
child = nextChild;
}
}
bool XmlElement::containsChildElement (const XmlElement* const possibleChild) const throw()
{
const XmlElement* child = firstChildElement;
while (child != 0)
{
if (child == possibleChild)
return true;
child = child->nextElement;
}
return false;
return firstChildElement.contains (possibleChild);
}
XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLookFor) throw()
@@ -956,7 +749,7 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo
if (found != 0)
return found;
child = child->nextElement;
child = child->nextListItem;
}
return 0;
@@ -964,13 +757,7 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo
void XmlElement::getChildElementsAsArray (XmlElement** elems) const throw()
{
XmlElement* e = firstChildElement;
while (e != 0)
{
*elems++ = e;
e = e->nextElement;
}
firstChildElement.copyToArray (elems);
}
void XmlElement::reorderChildElements (XmlElement** const elems, const int num) throw()
@@ -979,11 +766,11 @@ void XmlElement::reorderChildElements (XmlElement** const elems, const int num)
for (int i = 1; i < num; ++i)
{
e->nextElement = elems[i];
e = e->nextElement;
e->nextListItem = elems[i];
e = e->nextListItem;
}
e->nextElement = 0;
e->nextListItem = 0;
}
//==============================================================================
@@ -1023,7 +810,7 @@ const String XmlElement::getAllSubText() const
while (child != 0)
{
concatenator.append (child->getAllSubText());
child = child->nextElement;
child = child->nextListItem;
}
return result;
@@ -1058,7 +845,7 @@ void XmlElement::deleteAllTextElements() throw()
while (child != 0)
{
XmlElement* const next = child->nextElement;
XmlElement* const next = child->nextListItem;
if (child->isTextElement())
removeChildElement (child, true);


+ 8
- 5
src/text/juce_XmlElement.h View File

@@ -29,6 +29,7 @@
#include "juce_String.h"
#include "../io/streams/juce_OutputStream.h"
#include "../io/files/juce_File.h"
#include "../containers/juce_LinkedListPointer.h"
//==============================================================================
@@ -451,7 +452,7 @@ public:
@see getNextElement, isTextElement, forEachXmlChildElement
*/
inline XmlElement* getNextElement() const throw() { return nextElement; }
inline XmlElement* getNextElement() const throw() { return nextListItem; }
/** Returns the next of this element's siblings which has the specified tag
name.
@@ -690,8 +691,9 @@ private:
friend class XmlDocument;
String tagName;
XmlElement* firstChildElement;
XmlElement* nextElement;
friend class LinkedListPointer <XmlElement>;
LinkedListPointer <XmlElement> firstChildElement;
LinkedListPointer <XmlElement> nextListItem;
struct XmlAttributeNode
{
@@ -699,7 +701,7 @@ private:
XmlAttributeNode (const String& name, const String& value) throw();
String name, value;
XmlAttributeNode* next;
LinkedListPointer<XmlAttributeNode> nextListItem;
bool hasName (const String& name) const throw();
@@ -707,7 +709,8 @@ private:
XmlAttributeNode& operator= (const XmlAttributeNode&);
};
XmlAttributeNode* attributes;
friend class LinkedListPointer<XmlAttributeNode>;
LinkedListPointer <XmlAttributeNode> attributes;
XmlElement (int) throw();
void copyChildrenAndAttributesFrom (const XmlElement& other);


Loading…
Cancel
Save