diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 978c2608dc..3e09722b69 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -93,6 +93,7 @@ OBJECTS := \ $(OBJDIR)/juce_Synthesiser.o \ $(OBJDIR)/juce_BigInteger.o \ $(OBJDIR)/juce_DynamicObject.o \ + $(OBJDIR)/juce_Identifier.o \ $(OBJDIR)/juce_MemoryBlock.o \ $(OBJDIR)/juce_NamedValueSet.o \ $(OBJDIR)/juce_PropertySet.o \ @@ -322,6 +323,7 @@ OBJECTS := \ $(OBJDIR)/juce_String.o \ $(OBJDIR)/juce_StringArray.o \ $(OBJDIR)/juce_StringPairArray.o \ + $(OBJDIR)/juce_StringPool.o \ $(OBJDIR)/juce_XmlDocument.o \ $(OBJDIR)/juce_XmlElement.o \ $(OBJDIR)/juce_ReadWriteLock.o \ @@ -619,6 +621,11 @@ $(OBJDIR)/juce_DynamicObject.o: ../../src/containers/juce_DynamicObject.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_Identifier.o: ../../src/containers/juce_Identifier.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_MemoryBlock.o: ../../src/containers/juce_MemoryBlock.cpp -@mkdir -p $(OBJDIR) @echo $(notdir $<) @@ -1764,6 +1771,11 @@ $(OBJDIR)/juce_StringPairArray.o: ../../src/text/juce_StringPairArray.cpp @echo $(notdir $<) @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" +$(OBJDIR)/juce_StringPool.o: ../../src/text/juce_StringPool.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + $(OBJDIR)/juce_XmlDocument.o: ../../src/text/juce_XmlDocument.cpp -@mkdir -p $(OBJDIR) @echo $(notdir $<) diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj index f9e39456af..728df2c27e 100644 --- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj +++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj @@ -62,6 +62,7 @@ E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; }; BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; }; 4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; }; + 95577AE91AA6CBA7FE9434F3 = { isa = PBXBuildFile; fileRef = 1CF7CC0EB057F995BBBEFC90; }; 21BA256CBCC9C15265928A23 = { isa = PBXBuildFile; fileRef = FF40DA899AE16A5E1D8AA54A; }; 9D2D1BA65C27BDA1F7C44769 = { isa = PBXBuildFile; fileRef = 70E5409425A76782B6188B31; }; 43B3119E2F1B559263AE956C = { isa = PBXBuildFile; fileRef = 9BD379D2F7995BFE0B3E5369; }; @@ -317,6 +318,7 @@ C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; 82568CF438EF4C950E4A42DF = { isa = PBXBuildFile; fileRef = 81B36E7C56DF1A777AA04F71; }; + B2E9D0C534DDE9F96921A054 = { isa = PBXBuildFile; fileRef = 0EC7DE81A516F4130AC59557; }; C8D06AE9C68A675A87DC9C99 = { isa = PBXBuildFile; fileRef = 5715BC14D93D61D71206FCB2; }; FE2999972FE3D6E251DA6653 = { isa = PBXBuildFile; fileRef = 95F21C2733BD5932372E4157; }; 8B2193898D3465B5995EE98A = { isa = PBXBuildFile; fileRef = 8E78623B2D21CFE68DEC0483; }; @@ -457,6 +459,8 @@ 34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; }; 7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; }; F364AA2637B7CB89D3657DFF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_HeapBlock.h; path = ../../src/containers/juce_HeapBlock.h; sourceTree = SOURCE_ROOT; }; + 1CF7CC0EB057F995BBBEFC90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/containers/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; + C16848F86DF014F1CBECE248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/containers/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; FF40DA899AE16A5E1D8AA54A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MemoryBlock.cpp; path = ../../src/containers/juce_MemoryBlock.cpp; sourceTree = SOURCE_ROOT; }; 2E5D896B8DB2B357D7440F60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MemoryBlock.h; path = ../../src/containers/juce_MemoryBlock.h; sourceTree = SOURCE_ROOT; }; 70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; }; @@ -949,6 +953,8 @@ D4FED84C92ADC4B2C41A4275 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringArray.h; path = ../../src/text/juce_StringArray.h; sourceTree = SOURCE_ROOT; }; 81B36E7C56DF1A777AA04F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPairArray.cpp; path = ../../src/text/juce_StringPairArray.cpp; sourceTree = SOURCE_ROOT; }; E5458BE2F33DBBF5AF834BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPairArray.h; path = ../../src/text/juce_StringPairArray.h; sourceTree = SOURCE_ROOT; }; + 0EC7DE81A516F4130AC59557 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPool.cpp; path = ../../src/text/juce_StringPool.cpp; sourceTree = SOURCE_ROOT; }; + C972C24A7D2FC817362E1FD7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPool.h; path = ../../src/text/juce_StringPool.h; sourceTree = SOURCE_ROOT; }; 5715BC14D93D61D71206FCB2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlDocument.cpp; path = ../../src/text/juce_XmlDocument.cpp; sourceTree = SOURCE_ROOT; }; B4575FEE10C67D45C9532540 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_XmlDocument.h; path = ../../src/text/juce_XmlDocument.h; sourceTree = SOURCE_ROOT; }; 95F21C2733BD5932372E4157 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlElement.cpp; path = ../../src/text/juce_XmlElement.cpp; sourceTree = SOURCE_ROOT; }; @@ -1133,6 +1139,8 @@ 34C402EF9ADCAD34FB657D43, 7DA9AC75A4D9227C8FC4B2F7, F364AA2637B7CB89D3657DFF, + 1CF7CC0EB057F995BBBEFC90, + C16848F86DF014F1CBECE248, FF40DA899AE16A5E1D8AA54A, 2E5D896B8DB2B357D7440F60, 70E5409425A76782B6188B31, @@ -1690,6 +1698,8 @@ D4FED84C92ADC4B2C41A4275, 81B36E7C56DF1A777AA04F71, E5458BE2F33DBBF5AF834BB6, + 0EC7DE81A516F4130AC59557, + C972C24A7D2FC817362E1FD7, 5715BC14D93D61D71206FCB2, B4575FEE10C67D45C9532540, 95F21C2733BD5932372E4157, @@ -1874,6 +1884,7 @@ E8DFABC1603D55B97429A8E4, BE25871C34D79FEFFD1B94B6, 4AB5E55BDF79028F82F83D8E, + 95577AE91AA6CBA7FE9434F3, 21BA256CBCC9C15265928A23, 9D2D1BA65C27BDA1F7C44769, 43B3119E2F1B559263AE956C, @@ -2129,6 +2140,7 @@ C8F81E843F446868FAD88197, 50D91A2EC0ABF894E612D936, 82568CF438EF4C950E4A42DF, + B2E9D0C534DDE9F96921A054, C8D06AE9C68A675A87DC9C99, FE2999972FE3D6E251DA6653, 8B2193898D3465B5995EE98A, diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj index 59717b9384..2824c4f33c 100644 --- a/Builds/VisualStudio2005/Juce.vcproj +++ b/Builds/VisualStudio2005/Juce.vcproj @@ -251,6 +251,8 @@ + + @@ -815,6 +817,8 @@ + + diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj index 63f9e9e586..6fdf00727f 100644 --- a/Builds/VisualStudio2008/Juce.vcproj +++ b/Builds/VisualStudio2008/Juce.vcproj @@ -251,6 +251,8 @@ + + @@ -815,6 +817,8 @@ + + diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj index de09f23a74..5e55d73ebe 100644 --- a/Builds/VisualStudio2008_DLL/Juce.vcproj +++ b/Builds/VisualStudio2008_DLL/Juce.vcproj @@ -253,6 +253,8 @@ + + @@ -817,6 +819,8 @@ + + diff --git a/Builds/iPhone/Juce.xcodeproj/project.pbxproj b/Builds/iPhone/Juce.xcodeproj/project.pbxproj index bf76287b13..0682b1b781 100644 --- a/Builds/iPhone/Juce.xcodeproj/project.pbxproj +++ b/Builds/iPhone/Juce.xcodeproj/project.pbxproj @@ -62,6 +62,7 @@ E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; }; BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; }; 4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; }; + 95577AE91AA6CBA7FE9434F3 = { isa = PBXBuildFile; fileRef = 1CF7CC0EB057F995BBBEFC90; }; 21BA256CBCC9C15265928A23 = { isa = PBXBuildFile; fileRef = FF40DA899AE16A5E1D8AA54A; }; 9D2D1BA65C27BDA1F7C44769 = { isa = PBXBuildFile; fileRef = 70E5409425A76782B6188B31; }; 43B3119E2F1B559263AE956C = { isa = PBXBuildFile; fileRef = 9BD379D2F7995BFE0B3E5369; }; @@ -317,6 +318,7 @@ C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; }; 50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; }; 82568CF438EF4C950E4A42DF = { isa = PBXBuildFile; fileRef = 81B36E7C56DF1A777AA04F71; }; + B2E9D0C534DDE9F96921A054 = { isa = PBXBuildFile; fileRef = 0EC7DE81A516F4130AC59557; }; C8D06AE9C68A675A87DC9C99 = { isa = PBXBuildFile; fileRef = 5715BC14D93D61D71206FCB2; }; FE2999972FE3D6E251DA6653 = { isa = PBXBuildFile; fileRef = 95F21C2733BD5932372E4157; }; 8B2193898D3465B5995EE98A = { isa = PBXBuildFile; fileRef = 8E78623B2D21CFE68DEC0483; }; @@ -457,6 +459,8 @@ 34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; }; 7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; }; F364AA2637B7CB89D3657DFF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_HeapBlock.h; path = ../../src/containers/juce_HeapBlock.h; sourceTree = SOURCE_ROOT; }; + 1CF7CC0EB057F995BBBEFC90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/containers/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; }; + C16848F86DF014F1CBECE248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/containers/juce_Identifier.h; sourceTree = SOURCE_ROOT; }; FF40DA899AE16A5E1D8AA54A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MemoryBlock.cpp; path = ../../src/containers/juce_MemoryBlock.cpp; sourceTree = SOURCE_ROOT; }; 2E5D896B8DB2B357D7440F60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MemoryBlock.h; path = ../../src/containers/juce_MemoryBlock.h; sourceTree = SOURCE_ROOT; }; 70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; }; @@ -949,6 +953,8 @@ D4FED84C92ADC4B2C41A4275 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringArray.h; path = ../../src/text/juce_StringArray.h; sourceTree = SOURCE_ROOT; }; 81B36E7C56DF1A777AA04F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPairArray.cpp; path = ../../src/text/juce_StringPairArray.cpp; sourceTree = SOURCE_ROOT; }; E5458BE2F33DBBF5AF834BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPairArray.h; path = ../../src/text/juce_StringPairArray.h; sourceTree = SOURCE_ROOT; }; + 0EC7DE81A516F4130AC59557 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPool.cpp; path = ../../src/text/juce_StringPool.cpp; sourceTree = SOURCE_ROOT; }; + C972C24A7D2FC817362E1FD7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPool.h; path = ../../src/text/juce_StringPool.h; sourceTree = SOURCE_ROOT; }; 5715BC14D93D61D71206FCB2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlDocument.cpp; path = ../../src/text/juce_XmlDocument.cpp; sourceTree = SOURCE_ROOT; }; B4575FEE10C67D45C9532540 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_XmlDocument.h; path = ../../src/text/juce_XmlDocument.h; sourceTree = SOURCE_ROOT; }; 95F21C2733BD5932372E4157 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlElement.cpp; path = ../../src/text/juce_XmlElement.cpp; sourceTree = SOURCE_ROOT; }; @@ -1133,6 +1139,8 @@ 34C402EF9ADCAD34FB657D43, 7DA9AC75A4D9227C8FC4B2F7, F364AA2637B7CB89D3657DFF, + 1CF7CC0EB057F995BBBEFC90, + C16848F86DF014F1CBECE248, FF40DA899AE16A5E1D8AA54A, 2E5D896B8DB2B357D7440F60, 70E5409425A76782B6188B31, @@ -1690,6 +1698,8 @@ D4FED84C92ADC4B2C41A4275, 81B36E7C56DF1A777AA04F71, E5458BE2F33DBBF5AF834BB6, + 0EC7DE81A516F4130AC59557, + C972C24A7D2FC817362E1FD7, 5715BC14D93D61D71206FCB2, B4575FEE10C67D45C9532540, 95F21C2733BD5932372E4157, @@ -1874,6 +1884,7 @@ E8DFABC1603D55B97429A8E4, BE25871C34D79FEFFD1B94B6, 4AB5E55BDF79028F82F83D8E, + 95577AE91AA6CBA7FE9434F3, 21BA256CBCC9C15265928A23, 9D2D1BA65C27BDA1F7C44769, 43B3119E2F1B559263AE956C, @@ -2129,6 +2140,7 @@ C8F81E843F446868FAD88197, 50D91A2EC0ABF894E612D936, 82568CF438EF4C950E4A42DF, + B2E9D0C534DDE9F96921A054, C8D06AE9C68A675A87DC9C99, FE2999972FE3D6E251DA6653, 8B2193898D3465B5995EE98A, diff --git a/Juce.jucer b/Juce.jucer index a1562a0982..f714b9aa8d 100644 --- a/Juce.jucer +++ b/Juce.jucer @@ -311,6 +311,10 @@ file="src/containers/juce_ElementComparator.h"/> + + + + + + + + - - + + + diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj index 83dded36e4..04412dbf47 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj @@ -223,17 +223,22 @@ + + + + - - + + + diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp index 804b52248c..862d572556 100644 --- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp @@ -694,10 +694,6 @@ static const unsigned char temp_73015554[] = "%%staticMemberDefinitions%%\r\n" "\r\n" "//==============================================================================\r\n" -"/* This data contains the ValueTree that holds all the Jucer-generated settings for the components */\r\n" -"const unsigned char %%className%%_ComponentStateData[] = %%statedata%%;\r\n" -"\r\n" -"//==============================================================================\r\n" "//======================= Jucer Information Section ==========================\r\n" "//==============================================================================\r\n" "#if 0\r\n" @@ -770,8 +766,6 @@ static const unsigned char temp_b930c59[] = " %%privateMemberDeclarations%%\r\n" "\r\n" " //==============================================================================\r\n" -" ValueTree componentState;\r\n" -" \r\n" " // (prevent copy constructor and operator= being generated..)\r\n" " %%className%% (const %%className%%&);\r\n" " %%className%%& operator= (const %%className%%&);\r\n" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h index 50f94d0b3c..0c156266ad 100644 --- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h @@ -26,10 +26,10 @@ namespace BinaryData const int jucer_AudioPluginFilterTemplate_hSize = 2353; extern const char* jucer_ComponentTemplate_cpp; - const int jucer_ComponentTemplate_cppSize = 2534; + const int jucer_ComponentTemplate_cppSize = 2274; extern const char* jucer_ComponentTemplate_h; - const int jucer_ComponentTemplate_hSize = 2276; + const int jucer_ComponentTemplate_hSize = 2239; extern const char* jucer_MainConsoleAppTemplate_cpp; const int jucer_MainConsoleAppTemplate_cppSize = 749; diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer index fef6f242de..74d06366e8 100644 --- a/extras/Jucer (experimental)/Jucer.jucer +++ b/extras/Jucer (experimental)/Jucer.jucer @@ -14,9 +14,9 @@ + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/> @@ -193,6 +193,10 @@ + + + + - - + + + diff --git a/extras/Jucer (experimental)/Source/jucer_Headers.h b/extras/Jucer (experimental)/Source/jucer_Headers.h index 3dd37e6943..29b413038e 100644 --- a/extras/Jucer (experimental)/Source/jucer_Headers.h +++ b/extras/Jucer (experimental)/Source/jucer_Headers.h @@ -34,7 +34,9 @@ //============================================================================== #include "../JuceLibraryCode/JuceHeader.h" #include "utility/jucer_StoredSettings.h" -#include "utility/jucer_UtilityFunctions.h" +#include "utility/jucer_MiscUtilities.h" +#include "utility/jucer_CodeHelpers.h" +#include "utility/jucer_FileHelpers.h" #include "utility/jucer_RelativePath.h" #include "utility/jucer_ValueRemapperSource.h" #include "ui/jucer_CommandIDs.h" diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h index b280c11f31..59da4d5986 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h @@ -50,11 +50,11 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("items", "Item 1\nItem 2"); - item.set ("editable", false); - item.set ("textJustification", (int) Justification::centredLeft); - item.set ("unselectedText", ""); - item.set ("noItemsText", "(No Choices)"); + item.set (Ids::items, "Item 1\nItem 2"); + item.set (Ids::editable, false); + item.set (Ids::textJustification, (int) Justification::centredLeft); + item.set (Ids::unselectedText, ""); + item.set (Ids::noItemsText, "(No Choices)"); } void updateItems (ComboBox* comp, const String& itemString) @@ -79,11 +79,11 @@ public: void update (ComponentTypeInstance& item, ComboBox* comp) { - updateItems (comp, item ["items"]); - comp->setEditableText (item ["editable"]); - comp->setJustificationType ((int) item ["textJustification"]); - comp->setTextWhenNothingSelected (item ["unselectedText"].toString()); - comp->setTextWhenNoChoicesAvailable (item ["noItemsText"].toString()); + updateItems (comp, item [Ids::items]); + comp->setEditableText (item [Ids::editable]); + comp->setJustificationType ((int) item [Ids::textJustification]); + comp->setTextWhenNothingSelected (item [Ids::unselectedText].toString()); + comp->setTextWhenNoChoicesAvailable (item [Ids::noItemsText].toString()); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -91,20 +91,43 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("items"), "Items", 16384, true)); + props.add (new TextPropertyComponent (item.getValue (Ids::items), "Items", 16384, true)); props.getLast()->setTooltip ("A list of items to use to initialise the ComboBox"); - props.add (new BooleanPropertyComponent (item.getValue ("editable"), "Editable", "Text is editable")); - item.addJustificationProperty (props, "Text Position", item.getValue ("textJustification"), false); - props.add (new TextPropertyComponent (item.getValue ("unselectedText"), "Text when none selected", 512, false)); - props.add (new TextPropertyComponent (item.getValue ("noItemsText"), "Text when no items", 512, false)); + props.add (new BooleanPropertyComponent (item.getValue (Ids::editable), "Editable", "Text is editable")); + item.addJustificationProperty (props, "Text Position", item.getValue (Ids::textJustification), false); + props.add (new TextPropertyComponent (item.getValue (Ids::unselectedText), "Text when none selected", 512, false)); + props.add (new TextPropertyComponent (item.getValue (Ids::noItemsText), "Text when no items", 512, false)); addEditableColourProperties (item, props); } void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode << item.createConstructorStatement (String::empty); + ComboBox defaultBox; + + code.constructorCode + << item.createConstructorStatement (String::empty) + << item.getMemberName() << "->setEditableText (" << CodeHelpers::boolLiteral (item [Ids::editable]) << ");" << newLine; + + Justification justification ((int) item [Ids::textJustification]); + if (justification.getFlags() != 0 && justification.getFlags() != defaultBox.getJustificationType().getFlags()) + code.constructorCode << item.getMemberName() << "->setJustificationType (" << CodeHelpers::justificationToCode (justification) << ");" << newLine; + + if (item [Ids::unselectedText].toString() != defaultBox.getTextWhenNothingSelected()) + code.constructorCode << item.getMemberName() << "->setTextWhenNothingSelected (" + << CodeHelpers::stringLiteral (item [Ids::unselectedText]) << ");" << newLine; + + if (item [Ids::noItemsText].toString() != defaultBox.getTextWhenNoChoicesAvailable()) + code.constructorCode << item.getMemberName() << "->setTextWhenNoChoicesAvailable (" + << CodeHelpers::stringLiteral (item [Ids::noItemsText]) << ");" << newLine; + + StringArray items; + items.addLines (item [Ids::items]); + items.removeEmptyStrings (true); + + for (int i = 0; i < items.size(); ++i) + code.constructorCode << item.getMemberName() << "->addItem (" << CodeHelpers::stringLiteral (items[i]) << ");" << newLine; } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp index db20f38549..e87dec5688 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp @@ -24,6 +24,46 @@ */ #include "jucer_ComponentTypeManager.h" + +// Handy list of static ids for use by component types.. +namespace Ids +{ + #define DECLARE_ID(name) const Identifier name (#name) + + DECLARE_ID (text); + DECLARE_ID (font); + DECLARE_ID (mode); + DECLARE_ID (type); + DECLARE_ID (readOnly); + DECLARE_ID (editMode); + DECLARE_ID (justification); + DECLARE_ID (items); + DECLARE_ID (editable); + DECLARE_ID (textJustification); + DECLARE_ID (unselectedText); + DECLARE_ID (noItemsText); + DECLARE_ID (min); + DECLARE_ID (max); + DECLARE_ID (interval); + DECLARE_ID (textBoxPos); + DECLARE_ID (textBoxWidth); + DECLARE_ID (textBoxHeight); + DECLARE_ID (skew); + DECLARE_ID (scrollBarV); + DECLARE_ID (scrollBarH); + DECLARE_ID (scrollbarWidth); + DECLARE_ID (initialState); + DECLARE_ID (scrollbarsShown); + DECLARE_ID (caretVisible); + DECLARE_ID (popupMenuEnabled); + DECLARE_ID (radioGroup); + DECLARE_ID (connectedLeft); + DECLARE_ID (connectedRight); + DECLARE_ID (connectedTop); + DECLARE_ID (connectedBottom); + const Identifier class_ ("class"); +} + #include "jucer_ComponentTypes.h" #include "../../../utility/jucer_CoordinatePropertyComponent.h" @@ -261,12 +301,12 @@ ComponentTypeInstance::ComponentTypeInstance (ComponentDocument& document_, cons { } -Value ComponentTypeInstance::getValue (const var::identifier& name) const +Value ComponentTypeInstance::getValue (const Identifier& name) const { return state.getPropertyAsValue (name, document.getUndoManager()); } -void ComponentTypeInstance::set (const var::identifier& name, const var& value) +void ComponentTypeInstance::set (const Identifier& name, const var& value) { state.setProperty (name, value, 0); } @@ -352,7 +392,7 @@ void ComponentTypeInstance::addFocusOrderProperty (Array & p "Focus Order", 10, false)); } -void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const String& propertyName) +void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const Identifier& propertyName) { props.add (new ColourPropertyComponent (document, name, getValue (propertyName), LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true)); @@ -498,7 +538,7 @@ private: Value sourceValue; }; -void ComponentTypeInstance::addFontProperties (Array & props, const var::identifier& name) +void ComponentTypeInstance::addFontProperties (Array & props, const Identifier& name) { Value v (getValue (name)); props.add (FontNameValueSource::createProperty ("Font", v)); @@ -551,7 +591,7 @@ const String ComponentTypeInstance::createConstructorStatement (const String& pa else { s << " ("; - s << CodeFormatting::indent (params.trim(), s.length(), false) << "));" << newLine; + s << CodeHelpers::indent (params.trim(), s.length(), false) << "));" << newLine; } // s << getMemberName() << "->updateStateFrom (componentStateList.getChild (" diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h index 8865010532..8a9f95cf85 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h @@ -29,6 +29,7 @@ #include "../../../jucer_Headers.h" #include "../jucer_ComponentDocument.h" #include "../../../utility/jucer_ColourEditorComponent.h" + class ComponentTypeHandler; class JucerState @@ -60,9 +61,9 @@ public: ComponentDocument& getDocument() throw() { return document; } ValueTree& getState() throw() { return state; } - Value getValue (const var::identifier& name) const; - void set (const var::identifier& name, const var& value); - const var operator[] (const var::identifier& name) const { return state [name] ;} + Value getValue (const Identifier& name) const; + void set (const Identifier& name, const var& value); + const var operator[] (const Identifier& name) const { return state [name] ;} const String getMemberName() const { return state [ComponentDocument::memberNameProperty]; } const String getComponentName() const { return state [ComponentDocument::compNameProperty]; } @@ -75,8 +76,8 @@ public: void addBoundsProperties (Array & props); void addTooltipProperty (Array & props); void addFocusOrderProperty (Array & props); - void addColourProperty (Array & props, int colourId, const String& name, const String& propertyName); - void addFontProperties (Array & props, const var::identifier& name); + void addColourProperty (Array & props, int colourId, const String& name, const Identifier& propertyName); + void addFontProperties (Array & props, const Identifier& name); void addJustificationProperty (Array & props, const String& name, const Value& value, bool onlyHorizontal); //============================================================================== @@ -104,7 +105,7 @@ public: virtual ~ComponentTypeHandler(); const String& getDisplayName() const { return displayName; } - const String& getXmlTag() const { return xmlTag; } + const Identifier& getXmlTag() const { return xmlTag; } const String& getMemberNameRoot() const { return memberNameRoot; } virtual Component* createComponent() = 0; @@ -118,7 +119,8 @@ public: protected: //============================================================================== - const String displayName, className, xmlTag, memberNameRoot; + const String displayName, className, memberNameRoot; + const Identifier xmlTag; private: ComponentTypeHandler (const ComponentTypeHandler&); @@ -196,12 +198,13 @@ protected: struct EditableColour { int colourId; - String name, propertyName; + String name; + Identifier propertyName; }; Array editableColours; - void addEditableColour (int colourId, const String& displayName, const String& propertyName) + void addEditableColour (int colourId, const String& displayName, const Identifier& propertyName) { EditableColour ec; ec.colourId = colourId; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h index 99e05c274f..4a1db5efd9 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h @@ -68,26 +68,26 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("class", "Component"); + item.set (Ids::class_, "Component"); } void update (ComponentTypeInstance& item, Component* comp) { static_cast (comp)->setDetails (item [ComponentDocument::memberNameProperty], - item ["class"]); + item [Ids::class_]); } void createProperties (ComponentTypeInstance& item, Array & props) { item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("class"), "Class", 256, false)); + props.add (new TextPropertyComponent (item.getValue (Ids::class_), "Class", 256, false)); props.getLast()->setTooltip ("The class that this component is an instance of."); } const String getClassName (ComponentTypeInstance& item) const { - return item ["class"]; + return item [Ids::class_]; } void createCode (ComponentTypeInstance& item, CodeGenerator& code) diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h index 78abea46d7..277555514a 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h @@ -47,14 +47,14 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("text", "Group"); - item.set ("justification", (int) Justification::left); + item.set (Ids::text, "Group"); + item.set (Ids::justification, (int) Justification::left); } void update (ComponentTypeInstance& item, GroupComponent* comp) { - comp->setText (item ["text"].toString()); - comp->setTextLabelPosition ((int) item ["justification"]); + comp->setText (item [Ids::text].toString()); + comp->setTextLabelPosition ((int) item [Ids::justification]); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -62,10 +62,10 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("text"), "Label", 512, false)); + props.add (new TextPropertyComponent (item.getValue (Ids::text), "Label", 512, false)); props.getLast()->setTooltip ("The group's display name."); - item.addJustificationProperty (props, "Text Position", item.getValue ("justification"), true); + item.addJustificationProperty (props, "Text Position", item.getValue (Ids::justification), true); addEditableColourProperties (item, props); } diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h index 0b28894830..bf0c1df98f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h @@ -48,19 +48,19 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("text", "New Label"); - item.set ("font", Font (14.0f).toString()); - item.set ("editMode", 1); - item.set ("justification", (int) Justification::centredLeft); + item.set (Ids::text, "New Label"); + item.set (Ids::font, Font (14.0f).toString()); + item.set (Ids::editMode, 1); + item.set (Ids::justification, (int) Justification::centredLeft); } void update (ComponentTypeInstance& item, Label* comp) { - comp->setText (item ["text"].toString(), false); - comp->setFont (Font::fromString (item ["font"])); - int editMode = (int) item ["editMode"]; + comp->setText (item [Ids::text].toString(), false); + comp->setFont (Font::fromString (item [Ids::font])); + int editMode = (int) item [Ids::editMode]; comp->setEditable (editMode == 2, editMode == 3, false); - comp->setJustificationType ((int) item ["justification"]); + comp->setJustificationType ((int) item [Ids::justification]); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -68,22 +68,34 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("text"), "Text", 16384, true)); + props.add (new TextPropertyComponent (item.getValue (Ids::text), "Text", 16384, true)); props.getLast()->setTooltip ("The label's text."); item.addJustificationProperty (props, "Layout", item.getValue ("justification"), false); const char* const editModes[] = { "Read-only", "Edit on Single-Click", "Edit on Double-Click", 0 }; - props.add (new ChoicePropertyComponent (item.getValue ("editMode"), "Edit Mode", StringArray (editModes))); + props.add (new ChoicePropertyComponent (item.getValue (Ids::editMode), "Edit Mode", StringArray (editModes))); - item.addFontProperties (props, "font"); + item.addFontProperties (props, Ids::font); addEditableColourProperties (item, props); } void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode << item.createConstructorStatement (String::empty); + int editMode = (int) item [Ids::editMode]; + + code.constructorCode + << item.createConstructorStatement (String::empty) + << item.getMemberName() << "->setText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine + << item.getMemberName() << "->setFont (" << CodeHelpers::fontToCode (Font::fromString (item [Ids::font])) << ");" << newLine + << item.getMemberName() << "->setEditable (" << CodeHelpers::boolLiteral (editMode == 2) + << ", " << CodeHelpers::boolLiteral (editMode == 3) << ", false);" << newLine; + + Justification justification ((int) item ["textJustification"]); + if (justification.getFlags() != 0) + code.constructorCode << item.getMemberName() << "->setJustificationType (" + << CodeHelpers::justificationToCode (justification) << ");" << newLine; } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h index 2009617240..4b32a078a9 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h @@ -54,25 +54,25 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("min", 0); - item.set ("max", 100); - item.set ("interval", 1); - item.set ("type", 1 + Slider::LinearHorizontal); - item.set ("textBoxPos", 2); - item.set ("editable", true); - item.set ("textBoxWidth", 80); - item.set ("textBoxHeight", 20); - item.set ("skew", 1); + item.set (Ids::min, 0); + item.set (Ids::max, 100); + item.set (Ids::interval, 1); + item.set (Ids::type, 1 + Slider::LinearHorizontal); + item.set (Ids::textBoxPos, 2); + item.set (Ids::editable, true); + item.set (Ids::textBoxWidth, 80); + item.set (Ids::textBoxHeight, 20); + item.set (Ids::skew, 1); } void update (ComponentTypeInstance& item, Slider* comp) { - comp->setRange ((double) item ["min"], (double) item ["max"], (double) item ["interval"]); - comp->setSliderStyle ((Slider::SliderStyle) ((int) item ["type"] - 1)); - comp->setTextBoxStyle ((Slider::TextEntryBoxPosition) ((int) item ["textBoxPos"] - 1), - ! (bool) item ["editable"], - (int) item ["textBoxWidth"], (int) item ["textBoxHeight"]); - comp->setSkewFactor ((double) item ["skew"]); + comp->setRange ((double) item [Ids::min], (double) item [Ids::max], (double) item [Ids::interval]); + comp->setSliderStyle ((Slider::SliderStyle) ((int) item [Ids::type] - 1)); + comp->setTextBoxStyle ((Slider::TextEntryBoxPosition) ((int) item [Ids::textBoxPos] - 1), + ! (bool) item [Ids::editable], + (int) item [Ids::textBoxWidth], (int) item [Ids::textBoxHeight]); + comp->setSkewFactor ((double) item [Ids::skew]); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -80,28 +80,79 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("min"))), "Minimum", 16, false)); - props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("max"))), "Maximum", 16, false)); - props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("interval"))), "Interval", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::min))), "Minimum", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::max))), "Maximum", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::interval))), "Interval", 16, false)); const char* const types[] = { "LinearHorizontal", "LinearVertical", "LinearBar", "Rotary", "RotaryHorizontalDrag", "RotaryVerticalDrag", "IncDecButtons", "TwoValueHorizontal", "TwoValueVertical", "ThreeValueHorizontal", "ThreeValueVertical", 0 }; - props.add (new ChoicePropertyComponent (item.getValue ("type"), "Type", StringArray (types))); + props.add (new ChoicePropertyComponent (item.getValue (Ids::type), "Type", StringArray (types))); const char* const textBoxPositions[] = { "NoTextBox", "TextBoxLeft", "TextBoxRight", "TextBoxAbove", "TextBoxBelow", 0 }; - props.add (new ChoicePropertyComponent (item.getValue ("textBoxPos"), "Text Box", StringArray (textBoxPositions))); + props.add (new ChoicePropertyComponent (item.getValue (Ids::textBoxPos), "Text Box", StringArray (textBoxPositions))); - props.add (new BooleanPropertyComponent (item.getValue ("editable"), "Editable", "Value can be edited")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::editable), "Editable", "Value can be edited")); props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("textBoxWidth"))), "Text Box Width", 8, false)); props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("textBoxHeight"))), "Text Box Height", 8, false)); - props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("skew"))), "Skew Factor", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::skew))), "Skew Factor", 16, false)); addEditableColourProperties (item, props); } + static const char* sliderTypeString (int type) throw() + { + switch (type) + { + case Slider::LinearHorizontal: return "LinearHorizontal"; + case Slider::LinearVertical: return "LinearVertical"; + case Slider::LinearBar: return "LinearBar"; + case Slider::Rotary: return "Rotary"; + case Slider::RotaryHorizontalDrag: return "RotaryHorizontalDrag"; + case Slider::RotaryVerticalDrag: return "RotaryVerticalDrag"; + case Slider::IncDecButtons: return "IncDecButtons"; + case Slider::TwoValueHorizontal: return "TwoValueHorizontal"; + case Slider::TwoValueVertical: return "TwoValueVertical"; + case Slider::ThreeValueHorizontal: return "ThreeValueHorizontal"; + case Slider::ThreeValueVertical: return "ThreeValueVertical"; + default: jassertfalse; break; + } + + return ""; + } + + static const char* sliderTextBoxString (int type) throw() + { + switch (type) + { + case Slider::NoTextBox: return "NoTextBox"; + case Slider::TextBoxLeft: return "TextBoxLeft"; + case Slider::TextBoxRight: return "TextBoxRight"; + case Slider::TextBoxAbove: return "TextBoxAbove"; + case Slider::TextBoxBelow: return "TextBoxBelow"; + default: jassertfalse; break; + } + + return ""; + } + void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode << item.createConstructorStatement (CodeFormatting::stringLiteral (item.getComponentName())); + code.constructorCode + << item.createConstructorStatement (CodeHelpers::stringLiteral (item.getComponentName())) + << item.getMemberName() << "->setRange (" << CodeHelpers::doubleLiteral (item [Ids::min]) + << ", " << CodeHelpers::doubleLiteral (item [Ids::max]) + << ", " << CodeHelpers::doubleLiteral (item [Ids::interval]) + << ");" << newLine + << item.getMemberName() << "->setSliderStyle (Slider::" << sliderTypeString ((int) item [Ids::type] - 1) << ");" << newLine + << item.getMemberName() << "->setTextBoxStyle (Slider::" << sliderTextBoxString ((int) item [Ids::type] - 1) + << ", " << CodeHelpers::boolLiteral (! (bool) item [Ids::editable]) + << ", " << String ((int) item [Ids::textBoxWidth]) + << ", " << String ((int) item [Ids::textBoxHeight]) + << ");" << newLine; + + double skew = (double) item [Ids::skew]; + if (skew != 1.0 && skew != 0) + code.constructorCode << item.getMemberName() << "->setSkewFactor (" << CodeHelpers::doubleLiteral (skew) << ");" << newLine; } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h index 1f4aa2fc91..034f65d960 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h @@ -47,26 +47,29 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("text", "New Button"); - item.set ("radioGroup", 0); - item.set ("connectedLeft", false); - item.set ("connectedRight", false); - item.set ("connectedTop", false); - item.set ("connectedBottom", false); + item.set (Ids::text, "New Button"); + item.set (Ids::radioGroup, 0); + item.set (Ids::connectedLeft, false); + item.set (Ids::connectedRight, false); + item.set (Ids::connectedTop, false); + item.set (Ids::connectedBottom, false); } - void update (ComponentTypeInstance& item, TextButton* comp) + static int getConnectedFlags (ComponentTypeInstance& item) { - comp->setButtonText (item ["text"].toString()); - comp->setRadioGroupId (item ["radioGroup"]); - int connected = 0; - if (item ["connectedLeft"]) connected |= TextButton::ConnectedOnLeft; - if (item ["connectedRight"]) connected |= TextButton::ConnectedOnRight; - if (item ["connectedTop"]) connected |= TextButton::ConnectedOnTop; - if (item ["connectedBottom"]) connected |= TextButton::ConnectedOnBottom; + if (item [Ids::connectedLeft]) connected |= TextButton::ConnectedOnLeft; + if (item [Ids::connectedRight]) connected |= TextButton::ConnectedOnRight; + if (item [Ids::connectedTop]) connected |= TextButton::ConnectedOnTop; + if (item [Ids::connectedBottom]) connected |= TextButton::ConnectedOnBottom; + return connected; + } - comp->setConnectedEdges (connected); + void update (ComponentTypeInstance& item, TextButton* comp) + { + comp->setButtonText (item [Ids::text].toString()); + comp->setRadioGroupId (item [Ids::radioGroup]); + comp->setConnectedEdges (getConnectedFlags (item)); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -74,23 +77,31 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("text"), "Button Text", 1024, false)); + props.add (new TextPropertyComponent (item.getValue (Ids::text), "Button Text", 1024, false)); props.getLast()->setTooltip ("The button's text."); - props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("radioGroup"))), "Radio Group", 8, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::radioGroup))), "Radio Group", 8, false)); props.getLast()->setTooltip ("The radio group that this button is a member of."); - props.add (new BooleanPropertyComponent (item.getValue ("connectedLeft"), "Connected left", "Connected")); - props.add (new BooleanPropertyComponent (item.getValue ("connectedRight"), "Connected right", "Connected")); - props.add (new BooleanPropertyComponent (item.getValue ("connectedTop"), "Connected top", "Connected")); - props.add (new BooleanPropertyComponent (item.getValue ("connectedBottom"), "Connected bottom", "Connected")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedLeft), "Connected left", "Connected")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedRight), "Connected right", "Connected")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedTop), "Connected top", "Connected")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedBottom), "Connected bottom", "Connected")); addEditableColourProperties (item, props); } void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode += item.createConstructorStatement (String::empty); + code.constructorCode + << item.createConstructorStatement (String::empty) + << item.getMemberName() << "->setButtonText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine; + + if ((int) item [Ids::radioGroup] != 0) + code.constructorCode << item.getMemberName() << "->setRadioGroupId (" << String ((int) item [Ids::radioGroup]) << ");" << newLine; + + if (getConnectedFlags (item) != 0) + code.constructorCode << item.getMemberName() << "->setConnectedEdges (" << String (getConnectedFlags (item)) << ");" << newLine; } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h index a433b50847..8b6f273e95 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h @@ -53,24 +53,32 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("text", "Text Editor Content"); - item.set ("readOnly", false); - item.set ("scrollbarsShown", true); - item.set ("caretVisible", true); - item.set ("popupMenuEnabled", true); - item.set ("mode", 1); + TextEditor defaultComp; + + item.set (Ids::text, "Text Editor Content"); + item.set (Ids::readOnly, false); + item.set (Ids::scrollbarsShown, true); + item.set (Ids::caretVisible, true); + item.set (Ids::popupMenuEnabled, true); + item.set (Ids::mode, 1); + item.set (Ids::font, defaultComp.getFont().toString()); } void update (ComponentTypeInstance& item, TextEditor* comp) { - comp->setReadOnly (item ["readOnly"]); - comp->setScrollbarsShown (item ["scrollbarsShown"]); - comp->setCaretVisible (item ["caretVisible"]); - comp->setPopupMenuEnabled (item ["popupMenuEnabled"]); - int mode = item ["mode"]; + comp->setReadOnly (item [Ids::readOnly]); + comp->setScrollbarsShown (item [Ids::scrollbarsShown]); + comp->setCaretVisible (item [Ids::caretVisible]); + comp->setPopupMenuEnabled (item [Ids::popupMenuEnabled]); + int mode = item [Ids::mode]; comp->setMultiLine (mode > 1, true); comp->setReturnKeyStartsNewLine (mode != 3); - comp->setText (item ["text"].toString()); + + const Font font (Font::fromString (item [Ids::font])); + if (comp->getFont() != font) + comp->applyFontToAllText (font); + + comp->setText (item [Ids::text].toString()); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -78,23 +86,53 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("text"), "Text", 16384, true)); + props.add (new TextPropertyComponent (item.getValue (Ids::text), "Text", 16384, true)); props.getLast()->setTooltip ("The editor's initial content."); const char* const modes[] = { "Single-Line", "Multi-Line (Return key starts new line)", "Multi-Line (Return key disabled)", 0 }; - props.add (new ChoicePropertyComponent (item.getValue ("mode"), "Mode", StringArray (modes))); + props.add (new ChoicePropertyComponent (item.getValue (Ids::mode), "Mode", StringArray (modes))); + + props.add (new BooleanPropertyComponent (item.getValue (Ids::readOnly), "Read-Only", "Read-Only")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollbarsShown), "Scrollbars", "Scrollbars Shown")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::caretVisible), "Caret", "Caret Visible")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::popupMenuEnabled), "Popup Menu", "Popup Menu Enabled")); - props.add (new BooleanPropertyComponent (item.getValue ("readOnly"), "Read-Only", "Read-Only")); - props.add (new BooleanPropertyComponent (item.getValue ("scrollbarsShown"), "Scrollbars", "Scrollbars Shown")); - props.add (new BooleanPropertyComponent (item.getValue ("caretVisible"), "Caret", "Caret Visible")); - props.add (new BooleanPropertyComponent (item.getValue ("popupMenuEnabled"), "Popup Menu", "Popup Menu Enabled")); + item.addFontProperties (props, Ids::font); addEditableColourProperties (item, props); } void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode += item.createConstructorStatement (String::empty); + TextEditor defaultComp; + + code.constructorCode + << item.createConstructorStatement (String::empty); + + if (defaultComp.isReadOnly() != (bool) item [Ids::readOnly]) + code.constructorCode << item.getMemberName() << "->setReadOnly (" << CodeHelpers::boolLiteral (item [Ids::readOnly]) << ");" << newLine; + + if (defaultComp.areScrollbarsShown() != (bool) item [Ids::scrollbarsShown]) + code.constructorCode << item.getMemberName() << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (item [Ids::scrollbarsShown]) << ");" << newLine; + + if (defaultComp.isCaretVisible() != (bool) item [Ids::caretVisible]) + code.constructorCode << item.getMemberName() << "->setCaretVisible (" << CodeHelpers::boolLiteral (item [Ids::caretVisible]) << ");" << newLine; + + if (defaultComp.isPopupMenuEnabled() != (bool) item [Ids::popupMenuEnabled]) + code.constructorCode << item.getMemberName() << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (item [Ids::popupMenuEnabled]) << ");" << newLine; + + int mode = item [Ids::mode]; + if (defaultComp.isMultiLine() != (mode > 1)) + code.constructorCode << item.getMemberName() << "->setMultiLine (" << CodeHelpers::boolLiteral (mode > 1) << ", true);" << newLine; + + if (defaultComp.getReturnKeyStartsNewLine() != (mode != 3)) + code.constructorCode << item.getMemberName() << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (mode != 3) << ");" << newLine; + + const Font font (Font::fromString (item [Ids::font])); + if (font != defaultComp.getFont()) + code.constructorCode << item.getMemberName() << "->setFont (" << CodeHelpers::fontToCode (font) << ");" << newLine; + + code.constructorCode << item.getMemberName() << "->setText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine; } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h index c3f0fd6dda..f5cc185c03 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h @@ -46,14 +46,14 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("text", "New Toggle Button"); - item.set ("initialState", false); + item.set (Ids::text, "New Toggle Button"); + item.set (Ids::initialState, false); } void update (ComponentTypeInstance& item, ToggleButton* comp) { - comp->setButtonText (item ["text"].toString()); - comp->setToggleState (item ["initialState"], false); + comp->setButtonText (item [Ids::text].toString()); + comp->setToggleState (item [Ids::initialState], false); } void createProperties (ComponentTypeInstance& item, Array & props) @@ -61,10 +61,10 @@ public: item.addTooltipProperty (props); item.addFocusOrderProperty (props); - props.add (new TextPropertyComponent (item.getValue ("text"), "Button Text", 1024, false)); + props.add (new TextPropertyComponent (item.getValue (Ids::text), "Button Text", 1024, false)); props.getLast()->setTooltip ("The button's text."); - props.add (new BooleanPropertyComponent (item.getValue ("initialState"), "Initial State", "Enabled initially")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::initialState), "Initial State", "Enabled initially")); addEditableColourProperties (item, props); } diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h index 8c0224eb72..2654477535 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h @@ -62,29 +62,30 @@ public: void initialiseNew (ComponentTypeInstance& item) { - item.set ("scrollBarV", true); - item.set ("scrollBarH", true); - item.set ("scrollbarWidth", 18); + item.set (Ids::scrollBarV, true); + item.set (Ids::scrollBarH, true); + item.set (Ids::scrollbarWidth, 18); } void update (ComponentTypeInstance& item, Viewport* comp) { - comp->setScrollBarsShown (item ["scrollBarV"], item ["scrollBarH"]); - comp->setScrollBarThickness (item ["scrollbarWidth"]); + comp->setScrollBarsShown (item [Ids::scrollBarV], item [Ids::scrollBarH]); + comp->setScrollBarThickness (item [Ids::scrollbarWidth]); } void createProperties (ComponentTypeInstance& item, Array & props) { - props.add (new BooleanPropertyComponent (item.getValue ("scrollBarV"), "Scrollbar V", "Vertical scrollbar shown")); - props.add (new BooleanPropertyComponent (item.getValue ("scrollBarH"), "Scrollbar H", "Horizontal scrollbar shown")); - props.add (new SliderPropertyComponent (item.getValue ("scrollbarWidth"), "Scrollbar Thickness", 3, 40, 1)); + props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollBarV), "Scrollbar V", "Vertical scrollbar shown")); + props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollBarH), "Scrollbar H", "Horizontal scrollbar shown")); + props.add (new SliderPropertyComponent (item.getValue (Ids::scrollbarWidth), "Scrollbar Thickness", 3, 40, 1)); addEditableColourProperties (item, props); } void createCode (ComponentTypeInstance& item, CodeGenerator& code) { - code.constructorCode << item.createConstructorStatement (CodeFormatting::stringLiteral (item.getComponentName())); + code.constructorCode << item.createConstructorStatement (CodeHelpers::stringLiteral (item.getComponentName())); } }; + #endif diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp index f54538e334..a951f0021d 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp @@ -127,7 +127,7 @@ const String CodeGenerator::getCallbackDefinitions() const { CallbackMethod* const cm = callbacks.getUnchecked(i); - const String userCodeBlockName ("User" + CodeFormatting::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false), + const String userCodeBlockName ("User" + CodeHelpers::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false), true, true, false).trim()); if (userCodeBlockName.isNotEmpty() && cm->hasPrePostUserSections) @@ -138,7 +138,7 @@ const String CodeGenerator::getCallbackDefinitions() const << " //[" << userCodeBlockName << "_Pre]" << newLine << " //[/" << userCodeBlockName << "_Pre]" << newLine << newLine - << " " << CodeFormatting::indent (cm->content.trim(), 4, false) << newLine + << " " << CodeHelpers::indent (cm->content.trim(), 4, false) << newLine << newLine << " //[" << userCodeBlockName << "_Post]" << newLine << " //[/" << userCodeBlockName << "_Post]" << newLine @@ -149,7 +149,7 @@ const String CodeGenerator::getCallbackDefinitions() const { s << cm->returnType << " " << className << "::" << cm->prototype << newLine << "{" << newLine - << " " << CodeFormatting::indent (cm->content.trim(), 4, false) << newLine + << " " << CodeHelpers::indent (cm->content.trim(), 4, false) << newLine << "}" << newLine << newLine; } @@ -250,7 +250,7 @@ static void replaceTemplate (String& text, const String& itemName, const String& } } - text = text.replaceSection (index, itemName.length() + 4, CodeFormatting::indent (value, indentLevel, false)); + text = text.replaceSection (index, itemName.length() + 4, CodeHelpers::indent (value, indentLevel, false)); } } @@ -259,7 +259,7 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile, bool isForPreview, Project* project) const { replaceTemplate (code, "juceVersion", SystemStats::getJUCEVersion()); - replaceTemplate (code, "headerGuard", CodeFormatting::makeHeaderGuardName (targetFile)); + replaceTemplate (code, "headerGuard", CodeHelpers::makeHeaderGuardName (targetFile)); replaceTemplate (code, "className", className); replaceTemplate (code, "constructorParams", constructorParams); @@ -272,7 +272,7 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile, replaceTemplate (code, "methodDefinitions", getCallbackDefinitions()); if (project != 0) - replaceTemplate (code, "defaultJuceInclude", CodeFormatting::createIncludeStatement (project->getAppIncludeFile(), targetFile)); + replaceTemplate (code, "defaultJuceInclude", CodeHelpers::createIncludeStatement (project->getAppIncludeFile(), targetFile)); else replaceTemplate (code, "defaultJuceInclude", "#include \"juce_amalgamated.h\""); @@ -293,13 +293,13 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile, replaceTemplate (code, "staticMemberDefinitions", "// Static member declarations and resources would go here... (these aren't shown in the code preview)"); } - { + /*{ MemoryOutputStream compDataCpp; - CodeFormatting::writeDataAsCppLiteral (componentStateData, compDataCpp); + CodeHelpers::writeDataAsCppLiteral (componentStateData, compDataCpp); replaceTemplate (code, "statedata", compDataCpp.toUTF8(), false); replaceTemplate (code, "statedatasize", String ((int) componentStateData.getSize())); - } + }*/ } diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp index b39e4270e3..5e6f15a55f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp @@ -29,20 +29,21 @@ //============================================================================== -static const char* const componentDocumentTag = "COMPONENT"; -static const char* const componentGroupTag = "COMPONENTS"; -static const char* const markersGroupXTag = "MARKERS_X"; -static const char* const markersGroupYTag = "MARKERS_Y"; +static const Identifier componentDocumentTag ("COMPONENT"); +static const Identifier componentGroupTag ("COMPONENTS"); +static const Identifier markersGroupXTag ("MARKERS_X"); +static const Identifier markersGroupYTag ("MARKERS_Y"); -static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component! -static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END"; +static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component! +static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END"; -const char* const ComponentDocument::idProperty = "id"; -const char* const ComponentDocument::compBoundsProperty = "position"; -const char* const ComponentDocument::memberNameProperty = "memberName"; -const char* const ComponentDocument::compNameProperty = "name"; -const char* const ComponentDocument::compTooltipProperty = "tooltip"; -const char* const ComponentDocument::compFocusOrderProperty = "focusOrder"; +const Identifier ComponentDocument::idProperty ("id"); +const Identifier ComponentDocument::compBoundsProperty ("position"); +const Identifier ComponentDocument::memberNameProperty ("memberName"); +const Identifier ComponentDocument::compNameProperty ("name"); +const Identifier ComponentDocument::compTooltipProperty ("tooltip"); +const Identifier ComponentDocument::compFocusOrderProperty ("focusOrder"); +const Identifier ComponentDocument::jucerIDProperty ("jucerID"); //============================================================================== @@ -84,7 +85,7 @@ void ComponentDocument::changed() changedSinceSaved = true; } -void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property) +void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { changed(); } @@ -196,8 +197,8 @@ bool ComponentDocument::save() MemoryOutputStream cpp, header; writeCode (cpp, header); - bool savedOk = FileUtils::overwriteFileWithNewDataIfDifferent (cppFile, cpp) - && FileUtils::overwriteFileWithNewDataIfDifferent (cppFile.withFileExtension (".h"), header); + bool savedOk = FileHelpers::overwriteFileWithNewDataIfDifferent (cppFile, cpp) + && FileHelpers::overwriteFileWithNewDataIfDifferent (cppFile.withFileExtension (".h"), header); if (savedOk) changedSinceSaved = false; @@ -247,9 +248,9 @@ bool ComponentDocument::reload() ScopedPointer xml (doc.getDocumentElement()); if (xml == 0 && hadMetaDataTags) - xml = new XmlElement (componentDocumentTag); + xml = new XmlElement (componentDocumentTag.toString()); - if (xml != 0 && xml->hasTagName (componentDocumentTag)) + if (xml != 0 && xml->hasTagName (componentDocumentTag.toString())) { ValueTree newTree (ValueTree::fromXml (*xml)); @@ -278,7 +279,7 @@ bool ComponentDocument::hasChangedSinceLastSave() return changedSinceSaved || customCode.needsSaving(); } -void ComponentDocument::createSubTreeIfNotThere (const String& name) +void ComponentDocument::createSubTreeIfNotThere (const Identifier& name) { if (! root.getChildWithName (name).isValid()) root.addChild (ValueTree (name), -1, 0); @@ -562,7 +563,7 @@ bool ComponentDocument::setCoordsFor (ValueTree& state, const RectangleCoordinat const String ComponentDocument::getNonexistentMemberName (String name) { - String n (CodeFormatting::makeValidIdentifier (name, false, true, false)); + String n (CodeHelpers::makeValidIdentifier (name, false, true, false)); int suffix = 2; while (markersX->getMarkerNamed (n).isValid() || markersY->getMarkerNamed (n).isValid() @@ -857,8 +858,6 @@ UndoManager* ComponentDocument::getUndoManager() const } //============================================================================== -const char* const ComponentDocument::jucerIDProperty = "jucerID"; - const String ComponentDocument::getJucerIDFor (Component* c) { if (c == 0) diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h index f74887f59b..d8f0988870 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h @@ -148,18 +148,18 @@ public: UndoManager* getUndoManager() const; void beginNewTransaction(); - void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property); + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property); void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged); void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); - static const char* const idProperty; - static const char* const compBoundsProperty; - static const char* const memberNameProperty; - static const char* const compNameProperty; - static const char* const compTooltipProperty; - static const char* const compFocusOrderProperty; + static const Identifier idProperty; + static const Identifier compBoundsProperty; + static const Identifier memberNameProperty; + static const Identifier compNameProperty; + static const Identifier compTooltipProperty; + static const Identifier compFocusOrderProperty; - static const char* const jucerIDProperty; + static const Identifier jucerIDProperty; static const String getJucerIDFor (Component* c); //============================================================================== @@ -192,12 +192,12 @@ private: Value tempCanvasWidth, tempCanvasHeight; void checkRootObject(); - void createSubTreeIfNotThere (const String& name); + void createSubTreeIfNotThere (const Identifier& name); void addMarkerMenuItem (int i, const Coordinate& coord, const String& name, PopupMenu& menu, bool isAnchor1, const String& fullCoordName); - Value getRootValueUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); } - Value getRootValueNonUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, 0); } + Value getRootValueUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); } + Value getRootValueNonUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, 0); } void writeCode (OutputStream& cpp, OutputStream& header); void writeMetadata (OutputStream& out); diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp index ccc4b9b155..7bccc6fd87 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp @@ -248,7 +248,7 @@ void DrawableDocument::addImage (const File& imageFile) } //============================================================================== -void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const var::identifier& name) +void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const Identifier& name) { changed(); } @@ -392,7 +392,7 @@ const String DrawableDocument::MarkerList::getNonexistentMarkerName (const Strin const String DrawableDocument::getNonexistentMarkerName (const String& name) { - String n (CodeFormatting::makeValidIdentifier (name, false, true, false)); + String n (CodeHelpers::makeValidIdentifier (name, false, true, false)); int suffix = 2; while (markersX->getMarkerNamed (n).isValid() || markersY->getMarkerNamed (n).isValid()) diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h index 8e118843d5..957d6bf453 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h @@ -92,7 +92,7 @@ public: void renameAnchor (const String& oldName, const String& newName); //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& name); + void valueTreePropertyChanged (ValueTree& tree, const Identifier& name); void valueTreeChildrenChanged (ValueTree& tree); void valueTreeParentChanged (ValueTree& tree); @@ -108,8 +108,8 @@ private: void checkRootObject(); - Value getRootValueUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); } - Value getRootValueNonUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, 0); } + Value getRootValueUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); } + Value getRootValueNonUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, 0); } void save (OutputStream& output); bool load (InputStream& input); diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp index b6a18d79e4..cb26b10633 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp @@ -35,9 +35,9 @@ static bool fillInNewCppFileTemplate (const File& file, const Project::Item& ite .replace ("FILENAME", file.getFileName(), false) .replace ("DATE", Time::getCurrentTime().toString (true, true, true), false) .replace ("AUTHOR", SystemStats::getFullUserName(), false) - .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (file), false); + .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (file), false); - return FileUtils::overwriteFileWithNewDataIfDifferent (file, s); + return FileHelpers::overwriteFileWithNewDataIfDifferent (file, s); } //============================================================================== diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp index 378cca6d9d..5e4c6fa624 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp @@ -33,13 +33,13 @@ //============================================================================== namespace Tags { - const char* const projectRoot = "JUCERPROJECT"; - const char* const projectMainGroup = "MAINGROUP"; - const char* const group = "GROUP"; - const char* const file = "FILE"; - const char* const configurations = "CONFIGURATIONS"; - const char* const configuration = "CONFIGURATION"; - const char* const exporters = "EXPORTFORMATS"; + const Identifier projectRoot ("JUCERPROJECT"); + const Identifier projectMainGroup ("MAINGROUP"); + const Identifier group ("GROUP"); + const Identifier file ("FILE"); + const Identifier configurations ("CONFIGURATIONS"); + const Identifier configuration ("CONFIGURATION"); + const Identifier exporters ("EXPORTFORMATS"); } const char* Project::projectFileExtension = ".jucer"; @@ -122,7 +122,7 @@ void Project::setMissingDefaultValues() if (! projectRoot.getChildWithName (Tags::exporters).isValid()) createDefaultExporters(); - const String sanitisedProjectName (CodeFormatting::makeValidIdentifier (getProjectName().toString(), false, true, false)); + const String sanitisedProjectName (CodeHelpers::makeValidIdentifier (getProjectName().toString(), false, true, false)); if (! projectRoot.hasProperty ("buildVST")) { @@ -157,7 +157,7 @@ const String Project::loadDocument (const File& file) XmlDocument doc (file); ScopedPointer xml (doc.getDocumentElement()); - if (xml == 0 || ! xml->hasTagName (Tags::projectRoot)) + if (xml == 0 || ! xml->hasTagName (Tags::projectRoot.toString())) return "Not a valid Jucer project!"; ValueTree newTree (ValueTree::fromXml (*xml)); @@ -184,7 +184,7 @@ const String Project::saveDocument (const File& file) getJuceConfigFlags (flags); } - if (FileUtils::isJuceFolder (getLocalJuceFolder())) + if (FileHelpers::isJuceFolder (getLocalJuceFolder())) StoredSettings::getInstance()->setLastKnownJuceFolder (getLocalJuceFolder().getFullPathName()); StoredSettings::getInstance()->recentFiles.addFile (file); @@ -207,7 +207,7 @@ void Project::setLastDocumentOpened (const File& file) } //============================================================================== -void Project::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) +void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { if (isLibrary()) getJuceLinkageModeValue() = (int) notLinkedToJuce; @@ -310,7 +310,7 @@ const File Project::getLocalJuceFolder() { File f (resolveFilename (exp->getJuceFolder().toString())); - if (FileUtils::isJuceFolder (f)) + if (FileHelpers::isJuceFolder (f)) return f; } diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h index 0b0c550e7a..1941d74ce0 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h @@ -85,7 +85,7 @@ public: Value getVersion() const { return getProjectValue ("version"); } Value getBundleIdentifier() const { return getProjectValue ("bundleIdentifier"); } - void setBundleIdentifierToDefault() { getBundleIdentifier() = "com.yourcompany." + CodeFormatting::makeValidIdentifier (getProjectName().toString(), false, true, false); } + void setBundleIdentifierToDefault() { getBundleIdentifier() = "com.yourcompany." + CodeHelpers::makeValidIdentifier (getProjectName().toString(), false, true, false); } //============================================================================== enum JuceLinkage @@ -107,7 +107,7 @@ public: bool isUsingMultipleTemplateFiles() const { return getJuceLinkageMode() == useAmalgamatedJuceViaMultipleTemplates; } //============================================================================== - Value getProjectValue (const var::identifier& name) const { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); } + Value getProjectValue (const Identifier& name) const { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); } Value shouldBuildVST() const { return getProjectValue ("buildVST"); } Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); } @@ -281,7 +281,7 @@ public: const String getFileTemplate (const String& templateName); //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property); + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property); void valueTreeChildrenChanged (ValueTree& tree); void valueTreeParentChanged (ValueTree& tree); diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h index 6a17d45a26..bcba4b7134 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h @@ -145,7 +145,7 @@ public: MemoryOutputStream mo; writeVC6Project (mo); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo)) return "Can't write to the VC project file: " + getDSPFile().getFullPathName(); } @@ -153,7 +153,7 @@ public: MemoryOutputStream mo; writeDSWFile (mo); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo)) return "Can't write to the VC solution file: " + getDSWFile().getFullPathName(); } } @@ -168,7 +168,7 @@ public: MemoryOutputStream mo; masterXml.writeToStream (mo, String::empty, false, true, "UTF-8", 10); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); } @@ -176,7 +176,7 @@ public: MemoryOutputStream mo; writeSolutionFile (mo); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); } } @@ -370,7 +370,7 @@ private: { RelativePath rtasFolder (getRTASFolder().toString(), RelativePath::unknown); defines.add ("JucePlugin_WinBag_path=" - + CodeFormatting::addEscapeChars (rtasFolder.getChildFile ("WinBag") + + CodeHelpers::addEscapeChars (rtasFolder.getChildFile ("WinBag") .toWindowsStyle().quoted())); } @@ -452,8 +452,8 @@ private: const String binaryName (File::createLegalFileName (config.getTargetBinaryName().toString())); xml.setAttribute ("Name", createConfigName (config)); - xml.setAttribute ("OutputDirectory", FileUtils::windowsStylePath (binariesPath)); - xml.setAttribute ("IntermediateDirectory", FileUtils::windowsStylePath (intermediatesPath)); + xml.setAttribute ("OutputDirectory", FileHelpers::windowsStylePath (binariesPath)); + xml.setAttribute ("IntermediateDirectory", FileHelpers::windowsStylePath (intermediatesPath)); xml.setAttribute ("ConfigurationType", (project.isAudioPlugin() || project.isBrowserPlugin() || isLibraryDLL()) ? "2" : (project.isLibrary() ? "4" : "1")); xml.setAttribute ("UseOfMFC", "0"); @@ -485,7 +485,7 @@ private: midl->setAttribute ("MkTypLibCompatible", "true"); midl->setAttribute ("SuppressStartupBanner", "true"); midl->setAttribute ("TargetEnvironment", "1"); - midl->setAttribute ("TypeLibraryName", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".tlb")); + midl->setAttribute ("TypeLibraryName", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".tlb")); midl->setAttribute ("HeaderFileName", ""); } @@ -512,10 +512,10 @@ private: : (isDebug ? 1 : 0)); // MT static compiler->setAttribute ("RuntimeTypeInfo", "true"); compiler->setAttribute ("UsePrecompiledHeader", "0"); - compiler->setAttribute ("PrecompiledHeaderFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".pch")); - compiler->setAttribute ("AssemblerListingLocation", FileUtils::windowsStylePath (intermediatesPath + "/")); - compiler->setAttribute ("ObjectFile", FileUtils::windowsStylePath (intermediatesPath + "/")); - compiler->setAttribute ("ProgramDataBaseFileName", FileUtils::windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("PrecompiledHeaderFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pch")); + compiler->setAttribute ("AssemblerListingLocation", FileHelpers::windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("ObjectFile", FileHelpers::windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("ProgramDataBaseFileName", FileHelpers::windowsStylePath (intermediatesPath + "/")); compiler->setAttribute ("WarningLevel", project.isLibrary() ? "4" : "3"); compiler->setAttribute ("SuppressStartupBanner", "true"); @@ -538,7 +538,7 @@ private: { XmlElement* linker = createToolElement (xml, "VCLinkerTool"); - linker->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName)); + linker->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName)); linker->setAttribute ("SuppressStartupBanner", "true"); if (project.getJuceLinkageMode() == Project::useLinkedJuce) @@ -546,7 +546,7 @@ private: linker->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : ""); linker->setAttribute ("GenerateDebugInformation", isDebug ? "true" : "false"); - linker->setAttribute ("ProgramDatabaseFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); + linker->setAttribute ("ProgramDatabaseFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); linker->setAttribute ("SubSystem", project.isCommandLineApp() ? "1" : "2"); if (! isDebug) @@ -579,17 +579,17 @@ private: XmlElement* linker = createToolElement (xml, "VCLinkerTool"); String extraLinkerOptions (getExtraLinkerFlags().toString()); - extraLinkerOptions << " /IMPLIB:" << FileUtils::windowsStylePath (binariesPath + "/" + outputFileName.upToLastOccurrenceOf (".", false, false) + ".lib"); + extraLinkerOptions << " /IMPLIB:" << FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName.upToLastOccurrenceOf (".", false, false) + ".lib"); linker->setAttribute ("AdditionalOptions", extraLinkerOptions.trim()); - linker->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName)); + linker->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName)); linker->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : ""); } else { XmlElement* librarian = createToolElement (xml, "VCLibrarianTool"); - librarian->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName)); + librarian->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName)); librarian->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : ""); } } @@ -601,7 +601,7 @@ private: { XmlElement* bscMake = createToolElement (xml, "VCBscMakeTool"); bscMake->setAttribute ("SuppressStartupBanner", "true"); - bscMake->setAttribute ("OutputFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); + bscMake->setAttribute ("OutputFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); } createToolElement (xml, "VCFxCopTool"); @@ -727,7 +727,7 @@ private: targetList << "# Name \"" << configName << '"' << newLine; const String binariesPath (getConfigTargetPath (config)); - const String targetBinary (FileUtils::windowsStylePath (binariesPath + "/" + getBinaryFileForConfig (config))); + const String targetBinary (FileHelpers::windowsStylePath (binariesPath + "/" + getBinaryFileForConfig (config))); const String optimisationFlag (((int) config.getOptimisationLevel().getValue() <= 1) ? "Od" : (config.getOptimisationLevel() == 2 ? "O2" : "O3")); const String defines (getPreprocessorDefs (config, " /D ")); const bool isDebug = (bool) config.isDebug().getValue(); diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h index b8d6adf82e..ef054ef86e 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h @@ -101,7 +101,7 @@ public: writeMakefile (mo, files); const File makefile (getTargetFolder().getChildFile ("Makefile")); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (makefile, mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (makefile, mo)) return "Can't write to the Makefile: " + makefile.getFullPathName(); return String::empty; @@ -152,7 +152,7 @@ private: headerPaths.insert (0, "/usr/include"); for (int i = 0; i < headerPaths.size(); ++i) - out << " -I " << FileUtils::unixStylePath (headerPaths[i]).quoted(); + out << " -I " << FileHelpers::unixStylePath (headerPaths[i]).quoted(); } void writeCppFlags (OutputStream& out, const Project::BuildConfiguration& config) diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h index 3f8a347b6b..60cdeb923c 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h @@ -122,7 +122,7 @@ public: MemoryOutputStream mo; writeProjectFile (mo); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (projectFile, mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo)) return "Can't write to file: " + projectFile.getFullPathName(); } @@ -266,7 +266,7 @@ private: MemoryOutputStream mo; plist.writeToStream (mo, ""); - return FileUtils::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo); + return FileHelpers::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo); } const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) @@ -566,7 +566,7 @@ private: for (int j = 0; j < o.getNumProperties(); ++j) { - const var::identifier propertyName (o.getPropertyName(j)); + const Identifier propertyName (o.getPropertyName(j)); String val (o.getProperty (propertyName).toString()); if (val.isEmpty() || (val.containsAnyOf (" \t;<>()=,-\r\n") @@ -574,7 +574,7 @@ private: || val.trimStart().startsWithChar ('{')))) val = val.quoted(); - output << propertyName.name << " = " << val << "; "; + output << propertyName.toString() << " = " << val << "; "; } output << "};\n"; diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp index 29969a74ea..3b781802bb 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp @@ -75,7 +75,7 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int File juceFolder (StoredSettings::getInstance()->getLastKnownJuceFolder()); File target (exp->getTargetFolder()); - if (FileUtils::shouldPathsBeRelative (juceFolder.getFullPathName(), project.getFile().getFullPathName())) + if (FileHelpers::shouldPathsBeRelative (juceFolder.getFullPathName(), project.getFile().getFullPathName())) exp->getJuceFolder() = juceFolder.getRelativePathFrom (project.getFile().getParentDirectory()); else exp->getJuceFolder() = juceFolder.getFullPathName(); @@ -121,7 +121,7 @@ const String ProjectExporter::getIncludePathForFileInJuceFolder (const String& p if (juceFolderPath.startsWithChar ('<')) { - juceFolderPath = FileUtils::unixStylePath (File::addTrailingSeparator (juceFolderPath.substring (1).dropLastCharacters(1))); + juceFolderPath = FileHelpers::unixStylePath (File::addTrailingSeparator (juceFolderPath.substring (1).dropLastCharacters(1))); if (juceFolderPath == "/") juceFolderPath = String::empty; diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h index 9289372893..720c4581b9 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h @@ -62,7 +62,7 @@ public: const File getTargetFolder() const; const ValueTree& getSettings() const { return settings; } - Value getSetting (const var::identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); } + Value getSetting (const Identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); } Value getJuceFolder() const { return getSetting ("juceFolder"); } Value getTargetLocation() const { return getSetting ("targetFolder"); } diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h index 21c54d6c4e..b72d9fc398 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h @@ -123,7 +123,7 @@ private: MemoryOutputStream mo; xml->writeToStream (mo, String::empty); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (projectFile, mo)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo)) errors.add ("Couldn't write to the target file!"); } } @@ -192,7 +192,7 @@ private: << newLine << "*/" << newLine << newLine - << CodeFormatting::createIncludeStatement (appConfigFile, appConfigFile) << newLine; + << CodeHelpers::createIncludeStatement (appConfigFile, appConfigFile) << newLine; if (fileNumber == 0) writeInclude (out, project.isUsingFullyAmalgamatedFile() ? "juce_amalgamated.cpp" @@ -216,7 +216,7 @@ private: << "#define " << headerGuard << newLine << newLine; if (hasAppConfigFile) - out << CodeFormatting::createIncludeStatement (appConfigFile, appConfigFile) << newLine; + out << CodeHelpers::createIncludeStatement (appConfigFile, appConfigFile) << newLine; if (project.getJuceLinkageMode() != Project::notLinkedToJuce) { @@ -228,13 +228,13 @@ private: } if (binaryDataCpp.exists()) - out << CodeFormatting::createIncludeStatement (binaryDataCpp.withFileExtension (".h"), appConfigFile) << newLine; + out << CodeHelpers::createIncludeStatement (binaryDataCpp.withFileExtension (".h"), appConfigFile) << newLine; out << newLine << "namespace ProjectInfo" << newLine << "{" << newLine - << " const char* const projectName = " << CodeFormatting::addEscapeChars (project.getProjectName().toString()).quoted() << ";" << newLine - << " const char* const versionString = " << CodeFormatting::addEscapeChars (project.getVersion().toString()).quoted() << ";" << newLine + << " const char* const projectName = " << CodeHelpers::addEscapeChars (project.getProjectName().toString()).quoted() << ";" << newLine + << " const char* const versionString = " << CodeHelpers::addEscapeChars (project.getVersion().toString()).quoted() << ";" << newLine << " const int versionNumber = " << createVersionCode (project.getVersion().toString()) << ";" << newLine << "}" << newLine << newLine @@ -370,7 +370,7 @@ private: bool replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData) { - if (! FileUtils::overwriteFileWithNewDataIfDifferent (f, newData)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (f, newData)) { errors.add ("Can't write to file: " + f.getFullPathName()); return false; diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp index 490426cd89..effd1c47c8 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp @@ -79,30 +79,30 @@ public: for (int i = project.getNumConfigurations(); --i >= 0;) project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); - String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); + String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); String initCode, shutdownCode, anotherInstanceStartedCode, privateMembers, memberInitialisers; if (createWindow) { - appHeaders << newLine << CodeFormatting::createIncludeStatement (mainWindowH, mainCppFile); + appHeaders << newLine << CodeHelpers::createIncludeStatement (mainWindowH, mainCppFile); memberInitialisers = " : mainWindow (0)"; initCode = "mainWindow = new " + windowClassName + "();"; shutdownCode = "deleteAndZero (mainWindow);"; privateMembers = windowClassName + "* mainWindow;"; String windowH = project.getFileTemplate ("jucer_WindowTemplate_h") - .replace ("INCLUDES", CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainWindowH), false) + .replace ("INCLUDES", CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainWindowH), false) .replace ("WINDOWCLASS", windowClassName, false) - .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (mainWindowH), false); + .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (mainWindowH), false); String windowCpp = project.getFileTemplate ("jucer_WindowTemplate_cpp") - .replace ("INCLUDES", CodeFormatting::createIncludeStatement (mainWindowH, mainWindowCpp), false) + .replace ("INCLUDES", CodeHelpers::createIncludeStatement (mainWindowH, mainWindowCpp), false) .replace ("WINDOWCLASS", windowClassName, false); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainWindowH, windowH)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainWindowH, windowH)) failedFiles.add (mainWindowH.getFullPathName()); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainWindowCpp, windowCpp)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainWindowCpp, windowCpp)) failedFiles.add (mainWindowCpp.getFullPathName()); group.addFile (mainWindowCpp, -1); @@ -113,17 +113,17 @@ public: { String mainCpp = project.getFileTemplate ("jucer_MainTemplate_cpp") .replace ("APPHEADERS", appHeaders, false) - .replace ("APPCLASSNAME", CodeFormatting::makeValidIdentifier (appTitle + "Application", false, true, false), false) + .replace ("APPCLASSNAME", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false) .replace ("MEMBERINITIALISERS", memberInitialisers, false) .replace ("APPINITCODE", initCode, false) .replace ("APPSHUTDOWNCODE", shutdownCode, false) - .replace ("APPNAME", CodeFormatting::addEscapeChars (appTitle), false) + .replace ("APPNAME", CodeHelpers::addEscapeChars (appTitle), false) .replace ("APPVERSION", "1.0", false) .replace ("ALLOWMORETHANONEINSTANCE", "true", false) .replace ("ANOTHERINSTANCECODE", anotherInstanceStartedCode, false) .replace ("PRIVATEMEMBERS", privateMembers, false); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) failedFiles.add (mainCppFile.getFullPathName()); group.addFile (mainCppFile, -1); @@ -186,12 +186,12 @@ public: if (createMainCpp) { - String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); + String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); String mainCpp = project.getFileTemplate ("jucer_MainConsoleAppTemplate_cpp") .replace ("APPHEADERS", appHeaders, false); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) failedFiles.add (mainCppFile.getFullPathName()); group.addFile (mainCppFile, -1); @@ -228,7 +228,7 @@ public: if (! getSourceFilesFolder().createDirectory()) failedFiles.add (getSourceFilesFolder().getFullPathName()); - String filterClassName = CodeFormatting::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor"; + String filterClassName = CodeHelpers::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor"; filterClassName = filterClassName.substring (0, 1).toUpperCase() + filterClassName.substring (1); String editorClassName = filterClassName + "Editor"; @@ -247,42 +247,42 @@ public: for (int i = project.getNumConfigurations(); --i >= 0;) project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); - String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), filterCppFile)); - appHeaders << newLine << CodeFormatting::createIncludeStatement (project.getPluginCharacteristicsFile(), filterCppFile); + String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), filterCppFile)); + appHeaders << newLine << CodeHelpers::createIncludeStatement (project.getPluginCharacteristicsFile(), filterCppFile); String filterCpp = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_cpp") - .replace ("FILTERHEADERS", CodeFormatting::createIncludeStatement (filterHFile, filterCppFile) - + newLine + CodeFormatting::createIncludeStatement (editorHFile, filterCppFile), false) + .replace ("FILTERHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile) + + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false) .replace ("FILTERCLASSNAME", filterClassName, false) .replace ("EDITORCLASSNAME", editorClassName, false); String filterH = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_h") .replace ("APPHEADERS", appHeaders, false) .replace ("FILTERCLASSNAME", filterClassName, false) - .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (filterHFile), false); + .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (filterHFile), false); String editorCpp = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_cpp") - .replace ("EDITORCPPHEADERS", CodeFormatting::createIncludeStatement (filterHFile, filterCppFile) - + newLine + CodeFormatting::createIncludeStatement (editorHFile, filterCppFile), false) + .replace ("EDITORCPPHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile) + + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false) .replace ("FILTERCLASSNAME", filterClassName, false) .replace ("EDITORCLASSNAME", editorClassName, false); String editorH = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_h") - .replace ("EDITORHEADERS", appHeaders + newLine + CodeFormatting::createIncludeStatement (filterHFile, filterCppFile), false) + .replace ("EDITORHEADERS", appHeaders + newLine + CodeHelpers::createIncludeStatement (filterHFile, filterCppFile), false) .replace ("FILTERCLASSNAME", filterClassName, false) .replace ("EDITORCLASSNAME", editorClassName, false) - .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (editorHFile), false); + .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (editorHFile), false); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp)) failedFiles.add (filterCppFile.getFullPathName()); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (filterHFile, filterH)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterHFile, filterH)) failedFiles.add (filterHFile.getFullPathName()); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp)) failedFiles.add (editorCppFile.getFullPathName()); - if (! FileUtils::overwriteFileWithNewDataIfDifferent (editorHFile, editorH)) + if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorHFile, editorH)) failedFiles.add (editorHFile.getFullPathName()); group.addFile (filterCppFile, -1); @@ -381,7 +381,7 @@ Project* ProjectWizard::runWizard (Component* ownerWindow_) failedFiles.add (newProjectFolder.getFullPathName()); } - if (FileUtils::containsAnyNonHiddenFiles (newProjectFolder)) + if (FileHelpers::containsAnyNonHiddenFiles (newProjectFolder)) { if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, "New Juce Project", "The folder you chose isn't empty - are you sure you want to create the project there?\n\nAny existing files with the same names may be overwritten by the new files.")) @@ -480,7 +480,7 @@ Project* ProjectWizard::runNewProjectWizard (Component* ownerWindow) if (aw.runModalLoop() == 0) return 0; - if (FileUtils::isJuceFolder (juceFolderSelector.getCurrentFile())) + if (FileHelpers::isJuceFolder (juceFolderSelector.getCurrentFile())) { wizard = createWizard (aw.getComboBoxComponent ("type")->getSelectedItemIndex()); break; diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp index b47a4af618..18ae54deae 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp @@ -100,16 +100,6 @@ int64 ResourceFile::getTotalDataSize() const return total; } -static int calcResourceHashCode (const String& s) -{ - const char* t = s.toUTF8(); - int hash = 0; - while (*t != 0) - hash = 31 * hash + *t++; - - return hash; -} - bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& header) { String comment; @@ -125,15 +115,15 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& << comment; if (juceHeader.exists()) - header << CodeFormatting::createIncludeStatement (juceHeader, cppFile) << newLine; + header << CodeHelpers::createIncludeStatement (juceHeader, cppFile) << newLine; const String namespaceName (className); - StringArray variableNames; + StringArray variableNames, returnCodes; int i; for (i = 0; i < files.size(); ++i) { - String variableNameRoot (CodeFormatting::makeValidIdentifier (files.getUnchecked(i)->getFileName() + String variableNameRoot (CodeHelpers::makeValidIdentifier (files.getUnchecked(i)->getFileName() .replaceCharacters (" .", "__") .retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"), false, true, false)); @@ -144,32 +134,19 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& variableName = variableNameRoot + String (suffix++); variableNames.add (variableName); + returnCodes.add ("numBytes = " + namespaceName + "::" + variableName + "Size; return " + + namespaceName + "::" + variableName + ";"); } - cpp << CodeFormatting::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine + cpp << CodeHelpers::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine << newLine << newLine << "const char* " << namespaceName << "::getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()" << newLine - << "{" << newLine - << " int hash = 0;" << newLine - << " if (resourceNameUTF8 != 0)" << newLine - << " while (*resourceNameUTF8 != 0)" << newLine - << " hash = 31 * hash + *resourceNameUTF8++;" << newLine - << newLine - << " switch (hash)" << newLine - << " {" << newLine; + << "{" << newLine; - for (i = 0; i < files.size(); ++i) - { - cpp << " case 0x" << hexString8Digits (calcResourceHashCode (variableNames[i])) - << ": numBytes = " << namespaceName << "::" << variableNames[i] << "Size; return " - << namespaceName << "::" << variableNames[i] << ";" << newLine; - } + CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4); - cpp << " default: break;" << newLine - << " }" << newLine - << newLine - << " numBytes = 0;" << newLine + cpp << " numBytes = 0;" << newLine << " return 0;" << newLine << "}" << newLine << newLine; @@ -199,7 +176,7 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& { MemoryBlock data; fileStream->readIntoMemoryBlock (data); - CodeFormatting::writeDataAsCppLiteral (data, cpp); + CodeHelpers::writeDataAsCppLiteral (data, cpp); } cpp << newLine << newLine @@ -231,8 +208,8 @@ bool ResourceFile::write (const File& cppFile) cppOut = 0; hppOut = 0; - return (FileUtils::areFilesIdentical (tempCpp.getFile(), tempCpp.getTargetFile()) || tempCpp.overwriteTargetFileWithTemporary()) - && (FileUtils::areFilesIdentical (tempH.getFile(), tempH.getTargetFile()) || tempH.overwriteTargetFileWithTemporary()); + return (tempCpp.getFile().hasIdenticalContentTo (tempCpp.getTargetFile()) || tempCpp.overwriteTargetFileWithTemporary()) + && (tempH.getFile().hasIdenticalContentTo (tempH.getTargetFile()) || tempH.overwriteTargetFileWithTemporary()); } } diff --git a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp index 38bf48bdd7..6719826221 100644 --- a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp +++ b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp @@ -58,10 +58,6 @@ extern const unsigned char %%className%%_ComponentStateData[]; %%staticMemberDefinitions%% -//============================================================================== -/* This data contains the ValueTree that holds all the Jucer-generated settings for the components */ -const unsigned char %%className%%_ComponentStateData[] = %%statedata%%; - //============================================================================== //======================= Jucer Information Section ========================== //============================================================================== diff --git a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h index f2b14961f7..fcb197e0af 100644 --- a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h +++ b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h @@ -57,8 +57,6 @@ private: %%privateMemberDeclarations%% //============================================================================== - ValueTree componentState; - // (prevent copy constructor and operator= being generated..) %%className%% (const %%className%%&); %%className%%& operator= (const %%className%%&); diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h index 75ec2a305a..be5046be39 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h @@ -189,7 +189,7 @@ public: float getMarkerPosition (const ValueTree& marker, bool isX) { ComponentDocument& doc = getDocument(); - return doc.getMarkerList (isX).getCoordinate (marker).resolve (doc); + return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (doc); } }; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h index 9867899a68..e8d14cabe0 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h @@ -52,7 +52,7 @@ public: return true; } - void paintButton (Graphics& g, const bool over, const bool down) + void paintButton (Graphics& g, bool over, bool down) { Path p; p.addRoundedRectangle (1.5f, 2.5f, getWidth() - 3.0f, getHeight() - 5.0f, 3.0f); diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h index b4bc06c77a..b349746dde 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h @@ -48,7 +48,7 @@ namespace ComponentEditorTreeView } //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) {} + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property) {} void valueTreeParentChanged (ValueTree& tree) {} void valueTreeChildrenChanged (ValueTree& tree) {} @@ -128,7 +128,7 @@ namespace ComponentEditorTreeView const String getDragSourceDescription() { return getDragIdFor (editor); } - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { if (property == ComponentDocument::memberNameProperty) repaintItem(); @@ -303,7 +303,7 @@ namespace ComponentEditorTreeView const String getDragSourceDescription() { return String::empty; } - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { if (property == MarkerListBase::getMarkerNameProperty()) repaintItem(); diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h index 3e1ee597b8..e25f8d5495 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h @@ -79,7 +79,7 @@ public: } //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { } diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp index 419263b26b..f58846a25c 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp @@ -24,6 +24,7 @@ */ #include "../../jucer_Headers.h" +#include "../../utility/jucer_TickIterator.h" #include "jucer_EditorCanvas.h" #include "jucer_EditorPanel.h" @@ -53,7 +54,7 @@ public: g.drawRect (0, 0, getWidth(), getHeight(), borderThickness); } - void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updatePosition(); } + void valueTreePropertyChanged (ValueTree&, const Identifier&) { updatePosition(); } void valueTreeChildrenChanged (ValueTree&) { updatePosition(); } void valueTreeParentChanged (ValueTree&) { @@ -346,7 +347,7 @@ public: MarkerListBase& getMarkerList() { return canvas->getMarkerList (isX); } - void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updatePosition(); } + void valueTreePropertyChanged (ValueTree&, const Identifier&) { updatePosition(); } void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) {} void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} @@ -536,7 +537,7 @@ public: } } - void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updateMarkers(); } + void valueTreePropertyChanged (ValueTree&, const Identifier&) { updateMarkers(); } void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { updateMarkers(); } void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h index 9546c1dab6..f58f217377 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h @@ -54,7 +54,7 @@ public: void drawYAxis (Graphics& g, const Rectangle& r); //============================================================================== - void valueTreePropertyChanged (ValueTree&, const var::identifier&) { update(); } + void valueTreePropertyChanged (ValueTree&, const Identifier&) { update(); } void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { update(); } void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h index b2014730c6..8ae795d117 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h @@ -62,7 +62,7 @@ public: verticalSnapPositions.add (SnapLine (floatPos.getX(), floatPos.getY(), floatPos.getBottom())); if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge())) - verticalSnapPositions.add (SnapLine ((int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom())); + verticalSnapPositions.add (SnapLine ((float) (int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom())); if (zone.isDraggingWholeObject() || zone.isDraggingRightEdge()) verticalSnapPositions.add (SnapLine (floatPos.getRight(), floatPos.getY(), floatPos.getBottom())); @@ -71,7 +71,7 @@ public: horizontalSnapPositions.add (SnapLine (floatPos.getY(), floatPos.getX(), floatPos.getRight())); if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge())) - horizontalSnapPositions.add (SnapLine ((int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight())); + horizontalSnapPositions.add (SnapLine ((float) (int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight())); if (zone.isDraggingWholeObject() || zone.isDraggingBottomEdge()) horizontalSnapPositions.add (SnapLine (floatPos.getBottom(), floatPos.getX(), floatPos.getRight())); @@ -116,7 +116,7 @@ public: } if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge())) - verticalSnapTargets.add (SnapLine ((int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom())); + verticalSnapTargets.add (SnapLine ((float) (int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom())); if (isDraggingUpDown()) { @@ -125,7 +125,7 @@ public: } if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge())) - horizontalSnapTargets.add (SnapLine ((int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight())); + horizontalSnapTargets.add (SnapLine ((float) (int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight())); } mergeSnapLines (verticalSnapTargets); diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp index 02c8154f93..cd8ecd049a 100644 --- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp +++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp @@ -57,7 +57,7 @@ void GroupInformationComponent::paintListBoxItem (int rowNumber, Graphics& g, in } //============================================================================== -void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property) +void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { list->updateContent(); } diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h index cb542340c2..dbffee4e77 100644 --- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h +++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h @@ -48,7 +48,7 @@ public: Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); //============================================================================== - void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property); + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property); void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged); void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp index 953c010d11..c240fe68bb 100644 --- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp +++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp @@ -362,7 +362,7 @@ void ProjectTreeViewBase::itemDropped (const String& sourceDescription, Componen } //============================================================================== -void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) +void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const Identifier& property) { if (tree == item.getNode()) repaintItem(); diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h index 3ac6cfae08..14bd610492 100644 --- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h +++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h @@ -71,7 +71,7 @@ public: virtual ProjectTreeViewBase* findTreeViewItem (const Project::Item& itemToFind); //============================================================================== - void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property); + void valueTreePropertyChanged (ValueTree& tree, const Identifier& property); void valueTreeChildrenChanged (ValueTree& tree); void valueTreeParentChanged (ValueTree& tree); diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp new file mode 100644 index 0000000000..68e4c98a76 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp @@ -0,0 +1,456 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "jucer_CodeHelpers.h" + + +//============================================================================== +namespace CodeHelpers +{ + const String indent (const String& code, const int numSpaces, bool indentFirstLine) + { + if (numSpaces == 0) + return code; + + const String space (String::repeatedString (" ", numSpaces)); + + StringArray lines; + lines.addLines (code); + + for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i) + { + String s (lines[i].trimEnd()); + if (s.isNotEmpty()) + s = space + s; + + lines.set (i, s); + } + + return lines.joinIntoString (newLine); + } + + const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates) + { + if (s.isEmpty()) + return "unknown"; + + if (removeColons) + s = s.replaceCharacters (".,;:/@", "______"); + else + s = s.replaceCharacters (".,;/@", "_____"); + + int i; + for (i = s.length(); --i > 0;) + if (CharacterFunctions::isLetter (s[i]) + && CharacterFunctions::isLetter (s[i - 1]) + && CharacterFunctions::isUpperCase (s[i]) + && ! CharacterFunctions::isUpperCase (s[i - 1])) + s = s.substring (0, i) + " " + s.substring (i); + + String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789"); + if (allowTemplates) + allowedChars += "<>"; + + if (! removeColons) + allowedChars += ":"; + + StringArray words; + words.addTokens (s.retainCharacters (allowedChars), false); + words.trim(); + + String n (words[0]); + + if (capitalise) + n = n.toLowerCase(); + + for (i = 1; i < words.size(); ++i) + { + if (capitalise && words[i].length() > 1) + n << words[i].substring (0, 1).toUpperCase() + << words[i].substring (1).toLowerCase(); + else + n << words[i]; + } + + if (CharacterFunctions::isDigit (n[0])) + n = "_" + n; + + if (CPlusPlusCodeTokeniser::isReservedKeyword (n)) + n << '_'; + + return n; + } + + template + static void writeEscapeChars (OutputStream& out, const CharType* data, const int numChars, + const int maxCharsOnLine, const bool breakAtNewLines, const bool replaceSingleQuotes) + { + int charsOnLine = 0; + bool lastWasHexEscapeCode = false; + + for (int i = 0; i < numChars || numChars < 0; ++i) + { + const CharType c = data[i]; + bool startNewLine = false; + + switch (c) + { + case '\t': out << "\\t"; lastWasHexEscapeCode = false; break; + case '\r': out << "\\r"; lastWasHexEscapeCode = false; break; + case '\n': out << "\\n"; lastWasHexEscapeCode = false; startNewLine = breakAtNewLines; break; + case '\\': out << "\\\\"; lastWasHexEscapeCode = false; break; + case '\"': out << "\\\""; lastWasHexEscapeCode = false; break; + + case 0: + if (numChars < 0) + return; + + out << "\\0"; + lastWasHexEscapeCode = true; + break; + + case '\'': + if (replaceSingleQuotes) + { + out << "\\\'"; + lastWasHexEscapeCode = false; + break; + } + + // deliberate fall-through... + + default: + if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) + && ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) + { + out << (char) c; + lastWasHexEscapeCode = false; + } + else + { + out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) (unsigned int) c); + lastWasHexEscapeCode = true; + } + + break; + } + + if ((startNewLine || (maxCharsOnLine > 0 && ++charsOnLine >= maxCharsOnLine)) + && (numChars < 0 || i < numChars - 1)) + { + charsOnLine = 0; + out << "\"" << newLine << "\""; + } + } + } + + const String addEscapeChars (const String& s) + { + MemoryOutputStream out; + writeEscapeChars (out, (const juce_wchar*) s, -1, -1, false, true); + return out.toUTF8(); + } + + const String createIncludeStatement (const File& includeFile, const File& targetFile) + { + return "#include \"" + FileHelpers::unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + "\""; + } + + const String makeHeaderGuardName (const File& file) + { + return "__" + file.getFileName().toUpperCase() + .replaceCharacters (" .", "__") + .retainCharacters ("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + + "_" + String::toHexString (file.hashCode()).toUpperCase() + "__"; + } + + const String stringLiteral (const String& text) + { + if (text.isEmpty()) + return "String::empty"; + + return CodeHelpers::addEscapeChars (text).quoted(); + } + + const String boolLiteral (const bool b) + { + return b ? "true" : "false"; + } + + const String floatLiteral (float v) + { + String s ((double) v, 4); + + if (s.containsChar ('.')) + { + s = s.trimCharactersAtEnd ("0"); + if (s.endsWithChar ('.')) + s << '0'; + + s << 'f'; + } + else + { + s << ".0f"; + } + + return s; + } + + const String doubleLiteral (double v) + { + String s (v, 7); + + if (s.containsChar ('.')) + { + s = s.trimCharactersAtEnd ("0"); + if (s.endsWithChar ('.')) + s << '0'; + } + else + { + s << ".0"; + } + + return s; + } + + const String colourToCode (const Colour& col) + { + const Colour colours[] = + { + #define COL(col) Colours::col, + #include "jucer_Colours.h" + #undef COL + Colours::transparentBlack + }; + + static const char* colourNames[] = + { + #define COL(col) #col, + #include "jucer_Colours.h" + #undef COL + 0 + }; + + for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i) + if (col == colours[i]) + return "Colours::" + String (colourNames[i]); + + return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')'; + } + + const String justificationToCode (const Justification& justification) + { + switch (justification.getFlags()) + { + case Justification::centred: return "Justification::centred"; + case Justification::centredLeft: return "Justification::centredLeft"; + case Justification::centredRight: return "Justification::centredRight"; + case Justification::centredTop: return "Justification::centredTop"; + case Justification::centredBottom: return "Justification::centredBottom"; + case Justification::topLeft: return "Justification::topLeft"; + case Justification::topRight: return "Justification::topRight"; + case Justification::bottomLeft: return "Justification::bottomLeft"; + case Justification::bottomRight: return "Justification::bottomRight"; + case Justification::left: return "Justification::left"; + case Justification::right: return "Justification::right"; + case Justification::horizontallyCentred: return "Justification::horizontallyCentred"; + case Justification::top: return "Justification::top"; + case Justification::bottom: return "Justification::bottom"; + case Justification::verticallyCentred: return "Justification::verticallyCentred"; + case Justification::horizontallyJustified: return "Justification::horizontallyJustified"; + default: jassertfalse; break; + } + + return "Justification (" + String (justification.getFlags()) + ")"; + } + + const String fontToCode (const Font& font) + { + String s ("Font ("); + String name (font.getTypefaceName()); + + if (name != Font::getDefaultSansSerifFontName()) + { + if (name == Font::getDefaultSerifFontName()) + name = "Font::getDefaultSerifFontName()"; + else if (name == Font::getDefaultMonospacedFontName()) + name = "Font::getDefaultMonospacedFontName()"; + else + name = stringLiteral (font.getTypefaceName()); + + s << name << ", "; + } + + s << floatLiteral (font.getHeight()); + + if (font.isBold() && font.isItalic()) + s << ", Font::bold | Font::italic"; + else if (font.isBold()) + s << ", Font::bold"; + else if (font.isItalic()) + s << ", Font::italic"; + + return s + ")"; + } + + const String castToFloat (const String& expression) + { + if (expression.containsOnly ("0123456789.f")) + { + String s (expression.getFloatValue()); + + if (s.containsChar (T('.'))) + return s + "f"; + + return s + ".0f"; + } + + return "(float) (" + expression + ")"; + } + + void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out) + { + const int maxCharsOnLine = 250; + + const unsigned char* data = (const unsigned char*) mb.getData(); + int charsOnLine = 0; + + bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals.. + + if (canUseStringLiteral) + { + int numEscaped = 0; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + const unsigned int num = (unsigned int) data[i]; + if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n')) + { + if (++numEscaped > mb.getSize() / 4) + { + canUseStringLiteral = false; + break; + } + } + } + } + + if (! canUseStringLiteral) + { + out << "{ "; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + const int num = (int) (unsigned int) data[i]; + out << num << ','; + + charsOnLine += 2; + if (num >= 10) + ++charsOnLine; + if (num >= 100) + ++charsOnLine; + + if (charsOnLine >= maxCharsOnLine) + { + charsOnLine = 0; + out << newLine; + } + } + + out << "0,0 };"; + } + else + { + out << "\""; + writeEscapeChars (out, data, (int) mb.getSize(), maxCharsOnLine, true, false); + out << "\";"; + } + } + + static int calculateHash (const String& s, const int hashMultiplier) + { + const char* t = s.toUTF8(); + int hash = 0; + while (*t != 0) + hash = hashMultiplier * hash + *t++; + + return hash; + } + + static int findBestHashMultiplier (const StringArray& strings) + { + int v = 31; + + for (;;) + { + SortedSet hashes; + bool collision = false; + for (int i = strings.size(); --i >= 0;) + { + const int hash = calculateHash (strings[i], v); + if (hashes.contains (hash)) + { + collision = true; + break; + } + + hashes.add (hash); + } + + if (! collision) + break; + + v += 2; + } + + return v; + } + + void createStringMatcher (OutputStream& out, const String& utf8PointerVariable, + const StringArray& strings, const StringArray& codeToExecute, const int indentLevel) + { + jassert (strings.size() == codeToExecute.size()); + const String indent (String::repeatedString (" ", indentLevel)); + const int hashMultiplier = findBestHashMultiplier (strings); + + out << indent << "int hash = 0;" << newLine + << indent << "if (" << utf8PointerVariable << " != 0)" << newLine + << indent << " while (*" << utf8PointerVariable << " != 0)" << newLine + << indent << " hash = " << hashMultiplier << " * hash + *" << utf8PointerVariable << "++;" << newLine + << newLine + << indent << "switch (hash)" << newLine + << indent << "{" << newLine; + + for (int i = 0; i < strings.size(); ++i) + out << indent << " case 0x" << hexString8Digits (calculateHash (strings[i], hashMultiplier)) + << ": " << codeToExecute[i] << newLine; + + out << indent << " default: break;" << newLine + << indent << "}" << newLine << newLine; + } +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h new file mode 100644 index 0000000000..91965b815a --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h @@ -0,0 +1,57 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_CODEUTILITIES_H_B86AA5D2__ +#define __JUCER_CODEUTILITIES_H_B86AA5D2__ + + +//============================================================================== +namespace CodeHelpers +{ + const String indent (const String& code, const int numSpaces, bool indentFirstLine); + const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates); + const String addEscapeChars (const String& text); + const String createIncludeStatement (const File& includeFile, const File& targetFile); + const String makeHeaderGuardName (const File& file); + + const String stringLiteral (const String& text); + const String boolLiteral (bool b); + const String floatLiteral (float v); + const String doubleLiteral (double v); + + const String colourToCode (const Colour& col); + const String justificationToCode (const Justification& justification); + const String castToFloat (const String& expression); + const String fontToCode (const Font& font); + + void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out); + + void createStringMatcher (OutputStream& out, const String& utf8PointerVariable, + const StringArray& strings, const StringArray& codeToExecute, const int indentLevel); + +} + + +#endif // __JUCER_CODEUTILITIES_H_B86AA5D2__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h index d0b2e359ff..6c69f83aad 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h @@ -166,5 +166,20 @@ public: Coordinate left, right, top, bottom; }; +//============================================================================== +class ComponentAutoLayoutManager : public ComponentListener +{ +public: + ComponentAutoLayoutManager (Component* parentComponent); + ~ComponentAutoLayoutManager(); + + void addMarker (bool isX, const String& name, const String& position); + void moveMarker (const String& name, int newPosition); + +private: + Array components; + +}; + #endif // __JUCER_COORDINATE_H_EF56ACFA__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp new file mode 100644 index 0000000000..5aebac4fc3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp @@ -0,0 +1,177 @@ +/* + ============================================================================== + + jucer_FileUtilities.cpp + Created: 14 May 2010 11:24:09pm + Author: Julian Storer + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "jucer_CodeHelpers.h" + + +//============================================================================== +namespace FileHelpers +{ + int64 calculateStreamHashCode (InputStream& in) + { + int64 t = 0; + + const int bufferSize = 4096; + HeapBlock buffer; + buffer.malloc (bufferSize); + + for (;;) + { + const int num = in.read (buffer, bufferSize); + + if (num <= 0) + break; + + for (int i = 0; i < num; ++i) + t = t * 65599 + buffer[i]; + } + + return t; + } + + int64 calculateFileHashCode (const File& file) + { + ScopedPointer stream (file.createInputStream()); + return stream != 0 ? calculateStreamHashCode (*stream) : 0; + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes) + { + if (file.getSize() == numBytes) + { + MemoryInputStream newStream (data, numBytes, false); + + if (calculateStreamHashCode (newStream) == calculateFileHashCode (file)) + return true; + } + + TemporaryFile temp (file); + + return temp.getFile().appendData (data, numBytes) + && temp.overwriteTargetFileWithTemporary(); + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData) + { + return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize()); + } + + bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData) + { + return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8())); + } + + bool containsAnyNonHiddenFiles (const File& folder) + { + DirectoryIterator di (folder, false); + + while (di.next()) + if (! di.getFile().isHidden()) + return true; + + return false; + } + + const String unixStylePath (const String& path) + { + return path.replaceCharacter ('\\', '/'); + } + + const String windowsStylePath (const String& path) + { + return path.replaceCharacter ('/', '\\'); + } + + const String appendPath (const String& path, const String& subpath) + { + if (File::isAbsolutePath (subpath) + || subpath.startsWithChar ('$') + || subpath.startsWithChar ('~') + || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':')) + return subpath.replaceCharacter ('\\', '/'); + + String path1 (path.replaceCharacter ('\\', '/')); + if (! path1.endsWithChar ('/')) + path1 << '/'; + + return path1 + subpath.replaceCharacter ('\\', '/'); + } + + bool shouldPathsBeRelative (String path1, String path2) + { + path1 = unixStylePath (path1); + path2 = unixStylePath (path2); + + const int len = jmin (path1.length(), path2.length()); + int commonBitLength = 0; + + for (int i = 0; i < len; ++i) + { + if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i])) + break; + + ++commonBitLength; + } + + return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty(); + } + + //============================================================================== + bool isJuceFolder (const File& folder) + { + return folder.getFileName().containsIgnoreCase ("juce") + && folder.getChildFile ("juce.h").exists() + && folder.getChildFile ("juce_Config.h").exists(); + } + + static const File lookInFolderForJuceFolder (const File& folder) + { + for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();) + { + if (isJuceFolder (di.getFile())) + return di.getFile(); + } + + return File::nonexistent; + } + + const File findParentJuceFolder (const File& file) + { + File f (file); + + while (f.exists() && f.getParentDirectory() != f) + { + if (isJuceFolder (f)) + return f; + + File found = lookInFolderForJuceFolder (f); + if (found.exists()) + return found; + + f = f.getParentDirectory(); + } + + return File::nonexistent; + } + + const File findDefaultJuceFolder() + { + File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile)); + + if (! f.exists()) + f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory)); + + if (! f.exists()) + f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory)); + + return f; + } +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h new file mode 100644 index 0000000000..dd19d66aa3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h @@ -0,0 +1,86 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_FILEUTILITIES_H_EEE25EE3__ +#define __JUCER_FILEUTILITIES_H_EEE25EE3__ + + +//============================================================================== +namespace FileHelpers +{ + int64 calculateStreamHashCode (InputStream& stream); + int64 calculateFileHashCode (const File& file); + + bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes); + bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData); + bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData); + + bool containsAnyNonHiddenFiles (const File& folder); + + const String unixStylePath (const String& path); + const String windowsStylePath (const String& path); + + bool shouldPathsBeRelative (String path1, String path2); + + //============================================================================== + bool isJuceFolder (const File& folder); + const File findParentJuceFolder (const File& file); + const File findDefaultJuceFolder(); +} + +//============================================================================== +class FileModificationDetector +{ +public: + FileModificationDetector (const File& file_) + : file (file_) + { + } + + const File& getFile() const { return file; } + void fileHasBeenRenamed (const File& newFile) { file = newFile; } + + bool hasBeenModified() const + { + return fileModificationTime != file.getLastModificationTime() + && (fileSize != file.getSize() + || FileHelpers::calculateFileHashCode (file) != fileHashCode); + } + + void updateHash() + { + fileModificationTime = file.getLastModificationTime(); + fileSize = file.getSize(); + fileHashCode = FileHelpers::calculateFileHashCode (file); + } + +private: + File file; + Time fileModificationTime; + int64 fileHashCode, fileSize; +}; + + +#endif // __JUCER_FILEUTILITIES_H_EEE25EE3__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp new file mode 100644 index 0000000000..19c23cc1ab --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp @@ -0,0 +1,268 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" + + +//============================================================================== +const int64 hashCode64 (const String& s) +{ + return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode(); +} + +const String createAlphaNumericUID() +{ + String uid; + static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random r (Random::getSystemRandom().nextInt64()); + + for (int i = 9; --i >= 0;) + { + r.setSeedRandomly(); + uid << (juce_wchar) chars [r.nextInt (sizeof (chars))]; + } + + return uid; +} + +const String randomHexString (Random& random, int numChars) +{ + String s; + const char hexChars[] = "0123456789ABCDEF"; + + while (--numChars >= 0) + s << hexChars [random.nextInt (16)]; + + return s; +} + +const String hexString8Digits (int value) +{ + return String::toHexString (value).paddedLeft ('0', 8); +} + +const String createGUID (const String& seed) +{ + String guid; + Random r (hashCode64 (seed + "_jucersalt")); + guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution) + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 12) << "}"; + return guid; +} + +//============================================================================== +void autoScrollForMouseEvent (const MouseEvent& e) +{ + Viewport* const viewport = e.eventComponent->findParentComponentOfClass ((Viewport*) 0); + + if (viewport != 0) + { + const MouseEvent e2 (e.getEventRelativeTo (viewport)); + viewport->autoScroll (e2.x, e2.y, 8, 16); + } +} + +void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text) +{ + g.fillAll (Colours::white.withAlpha (0.4f)); + g.setColour (Colours::grey); + g.drawRect (0, 0, w, h); + + g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f); + g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f); + + g.setColour (Colours::black); + g.setFont (11.0f); + g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2); +} + +void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize) +{ + ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0, + Colours::transparentBlack, 0, (float) shadowSize, false); + cg.addColour (0.4, Colours::black.withAlpha (0.07f)); + cg.addColour (0.6, Colours::black.withAlpha (0.02f)); + + g.setGradientFill (cg); + g.fillRect (0, 0, w, shadowSize); + + cg.point1.setXY (0.0f, (float) h); + cg.point2.setXY (0.0f, (float) h - shadowSize); + g.setGradientFill (cg); + g.fillRect (0, h - shadowSize, w, shadowSize); + + cg.point1.setXY (0.0f, 0.0f); + cg.point2.setXY ((float) shadowSize, 0.0f); + g.setGradientFill (cg); + g.fillRect (0, 0, shadowSize, h); + + cg.point1.setXY ((float) w, 0.0f); + cg.point2.setXY ((float) w - shadowSize, 0.0f); + g.setGradientFill (cg); + g.fillRect (w - shadowSize, 0, shadowSize, h); +} + +//============================================================================== +int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex) +{ + startIndex = jmax (0, startIndex); + + while (startIndex < lines.size()) + { + if (lines[startIndex].trimStart().startsWithIgnoreCase (text)) + return startIndex; + + ++startIndex; + } + + return -1; +} + + +//============================================================================== +PropertyPanelWithTooltips::PropertyPanelWithTooltips() + : lastComp (0) +{ + addAndMakeVisible (panel = new PropertyPanel()); + startTimer (150); +} + +PropertyPanelWithTooltips::~PropertyPanelWithTooltips() +{ + deleteAllChildren(); +} + +void PropertyPanelWithTooltips::paint (Graphics& g) +{ + g.setColour (Colour::greyLevel (0.15f)); + g.setFont (13.0f); + + TextLayout tl; + tl.appendText (lastTip, Font (14.0f)); + tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice + if (tl.getNumLines() > 3) + tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in.. + + tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10, + getHeight() - panel->getBottom() - 4, + Justification::centredLeft); +} + +void PropertyPanelWithTooltips::resized() +{ + panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f))); +} + +void PropertyPanelWithTooltips::timerCallback() +{ + Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + + if (newComp != lastComp) + { + lastComp = newComp; + + String newTip (findTip (newComp)); + + if (newTip != lastTip) + { + lastTip = newTip; + repaint (0, panel->getBottom(), getWidth(), getHeight()); + } + } +} + +const String PropertyPanelWithTooltips::findTip (Component* c) +{ + while (c != 0 && c != this) + { + TooltipClient* const tc = dynamic_cast (c); + if (tc != 0) + { + const String tip (tc->getTooltip()); + + if (tip.isNotEmpty()) + return tip; + } + + c = c->getParentComponent(); + } + + return String::empty; +} + +//============================================================================== +FloatingLabelComponent::FloatingLabelComponent() + : font (10.0f) +{ + setInterceptsMouseClicks (false ,false); +} + +void FloatingLabelComponent::remove() +{ + if (getParentComponent() != 0) + getParentComponent()->removeChildComponent (this); +} + +void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below) +{ + colour = textColour; + + Rectangle r; + + if (text != getName()) + { + setName (text); + glyphs.clear(); + glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left); + glyphs.justifyGlyphs (0, std::numeric_limits::max(), 0, 0, 1000, 1000, Justification::topLeft); + + r = glyphs.getBoundingBox (0, std::numeric_limits::max(), false) + .getSmallestIntegerContainer().expanded (2, 2); + } + else + { + r = getLocalBounds(); + } + + r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2))); + setBounds (r); + parent->addAndMakeVisible (this); +} + +void FloatingLabelComponent::paint (Graphics& g) +{ + g.setFont (font); + g.setColour (Colours::white.withAlpha (0.5f)); + + for (int y = -1; y <= 1; ++y) + for (int x = -1; x <= 1; ++x) + glyphs.draw (g, AffineTransform::translation (1.0f + x, 1.0f + y)); + + g.setColour (colour); + glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h new file mode 100644 index 0000000000..85879d6400 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h @@ -0,0 +1,82 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + + +//============================================================================== +// String::hashCode64 actually hit some dupes, so this is a more powerful version. +const int64 hashCode64 (const String& s); +const String randomHexString (Random& random, int numChars); +const String hexString8Digits (int value); + +const String createAlphaNumericUID(); +const String createGUID (const String& seed); // Turns a seed into a windows GUID + +//============================================================================== +int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex); + +void autoScrollForMouseEvent (const MouseEvent& e); + +void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text); +void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize); + + +//============================================================================== +class PropertyPanelWithTooltips : public Component, + public Timer +{ +public: + PropertyPanelWithTooltips(); + ~PropertyPanelWithTooltips(); + + PropertyPanel* getPanel() const { return panel; } + + void paint (Graphics& g); + void resized(); + void timerCallback(); + +private: + PropertyPanel* panel; + TextLayout layout; + Component* lastComp; + String lastTip; + + const String findTip (Component* c); +}; + +//============================================================================== +class FloatingLabelComponent : public Component +{ +public: + FloatingLabelComponent(); + + void remove(); + void update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below); + void paint (Graphics& g); + +private: + Font font; + Colour colour; + GlyphArrangement glyphs; +}; diff --git a/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h index 4931634310..100754efe3 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h @@ -59,8 +59,8 @@ public: RootFolder getRoot() const { return root; } - const String toUnixStyle() const { return FileUtils::unixStylePath (path); } - const String toWindowsStyle() const { return FileUtils::windowsStylePath (path); } + const String toUnixStyle() const { return FileHelpers::unixStylePath (path); } + const String toWindowsStyle() const { return FileHelpers::windowsStylePath (path); } const String getFileName() const { return getFakeFile().getFileName(); } const String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); } diff --git a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp index c5250d3dc4..514f262ef7 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp +++ b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp @@ -112,10 +112,10 @@ void StoredSettings::setLastProject (const File& file) const File StoredSettings::getLastKnownJuceFolder() const { - File defaultJuceFolder (FileUtils::findDefaultJuceFolder()); + File defaultJuceFolder (FileHelpers::findDefaultJuceFolder()); File f (props->getValue ("lastJuceFolder", defaultJuceFolder.getFullPathName())); - if ((! FileUtils::isJuceFolder (f)) && FileUtils::isJuceFolder (defaultJuceFolder)) + if ((! FileHelpers::isJuceFolder (f)) && FileHelpers::isJuceFolder (defaultJuceFolder)) f = defaultJuceFolder; return f; @@ -123,7 +123,7 @@ const File StoredSettings::getLastKnownJuceFolder() const void StoredSettings::setLastKnownJuceFolder (const File& file) { - jassert (FileUtils::isJuceFolder (file)); + jassert (FileHelpers::isJuceFolder (file)); props->setValue ("lastJuceFolder", file.getFullPathName()); } diff --git a/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h b/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h new file mode 100644 index 0000000000..3751c9757b --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h @@ -0,0 +1,148 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_TICKITERATOR_H_8D744D8A__ +#define __JUCER_TICKITERATOR_H_8D744D8A__ + + +//============================================================================== +class TickIterator +{ +public: + TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_, + int minPixelsPerTick, int minWidthForLabels) + : startValue (startValue_), + endValue (endValue_), + valuePerPixel (valuePerPixel_) + { + tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick); + labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels); + + tickPosition = pixelsToValue (-minWidthForLabels); + tickPosition = snapValueDown (tickPosition, tickLevelIndex); + } + + bool getNextTick (float& pixelX, float& tickLength, String& label) + { + const double tickUnits = getTickSizes() [tickLevelIndex]; + tickPosition += tickUnits; + + const int totalLevels = getNumTickSizes(); + int highestIndex = tickLevelIndex; + + while (++highestIndex < totalLevels) + { + const double ticksAtThisLevel = tickPosition / getTickSizes() [highestIndex]; + + if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001) + break; + } + + --highestIndex; + + if (highestIndex >= labelLevelIndex) + label = getDescriptionOfValue (tickPosition, labelLevelIndex); + else + label = String::empty; + + tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex); + pixelX = valueToPixels (tickPosition); + + return tickPosition < endValue; + } + +private: + double tickPosition; + int tickLevelIndex, labelLevelIndex; + const double startValue, endValue, valuePerPixel; + + static int getNumTickSizes() + { + return 10; + } + + static const double* getTickSizes() + { + static const double tickSizes[] = { 1.0, 2.0, 5.0, + 10.0, 20.0, 50.0, + 100.0, 200.0, 500.0, 1000.0 }; + return tickSizes; + } + + int findLevelIndexForValue (const double value) const + { + int i; + for (i = 0; i < getNumTickSizes(); ++i) + if (getTickSizes() [i] >= value) + break; + + return i; + } + + double pixelsToValue (int pixels) const + { + return startValue + pixels * valuePerPixel; + } + + float valueToPixels (double value) const + { + return (float) ((value - startValue) / valuePerPixel); + } + + static double snapValueToNearest (const double t, const int valueLevelIndex) + { + const double unitsPerInterval = getTickSizes() [valueLevelIndex]; + return unitsPerInterval * floor (t / unitsPerInterval + 0.5); + } + + static double snapValueDown (const double t, const int valueLevelIndex) + { + const double unitsPerInterval = getTickSizes() [valueLevelIndex]; + return unitsPerInterval * floor (t / unitsPerInterval); + } + + static inline int roundDoubleToInt (const double value) + { + union { int asInt[2]; double asDouble; } n; + n.asDouble = value + 6755399441055744.0; + + #if TARGET_RT_BIG_ENDIAN + return n.asInt [1]; + #else + return n.asInt [0]; + #endif + } + + static const String getDescriptionOfValue (const double value, const int valueLevelIndex) + { + return String (roundToInt (value)); + } + + TickIterator (const TickIterator&); + TickIterator& operator= (const TickIterator&); +}; + + +#endif // __JUCER_TICKITERATOR_H_8D744D8A__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp deleted file mode 100644 index 1c28b76e55..0000000000 --- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp +++ /dev/null @@ -1,758 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-10 by Raw Material Software Ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the GNU General - Public License (Version 2), as published by the Free Software Foundation. - A copy of the license is included in the JUCE distribution, or can be found - online at www.gnu.org/licenses. - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.rawmaterialsoftware.com/juce for more information. - - ============================================================================== -*/ - -#include "../jucer_Headers.h" - - -//============================================================================== -const int64 hashCode64 (const String& s) -{ - return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode(); -} - -const String createAlphaNumericUID() -{ - String uid; - static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - Random r (Random::getSystemRandom().nextInt64()); - - for (int i = 9; --i >= 0;) - { - r.setSeedRandomly(); - uid << (juce_wchar) chars [r.nextInt (sizeof (chars))]; - } - - return uid; -} - -const String randomHexString (Random& random, int numChars) -{ - String s; - const char hexChars[] = "0123456789ABCDEF"; - - while (--numChars >= 0) - s << hexChars [random.nextInt (16)]; - - return s; -} - -const String hexString8Digits (int value) -{ - return String::toHexString (value).paddedLeft ('0', 8); -} - -const String createGUID (const String& seed) -{ - String guid; - Random r (hashCode64 (seed + "_jucersalt")); - guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution) - guid << "-" << randomHexString (r, 4); - guid << "-" << randomHexString (r, 4); - guid << "-" << randomHexString (r, 4); - guid << "-" << randomHexString (r, 12) << "}"; - return guid; -} - -//============================================================================== -namespace FileUtils -{ - int64 calculateStreamHashCode (InputStream& in) - { - int64 t = 0; - - const int bufferSize = 4096; - HeapBlock buffer; - buffer.malloc (bufferSize); - - for (;;) - { - const int num = in.read (buffer, bufferSize); - - if (num <= 0) - break; - - for (int i = 0; i < num; ++i) - t = t * 65599 + buffer[i]; - } - - return t; - } - - int64 calculateFileHashCode (const File& file) - { - ScopedPointer stream (file.createInputStream()); - return stream != 0 ? calculateStreamHashCode (*stream) : 0; - } - - bool areFilesIdentical (const File& file1, const File& file2) - { - return file1.getSize() == file2.getSize() - && calculateFileHashCode (file1) == calculateFileHashCode (file2); - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes) - { - if (file.getSize() == numBytes) - { - MemoryInputStream newStream (data, numBytes, false); - - if (calculateStreamHashCode (newStream) == calculateFileHashCode (file)) - return true; - } - - TemporaryFile temp (file); - - return temp.getFile().appendData (data, numBytes) - && temp.overwriteTargetFileWithTemporary(); - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData) - { - return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize()); - } - - bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData) - { - return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8())); - } - - bool containsAnyNonHiddenFiles (const File& folder) - { - DirectoryIterator di (folder, false); - - while (di.next()) - if (! di.getFile().isHidden()) - return true; - - return false; - } - - const String unixStylePath (const String& path) - { - return path.replaceCharacter ('\\', '/'); - } - - const String windowsStylePath (const String& path) - { - return path.replaceCharacter ('/', '\\'); - } - - const String appendPath (const String& path, const String& subpath) - { - if (File::isAbsolutePath (subpath) - || subpath.startsWithChar ('$') - || subpath.startsWithChar ('~') - || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':')) - return subpath.replaceCharacter ('\\', '/'); - - String path1 (path.replaceCharacter ('\\', '/')); - if (! path1.endsWithChar ('/')) - path1 << '/'; - - return path1 + subpath.replaceCharacter ('\\', '/'); - } - - bool shouldPathsBeRelative (String path1, String path2) - { - path1 = unixStylePath (path1); - path2 = unixStylePath (path2); - - const int len = jmin (path1.length(), path2.length()); - int commonBitLength = 0; - - for (int i = 0; i < len; ++i) - { - if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i])) - break; - - ++commonBitLength; - } - - return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty(); - } - - //============================================================================== - bool isJuceFolder (const File& folder) - { - return folder.getFileName().containsIgnoreCase ("juce") - && folder.getChildFile ("juce.h").exists() - && folder.getChildFile ("juce_Config.h").exists(); - } - - static const File lookInFolderForJuceFolder (const File& folder) - { - for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();) - { - if (isJuceFolder (di.getFile())) - return di.getFile(); - } - - return File::nonexistent; - } - - const File findParentJuceFolder (const File& file) - { - File f (file); - - while (f.exists() && f.getParentDirectory() != f) - { - if (isJuceFolder (f)) - return f; - - File found = lookInFolderForJuceFolder (f); - if (found.exists()) - return found; - - f = f.getParentDirectory(); - } - - return File::nonexistent; - } - - const File findDefaultJuceFolder() - { - File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile)); - - if (! f.exists()) - f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory)); - - if (! f.exists()) - f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory)); - - return f; - } -} - -//============================================================================== -void autoScrollForMouseEvent (const MouseEvent& e) -{ - Viewport* const viewport = e.eventComponent->findParentComponentOfClass ((Viewport*) 0); - - if (viewport != 0) - { - const MouseEvent e2 (e.getEventRelativeTo (viewport)); - viewport->autoScroll (e2.x, e2.y, 8, 16); - } -} - -void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text) -{ - g.fillAll (Colours::white.withAlpha (0.4f)); - g.setColour (Colours::grey); - g.drawRect (0, 0, w, h); - - g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f); - g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f); - - g.setColour (Colours::black); - g.setFont (11.0f); - g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2); -} - -void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize) -{ - ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0, - Colours::transparentBlack, 0, (float) shadowSize, false); - cg.addColour (0.4, Colours::black.withAlpha (0.07f)); - cg.addColour (0.6, Colours::black.withAlpha (0.02f)); - - g.setGradientFill (cg); - g.fillRect (0, 0, w, shadowSize); - - cg.point1.setXY (0.0f, (float) h); - cg.point2.setXY (0.0f, (float) h - shadowSize); - g.setGradientFill (cg); - g.fillRect (0, h - shadowSize, w, shadowSize); - - cg.point1.setXY (0.0f, 0.0f); - cg.point2.setXY ((float) shadowSize, 0.0f); - g.setGradientFill (cg); - g.fillRect (0, 0, shadowSize, h); - - cg.point1.setXY ((float) w, 0.0f); - cg.point2.setXY ((float) w - shadowSize, 0.0f); - g.setGradientFill (cg); - g.fillRect (w - shadowSize, 0, shadowSize, h); -} - -//============================================================================== -namespace CodeFormatting -{ - const String indent (const String& code, const int numSpaces, bool indentFirstLine) - { - if (numSpaces == 0) - return code; - - const String space (String::repeatedString (" ", numSpaces)); - - StringArray lines; - lines.addLines (code); - - for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i) - { - String s (lines[i].trimEnd()); - if (s.isNotEmpty()) - s = space + s; - - lines.set (i, s); - } - - return lines.joinIntoString (newLine); - } - - const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates) - { - if (s.isEmpty()) - return "unknown"; - - if (removeColons) - s = s.replaceCharacters (".,;:/@", "______"); - else - s = s.replaceCharacters (".,;/@", "_____"); - - int i; - for (i = s.length(); --i > 0;) - if (CharacterFunctions::isLetter (s[i]) - && CharacterFunctions::isLetter (s[i - 1]) - && CharacterFunctions::isUpperCase (s[i]) - && ! CharacterFunctions::isUpperCase (s[i - 1])) - s = s.substring (0, i) + " " + s.substring (i); - - String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789"); - if (allowTemplates) - allowedChars += "<>"; - - if (! removeColons) - allowedChars += ":"; - - StringArray words; - words.addTokens (s.retainCharacters (allowedChars), false); - words.trim(); - - String n (words[0]); - - if (capitalise) - n = n.toLowerCase(); - - for (i = 1; i < words.size(); ++i) - { - if (capitalise && words[i].length() > 1) - n << words[i].substring (0, 1).toUpperCase() - << words[i].substring (1).toLowerCase(); - else - n << words[i]; - } - - if (CharacterFunctions::isDigit (n[0])) - n = "_" + n; - - if (CPlusPlusCodeTokeniser::isReservedKeyword (n)) - n << '_'; - - return n; - } - - const String addEscapeChars (const String& s) - { - const int len = s.length(); - String r; - r.preallocateStorage (len + 2); - bool lastWasHexEscapeCode = false; - - for (int i = 0; i < len; ++i) - { - const juce_wchar c = s[i]; - - switch (c) - { - case '\t': r << "\\t"; lastWasHexEscapeCode = false; break; - case '\r': r << "\\r"; lastWasHexEscapeCode = false; break; - case '\n': r << "\\n"; lastWasHexEscapeCode = false; break; - case '\\': r << "\\\\"; lastWasHexEscapeCode = false; break; - case '\'': r << "\\\'"; lastWasHexEscapeCode = false; break; - case '\"': r << "\\\""; lastWasHexEscapeCode = false; break; - - default: - if (c < 128 - && ! (lastWasHexEscapeCode - && String ("0123456789abcdefABCDEF").containsChar (c))) // (have to avoid following a hex escape sequence with a valid hex digit) - { - r << c; - lastWasHexEscapeCode = false; - } - else - { - r << "\\x" << String::toHexString ((int) c); - lastWasHexEscapeCode = true; - } - - break; - } - } - - return r; - } - - const String createIncludeStatement (const File& includeFile, const File& targetFile) - { - return "#include \"" + FileUtils::unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + "\""; - } - - const String makeHeaderGuardName (const File& file) - { - return "__" + file.getFileName().toUpperCase() - .replaceCharacters (" .", "__") - .retainCharacters ("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - + "_" + String::toHexString (file.hashCode()).toUpperCase() + "__"; - } - - const String stringLiteral (const String& text) - { - if (text.isEmpty()) - return "String::empty"; - - return CodeFormatting::addEscapeChars (text).quoted(); - } - - const String boolLiteral (bool b) - { - return b ? "true" : "false"; - } - - const String floatLiteral (float v) - { - String s ((double) v, 4); - - if (s.containsChar ('.')) - s << 'f'; - else - s << ".0f"; - - return s; - } - - const String doubleLiteral (double v) - { - String s (v, 7); - - if (! s.containsChar ('.')) - s << ".0"; - - return s; - } - - const String colourToCode (const Colour& col) - { - const Colour colours[] = - { - #define COL(col) Colours::col, - #include "jucer_Colours.h" - #undef COL - Colours::transparentBlack - }; - - static const char* colourNames[] = - { - #define COL(col) #col, - #include "jucer_Colours.h" - #undef COL - 0 - }; - - for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i) - if (col == colours[i]) - return "Colours::" + String (colourNames[i]); - - return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')'; - } - - const String justificationToCode (const Justification& justification) - { - switch (justification.getFlags()) - { - case Justification::centred: return "Justification::centred"; - case Justification::centredLeft: return "Justification::centredLeft"; - case Justification::centredRight: return "Justification::centredRight"; - case Justification::centredTop: return "Justification::centredTop"; - case Justification::centredBottom: return "Justification::centredBottom"; - case Justification::topLeft: return "Justification::topLeft"; - case Justification::topRight: return "Justification::topRight"; - case Justification::bottomLeft: return "Justification::bottomLeft"; - case Justification::bottomRight: return "Justification::bottomRight"; - case Justification::left: return "Justification::left"; - case Justification::right: return "Justification::right"; - case Justification::horizontallyCentred: return "Justification::horizontallyCentred"; - case Justification::top: return "Justification::top"; - case Justification::bottom: return "Justification::bottom"; - case Justification::verticallyCentred: return "Justification::verticallyCentred"; - case Justification::horizontallyJustified: return "Justification::horizontallyJustified"; - default: jassertfalse; break; - } - - return "Justification (" + String (justification.getFlags()) + ")"; - } - - const String castToFloat (const String& expression) - { - if (expression.containsOnly ("0123456789.f")) - { - String s (expression.getFloatValue()); - - if (s.containsChar (T('.'))) - return s + "f"; - - return s + ".0f"; - } - - return "(float) (" + expression + ")"; - } - - void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out) - { - const int maxCharsOnLine = 250; - - const unsigned char* data = (const unsigned char*) mb.getData(); - int charsOnLine = 0; - - bool canUseStringLiteral = mb.getSize() < 65535; // MS compilers can't handle strings bigger than 65536 chars.. - - if (canUseStringLiteral) - { - int numEscaped = 0; - - for (size_t i = 0; i < mb.getSize(); ++i) - { - const unsigned int num = (unsigned int) data[i]; - if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n')) - { - if (++numEscaped > mb.getSize() / 4) - { - canUseStringLiteral = false; - break; - } - } - } - } - - if (! canUseStringLiteral) - { - out << "{ "; - - for (size_t i = 0; i < mb.getSize(); ++i) - { - const int num = (int) (unsigned int) data[i]; - out << num << ','; - - charsOnLine += 2; - if (num >= 10) - ++charsOnLine; - if (num >= 100) - ++charsOnLine; - - if (charsOnLine >= maxCharsOnLine) - { - charsOnLine = 0; - out << newLine; - } - } - - out << "0,0 };"; - } - else - { - out << "\""; - - for (size_t i = 0; i < mb.getSize(); ++i) - { - const unsigned int num = (unsigned int) data[i]; - - switch (num) - { - case '\t': out << "\\t"; break; - case '\r': out << "\\r"; break; - case '\n': out << "\\n"; charsOnLine = maxCharsOnLine; break; - case '"': out << "\\\""; break; - case '\\': out << "\\\\"; break; - default: - if (num >= 32 && num < 127) - out << (char) num; - else if (num <= 0x0f) - out << "\\x0" << String::toHexString ((int) num); - else - out << "\\x" << String::toHexString ((int) num); - break; - } - - if (++charsOnLine >= maxCharsOnLine && i < mb.getSize() - 1) - { - charsOnLine = 0; - out << "\"" << newLine << "\""; - } - } - - out << "\";"; - } - } -} - -//============================================================================== -int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex) -{ - startIndex = jmax (0, startIndex); - - while (startIndex < lines.size()) - { - if (lines[startIndex].trimStart().startsWithIgnoreCase (text)) - return startIndex; - - ++startIndex; - } - - return -1; -} - - -//============================================================================== -PropertyPanelWithTooltips::PropertyPanelWithTooltips() - : lastComp (0) -{ - addAndMakeVisible (panel = new PropertyPanel()); - startTimer (150); -} - -PropertyPanelWithTooltips::~PropertyPanelWithTooltips() -{ - deleteAllChildren(); -} - -void PropertyPanelWithTooltips::paint (Graphics& g) -{ - g.setColour (Colour::greyLevel (0.15f)); - g.setFont (13.0f); - - TextLayout tl; - tl.appendText (lastTip, Font (14.0f)); - tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice - if (tl.getNumLines() > 3) - tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in.. - - tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10, - getHeight() - panel->getBottom() - 4, - Justification::centredLeft); -} - -void PropertyPanelWithTooltips::resized() -{ - panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f))); -} - -void PropertyPanelWithTooltips::timerCallback() -{ - Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); - - if (newComp != lastComp) - { - lastComp = newComp; - - String newTip (findTip (newComp)); - - if (newTip != lastTip) - { - lastTip = newTip; - repaint (0, panel->getBottom(), getWidth(), getHeight()); - } - } -} - -const String PropertyPanelWithTooltips::findTip (Component* c) -{ - while (c != 0 && c != this) - { - TooltipClient* const tc = dynamic_cast (c); - if (tc != 0) - { - const String tip (tc->getTooltip()); - - if (tip.isNotEmpty()) - return tip; - } - - c = c->getParentComponent(); - } - - return String::empty; -} - -//============================================================================== -FloatingLabelComponent::FloatingLabelComponent() - : font (10.0f) -{ - setInterceptsMouseClicks (false ,false); -} - -void FloatingLabelComponent::remove() -{ - if (getParentComponent() != 0) - getParentComponent()->removeChildComponent (this); -} - -void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below) -{ - colour = textColour; - - Rectangle r; - - if (text != getName()) - { - setName (text); - glyphs.clear(); - glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left); - glyphs.justifyGlyphs (0, std::numeric_limits::max(), 0, 0, 1000, 1000, Justification::topLeft); - - r = glyphs.getBoundingBox (0, std::numeric_limits::max(), false) - .getSmallestIntegerContainer().expanded (2, 2); - } - else - { - r = getLocalBounds(); - } - - r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2))); - setBounds (r); - parent->addAndMakeVisible (this); -} - -void FloatingLabelComponent::paint (Graphics& g) -{ - g.setFont (font); - g.setColour (Colours::white.withAlpha (0.5f)); - - for (int y = -1; y <= 1; ++y) - for (int x = -1; x <= 1; ++x) - glyphs.draw (g, AffineTransform::translation (1.0f + x, 1.0f + y)); - - g.setColour (colour); - glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); -} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h deleted file mode 100644 index 7d443e2609..0000000000 --- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-10 by Raw Material Software Ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the GNU General - Public License (Version 2), as published by the Free Software Foundation. - A copy of the license is included in the JUCE distribution, or can be found - online at www.gnu.org/licenses. - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.rawmaterialsoftware.com/juce for more information. - - ============================================================================== -*/ - - -//============================================================================== -namespace FileUtils -{ - int64 calculateStreamHashCode (InputStream& stream); - int64 calculateFileHashCode (const File& file); - bool areFilesIdentical (const File& file1, const File& file2); - - bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes); - bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData); - bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData); - - bool containsAnyNonHiddenFiles (const File& folder); - - const String unixStylePath (const String& path); - const String windowsStylePath (const String& path); - - bool shouldPathsBeRelative (String path1, String path2); - - //============================================================================== - bool isJuceFolder (const File& folder); - const File findParentJuceFolder (const File& file); - const File findDefaultJuceFolder(); -} - -//============================================================================== -// String::hashCode64 actually hit some dupes, so this is a more powerful version. -const int64 hashCode64 (const String& s); -const String randomHexString (Random& random, int numChars); -const String hexString8Digits (int value); - -const String createAlphaNumericUID(); -const String createGUID (const String& seed); // Turns a seed into a windows GUID - -//============================================================================== -int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex); - -void autoScrollForMouseEvent (const MouseEvent& e); - -void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text); -void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize); - -//============================================================================== -class FileModificationDetector -{ -public: - FileModificationDetector (const File& file_) - : file (file_) - { - } - - const File& getFile() const { return file; } - void fileHasBeenRenamed (const File& newFile) { file = newFile; } - - bool hasBeenModified() const - { - return fileModificationTime != file.getLastModificationTime() - && (fileSize != file.getSize() - || FileUtils::calculateFileHashCode (file) != fileHashCode); - } - - void updateHash() - { - fileModificationTime = file.getLastModificationTime(); - fileSize = file.getSize(); - fileHashCode = FileUtils::calculateFileHashCode (file); - } - -private: - File file; - Time fileModificationTime; - int64 fileHashCode, fileSize; -}; - -//============================================================================== -namespace CodeFormatting -{ - const String indent (const String& code, const int numSpaces, bool indentFirstLine); - const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates); - const String addEscapeChars (const String& text); - const String createIncludeStatement (const File& includeFile, const File& targetFile); - const String makeHeaderGuardName (const File& file); - - const String stringLiteral (const String& text); - const String boolLiteral (bool b); - const String floatLiteral (float v); - const String doubleLiteral (double v); - - const String colourToCode (const Colour& col); - const String justificationToCode (const Justification& justification); - const String castToFloat (const String& expression); - - void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out); -} - -//============================================================================== -class PropertyPanelWithTooltips : public Component, - public Timer -{ -public: - PropertyPanelWithTooltips(); - ~PropertyPanelWithTooltips(); - - PropertyPanel* getPanel() const { return panel; } - - void paint (Graphics& g); - void resized(); - void timerCallback(); - -private: - PropertyPanel* panel; - TextLayout layout; - Component* lastComp; - String lastTip; - - const String findTip (Component* c); -}; - -//============================================================================== -class FloatingLabelComponent : public Component -{ -public: - FloatingLabelComponent(); - - void remove(); - void update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below); - void paint (Graphics& g); - -private: - Font font; - Colour colour; - GlyphArrangement glyphs; -}; - -//============================================================================== -static const double tickSizes[] = { 1.0, 2.0, 5.0, - 10.0, 20.0, 50.0, - 100.0, 200.0, 500.0, 1000.0 }; - -class TickIterator -{ -public: - TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_, - int minPixelsPerTick, int minWidthForLabels) - : startValue (startValue_), - endValue (endValue_), - valuePerPixel (valuePerPixel_) - { - tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick); - labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels); - - tickPosition = pixelsToValue (-minWidthForLabels); - tickPosition = snapValueDown (tickPosition, tickLevelIndex); - } - - bool getNextTick (float& pixelX, float& tickLength, String& label) - { - const double tickUnits = tickSizes [tickLevelIndex]; - tickPosition += tickUnits; - - const int totalLevels = sizeof (tickSizes) / sizeof (*tickSizes); - int highestIndex = tickLevelIndex; - - while (++highestIndex < totalLevels) - { - const double ticksAtThisLevel = tickPosition / tickSizes [highestIndex]; - - if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001) - break; - } - - --highestIndex; - - if (highestIndex >= labelLevelIndex) - label = getDescriptionOfValue (tickPosition, labelLevelIndex); - else - label = String::empty; - - tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex); - pixelX = valueToPixels (tickPosition); - - return tickPosition < endValue; - } - -private: - double tickPosition; - int tickLevelIndex, labelLevelIndex; - const double startValue, endValue, valuePerPixel; - - int findLevelIndexForValue (const double value) const - { - int i; - for (i = 0; i < (int) (sizeof (tickSizes) / sizeof (*tickSizes)); ++i) - if (tickSizes [i] >= value) - break; - - return i; - } - - double pixelsToValue (int pixels) const - { - return startValue + pixels * valuePerPixel; - } - - float valueToPixels (double value) const - { - return (float) ((value - startValue) / valuePerPixel); - } - - static double snapValueToNearest (const double t, const int valueLevelIndex) - { - const double unitsPerInterval = tickSizes [valueLevelIndex]; - return unitsPerInterval * floor (t / unitsPerInterval + 0.5); - } - - static double snapValueDown (const double t, const int valueLevelIndex) - { - const double unitsPerInterval = tickSizes [valueLevelIndex]; - return unitsPerInterval * floor (t / unitsPerInterval); - } - - static inline int roundDoubleToInt (const double value) - { - union { int asInt[2]; double asDouble; } n; - n.asDouble = value + 6755399441055744.0; - - #if TARGET_RT_BIG_ENDIAN - return n.asInt [1]; - #else - return n.asInt [0]; - #endif - } - - static const String getDescriptionOfValue (const double value, const int valueLevelIndex) - { - return String (roundToInt (value)); - } - - TickIterator (const TickIterator&); - TickIterator& operator= (const TickIterator&); -}; diff --git a/extras/juce demo/Juce Demo.jucer b/extras/juce demo/Juce Demo.jucer index 800c840baf..355914ee01 100644 --- a/extras/juce demo/Juce Demo.jucer +++ b/extras/juce demo/Juce Demo.jucer @@ -14,9 +14,9 @@ + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"/> + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"/> diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 31a6f3314c..2a3c0b84fe 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -3879,6 +3879,62 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_PropertySet.cpp ***/ +/*** Start of inlined file: juce_Identifier.cpp ***/ +BEGIN_JUCE_NAMESPACE + +class Identifier::Pool : public DeletedAtShutdown +{ +public: + Pool() {} + ~Pool() {} + + StringPool pool; + + juce_DeclareSingleton_SingleThreaded_Minimal (Pool); +}; + +juce_ImplementSingleton_SingleThreaded (Identifier::Pool); + +Identifier::Identifier() throw() + : name (0) +{ +} + +Identifier::Identifier (const Identifier& other) throw() + : name (other.name) +{ +} + +Identifier& Identifier::operator= (const Identifier& other) throw() +{ + name = other.name; + return *this; +} + +Identifier::Identifier (const String& name_) + : name (Identifier::Pool::getInstance()->pool.getPooledString (name_)) +{ + /* An Identifier string must be suitable for use as a script variable or XML + attribute, so it can only contain this limited set of characters.. */ + jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty()); +} + +Identifier::Identifier (const char* const name_) + : name (Identifier::Pool::getInstance()->pool.getPooledString (name_)) +{ + /* An Identifier string must be suitable for use as a script variable or XML + attribute, so it can only contain this limited set of characters.. */ + jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty()); +} + +Identifier::~Identifier() +{ +} + +END_JUCE_NAMESPACE +/*** End of inlined file: juce_Identifier.cpp ***/ + + /*** Start of inlined file: juce_Variant.cpp ***/ BEGIN_JUCE_NAMESPACE @@ -4129,7 +4185,7 @@ const var var::readFromStream (InputStream& input) return var::null; } -const var var::operator[] (const var::identifier& propertyName) const +const var var::operator[] (const Identifier& propertyName) const { if (type == objectType && value.objectValue != 0) return value.objectValue->getProperty (propertyName); @@ -4137,7 +4193,7 @@ const var var::operator[] (const var::identifier& propertyName) const return var::null; } -const var var::invoke (const var::identifier& method, const var* arguments, int numArguments) const +const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { if (type == objectType && value.objectValue != 0) return value.objectValue->invokeMethod (method, arguments, numArguments); @@ -4158,67 +4214,40 @@ const var var::invoke (const var& targetObject, const var* arguments, int numArg return var::null; } -const var var::call (const var::identifier& method) const +const var var::call (const Identifier& method) const { return invoke (method, 0, 0); } -const var var::call (const var::identifier& method, const var& arg1) const +const var var::call (const Identifier& method, const var& arg1) const { return invoke (method, &arg1, 1); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2) const +const var var::call (const Identifier& method, const var& arg1, const var& arg2) const { var args[] = { arg1, arg2 }; return invoke (method, args, 2); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3) +const 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); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const +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); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const +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); } -var::identifier::identifier() throw() - : hashCode (0) -{ -} - -var::identifier::identifier (const String& name_) - : name (name_), - hashCode (name_.hashCode()) -{ - /* An identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty()); -} - -var::identifier::identifier (const char* const name_) - : name (name_), - hashCode (name.hashCode()) -{ - /* An identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty()); -} - -var::identifier::~identifier() -{ -} - END_JUCE_NAMESPACE /*** End of inlined file: juce_Variant.cpp ***/ @@ -4230,7 +4259,7 @@ NamedValueSet::NamedValue::NamedValue() throw() { } -inline NamedValueSet::NamedValue::NamedValue (const var::identifier& name_, const var& value_) +inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var& value_) : name (name_), value (value_) { } @@ -4259,7 +4288,7 @@ int NamedValueSet::size() const throw() return values.size(); } -const var& NamedValueSet::operator[] (const var::identifier& name) const +const var& NamedValueSet::operator[] (const Identifier& name) const { for (int i = values.size(); --i >= 0;) { @@ -4272,13 +4301,13 @@ const var& NamedValueSet::operator[] (const var::identifier& name) const return var::null; } -const var NamedValueSet::getWithDefault (const var::identifier& name, const var& defaultReturnValue) const +const var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const { const var* v = getItem (name); return v != 0 ? *v : defaultReturnValue; } -var* NamedValueSet::getItem (const var::identifier& name) const +var* NamedValueSet::getItem (const Identifier& name) const { for (int i = values.size(); --i >= 0;) { @@ -4291,7 +4320,7 @@ var* NamedValueSet::getItem (const var::identifier& name) const return 0; } -bool NamedValueSet::set (const var::identifier& name, const var& newValue) +bool NamedValueSet::set (const Identifier& name, const var& newValue) { for (int i = values.size(); --i >= 0;) { @@ -4311,12 +4340,12 @@ bool NamedValueSet::set (const var::identifier& name, const var& newValue) return true; } -bool NamedValueSet::contains (const var::identifier& name) const +bool NamedValueSet::contains (const Identifier& name) const { return getItem (name) != 0; } -bool NamedValueSet::remove (const var::identifier& name) +bool NamedValueSet::remove (const Identifier& name) { for (int i = values.size(); --i >= 0;) { @@ -4330,7 +4359,7 @@ bool NamedValueSet::remove (const var::identifier& name) return false; } -const var::identifier NamedValueSet::getName (const int index) const +const Identifier NamedValueSet::getName (const int index) const { jassert (((unsigned int) index) < (unsigned int) values.size()); return values [index].name; @@ -4362,40 +4391,40 @@ DynamicObject::~DynamicObject() { } -bool DynamicObject::hasProperty (const var::identifier& propertyName) const +bool DynamicObject::hasProperty (const Identifier& propertyName) const { var* const v = properties.getItem (propertyName); return v != 0 && ! v->isMethod(); } -const var DynamicObject::getProperty (const var::identifier& propertyName) const +const var DynamicObject::getProperty (const Identifier& propertyName) const { return properties [propertyName]; } -void DynamicObject::setProperty (const var::identifier& propertyName, const var& newValue) +void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue) { properties.set (propertyName, newValue); } -void DynamicObject::removeProperty (const var::identifier& propertyName) +void DynamicObject::removeProperty (const Identifier& propertyName) { properties.remove (propertyName); } -bool DynamicObject::hasMethod (const var::identifier& methodName) const +bool DynamicObject::hasMethod (const Identifier& methodName) const { return getProperty (methodName).isMethod(); } -const var DynamicObject::invokeMethod (const var::identifier& methodName, +const var DynamicObject::invokeMethod (const Identifier& methodName, const var* parameters, int numParameters) { return properties [methodName].invoke (var (this), parameters, numParameters); } -void DynamicObject::setMethod (const var::identifier& name, +void DynamicObject::setMethod (const Identifier& name, var::MethodFunction methodFunction) { properties.set (name, var (methodFunction)); @@ -6673,6 +6702,39 @@ bool File::replaceWithText (const String& textToWrite, return tempFile.overwriteTargetFileWithTemporary(); } +bool File::hasIdenticalContentTo (const File& other) const +{ + if (other == *this) + return true; + + if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile()) + { + FileInputStream in1 (*this), in2 (other); + + const int bufferSize = 4096; + HeapBlock buffer1, buffer2; + buffer1.malloc (bufferSize); + buffer2.malloc (bufferSize); + + for (;;) + { + const int num1 = in1.read (buffer1, bufferSize); + const int num2 = in2.read (buffer2, bufferSize); + + if (num1 != num2) + break; + + if (num1 <= 0) + return true; + + if (memcmp (buffer1, buffer2, num1) != 0) + break; + } + } + + return false; +} + const String File::createLegalPathName (const String& original) { String s (original); @@ -10079,12 +10141,17 @@ bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw() int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw() { - if (digit >= '0' && digit <= '9') - return digit - '0'; - else if (digit >= 'a' && digit <= 'f') - return digit - ('a' - 10); - else if (digit >= 'A' && digit <= 'F') - return digit - ('A' - 10); + unsigned int d = digit - '0'; + if (d < (unsigned int) 10) + return (int) d; + + d += '0' - 'a'; + if (d < (unsigned int) 6) + return (int) d + 10; + + d += 'a' - 'A'; + if (d < (unsigned int) 6) + return (int) d + 10; return -1; } @@ -12955,6 +13022,84 @@ END_JUCE_NAMESPACE /*** End of inlined file: juce_StringPairArray.cpp ***/ +/*** Start of inlined file: juce_StringPool.cpp ***/ +BEGIN_JUCE_NAMESPACE + +StringPool::StringPool() throw() {} +StringPool::~StringPool() {} + +template +static const juce_wchar* getPooledStringFromArray (Array& strings, StringType newString) +{ + int start = 0; + int end = strings.size(); + + for (;;) + { + if (start >= end) + { + jassert (start <= end); + strings.insert (start, newString); + return strings.getReference (start); + } + else + { + const String& startString = strings.getReference (start); + + if (startString == newString) + return startString; + + const int halfway = (start + end) >> 1; + + if (halfway == start) + { + if (startString.compare (newString) < 0) + ++start; + + strings.insert (start, newString); + return strings.getReference (start); + } + + const int comp = strings.getReference (halfway).compare (newString); + + if (comp == 0) + return strings.getReference (halfway); + else if (comp < 0) + start = halfway; + else + end = halfway; + } + } +} + +const juce_wchar* StringPool::getPooledString (const String& s) +{ + if (s.isEmpty()) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +const juce_wchar* StringPool::getPooledString (const char* const s) +{ + if (s == 0 || *s == 0) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +const juce_wchar* StringPool::getPooledString (const juce_wchar* const s) +{ + if (s == 0 || *s == 0) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +END_JUCE_NAMESPACE +/*** End of inlined file: juce_StringPool.cpp ***/ + + /*** Start of inlined file: juce_XmlDocument.cpp ***/ BEGIN_JUCE_NAMESPACE @@ -15811,7 +15956,7 @@ BEGIN_JUCE_NAMESPACE class ValueTree::SetPropertyAction : public UndoableAction { public: - SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_, + SetPropertyAction (const SharedObjectPtr& target_, const Identifier& name_, const var& newValue_, const var& oldValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) : target (target_), name (name_), newValue (newValue_), oldValue (oldValue_), @@ -15866,7 +16011,7 @@ public: private: const SharedObjectPtr target; - const var::identifier name; + const Identifier name; const var newValue; var oldValue; const bool isAddingNewProperty : 1, isDeletingProperty : 1; @@ -15979,7 +16124,7 @@ private: MoveChildAction& operator= (const MoveChildAction&); }; -ValueTree::SharedObject::SharedObject (const String& type_) +ValueTree::SharedObject::SharedObject (const Identifier& type_) : type (type_), parent (0) { } @@ -16008,7 +16153,7 @@ ValueTree::SharedObject::~SharedObject() } } -void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property) +void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const Identifier& property) { for (int i = valueTreesWithListeners.size(); --i >= 0;) { @@ -16018,7 +16163,7 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const } } -void ValueTree::SharedObject::sendPropertyChangeMessage (const var::identifier& property) +void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& property) { ValueTree tree (this); ValueTree::SharedObject* t = this; @@ -16072,17 +16217,17 @@ void ValueTree::SharedObject::sendParentChangeMessage() } } -const var& ValueTree::SharedObject::getProperty (const var::identifier& name) const +const var& ValueTree::SharedObject::getProperty (const Identifier& name) const { return properties [name]; } -const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const +const var ValueTree::SharedObject::getProperty (const Identifier& name, const var& defaultReturnValue) const { return properties.getWithDefault (name, defaultReturnValue); } -void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) +void ValueTree::SharedObject::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager) { if (undoManager == 0) { @@ -16105,12 +16250,12 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va } } -bool ValueTree::SharedObject::hasProperty (const var::identifier& name) const +bool ValueTree::SharedObject::hasProperty (const Identifier& name) const { return properties.contains (name); } -void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoManager* const undoManager) +void ValueTree::SharedObject::removeProperty (const Identifier& name, UndoManager* const undoManager) { if (undoManager == 0) { @@ -16130,7 +16275,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage { while (properties.size() > 0) { - const var::identifier name (properties.getName (properties.size() - 1)); + const Identifier name (properties.getName (properties.size() - 1)); properties.remove (name); sendPropertyChangeMessage (name); } @@ -16142,7 +16287,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage } } -ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) const +ValueTree ValueTree::SharedObject::getChildWithName (const Identifier& typeToMatch) const { for (int i = 0; i < children.size(); ++i) if (children.getUnchecked(i)->type == typeToMatch) @@ -16151,7 +16296,7 @@ ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) return ValueTree::invalid; } -ValueTree ValueTree::SharedObject::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const +ValueTree ValueTree::SharedObject::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const { for (int i = 0; i < children.size(); ++i) if (children.getUnchecked(i)->getProperty (propertyName) == propertyValue) @@ -16277,10 +16422,10 @@ ValueTree::ValueTree() throw() const ValueTree ValueTree::invalid; -ValueTree::ValueTree (const String& type_) +ValueTree::ValueTree (const Identifier& type_) : object (new ValueTree::SharedObject (type_)) { - jassert (type_.isNotEmpty()); // All objects should be given a sensible type name! + jassert (type_.toString().isNotEmpty()); // All objects should be given a sensible type name! } ValueTree::ValueTree (SharedObject* const object_) @@ -16330,14 +16475,14 @@ ValueTree ValueTree::createCopy() const return ValueTree (object != 0 ? new SharedObject (*object) : 0); } -bool ValueTree::hasType (const String& typeName) const +bool ValueTree::hasType (const Identifier& typeName) const { return object != 0 && object->type == typeName; } const String ValueTree::getType() const { - return object != 0 ? object->type : String::empty; + return object != 0 ? object->type.toString() : String::empty; } ValueTree ValueTree::getParent() const @@ -16345,35 +16490,35 @@ ValueTree ValueTree::getParent() const return ValueTree (object != 0 ? object->parent : (SharedObject*) 0); } -const var& ValueTree::operator[] (const var::identifier& name) const +const var& ValueTree::operator[] (const Identifier& name) const { return object == 0 ? var::null : object->getProperty (name); } -const var& ValueTree::getProperty (const var::identifier& name) const +const var& ValueTree::getProperty (const Identifier& name) const { return object == 0 ? var::null : object->getProperty (name); } -const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const +const var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const { return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue); } -void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) +void ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager) { - jassert (name.name.isNotEmpty()); + jassert (name.toString().isNotEmpty()); - if (object != 0 && name.name.isNotEmpty()) + if (object != 0 && name.toString().isNotEmpty()) object->setProperty (name, newValue, undoManager); } -bool ValueTree::hasProperty (const var::identifier& name) const +bool ValueTree::hasProperty (const Identifier& name) const { return object != 0 && object->hasProperty (name); } -void ValueTree::removeProperty (const var::identifier& name, UndoManager* const undoManager) +void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager) { if (object != 0) object->removeProperty (name, undoManager); @@ -16390,9 +16535,9 @@ int ValueTree::getNumProperties() const return object == 0 ? 0 : object->properties.size(); } -const var::identifier ValueTree::getPropertyName (const int index) const +const Identifier ValueTree::getPropertyName (const int index) const { - return object == 0 ? var::identifier() + return object == 0 ? Identifier() : object->properties.getName (index); } @@ -16401,7 +16546,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource, { public: ValueTreePropertyValueSource (const ValueTree& tree_, - const var::identifier& property_, + const Identifier& property_, UndoManager* const undoManager_) : tree (tree_), property (property_), @@ -16425,7 +16570,7 @@ public: tree.setProperty (property, newValue, undoManager); } - void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& changedProperty) + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& changedProperty) { if (tree == treeWhosePropertyHasChanged && property == changedProperty) sendChangeMessage (false); @@ -16436,13 +16581,13 @@ public: private: ValueTree tree; - const var::identifier property; + const Identifier property; UndoManager* const undoManager; ValueTreePropertyValueSource& operator= (const ValueTreePropertyValueSource&); }; -Value ValueTree::getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const +Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager) const { return Value (new ValueTreePropertyValueSource (*this, name, undoManager)); } @@ -16457,12 +16602,12 @@ ValueTree ValueTree::getChild (int index) const return ValueTree (object != 0 ? (SharedObject*) object->children [index] : (SharedObject*) 0); } -ValueTree ValueTree::getChildWithName (const String& type) const +ValueTree ValueTree::getChildWithName (const Identifier& type) const { return object != 0 ? object->getChildWithName (type) : ValueTree::invalid; } -ValueTree ValueTree::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const +ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const { return object != 0 ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree::invalid; } @@ -16528,17 +16673,17 @@ void ValueTree::removeListener (Listener* listener) XmlElement* ValueTree::SharedObject::createXml() const { - XmlElement* xml = new XmlElement (type); + XmlElement* xml = new XmlElement (type.toString()); int i; for (i = 0; i < properties.size(); ++i) { - var::identifier name (properties.getName(i)); + Identifier name (properties.getName(i)); const var& v = properties [name]; jassert (! v.isObject()); // DynamicObjects can't be stored as XML! - xml->setAttribute (name.name, v.toString()); + xml->setAttribute (name.toString(), v.toString()); } for (i = 0; i < children.size(); ++i) @@ -16579,8 +16724,8 @@ void ValueTree::writeToStream (OutputStream& output) int i; for (i = 0; i < numProps; ++i) { - const var::identifier name (getPropertyName(i)); - output.writeString (name.name); + const Identifier name (getPropertyName(i)); + output.writeString (name.toString()); getProperty(name).writeToStream (output); } @@ -39985,7 +40130,7 @@ void Component::sendLookAndFeelChange() } } -static const var::identifier getColourPropertyId (const int colourId) +static const Identifier getColourPropertyId (const int colourId) { String s; s.preallocateStorage (18); @@ -40029,9 +40174,9 @@ void Component::copyAllExplicitColoursTo (Component& target) const for (int i = properties.size(); --i >= 0;) { - const var::identifier name (properties.getName(i)); + const Identifier name (properties.getName(i)); - if (name.name.startsWith ("jcclr_")) + if (name.toString().startsWith ("jcclr_")) if (target.properties.set (name, properties [name])) changed = true; } @@ -50357,7 +50502,7 @@ public: { jassert (row >= 0); - const var::identifier tagPropertyName ("_tableLastUseNum"); + const Identifier tagPropertyName ("_tableLastUseNum"); const int newTag = Random::getSystemRandom().nextInt(); const TableHeaderComponent* const header = owner.getHeader(); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 0f961e5bef..a8c5c3f0ec 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -1620,7 +1620,6 @@ public: /** Destructor. */ ~String() throw(); - //========================juce_wchar====================================================== /** This is an empty string that can be used whenever one is needed. It's better to use this than String() because it explains what's going on @@ -4684,6 +4683,65 @@ typedef BigInteger BitArray; #define __JUCE_VARIANT_JUCEHEADER__ +/*** Start of inlined file: juce_Identifier.h ***/ +#ifndef __JUCE_IDENTIFIER_JUCEHEADER__ +#define __JUCE_IDENTIFIER_JUCEHEADER__ + +/** + Represents a string identifier, designed for accessing properties by name. + + Identifier objects are very light and fast to copy, but slower to initialise + from a string, so it's much faster to keep a static identifier object to refer + to frequently-used names, rather than constructing them each time you need it. + + @see NamedPropertySet, ValueTree +*/ +class JUCE_API Identifier +{ +public: + /** Creates a null identifier. */ + Identifier() throw(); + + /** Creates an identifier with a specified name. + Because this name may need to be used in contexts such as script variables or XML + tags, it must only contain ascii letters and digits, or the underscore character. + */ + Identifier (const char* name); + + /** Creates an identifier with a specified name. + Because this name may need to be used in contexts such as script variables or XML + tags, it must only contain ascii letters and digits, or the underscore character. + */ + Identifier (const String& name); + + /** Creates a copy of another identifier. */ + Identifier (const Identifier& other) throw(); + + /** Creates a copy of another identifier. */ + Identifier& operator= (const Identifier& other) throw(); + + /** Destructor */ + ~Identifier(); + + /** Compares two identifiers. This is a very fast operation. */ + inline bool operator== (const Identifier& other) const throw() { return name == other.name; } + + /** Compares two identifiers. This is a very fast operation. */ + inline bool operator!= (const Identifier& other) const throw() { return name != other.name; } + + const String toString() const { return name; } + +private: + + const juce_wchar* name; + + class Pool; +}; + +#endif // __JUCE_IDENTIFIER_JUCEHEADER__ +/*** End of inlined file: juce_Identifier.h ***/ + + /*** Start of inlined file: juce_OutputStream.h ***/ #ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__ #define __JUCE_OUTPUTSTREAM_JUCEHEADER__ @@ -5356,6 +5414,7 @@ class JUCE_API var public: typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments); + typedef Identifier identifier; /** Creates a void variant. */ var() throw(); @@ -5415,55 +5474,24 @@ public: */ static const var readFromStream (InputStream& input); - class JUCE_API identifier - { - public: - /** Creates a null identifier. */ - identifier() throw(); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - identifier (const char* name); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - identifier (const String& name); - - /** Destructor */ - ~identifier(); - - bool operator== (const identifier& other) const throw() - { - jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions - return hashCode == other.hashCode; - } - - String name; - int hashCode; - }; - /** If this variant is an object, this returns one of its properties. */ - const var operator[] (const identifier& propertyName) const; + const var operator[] (const Identifier& propertyName) const; /** If this variant is an object, this invokes one of its methods with no arguments. */ - const var call (const identifier& method) const; + const var call (const Identifier& method) const; /** If this variant is an object, this invokes one of its methods with one argument. */ - const var call (const identifier& method, const var& arg1) const; + const var call (const Identifier& method, const var& arg1) const; /** If this variant is an object, this invokes one of its methods with 2 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2) const; + const var call (const Identifier& method, const var& arg1, const var& arg2) const; /** If this variant is an object, this invokes one of its methods with 3 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3); /** If this variant is an object, this invokes one of its methods with 4 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; /** If this variant is an object, this invokes one of its methods with 5 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; /** If this variant is an object, this invokes one of its methods with a list of arguments. */ - const var invoke (const identifier& method, const var* arguments, int numArguments) const; + const var invoke (const Identifier& method, const var* arguments, int numArguments) const; /** If this variant is a method pointer, this invokes it on a target object. */ const var invoke (const var& targetObject, const var* arguments, int numArguments) const; @@ -5534,37 +5562,37 @@ public: If the name isn't found, this will return a void variant. @see getProperty */ - const var& operator[] (const var::identifier& name) const; + const var& operator[] (const Identifier& name) const; /** Tries to return the named value, but if no such value is found, this will instead return the supplied default value. */ - const var getWithDefault (const var::identifier& name, const var& defaultReturnValue) const; + const var getWithDefault (const Identifier& name, const var& defaultReturnValue) const; /** Returns a pointer to the object holding a named value, or null if there is no value with this name. */ - var* getItem (const var::identifier& name) const; + var* getItem (const Identifier& name) const; /** Changes or adds a named value. @returns true if a value was changed or added; false if the value was already set the the value passed-in. */ - bool set (const var::identifier& name, const var& newValue); + bool set (const Identifier& name, const var& newValue); /** Returns true if the set contains an item with the specified name. */ - bool contains (const var::identifier& name) const; + bool contains (const Identifier& name) const; /** Removes a value from the set. @returns true if a value was removed; false if there was no value with the name that was given. */ - bool remove (const var::identifier& name); + 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. */ - const var::identifier getName (int index) const; + 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 @@ -5581,9 +5609,9 @@ private: struct NamedValue { NamedValue() throw(); - NamedValue (const var::identifier& name, const var& value); + NamedValue (const Identifier& name, const var& value); - var::identifier name; + Identifier name; var value; }; @@ -6153,19 +6181,19 @@ public: /** Returns true if the object has a property with this name. Note that if the property is actually a method, this will return false. */ - virtual bool hasProperty (const var::identifier& propertyName) const; + virtual bool hasProperty (const Identifier& propertyName) const; /** Returns a named property. This returns a void if no such property exists. */ - virtual const var getProperty (const var::identifier& propertyName) const; + virtual const var getProperty (const Identifier& propertyName) const; /** Sets a named property. */ - virtual void setProperty (const var::identifier& propertyName, const var& newValue); + virtual void setProperty (const Identifier& propertyName, const var& newValue); /** Removes a named property. */ - virtual void removeProperty (const var::identifier& propertyName); + virtual void removeProperty (const Identifier& propertyName); /** Checks whether this object has the specified method. @@ -6173,7 +6201,7 @@ public: with this name that's actually a method, but this can be overridden for building objects with dynamic invocation. */ - virtual bool hasMethod (const var::identifier& methodName) const; + virtual bool hasMethod (const Identifier& methodName) const; /** Invokes a named method on this object. @@ -6183,7 +6211,7 @@ public: This method is virtual to allow more dynamic invocation to used for objects where the methods may not already be set as properies. */ - virtual const var invokeMethod (const var::identifier& methodName, + virtual const var invokeMethod (const Identifier& methodName, const var* parameters, int numParameters); @@ -6198,7 +6226,7 @@ public: setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething); @endcode */ - void setMethod (const var::identifier& methodName, + void setMethod (const Identifier& methodName, var::MethodFunction methodFunction); /** Removes all properties and methods from the object. */ @@ -6220,6 +6248,9 @@ private: #endif #ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ +#endif +#ifndef __JUCE_IDENTIFIER_JUCEHEADER__ + #endif #ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ @@ -8676,6 +8707,11 @@ public: bool asUnicode = false, bool writeUnicodeHeaderBytes = false) const; + /** Attempts to scan the contents of this file and compare it to another file, returning + true if this is possible and they match byte-for-byte. + */ + bool hasIdenticalContentTo (const File& other) const; + /** Creates a set of files to represent each file root. e.g. on Windows this will create files for "c:\", "d:\" etc according @@ -12875,7 +12911,7 @@ public: Like an XmlElement, each ValueTree node has a type, which you can access with getType() and hasType(). */ - explicit ValueTree (const String& type); + explicit ValueTree (const Identifier& type); /** Creates a reference to another ValueTree. */ ValueTree (const ValueTree& other); @@ -12916,44 +12952,44 @@ public: /** Returns true if the node has this type. The comparison is case-sensitive. */ - bool hasType (const String& typeName) const; + bool hasType (const Identifier& typeName) const; /** Returns the value of a named property. If no such property has been set, this will return a void variant. You can also use operator[] to get a property. @see var, setProperty, hasProperty */ - const var& getProperty (const var::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 */ - const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; + 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 var::identifier& name) const; + const var& operator[] (const Identifier& name) const; /** Changes a named property of the node. If the undoManager parameter is non-null, its UndoManager::perform() method will be used, so that this change can be undone. @see var, getProperty, removeProperty */ - void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager); + void setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager); /** Returns true if the node contains a named property. */ - bool hasProperty (const var::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 var::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, @@ -12969,7 +13005,7 @@ public: /** Returns the identifier of the property with a given index. @see getNumProperties */ - const var::identifier getPropertyName (int index) const; + const Identifier getPropertyName (int index) const; /** Returns a Value object that can be used to control and respond to one of the tree's properties. @@ -12977,7 +13013,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 var::identifier& name, UndoManager* undoManager) const; + Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager) const; /** Returns the number of child nodes belonging to this one. @see getChild @@ -12994,7 +13030,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 getChildWithName (const String& type) const; + ValueTree getChildWithName (const Identifier& type) const; /** Looks for the first child node that has the speficied property value. @@ -13004,7 +13040,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 var::identifier& propertyName, const var& propertyValue) const; + ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const; /** Adds a child to this node. @@ -13121,7 +13157,7 @@ public: simply check the tree parameter in this callback to make sure it's the tree you're interested in. */ virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, - const var::identifier& property) = 0; + const Identifier& property) = 0; /** This method is called when a child sub-tree is added or removed. @@ -13214,31 +13250,31 @@ private: class JUCE_API SharedObject : public ReferenceCountedObject { public: - explicit SharedObject (const String& type); + explicit SharedObject (const Identifier& type); SharedObject (const SharedObject& other); ~SharedObject(); - const String type; + const Identifier type; NamedValueSet properties; ReferenceCountedArray children; SortedSet valueTreesWithListeners; SharedObject* parent; - void sendPropertyChangeMessage (const var::identifier& property); - void sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property); + void sendPropertyChangeMessage (const Identifier& property); + void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property); void sendChildChangeMessage(); void sendChildChangeMessage (ValueTree& tree); void sendParentChangeMessage(); - const var& getProperty (const var::identifier& name) const; - const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; - void setProperty (const var::identifier& name, const var& newValue, UndoManager*); - bool hasProperty (const var::identifier& name) const; - void removeProperty (const var::identifier& name, UndoManager*); + const var& getProperty (const Identifier& name) const; + const var getProperty (const Identifier& name, const var& defaultReturnValue) const; + void setProperty (const Identifier& name, const var& newValue, UndoManager*); + bool hasProperty (const Identifier& name) const; + void removeProperty (const Identifier& name, UndoManager*); void removeAllProperties (UndoManager*); bool isAChildOf (const SharedObject* possibleParent) const; int indexOf (const ValueTree& child) const; - ValueTree getChildWithName (const String& type) const; - ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; + ValueTree getChildWithName (const Identifier& type) const; + ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const; void addChild (SharedObject* child, int index, UndoManager*); void removeChild (int childIndex, UndoManager*); void removeAllChildren (UndoManager*); @@ -16743,6 +16779,64 @@ private: #endif #ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__ +#endif +#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ + +/*** Start of inlined file: juce_StringPool.h ***/ +#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ +#define __JUCE_STRINGPOOL_JUCEHEADER__ + +/** + A StringPool holds a set of shared strings, which reduces storage overheads and improves + comparison speed when dealing with many duplicate strings. + + When you add a string to a pool using getPooledString, it'll return a character + array containing the same string. This array is owned by the pool, and the same array + is returned every time a matching string is asked for. This means that it's trivial to + compare two pooled strings for equality, as you can simply compare their pointers. It + also cuts down on storage if you're using many copies of the same string. +*/ +class JUCE_API StringPool +{ +public: + /** Creates an empty pool. */ + StringPool() throw(); + + /** Destructor */ + ~StringPool(); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const String& original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const char* original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const juce_wchar* original); + +private: + Array strings; +}; + +#endif // __JUCE_STRINGPOOL_JUCEHEADER__ +/*** End of inlined file: juce_StringPool.h ***/ + + #endif #ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__ diff --git a/src/containers/juce_DynamicObject.cpp b/src/containers/juce_DynamicObject.cpp index 38ea1b96c4..497379e559 100644 --- a/src/containers/juce_DynamicObject.cpp +++ b/src/containers/juce_DynamicObject.cpp @@ -39,40 +39,40 @@ DynamicObject::~DynamicObject() { } -bool DynamicObject::hasProperty (const var::identifier& propertyName) const +bool DynamicObject::hasProperty (const Identifier& propertyName) const { var* const v = properties.getItem (propertyName); return v != 0 && ! v->isMethod(); } -const var DynamicObject::getProperty (const var::identifier& propertyName) const +const var DynamicObject::getProperty (const Identifier& propertyName) const { return properties [propertyName]; } -void DynamicObject::setProperty (const var::identifier& propertyName, const var& newValue) +void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue) { properties.set (propertyName, newValue); } -void DynamicObject::removeProperty (const var::identifier& propertyName) +void DynamicObject::removeProperty (const Identifier& propertyName) { properties.remove (propertyName); } -bool DynamicObject::hasMethod (const var::identifier& methodName) const +bool DynamicObject::hasMethod (const Identifier& methodName) const { return getProperty (methodName).isMethod(); } -const var DynamicObject::invokeMethod (const var::identifier& methodName, +const var DynamicObject::invokeMethod (const Identifier& methodName, const var* parameters, int numParameters) { return properties [methodName].invoke (var (this), parameters, numParameters); } -void DynamicObject::setMethod (const var::identifier& name, +void DynamicObject::setMethod (const Identifier& name, var::MethodFunction methodFunction) { properties.set (name, var (methodFunction)); diff --git a/src/containers/juce_DynamicObject.h b/src/containers/juce_DynamicObject.h index 0bfff07029..0a321ee00d 100644 --- a/src/containers/juce_DynamicObject.h +++ b/src/containers/juce_DynamicObject.h @@ -54,19 +54,19 @@ public: /** Returns true if the object has a property with this name. Note that if the property is actually a method, this will return false. */ - virtual bool hasProperty (const var::identifier& propertyName) const; + virtual bool hasProperty (const Identifier& propertyName) const; /** Returns a named property. This returns a void if no such property exists. */ - virtual const var getProperty (const var::identifier& propertyName) const; + virtual const var getProperty (const Identifier& propertyName) const; /** Sets a named property. */ - virtual void setProperty (const var::identifier& propertyName, const var& newValue); + virtual void setProperty (const Identifier& propertyName, const var& newValue); /** Removes a named property. */ - virtual void removeProperty (const var::identifier& propertyName); + virtual void removeProperty (const Identifier& propertyName); //============================================================================== /** Checks whether this object has the specified method. @@ -75,7 +75,7 @@ public: with this name that's actually a method, but this can be overridden for building objects with dynamic invocation. */ - virtual bool hasMethod (const var::identifier& methodName) const; + virtual bool hasMethod (const Identifier& methodName) const; /** Invokes a named method on this object. @@ -85,7 +85,7 @@ public: This method is virtual to allow more dynamic invocation to used for objects where the methods may not already be set as properies. */ - virtual const var invokeMethod (const var::identifier& methodName, + virtual const var invokeMethod (const Identifier& methodName, const var* parameters, int numParameters); @@ -100,7 +100,7 @@ public: setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething); @endcode */ - void setMethod (const var::identifier& methodName, + void setMethod (const Identifier& methodName, var::MethodFunction methodFunction); //============================================================================== diff --git a/src/containers/juce_Identifier.cpp b/src/containers/juce_Identifier.cpp new file mode 100644 index 0000000000..0d00961ce6 --- /dev/null +++ b/src/containers/juce_Identifier.cpp @@ -0,0 +1,88 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../core/juce_StandardHeader.h" + +BEGIN_JUCE_NAMESPACE + +#include "juce_Identifier.h" +#include "../utilities/juce_DeletedAtShutdown.h" +#include "../core/juce_Singleton.h" +#include "../text/juce_StringPool.h" + + +//============================================================================== +class Identifier::Pool : public DeletedAtShutdown +{ +public: + Pool() {} + ~Pool() {} + + StringPool pool; + + juce_DeclareSingleton_SingleThreaded_Minimal (Pool); +}; + +juce_ImplementSingleton_SingleThreaded (Identifier::Pool); + + +//============================================================================== +Identifier::Identifier() throw() + : name (0) +{ +} + +Identifier::Identifier (const Identifier& other) throw() + : name (other.name) +{ +} + +Identifier& Identifier::operator= (const Identifier& other) throw() +{ + name = other.name; + return *this; +} + +Identifier::Identifier (const String& name_) + : name (Identifier::Pool::getInstance()->pool.getPooledString (name_)) +{ + /* An Identifier string must be suitable for use as a script variable or XML + attribute, so it can only contain this limited set of characters.. */ + jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty()); +} + +Identifier::Identifier (const char* const name_) + : name (Identifier::Pool::getInstance()->pool.getPooledString (name_)) +{ + /* An Identifier string must be suitable for use as a script variable or XML + attribute, so it can only contain this limited set of characters.. */ + jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty()); +} + +Identifier::~Identifier() +{ +} + +END_JUCE_NAMESPACE diff --git a/src/containers/juce_Identifier.h b/src/containers/juce_Identifier.h new file mode 100644 index 0000000000..549a1f31f8 --- /dev/null +++ b/src/containers/juce_Identifier.h @@ -0,0 +1,85 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_IDENTIFIER_JUCEHEADER__ +#define __JUCE_IDENTIFIER_JUCEHEADER__ + +#include "../text/juce_String.h" + + +//============================================================================== +/** + Represents a string identifier, designed for accessing properties by name. + + Identifier objects are very light and fast to copy, but slower to initialise + from a string, so it's much faster to keep a static identifier object to refer + to frequently-used names, rather than constructing them each time you need it. + + @see NamedPropertySet, ValueTree +*/ +class JUCE_API Identifier +{ +public: + /** Creates a null identifier. */ + Identifier() throw(); + + /** Creates an identifier with a specified name. + Because this name may need to be used in contexts such as script variables or XML + tags, it must only contain ascii letters and digits, or the underscore character. + */ + Identifier (const char* name); + + /** Creates an identifier with a specified name. + Because this name may need to be used in contexts such as script variables or XML + tags, it must only contain ascii letters and digits, or the underscore character. + */ + Identifier (const String& name); + + /** Creates a copy of another identifier. */ + Identifier (const Identifier& other) throw(); + + /** Creates a copy of another identifier. */ + Identifier& operator= (const Identifier& other) throw(); + + /** Destructor */ + ~Identifier(); + + /** Compares two identifiers. This is a very fast operation. */ + inline bool operator== (const Identifier& other) const throw() { return name == other.name; } + + /** Compares two identifiers. This is a very fast operation. */ + inline bool operator!= (const Identifier& other) const throw() { return name != other.name; } + + const String toString() const { return name; } + +private: + //============================================================================== + const juce_wchar* name; + + class Pool; +}; + + +#endif // __JUCE_IDENTIFIER_JUCEHEADER__ diff --git a/src/containers/juce_NamedValueSet.cpp b/src/containers/juce_NamedValueSet.cpp index 32ba2df022..e6ae1c033e 100644 --- a/src/containers/juce_NamedValueSet.cpp +++ b/src/containers/juce_NamedValueSet.cpp @@ -35,7 +35,7 @@ NamedValueSet::NamedValue::NamedValue() throw() { } -inline NamedValueSet::NamedValue::NamedValue (const var::identifier& name_, const var& value_) +inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var& value_) : name (name_), value (value_) { } @@ -65,7 +65,7 @@ int NamedValueSet::size() const throw() return values.size(); } -const var& NamedValueSet::operator[] (const var::identifier& name) const +const var& NamedValueSet::operator[] (const Identifier& name) const { for (int i = values.size(); --i >= 0;) { @@ -78,13 +78,13 @@ const var& NamedValueSet::operator[] (const var::identifier& name) const return var::null; } -const var NamedValueSet::getWithDefault (const var::identifier& name, const var& defaultReturnValue) const +const var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const { const var* v = getItem (name); return v != 0 ? *v : defaultReturnValue; } -var* NamedValueSet::getItem (const var::identifier& name) const +var* NamedValueSet::getItem (const Identifier& name) const { for (int i = values.size(); --i >= 0;) { @@ -97,7 +97,7 @@ var* NamedValueSet::getItem (const var::identifier& name) const return 0; } -bool NamedValueSet::set (const var::identifier& name, const var& newValue) +bool NamedValueSet::set (const Identifier& name, const var& newValue) { for (int i = values.size(); --i >= 0;) { @@ -117,12 +117,12 @@ bool NamedValueSet::set (const var::identifier& name, const var& newValue) return true; } -bool NamedValueSet::contains (const var::identifier& name) const +bool NamedValueSet::contains (const Identifier& name) const { return getItem (name) != 0; } -bool NamedValueSet::remove (const var::identifier& name) +bool NamedValueSet::remove (const Identifier& name) { for (int i = values.size(); --i >= 0;) { @@ -136,7 +136,7 @@ bool NamedValueSet::remove (const var::identifier& name) return false; } -const var::identifier NamedValueSet::getName (const int index) const +const Identifier NamedValueSet::getName (const int index) const { jassert (((unsigned int) index) < (unsigned int) values.size()); return values [index].name; diff --git a/src/containers/juce_NamedValueSet.h b/src/containers/juce_NamedValueSet.h index a364deecd3..1edf78d4fb 100644 --- a/src/containers/juce_NamedValueSet.h +++ b/src/containers/juce_NamedValueSet.h @@ -59,37 +59,37 @@ public: If the name isn't found, this will return a void variant. @see getProperty */ - const var& operator[] (const var::identifier& name) const; + const var& operator[] (const Identifier& name) const; /** Tries to return the named value, but if no such value is found, this will instead return the supplied default value. */ - const var getWithDefault (const var::identifier& name, const var& defaultReturnValue) const; + const var getWithDefault (const Identifier& name, const var& defaultReturnValue) const; /** Returns a pointer to the object holding a named value, or null if there is no value with this name. */ - var* getItem (const var::identifier& name) const; + var* getItem (const Identifier& name) const; /** Changes or adds a named value. @returns true if a value was changed or added; false if the value was already set the the value passed-in. */ - bool set (const var::identifier& name, const var& newValue); + bool set (const Identifier& name, const var& newValue); /** Returns true if the set contains an item with the specified name. */ - bool contains (const var::identifier& name) const; + bool contains (const Identifier& name) const; /** Removes a value from the set. @returns true if a value was removed; false if there was no value with the name that was given. */ - bool remove (const var::identifier& name); + 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. */ - const var::identifier getName (int index) const; + 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 @@ -107,9 +107,9 @@ private: struct NamedValue { NamedValue() throw(); - NamedValue (const var::identifier& name, const var& value); + NamedValue (const Identifier& name, const var& value); - var::identifier name; + Identifier name; var value; }; diff --git a/src/containers/juce_ValueTree.cpp b/src/containers/juce_ValueTree.cpp index a2927866c3..d340a22a3c 100644 --- a/src/containers/juce_ValueTree.cpp +++ b/src/containers/juce_ValueTree.cpp @@ -35,7 +35,7 @@ BEGIN_JUCE_NAMESPACE class ValueTree::SetPropertyAction : public UndoableAction { public: - SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_, + SetPropertyAction (const SharedObjectPtr& target_, const Identifier& name_, const var& newValue_, const var& oldValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) : target (target_), name (name_), newValue (newValue_), oldValue (oldValue_), @@ -90,7 +90,7 @@ public: private: const SharedObjectPtr target; - const var::identifier name; + const Identifier name; const var newValue; var oldValue; const bool isAddingNewProperty : 1, isDeletingProperty : 1; @@ -207,7 +207,7 @@ private: //============================================================================== -ValueTree::SharedObject::SharedObject (const String& type_) +ValueTree::SharedObject::SharedObject (const Identifier& type_) : type (type_), parent (0) { } @@ -237,7 +237,7 @@ ValueTree::SharedObject::~SharedObject() } //============================================================================== -void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property) +void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const Identifier& property) { for (int i = valueTreesWithListeners.size(); --i >= 0;) { @@ -247,7 +247,7 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const } } -void ValueTree::SharedObject::sendPropertyChangeMessage (const var::identifier& property) +void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& property) { ValueTree tree (this); ValueTree::SharedObject* t = this; @@ -302,17 +302,17 @@ void ValueTree::SharedObject::sendParentChangeMessage() } //============================================================================== -const var& ValueTree::SharedObject::getProperty (const var::identifier& name) const +const var& ValueTree::SharedObject::getProperty (const Identifier& name) const { return properties [name]; } -const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const +const var ValueTree::SharedObject::getProperty (const Identifier& name, const var& defaultReturnValue) const { return properties.getWithDefault (name, defaultReturnValue); } -void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) +void ValueTree::SharedObject::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager) { if (undoManager == 0) { @@ -335,12 +335,12 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va } } -bool ValueTree::SharedObject::hasProperty (const var::identifier& name) const +bool ValueTree::SharedObject::hasProperty (const Identifier& name) const { return properties.contains (name); } -void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoManager* const undoManager) +void ValueTree::SharedObject::removeProperty (const Identifier& name, UndoManager* const undoManager) { if (undoManager == 0) { @@ -360,7 +360,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage { while (properties.size() > 0) { - const var::identifier name (properties.getName (properties.size() - 1)); + const Identifier name (properties.getName (properties.size() - 1)); properties.remove (name); sendPropertyChangeMessage (name); } @@ -372,7 +372,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage } } -ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) const +ValueTree ValueTree::SharedObject::getChildWithName (const Identifier& typeToMatch) const { for (int i = 0; i < children.size(); ++i) if (children.getUnchecked(i)->type == typeToMatch) @@ -381,7 +381,7 @@ ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) return ValueTree::invalid; } -ValueTree ValueTree::SharedObject::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const +ValueTree ValueTree::SharedObject::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const { for (int i = 0; i < children.size(); ++i) if (children.getUnchecked(i)->getProperty (propertyName) == propertyValue) @@ -508,10 +508,10 @@ ValueTree::ValueTree() throw() const ValueTree ValueTree::invalid; -ValueTree::ValueTree (const String& type_) +ValueTree::ValueTree (const Identifier& type_) : object (new ValueTree::SharedObject (type_)) { - jassert (type_.isNotEmpty()); // All objects should be given a sensible type name! + jassert (type_.toString().isNotEmpty()); // All objects should be given a sensible type name! } ValueTree::ValueTree (SharedObject* const object_) @@ -561,14 +561,14 @@ ValueTree ValueTree::createCopy() const return ValueTree (object != 0 ? new SharedObject (*object) : 0); } -bool ValueTree::hasType (const String& typeName) const +bool ValueTree::hasType (const Identifier& typeName) const { return object != 0 && object->type == typeName; } const String ValueTree::getType() const { - return object != 0 ? object->type : String::empty; + return object != 0 ? object->type.toString() : String::empty; } ValueTree ValueTree::getParent() const @@ -576,35 +576,35 @@ ValueTree ValueTree::getParent() const return ValueTree (object != 0 ? object->parent : (SharedObject*) 0); } -const var& ValueTree::operator[] (const var::identifier& name) const +const var& ValueTree::operator[] (const Identifier& name) const { return object == 0 ? var::null : object->getProperty (name); } -const var& ValueTree::getProperty (const var::identifier& name) const +const var& ValueTree::getProperty (const Identifier& name) const { return object == 0 ? var::null : object->getProperty (name); } -const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const +const var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const { return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue); } -void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) +void ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager) { - jassert (name.name.isNotEmpty()); + jassert (name.toString().isNotEmpty()); - if (object != 0 && name.name.isNotEmpty()) + if (object != 0 && name.toString().isNotEmpty()) object->setProperty (name, newValue, undoManager); } -bool ValueTree::hasProperty (const var::identifier& name) const +bool ValueTree::hasProperty (const Identifier& name) const { return object != 0 && object->hasProperty (name); } -void ValueTree::removeProperty (const var::identifier& name, UndoManager* const undoManager) +void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager) { if (object != 0) object->removeProperty (name, undoManager); @@ -621,9 +621,9 @@ int ValueTree::getNumProperties() const return object == 0 ? 0 : object->properties.size(); } -const var::identifier ValueTree::getPropertyName (const int index) const +const Identifier ValueTree::getPropertyName (const int index) const { - return object == 0 ? var::identifier() + return object == 0 ? Identifier() : object->properties.getName (index); } @@ -633,7 +633,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource, { public: ValueTreePropertyValueSource (const ValueTree& tree_, - const var::identifier& property_, + const Identifier& property_, UndoManager* const undoManager_) : tree (tree_), property (property_), @@ -657,7 +657,7 @@ public: tree.setProperty (property, newValue, undoManager); } - void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& changedProperty) + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& changedProperty) { if (tree == treeWhosePropertyHasChanged && property == changedProperty) sendChangeMessage (false); @@ -668,13 +668,13 @@ public: private: ValueTree tree; - const var::identifier property; + const Identifier property; UndoManager* const undoManager; ValueTreePropertyValueSource& operator= (const ValueTreePropertyValueSource&); }; -Value ValueTree::getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const +Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager) const { return Value (new ValueTreePropertyValueSource (*this, name, undoManager)); } @@ -690,12 +690,12 @@ ValueTree ValueTree::getChild (int index) const return ValueTree (object != 0 ? (SharedObject*) object->children [index] : (SharedObject*) 0); } -ValueTree ValueTree::getChildWithName (const String& type) const +ValueTree ValueTree::getChildWithName (const Identifier& type) const { return object != 0 ? object->getChildWithName (type) : ValueTree::invalid; } -ValueTree ValueTree::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const +ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const { return object != 0 ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree::invalid; } @@ -763,17 +763,17 @@ void ValueTree::removeListener (Listener* listener) //============================================================================== XmlElement* ValueTree::SharedObject::createXml() const { - XmlElement* xml = new XmlElement (type); + XmlElement* xml = new XmlElement (type.toString()); int i; for (i = 0; i < properties.size(); ++i) { - var::identifier name (properties.getName(i)); + Identifier name (properties.getName(i)); const var& v = properties [name]; jassert (! v.isObject()); // DynamicObjects can't be stored as XML! - xml->setAttribute (name.name, v.toString()); + xml->setAttribute (name.toString(), v.toString()); } for (i = 0; i < children.size(); ++i) @@ -815,8 +815,8 @@ void ValueTree::writeToStream (OutputStream& output) int i; for (i = 0; i < numProps; ++i) { - const var::identifier name (getPropertyName(i)); - output.writeString (name.name); + const Identifier name (getPropertyName(i)); + output.writeString (name.toString()); getProperty(name).writeToStream (output); } diff --git a/src/containers/juce_ValueTree.h b/src/containers/juce_ValueTree.h index d591c819ab..27007a20a0 100644 --- a/src/containers/juce_ValueTree.h +++ b/src/containers/juce_ValueTree.h @@ -87,7 +87,7 @@ public: Like an XmlElement, each ValueTree node has a type, which you can access with getType() and hasType(). */ - explicit ValueTree (const String& type); + explicit ValueTree (const Identifier& type); /** Creates a reference to another ValueTree. */ ValueTree (const ValueTree& other); @@ -130,7 +130,7 @@ public: /** Returns true if the node has this type. The comparison is case-sensitive. */ - bool hasType (const String& typeName) const; + bool hasType (const Identifier& typeName) const; //============================================================================== /** Returns the value of a named property. @@ -138,37 +138,37 @@ public: You can also use operator[] to get a property. @see var, setProperty, hasProperty */ - const var& getProperty (const var::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 */ - const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; + 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 var::identifier& name) const; + const var& operator[] (const Identifier& name) const; /** Changes a named property of the node. If the undoManager parameter is non-null, its UndoManager::perform() method will be used, so that this change can be undone. @see var, getProperty, removeProperty */ - void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager); + void setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager); /** Returns true if the node contains a named property. */ - bool hasProperty (const var::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 var::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, @@ -184,7 +184,7 @@ public: /** Returns the identifier of the property with a given index. @see getNumProperties */ - const var::identifier getPropertyName (int index) const; + const Identifier getPropertyName (int index) const; /** Returns a Value object that can be used to control and respond to one of the tree's properties. @@ -192,7 +192,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 var::identifier& name, UndoManager* undoManager) const; + Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager) const; //============================================================================== /** Returns the number of child nodes belonging to this one. @@ -210,7 +210,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 getChildWithName (const String& type) const; + ValueTree getChildWithName (const Identifier& type) const; /** Looks for the first child node that has the speficied property value. @@ -220,7 +220,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 var::identifier& propertyName, const var& propertyValue) const; + ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const; /** Adds a child to this node. @@ -340,7 +340,7 @@ public: simply check the tree parameter in this callback to make sure it's the tree you're interested in. */ virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, - const var::identifier& property) = 0; + const Identifier& property) = 0; /** This method is called when a child sub-tree is added or removed. @@ -435,31 +435,31 @@ private: class JUCE_API SharedObject : public ReferenceCountedObject { public: - explicit SharedObject (const String& type); + explicit SharedObject (const Identifier& type); SharedObject (const SharedObject& other); ~SharedObject(); - const String type; + const Identifier type; NamedValueSet properties; ReferenceCountedArray children; SortedSet valueTreesWithListeners; SharedObject* parent; - void sendPropertyChangeMessage (const var::identifier& property); - void sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property); + void sendPropertyChangeMessage (const Identifier& property); + void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property); void sendChildChangeMessage(); void sendChildChangeMessage (ValueTree& tree); void sendParentChangeMessage(); - const var& getProperty (const var::identifier& name) const; - const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; - void setProperty (const var::identifier& name, const var& newValue, UndoManager*); - bool hasProperty (const var::identifier& name) const; - void removeProperty (const var::identifier& name, UndoManager*); + const var& getProperty (const Identifier& name) const; + const var getProperty (const Identifier& name, const var& defaultReturnValue) const; + void setProperty (const Identifier& name, const var& newValue, UndoManager*); + bool hasProperty (const Identifier& name) const; + void removeProperty (const Identifier& name, UndoManager*); void removeAllProperties (UndoManager*); bool isAChildOf (const SharedObject* possibleParent) const; int indexOf (const ValueTree& child) const; - ValueTree getChildWithName (const String& type) const; - ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; + ValueTree getChildWithName (const Identifier& type) const; + ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const; void addChild (SharedObject* child, int index, UndoManager*); void removeChild (int childIndex, UndoManager*); void removeAllChildren (UndoManager*); diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp index ce30252db3..b12258a5d9 100644 --- a/src/containers/juce_Variant.cpp +++ b/src/containers/juce_Variant.cpp @@ -30,6 +30,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_Variant.h" #include "juce_DynamicObject.h" + //============================================================================== var::var() throw() : type (voidType) @@ -283,7 +284,7 @@ const var var::readFromStream (InputStream& input) return var::null; } -const var var::operator[] (const var::identifier& propertyName) const +const var var::operator[] (const Identifier& propertyName) const { if (type == objectType && value.objectValue != 0) return value.objectValue->getProperty (propertyName); @@ -291,7 +292,7 @@ const var var::operator[] (const var::identifier& propertyName) const return var::null; } -const var var::invoke (const var::identifier& method, const var* arguments, int numArguments) const +const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { if (type == objectType && value.objectValue != 0) return value.objectValue->invokeMethod (method, arguments, numArguments); @@ -312,68 +313,39 @@ const var var::invoke (const var& targetObject, const var* arguments, int numArg return var::null; } -const var var::call (const var::identifier& method) const +const var var::call (const Identifier& method) const { return invoke (method, 0, 0); } -const var var::call (const var::identifier& method, const var& arg1) const +const var var::call (const Identifier& method, const var& arg1) const { return invoke (method, &arg1, 1); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2) const +const var var::call (const Identifier& method, const var& arg1, const var& arg2) const { var args[] = { arg1, arg2 }; return invoke (method, args, 2); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3) +const 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); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const +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); } -const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const +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); } -//============================================================================== -var::identifier::identifier() throw() - : hashCode (0) -{ -} - -var::identifier::identifier (const String& name_) - : name (name_), - hashCode (name_.hashCode()) -{ - /* An identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty()); -} - -var::identifier::identifier (const char* const name_) - : name (name_), - hashCode (name.hashCode()) -{ - /* An identifier string must be suitable for use as a script variable or XML - attribute, so it can only contain this limited set of characters.. */ - jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty()); -} - -var::identifier::~identifier() -{ -} - - END_JUCE_NAMESPACE diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h index aa59713831..17b6b8c32a 100644 --- a/src/containers/juce_Variant.h +++ b/src/containers/juce_Variant.h @@ -26,6 +26,7 @@ #ifndef __JUCE_VARIANT_JUCEHEADER__ #define __JUCE_VARIANT_JUCEHEADER__ +#include "juce_Identifier.h" #include "../io/streams/juce_OutputStream.h" #include "../io/streams/juce_InputStream.h" @@ -47,6 +48,7 @@ class JUCE_API var public: //============================================================================== typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments); + typedef Identifier identifier; //============================================================================== /** Creates a void variant. */ @@ -109,56 +111,25 @@ public: static const var readFromStream (InputStream& input); //============================================================================== - class JUCE_API identifier - { - public: - /** Creates a null identifier. */ - identifier() throw(); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - identifier (const char* name); - - /** Creates an identifier with a specified name. - Because this name may need to be used in contexts such as script variables or XML - tags, it must only contain ascii letters and digits, or the underscore character. - */ - identifier (const String& name); - - /** Destructor */ - ~identifier(); - - bool operator== (const identifier& other) const throw() - { - jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions - return hashCode == other.hashCode; - } - - String name; - int hashCode; - }; - /** If this variant is an object, this returns one of its properties. */ - const var operator[] (const identifier& propertyName) const; + const var operator[] (const Identifier& propertyName) const; //============================================================================== /** If this variant is an object, this invokes one of its methods with no arguments. */ - const var call (const identifier& method) const; + const var call (const Identifier& method) const; /** If this variant is an object, this invokes one of its methods with one argument. */ - const var call (const identifier& method, const var& arg1) const; + const var call (const Identifier& method, const var& arg1) const; /** If this variant is an object, this invokes one of its methods with 2 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2) const; + const var call (const Identifier& method, const var& arg1, const var& arg2) const; /** If this variant is an object, this invokes one of its methods with 3 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3); /** If this variant is an object, this invokes one of its methods with 4 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; /** If this variant is an object, this invokes one of its methods with 5 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; + const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; /** If this variant is an object, this invokes one of its methods with a list of arguments. */ - const var invoke (const identifier& method, const var* arguments, int numArguments) const; + const var invoke (const Identifier& method, const var* arguments, int numArguments) const; //============================================================================== /** If this variant is a method pointer, this invokes it on a target object. */ diff --git a/src/gui/components/controls/juce_TableListBox.cpp b/src/gui/components/controls/juce_TableListBox.cpp index 8ce0111bb4..834091d34f 100644 --- a/src/gui/components/controls/juce_TableListBox.cpp +++ b/src/gui/components/controls/juce_TableListBox.cpp @@ -100,7 +100,7 @@ public: { jassert (row >= 0); - const var::identifier tagPropertyName ("_tableLastUseNum"); + const Identifier tagPropertyName ("_tableLastUseNum"); const int newTag = Random::getSystemRandom().nextInt(); const TableHeaderComponent* const header = owner.getHeader(); diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index 407df7202b..bd2f98cbdb 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -1783,7 +1783,7 @@ void Component::sendLookAndFeelChange() } } -static const var::identifier getColourPropertyId (const int colourId) +static const Identifier getColourPropertyId (const int colourId) { String s; s.preallocateStorage (18); @@ -1827,9 +1827,9 @@ void Component::copyAllExplicitColoursTo (Component& target) const for (int i = properties.size(); --i >= 0;) { - const var::identifier name (properties.getName(i)); + const Identifier name (properties.getName(i)); - if (name.name.startsWith ("jcclr_")) + if (name.toString().startsWith ("jcclr_")) if (target.properties.set (name, properties [name])) changed = true; } diff --git a/src/io/files/juce_File.cpp b/src/io/files/juce_File.cpp index 92cd7b60ff..a862d06fc5 100644 --- a/src/io/files/juce_File.cpp +++ b/src/io/files/juce_File.cpp @@ -826,6 +826,39 @@ bool File::replaceWithText (const String& textToWrite, return tempFile.overwriteTargetFileWithTemporary(); } +bool File::hasIdenticalContentTo (const File& other) const +{ + if (other == *this) + return true; + + if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile()) + { + FileInputStream in1 (*this), in2 (other); + + const int bufferSize = 4096; + HeapBlock buffer1, buffer2; + buffer1.malloc (bufferSize); + buffer2.malloc (bufferSize); + + for (;;) + { + const int num1 = in1.read (buffer1, bufferSize); + const int num2 = in2.read (buffer2, bufferSize); + + if (num1 != num2) + break; + + if (num1 <= 0) + return true; + + if (memcmp (buffer1, buffer2, num1) != 0) + break; + } + } + + return false; +} + //============================================================================== const String File::createLegalPathName (const String& original) { diff --git a/src/io/files/juce_File.h b/src/io/files/juce_File.h index ed8f3fcb3e..4c67c297db 100644 --- a/src/io/files/juce_File.h +++ b/src/io/files/juce_File.h @@ -669,6 +669,11 @@ public: bool asUnicode = false, bool writeUnicodeHeaderBytes = false) const; + /** Attempts to scan the contents of this file and compare it to another file, returning + true if this is possible and they match byte-for-byte. + */ + bool hasIdenticalContentTo (const File& other) const; + //============================================================================== /** Creates a set of files to represent each file root. diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h index fe2cf41560..3865fa2db5 100644 --- a/src/juce_core_includes.h +++ b/src/juce_core_includes.h @@ -44,6 +44,9 @@ #ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ #include "containers/juce_HeapBlock.h" #endif +#ifndef __JUCE_IDENTIFIER_JUCEHEADER__ + #include "containers/juce_Identifier.h" +#endif #ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ #include "containers/juce_MemoryBlock.h" #endif @@ -224,6 +227,9 @@ #ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__ #include "text/juce_StringPairArray.h" #endif +#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ + #include "text/juce_StringPool.h" +#endif #ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__ #include "text/juce_XmlDocument.h" #endif diff --git a/src/text/juce_CharacterFunctions.cpp b/src/text/juce_CharacterFunctions.cpp index 0c8c7ceffa..f620f4d3e3 100644 --- a/src/text/juce_CharacterFunctions.cpp +++ b/src/text/juce_CharacterFunctions.cpp @@ -781,12 +781,17 @@ bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw() int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw() { - if (digit >= '0' && digit <= '9') - return digit - '0'; - else if (digit >= 'a' && digit <= 'f') - return digit - ('a' - 10); - else if (digit >= 'A' && digit <= 'F') - return digit - ('A' - 10); + unsigned int d = digit - '0'; + if (d < (unsigned int) 10) + return (int) d; + + d += '0' - 'a'; + if (d < (unsigned int) 6) + return (int) d + 10; + + d += 'a' - 'A'; + if (d < (unsigned int) 6) + return (int) d + 10; return -1; } diff --git a/src/text/juce_String.h b/src/text/juce_String.h index 5416913e03..401123d5f7 100644 --- a/src/text/juce_String.h +++ b/src/text/juce_String.h @@ -81,7 +81,7 @@ public: /** Destructor. */ ~String() throw(); - //========================juce_wchar====================================================== + //============================================================================== /** This is an empty string that can be used whenever one is needed. It's better to use this than String() because it explains what's going on diff --git a/src/text/juce_StringPool.cpp b/src/text/juce_StringPool.cpp new file mode 100644 index 0000000000..9ef0f9a8d7 --- /dev/null +++ b/src/text/juce_StringPool.cpp @@ -0,0 +1,105 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../core/juce_StandardHeader.h" + +BEGIN_JUCE_NAMESPACE + +#include "juce_StringPool.h" + + +//============================================================================== +StringPool::StringPool() throw() {} +StringPool::~StringPool() {} + +template +static const juce_wchar* getPooledStringFromArray (Array& strings, StringType newString) +{ + int start = 0; + int end = strings.size(); + + for (;;) + { + if (start >= end) + { + jassert (start <= end); + strings.insert (start, newString); + return strings.getReference (start); + } + else + { + const String& startString = strings.getReference (start); + + if (startString == newString) + return startString; + + const int halfway = (start + end) >> 1; + + if (halfway == start) + { + if (startString.compare (newString) < 0) + ++start; + + strings.insert (start, newString); + return strings.getReference (start); + } + + const int comp = strings.getReference (halfway).compare (newString); + + if (comp == 0) + return strings.getReference (halfway); + else if (comp < 0) + start = halfway; + else + end = halfway; + } + } +} + +const juce_wchar* StringPool::getPooledString (const String& s) +{ + if (s.isEmpty()) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +const juce_wchar* StringPool::getPooledString (const char* const s) +{ + if (s == 0 || *s == 0) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +const juce_wchar* StringPool::getPooledString (const juce_wchar* const s) +{ + if (s == 0 || *s == 0) + return String::empty; + + return getPooledStringFromArray (strings, s); +} + +END_JUCE_NAMESPACE diff --git a/src/text/juce_StringPool.h b/src/text/juce_StringPool.h new file mode 100644 index 0000000000..ed1607e0d6 --- /dev/null +++ b/src/text/juce_StringPool.h @@ -0,0 +1,82 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_STRINGPOOL_JUCEHEADER__ +#define __JUCE_STRINGPOOL_JUCEHEADER__ + +#include "juce_String.h" +#include "../containers/juce_Array.h" + + +//============================================================================== +/** + A StringPool holds a set of shared strings, which reduces storage overheads and improves + comparison speed when dealing with many duplicate strings. + + When you add a string to a pool using getPooledString, it'll return a character + array containing the same string. This array is owned by the pool, and the same array + is returned every time a matching string is asked for. This means that it's trivial to + compare two pooled strings for equality, as you can simply compare their pointers. It + also cuts down on storage if you're using many copies of the same string. +*/ +class JUCE_API StringPool +{ +public: + /** Creates an empty pool. */ + StringPool() throw(); + + /** Destructor */ + ~StringPool(); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const String& original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const char* original); + + /** Returns a pointer to a copy of the string that is passed in. + + The pool will always return the same pointer when asked for a string that matches it. + The pool will own all the pointers that it returns, deleting them when the pool itself + is deleted. + */ + const juce_wchar* getPooledString (const juce_wchar* original); + +private: + Array strings; +}; + + +#endif // __JUCE_STRINGPOOL_JUCEHEADER__