From 2e664976ec1f30ca7fd2af67a5dde7e052e1653f Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 9 Feb 2012 13:35:37 +0000 Subject: [PATCH] Changed the introjucer's config list system: each exporter now contains its own list of configs. If you load an old project, its global config list will be copied into each of its exporters. Added x64 support for VC2010 projects, as an option in its configs. --- extras/Introjucer/Introjucer.jucer | 43 ++- .../jucer_ProjectExport_Android.h | 42 ++- .../Project Saving/jucer_ProjectExport_MSVC.h | 208 +++++++++----- .../Project Saving/jucer_ProjectExport_Make.h | 37 ++- .../jucer_ProjectExport_XCode.h | 100 +++++-- .../Project Saving/jucer_ProjectExporter.cpp | 159 ++++++++++- .../Project Saving/jucer_ProjectExporter.h | 77 +++++- .../Source/Project/jucer_NewProjectWizard.cpp | 24 +- .../Source/Project/jucer_Project.cpp | 239 +++------------- .../Introjucer/Source/Project/jucer_Project.h | 62 +---- .../jucer_ProjectInformationComponent.cpp | 257 +++++++++++------- .../Source/Utility/jucer_PresetIDs.h | 1 + extras/JuceDemo/Juce Demo.jucer | 75 ++++- extras/audio plugin demo/JuceDemoPlugin.jucer | 36 ++- extras/audio plugin host/Plugin Host.jucer | 36 ++- extras/binarybuilder/BinaryBuilder.jucer | 29 +- extras/example projects/HelloWorld.jucer | 45 ++- extras/static library/juce.jucer | 33 ++- extras/the jucer/Jucer.jucer | 32 ++- .../opengl/juce_OpenGLGraphicsContext.cpp | 4 +- 20 files changed, 970 insertions(+), 569 deletions(-) diff --git a/extras/Introjucer/Introjucer.jucer b/extras/Introjucer/Introjucer.jucer index 281b832f97..df3fd08898 100644 --- a/extras/Introjucer/Introjucer.jucer +++ b/extras/Introjucer/Introjucer.jucer @@ -14,21 +14,42 @@ bigIcon="rVgowdy"> + juceFolder="../.." documentExtensions=".jucer" objCExtraSuffix="zNNCr"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + - + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + + + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" libraryType="1" juceFolder="../.."> + + + + + - - - - isDebug() == forDebug) { - flags << createIncludePathFlags (configs.getReference(i)); + flags << createIncludePathFlags (*config); break; } } @@ -303,15 +327,15 @@ private: defines.set ("NDEBUG", "1"); } - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); + const BuildConfiguration::Ptr config (getConfiguration(i)); - if (config.isDebug() == forDebug) + if (config->isDebug() == forDebug) { - flags << " -O" << config.getGCCOptimisationFlag(); + flags << " -O" << config->getGCCOptimisationFlag(); - defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); + defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (*config)); break; } } diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index 5871541890..bce5a0523c 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -85,12 +85,32 @@ protected: bool isLibraryDLL() const { return msvcIsDLL || (projectType.isLibrary() && getLibraryType() == 2); } //============================================================================== - String getIntermediatesPath (const Project::BuildConfiguration& config) const + class MSVCBuildConfiguration : public BuildConfiguration + { + public: + MSVCBuildConfiguration (Project& project, const ValueTree& settings) + : BuildConfiguration (project, settings) + { + } + + void createPropertyEditors (PropertyListBuilder& props) + { + createBasicPropertyEditors (props); + } + }; + + BuildConfiguration::Ptr createBuildConfig (const ValueTree& settings) const + { + return new MSVCBuildConfiguration (project, settings); + } + + //============================================================================== + String getIntermediatesPath (const BuildConfiguration& config) const { return ".\\" + File::createLegalFileName (config.getName().toString().trim()); } - String getConfigTargetPath (const Project::BuildConfiguration& config) const + String getConfigTargetPath (const BuildConfiguration& config) const { const String binaryPath (config.getTargetBinaryRelativePath().toString().trim()); if (binaryPath.isEmpty()) @@ -105,7 +125,7 @@ protected: .toWindowsStyle(); } - String getPreprocessorDefs (const Project::BuildConfiguration& config, const String& joinString) const + String getPreprocessorDefs (const BuildConfiguration& config, const String& joinString) const { StringPairArray defines (msvcExtraPreprocessorDefs); defines.set ("WIN32", ""); @@ -138,7 +158,7 @@ protected: return result.joinIntoString (joinString); } - StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) const + StringArray getHeaderSearchPaths (const BuildConfiguration& config) const { StringArray searchPaths (extraSearchPaths); searchPaths.addArray (config.getHeaderSearchPaths()); @@ -146,7 +166,7 @@ protected: return searchPaths; } - String getBinaryFileForConfig (const Project::BuildConfiguration& config) const + String getBinaryFileForConfig (const BuildConfiguration& config) const { const String targetBinary (getSetting (config.isDebug().getValue() ? Ids::libraryName_Debug : Ids::libraryName_Release).toString().trim()); if (targetBinary.isNotEmpty()) @@ -155,7 +175,7 @@ protected: return config.getTargetBinaryName().toString() + msvcTargetSuffix; } - static String createConfigName (const Project::BuildConfiguration& config) + virtual String createConfigName (const BuildConfiguration& config) const { return config.getName().toString() + "|Win32"; } @@ -175,20 +195,20 @@ protected: << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution" << newLine; int i; - for (i = 0; i < configs.size(); ++i) + for (i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); - out << "\t\t" << createConfigName (config) << " = " << createConfigName (config) << newLine; + const String configName (createConfigName (*getConfiguration(i))); + out << "\t\t" << configName << " = " << configName << newLine; } out << "\tEndGlobalSection" << newLine << "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution" << newLine; - for (i = 0; i < configs.size(); ++i) + for (i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); - out << "\t\t" << projectGUID << "." << createConfigName (config) << ".ActiveCfg = " << createConfigName (config) << newLine; - out << "\t\t" << projectGUID << "." << createConfigName (config) << ".Build.0 = " << createConfigName (config) << newLine; + const String configName (createConfigName (*getConfiguration(i))); + out << "\t\t" << projectGUID << "." << configName << ".ActiveCfg = " << configName << newLine; + out << "\t\t" << projectGUID << "." << configName << ".Build.0 = " << configName << newLine; } out << "\tEndGlobalSection" << newLine @@ -449,12 +469,10 @@ protected: if (excludeFromBuild || useStdcall) { - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); - XmlElement* fileConfig = fileXml->createNewChildElement ("FileConfiguration"); - fileConfig->setAttribute ("Name", createConfigName (config)); + fileConfig->setAttribute ("Name", createConfigName (*getConfiguration (i))); if (excludeFromBuild) fileConfig->setAttribute ("ExcludedFromBuild", "true"); @@ -508,7 +526,7 @@ protected: return e; } - void createConfig (XmlElement& xml, const Project::BuildConfiguration& config) const + void createConfig (XmlElement& xml, const BuildConfiguration& config) const { String binariesPath (getConfigTargetPath (config)); String intermediatesPath (getIntermediatesPath (config)); @@ -679,8 +697,8 @@ protected: void createConfigs (XmlElement& xml) { - for (int i = 0; i < configs.size(); ++i) - createConfig (*xml.createNewChildElement ("Configuration"), configs.getReference(i)); + for (int i = 0; i < getNumConfigurations(); ++i) + createConfig (*xml.createNewChildElement ("Configuration"), *getConfiguration(i)); } //============================================================================== @@ -780,14 +798,14 @@ private: File getDSWFile() const { return getProjectFile (".dsw"); } //============================================================================== - String createConfigName (const Project::BuildConfiguration& config) const + String createConfigName (const BuildConfiguration& config) const { return projectName + " - Win32 " + config.getName().toString(); } void writeProject (OutputStream& out) { - const String defaultConfigName (createConfigName (configs.getReference(0))); + const String defaultConfigName (createConfigName (*getConfiguration(0))); String targetType, targetCode; @@ -816,8 +834,8 @@ private: << "!MESSAGE " << newLine; int i; - for (i = 0; i < configs.size(); ++i) - out << "!MESSAGE \"" << createConfigName (configs.getReference (i)) << "\" (based on " << targetType << ")" << newLine; + for (i = 0; i < getNumConfigurations(); ++i) + out << "!MESSAGE \"" << createConfigName (*getConfiguration (i)) << "\" (based on " << targetType << ")" << newLine; out << "!MESSAGE " << newLine << "# Begin Project" << newLine @@ -830,37 +848,37 @@ private: String targetList; - for (i = 0; i < configs.size(); ++i) + for (i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); - const String configName (createConfigName (config)); + const BuildConfiguration::Ptr config (getConfiguration(i)); + const String configName (createConfigName (*config)); targetList << "# Name \"" << configName << '"' << newLine; - const String binariesPath (getConfigTargetPath (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(); + const String binariesPath (getConfigTargetPath (*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(); const String extraDebugFlags (isDebug ? "/Gm /ZI /GZ" : ""); out << (i == 0 ? "!IF" : "!ELSEIF") << " \"$(CFG)\" == \"" << configName << '"' << newLine << "# PROP BASE Use_MFC 0" << newLine << "# PROP BASE Use_Debug_Libraries " << (isDebug ? "1" : "0") << newLine << "# PROP BASE Output_Dir \"" << binariesPath << '"' << newLine - << "# PROP BASE Intermediate_Dir \"" << getIntermediatesPath (config) << '"' << newLine + << "# PROP BASE Intermediate_Dir \"" << getIntermediatesPath (*config) << '"' << newLine << "# PROP BASE Target_Dir \"\"" << newLine << "# PROP Use_MFC 0" << newLine << "# PROP Use_Debug_Libraries " << (isDebug ? "1" : "0") << newLine << "# PROP Output_Dir \"" << binariesPath << '"' << newLine - << "# PROP Intermediate_Dir \"" << getIntermediatesPath (config) << '"' << newLine + << "# PROP Intermediate_Dir \"" << getIntermediatesPath (*config) << '"' << newLine << "# PROP Ignore_Export_Lib 0" << newLine << "# PROP Target_Dir \"\"" << newLine << "# ADD BASE CPP /nologo /W3 /GX /" << optimisationFlag << " /D " << defines << " /YX /FD /c " << extraDebugFlags << " /Zm1024" << newLine << "# ADD CPP /nologo " << (isDebug ? "/MTd" : "/MT") << " /W3 /GR /GX /" << optimisationFlag - << " /I " << replacePreprocessorTokens (config, getHeaderSearchPaths (config).joinIntoString (" /I ")) + << " /I " << replacePreprocessorTokens (*config, getHeaderSearchPaths (*config).joinIntoString (" /I ")) << " /D " << defines << " /D \"_UNICODE\" /D \"UNICODE\" /FD /c /Zm1024 " << extraDebugFlags - << " " << replacePreprocessorTokens (config, getExtraCompilerFlags().toString()).trim() << newLine; + << " " << replacePreprocessorTokens (*config, getExtraCompilerFlags().toString()).trim() << newLine; if (! isDebug) out << "# SUBTRACT CPP /YX" << newLine; @@ -891,7 +909,7 @@ private: << " /nologo /machine:I386 /out:\"" << targetBinary << "\" " << (isLibraryDLL() ? "/dll" : (msvcIsWindowsSubsystem ? "/subsystem:windows " : "/subsystem:console ")) - << replacePreprocessorTokens (config, getExtraLinkerFlags().toString()).trim() << newLine; + << replacePreprocessorTokens (*config, getExtraLinkerFlags().toString()).trim() << newLine; } } @@ -1053,16 +1071,57 @@ public: } protected: + //============================================================================== + class VC2010BuildConfiguration : public MSVCBuildConfiguration + { + public: + VC2010BuildConfiguration (Project& project, const ValueTree& settings) + : MSVCBuildConfiguration (project, settings) + { + if (getArchitectureType().toString().isEmpty()) + getArchitectureType() = get32BitArchName(); + } + + //============================================================================== + static const char* get32BitArchName() { return "32-bit"; } + static const char* get64BitArchName() { return "x64"; } + + Value getArchitectureType() const { return getValue (Ids::winArchitecture); } + bool is64Bit() const { return getArchitectureType().toString() == get64BitArchName(); } + + //============================================================================== + void createPropertyEditors (PropertyListBuilder& props) + { + MSVCBuildConfiguration::createPropertyEditors (props); + + const char* const archTypes[] = { get32BitArchName(), get64BitArchName(), nullptr }; + props.add (new ChoicePropertyComponent (getArchitectureType(), "Architecture", + StringArray (archTypes), Array (archTypes))); + } + }; + + BuildConfiguration::Ptr createBuildConfig (const ValueTree& settings) const + { + return new VC2010BuildConfiguration (project, settings); + } + + static bool is64Bit (const BuildConfiguration& config) + { + return dynamic_cast (config).is64Bit(); + } + + //============================================================================== File getVCProjFile() const { return getProjectFile (".vcxproj"); } File getVCProjFiltersFile() const { return getProjectFile (".vcxproj.filters"); } File getSLNFile() const { return getProjectFile (".sln"); } - static String createConfigName (const Project::BuildConfiguration& config) + String createConfigName (const BuildConfiguration& config) const { - return config.getName().toString() + "|Win32"; + return config.getName().toString() + (is64Bit (config) ? "|x64" + : "|Win32"); } - static void setConditionAttribute (XmlElement& xml, const Project::BuildConfiguration& config) + void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config) { xml.setAttribute ("Condition", "'$(Configuration)|$(Platform)'=='" + createConfigName (config) + "'"); } @@ -1078,14 +1137,14 @@ protected: XmlElement* configsGroup = projectXml.createNewChildElement ("ItemGroup"); configsGroup->setAttribute ("Label", "ProjectConfigurations"); - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); + const BuildConfiguration::Ptr config (getConfiguration(i)); XmlElement* e = configsGroup->createNewChildElement ("ProjectConfiguration"); - e->setAttribute ("Include", createConfigName (config)); - e->createNewChildElement ("Configuration")->addTextElement (config.getName().toString()); - e->createNewChildElement ("Platform")->addTextElement ("Win32"); + e->setAttribute ("Include", createConfigName (*config)); + e->createNewChildElement ("Configuration")->addTextElement (config->getName().toString()); + e->createNewChildElement ("Platform")->addTextElement (is64Bit (*config) ? "x64" : "Win32"); } } @@ -1100,19 +1159,22 @@ protected: imports->setAttribute ("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); } - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); + const BuildConfiguration::Ptr config (getConfiguration(i)); XmlElement* e = projectXml.createNewChildElement ("PropertyGroup"); - setConditionAttribute (*e, config); + setConditionAttribute (*e, *config); e->setAttribute ("Label", "Configuration"); e->createNewChildElement ("ConfigurationType")->addTextElement (getProjectType()); e->createNewChildElement ("UseOfMfc")->addTextElement ("false"); e->createNewChildElement ("CharacterSet")->addTextElement ("MultiByte"); - if (! config.isDebug().getValue()) + if (! config->isDebug().getValue()) e->createNewChildElement ("WholeProgramOptimization")->addTextElement ("true"); + + if (is64Bit (*config)) + e->createNewChildElement ("PlatformToolset")->addTextElement ("Windows7.1SDK"); } { @@ -1143,35 +1205,35 @@ protected: XmlElement* props = projectXml.createNewChildElement ("PropertyGroup"); props->createNewChildElement ("_ProjectFileVersion")->addTextElement ("10.0.30319.1"); - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); + const BuildConfiguration::Ptr config (getConfiguration(i)); XmlElement* outdir = props->createNewChildElement ("OutDir"); - setConditionAttribute (*outdir, config); - outdir->addTextElement (getConfigTargetPath (config) + "\\"); + setConditionAttribute (*outdir, *config); + outdir->addTextElement (getConfigTargetPath (*config) + "\\"); XmlElement* intdir = props->createNewChildElement ("IntDir"); - setConditionAttribute (*intdir, config); - intdir->addTextElement (getConfigTargetPath (config) + "\\"); + setConditionAttribute (*intdir, *config); + intdir->addTextElement (getConfigTargetPath (*config) + "\\"); XmlElement* name = props->createNewChildElement ("TargetName"); - setConditionAttribute (*name, config); - name->addTextElement (getBinaryFileForConfig (config).upToLastOccurrenceOf (".", false, false)); + setConditionAttribute (*name, *config); + name->addTextElement (getBinaryFileForConfig (*config).upToLastOccurrenceOf (".", false, false)); } } - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); - String binariesPath (getConfigTargetPath (config)); - String intermediatesPath (getIntermediatesPath (config)); - const bool isDebug = (bool) config.isDebug().getValue(); - const String binaryName (File::createLegalFileName (config.getTargetBinaryName().toString())); - const String outputFileName (getBinaryFileForConfig (config)); + const BuildConfiguration::Ptr config (getConfiguration(i)); + String binariesPath (getConfigTargetPath (*config)); + String intermediatesPath (getIntermediatesPath (*config)); + const bool isDebug = (bool) config->isDebug().getValue(); + const String binaryName (File::createLegalFileName (config->getTargetBinaryName().toString())); + const String outputFileName (getBinaryFileForConfig (*config)); XmlElement* group = projectXml.createNewChildElement ("ItemDefinitionGroup"); - setConditionAttribute (*group, config); + setConditionAttribute (*group, *config); { XmlElement* midl = group->createNewChildElement ("Midl"); @@ -1180,7 +1242,6 @@ protected: midl->createNewChildElement ("MkTypLibCompatible")->addTextElement ("true"); midl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); midl->createNewChildElement ("TargetEnvironment")->addTextElement ("Win32"); - //midl->createNewChildElement ("TypeLibraryName")->addTextElement (""); midl->createNewChildElement ("HeaderFileName"); } @@ -1189,12 +1250,13 @@ protected: cl->createNewChildElement ("Optimization")->addTextElement (isDebug ? "Disabled" : "MaxSpeed"); if (isDebug) - cl->createNewChildElement ("DebugInformationFormat")->addTextElement ("EditAndContinue"); + cl->createNewChildElement ("DebugInformationFormat")->addTextElement (is64Bit (*config) ? "ProgramDatabase" + : "EditAndContinue"); - StringArray includePaths (getHeaderSearchPaths (config)); + StringArray includePaths (getHeaderSearchPaths (*config)); includePaths.add ("%(AdditionalIncludeDirectories)"); cl->createNewChildElement ("AdditionalIncludeDirectories")->addTextElement (includePaths.joinIntoString (";")); - cl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (getPreprocessorDefs (config, ";") + ";%(PreprocessorDefinitions)"); + cl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (getPreprocessorDefs (*config, ";") + ";%(PreprocessorDefinitions)"); cl->createNewChildElement ("RuntimeLibrary")->addTextElement (msvcNeedsDLLRuntimeLib ? (isDebug ? "MultiThreadedDLLDebug" : "MultiThreadedDLL") : (isDebug ? "MultiThreadedDebug" : "MultiThreaded")); cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true"); @@ -1206,7 +1268,7 @@ protected: cl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); cl->createNewChildElement ("MultiProcessorCompilation")->addTextElement ("true"); - const String extraFlags (replacePreprocessorTokens (config, getExtraCompilerFlags().toString()).trim()); + const String extraFlags (replacePreprocessorTokens (*config, getExtraCompilerFlags().toString()).trim()); if (extraFlags.isNotEmpty()) cl->createNewChildElement ("AdditionalOptions")->addTextElement (extraFlags + " %(AdditionalOptions)"); } @@ -1226,7 +1288,9 @@ protected: link->createNewChildElement ("GenerateDebugInformation")->addTextElement (isDebug ? "true" : "false"); link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); link->createNewChildElement ("SubSystem")->addTextElement (msvcIsWindowsSubsystem ? "Windows" : "Console"); - link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); + + if (! is64Bit (*config)) + link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); if (! isDebug) { @@ -1236,7 +1300,7 @@ protected: String extraLinkerOptions (getExtraLinkerFlags().toString()); if (extraLinkerOptions.isNotEmpty()) - link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (config, extraLinkerOptions).trim() + link->createNewChildElement ("AdditionalOptions")->addTextElement (replacePreprocessorTokens (*config, extraLinkerOptions).trim() + " %(AdditionalOptions)"); } diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h index 25278a328a..dd2410367a 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_Make.h @@ -94,6 +94,27 @@ public: overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo); } +protected: + //============================================================================== + class MakeBuildConfiguration : public BuildConfiguration + { + public: + MakeBuildConfiguration (Project& project, const ValueTree& settings) + : BuildConfiguration (project, settings) + { + } + + void createPropertyEditors (PropertyListBuilder& props) + { + createBasicPropertyEditors (props); + } + }; + + BuildConfiguration::Ptr createBuildConfig (const ValueTree& settings) const + { + return new MakeBuildConfiguration (project, settings); + } + private: //============================================================================== void findAllFilesToCompile (const Project::Item& projectItem, Array& results) @@ -110,7 +131,7 @@ private: } } - void writeDefineFlags (OutputStream& out, const Project::BuildConfiguration& config) + void writeDefineFlags (OutputStream& out, const BuildConfiguration& config) { StringPairArray defines; defines.set ("LINUX", "1"); @@ -128,7 +149,7 @@ private: out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config))); } - void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config) + void writeHeaderPathFlags (OutputStream& out, const BuildConfiguration& config) { StringArray searchPaths (extraSearchPaths); searchPaths.addArray (config.getHeaderSearchPaths()); @@ -142,7 +163,7 @@ private: out << " -I " << FileHelpers::unixStylePath (replacePreprocessorTokens (config, searchPaths[i])).quoted(); } - void writeCppFlags (OutputStream& out, const Project::BuildConfiguration& config) + void writeCppFlags (OutputStream& out, const BuildConfiguration& config) { out << " CPPFLAGS := $(DEPFLAGS)"; writeDefineFlags (out, config); @@ -150,7 +171,7 @@ private: out << newLine; } - void writeLinkerFlags (OutputStream& out, const Project::BuildConfiguration& config) + void writeLinkerFlags (OutputStream& out, const BuildConfiguration& config) { out << " LDFLAGS += -L$(BINDIR) -L$(LIBDIR)"; @@ -176,7 +197,7 @@ private: << newLine; } - void writeConfig (OutputStream& out, const Project::BuildConfiguration& config) + void writeConfig (OutputStream& out, const BuildConfiguration& config) { const String buildDirName ("build"); const String intermediatesDirName (buildDirName + "/intermediate/" + config.getName().toString()); @@ -251,7 +272,7 @@ private: << newLine; out << "ifndef CONFIG" << newLine - << " CONFIG=" << escapeSpaces (configs.getReference(0).getName().toString()) << newLine + << " CONFIG=" << escapeSpaces (getConfiguration(0)->getName().toString()) << newLine << "endif" << newLine << newLine; @@ -265,8 +286,8 @@ private: << newLine; int i; - for (i = 0; i < configs.size(); ++i) - writeConfig (out, configs.getReference(i)); + for (i = 0; i < getNumConfigurations(); ++i) + writeConfig (out, *getConfiguration(i)); writeObjects (out, files); diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h index 0259315906..96183a5f2b 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_XCode.h @@ -28,6 +28,19 @@ #include "jucer_ProjectExporter.h" +namespace +{ + const char* const osxVersionDefault = "default"; + const char* const osxVersion10_4 = "10.4 SDK"; + const char* const osxVersion10_5 = "10.5 SDK"; + const char* const osxVersion10_6 = "10.6 SDK"; + + const char* const osxArch_Default = "default"; + const char* const osxArch_Native = "Native"; + const char* const osxArch_32BitUniversal = "32BitUniversal"; + const char* const osxArch_64BitUniversal = "64BitUniversal"; + const char* const osxArch_64Bit = "64BitIntel"; +} //============================================================================== class XCodeProjectExporter : public ProjectExporter @@ -147,6 +160,55 @@ public: writeInfoPlistFile(); } +protected: + //============================================================================== + class XcodeBuildConfiguration : public BuildConfiguration + { + public: + XcodeBuildConfiguration (Project& project, const ValueTree& settings) + : BuildConfiguration (project, settings) + { + } + + Value getMacSDKVersion() const { return getValue (Ids::osxSDK); } + Value getMacCompatibilityVersion() const { return getValue (Ids::osxCompatibility); } + Value getMacArchitecture() const { return getValue (Ids::osxArchitecture); } + + void createPropertyEditors (PropertyListBuilder& props) + { + createBasicPropertyEditors (props); + + if (getMacSDKVersion().toString().isEmpty()) + getMacSDKVersion() = osxVersionDefault; + + const char* osxVersions[] = { "Use Default", osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; + const char* osxVersionValues[] = { osxVersionDefault, osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; + + props.add (new ChoicePropertyComponent (getMacSDKVersion(), "OSX Base SDK Version", StringArray (osxVersions), Array (osxVersionValues)), + "The version of OSX to link against in the XCode build."); + + if (getMacCompatibilityVersion().toString().isEmpty()) + getMacCompatibilityVersion() = osxVersionDefault; + + props.add (new ChoicePropertyComponent (getMacCompatibilityVersion(), "OSX Compatibility Version", StringArray (osxVersions), Array (osxVersionValues)), + "The minimum version of OSX that the target binary will be compatible with."); + + const char* osxArch[] = { "Use Default", "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (64-bit)", "64-bit Intel", 0 }; + const char* osxArchValues[] = { osxArch_Default, osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit, 0 }; + + if (getMacArchitecture().toString().isEmpty()) + getMacArchitecture() = osxArch_Default; + + props.add (new ChoicePropertyComponent (getMacArchitecture(), "OSX Architecture", StringArray (osxArch), Array (osxArchValues)), + "The type of OSX binary that will be produced."); + } + }; + + BuildConfiguration::Ptr createBuildConfig (const ValueTree& settings) const + { + return new XcodeBuildConfiguration (project, settings); + } + private: OwnedArray pbxBuildFiles, pbxFileReferences, pbxGroups, misc, projectConfigs, targetConfigs; StringArray buildPhaseIDs, resourceIDs, sourceIDs, frameworkIDs; @@ -215,12 +277,12 @@ private: addGroup (createID ("__mainsourcegroup"), "Source", topLevelGroupIDs); } - for (int i = 0; i < configs.size(); ++i) + for (int i = 0; i < getNumConfigurations(); ++i) { - const Project::BuildConfiguration& config = configs.getReference(i); + const BuildConfiguration::Ptr config (getConfiguration (i)); - addProjectConfig (config.getName().getValue(), getProjectSettings (config)); - addTargetConfig (config.getName().getValue(), getTargetSettings (config)); + addProjectConfig (config->getName().getValue(), getProjectSettings (*config)); + addTargetConfig (config->getName().getValue(), getTargetSettings (dynamic_cast (*config))); } addConfigList (projectConfigs, createID ("__projList")); @@ -413,7 +475,7 @@ private: overwriteFileIfDifferentOrThrow (infoPlistFile, mo); } - StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) + StringArray getHeaderSearchPaths (const BuildConfiguration& config) { StringArray searchPaths (extraSearchPaths); searchPaths.addArray (config.getHeaderSearchPaths()); @@ -434,7 +496,7 @@ private: librarySearchPaths.add (sanitisePath (searchPath)); } - void getLinkerFlags (const Project::BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) + void getLinkerFlags (const BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) { if (xcodeIsBundle) flags.add ("-bundle"); @@ -449,7 +511,7 @@ private: flags.removeEmptyStrings (true); } - StringArray getProjectSettings (const Project::BuildConfiguration& config) + StringArray getProjectSettings (const BuildConfiguration& config) { StringArray s; s.add ("ALWAYS_SEARCH_USER_PATHS = NO"); @@ -489,15 +551,15 @@ private: return s; } - StringArray getTargetSettings (const Project::BuildConfiguration& config) + StringArray getTargetSettings (const XcodeBuildConfiguration& config) { StringArray s; const String arch (config.getMacArchitecture().toString()); - if (arch == Project::BuildConfiguration::osxArch_Native) s.add ("ARCHS = \"$(ARCHS_NATIVE)\""); - else if (arch == Project::BuildConfiguration::osxArch_32BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_BIT)\""); - else if (arch == Project::BuildConfiguration::osxArch_64BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_64_BIT)\""); - else if (arch == Project::BuildConfiguration::osxArch_64Bit) s.add ("ARCHS = \"$(ARCHS_STANDARD_64_BIT)\""); + if (arch == osxArch_Native) s.add ("ARCHS = \"$(ARCHS_NATIVE)\""); + else if (arch == osxArch_32BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_BIT)\""); + else if (arch == osxArch_64BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_64_BIT)\""); + else if (arch == osxArch_64Bit) s.add ("ARCHS = \"$(ARCHS_STANDARD_64_BIT)\""); s.add ("HEADER_SEARCH_PATHS = \"" + replacePreprocessorTokens (config, getHeaderSearchPaths (config).joinIntoString (" ")) + " $(inherited)\""); s.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag()); @@ -542,23 +604,23 @@ private: const String sdk (config.getMacSDKVersion().toString()); const String sdkCompat (config.getMacCompatibilityVersion().toString()); - if (sdk == Project::BuildConfiguration::osxVersion10_4) + if (sdk == osxVersion10_4) { s.add ("SDKROOT = macosx10.4"); gccVersion = "4.0"; } - else if (sdk == Project::BuildConfiguration::osxVersion10_5) + else if (sdk == osxVersion10_5) { s.add ("SDKROOT = macosx10.5"); } - else if (sdk == Project::BuildConfiguration::osxVersion10_6) + else if (sdk == osxVersion10_6) { s.add ("SDKROOT = macosx10.6"); } - if (sdkCompat == Project::BuildConfiguration::osxVersion10_4) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.4"); - else if (sdkCompat == Project::BuildConfiguration::osxVersion10_5) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.5"); - else if (sdkCompat == Project::BuildConfiguration::osxVersion10_6) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.6"); + if (sdkCompat == osxVersion10_4) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.4"); + else if (sdkCompat == osxVersion10_5) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.5"); + else if (sdkCompat == osxVersion10_6) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.6"); s.add ("MACOSX_DEPLOYMENT_TARGET_ppc = 10.4"); } @@ -888,7 +950,7 @@ private: { jassert (xcodeFileType.isNotEmpty()); jassert (xcodeBundleExtension.isEmpty() || xcodeBundleExtension.startsWithChar('.')); - String productName (configs.getReference(0).getTargetBinaryName().toString()); + String productName (getConfiguration(0)->getTargetBinaryName().toString()); if (xcodeFileType == "archive.ar") productName = getLibbedFilename (productName); diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp index a93a90b17f..e7fa334bcc 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp @@ -85,6 +85,8 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int else exp->getJuceFolder() = juceFolder.getFullPathName(); + exp->createDefaultConfigs(); + return exp; } @@ -136,16 +138,13 @@ ProjectExporter::ProjectExporter (Project& project_, const ValueTree& settings_) msvcIsDLL (false), msvcIsWindowsSubsystem (true), msvcNeedsDLLRuntimeLib (false), + settings (settings_), project (project_), projectType (project_.getProjectType()), projectName (project_.getProjectName().toString()), projectFolder (project_.getFile().getParentDirectory()), - settings (settings_), modulesGroup (nullptr) { - for (int i = 0; i < jmax (1, project.getNumConfigurations()); ++i) - configs.add (project.getConfiguration (i)); - groups.add (project.getMainGroup().createCopy()); } @@ -224,7 +223,7 @@ void ProjectExporter::createPropertyEditors (PropertyListBuilder& props) "Extra command-line flags to be passed to the linker. You might want to use this for adding additional libraries. This string can contain references to preprocessor definitions in the form ${NAME_OF_VALUE}, which will be replaced with their values."); } -StringPairArray ProjectExporter::getAllPreprocessorDefs (const Project::BuildConfiguration& config) const +StringPairArray ProjectExporter::getAllPreprocessorDefs (const ProjectExporter::BuildConfiguration& config) const { StringPairArray defs (mergePreprocessorDefs (config.getAllPreprocessorDefs(), parsePreprocessorDefs (getExporterPreprocessorDefs().toString()))); @@ -240,7 +239,7 @@ StringPairArray ProjectExporter::getAllPreprocessorDefs() const return defs; } -String ProjectExporter::replacePreprocessorTokens (const Project::BuildConfiguration& config, const String& sourceString) const +String ProjectExporter::replacePreprocessorTokens (const ProjectExporter::BuildConfiguration& config, const String& sourceString) const { return replacePreprocessorDefs (getAllPreprocessorDefs (config), sourceString); } @@ -299,3 +298,151 @@ void ProjectExporter::addToExtraSearchPaths (const RelativePath& pathFromProject const String path (isVisualStudio() ? localPath.toWindowsStyle() : localPath.toUnixStyle()); extraSearchPaths.addIfNotAlreadyThere (path, false); } + + +//============================================================================== +const Identifier ProjectExporter::configurations ("CONFIGURATIONS"); +const Identifier ProjectExporter::configuration ("CONFIGURATION"); + +ValueTree ProjectExporter::getConfigurations() const +{ + return settings.getChildWithName (configurations); +} + +int ProjectExporter::getNumConfigurations() const +{ + return getConfigurations().getNumChildren(); +} + +ProjectExporter::BuildConfiguration::Ptr ProjectExporter::getConfiguration (int index) const +{ + return createBuildConfig (getConfigurations().getChild (index)); +} + +bool ProjectExporter::hasConfigurationNamed (const String& name) const +{ + const ValueTree configs (getConfigurations()); + for (int i = configs.getNumChildren(); --i >= 0;) + if (configs.getChild(i) [Ids::name].toString() == name) + return true; + + return false; +} + +String ProjectExporter::getUniqueConfigName (String name) const +{ + String nameRoot (name); + while (CharacterFunctions::isDigit (nameRoot.getLastCharacter())) + nameRoot = nameRoot.dropLastCharacters (1); + + nameRoot = nameRoot.trim(); + + int suffix = 2; + while (hasConfigurationNamed (name)) + name = nameRoot + " " + String (suffix++); + + return name; +} + +void ProjectExporter::addNewConfiguration (const BuildConfiguration* configToCopy) +{ + const String configName (getUniqueConfigName (configToCopy != nullptr ? configToCopy->config [Ids::name].toString() + : "New Build Configuration")); + + ValueTree configs (getConfigurations()); + + if (! configs.isValid()) + { + settings.addChild (ValueTree (configurations), 0, project.getUndoManagerFor (settings)); + configs = getConfigurations(); + } + + ValueTree newConfig (configuration); + if (configToCopy != nullptr) + newConfig = configToCopy->config.createCopy(); + + newConfig.setProperty (Ids::name, configName, 0); + + configs.addChild (newConfig, -1, project.getUndoManagerFor (configs)); +} + +void ProjectExporter::deleteConfiguration (int index) +{ + ValueTree configs (getConfigurations()); + configs.removeChild (index, project.getUndoManagerFor (configs)); +} + +void ProjectExporter::createDefaultConfigs() +{ + settings.getOrCreateChildWithName (configurations, nullptr); + + for (int i = 0; i < 2; ++i) + { + addNewConfiguration (nullptr); + BuildConfiguration::Ptr config (getConfiguration (i)); + + const bool debugConfig = i == 0; + + config->getName() = debugConfig ? "Debug" : "Release"; + config->isDebug() = debugConfig; + config->getOptimisationLevel() = debugConfig ? 1 : 2; + config->getTargetBinaryName() = project.getProjectFilenameRoot(); + } +} + +//============================================================================== +ProjectExporter::BuildConfiguration::BuildConfiguration (Project& project_, const ValueTree& configNode) + : config (configNode), project (project_) +{ +} + +ProjectExporter::BuildConfiguration::~BuildConfiguration() +{ +} + +String ProjectExporter::BuildConfiguration::getGCCOptimisationFlag() const +{ + const int level = (int) getOptimisationLevel().getValue(); + return String (level <= 1 ? "0" : (level == 2 ? "s" : "3")); +} + +void ProjectExporter::BuildConfiguration::createBasicPropertyEditors (PropertyListBuilder& props) +{ + props.add (new TextPropertyComponent (getName(), "Name", 96, false), + "The name of this configuration."); + + props.add (new BooleanPropertyComponent (isDebug(), "Debug mode", "Debugging enabled"), + "If enabled, this means that the configuration should be built with debug synbols."); + + const char* optimisationLevels[] = { "No optimisation", "Optimise for size and speed", "Optimise for maximum speed", 0 }; + const int optimisationLevelValues[] = { 1, 2, 3, 0 }; + props.add (new ChoicePropertyComponent (getOptimisationLevel(), "Optimisation", StringArray (optimisationLevels), Array (optimisationLevelValues)), + "The optimisation level for this configuration"); + + props.add (new TextPropertyComponent (getTargetBinaryName(), "Binary name", 256, false), + "The filename to use for the destination binary executable file. Don't add a suffix to this, because platform-specific suffixes will be added for each target platform."); + + props.add (new TextPropertyComponent (getTargetBinaryRelativePath(), "Binary location", 1024, false), + "The folder in which the finished binary should be placed. Leave this blank to cause the binary to be placed in its default location in the build folder."); + + props.add (new TextPropertyComponent (getHeaderSearchPath(), "Header search path", 16384, false), + "Extra header search paths. Use semi-colons to separate multiple paths."); + + props.add (new TextPropertyComponent (getBuildConfigPreprocessorDefs(), "Preprocessor definitions", 32768, false), + "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash."); + + props.setPreferredHeight (22); +} + +StringPairArray ProjectExporter::BuildConfiguration::getAllPreprocessorDefs() const +{ + return mergePreprocessorDefs (project.getPreprocessorDefs(), + parsePreprocessorDefs (getBuildConfigPreprocessorDefs().toString())); +} + +StringArray ProjectExporter::BuildConfiguration::getHeaderSearchPaths() const +{ + StringArray s; + s.addTokens (getHeaderSearchPath().toString(), ";", String::empty); + return s; +} diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h index cb52dffa31..f90d4864b2 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.h @@ -80,15 +80,6 @@ public: Value getExtraCompilerFlags() const { return getSetting (Ids::extraCompilerFlags); } Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); } - Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } - - // includes exporter, project + config defs - StringPairArray getAllPreprocessorDefs (const Project::BuildConfiguration& config) const; - // includes exporter + project defs.. - StringPairArray getAllPreprocessorDefs() const; - - String replacePreprocessorTokens (const Project::BuildConfiguration&, const String& sourceString) const; - // This adds the quotes, and may return angle-brackets, eg: or normal quotes. String getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const; @@ -149,6 +140,70 @@ public: //============================================================================== StringArray extraSearchPaths; + //============================================================================== + class BuildConfiguration : public ReferenceCountedObject + { + public: + BuildConfiguration (Project& project, const ValueTree& configNode); + ~BuildConfiguration(); + + typedef ReferenceCountedObjectPtr Ptr; + + //============================================================================== + virtual void createPropertyEditors (PropertyListBuilder&) = 0; + + //============================================================================== + Value getName() const { return getValue (Ids::name); } + Value isDebug() const { return getValue (Ids::isDebug); } + Value getTargetBinaryName() const { return getValue (Ids::targetName); } + // the path relative to the build folder in which the binary should go + Value getTargetBinaryRelativePath() const { return getValue (Ids::binaryPath); } + Value getOptimisationLevel() const { return getValue (Ids::optimisation); } + String getGCCOptimisationFlag() const; + Value getBuildConfigPreprocessorDefs() const { return getValue (Ids::defines); } + StringPairArray getAllPreprocessorDefs() const; // includes inherited definitions + Value getHeaderSearchPath() const { return getValue (Ids::headerPath); } + StringArray getHeaderSearchPaths() const; + + //============================================================================== + ValueTree config; + + protected: + Project& project; + + Value getValue (const Identifier& name) const { return config.getPropertyAsValue (name, getUndoManager()); } + UndoManager* getUndoManager() const { return project.getUndoManagerFor (config); } + + void createBasicPropertyEditors (PropertyListBuilder&); + + private: + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BuildConfiguration); + }; + + int getNumConfigurations() const; + BuildConfiguration::Ptr getConfiguration (int index) const; + void addNewConfiguration (const BuildConfiguration* configToCopy); + void deleteConfiguration (int index); + bool hasConfigurationNamed (const String& name) const; + String getUniqueConfigName (String name) const; + + ValueTree getConfigurations() const; + void createDefaultConfigs(); + + static const Identifier configurations, configuration; + + //============================================================================== + Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } + + // includes exporter, project + config defs + StringPairArray getAllPreprocessorDefs (const BuildConfiguration& config) const; + // includes exporter + project defs.. + StringPairArray getAllPreprocessorDefs() const; + + String replacePreprocessorTokens (const BuildConfiguration&, const String& sourceString) const; + + ValueTree settings; + protected: //============================================================================== String name; @@ -156,10 +211,10 @@ protected: const ProjectType& projectType; const String projectName; const File projectFolder; - Array configs; - ValueTree settings; Project::Item* modulesGroup; + virtual BuildConfiguration::Ptr createBuildConfig (const ValueTree&) const = 0; + static String getDefaultBuildsRootFolder() { return "Builds/"; } static String getLibbedFilename (String name) diff --git a/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp b/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp index a26982f605..0f267533c3 100644 --- a/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp +++ b/extras/Introjucer/Source/Project/jucer_NewProjectWizard.cpp @@ -26,6 +26,7 @@ #include "jucer_NewProjectWizard.h" #include "jucer_ProjectType.h" #include "jucer_Module.h" +#include "../Project Saving/jucer_ProjectExporter.h" #include "../Application/jucer_Application.h" #include "../Application/jucer_MainWindow.h" @@ -51,6 +52,20 @@ static void createFileCreationOptionComboBox (Component& setupComp, c->setBounds ("parent.width / 2 + 160, 10, parent.width - 10, top + 22"); } +static void setExecutableNameForAllTargets (Project& project, const String& exeName) +{ + for (int j = project.getNumExporters(); --j >= 0;) + { + ScopedPointer exporter (project.createExporter(j)); + + if (exporter != nullptr) + { + for (int i = exporter->getNumConfigurations(); --i >= 0;) + exporter->getConfiguration(i)->getTargetBinaryName() = exeName; + } + } +} + //============================================================================== class GUIAppWizard : public NewProjectWizard { @@ -100,8 +115,7 @@ public: Project::Item sourceGroup (project.getMainGroup().addNewSubGroup ("Source", 0)); - for (int i = project.getNumConfigurations(); --i >= 0;) - project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); String initCode, shutdownCode, anotherInstanceStartedCode, privateMembers, memberInitialisers; @@ -204,8 +218,7 @@ public: Project::Item sourceGroup (project.getMainGroup().addNewSubGroup ("Source", 0)); - for (int i = project.getNumConfigurations(); --i >= 0;) - project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); if (createMainCpp) { @@ -265,8 +278,7 @@ public: Project::Item sourceGroup (project.getMainGroup().addNewSubGroup ("Source", 0)); project.getConfigFlag ("JUCE_QUICKTIME") = Project::configFlagDisabled; // disabled because it interferes with RTAS build on PC - for (int i = project.getNumConfigurations(); --i >= 0;) - project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + setExecutableNameForAllTargets (project, File::createLegalFileName (appTitle)); String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), filterCppFile)); diff --git a/extras/Introjucer/Source/Project/jucer_Project.cpp b/extras/Introjucer/Source/Project/jucer_Project.cpp index d1d211eecd..329a82d1f2 100644 --- a/extras/Introjucer/Source/Project/jucer_Project.cpp +++ b/extras/Introjucer/Source/Project/jucer_Project.cpp @@ -37,8 +37,6 @@ namespace Tags 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 Identifier configGroup ("JUCEOPTIONS"); const Identifier modulesGroup ("MODULES"); @@ -112,11 +110,14 @@ void Project::setMissingDefaultValues() if (! projectRoot.hasProperty (Ids::version)) getVersion() = "1.0.0"; - // Create configs group - if (! projectRoot.getChildWithName (Tags::configurations).isValid()) + updateOldStyleConfigList(); + + for (int i = 0; i < getNumExporters(); ++i) { - projectRoot.addChild (ValueTree (Tags::configurations), 0, 0); - createDefaultConfigs(); + ScopedPointer exporter (createExporter(i)); + + if (exporter != nullptr && exporter->getNumConfigurations() == 0) + exporter->createDefaultConfigs(); } if (! projectRoot.getChildWithName (Tags::exporters).isValid()) @@ -131,6 +132,40 @@ void Project::setMissingDefaultValues() addDefaultModules (false); } +void Project::updateOldStyleConfigList() +{ + ValueTree deprecatedConfigsList (projectRoot.getChildWithName (ProjectExporter::configurations)); + + if (deprecatedConfigsList.isValid()) + { + projectRoot.removeChild (deprecatedConfigsList, nullptr); + + for (int i = 0; i < getNumExporters(); ++i) + { + ScopedPointer exporter (createExporter(i)); + + if (exporter != nullptr && exporter->getNumConfigurations() == 0) + { + ValueTree newConfigs (deprecatedConfigsList.createCopy()); + + if (! exporter->isXcode()) + { + for (int j = newConfigs.getNumChildren(); --j >= 0;) + { + ValueTree config (newConfigs.getChild(j)); + + config.removeProperty (Ids::osxSDK, nullptr); + config.removeProperty (Ids::osxCompatibility, nullptr); + config.removeProperty (Ids::osxArchitecture, nullptr); + } + } + + exporter->settings.addChild (newConfigs, 0, nullptr); + } + } + } +} + void Project::addDefaultModules (bool shouldCopyFilesLocally) { addModule ("juce_core", shouldCopyFilesLocally); @@ -862,198 +897,6 @@ String Project::getModuleID (int index) const return projectRoot.getChildWithName (Tags::modulesGroup).getChild (index) [ComponentBuilder::idProperty].toString(); } -//============================================================================== -ValueTree Project::getConfigurations() const -{ - return projectRoot.getChildWithName (Tags::configurations); -} - -int Project::getNumConfigurations() const -{ - return getConfigurations().getNumChildren(); -} - -Project::BuildConfiguration Project::getConfiguration (int index) -{ - jassert (index < getConfigurations().getNumChildren()); - return BuildConfiguration (this, getConfigurations().getChild (index)); -} - -bool Project::hasConfigurationNamed (const String& name) const -{ - const ValueTree configs (getConfigurations()); - for (int i = configs.getNumChildren(); --i >= 0;) - if (configs.getChild(i) [Ids::name].toString() == name) - return true; - - return false; -} - -String Project::getUniqueConfigName (String name) const -{ - String nameRoot (name); - while (CharacterFunctions::isDigit (nameRoot.getLastCharacter())) - nameRoot = nameRoot.dropLastCharacters (1); - - nameRoot = nameRoot.trim(); - - int suffix = 2; - while (hasConfigurationNamed (name)) - name = nameRoot + " " + String (suffix++); - - return name; -} - -void Project::addNewConfiguration (BuildConfiguration* configToCopy) -{ - const String configName (getUniqueConfigName (configToCopy != nullptr ? configToCopy->config [Ids::name].toString() - : "New Build Configuration")); - - ValueTree configs (getConfigurations()); - - if (! configs.isValid()) - { - projectRoot.addChild (ValueTree (Tags::configurations), 0, getUndoManagerFor (projectRoot)); - configs = getConfigurations(); - } - - ValueTree newConfig (Tags::configuration); - if (configToCopy != nullptr) - newConfig = configToCopy->config.createCopy(); - - newConfig.setProperty (Ids::name, configName, 0); - - configs.addChild (newConfig, -1, getUndoManagerFor (configs)); -} - -void Project::deleteConfiguration (int index) -{ - ValueTree configs (getConfigurations()); - configs.removeChild (index, getUndoManagerFor (getConfigurations())); -} - -void Project::createDefaultConfigs() -{ - for (int i = 0; i < 2; ++i) - { - addNewConfiguration (nullptr); - BuildConfiguration config = getConfiguration (i); - - const bool debugConfig = i == 0; - - config.getName() = debugConfig ? "Debug" : "Release"; - config.isDebug() = debugConfig; - config.getOptimisationLevel() = debugConfig ? 1 : 2; - config.getTargetBinaryName() = getProjectFilenameRoot(); - } -} - -//============================================================================== -Project::BuildConfiguration::BuildConfiguration (Project* project_, const ValueTree& configNode) - : project (project_), - config (configNode) -{ -} - -Project::BuildConfiguration::BuildConfiguration (const BuildConfiguration& other) - : project (other.project), - config (other.config) -{ -} - -const Project::BuildConfiguration& Project::BuildConfiguration::operator= (const BuildConfiguration& other) -{ - project = other.project; - config = other.config; - return *this; -} - -Project::BuildConfiguration::~BuildConfiguration() -{ -} - -String Project::BuildConfiguration::getGCCOptimisationFlag() const -{ - const int level = (int) getOptimisationLevel().getValue(); - return String (level <= 1 ? "0" : (level == 2 ? "s" : "3")); -} - -const char* const Project::BuildConfiguration::osxVersionDefault = "default"; -const char* const Project::BuildConfiguration::osxVersion10_4 = "10.4 SDK"; -const char* const Project::BuildConfiguration::osxVersion10_5 = "10.5 SDK"; -const char* const Project::BuildConfiguration::osxVersion10_6 = "10.6 SDK"; - -const char* const Project::BuildConfiguration::osxArch_Default = "default"; -const char* const Project::BuildConfiguration::osxArch_Native = "Native"; -const char* const Project::BuildConfiguration::osxArch_32BitUniversal = "32BitUniversal"; -const char* const Project::BuildConfiguration::osxArch_64BitUniversal = "64BitUniversal"; -const char* const Project::BuildConfiguration::osxArch_64Bit = "64BitIntel"; - -void Project::BuildConfiguration::createPropertyEditors (PropertyListBuilder& props) -{ - props.add (new TextPropertyComponent (getName(), "Name", 96, false), - "The name of this configuration."); - - props.add (new BooleanPropertyComponent (isDebug(), "Debug mode", "Debugging enabled"), - "If enabled, this means that the configuration should be built with debug synbols."); - - const char* optimisationLevels[] = { "No optimisation", "Optimise for size and speed", "Optimise for maximum speed", 0 }; - const int optimisationLevelValues[] = { 1, 2, 3, 0 }; - props.add (new ChoicePropertyComponent (getOptimisationLevel(), "Optimisation", StringArray (optimisationLevels), Array (optimisationLevelValues)), - "The optimisation level for this configuration"); - - props.add (new TextPropertyComponent (getTargetBinaryName(), "Binary name", 256, false), - "The filename to use for the destination binary executable file. Don't add a suffix to this, because platform-specific suffixes will be added for each target platform."); - - props.add (new TextPropertyComponent (getTargetBinaryRelativePath(), "Binary location", 1024, false), - "The folder in which the finished binary should be placed. Leave this blank to cause the binary to be placed in its default location in the build folder."); - - props.add (new TextPropertyComponent (getHeaderSearchPath(), "Header search path", 16384, false), - "Extra header search paths. Use semi-colons to separate multiple paths."); - - props.add (new TextPropertyComponent (getBuildConfigPreprocessorDefs(), "Preprocessor definitions", 32768, false), - "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace or commas to separate the items - to include a space or comma in a definition, precede it with a backslash."); - - if (getMacSDKVersion().toString().isEmpty()) - getMacSDKVersion() = osxVersionDefault; - - const char* osxVersions[] = { "Use Default", osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; - const char* osxVersionValues[] = { osxVersionDefault, osxVersion10_4, osxVersion10_5, osxVersion10_6, 0 }; - - props.add (new ChoicePropertyComponent (getMacSDKVersion(), "OSX Base SDK Version", StringArray (osxVersions), Array (osxVersionValues)), - "The version of OSX to link against in the XCode build."); - - if (getMacCompatibilityVersion().toString().isEmpty()) - getMacCompatibilityVersion() = osxVersionDefault; - - props.add (new ChoicePropertyComponent (getMacCompatibilityVersion(), "OSX Compatibility Version", StringArray (osxVersions), Array (osxVersionValues)), - "The minimum version of OSX that the target binary will be compatible with."); - - const char* osxArch[] = { "Use Default", "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (64-bit)", "64-bit Intel", 0 }; - const char* osxArchValues[] = { osxArch_Default, osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit, 0 }; - - if (getMacArchitecture().toString().isEmpty()) - getMacArchitecture() = osxArch_Default; - - props.add (new ChoicePropertyComponent (getMacArchitecture(), "OSX Architecture", StringArray (osxArch), Array (osxArchValues)), - "The type of OSX binary that will be produced."); - - props.setPreferredHeight (22); -} - -StringPairArray Project::BuildConfiguration::getAllPreprocessorDefs() const -{ - return mergePreprocessorDefs (project->getPreprocessorDefs(), - parsePreprocessorDefs (getBuildConfigPreprocessorDefs().toString())); -} - -StringArray Project::BuildConfiguration::getHeaderSearchPaths() const -{ - StringArray s; - s.addTokens (getHeaderSearchPath().toString(), ";", String::empty); - return s; -} - //============================================================================== ValueTree Project::getExporters() { diff --git a/extras/Introjucer/Source/Project/jucer_Project.h b/extras/Introjucer/Source/Project/jucer_Project.h index 99ef6da33c..e8da3b176d 100644 --- a/extras/Introjucer/Source/Project/jucer_Project.h +++ b/extras/Introjucer/Source/Project/jucer_Project.h @@ -186,65 +186,6 @@ public: void findAllImageItems (OwnedArray& items); - //============================================================================== - class BuildConfiguration - { - public: - BuildConfiguration (const BuildConfiguration&); - const BuildConfiguration& operator= (const BuildConfiguration&); - ~BuildConfiguration(); - - //============================================================================== - Project& getProject() const { return *project; } - - void createPropertyEditors (PropertyListBuilder&); - - //============================================================================== - Value getName() const { return getValue (Ids::name); } - Value isDebug() const { return getValue (Ids::isDebug); } - Value getTargetBinaryName() const { return getValue (Ids::targetName); } - // the path relative to the build folder in which the binary should go - Value getTargetBinaryRelativePath() const { return getValue (Ids::binaryPath); } - Value getOptimisationLevel() const { return getValue (Ids::optimisation); } - String getGCCOptimisationFlag() const; - Value getBuildConfigPreprocessorDefs() const { return getValue (Ids::defines); } - StringPairArray getAllPreprocessorDefs() const; // includes inherited definitions - Value getHeaderSearchPath() const { return getValue (Ids::headerPath); } - StringArray getHeaderSearchPaths() const; - - static const char* const osxVersionDefault; - static const char* const osxVersion10_4; - static const char* const osxVersion10_5; - static const char* const osxVersion10_6; - Value getMacSDKVersion() const { return getValue (Ids::osxSDK); } - Value getMacCompatibilityVersion() const { return getValue (Ids::osxCompatibility); } - - static const char* const osxArch_Default; - static const char* const osxArch_Native; - static const char* const osxArch_32BitUniversal; - static const char* const osxArch_64BitUniversal; - static const char* const osxArch_64Bit; - Value getMacArchitecture() const { return getValue (Ids::osxArchitecture); } - - //============================================================================== - private: - friend class Project; - Project* project; - ValueTree config; - - Value getValue (const Identifier& name) const { return config.getPropertyAsValue (name, getUndoManager()); } - UndoManager* getUndoManager() const { return project->getUndoManagerFor (config); } - - BuildConfiguration (Project* project, const ValueTree& configNode); - }; - - int getNumConfigurations() const; - BuildConfiguration getConfiguration (int index); - void addNewConfiguration (BuildConfiguration* configToCopy); - void deleteConfiguration (int index); - bool hasConfigurationNamed (const String& name) const; - String getUniqueConfigName (String name) const; - //============================================================================== ValueTree getExporters(); int getNumExporters(); @@ -305,10 +246,11 @@ private: void sanitiseConfigFlags(); void setMissingDefaultValues(); ValueTree getConfigurations() const; - void createDefaultConfigs(); ValueTree getConfigNode(); ValueTree getModulesNode(); + void updateOldStyleConfigList(); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Project); }; diff --git a/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp index dbd3fbd527..560863e5bb 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp @@ -398,20 +398,14 @@ class ProjectSettingsComponent : public Component public: ProjectSettingsComponent (Project& project_) : project (project_), - configs ("Configurations", "Add a New Configuration", false), - exporters ("Export Targets", "Add a New Exporter...", true) + exporters ("Export Targets", "Add a New Exporter...", true, false) { addAndMakeVisible (&mainProjectInfoPanel); addAndMakeVisible (&modulesPanelGroup); - addAndMakeVisible (&configs); addAndMakeVisible (&exporters); - PropertyListBuilder props; - props.add (new ModulesPanel (project)); - modulesPanelGroup.setProperties (props); - modulesPanelGroup.setName ("Modules"); - - createItems(); + mainProjectInfoPanel.backgroundColour = Colours::white.withAlpha (0.3f); + modulesPanelGroup.backgroundColour = Colours::white.withAlpha (0.3f); } void updateSize (int width) @@ -421,7 +415,6 @@ public: int y = 0; y += mainProjectInfoPanel.updateSize (y, width); y += modulesPanelGroup.updateSize (y, width); - y += configs.updateSize (y, width); y += exporters.updateSize (y, width); setSize (width, y); @@ -435,112 +428,152 @@ public: void visibilityChanged() { if (isVisible()) - refreshAll(); + createAllPanels(); } - void refreshAll() + void createModulesPanel() { + PropertyListBuilder props; + props.add (new ModulesPanel (project)); + modulesPanelGroup.setProperties (props); + modulesPanelGroup.setName ("Modules"); + } + + void createProjectPanel() + { + PropertyListBuilder props; + project.createPropertyEditors (props); + mainProjectInfoPanel.setProperties (props); + mainProjectInfoPanel.setName ("Project Settings"); + + lastProjectType = project.getProjectTypeValue().getValue(); + } + + void createExportersPanel() + { + exporters.clear(); + + for (int i = 0; i < project.getNumExporters(); ++i) { - PropertyListBuilder props; - project.createPropertyEditors (props); - mainProjectInfoPanel.setProperties (props); - mainProjectInfoPanel.setName ("Project Settings"); + PropertyGroup* exporterGroup = exporters.createGroup(); + exporterGroup->backgroundColour = Colours::white.withAlpha (0.3f); + exporterGroup->addDeleteButton ("exporter " + String (i), "Deletes this export target."); + + ScopedPointer exp (project.createExporter (i)); + jassert (exp != nullptr); + + if (exp != nullptr) + { + PropertyListBuilder props; + exp->createPropertyEditors (props); + + PropertyGroupList* configList = new PropertyGroupList ("Configurations", "Add a New Configuration", false, true); + props.add (configList); + exporterGroup->setProperties (props); + + configList->createNewButton.setName ("newconfig " + String (i)); + + for (int j = 0; j < exp->getNumConfigurations(); ++j) + { + PropertyGroup* configGroup = configList->createGroup(); + + if (exp->getNumConfigurations() > 1) + configGroup->addDeleteButton ("config " + String (i) + "/" + String (j), "Deletes this configuration."); + + PropertyListBuilder configProps; + exp->getConfiguration(j)->createPropertyEditors (configProps); + configGroup->setProperties (configProps); + } + } } + } - int i; - for (i = configs.groups.size(); --i >= 0;) + void createAllPanels() + { + createProjectPanel(); + createModulesPanel(); + createExportersPanel(); + updateNames(); + + updateSize (getWidth()); + } + + bool needsFullUpdate() const + { + if (exporters.groups.size() != project.getNumExporters() + || lastProjectType != project.getProjectTypeValue().getValue()) + return true; + + for (int i = exporters.groups.size(); --i >= 0;) { - PropertyGroup& pp = *configs.groups.getUnchecked(i); - - PropertyListBuilder props; - project.getConfiguration (i).createPropertyEditors (props); - pp.setProperties (props); - } - - for (i = exporters.groups.size(); --i >= 0;) - { - PropertyGroup& pp = *exporters.groups.getUnchecked(i); - PropertyListBuilder props; ScopedPointer exp (project.createExporter (i)); jassert (exp != nullptr); if (exp != nullptr) { - exp->createPropertyEditors (props); - pp.setProperties (props); + PropertyGroupList* configList = dynamic_cast (exporters.groups.getUnchecked(i)->properties.getLast()); + + if (configList != nullptr && configList->groups.size() != exp->getNumConfigurations()) + return true; } } - refreshSectionNames(); - - updateSize (getWidth()); + return false; } - void refreshSectionNames() + void updateNames() { - int i; - for (i = configs.groups.size(); --i >= 0;) + for (int i = exporters.groups.size(); --i >= 0;) { - PropertyGroup& pp = *configs.groups.getUnchecked(i); - pp.setName (project.getConfiguration (i).getName().toString().quoted()); - pp.repaint(); - } - - for (i = exporters.groups.size(); --i >= 0;) - { - PropertyGroup& pp = *exporters.groups.getUnchecked(i); + PropertyGroup& exporterGroup = *exporters.groups.getUnchecked(i); ScopedPointer exp (project.createExporter (i)); - jassert (exp != nullptr); + if (exp != nullptr) - pp.setName (exp->getName()); + { + exporterGroup.setName (exp->getName()); + exporterGroup.repaint(); - pp.repaint(); + PropertyGroupList* configList = dynamic_cast (exporterGroup.properties.getLast()); + + if (configList != nullptr) + { + for (int j = configList->groups.size(); --j >= 0;) + { + PropertyGroup& configGroup = *configList->groups.getUnchecked(j); + configGroup.setName ("Configuration: " + exp->getConfiguration (j)->getName().toString().quoted()); + configGroup.repaint(); + } + } + } } } - void createItems() - { - configs.clear(); - exporters.clear(); - - int i; - for (i = 0; i < project.getNumConfigurations(); ++i) - { - PropertyGroup* p = configs.createGroup(); - - if (project.getNumConfigurations() > 1) - p->addDeleteButton ("config " + String (i), "Deletes this configuration."); - } - - for (i = 0; i < project.getNumExporters(); ++i) - { - PropertyGroup* p = exporters.createGroup(); - p->addDeleteButton ("exporter " + String (i), "Deletes this export target."); - } - - lastProjectType = project.getProjectTypeValue().getValue(); - refreshAll(); - } - void update() { - if (configs.groups.size() != project.getNumConfigurations() - || exporters.groups.size() != project.getNumExporters() - || lastProjectType != project.getProjectTypeValue().getValue()) - { - createItems(); - } - - refreshSectionNames(); + if (needsFullUpdate()) + createAllPanels(); + else + updateNames(); } void deleteButtonClicked (const String& name) { if (name.startsWith ("config")) - project.deleteConfiguration (name.getTrailingIntValue()); + { + int exporterIndex = name.upToLastOccurrenceOf ("/", false, false).getTrailingIntValue(); + int configIndex = name.getTrailingIntValue(); + + ScopedPointer exporter (project.createExporter (exporterIndex)); + jassert (exporter != nullptr); + + if (exporter != nullptr) + exporter->deleteConfiguration (configIndex); + } else + { project.deleteExporter (name.getTrailingIntValue()); + } } static void newExporterMenuItemChosen (int resultCode, ProjectSettingsComponent* settingsComp) @@ -562,17 +595,21 @@ public: ModalCallbackFunction::forComponent (newExporterMenuItemChosen, this)); } - void createNewConfig() + void createNewConfig (int exporterIndex) { - project.addNewConfiguration (nullptr); + ScopedPointer exp (project.createExporter (exporterIndex)); + jassert (exp != nullptr); + + if (exp != nullptr) + exp->addNewConfiguration (nullptr); } void newItemButtonClicked (TextButton& button) { if (button.getName().containsIgnoreCase ("export")) createNewExporter (button); - else - createNewConfig(); + else if (button.getName().containsIgnoreCase ("newconfig")) + createNewConfig (button.getName().getTrailingIntValue()); } private: @@ -614,16 +651,32 @@ private: for (int i = 0; i < properties.size(); ++i) { PropertyComponent* pp = properties.getUnchecked(i); + + PropertyGroupList* pgl = dynamic_cast (pp); + + if (pgl != nullptr) + pgl->updateSize (height, width - 20); + pp->setBounds (10, height, width - 20, pp->getPreferredHeight()); height += pp->getHeight(); } + height += 16; setBounds (0, y, width, height); return height; } void paint (Graphics& g) { + if (! backgroundColour.isTransparent()) + { + g.setColour (backgroundColour); + g.fillRect (0, 0, getWidth(), getHeight() - 10); + + g.setColour (Colours::black.withAlpha (0.4f)); + g.drawRect (0, 0, getWidth(), getHeight() - 10); + } + g.setFont (14.0f, Font::bold); g.setColour (Colours::black); g.drawFittedText (getName(), 12, 0, getWidth() - 16, 28, Justification::bottomLeft, 1); @@ -636,22 +689,25 @@ private: psc->deleteButtonClicked (deleteButton.getName()); } - private: OwnedArray properties; TextButton deleteButton; + Colour backgroundColour; }; //============================================================================== - class PropertyGroupList : public Component, + class PropertyGroupList : public PropertyComponent, public ButtonListener { public: - PropertyGroupList (const String& title, const String& newButtonText, bool triggerOnMouseDown) - : Component (title), createNewButton (newButtonText) + PropertyGroupList (const String& title, const String& newButtonText, + bool triggerOnMouseDown, bool hideNameAndPutButtonAtBottom) + : PropertyComponent (title), createNewButton (newButtonText), + dontDisplayName (hideNameAndPutButtonAtBottom) { addAndMakeVisible (&createNewButton); createNewButton.setColour (TextButton::buttonColourId, Colours::lightgreen.withAlpha (0.5f)); - createNewButton.setBounds ("right - 140, 30, parent.width - 10, top + 20"); + createNewButton.setBounds (hideNameAndPutButtonAtBottom ? "right - 140, parent.height - 25, parent.width - 10, top + 20" + : "right - 140, 30, parent.width - 10, top + 20"); createNewButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight); createNewButton.addListener (this); createNewButton.setTriggeredOnMouseDown (triggerOnMouseDown); @@ -659,21 +715,29 @@ private: int updateSize (int ourY, int width) { - int y = 55; + int y = dontDisplayName ? 10 : 55; for (int i = 0; i < groups.size(); ++i) y += groups.getUnchecked(i)->updateSize (y, width); y = jmax (y, 100); setBounds (0, ourY, width, y); + + if (dontDisplayName) + y += 25; + + setPreferredHeight (y); return y; } void paint (Graphics& g) { - g.setFont (17.0f, Font::bold); - g.setColour (Colours::black); - g.drawFittedText (getName(), 0, 30, getWidth(), 20, Justification::centred, 1); + if (! dontDisplayName) + { + g.setFont (17.0f, Font::bold); + g.setColour (Colours::black); + g.drawFittedText (getName(), 0, 30, getWidth(), 20, Justification::centred, 1); + } } void clear() @@ -681,6 +745,8 @@ private: groups.clear(); } + void refresh() {} + PropertyGroup* createGroup() { PropertyGroup* p = new PropertyGroup(); @@ -698,12 +764,13 @@ private: OwnedArray groups; TextButton createNewButton; + bool dontDisplayName; }; Project& project; var lastProjectType; PropertyGroup mainProjectInfoPanel, modulesPanelGroup; - PropertyGroupList configs, exporters; + PropertyGroupList exporters; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectSettingsComponent); }; diff --git a/extras/Introjucer/Source/Utility/jucer_PresetIDs.h b/extras/Introjucer/Source/Utility/jucer_PresetIDs.h index abbe788874..29a0c6e8d1 100644 --- a/extras/Introjucer/Source/Utility/jucer_PresetIDs.h +++ b/extras/Introjucer/Source/Utility/jucer_PresetIDs.h @@ -61,6 +61,7 @@ namespace Ids DECLARE_ID (osxSDK); DECLARE_ID (osxCompatibility); DECLARE_ID (osxArchitecture); + DECLARE_ID (winArchitecture); DECLARE_ID (jucerVersion); DECLARE_ID (projectType); DECLARE_ID (prebuildCommand); diff --git a/extras/JuceDemo/Juce Demo.jucer b/extras/JuceDemo/Juce Demo.jucer index d0e5e0599d..5e8db01b81 100644 --- a/extras/JuceDemo/Juce Demo.jucer +++ b/extras/JuceDemo/Juce Demo.jucer @@ -11,28 +11,73 @@ bigIcon="f4hwldS"> + juceFolder="../../../juce" objCExtraSuffix="JSLvvV6j"> + + + + + + juceFolder="../../../juce" objCExtraSuffix="JSLvvV6j"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"> + + + + + - + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"> + + + + + + + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" libraryType="1" juceFolder="../../../juce"> + + + + + + androidInternetNeeded="1"> + + + + + - - - - diff --git a/extras/audio plugin demo/JuceDemoPlugin.jucer b/extras/audio plugin demo/JuceDemoPlugin.jucer index 6aa50f38a8..a1f8a681af 100644 --- a/extras/audio plugin demo/JuceDemoPlugin.jucer +++ b/extras/audio plugin demo/JuceDemoPlugin.jucer @@ -11,20 +11,36 @@ bundleIdentifier="com.rawmaterialsoftware.JuceDemoPlugin" jucerVersion="3.0.0"> + juceFolder="../.." objCExtraSuffix="JuceDemo"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + + rtasFolder="~/SDKs/PT_80_SDK"> + + + + + - - - - diff --git a/extras/audio plugin host/Plugin Host.jucer b/extras/audio plugin host/Plugin Host.jucer index 8e7e2c77e8..4e7e456bff 100644 --- a/extras/audio plugin host/Plugin Host.jucer +++ b/extras/audio plugin host/Plugin Host.jucer @@ -13,19 +13,35 @@ jucerVersion="3.0.0"> + juceFolder="../.." objCExtraSuffix="M73TRi"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + - + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + + + + + + + - - - - diff --git a/extras/binarybuilder/BinaryBuilder.jucer b/extras/binarybuilder/BinaryBuilder.jucer index cc6cef6645..754e32d21e 100644 --- a/extras/binarybuilder/BinaryBuilder.jucer +++ b/extras/binarybuilder/BinaryBuilder.jucer @@ -11,17 +11,28 @@ bundleIdentifier="com.rawmaterialsoftware.binarybuilder"> + juceFolder="../../../juce" objCExtraSuffix="OeJtJb"> + + + + + - + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"> + + + + + + + + + + + - - - - diff --git a/extras/example projects/HelloWorld.jucer b/extras/example projects/HelloWorld.jucer index a830c69203..dd5c3672a8 100644 --- a/extras/example projects/HelloWorld.jucer +++ b/extras/example projects/HelloWorld.jucer @@ -12,21 +12,44 @@ pluginAUViewClass="HelloWorldAU_V1" pluginRTASCategory="" bundleIdentifier="com.rawmaterialsoftware.jucehelloworld"> + juceFolder="../.." objCExtraSuffix="JtTAKTK1s"> + + + + + + juceFolder="../.." objCExtraSuffix="JtTAKTK1s"> + + + + + + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + - + rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"> + + + + + + + + + + + - - - - diff --git a/extras/static library/juce.jucer b/extras/static library/juce.jucer index 02a4e53cdd..c9e8ae3eb1 100644 --- a/extras/static library/juce.jucer +++ b/extras/static library/juce.jucer @@ -4,16 +4,31 @@ juceLinkage="none" bundleIdentifier="com.rawmaterialsoftware.juce" jucerVersion="3.0.0"> - - - + + + + + + + + + + + + + + + + + + - - - - diff --git a/extras/the jucer/Jucer.jucer b/extras/the jucer/Jucer.jucer index 4431b08fea..fde249e760 100644 --- a/extras/the jucer/Jucer.jucer +++ b/extras/the jucer/Jucer.jucer @@ -4,15 +4,31 @@ bundleIdentifier="com.yourcompany.Jucer" jucerVersion="3.0.0" bigIcon="HFdB13"> - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 9365e44a16..247e7cca1c 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -2171,7 +2171,7 @@ public: void fillRect (const Rectangle& area, const FillType& fill, bool replaceContents) { - jassert (! replaceContents); + (void) replaceContents; jassert (! replaceContents); const Rectangle r (clip.getIntersection (area)); if (! r.isEmpty()) @@ -2605,7 +2605,7 @@ public: void fillRect (const Rectangle& area, const FillType& fill, bool replaceContents) { - jassert (! replaceContents); + (void) replaceContents; jassert (! replaceContents); const Rectangle r (clip.getIntersection (area)); if (! r.isEmpty())