| @@ -183,7 +183,6 @@ struct UnitTestClasses | |||
| TextButton startTestButton; | |||
| TextEditor testResultsBox; | |||
| Label label; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnitTestsDemo); | |||
| }; | |||
| @@ -88,8 +88,9 @@ private: | |||
| props.add (new MissingDependenciesComponent (project, moduleID)); | |||
| for (Project::ExporterIterator exporter (project); exporter.next();) | |||
| props.add (new TextPropertyComponent (exporter->getPathForModuleValue (moduleID), | |||
| "Path for " + exporter->getName().quoted(), 1024, false), | |||
| props.add (new FilePathPropertyComponent (exporter->getPathForModuleValue (moduleID), | |||
| "Path for " + exporter->getName().quoted(), | |||
| true, "*", project.getProjectFolder()), | |||
| "A path to the folder that contains the " + moduleID + " module when compiling the " | |||
| + exporter->getName().quoted() + " target. " | |||
| "This can be an absolute path, or relative to the jucer project folder, but it " | |||
| @@ -146,28 +147,37 @@ private: | |||
| String moduleID; | |||
| //============================================================================== | |||
| class ModuleInfoComponent : public PropertyComponent | |||
| class ModuleInfoComponent : public PropertyComponent, | |||
| private Value::Listener | |||
| { | |||
| public: | |||
| ModuleInfoComponent (Project& p, const String& modID) | |||
| : PropertyComponent ("Module", 150), project (p), moduleID (modID) | |||
| { | |||
| for (Project::ExporterIterator exporter (project); exporter.next();) | |||
| listeningValues.add (new Value (exporter->getPathForModuleValue (moduleID))) | |||
| ->addListener (this); | |||
| refresh(); | |||
| } | |||
| void refresh() {} | |||
| private: | |||
| void refresh() override | |||
| { | |||
| info = project.getModules().getModuleInfo (moduleID); | |||
| repaint(); | |||
| } | |||
| void paint (Graphics& g) | |||
| void paint (Graphics& g) override | |||
| { | |||
| g.setColour (Colours::white.withAlpha (0.4f)); | |||
| g.fillRect (0, 0, getWidth(), getHeight() - 1); | |||
| g.fillRect (getLocalBounds().withTrimmedBottom (1)); | |||
| AttributedString s; | |||
| s.setJustification (Justification::topLeft); | |||
| Font f (14.0f); | |||
| ModuleDescription info (project.getModules().getModuleInfo (moduleID)); | |||
| if (info.isValid()) | |||
| { | |||
| s.append (info.getName() + "\n\n", f.boldened()); | |||
| @@ -184,9 +194,15 @@ private: | |||
| s.draw (g, getLocalBounds().reduced (6, 5).toFloat()); | |||
| } | |||
| private: | |||
| void valueChanged (Value&) override | |||
| { | |||
| refresh(); | |||
| } | |||
| Project& project; | |||
| String moduleID; | |||
| OwnedArray<Value> listeningValues; | |||
| ModuleDescription info; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleInfoComponent) | |||
| }; | |||
| @@ -208,9 +224,9 @@ private: | |||
| fixButton.addListener (this); | |||
| } | |||
| void refresh() {} | |||
| void refresh() override {} | |||
| void paint (Graphics& g) | |||
| void paint (Graphics& g) override | |||
| { | |||
| g.setColour (Colours::white.withAlpha (0.4f)); | |||
| g.fillRect (0, 0, getWidth(), getHeight() - 1); | |||
| @@ -225,7 +241,7 @@ private: | |||
| s.draw (g, getLocalBounds().reduced (4, 16).toFloat()); | |||
| } | |||
| void buttonClicked (Button*) | |||
| void buttonClicked (Button*) override | |||
| { | |||
| bool anyFailed = false; | |||
| @@ -250,7 +266,7 @@ private: | |||
| "folders manually and add them to the list."); | |||
| } | |||
| void resized() | |||
| void resized() override | |||
| { | |||
| fixButton.setBounds (getWidth() - 168, getHeight() - 26, 160, 22); | |||
| } | |||
| @@ -289,7 +305,7 @@ public: | |||
| bool isMissing() override { return false; } | |||
| Icon getIcon() const override { return Icon (getIcons().graph, getContrastingColour (Colours::red, 0.5f)); } | |||
| void showDocument() | |||
| void showDocument() override | |||
| { | |||
| if (ProjectContentComponent* pcc = getProjectContentComponent()) | |||
| pcc->setEditorComponent (new ModulesPanel (project), nullptr); | |||
| @@ -380,3 +380,119 @@ public: | |||
| protected: | |||
| ColourEditorComponent colourEditor; | |||
| }; | |||
| //============================================================================== | |||
| class FilePathPropertyComponent : public PropertyComponent | |||
| { | |||
| public: | |||
| /** A Property Component for selecting files or folders. | |||
| The user may drag files over the property box, enter the path | |||
| manually and/or click the '...' button to open a file selection | |||
| dialog box | |||
| */ | |||
| FilePathPropertyComponent (Value valueToControl, | |||
| const String& propertyDescription, | |||
| bool isDirectory, | |||
| const String& wildcards = "*", | |||
| const File& rootToUseForRelativePaths = File::nonexistent) | |||
| : PropertyComponent (propertyDescription), | |||
| innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths) | |||
| { | |||
| addAndMakeVisible (innerComp); | |||
| } | |||
| void refresh() override {} // N/A | |||
| private: | |||
| struct InnerComponent : public Component, | |||
| public FileDragAndDropTarget, | |||
| private Button::Listener | |||
| { | |||
| InnerComponent (Value v, bool isDir, const String& wc, const File& rt) | |||
| : value (v), | |||
| isDirectory (isDir), | |||
| highlightForDragAndDrop (false), | |||
| wildcards (wc), | |||
| root (rt), | |||
| button ("...") | |||
| { | |||
| addAndMakeVisible (textbox); | |||
| textbox.getTextValue().referTo (value); | |||
| addAndMakeVisible (button); | |||
| button.addListener (this); | |||
| } | |||
| void paintOverChildren (Graphics& g) override | |||
| { | |||
| if (highlightForDragAndDrop) | |||
| { | |||
| g.setColour (Colours::green.withAlpha (0.1f)); | |||
| g.fillRect (getLocalBounds()); | |||
| } | |||
| } | |||
| void resized() override | |||
| { | |||
| Rectangle<int> r (getLocalBounds()); | |||
| button.setBounds (r.removeFromRight (24)); | |||
| textbox.setBounds (r); | |||
| } | |||
| bool isInterestedInFileDrag (const StringArray&) override { return true; } | |||
| void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); } | |||
| void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); } | |||
| void filesDropped (const StringArray& files, int, int) override | |||
| { | |||
| const File firstFile (files[0]); | |||
| if (isDirectory) | |||
| setTo (firstFile.isDirectory() ? firstFile | |||
| : firstFile.getParentDirectory()); | |||
| else | |||
| setTo (firstFile); | |||
| } | |||
| void buttonClicked (Button*) override | |||
| { | |||
| const File currentFile (root.getChildFile (value.toString())); | |||
| if (isDirectory) | |||
| { | |||
| FileChooser chooser ("Select directory", currentFile); | |||
| if (chooser.browseForDirectory()) | |||
| setTo (chooser.getResult()); | |||
| } | |||
| else | |||
| { | |||
| FileChooser chooser ("Select file", currentFile, wildcards); | |||
| if (chooser.browseForFileToOpen()) | |||
| setTo (chooser.getResult()); | |||
| } | |||
| } | |||
| void setTo (const File& f) | |||
| { | |||
| value = (root == File::nonexistent) ? f.getFullPathName() | |||
| : f.getRelativePathFrom (root); | |||
| } | |||
| Value value; | |||
| bool isDirectory, highlightForDragAndDrop; | |||
| String wildcards; | |||
| File root; | |||
| TextEditor textbox; | |||
| TextButton button; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent) | |||
| }; | |||
| InnerComponent innerComp; // Used so that the PropertyComponent auto first-child positioning works | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent) | |||
| }; | |||
| @@ -256,7 +256,8 @@ private: | |||
| class WizardComp : public Component, | |||
| private ButtonListener, | |||
| private ComboBoxListener, | |||
| private TextEditorListener | |||
| private TextEditorListener, | |||
| private FileBrowserListener | |||
| { | |||
| public: | |||
| WizardComp() | |||
| @@ -264,7 +265,9 @@ public: | |||
| projectName (TRANS("Project name")), | |||
| nameLabel (String::empty, TRANS("Project Name") + ":"), | |||
| typeLabel (String::empty, TRANS("Project Type") + ":"), | |||
| fileBrowser (FileBrowserComponent::saveMode | FileBrowserComponent::canSelectDirectories, | |||
| fileBrowser (FileBrowserComponent::saveMode | |||
| | FileBrowserComponent::canSelectDirectories | |||
| | FileBrowserComponent::doNotClearFileNameOnRootChange, | |||
| NewProjectWizardClasses::getLastWizardFolder(), nullptr, nullptr), | |||
| fileOutline (String::empty, TRANS("Project Folder") + ":"), | |||
| targetsOutline (String::empty, TRANS("Target Platforms") + ":"), | |||
| @@ -303,6 +306,8 @@ public: | |||
| addChildAndSetID (&fileBrowser, "fileBrowser"); | |||
| fileBrowser.setBounds ("fileOutline.left + 10, fileOutline.top + 20, fileOutline.right - 10, fileOutline.bottom - 32"); | |||
| fileBrowser.setFilenameBoxLabel ("Folder:"); | |||
| fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); | |||
| fileBrowser.addListener (this); | |||
| addChildAndSetID (&createButton, "createButton"); | |||
| createButton.setBounds ("right - 130, bottom - 34, parent.width - 30, parent.height - 30"); | |||
| @@ -409,6 +414,16 @@ public: | |||
| fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); | |||
| } | |||
| void selectionChanged() override {} | |||
| void fileClicked (const File&, const MouseEvent&) override {} | |||
| void fileDoubleClicked (const File&) override {} | |||
| void browserRootChanged (const File&) override | |||
| { | |||
| fileBrowser.setFileName (File::createLegalFileName (projectName.getText())); | |||
| } | |||
| ComboBox projectType; | |||
| PlatformTargetsComp platformTargets; | |||
| @@ -318,6 +318,8 @@ namespace | |||
| static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) noexcept | |||
| { | |||
| ignoreUnused (e); | |||
| if (increment < 0) | |||
| { | |||
| ev.xbutton.button = Button5; | |||
| @@ -1633,7 +1635,7 @@ public: | |||
| void* data = nullptr; | |||
| const size_t bytes = (size_t) dispatch (effGetChunk, isPreset ? 1 : 0, 0, &data, 0.0f); | |||
| if (data != nullptr && bytes <= maxSizeMB * 1024 * 1024) | |||
| if (data != nullptr && bytes <= (size_t) maxSizeMB * 1024 * 1024) | |||
| { | |||
| mb.setSize (bytes); | |||
| mb.copyFrom (data, 0, bytes); | |||
| @@ -584,7 +584,7 @@ public: | |||
| }; | |||
| //============================================================================== | |||
| static NPIdentifier getIdentifierFromString (const var::identifier& s) noexcept | |||
| static NPIdentifier getIdentifierFromString (const Identifier& s) noexcept | |||
| { | |||
| return browser.getstringidentifier (s.toString().toUTF8()); | |||
| } | |||
| @@ -601,6 +601,7 @@ class DynamicObjectWrappingNPObject : public DynamicObject | |||
| { | |||
| NPP npp; | |||
| NPObject* const source; | |||
| mutable var returnValue; | |||
| public: | |||
| DynamicObjectWrappingNPObject (NPP npp_, NPObject* const source_) | |||
| @@ -616,17 +617,20 @@ public: | |||
| DBG ("num NP wrapper objs: " + String (--numDOWNP)); | |||
| } | |||
| var getProperty (const var::identifier& propertyName) const override | |||
| const var& getProperty (const Identifier& propertyName) const override | |||
| { | |||
| NPVariant result; | |||
| VOID_TO_NPVARIANT (result); | |||
| browser.getproperty (npp, source, getIdentifierFromString (propertyName), &result); | |||
| const var v (createValueFromNPVariant (npp, result)); | |||
| // NB: this is just a workaorund for the return type being a reference - not too bothered | |||
| // about threading implications of this since this code will all soon be deprecated anyway. | |||
| returnValue = createValueFromNPVariant (npp, result); | |||
| browser.releasevariantvalue (&result); | |||
| return v; | |||
| return returnValue; | |||
| } | |||
| bool hasProperty (const var::identifier& propertyName) const override | |||
| bool hasProperty (const Identifier& propertyName) const override | |||
| { | |||
| NPVariant result; | |||
| VOID_TO_NPVARIANT (result); | |||
| @@ -635,7 +639,7 @@ public: | |||
| return hasProp; | |||
| } | |||
| void setProperty (const var::identifier& propertyName, const var& newValue) override | |||
| void setProperty (const Identifier& propertyName, const var& newValue) override | |||
| { | |||
| NPVariant value; | |||
| createNPVariantFromValue (npp, value, newValue); | |||
| @@ -644,12 +648,12 @@ public: | |||
| browser.releasevariantvalue (&value); | |||
| } | |||
| void removeProperty (const var::identifier& propertyName) override | |||
| void removeProperty (const Identifier& propertyName) override | |||
| { | |||
| browser.removeproperty (npp, source, getIdentifierFromString (propertyName)); | |||
| } | |||
| bool hasMethod (const var::identifier& methodName) const override | |||
| bool hasMethod (const Identifier& methodName) const override | |||
| { | |||
| return browser.hasmethod (npp, source, getIdentifierFromString (methodName)); | |||
| } | |||
| @@ -721,7 +725,7 @@ private: | |||
| bool invoke (NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* out) | |||
| { | |||
| DynamicObject* const o = object.getDynamicObject(); | |||
| const var::identifier methodName (identifierToString (name)); | |||
| const Identifier methodName (identifierToString (name)); | |||
| if (o == nullptr || ! o->hasMethod (methodName)) | |||
| return false; | |||
| @@ -761,7 +765,7 @@ private: | |||
| bool getProperty (NPIdentifier name, NPVariant* out) | |||
| { | |||
| DynamicObject* const o = object.getDynamicObject(); | |||
| const var::identifier propName (identifierToString (name)); | |||
| const Identifier propName (identifierToString (name)); | |||
| if (o == nullptr || ! o->hasProperty (propName)) | |||
| return false; | |||
| @@ -788,7 +792,7 @@ private: | |||
| bool removeProperty (NPIdentifier name) | |||
| { | |||
| DynamicObject* const o = object.getDynamicObject(); | |||
| const var::identifier propName (identifierToString (name)); | |||
| const Identifier propName (identifierToString (name)); | |||
| if (o == nullptr || ! o->hasProperty (propName)) | |||
| return false; | |||
| @@ -806,10 +810,10 @@ private: | |||
| NPP npp; | |||
| var object; | |||
| static var::identifier identifierToString (NPIdentifier id) | |||
| static Identifier identifierToString (NPIdentifier id) | |||
| { | |||
| NPUTF8* const name = browser.utf8fromidentifier (id); | |||
| const var::identifier result ((const char*) name); | |||
| const Identifier result ((const char*) name); | |||
| browser.memfree (name); | |||
| return result; | |||
| } | |||
| @@ -29,7 +29,7 @@ | |||
| struct NamedValueSet::NamedValue | |||
| { | |||
| NamedValue() noexcept {} | |||
| NamedValue (Identifier n, const var& v) : name (n), value (v) {} | |||
| NamedValue (const Identifier& n, const var& v) : name (n), value (v) {} | |||
| NamedValue (const NamedValue& other) : name (other.name), value (other.value) {} | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| @@ -39,7 +39,9 @@ struct NamedValueSet::NamedValue | |||
| { | |||
| } | |||
| NamedValue (Identifier n, var&& v) : name (n), value (static_cast<var&&> (v)) | |||
| NamedValue (Identifier&& n, var&& v) | |||
| : name (static_cast<Identifier&&> (n)), | |||
| value (static_cast<var&&> (v)) | |||
| { | |||
| } | |||
| @@ -138,7 +140,7 @@ var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept | |||
| } | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| bool NamedValueSet::set (Identifier name, var&& newValue) | |||
| bool NamedValueSet::set (const Identifier& name, var&& newValue) | |||
| { | |||
| if (var* const v = getVarPointer (name)) | |||
| { | |||
| @@ -154,7 +156,7 @@ bool NamedValueSet::set (Identifier name, var&& newValue) | |||
| } | |||
| #endif | |||
| bool NamedValueSet::set (Identifier name, const var& newValue) | |||
| bool NamedValueSet::set (const Identifier& name, const var& newValue) | |||
| { | |||
| if (var* const v = getVarPointer (name)) | |||
| { | |||
| @@ -78,14 +78,14 @@ public: | |||
| @returns true if a value was changed or added; false if the | |||
| value was already set the value passed-in. | |||
| */ | |||
| bool set (Identifier name, const var& newValue); | |||
| bool set (const Identifier& name, const var& newValue); | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| /** Changes or adds a named value. | |||
| @returns true if a value was changed or added; false if the | |||
| value was already set the value passed-in. | |||
| */ | |||
| bool set (Identifier name, var&& newValue); | |||
| bool set (const Identifier& name, var&& newValue); | |||
| #endif | |||
| /** Returns true if the set contains an item with the specified name. */ | |||
| @@ -576,7 +576,7 @@ var var::clone() const noexcept | |||
| } | |||
| //============================================================================== | |||
| const var& var::operator[] (Identifier propertyName) const | |||
| const var& var::operator[] (const Identifier& propertyName) const | |||
| { | |||
| if (DynamicObject* const o = getDynamicObject()) | |||
| return o->getProperty (propertyName); | |||
| @@ -589,7 +589,7 @@ const var& var::operator[] (const char* const propertyName) const | |||
| return operator[] (Identifier (propertyName)); | |||
| } | |||
| var var::getProperty (const Identifier propertyName, const var& defaultReturnValue) const | |||
| var var::getProperty (const Identifier& propertyName, const var& defaultReturnValue) const | |||
| { | |||
| if (DynamicObject* const o = getDynamicObject()) | |||
| return o->getProperties().getWithDefault (propertyName, defaultReturnValue); | |||
| @@ -602,7 +602,7 @@ var::NativeFunction var::getNativeFunction() const | |||
| return isMethod() ? value.methodValue : nullptr; | |||
| } | |||
| var var::invoke (Identifier method, const var* arguments, int numArguments) const | |||
| var var::invoke (const Identifier& method, const var* arguments, int numArguments) const | |||
| { | |||
| if (DynamicObject* const o = getDynamicObject()) | |||
| return o->invokeMethod (method, var::NativeFunctionArgs (*this, arguments, numArguments)); | |||
| @@ -610,35 +610,35 @@ var var::invoke (Identifier method, const var* arguments, int numArguments) cons | |||
| return var(); | |||
| } | |||
| var var::call (const Identifier method) const | |||
| var var::call (const Identifier& method) const | |||
| { | |||
| return invoke (method, nullptr, 0); | |||
| } | |||
| var var::call (const Identifier method, const var& arg1) const | |||
| var var::call (const Identifier& method, const var& arg1) const | |||
| { | |||
| return invoke (method, &arg1, 1); | |||
| } | |||
| var var::call (const Identifier method, const var& arg1, const var& arg2) const | |||
| var var::call (const Identifier& method, const var& arg1, const var& arg2) const | |||
| { | |||
| var args[] = { arg1, arg2 }; | |||
| return invoke (method, args, 2); | |||
| } | |||
| var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3) | |||
| var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3) | |||
| { | |||
| var args[] = { arg1, arg2, arg3 }; | |||
| return invoke (method, args, 3); | |||
| } | |||
| var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const | |||
| var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const | |||
| { | |||
| var args[] = { arg1, arg2, arg3, arg4 }; | |||
| return invoke (method, args, 4); | |||
| } | |||
| var var::call (const Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const | |||
| var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const | |||
| { | |||
| var args[] = { arg1, arg2, arg3, arg4, arg5 }; | |||
| return invoke (method, args, 5); | |||
| @@ -62,7 +62,6 @@ public: | |||
| }; | |||
| typedef var (*NativeFunction) (const NativeFunctionArgs&); | |||
| typedef Identifier identifier; | |||
| //============================================================================== | |||
| /** Creates a void variant. */ | |||
| @@ -242,27 +241,27 @@ public: | |||
| //============================================================================== | |||
| /** If this variant is an object, this returns one of its properties. */ | |||
| const var& operator[] (Identifier propertyName) const; | |||
| const var& operator[] (const Identifier& propertyName) const; | |||
| /** If this variant is an object, this returns one of its properties. */ | |||
| const var& operator[] (const char* propertyName) const; | |||
| /** If this variant is an object, this returns one of its properties, or a default | |||
| fallback value if the property is not set. */ | |||
| var getProperty (Identifier propertyName, const var& defaultReturnValue) const; | |||
| var getProperty (const Identifier& propertyName, const var& defaultReturnValue) const; | |||
| /** Invokes a named method call with no arguments. */ | |||
| var call (Identifier method) const; | |||
| var call (const Identifier& method) const; | |||
| /** Invokes a named method call with one argument. */ | |||
| var call (Identifier method, const var& arg1) const; | |||
| var call (const Identifier& method, const var& arg1) const; | |||
| /** Invokes a named method call with 2 arguments. */ | |||
| var call (Identifier method, const var& arg1, const var& arg2) const; | |||
| var call (const Identifier& method, const var& arg1, const var& arg2) const; | |||
| /** Invokes a named method call with 3 arguments. */ | |||
| var call (Identifier method, const var& arg1, const var& arg2, const var& arg3); | |||
| var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3); | |||
| /** Invokes a named method call with 4 arguments. */ | |||
| var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; | |||
| var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; | |||
| /** Invokes a named method call with 5 arguments. */ | |||
| var call (Identifier method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; | |||
| var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; | |||
| /** Invokes a named method call with a list of arguments. */ | |||
| var invoke (Identifier method, const var* arguments, int numArguments) const; | |||
| var invoke (const Identifier& method, const var* arguments, int numArguments) const; | |||
| /** If this object is a method, this returns the function pointer. */ | |||
| NativeFunction getNativeFunction() const; | |||
| @@ -102,7 +102,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| static bool isNumericOrUndefined (const var& v) { return v.isInt() || v.isDouble() || v.isInt64() || v.isBool() || v.isUndefined(); } | |||
| static int64 getOctalValue (const String& s) { BigInteger b; b.parseString (s, 8); return b.toInt64(); } | |||
| static Identifier getPrototypeIdentifier() { static const Identifier i ("prototype"); return i; } | |||
| static var* getPropertyPointer (DynamicObject* o, Identifier i) { return o->getProperties().getVarPointer (i); } | |||
| static var* getPropertyPointer (DynamicObject* o, const Identifier& i) { return o->getProperties().getVarPointer (i); } | |||
| //============================================================================== | |||
| struct CodeLocation | |||
| @@ -136,7 +136,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| ReferenceCountedObjectPtr<RootObject> root; | |||
| DynamicObject::Ptr scope; | |||
| var findFunctionCall (const CodeLocation& location, const var& targetObject, Identifier functionName) const | |||
| var findFunctionCall (const CodeLocation& location, const var& targetObject, const Identifier& functionName) const | |||
| { | |||
| if (DynamicObject* o = targetObject.getDynamicObject()) | |||
| { | |||
| @@ -170,7 +170,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| return var(); | |||
| } | |||
| var* findRootClassProperty (Identifier className, Identifier propName) const | |||
| var* findRootClassProperty (const Identifier& className, const Identifier& propName) const | |||
| { | |||
| if (DynamicObject* cls = root->getProperty (className).getDynamicObject()) | |||
| return getPropertyPointer (cls, propName); | |||
| @@ -178,7 +178,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| return nullptr; | |||
| } | |||
| var findSymbolInParentScopes (Identifier name) const | |||
| var findSymbolInParentScopes (const Identifier& name) const | |||
| { | |||
| if (const var* v = getPropertyPointer (scope, name)) | |||
| return *v; | |||
| @@ -187,7 +187,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| : var::undefined(); | |||
| } | |||
| bool findAndInvokeMethod (Identifier function, const var::NativeFunctionArgs& args, var& result) const | |||
| bool findAndInvokeMethod (const Identifier& function, const var::NativeFunctionArgs& args, var& result) const | |||
| { | |||
| DynamicObject* target = args.thisObject.getDynamicObject(); | |||
| @@ -352,7 +352,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| struct UnqualifiedName : public Expression | |||
| { | |||
| UnqualifiedName (const CodeLocation& l, Identifier n) noexcept : Expression (l), name (n) {} | |||
| UnqualifiedName (const CodeLocation& l, const Identifier& n) noexcept : Expression (l), name (n) {} | |||
| var getResult (const Scope& s) const override { return s.findSymbolInParentScopes (name); } | |||
| @@ -369,7 +369,7 @@ struct JavascriptEngine::RootObject : public DynamicObject | |||
| struct DotOperator : public Expression | |||
| { | |||
| DotOperator (const CodeLocation& l, ExpPtr& p, Identifier c) noexcept : Expression (l), parent (p), child (c) {} | |||
| DotOperator (const CodeLocation& l, ExpPtr& p, const Identifier& c) noexcept : Expression (l), parent (p), child (c) {} | |||
| var getResult (const Scope& s) const override | |||
| { | |||
| @@ -1670,7 +1670,7 @@ JavascriptEngine::~JavascriptEngine() {} | |||
| void JavascriptEngine::prepareTimeout() const noexcept { root->timeout = Time::getCurrentTime() + maximumExecutionTime; } | |||
| void JavascriptEngine::registerNativeObject (Identifier name, DynamicObject* object) | |||
| void JavascriptEngine::registerNativeObject (const Identifier& name, DynamicObject* object) | |||
| { | |||
| root->setProperty (name, object); | |||
| } | |||
| @@ -1706,7 +1706,7 @@ var JavascriptEngine::evaluate (const String& code, Result* result) | |||
| return var::undefined(); | |||
| } | |||
| var JavascriptEngine::callFunction (Identifier function, const var::NativeFunctionArgs& args, Result* result) | |||
| var JavascriptEngine::callFunction (const Identifier& function, const var::NativeFunctionArgs& args, Result* result) | |||
| { | |||
| var returnVal (var::undefined()); | |||
| @@ -78,7 +78,7 @@ public: | |||
| The function arguments are passed in the same format as used by native | |||
| methods in the var class. | |||
| */ | |||
| var callFunction (Identifier function, | |||
| var callFunction (const Identifier& function, | |||
| const var::NativeFunctionArgs& args, | |||
| Result* errorMessage = nullptr); | |||
| @@ -87,7 +87,7 @@ public: | |||
| engine until the engine is deleted. The name must be a simple JS identifier, | |||
| without any dots. | |||
| */ | |||
| void registerNativeObject (Identifier objectName, DynamicObject* object); | |||
| void registerNativeObject (const Identifier& objectName, DynamicObject* object); | |||
| /** This value indicates how long a call to one of the evaluate methods is permitted | |||
| to run before timing-out and failing. | |||
| @@ -248,6 +248,9 @@ public: | |||
| /** Attempts to open a stream that can read from this URL. | |||
| Note that on some platforms (Android, for example) it's not permitted to do any network | |||
| action from the message thread, so you must only call it from a background thread. | |||
| @param usePostCommand if true, it will try to do use a http 'POST' to pass | |||
| the parameters, otherwise it'll encode them into the | |||
| URL and do a 'GET'. | |||
| @@ -287,6 +290,9 @@ public: | |||
| If it succeeds, this will return true and append the data it read onto the end | |||
| of the memory block. | |||
| Note that on some platforms (Android, for example) it's not permitted to do any network | |||
| action from the message thread, so you must only call it from a background thread. | |||
| @param destData the memory block to append the new data to | |||
| @param usePostCommand whether to use a POST command to get the data (uses | |||
| a GET command if this is false) | |||
| @@ -302,6 +308,9 @@ public: | |||
| operation that fails and one that returns an empty string, you'll need to use | |||
| a different method, such as readEntireBinaryStream(). | |||
| Note that on some platforms (Android, for example) it's not permitted to do any network | |||
| action from the message thread, so you must only call it from a background thread. | |||
| @param usePostCommand whether to use a POST command to get the data (uses | |||
| a GET command if this is false) | |||
| @see readEntireBinaryStream, readEntireXmlStream | |||
| @@ -316,6 +325,9 @@ public: | |||
| When it returns a valid XmlElement object, the caller is responsibile for deleting | |||
| this object when no longer needed. | |||
| Note that on some platforms (Android, for example) it's not permitted to do any network | |||
| action from the message thread, so you must only call it from a background thread. | |||
| @param usePostCommand whether to use a POST command to get the data (uses | |||
| a GET command if this is false) | |||
| @@ -31,7 +31,17 @@ Identifier::~Identifier() noexcept {} | |||
| Identifier::Identifier (const Identifier& other) noexcept : name (other.name) {} | |||
| Identifier& Identifier::operator= (const Identifier other) noexcept | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| Identifier::Identifier (Identifier&& other) noexcept : name (static_cast<String&&> (other.name)) {} | |||
| Identifier& Identifier::operator= (Identifier&& other) noexcept | |||
| { | |||
| name = static_cast<String&&> (other.name); | |||
| return *this; | |||
| } | |||
| #endif | |||
| Identifier& Identifier::operator= (const Identifier& other) noexcept | |||
| { | |||
| name = other.name; | |||
| return *this; | |||
| @@ -68,16 +68,24 @@ public: | |||
| Identifier (const Identifier& other) noexcept; | |||
| /** Creates a copy of another identifier. */ | |||
| Identifier& operator= (const Identifier other) noexcept; | |||
| Identifier& operator= (const Identifier& other) noexcept; | |||
| #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
| /** Creates a copy of another identifier. */ | |||
| Identifier (Identifier&& other) noexcept; | |||
| /** Creates a copy of another identifier. */ | |||
| Identifier& operator= (Identifier&& other) noexcept; | |||
| #endif | |||
| /** Destructor */ | |||
| ~Identifier() noexcept; | |||
| /** Compares two identifiers. This is a very fast operation. */ | |||
| inline bool operator== (Identifier other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); } | |||
| inline bool operator== (const Identifier& other) const noexcept { return name.getCharPointer() == other.name.getCharPointer(); } | |||
| /** Compares two identifiers. This is a very fast operation. */ | |||
| inline bool operator!= (Identifier other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); } | |||
| inline bool operator!= (const Identifier& other) const noexcept { return name.getCharPointer() != other.name.getCharPointer(); } | |||
| /** Compares the identifier with a string. */ | |||
| inline bool operator== (StringRef other) const noexcept { return name == other; } | |||
| @@ -27,7 +27,7 @@ class ValueTree::SharedObject : public ReferenceCountedObject | |||
| public: | |||
| typedef ReferenceCountedObjectPtr<SharedObject> Ptr; | |||
| explicit SharedObject (Identifier t) noexcept | |||
| explicit SharedObject (const Identifier& t) noexcept | |||
| : type (t), parent (nullptr) | |||
| { | |||
| } | |||
| @@ -126,7 +126,7 @@ public: | |||
| } | |||
| } | |||
| void sendPropertyChangeMessage (const Identifier property) | |||
| void sendPropertyChangeMessage (const Identifier& property) | |||
| { | |||
| ValueTree tree (this); | |||
| @@ -169,7 +169,7 @@ public: | |||
| callListeners (&ValueTree::Listener::valueTreeParentChanged, tree); | |||
| } | |||
| void setProperty (const Identifier name, const var& newValue, UndoManager* const undoManager) | |||
| void setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager) | |||
| { | |||
| if (undoManager == nullptr) | |||
| { | |||
| @@ -190,12 +190,12 @@ public: | |||
| } | |||
| } | |||
| bool hasProperty (const Identifier name) const noexcept | |||
| bool hasProperty (const Identifier& name) const noexcept | |||
| { | |||
| return properties.contains (name); | |||
| } | |||
| void removeProperty (const Identifier name, UndoManager* const undoManager) | |||
| void removeProperty (const Identifier& name, UndoManager* const undoManager) | |||
| { | |||
| if (undoManager == nullptr) | |||
| { | |||
| @@ -238,7 +238,7 @@ public: | |||
| setProperty (source.properties.getName(i), source.properties.getValueAt(i), undoManager); | |||
| } | |||
| ValueTree getChildWithName (const Identifier typeToMatch) const | |||
| ValueTree getChildWithName (const Identifier& typeToMatch) const | |||
| { | |||
| for (int i = 0; i < children.size(); ++i) | |||
| { | |||
| @@ -250,7 +250,7 @@ public: | |||
| return ValueTree(); | |||
| } | |||
| ValueTree getOrCreateChildWithName (const Identifier typeToMatch, UndoManager* undoManager) | |||
| ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager) | |||
| { | |||
| for (int i = 0; i < children.size(); ++i) | |||
| { | |||
| @@ -265,7 +265,7 @@ public: | |||
| } | |||
| ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const | |||
| ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const | |||
| { | |||
| for (int i = 0; i < children.size(); ++i) | |||
| { | |||
| @@ -458,7 +458,7 @@ public: | |||
| class SetPropertyAction : public UndoableAction | |||
| { | |||
| public: | |||
| SetPropertyAction (SharedObject* const so, const Identifier propertyName, | |||
| SetPropertyAction (SharedObject* const so, const Identifier& propertyName, | |||
| const var& newVal, const var& oldVal, bool isAdding, bool isDeleting) | |||
| : target (so), name (propertyName), newValue (newVal), oldValue (oldVal), | |||
| isAddingNewProperty (isAdding), isDeletingProperty (isDeleting) | |||
| @@ -629,7 +629,7 @@ ValueTree::ValueTree() noexcept | |||
| const ValueTree ValueTree::invalid; | |||
| ValueTree::ValueTree (Identifier type) : object (new ValueTree::SharedObject (type)) | |||
| ValueTree::ValueTree (const Identifier& type) : object (new ValueTree::SharedObject (type)) | |||
| { | |||
| jassert (type.toString().isNotEmpty()); // All objects must be given a sensible type name! | |||
| } | |||
| @@ -702,7 +702,7 @@ ValueTree ValueTree::createCopy() const | |||
| return ValueTree (createCopyIfNotNull (object.get())); | |||
| } | |||
| bool ValueTree::hasType (const Identifier typeName) const | |||
| bool ValueTree::hasType (const Identifier& typeName) const | |||
| { | |||
| return object != nullptr && object->type == typeName; | |||
| } | |||
| @@ -727,24 +727,23 @@ ValueTree ValueTree::getSibling (const int delta) const | |||
| return ValueTree (object->parent->children.getObjectPointer (index)); | |||
| } | |||
| const var& ValueTree::operator[] (const Identifier name) const | |||
| const var& ValueTree::operator[] (const Identifier& name) const | |||
| { | |||
| return object == nullptr ? var::null : object->properties[name]; | |||
| } | |||
| const var& ValueTree::getProperty (const Identifier name) const | |||
| const var& ValueTree::getProperty (const Identifier& name) const | |||
| { | |||
| return object == nullptr ? var::null : object->properties[name]; | |||
| } | |||
| var ValueTree::getProperty (const Identifier name, const var& defaultReturnValue) const | |||
| var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const | |||
| { | |||
| return object == nullptr ? defaultReturnValue | |||
| : object->properties.getWithDefault (name, defaultReturnValue); | |||
| } | |||
| ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue, | |||
| UndoManager* const undoManager) | |||
| ValueTree& ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager) | |||
| { | |||
| jassert (name.toString().isNotEmpty()); // Must have a valid property name! | |||
| jassert (object != nullptr); // Trying to add a property to a null ValueTree will fail! | |||
| @@ -755,12 +754,12 @@ ValueTree& ValueTree::setProperty (const Identifier name, const var& newValue, | |||
| return *this; | |||
| } | |||
| bool ValueTree::hasProperty (const Identifier name) const | |||
| bool ValueTree::hasProperty (const Identifier& name) const | |||
| { | |||
| return object != nullptr && object->hasProperty (name); | |||
| } | |||
| void ValueTree::removeProperty (const Identifier name, UndoManager* const undoManager) | |||
| void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager) | |||
| { | |||
| if (object != nullptr) | |||
| object->removeProperty (name, undoManager); | |||
| @@ -803,7 +802,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource, | |||
| private ValueTree::Listener | |||
| { | |||
| public: | |||
| ValueTreePropertyValueSource (const ValueTree& vt, const Identifier prop, UndoManager* um) | |||
| ValueTreePropertyValueSource (const ValueTree& vt, const Identifier& prop, UndoManager* um) | |||
| : tree (vt), property (prop), undoManager (um) | |||
| { | |||
| tree.addListener (this); | |||
| @@ -836,7 +835,7 @@ private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource) | |||
| }; | |||
| Value ValueTree::getPropertyAsValue (const Identifier name, UndoManager* const undoManager) | |||
| Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager) | |||
| { | |||
| return Value (new ValueTreePropertyValueSource (*this, name, undoManager)); | |||
| } | |||
| @@ -853,17 +852,17 @@ ValueTree ValueTree::getChild (int index) const | |||
| : static_cast<SharedObject*> (nullptr)); | |||
| } | |||
| ValueTree ValueTree::getChildWithName (const Identifier type) const | |||
| ValueTree ValueTree::getChildWithName (const Identifier& type) const | |||
| { | |||
| return object != nullptr ? object->getChildWithName (type) : ValueTree(); | |||
| } | |||
| ValueTree ValueTree::getOrCreateChildWithName (const Identifier type, UndoManager* undoManager) | |||
| ValueTree ValueTree::getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager) | |||
| { | |||
| return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree(); | |||
| } | |||
| ValueTree ValueTree::getChildWithProperty (const Identifier propertyName, const var& propertyValue) const | |||
| ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const | |||
| { | |||
| return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree(); | |||
| } | |||
| @@ -945,7 +944,7 @@ void ValueTree::removeListener (Listener* listener) | |||
| object->valueTreesWithListeners.removeValue (this); | |||
| } | |||
| void ValueTree::sendPropertyChangeMessage (const Identifier property) | |||
| void ValueTree::sendPropertyChangeMessage (const Identifier& property) | |||
| { | |||
| if (object != nullptr) | |||
| object->sendPropertyChangeMessage (property); | |||
| @@ -79,7 +79,7 @@ public: | |||
| Like an XmlElement, each ValueTree node has a type, which you can access with | |||
| getType() and hasType(). | |||
| */ | |||
| explicit ValueTree (Identifier type); | |||
| explicit ValueTree (const Identifier& type); | |||
| /** Creates a reference to another ValueTree. */ | |||
| ValueTree (const ValueTree&); | |||
| @@ -134,7 +134,7 @@ public: | |||
| /** Returns true if the node has this type. | |||
| The comparison is case-sensitive. | |||
| */ | |||
| bool hasType (const Identifier typeName) const; | |||
| bool hasType (const Identifier& typeName) const; | |||
| //============================================================================== | |||
| /** Returns the value of a named property. | |||
| @@ -142,21 +142,21 @@ public: | |||
| You can also use operator[] to get a property. | |||
| @see var, setProperty, hasProperty | |||
| */ | |||
| const var& getProperty (const Identifier name) const; | |||
| const var& getProperty (const Identifier& name) const; | |||
| /** Returns the value of a named property, or a user-specified default if the property doesn't exist. | |||
| If no such property has been set, this will return the value of defaultReturnValue. | |||
| You can also use operator[] and getProperty to get a property. | |||
| @see var, getProperty, setProperty, hasProperty | |||
| */ | |||
| var getProperty (const Identifier name, const var& defaultReturnValue) const; | |||
| var getProperty (const Identifier& name, const var& defaultReturnValue) const; | |||
| /** Returns the value of a named property. | |||
| If no such property has been set, this will return a void variant. This is the same as | |||
| calling getProperty(). | |||
| @see getProperty | |||
| */ | |||
| const var& operator[] (const Identifier name) const; | |||
| const var& operator[] (const Identifier& name) const; | |||
| /** Changes a named property of the node. | |||
| The name identifier must not be an empty string. | |||
| @@ -165,16 +165,16 @@ public: | |||
| @see var, getProperty, removeProperty | |||
| @returns a reference to the value tree, so that you can daisy-chain calls to this method. | |||
| */ | |||
| ValueTree& setProperty (const Identifier name, const var& newValue, UndoManager* undoManager); | |||
| ValueTree& setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager); | |||
| /** Returns true if the node contains a named property. */ | |||
| bool hasProperty (const Identifier name) const; | |||
| bool hasProperty (const Identifier& name) const; | |||
| /** Removes a property from the node. | |||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | |||
| so that this change can be undone. | |||
| */ | |||
| void removeProperty (const Identifier name, UndoManager* undoManager); | |||
| void removeProperty (const Identifier& name, UndoManager* undoManager); | |||
| /** Removes all properties from the node. | |||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | |||
| @@ -198,7 +198,7 @@ public: | |||
| it needs to change the value. Attaching a Value::Listener to the value object will provide | |||
| callbacks whenever the property changes. | |||
| */ | |||
| Value getPropertyAsValue (const Identifier name, UndoManager* undoManager); | |||
| Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager); | |||
| /** Overwrites all the properties in this tree with the properties of the source tree. | |||
| Any properties that already exist will be updated; and new ones will be added, and | |||
| @@ -223,7 +223,7 @@ public: | |||
| whether a node is valid). | |||
| @see getOrCreateChildWithName | |||
| */ | |||
| ValueTree getChildWithName (const Identifier type) const; | |||
| ValueTree getChildWithName (const Identifier& type) const; | |||
| /** Returns the first child node with the speficied type name, creating and adding | |||
| a child with this name if there wasn't already one there. | |||
| @@ -232,7 +232,7 @@ public: | |||
| the method on is itself invalid. | |||
| @see getChildWithName | |||
| */ | |||
| ValueTree getOrCreateChildWithName (const Identifier type, UndoManager* undoManager); | |||
| ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager); | |||
| /** Looks for the first child node that has the speficied property value. | |||
| @@ -242,7 +242,7 @@ public: | |||
| If no such node is found, it'll return an invalid node. (See isValid() to find out | |||
| whether a node is valid). | |||
| */ | |||
| ValueTree getChildWithProperty (const Identifier propertyName, const var& propertyValue) const; | |||
| ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const; | |||
| /** Adds a child to this node. | |||
| @@ -453,7 +453,7 @@ public: | |||
| /** Causes a property-change callback to be triggered for the specified property, | |||
| calling any listeners that are registered. | |||
| */ | |||
| void sendPropertyChangeMessage (const Identifier property); | |||
| void sendPropertyChangeMessage (const Identifier& property); | |||
| //============================================================================== | |||
| /** This method uses a comparator object to sort the tree's children into order. | |||
| @@ -387,7 +387,7 @@ void FileBrowserComponent::fileDoubleClicked (const File& f) | |||
| { | |||
| setRoot (f); | |||
| if ((flags & canSelectDirectories) != 0) | |||
| if ((flags & canSelectDirectories) != 0 && (flags & doNotClearFileNameOnRootChange) == 0) | |||
| filenameBox.setText (String::empty); | |||
| } | |||
| else | |||
| @@ -432,7 +432,9 @@ void FileBrowserComponent::textEditorReturnKeyPressed (TextEditor&) | |||
| { | |||
| setRoot (f); | |||
| chosenFiles.clear(); | |||
| filenameBox.setText (String::empty); | |||
| if ((flags & doNotClearFileNameOnRootChange) == 0) | |||
| filenameBox.setText (String()); | |||
| } | |||
| else | |||
| { | |||
| @@ -51,18 +51,19 @@ public: | |||
| */ | |||
| enum FileChooserFlags | |||
| { | |||
| openMode = 1, /**< specifies that the component should allow the user to | |||
| choose an existing file with the intention of opening it. */ | |||
| saveMode = 2, /**< specifies that the component should allow the user to specify | |||
| the name of a file that will be used to save something. */ | |||
| canSelectFiles = 4, /**< specifies that the user can select files (can be used in | |||
| conjunction with canSelectDirectories). */ | |||
| canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in | |||
| conjuction with canSelectFiles). */ | |||
| canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */ | |||
| useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */ | |||
| filenameBoxIsReadOnly = 64, /**< specifies that the user can't type directly into the filename box. */ | |||
| warnAboutOverwriting = 128 /**< specifies that the dialog should warn about overwriting existing files (if possible). */ | |||
| openMode = 1, /**< specifies that the component should allow the user to | |||
| choose an existing file with the intention of opening it. */ | |||
| saveMode = 2, /**< specifies that the component should allow the user to specify | |||
| the name of a file that will be used to save something. */ | |||
| canSelectFiles = 4, /**< specifies that the user can select files (can be used in | |||
| conjunction with canSelectDirectories). */ | |||
| canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in | |||
| conjuction with canSelectFiles). */ | |||
| canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */ | |||
| useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */ | |||
| filenameBoxIsReadOnly = 64, /**< specifies that the user can't type directly into the filename box. */ | |||
| warnAboutOverwriting = 128, /**< specifies that the dialog should warn about overwriting existing files (if possible). */ | |||
| doNotClearFileNameOnRootChange = 256 /**< specifies that the file name should not be cleared upon root change. */ | |||
| }; | |||
| //============================================================================== | |||
| @@ -24,13 +24,13 @@ | |||
| Viewport::Viewport (const String& name) | |||
| : Component (name), | |||
| customScrollBarThickness(false), | |||
| scrollBarThickness (0), | |||
| singleStepX (16), | |||
| singleStepY (16), | |||
| showHScrollbar (true), | |||
| showVScrollbar (true), | |||
| deleteContent (true), | |||
| customScrollBarThickness (false), | |||
| allowScrollingWithoutScrollbarV (false), | |||
| allowScrollingWithoutScrollbarH (false), | |||
| verticalScrollBar (true), | |||
| @@ -55,7 +55,6 @@ Viewport::Viewport (const String& name) | |||
| Viewport::~Viewport() | |||
| { | |||
| deleteContentComp(); | |||
| mouseWheelTimer = nullptr; | |||
| } | |||
| //============================================================================== | |||
| @@ -382,30 +381,6 @@ static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexce | |||
| : jmax (distance, 1.0f)); | |||
| } | |||
| // This puts a temporary component overlay over the content component, to prevent | |||
| // wheel events from reaching components inside it, so that while spinning a wheel | |||
| // with momentum, it won't accidentally scroll any subcomponents of the viewport. | |||
| struct Viewport::MouseWheelTimer : public Timer | |||
| { | |||
| MouseWheelTimer (Viewport& v) : viewport (v) | |||
| { | |||
| viewport.contentHolder.addAndMakeVisible (dummyOverlay); | |||
| dummyOverlay.setAlwaysOnTop (true); | |||
| dummyOverlay.setPaintingIsUnclipped (true); | |||
| dummyOverlay.setBounds (viewport.contentHolder.getLocalBounds()); | |||
| } | |||
| void timerCallback() override | |||
| { | |||
| viewport.mouseWheelTimer = nullptr; | |||
| } | |||
| Component dummyOverlay; | |||
| Viewport& viewport; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseWheelTimer) | |||
| }; | |||
| bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel) | |||
| { | |||
| if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown())) | |||
| @@ -436,11 +411,6 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD | |||
| if (pos != getViewPosition()) | |||
| { | |||
| if (mouseWheelTimer == nullptr) | |||
| mouseWheelTimer = new MouseWheelTimer (*this); | |||
| mouseWheelTimer->startTimer (300); | |||
| setViewPosition (pos); | |||
| return true; | |||
| } | |||
| @@ -263,15 +263,13 @@ private: | |||
| //============================================================================== | |||
| WeakReference<Component> contentComp; | |||
| Rectangle<int> lastVisibleArea; | |||
| bool customScrollBarThickness; | |||
| int scrollBarThickness; | |||
| int singleStepX, singleStepY; | |||
| bool showHScrollbar, showVScrollbar, deleteContent; | |||
| bool customScrollBarThickness; | |||
| bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH; | |||
| Component contentHolder; | |||
| ScrollBar verticalScrollBar, horizontalScrollBar; | |||
| struct MouseWheelTimer; | |||
| ScopedPointer<Timer> mouseWheelTimer; | |||
| Point<int> viewportPosToCompPos (Point<int>) const; | |||
| @@ -354,6 +354,10 @@ struct MouseWheelDetails | |||
| /** If true, then the wheel has continuous, un-stepped motion. */ | |||
| bool isSmooth; | |||
| /** If true, then this event is part of the intertial momentum phase that follows | |||
| the wheel being released. */ | |||
| bool isInertial; | |||
| }; | |||
| @@ -331,10 +331,17 @@ public: | |||
| Time time, const MouseWheelDetails& wheel) | |||
| { | |||
| Desktop::getInstance().incrementMouseWheelCounter(); | |||
| Point<float> screenPos; | |||
| if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos)) | |||
| sendMouseWheel (*current, screenPos, time, wheel); | |||
| // This will make sure that when the wheel spins in its inertial phase, any events | |||
| // continue to be sent to the last component that the mouse was over when it was being | |||
| // actively controlled by the user. This avoids confusion when scrolling through nested | |||
| // scrollable components. | |||
| if (lastNonInertialWheelTarget == nullptr || ! wheel.isInertial) | |||
| lastNonInertialWheelTarget = getTargetForGesture (peer, positionWithinPeer, time, screenPos); | |||
| if (Component* target = lastNonInertialWheelTarget) | |||
| sendMouseWheel (*target, screenPos, time, wheel); | |||
| } | |||
| void handleMagnifyGesture (ComponentPeer& peer, Point<float> positionWithinPeer, | |||
| @@ -467,7 +474,7 @@ public: | |||
| bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | |||
| private: | |||
| WeakReference<Component> componentUnderMouse; | |||
| WeakReference<Component> componentUnderMouse, lastNonInertialWheelTarget; | |||
| ComponentPeer* lastPeer; | |||
| void* currentCursorHandle; | |||
| @@ -512,6 +519,7 @@ private: | |||
| mouseDowns[0].peerID = 0; | |||
| mouseMovedSignificantlySincePressed = false; | |||
| lastNonInertialWheelTarget = nullptr; | |||
| } | |||
| void registerMouseDrag (Point<float> screenPos) noexcept | |||
| @@ -978,9 +978,9 @@ private: | |||
| //============================================================================== | |||
| #if JUCE_USE_XRANDR | |||
| friend class ContainerDeletePolicy<XRRScreenResources>; | |||
| friend class ContainerDeletePolicy<XRROutputInfo>; | |||
| friend class ContainerDeletePolicy<XRRCrtcInfo>; | |||
| friend struct ContainerDeletePolicy<XRRScreenResources>; | |||
| friend struct ContainerDeletePolicy<XRROutputInfo>; | |||
| friend struct ContainerDeletePolicy<XRRCrtcInfo>; | |||
| class XRandrWrapper | |||
| { | |||
| @@ -1062,9 +1062,9 @@ private: | |||
| private: | |||
| //============================================================================== | |||
| friend class ContainerDeletePolicy<XRRScreenResources>; | |||
| friend class ContainerDeletePolicy<XRROutputInfo>; | |||
| friend class ContainerDeletePolicy<XRRCrtcInfo>; | |||
| friend struct ContainerDeletePolicy<XRRScreenResources>; | |||
| friend struct ContainerDeletePolicy<XRROutputInfo>; | |||
| friend struct ContainerDeletePolicy<XRRCrtcInfo>; | |||
| void freeScreenResources (XRRScreenResources* ptr) | |||
| { | |||
| @@ -2209,6 +2209,7 @@ public: | |||
| wheel.deltaY = amount; | |||
| wheel.isReversed = false; | |||
| wheel.isSmooth = false; | |||
| wheel.isInertial = false; | |||
| handleMouseWheel (0, getMousePos (buttonPressEvent), getEventTime (buttonPressEvent), wheel); | |||
| } | |||
| @@ -497,10 +497,7 @@ public: | |||
| void toBehind (ComponentPeer* other) override | |||
| { | |||
| NSViewComponentPeer* const otherPeer = dynamic_cast<NSViewComponentPeer*> (other); | |||
| jassert (otherPeer != nullptr); // wrong type of window? | |||
| if (otherPeer != nullptr) | |||
| if (NSViewComponentPeer* const otherPeer = dynamic_cast<NSViewComponentPeer*> (other)) | |||
| { | |||
| if (isSharedWindow) | |||
| { | |||
| @@ -514,6 +511,10 @@ public: | |||
| relativeTo: [otherPeer->window windowNumber]]; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // wrong type of window? | |||
| } | |||
| } | |||
| void setIcon (const Image&) override | |||
| @@ -620,6 +621,7 @@ public: | |||
| wheel.deltaY = 0; | |||
| wheel.isReversed = false; | |||
| wheel.isSmooth = false; | |||
| wheel.isInertial = false; | |||
| #if ! JUCE_PPC | |||
| @try | |||
| @@ -628,6 +630,8 @@ public: | |||
| if ([ev respondsToSelector: @selector (isDirectionInvertedFromDevice)]) | |||
| wheel.isReversed = [ev isDirectionInvertedFromDevice]; | |||
| wheel.isInertial = ([ev momentumPhase] != NSEventPhaseNone); | |||
| if ([ev respondsToSelector: @selector (hasPreciseScrollingDeltas)]) | |||
| { | |||
| if ([ev hasPreciseScrollingDeltas]) | |||
| @@ -1820,6 +1820,7 @@ private: | |||
| wheel.deltaY = isVertical ? amount / 256.0f : 0.0f; | |||
| wheel.isReversed = false; | |||
| wheel.isSmooth = false; | |||
| wheel.isInertial = false; | |||
| Point<float> localPos; | |||
| if (ComponentPeer* const peer = findPeerUnderMouse (localPos)) | |||
| @@ -32,13 +32,10 @@ class AllComponentRepainter : private Timer, | |||
| private DeletedAtShutdown | |||
| { | |||
| public: | |||
| AllComponentRepainter() {} | |||
| AllComponentRepainter() {} | |||
| ~AllComponentRepainter() { clearSingletonInstance(); } | |||
| static AllComponentRepainter& getInstance() | |||
| { | |||
| static AllComponentRepainter* instance = new AllComponentRepainter(); | |||
| return *instance; | |||
| } | |||
| juce_DeclareSingleton (AllComponentRepainter, false) | |||
| void trigger() | |||
| { | |||
| @@ -57,8 +54,10 @@ private: | |||
| if (Component* c = TopLevelWindow::getTopLevelWindow(i)) | |||
| repaintAndResizeAllComps (c, alreadyDone); | |||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | |||
| if (Component* c = Desktop::getInstance().getComponent(i)) | |||
| Desktop& desktop = Desktop::getInstance(); | |||
| for (int i = desktop.getNumComponents(); --i >= 0;) | |||
| if (Component* c = desktop.getComponent(i)) | |||
| repaintAndResizeAllComps (c, alreadyDone); | |||
| } | |||
| @@ -85,6 +84,9 @@ private: | |||
| } | |||
| }; | |||
| juce_ImplementSingleton (AllComponentRepainter) | |||
| juce_ImplementSingleton (ValueList) | |||
| //============================================================================== | |||
| int64 parseInt (String s) | |||
| { | |||
| @@ -189,7 +191,7 @@ void LivePropertyEditorBase::applyNewValue (const String& s) | |||
| selectOriginalValue(); | |||
| valueEditor.setText (s, dontSendNotification); | |||
| AllComponentRepainter::getInstance().trigger(); | |||
| AllComponentRepainter::getInstance()->trigger(); | |||
| } | |||
| void LivePropertyEditorBase::selectOriginalValue() | |||
| @@ -347,14 +349,8 @@ public: | |||
| }; | |||
| //============================================================================== | |||
| ValueList::ValueList() {} | |||
| ValueList::~ValueList() {} | |||
| ValueList& ValueList::getInstance() | |||
| { | |||
| static ValueList* i = new ValueList(); | |||
| return *i; | |||
| } | |||
| ValueList::ValueList() {} | |||
| ValueList::~ValueList() { clearSingletonInstance(); } | |||
| void ValueList::addValue (LiveValueBase* v) | |||
| { | |||
| @@ -194,7 +194,7 @@ namespace LiveConstantEditor | |||
| ValueList(); | |||
| ~ValueList(); | |||
| static ValueList& getInstance(); | |||
| juce_DeclareSingleton (ValueList, false) | |||
| template <typename Type> | |||
| LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue) | |||
| @@ -233,7 +233,7 @@ namespace LiveConstantEditor | |||
| template <typename Type> | |||
| inline LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue) | |||
| { | |||
| return ValueList::getInstance().getValue (file, line, initialValue); | |||
| return ValueList::getInstance()->getValue (file, line, initialValue); | |||
| } | |||
| inline LiveValue<String>& getValue (const char* file, int line, const char* initialValue) | |||