| @@ -78,6 +78,8 @@ | |||
| #undef min | |||
| #define NO_DUMMY_DECL | |||
| #define JUCE_AMALGAMATED_TEMPLATE 1 | |||
| #if JUCE_BUILD_NATIVE | |||
| #include "../juce_amalgamated.h" // FORCE_AMALGAMATOR_INCLUDE | |||
| #endif | |||
| @@ -92,8 +94,6 @@ | |||
| END_JUCE_NAMESPACE | |||
| #endif | |||
| #define JUCE_AMALGAMATED_TEMPLATE 1 | |||
| //============================================================================== | |||
| #if JUCE_BUILD_CORE | |||
| #include "../src/core/juce_FileLogger.cpp" | |||
| @@ -139,60 +139,6 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| class DrawableComponent : public Component, | |||
| public ValueTree::Listener | |||
| { | |||
| public: | |||
| DrawableComponent (const ValueTree& drawable_) | |||
| { | |||
| setDrawable (drawable_); | |||
| } | |||
| ~DrawableComponent() | |||
| { | |||
| } | |||
| void setDrawable (const ValueTree& newDrawable) | |||
| { | |||
| drawable.removeListener (this); | |||
| drawable = newDrawable; | |||
| drawable.addListener (this); | |||
| drawableObject = Drawable::createFromValueTree (drawable, 0); // xxx image provider missing | |||
| addAndMakeVisible (drawableObject); | |||
| resized(); | |||
| repaint(); | |||
| } | |||
| void resized() | |||
| { | |||
| /* DrawableComposite* dc = dynamic_cast <DrawableComposite*> (static_cast <Drawable*> (drawableObject)); | |||
| if (dc != 0) | |||
| { | |||
| const RelativeCoordinate origin, right (getWidth()), bottom (getHeight()); | |||
| dc->setContentArea (RelativeRectangle (origin, right, origin, bottom)); | |||
| //dc->resetBoundingBoxToContentArea(); | |||
| }*/ | |||
| } | |||
| void valueTreePropertyChanged (ValueTree&, const Identifier&) { updateGraphics(); } | |||
| void valueTreeChildrenChanged (ValueTree&) { updateGraphics(); } | |||
| void valueTreeParentChanged (ValueTree&) { updateGraphics(); } | |||
| private: | |||
| ValueTree drawable; | |||
| ScopedPointer<Drawable> drawableObject; | |||
| void updateGraphics() | |||
| { | |||
| if (drawableObject != 0) | |||
| drawableObject->refreshFromValueTree (drawable, 0); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| /** | |||
| */ | |||
| @@ -59,7 +59,8 @@ public: | |||
| SteinbergWavelab7, | |||
| SteinbergWavelabGeneric, | |||
| MuseReceptorGeneric, | |||
| MagixSamplitude | |||
| MagixSamplitude, | |||
| FruityLoops | |||
| }; | |||
| const HostType type; | |||
| @@ -120,6 +121,11 @@ public: | |||
| return type == MagixSamplitude; | |||
| } | |||
| bool isFruityLoops() const throw() | |||
| { | |||
| return type == FruityLoops; | |||
| } | |||
| //============================================================================== | |||
| static String getHostPath() | |||
| { | |||
| @@ -169,6 +175,7 @@ private: | |||
| if (hostFilename.containsIgnoreCase ("Wavelab")) return SteinbergWavelabGeneric; | |||
| if (hostFilename.containsIgnoreCase ("rm-host")) return MuseReceptorGeneric; | |||
| if (hostFilename.startsWithIgnoreCase ("Sam")) return MagixSamplitude; | |||
| if (hostFilename.startsWith ("FL") return FruityLoops; | |||
| #elif JUCE_LINUX | |||
| jassertfalse // not yet done! | |||
| @@ -156,4 +156,9 @@ END_JUCE_NAMESPACE | |||
| #endif | |||
| #if ! JUCE_AMALGAMATED_TEMPLATE | |||
| #undef BEGIN_JUCE_NAMESPACE | |||
| #undef END_JUCE_NAMESPACE | |||
| #endif | |||
| #endif // __JUCE_JUCEHEADER__ | |||
| @@ -892,7 +892,8 @@ protected: | |||
| #import <IOKit/hid/IOHIDKeys.h> | |||
| #import <IOKit/pwr_mgt/IOPMLib.h> | |||
| #endif | |||
| #if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) | |||
| #if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \ | |||
| && ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) | |||
| #include <Carbon/Carbon.h> | |||
| #endif | |||
| #include <sys/dir.h> | |||
| @@ -934,6 +935,8 @@ protected: | |||
| #undef min | |||
| #define NO_DUMMY_DECL | |||
| #define JUCE_AMALGAMATED_TEMPLATE 1 | |||
| #if JUCE_BUILD_NATIVE | |||
| #include "juce_amalgamated.h" // FORCE_AMALGAMATOR_INCLUDE | |||
| #endif | |||
| @@ -1204,8 +1207,6 @@ protected: | |||
| END_JUCE_NAMESPACE | |||
| #endif | |||
| #define JUCE_AMALGAMATED_TEMPLATE 1 | |||
| //============================================================================== | |||
| #if JUCE_BUILD_CORE | |||
| @@ -4425,23 +4426,42 @@ NamedValueSet::NamedValueSet() throw() | |||
| } | |||
| NamedValueSet::NamedValueSet (const NamedValueSet& other) | |||
| : values (other.values) | |||
| { | |||
| values.addCopyOfList (other.values); | |||
| } | |||
| NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other) | |||
| { | |||
| values = other.values; | |||
| clear(); | |||
| values.addCopyOfList (other.values); | |||
| return *this; | |||
| } | |||
| NamedValueSet::~NamedValueSet() | |||
| { | |||
| clear(); | |||
| } | |||
| void NamedValueSet::clear() | |||
| { | |||
| values.deleteAll(); | |||
| } | |||
| bool NamedValueSet::operator== (const NamedValueSet& other) const | |||
| { | |||
| return values == other.values; | |||
| const NamedValue* i1 = values; | |||
| const NamedValue* i2 = other.values; | |||
| while (i1 != 0 && i2 != 0) | |||
| { | |||
| if (! (*i1 == *i2)) | |||
| return false; | |||
| i1 = i1->nextListItem; | |||
| i2 = i2->nextListItem; | |||
| } | |||
| return true; | |||
| } | |||
| bool NamedValueSet::operator!= (const NamedValueSet& other) const | |||
| @@ -4456,13 +4476,9 @@ int NamedValueSet::size() const throw() | |||
| const var& NamedValueSet::operator[] (const Identifier& name) const | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| { | |||
| const NamedValue& v = values.getReference(i); | |||
| if (v.name == name) | |||
| return v.value; | |||
| } | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| if (i->name == name) | |||
| return i->value; | |||
| return var::null; | |||
| } | |||
| @@ -4475,34 +4491,34 @@ const var NamedValueSet::getWithDefault (const Identifier& name, const var& defa | |||
| var* NamedValueSet::getVarPointer (const Identifier& name) const | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| { | |||
| NamedValue& v = values.getReference(i); | |||
| if (v.name == name) | |||
| return &(v.value); | |||
| } | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| if (i->name == name) | |||
| return &(i->value); | |||
| return 0; | |||
| } | |||
| bool NamedValueSet::set (const Identifier& name, const var& newValue) | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| LinkedListPointer<NamedValue>* i = &values; | |||
| while (i->get() != 0) | |||
| { | |||
| NamedValue& v = values.getReference(i); | |||
| NamedValue* const v = i->get(); | |||
| if (v.name == name) | |||
| if (v->name == name) | |||
| { | |||
| if (v.value == newValue) | |||
| if (v->value == newValue) | |||
| return false; | |||
| v.value = newValue; | |||
| v->value = newValue; | |||
| return true; | |||
| } | |||
| i = &(v->nextListItem); | |||
| } | |||
| values.add (NamedValue (name, newValue)); | |||
| i->insertNext (new NamedValue (name, newValue)); | |||
| return true; | |||
| } | |||
| @@ -4513,13 +4529,22 @@ bool NamedValueSet::contains (const Identifier& name) const | |||
| bool NamedValueSet::remove (const Identifier& name) | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| LinkedListPointer<NamedValue>* i = &values; | |||
| for (;;) | |||
| { | |||
| if (values.getReference(i).name == name) | |||
| NamedValue* const v = i->get(); | |||
| if (v == 0) | |||
| break; | |||
| if (v->name == name) | |||
| { | |||
| values.remove (i); | |||
| delete i->removeNext(); | |||
| return true; | |||
| } | |||
| i = &(v->nextListItem); | |||
| } | |||
| return false; | |||
| @@ -4527,19 +4552,37 @@ bool NamedValueSet::remove (const Identifier& name) | |||
| const Identifier NamedValueSet::getName (const int index) const | |||
| { | |||
| jassert (isPositiveAndBelow (index, values.size())); | |||
| return values [index].name; | |||
| const NamedValue* const v = values[index]; | |||
| jassert (v != 0); | |||
| return v->name; | |||
| } | |||
| const var NamedValueSet::getValueAt (const int index) const | |||
| { | |||
| jassert (isPositiveAndBelow (index, values.size())); | |||
| return values [index].value; | |||
| const NamedValue* const v = values[index]; | |||
| jassert (v != 0); | |||
| return v->value; | |||
| } | |||
| void NamedValueSet::clear() | |||
| void NamedValueSet::setFromXmlAttributes (const XmlElement& xml) | |||
| { | |||
| values.clear(); | |||
| LinkedListPointer<NamedValue>::Appender appender (values.getLast()); | |||
| const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator.. | |||
| for (int i = 0; i < numAtts; ++i) | |||
| set (xml.getAttributeName (i), var (xml.getAttributeValue (i))); | |||
| } | |||
| void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const | |||
| { | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| { | |||
| jassert (! i->value.isObject()); // DynamicObjects can't be stored as XML! | |||
| xml.setAttribute (i->name.toString(), | |||
| i->value.toString()); | |||
| } | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -18315,20 +18358,10 @@ void ValueTree::removeListener (Listener* listener) | |||
| XmlElement* ValueTree::SharedObject::createXml() const | |||
| { | |||
| XmlElement* xml = new XmlElement (type.toString()); | |||
| int i; | |||
| for (i = 0; i < properties.size(); ++i) | |||
| { | |||
| Identifier name (properties.getName(i)); | |||
| const var& v = properties [name]; | |||
| jassert (! v.isObject()); // DynamicObjects can't be stored as XML! | |||
| XmlElement* const xml = new XmlElement (type.toString()); | |||
| properties.copyToXmlAttributes (*xml); | |||
| xml->setAttribute (name.toString(), v.toString()); | |||
| } | |||
| for (i = 0; i < children.size(); ++i) | |||
| for (int i = 0; i < children.size(); ++i) | |||
| xml->addChildElement (children.getUnchecked(i)->createXml()); | |||
| return xml; | |||
| @@ -18342,16 +18375,10 @@ XmlElement* ValueTree::createXml() const | |||
| ValueTree ValueTree::fromXml (const XmlElement& xml) | |||
| { | |||
| ValueTree v (xml.getTagName()); | |||
| const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator.. | |||
| for (int i = 0; i < numAtts; ++i) | |||
| v.setProperty (xml.getAttributeName (i), var (xml.getAttributeValue (i)), 0); | |||
| v.object->properties.setFromXmlAttributes (xml); | |||
| forEachXmlChildElement (xml, e) | |||
| { | |||
| v.addChild (fromXml (*e), -1, 0); | |||
| } | |||
| return v; | |||
| } | |||
| @@ -18401,13 +18428,18 @@ ValueTree ValueTree::readFromStream (InputStream& input) | |||
| const String name (input.readString()); | |||
| jassert (name.isNotEmpty()); | |||
| const var value (var::readFromStream (input)); | |||
| v.setProperty (name, value, 0); | |||
| v.object->properties.set (name, value); | |||
| } | |||
| const int numChildren = input.readCompressedInt(); | |||
| for (i = 0; i < numChildren; ++i) | |||
| v.addChild (readFromStream (input), -1, 0); | |||
| { | |||
| ValueTree child (readFromStream (input)); | |||
| v.object->children.add (child.object); | |||
| child.object->parent = v.object; | |||
| } | |||
| return v; | |||
| } | |||
| @@ -39924,6 +39956,11 @@ void Component::setName (const String& name) | |||
| } | |||
| } | |||
| void Component::setComponentID (const String& newID) | |||
| { | |||
| componentID = newID; | |||
| } | |||
| void Component::setVisible (bool shouldBeVisible) | |||
| { | |||
| if (flags.visibleFlag != shouldBeVisible) | |||
| @@ -262329,40 +262366,23 @@ namespace SystemStatsHelpers | |||
| static int64 highResTimerFrequency = 0; | |||
| static double highResTimerToMillisecRatio = 0; | |||
| #if JUCE_INTEL | |||
| static void juce_getCpuVendor (char* const v) throw() | |||
| #if JUCE_INTEL | |||
| void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type) | |||
| { | |||
| int vendor[4]; | |||
| zerostruct (vendor); | |||
| int dummy = 0; | |||
| uint32 la = a, lb = b, lc = c, ld = d; | |||
| asm ("mov %%ebx, %%esi \n\t" | |||
| "cpuid \n\t" | |||
| "xchg %%esi, %%ebx" | |||
| : "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0)); | |||
| memcpy (v, vendor, 16); | |||
| } | |||
| static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) | |||
| { | |||
| unsigned int cpu = 0; | |||
| unsigned int ext = 0; | |||
| unsigned int family = 0; | |||
| unsigned int dummy = 0; | |||
| asm ("mov %%ebx, %%esi \n\t" | |||
| "cpuid \n\t" | |||
| "xchg %%esi, %%ebx" | |||
| : "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1)); | |||
| : "=a" (la), "=S" (lb), "=c" (lc), "=d" (ld) : "a" (type) | |||
| #if JUCE_64BIT | |||
| , "b" (lb), "c" (lc), "d" (ld) | |||
| #endif | |||
| ); | |||
| familyModel = family; | |||
| extFeatures = ext; | |||
| return cpu; | |||
| a = la; b = lb; c = lc; d = ld; | |||
| } | |||
| #endif | |||
| #endif | |||
| } | |||
| void SystemStats::initialiseStats() | |||
| @@ -262379,8 +262399,8 @@ void SystemStats::initialiseStats() | |||
| #endif | |||
| #if JUCE_INTEL | |||
| unsigned int familyModel, extFeatures; | |||
| const unsigned int features = getCPUIDWord (familyModel, extFeatures); | |||
| uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; | |||
| doCPUID (familyModel, extFeatures, dummy, features, 1); | |||
| cpuFlags.hasMMX = ((features & (1 << 23)) != 0); | |||
| cpuFlags.hasSSE = ((features & (1 << 25)) != 0); | |||
| @@ -262457,9 +262477,13 @@ int SystemStats::getMemorySizeInMegabytes() | |||
| const String SystemStats::getCpuVendor() | |||
| { | |||
| #if JUCE_INTEL | |||
| char v [16]; | |||
| SystemStatsHelpers::juce_getCpuVendor (v); | |||
| return String (v, 16); | |||
| uint32 dummy = 0; | |||
| uint32 vendor[4]; | |||
| zerostruct (vendor); | |||
| SystemStatsHelpers::doCPUID (dummy, vendor[0], vendor[2], vendor[1], 0); | |||
| return String (reinterpret_cast <const char*> (vendor), 12); | |||
| #else | |||
| return String::empty; | |||
| #endif | |||
| @@ -272458,9 +272482,17 @@ void Desktop::createMouseInputSources() | |||
| void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) | |||
| { | |||
| // Very annoyingly, this function has to use the old SetSystemUIMode function, | |||
| // which is in Carbon.framework. But, because there's no Cocoa equivalent, it | |||
| // is apparently still available in 64-bit apps.. | |||
| #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 | |||
| if (enableOrDisable) | |||
| { | |||
| [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar]; | |||
| kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); | |||
| } | |||
| else | |||
| { | |||
| [NSApp setPresentationOptions: NSApplicationPresentationDefault]; | |||
| } | |||
| #else | |||
| if (enableOrDisable) | |||
| { | |||
| SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); | |||
| @@ -272470,6 +272502,7 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable | |||
| { | |||
| SetSystemUIMode (kUIModeNormal, 0); | |||
| } | |||
| #endif | |||
| } | |||
| void NSViewComponentPeer::repaint (const Rectangle<int>& area) | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 111 | |||
| #define JUCE_BUILDNUMBER 112 | |||
| /** Current Juce version number. | |||
| @@ -3316,7 +3316,7 @@ private: | |||
| @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector | |||
| */ | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) JUCE_NAMESPACE::LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #else | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) | |||
| #endif | |||
| @@ -6189,6 +6189,324 @@ bool operator!= (const var& v1, const String& v2) throw(); | |||
| #endif // __JUCE_VARIANT_JUCEHEADER__ | |||
| /*** End of inlined file: juce_Variant.h ***/ | |||
| /*** 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 ***/ | |||
| class XmlElement; | |||
| /** Holds a set of named var objects. | |||
| This can be used as a basic structure to hold a set of var object, which can | |||
| @@ -6242,14 +6560,12 @@ public: | |||
| bool remove (const Identifier& name); | |||
| /** Returns the name of the value at a given index. | |||
| The index must be between 0 and size() - 1. Out-of-range indexes will | |||
| return an empty identifier. | |||
| The index must be between 0 and size() - 1. | |||
| */ | |||
| const Identifier getName (int index) const; | |||
| /** Returns the value of the item at a given index. | |||
| The index must be between 0 and size() - 1. Out-of-range indexes will | |||
| return an empty identifier. | |||
| The index must be between 0 and size() - 1. | |||
| */ | |||
| const var getValueAt (int index) const; | |||
| @@ -6264,19 +6580,33 @@ public: | |||
| */ | |||
| var* getVarPointer (const Identifier& name) const; | |||
| /** Sets properties to the values of all of an XML element's attributes. */ | |||
| void setFromXmlAttributes (const XmlElement& xml); | |||
| /** Sets attributes in an XML element corresponding to each of this object's | |||
| properties. | |||
| */ | |||
| void copyToXmlAttributes (XmlElement& xml) const; | |||
| private: | |||
| struct NamedValue | |||
| class NamedValue | |||
| { | |||
| public: | |||
| NamedValue() throw(); | |||
| NamedValue (const Identifier& name, const var& value); | |||
| bool operator== (const NamedValue& other) const throw(); | |||
| LinkedListPointer<NamedValue> nextListItem; | |||
| Identifier name; | |||
| var value; | |||
| private: | |||
| JUCE_LEAK_DETECTOR (NamedValue); | |||
| }; | |||
| Array <NamedValue> values; | |||
| friend class LinkedListPointer<NamedValue>; | |||
| LinkedListPointer<NamedValue> values; | |||
| }; | |||
| #endif // __JUCE_NAMEDVALUESET_JUCEHEADER__ | |||
| @@ -6627,322 +6957,6 @@ private: | |||
| #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__ | |||
| @@ -10286,13 +10300,11 @@ public: | |||
| To improve performance, the compareElements() method can be declared as static or const. | |||
| @param comparator the comparator to use for comparing elements. | |||
| @param retainOrderOfEquivalentItems if this is true, then items | |||
| which the comparator says are equivalent will be | |||
| kept in the order in which they currently appear | |||
| in the array. This is slower to perform, but may | |||
| be important in some cases. If it's false, a faster | |||
| algorithm is used, but equivalent elements may be | |||
| rearranged. | |||
| @param retainOrderOfEquivalentItems if this is true, then items which the comparator | |||
| says are equivalent will be kept in the order in which they | |||
| currently appear in the array. This is slower to perform, but | |||
| may be important in some cases. If it's false, a faster algorithm | |||
| is used, but equivalent elements may be rearranged. | |||
| */ | |||
| template <class ElementComparator> | |||
| void sortChildElements (ElementComparator& comparator, | |||
| @@ -10386,20 +10398,13 @@ public: | |||
| static XmlElement* createTextElement (const String& text); | |||
| private: | |||
| friend class XmlDocument; | |||
| String tagName; | |||
| friend class LinkedListPointer <XmlElement>; | |||
| LinkedListPointer <XmlElement> firstChildElement; | |||
| LinkedListPointer <XmlElement> nextListItem; | |||
| struct XmlAttributeNode | |||
| { | |||
| XmlAttributeNode (const XmlAttributeNode& other) throw(); | |||
| XmlAttributeNode (const String& name, const String& value) throw(); | |||
| String name, value; | |||
| LinkedListPointer<XmlAttributeNode> nextListItem; | |||
| String name, value; | |||
| bool hasName (const String& name) const throw(); | |||
| @@ -10407,8 +10412,14 @@ private: | |||
| XmlAttributeNode& operator= (const XmlAttributeNode&); | |||
| }; | |||
| friend class XmlDocument; | |||
| friend class LinkedListPointer<XmlAttributeNode>; | |||
| friend class LinkedListPointer <XmlElement>; | |||
| LinkedListPointer <XmlElement> nextListItem; | |||
| LinkedListPointer <XmlElement> firstChildElement; | |||
| LinkedListPointer <XmlAttributeNode> attributes; | |||
| String tagName; | |||
| XmlElement (int) throw(); | |||
| void copyChildrenAndAttributesFrom (const XmlElement& other); | |||
| @@ -26910,6 +26921,17 @@ public: | |||
| */ | |||
| virtual void setName (const String& newName); | |||
| /** Returns the ID string that was set by setComponentID(). | |||
| @see setComponentID | |||
| */ | |||
| const String& getComponentID() const throw() { return componentID; } | |||
| /** Sets the component's ID string. | |||
| You can retrieve the ID using getComponentID(). | |||
| @see getComponentID | |||
| */ | |||
| void setComponentID (const String& newID); | |||
| /** Makes the component visible or invisible. | |||
| This method will show or hide the component. | |||
| @@ -28875,7 +28897,7 @@ private: | |||
| #ifndef DOXYGEN | |||
| static Component* currentlyFocusedComponent; | |||
| String componentName_; | |||
| String componentName_, componentID; | |||
| Component* parentComponent_; | |||
| Rectangle<int> bounds_; | |||
| ScopedPointer <AffineTransform> affineTransform_; | |||
| @@ -63812,6 +63834,11 @@ END_JUCE_NAMESPACE | |||
| #endif | |||
| #if ! JUCE_AMALGAMATED_TEMPLATE | |||
| #undef BEGIN_JUCE_NAMESPACE | |||
| #undef END_JUCE_NAMESPACE | |||
| #endif | |||
| #endif // __JUCE_JUCEHEADER__ | |||
| /*** End of inlined file: juce.h ***/ | |||
| @@ -28,6 +28,7 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_NamedValueSet.h" | |||
| #include "../text/juce_XmlElement.h" | |||
| //============================================================================== | |||
| @@ -51,23 +52,42 @@ NamedValueSet::NamedValueSet() throw() | |||
| } | |||
| NamedValueSet::NamedValueSet (const NamedValueSet& other) | |||
| : values (other.values) | |||
| { | |||
| values.addCopyOfList (other.values); | |||
| } | |||
| NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other) | |||
| { | |||
| values = other.values; | |||
| clear(); | |||
| values.addCopyOfList (other.values); | |||
| return *this; | |||
| } | |||
| NamedValueSet::~NamedValueSet() | |||
| { | |||
| clear(); | |||
| } | |||
| void NamedValueSet::clear() | |||
| { | |||
| values.deleteAll(); | |||
| } | |||
| bool NamedValueSet::operator== (const NamedValueSet& other) const | |||
| { | |||
| return values == other.values; | |||
| const NamedValue* i1 = values; | |||
| const NamedValue* i2 = other.values; | |||
| while (i1 != 0 && i2 != 0) | |||
| { | |||
| if (! (*i1 == *i2)) | |||
| return false; | |||
| i1 = i1->nextListItem; | |||
| i2 = i2->nextListItem; | |||
| } | |||
| return true; | |||
| } | |||
| bool NamedValueSet::operator!= (const NamedValueSet& other) const | |||
| @@ -82,13 +102,9 @@ int NamedValueSet::size() const throw() | |||
| const var& NamedValueSet::operator[] (const Identifier& name) const | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| { | |||
| const NamedValue& v = values.getReference(i); | |||
| if (v.name == name) | |||
| return v.value; | |||
| } | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| if (i->name == name) | |||
| return i->value; | |||
| return var::null; | |||
| } | |||
| @@ -101,34 +117,34 @@ const var NamedValueSet::getWithDefault (const Identifier& name, const var& defa | |||
| var* NamedValueSet::getVarPointer (const Identifier& name) const | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| { | |||
| NamedValue& v = values.getReference(i); | |||
| if (v.name == name) | |||
| return &(v.value); | |||
| } | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| if (i->name == name) | |||
| return &(i->value); | |||
| return 0; | |||
| } | |||
| bool NamedValueSet::set (const Identifier& name, const var& newValue) | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| LinkedListPointer<NamedValue>* i = &values; | |||
| while (i->get() != 0) | |||
| { | |||
| NamedValue& v = values.getReference(i); | |||
| NamedValue* const v = i->get(); | |||
| if (v.name == name) | |||
| if (v->name == name) | |||
| { | |||
| if (v.value == newValue) | |||
| if (v->value == newValue) | |||
| return false; | |||
| v.value = newValue; | |||
| v->value = newValue; | |||
| return true; | |||
| } | |||
| i = &(v->nextListItem); | |||
| } | |||
| values.add (NamedValue (name, newValue)); | |||
| i->insertNext (new NamedValue (name, newValue)); | |||
| return true; | |||
| } | |||
| @@ -139,13 +155,22 @@ bool NamedValueSet::contains (const Identifier& name) const | |||
| bool NamedValueSet::remove (const Identifier& name) | |||
| { | |||
| for (int i = values.size(); --i >= 0;) | |||
| LinkedListPointer<NamedValue>* i = &values; | |||
| for (;;) | |||
| { | |||
| if (values.getReference(i).name == name) | |||
| NamedValue* const v = i->get(); | |||
| if (v == 0) | |||
| break; | |||
| if (v->name == name) | |||
| { | |||
| values.remove (i); | |||
| delete i->removeNext(); | |||
| return true; | |||
| } | |||
| i = &(v->nextListItem); | |||
| } | |||
| return false; | |||
| @@ -153,19 +178,37 @@ bool NamedValueSet::remove (const Identifier& name) | |||
| const Identifier NamedValueSet::getName (const int index) const | |||
| { | |||
| jassert (isPositiveAndBelow (index, values.size())); | |||
| return values [index].name; | |||
| const NamedValue* const v = values[index]; | |||
| jassert (v != 0); | |||
| return v->name; | |||
| } | |||
| const var NamedValueSet::getValueAt (const int index) const | |||
| { | |||
| jassert (isPositiveAndBelow (index, values.size())); | |||
| return values [index].value; | |||
| const NamedValue* const v = values[index]; | |||
| jassert (v != 0); | |||
| return v->value; | |||
| } | |||
| void NamedValueSet::clear() | |||
| void NamedValueSet::setFromXmlAttributes (const XmlElement& xml) | |||
| { | |||
| values.clear(); | |||
| LinkedListPointer<NamedValue>::Appender appender (values.getLast()); | |||
| const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator.. | |||
| for (int i = 0; i < numAtts; ++i) | |||
| set (xml.getAttributeName (i), var (xml.getAttributeValue (i))); | |||
| } | |||
| void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const | |||
| { | |||
| for (NamedValue* i = values; i != 0; i = i->nextListItem) | |||
| { | |||
| jassert (! i->value.isObject()); // DynamicObjects can't be stored as XML! | |||
| xml.setAttribute (i->name.toString(), | |||
| i->value.toString()); | |||
| } | |||
| } | |||
| @@ -27,7 +27,8 @@ | |||
| #define __JUCE_NAMEDVALUESET_JUCEHEADER__ | |||
| #include "juce_Variant.h" | |||
| #include "../containers/juce_Array.h" | |||
| #include "../containers/juce_LinkedListPointer.h" | |||
| class XmlElement; | |||
| //============================================================================== | |||
| @@ -85,14 +86,12 @@ public: | |||
| bool remove (const Identifier& name); | |||
| /** Returns the name of the value at a given index. | |||
| The index must be between 0 and size() - 1. Out-of-range indexes will | |||
| return an empty identifier. | |||
| The index must be between 0 and size() - 1. | |||
| */ | |||
| const Identifier getName (int index) const; | |||
| /** Returns the value of the item at a given index. | |||
| The index must be between 0 and size() - 1. Out-of-range indexes will | |||
| return an empty identifier. | |||
| The index must be between 0 and size() - 1. | |||
| */ | |||
| const var getValueAt (int index) const; | |||
| @@ -108,19 +107,34 @@ public: | |||
| */ | |||
| var* getVarPointer (const Identifier& name) const; | |||
| //============================================================================== | |||
| /** Sets properties to the values of all of an XML element's attributes. */ | |||
| void setFromXmlAttributes (const XmlElement& xml); | |||
| /** Sets attributes in an XML element corresponding to each of this object's | |||
| properties. | |||
| */ | |||
| void copyToXmlAttributes (XmlElement& xml) const; | |||
| private: | |||
| //============================================================================== | |||
| struct NamedValue | |||
| class NamedValue | |||
| { | |||
| public: | |||
| NamedValue() throw(); | |||
| NamedValue (const Identifier& name, const var& value); | |||
| bool operator== (const NamedValue& other) const throw(); | |||
| LinkedListPointer<NamedValue> nextListItem; | |||
| Identifier name; | |||
| var value; | |||
| private: | |||
| JUCE_LEAK_DETECTOR (NamedValue); | |||
| }; | |||
| Array <NamedValue> values; | |||
| friend class LinkedListPointer<NamedValue>; | |||
| LinkedListPointer<NamedValue> values; | |||
| }; | |||
| @@ -830,20 +830,10 @@ void ValueTree::removeListener (Listener* listener) | |||
| //============================================================================== | |||
| XmlElement* ValueTree::SharedObject::createXml() const | |||
| { | |||
| XmlElement* xml = new XmlElement (type.toString()); | |||
| XmlElement* const xml = new XmlElement (type.toString()); | |||
| properties.copyToXmlAttributes (*xml); | |||
| int i; | |||
| for (i = 0; i < properties.size(); ++i) | |||
| { | |||
| Identifier name (properties.getName(i)); | |||
| const var& v = properties [name]; | |||
| jassert (! v.isObject()); // DynamicObjects can't be stored as XML! | |||
| xml->setAttribute (name.toString(), v.toString()); | |||
| } | |||
| for (i = 0; i < children.size(); ++i) | |||
| for (int i = 0; i < children.size(); ++i) | |||
| xml->addChildElement (children.getUnchecked(i)->createXml()); | |||
| return xml; | |||
| @@ -857,16 +847,10 @@ XmlElement* ValueTree::createXml() const | |||
| ValueTree ValueTree::fromXml (const XmlElement& xml) | |||
| { | |||
| ValueTree v (xml.getTagName()); | |||
| const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator.. | |||
| for (int i = 0; i < numAtts; ++i) | |||
| v.setProperty (xml.getAttributeName (i), var (xml.getAttributeValue (i)), 0); | |||
| v.object->properties.setFromXmlAttributes (xml); | |||
| forEachXmlChildElement (xml, e) | |||
| { | |||
| v.addChild (fromXml (*e), -1, 0); | |||
| } | |||
| return v; | |||
| } | |||
| @@ -917,13 +901,18 @@ ValueTree ValueTree::readFromStream (InputStream& input) | |||
| const String name (input.readString()); | |||
| jassert (name.isNotEmpty()); | |||
| const var value (var::readFromStream (input)); | |||
| v.setProperty (name, value, 0); | |||
| v.object->properties.set (name, value); | |||
| } | |||
| const int numChildren = input.readCompressedInt(); | |||
| for (i = 0; i < numChildren; ++i) | |||
| v.addChild (readFromStream (input), -1, 0); | |||
| { | |||
| ValueTree child (readFromStream (input)); | |||
| v.object->children.add (child.object); | |||
| child.object->parent = v.object; | |||
| } | |||
| return v; | |||
| } | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 111 | |||
| #define JUCE_BUILDNUMBER 112 | |||
| /** Current Juce version number. | |||
| @@ -458,6 +458,11 @@ void Component::setName (const String& name) | |||
| } | |||
| } | |||
| void Component::setComponentID (const String& newID) | |||
| { | |||
| componentID = newID; | |||
| } | |||
| void Component::setVisible (bool shouldBeVisible) | |||
| { | |||
| if (flags.visibleFlag != shouldBeVisible) | |||
| @@ -108,6 +108,17 @@ public: | |||
| */ | |||
| virtual void setName (const String& newName); | |||
| /** Returns the ID string that was set by setComponentID(). | |||
| @see setComponentID | |||
| */ | |||
| const String& getComponentID() const throw() { return componentID; } | |||
| /** Sets the component's ID string. | |||
| You can retrieve the ID using getComponentID(). | |||
| @see getComponentID | |||
| */ | |||
| void setComponentID (const String& newID); | |||
| //============================================================================== | |||
| /** Makes the component visible or invisible. | |||
| @@ -2115,7 +2126,7 @@ private: | |||
| static Component* currentlyFocusedComponent; | |||
| //============================================================================== | |||
| String componentName_; | |||
| String componentName_, componentID; | |||
| Component* parentComponent_; | |||
| Rectangle<int> bounds_; | |||
| ScopedPointer <AffineTransform> affineTransform_; | |||
| @@ -127,7 +127,7 @@ private: | |||
| @see JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR, LeakedObjectDetector | |||
| */ | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) JUCE_NAMESPACE::LeakedObjectDetector<OwnerClass> JUCE_JOIN_MACRO (leakDetector, __LINE__); | |||
| #else | |||
| #define JUCE_LEAK_DETECTOR(OwnerClass) | |||
| #endif | |||
| @@ -1659,9 +1659,17 @@ void Desktop::createMouseInputSources() | |||
| //============================================================================== | |||
| void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) | |||
| { | |||
| // Very annoyingly, this function has to use the old SetSystemUIMode function, | |||
| // which is in Carbon.framework. But, because there's no Cocoa equivalent, it | |||
| // is apparently still available in 64-bit apps.. | |||
| #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 | |||
| if (enableOrDisable) | |||
| { | |||
| [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar]; | |||
| kioskModeComponent->setBounds (Desktop::getInstance().getMainMonitorArea (false)); | |||
| } | |||
| else | |||
| { | |||
| [NSApp setPresentationOptions: NSApplicationPresentationDefault]; | |||
| } | |||
| #else | |||
| if (enableOrDisable) | |||
| { | |||
| SetSystemUIMode (kUIModeAllSuppressed, allowMenusAndBars ? kUIOptionAutoShowMenuBar : 0); | |||
| @@ -1671,6 +1679,7 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable | |||
| { | |||
| SetSystemUIMode (kUIModeNormal, 0); | |||
| } | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| @@ -65,7 +65,8 @@ | |||
| #import <IOKit/hid/IOHIDKeys.h> | |||
| #import <IOKit/pwr_mgt/IOPMLib.h> | |||
| #endif | |||
| #if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) | |||
| #if JUCE_BUILD_MISC && (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_AU) \ | |||
| && ! (defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) | |||
| #include <Carbon/Carbon.h> | |||
| #endif | |||
| #include <sys/dir.h> | |||
| @@ -32,40 +32,23 @@ namespace SystemStatsHelpers | |||
| static int64 highResTimerFrequency = 0; | |||
| static double highResTimerToMillisecRatio = 0; | |||
| #if JUCE_INTEL | |||
| static void juce_getCpuVendor (char* const v) throw() | |||
| { | |||
| int vendor[4]; | |||
| zerostruct (vendor); | |||
| int dummy = 0; | |||
| asm ("mov %%ebx, %%esi \n\t" | |||
| "cpuid \n\t" | |||
| "xchg %%esi, %%ebx" | |||
| : "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0)); | |||
| memcpy (v, vendor, 16); | |||
| } | |||
| static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures) | |||
| #if JUCE_INTEL | |||
| void doCPUID (uint32& a, uint32& b, uint32& c, uint32& d, uint32 type) | |||
| { | |||
| unsigned int cpu = 0; | |||
| unsigned int ext = 0; | |||
| unsigned int family = 0; | |||
| unsigned int dummy = 0; | |||
| uint32 la = a, lb = b, lc = c, ld = d; | |||
| asm ("mov %%ebx, %%esi \n\t" | |||
| "cpuid \n\t" | |||
| "xchg %%esi, %%ebx" | |||
| : "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1)); | |||
| : "=a" (la), "=S" (lb), "=c" (lc), "=d" (ld) : "a" (type) | |||
| #if JUCE_64BIT | |||
| , "b" (lb), "c" (lc), "d" (ld) | |||
| #endif | |||
| ); | |||
| familyModel = family; | |||
| extFeatures = ext; | |||
| return cpu; | |||
| a = la; b = lb; c = lc; d = ld; | |||
| } | |||
| #endif | |||
| #endif | |||
| } | |||
| //============================================================================== | |||
| @@ -83,8 +66,8 @@ void SystemStats::initialiseStats() | |||
| #endif | |||
| #if JUCE_INTEL | |||
| unsigned int familyModel, extFeatures; | |||
| const unsigned int features = getCPUIDWord (familyModel, extFeatures); | |||
| uint32 familyModel = 0, extFeatures = 0, features = 0, dummy = 0; | |||
| doCPUID (familyModel, extFeatures, dummy, features, 1); | |||
| cpuFlags.hasMMX = ((features & (1 << 23)) != 0); | |||
| cpuFlags.hasSSE = ((features & (1 << 25)) != 0); | |||
| @@ -162,9 +145,13 @@ int SystemStats::getMemorySizeInMegabytes() | |||
| const String SystemStats::getCpuVendor() | |||
| { | |||
| #if JUCE_INTEL | |||
| char v [16]; | |||
| SystemStatsHelpers::juce_getCpuVendor (v); | |||
| return String (v, 16); | |||
| uint32 dummy = 0; | |||
| uint32 vendor[4]; | |||
| zerostruct (vendor); | |||
| SystemStatsHelpers::doCPUID (dummy, vendor[0], vendor[2], vendor[1], 0); | |||
| return String (reinterpret_cast <const char*> (vendor), 12); | |||
| #else | |||
| return String::empty; | |||
| #endif | |||
| @@ -586,13 +586,11 @@ public: | |||
| To improve performance, the compareElements() method can be declared as static or const. | |||
| @param comparator the comparator to use for comparing elements. | |||
| @param retainOrderOfEquivalentItems if this is true, then items | |||
| which the comparator says are equivalent will be | |||
| kept in the order in which they currently appear | |||
| in the array. This is slower to perform, but may | |||
| be important in some cases. If it's false, a faster | |||
| algorithm is used, but equivalent elements may be | |||
| rearranged. | |||
| @param retainOrderOfEquivalentItems if this is true, then items which the comparator | |||
| says are equivalent will be kept in the order in which they | |||
| currently appear in the array. This is slower to perform, but | |||
| may be important in some cases. If it's false, a faster algorithm | |||
| is used, but equivalent elements may be rearranged. | |||
| */ | |||
| template <class ElementComparator> | |||
| void sortChildElements (ElementComparator& comparator, | |||
| @@ -688,20 +686,13 @@ public: | |||
| //============================================================================== | |||
| private: | |||
| friend class XmlDocument; | |||
| String tagName; | |||
| friend class LinkedListPointer <XmlElement>; | |||
| LinkedListPointer <XmlElement> firstChildElement; | |||
| LinkedListPointer <XmlElement> nextListItem; | |||
| struct XmlAttributeNode | |||
| { | |||
| XmlAttributeNode (const XmlAttributeNode& other) throw(); | |||
| XmlAttributeNode (const String& name, const String& value) throw(); | |||
| String name, value; | |||
| LinkedListPointer<XmlAttributeNode> nextListItem; | |||
| String name, value; | |||
| bool hasName (const String& name) const throw(); | |||
| @@ -709,8 +700,14 @@ private: | |||
| XmlAttributeNode& operator= (const XmlAttributeNode&); | |||
| }; | |||
| friend class XmlDocument; | |||
| friend class LinkedListPointer<XmlAttributeNode>; | |||
| friend class LinkedListPointer <XmlElement>; | |||
| LinkedListPointer <XmlElement> nextListItem; | |||
| LinkedListPointer <XmlElement> firstChildElement; | |||
| LinkedListPointer <XmlAttributeNode> attributes; | |||
| String tagName; | |||
| XmlElement (int) throw(); | |||
| void copyChildrenAndAttributesFrom (const XmlElement& other); | |||