Browse Source

Projucer: Added default module search paths to the Projucer

tags/2021-05-28
ed 8 years ago
parent
commit
26596fbfad
41 changed files with 1614 additions and 918 deletions
  1. +2
    -6
      extras/Projucer/Builds/LinuxMakefile/Makefile
  2. +4
    -6
      extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj
  3. +7
    -2
      extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj
  4. +6
    -6
      extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj.filters
  5. +7
    -2
      extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj
  6. +6
    -6
      extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters
  7. +7
    -2
      extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
  8. +6
    -6
      extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
  9. +15
    -15
      extras/Projucer/JuceLibraryCode/AppConfig.h
  10. +4
    -4
      extras/Projucer/Projucer.jucer
  11. +0
    -1
      extras/Projucer/Source/Application/jucer_AppearanceSettings.cpp
  12. +0
    -3
      extras/Projucer/Source/Application/jucer_AppearanceSettings.h
  13. +41
    -13
      extras/Projucer/Source/Application/jucer_Application.cpp
  14. +5
    -2
      extras/Projucer/Source/Application/jucer_Application.h
  15. +1
    -1
      extras/Projucer/Source/Application/jucer_AutoUpdater.cpp
  16. +1
    -1
      extras/Projucer/Source/Application/jucer_CommandIDs.h
  17. +0
    -465
      extras/Projucer/Source/Application/jucer_GlobalPreferences.cpp
  18. +0
    -116
      extras/Projucer/Source/Application/jucer_GlobalPreferences.h
  19. +2
    -0
      extras/Projucer/Source/Application/jucer_Main.cpp
  20. +0
    -36
      extras/Projucer/Source/Application/jucer_MainWindow.cpp
  21. +0
    -1
      extras/Projucer/Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp
  22. +1
    -3
      extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp
  23. +32
    -2
      extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp
  24. +3
    -1
      extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h
  25. +30
    -26
      extras/Projucer/Source/Project/jucer_ConfigTree_Base.h
  26. +181
    -37
      extras/Projucer/Source/Project/jucer_ConfigTree_Modules.h
  27. +153
    -4
      extras/Projucer/Source/Project/jucer_DependencyPathPropertyComponent.cpp
  28. +68
    -4
      extras/Projucer/Source/Project/jucer_DependencyPathPropertyComponent.h
  29. +180
    -39
      extras/Projucer/Source/Project/jucer_Module.cpp
  30. +16
    -7
      extras/Projucer/Source/Project/jucer_Module.h
  31. +44
    -8
      extras/Projucer/Source/Project/jucer_ModulesPanel.h
  32. +26
    -13
      extras/Projucer/Source/Project/jucer_Project.cpp
  33. +1
    -0
      extras/Projucer/Source/Project/jucer_TreeItemTypes.h
  34. +344
    -0
      extras/Projucer/Source/Utility/jucer_EditorColourSchemeWindowComponent.h
  35. +75
    -11
      extras/Projucer/Source/Utility/jucer_FilePathPropertyComponent.h
  36. +200
    -0
      extras/Projucer/Source/Utility/jucer_GlobalSearchPathsWindowComponent.h
  37. +6
    -0
      extras/Projucer/Source/Utility/jucer_PresetIDs.h
  38. +70
    -41
      extras/Projucer/Source/Utility/jucer_StoredSettings.cpp
  39. +15
    -11
      extras/Projucer/Source/Utility/jucer_StoredSettings.h
  40. +5
    -4
      extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h
  41. +50
    -13
      extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h

+ 2
- 6
extras/Projucer/Builds/LinuxMakefile/Makefile View File

@@ -71,7 +71,6 @@ OBJECTS_APP := \
$(JUCE_OBJDIR)/jucer_CommandLine_f35de107.o \
$(JUCE_OBJDIR)/jucer_DocumentEditorComponent_695dff1d.o \
$(JUCE_OBJDIR)/jucer_DownloadCompileEngineThread_8a38703f.o \
$(JUCE_OBJDIR)/jucer_GlobalPreferences_b0f1bd3d.o \
$(JUCE_OBJDIR)/jucer_Main_f8488f5b.o \
$(JUCE_OBJDIR)/jucer_MainWindow_1e163aeb.o \
$(JUCE_OBJDIR)/jucer_OpenDocumentManager_4c72d210.o \
@@ -126,6 +125,8 @@ OBJECTS_APP := \
.PHONY: clean all
all : $(JUCE_OUTDIR)/$(JUCE_TARGET_APP)
$(JUCE_OUTDIR)/$(JUCE_TARGET_APP) : check-pkg-config $(OBJECTS_APP) $(RESOURCES)
@echo Linking "Projucer - App"
-$(V_AT)mkdir -p $(JUCE_BINDIR)
@@ -158,11 +159,6 @@ $(JUCE_OBJDIR)/jucer_DownloadCompileEngineThread_8a38703f.o: ../../Source/Applic
@echo "Compiling jucer_DownloadCompileEngineThread.cpp"
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
$(JUCE_OBJDIR)/jucer_GlobalPreferences_b0f1bd3d.o: ../../Source/Application/jucer_GlobalPreferences.cpp
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
@echo "Compiling jucer_GlobalPreferences.cpp"
$(V_AT)$(CXX) $(JUCE_CXXFLAGS) $(JUCE_CPPFLAGS_APP) $(JUCE_CFLAGS_APP) -o "$@" -c "$<"
$(JUCE_OBJDIR)/jucer_Main_f8488f5b.o: ../../Source/Application/jucer_Main.cpp
-$(V_AT)mkdir -p $(JUCE_OBJDIR)
@echo "Compiling jucer_Main.cpp"


+ 4
- 6
extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj View File

@@ -29,7 +29,6 @@
954A036F5DDB375DB23FFB3E = {isa = PBXBuildFile; fileRef = 0400CB0E056A1D840304D2DE; };
3EB3D569250C4BA4CA9AF578 = {isa = PBXBuildFile; fileRef = C7608A3967D9AB9481848F2B; };
636D21BF846031A6A1A7476A = {isa = PBXBuildFile; fileRef = 11EB44786085029106099D01; };
3C3B0ED6C43FDA3AF76DEE2E = {isa = PBXBuildFile; fileRef = 84DE44680C9D37CDDCD127FF; };
95B44E6C74B1DED31DBE37EB = {isa = PBXBuildFile; fileRef = 8C52A3DDA62A746AA7A68535; };
AA9D0B8E23F3D87A23DE9F8A = {isa = PBXBuildFile; fileRef = 9069981E414A631B036CC9AC; };
244BA1BDA5FAA465EA3F9C6D = {isa = PBXBuildFile; fileRef = 2247EE920DF0610CAF9F4513; };
@@ -115,7 +114,6 @@
1B9B5A37F079FE3B3CF8FAB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_graphics.mm"; path = "../../JuceLibraryCode/include_juce_graphics.mm"; sourceTree = "SOURCE_ROOT"; };
1C216FE9B7A5209C5CCF2517 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintElement.cpp"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElement.cpp"; sourceTree = "SOURCE_ROOT"; };
1C73D7591E63E8018E279716 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "export_android.svg"; path = "../../Source/BinaryData/export_android.svg"; sourceTree = "SOURCE_ROOT"; };
1C81C5501BE7F2C912250711 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GlobalPreferences.h"; path = "../../Source/Application/jucer_GlobalPreferences.h"; sourceTree = "SOURCE_ROOT"; };
1D3D6A19A60F0B03DE2F1C14 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementPath.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementPath.h"; sourceTree = "SOURCE_ROOT"; };
1D99EA99F946D665FE583414 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "wizard_Highlight.svg"; path = "../../Source/BinaryData/wizard_Highlight.svg"; sourceTree = "SOURCE_ROOT"; };
1DE5BBC777FB64798D823002 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "include_juce_data_structures.mm"; path = "../../JuceLibraryCode/include_juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
@@ -165,6 +163,7 @@
472F9A90F685220D730EBF6C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = "SOURCE_ROOT"; };
47B49049B85EED74D29C9906 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectTree_File.h"; path = "../../Source/Project/jucer_ProjectTree_File.h"; sourceTree = "SOURCE_ROOT"; };
47DD50A5A9091F9900E0EAD9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_JucerTreeViewBase.cpp"; path = "../../Source/Utility/jucer_JucerTreeViewBase.cpp"; sourceTree = "SOURCE_ROOT"; };
4856DA6706D794E2D89DAB63 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GlobalSearchPathsWindowComponent.h"; path = "../../Source/Utility/jucer_GlobalSearchPathsWindowComponent.h"; sourceTree = "SOURCE_ROOT"; };
4A035FB6A8D93BF154C08C3F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "projucer_BuildTabStatusComp.h"; path = "../../Source/LiveBuildEngine/projucer_BuildTabStatusComp.h"; sourceTree = "SOURCE_ROOT"; };
4A41FD3066D0979DB48691E5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_MiscUtilities.h"; path = "../../Source/Utility/jucer_MiscUtilities.h"; sourceTree = "SOURCE_ROOT"; };
4A4EBDAD8D098F72CE053235 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectWizard_AudioPlugin.h"; path = "../../Source/Wizards/jucer_ProjectWizard_AudioPlugin.h"; sourceTree = "SOURCE_ROOT"; };
@@ -233,7 +232,6 @@
8138A55052E9FC27284B74DD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FontPropertyComponent.h"; path = "../../Source/ComponentEditor/properties/jucer_FontPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; };
820291543BF93243B718F0EE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JucerTreeViewBase.h"; path = "../../Source/Utility/jucer_JucerTreeViewBase.h"; sourceTree = "SOURCE_ROOT"; };
842427CFE565F3FCE5B99174 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; };
84DE44680C9D37CDDCD127FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_GlobalPreferences.cpp"; path = "../../Source/Application/jucer_GlobalPreferences.cpp"; sourceTree = "SOURCE_ROOT"; };
86E468DE6556BB2AD76A3D80 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectContentComponent.cpp"; path = "../../Source/Project/jucer_ProjectContentComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
86E8A40E5A83781A8478454D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_MainTemplate_Window.cpp"; path = "../../Source/BinaryData/jucer_MainTemplate_Window.cpp"; sourceTree = "SOURCE_ROOT"; };
8702F43110E4CCA5E5F827F5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = "SOURCE_ROOT"; };
@@ -314,6 +312,7 @@
C00793A0D4A59BDADC62EEF7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "projucer_CompileEngineClient.h"; path = "../../Source/LiveBuildEngine/projucer_CompileEngineClient.h"; sourceTree = "SOURCE_ROOT"; };
C094F3B6A65A79A6DF87C9C2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementGroup.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementGroup.h"; sourceTree = "SOURCE_ROOT"; };
C09BBB58CA45B66D693E8C31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TemplateThumbnailsComponent.h"; path = "../../Source/Wizards/jucer_TemplateThumbnailsComponent.h"; sourceTree = "SOURCE_ROOT"; };
C15220EDA1A8315DA3255E87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_EditorColourSchemeWindowComponent.h"; path = "../../Source/Utility/jucer_EditorColourSchemeWindowComponent.h"; sourceTree = "SOURCE_ROOT"; };
C187718F7B9EBA88584B43F3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_PaintRoutine.cpp"; path = "../../Source/ComponentEditor/jucer_PaintRoutine.cpp"; sourceTree = "SOURCE_ROOT"; };
C22791DB75870C4F102AA8A3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_SlidingPanelComponent.h"; path = "../../Source/Utility/jucer_SlidingPanelComponent.h"; sourceTree = "SOURCE_ROOT"; };
C2990A8D054BC230E7C637C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_NewProjectWizardClasses.h"; path = "../../Source/Wizards/jucer_NewProjectWizardClasses.h"; sourceTree = "SOURCE_ROOT"; };
@@ -396,8 +395,6 @@
11EB44786085029106099D01,
B7307A82D9EB1EDBA91EE43D,
D526C38D581425949BA0E4AC,
84DE44680C9D37CDDCD127FF,
1C81C5501BE7F2C912250711,
F03E2BDD36E6F4F53AB767A8,
8C52A3DDA62A746AA7A68535,
9069981E414A631B036CC9AC,
@@ -569,10 +566,12 @@
914ADDB50ED7365F08BA91F9,
DF78EF6242D82F912534A277,
188D03A4247F4BC0539F5C49,
C15220EDA1A8315DA3255E87,
1729AEDC34001C31B8CC357C,
553725A0E3A391651ED1731E,
35A36102EAD2D2620EE99E7E,
E382C78A1D837DD98916E86A,
4856DA6706D794E2D89DAB63,
CF21D9DB3AEC0A4DCAB36A99,
515FF6E74826E3E3F7273621,
47DD50A5A9091F9900E0EAD9,
@@ -839,7 +838,6 @@
954A036F5DDB375DB23FFB3E,
3EB3D569250C4BA4CA9AF578,
636D21BF846031A6A1A7476A,
3C3B0ED6C43FDA3AF76DEE2E,
95B44E6C74B1DED31DBE37EB,
AA9D0B8E23F3D87A23DE9F8A,
244BA1BDA5FAA465EA3F9C6D,


+ 7
- 2
extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj View File

@@ -16,6 +16,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{E4CFCE31-1AF5-C360-751D-9682E333BE4D}</ProjectGuid>
<PlatformToolset>v120</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"
@@ -24,6 +25,7 @@
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"
Label="Configuration">
@@ -32,6 +34,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
@@ -42,6 +45,7 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<PlatformToolset>v120</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
@@ -55,6 +59,7 @@
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Projucer</TargetName>
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
<PlatformToolset>v120</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
@@ -146,7 +151,6 @@
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/>
@@ -1376,7 +1380,6 @@
<ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.h"/>
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h"/>
<ClInclude Include="..\..\Source\jucer_Headers.h"/>
<ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/>
<ClInclude Include="..\..\Source\Application\jucer_OpenDocumentManager.h"/>
@@ -1496,9 +1499,11 @@
<ClInclude Include="..\..\Source\Utility\jucer_CodeHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_ColourPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FilePathPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_JucerTreeViewBase.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_MiscUtilities.h"/>


+ 6
- 6
extras/Projucer/Builds/VisualStudio2013/Projucer_App.vcxproj.filters View File

@@ -286,9 +286,6 @@
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
@@ -1719,9 +1716,6 @@
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\jucer_Headers.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
@@ -2079,6 +2073,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
@@ -2088,6 +2085,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>


+ 7
- 2
extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj View File

@@ -16,6 +16,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{E4CFCE31-1AF5-C360-751D-9682E333BE4D}</ProjectGuid>
<PlatformToolset>v140</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"
@@ -24,6 +25,7 @@
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"
Label="Configuration">
@@ -32,6 +34,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
@@ -42,6 +45,7 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<PlatformToolset>v140</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
@@ -55,6 +59,7 @@
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Projucer</TargetName>
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
<PlatformToolset>v140</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
@@ -146,7 +151,6 @@
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/>
@@ -1376,7 +1380,6 @@
<ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.h"/>
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h"/>
<ClInclude Include="..\..\Source\jucer_Headers.h"/>
<ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/>
<ClInclude Include="..\..\Source\Application\jucer_OpenDocumentManager.h"/>
@@ -1496,9 +1499,11 @@
<ClInclude Include="..\..\Source\Utility\jucer_CodeHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_ColourPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FilePathPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_JucerTreeViewBase.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_MiscUtilities.h"/>


+ 6
- 6
extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters View File

@@ -286,9 +286,6 @@
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
@@ -1719,9 +1716,6 @@
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\jucer_Headers.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
@@ -2079,6 +2073,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
@@ -2088,6 +2085,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>


+ 7
- 2
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj View File

@@ -16,6 +16,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{E4CFCE31-1AF5-C360-751D-9682E333BE4D}</ProjectGuid>
<PlatformToolset>v141</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"
@@ -24,6 +25,7 @@
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"
Label="Configuration">
@@ -32,6 +34,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v141</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
@@ -42,6 +45,7 @@
</ImportGroup>
<PropertyGroup Label="UserMacros">
<PlatformToolset>v141</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
@@ -55,6 +59,7 @@
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Projucer</TargetName>
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
<PlatformToolset>v141</PlatformToolset>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
@@ -146,7 +151,6 @@
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/>
<ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/>
@@ -1376,7 +1380,6 @@
<ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.h"/>
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h"/>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h"/>
<ClInclude Include="..\..\Source\jucer_Headers.h"/>
<ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/>
<ClInclude Include="..\..\Source\Application\jucer_OpenDocumentManager.h"/>
@@ -1496,9 +1499,11 @@
<ClInclude Include="..\..\Source\Utility\jucer_CodeHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_ColourPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FilePathPropertyComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_JucerTreeViewBase.h"/>
<ClInclude Include="..\..\Source\Utility\jucer_MiscUtilities.h"/>


+ 6
- 6
extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters View File

@@ -286,9 +286,6 @@
<ClCompile Include="..\..\Source\Application\jucer_DownloadCompileEngineThread.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_GlobalPreferences.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp">
<Filter>Projucer\Application</Filter>
</ClCompile>
@@ -1719,9 +1716,6 @@
<ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Application\jucer_GlobalPreferences.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\jucer_Headers.h">
<Filter>Projucer\Application</Filter>
</ClInclude>
@@ -2079,6 +2073,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_Colours.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_EditorColourSchemeWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_FileHelpers.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
@@ -2088,6 +2085,9 @@
<ClInclude Include="..\..\Source\Utility\jucer_FloatingToolWindow.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_GlobalSearchPathsWindowComponent.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\Utility\jucer_Icons.h">
<Filter>Projucer\Utility</Filter>
</ClInclude>


+ 15
- 15
extras/Projucer/JuceLibraryCode/AppConfig.h View File

@@ -74,7 +74,7 @@
// juce_core flags:
#ifndef JUCE_FORCE_DEBUG
//#define JUCE_FORCE_DEBUG
//#define JUCE_FORCE_DEBUG 1
#endif
#ifndef JUCE_LOG_ASSERTIONS
@@ -82,15 +82,15 @@
#endif
#ifndef JUCE_CHECK_MEMORY_LEAKS
//#define JUCE_CHECK_MEMORY_LEAKS
//#define JUCE_CHECK_MEMORY_LEAKS 1
#endif
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES 1
#endif
#ifndef JUCE_INCLUDE_ZLIB_CODE
//#define JUCE_INCLUDE_ZLIB_CODE
//#define JUCE_INCLUDE_ZLIB_CODE 1
#endif
#ifndef JUCE_USE_CURL
@@ -98,59 +98,59 @@
#endif
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
#endif
#ifndef JUCE_ALLOW_STATIC_NULL_VARIABLES
//#define JUCE_ALLOW_STATIC_NULL_VARIABLES
//#define JUCE_ALLOW_STATIC_NULL_VARIABLES 1
#endif
//==============================================================================
// juce_events flags:
#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
//#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK
//#define JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK 1
#endif
//==============================================================================
// juce_graphics flags:
#ifndef JUCE_USE_COREIMAGE_LOADER
//#define JUCE_USE_COREIMAGE_LOADER
//#define JUCE_USE_COREIMAGE_LOADER 1
#endif
#ifndef JUCE_USE_DIRECTWRITE
//#define JUCE_USE_DIRECTWRITE
//#define JUCE_USE_DIRECTWRITE 1
#endif
//==============================================================================
// juce_gui_basics flags:
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
//#define JUCE_ENABLE_REPAINT_DEBUGGING
//#define JUCE_ENABLE_REPAINT_DEBUGGING 1
#endif
#ifndef JUCE_USE_XSHM
//#define JUCE_USE_XSHM
//#define JUCE_USE_XSHM 1
#endif
#ifndef JUCE_USE_XRENDER
//#define JUCE_USE_XRENDER
//#define JUCE_USE_XRENDER 1
#endif
#ifndef JUCE_USE_XCURSOR
//#define JUCE_USE_XCURSOR
//#define JUCE_USE_XCURSOR 1
#endif
//==============================================================================
// juce_gui_extra flags:
#ifndef JUCE_WEB_BROWSER
//#define JUCE_WEB_BROWSER
//#define JUCE_WEB_BROWSER 1
#endif
#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
//#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
//#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 1
#endif
//==============================================================================
#ifndef JUCE_STANDALONE_APPLICATION


+ 4
- 4
extras/Projucer/Projucer.jucer View File

@@ -136,10 +136,6 @@
resource="0" file="Source/Application/jucer_DownloadCompileEngineThread.h"/>
<FILE id="eo4r70" name="jucer_FilePreviewComponent.h" compile="0" resource="0"
file="Source/Application/jucer_FilePreviewComponent.h"/>
<FILE id="Hq3STq" name="jucer_GlobalPreferences.cpp" compile="1" resource="0"
file="Source/Application/jucer_GlobalPreferences.cpp"/>
<FILE id="Ym81lY" name="jucer_GlobalPreferences.h" compile="0" resource="0"
file="Source/Application/jucer_GlobalPreferences.h"/>
<FILE id="YVE38f" name="jucer_Headers.h" compile="0" resource="0" file="Source/jucer_Headers.h"/>
<FILE id="eMFQFu" name="jucer_Main.cpp" compile="1" resource="0" file="Source/Application/jucer_Main.cpp"/>
<FILE id="WuEh1e" name="jucer_MainWindow.cpp" compile="1" resource="0"
@@ -467,6 +463,8 @@
<FILE id="ZZK5JV" name="jucer_ColourPropertyComponent.h" compile="0"
resource="0" file="Source/Utility/jucer_ColourPropertyComponent.h"/>
<FILE id="Y5kN1C" name="jucer_Colours.h" compile="0" resource="0" file="Source/Utility/jucer_Colours.h"/>
<FILE id="DYaDr0" name="jucer_EditorColourSchemeWindowComponent.h"
compile="0" resource="0" file="Source/Utility/jucer_EditorColourSchemeWindowComponent.h"/>
<FILE id="Wmahr3" name="jucer_FileHelpers.cpp" compile="1" resource="0"
file="Source/Utility/jucer_FileHelpers.cpp"/>
<FILE id="UhuxIZ" name="jucer_FileHelpers.h" compile="0" resource="0"
@@ -475,6 +473,8 @@
resource="0" file="Source/Utility/jucer_FilePathPropertyComponent.h"/>
<FILE id="bFaUy6" name="jucer_FloatingToolWindow.h" compile="0" resource="0"
file="Source/Utility/jucer_FloatingToolWindow.h"/>
<FILE id="AZcyKs" name="jucer_GlobalSearchPathsWindowComponent.h" compile="0"
resource="0" file="Source/Utility/jucer_GlobalSearchPathsWindowComponent.h"/>
<FILE id="alvpK9" name="jucer_Icons.cpp" compile="1" resource="0" file="Source/Utility/jucer_Icons.cpp"/>
<FILE id="iTXdnI" name="jucer_Icons.h" compile="0" resource="0" file="Source/Utility/jucer_Icons.h"/>
<FILE id="umjCJo" name="jucer_JucerTreeViewBase.cpp" compile="1" resource="0"


+ 0
- 1
extras/Projucer/Source/Application/jucer_AppearanceSettings.cpp View File

@@ -27,7 +27,6 @@
#include "../jucer_Headers.h"
#include "jucer_Application.h"
#include "jucer_AppearanceSettings.h"
#include "jucer_GlobalPreferences.h"
//==============================================================================
AppearanceSettings::AppearanceSettings (bool updateAppWhenChanged)


+ 0
- 3
extras/Projucer/Source/Application/jucer_AppearanceSettings.h View File

@@ -55,9 +55,6 @@ public:
static Font getDefaultCodeFont();
static void showGlobalPreferences (ScopedPointer<Component>& ownerPointer,
bool showCodeEditorTab = false);
static const char* getSchemeFileSuffix() { return ".scheme"; }
static const char* getSchemeFileWildCard() { return "*.scheme"; }


+ 41
- 13
extras/Projucer/Source/Application/jucer_Application.cpp View File

@@ -196,11 +196,11 @@ void ProjucerApplication::shutdown()
}
versionChecker = nullptr;
appearanceEditorWindow = nullptr;
globalPreferencesWindow = nullptr;
utf8Window = nullptr;
svgPathWindow = nullptr;
aboutWindow = nullptr;
pathsWindow = nullptr;
editorColourSchemeWindow = nullptr;
if (licenseController != nullptr)
{
@@ -386,7 +386,7 @@ void ProjucerApplication::createFileMenu (PopupMenu& menu)
#if ! JUCE_MAC
menu.addCommandItem (commandManager, CommandIDs::showAboutWindow);
menu.addCommandItem (commandManager, CommandIDs::showAppUsageWindow);
menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences);
menu.addCommandItem (commandManager, CommandIDs::showGlobalPathsWindow);
menu.addSeparator();
menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
#endif
@@ -463,7 +463,7 @@ void ProjucerApplication::createColourSchemeItems (PopupMenu& menu)
for (auto s : schemes)
{
editorColourSchemes.addItem (codeEditorColourSchemeBaseID + i, s,
globalPreferencesWindow == nullptr,
editorColourSchemeWindow == nullptr,
selectedEditorColourSchemeIndex == i);
++i;
}
@@ -472,7 +472,7 @@ void ProjucerApplication::createColourSchemeItems (PopupMenu& menu)
editorColourSchemes.addSeparator();
editorColourSchemes.addItem (codeEditorColourSchemeBaseID + numEditorColourSchemes,
"Create...", globalPreferencesWindow == nullptr);
"Create...", editorColourSchemeWindow == nullptr);
menu.addSubMenu ("Editor Colour Scheme", editorColourSchemes);
}
@@ -511,7 +511,7 @@ void ProjucerApplication::createExtraAppleMenuItems (PopupMenu& menu)
menu.addCommandItem (commandManager, CommandIDs::showAboutWindow);
menu.addCommandItem (commandManager, CommandIDs::showAppUsageWindow);
menu.addSeparator();
menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences);
menu.addCommandItem (commandManager, CommandIDs::showGlobalPathsWindow);
}
void ProjucerApplication::handleMainMenuCommand (int menuItemID)
@@ -539,7 +539,7 @@ void ProjucerApplication::handleMainMenuCommand (int menuItemID)
}
else if (menuItemID == (codeEditorColourSchemeBaseID + numEditorColourSchemes))
{
AppearanceSettings::showGlobalPreferences (globalPreferencesWindow, true);
showEditorColourSchemeWindow();
}
else
{
@@ -556,7 +556,7 @@ void ProjucerApplication::getAllCommands (Array <CommandID>& commands)
CommandIDs::open,
CommandIDs::closeAllDocuments,
CommandIDs::saveAll,
CommandIDs::showGlobalPreferences,
CommandIDs::showGlobalPathsWindow,
CommandIDs::showUTF8Tool,
CommandIDs::showSVGPathTool,
CommandIDs::showAboutWindow,
@@ -580,9 +580,10 @@ void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationComman
result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));
break;
case CommandIDs::showGlobalPreferences:
result.setInfo ("Preferences...", "Shows the preferences window.", CommandCategories::general, 0);
result.defaultKeypresses.add (KeyPress (',', ModifierKeys::commandModifier, 0));
case CommandIDs::showGlobalPathsWindow:
result.setInfo ("Global Search Paths...",
"Shows the window to change the global search paths.",
CommandCategories::general, 0);
break;
case CommandIDs::closeAllDocuments:
@@ -646,7 +647,7 @@ bool ProjucerApplication::perform (const InvocationInfo& info)
case CommandIDs::closeAllDocuments: closeAllDocuments (true); break;
case CommandIDs::showUTF8Tool: showUTF8ToolWindow(); break;
case CommandIDs::showSVGPathTool: showSVGPathDataToolWindow(); break;
case CommandIDs::showGlobalPreferences: AppearanceSettings::showGlobalPreferences (globalPreferencesWindow); break;
case CommandIDs::showGlobalPathsWindow: showPathsWindow(); break;
case CommandIDs::showAboutWindow: showAboutWindow(); break;
case CommandIDs::showAppUsageWindow: showApplicationUsageDataAgreementPopup(); break;
case CommandIDs::loginLogout: doLogout(); break;
@@ -742,6 +743,32 @@ void ProjucerApplication::dismissApplicationUsageDataAgreementPopup()
applicationUsageDataWindow = nullptr;
}
void ProjucerApplication::showPathsWindow()
{
if (pathsWindow != nullptr)
pathsWindow->toFront (true);
else
new FloatingToolWindow ("Global Search Paths",
"pathsWindowPos",
new GlobalSearchPathsWindowComponent(), pathsWindow, false,
600, 500, 600, 500, 600, 500);
}
void ProjucerApplication::showEditorColourSchemeWindow()
{
if (editorColourSchemeWindow != nullptr)
editorColourSchemeWindow->toFront (true);
else
{
new FloatingToolWindow ("Editor Colour Scheme",
"editorColourSchemeWindowPos",
new EditorColourSchemeWindowComponent(),
editorColourSchemeWindow,
false,
500, 500, 500, 500, 500, 500);
}
}
//==============================================================================
struct FileWithTime
{
@@ -846,9 +873,10 @@ void ProjucerApplication::setColourScheme (int index, bool saveSetting)
if (utf8Window != nullptr) utf8Window->sendLookAndFeelChange();
if (svgPathWindow != nullptr) svgPathWindow->sendLookAndFeelChange();
if (globalPreferencesWindow != nullptr) globalPreferencesWindow->sendLookAndFeelChange();
if (aboutWindow != nullptr) aboutWindow->sendLookAndFeelChange();
if (applicationUsageDataWindow != nullptr) applicationUsageDataWindow->sendLookAndFeelChange();
if (pathsWindow != nullptr) pathsWindow->sendLookAndFeelChange();
if (editorColourSchemeWindow != nullptr) editorColourSchemeWindow->sendLookAndFeelChange();
auto* mcm = ModalComponentManager::getInstance();
for (auto i = 0; i < mcm->getNumModalComponents(); ++i)


+ 5
- 2
extras/Projucer/Source/Application/jucer_Application.h View File

@@ -102,6 +102,9 @@ public:
void showApplicationUsageDataAgreementPopup();
void dismissApplicationUsageDataAgreementPopup();
void showPathsWindow();
void showEditorColourSchemeWindow();
void updateAllBuildTabs();
LatestVersionChecker* createVersionChecker() const;
@@ -129,8 +132,8 @@ public:
OpenDocumentManager openDocumentManager;
ScopedPointer<ApplicationCommandManager> commandManager;
ScopedPointer<Component> appearanceEditorWindow, globalPreferencesWindow, utf8Window,
svgPathWindow, aboutWindow, applicationUsageDataWindow;
ScopedPointer<Component> utf8Window, svgPathWindow, aboutWindow, applicationUsageDataWindow,
pathsWindow, editorColourSchemeWindow;
ScopedPointer<FileLogger> logger;


+ 1
- 1
extras/Projucer/Source/Application/jucer_AutoUpdater.cpp View File

@@ -745,7 +745,7 @@ void LatestVersionChecker::modalStateFinished (int result,
void LatestVersionChecker::askUserForLocationToDownload (URL& newVersionToDownload, const String& extraHeaders)
{
File targetFolder (findDefaultModulesFolder());
File targetFolder (EnabledModuleList::findGlobalModulesFolder());
if (isJuceModulesFolder (targetFolder))
targetFolder = targetFolder.getParentDirectory();


+ 1
- 1
extras/Projucer/Source/Application/jucer_CommandIDs.h View File

@@ -45,7 +45,7 @@ namespace CommandIDs
createNewExporter = 0x300015,
showUTF8Tool = 0x300020,
showGlobalPreferences = 0x300021,
showGlobalPathsWindow = 0x300021,
showTranslationTool = 0x300022,
showSVGPathTool = 0x300023,
showAboutWindow = 0x300024,


+ 0
- 465
extras/Projucer/Source/Application/jucer_GlobalPreferences.cpp View File

@@ -1,465 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../jucer_Headers.h"
#include "jucer_GlobalPreferences.h"
#include "../Utility/jucer_FloatingToolWindow.h"
#include "../Utility/jucer_ColourPropertyComponent.h"
#include "jucer_Application.h"
//==============================================================================
PathSettingsTab::PathSettingsTab (DependencyPathOS os)
{
const int maxChars = 1024;
auto& settings = getAppSettings();
vst3PathComponent = pathComponents.add (new TextPropertyComponent (settings.getGlobalPath (Ids::vst3Path, os), "VST3 SDK", maxChars, false));
#if ! JUCE_LINUX
rtasPathComponent = pathComponents.add (new TextPropertyComponent (settings.getGlobalPath (Ids::rtasPath, os), "RTAS SDK", maxChars, false));
aaxPathComponent = pathComponents.add (new TextPropertyComponent (settings.getGlobalPath (Ids::aaxPath, os), "AAX SDK", maxChars, false));
#endif
androidSdkPathComponent = pathComponents.add (new TextPropertyComponent (settings.getGlobalPath (Ids::androidSDKPath, os), "Android SDK", maxChars, false));
androidNdkPathComponent = pathComponents.add (new TextPropertyComponent (settings.getGlobalPath (Ids::androidNDKPath, os), "Android NDK", maxChars, false));
for (auto component : pathComponents)
{
addAndMakeVisible (component);
component->addListener (this);
textPropertyComponentChanged (component);
}
}
PathSettingsTab::~PathSettingsTab()
{
}
void PathSettingsTab::textPropertyComponentChanged (TextPropertyComponent* textPropertyComponent)
{
auto keyName = getKeyForPropertyComponent (textPropertyComponent);
auto textColour = getAppSettings().isGlobalPathValid (File::getCurrentWorkingDirectory(), keyName, textPropertyComponent->getText())
? findColour (widgetTextColourId)
: Colours::red;
textPropertyComponent->setColour (TextPropertyComponent::textColourId, textColour);
}
Identifier PathSettingsTab::getKeyForPropertyComponent (TextPropertyComponent* component) const
{
if (component == vst3PathComponent) return Ids::vst3Path;
if (component == rtasPathComponent) return Ids::rtasPath;
if (component == aaxPathComponent) return Ids::aaxPath;
if (component == androidSdkPathComponent) return Ids::androidSDKPath;
if (component == androidNdkPathComponent) return Ids::androidNDKPath;
// this property component does not have a key associated to it!
jassertfalse;
return {};
}
Component* PathSettingsTab::getContent()
{
return this;
}
String PathSettingsTab::getName() const noexcept
{
return "Paths";
}
void PathSettingsTab::resized()
{
const int componentHeight = 25;
for (auto component : pathComponents)
{
const auto elementNumber = pathComponents.indexOf (component);
component->setBounds (10, componentHeight * elementNumber, getWidth() - 20, componentHeight);
}
}
void PathSettingsTab::lookAndFeelChanged()
{
for (auto* comp : pathComponents)
textPropertyComponentChanged (comp);
}
//==============================================================================
struct AppearanceEditor
{
struct FontScanPanel : public Component,
private Timer
{
FontScanPanel()
{
fontsToScan = Font::findAllTypefaceNames();
startTimer (1);
}
void paint (Graphics& g) override
{
g.fillAll (findColour (backgroundColourId));
g.setFont (14.0f);
g.setColour (findColour (defaultTextColourId));
g.drawFittedText ("Scanning for fonts..", getLocalBounds(), Justification::centred, 2);
const auto size = 30;
getLookAndFeel().drawSpinningWaitAnimation (g, Colours::white, (getWidth() - size) / 2, getHeight() / 2 - 50, size, size);
}
void timerCallback() override
{
repaint();
if (fontsToScan.size() == 0)
{
getAppSettings().monospacedFontNames = fontsFound;
if (auto* tab = findParentComponentOfClass<AppearanceSettingsTab>())
tab->changeContent (new EditorPanel());
}
else
{
if (isMonospacedTypeface (fontsToScan[0]))
fontsFound.add (fontsToScan[0]);
fontsToScan.remove (0);
}
}
// A rather hacky trick to select only the fixed-pitch fonts..
// This is unfortunately a bit slow, but will work on all platforms.
static bool isMonospacedTypeface (const String& name)
{
const Font font (name, 20.0f, Font::plain);
const auto width = font.getStringWidth ("....");
return width == font.getStringWidth ("WWWW")
&& width == font.getStringWidth ("0000")
&& width == font.getStringWidth ("1111")
&& width == font.getStringWidth ("iiii");
}
StringArray fontsToScan, fontsFound;
};
//==============================================================================
struct EditorPanel : public Component,
private ButtonListener
{
EditorPanel()
: loadButton ("Load Scheme..."),
saveButton ("Save Scheme...")
{
rebuildProperties();
addAndMakeVisible (panel);
addAndMakeVisible (loadButton);
addAndMakeVisible (saveButton);
loadButton.addListener (this);
saveButton.addListener (this);
lookAndFeelChanged();
saveSchemeState();
}
~EditorPanel()
{
if (hasSchemeBeenModifiedSinceSave())
saveScheme (true);
}
void rebuildProperties()
{
auto& scheme = getAppSettings().appearance;
Array<PropertyComponent*> props;
auto fontValue = scheme.getCodeFontValue();
props.add (FontNameValueSource::createProperty ("Code Editor Font", fontValue));
props.add (FontSizeValueSource::createProperty ("Font Size", fontValue));
const auto colourNames = scheme.getColourNames();
for (int i = 0; i < colourNames.size(); ++i)
props.add (new ColourPropertyComponent (nullptr, colourNames[i],
scheme.getColourValue (colourNames[i]),
Colours::white, false));
panel.clear();
panel.addProperties (props);
}
void resized() override
{
auto r = getLocalBounds();
panel.setBounds (r.removeFromTop (getHeight() - 28).reduced (10, 2));
loadButton.setBounds (r.removeFromLeft (getWidth() / 2).reduced (10, 1));
saveButton.setBounds (r.reduced (10, 1));
}
private:
PropertyPanel panel;
TextButton loadButton, saveButton;
Font codeFont;
Array<var> colourValues;
void buttonClicked (Button* b) override
{
if (b == &loadButton)
loadScheme();
else
saveScheme (false);
}
void saveScheme (bool isExit)
{
FileChooser fc ("Select a file in which to save this colour-scheme...",
getAppSettings().appearance.getSchemesFolder()
.getNonexistentChildFile ("Scheme", AppearanceSettings::getSchemeFileSuffix()),
AppearanceSettings::getSchemeFileWildCard());
if (fc.browseForFileToSave (true))
{
File file (fc.getResult().withFileExtension (AppearanceSettings::getSchemeFileSuffix()));
getAppSettings().appearance.writeToFile (file);
getAppSettings().appearance.refreshPresetSchemeList();
saveSchemeState();
ProjucerApplication::getApp().selectEditorColourSchemeWithName (file.getFileNameWithoutExtension());
}
else if (isExit)
{
restorePreviousScheme();
}
}
void loadScheme()
{
FileChooser fc ("Please select a colour-scheme file to load...",
getAppSettings().appearance.getSchemesFolder(),
AppearanceSettings::getSchemeFileWildCard());
if (fc.browseForFileToOpen())
{
if (getAppSettings().appearance.readFromFile (fc.getResult()))
{
rebuildProperties();
saveSchemeState();
}
}
}
void lookAndFeelChanged() override
{
loadButton.setColour (TextButton::buttonColourId,
findColour (secondaryButtonBackgroundColourId));
}
void saveSchemeState()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
codeFont = appearance.getCodeFont();
colourValues.clear();
for (int i = 0; i < colourNames.size(); ++i)
colourValues.add (appearance.getColourValue (colourNames[i]).getValue());
}
bool hasSchemeBeenModifiedSinceSave()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
if (codeFont != appearance.getCodeFont())
return true;
for (int i = 0; i < colourNames.size(); ++i)
if (colourValues[i] != appearance.getColourValue (colourNames[i]).getValue())
return true;
return false;
}
void restorePreviousScheme()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
appearance.getCodeFontValue().setValue (codeFont.toString());
for (int i = 0; i < colourNames.size(); ++i)
appearance.getColourValue (colourNames[i]).setValue (colourValues[i]);
}
JUCE_DECLARE_NON_COPYABLE (EditorPanel)
};
//==============================================================================
struct FontNameValueSource : public ValueSourceFilter
{
FontNameValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return Font::fromString (sourceValue.toString()).getTypefaceName();
}
void setValue (const var& newValue) override
{
auto font = Font::fromString (sourceValue.toString());
font.setTypefaceName (newValue.toString().isEmpty() ? Font::getDefaultMonospacedFontName()
: newValue.toString());
sourceValue = font.toString();
}
static ChoicePropertyComponent* createProperty (const String& title, const Value& value)
{
auto fontNames = getAppSettings().monospacedFontNames;
Array<var> values;
values.add (Font::getDefaultMonospacedFontName());
values.add (var());
for (int i = 0; i < fontNames.size(); ++i)
values.add (fontNames[i]);
StringArray names;
names.add ("<Default Monospaced>");
names.add (String());
names.addArray (getAppSettings().monospacedFontNames);
return new ChoicePropertyComponent (Value (new FontNameValueSource (value)),
title, names, values);
}
};
//==============================================================================
struct FontSizeValueSource : public ValueSourceFilter
{
FontSizeValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return Font::fromString (sourceValue.toString()).getHeight();
}
void setValue (const var& newValue) override
{
sourceValue = Font::fromString (sourceValue.toString()).withHeight (newValue).toString();
}
static PropertyComponent* createProperty (const String& title, const Value& value)
{
return new SliderPropertyComponent (Value (new FontSizeValueSource (value)),
title, 5.0, 40.0, 0.1, 0.5);
}
};
};
void AppearanceSettings::showGlobalPreferences (ScopedPointer<Component>& ownerPointer, bool showCodeEditorTab)
{
if (ownerPointer != nullptr)
ownerPointer->toFront (true);
else
{
auto* prefs = new GlobalPreferencesComponent();
new FloatingToolWindow ("Preferences",
"globalPreferencesEditorPos",
prefs,
ownerPointer, false,
500, 500, 500, 500, 500, 500);
if (showCodeEditorTab)
prefs->setCurrentTabIndex (1);
}
}
//==============================================================================
AppearanceSettingsTab::AppearanceSettingsTab()
{
if (getAppSettings().monospacedFontNames.size() == 0)
content = new AppearanceEditor::FontScanPanel();
else
content = new AppearanceEditor::EditorPanel();
changeContent (content);
}
Component* AppearanceSettingsTab::getContent()
{
return this;
}
void AppearanceSettingsTab::changeContent (Component* newContent)
{
content = newContent;
addAndMakeVisible (content);
content->setBounds (getLocalBounds());
}
String AppearanceSettingsTab::getName() const noexcept
{
return "Code Editor";
}
void AppearanceSettingsTab::resized()
{
content->setBounds (getLocalBounds());
}
//==============================================================================
GlobalPreferencesComponent::GlobalPreferencesComponent()
: TabbedComponent (TabbedButtonBar::TabsAtTop)
{
preferenceTabs.add (new PathSettingsTab (TargetOS::getThisOS()));
preferenceTabs.add (new AppearanceSettingsTab);
for (GlobalPreferencesTab** tab = preferenceTabs.begin(); tab != preferenceTabs.end(); ++tab)
addTab ((*tab)->getName(), findColour (backgroundColourId, true), (*tab)->getContent(), true);
}
void GlobalPreferencesComponent::paint (Graphics& g)
{
g.fillAll (findColour (backgroundColourId));
}
void GlobalPreferencesComponent::lookAndFeelChanged()
{
for (auto* tab : preferenceTabs)
tab->getContent()->sendLookAndFeelChange();
}

+ 0
- 116
extras/Projucer/Source/Application/jucer_GlobalPreferences.h View File

@@ -1,116 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
#include "../Project/jucer_DependencyPathPropertyComponent.h"
class GlobalPreferencesTab
{
public:
virtual ~GlobalPreferencesTab() {}
virtual Component* getContent() = 0;
virtual String getName() const noexcept = 0;
};
//==============================================================================
/** This component implements the "Paths" tab in the global preferences window,
which defines the default paths for dependencies like third-party SDKs
for this machine.
*/
class PathSettingsTab : public GlobalPreferencesTab,
public Component,
private TextPropertyComponent::Listener
{
public:
PathSettingsTab (DependencyPathOS);
~PathSettingsTab();
Component* getContent() override;
String getName() const noexcept override;
void resized() override;
private:
void textPropertyComponentChanged (TextPropertyComponent*) override;
Identifier getKeyForPropertyComponent (TextPropertyComponent*) const;
void lookAndFeelChanged() override;
OwnedArray<TextPropertyComponent> pathComponents;
TextPropertyComponent* vst3PathComponent;
TextPropertyComponent* rtasPathComponent;
TextPropertyComponent* aaxPathComponent;
TextPropertyComponent* androidSdkPathComponent;
TextPropertyComponent* androidNdkPathComponent;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PathSettingsTab)
};
//==============================================================================
/** This component implements the "Code Editor" tab in the global preferences window,
which sets font sizes and colours for the Projucer's code editor.
The content is either an EditorPanel (the actual settings tab) or a FontScanPanel
(shown if the tab is scanning for available fonts before showing the EditorPanel).
*/
class AppearanceSettingsTab : public GlobalPreferencesTab,
public Component
{
public:
AppearanceSettingsTab();
Component* getContent() override;
void changeContent (Component* newContent);
String getName() const noexcept override;
void resized() override;
private:
ScopedPointer<Component> content;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AppearanceSettingsTab)
};
//==============================================================================
class GlobalPreferencesComponent : public TabbedComponent
{
public:
GlobalPreferencesComponent();
void paint (Graphics&) override;
private:
void lookAndFeelChanged() override;
OwnedArray<GlobalPreferencesTab> preferenceTabs;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlobalPreferencesComponent)
};

+ 2
- 0
extras/Projucer/Source/Application/jucer_Main.cpp View File

@@ -35,6 +35,8 @@
#include "../Utility/jucer_SVGPathDataComponent.h"
#include "../Utility/jucer_AboutWindowComponent.h"
#include "../Utility/jucer_ApplicationUsageDataWindowComponent.h"
#include "../Utility/jucer_EditorColourSchemeWindowComponent.h"
#include "../Utility/jucer_GlobalSearchPathsWindowComponent.h"
#include "../Utility/jucer_FloatingToolWindow.h"
#include "../LiveBuildEngine/projucer_MessageIDs.h"


+ 0
- 36
extras/Projucer/Source/Application/jucer_MainWindow.cpp View File

@@ -580,39 +580,3 @@ Project* MainWindowList::getFrontmostProject()
return nullptr;
}
File findDefaultModulesFolder (bool mustContainJuceCoreModule)
{
auto& windows = ProjucerApplication::getApp().mainWindowList;
for (int i = windows.windows.size(); --i >= 0;)
{
if (auto* p = windows.windows.getUnchecked (i)->getProject())
{
const File f (EnabledModuleList::findDefaultModulesFolder (*p));
if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule))
return f;
}
}
if (mustContainJuceCoreModule)
return findDefaultModulesFolder (false);
auto f = File::getSpecialLocation (File::currentApplicationFile);
for (;;)
{
auto parent = f.getParentDirectory();
if (parent == f || ! parent.isDirectory())
break;
if (isJuceFolder (parent))
return parent.getChildFile ("modules");
f = parent;
}
return {};
}

+ 0
- 1
extras/Projucer/Source/ComponentEditor/ui/jucer_JucerDocumentEditor.cpp View File

@@ -26,7 +26,6 @@
#include "../../jucer_Headers.h"
#include "../../Application/jucer_AppearanceSettings.h"
#include "../../Application/jucer_GlobalPreferences.h"
#include "../../Application/jucer_Application.h"
#include "jucer_JucerDocumentEditor.h"
#include "jucer_TestComponent.h"


+ 1
- 3
extras/Projucer/Source/LiveBuildEngine/projucer_CompileEngineClient.cpp View File

@@ -519,9 +519,7 @@ private:
paths.addArray (getSearchPathsFromString (ProjectProperties::getSystemHeaderPathString (project)));
if (project.getProjectType().isAudioPlugin())
{
paths.add (getAppSettings().getGlobalPath (Ids::vst3Path, TargetOS::getThisOS()).toString());
}
paths.add (getAppSettings().getStoredPath (Ids::vst3Path).toString());
OwnedArray<LibraryModule> modules;
project.getModules().createRequiredModules (modules);


+ 32
- 2
extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp View File

@@ -493,8 +493,26 @@ Value ProjectExporter::getPathForModuleValue (const String& moduleID)
String ProjectExporter::getPathForModuleString (const String& moduleID) const
{
return settings.getChildWithName (Ids::MODULEPATHS)
.getChildWithProperty (Ids::ID, moduleID) [Ids::path].toString();
auto exporterPath = settings.getChildWithName (Ids::MODULEPATHS)
.getChildWithProperty (Ids::ID, moduleID) [Ids::path].toString();
if (exporterPath.isEmpty() || project.getModules().shouldUseGlobalPath (moduleID).getValue())
{
auto id = EnabledModuleList::isJuceModule (moduleID) ? Ids::defaultJuceModulePath
: Ids::defaultUserModulePath;
if (TargetOS::getThisOS() != getTargetOSForExporter())
return getAppSettings().getFallbackPathForOS (id, getTargetOSForExporter()).toString();
if (id == Ids::defaultJuceModulePath)
return getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString();
return EnabledModuleList::findUserModuleFolder (moduleID,
getAppSettings().getStoredPath (Ids::defaultUserModulePath).toString(),
project).getFullPathName();
}
return exporterPath;
}
void ProjectExporter::removePathForModule (const String& moduleID)
@@ -504,6 +522,18 @@ void ProjectExporter::removePathForModule (const String& moduleID)
paths.removeChild (m, project.getUndoManagerFor (settings));
}
TargetOS::OS ProjectExporter::getTargetOSForExporter() const
{
auto targetOS = TargetOS::unknown;
if (isWindows()) targetOS = TargetOS::windows;
else if (isOSX() || isiOS()) targetOS = TargetOS::osx;
else if (isLinux()) targetOS = TargetOS::linux;
else if (isAndroid()) targetOS = TargetOS::getThisOS();
return targetOS;
}
RelativePath ProjectExporter::getModuleFolderRelativeToProject (const String& moduleID) const
{
if (project.getModules().shouldCopyModuleFilesLocally (moduleID).getValue())


+ 3
- 1
extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h View File

@@ -28,7 +28,7 @@
#include "../Project/jucer_Project.h"
#include "../Project/jucer_ProjectType.h"
#include "../Application/jucer_GlobalPreferences.h"
#include "../Project/jucer_DependencyPathPropertyComponent.h"
class ProjectSaver;
@@ -160,6 +160,8 @@ public:
String getPathForModuleString (const String& moduleID) const;
void removePathForModule (const String& moduleID);
TargetOS::OS getTargetOSForExporter() const;
RelativePath getLegacyModulePath (const String& moduleID) const;
String getLegacyModulePath() const;


+ 30
- 26
extras/Projucer/Source/Project/jucer_ConfigTree_Base.h View File

@@ -28,24 +28,11 @@
class InfoButton : public Button
{
public:
InfoButton (PropertyComponent& comp)
: Button (String()),
associatedComponent (comp)
InfoButton (const String& infoToDisplay = String())
: Button (String())
{
tooltip = associatedComponent.getTooltip();
auto stringWidth = Font (14.0f).getStringWidthFloat (tooltip);
int maxWidth = 300;
if (stringWidth > maxWidth)
{
width = maxWidth;
numLines += static_cast<int> (stringWidth / width);
}
else
{
width = roundToInt (stringWidth);
}
if (infoToDisplay.isNotEmpty())
setInfoToDisplay (infoToDisplay);
}
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
@@ -64,23 +51,38 @@ public:
void clicked() override
{
auto* w = new InfoWindow (tooltip);
auto* w = new InfoWindow (info);
w->setSize (width, w->getHeight() * numLines + 10);
CallOutBox::launchAsynchronously (w, getScreenBounds(), nullptr);
}
PropertyComponent& associatedComponent;
void setInfoToDisplay (const String& infoToDisplay)
{
if (infoToDisplay.isNotEmpty())
{
info = infoToDisplay;
auto stringWidth = roundToInt (Font (14.0f).getStringWidthFloat (info));
width = jmin (300, stringWidth);
numLines += static_cast<int> (stringWidth / width);
}
}
void setAssociatedComponent (Component* comp) { associatedComponent = comp; }
Component* getAssociatedComponent() { return associatedComponent; }
private:
String tooltip;
String info;
Component* associatedComponent = nullptr;
int width;
int numLines = 1;
//==============================================================================
struct InfoWindow : public Component
{
InfoWindow (String s)
InfoWindow (const String& s)
: stringToDisplay (s)
{
setSize (150, 14);
@@ -125,7 +127,8 @@ public:
if (! prop->getTooltip().isEmpty())
{
addAndMakeVisible (infoButtons.add (new InfoButton (*prop)));
addAndMakeVisible (infoButtons.add (new InfoButton (prop->getTooltip())));
infoButtons.getLast()->setAssociatedComponent (prop);
prop->setTooltip (String()); // set the tooltip to empty so it only displays when its button is clicked
}
}
@@ -145,7 +148,7 @@ public:
InfoButton* buttonToUse = nullptr;
for (auto* b : infoButtons)
if (&b->associatedComponent == pp)
if (b->getAssociatedComponent() == pp)
buttonToUse = b;
if (buttonToUse != nullptr)
@@ -189,11 +192,12 @@ public:
if (pp->getName() == "Dependencies")
return;
if (auto* propertyChild = pp->getChildComponent (0))
for (int i = pp->getNumChildComponents() - 1; i >= 0; --i)
{
auto bounds = propertyChild->getBounds();
auto* child = pp->getChildComponent (i);
propertyChild->setBounds (bounds.withSizeKeepingCentre (propertyChild->getWidth(), pp->getPreferredHeight()));
auto bounds = child->getBounds();
child->setBounds (bounds.withSizeKeepingCentre (child->getWidth(), pp->getPreferredHeight()));
}
}


+ 181
- 37
extras/Projucer/Source/Project/jucer_ConfigTree_Modules.h View File

@@ -30,12 +30,16 @@ public:
ModuleItem (Project& p, const String& modID)
: project (p), moduleID (modID)
{
auto moduleVersionNum = project.getModules().getModuleInfo (moduleID).getVersion();
if (moduleVersionNum != ProjucerApplication::getApp().getApplicationVersion())
moduleVersion = moduleVersionNum;
}
bool canBeSelected() const override { return true; }
bool mightContainSubItems() override { return false; }
String getUniqueName() const override { return "module_" + moduleID; }
String getDisplayName() const override { return moduleID; }
String getDisplayName() const override { return moduleID + (moduleVersion.isNotEmpty() ? String (" (" + moduleVersion + ")") : ""); }
String getRenamingName() const override { return getDisplayName(); }
void setName (const String&) override {}
bool isMissing() const override { return hasMissingDependencies(); }
@@ -86,6 +90,7 @@ public:
Project& project;
String moduleID;
String moduleVersion;
private:
bool hasMissingDependencies() const
@@ -94,7 +99,8 @@ private:
}
//==============================================================================
class ModuleSettingsPanel : public Component
class ModuleSettingsPanel : public Component,
private Value::Listener
{
public:
ModuleSettingsPanel (Project& p, const String& modID)
@@ -102,37 +108,72 @@ private:
project (p),
moduleID (modID)
{
defaultJuceModulePathValue.referTo (getAppSettings().getStoredPath (Ids::defaultJuceModulePath));
defaultUserModulePathValue.referTo (getAppSettings().getStoredPath (Ids::defaultUserModulePath));
defaultJuceModulePathValue.addListener (this);
defaultUserModulePathValue.addListener (this);
addAndMakeVisible (group);
refresh();
}
void refresh()
{
setEnabled (project.getModules().isModuleEnabled (moduleID));
auto& modules = project.getModules();
const auto& isUsingGlobalPathValue = modules.shouldUseGlobalPath (moduleID);
setEnabled (modules.isModuleEnabled (moduleID));
PropertyListBuilder props;
props.add (new ModuleInfoComponent (project, moduleID));
if (project.getModules().getExtraDependenciesNeeded (moduleID).size() > 0)
if (modules.getExtraDependenciesNeeded (moduleID).size() > 0)
props.add (new MissingDependenciesComponent (project, moduleID));
modulePathValueSources.clear();
for (Project::ExporterIterator exporter (project); exporter.next();)
props.add (new FilePathPropertyComponent (exporter->getPathForModuleValue (moduleID),
"Path for " + exporter->getName().quoted(),
true, "*", project.getProjectFolder()),
{
auto key = modules.isJuceModule (moduleID) ? Ids::defaultJuceModulePath
: Ids::defaultUserModulePath;
Value src (modulePathValueSources.add (new DependencyPathValueSource (exporter->getPathForModuleValue (moduleID),
key, exporter->getTargetOSForExporter())));
auto* pathComponent = new DependencyFilePathPropertyComponent (src, "Path for " + exporter->getName().quoted(),
true, "*", project.getProjectFolder());
props.add (pathComponent,
"A path to the folder that contains the " + moduleID + " module when compiling the "
+ exporter->getName().quoted() + " target. "
+ exporter->getName().quoted() + " target. "
"This can be an absolute path, or relative to the jucer project folder, but it "
"must be valid on the filesystem of the target machine that will be performing this build.");
"must be valid on the filesystem of the target machine that will be performing this build. If this "
"is empty then the global path will be used.");
props.add (new BooleanPropertyComponent (project.getModules().shouldCopyModuleFilesLocally (moduleID),
pathComponent->setEnabled (! isUsingGlobalPathValue.getValue());
}
globalPathValue.referTo (isUsingGlobalPathValue);
auto menuItemString = (TargetOS::getThisOS() == TargetOS::osx ? "\"Projucer->Global Search Paths...\""
: "\"File->Global Search Paths...\"");
props.add (new BooleanPropertyComponent (globalPathValue,
"Use global path", "Use global path for this module"),
String ("If this is enabled, then the locally-stored global path (set in the ") + menuItemString + " menu item) "
"will be used as the path to this module. "
"This means that if this Projucer project is opened on another machine it will use that machine's global path as the path to this module.");
globalPathValue.addListener (this);
props.add (new BooleanPropertyComponent (modules.shouldCopyModuleFilesLocally (moduleID),
"Create local copy", "Copy the module into the project folder"),
"If this is enabled, then a local copy of the entire module will be made inside your project (in the auto-generated JuceLibraryFiles folder), "
"so that your project will be self-contained, and won't need to contain any references to files in other folders. "
"This also means that you can check the module into your source-control system to make sure it is always in sync with your own code.");
props.add (new BooleanPropertyComponent (project.getModules().shouldShowAllModuleFilesInProject (moduleID),
props.add (new BooleanPropertyComponent (modules.shouldShowAllModuleFilesInProject (moduleID),
"Add source to project", "Make module files browsable in projects"),
"If this is enabled, then the entire source tree from this module will be shown inside your project, "
"making it easy to browse/edit the module's classes. If disabled, then only the minimum number of files "
@@ -148,7 +189,7 @@ private:
mappings.add (Project::configFlagEnabled);
mappings.add (Project::configFlagDisabled);
ModuleDescription info (project.getModules().getModuleInfo (moduleID));
ModuleDescription info (modules.getModuleInfo (moduleID));
if (info.isValid())
{
@@ -177,6 +218,28 @@ private:
PropertyGroupComponent group;
Project& project;
String moduleID;
Value globalPathValue;
Value defaultJuceModulePathValue, defaultUserModulePathValue;
ReferenceCountedArray<Value::ValueSource> modulePathValueSources;
//==============================================================================
void valueChanged (Value& v) override
{
if (v == globalPathValue)
{
auto useGlobalPath = globalPathValue.getValue();
for (auto prop : group.properties)
{
if (auto* pathPropertyComponent = dynamic_cast<DependencyFilePathPropertyComponent*> (prop))
pathPropertyComponent->setEnabled (! useGlobalPath);
}
}
if (auto* moduleInfo = dynamic_cast<ModuleInfoComponent*> (group.properties.getUnchecked (0)))
moduleInfo->refresh();
}
//==============================================================================
class ModuleInfoComponent : public PropertyComponent,
@@ -193,13 +256,13 @@ private:
refresh();
}
private:
void refresh() override
{
info = project.getModules().getModuleInfo (moduleID);
repaint();
}
private:
void paint (Graphics& g) override
{
auto bounds = getLocalBounds().reduced (10);
@@ -207,15 +270,17 @@ private:
if (info.isValid())
{
auto topSlice = bounds.removeFromTop (bounds.getHeight() / 3);
auto topSlice = bounds.removeFromTop (bounds.getHeight() / 2);
bounds.removeFromTop (bounds.getHeight() / 6);
auto bottomSlice = bounds;
g.setColour (findColour (defaultTextColourId));
g.drawFittedText (info.getName(), topSlice.removeFromTop (topSlice.getHeight() / 3), Justification::centredLeft, 1);
g.drawFittedText ("Version: " + info.getVersion(), topSlice.removeFromTop (topSlice.getHeight() / 2), Justification::centredLeft, 1);
g.drawFittedText ("License: " + info.getLicense(), topSlice.removeFromTop (topSlice.getHeight()), Justification::centredLeft, 1);
g.drawFittedText (info.getName(), topSlice.removeFromTop (topSlice.getHeight() / 4), Justification::centredLeft, 1);
g.drawFittedText ("Version: " + info.getVersion(), topSlice.removeFromTop (topSlice.getHeight() / 3), Justification::centredLeft, 1);
g.drawFittedText ("License: " + info.getLicense(), topSlice.removeFromTop (topSlice.getHeight() / 2), Justification::centredLeft, 1);
g.drawFittedText ("Location: " + info.getFolder().getParentDirectory().getFullPathName(),
topSlice.removeFromTop (topSlice.getHeight()), Justification::centredLeft, 1);
g.drawFittedText (info.getDescription(), bottomSlice, Justification::topLeft, 3, 1.0f);
}
@@ -270,23 +335,22 @@ private:
void buttonClicked (Button*) override
{
bool anyFailed = false;
ModuleList list;
list.scanAllKnownFolders (project);
for (int i = missingDependencies.size(); --i >= 0;)
{
if (const ModuleDescription* info = list.getModuleWithID (missingDependencies[i]))
project.getModules().addModule (info->moduleFolder, project.getModules().areMostModulesCopiedLocally());
else
anyFailed = true;
}
list.scanGlobalJuceModulePath();
if (! tryToFix (list))
list.scanGlobalUserModulePath();
if (! tryToFix (list))
list.scanProjectExporterModulePaths (project);
bool fixed = tryToFix (list);
if (ModuleSettingsPanel* p = findParentComponentOfClass<ModuleSettingsPanel>())
p->refresh();
if (anyFailed)
if (! fixed)
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Adding Missing Dependencies",
"Couldn't locate some of these modules - you'll need to find their "
@@ -304,6 +368,26 @@ private:
StringArray missingDependencies;
TextButton fixButton;
bool tryToFix (ModuleList& list)
{
auto& modules = project.getModules();
auto copyLocally = modules.areMostModulesCopiedLocally();
auto useGlobalPath = modules.areMostModulesUsingGlobalPath();
StringArray missing;
for (auto missingModule : missingDependencies)
{
if (auto* info = list.getModuleWithID (missingModule))
modules.addModule (info->moduleFolder, copyLocally, useGlobalPath);
else
missing.add (missingModule);
}
missingDependencies.swapWith (missing);
return (missingDependencies.size() == 0);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MissingDependenciesComponent)
};
};
@@ -370,7 +454,8 @@ public:
for (int i = 0; i < modules.size(); ++i)
project.getModules().addModule (modules.getReference(i).moduleFolder,
project.getModules().areMostModulesCopiedLocally());
project.getModules().areMostModulesCopiedLocally(),
project.getModules().areMostModulesUsingGlobalPath());
}
void addSubItems() override
@@ -381,12 +466,36 @@ public:
void showPopupMenu() override
{
PopupMenu menu, knownModules, copyModeMenu;
auto& modules = project.getModules();
PopupMenu knownModules, jucePathModules, userPathModules, exporterPathsModules;
const StringArray modules (getAvailableModules());
for (int i = 0; i < modules.size(); ++i)
knownModules.addItem (1 + i, modules[i], ! project.getModules().isModuleEnabled (modules[i]));
auto index = 100;
auto globalJucePathModules = getAvailableModulesInGlobalJucePath();
for (auto m : globalJucePathModules)
jucePathModules.addItem (index++, m, ! modules.isModuleEnabled (m));
knownModules.addSubMenu ("Global JUCE modules path", jucePathModules);
index = 200;
auto globalUserPathModules = getAvailableModulesInGlobalUserPath();
for (auto m : getAvailableModulesInGlobalUserPath())
{
if (! globalJucePathModules.contains (m))
userPathModules.addItem (index++, m, ! modules.isModuleEnabled (m));
}
knownModules.addSubMenu ("Global user modules path", userPathModules);
index = 300;
for (auto m : getAvailableModulesInExporterPaths())
{
if (! globalJucePathModules.contains (m) && ! globalUserPathModules.contains (m))
exporterPathsModules.addItem (index++, m, ! modules.isModuleEnabled (m));
}
knownModules.addSubMenu ("Exporter paths", exporterPathsModules);
PopupMenu menu;
menu.addSubMenu ("Add a module", knownModules);
menu.addSeparator();
menu.addItem (1001, "Add a module from a specified folder...");
@@ -396,16 +505,51 @@ public:
void handlePopupMenuResult (int resultCode) override
{
auto& modules = project.getModules();
if (resultCode == 1001)
project.getModules().addModuleFromUserSelectedFile();
{
modules.addModuleFromUserSelectedFile();
}
else if (resultCode > 0)
project.getModules().addModuleInteractive (getAvailableModules() [resultCode - 1]);
{
if (resultCode < 200)
modules.addModuleInteractive (getAvailableModulesInGlobalJucePath() [resultCode - 100]);
else if (resultCode < 300)
modules.addModuleInteractive (getAvailableModulesInGlobalUserPath() [resultCode - 200]);
else if (resultCode < 400)
modules.addModuleInteractive (getAvailableModulesInExporterPaths() [resultCode - 300]);
}
}
StringArray getAvailableModulesInExporterPaths()
{
ModuleList list;
list.scanProjectExporterModulePaths (project);
return list.getIDs();
}
StringArray getAvailableModulesInGlobalJucePath()
{
ModuleList list;
list.addAllModulesInFolder ({ getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString() });
return list.getIDs();
}
StringArray getAvailableModules()
StringArray getAvailableModulesInGlobalUserPath()
{
ModuleList list;
list.scanAllKnownFolders (project);
auto paths = StringArray::fromTokens (getAppSettings().getStoredPath (Ids::defaultUserModulePath).toString(), ";", {});
for (auto p : paths)
{
auto f = File::createFileWithoutCheckingPath (p.trim());
if (f.exists())
list.addAllModulesInFolder (f);
}
return list.getIDs();
}


+ 153
- 4
extras/Projucer/Source/Project/jucer_DependencyPathPropertyComponent.cpp View File

@@ -26,8 +26,6 @@
#include "../jucer_Headers.h"
#include "jucer_DependencyPathPropertyComponent.h"
#include "../Application/jucer_GlobalPreferences.h"
//==============================================================================
DependencyPathValueSource::DependencyPathValueSource (const Value& projectSettingsPath,
@@ -36,10 +34,11 @@ DependencyPathValueSource::DependencyPathValueSource (const Value& projectSettin
: projectSettingsValue (projectSettingsPath),
globalKey (globalSettingsKey),
os (osThisSettingAppliesTo),
globalSettingsValue (getAppSettings().getGlobalPath (globalKey, os)),
fallbackValue (getAppSettings().getFallbackPath (globalKey, os))
globalSettingsValue (getAppSettings().getStoredPath (globalKey)),
fallbackValue (getAppSettings().getFallbackPathForOS (globalKey, os))
{
globalSettingsValue.addListener (this);
fallbackValue.addListener (this);
}
bool DependencyPathValueSource::isValidPath (const File& relativeTo) const
@@ -135,3 +134,153 @@ void DependencyPathPropertyComponent::lookAndFeelChanged()
{
textWasEdited();
}
//==============================================================================
DependencyFilePathPropertyComponent::DependencyFilePathPropertyComponent (Value& value,
const String& propertyDescription,
bool isDir,
const String& wc,
const File& rootToUseForRelativePaths)
try : TextPropertyComponent (propertyDescription, 1024, false),
pathRelativeTo (rootToUseForRelativePaths),
pathValue (value),
pathValueSource (dynamic_cast<DependencyPathValueSource&> (pathValue.getValueSource())),
browseButton ("..."),
isDirectory (isDir),
wildcards (wc)
{
auto initialValueIsEmpty = ! pathValueSource.isUsingProjectSettings();
getValue().referTo (pathValue);
if (initialValueIsEmpty)
getValue().setValue (String());
getValue().addListener (this);
if (auto* label = dynamic_cast<Label*> (getChildComponent (0)))
label->addListener (this);
else
jassertfalse;
setInterestedInFileDrag (false);
addAndMakeVisible (browseButton);
browseButton.addListener (this);
lookAndFeelChanged();
}
catch (const std::bad_cast&)
{
// a DependencyPathPropertyComponent must be initialised with a Value
// that is referring to a DependencyPathValueSource!
jassertfalse;
throw;
}
void DependencyFilePathPropertyComponent::resized()
{
auto bounds = getLookAndFeel().getPropertyComponentContentPosition (*this);
browseButton.setBounds (bounds.removeFromRight (30));
getChildComponent (0)->setBounds (bounds);
}
void DependencyFilePathPropertyComponent::paintOverChildren (Graphics& g)
{
if (highlightForDragAndDrop)
{
g.setColour (findColour (defaultHighlightColourId).withAlpha (0.5f));
g.fillRect (getChildComponent (0)->getBounds());
}
}
void DependencyFilePathPropertyComponent::filesDropped (const StringArray& files, int, int)
{
const File firstFile (files[0]);
if (isDirectory)
setTo (firstFile.isDirectory() ? firstFile
: firstFile.getParentDirectory());
else
setTo (firstFile);
highlightForDragAndDrop = false;
}
void DependencyFilePathPropertyComponent::setTo (const File& f)
{
pathValue = (pathRelativeTo == File()) ? f.getFullPathName()
: f.getRelativePathFrom (pathRelativeTo);
textWasEdited();
}
void DependencyFilePathPropertyComponent::enablementChanged()
{
getValue().referTo (isEnabled() ? pathValue
: pathValueSource.appliesToThisOS() ? pathValueSource.getGlobalSettingsValue()
: pathValueSource.getFallbackSettingsValue());
textWasEdited();
repaint();
}
void DependencyFilePathPropertyComponent::textWasEdited()
{
setColour (textColourId, getTextColourToDisplay());
TextPropertyComponent::textWasEdited();
}
void DependencyFilePathPropertyComponent::valueChanged (Value& value)
{
if ((value.refersToSameSourceAs (pathValue) && pathValueSource.isUsingGlobalSettings())
|| value.refersToSameSourceAs (pathValueSource.getGlobalSettingsValue()))
textWasEdited();
}
void DependencyFilePathPropertyComponent::editorShown (Label*, TextEditor& editor)
{
if (! pathValueSource.isUsingProjectSettings())
editor.setText (String(), dontSendNotification);
}
void DependencyFilePathPropertyComponent::buttonClicked (Button*)
{
auto currentFile = pathRelativeTo.getChildFile (pathValue.toString());
if (isDirectory)
{
FileChooser chooser ("Select directory", currentFile);
if (chooser.browseForDirectory())
setTo (chooser.getResult());
}
else
{
FileChooser chooser ("Select file", currentFile, wildcards);
if (chooser.browseForFileToOpen())
setTo (chooser.getResult());
}
}
Colour DependencyFilePathPropertyComponent::getTextColourToDisplay() const
{
auto alpha = 1.0f;
auto key = pathValueSource.getKey();
const auto& globalSettingsValue = pathValueSource.getGlobalSettingsValue();
if (! pathValueSource.isUsingProjectSettings() && isEnabled())
alpha = 0.5f;
if ((key == Ids::defaultUserModulePath && getValue().toString().contains (";")) || ! pathValueSource.appliesToThisOS())
return findColour (widgetTextColourId).withMultipliedAlpha (alpha);
auto usingGlobalPath = (getValue().refersToSameSourceAs (globalSettingsValue));
auto isValidPath = getAppSettings().isGlobalPathValid (pathRelativeTo, key,
(usingGlobalPath ? globalSettingsValue : pathValue).toString());
return isValidPath ? findColour (widgetTextColourId).withMultipliedAlpha (alpha)
: Colours::red.withMultipliedAlpha (alpha);
}

+ 68
- 4
extras/Projucer/Source/Project/jucer_DependencyPathPropertyComponent.h View File

@@ -52,7 +52,7 @@ public:
if (isUsingGlobalSettings())
return globalSettingsValue.getValue();
return fallbackValue;
return fallbackValue.getValue();
}
void setValue (const var& newValue) override
@@ -75,7 +75,7 @@ public:
bool isUsingFallbackValue() const
{
return ! projectSettingsValueIsValid() && !globalSettingsValueIsValid();
return ! projectSettingsValueIsValid() && ! globalSettingsValueIsValid();
}
bool appliesToThisOS() const
@@ -87,10 +87,16 @@ public:
bool isValidPath() const;
Identifier getKey() { return globalKey; }
Value getGlobalSettingsValue() { return globalSettingsValue; }
Value getFallbackSettingsValue() { return fallbackValue; }
private:
void valueChanged (Value& value) override
{
if ((value.refersToSameSourceAs (globalSettingsValue) && isUsingGlobalSettings()))
if ((value.refersToSameSourceAs (globalSettingsValue) && isUsingGlobalSettings())
|| (value.refersToSameSourceAs (fallbackValue) && isUsingFallbackValue()))
{
sendChangeMessage (true);
setValue (String()); // make sure that the project-specific value is still blank
@@ -136,7 +142,7 @@ private:
/** the dependency path fallback setting. used instead of the global setting
whenever the latter doesn't apply, e.g. the setting is for another
OS than the ome this machine is running. */
String fallbackValue;
Value fallbackValue;
};
@@ -181,3 +187,61 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DependencyPathPropertyComponent)
};
//==============================================================================
class DependencyFilePathPropertyComponent : public TextPropertyComponent,
public FileDragAndDropTarget,
private Value::Listener,
private Label::Listener,
private Button::Listener
{
public:
DependencyFilePathPropertyComponent (Value& value,
const String& propertyDescription,
bool isDirectory,
const String& wildcards = "*",
const File& rootToUseForRelativePaths = File());
void resized() override;
void paintOverChildren (Graphics& g) override;
bool isInterestedInFileDrag (const StringArray&) override { return isEnabled(); }
void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
void filesDropped (const StringArray&, int, int) override;
void setTo (const File& f);
void enablementChanged() override;
private:
void textWasEdited() override;
void valueChanged (Value&) override;
void labelTextChanged (Label*) override {}
void editorHidden (Label*, TextEditor&) override {}
void editorShown (Label*, TextEditor&) override;
void buttonClicked (Button*) override;
void lookAndFeelChanged() override
{
browseButton.setColour (TextButton::buttonColourId,
findColour (secondaryButtonBackgroundColourId));
textWasEdited();
}
Colour getTextColourToDisplay() const;
//==========================================================================
File pathRelativeTo;
Value pathValue;
DependencyPathValueSource& pathValueSource;
TextButton browseButton;
bool isDirectory, highlightForDragAndDrop = false;
String wildcards;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DependencyFilePathPropertyComponent)
};

+ 180
- 39
extras/Projucer/Source/Project/jucer_Module.cpp View File

@@ -209,15 +209,23 @@ Result ModuleList::addAllModulesInSubfoldersRecursively (const File& path, int d
return Result::ok();
}
static Array<File> getAllPossibleModulePaths (Project& project)
static Array<File> getAllPossibleModulePathsFromExporters (Project& project)
{
StringArray paths;
for (Project::ExporterIterator exporter (project); exporter.next();)
{
for (int i = 0; i < project.getModules().getNumModules(); ++i)
auto& modules = project.getModules();
auto n = modules.getNumModules();
for (int i = 0; i < n; ++i)
{
const String path (exporter->getPathForModuleString (project.getModules().getModuleID (i)));
auto id = modules.getModuleID (i);
if (modules.shouldUseGlobalPath (id).getValue())
continue;
const auto path = exporter->getPathForModuleString (id);
if (path.isNotEmpty())
paths.addIfNotAlreadyThere (path);
@@ -237,7 +245,7 @@ static Array<File> getAllPossibleModulePaths (Project& project)
if (f.isDirectory())
{
files.add (f);
files.addIfNotAlreadyThere (f);
if (f.getChildFile ("modules").isDirectory())
files.addIfNotAlreadyThere (f.getChildFile ("modules"));
@@ -247,12 +255,12 @@ static Array<File> getAllPossibleModulePaths (Project& project)
return files;
}
Result ModuleList::scanAllKnownFolders (Project& project)
Result ModuleList::scanProjectExporterModulePaths (Project& project)
{
modules.clear();
Result result (Result::ok());
for (auto& m : getAllPossibleModulePaths (project))
for (auto& m : getAllPossibleModulePathsFromExporters (project))
{
result = addAllModulesInFolder (m);
@@ -264,6 +272,36 @@ Result ModuleList::scanAllKnownFolders (Project& project)
return result;
}
void ModuleList::scanGlobalJuceModulePath()
{
modules.clear();
auto& settings = getAppSettings();
auto path = settings.getStoredPath (Ids::defaultJuceModulePath).toString();
if (path.isNotEmpty())
addAllModulesInFolder ({ path });
sort();
}
void ModuleList::scanGlobalUserModulePath()
{
modules.clear();
auto paths = StringArray::fromTokens (getAppSettings().getStoredPath (Ids::defaultUserModulePath).toString(), ";", {});
for (auto p : paths)
{
auto f = File::createFileWithoutCheckingPath (p.trim());
if (f.exists())
addAllModulesInFolder (f);
}
sort();
}
//==============================================================================
LibraryModule::LibraryModule (const ModuleDescription& d)
: moduleInfo (d)
@@ -342,14 +380,16 @@ void LibraryModule::addSettingsForModuleToExporter (ProjectExporter& exporter, P
{
Array<File> compiled;
auto& modules = project.getModules();
auto id = getID();
const File localModuleFolder = project.getModules().shouldCopyModuleFilesLocally (getID()).getValue()
? project.getLocalModuleFolder (getID())
const File localModuleFolder = modules.shouldCopyModuleFilesLocally (id).getValue()
? project.getLocalModuleFolder (id)
: moduleInfo.getFolder();
findAndAddCompiledUnits (exporter, &projectSaver, compiled);
if (project.getModules().shouldShowAllModuleFilesInProject (getID()).getValue())
if (modules.shouldShowAllModuleFilesInProject (id).getValue())
addBrowseableCode (exporter, compiled, localModuleFolder);
}
@@ -606,35 +646,33 @@ bool EnabledModuleList::isAudioPluginModuleMissing() const
&& ! isModuleEnabled ("juce_audio_plugin_client");
}
Value EnabledModuleList::shouldUseGlobalPath (const String& moduleID) const
{
return state.getChildWithProperty (Ids::ID, moduleID)
.getPropertyAsValue (Ids::useGlobalPath, getUndoManager());
}
Value EnabledModuleList::shouldShowAllModuleFilesInProject (const String& moduleID)
{
return state.getChildWithProperty (Ids::ID, moduleID)
.getPropertyAsValue (Ids::showAllCode, getUndoManager());
}
File EnabledModuleList::findLocalModuleFolder (const String& moduleID, bool useExportersForOtherOSes)
File EnabledModuleList::getModuleFolderFromPathIfItExists (const String& path, const String& moduleID, const Project& project)
{
for (Project::ExporterIterator exporter (project); exporter.next();)
if (path.isNotEmpty())
{
if (useExportersForOtherOSes || exporter->mayCompileOnCurrentOS())
{
auto path = exporter->getPathForModuleString (moduleID);
auto moduleFolder = project.resolveFilename (path);
if (path.isNotEmpty())
{
auto moduleFolder = project.resolveFilename (path);
if (moduleFolder.exists())
{
if (ModuleDescription (moduleFolder).isValid())
return moduleFolder;
if (moduleFolder.exists())
{
if (ModuleDescription (moduleFolder).isValid())
return moduleFolder;
auto f = moduleFolder.getChildFile (moduleID);
auto f = moduleFolder.getChildFile (moduleID);
if (ModuleDescription (f).isValid())
return f;
}
}
if (ModuleDescription (f).isValid())
return f;
}
}
@@ -643,12 +681,23 @@ File EnabledModuleList::findLocalModuleFolder (const String& moduleID, bool useE
File EnabledModuleList::getModuleFolder (const String& moduleID)
{
File f = findLocalModuleFolder (moduleID, false);
if (shouldUseGlobalPath (moduleID).getValue())
{
if (isJuceModule (moduleID))
return getModuleFolderFromPathIfItExists (getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString(), moduleID, project);
return findUserModuleFolder (moduleID, getAppSettings().getStoredPath (Ids::defaultUserModulePath).toString(), project);
}
if (f == File())
f = findLocalModuleFolder (moduleID, true);
auto paths = getAllPossibleModulePathsFromExporters (project);
for (auto p : paths)
{
auto f = getModuleFolderFromPathIfItExists (p.getFullPathName(), moduleID, project);
if (f != File())
return f;
}
return f;
return {};
}
struct ModuleTreeSorter
@@ -671,7 +720,7 @@ Value EnabledModuleList::shouldCopyModuleFilesLocally (const String& moduleID) c
.getPropertyAsValue (Ids::useLocalCopy, getUndoManager());
}
void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally)
void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally, bool useGlobalPath)
{
ModuleDescription info (moduleFolder);
@@ -689,6 +738,7 @@ void EnabledModuleList::addModule (const File& moduleFolder, bool copyLocally)
shouldShowAllModuleFilesInProject (moduleID) = true;
shouldCopyModuleFilesLocally (moduleID) = copyLocally;
shouldUseGlobalPath (moduleID) = useGlobalPath;
RelativePath path (moduleFolder.getParentDirectory(),
project.getProjectFolder(), RelativePath::projectFolder);
@@ -720,7 +770,7 @@ StringArray EnabledModuleList::getAllModules() const
StringArray moduleIDs;
for (int i = 0; i < getNumModules(); ++i)
moduleIDs.add (getModuleID(i));
moduleIDs.add (getModuleID (i));
return moduleIDs;
}
@@ -751,11 +801,26 @@ StringArray EnabledModuleList::getExtraDependenciesNeeded (const String& moduleI
return extraDepsNeeded;
}
bool EnabledModuleList::areMostModulesUsingGlobalPath() const
{
auto numYes = 0, numNo = 0;
for (auto i = getNumModules(); --i >= 0;)
{
if (shouldUseGlobalPath (getModuleID (i)).getValue())
++numYes;
else
++numNo;
}
return numYes > numNo;
}
bool EnabledModuleList::areMostModulesCopiedLocally() const
{
int numYes = 0, numNo = 0;
auto numYes = 0, numNo = 0;
for (int i = getNumModules(); --i >= 0;)
for (auto i = getNumModules(); --i >= 0;)
{
if (shouldCopyModuleFilesLocally (getModuleID (i)).getValue())
++numYes;
@@ -772,10 +837,26 @@ void EnabledModuleList::setLocalCopyModeForAllModules (bool copyLocally)
shouldCopyModuleFilesLocally (project.getModules().getModuleID (i)) = copyLocally;
}
File EnabledModuleList::findGlobalModulesFolder()
{
auto& settings = getAppSettings();
auto path = settings.getStoredPath (Ids::defaultJuceModulePath).toString();
if (settings.isGlobalPathValid (File(), Ids::defaultJuceModulePath, path))
return { path };
return {};
}
File EnabledModuleList::findDefaultModulesFolder (Project& project)
{
auto globalPath = findGlobalModulesFolder();
if (globalPath != File())
return globalPath;
ModuleList available;
available.scanAllKnownFolders (project);
available.scanProjectExporterModulePaths (project);
for (int i = available.modules.size(); --i >= 0;)
{
@@ -788,6 +869,52 @@ File EnabledModuleList::findDefaultModulesFolder (Project& project)
return File::getCurrentWorkingDirectory();
}
File EnabledModuleList::findUserModuleFolder (const String& moduleID, const String& possiblePaths, const Project& project)
{
auto paths = StringArray::fromTokens (possiblePaths, ";", {});
for (auto p : paths)
{
auto f = File::createFileWithoutCheckingPath (p.trim());
if (f.exists())
{
auto moduleFolder = getModuleFolderFromPathIfItExists (f.getFullPathName(), moduleID, project);
if (moduleFolder != File())
return moduleFolder;
}
}
return {};
}
bool EnabledModuleList::isJuceModule (const String& moduleID)
{
static StringArray juceModuleIds =
{
"juce_audio_basics",
"juce_audio_devices",
"juce_audio_formats",
"juce_audio_plugin_client",
"juce_audio_processors",
"juce_audio_utils",
"juce_blocks_basics",
"juce_box2d",
"juce_core",
"juce_cryptography",
"juce_data_structures",
"juce_events",
"juce_graphics",
"juce_gui_basics",
"juce_gui_extra",
"juce_opengl",
"juce_osc",
"juce_product_unlocking",
"juce_video"
};
return juceModuleIds.contains (moduleID);
}
void EnabledModuleList::addModuleFromUserSelectedFile()
{
static File lastLocation (findDefaultModulesFolder (project));
@@ -804,10 +931,24 @@ void EnabledModuleList::addModuleFromUserSelectedFile()
void EnabledModuleList::addModuleInteractive (const String& moduleID)
{
ModuleList list;
list.scanAllKnownFolders (project);
list.scanGlobalJuceModulePath();
if (auto* info = list.getModuleWithID (moduleID))
{
addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath());
return;
}
list.scanGlobalUserModulePath();
if (auto* info = list.getModuleWithID (moduleID))
{
addModule (info->moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath());
return;
}
list.scanProjectExporterModulePaths (project);
if (auto* info = list.getModuleWithID (moduleID))
addModule (info->moduleFolder, areMostModulesCopiedLocally());
addModule (info->moduleFolder, areMostModulesCopiedLocally(), false);
else
addModuleFromUserSelectedFile();
}
@@ -830,7 +971,7 @@ void EnabledModuleList::addModuleOfferingToCopy (const File& f)
return;
}
addModule (m.moduleFolder, areMostModulesCopiedLocally());
addModule (m.moduleFolder, areMostModulesCopiedLocally(), areMostModulesUsingGlobalPath());
}
bool isJuceFolder (const File& f)


+ 16
- 7
extras/Projucer/Source/Project/jucer_Module.h View File

@@ -31,7 +31,6 @@ class ProjectExporter;
class ProjectSaver;
//==============================================================================
File findDefaultModulesFolder (bool mustContainJuceCoreModule = true);
bool isJuceModulesFolder (const File&);
bool isJuceFolder (const File&);
@@ -79,7 +78,9 @@ struct ModuleList
Result addAllModulesInFolder (const File&);
Result addAllModulesInSubfoldersRecursively (const File&, int depth);
Result scanAllKnownFolders (Project&);
Result scanProjectExporterModulePaths (Project&);
void scanGlobalJuceModulePath();
void scanGlobalUserModulePath();
OwnedArray<ModuleDescription> modules;
};
@@ -135,17 +136,24 @@ class EnabledModuleList
public:
EnabledModuleList (Project&, const ValueTree&);
static File findGlobalModulesFolder();
static File findDefaultModulesFolder (Project&);
static File findUserModuleFolder (const String& moduleID, const String& possiblePaths, const Project&);
static bool isJuceModule (const String& moduleID);
bool isModuleEnabled (const String& moduleID) const;
Value shouldUseGlobalPath (const String& moduleID) const;
Value shouldShowAllModuleFilesInProject (const String& moduleID);
Value shouldCopyModuleFilesLocally (const String& moduleID) const;
void removeModule (String moduleID);
bool isAudioPluginModuleMissing() const;
ModuleDescription getModuleInfo (const String& moduleID);
File getModuleFolder (const String& moduleID);
void addModule (const File& moduleManifestFile, bool copyLocally);
void addModule (const File& moduleManifestFile, bool copyLocally, bool useGlobalPath);
void addModuleInteractive (const String& moduleID);
void addModuleFromUserSelectedFile();
void addModuleOfferingToCopy (const File&);
@@ -157,11 +165,12 @@ public:
int getNumModules() const { return state.getNumChildren(); }
String getModuleID (int index) const { return state.getChild (index) [Ids::ID].toString(); }
bool areMostModulesUsingGlobalPath() const;
bool areMostModulesCopiedLocally() const;
void setLocalCopyModeForAllModules (bool copyLocally);
void sortAlphabetically();
static File findDefaultModulesFolder (Project&);
void sortAlphabetically();
Project& project;
ValueTree state;
@@ -169,7 +178,7 @@ public:
private:
UndoManager* getUndoManager() const { return project.getUndoManagerFor (state); }
File findLocalModuleFolder (const String& moduleID, bool useExportersForOtherOSes);
static File getModuleFolderFromPathIfItExists (const String& path, const String& moduleID, const Project&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EnabledModuleList)
};

+ 44
- 8
extras/Projucer/Source/Project/jucer_ModulesPanel.h View File

@@ -35,7 +35,8 @@ public:
modulesValueTree (p.getModules().state),
header ("Modules", Icon (getIcons().modules, Colours::transparentBlack)),
setCopyModeButton ("Set copy-mode for all modules..."),
copyPathButton ("Set paths for all modules...")
copyPathButton ("Set paths for all modules..."),
globalPathsButton ("Enable/disable global path for all modules...")
{
listHeader = new ListBoxHeader ( { "Module", "Version", "Make Local Copy", "Paths" },
{ 0.25f, 0.2f, 0.2f, 0.35f } );
@@ -51,10 +52,12 @@ public:
addAndMakeVisible (setCopyModeButton);
addAndMakeVisible (copyPathButton);
addAndMakeVisible (globalPathsButton);
setCopyModeButton.addListener (this);
setCopyModeButton.setTriggeredOnMouseDown (true);
copyPathButton.addListener (this);
copyPathButton.setTriggeredOnMouseDown (true);
globalPathsButton.addListener (this);
modulesValueTree.addListener (this);
lookAndFeelChanged();
@@ -85,13 +88,15 @@ public:
setCopyModeButton.setBounds (buttonRow.removeFromLeft (jmin (200, bounds.getWidth() / 3)));
buttonRow.removeFromLeft (8);
copyPathButton.setBounds (buttonRow.removeFromLeft (jmin (200, bounds.getWidth() / 3)));
buttonRow.removeFromLeft (8);
globalPathsButton.setBounds (buttonRow.removeFromLeft (jmin (200, bounds.getWidth() / 3)));
}
}
void parentSizeChanged() override
{
const auto width = jmax (550, getParentWidth());
auto y = list.getRowPosition (getNumRows() - 1, true).getBottom() + 100;
auto y = list.getRowPosition (getNumRows() - 1, true).getBottom() + 200;
y = jmax (getParentHeight(), y);
@@ -135,12 +140,21 @@ public:
g.drawFittedText (copyLocally, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (2) * width)), Justification::centredLeft, 1);
//======================================================================
StringArray paths;
String pathText;
for (Project::ExporterIterator exporter (project); exporter.next();)
paths.addIfNotAlreadyThere (exporter->getPathForModuleString (moduleID).trim());
if (project.getModules().shouldUseGlobalPath (moduleID).getValue())
{
pathText = "Global";
}
else
{
StringArray paths;
const auto pathText = paths.joinIntoString (", ");
for (Project::ExporterIterator exporter (project); exporter.next();)
paths.addIfNotAlreadyThere (exporter->getPathForModuleString (moduleID).trim());
pathText = paths.joinIntoString (", ");
}
g.drawFittedText (pathText, bounds.removeFromLeft (roundToInt (listHeader->getProportionAtIndex (3) * width)), Justification::centredLeft, 1);
}
@@ -163,12 +177,14 @@ public:
{
if (b == &setCopyModeButton) showCopyModeMenu();
if (b == &copyPathButton) showSetPathsMenu();
if (b == &globalPathsButton) showGlobalPathsMenu();
}
void lookAndFeelChanged() override
{
setCopyModeButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
copyPathButton.setColour (TextButton::buttonColourId, findColour (defaultButtonBackgroundColourId));
globalPathsButton.setColour (TextButton::buttonColourId, findColour (defaultButtonBackgroundColourId));
}
private:
@@ -185,7 +201,7 @@ private:
ContentViewHeader header;
ListBox list;
ListBoxHeader* listHeader;
TextButton setCopyModeButton, copyPathButton;
TextButton setCopyModeButton, copyPathButton, globalPathsButton;
std::map<String, var> modulePathClipboard;
void valueTreePropertyChanged (ValueTree&, const Identifier&) override { itemChanged(); }
@@ -207,12 +223,32 @@ private:
m.addItem (1, "Set all modules to copy locally");
m.addItem (2, "Set all modules to not copy locally");
int res = m.showAt (&setCopyModeButton);
auto res = m.showAt (&setCopyModeButton);
if (res != 0)
project.getModules().setLocalCopyModeForAllModules (res == 1);
}
void showGlobalPathsMenu()
{
PopupMenu m;
m.addItem (1, "Set all modules to use global paths");
m.addItem (2, "Set all modules to not use global paths");
auto res = m.showAt (&globalPathsButton);
if (res != 0)
{
auto enableGlobalPaths = (res == 1);
auto& modules = project.getModules();
auto moduleIDs = modules.getAllModules();
for (auto id : moduleIDs)
modules.shouldUseGlobalPath (id).setValue (enableGlobalPaths);
}
}
void showSetPathsMenu()
{
enum


+ 26
- 13
extras/Projucer/Source/Project/jucer_Project.cpp View File

@@ -307,20 +307,28 @@ static bool isAnyModuleNewerThanProjucer (const OwnedArray<ModuleDescription>& m
void Project::warnAboutOldProjucerVersion()
{
ModuleList available;
available.scanAllKnownFolders (*this);
if (isAnyModuleNewerThanProjucer (available.modules))
{
if (ProjucerApplication::getApp().isRunningCommandLine)
std::cout << "WARNING! This version of the Projucer is out-of-date!" << std::endl;
else
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Projucer",
"This version of the Projucer is out-of-date!"
"\n\n"
"Always make sure that you're running the very latest version, "
"preferably compiled directly from the JUCE repository that you're working with!");
}
available.scanGlobalJuceModulePath();
if (! isAnyModuleNewerThanProjucer (available.modules))
available.scanGlobalUserModulePath();
if (! isAnyModuleNewerThanProjucer (available.modules))
available.scanProjectExporterModulePaths (*this);
if (! isAnyModuleNewerThanProjucer (available.modules))
return;
// Projucer is out of date!
if (ProjucerApplication::getApp().isRunningCommandLine)
std::cout << "WARNING! This version of the Projucer is out-of-date!" << std::endl;
else
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Projucer",
"This version of the Projucer is out-of-date!"
"\n\n"
"Always make sure that you're running the very latest version, "
"preferably compiled directly from the JUCE repository that you're working with!");
}
//==============================================================================
@@ -423,6 +431,11 @@ File Project::resolveFilename (String filename) const
filename = replacePreprocessorDefs (getPreprocessorDefs(), filename);
#if ! JUCE_WINDOWS
if (filename.startsWith ("~"))
return File::getSpecialLocation (File::userHomeDirectory).getChildFile (filename.trimCharactersAtStart ("~/"));
#endif
if (FileHelpers::isAbsolutePath (filename))
return File::createFileWithoutCheckingPath (FileHelpers::currentOSStylePath (filename)); // (avoid assertions for windows-style paths)


+ 1
- 0
extras/Projucer/Source/Project/jucer_TreeItemTypes.h View File

@@ -32,6 +32,7 @@
#include "../Wizards/jucer_NewFileWizard.h"
#include "jucer_GroupInformationComponent.h"
#include "jucer_ModulesPanel.h"
#include "jucer_DependencyPathPropertyComponent.h"
struct FileTreeItemTypes


+ 344
- 0
extras/Projucer/Source/Utility/jucer_EditorColourSchemeWindowComponent.h View File

@@ -0,0 +1,344 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../Utility/jucer_ColourPropertyComponent.h"
class EditorColourSchemeWindowComponent : public Component
{
public:
EditorColourSchemeWindowComponent()
{
if (getAppSettings().monospacedFontNames.size() == 0)
content = new AppearanceEditor::FontScanPanel();
else
content = new AppearanceEditor::EditorPanel();
changeContent (content);
}
void paint (Graphics& g) override
{
g.fillAll (findColour (backgroundColourId));
}
void resized() override
{
content->setBounds (getLocalBounds());
}
void changeContent (Component* newContent)
{
content = newContent;
addAndMakeVisible (content);
content->setBounds (getLocalBounds().reduced (10));
}
private:
ScopedPointer<Component> content;
//==============================================================================
struct AppearanceEditor
{
struct FontScanPanel : public Component,
private Timer
{
FontScanPanel()
{
fontsToScan = Font::findAllTypefaceNames();
startTimer (1);
}
void paint (Graphics& g) override
{
g.fillAll (findColour (backgroundColourId));
g.setFont (14.0f);
g.setColour (findColour (defaultTextColourId));
g.drawFittedText ("Scanning for fonts..", getLocalBounds(), Justification::centred, 2);
const auto size = 30;
getLookAndFeel().drawSpinningWaitAnimation (g, Colours::white, (getWidth() - size) / 2, getHeight() / 2 - 50, size, size);
}
void timerCallback() override
{
repaint();
if (fontsToScan.size() == 0)
{
getAppSettings().monospacedFontNames = fontsFound;
if (auto* owner = findParentComponentOfClass<EditorColourSchemeWindowComponent>())
owner->changeContent (new EditorPanel());
}
else
{
if (isMonospacedTypeface (fontsToScan[0]))
fontsFound.add (fontsToScan[0]);
fontsToScan.remove (0);
}
}
// A rather hacky trick to select only the fixed-pitch fonts..
// This is unfortunately a bit slow, but will work on all platforms.
static bool isMonospacedTypeface (const String& name)
{
const Font font (name, 20.0f, Font::plain);
const auto width = font.getStringWidth ("....");
return width == font.getStringWidth ("WWWW")
&& width == font.getStringWidth ("0000")
&& width == font.getStringWidth ("1111")
&& width == font.getStringWidth ("iiii");
}
StringArray fontsToScan, fontsFound;
};
//==============================================================================
struct EditorPanel : public Component,
private ButtonListener
{
EditorPanel()
: loadButton ("Load Scheme..."),
saveButton ("Save Scheme...")
{
rebuildProperties();
addAndMakeVisible (panel);
addAndMakeVisible (loadButton);
addAndMakeVisible (saveButton);
loadButton.addListener (this);
saveButton.addListener (this);
lookAndFeelChanged();
saveSchemeState();
}
~EditorPanel()
{
if (hasSchemeBeenModifiedSinceSave())
saveScheme (true);
}
void rebuildProperties()
{
auto& scheme = getAppSettings().appearance;
Array<PropertyComponent*> props;
auto fontValue = scheme.getCodeFontValue();
props.add (FontNameValueSource::createProperty ("Code Editor Font", fontValue));
props.add (FontSizeValueSource::createProperty ("Font Size", fontValue));
const auto colourNames = scheme.getColourNames();
for (int i = 0; i < colourNames.size(); ++i)
props.add (new ColourPropertyComponent (nullptr, colourNames[i],
scheme.getColourValue (colourNames[i]),
Colours::white, false));
panel.clear();
panel.addProperties (props);
}
void resized() override
{
auto r = getLocalBounds();
panel.setBounds (r.removeFromTop (getHeight() - 28).reduced (10, 2));
loadButton.setBounds (r.removeFromLeft (getWidth() / 2).reduced (10, 1));
saveButton.setBounds (r.reduced (10, 1));
}
private:
PropertyPanel panel;
TextButton loadButton, saveButton;
Font codeFont;
Array<var> colourValues;
void buttonClicked (Button* b) override
{
if (b == &loadButton)
loadScheme();
else
saveScheme (false);
}
void saveScheme (bool isExit)
{
FileChooser fc ("Select a file in which to save this colour-scheme...",
getAppSettings().appearance.getSchemesFolder()
.getNonexistentChildFile ("Scheme", AppearanceSettings::getSchemeFileSuffix()),
AppearanceSettings::getSchemeFileWildCard());
if (fc.browseForFileToSave (true))
{
File file (fc.getResult().withFileExtension (AppearanceSettings::getSchemeFileSuffix()));
getAppSettings().appearance.writeToFile (file);
getAppSettings().appearance.refreshPresetSchemeList();
saveSchemeState();
ProjucerApplication::getApp().selectEditorColourSchemeWithName (file.getFileNameWithoutExtension());
}
else if (isExit)
{
restorePreviousScheme();
}
}
void loadScheme()
{
FileChooser fc ("Please select a colour-scheme file to load...",
getAppSettings().appearance.getSchemesFolder(),
AppearanceSettings::getSchemeFileWildCard());
if (fc.browseForFileToOpen())
{
if (getAppSettings().appearance.readFromFile (fc.getResult()))
{
rebuildProperties();
saveSchemeState();
}
}
}
void lookAndFeelChanged() override
{
loadButton.setColour (TextButton::buttonColourId,
findColour (secondaryButtonBackgroundColourId));
}
void saveSchemeState()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
codeFont = appearance.getCodeFont();
colourValues.clear();
for (int i = 0; i < colourNames.size(); ++i)
colourValues.add (appearance.getColourValue (colourNames[i]).getValue());
}
bool hasSchemeBeenModifiedSinceSave()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
if (codeFont != appearance.getCodeFont())
return true;
for (int i = 0; i < colourNames.size(); ++i)
if (colourValues[i] != appearance.getColourValue (colourNames[i]).getValue())
return true;
return false;
}
void restorePreviousScheme()
{
auto& appearance = getAppSettings().appearance;
const auto colourNames = appearance.getColourNames();
appearance.getCodeFontValue().setValue (codeFont.toString());
for (int i = 0; i < colourNames.size(); ++i)
appearance.getColourValue (colourNames[i]).setValue (colourValues[i]);
}
JUCE_DECLARE_NON_COPYABLE (EditorPanel)
};
//==============================================================================
struct FontNameValueSource : public ValueSourceFilter
{
FontNameValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return Font::fromString (sourceValue.toString()).getTypefaceName();
}
void setValue (const var& newValue) override
{
auto font = Font::fromString (sourceValue.toString());
font.setTypefaceName (newValue.toString().isEmpty() ? Font::getDefaultMonospacedFontName()
: newValue.toString());
sourceValue = font.toString();
}
static ChoicePropertyComponent* createProperty (const String& title, const Value& value)
{
auto fontNames = getAppSettings().monospacedFontNames;
Array<var> values;
values.add (Font::getDefaultMonospacedFontName());
values.add (var());
for (int i = 0; i < fontNames.size(); ++i)
values.add (fontNames[i]);
StringArray names;
names.add ("<Default Monospaced>");
names.add (String());
names.addArray (getAppSettings().monospacedFontNames);
return new ChoicePropertyComponent (Value (new FontNameValueSource (value)),
title, names, values);
}
};
//==============================================================================
struct FontSizeValueSource : public ValueSourceFilter
{
FontSizeValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return Font::fromString (sourceValue.toString()).getHeight();
}
void setValue (const var& newValue) override
{
sourceValue = Font::fromString (sourceValue.toString()).withHeight (newValue).toString();
}
static PropertyComponent* createProperty (const String& title, const Value& value)
{
return new SliderPropertyComponent (Value (new FontSizeValueSource (value)),
title, 5.0, 40.0, 0.1, 0.5);
}
};
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorColourSchemeWindowComponent)
};

+ 75
- 11
extras/Projucer/Source/Utility/jucer_FilePathPropertyComponent.h View File

@@ -40,9 +40,10 @@ public:
const String& propertyDescription,
bool isDirectory,
const String& wildcards = "*",
const File& rootToUseForRelativePaths = File())
const File& rootToUseForRelativePaths = File(),
const bool supportsMultiplePaths = false)
: PropertyComponent (propertyDescription),
innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths)
innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths, supportsMultiplePaths)
{
addAndMakeVisible (innerComp);
}
@@ -52,18 +53,21 @@ public:
private:
struct InnerComponent : public Component,
public FileDragAndDropTarget,
private Button::Listener
private Button::Listener,
private TextEditor::Listener
{
InnerComponent (Value v, bool isDir, const String& wc, const File& rt)
InnerComponent (Value v, bool isDir, const String& wc, const File& rt, const bool multiplePaths)
: value (v),
isDirectory (isDir),
highlightForDragAndDrop (false),
wildcards (wc),
root (rt),
button ("...")
button ("..."),
supportsMultiplePaths (multiplePaths)
{
addAndMakeVisible (textbox);
textbox.getTextValue().referTo (value);
textbox.addListener (this);
addAndMakeVisible (button);
button.addListener (this);
@@ -75,8 +79,8 @@ private:
{
if (highlightForDragAndDrop)
{
g.setColour (Colours::green.withAlpha (0.1f));
g.fillRect (getLocalBounds());
g.setColour (findColour (defaultHighlightColourId).withAlpha (0.5f));
g.fillRect (textbox.getBounds());
}
}
@@ -101,6 +105,9 @@ private:
: firstFile.getParentDirectory());
else
setTo (firstFile);
highlightForDragAndDrop = false;
repaint();
}
void buttonClicked (Button*) override
@@ -123,18 +130,74 @@ private:
}
}
void textEditorReturnKeyPressed (TextEditor& editor) override { updateEditorColour (editor); }
void textEditorFocusLost (TextEditor& editor) override { updateEditorColour (editor); }
void updateEditorColour (TextEditor& editor)
{
if (supportsMultiplePaths)
{
auto paths = StringArray::fromTokens (editor.getTextValue().toString(), ";", {});
editor.clear();
AttributedString str;
for (auto p : paths)
{
if (root.getChildFile (p.trim()).exists()) editor.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
else editor.setColour (TextEditor::textColourId, Colours::red);
editor.insertTextAtCaret (p);
if (paths.indexOf (p) < paths.size() - 1)
{
editor.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
editor.insertTextAtCaret (";");
}
}
editor.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
}
else
{
auto pathToCheck = editor.getTextValue().toString();
//android SDK/NDK paths
if (pathToCheck.contains ("${user.home}"))
pathToCheck = pathToCheck.replace ("${user.home}", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
#if JUCE_WINDOWS
if (pathToCheck.startsWith ("~"))
pathToCheck = pathToCheck.replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
#endif
const auto currentFile = root.getChildFile (pathToCheck);
if (currentFile.exists())
editor.applyColourToAllText (findColour (widgetTextColourId));
else
editor.applyColourToAllText (Colours::red);
}
}
void setTo (const File& f)
{
value = (root == File()) ? f.getFullPathName()
: f.getRelativePathFrom (root);
auto pathName = (root == File()) ? f.getFullPathName()
: f.getRelativePathFrom (root);
if (supportsMultiplePaths && value.toString().isNotEmpty())
value = value.toString().trimCharactersAtEnd (" ;") + "; " + pathName;
else
value = pathName;
updateEditorColour (textbox);
}
void lookAndFeelChanged() override
{
textbox.setColour (TextEditor::backgroundColourId, findColour (widgetBackgroundColourId));
textbox.setColour (TextEditor::outlineColourId, Colours::transparentBlack);
textbox.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
textbox.applyFontToAllText (textbox.getFont());
updateEditorColour (textbox);
button.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
button.setColour (TextButton::textColourOffId, Colours::white);
@@ -146,6 +209,7 @@ private:
File root;
TextEditor textbox;
TextButton button;
bool supportsMultiplePaths;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent)
};


+ 200
- 0
extras/Projucer/Source/Utility/jucer_GlobalSearchPathsWindowComponent.h View File

@@ -0,0 +1,200 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
class GlobalSearchPathsWindowComponent : public Component,
private ComboBox::Listener
{
public:
GlobalSearchPathsWindowComponent()
: modulesLabel ("modulesLabel", "Modules"),
sdksLabel ("sdksLabel", "SDKs")
{
addAndMakeVisible (modulesLabel);
addAndMakeVisible (sdksLabel);
modulesLabel.setFont (Font (18.0f, Font::FontStyleFlags::bold));
sdksLabel.setFont (Font (18.0f, Font::FontStyleFlags::bold));
modulesLabel.setJustificationType (Justification::centredLeft);
sdksLabel.setJustificationType (Justification::centredLeft);
addAndMakeVisible (info);
info.setInfoToDisplay ("Use this dropdown to set the global paths for different OSes. "
"\nN.B. These paths are stored locally and will only be used when "
"saving a project on this machine. Other machines will have their own "
"locally stored paths.");
addAndMakeVisible (osSelector);
osSelector.addItem ("OSX", 1);
osSelector.addItem ("Windows", 2);
osSelector.addItem ("Linux", 3);
osSelector.addListener (this);
auto os = TargetOS::getThisOS();
if (os == TargetOS::osx) osSelector.setSelectedId (1);
else if (os == TargetOS::windows) osSelector.setSelectedId (2);
else if (os == TargetOS::linux) osSelector.setSelectedId (3);
updateFilePathPropertyComponents();
}
void paint (Graphics& g) override
{
g.fillAll (findColour (backgroundColourId));
}
void resized() override
{
auto b = getLocalBounds().reduced (10);
auto topSlice = b.removeFromTop (25);
osSelector.setSize (200, 25);
osSelector.setCentrePosition (topSlice.getCentre());
info.setBounds (osSelector.getBounds().withWidth (osSelector.getHeight()).translated ((osSelector.getWidth() + 5), 0).reduced (2));
modulesLabel.setBounds (b.removeFromTop (20));
b.removeFromTop (20);
auto i = 0;
for (auto propertyComponent : pathPropertyComponents)
{
propertyComponent->setBounds (b.removeFromTop (propertyComponent->getPreferredHeight()));
b.removeFromTop (5);
if (i == 1)
{
b.removeFromTop (15);
sdksLabel.setBounds (b.removeFromTop (20));
b.removeFromTop (20);
}
++i;
}
}
private:
Label modulesLabel, sdksLabel;
OwnedArray<PropertyComponent> pathPropertyComponents;
ComboBox osSelector;
ConfigTreeItemTypes::InfoButton info;
void comboBoxChanged (ComboBox*) override
{
updateFilePathPropertyComponents();
}
void updateFilePathPropertyComponents()
{
pathPropertyComponents.clear();
auto thisOS = TargetOS::getThisOS();
auto selectedOS = TargetOS::unknown;
switch (osSelector.getSelectedId())
{
case 1: selectedOS = TargetOS::osx; break;
case 2: selectedOS = TargetOS::windows; break;
case 3: selectedOS = TargetOS::linux; break;
default: break;
}
auto& settings = getAppSettings();
if (selectedOS == thisOS)
{
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::defaultJuceModulePath),
"JUCE Modules", true)));
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::defaultUserModulePath),
"User Modules", true, {}, {}, true)));
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::vst3Path),
"VST3 SDK", true)));
if (selectedOS == TargetOS::linux)
{
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (Value(), "RTAS SDK", true)));
pathPropertyComponents.getLast()->setEnabled (false);
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (Value(), "AAX SDK", true)));
pathPropertyComponents.getLast()->setEnabled (false);
}
else
{
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::rtasPath),
"RTAS SDK", true)));
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::aaxPath),
"AAX SDK", true)));
}
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::androidSDKPath),
"Android SDK", true)));
addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::androidNDKPath),
"Android NDK", true)));
}
else
{
auto maxChars = 1024;
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::defaultJuceModulePath, selectedOS),
"JUCE Modules", maxChars, false)));
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::defaultUserModulePath, selectedOS),
"User Modules", maxChars, false)));
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::vst3Path, selectedOS),
"VST3 SDK", maxChars, false)));
if (selectedOS == TargetOS::linux)
{
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (Value(), "RTAS SDK", maxChars, false)));
pathPropertyComponents.getLast()->setEnabled (false);
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (Value(), "AAX SDK", maxChars, false)));
pathPropertyComponents.getLast()->setEnabled (false);
}
else
{
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::rtasPath, selectedOS),
"RTAS SDK", maxChars, false)));
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::aaxPath, selectedOS),
"AAX SDK", maxChars, false)));
}
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::androidSDKPath, selectedOS),
"Android SDK", maxChars, false)));
addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::androidNDKPath, selectedOS),
"Android NDK", maxChars, false)));
}
resized();
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlobalSearchPathsWindowComponent)
};

+ 6
- 0
extras/Projucer/Source/Utility/jucer_PresetIDs.h View File

@@ -59,6 +59,11 @@ namespace Ids
DECLARE_ID (intermediatesPath);
DECLARE_ID (modulePaths);
DECLARE_ID (searchpaths);
DECLARE_ID (osxFallback);
DECLARE_ID (windowsFallback);
DECLARE_ID (linuxFallback);
DECLARE_ID (defaultJuceModulePath);
DECLARE_ID (defaultUserModulePath);
DECLARE_ID (vst3Folder);
DECLARE_ID (rtasFolder);
DECLARE_ID (auFolder);
@@ -152,6 +157,7 @@ namespace Ids
DECLARE_ID (focusOrder);
DECLARE_ID (hidden);
DECLARE_ID (useStdCall);
DECLARE_ID (useGlobalPath);
DECLARE_ID (showAllCode);
DECLARE_ID (useLocalCopy);
DECLARE_ID (overwriteOnSave);


+ 70
- 41
extras/Projucer/Source/Utility/jucer_StoredSettings.cpp View File

@@ -27,7 +27,6 @@
#include "../jucer_Headers.h"
#include "jucer_StoredSettings.h"
#include "../Application/jucer_Application.h"
#include "../Application/jucer_GlobalPreferences.h"
//==============================================================================
StoredSettings& getAppSettings()
@@ -42,16 +41,20 @@ PropertiesFile& getGlobalProperties()
//==============================================================================
StoredSettings::StoredSettings()
: appearance (true), projectDefaults ("PROJECT_DEFAULT_SETTINGS")
: appearance (true),
projectDefaults ("PROJECT_DEFAULT_SETTINGS"),
fallbackPaths ("FALLBACK_PATHS")
{
updateOldProjectSettingsFiles();
reload();
projectDefaults.addListener (this);
fallbackPaths.addListener (this);
}
StoredSettings::~StoredSettings()
{
projectDefaults.removeListener (this);
fallbackPaths.removeListener (this);
flush();
}
@@ -122,10 +125,13 @@ void StoredSettings::reload()
propertyFiles.add (createPropsFile ("Projucer", false));
ScopedPointer<XmlElement> projectDefaultsXml (propertyFiles.getFirst()->getXmlValue ("PROJECT_DEFAULT_SETTINGS"));
if (projectDefaultsXml != nullptr)
projectDefaults = ValueTree::fromXml (*projectDefaultsXml);
ScopedPointer<XmlElement> fallbackPathsXml (propertyFiles.getFirst()->getXmlValue ("FALLBACK_PATHS"));
if (fallbackPathsXml != nullptr)
fallbackPaths = ValueTree::fromXml (*fallbackPathsXml);
// recent files...
recentFiles.restoreFromString (getGlobalProperties().getValue ("recentFiles"));
recentFiles.removeNonExistentFiles();
@@ -228,61 +234,76 @@ void StoredSettings::ColourSelectorWithSwatches::setSwatchColour (int index, con
}
//==============================================================================
static bool doesSDKPathContainFile (const File& relativeTo, const String& path, const String& fileToCheckFor)
{
auto actualPath = path.replace ("${user.home}", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
return relativeTo.getChildFile (actualPath + "/" + fileToCheckFor).existsAsFile();
}
Value StoredSettings::getGlobalPath (const Identifier& key, DependencyPathOS os)
Value StoredSettings::getStoredPath (const Identifier& key)
{
auto v = projectDefaults.getPropertyAsValue (key, nullptr);
if (v.toString().isEmpty())
{
auto defaultPath = getFallbackPath (key, os);
if (os == TargetOS::getThisOS())
v = defaultPath;
}
v = getFallbackPathForOS (key, TargetOS::getThisOS()).toString();
return v;
}
String StoredSettings::getFallbackPath (const Identifier& key, DependencyPathOS os)
Value StoredSettings::getFallbackPathForOS (const Identifier& key, DependencyPathOS os)
{
if (key == Ids::vst3Path)
return os == TargetOS::windows ? "c:\\SDKs\\VST_SDK\\VST3_SDK"
: "~/SDKs/VST_SDK/VST3_SDK";
auto id = Identifier();
if (key == Ids::rtasPath)
{
if (os == TargetOS::windows) return "c:\\SDKs\\PT_90_SDK";
if (os == TargetOS::osx) return "~/SDKs/PT_90_SDK";
if (os == TargetOS::osx) id = Ids::osxFallback;
else if (os == TargetOS::windows) id = Ids::windowsFallback;
else if (os == TargetOS::linux) id = Ids::linuxFallback;
// no RTAS on this OS!
if (id == Identifier())
jassertfalse;
return {};
}
if (key == Ids::aaxPath)
{
if (os == TargetOS::windows) return "c:\\SDKs\\AAX";
if (os == TargetOS::osx) return "~/SDKs/AAX" ;
auto v = fallbackPaths.getOrCreateChildWithName (id, nullptr)
.getPropertyAsValue (key, nullptr);
// no AAX on this OS!
jassertfalse;
return {};
if (v.toString().isEmpty())
{
if (key == Ids::defaultJuceModulePath)
{
v = (os == TargetOS::windows ? "C:\\JUCE\\modules"
: "~/JUCE/modules");
}
else if (key == Ids::defaultUserModulePath)
{
v = (os == TargetOS::windows ? "C:\\modules"
: "~/modules");
}
else if (key == Ids::vst3Path)
{
v = (os == TargetOS::windows ? "C:\\SDKs\\VST_SDK\\VST3_SDK"
: "~/SDKs/VST_SDK/VST3_SDK");
}
else if (key == Ids::rtasPath)
{
if (os == TargetOS::windows) v = "C:\\SDKs\\PT_90_SDK";
else if (os == TargetOS::osx) v = "~/SDKs/PT_90_SDK";
else jassertfalse; // no RTAS on this OS!
}
else if (key == Ids::aaxPath)
{
if (os == TargetOS::windows) v = "C:\\SDKs\\AAX";
else if (os == TargetOS::osx) v = "~/SDKs/AAX" ;
else jassertfalse; // no AAX on this OS!
}
else if (key == Ids::androidSDKPath)
{
v = "${user.home}/Library/Android/sdk";
}
else if (key == Ids::androidNDKPath)
{
v = "${user.home}/Library/Android/sdk/ndk-bundle";
}
}
if (key == Ids::androidSDKPath)
return "${user.home}/Library/Android/sdk";
if (key == Ids::androidNDKPath)
return "${user.home}/Library/Android/sdk/ndk-bundle";
return v;
}
// didn't recognise the key provided!
jassertfalse;
return {};
static bool doesSDKPathContainFile (const File& relativeTo, const String& path, const String& fileToCheckFor)
{
auto actualPath = path.replace ("${user.home}", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
return relativeTo.getChildFile (actualPath + "/" + fileToCheckFor).exists();
}
bool StoredSettings::isGlobalPathValid (const File& relativeTo, const Identifier& key, const String& path)
@@ -317,6 +338,14 @@ bool StoredSettings::isGlobalPathValid (const File& relativeTo, const Identifier
fileToCheckFor = "ndk-depends";
#endif
}
else if (key == Ids::defaultJuceModulePath)
{
fileToCheckFor = "juce_core";
}
else if (key == Ids::defaultUserModulePath)
{
fileToCheckFor = {};
}
else
{
// didn't recognise the key provided!


+ 15
- 11
extras/Projucer/Source/Utility/jucer_StoredSettings.h View File

@@ -62,23 +62,27 @@ public:
//==============================================================================
AppearanceSettings appearance;
StringArray monospacedFontNames;
//==============================================================================
Value getGlobalPath (const Identifier& key, DependencyPathOS);
String getFallbackPath (const Identifier& key, DependencyPathOS);
Value getStoredPath (const Identifier& key);
Value getFallbackPathForOS (const Identifier& key, DependencyPathOS);
bool isGlobalPathValid (const File& relativeTo, const Identifier& key, const String& path);
private:
OwnedArray<PropertiesFile> propertyFiles;
ValueTree projectDefaults;
ValueTree fallbackPaths;
void changed()
void changed (bool isProjectDefaults)
{
ScopedPointer<XmlElement> data (projectDefaults.createXml());
propertyFiles.getUnchecked (0)->setValue ("PROJECT_DEFAULT_SETTINGS", data);
ScopedPointer<XmlElement> data (isProjectDefaults ? projectDefaults.createXml()
: fallbackPaths.createXml());
propertyFiles.getUnchecked (0)->setValue (isProjectDefaults ? "PROJECT_DEFAULT_SETTINGS"
: "FALLBACK_PATHS",
data);
}
void updateGlobalPreferences();
@@ -91,11 +95,11 @@ private:
void updateOldProjectSettingsFiles();
//==============================================================================
void valueTreePropertyChanged (ValueTree&, const Identifier&) override { changed(); }
void valueTreeChildAdded (ValueTree&, ValueTree&) override { changed(); }
void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override { changed(); }
void valueTreeChildOrderChanged (ValueTree&, int, int) override { changed(); }
void valueTreeParentChanged (ValueTree&) override { changed(); }
void valueTreePropertyChanged (ValueTree& vt, const Identifier&) override { changed (vt == projectDefaults); }
void valueTreeChildAdded (ValueTree& vt, ValueTree&) override { changed (vt == projectDefaults); }
void valueTreeChildRemoved (ValueTree& vt, ValueTree&, int) override { changed (vt == projectDefaults); }
void valueTreeChildOrderChanged (ValueTree& vt, int, int) override { changed (vt == projectDefaults); }
void valueTreeParentChanged (ValueTree& vt) override { changed (vt == projectDefaults); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StoredSettings)
};


+ 5
- 4
extras/Projucer/Source/Wizards/jucer_NewProjectWizard.h View File

@@ -103,7 +103,8 @@ struct NewProjectWizard
//==============================================================================
Project* runWizard (WizardComp& wc,
const String& projectName,
const File& target)
const File& target,
bool useGlobalPath)
{
ownerWizardComp = &wc;
appTitle = projectName;
@@ -140,7 +141,7 @@ struct NewProjectWizard
return nullptr;
addExporters (*project, wc);
addDefaultModules (*project, false);
addDefaultModules (*project, useGlobalPath);
if (project->save (false, true) != FileBasedDocument::savedOk)
return nullptr;
@@ -173,7 +174,7 @@ struct NewProjectWizard
failedFiles.add (getSourceFilesFolder().getFullPathName());
}
void addDefaultModules (Project& project, bool areModulesCopiedLocally)
void addDefaultModules (Project& project, bool useGlobalPath)
{
StringArray mods (getDefaultModules());
@@ -182,7 +183,7 @@ struct NewProjectWizard
for (int i = 0; i < mods.size(); ++i)
if (const ModuleDescription* info = list.getModuleWithID (mods[i]))
project.getModules().addModule (info->moduleFolder, areModulesCopiedLocally);
project.getModules().addModule (info->moduleFolder, false, useGlobalPath);
}
void addExporters (Project& project, WizardComp& wizardComp)


+ 50
- 13
extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h View File

@@ -35,10 +35,11 @@ public:
ModulesFolderPathBox (File initialFileOrDirectory)
: currentPathBox ("currentPathBox"),
openFolderButton (TRANS("...")),
modulesLabel (String(), TRANS("Modules Folder") + ":")
modulesLabel (String(), TRANS("Modules Folder") + ":"),
useGlobalPathsToggle ("Use global module path")
{
if (initialFileOrDirectory == File())
initialFileOrDirectory = findDefaultModulesFolder();
initialFileOrDirectory = EnabledModuleList::findGlobalModulesFolder();
setModulesFolder (initialFileOrDirectory);
@@ -52,15 +53,24 @@ public:
addAndMakeVisible (modulesLabel);
modulesLabel.attachToComponent (&currentPathBox, true);
addAndMakeVisible (useGlobalPathsToggle);
useGlobalPathsToggle.addListener (this);
useGlobalPathsToggle.setToggleState (true, sendNotification);
}
void resized() override
{
auto r = getLocalBounds();
auto b = getLocalBounds();
auto topSlice = b.removeFromTop (b.getHeight() / 2);
openFolderButton.setBounds (topSlice.removeFromRight (30));
modulesLabel.setBounds (topSlice.removeFromLeft (110));
currentPathBox.setBounds (topSlice);
openFolderButton.setBounds (r.removeFromRight (30));
modulesLabel.setBounds (r.removeFromLeft (110));
currentPathBox.setBounds (r);
b.removeFromTop (5);
useGlobalPathsToggle.setBounds (b.translated (20, 0));
}
static bool selectJuceFolder (File& result)
@@ -68,7 +78,7 @@ public:
for (;;)
{
FileChooser fc ("Select your JUCE modules folder...",
findDefaultModulesFolder(),
EnabledModuleList::findGlobalModulesFolder(),
"*");
if (! fc.browseForDirectory())
@@ -104,9 +114,21 @@ public:
}
}
void buttonClicked (Button*) override
void buttonClicked (Button* b) override
{
selectJuceFolder();
if (b == &openFolderButton)
{
selectJuceFolder();
}
else if (b == &useGlobalPathsToggle)
{
isUsingGlobalPaths = useGlobalPathsToggle.getToggleState();
currentPathBox.setEnabled (! isUsingGlobalPaths);
openFolderButton.setEnabled (! isUsingGlobalPaths);
modulesLabel.setEnabled (! isUsingGlobalPaths);
}
}
void comboBoxChanged (ComboBox*) override
@@ -115,11 +137,13 @@ public:
}
File modulesFolder;
bool isUsingGlobalPaths;
private:
ComboBox currentPathBox;
TextButton openFolderButton;
Label modulesLabel;
ToggleButton useGlobalPathsToggle;
};
@@ -280,7 +304,7 @@ public:
WizardComp()
: platformTargets(),
projectName (TRANS("Project name")),
modulesPathBox (findDefaultModulesFolder())
modulesPathBox (EnabledModuleList::findGlobalModulesFolder())
{
setOpaque (false);
@@ -355,7 +379,7 @@ public:
filesToCreate.setBounds (right.removeFromTop (22).withTrimmedLeft (150));
right.removeFromTop (20);
modulesPathBox.setBounds (right.removeFromTop (22));
modulesPathBox.setBounds (right.removeFromTop (50));
right.removeFromTop (20);
targetsOutline.setBounds (right);
@@ -404,14 +428,27 @@ public:
return;
}
wizard->modulesFolder = modulesPathBox.modulesFolder;
wizard->modulesFolder = modulesPathBox.isUsingGlobalPaths ? File (getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString())
: modulesPathBox.modulesFolder;
if (! isJuceModulesFolder (wizard->modulesFolder))
{
if (modulesPathBox.isUsingGlobalPaths)
AlertWindow::showMessageBox (AlertWindow::AlertIconType::WarningIcon, "Invalid Global Path",
"Your global JUCE module search path is invalid. Please select the folder containing your JUCE modules "
"to set as the default path.");
if (! wizard->selectJuceFolder())
return;
if (modulesPathBox.isUsingGlobalPaths)
getAppSettings().getStoredPath (Ids::defaultJuceModulePath).setValue (wizard->modulesFolder.getFullPathName());
}
if (ScopedPointer<Project> project = wizard->runWizard (*this, projectName.getText(),
fileBrowser.getSelectedFile (0)))
fileBrowser.getSelectedFile (0),
modulesPathBox.isUsingGlobalPaths))
mw->setProject (project.release());
}
}


Loading…
Cancel
Save