From 188299adb92920acc8856d508c8e00f492b9c01f Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Mon, 15 Mar 2010 14:37:59 +0000 Subject: [PATCH] First check-in of the new Jucer codebase. --- .../Builds/Linux/Makefile | 224 ++++ .../Builds/MacOSX/Info.plist | 23 + .../The Jucer.xcodeproj/project.pbxproj | 356 ++++++ .../Builds/VisualStudio2005/The Jucer.sln | 20 + .../Builds/VisualStudio2005/The Jucer.vcproj | 336 ++++++ .../Builds/VisualStudio2008/The Jucer.sln | 20 + .../Builds/VisualStudio2008/The Jucer.vcproj | 336 ++++++ .../JuceLibraryCode/AppConfig.h | 37 + .../JuceLibraryCode/BinaryData.cpp | 936 +++++++++++++++ .../JuceLibraryCode/BinaryData.h | 49 + .../JuceLibraryCode/JuceHeader.h | 27 + .../JuceLibraryCode/JuceLibraryCode1.cpp | 15 + .../JuceLibraryCode/JuceLibraryCode1.mm | 15 + .../JuceLibraryCode/JuceLibraryCode2.cpp | 15 + .../JuceLibraryCode/JuceLibraryCode2.mm | 15 + .../JuceLibraryCode/JuceLibraryCode3.cpp | 15 + .../JuceLibraryCode/JuceLibraryCode3.mm | 15 + .../JuceLibraryCode/JuceLibraryCode4.cpp | 15 + .../JuceLibraryCode/JuceLibraryCode4.mm | 15 + extras/Jucer (experimental)/Jucer.jucer | 187 +++ .../Source/jucer_Headers.h | 59 + .../Source/jucer_Main.cpp | 113 ++ .../Source/model/jucer_ComponentDocument.cpp | 65 ++ .../Source/model/jucer_ComponentDocument.h | 56 + .../Source/model/jucer_DrawableDocument.cpp | 253 +++++ .../Source/model/jucer_DrawableDocument.h | 83 ++ .../Source/model/jucer_NewFileWizard.cpp | 233 ++++ .../Source/model/jucer_NewFileWizard.h | 62 + .../Source/model/jucer_Project.cpp | 931 +++++++++++++++ .../Source/model/jucer_Project.h | 306 +++++ .../Source/model/jucer_ProjectExport_MSVC.h | 592 ++++++++++ .../Source/model/jucer_ProjectExport_Make.h | 319 ++++++ .../Source/model/jucer_ProjectExport_XCode.h | 1010 +++++++++++++++++ .../Source/model/jucer_ProjectExporter.cpp | 164 +++ .../Source/model/jucer_ProjectExporter.h | 102 ++ .../Source/model/jucer_ProjectSaver.h | 539 +++++++++ .../Source/model/jucer_ProjectWizard.cpp | 495 ++++++++ .../Source/model/jucer_ProjectWizard.h | 68 ++ .../Source/model/jucer_ResourceFile.cpp | 303 +++++ .../Source/model/jucer_ResourceFile.h | 66 ++ .../templates/AudioPluginXCodeScript.txt | 44 + .../Source/templates/juce_icon.png | Bin 0 -> 19826 bytes .../jucer_AudioPluginEditorTemplate.cpp | 35 + .../jucer_AudioPluginEditorTemplate.h | 32 + .../jucer_AudioPluginFilterTemplate.cpp | 173 +++ .../jucer_AudioPluginFilterTemplate.h | 71 ++ .../jucer_MainConsoleAppTemplate.cpp | 27 + .../Source/templates/jucer_MainTemplate.cpp | 77 ++ .../templates/jucer_NewCppFileTemplate.cpp | 10 + .../templates/jucer_NewCppFileTemplate.h | 18 + .../Source/templates/jucer_WindowTemplate.cpp | 31 + .../Source/templates/jucer_WindowTemplate.h | 44 + .../Drawable Editor/jucer_DrawableEditor.cpp | 222 ++++ .../ui/Drawable Editor/jucer_DrawableEditor.h | 97 ++ .../jucer_DrawableObjectComponent.h | 321 ++++++ .../jucer_DrawableTreeviewItem.h | 246 ++++ .../Source/ui/jucer_CommandIDs.h | 88 ++ .../ui/jucer_DocumentEditorComponent.cpp | 129 +++ .../Source/ui/jucer_DocumentEditorComponent.h | 60 + .../ui/jucer_GroupInformationComponent.cpp | 160 +++ .../ui/jucer_GroupInformationComponent.h | 68 ++ .../Source/ui/jucer_ItemPreviewComponent.cpp | 93 ++ .../Source/ui/jucer_ItemPreviewComponent.h | 57 + .../Source/ui/jucer_JucerTreeViewBase.cpp | 104 ++ .../Source/ui/jucer_JucerTreeViewBase.h | 72 ++ .../Source/ui/jucer_MainWindow.cpp | 486 ++++++++ .../Source/ui/jucer_MainWindow.h | 90 ++ .../Source/ui/jucer_OpenDocumentManager.cpp | 384 +++++++ .../Source/ui/jucer_OpenDocumentManager.h | 96 ++ .../ui/jucer_ProjectContentComponent.cpp | 319 ++++++ .../Source/ui/jucer_ProjectContentComponent.h | 83 ++ .../ui/jucer_ProjectInformationComponent.cpp | 439 +++++++ .../ui/jucer_ProjectInformationComponent.h | 86 ++ .../Source/ui/jucer_ProjectTreeViewBase.cpp | 490 ++++++++ .../Source/ui/jucer_ProjectTreeViewBase.h | 118 ++ .../Source/ui/jucer_SourceCodeEditor.cpp | 66 ++ .../Source/ui/jucer_SourceCodeEditor.h | 59 + .../Source/ui/jucer_TreeViewTypes.cpp | 219 ++++ .../Source/ui/jucer_TreeViewTypes.h | 70 ++ .../utility/jucer_ColourEditorComponent.h | 184 +++ .../Source/utility/jucer_Colours.h | 162 +++ .../Source/utility/jucer_RelativePath.h | 126 ++ .../Source/utility/jucer_StoredSettings.cpp | 105 ++ .../Source/utility/jucer_StoredSettings.h | 64 ++ .../Source/utility/jucer_UtilityFunctions.cpp | 526 +++++++++ .../Source/utility/jucer_UtilityFunctions.h | 110 ++ .../utility/jucer_ValueRemapperSource.h | 107 ++ 87 files changed, 15158 insertions(+) create mode 100644 extras/Jucer (experimental)/Builds/Linux/Makefile create mode 100644 extras/Jucer (experimental)/Builds/MacOSX/Info.plist create mode 100644 extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj create mode 100644 extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.sln create mode 100644 extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj create mode 100644 extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.sln create mode 100644 extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/AppConfig.h create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceHeader.h create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.cpp create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.mm create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.cpp create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.mm create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.cpp create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.mm create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.cpp create mode 100644 extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.mm create mode 100644 extras/Jucer (experimental)/Jucer.jucer create mode 100644 extras/Jucer (experimental)/Source/jucer_Headers.h create mode 100644 extras/Jucer (experimental)/Source/jucer_Main.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_Project.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_Project.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectExport_XCode.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectSaver.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.h create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ResourceFile.cpp create mode 100644 extras/Jucer (experimental)/Source/model/jucer_ResourceFile.h create mode 100644 extras/Jucer (experimental)/Source/templates/AudioPluginXCodeScript.txt create mode 100644 extras/Jucer (experimental)/Source/templates/juce_icon.png create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.h create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.h create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_MainConsoleAppTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_MainTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.h create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.cpp create mode 100644 extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.h create mode 100644 extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h create mode 100644 extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableObjectComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableTreeviewItem.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_CommandIDs.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_MainWindow.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_MainWindow.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.h create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.cpp create mode 100644 extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_Colours.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h create mode 100644 extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h diff --git a/extras/Jucer (experimental)/Builds/Linux/Makefile b/extras/Jucer (experimental)/Builds/Linux/Makefile new file mode 100644 index 0000000000..583912c39b --- /dev/null +++ b/extras/Jucer (experimental)/Builds/Linux/Makefile @@ -0,0 +1,224 @@ +# Automatically generated makefile, created by the Jucer +# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project! + +ifndef CONFIG + CONFIG=Debug +endif + +ifeq ($(TARGET_ARCH),) + TARGET_ARCH := -march=native +endif + +# (this disables dependency generation if multiple architectures are set) +DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD) + +ifeq ($(CONFIG),Debug) + BINDIR := build + LIBDIR := build + OBJDIR := build/intermediate/Debug + OUTDIR := build + CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 + CXXFLAGS += $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound + LDDEPS := + RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2" + TARGET := Jucer + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),Release) + BINDIR := build + LIBDIR := build + OBJDIR := build/intermediate/Release + OUTDIR := build + CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 + CXXFLAGS += $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound + LDDEPS := + RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2" + TARGET := Jucer + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/jucer_ComponentDocument.o \ + $(OBJDIR)/jucer_DrawableDocument.o \ + $(OBJDIR)/jucer_NewFileWizard.o \ + $(OBJDIR)/jucer_Project.o \ + $(OBJDIR)/jucer_ProjectExporter.o \ + $(OBJDIR)/jucer_ProjectWizard.o \ + $(OBJDIR)/jucer_ResourceFile.o \ + $(OBJDIR)/jucer_DrawableEditor.o \ + $(OBJDIR)/jucer_DocumentEditorComponent.o \ + $(OBJDIR)/jucer_GroupInformationComponent.o \ + $(OBJDIR)/jucer_ItemPreviewComponent.o \ + $(OBJDIR)/jucer_JucerTreeViewBase.o \ + $(OBJDIR)/jucer_MainWindow.o \ + $(OBJDIR)/jucer_OpenDocumentManager.o \ + $(OBJDIR)/jucer_ProjectContentComponent.o \ + $(OBJDIR)/jucer_ProjectInformationComponent.o \ + $(OBJDIR)/jucer_ProjectTreeViewBase.o \ + $(OBJDIR)/jucer_SourceCodeEditor.o \ + $(OBJDIR)/jucer_TreeViewTypes.o \ + $(OBJDIR)/jucer_StoredSettings.o \ + $(OBJDIR)/jucer_UtilityFunctions.o \ + $(OBJDIR)/jucer_Main.o \ + $(OBJDIR)/BinaryData.o \ + $(OBJDIR)/JuceLibraryCode1.o \ + $(OBJDIR)/JuceLibraryCode2.o \ + $(OBJDIR)/JuceLibraryCode3.o \ + $(OBJDIR)/JuceLibraryCode4.o \ + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking The Jucer + -@mkdir -p $(BINDIR) + -@mkdir -p $(LIBDIR) + -@mkdir -p $(OUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning The Jucer + -@rm -f $(OUTDIR)/$(TARGET) + -@rm -rf $(OBJDIR)/* + -@rm -rf $(OBJDIR) + +$(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/jucer_ComponentDocument.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/jucer_DrawableDocument.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_NewFileWizard.o: ../../Source/model/jucer_NewFileWizard.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_Project.o: ../../Source/model/jucer_Project.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ProjectExporter.o: ../../Source/model/jucer_ProjectExporter.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ProjectWizard.o: ../../Source/model/jucer_ProjectWizard.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ResourceFile.o: ../../Source/model/jucer_ResourceFile.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_DrawableEditor.o: ../../Source/ui/Drawable\ Editor/jucer_DrawableEditor.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_DocumentEditorComponent.o: ../../Source/ui/jucer_DocumentEditorComponent.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_GroupInformationComponent.o: ../../Source/ui/jucer_GroupInformationComponent.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ItemPreviewComponent.o: ../../Source/ui/jucer_ItemPreviewComponent.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_JucerTreeViewBase.o: ../../Source/ui/jucer_JucerTreeViewBase.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_MainWindow.o: ../../Source/ui/jucer_MainWindow.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_OpenDocumentManager.o: ../../Source/ui/jucer_OpenDocumentManager.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ProjectContentComponent.o: ../../Source/ui/jucer_ProjectContentComponent.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ProjectInformationComponent.o: ../../Source/ui/jucer_ProjectInformationComponent.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_ProjectTreeViewBase.o: ../../Source/ui/jucer_ProjectTreeViewBase.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_SourceCodeEditor.o: ../../Source/ui/jucer_SourceCodeEditor.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_TreeViewTypes.o: ../../Source/ui/jucer_TreeViewTypes.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_UtilityFunctions.o: ../../Source/utility/jucer_UtilityFunctions.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +$(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp + -@mkdir -p $(OBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" + +-include $(OBJECTS:%.o=%.d) diff --git a/extras/Jucer (experimental)/Builds/MacOSX/Info.plist b/extras/Jucer (experimental)/Builds/MacOSX/Info.plist new file mode 100644 index 0000000000..7fc21c774e --- /dev/null +++ b/extras/Jucer (experimental)/Builds/MacOSX/Info.plist @@ -0,0 +1,23 @@ + + + + + + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.rawmaterialsoftware.thejucer + CFBundleName + The Jucer + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleShortVersionString + 3.0.0 + CFBundleVersion + 3.0.0 + + diff --git a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..cb011e257d --- /dev/null +++ b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj @@ -0,0 +1,356 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 44; + objects = { + + 7BDFF9F0E16DF33A980F46DC = { isa = PBXBuildFile; fileRef = 046FA2877C08618339161EE2; }; + B703C44375C75E5AB099E74A = { isa = PBXBuildFile; fileRef = 43A5218D223AA21E0A55D986; }; + 022036CBB0FBE47C417A6222 = { isa = PBXBuildFile; fileRef = 151135F18422E2B1368D7BC2; }; + 52A4EFC1F732A9D5BBB61AF5 = { isa = PBXBuildFile; fileRef = B36C44190E6AEEBFA3DB3046; }; + C65112B26E0BB0BB8DBD3F3C = { isa = PBXBuildFile; fileRef = FB3773F08466794F949B0AFF; }; + E63745F5956C698352A2ACA0 = { isa = PBXBuildFile; fileRef = 74125C6A6DE28C538A518C3C; }; + 2C3270317859BA6DF8EC1458 = { isa = PBXBuildFile; fileRef = A5A4B15B9F5C3D32C82DFDC6; }; + AA7B50F22523465B07D4A25B = { isa = PBXBuildFile; fileRef = 6E1144678BD61868D73EF1FB; }; + DBE3CE9482B19CF1AE700805 = { isa = PBXBuildFile; fileRef = 23CF69B4C644D1E6E61E5C82; }; + 93C9F3F27602A33DDC9C2250 = { isa = PBXBuildFile; fileRef = 2767E1D082874D301D5D5F43; }; + 2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; }; + CD4226951C3F7FE19CF8A7CE = { isa = PBXBuildFile; fileRef = 2D6D6985B452EA0B67A18914; }; + 1174D3512AF8207950094C56 = { isa = PBXBuildFile; fileRef = FF625CB50FB5C3536BA40604; }; + 087CCE9E7146F1EC4F241254 = { isa = PBXBuildFile; fileRef = DA142548FCADFAC50648ED3C; }; + E9935BFB0EFA8CCCD41DC08E = { isa = PBXBuildFile; fileRef = D47A40CB3CF6AAE14B3C7796; }; + 60CDC1358E84801B6526E434 = { isa = PBXBuildFile; fileRef = FE9A53032395E717F54AE85B; }; + EEC6FC8E546C88C825411DB2 = { isa = PBXBuildFile; fileRef = 0AD266A3E698D40DCD88A432; }; + B2B821DE12F1679A3ADA597A = { isa = PBXBuildFile; fileRef = DBE9A3BB502125C5D3433AE7; }; + E43D00B370F289420379B759 = { isa = PBXBuildFile; fileRef = 82F91CF84A296665177CB79A; }; + 944CE0EADAD951F48EC77071 = { isa = PBXBuildFile; fileRef = 3B2C45064E85B3B631D4F921; }; + 4E8860E0F8680956A6F5B493 = { isa = PBXBuildFile; fileRef = 8F731296532276CBF2B6190D; }; + 288F5E7A2EC305BB4D8D73D1 = { isa = PBXBuildFile; fileRef = 1E7EDE73A92751752BC90A62; }; + 2417927E323BFE201D5985B9 = { isa = PBXBuildFile; fileRef = 3C60CAE9481EE0113C15A0B9; }; + A1CB18029E09A66E192D9A29 = { isa = PBXBuildFile; fileRef = 17F5B1F00F15DB37EA4A4AEA; }; + F8C762CCE16669F76D2209B9 = { isa = PBXBuildFile; fileRef = 118A505BA7079B3C8C9B858B; }; + 4FF75A3C7DCB9FD245320FE6 = { isa = PBXBuildFile; fileRef = 487D3D6777F8C3E26C0D5887; }; + A70AED2E35B809981470A547 = { isa = PBXBuildFile; fileRef = 9170F22B59096F151A9FFFB3; }; + 4D6C7380B8BB0BA9470C146C = { isa = PBXBuildFile; fileRef = AEE4E1F518A91ABB386CFD9E; }; + 438FED16CFDB36A4BE1F5F35 = { isa = PBXBuildFile; fileRef = E55B34E6694D69E3DBB107D1; }; + 33A4BAAD7A79BA63E78CB503 = { isa = PBXBuildFile; fileRef = B4439D672F2977238755E1E2; }; + DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; + FA8C72364CDFD2B76F16C0F1 = { isa = PBXBuildFile; fileRef = E3BD76BDB547509885E14DEE; }; + 6B6B0EBBE899B0ACDCAD92F5 = { isa = PBXBuildFile; fileRef = 0DC331A7B856F30AD266A3E6; }; + 69CA42E334E4BA09E4FE8B65 = { isa = PBXBuildFile; fileRef = D02830A908A07FD46F7387DA; }; + 0C3A85F58C34FA91D16664EB = { isa = PBXBuildFile; fileRef = 933DADF4F3906510EA714CC0; }; + 08C0959668FFC1A90B4BA8E6 = { isa = PBXBuildFile; fileRef = DD6476FF0F8BE833CD54C01F; }; + 1457A52734BA97A13610ECF1 = { isa = PBXBuildFile; fileRef = 268B4FFB1C675B679138545F; }; + 20EDB5C810855EB960F520FC = { isa = PBXBuildFile; fileRef = 60A217F62952DE8A752BD79F; }; + 046FA2877C08618339161EE2 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 43A5218D223AA21E0A55D986 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; + 151135F18422E2B1368D7BC2 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + B36C44190E6AEEBFA3DB3046 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; + FB3773F08466794F949B0AFF = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; }; + 74125C6A6DE28C538A518C3C = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + A5A4B15B9F5C3D32C82DFDC6 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = System/Library/Frameworks/DiscRecording.framework; sourceTree = SDKROOT; }; + 6E1144678BD61868D73EF1FB = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 23CF69B4C644D1E6E61E5C82 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 2767E1D082874D301D5D5F43 = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = System/Library/Frameworks/QTKit.framework; sourceTree = SDKROOT; }; + D9FB1A5365FEEB854A0FF7BF = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; }; + 12E1601866B3489844AFD645 = { isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jucer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F4C5CF1AA7EB9298043D89D3 = { isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = SOURCE_ROOT; }; + 2D6D6985B452EA0B67A18914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ComponentDocument.cpp; path = ../../Source/model/jucer_ComponentDocument.cpp; sourceTree = SOURCE_ROOT; }; + E6CC3A04349F6B227FDAB26F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentDocument.h; path = ../../Source/model/jucer_ComponentDocument.h; sourceTree = SOURCE_ROOT; }; + FF625CB50FB5C3536BA40604 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; }; + A490098DA6400B3881F336D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableDocument.h; path = ../../Source/model/jucer_DrawableDocument.h; sourceTree = SOURCE_ROOT; }; + DA142548FCADFAC50648ED3C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewFileWizard.cpp; path = ../../Source/model/jucer_NewFileWizard.cpp; sourceTree = SOURCE_ROOT; }; + 765A993B1D7A4750FE92FE21 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_NewFileWizard.h; path = ../../Source/model/jucer_NewFileWizard.h; sourceTree = SOURCE_ROOT; }; + D47A40CB3CF6AAE14B3C7796 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Project.cpp; path = ../../Source/model/jucer_Project.cpp; sourceTree = SOURCE_ROOT; }; + FD44D5AD3D019B52485F4EB1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Project.h; path = ../../Source/model/jucer_Project.h; sourceTree = SOURCE_ROOT; }; + FE9A53032395E717F54AE85B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectExporter.cpp; path = ../../Source/model/jucer_ProjectExporter.cpp; sourceTree = SOURCE_ROOT; }; + C3C2FC6810F53559CAD7B08C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExporter.h; path = ../../Source/model/jucer_ProjectExporter.h; sourceTree = SOURCE_ROOT; }; + 21B09F5FD350D587F99A48E3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Make.h; path = ../../Source/model/jucer_ProjectExport_Make.h; sourceTree = SOURCE_ROOT; }; + 67FD7B3C04807976D280F1BA = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_MSVC.h; path = ../../Source/model/jucer_ProjectExport_MSVC.h; sourceTree = SOURCE_ROOT; }; + FFF343958E0C9BC1E14003CE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_XCode.h; path = ../../Source/model/jucer_ProjectExport_XCode.h; sourceTree = SOURCE_ROOT; }; + F1C676E178DEA8B86849CD64 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectSaver.h; path = ../../Source/model/jucer_ProjectSaver.h; sourceTree = SOURCE_ROOT; }; + 0AD266A3E698D40DCD88A432 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectWizard.cpp; path = ../../Source/model/jucer_ProjectWizard.cpp; sourceTree = SOURCE_ROOT; }; + 91C67387B525014760F514C2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectWizard.h; path = ../../Source/model/jucer_ProjectWizard.h; sourceTree = SOURCE_ROOT; }; + DBE9A3BB502125C5D3433AE7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ResourceFile.cpp; path = ../../Source/model/jucer_ResourceFile.cpp; sourceTree = SOURCE_ROOT; }; + 2DEE6D9FE17874DAB301648C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ResourceFile.h; path = ../../Source/model/jucer_ResourceFile.h; sourceTree = SOURCE_ROOT; }; + 82F91CF84A296665177CB79A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableEditor.cpp; path = "../../Source/ui/Drawable Editor/jucer_DrawableEditor.cpp"; sourceTree = SOURCE_ROOT; }; + D1776C5F3E6BB7E8C698BAD6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableEditor.h; path = "../../Source/ui/Drawable Editor/jucer_DrawableEditor.h"; sourceTree = SOURCE_ROOT; }; + F9EAFD5BC3E676BC59B326E0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableObjectComponent.h; path = "../../Source/ui/Drawable Editor/jucer_DrawableObjectComponent.h"; sourceTree = SOURCE_ROOT; }; + 654C1B62A2BE1FBB28BEAE72 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableTreeviewItem.h; path = "../../Source/ui/Drawable Editor/jucer_DrawableTreeviewItem.h"; sourceTree = SOURCE_ROOT; }; + E6BB0D9B515B50E418D98B9C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CommandIDs.h; path = ../../Source/ui/jucer_CommandIDs.h; sourceTree = SOURCE_ROOT; }; + 3B2C45064E85B3B631D4F921 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DocumentEditorComponent.cpp; path = ../../Source/ui/jucer_DocumentEditorComponent.cpp; sourceTree = SOURCE_ROOT; }; + 156F72179BBFCD0D9804C266 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DocumentEditorComponent.h; path = ../../Source/ui/jucer_DocumentEditorComponent.h; sourceTree = SOURCE_ROOT; }; + 8F731296532276CBF2B6190D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_GroupInformationComponent.cpp; path = ../../Source/ui/jucer_GroupInformationComponent.cpp; sourceTree = SOURCE_ROOT; }; + C1DB44D4E31AF6FAD8746EA6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_GroupInformationComponent.h; path = ../../Source/ui/jucer_GroupInformationComponent.h; sourceTree = SOURCE_ROOT; }; + 1E7EDE73A92751752BC90A62 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ItemPreviewComponent.cpp; path = ../../Source/ui/jucer_ItemPreviewComponent.cpp; sourceTree = SOURCE_ROOT; }; + 637290E424EEED413A6A6D83 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ItemPreviewComponent.h; path = ../../Source/ui/jucer_ItemPreviewComponent.h; sourceTree = SOURCE_ROOT; }; + 3C60CAE9481EE0113C15A0B9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_JucerTreeViewBase.cpp; path = ../../Source/ui/jucer_JucerTreeViewBase.cpp; sourceTree = SOURCE_ROOT; }; + BF0218D8FC9831826CD2F670 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_JucerTreeViewBase.h; path = ../../Source/ui/jucer_JucerTreeViewBase.h; sourceTree = SOURCE_ROOT; }; + 17F5B1F00F15DB37EA4A4AEA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MainWindow.cpp; path = ../../Source/ui/jucer_MainWindow.cpp; sourceTree = SOURCE_ROOT; }; + 65C0C87A85D4371BDE1C4347 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MainWindow.h; path = ../../Source/ui/jucer_MainWindow.h; sourceTree = SOURCE_ROOT; }; + 118A505BA7079B3C8C9B858B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_OpenDocumentManager.cpp; path = ../../Source/ui/jucer_OpenDocumentManager.cpp; sourceTree = SOURCE_ROOT; }; + 5377D74DB551C2B83F73FAE0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_OpenDocumentManager.h; path = ../../Source/ui/jucer_OpenDocumentManager.h; sourceTree = SOURCE_ROOT; }; + 487D3D6777F8C3E26C0D5887 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectContentComponent.cpp; path = ../../Source/ui/jucer_ProjectContentComponent.cpp; sourceTree = SOURCE_ROOT; }; + 442910162B36728054AACDFC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectContentComponent.h; path = ../../Source/ui/jucer_ProjectContentComponent.h; sourceTree = SOURCE_ROOT; }; + 9170F22B59096F151A9FFFB3 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectInformationComponent.cpp; path = ../../Source/ui/jucer_ProjectInformationComponent.cpp; sourceTree = SOURCE_ROOT; }; + 097BD8BB61EE09C908A8C99D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectInformationComponent.h; path = ../../Source/ui/jucer_ProjectInformationComponent.h; sourceTree = SOURCE_ROOT; }; + AEE4E1F518A91ABB386CFD9E = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectTreeViewBase.cpp; path = ../../Source/ui/jucer_ProjectTreeViewBase.cpp; sourceTree = SOURCE_ROOT; }; + F400D65DAD8A93736A7960CC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectTreeViewBase.h; path = ../../Source/ui/jucer_ProjectTreeViewBase.h; sourceTree = SOURCE_ROOT; }; + E55B34E6694D69E3DBB107D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_SourceCodeEditor.cpp; path = ../../Source/ui/jucer_SourceCodeEditor.cpp; sourceTree = SOURCE_ROOT; }; + 8A3A8D57685177B2F0D52C17 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_SourceCodeEditor.h; path = ../../Source/ui/jucer_SourceCodeEditor.h; sourceTree = SOURCE_ROOT; }; + B4439D672F2977238755E1E2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_TreeViewTypes.cpp; path = ../../Source/ui/jucer_TreeViewTypes.cpp; sourceTree = SOURCE_ROOT; }; + 4BF0300CA427D2D308542534 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TreeViewTypes.h; path = ../../Source/ui/jucer_TreeViewTypes.h; sourceTree = SOURCE_ROOT; }; + AAF3C58696944A256CA61730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourEditorComponent.h; path = ../../Source/utility/jucer_ColourEditorComponent.h; sourceTree = SOURCE_ROOT; }; + 9736236B5C4D6A16FC7E03AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Colours.h; path = ../../Source/utility/jucer_Colours.h; sourceTree = SOURCE_ROOT; }; + F99858EE1CD3B23057B8BEBD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_RelativePath.h; path = ../../Source/utility/jucer_RelativePath.h; sourceTree = SOURCE_ROOT; }; + 7A1CD936BD306A6E0BEFB046 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_StoredSettings.cpp; path = ../../Source/utility/jucer_StoredSettings.cpp; sourceTree = SOURCE_ROOT; }; + E99413C9561A66310DAD5EEB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_StoredSettings.h; path = ../../Source/utility/jucer_StoredSettings.h; sourceTree = SOURCE_ROOT; }; + E3BD76BDB547509885E14DEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_UtilityFunctions.cpp; path = ../../Source/utility/jucer_UtilityFunctions.cpp; sourceTree = SOURCE_ROOT; }; + 5FCA7C152179881180F14173 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_UtilityFunctions.h; path = ../../Source/utility/jucer_UtilityFunctions.h; sourceTree = SOURCE_ROOT; }; + B8469A2CDD0FBEA6BE01B1D5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ValueRemapperSource.h; path = ../../Source/utility/jucer_ValueRemapperSource.h; sourceTree = SOURCE_ROOT; }; + 0CA0CCCEBFA0AC8C577FC915 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Headers.h; path = ../../Source/jucer_Headers.h; sourceTree = SOURCE_ROOT; }; + 0DC331A7B856F30AD266A3E6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Main.cpp; path = ../../Source/jucer_Main.cpp; sourceTree = SOURCE_ROOT; }; + 1366A411A69F2020EE651CDB = { isa = PBXFileReference; lastKnownFileType = text.txt; name = AudioPluginXCodeScript.txt; path = ../../Source/templates/AudioPluginXCodeScript.txt; sourceTree = SOURCE_ROOT; }; + 607EB083892A70C2A770A1B6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_AudioPluginEditorTemplate.cpp; path = ../../Source/templates/jucer_AudioPluginEditorTemplate.cpp; sourceTree = SOURCE_ROOT; }; + 1C52B91B15DF56E0A37F3EEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_AudioPluginEditorTemplate.h; path = ../../Source/templates/jucer_AudioPluginEditorTemplate.h; sourceTree = SOURCE_ROOT; }; + 4D62A4E094921086FBB82248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_AudioPluginFilterTemplate.cpp; path = ../../Source/templates/jucer_AudioPluginFilterTemplate.cpp; sourceTree = SOURCE_ROOT; }; + C2AE936214AC10DC4FABAC2F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_AudioPluginFilterTemplate.h; path = ../../Source/templates/jucer_AudioPluginFilterTemplate.h; sourceTree = SOURCE_ROOT; }; + 061B86C84B0D279F1EABBBE2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MainConsoleAppTemplate.cpp; path = ../../Source/templates/jucer_MainConsoleAppTemplate.cpp; sourceTree = SOURCE_ROOT; }; + 1EC5B7483B37A4163CA19549 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MainTemplate.cpp; path = ../../Source/templates/jucer_MainTemplate.cpp; sourceTree = SOURCE_ROOT; }; + 4A80C6415DB1C1CB47DBE23F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewCppFileTemplate.cpp; path = ../../Source/templates/jucer_NewCppFileTemplate.cpp; sourceTree = SOURCE_ROOT; }; + 9F82562788D22155BA6027F2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_NewCppFileTemplate.h; path = ../../Source/templates/jucer_NewCppFileTemplate.h; sourceTree = SOURCE_ROOT; }; + CC9BA48C736AC8B5EF19E3B7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_WindowTemplate.cpp; path = ../../Source/templates/jucer_WindowTemplate.cpp; sourceTree = SOURCE_ROOT; }; + A85C2ED9EA2896E23CFC0C1D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_WindowTemplate.h; path = ../../Source/templates/jucer_WindowTemplate.h; sourceTree = SOURCE_ROOT; }; + E3CAAE006B081997B4A96B78 = { isa = PBXFileReference; lastKnownFileType = image.png; name = juce_icon.png; path = ../../Source/templates/juce_icon.png; sourceTree = SOURCE_ROOT; }; + C86084A495B96EA215958914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppConfig.h; path = ../../JuceLibraryCode/AppConfig.h; sourceTree = SOURCE_ROOT; }; + 8FEC5B519774920289A1FD73 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = SOURCE_ROOT; }; + D02830A908A07FD46F7387DA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = BinaryData.cpp; path = ../../JuceLibraryCode/BinaryData.cpp; sourceTree = SOURCE_ROOT; }; + A6A79D303B85B7C9D673ECD5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BinaryData.h; path = ../../JuceLibraryCode/BinaryData.h; sourceTree = SOURCE_ROOT; }; + 933DADF4F3906510EA714CC0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode1.mm; path = ../../JuceLibraryCode/JuceLibraryCode1.mm; sourceTree = SOURCE_ROOT; }; + DD6476FF0F8BE833CD54C01F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode2.mm; path = ../../JuceLibraryCode/JuceLibraryCode2.mm; sourceTree = SOURCE_ROOT; }; + 268B4FFB1C675B679138545F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode3.mm; path = ../../JuceLibraryCode/JuceLibraryCode3.mm; sourceTree = SOURCE_ROOT; }; + 60A217F62952DE8A752BD79F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode4.mm; path = ../../JuceLibraryCode/JuceLibraryCode4.mm; sourceTree = SOURCE_ROOT; }; + BF6238C9155879B9A9C47213 = { isa = PBXGroup; children = ( + 2D6D6985B452EA0B67A18914, + E6CC3A04349F6B227FDAB26F, + FF625CB50FB5C3536BA40604, + A490098DA6400B3881F336D0, + DA142548FCADFAC50648ED3C, + 765A993B1D7A4750FE92FE21, + D47A40CB3CF6AAE14B3C7796, + FD44D5AD3D019B52485F4EB1, + FE9A53032395E717F54AE85B, + C3C2FC6810F53559CAD7B08C, + 21B09F5FD350D587F99A48E3, + 67FD7B3C04807976D280F1BA, + FFF343958E0C9BC1E14003CE, + F1C676E178DEA8B86849CD64, + 0AD266A3E698D40DCD88A432, + 91C67387B525014760F514C2, + DBE9A3BB502125C5D3433AE7, + 2DEE6D9FE17874DAB301648C ); name = Model; sourceTree = ""; }; + 3A0BE83502CB509D623C2C07 = { isa = PBXGroup; children = ( ); name = "Component Editor"; sourceTree = ""; }; + E6053BD673F80E900DDA3593 = { isa = PBXGroup; children = ( + 82F91CF84A296665177CB79A, + D1776C5F3E6BB7E8C698BAD6, + F9EAFD5BC3E676BC59B326E0, + 654C1B62A2BE1FBB28BEAE72 ); name = "Drawable Editor"; sourceTree = ""; }; + 63A4428C116D97D7C5C05DC8 = { isa = PBXGroup; children = ( + 3A0BE83502CB509D623C2C07, + E6053BD673F80E900DDA3593, + E6BB0D9B515B50E418D98B9C, + 3B2C45064E85B3B631D4F921, + 156F72179BBFCD0D9804C266, + 8F731296532276CBF2B6190D, + C1DB44D4E31AF6FAD8746EA6, + 1E7EDE73A92751752BC90A62, + 637290E424EEED413A6A6D83, + 3C60CAE9481EE0113C15A0B9, + BF0218D8FC9831826CD2F670, + 17F5B1F00F15DB37EA4A4AEA, + 65C0C87A85D4371BDE1C4347, + 118A505BA7079B3C8C9B858B, + 5377D74DB551C2B83F73FAE0, + 487D3D6777F8C3E26C0D5887, + 442910162B36728054AACDFC, + 9170F22B59096F151A9FFFB3, + 097BD8BB61EE09C908A8C99D, + AEE4E1F518A91ABB386CFD9E, + F400D65DAD8A93736A7960CC, + E55B34E6694D69E3DBB107D1, + 8A3A8D57685177B2F0D52C17, + B4439D672F2977238755E1E2, + 4BF0300CA427D2D308542534 ); name = UI; sourceTree = ""; }; + 14B5B6D3D07644058F0F526F = { isa = PBXGroup; children = ( + AAF3C58696944A256CA61730, + 9736236B5C4D6A16FC7E03AC, + F99858EE1CD3B23057B8BEBD, + 7A1CD936BD306A6E0BEFB046, + E99413C9561A66310DAD5EEB, + E3BD76BDB547509885E14DEE, + 5FCA7C152179881180F14173, + B8469A2CDD0FBEA6BE01B1D5 ); name = Utility; sourceTree = ""; }; + FAFBE12D4C5798FC1BB3A4BA = { isa = PBXGroup; children = ( + 0CA0CCCEBFA0AC8C577FC915, + 0DC331A7B856F30AD266A3E6 ); name = Main; sourceTree = ""; }; + A3AA50DFBB048C92A2213BC1 = { isa = PBXGroup; children = ( + 1366A411A69F2020EE651CDB, + 607EB083892A70C2A770A1B6, + 1C52B91B15DF56E0A37F3EEE, + 4D62A4E094921086FBB82248, + C2AE936214AC10DC4FABAC2F, + 061B86C84B0D279F1EABBBE2, + 1EC5B7483B37A4163CA19549, + 4A80C6415DB1C1CB47DBE23F, + 9F82562788D22155BA6027F2, + CC9BA48C736AC8B5EF19E3B7, + A85C2ED9EA2896E23CFC0C1D, + E3CAAE006B081997B4A96B78 ); name = Resources; sourceTree = ""; }; + 265749F75DBA86EC3F19FE34 = { isa = PBXGroup; children = ( + C86084A495B96EA215958914, + 8FEC5B519774920289A1FD73, + D02830A908A07FD46F7387DA, + A6A79D303B85B7C9D673ECD5, + 933DADF4F3906510EA714CC0, + DD6476FF0F8BE833CD54C01F, + 268B4FFB1C675B679138545F, + 60A217F62952DE8A752BD79F ); name = "Juce Library Code"; sourceTree = ""; }; + EAC5B9DBB227CB2A002EF355 = { isa = PBXGroup; children = ( + F4C5CF1AA7EB9298043D89D3 ); name = Resources; sourceTree = ""; }; + 0D737FA088906E13707BAEB7 = { isa = PBXGroup; children = ( + 046FA2877C08618339161EE2, + 43A5218D223AA21E0A55D986, + 151135F18422E2B1368D7BC2, + B36C44190E6AEEBFA3DB3046, + FB3773F08466794F949B0AFF, + 74125C6A6DE28C538A518C3C, + A5A4B15B9F5C3D32C82DFDC6, + 6E1144678BD61868D73EF1FB, + 23CF69B4C644D1E6E61E5C82, + 2767E1D082874D301D5D5F43, + D9FB1A5365FEEB854A0FF7BF ); name = Frameworks; sourceTree = ""; }; + 18794C3CE7D0C95A5A70F213 = { isa = PBXGroup; children = ( + 12E1601866B3489844AFD645 ); name = Products; sourceTree = ""; }; + B01AA6CC1327A5DBCB35B7BF = { isa = PBXGroup; children = ( + BF6238C9155879B9A9C47213, + 63A4428C116D97D7C5C05DC8, + 14B5B6D3D07644058F0F526F, + FAFBE12D4C5798FC1BB3A4BA, + A3AA50DFBB048C92A2213BC1, + 265749F75DBA86EC3F19FE34, + EAC5B9DBB227CB2A002EF355, + 0D737FA088906E13707BAEB7, + 18794C3CE7D0C95A5A70F213 ); name = Source; sourceTree = ""; }; + DD9313457B3248E7646270A4 = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + PREBINDING = NO; + HEADER_SEARCH_PATHS = " $(inherited)"; + GCC_OPTIMIZATION_LEVEL = 0; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; + ONLY_ACTIVE_ARCH = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "_DEBUG=1", + "DEBUG=1 "); }; name = Debug; }; + 673FACB8969ADED17ACEFF7C = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + PREBINDING = NO; + HEADER_SEARCH_PATHS = " $(inherited)"; + GCC_OPTIMIZATION_LEVEL = 3; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + MACOSX_DEPLOYMENT_TARGET_ppc = 10.4; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "_NDEBUG=1", + "NDEBUG=1 "); }; name = Release; }; + 69D26A715A354ED1735D8438 = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_MODEL_TUNING = G5; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + ZERO_LINK = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + PRODUCT_NAME = "Jucer"; }; name = Debug; }; + 4C681DED23FC5056A83C964C = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_MODEL_TUNING = G5; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + ZERO_LINK = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + PRODUCT_NAME = "Jucer"; }; name = Release; }; + 045AC698C60073CCF5CC6116 = { isa = XCConfigurationList; buildConfigurations = ( + 69D26A715A354ED1735D8438, + 4C681DED23FC5056A83C964C ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + AC9DE3D3A6632D0494CC8609 = { isa = XCConfigurationList; buildConfigurations = ( + DD9313457B3248E7646270A4, + 673FACB8969ADED17ACEFF7C ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + 87CCE4CB1FAB40B6F21DEACE = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; + 5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CD4226951C3F7FE19CF8A7CE, + 1174D3512AF8207950094C56, + 087CCE9E7146F1EC4F241254, + E9935BFB0EFA8CCCD41DC08E, + 60CDC1358E84801B6526E434, + EEC6FC8E546C88C825411DB2, + B2B821DE12F1679A3ADA597A, + E43D00B370F289420379B759, + 944CE0EADAD951F48EC77071, + 4E8860E0F8680956A6F5B493, + 288F5E7A2EC305BB4D8D73D1, + 2417927E323BFE201D5985B9, + A1CB18029E09A66E192D9A29, + F8C762CCE16669F76D2209B9, + 4FF75A3C7DCB9FD245320FE6, + A70AED2E35B809981470A547, + 4D6C7380B8BB0BA9470C146C, + 438FED16CFDB36A4BE1F5F35, + 33A4BAAD7A79BA63E78CB503, + DDAB225ABE572196882C3524, + FA8C72364CDFD2B76F16C0F1, + 6B6B0EBBE899B0ACDCAD92F5, + 69CA42E334E4BA09E4FE8B65, + 0C3A85F58C34FA91D16664EB, + 08C0959668FFC1A90B4BA8E6, + 1457A52734BA97A13610ECF1, + 20EDB5C810855EB960F520FC ); runOnlyForDeploymentPostprocessing = 0; }; + 08881173C882953BE5F11D6C = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 7BDFF9F0E16DF33A980F46DC, + B703C44375C75E5AB099E74A, + 022036CBB0FBE47C417A6222, + 52A4EFC1F732A9D5BBB61AF5, + C65112B26E0BB0BB8DBD3F3C, + E63745F5956C698352A2ACA0, + 2C3270317859BA6DF8EC1458, + AA7B50F22523465B07D4A25B, + DBE3CE9482B19CF1AE700805, + 93C9F3F27602A33DDC9C2250, + 2E6836738CE7EB452FDC7E9A ); runOnlyForDeploymentPostprocessing = 0; }; + EB946A866C16B958168C9A39 = { isa = PBXNativeTarget; buildConfigurationList = AC9DE3D3A6632D0494CC8609; buildPhases = ( + 87CCE4CB1FAB40B6F21DEACE, + 5362E03ADF975A126C1F2F7B, + 08881173C882953BE5F11D6C ); buildRules = ( ); dependencies = ( ); name = "The Jucer"; productName = "The Jucer"; productReference = 12E1601866B3489844AFD645; productInstallPath = "$(HOME)/Applications"; productType = "com.apple.product-type.application"; }; + D64DFDDF5D2CD74A8171CF81 = { isa = PBXProject; buildConfigurationList = 045AC698C60073CCF5CC6116; compatibilityVersion = "Xcode 3.0"; hasScannedForEncodings = 0; mainGroup = B01AA6CC1327A5DBCB35B7BF; projectDirPath = ""; projectRoot = ""; targets = ( EB946A866C16B958168C9A39 ); }; + }; + rootObject = D64DFDDF5D2CD74A8171CF81; +} diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.sln b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.sln new file mode 100644 index 0000000000..1b75624dc6 --- /dev/null +++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 8.00 +# Visual C++ Express 2005 +Project("{4E9D0CBA-BFAB-E5E4-0A60-A20FD97F37CA}") = "The Jucer", "The Jucer.vcproj", "{C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Debug|Win32.ActiveCfg = Debug|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Debug|Win32.Build.0 = Debug|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Release|Win32.ActiveCfg = Release|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj new file mode 100644 index 0000000000..3b1ddf04b1 --- /dev/null +++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.sln b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.sln new file mode 100644 index 0000000000..7dd2bd2489 --- /dev/null +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{4E9D0CBA-BFAB-E5E4-0A60-A20FD97F37CA}") = "The Jucer", "The Jucer.vcproj", "{C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Debug|Win32.ActiveCfg = Debug|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Debug|Win32.Build.0 = Debug|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Release|Win32.ActiveCfg = Release|Win32 + {C9C4A72E-8CC9-D57E-C0D0-2E6109E48884}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj new file mode 100644 index 0000000000..9ae6139cec --- /dev/null +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/Jucer (experimental)/JuceLibraryCode/AppConfig.h b/extras/Jucer (experimental)/JuceLibraryCode/AppConfig.h new file mode 100644 index 0000000000..9bccf432c2 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/AppConfig.h @@ -0,0 +1,37 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + If you want to change any of these values, use the Jucer to do so, rather than + editing this file directly! + + Any commented-out settings will fall back to using the default values that + they are given in juce_Config.h + +*/ + +//#define JUCE_FORCE_DEBUG +//#define JUCE_LOG_ASSERTIONS +#define JUCE_ASIO 0 +#define JUCE_WASAPI 0 +#define JUCE_DIRECTSOUND 0 +#define JUCE_ALSA 0 +#define JUCE_QUICKTIME 0 +#define JUCE_OPENGL 0 +#define JUCE_USE_FLAC 0 +#define JUCE_USE_OGGVORBIS 0 +#define JUCE_USE_CDBURNER 0 +#define JUCE_USE_CDREADER 0 +#define JUCE_USE_CAMERA 0 +//#define JUCE_ENABLE_REPAINT_DEBUGGING +//#define JUCE_USE_XINERAMA +//#define JUCE_USE_XSHM +//#define JUCE_USE_XRENDER +#define JUCE_PLUGINHOST_VST 0 +#define JUCE_PLUGINHOST_AU 0 +//#define JUCE_ONLY_BUILD_CORE_LIBRARY +//#define JUCE_WEB_BROWSER +//#define JUCE_SUPPORT_CARBON +//#define JUCE_CHECK_MEMORY_LEAKS +//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp new file mode 100644 index 0000000000..7e44b6cab1 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp @@ -0,0 +1,936 @@ +/* ==================================== JUCER_BINARY_RESOURCE ==================================== + + This is an auto-generated file, created by The Jucer V3.0.0 + Do not edit anything in this file! + +*/ + +#include "BinaryData.h" + + +const char* BinaryData::getNamedResource (const wchar_t* resourceName, int& numBytes) throw() +{ + int hash = 0; + if (resourceName != 0) + while (*resourceName != 0) + hash = 31 * hash + *resourceName++; + + switch (hash) + { + case 0x44be9398: numBytes = BinaryData::AudioPluginXCodeScript_txtSize; return BinaryData::AudioPluginXCodeScript_txt; + case 0x27c5a93a: numBytes = BinaryData::jucer_AudioPluginEditorTemplate_cppSize; return BinaryData::jucer_AudioPluginEditorTemplate_cpp; + case 0x4d0721bf: numBytes = BinaryData::jucer_AudioPluginEditorTemplate_hSize; return BinaryData::jucer_AudioPluginEditorTemplate_h; + case 0x51b49ac5: numBytes = BinaryData::jucer_AudioPluginFilterTemplate_cppSize; return BinaryData::jucer_AudioPluginFilterTemplate_cpp; + case 0x488afa0a: numBytes = BinaryData::jucer_AudioPluginFilterTemplate_hSize; return BinaryData::jucer_AudioPluginFilterTemplate_h; + case 0x8905395b: numBytes = BinaryData::jucer_MainConsoleAppTemplate_cppSize; return BinaryData::jucer_MainConsoleAppTemplate_cpp; + case 0x7a0186b1: numBytes = BinaryData::jucer_MainTemplate_cppSize; return BinaryData::jucer_MainTemplate_cpp; + case 0x02a2a077: numBytes = BinaryData::jucer_NewCppFileTemplate_cppSize; return BinaryData::jucer_NewCppFileTemplate_cpp; + case 0x0842c43c: numBytes = BinaryData::jucer_NewCppFileTemplate_hSize; return BinaryData::jucer_NewCppFileTemplate_h; + case 0x3f052be8: numBytes = BinaryData::jucer_WindowTemplate_cppSize; return BinaryData::jucer_WindowTemplate_cpp; + case 0xb20377ed: numBytes = BinaryData::jucer_WindowTemplate_hSize; return BinaryData::jucer_WindowTemplate_h; + case 0x154a7275: numBytes = BinaryData::juce_icon_pngSize; return BinaryData::juce_icon_png; + default: break; + } + + numBytes = 0; + return 0; +} + + +//================== AudioPluginXCodeScript.txt ================== +static const unsigned char temp_198ab1e7[] = +"\r\n" +"# This script takes the build product and copies it to the AU, VST, and RTAS folders, depending on \r\n" +"# which plugin types you've built\r\n" +"\r\n" +"original=$CONFIGURATION_BUILD_DIR/$FULL_PRODUCT_NAME\r\n" +"\r\n" +"# this looks inside the binary to detect which platforms are needed.. \r\n" +"copyAU=`nm -g \"$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH\" | grep -i 'AudioUnit' | wc -l`\r\n" +"copyVST=`nm -g \"$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH\" | grep -i 'VSTPlugin' | wc -l`\r\n" +"copyRTAS=`nm -g \"$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH\" | grep -i 'CProcess' | wc -l`\r\n" +"\r\n" +"if [ $copyAU -gt 0 ]; then\r\n" +" echo \"Copying to AudioUnit folder...\"\r\n" +" AU=~/Library/Audio/Plug-Ins/Components/$PRODUCT_NAME.component\r\n" +" if [ -d \"$AU\" ]; then \r\n" +" rm -r \"$AU\"\r\n" +" fi\r\n" +"\r\n" +" cp -r \"$original\" \"$AU\"\r\n" +" sed -i \"\" -e 's/TDMwPTul/BNDLPTul/g' \"$AU/Contents/PkgInfo\"\r\n" +" sed -i \"\" -e 's/TDMw/BNDL/g' \"$AU/Contents/$INFOPLIST_FILE\"\r\n" +"fi\r\n" +"\r\n" +"if [ $copyVST -gt 0 ]; then\r\n" +" echo \"Copying to VST folder...\"\r\n" +" VST=~/Library/Audio/Plug-Ins/VST/$PRODUCT_NAME.vst\r\n" +" if [ -d \"$VST\" ]; then \r\n" +" rm -r \"$VST\"\r\n" +" fi\r\n" +"\r\n" +" cp -r \"$original\" \"$VST\"\r\n" +" sed -i \"\" -e 's/TDMwPTul/BNDLPTul/g' \"$VST/Contents/PkgInfo\"\r\n" +" sed -i \"\" -e 's/TDMw/BNDL/g' \"$VST/Contents/$INFOPLIST_FILE\"\r\n" +"fi\r\n" +"\r\n" +"if [ $copyRTAS -gt 0 ]; then\r\n" +" echo \"Copying to RTAS folder...\"\r\n" +" RTAS=/Library/Application\\ Support/Digidesign/Plug-Ins/$PRODUCT_NAME.dpm\r\n" +" if [ -d \"$RTAS\" ]; then\r\n" +" rm -r \"$RTAS\"\r\n" +" fi\r\n" +"\r\n" +" cp -r \"$original\" \"$RTAS\"\r\n" +"fi\r\n"; + +const char* BinaryData::AudioPluginXCodeScript_txt = (const char*) temp_198ab1e7; + +//================== jucer_AudioPluginEditorTemplate.cpp ================== +static const unsigned char temp_9d632c4d[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"EDITORCPPHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"EDITORCLASSNAME::EDITORCLASSNAME (FILTERCLASSNAME* ownerFilter)\r\n" +" : AudioProcessorEditor (ownerFilter)\r\n" +"{\r\n" +" // This is where our plugin's editor size is set.\r\n" +" setSize (400, 300);\r\n" +"}\r\n" +"\r\n" +"EDITORCLASSNAME::~EDITORCLASSNAME()\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"void EDITORCLASSNAME::paint (Graphics& g)\r\n" +"{\r\n" +" g.fillAll (Colours::white);\r\n" +" g.setColour (Colours::black);\r\n" +" g.setFont (15.0f);\r\n" +" g.drawFittedText (\"Hello World!\",\r\n" +" 0, 0, getWidth(), getHeight(),\r\n" +" Justification::centred, 1);\r\n" +"}\r\n"; + +const char* BinaryData::jucer_AudioPluginEditorTemplate_cpp = (const char*) temp_9d632c4d; + +//================== jucer_AudioPluginEditorTemplate.h ================== +static const unsigned char temp_ac404d92[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"#ifndef HEADERGUARD\r\n" +"#define HEADERGUARD\r\n" +"\r\n" +"EDITORHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"/**\r\n" +"*/\r\n" +"class EDITORCLASSNAME : public AudioProcessorEditor\r\n" +"{\r\n" +"public:\r\n" +" EDITORCLASSNAME (FILTERCLASSNAME* ownerFilter);\r\n" +" ~EDITORCLASSNAME();\r\n" +"\r\n" +" //==============================================================================\r\n" +" // This is just a standard Juce paint method...\r\n" +" void paint (Graphics& g);\r\n" +"};\r\n" +"\r\n" +"\r\n" +"#endif // HEADERGUARD\r\n"; + +const char* BinaryData::jucer_AudioPluginEditorTemplate_h = (const char*) temp_ac404d92; + +//================== jucer_AudioPluginFilterTemplate.cpp ================== +static const unsigned char temp_c7521dd8[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"FILTERHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"FILTERCLASSNAME::FILTERCLASSNAME()\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"FILTERCLASSNAME::~FILTERCLASSNAME()\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"const String FILTERCLASSNAME::getName() const\r\n" +"{\r\n" +" return JucePlugin_Name;\r\n" +"}\r\n" +"\r\n" +"int FILTERCLASSNAME::getNumParameters()\r\n" +"{\r\n" +" return 0;\r\n" +"}\r\n" +"\r\n" +"float FILTERCLASSNAME::getParameter (int index)\r\n" +"{\r\n" +" return 0.0f;\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::setParameter (int index, float newValue)\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"const String FILTERCLASSNAME::getParameterName (int index)\r\n" +"{\r\n" +" return String::empty;\r\n" +"}\r\n" +"\r\n" +"const String FILTERCLASSNAME::getParameterText (int index)\r\n" +"{\r\n" +" return String::empty;\r\n" +"}\r\n" +"\r\n" +"const String FILTERCLASSNAME::getInputChannelName (const int channelIndex) const\r\n" +"{\r\n" +" return String (channelIndex + 1);\r\n" +"}\r\n" +"\r\n" +"const String FILTERCLASSNAME::getOutputChannelName (const int channelIndex) const\r\n" +"{\r\n" +" return String (channelIndex + 1);\r\n" +"}\r\n" +"\r\n" +"bool FILTERCLASSNAME::isInputChannelStereoPair (int index) const\r\n" +"{\r\n" +" return true;\r\n" +"}\r\n" +"\r\n" +"bool FILTERCLASSNAME::isOutputChannelStereoPair (int index) const\r\n" +"{\r\n" +" return true;\r\n" +"}\r\n" +"\r\n" +"bool FILTERCLASSNAME::acceptsMidi() const\r\n" +"{\r\n" +"#if JucePlugin_WantsMidiInput\r\n" +" return true;\r\n" +"#else\r\n" +" return false;\r\n" +"#endif\r\n" +"}\r\n" +"\r\n" +"bool FILTERCLASSNAME::producesMidi() const\r\n" +"{\r\n" +"#if JucePlugin_ProducesMidiOutput\r\n" +" return true;\r\n" +"#else\r\n" +" return false;\r\n" +"#endif\r\n" +"}\r\n" +"\r\n" +"int FILTERCLASSNAME::getNumPrograms()\r\n" +"{\r\n" +" return 0;\r\n" +"}\r\n" +"\r\n" +"int FILTERCLASSNAME::getCurrentProgram()\r\n" +"{\r\n" +" return 0;\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::setCurrentProgram (int index)\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"const String FILTERCLASSNAME::getProgramName (int index)\r\n" +"{\r\n" +" return String::empty;\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::changeProgramName (int index, const String& newName)\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"void FILTERCLASSNAME::prepareToPlay (double sampleRate, int samplesPerBlock)\r\n" +"{\r\n" +" // Use this method as the place to do any pre-playback\r\n" +" // initialisation that you need..\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::releaseResources()\r\n" +"{\r\n" +" // When playback stops, you can use this as an opportunity to free up any\r\n" +" // spare memory, etc.\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::processBlock (AudioSampleBuffer& buffer,\r\n" +" MidiBuffer& midiMessages)\r\n" +"{\r\n" +" // This is the place where you'd normally do the guts of your plugin's\r\n" +" // audio processing...\r\n" +" for (int channel = 0; channel < getNumInputChannels(); ++channel)\r\n" +" {\r\n" +" float* channelData = buffer.getSampleData (channel);\r\n" +"\r\n" +" // ..do something to the data...\r\n" +" }\r\n" +"\r\n" +" // In case we have more outputs than inputs, we'll clear any output\r\n" +" // channels that didn't contain input data, (because these aren't\r\n" +" // guaranteed to be empty - they may contain garbage).\r\n" +" for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)\r\n" +" {\r\n" +" buffer.clear (i, 0, buffer.getNumSamples());\r\n" +" }\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"AudioProcessorEditor* FILTERCLASSNAME::createEditor()\r\n" +"{\r\n" +" return new EDITORCLASSNAME (this);\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"void FILTERCLASSNAME::getStateInformation (MemoryBlock& destData)\r\n" +"{\r\n" +" // You should use this method to store your parameters in the memory block.\r\n" +" // You could do that either as raw data, or use the XML or ValueTree classes\r\n" +" // as intermediaries to make it easy to save and load complex data.\r\n" +"}\r\n" +"\r\n" +"void FILTERCLASSNAME::setStateInformation (const void* data, int sizeInBytes)\r\n" +"{\r\n" +" // You should use this method to restore your parameters from this memory block,\r\n" +" // whose contents will have been created by the getStateInformation() call.\r\n" +"}\r\n" +"\r\n" +"//==============================================================================\r\n" +"// This creates new instances of the plugin..\r\n" +"AudioProcessor* JUCE_CALLTYPE createPluginFilter()\r\n" +"{\r\n" +" return new FILTERCLASSNAME();\r\n" +"}\r\n"; + +const char* BinaryData::jucer_AudioPluginFilterTemplate_cpp = (const char*) temp_c7521dd8; + +//================== jucer_AudioPluginFilterTemplate.h ================== +static const unsigned char temp_a7c425dd[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"#ifndef HEADERGUARD\r\n" +"#define HEADERGUARD\r\n" +"\r\n" +"APPHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"/**\r\n" +"*/\r\n" +"class FILTERCLASSNAME : public AudioProcessor\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" FILTERCLASSNAME();\r\n" +" ~FILTERCLASSNAME();\r\n" +"\r\n" +" //==============================================================================\r\n" +" void prepareToPlay (double sampleRate, int samplesPerBlock);\r\n" +" void releaseResources();\r\n" +"\r\n" +" void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);\r\n" +"\r\n" +" //==============================================================================\r\n" +" AudioProcessorEditor* createEditor();\r\n" +"\r\n" +" //==============================================================================\r\n" +" const String getName() const;\r\n" +"\r\n" +" int getNumParameters();\r\n" +"\r\n" +" float getParameter (int index);\r\n" +" void setParameter (int index, float newValue);\r\n" +"\r\n" +" const String getParameterName (int index);\r\n" +" const String getParameterText (int index);\r\n" +"\r\n" +" const String getInputChannelName (const int channelIndex) const;\r\n" +" const String getOutputChannelName (const int channelIndex) const;\r\n" +" bool isInputChannelStereoPair (int index) const;\r\n" +" bool isOutputChannelStereoPair (int index) const;\r\n" +"\r\n" +" bool acceptsMidi() const;\r\n" +" bool producesMidi() const;\r\n" +"\r\n" +" //==============================================================================\r\n" +" int getNumPrograms();\r\n" +" int getCurrentProgram();\r\n" +" void setCurrentProgram (int index);\r\n" +" const String getProgramName (int index);\r\n" +" void changeProgramName (int index, const String& newName);\r\n" +"\r\n" +" //==============================================================================\r\n" +" void getStateInformation (MemoryBlock& destData);\r\n" +" void setStateInformation (const void* data, int sizeInBytes);\r\n" +"\r\n" +" //==============================================================================\r\n" +" juce_UseDebuggingNewOperator\r\n" +"\r\n" +"};\r\n" +"\r\n" +"#endif // HEADERGUARD\r\n"; + +const char* BinaryData::jucer_AudioPluginFilterTemplate_h = (const char*) temp_a7c425dd; + +//================== jucer_MainConsoleAppTemplate.cpp ================== +static const unsigned char temp_a4c7812a[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"APPHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"int main (int argc, char* argv[])\r\n" +"{\r\n" +" // This object makes sure that Juce is initialised and shut down correctly\r\n" +" // for the scope of this function call. Make sure this declaration is the\r\n" +" // first statement of this function.\r\n" +" const ScopedJuceInitialiser_NonGUI juceSystemInitialiser;\r\n" +"\r\n" +"\r\n" +" // ..your code goes here!\r\n" +"\r\n" +"\r\n" +" return 0;\r\n" +"}\r\n"; + +const char* BinaryData::jucer_MainConsoleAppTemplate_cpp = (const char*) temp_a4c7812a; + +//================== jucer_MainTemplate.cpp ================== +static const unsigned char temp_3f9400[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic startup code for a Juce application.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"APPHEADERS\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"class APPCLASSNAME : public JUCEApplication\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" APPCLASSNAME()MEMBERINITIALISERS\r\n" +" {\r\n" +" // Don't do anything in this constructor! It will be called before the\r\n" +" // main Juce subsystem has been initialised!\r\n" +" }\r\n" +"\r\n" +" ~APPCLASSNAME()\r\n" +" {\r\n" +" // Don't do anything in this destructor! It will be called after the\r\n" +" // main Juce subsystem has been shutdown and is no longer valid!\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" void initialise (const String& commandLine)\r\n" +" {\r\n" +" // Do your application's initialisation code here..\r\n" +" APPINITCODE\r\n" +" }\r\n" +"\r\n" +" void shutdown()\r\n" +" {\r\n" +" // Do your application's shutdown code here..\r\n" +" APPSHUTDOWNCODE\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" void systemRequestedQuit()\r\n" +" {\r\n" +" quit();\r\n" +" }\r\n" +"\r\n" +" //==============================================================================\r\n" +" const String getApplicationName()\r\n" +" {\r\n" +" return \"APPNAME\";\r\n" +" }\r\n" +"\r\n" +" const String getApplicationVersion()\r\n" +" {\r\n" +" return ProjectInfo::versionString;\r\n" +" }\r\n" +"\r\n" +" bool moreThanOneInstanceAllowed()\r\n" +" {\r\n" +" return ALLOWMORETHANONEINSTANCE;\r\n" +" }\r\n" +"\r\n" +" void anotherInstanceStarted (const String& commandLine)\r\n" +" {\r\n" +" ANOTHERINSTANCECODE\r\n" +" }\r\n" +"\r\n" +"private:\r\n" +" PRIVATEMEMBERS\r\n" +"};\r\n" +"\r\n" +"//==============================================================================\r\n" +"// This macro generates the main() routine that starts the app.\r\n" +"START_JUCE_APPLICATION(APPCLASSNAME)\r\n"; + +const char* BinaryData::jucer_MainTemplate_cpp = (const char*) temp_3f9400; + +//================== jucer_NewCppFileTemplate.cpp ================== +static const unsigned char temp_28679746[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" FILENAME\r\n" +" Created: DATE\r\n" +" Author: AUTHOR\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n"; + +const char* BinaryData::jucer_NewCppFileTemplate_cpp = (const char*) temp_28679746; + +//================== jucer_NewCppFileTemplate.h ================== +static const unsigned char temp_dd2522cb[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" FILENAME\r\n" +" Created: DATE\r\n" +" Author: AUTHOR\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"#ifndef HEADERGUARD\r\n" +"#define HEADERGUARD\r\n" +"\r\n" +"\r\n" +"\r\n" +"\r\n" +"\r\n" +"#endif // HEADERGUARD\r\n"; + +const char* BinaryData::jucer_NewCppFileTemplate_h = (const char*) temp_dd2522cb; + +//================== jucer_WindowTemplate.cpp ================== +static const unsigned char temp_817c51b7[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic outline for a simple desktop window.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"INCLUDES\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"WINDOWCLASS::WINDOWCLASS()\r\n" +" : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(),\r\n" +" Colours::lightgrey,\r\n" +" DocumentWindow::allButtons)\r\n" +"{\r\n" +" centreWithSize (500, 400);\r\n" +" setVisible (true);\r\n" +"}\r\n" +"\r\n" +"WINDOWCLASS::~WINDOWCLASS()\r\n" +"{\r\n" +"}\r\n" +"\r\n" +"void WINDOWCLASS::closeButtonPressed()\r\n" +"{\r\n" +" JUCEApplication::getInstance()->systemRequestedQuit();\r\n" +"}\r\n"; + +const char* BinaryData::jucer_WindowTemplate_cpp = (const char*) temp_817c51b7; + +//================== jucer_WindowTemplate.h ================== +static const unsigned char temp_3857c57c[] = +"/*\r\n" +" ==============================================================================\r\n" +"\r\n" +" This file was auto-generated by the Jucer!\r\n" +"\r\n" +" It contains the basic outline for a simple desktop window.\r\n" +"\r\n" +" ==============================================================================\r\n" +"*/\r\n" +"\r\n" +"#ifndef HEADERGUARD\r\n" +"#define HEADERGUARD\r\n" +"\r\n" +"INCLUDES\r\n" +"\r\n" +"\r\n" +"//==============================================================================\r\n" +"class WINDOWCLASS : public DocumentWindow\r\n" +"{\r\n" +"public:\r\n" +" //==============================================================================\r\n" +" WINDOWCLASS();\r\n" +" ~WINDOWCLASS();\r\n" +"\r\n" +" void closeButtonPressed();\r\n" +"\r\n" +"\r\n" +" /* Note: Be careful when overriding DocumentWindow methods - the base class\r\n" +" uses a lot of them, so by overriding you might break its functionality.\r\n" +" It's best to do all your work in you content component instead, but if\r\n" +" you really have to override any DocumentWindow methods, make sure your\r\n" +" implementation calls the superclass's method.\r\n" +" */\r\n" +"\r\n" +" //==============================================================================\r\n" +" juce_UseDebuggingNewOperator\r\n" +"\r\n" +"private:\r\n" +" WINDOWCLASS (const WINDOWCLASS&);\r\n" +" WINDOWCLASS& operator= (const WINDOWCLASS&);\r\n" +"};\r\n" +"\r\n" +"\r\n" +"#endif // HEADERGUARD\r\n"; + +const char* BinaryData::jucer_WindowTemplate_h = (const char*) temp_3857c57c; + +//================== juce_icon.png ================== +static const unsigned char temp_cf125308[] = +{ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,128,0,0,0,128,8,6,0,0,0,195,62,97,203,0,0,0,9,112,72,89,115,0,0,11,19,0,0,11,19,1,0,154,156,24,0,0,0,4,103,65,77,65,0,0,177,142,124,251,81,147,0,0,0,32,99,72,82,77,0,0,122,37,0,0,128,131,0,0,249,255, +0,0,128,233,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,111,146,95,197,70,0,0,76,232,73,68,65,84,120,218,98,252,255,255,63,3,35,35,35,195,16,4,140,88,216,76,72,124,70,36,113,70,52,113,108,102,192,192,127,52,246,127,52,241,255,104,226,255,112,232,27,18,0, +32,128,88,134,120,164,35,99,38,44,52,54,117,216,18,2,182,68,128,45,194,209,241,63,52,250,63,150,200,31,212,137,1,32,128,88,134,88,196,163,71,56,19,82,132,51,99,17,99,194,146,0,112,149,12,248,114,58,174,72,135,225,191,88,196,254,15,133,82,1,32,128,88, +134,80,196,51,97,137,120,102,52,140,44,198,136,150,24,144,205,64,174,46,208,19,0,122,177,254,15,45,242,97,252,191,80,252,15,137,141,44,246,15,45,177,12,202,132,0,16,64,44,67,40,226,209,35,152,5,137,70,102,51,179,50,51,177,176,48,252,103,102,97,102,102, +230,102,99,101,17,103,252,197,161,173,169,201,111,174,169,170,192,119,253,168,164,0,31,191,176,160,158,41,31,235,183,79,188,140,95,62,240,48,254,255,15,182,239,15,175,208,135,127,220,188,63,223,92,60,253,250,227,167,79,239,95,43,155,62,62,116,237,246, +253,219,183,111,127,251,202,196,246,251,211,175,223,191,254,252,251,255,239,207,127,134,191,191,255,254,251,3,141,108,100,26,93,236,47,150,18,98,80,37,4,128,0,98,28,100,141,64,92,17,207,140,22,241,172,232,180,32,7,43,187,0,59,43,7,47,39,7,71,156,185, +150,190,228,211,235,106,210,234,154,74,156,111,159,169,48,189,123,33,196,248,251,55,39,11,51,35,27,200,200,127,223,127,49,252,253,6,244,55,44,217,192,108,4,70,219,127,96,84,49,115,1,45,231,224,96,248,255,255,31,195,191,255,255,127,252,103,101,253,198, +32,169,244,225,227,127,230,187,111,63,127,121,116,237,55,219,249,109,183,159,221,122,253,237,231,183,15,191,255,253,120,255,253,215,79,160,238,223,208,136,255,141,196,254,131,165,116,64,46,85,6,60,33,0,4,208,96,73,0,232,17,207,132,37,183,195,34,28,134, +217,36,5,249,185,213,185,153,5,149,248,216,69,172,196,249,244,149,132,248,13,120,63,60,211,97,126,251,76,146,129,145,153,225,223,151,223,12,204,156,64,67,217,217,128,52,19,3,19,51,16,179,179,48,176,112,177,0,249,204,12,204,236,76,12,204,28,204,112,155, +255,124,253,195,0,202,215,127,191,253,1,226,223,12,127,127,2,249,191,255,49,252,253,245,159,225,223,215,95,12,255,129,114,140,32,245,127,255,50,48,42,170,191,124,245,139,225,210,51,86,158,75,123,174,223,63,253,232,47,235,187,43,47,223,191,7,38,134,239, +64,211,126,33,37,4,108,137,1,189,138,24,176,132,0,16,64,3,157,0,8,229,120,140,72,7,97,121,97,1,94,119,97,102,37,55,123,91,11,177,231,183,205,121,223,191,208,249,247,225,45,199,127,96,80,51,177,129,139,3,6,118,1,32,22,98,103,224,144,224,100,96,19,102, +103,96,7,98,102,54,38,6,86,46,102,6,70,78,86,164,22,5,35,82,109,15,141,131,191,255,25,254,127,255,195,240,27,152,32,254,254,252,199,240,243,253,79,134,159,175,129,248,205,15,134,159,239,126,130,249,191,223,127,7,39,22,70,86,70,6,70,110,222,175,95,228, +181,47,221,252,240,245,208,182,235,15,79,29,121,247,251,217,235,47,223,190,66,19,2,182,196,48,104,74,4,128,0,26,168,4,64,74,196,179,65,49,187,158,184,128,128,187,156,128,166,173,170,130,141,232,245,227,46,172,95,127,138,131,12,97,229,99,97,96,19,225, +100,224,16,230,96,224,146,226,98,224,81,225,99,224,18,227,96,96,224,102,129,154,206,8,142,84,48,254,7,165,225,65,141,20,222,200,225,192,204,8,193,224,178,136,9,218,12,252,199,240,255,219,95,134,111,79,191,49,124,121,240,133,225,251,139,31,12,63,94,127, +99,248,245,238,7,195,175,183,191,25,152,184,152,24,126,136,73,223,122,46,32,123,232,196,135,223,199,55,159,187,118,231,230,251,175,31,144,18,194,47,28,165,2,182,158,3,93,18,2,64,0,13,68,2,64,143,124,108,17,207,134,28,241,214,106,10,34,190,226,236,70, +58,28,255,237,196,126,125,179,96,120,250,68,132,149,155,137,129,75,154,155,129,91,153,159,129,91,142,155,129,83,156,19,152,227,129,202,217,153,33,65,247,251,47,52,104,255,163,6,37,41,94,69,209,199,8,209,203,2,36,216,160,29,136,31,127,129,165,193,47,134, +239,207,190,49,124,125,248,133,225,211,173,15,12,95,159,124,3,43,251,43,42,241,242,37,43,231,241,155,191,152,78,174,127,241,243,244,177,187,79,222,0,133,127,98,73,12,127,176,244,32,232,150,8,0,2,136,222,9,0,189,31,15,139,120,228,98,158,29,134,85,197, +132,248,147,141,148,204,76,57,25,188,249,238,95,179,96,250,245,141,131,133,135,153,129,83,146,151,65,80,79,152,129,79,155,159,129,141,159,13,18,41,160,92,13,172,175,193,17,254,143,196,136,38,21,252,135,86,29,32,31,176,50,65,216,127,255,49,124,7,150,12, +31,47,127,96,248,116,247,35,195,143,23,95,128,109,10,96,35,146,91,240,199,71,73,249,19,251,158,191,95,179,253,213,207,107,231,31,189,120,7,74,58,104,137,1,214,120,68,79,4,255,105,157,8,0,2,136,158,9,0,125,0,7,214,6,103,67,139,120,14,127,109,5,153,8,225, +127,62,82,2,188,70,172,15,238,169,114,252,255,46,36,100,32,196,192,171,38,8,204,229,28,12,172,192,186,157,77,128,21,146,43,127,254,67,212,221,140,180,114,246,127,112,241,143,232,197,129,74,3,102,212,225,3,80,34,0,37,6,160,91,126,125,252,5,172,22,126, +49,252,6,182,23,62,222,120,199,240,225,202,59,134,111,172,252,207,254,74,72,62,125,250,233,219,233,69,47,255,109,218,126,235,201,51,164,132,240,19,75,27,129,46,141,68,128,0,162,71,2,64,30,120,65,142,124,244,28,207,1,194,51,35,92,61,181,223,223,9,227, +120,241,68,253,207,135,223,108,130,186,188,12,18,78,210,12,220,10,60,144,22,59,44,204,255,64,235,114,70,28,86,162,12,237,252,39,207,217,255,128,153,243,247,39,136,126,70,86,136,24,40,162,255,253,131,200,49,177,64,251,140,160,222,37,19,68,29,72,158,5, +97,255,95,96,169,244,245,214,71,134,39,91,159,48,124,125,244,141,129,153,159,245,247,15,33,241,91,23,5,148,151,100,173,61,184,11,154,8,208,19,2,172,125,128,220,91,160,73,34,0,8,32,90,38,0,92,13,61,88,223,157,13,26,233,160,200,231,180,83,16,151,108,48, +145,41,228,125,112,215,252,255,199,15,252,172,192,6,156,168,133,40,131,168,141,56,3,155,32,59,180,104,255,143,39,8,96,173,121,96,248,253,254,2,84,251,23,90,230,0,173,99,1,245,5,217,160,74,136,12,195,63,95,33,17,43,97,203,192,32,160,206,192,192,163,0, +116,165,24,208,7,64,177,111,175,24,24,222,93,2,226,43,12,192,44,206,192,240,253,21,164,52,98,19,0,234,1,181,65,144,74,36,80,3,18,152,32,126,190,250,206,240,230,228,107,134,87,199,95,129,187,153,140,34,34,31,94,136,202,238,242,217,112,190,31,168,234,27, +90,66,64,175,22,104,214,83,0,8,32,90,37,0,92,13,61,22,164,198,29,7,20,115,89,41,203,136,215,75,253,41,19,126,255,214,250,255,239,63,204,130,58,2,12,18,14,146,12,156,242,60,144,94,26,161,136,7,141,222,252,1,70,250,95,96,216,177,242,50,48,8,233,3,109,224, +135,132,217,143,183,12,192,74,25,24,148,31,129,182,243,0,93,195,142,54,32,135,197,188,95,192,134,59,175,50,3,131,81,45,3,131,176,46,208,229,60,216,149,254,6,170,251,9,196,175,78,51,48,60,217,1,164,143,67,220,192,46,8,173,34,80,19,2,176,15,193,240,13, +216,123,120,177,255,5,195,135,203,239,24,24,185,88,126,190,16,83,216,157,114,226,89,223,139,207,223,128,14,100,248,142,163,52,160,89,3,17,32,128,104,145,0,144,35,159,25,173,200,103,67,42,238,57,65,184,222,207,222,194,237,221,149,2,246,247,111,229,88, +120,216,153,164,93,165,24,132,76,69,128,165,43,80,219,159,127,248,189,9,138,248,223,159,33,185,91,88,135,129,65,210,9,136,29,128,185,85,134,1,50,204,7,173,187,127,1,219,93,143,128,17,116,125,26,48,24,129,225,203,194,139,35,17,48,66,18,138,56,48,215,155, +180,66,114,252,203,135,12,255,79,109,5,234,191,193,240,255,229,35,160,235,57,25,24,197,229,25,24,84,140,24,24,141,93,128,9,69,8,90,98,124,131,148,10,55,231,3,19,194,81,72,73,4,178,7,61,33,48,3,19,2,208,95,111,79,190,98,120,182,235,25,195,239,95,255,255, +254,20,23,191,179,149,89,110,114,251,206,227,167,161,137,224,59,150,210,224,15,150,6,34,197,0,32,128,104,149,0,144,71,242,144,35,31,30,241,160,156,191,212,199,40,86,251,205,237,148,191,159,62,51,113,203,243,51,202,7,203,51,112,200,114,3,189,253,7,127, +38,5,73,130,114,26,51,59,36,210,149,35,129,185,94,23,26,233,160,224,3,38,138,15,175,33,197,47,168,200,22,145,130,232,121,118,144,129,225,108,53,36,135,131,19,1,90,255,16,148,152,68,76,24,24,108,103,129,139,255,255,7,87,51,252,235,74,0,22,208,191,161, +99,145,76,144,4,5,106,123,48,3,189,198,47,196,192,168,98,204,192,104,29,192,192,96,229,203,192,40,40,193,0,30,46,124,119,25,152,216,102,0,19,207,17,136,185,44,28,168,115,79,160,16,98,101,102,248,114,247,19,195,189,229,247,24,126,189,249,241,159,69,66, +232,235,5,22,145,249,169,7,238,172,252,243,239,223,87,164,106,1,91,105,64,181,68,0,16,64,212,78,0,140,104,131,58,44,232,185,158,135,149,153,71,73,86,70,184,89,133,35,93,246,249,77,127,6,22,102,6,62,101,1,6,89,127,89,6,54,73,96,186,248,242,7,127,255,235, +31,104,184,15,152,158,196,173,25,24,180,11,32,117,243,31,96,248,124,254,200,240,255,242,65,134,255,39,54,51,252,63,3,108,91,125,255,4,111,173,51,154,186,51,48,134,149,48,48,170,155,49,48,188,62,201,192,112,166,10,82,111,179,112,67,195,16,212,141,3,102, +58,46,105,6,6,199,101,144,34,255,248,38,134,191,237,209,192,196,2,204,128,220,60,136,158,6,220,41,255,33,141,193,159,223,33,209,34,36,200,192,232,155,201,192,20,152,15,116,19,176,45,192,10,244,246,155,19,192,132,48,155,129,225,61,176,173,240,23,218,104, +68,110,181,2,123,13,160,174,227,227,205,143,24,190,60,248,204,240,255,215,63,134,231,6,54,235,58,78,220,154,127,242,241,235,23,127,254,253,255,138,163,52,160,90,34,0,8,32,106,38,0,228,110,30,122,43,31,156,227,185,89,152,120,39,59,107,7,235,252,124,29, +195,252,230,165,56,151,20,15,131,148,167,44,3,159,6,47,52,231,254,67,157,164,133,7,246,63,72,206,2,181,184,165,93,129,57,62,12,216,48,211,6,230,176,39,12,255,15,0,35,236,232,6,134,127,143,129,141,177,183,239,33,234,185,128,214,50,179,32,34,234,51,48, +252,248,184,24,152,10,102,48,48,186,198,2,19,1,48,98,78,131,18,1,176,148,96,1,154,249,15,84,154,0,157,104,191,8,168,78,149,129,97,69,27,195,223,105,192,146,130,19,152,134,57,185,33,17,141,211,215,208,176,3,205,7,253,0,198,15,63,63,3,163,142,53,3,147, +123,18,3,131,177,27,48,241,0,253,246,233,14,3,195,229,94,160,189,167,160,61,10,22,68,136,177,49,131,19,215,135,203,31,24,94,238,125,202,240,229,241,23,134,255,138,202,79,231,63,248,220,56,237,250,171,11,208,146,0,185,145,72,213,68,0,16,64,212,74,0,232, +131,59,232,69,62,48,148,25,184,43,244,165,172,67,153,95,183,252,255,250,155,131,87,67,128,65,49,68,129,129,85,6,40,245,249,15,238,46,29,40,199,131,234,122,33,96,29,175,145,1,108,149,219,1,11,67,160,250,83,219,24,254,206,40,98,96,184,125,23,106,19,48, +80,217,216,17,195,182,40,67,188,160,32,252,194,192,40,42,205,192,212,182,147,129,65,17,152,120,174,77,98,96,184,49,27,52,237,7,12,214,55,64,179,83,25,24,12,128,137,226,225,53,134,191,73,218,16,115,184,120,240,71,62,70,215,243,63,164,68,248,250,23,28, +18,76,150,192,196,26,89,201,192,168,97,9,116,31,208,158,91,11,24,24,238,46,6,38,188,183,144,170,9,230,76,86,160,94,110,86,134,159,192,6,226,227,13,15,25,62,222,252,192,240,67,76,244,222,130,231,127,58,231,220,126,127,17,168,2,86,37,124,167,118,34,0,8, +32,106,36,0,244,200,103,65,234,219,115,65,49,79,166,142,148,97,20,239,183,10,206,79,31,101,133,141,69,25,228,252,229,24,152,120,128,233,228,235,31,44,185,158,17,146,235,65,93,49,54,62,6,6,133,16,6,6,157,92,112,11,254,255,131,171,12,255,119,45,100,248, +191,30,24,129,95,128,185,78,128,7,145,11,255,227,9,3,144,220,143,175,224,18,128,169,16,88,199,255,122,14,44,230,129,197,245,135,91,144,58,218,97,9,3,131,160,14,195,255,137,89,12,255,214,76,7,38,56,62,18,34,31,189,68,0,85,41,192,132,251,241,59,56,113, +50,250,103,48,48,69,0,19,151,184,44,176,90,0,150,2,103,234,129,254,126,140,84,5,65,1,176,235,251,247,211,47,134,199,235,31,49,188,187,240,154,225,135,128,200,195,121,175,24,218,230,222,122,67,179,68,0,16,64,76,84,206,249,200,117,62,172,177,199,157,102, +32,175,31,45,248,171,132,227,253,7,89,81,83,96,228,7,2,35,159,11,168,252,27,142,200,7,229,122,80,131,12,212,10,215,47,99,96,208,43,1,122,247,47,176,81,182,146,225,95,91,52,195,255,5,221,144,0,6,69,18,44,114,255,255,39,28,49,160,62,250,217,61,192,220, +15,172,2,120,20,25,24,68,205,33,137,76,200,0,88,116,3,187,125,95,129,237,8,96,117,194,0,74,152,255,201,44,85,255,67,123,30,32,187,64,238,3,54,22,255,175,156,193,240,111,66,22,48,247,3,75,116,17,96,59,196,164,5,232,55,113,200,120,5,114,177,7,108,255,48, +11,176,51,72,251,202,50,112,203,240,49,176,191,125,35,159,32,201,82,26,171,33,161,13,10,71,104,120,114,32,141,158,34,47,131,35,180,206,17,43,0,8,32,38,42,69,62,182,162,31,156,243,227,77,53,180,99,249,127,21,177,62,125,163,200,43,207,203,32,237,37,11, +158,147,103,248,241,15,211,185,160,72,2,245,231,65,117,50,168,174,183,232,99,96,144,15,98,248,127,251,28,195,191,73,192,156,217,17,7,236,102,1,51,131,16,48,44,56,184,73,207,161,172,192,18,228,221,11,134,127,39,54,65,248,18,86,64,49,160,57,98,230,224, +170,224,255,217,93,12,255,223,62,7,171,35,59,1,160,183,93,184,184,193,238,253,127,96,11,195,191,206,100,104,34,48,102,96,48,106,132,180,59,254,125,71,196,27,136,250,252,27,60,212,45,237,37,205,192,33,193,205,192,245,234,133,74,186,52,115,101,168,142, +130,58,52,17,112,65,19,2,59,210,160,26,19,3,230,58,71,162,0,64,0,81,171,4,64,238,234,193,235,124,31,107,83,133,120,254,159,185,108,143,158,171,114,73,115,2,27,124,50,12,204,160,41,218,95,127,49,157,9,170,231,65,117,49,168,88,212,202,97,96,48,111,7,246, +237,141,128,125,240,109,192,174,88,50,195,255,173,11,33,17,206,207,7,73,40,228,68,16,40,87,130,218,26,87,129,37,192,155,23,96,243,193,37,129,160,54,196,27,231,247,147,19,134,248,1,200,205,160,97,98,17,96,34,184,14,76,200,61,169,224,177,5,6,9,27,96,47, +6,232,207,223,223,33,126,71,182,19,88,50,242,104,10,128,171,73,54,97,78,6,142,39,79,85,178,100,216,10,28,117,84,101,145,18,0,108,20,149,5,169,36,32,217,225,0,1,196,68,133,220,207,130,54,180,11,78,0,110,38,250,114,197,242,28,57,60,183,239,235,115,203, +114,49,200,135,40,50,240,170,241,65,6,119,176,229,148,127,192,106,77,204,2,24,241,29,12,12,154,153,224,90,238,255,22,80,209,153,9,201,53,188,192,132,193,198,9,157,148,161,96,26,15,216,255,254,255,228,6,195,255,59,103,129,108,126,96,189,12,108,160,113, +75,64,226,234,230,105,160,29,108,212,201,253,24,211,135,140,224,246,202,255,235,103,24,254,245,167,131,27,165,12,138,126,192,94,135,50,164,212,67,142,59,144,23,191,253,101,224,213,226,103,144,3,141,141,136,115,50,240,220,187,101,88,163,35,84,32,43,42, +44,140,84,29,176,163,85,7,204,164,86,5,0,1,196,68,131,122,159,203,76,81,90,162,84,252,95,1,215,201,35,150,124,90,124,12,74,113,42,12,188,170,188,144,9,156,255,88,234,204,191,192,182,141,82,20,3,131,229,4,96,206,112,98,248,191,110,18,195,191,98,59,134, +127,51,129,245,63,176,200,6,247,195,25,25,169,51,248,197,6,76,163,31,223,51,252,63,183,27,152,251,128,237,8,5,127,160,249,178,12,255,159,221,3,230,204,7,136,238,35,173,0,15,176,36,56,179,147,225,223,212,60,96,180,9,49,48,168,197,65,198,8,192,109,57,164, +16,6,141,59,0,171,73,62,117,1,6,229,4,53,6,30,5,30,6,222,115,167,172,166,218,41,101,161,85,5,28,72,93,110,146,219,3,0,1,196,68,70,228,51,96,153,203,71,41,250,195,245,21,173,249,111,93,49,231,18,99,99,2,53,104,56,229,184,33,145,143,62,152,2,30,125,3,166, +126,25,79,6,6,221,2,96,252,242,0,115,124,58,48,226,171,25,254,223,187,0,105,232,177,178,81,55,2,64,221,59,80,14,187,117,1,146,184,4,52,129,98,64,167,63,190,14,204,117,159,161,179,122,180,156,27,101,4,15,39,255,63,178,142,225,255,93,96,123,70,198,17,88, +186,41,1,195,225,27,106,156,193,18,193,239,127,12,28,146,28,192,134,179,2,3,27,47,11,147,216,221,171,14,93,145,30,78,72,137,0,185,42,64,174,14,136,170,203,0,2,136,28,223,162,55,250,144,199,246,185,188,172,76,21,204,239,159,77,100,227,102,100,150,245, +149,103,224,81,6,22,251,223,255,224,142,124,73,123,6,6,227,102,96,11,252,39,176,145,23,197,240,127,195,60,160,201,192,220,192,206,77,187,220,8,52,246,255,171,187,12,255,223,63,131,204,35,128,192,155,39,216,171,39,90,0,80,91,228,231,119,134,255,59,230, +3,179,14,176,250,17,49,130,140,68,226,234,85,252,252,199,192,37,203,205,160,16,170,200,192,242,251,59,143,197,211,107,209,97,86,134,106,72,221,108,14,164,70,33,242,158,8,130,0,32,128,152,200,44,250,153,176,21,253,98,124,220,2,197,114,172,153,156,223, +191,139,138,217,75,51,240,25,3,139,184,159,127,177,148,220,208,161,87,94,96,3,204,162,23,40,207,202,240,111,235,76,96,255,126,19,120,64,4,60,206,78,43,0,10,80,80,43,31,212,218,7,69,58,76,248,221,43,160,175,232,184,30,19,88,18,253,191,115,30,18,22,66, +26,144,73,163,255,127,113,171,255,251,143,129,87,155,31,216,76,18,99,100,123,242,88,41,89,134,61,142,151,155,139,15,169,187,13,107,15,160,55,10,241,150,2,0,1,196,68,102,228,163,207,236,113,177,48,51,243,116,5,58,4,241,157,60,102,193,33,207,203,40,98, +42,2,212,192,136,88,128,137,234,27,200,92,187,73,51,164,213,15,236,126,49,44,1,246,141,121,25,105,95,7,131,0,40,129,129,18,230,147,187,144,117,3,32,240,241,53,3,93,1,40,52,127,253,128,132,15,151,4,98,65,9,158,118,36,19,80,147,144,129,48,176,42,96,98, +20,186,114,194,106,98,176,99,32,40,220,209,18,1,73,237,1,128,0,34,181,4,64,111,248,193,139,254,0,59,11,37,157,115,219,163,153,120,153,24,248,128,173,125,86,208,170,220,31,88,186,123,224,249,246,79,192,126,190,27,176,27,102,8,238,18,253,155,152,205,240, +255,203,55,72,177,255,159,14,185,144,17,210,14,248,255,236,54,176,222,255,4,17,3,45,222,101,26,136,229,241,36,12,224,1,171,81,78,96,85,32,110,37,14,26,62,96,81,191,127,214,59,211,197,194,0,71,215,144,133,152,174,33,64,0,49,145,144,251,209,39,122,224, +197,191,154,8,191,72,182,208,143,44,96,93,197,206,163,192,207,32,233,40,1,46,178,48,235,125,88,31,7,104,132,124,0,88,254,255,206,133,192,6,31,176,95,204,207,75,97,23,143,196,134,24,200,105,207,239,67,26,126,224,137,168,111,84,24,22,33,177,42,98,97,3, +175,15,96,248,241,158,129,168,149,172,160,82,128,133,137,65,196,90,156,65,64,155,143,129,237,241,11,105,95,97,230,32,3,21,69,113,180,4,64,116,85,0,16,64,164,84,1,204,216,38,122,128,69,16,119,151,155,65,28,223,229,179,250,160,212,169,16,34,199,192,204, +203,6,153,217,195,150,251,255,0,139,61,110,73,96,195,7,152,251,127,255,100,248,191,103,33,176,107,52,0,57,15,228,11,80,183,239,235,71,72,216,254,252,70,95,251,65,153,3,52,41,5,138,213,119,87,17,3,70,132,0,176,161,202,38,194,206,32,27,32,207,192,165,192, +201,32,112,248,144,85,165,149,90,144,152,160,0,63,218,80,49,11,218,80,49,86,0,16,64,164,148,0,232,131,62,224,220,159,19,224,174,39,127,227,184,15,104,173,188,184,173,4,3,155,60,47,142,49,126,100,91,217,33,141,30,96,253,251,31,148,3,153,153,232,187,31, +6,60,3,199,12,108,248,61,99,248,15,77,0,144,109,62,244,205,253,204,142,209,192,146,18,152,251,223,156,5,109,105,37,126,252,6,216,53,4,101,54,81,43,9,6,70,14,38,6,197,155,103,189,99,109,141,244,208,122,4,200,137,128,17,87,41,0,16,64,76,36,68,62,214,201, +30,255,191,79,34,255,126,251,197,196,173,192,203,32,108,44,194,192,240,233,55,129,6,24,208,163,223,159,67,134,125,217,57,24,24,117,108,25,24,190,252,165,115,253,251,31,226,142,47,192,158,200,231,119,116,46,122,128,254,252,1,180,87,203,156,129,65,31,232, +247,23,39,129,97,118,31,178,94,145,216,92,0,222,229,196,192,32,160,43,192,32,160,195,203,240,255,201,27,94,125,33,46,61,30,78,14,30,2,19,70,24,0,32,128,136,45,1,176,77,246,112,24,171,43,139,241,188,125,166,204,200,202,196,32,105,43,14,217,149,243,231, +31,158,132,12,93,12,1,26,250,124,186,27,220,31,102,242,207,2,58,25,180,210,246,59,237,7,97,176,181,3,96,9,128,46,123,35,160,51,157,160,0,13,175,4,218,255,139,129,225,209,22,232,10,102,180,81,92,240,34,152,127,72,237,34,52,247,253,254,203,192,42,204,193, +32,100,40,10,238,72,73,125,124,165,163,40,42,40,132,214,22,96,37,84,10,0,4,16,19,137,185,31,185,241,199,30,166,167,100,252,239,253,55,14,62,37,94,6,62,45,65,96,202,38,166,24,101,132,204,130,221,93,2,233,13,232,59,48,48,197,149,51,48,254,252,13,89,218, +69,175,68,192,8,169,118,254,127,122,139,40,153,104,93,13,129,74,185,143,63,24,24,93,163,25,24,141,157,33,43,146,222,92,0,134,40,15,116,129,43,48,60,126,0,197,126,190,133,132,13,12,131,196,126,127,66,77,8,255,33,37,1,191,150,0,3,175,26,55,3,239,173,43, +234,246,122,90,202,204,76,76,176,238,32,59,49,165,0,64,0,17,234,116,51,225,73,0,28,134,127,63,88,49,254,250,198,46,102,165,6,217,12,241,243,31,145,197,47,104,237,31,176,229,127,109,10,120,21,14,99,80,17,195,255,71,215,25,24,214,172,97,96,144,252,7,25, +175,167,117,119,16,148,227,65,206,125,15,237,255,179,178,50,208,52,5,128,34,255,21,48,18,213,53,24,152,146,219,33,98,247,128,254,253,120,11,50,37,205,12,244,51,143,60,3,3,159,34,176,108,87,131,172,108,6,137,129,102,11,223,94,130,44,61,255,8,236,182,178, +242,64,212,131,74,6,96,120,51,11,176,50,8,26,139,51,124,186,126,143,221,85,128,201,126,13,47,247,141,23,31,63,131,134,21,97,139,73,127,65,227,238,47,82,87,3,238,81,128,0,98,33,179,235,199,94,224,96,100,200,117,247,186,170,160,38,63,35,143,154,0,100,138, +151,164,58,24,216,94,121,176,22,104,146,48,3,131,102,58,3,83,106,63,195,191,95,255,192,99,228,12,223,127,67,102,255,192,203,187,254,211,56,1,188,132,112,217,56,104,151,230,64,161,248,246,51,3,163,130,60,3,83,201,108,96,15,72,154,129,225,254,74,6,134, +27,51,24,24,196,45,32,11,82,64,115,2,194,192,118,28,139,48,34,151,255,254,5,153,11,81,8,7,150,2,207,128,122,128,97,115,103,57,48,172,161,123,28,64,30,248,245,159,65,80,87,144,225,157,6,47,131,212,181,99,22,14,202,178,59,87,95,184,249,249,239,191,255, +63,144,74,128,95,208,76,12,219,95,0,79,4,0,1,196,66,194,192,15,188,1,200,198,194,194,225,206,253,219,155,227,245,87,126,9,71,53,240,34,93,134,63,68,134,4,124,217,2,51,36,21,223,154,11,12,156,51,192,146,160,154,129,169,28,200,246,207,96,248,55,191,134, +225,255,133,83,192,68,192,6,89,231,71,171,152,1,25,11,234,133,128,204,231,228,165,93,66,123,255,153,129,201,220,145,129,49,119,18,48,50,117,24,24,110,47,2,118,65,143,50,48,88,79,3,38,6,125,200,172,32,168,186,63,189,141,225,255,197,3,12,255,239,93,130, +12,80,253,249,5,89,213,44,163,194,192,24,215,196,192,168,153,3,89,12,123,44,23,50,131,10,42,73,129,109,1,102,126,54,6,126,13,65,134,207,183,31,177,199,232,242,249,109,190,202,122,231,235,207,95,223,144,18,0,8,255,70,138,83,120,110,5,8,32,66,37,0,122, +235,31,156,0,210,92,44,117,120,159,93,148,103,23,98,103,228,16,225,196,49,220,139,110,220,63,200,248,63,168,72,67,94,244,15,170,139,65,235,245,255,252,134,204,11,152,184,50,48,169,25,49,252,91,63,137,225,255,242,14,96,105,240,5,180,152,156,54,137,128, +17,218,253,3,37,68,80,3,154,218,3,81,160,18,236,3,48,34,197,196,16,145,15,170,250,64,107,0,20,67,32,43,146,95,62,98,248,183,174,153,225,255,201,173,64,246,83,232,178,119,38,104,12,48,66,6,203,110,159,5,102,136,131,192,210,99,46,120,137,59,131,70,26,3, +195,213,137,144,238,244,127,200,126,69,14,73,46,6,22,62,86,6,201,251,231,77,204,149,229,36,246,93,187,251,5,41,1,192,50,240,31,244,18,0,32,128,88,112,4,11,3,190,198,159,141,36,191,9,235,221,79,34,156,138,2,12,140,160,37,216,132,178,25,120,166,11,104, +156,32,176,136,19,183,66,172,136,5,1,208,214,173,247,87,33,107,231,119,251,3,27,133,229,12,12,114,190,12,76,241,141,12,12,230,62,12,127,123,147,129,69,223,101,96,34,224,162,254,72,29,248,92,160,223,144,86,56,55,63,245,115,254,87,96,233,194,199,11,137, +124,57,45,136,56,168,158,7,225,47,31,24,254,111,155,198,240,111,69,39,176,4,4,118,137,185,129,65,203,2,91,79,139,214,10,99,97,5,207,85,252,235,140,103,96,234,63,204,192,168,18,202,192,240,28,152,105,62,0,195,140,85,0,60,175,193,43,207,205,192,33,198, +197,240,229,198,71,150,24,123,93,43,96,2,120,132,150,0,144,27,130,240,68,0,16,64,44,68,54,254,224,137,192,92,77,81,92,252,237,35,45,160,17,140,188,202,188,12,76,44,140,56,134,124,25,32,107,249,255,254,133,212,115,160,84,43,98,138,40,122,209,123,11,63, +94,0,219,4,27,128,13,163,85,192,196,112,141,129,65,53,6,168,199,148,129,185,109,43,195,191,153,165,12,255,143,109,130,116,155,152,89,169,215,101,3,25,243,251,39,56,1,48,114,243,1,11,0,42,153,11,42,173,64,43,126,128,117,61,168,206,103,52,245,132,14,54, +1,195,226,243,123,134,255,91,103,51,252,223,56,153,225,255,243,231,144,136,23,224,197,29,134,240,178,154,21,162,119,239,98,6,198,132,38,96,130,242,130,236,64,2,149,90,191,25,25,152,4,217,24,64,241,241,245,193,71,6,181,23,87,44,129,189,129,245,127,255, +253,99,67,27,16,98,70,175,6,0,2,136,133,196,238,31,155,139,188,176,26,231,187,103,226,108,124,76,12,188,74,124,184,227,2,84,148,129,182,110,105,166,0,91,190,41,144,72,127,253,12,188,123,7,60,11,6,213,200,40,171,193,192,32,42,203,192,192,197,11,89,247, +15,194,31,128,9,224,205,121,96,238,249,0,148,211,100,96,170,89,193,240,255,248,102,134,127,139,129,165,194,93,96,105,193,244,15,50,107,72,105,151,17,60,35,247,29,82,10,128,118,243,80,101,136,23,24,174,63,127,130,19,47,83,222,84,6,70,117,104,162,255,244, +14,188,213,236,255,178,86,96,143,231,49,208,62,102,72,196,255,255,79,56,242,97,37,10,200,187,183,207,65,134,141,65,37,41,168,167,240,29,212,136,229,6,87,5,252,106,124,12,111,78,177,50,112,191,122,32,239,103,97,40,191,254,216,217,207,72,25,24,219,220, +192,127,128,0,98,33,162,248,71,169,255,85,24,191,169,49,191,124,38,192,163,35,192,192,34,196,129,189,231,4,174,199,128,218,180,243,24,24,148,163,128,69,225,39,200,10,152,85,221,12,255,239,92,195,28,147,23,145,1,7,20,163,29,176,94,4,209,66,114,208,34, +243,39,180,177,195,205,192,104,9,172,22,244,29,128,102,244,0,115,193,18,200,56,62,104,80,9,84,108,50,145,153,16,64,157,12,240,148,44,48,210,120,5,33,103,2,81,2,64,165,9,104,18,220,10,232,214,252,233,192,86,189,36,36,65,60,187,195,240,111,74,62,48,12, +118,66,134,104,132,121,17,37,5,73,9,150,153,225,255,67,96,248,129,150,175,73,201,65,26,132,224,253,5,60,224,106,0,180,104,132,93,148,139,225,27,176,20,112,226,251,98,176,30,216,196,102,192,92,51,200,140,212,100,103,4,8,32,22,28,197,63,250,228,15,184, +4,48,82,144,22,145,102,103,81,5,69,58,191,26,63,3,11,39,51,150,4,240,31,146,90,229,188,33,145,255,234,33,195,191,37,45,12,255,55,204,129,152,204,195,133,212,6,129,110,237,126,243,132,225,255,19,32,222,11,116,178,148,4,3,163,161,51,3,163,145,11,3,131, +172,38,3,35,104,99,167,24,100,123,54,35,176,148,96,76,0,150,2,206,209,12,255,87,180,49,252,63,123,136,225,255,135,39,144,163,97,64,99,7,132,230,212,177,249,20,20,105,160,165,103,124,34,144,46,215,255,255,36,86,49,140,144,72,6,38,36,70,113,96,164,184, +37,48,48,197,214,1,205,4,134,241,189,139,12,255,175,28,5,54,242,250,129,237,152,59,192,64,227,130,172,69,32,183,65,11,238,81,188,6,250,123,39,176,103,144,13,76,72,192,238,227,243,253,208,237,241,76,192,58,153,149,129,15,88,42,127,189,251,145,65,135,143, +213,152,155,131,125,211,215,31,63,145,207,84,68,223,71,240,31,32,128,88,136,40,254,225,85,128,179,146,132,42,255,139,59,138,108,2,204,12,220,138,192,226,31,52,184,129,190,140,10,20,24,92,192,148,175,145,14,172,179,62,49,252,155,86,200,240,127,39,48,98, +5,216,17,1,140,82,216,176,64,138,127,46,168,222,119,47,24,254,111,89,10,212,179,20,210,128,82,3,150,8,206,81,12,140,186,54,192,190,178,58,68,139,172,26,3,99,233,2,6,198,43,71,24,254,29,90,203,192,112,96,37,195,255,215,192,250,148,157,21,218,109,36,33, +1,252,252,1,73,0,160,220,10,90,117,252,227,43,241,9,0,164,14,84,130,252,250,205,192,168,109,193,192,148,210,14,30,217,252,255,244,54,195,255,77,192,18,224,240,122,32,251,1,36,36,249,120,200,203,245,232,246,253,249,9,172,70,129,13,65,127,96,2,16,2,150, +0,28,194,64,63,188,135,108,113,3,205,15,104,241,51,188,58,254,130,129,255,249,61,21,47,93,21,249,213,167,175,126,68,43,1,144,19,0,3,64,0,177,96,41,254,209,143,101,133,215,255,138,130,60,50,140,15,63,114,115,104,241,49,176,242,179,226,110,245,131,234, +38,78,73,134,255,123,128,17,121,8,216,120,227,101,65,139,124,44,141,38,88,151,16,156,24,254,67,138,229,239,95,25,254,159,218,199,240,255,252,62,112,66,96,176,13,0,86,5,126,12,140,138,58,16,245,58,54,12,76,64,204,0,236,26,253,219,60,11,220,143,102,248, +12,108,124,113,115,19,31,137,160,21,185,32,187,248,69,33,165,200,143,47,68,54,30,64,155,78,129,85,44,27,43,3,163,95,26,3,83,120,25,3,131,164,50,195,255,125,75,25,254,45,3,118,103,175,159,135,132,26,15,133,185,30,219,252,5,168,250,251,12,140,87,30,96, +162,101,23,133,12,41,131,98,10,88,13,112,74,114,2,227,134,131,225,219,243,111,76,118,202,188,90,171,129,46,65,235,9,160,180,3,0,2,136,5,199,224,15,70,9,32,201,207,195,35,254,251,179,44,72,148,83,156,11,114,94,15,186,167,64,45,82,144,35,37,44,25,254,127, +5,70,222,161,213,144,17,66,30,94,226,3,0,166,142,9,186,51,23,52,178,253,231,23,195,255,235,167,129,13,160,211,12,255,15,172,6,38,2,111,6,38,79,96,247,80,66,17,162,214,212,131,129,73,221,140,225,223,169,173,12,255,215,79,102,96,184,2,84,203,205,1,105, +57,227,179,23,150,131,127,3,115,48,104,32,8,188,39,128,136,57,4,80,162,121,15,212,167,164,194,192,20,85,206,192,232,145,8,113,239,182,57,12,255,38,20,3,35,2,216,247,23,228,66,28,23,67,205,49,12,80,12,125,120,7,44,250,129,237,0,85,77,96,248,0,19,192,7, +88,98,254,7,90,161,193,192,37,193,193,240,253,217,23,6,5,166,223,170,12,168,39,176,161,119,7,255,1,4,16,19,17,9,0,172,81,145,151,93,128,251,251,103,17,208,6,88,78,113,14,6,38,86,28,221,63,208,193,11,82,142,224,134,202,255,139,251,32,91,172,201,245,63, +44,240,64,93,63,62,94,72,17,125,247,2,195,255,229,237,224,131,27,254,239,95,129,24,188,225,19,98,96,114,137,101,96,42,95,200,192,96,231,15,108,28,253,128,12,34,225,42,9,64,110,2,173,67,0,45,4,1,13,78,1,213,49,242,8,225,95,152,9,106,108,254,254,1,222, +110,206,232,236,199,192,84,189,136,129,209,43,5,98,220,202,46,134,127,179,171,128,242,192,42,132,159,7,58,217,68,139,193,43,38,200,1,24,111,159,130,206,173,5,86,1,34,136,182,15,216,79,140,192,26,152,11,172,146,247,253,51,105,17,94,110,46,124,37,0,64, +0,49,17,104,3,192,27,130,202,210,18,66,252,255,126,137,177,112,49,130,143,96,69,108,195,70,11,85,208,106,31,78,57,134,255,55,142,131,135,64,25,216,217,169,51,201,242,31,122,42,7,104,203,54,11,59,176,113,5,172,255,39,100,51,252,171,242,2,150,52,171,16, +30,144,211,100,96,46,156,14,108,35,76,3,70,168,32,120,12,30,94,50,161,187,21,148,67,127,124,99,248,255,27,186,36,91,80,28,82,29,160,15,82,128,187,96,64,255,126,1,230,236,119,191,24,24,195,115,25,152,10,128,118,104,90,130,39,177,254,213,249,51,252,155, +95,207,240,255,27,232,108,33,78,218,206,42,2,221,2,114,239,255,247,47,32,124,80,27,128,1,169,148,1,102,74,208,241,184,160,41,122,30,198,191,66,190,6,234,138,104,221,64,148,68,0,16,64,76,120,34,31,165,26,16,99,103,22,100,126,245,84,136,13,216,152,3,47, +249,194,230,75,80,35,14,52,204,249,235,63,100,7,238,95,104,81,78,109,0,74,8,236,192,128,254,5,172,102,206,238,97,248,215,155,197,240,175,198,15,216,86,128,238,237,19,146,100,96,242,2,214,203,29,192,214,178,3,176,55,242,17,152,203,63,126,198,156,87,7, +23,231,255,33,231,13,128,19,128,24,226,116,49,228,200,7,53,20,95,126,2,87,73,76,37,61,192,198,94,39,176,209,40,197,240,111,59,176,200,175,3,218,123,106,59,244,148,48,118,218,79,41,131,236,1,245,92,160,147,88,224,147,201,96,231,33,49,66,214,9,112,138, +178,3,75,104,96,24,125,249,202,174,202,250,71,6,109,44,0,229,70,21,128,0,98,194,51,11,136,114,76,187,156,162,146,48,195,151,63,204,108,252,236,192,82,158,5,187,71,65,186,64,39,116,129,14,188,122,117,159,198,107,44,25,33,117,60,168,225,246,7,152,35,78, +111,7,70,70,0,195,191,246,24,134,255,87,143,65,18,158,186,9,3,83,229,18,6,166,166,165,192,86,186,17,164,129,8,106,241,35,15,32,129,252,1,93,15,200,40,38,135,178,67,11,50,114,247,25,28,177,76,1,177,12,204,125,7,24,24,67,139,193,185,239,111,107,20,195, +255,201,133,64,127,62,129,84,77,44,204,12,116,1,32,183,255,249,3,236,254,66,167,177,65,39,146,177,176,35,170,194,191,160,179,147,217,24,216,128,248,223,247,63,140,82,82,82,98,88,114,63,124,68,16,32,128,88,176,68,60,122,59,0,140,69,63,189,144,2,205,250, +177,9,115,0,237,99,198,82,255,255,135,28,209,6,58,86,237,219,23,72,17,197,74,143,0,97,68,228,190,127,127,192,103,8,252,63,190,137,129,81,82,137,129,49,2,216,64,115,140,4,98,96,55,210,200,21,60,185,244,111,105,31,48,39,3,19,1,7,23,162,85,253,17,186,40, +68,92,17,50,24,244,31,218,11,1,230,52,70,183,104,200,188,4,232,100,48,80,154,88,217,201,240,127,13,208,12,208,66,18,208,6,19,198,129,184,115,3,148,48,223,64,19,128,0,100,82,8,180,152,6,86,85,178,49,49,112,136,2,123,2,47,190,51,242,126,120,46,140,165, +10,128,119,5,1,2,136,9,71,238,199,72,4,44,207,238,243,50,130,142,91,231,102,129,52,0,177,109,242,4,173,77,226,146,129,172,252,5,77,103,50,209,51,80,160,245,52,43,7,120,168,244,255,195,43,12,255,154,163,24,254,21,219,131,187,145,160,227,220,24,211,186, +25,152,234,23,3,59,203,226,144,177,122,6,232,154,128,79,208,220,36,42,13,73,72,160,99,94,128,13,79,166,172,126,112,9,2,238,109,92,58,196,240,175,192,150,225,255,204,10,96,209,250,17,146,235,25,153,24,6,4,128,194,30,180,174,16,188,194,158,11,122,138,41, +210,9,232,76,140,224,19,212,255,51,252,99,100,124,243,148,19,91,227,15,86,23,2,4,16,190,70,32,74,2,224,226,229,231,248,247,253,31,3,51,55,51,142,85,188,255,32,39,114,130,122,1,63,126,128,251,240,144,110,208,0,4,16,40,103,179,114,130,119,21,255,191,0, +140,184,18,103,134,127,147,114,192,227,254,140,46,49,12,76,93,187,24,24,244,108,129,17,253,11,82,228,127,131,158,44,42,36,5,9,65,69,29,96,181,177,158,129,49,48,143,129,225,205,83,134,255,179,202,24,254,150,186,48,252,191,124,2,178,83,153,133,149,97,192, +0,172,49,11,170,182,64,109,19,80,152,51,49,99,38,0,110,54,96,135,134,9,40,205,203,138,165,68,135,183,3,0,2,136,9,207,80,48,74,66,224,22,145,226,130,196,49,43,246,173,218,224,57,117,97,232,152,248,87,136,3,153,153,24,6,28,128,78,233,98,231,96,248,191, +126,6,195,223,134,96,6,134,59,231,25,24,21,180,25,152,65,13,196,16,208,185,67,60,144,105,91,96,189,202,200,47,2,20,43,98,96,154,116,130,129,209,208,9,216,144,61,206,240,183,196,133,225,223,194,94,200,146,49,126,62,134,65,3,126,65,187,175,160,243,141, +64,243,46,104,93,78,22,80,70,101,98,96,228,22,22,97,71,107,216,35,199,45,3,64,0,177,96,201,253,200,227,1,240,226,130,237,251,39,46,208,104,35,19,43,19,142,235,22,255,66,150,119,129,152,160,34,244,23,168,158,165,82,23,144,226,238,35,208,155,188,192,162, +242,232,78,134,127,119,129,9,32,169,13,216,46,136,96,96,202,232,99,248,15,154,107,224,21,134,168,19,16,101,96,2,202,129,86,10,255,63,190,1,88,220,151,51,48,60,124,4,172,26,120,32,11,47,254,253,27,60,9,0,116,182,1,108,201,24,19,43,70,21,193,12,108,167, +49,49,255,103,96,250,254,133,141,1,251,245,121,224,120,6,8,32,124,211,193,200,235,2,24,25,255,254,102,6,149,52,76,176,226,31,219,24,0,27,116,81,197,151,15,208,69,63,131,232,70,82,80,125,45,200,203,240,255,245,43,134,255,45,41,12,140,87,79,50,48,69,150, +2,115,124,9,102,97,6,154,91,232,201,98,248,15,26,30,16,102,67,172,95,24,44,23,190,129,47,196,248,5,193,160,200,103,100,197,72,244,140,108,140,144,136,252,251,135,153,1,247,29,138,12,0,1,196,132,99,58,24,227,230,205,255,127,129,21,10,172,32,193,58,6,240, +31,114,228,10,116,238,27,178,254,116,176,36,0,104,236,129,119,33,129,186,123,192,198,222,157,75,208,237,217,12,24,171,229,25,117,108,24,24,147,27,25,24,157,220,128,165,26,48,247,127,250,2,105,116,49,12,162,68,13,26,11,97,134,174,243,68,31,189,4,141,113, +1,27,196,140,144,163,237,113,93,158,9,246,12,64,0,225,91,18,134,154,32,160,119,235,225,14,224,127,144,37,203,160,65,41,216,118,43,70,166,129,143,120,240,162,15,96,23,233,59,48,183,72,72,49,48,218,4,50,48,89,251,51,48,40,233,3,139,124,96,23,249,217,109, +96,143,225,6,176,155,232,12,140,108,46,134,255,123,151,129,207,243,99,140,171,99,96,4,246,100,254,159,220,198,240,127,223,114,134,255,103,119,51,48,124,0,77,52,209,120,161,42,177,13,65,94,1,72,213,245,243,14,228,160,106,92,9,19,18,111,140,56,170,121, +6,128,0,194,53,14,128,145,8,254,51,49,130,189,140,219,223,255,33,235,216,255,65,91,168,255,6,56,179,192,70,204,62,3,35,158,19,152,16,157,67,25,152,130,242,192,199,184,66,182,103,125,101,248,191,125,54,195,255,117,179,193,61,100,70,77,115,96,196,2,219, +185,243,170,192,71,190,50,154,58,49,48,133,150,128,219,10,140,230,94,224,4,240,15,52,247,112,100,61,176,68,248,12,89,182,206,200,68,255,132,0,179,15,20,249,160,54,214,167,15,144,99,245,208,23,197,252,255,7,235,17,252,199,87,116,1,4,16,161,101,225,112, +204,200,204,242,23,126,9,19,3,150,113,117,112,63,28,58,229,11,154,48,25,168,226,146,17,186,64,227,195,55,200,250,74,123,111,6,70,231,104,112,171,158,17,60,214,255,135,225,255,142,121,144,92,125,251,12,3,195,139,47,12,140,38,166,144,101,234,160,69,28, +160,217,193,119,47,193,83,217,255,110,3,27,140,174,113,12,140,158,201,12,140,182,193,12,76,6,142,12,255,237,67,25,254,47,107,103,96,184,124,1,88,26,48,65,102,44,25,24,232,151,16,254,67,59,111,130,144,147,205,24,126,188,131,28,129,207,136,122,26,249,63, +208,213,119,32,200,196,140,183,229,10,16,64,68,15,99,253,101,227,252,3,58,2,255,255,159,191,72,43,202,208,26,89,204,208,1,9,80,227,100,32,74,72,80,157,247,21,84,95,3,27,65,38,192,156,30,86,202,192,164,105,1,153,228,1,185,236,240,26,6,134,53,253,12,255, +238,92,6,207,35,128,71,242,64,137,4,212,183,7,5,42,120,107,26,208,12,78,118,112,215,234,255,147,91,12,255,23,214,51,48,2,19,11,163,123,60,3,163,111,22,3,163,125,24,3,3,208,76,208,250,3,134,45,211,25,254,191,2,70,0,15,27,100,210,139,30,137,224,63,100, +245,19,163,4,100,100,18,188,209,22,52,240,134,220,19,0,250,225,31,232,178,75,80,212,179,114,224,221,177,3,16,64,196,38,128,255,223,24,153,63,115,252,134,28,211,143,181,7,0,187,72,9,20,8,127,254,208,57,226,153,32,137,238,205,15,6,70,17,30,6,198,194,94, +200,25,254,160,58,30,228,186,215,143,25,254,47,110,2,230,234,85,144,250,18,212,117,130,13,5,131,67,129,3,98,198,207,175,208,201,32,38,232,240,50,7,100,11,251,227,235,12,255,231,84,131,231,251,153,252,51,25,24,253,114,24,152,226,235,25,24,220,227,24,254, +111,154,193,240,111,235,12,200,204,39,104,38,16,188,6,129,134,221,69,208,10,102,46,1,6,70,41,85,104,143,235,41,100,111,3,242,82,123,240,17,76,127,65,139,178,255,255,96,100,254,129,207,56,128,0,98,66,138,65,124,152,225,243,131,27,191,65,231,251,254,1, +93,158,240,15,219,186,57,70,164,121,233,63,244,41,1,224,197,253,39,240,74,92,38,255,120,6,166,41,167,24,24,61,146,192,145,15,58,123,224,223,210,22,134,127,5,54,192,98,127,1,80,253,31,72,78,69,174,47,65,51,197,224,190,52,19,176,219,247,13,58,29,140,28, +66,204,144,147,60,64,151,69,60,189,205,240,111,66,41,195,191,166,48,96,206,127,200,192,32,163,198,192,152,214,201,192,60,249,56,3,163,87,20,100,8,25,52,101,76,242,186,66,18,235,0,97,96,137,166,160,7,76,244,111,33,27,77,208,27,92,208,107,112,25,153,25, +25,190,63,125,240,7,41,142,49,0,64,0,177,16,89,235,48,252,230,21,250,198,240,237,61,208,224,223,12,255,127,255,3,27,142,181,175,77,175,250,16,52,171,247,227,39,120,249,23,147,83,32,3,99,88,25,184,104,6,131,63,64,55,110,159,7,142,124,134,167,247,129,69, +58,7,100,250,24,91,24,128,15,139,96,135,46,180,248,130,56,52,10,91,147,8,164,14,148,193,15,173,6,159,43,12,110,32,250,102,48,48,42,27,48,48,149,47,98,248,15,76,120,255,103,149,130,79,52,7,223,29,192,12,93,163,72,237,6,32,232,100,17,113,25,200,189,7,160, +4,0,191,136,226,63,164,243,254,231,31,195,239,47,191,193,252,63,92,188,160,229,75,56,35,4,32,128,88,176,4,7,86,252,89,66,233,221,255,199,119,24,126,125,248,9,172,6,254,51,176,112,35,175,192,133,174,238,253,250,140,129,65,10,116,254,143,54,100,238,233, +255,63,234,119,5,65,21,27,168,174,150,80,4,47,140,100,50,247,97,96,144,86,1,7,206,255,55,192,226,112,55,48,34,118,1,241,163,27,144,225,91,30,30,124,25,0,26,10,208,107,223,64,221,87,80,67,144,80,238,5,45,31,3,29,111,179,97,38,195,127,160,125,140,106,38, +224,158,2,99,112,1,3,227,244,115,12,12,247,175,128,79,34,253,183,127,57,3,195,237,139,208,129,88,42,108,104,1,133,39,143,32,48,193,199,64,252,243,108,63,164,13,128,124,253,13,120,225,40,232,252,13,80,201,207,252,255,151,152,60,48,85,63,194,25,183,0,1, +196,66,32,231,195,241,163,79,223,95,27,254,103,252,255,235,195,47,198,63,63,255,0,237,68,155,255,6,77,139,130,46,77,2,49,21,245,24,254,179,51,65,2,147,133,74,39,125,130,138,102,240,138,99,62,96,139,60,136,129,49,177,5,114,121,19,8,0,35,30,212,69,251, +191,182,143,129,225,49,48,17,114,49,66,22,134,254,39,98,153,56,184,4,96,133,84,11,160,129,34,80,201,66,240,168,58,232,240,50,104,153,26,168,87,113,241,48,195,255,83,135,25,24,14,174,98,96,74,106,103,96,212,182,4,38,134,66,6,230,160,66,134,127,7,129,238, +2,182,29,24,174,30,135,108,64,1,15,167,50,145,151,24,64,183,150,171,26,50,48,152,121,0,187,127,183,32,219,195,254,51,96,44,135,255,15,140,31,208,37,215,12,204,204,255,95,253,252,247,14,91,149,14,3,0,1,196,66,40,226,97,248,249,221,155,223,152,196,4,127, +253,254,252,133,253,47,232,146,7,17,180,162,13,148,194,63,221,3,223,150,5,94,138,197,47,12,153,103,167,244,232,117,80,34,2,69,10,27,47,3,163,1,48,96,65,125,115,208,68,13,184,97,242,14,178,155,118,97,3,195,255,171,151,33,75,203,133,121,160,37,18,9,199, +175,177,113,65,26,176,160,241,11,240,168,26,43,241,69,50,40,66,65,139,94,185,129,236,27,231,25,254,149,122,48,48,154,185,128,103,18,25,53,204,24,152,28,34,24,254,131,240,178,54,134,255,199,54,2,51,227,77,200,68,14,248,160,12,102,226,87,76,253,131,158, +22,98,236,10,241,215,203,227,160,134,25,228,172,0,100,127,130,238,40,124,241,11,88,74,255,101,96,230,229,252,247,244,249,211,15,12,152,87,209,194,3,7,32,128,88,8,68,60,252,230,202,23,12,236,31,191,137,72,189,99,184,117,65,242,247,7,96,181,34,199,141, +86,2,128,46,128,120,6,217,176,200,35,5,217,238,245,250,53,100,85,47,57,141,59,80,196,131,234,120,14,14,240,218,59,70,159,116,240,84,46,220,177,55,79,51,252,95,217,203,240,127,255,74,200,148,174,16,242,121,2,36,172,64,6,101,68,80,143,0,164,23,180,77,12, +84,210,176,50,146,87,55,243,242,66,86,235,28,219,3,44,17,246,0,19,172,45,216,205,224,75,171,162,170,24,24,194,203,129,238,93,202,240,255,40,48,33,220,56,11,62,164,10,188,113,150,25,186,195,9,20,134,176,5,46,48,115,193,139,83,126,131,47,175,98,52,112, +96,96,116,3,54,112,191,220,97,96,184,187,12,218,240,102,97,64,153,10,102,101,102,248,254,250,7,48,1,252,97,248,195,199,243,227,220,15,222,39,12,168,55,144,162,36,6,128,0,194,87,2,160,104,122,240,233,199,167,247,12,76,111,57,126,49,72,254,4,90,0,190,106, +134,137,1,245,122,55,208,128,196,211,189,12,12,234,197,12,140,58,118,192,220,121,14,218,37,98,36,46,210,161,13,56,240,122,2,144,223,100,180,129,245,124,42,3,163,107,60,100,232,19,60,240,241,5,28,128,255,22,53,3,3,17,152,155,132,160,203,194,254,145,185, +252,26,100,45,59,52,1,252,248,6,221,55,75,230,125,4,176,133,171,66,188,224,110,233,255,179,192,170,225,244,97,96,137,101,1,44,185,10,25,24,181,128,9,217,37,14,140,25,174,30,1,202,237,4,175,105,4,159,84,254,245,29,100,16,10,189,185,2,98,115,177,65,134, +176,211,187,33,213,206,137,70,200,105,33,28,162,12,24,119,35,1,193,183,231,223,129,5,217,127,134,143,28,188,111,142,29,185,241,26,45,62,81,50,57,64,0,161,151,0,255,176,69,62,8,63,126,255,233,235,27,38,214,183,146,140,160,27,215,190,129,79,243,96,6,223, +120,245,15,181,29,240,236,0,248,2,38,38,96,164,253,221,179,20,88,63,3,237,23,68,46,150,209,198,233,97,197,60,200,243,63,255,131,75,95,70,121,45,6,6,27,63,6,38,251,16,6,6,21,99,132,150,187,23,24,254,109,154,14,108,228,45,128,140,237,139,243,66,93,75,65, +21,3,74,196,28,208,210,12,84,2,80,163,3,3,94,29,5,244,8,232,58,251,223,192,30,201,165,19,192,158,65,18,248,218,58,70,75,31,240,62,71,6,109,27,96,91,1,136,221,19,193,7,66,252,127,122,7,178,231,239,37,176,215,242,238,53,36,17,130,110,27,17,7,54,118,245, +128,37,137,67,20,164,55,115,23,24,166,15,55,66,214,2,98,75,204,160,91,204,159,129,174,176,103,252,255,156,93,224,233,207,223,191,209,111,30,69,73,8,0,1,196,194,128,61,205,33,151,2,96,205,159,191,255,252,117,247,203,159,103,186,28,236,255,190,63,255,202, +244,23,216,29,4,205,57,99,12,200,124,125,2,217,226,173,6,76,4,192,98,239,31,104,9,213,91,96,67,20,116,71,16,120,137,56,180,187,2,202,233,160,57,237,159,208,42,87,72,148,129,81,197,16,178,201,3,88,212,49,128,216,48,0,90,149,115,100,45,195,255,45,179,25, +254,223,185,2,185,106,141,143,151,242,238,230,63,232,53,117,176,179,1,126,253,160,114,143,5,218,88,4,237,2,6,157,14,126,102,63,195,255,11,251,25,24,129,25,131,209,23,88,165,217,5,51,48,128,214,46,130,48,76,15,232,232,186,47,208,157,30,160,132,41,0,93, +132,242,253,49,48,242,129,13,205,235,211,33,155,65,25,209,206,52,2,49,129,225,242,247,227,47,134,31,175,190,51,48,114,176,48,156,127,247,227,46,82,228,99,77,4,0,1,196,66,32,226,255,33,107,190,240,244,245,51,103,1,190,55,204,47,222,136,125,7,22,51,224, +75,157,81,134,132,161,99,196,247,65,155,60,157,129,197,119,14,3,147,152,52,195,191,221,75,24,24,46,236,3,22,91,72,219,174,64,9,66,66,14,216,80,2,246,221,141,128,141,38,121,29,6,70,41,101,96,66,16,67,205,76,160,113,251,237,243,25,254,223,61,7,57,206,149, +135,154,103,7,65,219,0,176,4,0,26,200,161,197,248,13,120,161,38,39,100,171,24,176,62,255,127,235,28,195,255,25,192,106,242,240,58,6,166,152,106,6,6,208,89,137,32,183,188,2,70,240,59,96,183,145,91,10,178,208,243,61,176,91,250,20,152,161,62,191,0,150,235, +192,46,238,231,135,208,171,111,185,176,183,115,128,61,175,207,231,63,51,252,254,242,139,225,39,39,207,231,245,87,30,220,129,198,29,206,59,136,1,2,8,219,56,0,114,10,129,105,0,223,93,123,232,225,171,231,201,154,122,207,120,94,190,22,251,114,239,51,3,175, +58,63,3,19,122,125,9,26,148,0,53,6,207,0,235,41,227,122,6,70,251,80,6,102,125,71,200,53,45,160,179,111,62,191,101,96,228,23,103,96,144,85,103,96,4,13,213,10,203,64,183,142,125,133,180,108,127,232,0,83,62,100,162,227,255,218,9,12,255,150,181,2,27,150, +111,32,3,42,92,208,254,46,181,6,154,96,243,90,28,92,16,254,239,31,52,156,191,130,186,25,84,34,128,150,169,129,182,187,157,222,197,240,247,217,93,96,215,17,216,165,117,8,7,182,115,212,25,24,158,0,51,202,213,25,144,243,127,192,179,236,191,145,246,78,178, +64,102,92,177,69,62,19,100,167,214,199,91,159,24,254,125,255,203,240,66,89,235,238,163,227,199,63,51,32,238,29,254,131,165,4,248,7,16,64,132,74,128,191,200,6,124,249,254,227,231,125,6,174,39,178,156,44,122,159,238,126,100,18,253,44,206,192,198,207,134, +101,72,152,21,146,146,143,23,0,139,114,96,221,165,24,12,140,108,27,240,66,11,176,201,200,99,67,95,129,117,222,237,53,144,83,65,84,98,33,145,255,254,37,195,191,217,192,22,51,104,231,47,232,160,36,46,34,6,115,40,137,20,80,35,18,196,251,243,155,94,115,186, +144,54,2,40,49,188,124,192,240,111,50,176,203,248,233,45,3,147,95,22,176,52,40,132,228,242,71,155,33,179,171,76,108,104,51,171,56,70,51,217,24,25,126,191,249,1,172,129,191,128,59,19,167,191,179,220,96,64,92,65,143,158,8,96,87,210,255,7,8,32,124,37,192, +95,36,3,224,134,156,126,253,229,161,169,144,216,59,166,199,207,69,126,190,248,193,192,198,135,101,221,31,168,84,0,141,11,128,218,3,151,122,25,24,238,0,171,0,126,117,200,217,56,160,226,11,116,87,31,168,148,248,246,28,88,34,0,19,192,79,96,81,103,84,15, +44,254,245,192,183,116,255,235,75,129,172,192,101,103,163,254,149,49,216,0,204,142,191,127,232,59,131,13,155,112,250,242,158,225,63,232,24,156,111,159,193,123,25,24,244,75,33,103,38,129,194,143,88,7,1,219,99,95,239,127,97,248,245,254,59,195,95,110,174, +159,203,206,221,184,134,20,233,216,170,0,112,53,0,16,64,184,18,0,122,238,135,37,130,223,91,207,94,121,16,225,166,253,138,227,217,51,145,79,183,62,50,112,171,242,65,142,249,197,118,43,8,19,180,143,250,13,88,135,125,125,138,180,116,9,54,113,4,42,182,126, +65,174,137,83,12,4,159,134,245,175,3,216,229,187,15,116,59,23,23,29,150,148,65,219,0,204,172,136,161,214,129,0,160,68,0,236,129,252,91,80,203,192,4,108,248,49,6,228,64,74,78,80,230,33,102,98,137,25,114,78,195,135,155,159,25,254,126,249,199,240,66,75, +243,206,195,211,224,227,97,64,113,246,11,45,19,163,220,52,10,16,64,76,120,198,0,254,162,21,29,96,131,64,213,192,117,6,174,59,255,217,217,126,127,123,242,149,225,31,214,43,97,176,204,18,130,230,171,65,245,23,24,179,67,248,160,200,7,121,84,51,131,129,225, +193,117,134,127,45,209,192,210,226,42,105,251,251,41,110,165,51,161,78,165,14,8,248,15,153,172,2,150,64,255,102,20,1,171,190,117,144,91,212,36,29,193,35,171,4,107,49,96,238,255,9,108,148,127,125,248,17,92,189,30,254,201,121,17,91,233,141,165,29,192,0, +16,64,76,68,180,1,96,169,8,134,127,111,187,247,250,198,23,17,233,183,223,95,126,97,248,7,154,117,34,231,164,111,208,8,152,4,176,245,171,95,5,44,238,94,49,252,91,209,206,192,112,243,38,228,226,8,250,148,191,144,28,207,206,197,192,200,54,208,9,0,218,83, +0,53,114,129,225,9,58,75,137,1,116,135,145,78,54,228,238,100,134,127,248,7,178,88,24,25,190,62,250,202,240,235,237,119,134,31,66,130,31,151,158,189,121,13,185,212,102,64,189,103,24,165,4,0,8,32,38,28,105,10,150,66,254,96,73,0,191,142,92,190,241,226,154, +128,216,213,239,223,88,254,188,187,244,142,225,63,51,137,103,234,128,14,126,226,85,99,96,48,239,129,156,2,178,160,134,129,97,235,82,6,6,17,78,250,173,36,2,183,176,255,66,150,116,65,27,129,144,197,28,3,152,8,64,37,18,47,27,195,255,107,39,128,61,166,243, +192,146,80,17,216,91,242,134,174,194,193,53,144,5,41,254,191,60,248,4,94,23,178,151,79,253,192,235,119,239,191,225,40,254,255,160,13,4,49,0,4,16,182,4,240,15,75,21,128,145,8,22,220,124,115,230,171,136,212,187,87,39,94,130,7,31,136,62,97,11,148,235,64, +39,108,232,230,65,246,18,158,216,196,240,111,249,108,134,255,220,176,13,14,116,140,1,208,214,112,208,96,11,116,171,23,35,203,32,168,10,64,147,103,160,1,201,19,91,129,141,99,96,176,75,58,224,14,23,104,241,255,227,201,55,134,79,215,222,49,124,23,17,127, +183,232,234,227,203,191,255,252,249,133,37,247,99,45,1,0,2,136,9,123,191,8,165,26,64,54,8,118,250,244,175,115,183,238,190,121,40,42,125,231,251,187,63,127,223,95,0,205,250,17,121,245,0,168,7,32,8,236,235,139,219,128,199,222,255,174,232,128,172,218,101, +231,160,127,35,236,31,108,34,8,58,162,9,154,19,24,12,155,63,64,109,103,208,152,201,143,79,192,158,147,28,116,185,61,142,190,63,208,193,239,206,191,101,248,241,234,15,195,9,1,213,51,47,223,190,251,130,150,97,113,54,0,65,70,0,4,16,190,42,224,47,90,87,16, +150,0,224,137,96,231,243,47,87,128,13,182,223,47,79,188,134,148,2,44,140,4,2,240,63,244,102,112,55,200,204,23,232,208,200,107,64,143,242,114,12,204,182,43,144,149,160,197,29,176,249,127,142,65,146,0,192,71,216,254,132,14,85,195,246,118,98,113,24,7,19, +195,207,103,223,25,222,159,127,205,240,83,84,232,243,166,187,47,174,125,249,246,253,39,129,214,255,63,100,195,0,2,136,9,79,219,18,87,67,16,158,8,246,93,187,247,248,15,31,247,183,159,175,190,51,188,57,5,186,2,134,133,64,183,245,31,100,96,3,124,91,55,3, +228,128,228,127,12,72,199,20,208,25,128,214,127,130,18,0,172,4,0,29,24,61,24,54,254,128,66,28,116,164,60,248,216,186,55,208,101,223,140,88,71,254,222,95,4,22,253,207,127,49,60,20,81,184,115,251,233,203,15,216,26,237,88,122,0,240,18,0,32,128,112,149,0, +48,140,62,24,132,92,13,252,124,253,241,243,151,107,60,210,87,64,70,190,58,254,154,225,55,48,33,224,61,20,234,63,52,69,243,200,66,184,143,111,65,207,70,30,160,108,7,178,150,79,24,177,221,27,52,39,192,204,52,176,187,126,96,213,160,190,3,164,129,10,26,33, +5,237,182,70,63,108,1,88,247,127,3,214,253,111,129,185,31,52,188,114,243,31,251,163,55,95,190,126,69,111,171,225,43,254,65,0,32,128,152,8,20,144,232,35,130,176,220,255,3,102,65,239,149,215,7,191,203,201,189,249,245,238,59,195,243,253,207,33,41,149,133, +17,255,224,59,35,52,199,129,143,107,25,192,110,23,104,101,150,140,42,228,194,74,16,0,237,31,96,101,31,184,1,33,70,232,133,82,188,236,12,76,154,86,144,92,254,116,31,34,188,224,35,151,204,12,255,126,252,97,120,115,252,37,195,215,7,63,24,62,26,26,61,222, +117,255,213,237,63,127,255,253,68,175,166,113,36,0,56,0,8,32,38,252,131,228,24,9,224,23,90,34,248,113,243,225,227,247,147,126,73,173,251,199,206,244,251,221,249,55,12,175,246,128,214,228,225,57,132,28,180,100,28,52,42,8,242,47,104,246,239,215,0,37,0, +208,184,63,59,48,128,85,76,192,71,170,128,221,3,58,9,132,157,99,0,187,129,192,224,254,252,143,129,209,37,26,178,119,241,201,78,6,134,215,167,16,35,149,208,162,255,63,48,129,190,57,246,10,136,129,141,63,9,145,143,11,158,253,220,119,230,246,253,87,216, +170,105,164,4,240,15,91,2,0,8,32,38,2,5,36,182,222,0,44,242,225,169,109,245,161,19,247,142,41,88,30,249,251,254,15,195,75,160,195,190,222,4,86,69,60,88,14,146,2,165,228,63,192,20,254,241,38,132,175,101,137,119,140,131,166,57,13,180,145,68,76,6,216,205, +2,70,250,151,251,64,119,125,2,31,90,13,190,156,226,239,223,129,113,211,135,175,12,140,70,38,12,76,81,181,192,112,249,0,153,251,7,101,24,228,98,18,152,0,190,222,251,194,240,98,239,51,134,127,64,119,158,150,208,56,179,250,252,205,59,208,220,255,3,41,110, +144,27,129,40,19,64,200,137,0,32,128,8,245,221,208,135,133,145,83,216,119,100,11,27,247,94,56,252,73,78,238,37,168,42,120,117,248,53,80,244,31,100,51,5,198,252,0,80,236,237,5,176,209,140,22,190,192,92,39,2,89,138,69,239,173,228,63,129,246,131,54,118, +8,74,67,86,49,253,124,7,94,151,199,40,174,0,25,120,161,171,123,128,118,125,249,204,192,40,39,207,192,148,209,195,192,32,5,116,195,165,126,160,216,3,212,69,163,224,94,244,111,112,85,251,243,253,111,134,167,10,42,119,103,159,189,123,254,215,239,63,223, +209,75,102,164,68,128,49,252,139,12,0,2,136,152,18,224,63,218,160,208,47,36,75,224,137,224,61,176,1,50,245,51,247,150,255,140,12,127,191,62,252,196,240,245,225,23,72,255,254,63,250,64,7,176,161,245,28,88,175,125,186,11,62,161,155,209,43,21,200,166,115, +142,251,15,189,219,80,197,8,88,239,11,50,48,188,60,5,89,108,1,10,99,208,158,134,159,116,206,253,160,3,170,5,161,215,202,232,217,51,48,188,57,3,116,211,49,6,140,187,159,129,185,255,203,205,79,12,31,174,188,103,248,46,194,255,113,249,243,223,71,110,62, +121,254,22,41,67,126,71,43,157,127,163,13,254,96,180,184,1,2,136,152,209,155,127,104,213,192,47,180,148,6,79,4,91,46,221,126,176,87,193,122,255,183,23,191,255,191,60,248,130,225,255,231,63,224,85,42,168,137,157,5,178,63,239,206,98,72,123,16,116,16,147, +150,6,100,203,53,189,114,29,116,229,47,163,154,25,132,15,90,109,3,171,150,148,244,232,219,41,1,45,67,19,148,96,96,202,155,4,62,8,27,60,115,122,5,152,16,126,190,65,205,253,160,189,171,191,254,50,188,58,243,154,225,47,19,211,239,19,34,154,103,86,94,121, +120,7,41,14,190,163,37,2,244,250,31,235,114,105,128,0,34,166,10,192,214,37,252,133,102,49,56,1,252,4,22,69,29,251,207,158,120,97,96,124,231,237,169,183,12,79,119,62,5,102,182,255,104,163,132,255,33,167,91,130,174,140,123,121,152,129,65,8,232,249,220, +41,144,165,94,223,191,51,208,188,91,0,59,249,83,92,22,124,236,60,195,255,47,144,203,25,65,221,45,144,23,181,45,192,3,44,224,181,1,180,46,133,64,75,208,128,213,16,115,221,42,6,70,251,112,200,54,175,51,85,192,18,224,20,100,73,24,44,44,128,57,255,31,176, +104,125,177,227,25,195,135,171,31,255,63,82,215,191,85,185,237,228,17,164,56,248,6,197,176,248,192,86,252,99,77,214,0,1,68,236,190,45,124,165,192,119,36,203,127,124,248,246,227,203,148,7,223,247,253,228,21,252,242,250,200,51,134,215,135,94,50,252,5,37, +2,148,246,0,244,232,161,243,45,64,79,63,98,96,52,112,102,96,138,169,7,154,204,138,116,182,0,13,187,127,160,117,31,26,230,12,140,160,6,224,135,123,144,238,40,104,1,6,176,191,205,168,160,11,94,174,6,62,85,132,86,137,17,212,3,1,217,169,98,204,192,84,182, +144,129,1,116,104,5,168,216,7,69,254,139,67,144,161,95,88,105,200,12,172,83,129,110,126,123,236,37,195,139,131,207,25,62,136,136,189,234,187,252,106,223,191,255,255,145,115,252,55,36,252,3,169,248,71,111,253,99,36,2,128,0,34,38,1,252,199,209,24,252,137, +197,1,224,68,176,247,252,213,199,171,69,20,119,253,226,18,250,254,120,227,67,134,151,59,129,45,86,208,197,18,172,72,155,145,65,107,222,64,43,130,142,101,3,235,223,155,12,140,161,165,12,76,9,133,144,11,37,191,127,167,93,2,0,157,26,194,203,13,94,103,15, +94,155,7,218,95,7,242,18,104,87,211,171,83,224,97,97,102,207,36,160,27,64,237,4,42,215,5,160,56,253,9,57,204,129,209,61,137,129,185,113,29,3,163,186,33,3,195,85,96,145,127,36,29,216,229,59,13,172,50,133,160,221,101,6,112,120,129,242,206,11,96,248,61, +222,244,136,225,183,160,208,215,165,44,210,123,78,222,127,250,28,41,220,191,66,241,55,44,197,63,114,235,31,43,0,8,32,82,118,110,254,199,49,38,128,145,8,128,169,243,199,164,253,231,46,236,21,80,58,242,139,137,237,247,243,61,79,24,94,29,120,193,240,239, +23,242,45,225,208,147,69,65,27,28,142,131,206,216,7,150,4,9,173,12,76,169,205,224,13,144,12,95,190,208,96,68,142,17,60,195,6,218,205,11,222,94,246,7,216,238,120,117,2,186,234,6,88,223,62,222,2,81,102,27,194,192,32,192,3,185,252,137,42,165,0,116,225,44, +232,176,41,30,33,6,166,228,54,6,166,130,25,144,147,73,47,118,2,91,252,61,144,238,49,155,32,34,164,217,32,145,255,114,207,51,134,23,251,159,49,252,97,99,249,189,139,87,254,240,162,163,231,111,64,35,25,61,242,209,115,255,95,92,163,127,200,0,32,128,152, +72,136,124,244,146,0,185,26,248,134,134,193,245,80,207,225,75,167,143,51,177,158,254,251,143,225,239,211,157,79,24,222,156,120,13,73,0,140,200,237,1,62,96,9,0,236,17,92,232,4,71,8,99,64,46,3,83,62,48,71,200,3,139,225,207,95,241,108,215,38,167,241,247, +27,178,5,11,116,31,17,104,212,239,229,17,232,254,122,208,214,111,62,72,98,248,254,138,129,65,68,22,88,39,3,19,193,199,223,148,31,119,203,4,109,79,124,2,86,47,202,250,12,76,160,163,236,131,11,32,107,34,174,0,187,122,183,23,66,54,121,128,23,126,252,135, +231,124,240,197,32,192,190,254,243,3,207,25,24,129,41,225,48,187,196,241,134,61,231,143,161,229,252,111,4,114,255,63,66,227,236,0,1,68,170,247,96,9,0,189,75,136,205,81,223,223,127,255,245,185,227,9,243,225,43,58,86,23,254,3,251,221,207,118,61,5,175,92, +1,221,106,129,2,64,37,193,139,163,192,54,65,43,208,180,151,224,3,158,153,170,150,48,48,154,187,64,170,131,127,127,169,147,19,65,237,11,121,77,6,38,215,56,200,82,171,39,123,32,13,64,240,142,93,22,200,221,59,119,87,128,183,119,49,129,54,119,74,128,174, +99,249,65,94,239,4,182,199,15,216,191,103,248,240,157,129,209,57,132,129,169,114,62,120,103,51,120,65,236,233,90,6,134,27,179,33,85,33,8,195,14,117,2,13,163,3,123,78,175,129,37,38,40,231,255,251,252,151,225,162,145,235,233,202,51,79,15,32,149,184,232, +145,143,173,238,71,46,250,113,38,2,128,0,34,181,10,64,95,45,132,173,49,136,226,184,215,31,63,125,108,59,251,228,192,109,3,171,203,191,63,254,97,120,180,238,62,195,183,251,160,227,214,144,207,180,97,130,96,208,82,232,211,213,192,0,187,14,222,115,207,84, +52,155,129,209,46,0,152,19,191,67,239,209,165,32,17,128,143,126,97,97,96,114,8,101,96,144,82,130,12,70,129,26,94,140,240,11,180,128,57,15,216,254,120,184,22,114,7,143,162,62,3,131,115,48,176,113,248,27,106,47,35,241,145,14,30,211,7,6,193,235,207,224, +21,199,140,81,185,224,59,4,193,187,157,64,165,206,169,50,96,226,219,10,89,31,9,110,237,195,79,244,2,182,79,88,25,190,92,255,200,240,226,240,115,134,223,111,254,50,220,176,112,57,95,181,235,204,222,223,255,254,125,67,11,223,47,72,108,146,26,126,200,0, +32,128,152,27,26,26,24,26,27,27,41,109,218,96,59,139,14,126,206,240,251,143,31,255,92,250,206,244,220,196,64,83,128,251,206,125,209,175,15,190,48,112,8,177,51,176,203,65,23,58,252,249,15,221,51,207,2,217,242,12,42,138,65,219,158,101,44,25,24,245,157, +33,126,187,4,44,253,190,65,215,28,48,147,49,125,252,227,59,120,115,38,232,4,112,208,69,79,12,215,103,66,18,0,11,23,194,233,160,118,0,168,68,248,5,44,9,100,128,165,15,159,36,195,255,163,43,33,215,190,179,67,237,69,142,100,100,12,242,7,168,91,247,249,7, +228,104,58,30,118,6,70,87,96,73,150,213,199,192,228,145,2,217,252,114,115,62,164,216,7,45,133,7,217,11,91,53,13,138,34,208,29,76,92,204,12,159,206,191,103,120,188,225,33,48,147,252,96,184,99,235,124,177,122,255,165,61,79,95,191,253,128,20,249,160,136, +255,140,39,1,160,15,251,226,5,0,1,196,8,222,229,75,90,206,66,191,89,4,148,149,65,201,24,52,139,2,10,77,208,46,14,94,52,12,18,227,210,86,86,20,233,82,102,13,18,127,116,75,142,141,159,149,65,202,77,142,65,200,84,136,129,17,84,37,124,133,186,25,188,29,250, +39,228,18,4,121,63,232,70,9,54,200,222,192,77,83,128,197,230,73,134,255,223,254,66,22,145,128,150,112,17,154,185,131,230,70,70,14,110,6,166,166,13,12,12,6,142,192,198,222,38,72,117,3,178,135,137,13,179,155,8,2,160,37,107,202,177,12,255,79,108,99,96,88, +80,203,240,15,180,53,237,43,212,167,160,222,12,108,131,11,232,206,194,159,144,144,96,20,226,7,230,114,96,3,83,11,216,173,179,14,4,118,41,245,128,161,194,6,185,9,245,234,52,96,130,59,1,41,137,208,78,244,2,87,137,223,126,51,188,62,249,154,225,197,222,39, +12,63,95,255,97,184,100,225,118,166,227,208,165,195,183,159,190,120,131,22,241,32,252,9,74,163,39,128,63,248,70,253,176,1,128,0,34,39,1,160,39,2,22,180,68,192,13,197,232,137,0,36,198,37,193,201,202,159,110,162,98,232,247,233,166,11,168,169,195,37,203, +207,32,237,41,197,192,173,198,143,72,4,96,167,255,133,68,16,159,60,3,131,54,48,17,72,185,64,78,245,126,114,147,225,255,186,126,134,127,123,150,65,210,59,232,100,46,88,137,128,182,249,24,60,226,247,13,180,0,149,15,216,223,6,214,191,54,192,250,247,254, +106,96,203,187,3,98,62,19,27,238,97,15,144,89,234,137,12,12,154,217,224,155,79,25,158,220,98,248,119,12,152,128,78,237,0,111,111,3,151,88,160,102,58,191,48,3,35,104,72,89,199,150,129,17,52,140,11,186,129,20,180,176,228,31,48,190,238,46,103,96,120,186, +11,168,255,57,164,149,207,200,136,122,100,14,19,164,190,255,124,237,3,176,125,244,156,225,203,253,143,12,255,121,184,255,108,100,22,223,63,253,218,171,115,111,63,131,78,156,130,23,247,95,144,34,254,51,82,15,0,91,228,19,125,72,2,64,0,145,155,0,144,19, +1,51,90,34,224,68,42,9,120,144,74,0,24,230,100,102,98,228,140,119,177,85,75,249,112,222,135,237,203,103,46,54,126,78,6,25,79,105,6,65,107,49,160,151,254,32,109,247,102,132,44,33,3,229,26,25,55,6,6,173,44,160,105,202,144,125,117,87,142,48,252,95,210,12, +190,153,147,225,199,111,168,43,88,144,6,123,254,130,175,113,1,69,10,99,102,47,3,163,146,1,176,161,185,143,129,225,68,9,228,88,53,22,78,252,97,244,31,26,142,210,192,238,162,86,46,48,249,202,33,142,192,67,30,37,4,29,47,3,222,247,192,4,209,3,58,38,231,193, +58,200,141,158,224,11,29,217,160,67,186,140,152,51,227,64,125,175,14,190,96,120,182,231,41,195,191,111,127,24,126,72,73,127,154,203,162,176,99,241,190,227,183,254,252,251,135,220,166,250,140,148,0,96,137,1,214,242,39,106,200,23,23,0,8,32,74,19,0,210, +176,30,252,110,58,228,68,192,141,37,17,112,67,229,57,108,100,132,164,235,53,5,189,133,158,223,19,103,230,100,97,148,116,146,102,16,177,22,5,86,141,160,211,58,254,161,22,203,127,191,66,174,164,145,7,230,98,149,72,160,41,178,16,39,60,188,198,240,239,228, +54,112,213,192,240,246,57,36,177,128,150,121,75,171,48,48,58,69,131,79,213,0,135,7,232,138,250,163,192,4,244,227,53,164,203,71,76,24,129,34,20,52,111,193,14,84,47,233,2,89,203,40,164,5,29,169,99,130,204,223,255,2,86,207,159,238,0,35,254,10,164,129,7, +218,19,9,78,96,92,152,11,57,224,189,30,70,134,127,191,255,131,199,70,158,238,125,10,108,250,48,253,127,201,47,254,180,249,230,151,29,199,95,124,124,134,165,159,255,25,173,222,255,138,20,249,191,72,173,247,145,1,64,0,81,146,0,208,27,128,176,146,0,118, +209,52,122,34,64,198,92,176,68,192,193,198,198,217,109,33,235,100,241,253,185,1,227,167,111,172,2,90,66,12,82,30,82,12,236,50,92,224,75,194,33,39,127,192,6,83,254,64,26,105,160,126,179,74,52,176,142,6,38,4,118,96,213,193,200,142,187,227,2,154,230,125, +180,29,216,0,155,13,90,196,6,116,33,129,141,22,88,7,113,64,103,25,124,129,158,134,202,9,57,22,31,20,193,160,42,10,212,96,4,173,217,3,177,65,173,122,112,163,18,203,34,78,200,129,187,12,255,152,254,51,252,120,250,157,225,201,150,39,12,31,111,125,96,248, +203,203,245,253,152,136,198,217,242,93,23,142,0,115,61,242,4,219,87,2,141,190,31,132,22,123,16,3,0,2,136,210,4,128,173,213,15,75,4,200,13,67,110,164,132,192,141,158,8,64,106,155,92,140,44,92,94,92,181,102,251,253,147,131,133,151,141,65,204,74,148,65, +216,76,148,1,116,75,25,234,21,235,208,253,132,160,8,1,221,81,40,102,13,185,68,153,95,13,104,26,244,126,36,80,233,249,11,40,255,234,36,164,107,9,26,231,7,29,170,0,26,111,32,123,5,10,244,40,60,6,232,105,101,224,209,67,38,104,241,206,132,148,219,177,47, +223,254,15,196,127,62,253,2,15,134,189,60,250,146,1,116,208,214,55,62,158,143,203,127,139,28,152,126,254,254,21,44,131,106,95,145,138,123,228,92,255,29,75,127,159,232,70,31,58,0,8,32,106,36,0,108,61,3,102,180,146,0,189,52,128,37,8,46,40,6,39,130,20,93, +25,237,96,129,63,230,34,31,223,72,252,255,242,135,153,75,150,147,65,214,75,150,129,71,131,31,82,45,128,27,118,255,161,87,187,253,135,108,47,3,237,51,0,207,43,179,65,138,106,208,190,195,223,159,33,231,231,130,115,37,59,228,28,61,70,106,222,248,192,136, +54,60,130,69,26,212,38,96,130,206,228,1,123,10,31,206,189,97,120,126,240,57,195,183,199,192,238,40,39,211,223,55,98,178,47,230,223,255,124,120,213,189,119,183,209,166,214,191,33,213,241,95,176,12,246,252,66,154,233,251,71,78,189,143,12,0,2,136,90,9,128, +80,34,64,111,23,112,227,74,4,42,194,124,130,121,90,98,230,106,108,127,228,184,222,188,227,231,101,254,198,45,102,41,194,192,167,42,200,192,12,186,15,79,128,21,88,10,179,64,18,194,31,164,165,139,224,99,212,96,97,194,2,29,87,96,102,160,235,85,31,140,208, +46,34,48,60,255,2,27,117,191,63,253,102,248,243,229,55,195,199,43,111,193,185,254,43,11,207,215,239,130,130,159,174,255,227,124,208,125,225,217,241,167,31,193,173,252,31,88,114,62,182,73,158,159,164,142,243,19,3,0,2,136,154,9,0,87,34,96,129,38,0,118, +44,165,1,50,205,137,84,37,176,73,11,240,242,58,75,112,201,123,11,177,233,42,125,124,169,200,194,250,139,25,116,43,54,175,18,63,131,128,150,0,3,183,34,15,3,51,232,112,10,80,66,0,53,24,255,13,192,82,110,216,9,35,160,238,28,27,100,6,239,215,251,159,12,223, +30,125,101,248,120,237,61,195,151,135,159,25,126,189,251,193,240,135,137,235,239,53,97,217,155,251,95,124,190,121,232,229,151,199,247,223,126,250,136,20,161,223,113,204,236,125,67,171,239,145,183,120,253,163,70,228,131,0,64,0,81,59,1,224,106,19,160,143, +21,112,34,229,124,228,82,0,150,8,96,9,134,85,150,143,139,47,70,83,74,211,130,253,151,134,212,251,231,210,192,46,31,19,43,15,19,3,191,166,16,3,191,190,16,176,51,192,13,57,171,8,182,43,9,52,48,3,154,122,254,135,165,180,166,70,132,195,250,239,32,251,96, +211,219,64,59,65,39,115,126,190,249,137,225,221,133,55,12,223,158,124,1,230,254,127,12,140,124,92,255,158,240,137,61,61,250,254,231,141,25,183,222,94,252,242,243,23,114,17,142,28,249,216,38,118,190,163,141,240,33,79,240,80,37,242,65,0,32,128,104,145, +0,208,123,7,200,35,134,172,72,145,203,129,20,233,232,165,0,188,36,128,98,86,67,113,126,17,43,45,85,73,107,166,143,234,202,159,95,41,50,189,251,200,198,202,207,204,192,41,197,195,192,37,205,13,196,92,12,28,98,156,224,123,115,25,121,88,225,187,102,225, +137,225,223,127,242,154,73,208,214,59,164,44,99,134,38,180,255,12,255,63,255,102,248,254,246,39,3,232,176,172,239,79,190,49,124,125,252,153,225,251,139,47,192,162,255,63,195,47,46,206,31,247,36,212,238,29,127,243,245,222,209,71,111,158,92,120,249,225, +45,3,238,229,116,216,102,82,145,87,245,252,198,50,187,247,159,90,245,26,64,0,209,42,1,224,74,4,176,132,192,134,86,26,112,34,37,0,46,36,113,14,36,181,172,208,18,129,215,144,159,69,60,64,75,65,75,231,227,67,117,230,143,31,217,192,183,166,115,48,50,176, +242,178,51,112,8,115,49,112,43,1,19,133,44,48,65,8,114,48,176,129,206,234,3,109,89,99,66,58,105,3,148,24,254,226,9,63,208,78,103,216,186,5,240,110,102,208,112,242,31,134,95,31,127,131,115,250,151,7,95,128,197,252,23,240,129,204,191,63,127,103,0,117,222, +64,199,18,127,226,230,255,112,142,67,252,198,254,167,159,238,157,127,253,249,213,179,79,224,157,58,232,219,234,144,35,31,121,53,21,114,113,255,19,203,162,142,127,148,180,246,113,1,128,0,162,101,2,96,96,192,188,133,140,25,203,120,1,7,18,230,196,82,10, +112,64,19,0,27,18,102,145,228,227,226,209,224,102,22,50,149,20,144,50,22,96,87,80,248,254,78,154,229,243,59,78,240,249,255,160,140,202,197,6,108,252,179,50,176,2,187,145,108,2,108,12,156,98,28,192,68,194,12,20,7,54,34,121,89,24,88,65,147,47,56,218,135, +191,191,255,1,54,222,254,128,27,112,127,127,252,101,248,249,250,39,48,226,127,1,35,251,39,248,190,4,240,81,185,44,144,218,248,175,176,232,143,155,12,236,15,174,252,102,127,178,231,238,139,135,183,62,255,250,240,249,39,248,62,122,228,101,244,191,144,34, +246,59,3,238,133,156,63,209,90,249,127,177,204,235,83,181,177,3,16,64,180,78,0,184,218,5,200,195,199,232,213,2,114,238,231,68,19,71,78,8,32,125,44,236,204,76,192,38,0,11,135,48,55,39,151,133,146,180,184,62,235,79,41,29,230,111,74,252,31,95,9,129,51,49, +35,11,195,63,208,134,89,208,108,48,23,19,248,58,53,208,197,17,204,176,141,172,88,130,19,116,206,238,255,127,144,9,31,208,117,185,32,215,50,131,174,98,253,243,151,225,255,223,191,12,111,165,52,94,94,123,255,233,201,101,118,137,39,39,110,221,123,245,242, +227,215,175,159,254,252,251,249,243,207,223,95,12,152,231,41,252,64,203,249,63,208,18,193,79,44,221,187,223,72,35,123,255,168,89,228,163,3,128,0,162,87,2,32,84,37,160,151,8,236,72,52,39,22,49,118,164,68,0,211,207,204,194,196,4,76,16,140,44,188,108,44, +108,170,10,242,188,6,2,236,162,226,207,175,11,241,201,40,176,138,139,138,241,49,63,190,197,198,193,240,151,157,71,84,146,141,229,231,55,86,112,93,142,230,119,208,221,104,127,216,57,127,127,122,247,250,199,207,255,204,191,127,73,43,127,123,251,250,245, +247,15,207,30,255,124,35,171,243,254,252,243,119,175,111,61,121,254,9,216,160,251,253,243,31,195,159,63,255,254,193,114,42,182,131,52,126,98,201,249,216,54,111,160,239,226,253,71,171,34,31,29,0,4,16,61,19,0,190,42,1,185,68,64,30,59,64,79,16,28,132,18, +1,3,218,245,232,12,168,187,43,176,94,137,135,163,173,207,128,165,193,133,126,150,50,250,25,10,191,209,114,61,122,100,163,71,58,174,237,219,52,43,242,209,1,64,0,209,123,99,62,242,37,172,200,129,137,126,44,45,44,32,217,144,104,88,0,34,39,0,88,34,96,193, +147,8,152,240,44,90,193,215,217,195,22,241,196,68,254,79,28,137,224,23,150,150,61,174,136,255,207,64,167,209,43,128,0,26,136,147,25,112,229,176,255,72,129,202,140,22,176,172,208,192,99,135,6,38,59,90,41,193,134,148,0,88,176,36,0,92,137,0,215,184,46,250, +81,57,12,12,152,39,168,227,58,67,9,57,1,252,194,81,204,35,183,238,209,235,122,6,6,58,238,77,2,8,32,122,87,1,196,84,11,76,56,218,8,172,104,61,1,54,180,42,128,13,45,1,192,48,35,145,213,1,177,197,62,182,131,52,127,225,40,5,126,227,137,248,127,244,46,238, +177,1,128,0,26,12,9,128,1,75,132,224,75,8,44,88,34,29,57,145,48,227,168,6,112,94,161,142,167,248,255,79,32,1,252,69,139,92,108,24,219,9,93,3,30,241,48,0,16,64,131,41,1,16,91,34,48,35,69,52,11,26,155,25,75,2,32,183,4,96,192,146,0,254,99,73,0,127,145,34, +248,55,26,251,239,96,141,120,24,0,8,160,193,152,0,112,37,4,70,164,72,101,38,128,153,112,244,4,112,229,124,66,13,65,98,74,2,108,248,223,64,215,241,132,0,64,0,177,48,12,94,128,28,72,127,145,122,15,140,80,62,122,233,192,68,160,200,103,194,146,176,136,41, +1,24,176,180,206,255,225,104,20,98,187,156,105,80,70,60,12,0,4,208,96,78,0,248,18,194,63,180,136,101,196,18,233,132,234,124,98,75,0,108,189,21,108,221,194,255,12,216,175,103,27,148,17,15,3,0,1,52,20,18,0,174,238,35,3,150,196,192,128,150,211,241,69,60, +169,9,0,87,15,129,129,1,247,197,140,255,7,123,160,2,4,208,80,74,0,184,18,2,250,200,222,95,34,70,253,24,73,176,3,215,216,5,190,132,57,100,0,64,0,13,197,4,64,76,201,64,40,146,73,77,0,164,202,15,25,0,16,96,0,155,121,235,71,10,157,3,42,0,0,0,0,73,69,78,68, +174,66,96,130,0,0 }; + +const char* BinaryData::juce_icon_png = (const char*) temp_cf125308; diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h new file mode 100644 index 0000000000..ae8e4274c8 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h @@ -0,0 +1,49 @@ +/* ========================================================================================= + + This is an auto-generated file, created by The Jucer V3.0.0 + Do not edit anything in this file! + +*/ + +namespace BinaryData +{ + extern const char* AudioPluginXCodeScript_txt; + const int AudioPluginXCodeScript_txtSize = 1449; + + extern const char* jucer_AudioPluginEditorTemplate_cpp; + const int jucer_AudioPluginEditorTemplate_cppSize = 1003; + + extern const char* jucer_AudioPluginEditorTemplate_h; + const int jucer_AudioPluginEditorTemplate_hSize = 794; + + extern const char* jucer_AudioPluginFilterTemplate_cpp; + const int jucer_AudioPluginFilterTemplate_cppSize = 4386; + + extern const char* jucer_AudioPluginFilterTemplate_h; + const int jucer_AudioPluginFilterTemplate_hSize = 2353; + + extern const char* jucer_MainConsoleAppTemplate_cpp; + const int jucer_MainConsoleAppTemplate_cppSize = 749; + + extern const char* jucer_MainTemplate_cpp; + const int jucer_MainTemplate_cppSize = 2106; + + extern const char* jucer_NewCppFileTemplate_cpp; + const int jucer_NewCppFileTemplate_cppSize = 232; + + extern const char* jucer_NewCppFileTemplate_h; + const int jucer_NewCppFileTemplate_hSize = 308; + + extern const char* jucer_WindowTemplate_cpp; + const int jucer_WindowTemplate_cppSize = 794; + + extern const char* jucer_WindowTemplate_h; + const int jucer_WindowTemplate_hSize = 1290; + + extern const char* juce_icon_png; + const int juce_icon_pngSize = 19826; + + // If you provide the name of one of the binary resource variables above, this function will + // return the corresponding data and its size (or a null pointer if the name isn't found). + const char* getNamedResource (const wchar_t* resourceName, int& dataSizeInBytes) throw(); +} diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceHeader.h b/extras/Jucer (experimental)/JuceLibraryCode/JuceHeader.h new file mode 100644 index 0000000000..1af13f0b74 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceHeader.h @@ -0,0 +1,27 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This is the header file that your files should include in order to get all the + Juce library headers. You should NOT include juce.h or juce_amalgamated.h directly in + your own source files, because that wouldn't pick up the correct Juce configuration + options for your app. + +*/ + +#ifndef __APPHEADERFILE_347B64F4__ +#define __APPHEADERFILE_347B64F4__ + +#include "AppConfig.h" +#include "../../../juce_amalgamated.h" +#include "BinaryData.h" + +namespace ProjectInfo +{ + const char* const projectName = "The Jucer"; + const char* const versionString = "3.0.0"; + const int versionNumber = 0x30000; +} + +#endif // __APPHEADERFILE_347B64F4__ diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.cpp b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.cpp new file mode 100644 index 0000000000..62f0352fc5 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.cpp @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated1.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.mm b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.mm new file mode 100644 index 0000000000..62f0352fc5 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode1.mm @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated1.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.cpp b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.cpp new file mode 100644 index 0000000000..ce9ad2f1bf --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.cpp @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated2.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.mm b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.mm new file mode 100644 index 0000000000..ce9ad2f1bf --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode2.mm @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated2.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.cpp b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.cpp new file mode 100644 index 0000000000..b749e4c478 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.cpp @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated3.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.mm b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.mm new file mode 100644 index 0000000000..b749e4c478 --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode3.mm @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated3.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.cpp b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.cpp new file mode 100644 index 0000000000..853375be1c --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.cpp @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated4.cpp" diff --git a/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.mm b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.mm new file mode 100644 index 0000000000..853375be1c --- /dev/null +++ b/extras/Jucer (experimental)/JuceLibraryCode/JuceLibraryCode4.mm @@ -0,0 +1,15 @@ +/* + + IMPORTANT! This file is auto-generated by the Jucer each time you save your + project - if you alter its contents, your changes may be overwritten! + + This file pulls in all the Juce source code, and builds it using the settings + defined in AppConfig.h. + + If you want to change the method by which Juce is linked into your app, use the + Jucer to change it, rather than trying to edit this file directly. + +*/ + +#include "AppConfig.h" +#include "../../../amalgamation/juce_amalgamated4.cpp" diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer new file mode 100644 index 0000000000..def35c844d --- /dev/null +++ b/extras/Jucer (experimental)/Jucer.jucer @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/Jucer (experimental)/Source/jucer_Headers.h b/extras/Jucer (experimental)/Source/jucer_Headers.h new file mode 100644 index 0000000000..be75c35f18 --- /dev/null +++ b/extras/Jucer (experimental)/Source/jucer_Headers.h @@ -0,0 +1,59 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_HEADERS_JUCEHEADER__ +#define __JUCER_HEADERS_JUCEHEADER__ + +#ifdef _MSC_VER + #pragma warning (disable: 4100 4505) + #define DONT_LIST_JUCE_AUTOLINKEDLIBS 1 +#endif + +//============================================================================== +#include "../JuceLibraryCode/JuceHeader.h" +#include "utility/jucer_StoredSettings.h" +#include "utility/jucer_UtilityFunctions.h" +#include "utility/jucer_RelativePath.h" +#include "utility/jucer_ValueRemapperSource.h" +#include "ui/jucer_CommandIDs.h" + +//============================================================================== +extern ApplicationCommandManager* commandManager; + +//============================================================================== +static const char* const newLine = "\r\n"; + +const char* const projectItemDragType = "Project Items"; +const char* const drawableItemDragType = "Drawable Items"; + +const char* const textFileExtensions = "cpp;h;hpp;mm;m;c;txt;xml;plist;rtf;html;htm;php;py;rb;cs"; +const char* const sourceFileExtensions = "cpp;mm;m;c;h;hpp"; +const char* const headerFileExtensions = "h;hpp"; + +const int numSwatchColours = 24; +const int snapSizes[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32 }; + + +#endif // __JUCER_HEADERS_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/jucer_Main.cpp b/extras/Jucer (experimental)/Source/jucer_Main.cpp new file mode 100644 index 0000000000..1d2f804730 --- /dev/null +++ b/extras/Jucer (experimental)/Source/jucer_Main.cpp @@ -0,0 +1,113 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_Headers.h" +#include "ui/jucer_MainWindow.h" + +ApplicationCommandManager* commandManager = 0; + + +//============================================================================== +class JucerApplication : public JUCEApplication +{ +public: + //============================================================================== + JucerApplication() + { + } + + ~JucerApplication() + { + } + + //============================================================================== + void initialise (const String& commandLine) + { + commandManager = new ApplicationCommandManager(); + + theMainWindow = new MainWindow(); + theMainWindow->setVisible (true); + + ImageCache::setCacheTimeout (30 * 1000); + + if (commandLine.trim().isNotEmpty() + && ! commandLine.trim().startsWithChar (T('-'))) + anotherInstanceStarted (commandLine); + + theMainWindow->reloadLastProject(); + } + + void shutdown() + { + theMainWindow = 0; + + OpenDocumentManager::deleteInstance(); + deleteAndZero (commandManager); + } + + //============================================================================== + void systemRequestedQuit() + { + if (theMainWindow == 0 || theMainWindow->closeCurrentProject()) + { + theMainWindow = 0; + StoredSettings::deleteInstance(); + + quit(); + } + } + + //============================================================================== + const String getApplicationName() + { + return "The Jucer V" + getApplicationVersion(); + } + + const String getApplicationVersion() + { + return ProjectInfo::versionString; + } + + bool moreThanOneInstanceAllowed() + { +#ifndef JUCE_LINUX + return false; +#else + return true; //xxx should be false but doesn't work on linux.. +#endif + } + + void anotherInstanceStarted (const String& commandLine) + { + if (theMainWindow != 0) + theMainWindow->openFile (commandLine.unquoted()); + } + +private: + ScopedPointer theMainWindow; +}; + + +START_JUCE_APPLICATION(JucerApplication) diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp new file mode 100644 index 0000000000..9b3bc1775e --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp @@ -0,0 +1,65 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ComponentDocument.h" + + +//============================================================================== +static const char* const componentDocumentTag = "COMPONENT"; + + +//============================================================================== +ComponentDocument::ComponentDocument (Project* project_, const File& cppFile_) + : project (project_), cppFile (cppFile_), root (componentDocumentTag) +{ +} + +ComponentDocument::~ComponentDocument() +{ +} + +bool ComponentDocument::isComponentFile (const File& file) +{ + if (! file.hasFileExtension (".cpp")) + return false; + + ScopedPointer in (file.createInputStream()); + + if (in == 0) + return false; + + const int amountToRead = 1024; + HeapBlock initialData; + initialData.calloc (amountToRead + 4); + in->read (initialData, amountToRead); + + return String::createStringFromData (initialData, amountToRead) + .contains (String ("JUCER_" "COMPONENT")); // written like this to avoid thinking this file is a component! +} + +bool ComponentDocument::save() +{ + return false; +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h new file mode 100644 index 0000000000..bec4736d67 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h @@ -0,0 +1,56 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ +#define __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class ComponentDocument +{ +public: + //============================================================================== + ComponentDocument (Project* project, const File& cppFile); + ~ComponentDocument(); + + static bool isComponentFile (const File& file); + + bool save(); + + //============================================================================== + UndoManager* getUndoManager() throw() { return &undoManager; } + +private: + Project* project; + File cppFile; + ValueTree root; + UndoManager undoManager; +}; + + +#endif // __JUCER_COMPONENTDOCUMENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.cpp new file mode 100644 index 0000000000..2f3160bedc --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.cpp @@ -0,0 +1,253 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_DrawableDocument.h" +#include "jucer_ResourceFile.h" + +//============================================================================== +static const char* const drawableTag = "DRAWABLE"; + + +//============================================================================== +DrawableDocument::DrawableDocument (Project* project_, const File& drawableFile_) + : project (project_), + drawableFile (drawableFile_), + drawableRoot (drawableTag), + saveAsXml (true), needsSaving (false) +{ + DrawableComposite dc; + drawableRoot.addChild (dc.createValueTree(), -1, 0); + + setName ("Drawable"); + + drawableRoot.addListener (this); +} + +DrawableDocument::~DrawableDocument() +{ + if (needsSaving) + save(); + + drawableRoot.removeListener (this); +} + +ValueTree DrawableDocument::getRootDrawableNode() const +{ + return drawableRoot.getChild (0); +} + +//============================================================================== +void DrawableDocument::setName (const String& name) +{ + drawableRoot.setProperty ("name", name, getUndoManager()); +} + +const String DrawableDocument::getName() const +{ + return drawableRoot ["name"]; +} + +void DrawableDocument::addMissingIds (ValueTree tree) const +{ + if (! tree.hasProperty ("id")) + tree.setProperty ("id", createAlphaNumericUID(), 0); + + for (int i = tree.getNumChildren(); --i >= 0;) + addMissingIds (tree.getChild(i)); +} + +bool DrawableDocument::hasChangedSinceLastSave() const +{ + return needsSaving; +} + +bool DrawableDocument::reload() +{ + ScopedPointer stream (drawableFile.createInputStream()); + + if (stream != 0 && load (*stream)) + { + undoManager.clearUndoHistory(); + needsSaving = false; + return true; + } + + return false; +} + +bool DrawableDocument::save() +{ + TemporaryFile tempFile (drawableFile); + ScopedPointer out (tempFile.getFile().createOutputStream()); + + if (out == 0) + return false; + + save (*out); + + needsSaving = ! tempFile.overwriteTargetFileWithTemporary(); + return ! needsSaving; +} + +void DrawableDocument::save (OutputStream& output) +{ + if (saveAsXml) + { + ScopedPointer xml (drawableRoot.createXml()); + jassert (xml != 0); + + if (xml != 0) + xml->writeToStream (output, String::empty, false, false); + } + else + { + drawableRoot.writeToStream (output); + } +} + +bool DrawableDocument::load (InputStream& input) +{ + int64 originalPos = input.getPosition(); + ValueTree loadedTree ("dummy"); + + XmlDocument xmlDoc (input.readEntireStreamAsString()); + ScopedPointer xml (xmlDoc.getDocumentElement()); + + if (xml != 0) + { + loadedTree = ValueTree::fromXml (*xml); + } + else + { + input.setPosition (originalPos); + loadedTree = ValueTree::readFromStream (input); + } + + if (loadedTree.hasType (drawableTag)) + { + addMissingIds (loadedTree); + + drawableRoot.removeListener (this); + drawableRoot = loadedTree; + drawableRoot.addListener (this); + + valueTreeParentChanged (loadedTree); + + needsSaving = false; + undoManager.clearUndoHistory(); + + return true; + } + + return false; +} + +void DrawableDocument::changed() +{ + needsSaving = true; + startTimer (1000); + sendChangeMessage (this); +} + +void DrawableDocument::timerCallback() +{ + stopTimer(); + getUndoManager()->beginNewTransaction(); + + //if (needsSaving) + // save(); +} + +//============================================================================== +static const Colour getRandomColour() +{ + return Colours::red.withHue (Random::getSystemRandom().nextFloat()); +} + +void DrawableDocument::addDrawable (Drawable& d) +{ + DrawableComposite dc; + dc.insertDrawable (d.createCopy()); + + ValueTree dcNode (dc.createValueTree()); + ValueTree subNode (dcNode.getChild(0)); + dcNode.removeChild (subNode, 0); + addMissingIds (subNode); + + getRootDrawableNode().addChild (subNode, -1, getUndoManager()); +} + +void DrawableDocument::addRectangle() +{ + Path p; + p.addRectangle ((float) Random::getSystemRandom().nextInt (500), + (float) Random::getSystemRandom().nextInt (500), + 100.0f, 100.0f); + + DrawablePath d; + d.setPath (p); + d.setFill (FillType (getRandomColour())); + + addDrawable (d); +} + +void DrawableDocument::addCircle() +{ + Path p; + p.addEllipse ((float) Random::getSystemRandom().nextInt (500), + (float) Random::getSystemRandom().nextInt (500), + 100.0f, 100.0f); + + DrawablePath d; + d.setPath (p); + d.setFill (FillType (getRandomColour())); + + addDrawable (d); +} + +void DrawableDocument::addImage (const File& imageFile) +{ + jassertfalse + + DrawableImage d; + + addDrawable (d); +} + +//============================================================================== +void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const var::identifier& name) +{ + changed(); +} + +void DrawableDocument::valueTreeChildrenChanged (ValueTree& tree) +{ + changed(); +} + +void DrawableDocument::valueTreeParentChanged (ValueTree& tree) +{ + changed(); +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.h new file mode 100644 index 0000000000..09ef86cc98 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_DrawableDocument.h @@ -0,0 +1,83 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DRAWABLEDOCUMENT_JUCEHEADER__ +#define __JUCER_DRAWABLEDOCUMENT_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class DrawableDocument : public ValueTree::Listener, + public ChangeBroadcaster, + public Timer +{ +public: + //============================================================================== + DrawableDocument (Project* project, const File& drawableFile); + ~DrawableDocument(); + + //============================================================================== + void setName (const String& name); + const String getName() const; + + bool reload(); + bool save(); + bool hasChangedSinceLastSave() const; + void changed(); + + ValueTree getRootDrawableNode() const; + + void addRectangle(); + void addCircle(); + void addImage (const File& imageFile); + + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const var::identifier& name); + void valueTreeChildrenChanged (ValueTree& tree); + void valueTreeParentChanged (ValueTree& tree); + + void timerCallback(); + + //============================================================================== + UndoManager* getUndoManager() throw() { return &undoManager; } + +private: + Project* project; + File drawableFile; + ValueTree drawableRoot; + UndoManager undoManager; + bool saveAsXml, needsSaving; + + void save (OutputStream& output); + bool load (InputStream& input); + + void addMissingIds (ValueTree tree) const; + void addDrawable (Drawable& d); +}; + + +#endif // __JUCER_DRAWABLEDOCUMENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.cpp b/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.cpp new file mode 100644 index 0000000000..23ed5fd2c2 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.cpp @@ -0,0 +1,233 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_NewFileWizard.h" +#include "jucer_DrawableDocument.h" +#include "jucer_ComponentDocument.h" + + +//============================================================================== +static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName) +{ + String s = item.getProject().getFileTemplate (templateName) + .replace (T("FILENAME"), file.getFileName(), false) + .replace (T("DATE"), Time::getCurrentTime().toString (true, true, true), false) + .replace (T("AUTHOR"), SystemStats::getFullUserName(), false) + .replace (T("HEADERGUARD"), makeHeaderGuardName (file), false); + + return overwriteFileWithNewDataIfDifferent (file, s); +} + +//============================================================================== +class NewCppFileWizard : public NewFileWizard +{ +public: + NewCppFileWizard() {} + ~NewCppFileWizard() {} + + const String getName() { return "CPP File"; } + + void createNewFile (Project::Item parent) + { + File newFile = askUserToChooseNewFile ("SourceCode.cpp", "*.cpp", parent); + + if (newFile != File::nonexistent) + { + if (fillInNewCppFileTemplate (newFile, parent, "jucer_NewCppFileTemplate_cpp")) + parent.addFile (newFile, 0); + else + showFailedToWriteMessage (newFile); + } + } +}; + +//============================================================================== +class NewHeaderFileWizard : public NewFileWizard +{ +public: + NewHeaderFileWizard() {} + ~NewHeaderFileWizard() {} + + const String getName() { return "Header File"; } + + void createNewFile (Project::Item parent) + { + File newFile = askUserToChooseNewFile ("SourceCode.h", "*.h", parent); + + if (newFile != File::nonexistent) + { + if (fillInNewCppFileTemplate (newFile, parent, "jucer_NewCppFileTemplate_h")) + parent.addFile (newFile, 0); + else + showFailedToWriteMessage (newFile); + } + } +}; + +//============================================================================== +class NewComponentWizard : public NewFileWizard +{ +public: + NewComponentWizard() {} + ~NewComponentWizard() {} + + const String getName() { return "Component"; } + + void createNewFile (Project::Item parent) + { + File cppFile = askUserToChooseNewFile ("Component.cpp", "*.cpp", parent); + + if (cppFile != File::nonexistent) + { + File header (cppFile.withFileExtension (".h")); + + if (header.exists()) + { + if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, "Create New Component", + "The file " + header.getFileName() + " already exists...\n\nDo you want to overwrite it?", + "Overwrite", "Cancel")) + return; + } + + ComponentDocument doc (&parent.getProject(), cppFile); + + if (doc.save()) + { + parent.addFile (header, 0); + parent.addFile (cppFile, 0); + } + else + { + showFailedToWriteMessage (cppFile); + } + } + } +}; + +//============================================================================== +class NewDrawableWizard : public NewFileWizard +{ +public: + NewDrawableWizard() {} + ~NewDrawableWizard() {} + + const String getName() { return "Drawable"; } + + void createNewFile (Project::Item parent) + { + File newFile = askUserToChooseNewFile ("New Drawable.drawable", "*.drawable", parent); + + if (newFile != File::nonexistent) + { + DrawableDocument newDrawable (&(parent.getProject()), newFile); + + if (newDrawable.save()) + parent.addFile (newFile, 0); + else + showFailedToWriteMessage (newFile); + } + } +}; + +//============================================================================== +const StringArray NewFileWizard::getWizards() +{ + StringArray s; + + for (int i = 0; i < getNumWizards(); ++i) + { + ScopedPointer wiz (createWizard (i)); + s.add (wiz->getName()); + } + + return s; +} + +int NewFileWizard::getNumWizards() +{ + return 2; +} + +NewFileWizard* NewFileWizard::createWizard (int index) +{ + switch (index) + { + case 0: return new NewCppFileWizard(); + case 1: return new NewHeaderFileWizard(); + case 2: return new NewComponentWizard(); + case 3: return new NewDrawableWizard(); + default: jassertfalse; break; + } + + return 0; +} + +static const int menuBaseID = 0x12d83f0; + +void NewFileWizard::addWizardsToMenu (PopupMenu& m) +{ + for (int i = 0; i < getNumWizards(); ++i) + { + ScopedPointer wiz (createWizard (i)); + m.addItem (menuBaseID + i, "Add New " + wiz->getName() + "..."); + } +} + +bool NewFileWizard::runWizardFromMenu (int chosenMenuItemID, const Project::Item& projectGroupToAddTo) +{ + int index = chosenMenuItemID - menuBaseID; + + if (index >= 0 && index < getNumWizards()) + { + ScopedPointer wiz (createWizard (index)); + + wiz->createNewFile (projectGroupToAddTo); + return true; + } + + return false; +} + +void NewFileWizard::showFailedToWriteMessage (const File& file) +{ + AlertWindow::showMessageBox (AlertWindow::WarningIcon, + "Failed to Create File!", + "Couldn't write to the file: " + file.getFullPathName()); +} + +const File NewFileWizard::askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard, + const Project::Item& projectGroupToAddTo) +{ + FileChooser fc (T("Select File to Create"), + projectGroupToAddTo.determineGroupFolder() + .getChildFile (suggestedFilename) + .getNonexistentSibling(), + wildcard); + + if (fc.browseForFileToSave (true)) + return fc.getResult(); + + return File::nonexistent; +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.h b/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.h new file mode 100644 index 0000000000..047e074962 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_NewFileWizard.h @@ -0,0 +1,62 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_NEWFILEWIZARD_JUCEHEADER__ +#define __JUCER_NEWFILEWIZARD_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class NewFileWizard +{ +public: + virtual ~NewFileWizard() {} + + //============================================================================== + static const StringArray getWizards(); + static int getNumWizards(); + static NewFileWizard* createWizard (int index); + + static void addWizardsToMenu (PopupMenu& m); + static bool runWizardFromMenu (int chosenMenuItemID, const Project::Item& projectGroupToAddTo); + + //============================================================================== + virtual const String getName() = 0; + virtual void createNewFile (Project::Item projectGroupToAddTo) = 0; + +protected: + //============================================================================== + NewFileWizard() {} + + const File askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard, + const Project::Item& projectGroupToAddTo); + + void showFailedToWriteMessage (const File& file); +}; + + +#endif // __JUCER_NEWFILEWIZARD_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_Project.cpp b/extras/Jucer (experimental)/Source/model/jucer_Project.cpp new file mode 100644 index 0000000000..f9ba8d8bd6 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_Project.cpp @@ -0,0 +1,931 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_Project.h" +#include "jucer_ProjectExporter.h" +#include "jucer_ResourceFile.h" +#include "jucer_ProjectSaver.h" +#include "../ui/jucer_OpenDocumentManager.h" + + +//============================================================================== +namespace Tags +{ + const char* const projectRoot = "JUCERPROJECT"; + const char* const projectMainGroup = "MAINGROUP"; + const char* const group = "GROUP"; + const char* const file = "FILE"; + const char* const configurations = "CONFIGURATIONS"; + const char* const configuration = "CONFIGURATION"; + const char* const exporters = "EXPORTFORMATS"; +} + +const char* Project::projectFileExtension = ".jucer"; + +//============================================================================== +Project::Project (const File& file_) + : FileBasedDocument (projectFileExtension, + String ("*") + projectFileExtension, + "Choose a Jucer project to load", + "Save Jucer project"), + projectRoot (Tags::projectRoot) +{ + setFile (file_); + setMissingDefaultValues(); + + setChangedFlag (false); + + projectRoot.addListener (this); +} + +Project::~Project() +{ + projectRoot.removeListener (this); + OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*this, false); +} + +//============================================================================== +void Project::setTitle (const String& newTitle) +{ + projectRoot.setProperty ("name", newTitle, getUndoManagerFor (projectRoot)); + getMainGroup().getName() = newTitle; +} + +const String Project::getDocumentTitle() +{ + return getProjectName().toString(); +} + +void Project::updateProjectSettings() +{ + projectRoot.setProperty ("jucerVersion", ProjectInfo::versionString, 0); + projectRoot.setProperty ("name", getDocumentTitle(), 0); +} + +void Project::setMissingDefaultValues() +{ + if (! projectRoot.hasProperty ("id")) + projectRoot.setProperty ("id", createAlphaNumericUID(), 0); + + // Create main file group if missing + if (! projectRoot.getChildWithName (Tags::projectMainGroup).isValid()) + { + Item mainGroup (*this, ValueTree (Tags::projectMainGroup)); + mainGroup.createUIDIfMissing(); + projectRoot.addChild (mainGroup.getNode(), 0, 0); + } + + if (getDocumentTitle().isEmpty()) + setTitle ("Juce Project"); + + if (! projectRoot.hasProperty ("projectType")) + getProjectType() = (int) application; + + if (! projectRoot.hasProperty ("version")) + getVersion() = "1.0.0"; + + if (! projectRoot.hasProperty ("juceLinkage")) + getJuceLinkageModeValue() = (int) useAmalgamatedJuceViaMultipleTemplates; + + const String juceFolderPath (getRelativePathForFile (StoredSettings::getInstance()->getLastKnownJuceFolder())); + + // Create configs group + if (! projectRoot.getChildWithName (Tags::configurations).isValid()) + { + projectRoot.addChild (ValueTree (Tags::configurations), 0, 0); + createDefaultConfigs(); + } + + if (! projectRoot.getChildWithName (Tags::exporters).isValid()) + createDefaultExporters(); + + const String sanitisedProjectName (makeValidCppIdentifier (getProjectName().toString(), false, true, false)); + + if (! projectRoot.hasProperty ("buildVST")) + { + shouldBuildVST() = true; + shouldBuildRTAS() = false; + shouldBuildAU() = true; + + getPluginName() = getProjectName().toString(); + getPluginDesc() = getProjectName().toString(); + getPluginManufacturer() = "yourcompany"; + getPluginManufacturerCode() = "abcd"; + getPluginCode() = "Abcd"; + getPluginChannelConfigs() = "{1, 1}, {2, 2}"; + getPluginIsSynth() = false; + getPluginWantsMidiInput() = false; + getPluginProducesMidiOut() = false; + getPluginSilenceInProducesSilenceOut() = false; + getPluginTailLengthSeconds() = 0; + getPluginEditorNeedsKeyFocus() = false; + getPluginAUExportPrefix() = sanitisedProjectName + "AU"; + getPluginAUCocoaViewClassName() = sanitisedProjectName + "AU_V1"; + getPluginRTASCategory() = String::empty; + } + + if (! projectRoot.hasProperty ("bundleIdentifier")) + setBundleIdentifierToDefault(); +} + +//============================================================================== +const String Project::loadDocument (const File& file) +{ + XmlDocument doc (file); + ScopedPointer xml (doc.getDocumentElement()); + + if (xml == 0 || ! xml->hasTagName (Tags::projectRoot)) + return "Not a valid Jucer project!"; + + ValueTree newTree (ValueTree::fromXml (*xml)); + + if (! newTree.hasType (Tags::projectRoot)) + return "The document contains errors and couldn't be parsed!"; + + StoredSettings::getInstance()->recentFiles.addFile (file); + StoredSettings::getInstance()->flush(); + projectRoot = newTree; + + setMissingDefaultValues(); + + return String::empty; +} + +const String Project::saveDocument (const File& file) +{ + updateProjectSettings(); + + { + // (getting these forces the values to be sanitised) + OwnedArray flags; + getJuceConfigFlags (flags); + } + + if (isJuceFolder (getLocalJuceFolder())) + StoredSettings::getInstance()->setLastKnownJuceFolder (getLocalJuceFolder().getFullPathName()); + + StoredSettings::getInstance()->recentFiles.addFile (file); + + ProjectSaver saver (*this, file); + return saver.save(); +} + +//============================================================================== +File Project::lastDocumentOpened; + +const File Project::getLastDocumentOpened() +{ + return lastDocumentOpened; +} + +void Project::setLastDocumentOpened (const File& file) +{ + lastDocumentOpened = file; +} + +//============================================================================== +void Project::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) +{ + if (isLibrary()) + getJuceLinkageModeValue() = (int) notLinkedToJuce; + + changed(); +} + +void Project::valueTreeChildrenChanged (ValueTree& tree) +{ + changed(); +} + +void Project::valueTreeParentChanged (ValueTree& tree) +{ +} + +//============================================================================== +const File Project::resolveFilename (const String& filename) const +{ + if (filename.isEmpty()) + return File::nonexistent; + + if (File::isAbsolutePath (filename)) + return File (filename); + + return getFile().getSiblingFile (filename); +} + +const String Project::getRelativePathForFile (const File& file) const +{ + String filename (file.getFullPathName()); + + File relativePathBase (getFile().getParentDirectory()); + + String p1 (relativePathBase.getFullPathName()); + String p2 (file.getFullPathName()); + + while (p1.startsWithChar (File::separator)) + p1 = p1.substring (1); + + while (p2.startsWithChar (File::separator)) + p2 = p2.substring (1); + + if (p1.upToFirstOccurrenceOf (File::separatorString, true, false) + .equalsIgnoreCase (p2.upToFirstOccurrenceOf (File::separatorString, true, false))) + { + filename = file.getRelativePathFrom (relativePathBase); + } + + return filename; +} + +//============================================================================== +bool Project::shouldBeAddedToBinaryResourcesByDefault (const File& file) +{ + return ! file.hasFileExtension (sourceFileExtensions); +} + +Value Project::getProjectType() const +{ + static const char* mappings[] = { "guiapp", "1", "consoleapp", "2", "audioplug", "3", "library", "4", "browserplug", "5", 0 }; + return Value (new ValueRemapperSource (projectRoot.getPropertyAsValue ("projectType", getUndoManagerFor (projectRoot)), mappings)); +} + +const StringArray Project::getProjectTypes() const +{ + const char* types[] = { "Application (GUI)", + "Application (Non-GUI)", + "Audio Plug-in", + //"Browser Plug-in", + "Static Library", + 0 }; + + return StringArray (types); +} + +Value Project::getJuceLinkageModeValue() const +{ + static const char* mappings[] = { "none", "1", "static", "2", "amalg_big", "3", "amalg_template", "4", "amalg_multi", "5", 0 }; + return Value (new ValueRemapperSource (projectRoot.getPropertyAsValue ("juceLinkage", getUndoManagerFor (projectRoot)), mappings)); +} + +const StringArray Project::getJuceLinkageModes() const +{ + const char* types[] = { "Not linked to Juce", + "Linked to Juce Static Library", + "Include Juce Amalgamated Files", + "Include Juce Source Code Directly (In a single file)", + "Include Juce Source Code Directly (Split across several files)", + 0 }; + + return StringArray (types); +} + +const File Project::getLocalJuceFolder() +{ + ScopedPointer exp (ProjectExporter::createPlatformDefaultExporter (*this)); + + if (exp != 0) + { + File f (resolveFilename (exp->getJuceFolder().toString())); + + if (isJuceFolder (f)) + return f; + } + + return StoredSettings::getInstance()->getLastKnownJuceFolder(); +} + +//============================================================================== +void Project::createPropertyEditors (Array & props) +{ + props.add (new TextPropertyComponent (getProjectName(), "Project Name", 256, false)); + props.getLast()->setTooltip ("The name of the project."); + + props.add (new TextPropertyComponent (getVersion(), "Project Version", 16, false)); + props.getLast()->setTooltip ("The project's version number, This should be in the format major.minor.point"); + + props.add (new ChoicePropertyComponent (getProjectType(), "Project Type", getProjectTypes())); + + props.add (new ChoicePropertyComponent (getJuceLinkageModeValue(), "Juce Linkage Method", getJuceLinkageModes())); + props.getLast()->setTooltip ("The method by which your project will be linked to Juce."); + + props.add (new TextPropertyComponent (getBundleIdentifier(), "Bundle Identifier", 256, false)); + props.getLast()->setTooltip ("A unique identifier for this product, mainly for use in Mac builds. It should be something like 'com.yourcompanyname.yourproductname'"); + + if (isAudioPlugin()) + { + props.add (new BooleanPropertyComponent (shouldBuildVST(), "Build VST", "Enabled")); + props.getLast()->setTooltip ("Whether the project should produce a VST plugin."); + props.add (new BooleanPropertyComponent (shouldBuildAU(), "Build AudioUnit", "Enabled")); + props.getLast()->setTooltip ("Whether the project should produce an AudioUnit plugin."); + props.add (new BooleanPropertyComponent (shouldBuildRTAS(), "Build RTAS", "Enabled")); + props.getLast()->setTooltip ("Whether the project should produce an RTAS plugin."); + } + + if (isAudioPlugin()) + { + props.add (new TextPropertyComponent (getPluginName(), "Plugin Name", 128, false)); + props.getLast()->setTooltip ("The name of your plugin (keep it short!)"); + props.add (new TextPropertyComponent (getPluginDesc(), "Plugin Description", 256, false)); + props.getLast()->setTooltip ("A short description of your plugin."); + + props.add (new TextPropertyComponent (getPluginManufacturer(), "Plugin Manufacturer", 256, false)); + props.getLast()->setTooltip ("The name of your company (cannot be blank)."); + props.add (new TextPropertyComponent (getPluginManufacturerCode(), "Plugin Manufacturer Code", 4, false)); + props.getLast()->setTooltip ("A four-character unique ID for your company."); + props.add (new TextPropertyComponent (getPluginCode(), "Plugin Code", 4, false)); + props.getLast()->setTooltip ("A four-character unique ID for your plugin. Note that for AU compatibility, this must contain at least one upper-case letter!"); + + props.add (new TextPropertyComponent (getPluginChannelConfigs(), "Plugin Channel Configurations", 256, false)); + props.getLast()->setTooltip ("This is the set of input/output channel configurations that your plugin can handle. The list is a comma-separated set of pairs of values in the form { numInputs, numOutputs }, and each " + "pair indicates a valid configuration that the plugin can handle. So for example, {1, 1}, {2, 2} means that the plugin can be used in just two configurations: either with 1 input " + "and 1 output, or with 2 inputs and 2 outputs."); + + props.add (new BooleanPropertyComponent (getPluginIsSynth(), "Plugin is a Synth", "Is a Synth")); + props.getLast()->setTooltip ("Enable this if you want your plugin to be treated as a synth or generator. It doesn't make much difference to the plugin itself, but some hosts treat synths differently to other plugins."); + + props.add (new BooleanPropertyComponent (getPluginWantsMidiInput(), "Plugin Midi Input", "Plugin wants midi input")); + props.getLast()->setTooltip ("Enable this if you want your plugin to accept midi messages."); + + props.add (new BooleanPropertyComponent (getPluginProducesMidiOut(), "Plugin Midi Output", "Plugin produces midi output")); + props.getLast()->setTooltip ("Enable this if your plugin is going to produce midi messages."); + + props.add (new BooleanPropertyComponent (getPluginSilenceInProducesSilenceOut(), "Silence", "Silence in produces silence out")); + props.getLast()->setTooltip ("Enable this if your plugin has no tail - i.e. if passing a silent buffer to it will always result in a silent buffer being produced."); + + props.add (new TextPropertyComponent (getPluginTailLengthSeconds(), "Tail Length (in seconds)", 12, false)); + props.getLast()->setTooltip ("This indicates the length, in seconds, of the plugin's tail. This information may or may not be used by the host."); + + props.add (new BooleanPropertyComponent (getPluginEditorNeedsKeyFocus(), "Key Focus", "Plugin editor requires keyboard focus")); + props.getLast()->setTooltip ("Enable this if your plugin needs keyboard input - some hosts can be a bit funny about keyboard focus.."); + + props.add (new TextPropertyComponent (getPluginAUExportPrefix(), "Plugin AU Export Prefix", 64, false)); + props.getLast()->setTooltip ("A prefix for the names of exported entry-point functions that the component exposes - typically this will be a version of your plugin's name that can be used as part of a C++ token."); + + props.add (new TextPropertyComponent (getPluginAUCocoaViewClassName(), "Plugin AU Cocoa View Name", 64, false)); + props.getLast()->setTooltip ("In an AU, this is the name of Cocoa class that creates the UI. Some hosts bizarrely display the class-name, so you might want to make it reflect your plugin. But the name must be " + "UNIQUE to this exact version of your plugin, to avoid objective-C linkage mix-ups that happen when different plugins containing the same class-name are loaded simultaneously."); + + props.add (new TextPropertyComponent (getPluginRTASCategory(), "Plugin RTAS Category", 64, false)); + props.getLast()->setTooltip ("(Leave this blank if your plugin is a synth). This is one of the RTAS categories from FicPluginEnums.h, such as: ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics, " + "ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay, " + "ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction, " + "ePlugInCategory_Dither, ePlugInCategory_SoundField"); + } + + for (int i = props.size(); --i >= 0;) + props.getUnchecked(i)->setPreferredHeight (22); +} + +//============================================================================== +Project::Item Project::getMainGroup() +{ + return Item (*this, projectRoot.getChildWithName (Tags::projectMainGroup)); +} + +Project::Item Project::createNewGroup() +{ + Item item (*this, ValueTree (Tags::group)); + item.createUIDIfMissing(); + item.getName() = "New Group"; + return item; +} + +Project::Item Project::createNewItem (const File& file) +{ + Item item (*this, ValueTree (Tags::file)); + item.createUIDIfMissing(); + item.getName() = file.getFileName(); + item.getShouldCompileValue() = file.hasFileExtension (T("cpp;mm;c;m")); + item.getShouldAddToResourceValue() = shouldBeAddedToBinaryResourcesByDefault (file); + return item; +} + +//============================================================================== +Project::Item::Item (Project& project_, const ValueTree& node_) + : project (project_), node (node_) +{ +} + +Project::Item::Item (const Item& other) + : project (other.project), node (other.node) +{ +} + +Project::Item::~Item() +{ +} + +const String Project::Item::getID() const { return node ["id"]; } + +bool Project::Item::isFile() const { return node.hasType (Tags::file); } +bool Project::Item::isGroup() const { return node.hasType (Tags::group) || isMainGroup(); } +bool Project::Item::isMainGroup() const { return node.hasType (Tags::projectMainGroup); } + +bool Project::Item::canContain (const Item& child) const +{ + if (isFile()) + return false; + + if (isGroup()) + return child.isFile() || child.isGroup(); + + jassertfalse + return false; +} + +bool Project::Item::shouldBeAddedToTargetProject() const +{ + return isFile(); +} + +bool Project::Item::shouldBeCompiled() const +{ + return getShouldCompileValue().getValue(); +} + +Value Project::Item::getShouldCompileValue() const +{ + return node.getPropertyAsValue ("compile", getUndoManager()); +} + +bool Project::Item::shouldBeAddedToBinaryResources() const +{ + return getShouldAddToResourceValue().getValue(); +} + +Value Project::Item::getShouldAddToResourceValue() const +{ + return node.getPropertyAsValue ("resource", getUndoManager()); +} + +const File Project::Item::getFile() const +{ + if (isFile()) + return project.resolveFilename (node ["file"].toString()); + else + return File::nonexistent; +} + +void Project::Item::setFile (const File& file) +{ + node.setProperty ("file", project.getRelativePathForFile (file), getUndoManager()); + jassert (getFile() == file); +} + +const File Project::Item::determineGroupFolder() const +{ + jassert (isGroup()); + File f; + + for (int i = 0; i < getNumChildren(); ++i) + { + f = getChild(i).getFile(); + + if (f.exists()) + return f.getParentDirectory(); + } + + Item parent (getParent()); + if (parent != *this) + { + f = parent.determineGroupFolder(); + + if (f.getChildFile (getName().toString()).isDirectory()) + f = f.getChildFile (getName().toString()); + } + else + { + f = project.getFile().getParentDirectory(); + + if (f.getChildFile ("Source").isDirectory()) + f = f.getChildFile ("Source"); + } + + return f; +} + +void Project::Item::createUIDIfMissing() +{ + if (! node.hasProperty ("id")) + node.setProperty ("id", createAlphaNumericUID(), getUndoManager()); +} + +Value Project::Item::getName() const +{ + return node.getPropertyAsValue ("name", getUndoManager()); +} + +void Project::Item::addChild (const Item& newChild, int insertIndex) +{ + node.addChild (newChild.getNode(), insertIndex, getUndoManager()); +} + +void Project::Item::removeItemFromProject() +{ + node.getParent().removeChild (node, getUndoManager()); +} + +Project::Item Project::Item::getParent() const +{ + if (isMainGroup() || ! isGroup()) + return *this; + + return Item (project, node.getParent()); +} + +struct ItemSorter +{ + static int compareElements (const ValueTree& first, const ValueTree& second) + { + return first["name"].toString().compareIgnoreCase (second["name"].toString()); + } +}; + +void Project::Item::sortAlphabetically() +{ + ItemSorter sorter; + node.sort (sorter); +} + +bool Project::Item::addFile (const File& file, int insertIndex) +{ + if (file == File::nonexistent || file.isHidden() || file.getFileName().startsWithChar ('.')) + return false; + + if (file.isDirectory()) + { + Item group (project.createNewGroup()); + group.getName() = file.getFileNameWithoutExtension(); + + jassert (canContain (group)); + + addChild (group, insertIndex); + //group.setFile (file); + + DirectoryIterator iter (file, false, "*", File::findFilesAndDirectories); + while (iter.next()) + group.addFile (iter.getFile(), -1); + + group.sortAlphabetically(); + } + else if (file.existsAsFile()) + { + Item item (project.createNewItem (file)); + + if (canContain (item)) + { + item.setFile (file); + addChild (item, insertIndex); + } + } + else + { + jassertfalse; + } + + return true; +} + +Image* Project::Item::getIcon() const +{ + if (isFile()) + return LookAndFeel::getDefaultLookAndFeel().getDefaultDocumentFileImage(); + else if (isMainGroup()) + return ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize); + else + return LookAndFeel::getDefaultLookAndFeel().getDefaultFolderImage(); +} + +//============================================================================== +ValueTree Project::getJuceConfigNode() +{ + ValueTree configNode = projectRoot.getChildWithName ("JUCEOPTIONS"); + + if (! configNode.isValid()) + { + configNode = ValueTree ("JUCEOPTIONS"); + projectRoot.addChild (configNode, -1, 0); + } + + return configNode; +} + +void Project::getJuceConfigFlags (OwnedArray & flags) +{ + ValueTree configNode (getJuceConfigNode()); + + File juceConfigH (getLocalJuceFolder().getChildFile ("juce_Config.h")); + StringArray lines; + lines.addLines (juceConfigH.loadFileAsString()); + + for (int i = 0; i < lines.size(); ++i) + { + String line (lines[i].trim()); + + if (line.startsWith (T("/** ")) && line.containsChar (':')) + { + ScopedPointer config (new JuceConfigFlag()); + config->symbol = line.substring (4).upToFirstOccurrenceOf (T(":"), false, false).trim(); + + if (config->symbol.length() > 4) + { + config->description = line.fromFirstOccurrenceOf (T(":"), false, false).trimStart(); + ++i; + while (! (lines[i].contains (T("*/")) || lines[i].contains (T("@see")))) + { + if (lines[i].trim().isNotEmpty()) + config->description = config->description.trim() + " " + lines[i].trim(); + + ++i; + } + + config->description = config->description.upToFirstOccurrenceOf (T("*/"), false, false); + config->value.referTo (getJuceConfigFlag (config->symbol)); + flags.add (config.release()); + } + } + } +} + +Value Project::getJuceConfigFlag (const String& name) +{ + static const char* valueRemappings[] = { "enabled", "1", "disabled", "2", "default", "3", 0 }; + + ValueTree configNode (getJuceConfigNode()); + Value v (new ValueRemapperSource (configNode.getPropertyAsValue (name, getUndoManagerFor (configNode)), + valueRemappings)); + + if ((int) v.getValue() == 0) + v = 3; + + return v; +} + +//============================================================================== +ValueTree Project::getConfigurations() const +{ + return projectRoot.getChildWithName (Tags::configurations); +} + +int Project::getNumConfigurations() const +{ + return getConfigurations().getNumChildren(); +} + +Project::BuildConfiguration Project::getConfiguration (int index) +{ + jassert (index < getConfigurations().getNumChildren()); + return BuildConfiguration (this, getConfigurations().getChild (index)); +} + +bool Project::hasConfigurationNamed (const String& name) const +{ + const ValueTree configs (getConfigurations()); + for (int i = configs.getNumChildren(); --i >= 0;) + if (configs.getChild(i) ["name"].toString() == name) + return true; + + return false; +} + +const String Project::getUniqueConfigName (String name) const +{ + String nameRoot (name); + while (CharacterFunctions::isDigit (nameRoot.getLastCharacter())) + nameRoot = nameRoot.dropLastCharacters (1); + + nameRoot = nameRoot.trim(); + + int suffix = 2; + while (hasConfigurationNamed (name)) + name = nameRoot + " " + String (suffix++); + + return name; +} + +void Project::addNewConfiguration (BuildConfiguration* configToCopy) +{ + const String configName (getUniqueConfigName (configToCopy != 0 ? configToCopy->config ["name"].toString() + : "New Build Configuration")); + + ValueTree configs (getConfigurations()); + + if (! configs.isValid()) + { + projectRoot.addChild (ValueTree (Tags::configurations), 0, getUndoManagerFor (projectRoot)); + configs = getConfigurations(); + } + + ValueTree newConfig (Tags::configuration); + if (configToCopy != 0) + newConfig = configToCopy->config.createCopy(); + + newConfig.setProperty ("name", configName, 0); + + configs.addChild (newConfig, -1, getUndoManagerFor (configs)); +} + +void Project::deleteConfiguration (int index) +{ + ValueTree configs (getConfigurations()); + configs.removeChild (index, getUndoManagerFor (getConfigurations())); +} + +void Project::createDefaultConfigs() +{ + for (int i = 0; i < 2; ++i) + { + addNewConfiguration (0); + BuildConfiguration config = getConfiguration (i); + + const bool debugConfig = i == 0; + + config.getName() = debugConfig ? "Debug" : "Release"; + config.isDebug() = debugConfig; + config.getOptimisationLevel() = debugConfig ? 1 : 2; + config.getTargetBinaryName() = getProjectFilenameRoot(); + } +} + +//============================================================================== +Project::BuildConfiguration::BuildConfiguration (Project* project_, const ValueTree& configNode) + : project (project_), + config (configNode) +{ +} + +Project::BuildConfiguration::BuildConfiguration (const BuildConfiguration& other) + : project (other.project), + config (other.config) +{ +} + +const Project::BuildConfiguration& Project::BuildConfiguration::operator= (const BuildConfiguration& other) +{ + project = other.project; + config = other.config; + return *this; +} + +Project::BuildConfiguration::~BuildConfiguration() +{ +} + +const String Project::BuildConfiguration::getGCCOptimisationFlag() const +{ + const int level = (int) getOptimisationLevel().getValue(); + return String (level <= 1 ? "0" : (level == 2 ? "s" : "3")); +} + +static const char* osxSDKs[] = { "Use default", "10.4 SDK", "10.5 SDK", "10.6 SDK", 0 }; +static const char* osxSDKMappings[] = { "default", "1", "10.4 SDK", "2", "10.5 SDK", "3", "10.6 SDK", "4", "10.7 SDK", "5", 0 }; + +void Project::BuildConfiguration::createPropertyEditors (Array & props) +{ + props.add (new TextPropertyComponent (getName(), "Name", 96, false)); + props.getLast()->setTooltip ("The name of this configuration."); + + props.add (new BooleanPropertyComponent (isDebug(), "Debug mode", "Debugging enabled")); + props.getLast()->setTooltip ("If enabled, this means that the configuration should be built with debug synbols."); + + const char* optimisationLevels[] = { "No optimisation", "Optimise for size and speed", "Optimise for maximum speed", 0 }; + props.add (new ChoicePropertyComponent (getOptimisationLevel(), "Optimisation", StringArray (optimisationLevels))); + props.getLast()->setTooltip ("The optimisation level for this configuration"); + + props.add (new TextPropertyComponent (getTargetBinaryName(), "Binary name", 256, false)); + props.getLast()->setTooltip ("The filename to use for the destination binary executable file. Don't add a suffix to this, because platform-specific suffixes will be added for each target platform."); + + props.add (new TextPropertyComponent (getTargetBinaryRelativePath(), "Binary location", 1024, false)); + props.getLast()->setTooltip ("The folder in which the finished binary should be placed. Leave this blank to cause the binary to be placed in its default location in the build folder."); + + props.add (new TextPropertyComponent (getHeaderSearchPath(), "Header search path", 16384, false)); + props.getLast()->setTooltip ("Extra header search paths. Use semi-colons to separate multiple paths."); + + props.add (new TextPropertyComponent (getPreprocessorDefs(), "Preprocessor definitions", 32768, false)); + props.getLast()->setTooltip ("Extra preprocessor definitions. Use whitespace or commas as a delimiter."); + + if ((int) getMacSDKVersion().getValue() == 0) + getMacSDKVersion() = 1; + + props.add (new ChoicePropertyComponent (getMacSDKVersion(), "OSX Base SDK Version", StringArray (osxSDKs))); + props.getLast()->setTooltip ("The version of OSX to link against in the XCode build."); + + if ((int) getMacCompatibilityVersion().getValue() == 0) + getMacCompatibilityVersion() = 1; + + props.add (new ChoicePropertyComponent (getMacCompatibilityVersion(), "OSX Compatibility Version", StringArray (osxSDKs))); + props.getLast()->setTooltip ("The minimum version of OSX that the target binary will be compatible with."); + + for (int i = props.size(); --i >= 0;) + props.getUnchecked(i)->setPreferredHeight (22); +} + +const StringArray Project::BuildConfiguration::parsePreprocessorDefs() const +{ + StringArray defines; + defines.addTokens (getPreprocessorDefs().toString(), T(" ,;")); + defines.removeEmptyStrings (true); + return defines; +} + +const StringArray Project::BuildConfiguration::getHeaderSearchPaths() const +{ + StringArray s; + s.addTokens (getHeaderSearchPath().toString(), T(";")); + return s; +} + +Value Project::BuildConfiguration::getMacSDKVersion() const +{ + return Value (new ValueRemapperSource (config.getPropertyAsValue ("osxSDK", getUndoManager()), osxSDKMappings)); +} + +Value Project::BuildConfiguration::getMacCompatibilityVersion() const +{ + return Value (new ValueRemapperSource (config.getPropertyAsValue ("osxCompatibility", getUndoManager()), osxSDKMappings)); +} + +//============================================================================== +ValueTree Project::getExporters() +{ + ValueTree exporters (projectRoot.getChildWithName (Tags::exporters)); + + if (! exporters.isValid()) + { + projectRoot.addChild (ValueTree (Tags::exporters), 0, getUndoManagerFor (projectRoot)); + exporters = getExporters(); + } + + return exporters; +} + +int Project::getNumExporters() +{ + return getExporters().getNumChildren(); +} + +ProjectExporter* Project::createExporter (int index) +{ + jassert (index >= 0 && index < getNumExporters()); + return ProjectExporter::createExporter (*this, getExporters().getChild (index)); +} + +void Project::addNewExporter (int exporterIndex) +{ + ScopedPointer exp (ProjectExporter::createNewExporter (*this, exporterIndex)); + + ValueTree exporters (getExporters()); + exporters.addChild (exp->getSettings(), -1, getUndoManagerFor (exporters)); +} + +void Project::deleteExporter (int index) +{ + ValueTree exporters (getExporters()); + exporters.removeChild (index, getUndoManagerFor (exporters)); +} + +void Project::createDefaultExporters() +{ + ValueTree exporters (getExporters()); + exporters.removeAllChildren (getUndoManagerFor (exporters)); + + for (int i = 0; i < ProjectExporter::getNumExporters(); ++i) + addNewExporter (i); +} + +//============================================================================== +const String Project::getFileTemplate (const String& templateName) +{ + int dataSize; + const char* data = BinaryData::getNamedResource (templateName, dataSize); + + if (data == 0) + { + jassertfalse; + return String::empty; + } + + return String::fromUTF8 (data, dataSize); +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_Project.h b/extras/Jucer (experimental)/Source/model/jucer_Project.h new file mode 100644 index 0000000000..e671af046c --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_Project.h @@ -0,0 +1,306 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECT_JUCEHEADER__ +#define __JUCER_PROJECT_JUCEHEADER__ + +#include "../jucer_Headers.h" +class ProjectExporter; + +//============================================================================== +class Project : public FileBasedDocument, + public ValueTree::Listener +{ +public: + //============================================================================== + Project (const File& file); + ~Project(); + + //============================================================================== + // FileBasedDocument stuff.. + const String getDocumentTitle(); + const String loadDocument (const File& file); + const String saveDocument (const File& file); + const File getLastDocumentOpened(); + void setLastDocumentOpened (const File& file); + + void setTitle (const String& newTitle); + + //============================================================================== + ValueTree getProjectRoot() const { return projectRoot; } + Value getProjectName() { return getMainGroup().getName(); } + const String getProjectFilenameRoot() { return File::createLegalFileName (getDocumentTitle()); } + const String getProjectUID() const { return projectRoot ["id"]; } + + //============================================================================== + bool shouldBeAddedToBinaryResourcesByDefault (const File& file); + const File resolveFilename (const String& filename) const; + const String getRelativePathForFile (const File& file) const; + + //============================================================================== + // Creates editors for the project settings + void createPropertyEditors (Array & properties); + + //============================================================================== + // project type info + enum ProjectType + { + application = 1, // must all be sequntial, starting from 1, so that combo boxes can update correctly + commandLineApp = 2, + audioPlugin = 3, + library = 4, + browserPlugin = 5 + }; + + const StringArray getProjectTypes() const; + Value getProjectType() const; + + bool isLibrary() const { return (int) getProjectType().getValue() == (int) library; } + bool isGUIApplication() const { return (int) getProjectType().getValue() == (int) application; } + bool isCommandLineApp() const { return (int) getProjectType().getValue() == (int) commandLineApp; } + bool isAudioPlugin() const { return (int) getProjectType().getValue() == (int) audioPlugin; } + bool isBrowserPlugin() const { return (int) getProjectType().getValue() == (int) browserPlugin; } + + Value getVersion() const { return getProjectValue ("version"); } + Value getBundleIdentifier() const { return getProjectValue ("bundleIdentifier"); } + void setBundleIdentifierToDefault() { getBundleIdentifier() = "com.yourcompany." + makeValidCppIdentifier (getProjectName().toString(), false, true, false); } + + //============================================================================== + enum JuceLinkage + { + notLinkedToJuce = 1, // must all be sequntial, starting from 1, so that combo boxes can update correctly + useLinkedJuce = 2, + useAmalgamatedJuce = 3, + useAmalgamatedJuceViaSingleTemplate = 4, + useAmalgamatedJuceViaMultipleTemplates = 5, + }; + + const StringArray getJuceLinkageModes() const; + Value getJuceLinkageModeValue() const; + JuceLinkage getJuceLinkageMode() const { return (JuceLinkage) (int) getJuceLinkageModeValue().getValue(); } + + bool isUsingWrapperFiles() const { return isUsingFullyAmalgamatedFile() || isUsingSingleTemplateFile() || isUsingMultipleTemplateFiles(); } + bool isUsingFullyAmalgamatedFile() const { return getJuceLinkageMode() == useAmalgamatedJuce; } + bool isUsingSingleTemplateFile() const { return getJuceLinkageMode() == useAmalgamatedJuceViaSingleTemplate; } + bool isUsingMultipleTemplateFiles() const { return getJuceLinkageMode() == useAmalgamatedJuceViaMultipleTemplates; } + + //============================================================================== + Value getProjectValue (const var::identifier& name) const { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); } + + Value shouldBuildVST() const { return getProjectValue ("buildVST"); } + Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); } + Value shouldBuildAU() const { return getProjectValue ("buildAU"); } + bool shouldAddVSTFolderToPath() { return (isAudioPlugin() && (bool) shouldBuildVST().getValue()) || (int) getJuceConfigFlag ("JUCE_PLUGINHOST_VST").getValue() == 1; } + + Value getPluginName() const { return getProjectValue ("pluginName"); } + Value getPluginDesc() const { return getProjectValue ("pluginDesc"); } + Value getPluginManufacturer() const { return getProjectValue ("pluginManufacturer"); } + Value getPluginManufacturerCode() const { return getProjectValue ("pluginManufacturerCode"); } + Value getPluginCode() const { return getProjectValue ("pluginCode"); } + Value getPluginChannelConfigs() const { return getProjectValue ("pluginChannelConfigs"); } + Value getPluginIsSynth() const { return getProjectValue ("pluginIsSynth"); } + Value getPluginWantsMidiInput() const { return getProjectValue ("pluginWantsMidiIn"); } + Value getPluginProducesMidiOut() const { return getProjectValue ("pluginProducesMidiOut"); } + Value getPluginSilenceInProducesSilenceOut() const { return getProjectValue ("pluginSilenceInIsSilenceOut"); } + Value getPluginTailLengthSeconds() const { return getProjectValue ("pluginTailLength"); } + Value getPluginEditorNeedsKeyFocus() const { return getProjectValue ("pluginEditorRequiresKeys"); } + Value getPluginAUExportPrefix() const { return getProjectValue ("pluginAUExportPrefix"); } + Value getPluginAUCocoaViewClassName() const { return getProjectValue ("pluginAUViewClass"); } + Value getPluginRTASCategory() const { return getProjectValue ("pluginRTASCategory"); } + + //============================================================================== + const File getAppIncludeFile() const { return getWrapperFolder().getChildFile (getJuceSourceHFilename()); } + const File getWrapperFolder() const { return getFile().getSiblingFile ("JuceLibraryCode"); } + const File getPluginCharacteristicsFile() const { return getWrapperFolder().getChildFile (getPluginCharacteristicsFilename()); } + + //============================================================================== + const String getAmalgamatedHeaderFileName() const { return "juce_amalgamated.h"; } + const String getAmalgamatedMMFileName() const { return "juce_amalgamated.mm"; } + const String getAmalgamatedCppFileName() const { return "juce_amalgamated.cpp"; } + + const String getAppConfigFilename() const { return "AppConfig.h"; } + const String getJuceSourceFilenameRoot() const { return "JuceLibraryCode"; } + int getNumSeparateAmalgamatedFiles() const { return 4; } + const String getJuceSourceHFilename() const { return "JuceHeader.h"; } + const String getJuceCodeGroupName() const { return "Juce Library Code"; } + const String getPluginCharacteristicsFilename() const { return "JucePluginCharacteristics.h"; } + + //============================================================================== + class Item + { + public: + //============================================================================== + Item (Project& project, const ValueTree& itemNode); + Item (const Item& other); + ~Item(); + + //============================================================================== + const ValueTree& getNode() const throw() { return node; } + ValueTree& getNode() throw() { return node; } + Project& getProject() const throw() { return project; } + bool operator== (const Item& other) const { return node == other.node && &project == &other.project; } + bool operator!= (const Item& other) const { return ! operator== (other); } + + //============================================================================== + bool isFile() const; + bool isGroup() const; + bool isMainGroup() const; + + const String getID() const; + void createUIDIfMissing(); + + //============================================================================== + Value getName() const; + const File getFile() const; + void setFile (const File& file); + const File determineGroupFolder() const; + + bool shouldBeAddedToTargetProject() const; + bool shouldBeCompiled() const; + Value getShouldCompileValue() const; + bool shouldBeAddedToBinaryResources() const; + Value getShouldAddToResourceValue() const; + + //============================================================================== + bool canContain (const Item& child) const; + int getNumChildren() const { return node.getNumChildren(); } + const Item getChild (int index) const { return Item (project, node.getChild (index)); } + void addChild (const Item& newChild, int insertIndex); + bool addFile (const File& file, int insertIndex); + void removeItemFromProject(); + void sortAlphabetically(); + + Item getParent() const; + + Image* getIcon() const; + + private: + //============================================================================== + Project& project; + ValueTree node; + + UndoManager* getUndoManager() const { return project.getUndoManagerFor (node); } + Item& operator= (const Item&); + }; + + Item getMainGroup(); + Item createNewGroup(); + Item createNewItem (const File& file); + + //============================================================================== + class BuildConfiguration + { + public: + BuildConfiguration (const BuildConfiguration&); + const BuildConfiguration& operator= (const BuildConfiguration&); + ~BuildConfiguration(); + + //============================================================================== + Project& getProject() const { return *project; } + + void createPropertyEditors (Array & properties); + + //============================================================================== + Value getName() const { return config.getPropertyAsValue ("name", getUndoManager()); } + Value isDebug() const { return config.getPropertyAsValue ("isDebug", getUndoManager()); } + Value getTargetBinaryName() const { return config.getPropertyAsValue ("targetName", getUndoManager()); } + // the path relative to the build folder in which the binary should go + Value getTargetBinaryRelativePath() const { return config.getPropertyAsValue ("binaryPath", getUndoManager()); } + Value getOptimisationLevel() const { return config.getPropertyAsValue ("optimisation", getUndoManager()); } + const String getGCCOptimisationFlag() const; + Value getPreprocessorDefs() const { return config.getPropertyAsValue ("defines", getUndoManager()); } + const StringArray parsePreprocessorDefs() const; + Value getHeaderSearchPath() const { return config.getPropertyAsValue ("headerPath", getUndoManager()); } + const StringArray getHeaderSearchPaths() const; + Value getMacSDKVersion() const; + Value getMacCompatibilityVersion() const; + + //============================================================================== + private: + friend class Project; + Project* project; + ValueTree config; + + UndoManager* getUndoManager() const { return project->getUndoManagerFor (config); } + + BuildConfiguration (Project* project, const ValueTree& configNode); + }; + + int getNumConfigurations() const; + BuildConfiguration getConfiguration (int index); + void addNewConfiguration (BuildConfiguration* configToCopy); + void deleteConfiguration (int index); + bool hasConfigurationNamed (const String& name) const; + const String getUniqueConfigName (String name) const; + + //============================================================================== + ValueTree getExporters(); + int getNumExporters(); + ProjectExporter* createExporter (int index); + void addNewExporter (int exporterIndex); + void deleteExporter (int index); + void createDefaultExporters(); + + //============================================================================== + struct JuceConfigFlag + { + String symbol, description; + Value value; // 1 = true, 2 = false, anything else = use default + }; + + void getJuceConfigFlags (OwnedArray & flags); + Value getJuceConfigFlag (const String& name); + + //============================================================================== + const String getFileTemplate (const String& templateName); + + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property); + void valueTreeChildrenChanged (ValueTree& tree); + void valueTreeParentChanged (ValueTree& tree); + + //============================================================================== + UndoManager* getUndoManagerFor (const ValueTree& node) const { return 0; } + + //============================================================================== + static const char* projectFileExtension; + +private: + ValueTree projectRoot; + static File lastDocumentOpened; + + const File getLocalJuceFolder(); + void updateProjectSettings(); + void setMissingDefaultValues(); + ValueTree getConfigurations() const; + void createDefaultConfigs(); + ValueTree getJuceConfigNode(); + + Project (const Project&); + const Project& operator= (const Project&); +}; + + +#endif // __JUCER_PROJECT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h new file mode 100644 index 0000000000..dc88c8dce8 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h @@ -0,0 +1,592 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTEXPORT_MSVC_JUCEHEADER__ +#define __JUCER_PROJECTEXPORT_MSVC_JUCEHEADER__ + +#include "jucer_ProjectExporter.h" + + +//============================================================================== +class MSVCProjectExporter : public ProjectExporter +{ +public: + //============================================================================== + enum VisualStudioVersion + { + visualStudio2005, + visualStudio2008 + }; + + static const char* getName2005() { return "Visual Studio 2005"; } + static const char* getName2008() { return "Visual Studio 2008"; } + + static const char* getValueTreeTypeName (VisualStudioVersion version) + { + switch (version) + { + case visualStudio2005: return "VS2005"; break; + case visualStudio2008: return "VS2008"; break; + default: jassertfalse; break; + } + + return 0; + } + + //============================================================================== + static MSVCProjectExporter* createForSettings (Project& project, const ValueTree& settings) + { + if (settings.hasType (getValueTreeTypeName (visualStudio2005))) + return new MSVCProjectExporter (project, settings, visualStudio2005); + else if (settings.hasType (getValueTreeTypeName (visualStudio2008))) + return new MSVCProjectExporter (project, settings, visualStudio2008); + + return 0; + } + + //============================================================================== + MSVCProjectExporter (Project& project_, const ValueTree& settings_, const VisualStudioVersion version_) + : ProjectExporter (project_, settings_), version (version_) + { + String subFolderName (getDefaultBuildsRootFolder()); + + switch (version) + { + case visualStudio2005: name = "Visual Studio 2005"; subFolderName += "VisualStudio2005"; break; + case visualStudio2008: name = "Visual Studio 2008"; subFolderName += "VisualStudio2008"; break; + default: jassertfalse; break; + } + + if (getTargetLocation().toString().isEmpty()) + getTargetLocation() = subFolderName; + + if (getVSTFolder().toString().isEmpty()) + getVSTFolder() = "c:\\SDKs\\vstsdk2.4"; + + if (getRTASFolder().toString().isEmpty()) + getRTASFolder() = "c:\\SDKs\\PT_80_SDK"; + } + + ~MSVCProjectExporter() {} + + //============================================================================== + bool isDefaultFormatForCurrentOS() + { + #if JUCE_WINDOWS + return true; + #else + return false; + #endif + } + + bool isPossibleForCurrentProject() { return true; } + bool usesMMFiles() const { return false; } + const String getOSTestMacro() { return "(defined (_WIN32) || defined (_WIN64))"; } + + void launchProject() + { + getSLNFile().startAsProcess(); + } + + void createPropertyEditors (Array & props) + { + ProjectExporter::createPropertyEditors (props); + } + + //============================================================================== + const String create() + { + projectGUID = createGUID (project.getProjectUID()); + + XmlElement masterXml ("VisualStudioProject"); + fillInMasterXml (masterXml); + + { + MemoryOutputStream mo; + masterXml.writeToStream (mo, String::empty, false, true, "UTF-8", 10); + + if (! overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) + return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); + } + + { + MemoryOutputStream mo; + writeSolutionFile (mo); + + if (! overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) + return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); + } + + return String::empty; + } + +private: + String projectGUID; + const VisualStudioVersion version; + + const File getVCProjFile() const { return getTargetFolder().getChildFile (project.getProjectFilenameRoot()).withFileExtension (".vcproj"); } + const File getSLNFile() const { return getVCProjFile().withFileExtension (".sln"); } + + + //============================================================================== + void fillInMasterXml (XmlElement& masterXml) + { + masterXml.setAttribute ("ProjectType", "Visual C++"); + + switch (version) + { + case visualStudio2005: masterXml.setAttribute ("Version", "8.00"); break; + case visualStudio2008: masterXml.setAttribute ("Version", "9.00"); break; + default: jassertfalse; break; + } + + masterXml.setAttribute ("Name", project.getProjectName().toString()); + masterXml.setAttribute ("ProjectGUID", projectGUID); + masterXml.setAttribute ("TargetFrameworkVersion", "131072"); + + { + XmlElement* platforms = masterXml.createNewChildElement ("Platforms"); + XmlElement* platform = platforms->createNewChildElement ("Platform"); + platform->setAttribute ("Name", "Win32"); + } + + masterXml.createNewChildElement ("ToolFiles"); + createConfigs (*masterXml.createNewChildElement ("Configurations")); + masterXml.createNewChildElement ("References"); + createFiles (*masterXml.createNewChildElement ("Files")); + masterXml.createNewChildElement ("Globals"); + } + + //============================================================================== + void addFile (const RelativePath& file, XmlElement& parent, const bool excludeFromBuild, const bool useStdcall) + { + jassert (file.getRoot() == RelativePath::buildTargetFolder); + + XmlElement* fileXml = parent.createNewChildElement ("File"); + fileXml->setAttribute ("RelativePath", file.toWindowsStyle()); + + if (excludeFromBuild || useStdcall) + { + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + + XmlElement* fileConfig = fileXml->createNewChildElement ("FileConfiguration"); + fileConfig->setAttribute ("Name", createConfigName (config)); + + if (excludeFromBuild) + fileConfig->setAttribute ("ExcludedFromBuild", "true"); + + XmlElement* tool = createToolElement (*fileConfig, "VCCLCompilerTool"); + + if (useStdcall) + tool->setAttribute ("CallingConvention", "2"); + } + } + } + + XmlElement* createGroup (const String& name, XmlElement& parent) + { + XmlElement* filter = parent.createNewChildElement ("Filter"); + filter->setAttribute ("Name", name); + return filter; + } + + void addFiles (const Project::Item& projectItem, XmlElement& parent) + { + if (projectItem.isGroup()) + { + XmlElement* filter = createGroup (projectItem.getName().toString(), parent); + + for (int i = 0; i < projectItem.getNumChildren(); ++i) + addFiles (projectItem.getChild(i), *filter); + } + else + { + if (projectItem.shouldBeAddedToTargetProject()) + { + const RelativePath path (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder); + + addFile (path, parent, + projectItem.shouldBeAddedToBinaryResources() || (shouldFileBeCompiledByDefault (path) && ! projectItem.shouldBeCompiled()), + false); + } + } + } + + void addGroup (XmlElement& parent, const String& groupName, const Array& files, const bool useStdcall) + { + if (files.size() > 0) + { + XmlElement* const group = createGroup (groupName, parent); + + for (int i = 0; i < files.size(); ++i) + if (files.getReference(i).hasFileExtension ("cpp;c;h")) + addFile (files.getReference(i), *group, false, + useStdcall && shouldFileBeCompiledByDefault (files.getReference(i))); + } + } + + void createFiles (XmlElement& files) + { + addFiles (project.getMainGroup(), files); + + addGroup (files, project.getJuceCodeGroupName(), juceWrapperFiles, false); + addGroup (files, "Juce VST Wrapper", getVSTFilesRequired(), false); + addGroup (files, "Juce RTAS Wrapper", getRTASFilesRequired(), true); + } + + //============================================================================== + const Array getRTASFilesRequired() const + { + Array s; + if (isRTAS()) + { + static const char* files[] = { "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode1.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode2.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode3.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode_Header.h", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_WinUtilities.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp" }; + + for (int i = 0; i < numElementsInArray (files); ++i) + s.add (getJucePathFromTargetFolder().getChildFile (files[i])); + } + + return s; + } + + const String getIntermediatesPath (const Project::BuildConfiguration& config) const + { + return ".\\" + File::createLegalFileName (config.getName().toString().trim()); + } + + const String getConfigTargetPath (const Project::BuildConfiguration& config) const + { + const String binaryPath (config.getTargetBinaryRelativePath().toString().trim()); + if (binaryPath.isEmpty()) + return getIntermediatesPath (config); + + return ".\\" + RelativePath (binaryPath, RelativePath::projectFolder) + .rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder) + .toWindowsStyle(); + } + + const String getTargetBinarySuffix() const + { + if (project.isLibrary()) + return ".lib"; + else if (isRTAS()) + return ".dpm"; + else if (project.isAudioPlugin() || project.isBrowserPlugin()) + return ".dll"; + + return ".exe"; + } + + const String getPreprocessorDefs (const Project::BuildConfiguration& config) const + { + StringArray defines; + defines.add ("WIN32"); + defines.add ("_WINDOWS"); + defines.add (config.isDebug().getValue() ? "_DEBUG" : "NDEBUG"); + if (project.isCommandLineApp()) + defines.add ("_CONSOLE"); + + if (project.isLibrary()) + defines.add ("_LIB"); + + if (isRTAS()) + { + RelativePath rtasFolder (getRTASFolder().toString(), RelativePath::unknown); + defines.add ("JucePlugin_WinBag_path=" + + replaceCEscapeChars (rtasFolder.getChildFile ("WinBag") + .toWindowsStyle().quoted())); + } + + defines.addArray (config.parsePreprocessorDefs()); + return defines.joinIntoString (";"); + } + + const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) const + { + StringArray searchPaths (config.getHeaderSearchPaths()); + + if (project.shouldAddVSTFolderToPath() && getVSTFolder().toString().isNotEmpty()) + searchPaths.add (RelativePath (getVSTFolder().toString(), RelativePath::projectFolder) + .rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder) + .toWindowsStyle()); + + if (project.isAudioPlugin()) + searchPaths.add (juceWrapperFiles[0].getParentDirectory().toWindowsStyle()); + + if (isRTAS()) + { + static const char* rtasIncludePaths[] = { "AlturaPorts/TDMPlugins/PluginLibrary/EffectClasses", + "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses", + "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses/Interfaces", + "AlturaPorts/TDMPlugins/PluginLibrary/Utilities", + "AlturaPorts/TDMPlugins/PluginLibrary/RTASP_Adapt", + "AlturaPorts/TDMPlugins/PluginLibrary/CoreClasses", + "AlturaPorts/TDMPlugins/PluginLibrary/Controls", + "AlturaPorts/TDMPlugins/PluginLibrary/Meters", + "AlturaPorts/TDMPlugins/PluginLibrary/ViewClasses", + "AlturaPorts/TDMPlugins/PluginLibrary/DSPClasses", + "AlturaPorts/TDMPlugins/PluginLibrary/Interfaces", + "AlturaPorts/TDMPlugins/common", + "AlturaPorts/TDMPlugins/common/Platform", + "AlturaPorts/TDMPlugins/SignalProcessing/Public", + "AlturaPorts/TDMPlugIns/DSPManager/Interfaces", + "AlturaPorts/SADriver/Interfaces", + "AlturaPorts/DigiPublic/Interfaces", + "AlturaPorts/Fic/Interfaces/DAEClient", + "AlturaPorts/NewFileLibs/Cmn", + "AlturaPorts/NewFileLibs/DOA", + "AlturaPorts/AlturaSource/PPC_H", + "AlturaPorts/AlturaSource/AppSupport", + "AvidCode/AVX2sdk/AVX/avx2/avx2sdk/inc", + "xplat/AVX/avx2/avx2sdk/inc" }; + + RelativePath sdkFolder (getRTASFolder().toString(), RelativePath::projectFolder); + sdkFolder = sdkFolder.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder); + + for (int i = 0; i < numElementsInArray (rtasIncludePaths); ++i) + searchPaths.add (sdkFolder.getChildFile (rtasIncludePaths[i]).toWindowsStyle()); + } + + return searchPaths; + } + + XmlElement* createToolElement (XmlElement& parent, const String& name) const + { + XmlElement* const e = parent.createNewChildElement ("Tool"); + e->setAttribute ("Name", name); + return e; + } + + void createConfig (XmlElement& xml, const Project::BuildConfiguration& config) const + { + String binariesPath (getConfigTargetPath (config)); + String intermediatesPath (getIntermediatesPath (config)); + const bool isDebug = (bool) config.isDebug().getValue(); + const String binaryName (File::createLegalFileName (config.getTargetBinaryName().toString())); + + xml.setAttribute ("Name", createConfigName (config)); + xml.setAttribute ("OutputDirectory", windowsStylePath (binariesPath)); + xml.setAttribute ("IntermediateDirectory", windowsStylePath (intermediatesPath)); + xml.setAttribute ("ConfigurationType", (project.isAudioPlugin() || project.isBrowserPlugin()) + ? "2" : (project.isLibrary() ? "4" : "1")); + xml.setAttribute ("UseOfMFC", "0"); + xml.setAttribute ("ATLMinimizesCRunTimeLibraryUsage", "false"); + xml.setAttribute ("CharacterSet", "2"); + + if (! isDebug) + xml.setAttribute ("WholeProgramOptimization", "1"); + + createToolElement (xml, "VCPreBuildEventTool"); + + XmlElement* customBuild = createToolElement (xml, "VCCustomBuildTool"); + + if (isRTAS()) + { + RelativePath rsrFile (getJucePathFromTargetFolder().getChildFile ("extras/audio plugins/wrapper/RTAS/juce_RTAS_WinResources.rsr")); + + customBuild->setAttribute ("CommandLine", "copy /Y \"" + rsrFile.toWindowsStyle() + "\" \"$(TargetPath)\".rsr"); + customBuild->setAttribute ("Outputs", "\"$(TargetPath)\".rsr"); + } + + createToolElement (xml, "VCXMLDataGeneratorTool"); + createToolElement (xml, "VCWebServiceProxyGeneratorTool"); + + if (! project.isLibrary()) + { + XmlElement* midl = createToolElement (xml, "VCMIDLTool"); + midl->setAttribute ("PreprocessorDefinitions", isDebug ? "_DEBUG" : "NDEBUG"); + midl->setAttribute ("MkTypLibCompatible", "true"); + midl->setAttribute ("SuppressStartupBanner", "true"); + midl->setAttribute ("TargetEnvironment", "1"); + midl->setAttribute ("TypeLibraryName", windowsStylePath (intermediatesPath + "/" + binaryName + ".tlb")); + midl->setAttribute ("HeaderFileName", ""); + } + + { + XmlElement* compiler = createToolElement (xml, "VCCLCompilerTool"); + + const int optimiseLevel = (int) config.getOptimisationLevel().getValue(); + compiler->setAttribute ("Optimization", optimiseLevel <= 1 ? "0" : (optimiseLevel == 2 ? "2" : "3")); + + if (isDebug) + { + compiler->setAttribute ("BufferSecurityCheck", ""); + compiler->setAttribute ("DebugInformationFormat", "4"); + } + else + { + compiler->setAttribute ("InlineFunctionExpansion", "1"); + compiler->setAttribute ("StringPooling", "true"); + } + + compiler->setAttribute ("AdditionalIncludeDirectories", getHeaderSearchPaths (config).joinIntoString (";")); + compiler->setAttribute ("PreprocessorDefinitions", getPreprocessorDefs (config)); + compiler->setAttribute ("RuntimeLibrary", isRTAS() ? (isDebug ? 3 : 2) // MT DLL + : (isDebug ? 1 : 0)); // MT static + compiler->setAttribute ("RuntimeTypeInfo", "true"); + compiler->setAttribute ("UsePrecompiledHeader", "0"); + compiler->setAttribute ("PrecompiledHeaderFile", windowsStylePath (intermediatesPath + "/" + binaryName + ".pch")); + compiler->setAttribute ("AssemblerListingLocation", windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("ObjectFile", windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("ProgramDataBaseFileName", windowsStylePath (intermediatesPath + "/")); + compiler->setAttribute ("WarningLevel", "3"); + compiler->setAttribute ("SuppressStartupBanner", "true"); + } + + createToolElement (xml, "VCManagedResourceCompilerTool"); + + { + XmlElement* resCompiler = createToolElement (xml, "VCResourceCompilerTool"); + resCompiler->setAttribute ("PreprocessorDefinitions", isDebug ? "_DEBUG" : "NDEBUG"); + } + + createToolElement (xml, "VCPreLinkEventTool"); + + if (! project.isLibrary()) + { + XmlElement* linker = createToolElement (xml, "VCLinkerTool"); + + linker->setAttribute ("OutputFile", windowsStylePath (binariesPath + "/" + config.getTargetBinaryName().toString() + getTargetBinarySuffix())); + linker->setAttribute ("SuppressStartupBanner", "true"); + + if (project.getJuceLinkageMode() == Project::useLinkedJuce) + linker->setAttribute ("AdditionalLibraryDirectories", getJucePathFromTargetFolder().getChildFile ("bin").toWindowsStyle()); + + linker->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : ""); + linker->setAttribute ("GenerateDebugInformation", isDebug ? "true" : "false"); + linker->setAttribute ("ProgramDatabaseFile", windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb")); + linker->setAttribute ("SubSystem", project.isCommandLineApp() ? "1" : "2"); + + if (! isDebug) + { + linker->setAttribute ("GenerateManifest", "false"); + linker->setAttribute ("OptimizeReferences", "2"); + linker->setAttribute ("EnableCOMDATFolding", "2"); + } + + linker->setAttribute ("RandomizedBaseAddress", "1"); + linker->setAttribute ("DataExecutionPrevention", "0"); + linker->setAttribute ("TargetMachine", "1"); + + if (isRTAS()) + { + linker->setAttribute ("AdditionalOptions", "/FORCE:multiple"); + linker->setAttribute ("DelayLoadDLLs", "DAE.dll; DigiExt.dll; DSI.dll; PluginLib.dll; DSPManager.dll"); + linker->setAttribute ("ModuleDefinitionFile", getJucePathFromTargetFolder() + .getChildFile ("extras/audio plugins/wrapper/RTAS/juce_RTAS_WinExports.def") + .toWindowsStyle()); + } + } + else + { + XmlElement* librarian = createToolElement (xml, "VCLibrarianTool"); + + librarian->setAttribute ("OutputFile", windowsStylePath (binariesPath + "/" + config.getTargetBinaryName().toString() + getTargetBinarySuffix())); + librarian->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : ""); + } + + createToolElement (xml, "VCALinkTool"); + createToolElement (xml, "VCManifestTool"); + createToolElement (xml, "VCXDCMakeTool"); + + { + XmlElement* bscMake = createToolElement (xml, "VCBscMakeTool"); + bscMake->setAttribute ("SuppressStartupBanner", "true"); + bscMake->setAttribute ("OutputFile", windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc")); + } + + createToolElement (xml, "VCFxCopTool"); + + if (! project.isLibrary()) + createToolElement (xml, "VCAppVerifierTool"); + + createToolElement (xml, "VCPostBuildEventTool"); + } + + void createConfigs (XmlElement& configs) + { + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + createConfig (*configs.createNewChildElement ("Configuration"), config); + } + } + + const String createConfigName (const Project::BuildConfiguration& config) const + { + return config.getName().toString() + "|Win32"; + } + + //============================================================================== + void writeSolutionFile (OutputStream& out) + { + out << newLine << "Microsoft Visual Studio Solution File, Format Version "; + + switch (version) + { + case visualStudio2005: out << "8.00" << newLine << "# Visual C++ Express 2005"; break; + case visualStudio2008: out << "10.00" << newLine << "# Visual C++ Express 2008"; break; + default: jassertfalse; break; + } + + out << newLine << "Project(\"" << createGUID (project.getProjectName().toString() + "sln_guid") << "\") = \"" << project.getProjectName().toString() << "\", \"" + << getVCProjFile().getFileName() << "\", \"" << projectGUID << "\"" << newLine + << "EndProject" << newLine + << "Global" << newLine + << "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution" << newLine; + + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + out << "\t\t" << createConfigName (config) << " = " << createConfigName (config) << newLine; + } + + out << "\tEndGlobalSection" << newLine + << "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution" << newLine; + + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + out << "\t\t" << projectGUID << "." << createConfigName (config) << ".ActiveCfg = " << createConfigName (config) << newLine; + out << "\t\t" << projectGUID << "." << createConfigName (config) << ".Build.0 = " << createConfigName (config) << newLine; + } + + out << "\tEndGlobalSection" << newLine + << "\tGlobalSection(SolutionProperties) = preSolution" << newLine + << "\t\tHideSolutionNode = FALSE" << newLine + << "\tEndGlobalSection" << newLine + << "EndGlobal" << newLine; + } +}; + + +#endif // __JUCER_PROJECTEXPORT_MSVC_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h new file mode 100644 index 0000000000..67b7e8e82a --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h @@ -0,0 +1,319 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__ +#define __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__ + +#include "jucer_ProjectExporter.h" + + +//============================================================================== +class MakefileProjectExporter : public ProjectExporter +{ +public: + //============================================================================== + static const char* getNameLinux() { return "Linux Makefile"; } + static const char* getValueTreeTypeName() { return "LINUX_MAKE"; } + + static MakefileProjectExporter* createForSettings (Project& project, const ValueTree& settings) + { + if (settings.hasType (getValueTreeTypeName())) + return new MakefileProjectExporter (project, settings); + + return 0; + } + + + //============================================================================== + MakefileProjectExporter (Project& project_, const ValueTree& settings_) + : ProjectExporter (project_, settings_) + { + name = getNameLinux(); + + if (getTargetLocation().toString().isEmpty()) + getTargetLocation() = getDefaultBuildsRootFolder() + "Linux"; + + if (getVSTFolder().toString().isEmpty()) + getVSTFolder() = "~/SDKs/vstsdk2.4"; + } + + ~MakefileProjectExporter() + { + } + + //============================================================================== + bool isDefaultFormatForCurrentOS() + { + #if JUCE_LINUX + return true; + #else + return false; + #endif + } + + bool isPossibleForCurrentProject() { return true; } + bool usesMMFiles() const { return false; } + const String getOSTestMacro() { return "(defined (LINUX) || defined (__linux__))"; } + + void launchProject() + { + // what to do on linux? + } + + void createPropertyEditors (Array & props) + { + ProjectExporter::createPropertyEditors (props); + } + + //============================================================================== + const String create() + { + Array files; + findAllFilesToCompile (project.getMainGroup(), files); + + for (int i = 0; i < juceWrapperFiles.size(); ++i) + if (shouldFileBeCompiledByDefault (juceWrapperFiles.getReference(i))) + files.add (juceWrapperFiles.getReference(i)); + + MemoryOutputStream mo; + writeMakefile (mo, files); + + const File makefile (getTargetFolder().getChildFile ("Makefile")); + if (! overwriteFileWithNewDataIfDifferent (makefile, mo)) + return "Can't write to the Makefile: " + makefile.getFullPathName(); + + return String::empty; + } + +private: + //============================================================================== + void findAllFilesToCompile (const Project::Item& projectItem, Array& results) + { + if (projectItem.isGroup()) + { + for (int i = 0; i < projectItem.getNumChildren(); ++i) + findAllFilesToCompile (projectItem.getChild(i), results); + } + else + { + if (projectItem.shouldBeCompiled()) + results.add (RelativePath (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder)); + } + } + + void writeDefineFlags (OutputStream& out, const Project::BuildConfiguration& config) + { + StringArray defines; + defines.add ("LINUX=1"); + + if (config.isDebug().getValue()) + { + defines.add ("DEBUG=1"); + defines.add ("_DEBUG=1"); + } + else + { + defines.add ("NDEBUG=1"); + } + + defines.addArray (config.parsePreprocessorDefs()); + + for (int i = 0; i < defines.size(); ++i) + out << " -D " << defines[i].quoted(); + } + + void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config) + { + StringArray headerPaths (config.getHeaderSearchPaths()); + headerPaths.insert (0, "/usr/include/freetype2"); + headerPaths.insert (0, "/usr/include"); + + for (int i = 0; i < headerPaths.size(); ++i) + out << " -I " << unixStylePath (headerPaths[i]).quoted(); + } + + void writeCppFlags (OutputStream& out, const Project::BuildConfiguration& config) + { + out << " CPPFLAGS := $(DEPFLAGS)"; + writeDefineFlags (out, config); + writeHeaderPathFlags (out, config); + out << newLine; + } + + void writeLinkerFlags (OutputStream& out, const Project::BuildConfiguration& config) + { + out << " LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows"; + + { + Array libraryPaths; + libraryPaths.add (RelativePath ("/usr/X11R6/lib/", RelativePath::unknown)); + libraryPaths.add (getJucePathFromTargetFolder().getChildFile ("bin")); + + for (int i = 0; i < libraryPaths.size(); ++i) + out << " -L" << libraryPaths.getReference(i).toUnixStyle().quoted(); + } + + const char* defaultLibs[] = { "freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", 0 }; + StringArray libs (defaultLibs); + + if (project.getJuceLinkageMode() == Project::useLinkedJuce) + libs.add ("juce"); + + for (int i = 0; i < libs.size(); ++i) + out << " -l" << libs[i]; + + out << newLine; + } + + void writeConfig (OutputStream& out, const Project::BuildConfiguration& config) + { + const String buildDirName ("build"); + const String intermediatesDirName (buildDirName + "/intermediate/" + config.getName().toString()); + + out << "ifeq ($(CONFIG)," << escapeSpaces (config.getName().toString()) << ")" << newLine; + out << " BINDIR := " << escapeSpaces (buildDirName) << newLine + << " LIBDIR := " << escapeSpaces (buildDirName) << newLine + << " OBJDIR := " << escapeSpaces (intermediatesDirName) << newLine + << " OUTDIR := " << escapeSpaces (buildDirName) << newLine; + + writeCppFlags (out, config); + + out << " CFLAGS += $(CPPFLAGS) $(TARGET_ARCH)"; + + if (config.isDebug().getValue()) + out << " -g -ggdb"; + + out << " -O" << config.getGCCOptimisationFlag() << newLine; + + out << " CXXFLAGS += $(CFLAGS)" << newLine; + + writeLinkerFlags (out, config); + + out << " LDDEPS :=" << newLine + << " RESFLAGS := "; + writeDefineFlags (out, config); + writeHeaderPathFlags (out, config); + out << newLine; + + String targetName (config.getTargetBinaryName().getValue().toString()); + + if (project.isLibrary()) + targetName = getLibbedFilename (targetName); + + out << " TARGET := " << escapeSpaces (targetName) << newLine; + + if (project.isLibrary()) + out << " BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH)" << newLine; + else + out << " BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)" << newLine; + + out << "endif" << newLine << newLine; + } + + void writeObjects (OutputStream& out, const Array& files) + { + out << "OBJECTS := \\" << newLine; + + for (int i = 0; i < files.size(); ++i) + if (shouldFileBeCompiledByDefault (files.getReference(i))) + out << " $(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) << " \\" << newLine; + + out << newLine; + } + + void writeMakefile (OutputStream& out, const Array& files) + { + out << "# Automatically generated makefile, created by the Jucer" << newLine + << "# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project!" << newLine + << newLine; + + out << "ifndef CONFIG" << newLine + << " CONFIG=" << escapeSpaces (project.getConfiguration(0).getName().toString()) << newLine + << "endif" << newLine + << newLine; + + if (! project.isLibrary()) + out << "ifeq ($(TARGET_ARCH),)" << newLine + << " TARGET_ARCH := -march=native" << newLine + << "endif" << newLine << newLine; + + out << "# (this disables dependency generation if multiple architectures are set)" << newLine + << "DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)" << newLine + << newLine; + + for (int i = 0; i < project.getNumConfigurations(); ++i) + writeConfig (out, project.getConfiguration(i)); + + writeObjects (out, files); + + out << ".PHONY: clean" << newLine + << newLine; + + out << "$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)" << newLine + << "\t@echo Linking " << project.getProjectName().toString() << newLine + << "\t-@mkdir -p $(BINDIR)" << newLine + << "\t-@mkdir -p $(LIBDIR)" << newLine + << "\t-@mkdir -p $(OUTDIR)" << newLine + << "\t@$(BLDCMD)" << newLine + << newLine; + + out << "clean:" << newLine + << "\t@echo Cleaning " << project.getProjectName().toString() << newLine + << "\t-@rm -f $(OUTDIR)/$(TARGET)" << newLine + << "\t-@rm -rf $(OBJDIR)/*" << newLine + << "\t-@rm -rf $(OBJDIR)" << newLine + << newLine; + + for (int i = 0; i < files.size(); ++i) + { + if (shouldFileBeCompiledByDefault (files.getReference(i))) + { + jassert (files.getReference(i).getRoot() == RelativePath::buildTargetFolder); + + out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) + << ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine + << "\t-@mkdir -p $(OBJDIR)" << newLine + << "\t@echo $(notdir $<)" << newLine + << "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"" << newLine + << newLine; + } + } + + out << "-include $(OBJECTS:%.o=%.d)" << newLine; + } + + static const String escapeSpaces (const String& s) + { + return s.replace (T(" "), T("\\ ")); + } + + const String getObjectFileFor (const RelativePath& file) const + { + return file.withFileExtension (".o").getFileName(); + } +}; + + +#endif // __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_XCode.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_XCode.h new file mode 100644 index 0000000000..1054193643 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_XCode.h @@ -0,0 +1,1010 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__ +#define __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__ + +#include "jucer_ProjectExporter.h" + + +//============================================================================== +class XCodeProjectExporter : public ProjectExporter +{ +public: + //============================================================================== + static const char* getNameMac() { return "XCode (MacOSX)"; } + static const char* getNameiPhone() { return "XCode (iPhone)"; } + static const char* getValueTreeTypeName (bool iPhone) { return iPhone ? "XCODE_IPHONE" : "XCODE_MAC"; } + + //============================================================================== + XCodeProjectExporter (Project& project_, const ValueTree& settings_, const bool iPhone_) + : ProjectExporter (project_, settings_), + iPhone (iPhone_) + { + name = iPhone ? getNameiPhone() : getNameMac(); + + projectIDSalt = hashCode64 (project.getProjectUID()); + + if (getTargetLocation().toString().isEmpty()) + getTargetLocation() = getDefaultBuildsRootFolder() + (iPhone ? "iPhone" : "MacOSX"); + + if (getVSTFolder().toString().isEmpty()) + getVSTFolder() = "~/SDKs/vstsdk2.4"; + + if (getRTASFolder().toString().isEmpty()) + getRTASFolder() = "~/SDKs/PT_80_SDK"; + } + + ~XCodeProjectExporter() + { + } + + static XCodeProjectExporter* createForSettings (Project& project, const ValueTree& settings) + { + if (settings.hasType (getValueTreeTypeName (false))) + return new XCodeProjectExporter (project, settings, false); + else if (settings.hasType (getValueTreeTypeName (true))) + return new XCodeProjectExporter (project, settings, true); + + return 0; + } + + //============================================================================== + bool isDefaultFormatForCurrentOS() + { + #if JUCE_MAC + return ! iPhone; + #else + return false; + #endif + } + + bool isPossibleForCurrentProject() { return project.isGUIApplication() || ! iPhone; } + const String getOSTestMacro() { return "(defined(__APPLE_CPP__) || defined(__APPLE_CC__))"; } + bool usesMMFiles() const { return true; } + + void createPropertyEditors (Array & props) + { + ProjectExporter::createPropertyEditors (props); + + props.add (new TextPropertyComponent (getSetting ("objCExtraSuffix"), "Objective-C class name suffix", 64, false)); + props.getLast()->setTooltip ("Because objective-C linkage is done by string-matching, you can get horrible linkage mix-ups when different modules containing the " + "same class-names are loaded simultaneously. This setting lets you provide a unique string that will be used in naming the obj-C classes in your executable to avoid this."); + } + + void launchProject() + { + getProjectBundle().startAsProcess(); + } + + //============================================================================== + const String create() + { + infoPlistFile = getTargetFolder().getChildFile ("Info.plist"); + + File projectBundle (getProjectBundle()); + if (! projectBundle.createDirectory()) + return "Can't write to the target directory"; + + createObjects(); + + File projectFile (projectBundle.getChildFile ("project.pbxproj")); + + { + MemoryOutputStream mo; + writeProjectFile (mo); + + if (! overwriteFileWithNewDataIfDifferent (projectFile, mo)) + return "Can't write to file: " + projectFile.getFullPathName(); + } + + if (! writeInfoPlistFile()) + return "Can't write the Info.plist file"; + + return String::empty; + } + +private: + OwnedArray pbxBuildFiles, pbxFileReferences, groups, misc, projectConfigs, targetConfigs; + StringArray buildPhaseIDs, resourceIDs, sourceIDs, frameworkIDs; + StringArray frameworkFileIDs, rezFileIDs, resourceFileRefs; + File infoPlistFile; + int64 projectIDSalt; + const bool iPhone; + + static const String sanitisePath (const String& path) + { + if (path.startsWithChar (T('~'))) + return "$(HOME)" + path.substring (1); + + return path; + } + + const File getProjectBundle() const { return getTargetFolder().getChildFile (project.getProjectFilenameRoot()).withFileExtension (".xcodeproj"); } + const RelativePath getJuceLibFile() const { return getJucePathFromTargetFolder().getChildFile ("bin/libjucedebug.a"); } + + bool hasPList() const { return ! (project.isLibrary() || project.isCommandLineApp()); } + const String getAudioPluginBundleExtension() const { return "component"; } + + //============================================================================== + void createObjects() + { + if (! project.isLibrary()) + addFrameworks(); + + const String productName (project.getConfiguration (0).getTargetBinaryName().toString()); + if (project.isGUIApplication()) + addBuildProduct ("wrapper.application", productName + ".app"); + else if (project.isCommandLineApp()) + addBuildProduct ("compiled.mach-o.executable", productName); + else if (project.isLibrary()) + addBuildProduct ("archive.ar", getLibbedFilename (productName)); + else if (project.isAudioPlugin()) + addBuildProduct ("wrapper.cfbundle", productName + "." + getAudioPluginBundleExtension()); + else if (project.isBrowserPlugin()) + addBuildProduct ("wrapper.cfbundle", productName + ".plugin"); + else + jassert (productName.isEmpty()); + + if (hasPList()) + { + RelativePath plistPath (infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder); + addFileReference (plistPath); + resourceFileRefs.add (createID (plistPath)); + } + + addProjectItem (project.getMainGroup()); + + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + + addProjectConfig (config.getName().getValue(), getProjectSettings (config)); + addTargetConfig (config.getName().getValue(), getTargetSettings (config)); + } + + addConfigList (projectConfigs, createID ("__projList")); + addConfigList (targetConfigs, createID ("__configList")); + + if (! project.isLibrary()) + addBuildPhase ("PBXResourcesBuildPhase", resourceIDs); + + if (rezFileIDs.size() > 0) + addBuildPhase ("PBXRezBuildPhase", rezFileIDs); + + addBuildPhase ("PBXSourcesBuildPhase", sourceIDs); + + if (! project.isLibrary()) + addBuildPhase ("PBXFrameworksBuildPhase", frameworkIDs); + + if (project.isAudioPlugin()) + addPluginShellScriptPhase(); + + addTargetObject(); + addProjectObject(); + } + + bool writeInfoPlistFile() + { + if (! hasPList()) + return true; + + XmlElement plist (T("plist")); + XmlElement* dict = plist.createNewChildElement ("dict"); + + addPlistDictionaryKey (dict, "CFBundleExecutable", "${EXECUTABLE_NAME}"); + addPlistDictionaryKey (dict, "CFBundleIconFile", ""); + addPlistDictionaryKey (dict, "CFBundleIdentifier", project.getBundleIdentifier().toString()); + addPlistDictionaryKey (dict, "CFBundleName", project.getProjectName().toString()); + + if (project.isAudioPlugin()) + { + addPlistDictionaryKey (dict, "CFBundlePackageType", "TDMw"); + addPlistDictionaryKey (dict, "CFBundleSignature", "PTul"); + } + else + { + addPlistDictionaryKey (dict, "CFBundlePackageType", "APPL"); + addPlistDictionaryKey (dict, "CFBundleSignature", "????"); + } + + addPlistDictionaryKey (dict, "CFBundleShortVersionString", project.getVersion().toString()); + addPlistDictionaryKey (dict, "CFBundleVersion", project.getVersion().toString()); + + MemoryOutputStream mo; + plist.writeToStream (mo, ""); + + return overwriteFileWithNewDataIfDifferent (infoPlistFile, mo); + } + + const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) + { + StringArray searchPaths (config.getHeaderSearchPaths()); + + if (project.shouldAddVSTFolderToPath() && getVSTFolder().toString().isNotEmpty()) + searchPaths.add (RelativePath (getVSTFolder().toString(), RelativePath::projectFolder) + .rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder) + .toUnixStyle()); + + if (project.isAudioPlugin()) + { + if (isAU()) + { + searchPaths.add ("$(DEVELOPER_DIR)/Extras/CoreAudio/PublicUtility"); + searchPaths.add ("$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/Utility"); + } + + if (isRTAS()) + { + searchPaths.add ("/Developer/Headers/FlatCarbon"); + + static const char* rtasIncludePaths[] = { "AlturaPorts/TDMPlugIns/PlugInLibrary/Controls", + "AlturaPorts/TDMPlugIns/PlugInLibrary/CoreClasses", + "AlturaPorts/TDMPlugIns/PlugInLibrary/DSPClasses", + "AlturaPorts/TDMPlugIns/PlugInLibrary/EffectClasses", + "AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild", + "AlturaPorts/TDMPlugIns/PlugInLibrary/Meters", + "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses", + "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses/Interfaces", + "AlturaPorts/TDMPlugIns/PlugInLibrary/RTASP_Adapt", + "AlturaPorts/TDMPlugIns/PlugInLibrary/Utilities", + "AlturaPorts/TDMPlugIns/PlugInLibrary/ViewClasses", + "AlturaPorts/TDMPlugIns/DSPManager/**", + "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/Encryption", + "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/GraphicsExtensions", + "AlturaPorts/TDMPlugIns/common", + "AlturaPorts/TDMPlugIns/common/PI_LibInterface", + "AlturaPorts/TDMPlugIns/PACEProtection/**", + "AlturaPorts/TDMPlugIns/SignalProcessing/**", + "AlturaPorts/OMS/Headers", + "AlturaPorts/Fic/Interfaces/**", + "AlturaPorts/Fic/Source/SignalNets", + "AlturaPorts/DSIPublicInterface/PublicHeaders", + "DAEWin/Include", + "AlturaPorts/DigiPublic/Interfaces", + "AlturaPorts/DigiPublic", + "AlturaPorts/NewFileLibs/DOA", + "AlturaPorts/NewFileLibs/Cmn", + "xplat/AVX/avx2/avx2sdk/inc", + "xplat/AVX/avx2/avx2sdk/utils" }; + + RelativePath sdkFolder (getRTASFolder().toString(), RelativePath::projectFolder); + sdkFolder = sdkFolder.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder); + + for (int i = 0; i < numElementsInArray (rtasIncludePaths); ++i) + searchPaths.add (sdkFolder.getChildFile (rtasIncludePaths[i]).toUnixStyle()); + } + } + + return searchPaths; + } + + void getLinkerFlagsForStaticLibrary (const RelativePath& library, StringArray& flags, StringArray& librarySearchPaths) + { + jassert (library.getFileNameWithoutExtension().substring (0, 3) == T("lib")); + + flags.add ("-l" + library.getFileNameWithoutExtension().substring (3)); + + String searchPath (library.toUnixStyle().upToLastOccurrenceOf (T("/"), false, false)); + if (! library.isAbsolute()) + searchPath = "$(SRCROOT)/" + searchPath; + + librarySearchPaths.add (sanitisePath (searchPath)); + } + + void getLinkerFlags (const Project::BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) + { + if (project.isAudioPlugin()) + { + flags.add ("-bundle"); + + if (isRTAS() && getRTASFolder().toString().isNotEmpty()) + { + getLinkerFlagsForStaticLibrary (RelativePath (getRTASFolder().toString(), RelativePath::buildTargetFolder) + .getChildFile (config.isDebug().getValue() ? "MacBag/Libs/Debug/libPluginLibrary.a" + : "MacBag/Libs/Release/libPluginLibrary.a"), + flags, librarySearchPaths); + } + } + + if (project.getJuceLinkageMode() == Project::useLinkedJuce) + getLinkerFlagsForStaticLibrary (getJuceLibFile(), flags, librarySearchPaths); + } + + const StringArray getProjectSettings (const Project::BuildConfiguration& config) + { + StringArray settings; + settings.add ("ALWAYS_SEARCH_USER_PATHS = NO"); + settings.add ("GCC_C_LANGUAGE_STANDARD = c99"); + settings.add ("GCC_WARN_ABOUT_RETURN_TYPE = YES"); + settings.add ("GCC_WARN_CHECK_SWITCH_STATEMENTS = YES"); + settings.add ("GCC_WARN_UNUSED_VARIABLE = YES"); + settings.add ("GCC_WARN_MISSING_PARENTHESES = YES"); + settings.add ("GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES"); + settings.add ("GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES"); + settings.add ("GCC_MODEL_TUNING = G5"); + settings.add ("GCC_INLINES_ARE_PRIVATE_EXTERN = YES"); + settings.add ("ZERO_LINK = NO"); + settings.add ("DEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\""); + settings.add ("PRODUCT_NAME = \"" + config.getTargetBinaryName().toString() + "\""); + return settings; + } + + const StringArray getTargetSettings (const Project::BuildConfiguration& config) + { + StringArray settings; + settings.add ("ARCHS = \"$(ARCHS_STANDARD_32_BIT)\""); + settings.add ("PREBINDING = NO"); + settings.add ("HEADER_SEARCH_PATHS = \"" + getHeaderSearchPaths (config).joinIntoString (" ") + " $(inherited)\""); + settings.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag()); + settings.add ("INFOPLIST_FILE = " + infoPlistFile.getFileName()); + + switch ((int) project.getProjectType().getValue()) + { + case Project::application: + settings.add ("INSTALL_PATH = \"$(HOME)/Applications\""); + break; + + case Project::commandLineApp: + break; + + case Project::audioPlugin: + settings.add ("LIBRARY_STYLE = Bundle"); + settings.add ("INSTALL_PATH = \"$(HOME)/Library/Audio/Plug-Ins/Components/\""); + settings.add ("WRAPPER_EXTENSION = " + getAudioPluginBundleExtension()); + settings.add ("GENERATE_PKGINFO_FILE = YES"); + settings.add ("OTHER_REZFLAGS = \"-d ppc_$ppc -d i386_$i386 -d ppc64_$ppc64 -d x86_64_$x86_64" + " -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers" + " -I \\\"$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/AUBase\\\"\""); + break; + + case Project::browserPlugin: + settings.add ("LIBRARY_STYLE = Bundle"); + settings.add ("INSTALL_PATH = \"/Library/Internet Plug-Ins/\""); + break; + + case Project::library: + if (config.getTargetBinaryRelativePath().toString().isNotEmpty()) + { + RelativePath binaryPath (config.getTargetBinaryRelativePath().toString(), RelativePath::projectFolder); + binaryPath = binaryPath.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder); + + settings.add ("DSTROOT = " + sanitisePath (binaryPath.toUnixStyle())); + settings.add ("SYMROOT = " + sanitisePath (binaryPath.toUnixStyle())); + } + + settings.add ("CONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)\""); + settings.add ("DEPLOYMENT_LOCATION = YES"); + break; + + default: + jassertfalse; break; + } + + if (iPhone) + { + settings.add ("SDKROOT = iphonesimulator3.0"); + } + else + { + switch ((int) config.getMacSDKVersion().getValue()) + { + case 2: settings.add ("SDKROOT = macosx10.4"); settings.add ("GCC_VERSION = 4.0"); break; + case 3: settings.add ("SDKROOT = macosx10.5"); break; + case 4: settings.add ("SDKROOT = macosx10.6"); break; + default: break; + } + + switch ((int) config.getMacCompatibilityVersion().getValue()) + { + case 2: settings.add ("MACOSX_DEPLOYMENT_TARGET = 10.4"); break; + case 3: settings.add ("MACOSX_DEPLOYMENT_TARGET = 10.5"); break; + case 4: settings.add ("MACOSX_DEPLOYMENT_TARGET = 10.6"); break; + default: break; + } + + settings.add ("MACOSX_DEPLOYMENT_TARGET_ppc = 10.4"); + } + + { + StringArray linkerFlags, librarySearchPaths; + getLinkerFlags (config, linkerFlags, librarySearchPaths); + + if (linkerFlags.size() > 0) + settings.add ("OTHER_LDFLAGS = \"" + linkerFlags.joinIntoString (T(" ")) + "\""); + + if (librarySearchPaths.size() > 0) + { + String libPaths ("LIBRARY_SEARCH_PATHS = (\"$(inherited)\""); + + for (int i = 0; i < librarySearchPaths.size(); ++i) + libPaths += ", \"\\\"" + librarySearchPaths[i] + "\\\"\""; + + settings.add (libPaths + ")"); + } + } + + StringArray defines; + + if (config.isDebug().getValue()) + { + defines.add ("_DEBUG=1"); + defines.add ("DEBUG=1 "); + settings.add ("ONLY_ACTIVE_ARCH = YES"); + settings.add ("COPY_PHASE_STRIP = NO"); + settings.add ("GCC_DYNAMIC_NO_PIC = NO"); + settings.add ("GCC_ENABLE_FIX_AND_CONTINUE = YES"); + } + else + { + defines.add ("_NDEBUG=1"); + defines.add ("NDEBUG=1 "); + settings.add ("GCC_GENERATE_DEBUGGING_SYMBOLS = NO"); + settings.add ("GCC_SYMBOLS_PRIVATE_EXTERN = YES"); + } + + { + const String objCSuffix (getSetting ("objCExtraSuffix").toString().trim()); + if (objCSuffix.isNotEmpty()) + defines.add ("JUCE_ObjCExtraSuffix=" + objCSuffix); + } + + { + defines.addArray (config.parsePreprocessorDefs()); + + for (int i = defines.size(); --i >= 0;) + defines.set (i, defines[i].quoted()); + + settings.add ("GCC_PREPROCESSOR_DEFINITIONS = (" + indentList (defines, ",") + ")"); + } + + return settings; + } + + void addFrameworks() + { + StringArray s; + + if (iPhone) + s.addTokens (T("UIKit Foundation CoreGraphics AudioToolbox"), false); + else + s.addTokens (T("Cocoa Carbon IOKit CoreAudio CoreMIDI WebKit DiscRecording OpenGL QuartzCore QTKit QuickTime"), false); + + if (isAU()) + s.addTokens (T("AudioUnit CoreAudioKit AudioToolbox"), false); + else if ((int) project.getJuceConfigFlag ("JUCE_PLUGINHOST_AU").getValue() == 1) + s.addTokens (T("AudioUnit CoreAudioKit"), false); + + for (int i = 0; i < s.size(); ++i) + addFramework (s[i]); + } + + //============================================================================== + void writeProjectFile (OutputStream& output) + { + output << "// !$*UTF8*$!\n{\n" + "\tarchiveVersion = 1;\n" + "\tclasses = {\n\t};\n" + "\tobjectVersion = 44;\n" + "\tobjects = {\n\n"; + + Array objects; + objects.addArray (pbxBuildFiles); + objects.addArray (pbxFileReferences); + objects.addArray (groups); + objects.addArray (targetConfigs); + objects.addArray (projectConfigs); + objects.addArray (misc); + + for (int i = 0; i < objects.size(); ++i) + { + ValueTree& o = *objects.getUnchecked(i); + output << "\t\t" << o.getType() << " = { "; + + for (int j = 0; j < o.getNumProperties(); ++j) + { + const var::identifier name (o.getPropertyName(j)); + String val (o.getProperty (name).toString()); + + if (val.isEmpty() || (val.containsAnyOf (T(" \t;<>()=,-\r\n")) + && ! (val.trimStart().startsWithChar (T('(')) + || val.trimStart().startsWithChar (T('{'))))) + val = val.quoted(); + + output << name.name << " = " << val << "; "; + } + + output << "};\n"; + } + + output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n"; + } + + static void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value) + { + xml->createNewChildElement ("key")->addTextElement (key); + xml->createNewChildElement ("string")->addTextElement (value); + } + + const String addBuildFile (const RelativePath& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings) + { + String fileID (createID (path.toUnixStyle() + "buildref")); + + if (addToSourceBuildPhase) + sourceIDs.add (fileID); + + ValueTree* v = new ValueTree (fileID); + v->setProperty ("isa", "PBXBuildFile", 0); + v->setProperty ("fileRef", fileRefID, 0); + + if (inhibitWarnings) + v->setProperty ("settings", "{COMPILER_FLAGS = \"-w\"; }", 0); + + pbxBuildFiles.add (v); + return fileID; + } + + const String addBuildFile (const RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings) + { + return addBuildFile (path, createID (path), addToSourceBuildPhase, inhibitWarnings); + } + + void addFileReference (const RelativePath& path, const String& sourceTree, const String& lastKnownFileType, const String& fileRefID) + { + ValueTree* v = new ValueTree (fileRefID); + v->setProperty ("isa", "PBXFileReference", 0); + v->setProperty ("lastKnownFileType", lastKnownFileType, 0); + v->setProperty ("name", path.getFileName(), 0); + v->setProperty ("path", sanitisePath (path.toUnixStyle()), 0); + v->setProperty ("sourceTree", sourceTree, 0); + pbxFileReferences.add (v); + } + + const String addFileReference (const RelativePath& path) + { + const String fileRefID (createID (path)); + + jassert (path.isAbsolute() || path.getRoot() == RelativePath::buildTargetFolder); + addFileReference (path, path.isAbsolute() ? "" : "SOURCE_ROOT", + getFileType (path), fileRefID); + + return fileRefID; + } + + static const String getFileType (const RelativePath& file) + { + if (file.hasFileExtension (T(".cpp"))) return "sourcecode.cpp.cpp"; + else if (file.hasFileExtension (T(".mm"))) return "sourcecode.cpp.objcpp"; + else if (file.hasFileExtension (T(".m"))) return "sourcecode.c.objc"; + else if (file.hasFileExtension (T(".h;.hpp"))) return "sourcecode.c.h"; + else if (file.hasFileExtension (T(".framework"))) return "wrapper.framework"; + else if (file.hasFileExtension (T(".jpeg;.jpg"))) return "image.jpeg"; + else if (file.hasFileExtension (T("png;gif"))) return "image" + file.getFileExtension(); + else if (file.hasFileExtension (T("html;htm"))) return "text.html"; + else if (file.hasFileExtension (T("txt;rtf"))) return "text" + file.getFileExtension(); + else if (file.hasFileExtension (T("plist"))) return "text.plist.xml"; + else if (file.hasFileExtension (T("app"))) return "wrapper.application"; + else if (file.hasFileExtension (T("component;vst;plugin"))) return "wrapper.cfbundle"; + else if (file.hasFileExtension (T("xcodeproj"))) return "wrapper.pb-project"; + else if (file.hasFileExtension (T("a"))) return "archive.ar"; + + return "file" + file.getFileExtension(); + } + + const String addFile (const RelativePath& path, bool shouldBeCompiled, bool inhibitWarnings) + { + if (shouldBeCompiled) + addBuildFile (path, true, inhibitWarnings); + else if (path.hasFileExtension (".r")) + rezFileIDs.add (addBuildFile (path, false, inhibitWarnings)); + + return addFileReference (path); + } + + const String addProjectItem (const Project::Item& projectItem) + { + if (projectItem.isGroup()) + { + StringArray childIDs; + for (int i = 0; i < projectItem.getNumChildren(); ++i) + { + const String childID (addProjectItem (projectItem.getChild(i))); + + if (childID.isNotEmpty()) + childIDs.add (childID); + } + + return addGroup (projectItem, childIDs); + } + else + { + if (projectItem.shouldBeAddedToTargetProject()) + { + const RelativePath path (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder); + return addFile (path, projectItem.shouldBeCompiled(), false); + } + } + + return String::empty; + } + + void addFramework (const String& frameworkName) + { + const RelativePath path ("System/Library/Frameworks/" + frameworkName + ".framework", RelativePath::unknown); + const String fileRefID (createID (path)); + addFileReference (path, "SDKROOT", getFileType (path), fileRefID); + frameworkIDs.add (addBuildFile (path, fileRefID, false, false)); + frameworkFileIDs.add (fileRefID); + } + + void addGroup (const String& groupID, const String& name, const StringArray& childIDs) + { + ValueTree* v = new ValueTree (groupID); + v->setProperty ("isa", "PBXGroup", 0); + v->setProperty ("children", "(" + indentList (childIDs, ",") + " )", 0); + v->setProperty ("name", name, 0); + v->setProperty ("sourceTree", "", 0); + groups.add (v); + } + + const String createGroup (const Array& files, const String& groupName, const String& groupIDName, bool inhibitWarnings) + { + StringArray fileIDs; + + for (int i = 0; i < files.size(); ++i) + { + addFile (files.getReference(i), shouldFileBeCompiledByDefault (files.getReference(i)), inhibitWarnings); + fileIDs.add (createID (files.getReference(i))); + } + + const String groupID (createID (groupIDName)); + addGroup (groupID, groupName, fileIDs); + return groupID; + } + + const String addGroup (const Project::Item& item, StringArray& childIDs) + { + String groupName (item.getName().toString()); + + if (item.isMainGroup()) + { + groupName = "Source"; + + // Add 'Juce Library Code' group + if (juceWrapperFiles.size() > 0) + childIDs.add (createGroup (juceWrapperFiles, project.getJuceCodeGroupName(), "__jucelibfiles", false)); + + if (isVST()) + childIDs.add (createGroup (getVSTFilesRequired(), "Juce VST Wrapper", "__jucevstfiles", false)); + + if (isAU()) + childIDs.add (createAUWrappersGroup()); + + if (isRTAS()) + childIDs.add (createGroup (getRTASFilesRequired(), "Juce RTAS Wrapper", "__jucertasfiles", true)); + + { // Add 'resources' group + String resourcesGroupID (createID ("__resources")); + addGroup (resourcesGroupID, "Resources", resourceFileRefs); + childIDs.add (resourcesGroupID); + } + + { // Add 'frameworks' group + String frameworksGroupID (createID ("__frameworks")); + addGroup (frameworksGroupID, "Frameworks", frameworkFileIDs); + childIDs.add (frameworksGroupID); + } + + { // Add 'products' group + String productsGroupID (createID ("__products")); + StringArray products; + products.add (createID ("__productFileID")); + addGroup (productsGroupID, "Products", products); + childIDs.add (productsGroupID); + } + } + + String groupID (getIDForGroup (item)); + addGroup (groupID, groupName, childIDs); + return groupID; + } + + void addBuildProduct (const String& fileType, const String& binaryName) + { + ValueTree* v = new ValueTree (createID ("__productFileID")); + v->setProperty ("isa", "PBXFileReference", 0); + v->setProperty ("explicitFileType", fileType, 0); + v->setProperty ("includeInIndex", (int) 0, 0); + v->setProperty ("path", sanitisePath (binaryName), 0); + v->setProperty ("sourceTree", "BUILT_PRODUCTS_DIR", 0); + pbxFileReferences.add (v); + } + + void addTargetConfig (const String& name, const StringArray& settings) + { + ValueTree* v = new ValueTree (createID ("targetconfigid_" + name)); + v->setProperty ("isa", "XCBuildConfiguration", 0); + v->setProperty ("buildSettings", "{" + indentList (settings, ";") + " }", 0); + v->setProperty ("name", name, 0); + targetConfigs.add (v); + } + + void addProjectConfig (const String& name, const StringArray& settings) + { + ValueTree* v = new ValueTree (createID ("projectconfigid_" + name)); + v->setProperty ("isa", "XCBuildConfiguration", 0); + v->setProperty ("buildSettings", "{" + indentList (settings, ";") + " }", 0); + v->setProperty ("name", name, 0); + projectConfigs.add (v); + } + + void addConfigList (const OwnedArray & configsToUse, const String& listID) + { + StringArray configIDs; + + for (int i = 0; i < configsToUse.size(); ++i) + configIDs.add (configsToUse[i]->getType()); + + ValueTree* v = new ValueTree (listID); + v->setProperty ("isa", "XCConfigurationList", 0); + v->setProperty ("buildConfigurations", "(" + indentList (configIDs, ",") + " )", 0); + v->setProperty ("defaultConfigurationIsVisible", (int) 0, 0); + + if (configsToUse[0] != 0) + v->setProperty ("defaultConfigurationName", configsToUse[0]->getProperty ("name"), 0); + + misc.add (v); + } + + ValueTree* addBuildPhase (const String& phaseType, const StringArray& fileIds) + { + String phaseId (createID (phaseType + "resbuildphase")); + buildPhaseIDs.add (phaseId); + + ValueTree* v = new ValueTree (phaseId); + v->setProperty ("isa", phaseType, 0); + v->setProperty ("buildActionMask", "2147483647", 0); + v->setProperty ("files", "(" + indentList (fileIds, ",") + " )", 0); + v->setProperty ("runOnlyForDeploymentPostprocessing", (int) 0, 0); + misc.add (v); + return v; + } + + void addTargetObject() + { + ValueTree* v = new ValueTree (createID ("__target")); + v->setProperty ("isa", "PBXNativeTarget", 0); + v->setProperty ("buildConfigurationList", createID ("__configList"), 0); + v->setProperty ("buildPhases", "(" + indentList (buildPhaseIDs, ",") + " )", 0); + v->setProperty ("buildRules", "( )", 0); + v->setProperty ("dependencies", "( )", 0); + v->setProperty ("name", project.getDocumentTitle(), 0); + v->setProperty ("productName", project.getDocumentTitle(), 0); + v->setProperty ("productReference", createID ("__productFileID"), 0); + + if (project.isGUIApplication()) + { + v->setProperty ("productInstallPath", "$(HOME)/Applications", 0); + v->setProperty ("productType", "com.apple.product-type.application", 0); + } + else if (project.isCommandLineApp()) + { + v->setProperty ("productInstallPath", "/usr/bin", 0); + v->setProperty ("productType", "com.apple.product-type.tool", 0); + } + else if (project.isAudioPlugin() || project.isBrowserPlugin()) + { + v->setProperty ("productInstallPath", "$(HOME)/Library/Audio/Plug-Ins/Components/", 0); + v->setProperty ("productType", "com.apple.product-type.bundle", 0); + } + else if (project.isLibrary()) + { + v->setProperty ("productType", "com.apple.product-type.library.static", 0); + } + else + jassertfalse; //xxx + + misc.add (v); + } + + void addProjectObject() + { + ValueTree* v = new ValueTree (createID ("__root")); + v->setProperty ("isa", "PBXProject", 0); + v->setProperty ("buildConfigurationList", createID ("__projList"), 0); + v->setProperty ("compatibilityVersion", "Xcode 3.0", 0); + v->setProperty ("hasScannedForEncodings", (int) 0, 0); + v->setProperty ("mainGroup", getIDForGroup (project.getMainGroup()), 0); + v->setProperty ("projectDirPath", "\"\"", 0); + v->setProperty ("projectRoot", "\"\"", 0); + v->setProperty ("targets", "( " + createID ("__target") + " )", 0); + misc.add (v); + } + + void addPluginShellScriptPhase() + { + ValueTree* v = addBuildPhase ("PBXShellScriptBuildPhase", StringArray()); + v->setProperty ("name", "Copy to the different plugin folders", 0); + v->setProperty ("shellPath", "/bin/sh", 0); + v->setProperty ("shellScript", String::fromUTF8 (BinaryData::AudioPluginXCodeScript_txt, BinaryData::AudioPluginXCodeScript_txtSize) + .replace (T("\\"), T("\\\\")) + .replace (T("\""), T("\\\"")) + .replace (T("\r\n"), T("\\n")) + .replace (T("\n"), T("\\n")), 0); + } + + //============================================================================== + static const String indentList (const StringArray& list, const String& separator) + { + if (list.size() == 0) + return " "; + + return "\n\t\t\t\t" + list.joinIntoString (separator + "\n\t\t\t\t") + + (separator == T(";") ? separator : String::empty); + } + + const String createID (const RelativePath& path) const + { + return createID (path.toUnixStyle()); + } + + const String createID (const String& name) const + { + static const char digits[] = "0123456789ABCDEF"; + char n[24]; + Random ran (projectIDSalt + hashCode64 (name)); + + for (int i = 0; i < numElementsInArray (n); ++i) + n[i] = digits [ran.nextInt (16)]; + + return String (n, numElementsInArray (n)); + } + + const String getIDForGroup (const Project::Item& item) const + { + return createID (item.getID()); + } + + bool shouldFileBeCompiledByDefault (const RelativePath& file) const + { + return file.hasFileExtension (T("cpp;mm;c;m")); + } + + //============================================================================== + const Array getRTASFilesRequired() const + { + Array s; + if (isRTAS()) + { + const char* files[] = { "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode1.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode2.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode3.cpp", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_DigiCode_Header.h", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_MacResources.r", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_MacUtilities.mm", + "extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp" }; + + for (int i = 0; i < numElementsInArray (files); ++i) + s.add (getJucePathFromTargetFolder().getChildFile (files[i])); + } + + return s; + } + + const String createAUWrappersGroup() + { + Array auWrappers; + + const char* files[] = { "extras/audio plugins/wrapper/AU/juce_AU_Resources.r", + "extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm" }; + + for (int i = 0; i < numElementsInArray (files); ++i) + auWrappers.add (getJucePathFromTargetFolder().getChildFile (files[i])); + + const char* appleAUFiles[] = { "Extras/CoreAudio/PublicUtility/CADebugMacros.h", + "Extras/CoreAudio/PublicUtility/CAAUParameter.cpp", + "Extras/CoreAudio/PublicUtility/CAAUParameter.h", + "Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp", + "Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.h", + "Extras/CoreAudio/PublicUtility/CAMutex.cpp", + "Extras/CoreAudio/PublicUtility/CAMutex.h", + "Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp", + "Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.h", + "Extras/CoreAudio/PublicUtility/CAVectorUnitTypes.h", + "Extras/CoreAudio/PublicUtility/CAVectorUnit.cpp", + "Extras/CoreAudio/PublicUtility/CAVectorUnit.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUViewBase/AUViewLocalizedStringKeys.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.h", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.h", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.h", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUDebugDispatcher.cpp", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUDebugDispatcher.h", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUInputFormatConverter.h", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUSilentTimeout.h", + "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUTimestampGenerator.h" }; + + StringArray fileIDs, appleFileIDs; + + int i; + for (i = 0; i < auWrappers.size(); ++i) + { + addFile (auWrappers.getReference(i), shouldFileBeCompiledByDefault (auWrappers.getReference(i)), false); + fileIDs.add (createID (auWrappers.getReference(i))); + } + + for (i = 0; i < numElementsInArray (appleAUFiles); ++i) + { + RelativePath file (appleAUFiles[i], RelativePath::unknown); + const String fileRefID (createID (file)); + + addFileReference (file, "DEVELOPER_DIR", getFileType (file), fileRefID); + + if (shouldFileBeCompiledByDefault (file)) + addBuildFile (file, fileRefID, true, true); + + appleFileIDs.add (fileRefID); + } + + const String appleGroupID (createID ("__juceappleaufiles")); + addGroup (appleGroupID, "Apple AU Files", appleFileIDs); + fileIDs.add (appleGroupID); + + const String groupID (createID ("__juceaufiles")); + addGroup (groupID, "Juce AU Wrapper", fileIDs); + return groupID; + } +}; + + +#endif // __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.cpp b/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.cpp new file mode 100644 index 0000000000..b0b01f753f --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.cpp @@ -0,0 +1,164 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ProjectExporter.h" +#include "jucer_ProjectExport_Make.h" +#include "jucer_ProjectExport_MSVC.h" +#include "jucer_ProjectExport_XCode.h" + + +//============================================================================== +ProjectExporter::ProjectExporter (Project& project_, const ValueTree& settings_) + : project (project_), settings (settings_) +{ +} + +ProjectExporter::~ProjectExporter() +{ +} + +//============================================================================== +int ProjectExporter::getNumExporters() +{ + return 5; +} + +const StringArray ProjectExporter::getExporterNames() +{ + StringArray s; + s.add (XCodeProjectExporter::getNameMac()); + s.add (XCodeProjectExporter::getNameiPhone()); + s.add (MSVCProjectExporter::getName2005()); + s.add (MSVCProjectExporter::getName2008()); + s.add (MakefileProjectExporter::getNameLinux()); + return s; +} + +ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int index) +{ + ProjectExporter* exp = 0; + + switch (index) + { + case 0: exp = new XCodeProjectExporter (project, ValueTree (XCodeProjectExporter::getValueTreeTypeName (false)), false); break; + case 1: exp = new XCodeProjectExporter (project, ValueTree (XCodeProjectExporter::getValueTreeTypeName (true)), true); break; + case 2: exp = new MSVCProjectExporter (project, ValueTree (MSVCProjectExporter::getValueTreeTypeName (MSVCProjectExporter::visualStudio2005)), MSVCProjectExporter::visualStudio2005); break; + case 3: exp = new MSVCProjectExporter (project, ValueTree (MSVCProjectExporter::getValueTreeTypeName (MSVCProjectExporter::visualStudio2008)), MSVCProjectExporter::visualStudio2008); break; + case 4: exp = new MakefileProjectExporter (project, ValueTree (MakefileProjectExporter::getValueTreeTypeName())); break; + default: jassertfalse; return 0; + } + + File juceFolder (StoredSettings::getInstance()->getLastKnownJuceFolder()); + File target (exp->getTargetFolder()); + + if (shouldPathsBeRelative (juceFolder.getFullPathName(), project.getFile().getFullPathName())) + exp->getJuceFolder() = juceFolder.getRelativePathFrom (project.getFile().getParentDirectory()); + else + exp->getJuceFolder() = juceFolder.getFullPathName(); + + return exp; +} + +ProjectExporter* ProjectExporter::createExporter (Project& project, const ValueTree& settings) +{ + ProjectExporter* exp = MSVCProjectExporter::createForSettings (project, settings); + + if (exp == 0) + exp = XCodeProjectExporter::createForSettings (project, settings); + + if (exp == 0) + exp = MakefileProjectExporter::createForSettings (project, settings); + + jassert (exp != 0); + return exp; +} + +ProjectExporter* ProjectExporter::createPlatformDefaultExporter (Project& project) +{ + for (int i = 0; i < project.getNumExporters(); ++i) + { + ScopedPointer exp (project.createExporter (i)); + + if (exp->isDefaultFormatForCurrentOS()) + return exp.release(); + } + + return 0; +} + +const File ProjectExporter::getTargetFolder() const +{ + return project.resolveFilename (getTargetLocation().toString()); +} + +const RelativePath ProjectExporter::getJucePathFromTargetFolder() const +{ + RelativePath juceFolder (getJuceFolder().toString(), RelativePath::projectFolder); + return juceFolder.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder); +} + +bool ProjectExporter::shouldFileBeCompiledByDefault (const RelativePath& file) const +{ + return file.hasFileExtension ("cpp;c"); +} + +void ProjectExporter::createPropertyEditors (Array & props) +{ + props.add (new TextPropertyComponent (getTargetLocation(), "Target Project Folder", 1024, false)); + props.getLast()->setTooltip ("The location of the folder in which the " + name + " project will be created. This path can be absolute, but it's much more sensible to make it relative to the jucer project directory."); + + props.add (new TextPropertyComponent (getJuceFolder(), "Juce Location", 1024, false)); + props.getLast()->setTooltip ("The location of the Juce library folder that the " + name + " project will use to when compiling. This can be an absolute path, or relative to the jucer project folder, but it must be valid on the filesystem of the machine you use to actually do the compiling."); + + if (project.isAudioPlugin()) + { + if (project.shouldAddVSTFolderToPath()) + { + props.add (new TextPropertyComponent (getVSTFolder(), "VST Folder", 1024, false)); + props.getLast()->setTooltip ("If you're building a VST, this must be the folder containing the VST SDK. This should be an absolute path."); + } + + if (isRTAS()) + { + props.add (new TextPropertyComponent (getRTASFolder(), "RTAS Folder", 1024, false)); + props.getLast()->setTooltip ("If you're building an RTAS, this must be the folder containing the RTAS SDK. This should be an absolute path."); + } + } +} + +const Array ProjectExporter::getVSTFilesRequired() const +{ + Array s; + if (isVST()) + { + const char* files[] = { "extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp", + "extras/audio plugins/wrapper/VST/juce_VST_Wrapper.mm" }; + + for (int i = 0; i < numElementsInArray (files); ++i) + s.add (getJucePathFromTargetFolder().getChildFile (files[i])); + } + + return s; +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.h new file mode 100644 index 0000000000..4af824cb92 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExporter.h @@ -0,0 +1,102 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTEXPORTER_JUCEHEADER__ +#define __JUCER_PROJECTEXPORTER_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class ProjectExporter +{ +protected: + //============================================================================== + ProjectExporter (Project& project, const ValueTree& settings); + +public: + virtual ~ProjectExporter(); + + static int getNumExporters(); + static const StringArray getExporterNames(); + static ProjectExporter* createNewExporter (Project& project, const int index); + + static ProjectExporter* createExporter (Project& project, const ValueTree& settings); + static ProjectExporter* createPlatformDefaultExporter (Project& project); + + //============================================================================= + virtual bool isDefaultFormatForCurrentOS() = 0; + virtual bool isPossibleForCurrentProject() = 0; + virtual bool usesMMFiles() const = 0; + virtual void createPropertyEditors (Array & props); + virtual void launchProject() = 0; + virtual const String create() = 0; + virtual const String getOSTestMacro() = 0; + virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const; + + //============================================================================== + const String getName() const { return name; } + const File getTargetFolder() const; + + const ValueTree& getSettings() const { return settings; } + Value getSetting (const var::identifier& name) const { return settings.getPropertyAsValue (name, project.getUndoManagerFor (settings)); } + + Value getJuceFolder() const { return getSetting ("juceFolder"); } + Value getTargetLocation() const { return getSetting ("targetFolder"); } + + Value getVSTFolder() const { return getSetting ("vstFolder"); } + Value getRTASFolder() const { return getSetting ("rtasFolder"); } + Value getAUFolder() const { return getSetting ("auFolder"); } + + bool isVST() const { return project.isAudioPlugin() && project.shouldBuildVST().getValue(); } + bool isRTAS() const { return project.isAudioPlugin() && project.shouldBuildRTAS().getValue(); } + bool isAU() const { return project.isAudioPlugin() && project.shouldBuildAU().getValue(); } + + Array juceWrapperFiles; + +protected: + //============================================================================== + Project& project; + ValueTree settings; + String name; + + const RelativePath getJucePathFromTargetFolder() const; + const String getDefaultBuildsRootFolder() const { return "Builds/"; } + + const Array getVSTFilesRequired() const; + + const String getLibbedFilename (String name) const + { + if (! name.startsWith (T("lib"))) + name = "lib" + name; + if (! name.endsWithIgnoreCase (T(".a"))) + name = name + ".a"; + return name; + } +}; + + +#endif // __JUCER_PROJECTEXPORTER_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectSaver.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectSaver.h new file mode 100644 index 0000000000..815d0de033 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectSaver.h @@ -0,0 +1,539 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTSAVER_JUCEHEADER__ +#define __JUCER_PROJECTSAVER_JUCEHEADER__ + + +//============================================================================== +class ProjectSaver +{ +public: + ProjectSaver (Project& project_, const File& projectFile_) + : project (project_), projectFile (projectFile_), resourceFile (project_) + { + } + + const String save() + { + const File oldFile (project.getFile()); + project.setFile (projectFile); + + switch (project.getJuceLinkageMode()) + { + case Project::notLinkedToJuce: + hasAppHeaderFile = ! project.isLibrary(); + hasAppConfigFile = false; + numJuceSourceFiles = 0; + break; + + case Project::useAmalgamatedJuce: + case Project::useAmalgamatedJuceViaSingleTemplate: + hasAppHeaderFile = true; + hasAppConfigFile = true; + numJuceSourceFiles = 1; + break; + + case Project::useAmalgamatedJuceViaMultipleTemplates: + hasAppHeaderFile = true; + hasAppConfigFile = true; + numJuceSourceFiles = project.getNumSeparateAmalgamatedFiles(); + break; + + case Project::useLinkedJuce: + hasAppHeaderFile = true; + hasAppConfigFile = true; + numJuceSourceFiles = 0; + break; + + default: + jassertfalse; + break; + } + + hasResources = (resourceFile.getNumFiles() > 0); + + writeMainProjectFile(); + + if (errors.size() == 0) + writeJuceSourceWrappers(); + + if (errors.size() == 0) + writeProjects(); + + if (errors.size() > 0) + project.setFile (oldFile); + + return errors[0]; + } + +private: + Project& project; + const File& projectFile; + ResourceFile resourceFile; + StringArray errors; + + File appConfigFile, juceHeaderFile, binaryDataCpp, pluginCharacteristicsFile; + bool hasAppHeaderFile, hasAppConfigFile, hasResources; + int numJuceSourceFiles; + + void writeMainProjectFile() + { + ScopedPointer xml (project.getProjectRoot().createXml()); + jassert (xml != 0); + + if (xml != 0) + { + #if JUCE_DEBUG + { + MemoryOutputStream mo; + project.getProjectRoot().writeToStream (mo); + + MemoryInputStream mi (mo.getData(), mo.getDataSize(), false); + ValueTree v = ValueTree::readFromStream (mi); + ScopedPointer xml2 (v.createXml()); + + // This bit just tests that ValueTree save/load works reliably.. Let me know if this asserts for you! + jassert (xml->isEquivalentTo (xml2, true)); + } + #endif + + MemoryOutputStream mo; + xml->writeToStream (mo, String::empty); + + if (! overwriteFileWithNewDataIfDifferent (projectFile, mo)) + errors.add ("Couldn't write to the target file!"); + } + } + + void writeJucerComment (OutputStream& out) + { + out << "/*" << newLine << newLine + << " IMPORTANT! This file is auto-generated by the Jucer each time you save your" << newLine + << " project - if you alter its contents, your changes may be overwritten!" << newLine + << newLine; + } + + void writeAppConfig (OutputStream& out) + { + writeJucerComment (out); + out << " If you want to change any of these values, use the Jucer to do so, rather than" << newLine + << " editing this file directly!" << newLine + << newLine + << " Any commented-out settings will fall back to using the default values that" << newLine + << " they are given in juce_Config.h" << newLine + << newLine + << "*/" << newLine << newLine; + + bool notActive = project.getJuceLinkageMode() == Project::useLinkedJuce + || project.getJuceLinkageMode() == Project::notLinkedToJuce; + if (notActive) + out << "/* NOTE: These configs aren't available when you're linking to the juce library statically!" << newLine + << " If you need to set a configuration that differs from the default, you'll need" << newLine + << " to include the amalgamated Juce files." << newLine << newLine; + + OwnedArray flags; + project.getJuceConfigFlags (flags); + + for (int i = 0; i < flags.size(); ++i) + { + const Project::JuceConfigFlag* const f = flags[i]; + int value = (int) f->value.getValue(); + + if (value < 1 || value > 2) + out << "//#define "; + else + out << "#define "; + + out << f->symbol; + + if (value == 1) + out << " 1"; + else if (value == 2) + out << " 0"; + + out << newLine; + } + + if (notActive) + out << newLine << "*/" << newLine; + } + + void writeSourceWrapper (OutputStream& out, int fileNumber) + { + writeJucerComment (out); + out << " This file pulls in all the Juce source code, and builds it using the settings" << newLine + << " defined in " << appConfigFile.getFileName() << "." << newLine + << newLine + << " If you want to change the method by which Juce is linked into your app, use the" << newLine + << " Jucer to change it, rather than trying to edit this file directly." << newLine + << newLine + << "*/" + << newLine << newLine + << createIncludeStatement (appConfigFile, appConfigFile) << newLine; + + if (fileNumber == 0) + writeInclude (out, project.isUsingFullyAmalgamatedFile() ? "juce_amalgamated.cpp" + : "amalgamation/juce_amalgamated_template.cpp"); + else + writeInclude (out, "amalgamation/juce_amalgamated" + String (fileNumber) + ".cpp"); + } + + void writeAppHeader (OutputStream& out) + { + writeJucerComment (out); + out << " This is the header file that your files should include in order to get all the" << newLine + << " Juce library headers. You should NOT include juce.h or juce_amalgamated.h directly in" << newLine + << " your own source files, because that wouldn't pick up the correct Juce configuration" << newLine + << " options for your app." << newLine + << newLine + << "*/" << newLine << newLine; + + String headerGuard ("__APPHEADERFILE_" + String::toHexString (juceHeaderFile.hashCode()).toUpperCase() + "__"); + out << "#ifndef " << headerGuard << newLine + << "#define " << headerGuard << newLine << newLine; + + if (hasAppConfigFile) + out << createIncludeStatement (appConfigFile, appConfigFile) << newLine; + + if (project.getJuceLinkageMode() != Project::notLinkedToJuce) + { + writeInclude (out, (project.isUsingSingleTemplateFile() || project.isUsingMultipleTemplateFiles()) + ? "juce_amalgamated.h" // could use "amalgamation/juce_amalgamated_template.h", but it's slower.. + : (project.isUsingFullyAmalgamatedFile() + ? "juce_amalgamated.h" + : "juce.h")); + } + + if (binaryDataCpp.exists()) + out << createIncludeStatement (binaryDataCpp.withFileExtension (".h"), appConfigFile) << newLine; + + out << newLine + << "namespace ProjectInfo" << newLine + << "{" << newLine + << " const char* const projectName = " << replaceCEscapeChars (project.getProjectName().toString()).quoted() << ";" << newLine + << " const char* const versionString = " << replaceCEscapeChars (project.getVersion().toString()).quoted() << ";" << newLine + << " const int versionNumber = " << createVersionCode (project.getVersion().toString()) << ";" << newLine + << "}" << newLine + << newLine + << "#endif // " << headerGuard << newLine; + } + + void writeInclude (OutputStream& out, const String& pathFromJuceFolder) + { + StringArray paths, guards; + + for (int i = project.getNumExporters(); --i >= 0;) + { + ScopedPointer exporter (project.createExporter (i)); + + if (exporter != 0) + { + const RelativePath juceFromProject (exporter->getJuceFolder().toString(), RelativePath::projectFolder); + const RelativePath fileFromProject (juceFromProject.getChildFile (pathFromJuceFolder)); + const RelativePath fileFromHere (fileFromProject.rebased (project.getFile().getParentDirectory(), + juceHeaderFile.getParentDirectory(), RelativePath::unknown)); + + paths.add (fileFromHere.toUnixStyle()); + guards.add (exporter->getOSTestMacro()); + } + } + + StringArray uniquePaths (paths); + uniquePaths.removeDuplicates (false); + + if (uniquePaths.size() == 1) + { + out << "#include " << paths[0].quoted() << newLine; + } + else + { + for (int i = paths.size(); --i >= 0;) + { + for (int j = i; --j >= 0;) + { + if (paths[i] == paths[j] && guards[i] == guards[j]) + { + paths.remove (i); + guards.remove (i); + } + } + } + + for (int i = 0; i < paths.size(); ++i) + { + out << (i == 0 ? "#if " : "#elif ") << guards[i] << newLine + << " #include " << paths[i].quoted() << newLine; + } + + out << "#endif" << newLine; + } + } + + static int countMaxPluginChannels (const String& configString, bool isInput) + { + StringArray configs; + configs.addTokens (configString, T(", {}"), String::empty); + configs.trim(); + configs.removeEmptyStrings(); + jassert ((configs.size() & 1) == 0); // looks like a syntax error in the configs? + + int maxVal = 0; + for (int i = (isInput ? 0 : 1); i < configs.size(); i += 2) + maxVal = jmax (maxVal, configs[i].getIntValue()); + + return maxVal; + } + + static const String createVersionCode (const String& version) + { + StringArray configs; + configs.addTokens (version, T(",.")); + configs.trim(); + configs.removeEmptyStrings(); + + int value = (configs[0].getIntValue() << 16) + (configs[1].getIntValue() << 8) + configs[2].getIntValue(); + + if (configs.size() >= 4) + value = (value << 8) + configs[3].getIntValue(); + + return "0x" + String::toHexString (value); + } + + void writePluginCharacteristics (OutputStream& out) + { + String headerGuard ("__PLUGINCHARACTERISTICS_" + String::toHexString (pluginCharacteristicsFile.hashCode()).toUpperCase() + "__"); + + writeJucerComment (out); + out << " This header file contains configuration options for the plug-in. If you need to change any of" << newLine + << " these, it'd be wise to do so using the Jucer, rather than editing this file directly..." << newLine + << newLine + << "*/" << newLine + << newLine + << "#ifndef " << headerGuard << newLine + << "#define " << headerGuard << newLine + << newLine + << "#define JucePlugin_Build_VST " << ((bool) project.shouldBuildVST().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_Build_AU " << ((bool) project.shouldBuildAU().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_Build_RTAS " << ((bool) project.shouldBuildRTAS().getValue() ? 1 : 0) << newLine + << newLine + << "#define JucePlugin_Name " << project.getPluginName().toString().quoted() << newLine + << "#define JucePlugin_Desc " << project.getPluginDesc().toString().quoted() << newLine + << "#define JucePlugin_Manufacturer " << project.getPluginManufacturer().toString().quoted() << newLine + << "#define JucePlugin_ManufacturerCode '" << project.getPluginManufacturerCode().toString().trim().substring (0, 4) << "'" << newLine + << "#define JucePlugin_PluginCode '" << project.getPluginCode().toString().trim().substring (0, 4) << "'" << newLine + << "#define JucePlugin_MaxNumInputChannels " << countMaxPluginChannels (project.getPluginChannelConfigs().toString(), true) << newLine + << "#define JucePlugin_MaxNumOutputChannels " << countMaxPluginChannels (project.getPluginChannelConfigs().toString(), false) << newLine + << "#define JucePlugin_PreferredChannelConfigurations " << project.getPluginChannelConfigs().toString() << newLine + << "#define JucePlugin_IsSynth " << ((bool) project.getPluginIsSynth().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_WantsMidiInput " << ((bool) project.getPluginWantsMidiInput().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_ProducesMidiOutput " << ((bool) project.getPluginProducesMidiOut().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_IsSynth " << ((bool) project.getPluginIsSynth().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_SilenceInProducesSilenceOut " << ((bool) project.getPluginSilenceInProducesSilenceOut().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_TailLengthSeconds " << (double) project.getPluginTailLengthSeconds().getValue() << newLine + << "#define JucePlugin_EditorRequiresKeyboardFocus " << ((bool) project.getPluginEditorNeedsKeyFocus().getValue() ? 1 : 0) << newLine + << "#define JucePlugin_VersionCode " << createVersionCode (project.getVersion().toString()) << newLine + << "#define JucePlugin_VersionString " << project.getVersion().toString().quoted() << newLine + << "#define JucePlugin_VSTUniqueID JucePlugin_PluginCode" << newLine + << "#define JucePlugin_VSTCategory " << ((bool) project.getPluginIsSynth().getValue() ? "kPlugCategSynth" : "kPlugCategEffect") << newLine + << "#define JucePlugin_AUMainType " << ((bool) project.getPluginIsSynth().getValue() ? "kAudioUnitType_MusicDevice" : "kAudioUnitType_Effect") << newLine + << "#define JucePlugin_AUSubType JucePlugin_PluginCode" << newLine + << "#define JucePlugin_AUExportPrefix " << project.getPluginAUExportPrefix().toString() << newLine + << "#define JucePlugin_AUExportPrefixQuoted " << project.getPluginAUExportPrefix().toString().quoted() << newLine + << "#define JucePlugin_AUManufacturerCode JucePlugin_ManufacturerCode" << newLine + << "#define JucePlugin_CFBundleIdentifier " << project.getBundleIdentifier().toString() << newLine + << "#define JucePlugin_AUCocoaViewClassName " << project.getPluginAUCocoaViewClassName().toString() << newLine + << "#define JucePlugin_RTASCategory " << ((bool) project.getPluginIsSynth().getValue() ? "ePlugInCategory_SWGenerators" : "ePlugInCategory_None") << newLine + << "#define JucePlugin_RTASManufacturerCode JucePlugin_ManufacturerCode" << newLine + << "#define JucePlugin_RTASProductId JucePlugin_PluginCode" << newLine + << "#define JUCE_USE_VSTSDK_2_4 1" << newLine + << newLine + << "#endif // " << headerGuard << newLine; + } + + bool replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData) + { + if (! overwriteFileWithNewDataIfDifferent (f, newData)) + { + errors.add ("Can't write to file: " + f.getFullPathName()); + return false; + } + + return true; + } + + void writeJuceSourceWrappers() + { + const File wrapperFolder (project.getWrapperFolder()); + + appConfigFile = wrapperFolder.getChildFile (project.getAppConfigFilename()); + pluginCharacteristicsFile = wrapperFolder.getChildFile (project.getPluginCharacteristicsFilename()); + + juceHeaderFile = project.getAppIncludeFile(); + binaryDataCpp = wrapperFolder.getChildFile ("BinaryData.cpp"); + + if (resourceFile.getNumFiles() > 0) + { + if (! wrapperFolder.createDirectory()) + { + errors.add ("Couldn't create folder: " + wrapperFolder.getFullPathName()); + return; + } + + //resourceFile.setJuceHeaderToInclude (juceHeaderFile); + resourceFile.setClassName ("BinaryData"); + + if (! resourceFile.write (binaryDataCpp)) + errors.add ("Can't create binary resources file: " + binaryDataCpp.getFullPathName()); + } + else + { + binaryDataCpp.deleteFile(); + binaryDataCpp.withFileExtension ("h").deleteFile(); + } + + if (project.isLibrary()) + return; + + if (! wrapperFolder.createDirectory()) + { + errors.add ("Couldn't create folder: " + wrapperFolder.getFullPathName()); + return; + } + + if (hasAppConfigFile) + { + MemoryOutputStream mem; + writeAppConfig (mem); + replaceFileIfDifferent (appConfigFile, mem); + } + else + { + appConfigFile.deleteFile(); + } + + if (project.isAudioPlugin()) + { + MemoryOutputStream mem; + writePluginCharacteristics (mem); + replaceFileIfDifferent (pluginCharacteristicsFile, mem); + } + + for (int i = 0; i <= project.getNumSeparateAmalgamatedFiles(); ++i) + { + const File sourceWrapperCpp (getSourceWrapperCpp (i)); + const File sourceWrapperMM (sourceWrapperCpp.withFileExtension (".mm")); + + if (numJuceSourceFiles > 0 + && ((i == 0 && numJuceSourceFiles == 1) || (i != 0 && numJuceSourceFiles > 1))) + { + MemoryOutputStream mem; + writeSourceWrapper (mem, i); + replaceFileIfDifferent (sourceWrapperCpp, mem); + replaceFileIfDifferent (sourceWrapperMM, mem); + } + else + { + sourceWrapperMM.deleteFile(); + sourceWrapperCpp.deleteFile(); + } + } + + if (hasAppHeaderFile) + { + MemoryOutputStream mem; + writeAppHeader (mem); + replaceFileIfDifferent (juceHeaderFile, mem); + } + else + { + juceHeaderFile.deleteFile(); + } + } + + void writeProjects() + { + for (int i = project.getNumExporters(); --i >= 0;) + { + ScopedPointer exporter (project.createExporter (i)); + + const File targetFolder (exporter->getTargetFolder()); + + if (targetFolder.createDirectory()) + { + if (hasAppConfigFile) + exporter->juceWrapperFiles.add (RelativePath (appConfigFile, targetFolder, RelativePath::buildTargetFolder)); + + if (hasAppHeaderFile) + exporter->juceWrapperFiles.add (RelativePath (juceHeaderFile, targetFolder, RelativePath::buildTargetFolder)); + + if (hasResources) + { + exporter->juceWrapperFiles.add (RelativePath (binaryDataCpp, targetFolder, RelativePath::buildTargetFolder)); + exporter->juceWrapperFiles.add (RelativePath (binaryDataCpp, targetFolder, RelativePath::buildTargetFolder) + .withFileExtension (".h")); + } + + if (numJuceSourceFiles > 0) + { + for (int i = 0; i <= project.getNumSeparateAmalgamatedFiles(); ++i) + { + const File sourceWrapperCpp (getSourceWrapperCpp (i)); + const File sourceWrapperMM (sourceWrapperCpp.withFileExtension (".mm")); + + if ((i == 0 && numJuceSourceFiles == 1) || (i != 0 && numJuceSourceFiles > 1)) + { + if (exporter->usesMMFiles()) + exporter->juceWrapperFiles.add (RelativePath (sourceWrapperMM, targetFolder, RelativePath::buildTargetFolder)); + else + exporter->juceWrapperFiles.add (RelativePath (sourceWrapperCpp, targetFolder, RelativePath::buildTargetFolder)); + } + } + } + + if (project.isAudioPlugin()) + exporter->juceWrapperFiles.add (RelativePath (pluginCharacteristicsFile, targetFolder, RelativePath::buildTargetFolder)); + + String error = exporter->create(); + + if (error.isNotEmpty()) + errors.add (error); + } + else + { + errors.add ("Can't create folder: " + exporter->getTargetFolder().getFullPathName()); + } + } + } + + const File getSourceWrapperCpp (int fileIndex) const + { + return project.getWrapperFolder().getChildFile (project.getJuceSourceFilenameRoot() + (fileIndex != 0 ? String (fileIndex) : String::empty)) + .withFileExtension (".cpp"); + } +}; + + +#endif diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.cpp b/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.cpp new file mode 100644 index 0000000000..927adaed63 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.cpp @@ -0,0 +1,495 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ProjectWizard.h" + + +//============================================================================== +class GUIAppWizard : public ProjectWizard +{ +public: + GUIAppWizard() {} + ~GUIAppWizard() {} + + const String getName() { return "GUI Application"; } + const String getDescription() { return "Creates a standard application"; } + + void addItemsToAlertWindow (AlertWindow& aw) + { + const char* fileOptions[] = { "Create a Main.cpp file", + "Create a Main.cpp file and a basic window", + "Don't create any files", 0 }; + + aw.addComboBox ("files", StringArray (fileOptions), "Files to Auto-Generate"); + } + + const String processResultsFromAlertWindow (AlertWindow& aw) + { + createMainCpp = createWindow = false; + + switch (aw.getComboBoxComponent("files")->getSelectedItemIndex()) + { + case 0: createMainCpp = true; break; + case 1: createMainCpp = createWindow = true; break; + case 2: break; + default: jassertfalse; break; + } + + return String::empty; + } + + bool initialiseProject (Project& project) + { + if (! getSourceFilesFolder().createDirectory()) + failedFiles.add (getSourceFilesFolder().getFullPathName()); + + File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); + File mainWindowCpp = getSourceFilesFolder().getChildFile ("MainWindow.cpp"); + File mainWindowH = mainWindowCpp.withFileExtension (".h"); + String windowClassName = "MainAppWindow"; + + project.getProjectType() = (int) Project::application; + + Project::Item group (project.createNewGroup()); + project.getMainGroup().addChild (group, 0); + group.getName() = "Source"; + + for (int i = project.getNumConfigurations(); --i >= 0;) + project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + + String appHeaders (createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); + String initCode, shutdownCode, anotherInstanceStartedCode, privateMembers, memberInitialisers; + + if (createWindow) + { + appHeaders << newLine << createIncludeStatement (mainWindowH, mainCppFile); + memberInitialisers = " : mainWindow (0)"; + initCode = "mainWindow = new " + windowClassName + "();"; + shutdownCode = "deleteAndZero (mainWindow);"; + privateMembers = windowClassName + "* mainWindow;"; + + String windowH = project.getFileTemplate ("jucer_WindowTemplate_h") + .replace (T("INCLUDES"), createIncludeStatement (project.getAppIncludeFile(), mainWindowH), false) + .replace (T("WINDOWCLASS"), windowClassName, false) + .replace (T("HEADERGUARD"), makeHeaderGuardName (mainWindowH), false); + + String windowCpp = project.getFileTemplate ("jucer_WindowTemplate_cpp") + .replace (T("INCLUDES"), createIncludeStatement (mainWindowH, mainWindowCpp), false) + .replace (T("WINDOWCLASS"), windowClassName, false); + + if (! overwriteFileWithNewDataIfDifferent (mainWindowH, windowH)) + failedFiles.add (mainWindowH.getFullPathName()); + + if (! overwriteFileWithNewDataIfDifferent (mainWindowCpp, windowCpp)) + failedFiles.add (mainWindowCpp.getFullPathName()); + + group.addFile (mainWindowCpp, -1); + group.addFile (mainWindowH, -1); + } + + if (createMainCpp) + { + String mainCpp = project.getFileTemplate ("jucer_MainTemplate_cpp") + .replace (T("APPHEADERS"), appHeaders, false) + .replace (T("APPCLASSNAME"), makeValidCppIdentifier (appTitle + "Application", false, true, false), false) + .replace (T("MEMBERINITIALISERS"), memberInitialisers, false) + .replace (T("APPINITCODE"), initCode, false) + .replace (T("APPSHUTDOWNCODE"), shutdownCode, false) + .replace (T("APPNAME"), replaceCEscapeChars (appTitle), false) + .replace (T("APPVERSION"), T("1.0"), false) + .replace (T("ALLOWMORETHANONEINSTANCE"), T("true"), false) + .replace (T("ANOTHERINSTANCECODE"), anotherInstanceStartedCode, false) + .replace (T("PRIVATEMEMBERS"), privateMembers, false); + + if (! overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) + failedFiles.add (mainCppFile.getFullPathName()); + + group.addFile (mainCppFile, -1); + } + + return true; + } + +private: + bool createMainCpp, createWindow; +}; + +//============================================================================== +class ConsoleAppWizard : public ProjectWizard +{ +public: + ConsoleAppWizard() {} + ~ConsoleAppWizard() {} + + const String getName() { return "Console Application"; } + const String getDescription() { return "Creates a command-line application with no GUI features"; } + + void addItemsToAlertWindow (AlertWindow& aw) + { + const char* fileOptions[] = { "Create a Main.cpp file", + "Don't create any files", 0 }; + + aw.addComboBox ("files", StringArray (fileOptions), "Files to Auto-Generate"); + } + + const String processResultsFromAlertWindow (AlertWindow& aw) + { + createMainCpp = false; + + switch (aw.getComboBoxComponent("files")->getSelectedItemIndex()) + { + case 0: createMainCpp = true; break; + case 1: break; + default: jassertfalse; break; + } + + return String::empty; + } + + bool initialiseProject (Project& project) + { + if (! getSourceFilesFolder().createDirectory()) + failedFiles.add (getSourceFilesFolder().getFullPathName()); + + File mainCppFile = getSourceFilesFolder().getChildFile ("Main.cpp"); + + project.getProjectType() = (int) Project::commandLineApp; + + Project::Item group (project.createNewGroup()); + project.getMainGroup().addChild (group, 0); + group.getName() = "Source"; + + for (int i = project.getNumConfigurations(); --i >= 0;) + project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + + if (createMainCpp) + { + String appHeaders (createIncludeStatement (project.getAppIncludeFile(), mainCppFile)); + + String mainCpp = project.getFileTemplate ("jucer_MainConsoleAppTemplate_cpp") + .replace (T("APPHEADERS"), appHeaders, false); + + if (! overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp)) + failedFiles.add (mainCppFile.getFullPathName()); + + group.addFile (mainCppFile, -1); + } + + return true; + } + +private: + bool createMainCpp; +}; + +//============================================================================== +class AudioPluginAppWizard : public ProjectWizard +{ +public: + AudioPluginAppWizard() {} + ~AudioPluginAppWizard() {} + + const String getName() { return "Audio Plug-In"; } + const String getDescription() { return "Creates an audio plugin project"; } + + void addItemsToAlertWindow (AlertWindow& aw) + { + } + + const String processResultsFromAlertWindow (AlertWindow& aw) + { + return String::empty; + } + + bool initialiseProject (Project& project) + { + if (! getSourceFilesFolder().createDirectory()) + failedFiles.add (getSourceFilesFolder().getFullPathName()); + + String filterClassName = makeValidCppIdentifier (appTitle, true, true, false) + "AudioProcessor"; + filterClassName = filterClassName.substring (0, 1).toUpperCase() + filterClassName.substring (1); + String editorClassName = filterClassName + "Editor"; + + File filterCppFile = getSourceFilesFolder().getChildFile ("PluginProcessor.cpp"); + File filterHFile = filterCppFile.withFileExtension (".h"); + File editorCppFile = getSourceFilesFolder().getChildFile ("PluginEditor.cpp"); + File editorHFile = editorCppFile.withFileExtension (".h"); + + project.getProjectType() = (int) Project::audioPlugin; + + Project::Item group (project.createNewGroup()); + project.getMainGroup().addChild (group, 0); + group.getName() = "Source"; + project.getJuceConfigFlag ("JUCE_QUICKTIME") = 2; // disabled because it interferes with RTAS build on PC + + for (int i = project.getNumConfigurations(); --i >= 0;) + project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle); + + String appHeaders (createIncludeStatement (project.getAppIncludeFile(), filterCppFile)); + appHeaders << newLine << createIncludeStatement (project.getPluginCharacteristicsFile(), filterCppFile); + + String filterCpp = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_cpp") + .replace (T("FILTERHEADERS"), createIncludeStatement (filterHFile, filterCppFile) + + newLine + createIncludeStatement (editorHFile, filterCppFile), false) + .replace (T("FILTERCLASSNAME"), filterClassName, false) + .replace (T("EDITORCLASSNAME"), editorClassName, false); + + String filterH = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_h") + .replace (T("APPHEADERS"), appHeaders, false) + .replace (T("FILTERCLASSNAME"), filterClassName, false) + .replace (T("HEADERGUARD"), makeHeaderGuardName (filterHFile), false); + + String editorCpp = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_cpp") + .replace (T("EDITORCPPHEADERS"), createIncludeStatement (filterHFile, filterCppFile) + + newLine + createIncludeStatement (editorHFile, filterCppFile), false) + .replace (T("FILTERCLASSNAME"), filterClassName, false) + .replace (T("EDITORCLASSNAME"), editorClassName, false); + + String editorH = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_h") + .replace (T("EDITORHEADERS"), appHeaders + newLine + createIncludeStatement (filterHFile, filterCppFile), false) + .replace (T("FILTERCLASSNAME"), filterClassName, false) + .replace (T("EDITORCLASSNAME"), editorClassName, false) + .replace (T("HEADERGUARD"), makeHeaderGuardName (editorHFile), false); + + if (! overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp)) + failedFiles.add (filterCppFile.getFullPathName()); + + if (! overwriteFileWithNewDataIfDifferent (filterHFile, filterH)) + failedFiles.add (filterHFile.getFullPathName()); + + if (! overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp)) + failedFiles.add (editorCppFile.getFullPathName()); + + if (! overwriteFileWithNewDataIfDifferent (editorHFile, editorH)) + failedFiles.add (editorHFile.getFullPathName()); + + group.addFile (filterCppFile, -1); + group.addFile (filterHFile, -1); + group.addFile (editorCppFile, -1); + group.addFile (editorHFile, -1); + + return true; + } +}; + +//============================================================================== +/*class BrowserPluginAppWizard : public ProjectWizard +{ +public: + BrowserPluginAppWizard() {} + ~BrowserPluginAppWizard() {} + + const String getName() { return "Browser Plug-In"; } + const String getDescription() { return "Creates an audio plugin project"; } + + void addItemsToAlertWindow (AlertWindow& aw) + { + } + + const String processResultsFromAlertWindow (AlertWindow& aw) + { + return String::empty; + } + + bool initialiseProject (Project& project) + { + return true; + } +};*/ + +//============================================================================== +//============================================================================== +ProjectWizard::ProjectWizard() +{ +} + +ProjectWizard::~ProjectWizard() +{ +} + +const StringArray ProjectWizard::getWizards() +{ + StringArray s; + + for (int i = 0; i < getNumWizards(); ++i) + { + ScopedPointer wiz (createWizard (i)); + s.add (wiz->getName()); + } + + return s; +} + +int ProjectWizard::getNumWizards() +{ + return 3; +} + +ProjectWizard* ProjectWizard::createWizard (int index) +{ + switch (index) + { + case 0: return new GUIAppWizard(); + case 1: return new ConsoleAppWizard(); + case 2: return new AudioPluginAppWizard(); + //case 3: return new BrowserPluginAppWizard(); + default: jassertfalse; break; + } + + return 0; +} + +//============================================================================== +Project* ProjectWizard::runWizard (Component* ownerWindow_) +{ + ownerWindow = ownerWindow_; + + { + static File newProjectFolder; + FileChooser fc ("New Juce Project", newProjectFolder, "*"); + + if (! fc.browseForDirectory()) + return 0; + + targetFolder = newProjectFolder = fc.getResult(); + + if (! newProjectFolder.exists()) + { + if (! newProjectFolder.createDirectory()) + failedFiles.add (newProjectFolder.getFullPathName()); + } + + if (containsAnyNonHiddenFiles (newProjectFolder)) + { + if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, "New Juce Project", + "The folder you chose isn't empty - are you sure you want to create the project there?\n\nAny existing files with the same names may be overwritten by the new files.")) + return 0; + } + } + + if (failedFiles.size() == 0) + { + AlertWindow aw ("New " + getName(), + "Please choose some basic project options...", + AlertWindow::NoIcon, ownerWindow); + + aw.addTextEditor ("name", "", "Project Name", false); + + addItemsToAlertWindow (aw); + + aw.addButton ("Create Project", 1, KeyPress (KeyPress::returnKey)); + aw.addButton ("Cancel", 0, KeyPress (KeyPress::escapeKey)); + + for (;;) + { + if (aw.runModalLoop() == 0) + return 0; + + appTitle = aw.getTextEditorContents ("name").trim(); + + String error (processResultsFromAlertWindow (aw)); + + if (error.isEmpty() && appTitle.isEmpty()) + error = "Please enter a sensible project title!"; + + if (error.isEmpty()) + break; + + aw.setColour (AlertWindow::textColourId, Colours::red); + aw.setMessage (error); + } + } + + projectFile = targetFolder.getChildFile (File::createLegalFileName (appTitle)) + .withFileExtension (Project::projectFileExtension); + + ScopedPointer project (new Project (projectFile)); + + if (failedFiles.size() == 0) + { + project->setFile (projectFile); + project->setTitle (appTitle); + project->setBundleIdentifierToDefault(); + + if (! initialiseProject (*project)) + return 0; + + if (project->save (false, true) != FileBasedDocument::savedOk) + return 0; + + project->setChangedFlag (false); + } + + if (failedFiles.size() > 0) + { + AlertWindow::showMessageBox (AlertWindow::WarningIcon, + "Errors in Creating Project!", + "The following files couldn't be written:\n\n" + + failedFiles.joinIntoString ("\n", 0, 10)); + return 0; + } + + return project.release(); +} + +Project* ProjectWizard::runNewProjectWizard (Component* ownerWindow) +{ + ScopedPointer wizard; + + { + AlertWindow aw ("New Juce Project", + "Select the type of project to create, and the location of your Juce folder", + AlertWindow::NoIcon, + ownerWindow); + + aw.addComboBox ("type", getWizards(), "Project Type"); + + FilenameComponent juceFolderSelector ("Juce Library Location", StoredSettings::getInstance()->getLastKnownJuceFolder(), + true, true, false, "*", String::empty, "(Please select the folder containing Juce!)"); + juceFolderSelector.setSize (350, 22); + + aw.addCustomComponent (&juceFolderSelector); + + aw.addButton ("Next", 1, KeyPress (KeyPress::returnKey)); + aw.addButton ("Cancel", 0, KeyPress (KeyPress::escapeKey)); + + for (;;) + { + if (aw.runModalLoop() == 0) + return 0; + + if (isJuceFolder (juceFolderSelector.getCurrentFile())) + { + wizard = createWizard (aw.getComboBoxComponent("type")->getSelectedItemIndex()); + break; + } + + aw.setColour (AlertWindow::textColourId, Colours::red); + aw.setMessage ("Please select a valid Juce folder for the project to use!"); + } + } + + return wizard != 0 ? wizard->runWizard (ownerWindow) : 0; +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.h new file mode 100644 index 0000000000..ae65b44272 --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectWizard.h @@ -0,0 +1,68 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTWIZARD_JUCEHEADER__ +#define __JUCER_PROJECTWIZARD_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class ProjectWizard +{ +public: + virtual ~ProjectWizard(); + + //============================================================================== + static const StringArray getWizards(); + static int getNumWizards(); + static ProjectWizard* createWizard (int index); + + static Project* runNewProjectWizard (Component* ownerWindow); + + //============================================================================== + virtual const String getName() = 0; + virtual const String getDescription() = 0; + + virtual void addItemsToAlertWindow (AlertWindow& aw) = 0; + virtual const String processResultsFromAlertWindow (AlertWindow& aw) = 0; + virtual bool initialiseProject (Project& project) = 0; + +protected: + String appTitle; + File targetFolder, projectFile; + Component* ownerWindow; + StringArray failedFiles; + + //============================================================================== + ProjectWizard(); + Project* runWizard (Component* ownerWindow); + + const File getSourceFilesFolder() const { return projectFile.getSiblingFile ("Source"); } +}; + + +#endif // __JUCER_PROJECTWIZARD_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.cpp b/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.cpp new file mode 100644 index 0000000000..891dd3231d --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.cpp @@ -0,0 +1,303 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ResourceFile.h" +#include "../ui/jucer_ProjectTreeViewBase.h" +#include "../ui/jucer_OpenDocumentManager.h" + +static const tchar* resourceFileIdentifierString = T("JUCER_BINARY_RESOURCE"); + + +//============================================================================== +ResourceFile::ResourceFile (Project& project_) + : project (project_), + className ("BinaryData") +{ + addResourcesFromProjectItem (project.getMainGroup()); +} + +ResourceFile::~ResourceFile() +{ +} + +bool ResourceFile::isResourceFile (const File& file) +{ + if (file.hasFileExtension (T("cpp;h"))) + { + ScopedPointer in (file.createInputStream()); + + if (in != 0) + { + MemoryBlock mb; + in->readIntoMemoryBlock (mb, 256); + return mb.toString().contains (resourceFileIdentifierString); + } + } + + return false; +} + +//============================================================================== +void ResourceFile::addResourcesFromProjectItem (const Project::Item& projectItem) +{ + if (projectItem.isGroup()) + { + for (int i = 0; i < projectItem.getNumChildren(); ++i) + addResourcesFromProjectItem (projectItem.getChild(i)); + } + else + { + if (projectItem.shouldBeAddedToBinaryResources()) + addFile (projectItem.getFile()); + } +} + +//============================================================================== +void ResourceFile::setJuceHeaderToInclude (const File& header) +{ + juceHeader = header; +} + +void ResourceFile::setClassName (const String& className_) +{ + className = className_; +} + +void ResourceFile::addFile (const File& file) +{ + files.add (new File (file)); +} + +int64 ResourceFile::getTotalDataSize() const +{ + int64 total = 0; + + for (int i = 0; i < files.size(); ++i) + total += files.getUnchecked(i)->getSize(); + + return total; +} + +static void writeCppData (InputStream& in, OutputStream& out) +{ + const int maxCharsOnLine = 250; + + MemoryBlock mb; + in.readIntoMemoryBlock (mb); + const unsigned char* data = (const unsigned char*) mb.getData(); + int charsOnLine = 0; + + bool canUseStringLiteral = mb.getSize() < 65535; // MS compilers can't handle strings bigger than 65536 chars.. + + if (canUseStringLiteral) + { + for (size_t i = 0; i < mb.getSize(); ++i) + { + const unsigned int num = (unsigned int) data[i]; + if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n')) + { + canUseStringLiteral = false; + break; + } + } + } + + if (! canUseStringLiteral) + { + out << "{ "; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + const int num = (int) (unsigned int) data[i]; + out << num << ','; + + charsOnLine += 2; + if (num >= 10) + ++charsOnLine; + if (num >= 100) + ++charsOnLine; + + if (charsOnLine >= maxCharsOnLine) + { + charsOnLine = 0; + out << newLine; + } + } + + out << "0,0 };"; + } + else + { + out << "\""; + + for (size_t i = 0; i < mb.getSize(); ++i) + { + const unsigned int num = (unsigned int) data[i]; + + switch (num) + { + case '\t': out << "\\t"; break; + case '\r': out << "\\r"; break; + case '\n': out << "\\n"; charsOnLine = maxCharsOnLine; break; + case '"': out << "\\\""; break; + case '\\': out << "\\\\"; break; + default: out << (char) num; break; + } + + if (++charsOnLine >= maxCharsOnLine && i < mb.getSize() - 1) + { + charsOnLine = 0; + out << "\"" << newLine << "\""; + } + } + + out << "\";"; + } +} + +bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& header) +{ + String comment; + comment << newLine << newLine + << " This is an auto-generated file, created by " << JUCEApplication::getInstance()->getApplicationName() << newLine + << " Do not edit anything in this file!" << newLine << newLine + << "*/" << newLine << newLine; + + header << "/* =========================================================================================" + << comment; + + cpp << "/* ==================================== " << resourceFileIdentifierString << " ====================================" + << comment; + + if (juceHeader.exists()) + header << createIncludeStatement (juceHeader, cppFile) << newLine; + + const String namespaceName (className); + StringArray variableNames; + + int i; + for (i = 0; i < files.size(); ++i) + { + String variableNameRoot (makeValidCppIdentifier (files.getUnchecked(i)->getFileName() + .replaceCharacters (T(" ."), T("__")) + .retainCharacters (T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789")), + false, true, false)); + String variableName (variableNameRoot); + + int suffix = 2; + while (variableNames.contains (variableName)) + variableName = variableNameRoot + String (suffix++); + + variableNames.add (variableName); + } + + cpp << createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine + << newLine + << newLine + << "const char* " << namespaceName << "::getNamedResource (const wchar_t* resourceName, int& numBytes) throw()" << newLine + << "{" << newLine + << " int hash = 0;" << newLine + << " if (resourceName != 0)" << newLine + << " while (*resourceName != 0)" << newLine + << " hash = 31 * hash + *resourceName++;" << newLine + << newLine + << " switch (hash)" << newLine + << " {" << newLine; + + for (i = 0; i < files.size(); ++i) + { + cpp << " case 0x" << hexString8Digits (variableNames[i].hashCode()) + << ": numBytes = " << namespaceName << "::" << variableNames[i] << "Size; return " + << namespaceName << "::" << variableNames[i] << ";" << newLine; + } + + cpp << " default: break;" << newLine + << " }" << newLine + << newLine + << " numBytes = 0;" << newLine + << " return 0;" << newLine + << "}" << newLine + << newLine; + + header << "namespace " << namespaceName << newLine << "{" << newLine; + + for (i = 0; i < files.size(); ++i) + { + const File file (*files.getUnchecked(i)); + const int64 dataSize = file.getSize(); + + ScopedPointer fileStream (file.createInputStream()); + jassert (fileStream != 0); + + if (fileStream != 0) + { + const String variableName (variableNames[i]); + const String tempVariable ("temp_" + String::toHexString (file.hashCode())); + + header << " extern const char* " << variableName << ";" << newLine; + header << " const int " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine; + + cpp << newLine << "//================== " << file.getFileName() << " ==================" << newLine + << "static const unsigned char " << tempVariable + << "[] =" << newLine; + + writeCppData (*fileStream, cpp); + + cpp << newLine << newLine + << "const char* " << namespaceName << "::" << variableName << " = (const char*) " + << tempVariable << ";" << newLine; + } + } + + header << " // If you provide the name of one of the binary resource variables above, this function will" << newLine + << " // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine + << " const char* getNamedResource (const wchar_t* resourceName, int& dataSizeInBytes) throw();" << newLine + << "}" << newLine; + + return true; +} + +bool ResourceFile::write (const File& cppFile) +{ + TemporaryFile tempH (cppFile.withFileExtension (".h"), TemporaryFile::useHiddenFile); + TemporaryFile tempCpp (cppFile, TemporaryFile::useHiddenFile); + + ScopedPointer cppOut (tempCpp.getFile().createOutputStream (32768)); + ScopedPointer hppOut (tempH.getFile().createOutputStream (32768)); + + if (cppOut != 0 && hppOut != 0) + { + if (write (cppFile, *cppOut, *hppOut)) + { + cppOut = 0; + hppOut = 0; + + return (areFilesIdentical (tempCpp.getFile(), tempCpp.getTargetFile()) || tempCpp.overwriteTargetFileWithTemporary()) + && (areFilesIdentical (tempH.getFile(), tempH.getTargetFile()) || tempH.overwriteTargetFileWithTemporary()); + } + } + + return false; +} diff --git a/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.h b/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.h new file mode 100644 index 0000000000..efb551197c --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/jucer_ResourceFile.h @@ -0,0 +1,66 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_RESOURCEFILE_JUCEHEADER__ +#define __JUCER_RESOURCEFILE_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "jucer_Project.h" + + +//============================================================================== +class ResourceFile +{ +public: + //============================================================================== + ResourceFile (Project& project); + ~ResourceFile(); + + //============================================================================== + static bool isResourceFile (const File& file); + + //============================================================================== + void setJuceHeaderToInclude (const File& header); + void setClassName (const String& className); + void addFile (const File& file); + + int getNumFiles() const { return files.size(); } + int64 getTotalDataSize() const; + + bool write (const File& cppFile); + bool write (const File& cppFile, OutputStream& cpp, OutputStream& header); + + //============================================================================== +private: + OwnedArray files; + Project& project; + File juceHeader; + String className; + + void addResourcesFromProjectItem (const Project::Item& node); +}; + + +#endif // __JUCER_RESOURCEFILE_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/templates/AudioPluginXCodeScript.txt b/extras/Jucer (experimental)/Source/templates/AudioPluginXCodeScript.txt new file mode 100644 index 0000000000..316bd11527 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/AudioPluginXCodeScript.txt @@ -0,0 +1,44 @@ + +# This script takes the build product and copies it to the AU, VST, and RTAS folders, depending on +# which plugin types you've built + +original=$CONFIGURATION_BUILD_DIR/$FULL_PRODUCT_NAME + +# this looks inside the binary to detect which platforms are needed.. +copyAU=`nm -g "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH" | grep -i 'AudioUnit' | wc -l` +copyVST=`nm -g "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH" | grep -i 'VSTPlugin' | wc -l` +copyRTAS=`nm -g "$CONFIGURATION_BUILD_DIR/$EXECUTABLE_PATH" | grep -i 'CProcess' | wc -l` + +if [ $copyAU -gt 0 ]; then + echo "Copying to AudioUnit folder..." + AU=~/Library/Audio/Plug-Ins/Components/$PRODUCT_NAME.component + if [ -d "$AU" ]; then + rm -r "$AU" + fi + + cp -r "$original" "$AU" + sed -i "" -e 's/TDMwPTul/BNDLPTul/g' "$AU/Contents/PkgInfo" + sed -i "" -e 's/TDMw/BNDL/g' "$AU/Contents/$INFOPLIST_FILE" +fi + +if [ $copyVST -gt 0 ]; then + echo "Copying to VST folder..." + VST=~/Library/Audio/Plug-Ins/VST/$PRODUCT_NAME.vst + if [ -d "$VST" ]; then + rm -r "$VST" + fi + + cp -r "$original" "$VST" + sed -i "" -e 's/TDMwPTul/BNDLPTul/g' "$VST/Contents/PkgInfo" + sed -i "" -e 's/TDMw/BNDL/g' "$VST/Contents/$INFOPLIST_FILE" +fi + +if [ $copyRTAS -gt 0 ]; then + echo "Copying to RTAS folder..." + RTAS=/Library/Application\ Support/Digidesign/Plug-Ins/$PRODUCT_NAME.dpm + if [ -d "$RTAS" ]; then + rm -r "$RTAS" + fi + + cp -r "$original" "$RTAS" +fi diff --git a/extras/Jucer (experimental)/Source/templates/juce_icon.png b/extras/Jucer (experimental)/Source/templates/juce_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..396aaeccb821d497fdab5d3e406d9a3046c7ee54 GIT binary patch literal 19826 zcmW(+dpuMB8$Y|)T*h3A&228ZMT|*>Y;#Mc=!O#Ju2O_b!Zw#7w<(DfD=9^p^bL_s zBZ|2fq00A!T@9T4EgO^o;@1vb6@S+XbUC;W0OIt- ze@+H~6;OQs1pw#p0Pvdv0M>;7pb~M#ugw_%Tqk!sk`Kpz4G@AL5vHrF%aey^dG)!v z#5->~>uh;8JcP@oTK=V4&Vga0VC1BlBA`X{V#MCn4b(TWv^v+P2z};A+w$_=9MN)> zSkQs{m;w2BfmdtUuI)+(QwV_yfiJHBk=IayDC@^AX(Jr3RuMY&;QudjZzcF=#D-XA znY>Cbz%bvE9-Ha&d4_Ti{4U$dXoaklS~{8N8jldN@O^P5Na(5 zHEg^vG{iq7SgNJ88UR=ho|1Bi!79jZ}Hp>O+f6*V}d%-_MZ`&nrnVN~Zw-<*vy(`NjTiU4< zcR~$46NWes(NYcw9cB&(QItYLDae2jD}98AX$Zo3zsFr=3EhLI(b>ry5G$gBJic0? zmPjOQ=P#_gF-oiHg12Z!>1<-s3TKFlG*EW-a7H+v8Lajj|Ih5ZkiXRXYzpnBadCOA zf68pA*!p?)>^W8V@W-Y)_9Y4@6p4g?8&7u(<(pekBc7>AQ#GOtmgewx$iWZ!2v)Kk;*| z8pl+8X{KHdeO3bVQG}8JSw|=-H$GgUhoL_A`J}W?^XMOEYjtqCH8G)<61(b{a;-Rn zzV}8k-Mgri?wwOiKXg;6aE$(@zetzb%G|I0u9%j5|ym@Y3&v;_4m{Yj_F?DWXv8K^&5J;s4>_$=9i&~Qf zk^nS)Pzrc~Luba02b5?qjDi^SibkyCvQ^bB3ZmTBbp4IOG!G3e9NU82M+ME}kp(E68I>Z4S=Qy{s`$}POH*{O zc=OwL?Ost@E8+Onu7Bz|HGz8(i`-)!mI3)3>*xjtPu%)vOoAs`0A?(v=f4Gl?+#m+gd_oNMlCp~XM zDeixd8j!YSD%+TJfuyM@XLXM|sA-`=Pd`X2T39wnPjvQ3#~9uL*ONQUYe;KZtU)~` zM-7(}34hR!@?df4^Dc&gcPTzTVKJLtRJyc`)}HfLk;uOu^k`?j%niw2C1_OwZNQtg zTL+NTI;IaCm)+?#bW2wC7pr69=^^>+;rKkG@r1}PLa-eztl}bWR-_sxS7dL86>Hf% z4FhuxBq@(BQUvQF=;1Y$V?TjMfsiGMe%79J6p!eqtzhim$<<Z+I_W961d-eX=t9a;&t{ z+M4{h44Y~TSn`1_uw=Gr?+@F)Ya+zMHL2F>{RF&iKjdz%!vNP*@{x|a5|oW@;mh`2 zimd@9cxj!p7)*m#Vzd0AzFSeFM~5!BDAogSS^2o%~)ZU4zze zgaNVWLOyDwLcaOr(iCD6RPh-4NaxE;T?M?o;^po5FU3#oqlBGlDA4V+#BWXuAN--q zn%aTIwEe(h4rgI7**-KWC&^<0@yYqp+a_R2FAuovhCe~>)W*YPzfSic%%mY2N|0lqe14&$D+UuDO3wsAq$fc*wFgk{<=hU;b7jIMPF}*pUc54E zyM`D z`uttlM@1-yAnbx6h@;e_2&>(c=Yn}86`aC_)uRhbS|4FCPi3^uE#N4Ecu@x*oF_9t z11o}%2n+X40O1jj2sfS+@QiDC{KH~%e3RX4Zsa}bgAuin4m|mf*{~36(-R0pdoWW6 z6zDTJ)9<*g&@S45ZF&h}zzEdNZYdqoey6jkgF9LLn!BM89iznF!j)e9Tdc%Q!57m< zcCsJwRlbHfp7{@YNtX3^Z0v0=rrB1|#RtC-850PrDeL_MH>mS-Qz}%^I(S*^jK}_k z`$>IZ{ETLtG4AGA!_mT61DjLGDPg<@Px!NZ`}Gaz4nKa&UsHJ6@UQ#Y&qyMgxEqE<`iHvumc)ME;zL-6?L zub@g0e8B!>MF=~e0=cn*K70eX6~>XQ*nf@g@1({XI>Eh?q*Tb*(V(r6{ozY58}=5t z4!lAWiLkPqt+1&1Q6PHAPw^cwSIr7vlnIE?R1!W;gN zITZ$Y`HkBIQ82K5dbLuf_X^OE=kn?QOS=b{OtzVHvcux~!7s~n2_>V)8Gak8fa zjco2nryoHWF0G(vOf?MKlYhr)Q#7jcAmP`(L1Y|QtB1Z}MBRn~l==jflS+8^{yqiX zGed_amX`1(*KqS&?#E|W>12h%*vI?C*O;qWP9ssDw~=ZOVKFFL#^}ga250wI`RMvs z{w_P`FAK!Gj)GMcbw$?#Zma6i*W3z!sTf>uiMI>}Gh>R-Z>nQHl=|uF!SX%h!6@Y- zM#p5)Si3<5M`3h7yGld9QXbPR`^fy=^JYn`!;kUkaAYlH-9HM^WHsSET-S zJ4GGb3rFCH5jSOR&Sv{ri`7s(-U(2;UT?xa1{6R;f73;YS%)Ra5cbsC@&_|U`xMT+ zsgZwUB#qX=yI76+`g1VOq4wW8xgPFb={RRsRnvYeM5`LNMNpYCwvIe{;1FdT3Dqr? zsSv8=bRd7kxhJDON`Em6r1Tm?;+D;^2x@vU}-YX{&J18Yq1qfbjx&b7~y(=-f?QBP^L{tqj9K_482`+1IEFwGk=4?)aZmHJmgQ}IN%{?Nd3 zfi6vu&skJFuA2;`Fwp@5>Y6%_vzvRfUjg|i1VTub$D3@g-`#V&imN#OU4}t5up$c- zJxJ!P9RWXw9}a{4J}7X=4q2&d17X$q)YrGntWzm6JWh8|m<~RKf2vU3UNyaG(-Sn)%%_ z6^}c0C^c48+7O;wQW>>78mbm=f$Cxzef6W7-;#PLw%xqK>*E`L3O)k)cRHJvz(37> z>}A0NAIWGdboU^48;(258+s;vRrRFnaf?+b3oUwdmQ}0T#PU@oh5*v>mgOIyK+&m} zbM4sqV7NvCA*Dt!LrnGz4QVItdZy%MF&`#PtK4nnzaNof;CAFmP@lB=xx>MEia_{= zYZ4DOY4wi)kXFakfu1C*r!xD2Gy1DhZS(3oZ0lyHqC2C^JJJj-_z&mEhzsl=`Bd)7 zeO*w@oCXSYqiFcp45;k>u1M}MA;eMa{YfM##nUVC+9=%X#=sgyasqK*7Yl6!i` zU3o;d4N$q;?i>X11HKiZDWQoNjJ{uW@2gSp?IRNEE|P?)4T1O$r3mMN=y+@VXeCxO)CioIta)-^ z8#zZx=(DD>pE9@yEg9WO|@V++5jXz$r%BCD3_dHDR@0Mg78Mv zPTp)$Y?-B^)UT*>8MRQDnwiYizVDTCK6#q^T{3`%&7{Y2=?^=_HNE=Koo%bk_P-5H zRjwPmW=r=4jfDgiEL{s7K7deO8v=)O;&)#{AjU!{GC~7(o=O{^%Clv?<_>VX_cabk zTK)wq8^tk1OzzU9af=Q5Dh-YS?%v}Q7Z{+;Pgt!SdsV?aDa_YtA6ovYXRmL>nN zgFC-wliT*;)H{C<#z~j&;c|DKwdYGDlfPr-Evl;M<`5_Ia{pce z9}CN@FQwMx5A@#l^rgVM?x+~{yx~Voxl+JHrC1W&wtK%ZAnopMjQjW%>16FH_-@Rq zo~+kY@={#qL~AN4+p98nmx0u?mEc+~-Ln|i=c*VObZOqp=qO`n&h_F<^n*s(Q)t#U z>A3>vzl94KFYEbpwgyjFh>@^{&)u>OY0>WKGz{1b{m4!CqGkM6>p0%Hn{f9N`cI;{ z3FL3~MeGSbWHMk#rz`%v+Q>Wy)8fxErY?T=|AQ+p@t!q z2li8rXr0lMQ?;WU;7~u?d}wij9;#~UloXiP7|DRg0jZSBu!bvel#F%yWFr=$b zKaS=kf8lyDS$*h7?JDcz19_cxZdWIwsGnD`1_GHo&+Mk~kcDehPz*IJPR=8^Ji$C!mI zfcVwjTt<9&{JVL+xUjJs9w=2Ber!M;t4D`DYN~$(hZWnJ<(MZ1dG~8)Yf{$NaQU#J zqRB=a!WPz!3K#4Q6rlG3%+q#@Z`ZqW-f^!e7OoB5lsJ7tFHwl-+X@f1I$$h?aF)|Y zv=xWG2t1v=*c%7$$e<~B8vO(5O^$Y-Uu%LKHyto>t*!MDw^J+J)tYSd-KaYFjo7Z<7 z82r&HZWoQk2d|S4zE<;1&^FzvxnE8bs^p9j$5r|k2z%e(NKB=1=3G<4y{?Woty(9H z<@&EJOyEjVP(CP#>T3LRwE5!)fj`MX2sV>txmdop+PVVNe7Ofyd=^2;Z3GwA+hMNsjJ}Xo74od@Yd8Ld7 zT*F+u=Dqtt!rAq0a&~&Y2)iw0${YQAnBbJIr0+h^U$T=nczoM60$wDPJ^IzD+L0^y z;Jk<$muXlO<|9kr(~wKVV0_B3nCx5H##aW90}MlS4BZ%Sn+UWeHm9b@qLNz^srLIM zL2W$~CfjFydgxfq)je#a0-b_41RD$&bawED_4q#V(Y znp?o-wV8!Yz$_2VB@W5SPu$a$P{uHJViLJhW?t*;&7`ZzEJq^}AvFNpw zpy_}c@rs|eVhXQ((+*gsiPmFfEcD)@774kwFj%P$JKQt5DjbnP50M%2O)}XDO8$BF zWS;afc@KgTOORn(NUCNM;-4qxem_EcohWOzoUMW*CNnnrXYQtw$7ak9dctN7h|Wv0bXzWuZ_p!eO z7SUf1;7VK8URpy$cC7I-f=m_8z*qe`pdIq^mI2-pTgfwMkIDEIXhiKCxP z%3g9YU&K9c5$q`Hl8K5%vh?QN^wW@#L@Pw1ESb?$hpTCyoL@QJ{3dQg4LsR&4d z&X*6xo{^B$veyIRrf@fb_s31n#g_WyhpGgGj?0g$Qn}UDtkW`s>rUCSe5OTJUj;{}&V@;WDu1SEbpTI8syJ z-E?kVhN7}qdVMKRu(9`K!ftA@)0OJ%tI{PPy`LW~dupGWxUdFOOZ|aDMKz;b=dw|# zpLQtfrK@zOpQ`<2AFp;5U@rL>Q=qXa1premiT|&$F>$mK4QFtV?>lf@IIX*drI6M1rU~V0lC_-? zkJUQ00*X>UMzanZ2V6Fcdv{5O=nH&G@ndc$dB9;c`r1?HYk ziYYEU`ru1247;#qupNSrT7bv^n~P*NKOz|?($4Ly=nl19N|CdI@J1IdF+lH7f^cZN zcwH7InCU9RZ5j;zlN%fFT$l|&yh_ohB+V!NAwjPl<6yCc@O}(wZf>b%7vet^PZRnJ zx|qaY4|GtI4{)wVh^wvC))`!JW)oX=qA_$dJl+-6v?soP40<@9{_M<&dw_Sd5z~db zj%vDuw3R`8>M*Qq;c9K}4@Tbyz^ab3YycUj}0H0}I?dvLl6<}s0)q-1tz@G!#pT-Y6OQLgFJAMl9>C3nKS z*Dl1R6$IV3&-?31cQn@ZkQv!zJ)?^Ie2tIkKMf?Fq{YGoOpe1nJ$;B(@K9a0e{?1`}%YNgUK(WIgJ=}NEaUY zE{@3KJoT$8c@X4=G7Yvb{GEMNug-$O(;D7eZkSY+@}dSUWD$sNQS8`m7v?T?INTzy zNS<^H#m_gvzmJvB4uu|olFFsR6bGayKMQ|xJzi|uM7C|@@gw%w;Zf)98DS|G74#%_ zOBIM$%7G%F7gXPJ_$SxOYzCi98qI$h#XxDU~BfZhH#G)Iu#1=a z5kWsQow$%P0xD?@%EUa$hr`Nli!*GV3@o`yAEp}?cpnpV$x2tu+_;K6`R;cp(DSLe zka#J51WYqvmidzcktshv)~syUaDr7H8n44N{Q`oUJj}D0E(rZi&Sxoi>-EH-_!;sR z&X{|Vi2|$DC9LLG>C=TaT+&!lm6KK-S!U)y6Jqs}0Xvi_>*~Ut8CzKIot|^$S{GfT zqrEm$U##Vk({eu*7AGfs_<|$m^&EB_+Qr9-rNneY(Z~^6?Uj_xV5ZIGaA+55;4*g< zXIW2g&XV4MInK?m&XcREwKEqMdvx%r2KWGpJ_ShD!9F(WGS#$V@Pe5**pEtotljXQ zb`Vw|*?j<&_1ucv{KVQZvq}{f_zQ}7WxNX`(m2-1jil)Dz%Sg@{97Bpp5CMl5egx@ z0oH)@v2(&P<2fnduH4}y;p$s%#pxDq{(Cviej&JM#RKocS^%iOBoUj^!q39qqQmA0P1d3$I=HfPqnXdfl~4Dp6CI5qOeFwD z0%|BmqIbE$sb9d$NwyYQXkt`!*qk|gzIOD?Qu1&8{ks|9C7QxT$-daJU~*=>Nw&V% zb@`hZk;CO5vwm1n=~uDDB(#gPr?6!K4~axn)@5t?C2K2`E2#_kqq_dhR%ReKM1Ts9 zKO3!t%V2G6&}tMoX_t58nmJl&l8X1!kC><#!^-?rVTWR|u;jbq7C&JxRSxW154^LOLR%_ytf9R%6lrQ@EebSbLOkF(_v34inJb3#PQ^8)-cN7NP z%aM9cP_cZnKB2+`r|#2bSs%nKWEDam8iCMvqb$4IE8O|~F`2&md)CO%gGVUvi(3e# z9(uU*E#$$3v0ieW1dIgA($8NW9^;%l^>-{PSiF-p2Q56R4 z+ZT`^L|iQ@NC8y`@~->P*49E5dJ$gx&&nb6J=DJwds}1<<_t65fSGGr-c_%ch$eiJ z57ExoMIm7s$^(B)4=1aMX8q`xrV*t8N>oNLWwT!gmokA4S6`>0bVfEykq2PPQG+s|!UYaX}!MJKkZ{91~3&F&U znn?4cT#8dT&spY3?@8SL9Sm?=PI4Lv+t>eq@OmB>w;37MX(eOBJ}XfL8Uzu9mGjU7 z%Sw4orZ~f!-joa1b%i-sXvLy5eJyS`Zp?R}#s>;Owdb3>-PI3ju+Rr-jT91?2>JQv z0tbWPMPm!ai9hUEl0l8=(+WXY?AOBw)h5HW_kZo)4E+v`ngy55wBp^>Xpjf_kdQsS zbM-8vIL%ia`)0)N%VFP1`Tr*pV|8%ls`7!M%0Y=shtp;I3Snj|FMsZJ*OjyETA3mS zA!q!;4(vY-?2-J#rHLe}Lb_-C1z(EW_|>n_eIB%#X{9SclzHgqP7UtoCouN5d4h6y~Iy(bA z&R+}z^voqImOPh&9r~e&xOcCd>+xLSE?x5EoGx06E`<1?I}G*Ho;b)@L@i_0Yg{2U zsICMg2IG*~(l8rwY6A~^ol2tG(GTx4=|aUowCcbW*dLMo{Ti~tl^VA0!AU-gj)YZCH#rfx{cXlpsizJ4e

^K+Cxh_rH@x~^^Qp4Es9t-;UWC#sdVMr3A3sD=q5(k% zC7%`|JdQjuH;+t*UV@r66Xp|RO|#0SX%{3Q&~&L?Gwm*Llb)Fci=-Uyi4eLaP;+`7 z{%GIm6?&CWVqd7mJAylF$DDk%;^Or)*xnP+;%4XI&hZB){QjUWfes#gqUP_IUD$3$7C<|tR6Mhs>#oUX7g zb8wuRTw=0$lY|u6NrUoVO$pr`pGzNkdx!znzQKqJp5uj_c<7TuMXA^Pxj>b<%)@7- z(@O4z1oJ?B;EWX|jUi?Dw)1kiV_Mz6TrJh(j^ATHteiKR)M{@0_tDqk9q0Tf3k9C( zVsZh4P^azx6)-^&a1s%`AqEA(u$jPOHa^7`l4V=vdm9{VnJ2s{FWz*RK{pr&P;SH| z(ckq-^)YvL^XpnuM}}Vdc3d$}v}2HAiR8v=)IGH73LfnLbcSyZVgDL<&f9G%haEpFo8nV;Ox zpkAO$X+4nbGfk&Z-b{+wj~l0kH!>=er{v~)~CF<4L(g1Bbs${xji z!vJbA2imTqd!2~MlgB6dlL}$hkiku{`?a6)!?nYz0>_DOyv*kxo`~Tsu~t^Yk*d+ieIL# zLQlk)qwYA$s>=8?9xpiJUcj@@LeyHbm}S#veM+SMqDa7qw<6<)7VE;)h}Q_wl6@gApOzNn##twiODQQv zWNm+V5kUi9Zk40uNs0*ONiVX#4T0KIeIVJp0z_=DLJ&EnAZ+)H5d-<{;E~9#j;?u?L@6a$!P#?> zM0M*QGB@zpiqR_y&q-svZ5^w7E=3@mC&D5tOB8HBgJ~mR&PC?&gf$e5muZH|(!a+H z{>^eyXZ5#SFl#x~51xUkWj#KN$|`w{%6is|8;><3dL>vL~vdc5J@Jpm~ihcx`*t0EX%*HPfiaYT+ zLWcT>-2ae3ql?rANvf!K$7qpO#>`tZ!dXER@k*Qlup*YV=J@k3x#IV62Kw{&5$3Am z$8$-t63Gs9Siq~E>fYB{`jdPMWRT3-*c1w!IGjAORwN`~G3!y7!qF)#W?)QQ(%%qE zcvGm3E`uZ!$a5g#;mOEt>6akw*c!{szN+oAL0YOTTh~BeZ488W3 z$?=6F3(0C6^2C}5;#0y$e|x^e`R>JE#6=^>aND{8f6sA!Fcxvo=spIs^9nZ)ZGCBY z=)E$7Dq+P9phDc&aW4Cv9-EN~ZNtr$O6+gTvep_|>h@jCtG1-;PPQ-Jils#(9_JpO z(oOB)YL&g>7Jh!swO!c`EA!kCB#E^QcAbB2uQ&zxQ!?(ckgkgn+G_iH)sFX`io_OS zvCYH;KGG=1TwJ8p$RC};3x950eZ`;N**iRh0;wQOE$6@LebuY-mX*t62C*wDR}X2y z0==;HVTfcRY1^4nWKKNe{xaRk8X2^T@y5{5nUplsr-G#ImeSr=CGX1Rx1b*(N{vxx zv{uE+{bn^h{+gLMLAl0)q1Te!ERjPRT$E3l%QQl3GDzVpw&Mko1qV3kqr|%lq6r*t z){N64Bpz>K{n)!*7yhp-fFnJGN9})o2iq@T5)%YcRR|G*9jRN*O?^DGzM4fROUHt)E_Q^21Y_)V~f!!)N(b=O=rE1x&y|W&g`Xo zZ4M8Eq#ERE;al2C!i8|+U0GWEx@_!-;iOR3{dJEJyk2OFKSF$ot^3FRX-)9v%G`$h z)I^~|aEfR4ibw>3X~$v^u`e^pbRX1w;}S+xOCUq9rtUFFNV*)tzZ_^s$+S(Uo7YH0 zT~v|;bTvOZt#O`-LDw9w5M^$!%n%s_6m74EQ&JDhu;@DOukHC2)?$YaD^jiSJUfTy zfrrwt7`ev*lszXyDIcG~^%?evpDcR@6-l3gKGVQF)=Ud0LD2Ut@~&e@bp@5G7Wl%8 zKqIwI>l;r*pqQkA=qy~X-WOC?7wESxT$b~`CihRovo{>|7p#0Q9x7~wQ`bep)OEAT zD@cW>cVzQl62HTS3M70lx0#`eLhmn5o^#iMI!UXU!O9?b3OOOV*HO0Ke_rlM@p*q3 z53Ibdy|**yIs2a~XSs2=rGkqKAf7B+hqHA$@{EY@$s3LZ2 z7p72M2O~=6Ke1wf?N(62*uD-&IROh5GV1BNo?N0F@JD*?OXnDifgP^`f~ZL|hVgSU zUVFe`%FiFd<;9f`XjGx+yO%Je*r_BPZG}JIsG$DfI2kT40_)F_=a-R`|8&~3J)ksG zS}dZU-JvVdKeM#DHRy=hj%*wE*5u!@a&r8yHqNCn{KKXLHQU?>Lcjh_J{8>4k^fkJ z{vvc!6$ugS=$;GQRe8D(b@)Bo;)>_Cg?W3ADfMqK6NSHkQq`8ex5IlY?>xj{UUt%F zeBSUuL%jCDb{V_7(oJUzu+Mo?8yIW}Q+#ww=Ap!7v+4lLND3teW);a9@Tb%_qQ3G& z{7FU9A>xrF(JB%T5&8>w?F(ZA=s^Qi#Wv=hP5)re6UqvUEzl?H?*pX=NB7z?S znolw^AWL!EdTFg6UZ7CF+fZ57=eYwH<-Y0#Y%+a+TXs7?4$2$~dP-l4-wZ1|Wg9f9 zWXqqEP^W>)TVXJT!r~NG=SxvugHSbSi;X2jC_sGQw)bZOoSj-}-!y#Y7g)=EII<|t zIl&N<25BtjKblm(o?I68u_olrG`#u*y!5bWNh3&J`b7gYAi9RkV1H=T{?wh}+;Ku% z{SFFqK^M|eH!(z)=%+Gr)te%6G#chqx7Z!9*g*nrUk5<8lbs|n5&Si!rvJI_N)}7) zOEcYVfr1!{T|)n-!T$pYp!)ihyX)U;H+T_Y(<+Xp1@B({@^7>4SRjJQd;Od*Zb2Z_ zhzR{P@zl!3z?6bU6^!Wg4Y}~~EwrrZ%msU&z2uFsJ+11!?@@=L?qx8TuZF~;5tjsL~zq*_*c&m=Us%R({4#|WWA*Ae5-vO zN_kt#0fpz5J4-{KtN#I;iQt<>l|Bvl+Z}tKM(CSgtR2&(y_-E<^63ZKV?lC6^dNj;C!d@3 z-qK{H7y&*h^XumLdAjV|sSn!4WbC_cOQ<=0WPW+fjDf3eCg7vk_?y(_G1G(Nf&2b1 zfM|_^+NYZNi%W!1Nb|NXv%&NPq%vW6@2vxjl-q%=%j9C)TlBUIaz? zADFVY%eTiQDSLalK6mKf@7c6${fio6@C~Ne%R9VvWu0A{UJyUhPUMd6YiTz^k>qax z8xE*;+-?((q2Jaw2&%-e?Lg|3IuFEhPtNnL5%&sDA`rbtGqmcOpw4_7N?o3}^poC& zoow&b4TZPuI6%P^*K}qgt+z6wfn66(+gaT+K_m!8^O++C20ar?o|*&nR~p?m=@6*o zx9vcbH2nlH16#B}~Ng|&`f5c)+ z0K%J3SmpwiTl0bNO4^}X8Wp#5$sa9@yeB46(BQ;^1U1*uFuu@ z_A>0(9f1yh^mBvLTbYN*hXcg?ut<-`>E|jF!Y0fnS({9C5YdJi8{BmjTh|tfeWRZ< zt)PbHP4QfQgax}(@M{a~s-H63(lBLwepj(}ZKZ2?7@=~zGoc@YP2{XVs^}b=jnaKi z?Er;zoSa)CN%4FSBE?;k9@lRZY?yH~as9{b2h2X3d+j|=iOqr*?yI!m@3@M?K(-9+ zE9`n47Bd4>0*U83`nR)2Wnw&W75Rd{>Rvix3eJskAoMWWM6|@Mivg$h(yO?^p=F|L z=6yg{4u?8vlPp^txjJ7mLY%~iw_CJa!eSQpYKQ96U*>utA>RW1W~u&yC6Nu!@66-U z&hGE^j19l~9s-eD#ad0hA`mx|rk6D2-Q#;ve&pWz<*|N3o?D%rMP%hXIcKHqys@Ox z)7({Aue5}O%THsZtj@wWKT9M(&NzgEmok>BVSPUu(J?kEDjEg(V&CqnO27S?4zL`7 zKXjqDdnXqjE-*)ollJU)|EV1kkb#Zb&r2&V#flPF+WGc-7rJ>LhR6I#XaCA1QQ*Nd;5uAYgSMFCHc& z(??p)F{oSKao>+_KC!lDbf%nedw;o{qySx11uYWNK9JZ zeyj1BAO=-{eBy<{HruVf;ZIFpVBqYNaMw#-T$FA27(#jxiYbTxo1#-cAzffE67OH( zL3E4uz&T@CTJa7 zObW!1)#%JNby%S!Nl(#CjR&4GpzXZ3z`f$G(C0nRc>JYoaEZkg7wLB9yje9qW+fn6#_~@UN=^q1rqo@>l6dXN~+#+;1CoQ7*ST)o zlB?=54Lft1#T@i(Hz!yy_Z!WVf_x%~_qVJi75JaE0?5wdr)}OmY`$#DfKP?(Ba92dyQs~6ITAN8_++4#30_khjja<=;kS^t^4cXD^n)v}_fXAkHyo&sUi;OF?o*xiiUaunwB*QZ06xnOlX6^E z7{5NZaQ&3+dry*cv$g2P$Tqz8@XigtiIz?a9rpFP5#%0cO;$MaNr4-t=DV7u0k_MN z-Iz%E#A=4!rAw=7OH4m=CWb@2mZ`AM>k;$@oMltg0&cBrn_qLHQ$*#6v55R{6ijjh zb5b{nJpjT&$g|hJAUU0{U#u+6*zgwCd$f(Nr7D2KHoBJW^xRWe?irP^;DW5p<1hEf z1JgK4Fs>e=?L3)!u;~xV^@a!YxF`mv(=@Dmy$b~<3jJfFg?hX%NFv5gRdwg!Iq=go zQ7qItR^L0j3E2KGaD>U@7^z{EV>*Jf3nOF8R}*(XT5IoKT>HMV4ORV@_IZ3{M~eE> zAa%>llJjO^e`mh{dO&YI(FRXD;>z9ikoFyBEtPUB5NM=xheg6%`a3<we?ImgILb7f70=Iv$ing`(?PPSfhSD@wNMD7OBoPJ7maK?qK!Vx`{Kt)40gBd;!I<#?#X_KYaP1{OV3xq3 zk}i}K^lq9+`WHBuVQoT zIl)%$iEkEbA++?xCDE5z z;?TRjA$J{V=E6*r*#8R^hlyWVy=I&C4rdJSWJ4^L2+IXv7K+NT6Sne~MpRrt5pk7- zWZzy=_o_~KE@OAQ_?_{_j(gELYv>o>+}k9*W@Rk!O|}w8!y(dvy(Ns&nC^8J?4iW% zFK;IM3HYWRu$T|#h^)p^dIQ+`)(wSw+!QJ>eF>gjSs2=N#_pm>*~lSrm+>uXnXHKN zv|db+7rrZ|hJE6iJxCO5W=bDsm2_@|diY+9MH^@OP*=G!4c zxU!SRT2D!=KP7%*`avDa?Sh>|$TKjkECtlQ@168G>(a$SI$3gZWx$A8?mNUG^fq|| zHYbZxqh2b`Tg}(tIt15_-`5zrf<;?S(BQH(~(AGBSj6`2q4q*X5XJ zfNUd`bq=TcQ#{jx7*4yyoG}c8AlRI@6)YLw#|XP4DIOULA7POG2jcB6ho3R&keD!u ziaw;1DAR#?+t2Gn2de52{Y>JeKYF~(d;vJ)T(ZX$;gs=yKT@mYn zo1o&CsSgphzrzSK+91P@>}BDn_DZJ>7uH7=S4FX74vgzI^erB}ZHiSc#d+jYgCygm zoM710P%$d&b~(ybDwQdt$D!W$fdaQwUv|p+hN69okzf6g^NL}fA1V(G`}>FVY+|XA zrs12vNU*lAOYP{QzuTEXZ#b&~D|@aD;~k;oQ8#Jy{jia(vPflp4@N}B(&xKnD1x1X zi|HeEtllr>ChsrpAEd6T8x3&m=eC)&5u>JX|7PhAo-f{rk59Xx?y}ZVq5sLD)U=LdapW>)zov6yZev@aH&Tq*9UKhWtk|y=3a_pj)E-@ z@%63DpzmK~-%RW|==0wQuOYiZ=z$Qmms~9_tU;Kuxg3ZYF_~l=X=)?xjawn^C1IIY zcblDudJA_lXUvPWbnf1cu65skzWUaOFj&r-*;2Y$AfBi`_Z@E*kVZUPkTs zm;7DQ;}^wyP*epBM$3|W&&b~UxrCY$(OT}v?1x)!n8BN|vb%w-j%kP;MGE+%aC{QJ zOEQpT3Oi(n-_-%j9O?0!3;&{je{NariG)lHP9f~$><@)WQC#om2s@Vmf#@=w?5OM| zmdje&hw^b3I^n0?;-Ma9Z&p#Rtg=7JGFqo}9s`YWbt?8&7ilVq!nBEaew!AzS+oG_ z5qFA4BlyPFImXV3+}l5d5%4IGXg~Hx?9dOF#pb-&oBsB|&=3_|Y8aDR7%{f?P!Yk_ zzW1EpDN%hK^8F+oO44h|EaO^{jeDP7ABL3_JuDFOJ&mM?$yDltt4ic)nTz`n`d_wp z9IQ0Bq$Nw@=lCdhe7CvaNvpeHPPe+ShxRydh3q>Ef7Xuf**U#fNR3*BX{zqe!U^Mp|!5nPv+%5n%QN# zdRG6Ri~lE0^4pT~$UJ?tUOX$35N@+J&K2jPP7YDzANzF1j#szF8vD%bdFr1;={-34 z;S(2VlpBohIc!->e`g95DsdcU-<4}A&~g*~{V7qB!4&4fB$P8<)i;YT^OUv&-6x8z zSB^sF-m!xvN8{ON1!^bFbm#KqG(R8_EmJ+i8{4xEGz{CoTN-bX%DW#}P)5H=AH_+X zndZ4ILZ7*LVVjSG9sE&#G-D`2WHG>w+~N1%RM+4TC`xdU88UMTzoMG>fA3LKRmG^P zsTrOAO0mh5OYG*a<>J8OtKEwOt)xS=weEy>)#zq?q+|_&-APul7OtSb6MCTi^Qg_2 z$=^zX#TvrWE$zfcxXF4m`HMRKs(FHN%qBKke-a+q>*R*|5^Apq$f&&h#X1jEI0__8 zq=IPW=+aF*u*_KdOLMKmv{Oz{5NaM-;k~?q91pYBJdbepr0g#E)Xp8xgZ2xfqV4YX zA-AL=`(?bh%3jv#)o?xDg(~glgvK_FXydO6DfNL<@ilQ^`A#=K&N@vjvZRAq1`rl{ zZS>y`2+6@8dyjS7bB@CEuaRG4EHk0f`+7~~d@WImWA8mYHvBpmBCAM^*_)GHdX4;M zUkG-{33DES<0$okh|{?t?j3H0%k~Lubf9Kh*Y@Iko?ox zS?-Kj2A4&l5IJH^OyA`k>`7XNY;Cb5l%;p-O^tYuWOyLO%e|A2e!6wq_~U)nASygr zX0rQbDU(UrFpB&cMS&fX>3dWw2S0DLM7#YG(IB<-+me!G12M|z-M{JpXN1;h(G^w6clx1YXvgBI~1{0T~fB+&V0iY)W z7PLgb4aMk*03^mG!O6;>ZlYr7_vxk!sHwvx%g-R~DaF98#*at@V5k3uL=c}m1A{g& z5lFc}PW66rli~lmeujU0mO;`x=wvQfiGa5G7(C+l4YUB257^%Z*1tBu`uF~7V9UD$ zVm=ca?qLs*S?Y-l44T>Cn@<^@++z55448mU?Er6Y1D9B!W;(wx10!fiS;v-v5j2bo zx`7n5u;d>wzV0q(V0gLnmCwkCdSnh0q`v=r?E|oV^qk?#{f`X)dAR>TF+kOq7Hg0FD_MG9kPF9V~J0kEODkAdMt3FKHc7Eb(O^dB0I(!lPb zRxU94${~)xLmnjr9WMjk_rL_v13D(>!8*u|p5O}|*`PzZjF>ayKz*+czF>H^=PAR# zZ+{qmNJ)R1%c8Jj@xJ4?{`~ug+@|`BlmK9f0oL*-YRDHC00&c}uG>FgitpPt^d22k46Wqre38<29tqM@$%jA`~=l z!46a}=>l2HD5M1)sbhl7-~R$u&!6r9BmN4cfd|?X2~J>Kmtyl$xdG#+Z>$1ZLJU$KQVi@eT;NN>At!&p22=h(8fl<@vr06u zjs_+Kc3{=P$d0??0-EN1v>n(0n+;mT26Q2TjTTr3aX@Doe1V>Z$_Y6Z9~8l$DhkwK z1g+Tvu|chRaHA5-B2LJGyA1!B{xke|`kmp)mM07!Z+&3+%ggosn25&N@?95>0CPR^ z1lv~vjlLg*7JCo_00M~81c0s84@(5d4MT3EgusoS2taC^T#PJSUR_Ukzv)^nN5z>G=yN|LP>9YY7_X2OX*a z8gC$b1q$>iJO=1#W#G|6CTQ`_gp}K{FW>$T#D6~h0uP40Jo=IWbkNo}KAw-ue~TQL ze*XRyEQ4xak&1idT>l+Qf1l_^A36XCAZjE4Y&`>Jw2}b5G=L=tE+_^kf)rgD?O=gF z<{}^8Nc{iuhnY*3lR?%?mVrluA5txV8+QMpSG)a(Y%c@tGXT#kvq6e#(7wappCRYx zf^#K10;h*}ANP$EEY7jWZB1S-OOf_YkE=4xzz z!40v%UiW}xd;AB@m0 zA}~Dv0vmO|KmBI-^W`_g$188ax&A8)&)4sQf}gJc<9yJ4;o0%0AHl8sA6Rlewn?6! zq>l3w0{{Yunh5|`B4B|g0Cp^;0W!^rR3)%U3-IzfOK{113$f`ceSE3N!upFDbSpNm z59LI5=w{|&%WZrBMUpza(SWCrio`=1Qo9(`r_cuWueB@F9mIz=8hEeCU(A~jqo8)@K7c4K>#3tXpsQWdk4rPhO9`D z%YhW>=%oO>B!FU8Lvel)D=k$?Yo?Ft%Aa2;GQIoA#>&skz$wMUz$MKM#9RyTQ{|x^>|7Q69_9p}Au&nP-zA=1#{F&kVi!Z>U z|3AYoF3unKB-HL5fAjU;(MNBdTzL86Ed%c5bl7H6kyrKn#xlG2pIY@AKmgGy0pLmm zu!O*dRvK_3B>*lYaSkN4tk4pH*N~q@JU~l9OXuT5b>@#B*}%7^b1*Wn^0G5<2y-!T zD*+RQEHFU`axk!g&guhgSz|&vX#f z#rzlWfy}=@e`f%7-ay9^f8yr<_N|W`DBh?u&=F zKL7gg`6u{3dgNvFzmOvKI|J^8oIlZ8`G2v@>r=I{0}w#8P5`*t1<1q4=+y#p?&m}k zM@|SJeJt$EOu!}p3x_Z_Czpkiw75R&PbnSdZ%X_hUkQOTF(V7ZKhTC*&}=Xl6Zkqc z(8UqVu#K!(f)jMk?*D&~2_MjPxgggvgRWxz^OxcO-@goRr8Hh%d;jUlWp;@tCvM$) z_44D_ub=+>`}y&SwfB>Rb0w7c+pqB{j zNHixFF?OUx0MpOR!o&nj5R5FmY%FZ53i7-L0_>vV&#w#d$tbXji;D3vKfcAr!SI)z zM^uuH<>xn6a9xh(chKEvf7m&He|q=&$It)Fzkf+9e|!7-_4g0Y9{+qJtMmT+^LMXr zJ$e2K*r5CU^B=>XKmY#0aw@iiG=5^q`PepZpzq@SN2?+q9RLInJre-FDgn7fKps0l zPY@i05&;9+_2>+!yDP9>iHD=D&w!=Dg?^SY`WXtp(Q-X{WTQtquI<}2EAr6+KmgHu zV?OdFtjK|hek?64AlZ;;SO6j?09Ybm!IKD>@GM%v*V)4s@x(;_PaKKh7nYViu89B7 zK&R0wfB+hZlNoU3u>VMb%8VAUtkA$?hXy7)S}DPXlmJ+;Bmi8A0N1!K`cXLy445aV z<2pkLIRX5_QOqN^?$PUd1_nCrO#%oYdRGC&R0~Wv+6b&@JpnefDu4|w0l+XLk<|gQ z#Xh!!G=JeJ1%Bg+_U?5L z0BpS#Y~8~D4A`${8z>% literal 0 HcmV?d00001 diff --git a/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.cpp new file mode 100644 index 0000000000..5c7fef48bf --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.cpp @@ -0,0 +1,35 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +EDITORCPPHEADERS + + +//============================================================================== +EDITORCLASSNAME::EDITORCLASSNAME (FILTERCLASSNAME* ownerFilter) + : AudioProcessorEditor (ownerFilter) +{ + // This is where our plugin's editor size is set. + setSize (400, 300); +} + +EDITORCLASSNAME::~EDITORCLASSNAME() +{ +} + +//============================================================================== +void EDITORCLASSNAME::paint (Graphics& g) +{ + g.fillAll (Colours::white); + g.setColour (Colours::black); + g.setFont (15.0f); + g.drawFittedText ("Hello World!", + 0, 0, getWidth(), getHeight(), + Justification::centred, 1); +} diff --git a/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.h new file mode 100644 index 0000000000..45c00f9b03 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginEditorTemplate.h @@ -0,0 +1,32 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +#ifndef HEADERGUARD +#define HEADERGUARD + +EDITORHEADERS + + +//============================================================================== +/** +*/ +class EDITORCLASSNAME : public AudioProcessorEditor +{ +public: + EDITORCLASSNAME (FILTERCLASSNAME* ownerFilter); + ~EDITORCLASSNAME(); + + //============================================================================== + // This is just a standard Juce paint method... + void paint (Graphics& g); +}; + + +#endif // HEADERGUARD diff --git a/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.cpp new file mode 100644 index 0000000000..0d317c6650 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.cpp @@ -0,0 +1,173 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +FILTERHEADERS + + +//============================================================================== +FILTERCLASSNAME::FILTERCLASSNAME() +{ +} + +FILTERCLASSNAME::~FILTERCLASSNAME() +{ +} + +//============================================================================== +const String FILTERCLASSNAME::getName() const +{ + return JucePlugin_Name; +} + +int FILTERCLASSNAME::getNumParameters() +{ + return 0; +} + +float FILTERCLASSNAME::getParameter (int index) +{ + return 0.0f; +} + +void FILTERCLASSNAME::setParameter (int index, float newValue) +{ +} + +const String FILTERCLASSNAME::getParameterName (int index) +{ + return String::empty; +} + +const String FILTERCLASSNAME::getParameterText (int index) +{ + return String::empty; +} + +const String FILTERCLASSNAME::getInputChannelName (const int channelIndex) const +{ + return String (channelIndex + 1); +} + +const String FILTERCLASSNAME::getOutputChannelName (const int channelIndex) const +{ + return String (channelIndex + 1); +} + +bool FILTERCLASSNAME::isInputChannelStereoPair (int index) const +{ + return true; +} + +bool FILTERCLASSNAME::isOutputChannelStereoPair (int index) const +{ + return true; +} + +bool FILTERCLASSNAME::acceptsMidi() const +{ +#if JucePlugin_WantsMidiInput + return true; +#else + return false; +#endif +} + +bool FILTERCLASSNAME::producesMidi() const +{ +#if JucePlugin_ProducesMidiOutput + return true; +#else + return false; +#endif +} + +int FILTERCLASSNAME::getNumPrograms() +{ + return 0; +} + +int FILTERCLASSNAME::getCurrentProgram() +{ + return 0; +} + +void FILTERCLASSNAME::setCurrentProgram (int index) +{ +} + +const String FILTERCLASSNAME::getProgramName (int index) +{ + return String::empty; +} + +void FILTERCLASSNAME::changeProgramName (int index, const String& newName) +{ +} + +//============================================================================== +void FILTERCLASSNAME::prepareToPlay (double sampleRate, int samplesPerBlock) +{ + // Use this method as the place to do any pre-playback + // initialisation that you need.. +} + +void FILTERCLASSNAME::releaseResources() +{ + // When playback stops, you can use this as an opportunity to free up any + // spare memory, etc. +} + +void FILTERCLASSNAME::processBlock (AudioSampleBuffer& buffer, + MidiBuffer& midiMessages) +{ + // This is the place where you'd normally do the guts of your plugin's + // audio processing... + for (int channel = 0; channel < getNumInputChannels(); ++channel) + { + float* channelData = buffer.getSampleData (channel); + + // ..do something to the data... + } + + // In case we have more outputs than inputs, we'll clear any output + // channels that didn't contain input data, (because these aren't + // guaranteed to be empty - they may contain garbage). + for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i) + { + buffer.clear (i, 0, buffer.getNumSamples()); + } +} + +//============================================================================== +AudioProcessorEditor* FILTERCLASSNAME::createEditor() +{ + return new EDITORCLASSNAME (this); +} + +//============================================================================== +void FILTERCLASSNAME::getStateInformation (MemoryBlock& destData) +{ + // You should use this method to store your parameters in the memory block. + // You could do that either as raw data, or use the XML or ValueTree classes + // as intermediaries to make it easy to save and load complex data. +} + +void FILTERCLASSNAME::setStateInformation (const void* data, int sizeInBytes) +{ + // You should use this method to restore your parameters from this memory block, + // whose contents will have been created by the getStateInformation() call. +} + +//============================================================================== +// This creates new instances of the plugin.. +AudioProcessor* JUCE_CALLTYPE createPluginFilter() +{ + return new FILTERCLASSNAME(); +} diff --git a/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.h new file mode 100644 index 0000000000..0b0647f975 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_AudioPluginFilterTemplate.h @@ -0,0 +1,71 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +#ifndef HEADERGUARD +#define HEADERGUARD + +APPHEADERS + + +//============================================================================== +/** +*/ +class FILTERCLASSNAME : public AudioProcessor +{ +public: + //============================================================================== + FILTERCLASSNAME(); + ~FILTERCLASSNAME(); + + //============================================================================== + void prepareToPlay (double sampleRate, int samplesPerBlock); + void releaseResources(); + + void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); + + //============================================================================== + AudioProcessorEditor* createEditor(); + + //============================================================================== + const String getName() const; + + int getNumParameters(); + + float getParameter (int index); + void setParameter (int index, float newValue); + + const String getParameterName (int index); + const String getParameterText (int index); + + const String getInputChannelName (const int channelIndex) const; + const String getOutputChannelName (const int channelIndex) const; + bool isInputChannelStereoPair (int index) const; + bool isOutputChannelStereoPair (int index) const; + + bool acceptsMidi() const; + bool producesMidi() const; + + //============================================================================== + int getNumPrograms(); + int getCurrentProgram(); + void setCurrentProgram (int index); + const String getProgramName (int index); + void changeProgramName (int index, const String& newName); + + //============================================================================== + void getStateInformation (MemoryBlock& destData); + void setStateInformation (const void* data, int sizeInBytes); + + //============================================================================== + juce_UseDebuggingNewOperator + +}; + +#endif // HEADERGUARD diff --git a/extras/Jucer (experimental)/Source/templates/jucer_MainConsoleAppTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_MainConsoleAppTemplate.cpp new file mode 100644 index 0000000000..4c8c3447bb --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_MainConsoleAppTemplate.cpp @@ -0,0 +1,27 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +APPHEADERS + + +//============================================================================== +int main (int argc, char* argv[]) +{ + // This object makes sure that Juce is initialised and shut down correctly + // for the scope of this function call. Make sure this declaration is the + // first statement of this function. + const ScopedJuceInitialiser_NonGUI juceSystemInitialiser; + + + // ..your code goes here! + + + return 0; +} diff --git a/extras/Jucer (experimental)/Source/templates/jucer_MainTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_MainTemplate.cpp new file mode 100644 index 0000000000..70cf976bd0 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_MainTemplate.cpp @@ -0,0 +1,77 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic startup code for a Juce application. + + ============================================================================== +*/ + +APPHEADERS + + +//============================================================================== +class APPCLASSNAME : public JUCEApplication +{ +public: + //============================================================================== + APPCLASSNAME()MEMBERINITIALISERS + { + // Don't do anything in this constructor! It will be called before the + // main Juce subsystem has been initialised! + } + + ~APPCLASSNAME() + { + // Don't do anything in this destructor! It will be called after the + // main Juce subsystem has been shutdown and is no longer valid! + } + + //============================================================================== + void initialise (const String& commandLine) + { + // Do your application's initialisation code here.. + APPINITCODE + } + + void shutdown() + { + // Do your application's shutdown code here.. + APPSHUTDOWNCODE + } + + //============================================================================== + void systemRequestedQuit() + { + quit(); + } + + //============================================================================== + const String getApplicationName() + { + return "APPNAME"; + } + + const String getApplicationVersion() + { + return ProjectInfo::versionString; + } + + bool moreThanOneInstanceAllowed() + { + return ALLOWMORETHANONEINSTANCE; + } + + void anotherInstanceStarted (const String& commandLine) + { + ANOTHERINSTANCECODE + } + +private: + PRIVATEMEMBERS +}; + +//============================================================================== +// This macro generates the main() routine that starts the app. +START_JUCE_APPLICATION(APPCLASSNAME) diff --git a/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.cpp new file mode 100644 index 0000000000..c3d6a5c445 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.cpp @@ -0,0 +1,10 @@ +/* + ============================================================================== + + FILENAME + Created: DATE + Author: AUTHOR + + ============================================================================== +*/ + diff --git a/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.h new file mode 100644 index 0000000000..1c1bdd816c --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_NewCppFileTemplate.h @@ -0,0 +1,18 @@ +/* + ============================================================================== + + FILENAME + Created: DATE + Author: AUTHOR + + ============================================================================== +*/ + +#ifndef HEADERGUARD +#define HEADERGUARD + + + + + +#endif // HEADERGUARD diff --git a/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.cpp new file mode 100644 index 0000000000..b6464917e0 --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.cpp @@ -0,0 +1,31 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic outline for a simple desktop window. + + ============================================================================== +*/ + +INCLUDES + + +//============================================================================== +WINDOWCLASS::WINDOWCLASS() + : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), + Colours::lightgrey, + DocumentWindow::allButtons) +{ + centreWithSize (500, 400); + setVisible (true); +} + +WINDOWCLASS::~WINDOWCLASS() +{ +} + +void WINDOWCLASS::closeButtonPressed() +{ + JUCEApplication::getInstance()->systemRequestedQuit(); +} diff --git a/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.h new file mode 100644 index 0000000000..5c0e0e74ac --- /dev/null +++ b/extras/Jucer (experimental)/Source/templates/jucer_WindowTemplate.h @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file was auto-generated by the Jucer! + + It contains the basic outline for a simple desktop window. + + ============================================================================== +*/ + +#ifndef HEADERGUARD +#define HEADERGUARD + +INCLUDES + + +//============================================================================== +class WINDOWCLASS : public DocumentWindow +{ +public: + //============================================================================== + WINDOWCLASS(); + ~WINDOWCLASS(); + + void closeButtonPressed(); + + + /* Note: Be careful when overriding DocumentWindow methods - the base class + uses a lot of them, so by overriding you might break its functionality. + It's best to do all your work in you content component instead, but if + you really have to override any DocumentWindow methods, make sure your + implementation calls the superclass's method. + */ + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + WINDOWCLASS (const WINDOWCLASS&); + WINDOWCLASS& operator= (const WINDOWCLASS&); +}; + + +#endif // HEADERGUARD diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp new file mode 100644 index 0000000000..4585a55d6d --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp @@ -0,0 +1,222 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../../jucer_Headers.h" +#include "jucer_DrawableObjectComponent.h" +#include "jucer_DrawableEditor.h" +#include "../jucer_JucerTreeViewBase.h" +#include "jucer_DrawableTreeViewItem.h" + + +//============================================================================== +class RightHandPanel : public Component +{ +public: + RightHandPanel (DrawableEditor& editor_) + : editor (editor_) + { + setOpaque (true); + + addAndMakeVisible (tree = new TreeView()); + tree->setRootItemVisible (true); + tree->setMultiSelectEnabled (true); + tree->setDefaultOpenness (true); + tree->setColour (TreeView::backgroundColourId, Colours::white); + tree->setIndentSize (15); + tree->setRootItem (DrawableTreeViewItem::createItemForNode (editor, editor.getDocument().getRootDrawableNode())); + } + + ~RightHandPanel() + { + tree->deleteRootItem(); + deleteAllChildren(); + } + + void paint (Graphics& g) + { + g.fillAll (Colour::greyLevel (0.92f)); + } + + void resized() + { + tree->setSize (getWidth(), getHeight()); + } + +private: + DrawableEditor& editor; + TreeView* tree; +}; + +//============================================================================== +DrawableEditor::DrawableEditor (OpenDocumentManager::Document* document, + Project* project_, + DrawableDocument* drawableDocument_) + : DocumentEditorComponent (document), + project (project_), + drawableDocument (drawableDocument_) +{ + jassert (drawableDocument_ != 0); + + setOpaque (true); + + addAndMakeVisible (rightHandPanel = new RightHandPanel (*this)); + + Canvas* canvas = new Canvas (*this); + addAndMakeVisible (viewport = new Viewport()); + viewport->setViewedComponent (canvas); + canvas->createRootObject(); +} + +DrawableEditor::~DrawableEditor() +{ + deleteAllChildren(); +} + +int64 DrawableEditor::getHashForNode (const ValueTree& node) +{ + return node ["id"].toString().hashCode64(); +} + +void DrawableEditor::paint (Graphics& g) +{ + g.fillAll (Colours::white); +} + +void DrawableEditor::resized() +{ + rightHandPanel->setBounds (getWidth() - 200, 0, 200, getHeight()); + viewport->setBounds (0, 0, rightHandPanel->getX(), getHeight()); + getCanvas()->updateSize(); +} + +//============================================================================== +DrawableEditor::Canvas::Canvas (DrawableEditor& editor_) + : editor (editor_), border (40) +{ + origin.setXY (50, 50); +} + +DrawableEditor::Canvas::~Canvas() +{ + rootObject = 0; +} + +void DrawableEditor::Canvas::createRootObject() +{ + addAndMakeVisible (rootObject = DrawableObjectComponent::create (editor.getDocument().getRootDrawableNode(), + editor, 0)); + rootObject->drawableOriginRelativeToParentTopLeft = origin; + rootObject->reloadFromValueTree(); +} + +void DrawableEditor::Canvas::paint (Graphics& g) +{ +/* g.setColour (Colours::lightgrey); + + g.fillRect (0, border.getTop() - 1, getWidth(), 1); + g.fillRect (0, getHeight() - border.getBottom(), getWidth(), 1); + g.fillRect (border.getLeft() - 1, 0, 1, getHeight()); + g.fillRect (getWidth() - border.getRight(), 0, 1, getHeight());*/ + + g.setColour (Colours::grey); + g.fillRect (0, origin.getY(), getWidth(), 1); + g.fillRect (origin.getX(), 0, 1, getHeight()); +} + +void DrawableEditor::Canvas::mouseDown (const MouseEvent& e) +{ + lasso = 0; + + if (e.mods.isPopupMenu()) + { + PopupMenu m; + m.addItem (1, "New Rectangle"); + m.addItem (2, "New Circle"); + + switch (m.show()) + { + case 1: + editor.getDocument().addRectangle(); + break; + + case 2: + editor.getDocument().addCircle(); + break; + + default: + break; + } + } + else + { + addAndMakeVisible (lasso = new LassoComponent ()); + lasso->beginLasso (e, this); + } +} + +void DrawableEditor::Canvas::mouseDrag (const MouseEvent& e) +{ + if (lasso != 0) + lasso->dragLasso (e); +} + +void DrawableEditor::Canvas::mouseUp (const MouseEvent& e) +{ + if (lasso != 0) + { + lasso->endLasso(); + lasso = 0; + } +} + +void DrawableEditor::Canvas::findLassoItemsInArea (Array & itemsFound, int x, int y, int width, int height) +{ + for (int i = getNumChildComponents(); --i >= 0;) + { + DrawableObjectComponent* d = dynamic_cast (getChildComponent(i)); + + if (d != 0) + d->findLassoItemsInArea (itemsFound, Rectangle (x, y, width, height)); + } +} + +SelectedItemSet & DrawableEditor::Canvas::getLassoSelection() +{ + return editor.selectedItems; +} + +void DrawableEditor::Canvas::updateSize() +{ + Rectangle r (rootObject->getBounds()); + + setSize (jmax (editor.viewport->getMaximumVisibleWidth(), r.getRight()), + jmax (editor.viewport->getMaximumVisibleHeight(), r.getBottom())); +} + +void DrawableEditor::Canvas::childBoundsChanged (Component* child) +{ + if (child == rootObject) + updateSize(); +} diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h new file mode 100644 index 0000000000..e073375eae --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h @@ -0,0 +1,97 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DRAWABLEEDITOR_JUCEHEADER__ +#define __JUCER_DRAWABLEEDITOR_JUCEHEADER__ + +#include "../jucer_DocumentEditorComponent.h" +class DrawableObjectComponent; + + +//============================================================================== +/** +*/ +class DrawableEditor : public DocumentEditorComponent +{ +public: + //============================================================================== + DrawableEditor (OpenDocumentManager::Document* document, + Project* project, + DrawableDocument* drawableDocument); + ~DrawableEditor(); + + void paint (Graphics& g); + void resized(); + + DrawableDocument& getDocument() const { return *drawableDocument; } + + static int64 getHashForNode (const ValueTree& node); + + //============================================================================== + class Canvas : public Component, + public LassoSource + { + public: + Canvas (DrawableEditor& editor_); + ~Canvas(); + + void createRootObject(); + const Point getOrigin() const throw() { return origin; } + + void paint (Graphics& g); + void mouseDown (const MouseEvent& e); + void mouseDrag (const MouseEvent& e); + void mouseUp (const MouseEvent& e); + void childBoundsChanged (Component* child); + void updateSize(); + + void findLassoItemsInArea (Array & itemsFound, int x, int y, int width, int height); + SelectedItemSet & getLassoSelection(); + + private: + DrawableEditor& editor; + ScopedPointer rootObject; + ScopedPointer > lasso; + BorderSize border; + Point origin; + }; + + Canvas* getCanvas() const { return (Canvas*) viewport->getViewedComponent(); } + + SelectedItemSet selectedItems; + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + Project* project; + DrawableDocument* drawableDocument; + + Viewport* viewport; + Component* rightHandPanel; +}; + + +#endif // __JUCER_DRAWABLEEDITOR_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableObjectComponent.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableObjectComponent.h new file mode 100644 index 0000000000..fe3ed5ea8c --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableObjectComponent.h @@ -0,0 +1,321 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__ +#define __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__ + +#include "jucer_DrawableEditor.h" + + +//============================================================================== +class DrawableObjectComponent : public Component, + public ValueTree::Listener, + public ChangeListener +{ +public: + DrawableObjectComponent (const ValueTree& drawableNode_, + DrawableEditor& editor_, + Drawable* drawable_) + : drawable (drawable_), + drawableNode (drawableNode_), + editor (editor_) + { + setVisible (true); + + nodeHashCode = DrawableEditor::getHashForNode (drawableNode); + + drawableNode.addListener (this); + editor.selectedItems.addChangeListener (this); + } + + ~DrawableObjectComponent() + { + deleteAllChildren(); + editor.selectedItems.removeChangeListener (this); + drawableNode.removeListener (this); + drawable = 0; + } + + static DrawableObjectComponent* create (const ValueTree& node, DrawableEditor& editor, Drawable* drawable_); + + //============================================================================== + void paint (Graphics& g) + { + //g.setColour (Colours::pink.withAlpha (0.2f)); + //g.fillRect (0, 0, getWidth(), getHeight()); + + if (isSelected()) + { + g.setColour (Colours::red); + g.drawRect (0, 0, getWidth(), getHeight(), 2); + } + + const Point offset (getDrawableOriginRelativeToTopLeft()); + g.setOrigin (offset.getX(), offset.getY()); + drawable->draw (g, 1.0f, transform); + } + + const Point getDrawableOriginRelativeToTopLeft() const + { + return drawableOriginRelativeToParentTopLeft - getPosition(); + } + + void findLassoItemsInArea (Array & itemsFound, Rectangle r) const + { + if (getBounds().intersects (r)) + itemsFound.add (nodeHashCode); + + r.translate (-getX(), -getY()); + + for (int i = getNumChildComponents(); --i >= 0;) + { + DrawableObjectComponent* d = dynamic_cast (getChildComponent(i)); + + if (d != 0) + d->findLassoItemsInArea (itemsFound, r); + } + } + + bool isSelected() const + { + return editor.selectedItems.isSelected (nodeHashCode); + } + + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) + { + if (tree == drawableNode) + { + editor.getDocument().changed(); + reloadFromValueTree(); + repaint(); + } + } + + void valueTreeChildrenChanged (ValueTree& tree) + { + if (tree == drawableNode) + { + editor.getDocument().changed(); + reloadFromValueTree(); + repaint(); + } + } + + void valueTreeParentChanged (ValueTree& tree) + { + editor.getDocument().changed(); + reloadFromValueTree(); + repaint(); + } + + void changeListenerCallback (void*) + { + repaint(); + } + + //============================================================================== + virtual void reloadFromValueTree() = 0; + + void commitModifiedPath() + { + drawableNode = drawable->createValueTree(); + } + + //============================================================================== + AffineTransform transform; + ScopedPointer drawable; + ValueTree drawableNode; + int64 nodeHashCode; + DrawableEditor& editor; + Point drawableOriginRelativeToParentTopLeft; +}; + +//============================================================================== +class PathDrawableComponent : public DrawableObjectComponent +{ +public: + PathDrawableComponent (const ValueTree& drawableNode_, + DrawableEditor& editor_, + DrawablePath* drawable_) + : DrawableObjectComponent (drawableNode_, editor_, drawable_) + { + } + + ~PathDrawableComponent() + { + } + + // Relative to the drawable's origin, not the parent component or any other comp. + const Rectangle getBoundsRectangle() + { + if (drawable == 0) + reloadFromValueTree(); + + return drawable->getBounds().getSmallestIntegerContainer().expanded (2, 2); + } + + bool hitTest (int x, int y) + { + const Point offset (getDrawableOriginRelativeToTopLeft()); + + return drawable->hitTest ((float) x - offset.getX(), + (float) y - offset.getY()); + } + + void mouseDown (const MouseEvent& e) + { + mouseDownSelectResult = editor.selectedItems.addToSelectionOnMouseDown (nodeHashCode, e.mods); + pathBoundsOnMouseDown = getPath()->getPath().getBounds(); + } + + void mouseDrag (const MouseEvent& e) + { + } + + void mouseUp (const MouseEvent& e) + { + editor.selectedItems.addToSelectionOnMouseUp (nodeHashCode, e.mods, + ! e.mouseWasClicked(), + mouseDownSelectResult); + } + + void reloadFromValueTree() + { + drawable = Drawable::createFromValueTree (drawableNode); + jassert (dynamic_cast ((Drawable*) drawable) != 0); + + setBounds (getBoundsRectangle().translated (drawableOriginRelativeToParentTopLeft.getX(), + drawableOriginRelativeToParentTopLeft.getY())); + } + +private: + bool mouseDownSelectResult; + Rectangle pathBoundsOnMouseDown; + + DrawablePath* getPath() const + { + return dynamic_cast ((Drawable*) drawable); + } +}; + +//============================================================================== +class CompositeDrawableComponent : public DrawableObjectComponent +{ +public: + CompositeDrawableComponent (const ValueTree& drawableNode_, + DrawableEditor& editor_, + DrawableComposite* drawable_) + : DrawableObjectComponent (drawableNode_, editor_, drawable_) + { + } + + ~CompositeDrawableComponent() + { + } + + void reloadFromValueTree() + { + drawable = Drawable::createFromValueTree (drawableNode); + + DrawableComposite* dc = dynamic_cast ((Drawable*) drawable); + jassert (dc != 0); + + deleteAllChildren(); + Rectangle childBounds; + + for (int i = 0; i < dc->getNumDrawables(); ++i) + { + Drawable* d = dc->getDrawable (i); + jassert (d != 0); + + DrawableObjectComponent* c = DrawableObjectComponent::create (drawableNode.getChild(i), editor, d); + + if (c != 0) + { + addChildComponent (c); + + const AffineTransform* t = dc->getDrawableTransform (i); + if (t != 0) + c->transform = *t; + + c->drawableOriginRelativeToParentTopLeft = drawableOriginRelativeToParentTopLeft; + c->reloadFromValueTree(); + + if (childBounds.isEmpty()) + childBounds = c->getBounds(); + else + childBounds = childBounds.getUnion (c->getBounds()); + } + } + + for (int i = dc->getNumDrawables(); --i >= 0;) + dc->removeDrawable (i, false); + + setBounds (childBounds); + + for (int i = getNumChildComponents(); --i >= 0;) + { + DrawableObjectComponent* dc = dynamic_cast (getChildComponent (i)); + + if (dc != 0) + { + dc->setTopLeftPosition (dc->getX() - getX(), dc->getY() - getY()); + dc->drawableOriginRelativeToParentTopLeft = drawableOriginRelativeToParentTopLeft - getPosition(); + } + } + } +}; + +//============================================================================== +DrawableObjectComponent* DrawableObjectComponent::create (const ValueTree& node, DrawableEditor& editor, Drawable* drawable_) +{ + ScopedPointer drawable (drawable_); + + if (drawable == 0) + drawable = Drawable::createFromValueTree (node); + + DrawablePath* p = dynamic_cast ((Drawable*) drawable); + + if (p != 0) + { + drawable.release(); + return new PathDrawableComponent (node, editor, p); + } + + DrawableComposite* dc = dynamic_cast ((Drawable*) drawable); + + if (dc != 0) + { + drawable.release(); + return new CompositeDrawableComponent (node, editor, dc); + } + + jassertfalse + return 0; +} + + +#endif // __JUCER_DRAWABLEOBJECTCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableTreeviewItem.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableTreeviewItem.h new file mode 100644 index 0000000000..2de885e01c --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableTreeviewItem.h @@ -0,0 +1,246 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DRAWABLETREEVIEWITEM_JUCEHEADER__ +#define __JUCER_DRAWABLETREEVIEWITEM_JUCEHEADER__ + +#include "../jucer_DocumentEditorComponent.h" +#include "../../model/jucer_DrawableDocument.h" + + +//============================================================================== +/** +*/ +class DrawableTreeViewItem : public JucerTreeViewBase, + public ValueTree::Listener, + public ChangeListener +{ + DrawableTreeViewItem (DrawableEditor& editor_, const ValueTree& drawableRoot, const String& typeName_) + : editor (editor_), node (drawableRoot), typeName (typeName_) + { + node.addListener (this); + editor.selectedItems.addChangeListener (this); + } + +public: + static DrawableTreeViewItem* createItemForNode (DrawableEditor& editor, const ValueTree& drawableRoot) + { + const char* typeName = 0; + + { + ScopedPointer d (Drawable::createFromValueTree (drawableRoot)); + + if (d != 0) + { + if (dynamic_cast ((Drawable*) d) != 0) + typeName = "Path"; + else if (dynamic_cast ((Drawable*) d) != 0) + typeName = "Image"; + else if (dynamic_cast ((Drawable*) d) != 0) + typeName = "Group"; + else if (dynamic_cast ((Drawable*) d) != 0) + typeName = "Text"; + else + { + jassertfalse + } + } + } + + if (typeName != 0) + return new DrawableTreeViewItem (editor, drawableRoot, typeName); + + return 0; + } + + ~DrawableTreeViewItem() + { + editor.selectedItems.removeChangeListener (this); + node.removeListener (this); + } + + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) + { + } + + void valueTreeChildrenChanged (ValueTree& tree) + { + if (tree == node) + refreshSubItems(); + } + + void valueTreeParentChanged (ValueTree& tree) + { + } + + //============================================================================== + // TreeViewItem stuff.. + bool mightContainSubItems() + { + return node.getNumChildren() > 0; + } + + const String getUniqueName() const + { + jassert (node ["id"].toString().isNotEmpty()); + return node ["id"]; + } + + void itemOpennessChanged (bool isNowOpen) + { + if (isNowOpen) + refreshSubItems(); + } + + void refreshSubItems() + { + ScopedPointer openness (getOpennessState()); + + clearSubItems(); + + for (int i = 0; i < node.getNumChildren(); ++i) + { + ValueTree subNode (node.getChild (i)); + DrawableTreeViewItem* const item = createItemForNode (editor, subNode); + + if (item != 0) + addSubItem (item); + } + + if (openness != 0) + restoreOpennessState (*openness); + + editor.selectedItems.changed(); + } + + const String getDisplayName() const + { + const String name (getRenamingName()); + return typeName + (name.isEmpty() ? String::empty + : (" \"" + name + "\"")); + } + + const String getRenamingName() const + { + return node ["name"]; + } + + void setName (const String& newName) + { + } + + bool isMissing() { return false; } + + Image* getIcon() const + { + return LookAndFeel::getDefaultLookAndFeel().getDefaultDocumentFileImage(); + } + + void itemClicked (const MouseEvent& e) + { + } + + void itemDoubleClicked (const MouseEvent& e) + { + } + + void itemSelectionChanged (bool isNowSelected) + { + DrawableEditor* ed = getEditor(); + jassert (ed != 0); + + if (ed != 0) + { + const int64 hash = DrawableEditor::getHashForNode (node); + + if (isNowSelected) + ed->selectedItems.addToSelection (hash); + else + ed->selectedItems.deselect (hash); + } + } + + void changeListenerCallback (void*) + { + setSelected (editor.selectedItems.isSelected (DrawableEditor::getHashForNode (node)), false); + } + + const String getTooltip() + { + return String::empty; + } + + const String getDragSourceDescription() + { + return drawableItemDragType; + } + + //============================================================================== + // Drag-and-drop stuff.. + bool isInterestedInFileDrag (const StringArray& files) + { + return false; + } + + void filesDropped (const StringArray& files, int insertIndex) + { + } + + bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent) + { + return false; + } + + void itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex) + { + } + + //============================================================================== + void showRenameBox() + { + } + + // Text editor listener for renaming.. + void textEditorTextChanged (TextEditor& editor) {} + void textEditorReturnKeyPressed (TextEditor& editor) { editor.exitModalState (1); } + void textEditorEscapeKeyPressed (TextEditor& editor) { editor.exitModalState (0); } + void textEditorFocusLost (TextEditor& editor) { editor.exitModalState (0); } + + //============================================================================== + DrawableEditor& editor; + ValueTree node; + +private: + String typeName; + + DrawableEditor* getEditor() const + { + return getOwnerView()->findParentComponentOfClass ((DrawableEditor*) 0); + } +}; + + +#endif // __JUCER_DRAWABLETREEVIEWITEM_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_CommandIDs.h b/extras/Jucer (experimental)/Source/ui/jucer_CommandIDs.h new file mode 100644 index 0000000000..b087cd880a --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_CommandIDs.h @@ -0,0 +1,88 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +/** + A namespace to hold all the possible command IDs. +*/ +namespace CommandIDs +{ + static const int newProject = 0x200010; + static const int open = 0x200020; + static const int closeDocument = 0x200030; + static const int saveDocument = 0x200040; + static const int saveDocumentAs = 0x200050; + + static const int closeProject = 0x200051; + static const int saveProject = 0x200060; + static const int saveProjectAs = 0x200070; + static const int openProjectInIDE = 0x200071; + static const int showProjectSettings = 0x200072; + + static const int saveAll = 0x200080; + static const int undo = 0x200090; + static const int redo = 0x2000a0; + + static const int closeAllDocuments = 0x201000; + + static const int test = 0x202090; + static const int toFront = 0x2020a0; + static const int toBack = 0x2030b0; + + static const int group = 0x202170; + static const int ungroup = 0x202180; + + static const int showPrefs = 0x2020c0; + static const int useTabbedWindows = 0x2020d0; + + static const int showGrid = 0x2020e0; + static const int enableSnapToGrid = 0x2020f0; + + static const int editCompLayout = 0x202100; + static const int editCompGraphics = 0x202110; + + static const int bringBackLostItems = 0x202120; + + static const int zoomIn = 0x202130; + static const int zoomOut = 0x202140; + static const int zoomNormal = 0x202150; + static const int spaceBarDrag = 0x202160; + + static const int compOverlay0 = 0x202200; + static const int compOverlay33 = 0x202210; + static const int compOverlay66 = 0x202220; + static const int compOverlay100 = 0x202230; + + static const int newDocumentBase = 0x322010; + static const int newComponentBase = 0x302010; + static const int newElementBase = 0x312010; +} + +namespace CommandCategories +{ + static const tchar* const general = T("General"); + static const tchar* const editing = T("Editing"); + static const tchar* const view = T("View"); + static const tchar* const windows = T("Windows"); +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.cpp b/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.cpp new file mode 100644 index 0000000000..1000bd8043 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.cpp @@ -0,0 +1,129 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_DocumentEditorComponent.h" +#include "jucer_ProjectContentComponent.h" + + +//============================================================================== +DocumentEditorComponent::DocumentEditorComponent (OpenDocumentManager::Document* document_) + : document (document_) +{ + OpenDocumentManager::getInstance()->registerEditor (this); +} + +DocumentEditorComponent::~DocumentEditorComponent() +{ + OpenDocumentManager::getInstance()->deregisterEditor (this); +} + +void DocumentEditorComponent::deleteSelf() +{ + jassert (document != 0); + + ProjectContentComponent* pcc = findParentComponentOfClass ((ProjectContentComponent*) 0); + + if (pcc != 0) + { + pcc->hideDocument (document); + return; + } + + jassertfalse +} + +ApplicationCommandTarget* DocumentEditorComponent::getNextCommandTarget() +{ + return findFirstTargetParentComponent(); +} + +void DocumentEditorComponent::getAllCommands (Array & commands) +{ + const CommandID ids[] = { CommandIDs::saveDocument, + CommandIDs::saveDocumentAs, + CommandIDs::closeDocument }; + + commands.addArray (ids, numElementsInArray (ids)); +} + +void DocumentEditorComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) +{ + result.setActive (document != 0); + String name; + + if (document != 0) + name = " '" + document->getName().substring (0, 32) + "'"; + + switch (commandID) + { + case CommandIDs::saveDocument: + result.setInfo ("Save" + name, + "Saves the current document", + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::saveDocumentAs: + result.setInfo ("Save" + name + " As...", + "Saves the current document to a different filename", + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); + break; + + case CommandIDs::closeDocument: + result.setInfo ("Close" + name, + "Closes the current document", + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T('w'), ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); + break; + + default: + break; + } +} + +bool DocumentEditorComponent::perform (const InvocationInfo& info) +{ + switch (info.commandID) + { + case CommandIDs::saveDocument: + document->save(); + return true; + + case CommandIDs::saveDocumentAs: + jassertfalse //xxxx + //document.save(); + return true; + + case CommandIDs::closeDocument: + OpenDocumentManager::getInstance()->closeDocument (document, true); + return true; + + default: + break; + } + + return false; +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.h b/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.h new file mode 100644 index 0000000000..061ca9a3fe --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_DocumentEditorComponent.h @@ -0,0 +1,60 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DOCUMENTEDITORCOMPONENT_JUCEHEADER__ +#define __JUCER_DOCUMENTEDITORCOMPONENT_JUCEHEADER__ + +#include "jucer_OpenDocumentManager.h" + + +//============================================================================== +/** +*/ +class DocumentEditorComponent : public Component, + public ApplicationCommandTarget +{ +public: + //============================================================================== + DocumentEditorComponent (OpenDocumentManager::Document* document); + ~DocumentEditorComponent(); + + OpenDocumentManager::Document* getDocument() const { return document; } + virtual void deleteSelf(); + + //============================================================================== + ApplicationCommandTarget* getNextCommandTarget(); + void getAllCommands (Array & commands); + void getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result); + bool perform (const InvocationInfo& info); + + //============================================================================== + juce_UseDebuggingNewOperator + +protected: + OpenDocumentManager::Document* document; +}; + + +#endif // __JUCER_DOCUMENTEDITORCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.cpp b/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.cpp new file mode 100644 index 0000000000..62ff41186e --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.cpp @@ -0,0 +1,160 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_GroupInformationComponent.h" + + +//============================================================================== +GroupInformationComponent::GroupInformationComponent (const Project::Item& item_) + : item (item_) +{ + addAndMakeVisible (list = new ListBox (String::empty, this)); + list->updateContent(); + list->setRowHeight (20); + item.getNode().addListener (this); +} + +GroupInformationComponent::~GroupInformationComponent() +{ + item.getNode().removeListener (this); + deleteAllChildren(); +} + +void GroupInformationComponent::resized() +{ + list->setSize (getWidth(), getHeight()); +} + +int GroupInformationComponent::getNumRows() +{ + return item.getNumChildren(); +} + +void GroupInformationComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) +{ +} + +//============================================================================== +void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property) +{ + list->updateContent(); +} + +void GroupInformationComponent::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) +{ + list->updateContent(); +} + +void GroupInformationComponent::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) +{ + list->updateContent(); +} + +//============================================================================== +class FileOptionComponent : public Component +{ +public: + FileOptionComponent (const Project::Item& item_) + : item (item_), compileButton (0), resourceButton (0) + { + if (item.isFile()) + { + addAndMakeVisible (compileButton = new ToggleButton ("Compile")); + compileButton->getToggleStateValue().referTo (item.getShouldCompileValue()); + + addAndMakeVisible (resourceButton = new ToggleButton ("Add to Binary Resources")); + resourceButton->getToggleStateValue().referTo (item.getShouldAddToResourceValue()); + } + } + + ~FileOptionComponent() + { + deleteAllChildren(); + } + + void paint (Graphics& g) + { + int x = getHeight() + 6; + Image* icon = item.getIcon(); + + if (icon != 0) + { + g.drawImageWithin (icon, 2, 2, x - 4, getHeight() - 4, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, + false); + + ImageCache::release (icon); + } + + g.setColour (Colours::black); + g.setFont (getHeight() * 0.6f); + + const int x2 = compileButton == 0 ? getWidth() - 4 + : compileButton->getX() - 4; + + g.drawText (item.getName().toString(), x, 0, x2 - x, getHeight(), Justification::centredLeft, true); + + g.setColour (Colours::lightgrey); + g.fillRect (0, getHeight() - 1, getWidth(), 1); + } + + void resized() + { + if (resourceButton != 0) + { + int w = 180; + resourceButton->setBounds (getWidth() - w, 1, w, getHeight() - 2); + w = 100; + compileButton->setBounds (resourceButton->getX() - w, 1, w, getHeight() - 2); + } + } + + Project::Item item; + +private: + ToggleButton* compileButton; + ToggleButton* resourceButton; +}; + +Component* GroupInformationComponent::refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate) +{ + if (rowNumber < getNumRows()) + { + Project::Item child (item.getChild (rowNumber)); + + if (existingComponentToUpdate == 0 + || dynamic_cast (existingComponentToUpdate)->item != child) + { + delete existingComponentToUpdate; + existingComponentToUpdate = new FileOptionComponent (child); + } + } + else + { + deleteAndZero (existingComponentToUpdate); + } + + return existingComponentToUpdate; +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.h b/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.h new file mode 100644 index 0000000000..cf16163351 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_GroupInformationComponent.h @@ -0,0 +1,68 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_GROUPINFORMATIONCOMPONENT_JUCEHEADER__ +#define __JUCER_GROUPINFORMATIONCOMPONENT_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "../model/jucer_Project.h" + + +//============================================================================== +class GroupInformationComponent : public Component, + private ListBoxModel, + private ValueTree::Listener +{ +public: + //============================================================================== + GroupInformationComponent (const Project::Item& item_); + ~GroupInformationComponent(); + + //============================================================================== + void resized(); + + int getNumRows(); + void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); + Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); + + //============================================================================== + void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property); + void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged); + void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + Project::Item item; + ListBox* list; + + //============================================================================== + GroupInformationComponent (const GroupInformationComponent&); + const GroupInformationComponent& operator= (const GroupInformationComponent&); +}; + + +#endif // __JUCER_GROUPINFORMATIONCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.cpp b/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.cpp new file mode 100644 index 0000000000..58d5a53765 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.cpp @@ -0,0 +1,93 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "jucer_ItemPreviewComponent.h" + + +//============================================================================== +ItemPreviewComponent::ItemPreviewComponent (const File& file_) + : file (file_) +{ + facts.add (file.getFullPathName()); + tryToLoadImage (file.createInputStream()); + facts.removeEmptyStrings (true); +} + +ItemPreviewComponent::ItemPreviewComponent (InputStream* input, const String& name) +{ + facts.add (name); + tryToLoadImage (input); + facts.removeEmptyStrings (true); +} + +ItemPreviewComponent::~ItemPreviewComponent() +{ +} + +void ItemPreviewComponent::tryToLoadImage (InputStream* in) +{ + if (in != 0) + { + ScopedPointer input (in); + + ImageFileFormat* format = ImageFileFormat::findImageFormatForStream (*input); + + String formatName; + if (format != 0) + formatName = " " + format->getFormatName(); + + image = ImageFileFormat::loadFrom (*input); + + if (image != 0) + facts.add (String (image->getWidth()) + " x " + String (image->getHeight()) + formatName); + + const int64 totalSize = input->getTotalLength(); + + if (totalSize > 0) + facts.add (File::descriptionOfSizeInBytes (totalSize)); + } +} + +void ItemPreviewComponent::paint (Graphics& g) +{ + if (image != 0) + { + g.drawImageWithin (image, + 2, 22, getWidth() - 4, getHeight() - 24, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, + false); + } + + g.setFont (15.0f, Font::bold); + g.setColour (Colours::white); + g.drawMultiLineText (facts.joinIntoString ("\n"), + 10, 15, getWidth() - 16); + +} + +void ItemPreviewComponent::resized() +{ +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.h b/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.h new file mode 100644 index 0000000000..648078b303 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ItemPreviewComponent.h @@ -0,0 +1,57 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_ITEMPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCER_ITEMPREVIEWCOMPONENT_JUCEHEADER__ + + +//============================================================================== +/** +*/ +class ItemPreviewComponent : public Component +{ +public: + //============================================================================== + // This will delete the stream + ItemPreviewComponent (InputStream* input, const String& name); + ItemPreviewComponent (const File& file); + ~ItemPreviewComponent(); + + void paint (Graphics& g); + void resized(); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + StringArray facts; + File file; + ScopedPointer image; + + void tryToLoadImage (InputStream* input); +}; + + +#endif // __JUCER_ITEMPREVIEWCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.cpp b/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.cpp new file mode 100644 index 0000000000..127444727b --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.cpp @@ -0,0 +1,104 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_JucerTreeViewBase.h" + + +//============================================================================== +JucerTreeViewBase::JucerTreeViewBase() +{ + setLinesDrawnForSubItems (false); +} + +JucerTreeViewBase::~JucerTreeViewBase() +{ +} + +const Font JucerTreeViewBase::getFont() const +{ + return Font (getItemHeight() * 0.6f); +} + +int JucerTreeViewBase::getTextX() const +{ + return getItemHeight() + 6; +} + +void JucerTreeViewBase::paintItem (Graphics& g, int width, int height) +{ + if (isSelected()) + g.fillAll (Colour (0x401111ee)); + + const int x = getTextX(); + + g.setColour (isMissing() ? Colours::red : Colours::black); + Image* icon = getIcon(); + + if (icon != 0) + { + g.drawImageWithin (icon, 2, 2, x - 4, height - 4, + RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, + false); + + ImageCache::release (icon); + } + + g.setFont (getFont()); + g.drawFittedText (getDisplayName(), x, 0, width - x, height, Justification::centredLeft, 1, 0.8f); +} + +void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver) +{ + Path p; + + if (isOpen()) + p.addTriangle (width * 0.2f, height * 0.25f, width * 0.8f, height * 0.25f, width * 0.5f, height * 0.75f); + else + p.addTriangle (width * 0.25f, height * 0.25f, width * 0.8f, height * 0.5f, width * 0.25f, height * 0.75f); + + g.setColour (Colours::lightgrey); + g.fillPath (p); +} + +//============================================================================== +void JucerTreeViewBase::showRenameBox() +{ + TextEditor ed (String::empty); + ed.setMultiLine (false, false); + ed.setPopupMenuEnabled (false); + ed.setSelectAllWhenFocused (true); + ed.setFont (getFont()); + ed.addListener (this); + ed.setText (getRenamingName()); + + Rectangle r (getItemPosition (true)); + r.setLeft (r.getX() + getTextX()); + r.setHeight (getItemHeight()); + ed.setBounds (r); + getOwnerView()->addAndMakeVisible (&ed); + + if (ed.runModalLoop() != 0) + setName (ed.getText()); +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.h b/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.h new file mode 100644 index 0000000000..775e655cf3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_JucerTreeViewBase.h @@ -0,0 +1,72 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__ +#define __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__ + +#include "../jucer_Headers.h" + + +//============================================================================== +class JucerTreeViewBase : public TreeViewItem, + public TextEditorListener +{ +protected: + //============================================================================== + JucerTreeViewBase(); + ~JucerTreeViewBase(); + +public: + //============================================================================== + int getItemWidth() const { return -1; } + int getItemHeight() const { return 20; } + Component* createItemComponent() { return 0; } + + void paintItem (Graphics& g, int width, int height); + void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver); + + //============================================================================== + virtual const String getRenamingName() const = 0; + virtual const String getDisplayName() const = 0; + virtual void setName (const String& newName) = 0; + virtual bool isMissing() = 0; + virtual Image* getIcon() const = 0; + + void showRenameBox(); + + // Text editor listener for renaming.. + void textEditorTextChanged (TextEditor& editor) {} + void textEditorReturnKeyPressed (TextEditor& editor) { editor.exitModalState (1); } + void textEditorEscapeKeyPressed (TextEditor& editor) { editor.exitModalState (0); } + void textEditorFocusLost (TextEditor& editor) { editor.exitModalState (0); } + + //============================================================================== +private: + const Font getFont() const; + int getTextX() const; +}; + + +#endif // __JUCER_JUCERTREEVIEWBASE_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.cpp b/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.cpp new file mode 100644 index 0000000000..678fe26811 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.cpp @@ -0,0 +1,486 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "jucer_MainWindow.h" +#include "jucer_OpenDocumentManager.h" +#include "jucer_SourceCodeEditor.h" +#include "../model/jucer_ProjectWizard.h" + + +//============================================================================== +MainWindow::MainWindow() + : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), + Colour::greyLevel (0.6f), + DocumentWindow::allButtons) +{ + setUsingNativeTitleBar (true); + setContentComponent (new ProjectContentComponent()); + + setApplicationCommandManagerToWatch (commandManager); + +#if JUCE_MAC + setMacMainMenu (this); +#else + setMenuBar (this); +#endif + + setResizable (true, false); + + centreWithSize (700, 600); + + // restore the last size and position from our settings file.. + restoreWindowStateFromString (StoredSettings::getInstance()->getProps() + .getValue ("lastMainWindowPos")); + + // Register all the app commands.. + { + commandManager->registerAllCommandsForTarget (JUCEApplication::getInstance()); + commandManager->registerAllCommandsForTarget (this); + + // use a temporary one of these to harvest its commands.. + ProjectContentComponent pcc; + commandManager->registerAllCommandsForTarget (&pcc); + + DocumentEditorComponent dec (0); + commandManager->registerAllCommandsForTarget (&dec); + } + + commandManager->getKeyMappings()->resetToDefaultMappings(); + + ScopedPointer keys (StoredSettings::getInstance()->getProps().getXmlValue ("keyMappings")); + + if (keys != 0) + commandManager->getKeyMappings()->restoreFromXml (*keys); + + addKeyListener (commandManager->getKeyMappings()); + + // don't want the window to take focus when the title-bar is clicked.. + setWantsKeyboardFocus (false); + + //getPeer()->setCurrentRenderingEngine (0); +} + +MainWindow::~MainWindow() +{ +#if JUCE_MAC + setMacMainMenu (0); +#else + setMenuBar (0); +#endif + + removeKeyListener (commandManager->getKeyMappings()); + + // save the current size and position to our settings file.. + StoredSettings::getInstance()->getProps() + .setValue ("lastMainWindowPos", getWindowStateAsString()); + + setContentComponent (0); + currentProject = 0; +} + +ProjectContentComponent* MainWindow::getProjectContentComponent() const +{ + return dynamic_cast (getContentComponent()); +} + +void MainWindow::closeButtonPressed() +{ + JUCEApplication::getInstance()->systemRequestedQuit(); +} + +bool MainWindow::closeProject (Project* project) +{ + jassert (project == currentProject && project != 0); + + if (project == 0) + return true; + + if (! OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*project, true)) + return false; + + FileBasedDocument::SaveResult r = project->saveIfNeededAndUserAgrees(); + + if (r == FileBasedDocument::savedOk) + { + setProject (0); + return true; + } + + return false; +} + +bool MainWindow::closeCurrentProject() +{ + return currentProject == 0 || closeProject (currentProject); +} + +bool MainWindow::closeAllDocuments (bool askUserToSave) +{ + for (int i = OpenDocumentManager::getInstance()->getNumOpenDocuments(); --i >= 0;) + { + OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument (i); + getProjectContentComponent()->hideDocument (doc); + + if (! OpenDocumentManager::getInstance()->closeDocument (i, askUserToSave)) + return false; + } + + return true; +} + +void MainWindow::setProject (Project* newProject) +{ + if (newProject != 0) + StoredSettings::getInstance()->setLastProject (newProject->getFile()); + + getProjectContentComponent()->setProject (newProject); + currentProject = newProject; + commandManager->commandStatusChanged(); +} + +void MainWindow::reloadLastProject() +{ + openFile (StoredSettings::getInstance()->getLastProject()); +} + +void MainWindow::askUserToOpenFile() +{ + FileChooser fc ("Open File"); + + if (fc.browseForFileToOpen()) + openFile (fc.getResult()); +} + +bool MainWindow::canOpenFile (const File& file) const +{ + return file.hasFileExtension (Project::projectFileExtension) + || OpenDocumentManager::getInstance()->canOpenFile (file); +} + +bool MainWindow::openFile (const File& file) +{ + if (file.hasFileExtension (Project::projectFileExtension)) + { + ScopedPointer newDoc (new Project (file)); + + if (file == File::nonexistent ? newDoc->loadFromUserSpecifiedFile (true) + : newDoc->loadFrom (file, true)) + { + if (closeCurrentProject()) + { + setProject (newDoc.release()); + return true; + } + } + } + else if (file.exists()) + { + return getProjectContentComponent()->showEditorForFile (file); + } + + return false; +} + +void MainWindow::createNewProject() +{ + ScopedPointer newProj (ProjectWizard::runNewProjectWizard (this)); + + if (newProj != 0 && closeCurrentProject()) + setProject (newProj.release()); +} + +bool MainWindow::isInterestedInFileDrag (const StringArray& filenames) +{ + for (int i = filenames.size(); --i >= 0;) + if (canOpenFile (filenames[i])) + return true; + + return false; +} + +void MainWindow::filesDropped (const StringArray& filenames, int mouseX, int mouseY) +{ + for (int i = filenames.size(); --i >= 0;) + { + const File f (filenames[i]); + + if (canOpenFile (f) && openFile (f)) + break; + } +} + +void MainWindow::activeWindowStatusChanged() +{ + DocumentWindow::activeWindowStatusChanged(); + + if (getProjectContentComponent() != 0) + getProjectContentComponent()->updateMissingFileStatuses(); + + OpenDocumentManager::getInstance()->reloadModifiedFiles(); +} + +void MainWindow::updateTitle (const String& documentName) +{ + String name (JUCEApplication::getInstance()->getApplicationName()); + if (documentName.isNotEmpty()) + name = documentName + " - " + name; + + setName (name); +} + +//============================================================================== +const StringArray MainWindow::getMenuBarNames() +{ + const char* const names[] = { "File", "Edit", "View", "Window", 0 }; + return StringArray ((const char**) names); +} + +const PopupMenu MainWindow::getMenuForIndex (int topLevelMenuIndex, + const String& menuName) +{ + PopupMenu menu; + + if (topLevelMenuIndex == 0) + { + // "File" menu + + menu.addCommandItem (commandManager, CommandIDs::newProject); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::open); + + PopupMenu recentFiles; + StoredSettings::getInstance()->recentFiles.createPopupMenuItems (recentFiles, 100, true, true); + menu.addSubMenu (T("Open recent file"), recentFiles); + + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::closeDocument); + menu.addCommandItem (commandManager, CommandIDs::saveDocument); + menu.addCommandItem (commandManager, CommandIDs::saveDocumentAs); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::closeProject); + menu.addCommandItem (commandManager, CommandIDs::saveProject); + menu.addCommandItem (commandManager, CommandIDs::saveProjectAs); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::openProjectInIDE); + +#if ! JUCE_MAC + menu.addSeparator(); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit); +#endif + } + else if (topLevelMenuIndex == 1) + { + // "Edit" menu + + menu.addCommandItem (commandManager, CommandIDs::undo); + menu.addCommandItem (commandManager, CommandIDs::redo); + menu.addSeparator(); + + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::cut); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::copy); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::paste); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::del); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::selectAll); + menu.addCommandItem (commandManager, StandardApplicationCommandIDs::deselectAll); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::toFront); + menu.addCommandItem (commandManager, CommandIDs::toBack); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::group); + menu.addCommandItem (commandManager, CommandIDs::ungroup); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::bringBackLostItems); + } + else if (topLevelMenuIndex == 2) + { + // "View" menu + + menu.addCommandItem (commandManager, CommandIDs::showProjectSettings); + + //menu.addCommandItem (commandManager, CommandIDs::test); + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::showGrid); + menu.addCommandItem (commandManager, CommandIDs::enableSnapToGrid); + + /* const int currentSnapSize = getActiveDocument() != 0 ? getActiveDocument()->getSnappingGridSize() : 0; + + PopupMenu m; + for (int i = 0; i < numElementsInArray (snapSizes); ++i) + m.addItem (300 + i, String (snapSizes[i]) + T(" pixels"), true, snapSizes[i] == currentSnapSize); + + menu.addSubMenu (T("Grid size"), m, getActiveDocument() != 0);*/ + + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::zoomIn); + menu.addCommandItem (commandManager, CommandIDs::zoomOut); + menu.addCommandItem (commandManager, CommandIDs::zoomNormal); + +/* menu.addSeparator(); + PopupMenu overlays; + overlays.addCommandItem (commandManager, CommandIDs::compOverlay0); + overlays.addCommandItem (commandManager, CommandIDs::compOverlay33); + overlays.addCommandItem (commandManager, CommandIDs::compOverlay66); + overlays.addCommandItem (commandManager, CommandIDs::compOverlay100); + menu.addSubMenu (T("Component Overlay"), overlays, + getActiveDocument() != 0 && getActiveDocument()->getComponentLayout() != 0);*/ + + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::useTabbedWindows); + //menu.addSeparator(); + //menu.addCommandItem (commandManager, CommandIDs::showPrefs); + } + else if (topLevelMenuIndex == 3) + { + // "Window" menu + + const int numDocs = jmin (50, OpenDocumentManager::getInstance()->getNumOpenDocuments()); + + for (int i = 0; i < numDocs; ++i) + { + OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument(i); + + menu.addItem (300 + i, doc->getName()); + } + + menu.addSeparator(); + menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments); + } + + return menu; +} + +void MainWindow::menuItemSelected (int menuItemID, + int topLevelMenuIndex) +{ + if (menuItemID >= 100 && menuItemID < 200) + { + // open a file from the "recent files" menu + const File file (StoredSettings::getInstance()->recentFiles.getFile (menuItemID - 100)); + + openFile (file); + } + else if (menuItemID == 201) + { + LookAndFeel::setDefaultLookAndFeel (0); + } + else if (menuItemID >= 300 && menuItemID < 400) + { + OpenDocumentManager::Document* doc = OpenDocumentManager::getInstance()->getOpenDocument (menuItemID - 300); + getProjectContentComponent()->showDocument (doc); + } +} + +//============================================================================== +ApplicationCommandTarget* MainWindow::getNextCommandTarget() +{ + return 0; +} + +void MainWindow::getAllCommands (Array & commands) +{ + const CommandID ids[] = { CommandIDs::newProject, + CommandIDs::open, + CommandIDs::showPrefs, + CommandIDs::closeAllDocuments, + CommandIDs::saveAll }; + + commands.addArray (ids, numElementsInArray (ids)); +} + +void MainWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) +{ + switch (commandID) + { + case CommandIDs::newProject: + result.setInfo (T("New Project..."), + T("Creates a new Jucer project"), + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T('o'), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::open: + result.setInfo (T("Open..."), + T("Opens a Jucer project"), + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T('o'), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::showPrefs: + result.setInfo (T("Preferences..."), + T("Shows the preferences panel."), + CommandCategories::general, 0); + result.defaultKeypresses.add (KeyPress (T(','), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::closeAllDocuments: + result.setInfo (T("Close All Documents"), + T("Closes all open documents"), + CommandCategories::general, 0); + result.setActive (OpenDocumentManager::getInstance()->getNumOpenDocuments() > 0); + break; + + case CommandIDs::saveAll: + result.setInfo (T("Save All"), + T("Saves all open documents"), + CommandCategories::general, 0); + result.setActive (OpenDocumentManager::getInstance()->anyFilesNeedSaving()); + break; + + default: + break; + } +} + +bool MainWindow::perform (const InvocationInfo& info) +{ + switch (info.commandID) + { + case CommandIDs::newProject: + createNewProject(); + break; + + case CommandIDs::open: + askUserToOpenFile(); + break; + + case CommandIDs::showPrefs: + // PrefsPanel::show(); + break; + + case CommandIDs::saveAll: + OpenDocumentManager::getInstance()->saveAll(); + break; + + case CommandIDs::closeAllDocuments: + closeAllDocuments (true); + break; + + default: + return false; + } + + return true; +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.h b/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.h new file mode 100644 index 0000000000..6094a30648 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_MainWindow.h @@ -0,0 +1,90 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_MAINWINDOW_JUCEHEADER__ +#define __JUCER_MAINWINDOW_JUCEHEADER__ + +#include "jucer_ProjectContentComponent.h" + + +//============================================================================== +/** + The big top-level window where everything happens. +*/ +class MainWindow : public DocumentWindow, + public MenuBarModel, + public ApplicationCommandTarget, + public FileDragAndDropTarget, + public DragAndDropContainer +{ +public: + //============================================================================== + MainWindow(); + ~MainWindow(); + + //============================================================================== + void closeButtonPressed(); + + //============================================================================== + void askUserToOpenFile(); + bool canOpenFile (const File& file) const; + bool openFile (const File& file); + void createNewProject(); + void setProject (Project* newProject); + void reloadLastProject(); + + bool closeProject (Project* project); + bool closeCurrentProject(); + bool closeAllDocuments (bool askUserToSave); + + bool isInterestedInFileDrag (const StringArray& files); + void filesDropped (const StringArray& filenames, int mouseX, int mouseY); + + void activeWindowStatusChanged(); + + void updateTitle (const String& documentName); + + //============================================================================== + const StringArray getMenuBarNames(); + const PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName); + void menuItemSelected (int menuItemID, int topLevelMenuIndex); + + //============================================================================== + ApplicationCommandTarget* getNextCommandTarget(); + void getAllCommands (Array & commands); + void getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result); + bool perform (const InvocationInfo& info); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + ScopedPointer currentProject; + + ProjectContentComponent* getProjectContentComponent() const; +}; + + +#endif // __JUCER_MAINWINDOW_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp new file mode 100644 index 0000000000..736c012bd4 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp @@ -0,0 +1,384 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_OpenDocumentManager.h" +#include "jucer_SourceCodeEditor.h" +#include "Drawable Editor/jucer_DrawableEditor.h" +#include "jucer_ItemPreviewComponent.h" + + +//============================================================================== +class SourceCodeDocument : public OpenDocumentManager::Document +{ +public: + SourceCodeDocument (const File& file_) + : modDetector (file_) + { + codeDoc = new CodeDocument(); + reloadFromFile(); + } + + ~SourceCodeDocument() + { + } + + bool loadedOk() const { return true; } + bool isForFile (const File& file) const { return modDetector.getFile() == file; } + bool isForNode (const ValueTree& node) const { return false; } + bool refersToProject (Project& project) const { return false; } + const String getName() const { return modDetector.getFile().getFileName(); } + const String getType() const { return modDetector.getFile().getFileExtension() + " file"; } + bool needsSaving() const { return codeDoc != 0 && codeDoc->hasChangedSinceSavePoint(); } + bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); } + + void reloadFromFile() + { + modDetector.updateHash(); + + ScopedPointer in (modDetector.getFile().createInputStream()); + + if (in != 0) + codeDoc->loadFromStream (*in); + } + + bool save() + { + TemporaryFile temp (modDetector.getFile()); + ScopedPointer out (temp.getFile().createOutputStream()); + + if (out == 0 || ! codeDoc->writeToStream (*out)) + return false; + + out = 0; + return temp.overwriteTargetFileWithTemporary(); + } + + Component* createEditor() + { + CodeTokeniser* tokeniser = 0; + + if (SourceCodeEditor::isCppFile (modDetector.getFile())) + tokeniser = &cppTokeniser; + + return new SourceCodeEditor (this, *codeDoc, tokeniser); + } + +private: + FileModificationDetector modDetector; + ScopedPointer codeDoc; + CPlusPlusCodeTokeniser cppTokeniser; +}; + +//============================================================================== +class DrawableDocumentType : public OpenDocumentManager::Document +{ +public: + DrawableDocumentType (Project* project_, const File& file_) + : project (project_), + modDetector (file_) + { + reloadFromFile(); + } + + ~DrawableDocumentType() + { + drawableDoc = 0; + } + + static bool isDrawableFile (const File& file) { return file.hasFileExtension (".drawable"); } + + bool loadedOk() const { return drawableDoc != 0; } + bool isForFile (const File& file) const { return modDetector.getFile() == file; } + bool isForNode (const ValueTree& node) const { return false; } + bool refersToProject (Project& p) const { return project == &p; } + const String getType() const { return "Drawable"; } + const String getName() const { return modDetector.getFile().getFileName(); } + bool needsSaving() const { return drawableDoc != 0 && drawableDoc->hasChangedSinceLastSave(); } + bool hasFileBeenModifiedExternally() { return modDetector.hasBeenModified(); } + + void reloadFromFile() + { + modDetector.updateHash(); + + if (drawableDoc == 0) + drawableDoc = new DrawableDocument (project, modDetector.getFile()); + + if (! drawableDoc->reload()) + drawableDoc = 0; + } + + bool save() + { + return drawableDoc->save(); + } + + Component* createEditor() + { + jassert (drawableDoc != 0); + + if (drawableDoc == 0) + return 0; + + return new DrawableEditor (this, project, drawableDoc); + } + +private: + Project* project; + FileModificationDetector modDetector; + ScopedPointer drawableDoc; +}; + +//============================================================================== +class UnknownDocument : public OpenDocumentManager::Document +{ +public: + UnknownDocument (Project* project_, const File& file_) + : project (project_), file (file_) + { + reloadFromFile(); + } + + ~UnknownDocument() {} + + bool loadedOk() const { return true; } + bool isForFile (const File& file_) const { return file == file_; } + bool isForNode (const ValueTree& node_) const { return false; } + bool refersToProject (Project& p) const { return project == &p; } + bool needsSaving() const { return false; } + bool save() { return true; } + bool hasFileBeenModifiedExternally() { return fileModificationTime != file.getLastModificationTime(); } + void reloadFromFile() { fileModificationTime = file.getLastModificationTime(); } + const String getName() const { return file.getFileName(); } + Component* createEditor() { return new ItemPreviewComponent (file); } + + const String getType() const + { + if (file.getFileExtension().isNotEmpty()) + return file.getFileExtension() + " file"; + + jassertfalse + return "Unknown"; + } + +private: + Project* const project; + const File file; + Time fileModificationTime; +}; + + +//============================================================================== +OpenDocumentManager::OpenDocumentManager() +{ +} + +OpenDocumentManager::~OpenDocumentManager() +{ + clearSingletonInstance(); +} + +juce_ImplementSingleton_SingleThreaded (OpenDocumentManager); + +//============================================================================== +void OpenDocumentManager::registerEditor (DocumentEditorComponent* editor) +{ + editors.add (editor); +} + +void OpenDocumentManager::deregisterEditor (DocumentEditorComponent* editor) +{ + editors.removeValue (editor); +} + +//============================================================================== +bool OpenDocumentManager::canOpenFile (const File& file) +{ + return DrawableDocumentType::isDrawableFile (file) + || SourceCodeEditor::isTextFile (file); +} + +OpenDocumentManager::Document* OpenDocumentManager::getDocumentForFile (Project* project, const File& file) +{ + for (int i = documents.size(); --i >= 0;) + if (documents.getUnchecked(i)->isForFile (file)) + return documents.getUnchecked(i); + + Document* d = 0; + + if (DrawableDocumentType::isDrawableFile (file)) + d = new DrawableDocumentType (project, file); + else if (SourceCodeEditor::isTextFile (file)) + d = new SourceCodeDocument (file); + else + d = new UnknownDocument (project, file); + + documents.add (d); + commandManager->commandStatusChanged(); + return d; +} + +int OpenDocumentManager::getNumOpenDocuments() const +{ + return documents.size(); +} + +OpenDocumentManager::Document* OpenDocumentManager::getOpenDocument (int index) const +{ + return documents.getUnchecked (index); +} + +void OpenDocumentManager::moveDocumentToTopOfStack (Document* doc) +{ + for (int i = documents.size(); --i >= 0;) + { + if (doc == documents.getUnchecked(i)) + { + documents.move (i, 0); + commandManager->commandStatusChanged(); + break; + } + } +} + +FileBasedDocument::SaveResult OpenDocumentManager::saveIfNeededAndUserAgrees (OpenDocumentManager::Document* doc) +{ + if (! doc->needsSaving()) + return FileBasedDocument::savedOk; + + const int r = AlertWindow::showYesNoCancelBox (AlertWindow::QuestionIcon, + TRANS("Closing document..."), + TRANS("Do you want to save the changes to \"") + + doc->getName() + T("\"?"), + TRANS("save"), + TRANS("discard changes"), + TRANS("cancel")); + + if (r == 1) + { + // save changes + return doc->save() ? FileBasedDocument::savedOk + : FileBasedDocument::failedToWriteToFile; + } + else if (r == 2) + { + // discard changes + return FileBasedDocument::savedOk; + } + + return FileBasedDocument::userCancelledSave; +} + + +bool OpenDocumentManager::closeDocument (int index, bool saveIfNeeded) +{ + Document* doc = documents [index]; + + if (doc != 0) + { + if (saveIfNeeded) + { + if (saveIfNeededAndUserAgrees (doc) != FileBasedDocument::savedOk) + return false; + } + + for (int i = editors.size(); --i >= 0;) + if (editors.getUnchecked(i)->getDocument() == doc) + editors.getUnchecked(i)->deleteSelf(); + + documents.remove (index); + commandManager->commandStatusChanged(); + } + + return true; +} + +bool OpenDocumentManager::closeDocument (Document* document, bool saveIfNeeded) +{ + return closeDocument (documents.indexOf (document), saveIfNeeded); +} + +void OpenDocumentManager::closeFile (const File& f, bool saveIfNeeded) +{ + for (int i = documents.size(); --i >= 0;) + { + Document* d = documents.getUnchecked (i); + + if (d->isForFile (f)) + closeDocument (i, saveIfNeeded); + } +} + +bool OpenDocumentManager::closeAllDocumentsUsingProject (Project& project, bool saveIfNeeded) +{ + for (int i = documents.size(); --i >= 0;) + { + Document* d = documents.getUnchecked (i); + + if (d->refersToProject (project)) + { + if (! closeDocument (i, saveIfNeeded)) + return false; + } + } + + return true; +} + +bool OpenDocumentManager::anyFilesNeedSaving() const +{ + for (int i = documents.size(); --i >= 0;) + { + Document* d = documents.getUnchecked (i); + + if (d->needsSaving()) + return true; + } + + return false; +} + +bool OpenDocumentManager::saveAll() +{ + for (int i = documents.size(); --i >= 0;) + { + Document* d = documents.getUnchecked (i); + + if (! d->save()) + return false; + } + + return true; +} + +void OpenDocumentManager::reloadModifiedFiles() +{ + for (int i = documents.size(); --i >= 0;) + { + Document* d = documents.getUnchecked (i); + + if (d->hasFileBeenModifiedExternally()) + d->reloadFromFile(); + } +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.h b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.h new file mode 100644 index 0000000000..d485257123 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.h @@ -0,0 +1,96 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_OPENDOCUMENTMANAGER_JUCEHEADER__ +#define __JUCER_OPENDOCUMENTMANAGER_JUCEHEADER__ + +#include "../model/jucer_Project.h" +#include "../model/jucer_DrawableDocument.h" +class DocumentEditorComponent; + + +//============================================================================== +/** +*/ +class OpenDocumentManager +{ +public: + //============================================================================== + OpenDocumentManager(); + ~OpenDocumentManager(); + + juce_DeclareSingleton_SingleThreaded_Minimal (OpenDocumentManager); + + //============================================================================== + class Document + { + public: + Document() {} + virtual ~Document() {} + + virtual bool loadedOk() const = 0; + virtual bool isForFile (const File& file) const = 0; + virtual bool isForNode (const ValueTree& node) const = 0; + virtual bool refersToProject (Project& project) const = 0; + virtual const String getName() const = 0; + virtual const String getType() const = 0; + virtual bool needsSaving() const = 0; + virtual bool save() = 0; + virtual bool hasFileBeenModifiedExternally() = 0; + virtual void reloadFromFile() = 0; + virtual Component* createEditor() = 0; + }; + + Document* getDocumentForFile (Project* project, const File& file); + bool canOpenFile (const File& file); + + //============================================================================== + int getNumOpenDocuments() const; + Document* getOpenDocument (int index) const; + void moveDocumentToTopOfStack (Document* doc); + + bool closeDocument (int index, bool saveIfNeeded); + bool closeDocument (Document* document, bool saveIfNeeded); + bool closeAllDocumentsUsingProject (Project& project, bool saveIfNeeded); + void closeFile (const File& f, bool saveIfNeeded); + bool anyFilesNeedSaving() const; + bool saveAll(); + FileBasedDocument::SaveResult saveIfNeededAndUserAgrees (Document* doc); + void reloadModifiedFiles(); + + //============================================================================== + void registerEditor (DocumentEditorComponent* editor); + void deregisterEditor (DocumentEditorComponent* editor); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + OwnedArray documents; + SortedSet editors; +}; + + +#endif // __JUCER_OPENDOCUMENTMANAGER_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.cpp b/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.cpp new file mode 100644 index 0000000000..850933faed --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.cpp @@ -0,0 +1,319 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ProjectContentComponent.h" +#include "jucer_MainWindow.h" +#include "jucer_SourceCodeEditor.h" +#include "Drawable Editor/jucer_DrawableEditor.h" +#include "jucer_ProjectInformationComponent.h" +#include "jucer_TreeViewTypes.h" +#include "../model/jucer_ProjectExporter.h" + + +//============================================================================== +ProjectContentComponent::ProjectContentComponent() + : projectTree (0), project (0), + currentDocument (0), resizerBar (0) +{ + setItemLayout (0, 100, 500, 300); + setItemLayout (1, 4, 4, 4); + setItemLayout (2, 100, 10000, 800); + + setOpaque (true); + setWantsKeyboardFocus (true); +} + +ProjectContentComponent::~ProjectContentComponent() +{ + setProject (0); + contentView = 0; + deleteAllChildren(); +} + +void ProjectContentComponent::paint (Graphics& g) +{ + g.fillAll (Colour::greyLevel (0.4f)); +} + +void ProjectContentComponent::hasBeenMoved() +{ + resized(); +} + +void ProjectContentComponent::resized() +{ + Component* comps[] = { projectTree, resizerBar, contentView }; + layOutComponents (comps, 3, 0, 0, getWidth(), getHeight(), false, true); +} + +void ProjectContentComponent::setProject (Project* newProject) +{ + if (project != newProject) + { + if (project != 0) + project->removeChangeListener (this); + + if (projectTree != 0) + projectTree->deleteRootItem(); + + projectTree = 0; + contentView = 0; + resizerBar = 0; + deleteAllChildren(); + + project = newProject; + + if (project != 0) + { + addAndMakeVisible (projectTree = new TreeView()); + projectTree->setRootItemVisible (true); + projectTree->setMultiSelectEnabled (true); + projectTree->setDefaultOpenness (true); + projectTree->setColour (TreeView::backgroundColourId, Colour::greyLevel (0.93f)); + projectTree->setIndentSize (14); + + addAndMakeVisible (resizerBar = new StretchableLayoutResizerBar (this, 1, true)); + + resized(); + + projectTree->setRootItem (new GroupTreeViewItem (project->getMainGroup())); + projectTree->getRootItem()->setOpen (true); + + project->addChangeListener (this); + + if (currentDocument == 0) + commandManager->invoke (CommandIDs::showProjectSettings, true); + + updateMissingFileStatuses(); + } + } +} + +void ProjectContentComponent::changeListenerCallback (void*) +{ + updateMissingFileStatuses(); +} + +void ProjectContentComponent::updateMissingFileStatuses() +{ + if (projectTree != 0) + { + ProjectTreeViewBase* p = dynamic_cast (projectTree->getRootItem()); + if (p != 0) + p->checkFileStatus(); + } +} + +bool ProjectContentComponent::showEditorForFile (const File& f) +{ + return showDocument (OpenDocumentManager::getInstance() + ->getDocumentForFile (project, f)); +} + +bool ProjectContentComponent::showDocument (OpenDocumentManager::Document* doc) +{ + if (doc == 0) + return false; + + OpenDocumentManager::getInstance()->moveDocumentToTopOfStack (doc); + + if (doc->hasFileBeenModifiedExternally()) + doc->reloadFromFile(); + + return setEditorComponent (doc->createEditor(), doc); +} + +void ProjectContentComponent::hideDocument (OpenDocumentManager::Document* doc) +{ + if (doc == currentDocument) + { + currentDocument = 0; + contentView = 0; + updateMainWindowTitle(); + commandManager->commandStatusChanged(); + } +} + +bool ProjectContentComponent::setEditorComponent (Component* editor, OpenDocumentManager::Document* doc) +{ + if (editor != 0) + { + contentView = editor; + currentDocument = doc; + addAndMakeVisible (editor); + resized(); + updateMainWindowTitle(); + commandManager->commandStatusChanged(); + + return true; + } + + updateMainWindowTitle(); + return false; +} + +void ProjectContentComponent::updateMainWindowTitle() +{ + MainWindow* mw = Component::findParentComponentOfClass ((MainWindow*) 0); + + if (mw != 0) + mw->updateTitle (currentDocument != 0 ? currentDocument->getName() : String::empty); +} + +ApplicationCommandTarget* ProjectContentComponent::getNextCommandTarget() +{ + return findFirstTargetParentComponent(); +} + +void ProjectContentComponent::getAllCommands (Array & commands) +{ + const CommandID ids[] = { CommandIDs::saveProject, + CommandIDs::saveProjectAs, + CommandIDs::closeProject, + CommandIDs::openProjectInIDE, + CommandIDs::showProjectSettings, + StandardApplicationCommandIDs::del}; + + commands.addArray (ids, numElementsInArray (ids)); +} + +void ProjectContentComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result) +{ + switch (commandID) + { + case CommandIDs::saveProject: + result.setInfo (T("Save Project"), + T("Saves the current project"), + CommandCategories::general, 0); + result.setActive (project != 0); + result.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::saveProjectAs: + result.setInfo (T("Save Project As..."), + T("Saves the current project to a different filename"), + CommandCategories::general, 0); + result.setActive (project != 0); + result.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); + break; + + case CommandIDs::closeProject: + result.setInfo (T("Close Project"), + T("Closes the current project"), + CommandCategories::general, 0); + result.setActive (project != 0); + result.defaultKeypresses.add (KeyPress (T('w'), ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); + break; + + case CommandIDs::openProjectInIDE: + #if JUCE_MAC + result.setInfo (T("Save Project and Open in XCode..."), + #elif JUCE_WINDOWS + result.setInfo (T("Save Project and Open in Visual Studio..."), + #else + result.setInfo (T("Save Project and Open as a Makefile..."), + #endif + T("Saves the project and launches it in an external IDE"), + CommandCategories::general, 0); + result.setActive (project != 0); + result.defaultKeypresses.add (KeyPress (T('l'), ModifierKeys::commandModifier, 0)); + break; + + case CommandIDs::showProjectSettings: + result.setInfo (T("Show Project Build Settings"), + T("Shows the build options for the project"), + CommandCategories::general, 0); + result.setActive (project != 0); + result.defaultKeypresses.add (KeyPress (T('i'), ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)); + break; + + case StandardApplicationCommandIDs::del: + result.setInfo (T("Delete"), String::empty, CommandCategories::general, 0); + result.setActive (projectTree != 0); + result.defaultKeypresses.add (KeyPress (KeyPress::deleteKey, 0, 0)); + break; + + default: + break; + } +} + +bool ProjectContentComponent::isCommandActive (const CommandID commandID) +{ + return project != 0; +} + +bool ProjectContentComponent::perform (const InvocationInfo& info) +{ + switch (info.commandID) + { + case CommandIDs::saveProject: + if (project != 0) + project->save (true, true); + + break; + + case CommandIDs::saveProjectAs: + if (project != 0) + project->saveAsInteractive (true); + + break; + + case CommandIDs::closeProject: + if (((MainWindow*) getParentComponent())->closeCurrentProject()) + StoredSettings::getInstance()->setLastProject (File::nonexistent); + + break; + + case CommandIDs::openProjectInIDE: + if (project != 0 && project->save (true, true) == FileBasedDocument::savedOk) + { + ScopedPointer exporter (ProjectExporter::createPlatformDefaultExporter (*project)); + exporter->launchProject(); + } + break; + + case CommandIDs::showProjectSettings: + if (projectTree != 0) + projectTree->getRootItem()->setSelected (true, true); + + break; + + case StandardApplicationCommandIDs::del: + if (projectTree != 0) + { + ProjectTreeViewBase* p = dynamic_cast (projectTree->getRootItem()); + if (p != 0) + p->deleteAllSelectedItems(); + } + + break; + + default: + return false; + } + + return true; +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.h b/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.h new file mode 100644 index 0000000000..f41cf3c8f3 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectContentComponent.h @@ -0,0 +1,83 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTCONTENTCOMPONENT_JUCEHEADER__ +#define __JUCER_PROJECTCONTENTCOMPONENT_JUCEHEADER__ + +#include "../model/jucer_Project.h" +#include "jucer_OpenDocumentManager.h" + + +//============================================================================== +/** +*/ +class ProjectContentComponent : public Component, + public ApplicationCommandTarget, + public ChangeListener, + public StretchableLayoutManager +{ +public: + //============================================================================== + ProjectContentComponent(); + ~ProjectContentComponent(); + + void paint (Graphics& g); + void resized(); + + void setProject (Project* project); + + bool showEditorForFile (const File& f); + bool showDocument (OpenDocumentManager::Document* doc); + void hideDocument (OpenDocumentManager::Document* doc); + bool setEditorComponent (Component* editor, OpenDocumentManager::Document* doc); + + void updateMissingFileStatuses(); + + void changeListenerCallback (void*); + void hasBeenMoved(); + + //============================================================================== + ApplicationCommandTarget* getNextCommandTarget(); + void getAllCommands (Array & commands); + void getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result); + bool isCommandActive (const CommandID commandID); + bool perform (const InvocationInfo& info); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + TreeView* projectTree; + Project* project; + ScopedPointer contentView; + OpenDocumentManager::Document* currentDocument; + + StretchableLayoutResizerBar* resizerBar; + + void updateMainWindowTitle(); +}; + + +#endif // __JUCER_PROJECTCONTENTCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.cpp b/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.cpp new file mode 100644 index 0000000000..787cb0a209 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.cpp @@ -0,0 +1,439 @@ +/* + ============================================================================== + + This is an automatically generated file created by the Jucer! + + Creation date: 14 Feb 2010 3:06:06 pm + + Be careful when adding custom code to these files, as only the code within + the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded + and re-saved. + + Jucer version: 1.12 + + ------------------------------------------------------------------------------ + + The Jucer is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-6 by Raw Material Software ltd. + + ============================================================================== +*/ + +//[Headers] You can add your own extra header files here... +#include "../model/jucer_ProjectExporter.h" +//[/Headers] + +#include "jucer_ProjectInformationComponent.h" + + +//[MiscUserDefs] You can add your own user definitions and misc code here... +class PropertiesWithHelpComponent : public Component, + public Timer +{ +public: + PropertiesWithHelpComponent (Project& project_, int tabIndex_) + : project (project_), lastComp (0), tabIndex (tabIndex_) + { + addAndMakeVisible (panel = new PropertyPanel()); + startTimer (150); + } + + ~PropertiesWithHelpComponent() + { + deleteAllChildren(); + } + + PropertyPanel* getPanel() const { return panel; } + + void rebuildProperties() + { + panel->clear(); + Array props; + + if (tabIndex == 0) + { + // The main project tab... + project.createPropertyEditors (props); + } + else if (tabIndex == 1) + { + // The Juce options tab... + OwnedArray flags; + project.getJuceConfigFlags (flags); + + StringArray possibleValues; + possibleValues.add ("Enabled"); + possibleValues.add ("Disabled"); + possibleValues.add ("(Use default from juce_Config.h)"); + + for (int i = 0; i < flags.size(); ++i) + { + if ((int) flags[i]->value.getValue() == 0) + flags[i]->value = 3; + + ChoicePropertyComponent* c = new ChoicePropertyComponent (flags[i]->value, flags[i]->symbol, possibleValues); + c->setTooltip (flags[i]->description); + c->setPreferredHeight (22); + props.add (c); + } + } + else if (tabIndex < 2 + project.getNumConfigurations()) + { + // A config tab.. + project.getConfiguration (tabIndex - 2).createPropertyEditors (props); + } + else + { + // An export tab.. + ScopedPointer exp (project.createExporter (tabIndex - (2 + project.getNumConfigurations()))); + + if (exp != 0) + exp->createPropertyEditors (props); + } + + panel->addProperties (props); + } + + void visibilityChanged() + { + if (isVisible()) + rebuildProperties(); + } + + void paint (Graphics& g) + { + g.setColour (Colour::greyLevel (0.15f)); + g.setFont (13.0f); + + TextLayout tl; + tl.appendText (lastTip, Font (14.0f)); + tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice + if (tl.getNumLines() > 3) + tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in.. + + tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10, + getHeight() - panel->getBottom() - 4, + Justification::centredLeft); + } + + void resized() + { + panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f))); + } + + void timerCallback() + { + Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + + if (newComp != lastComp) + { + lastComp = newComp; + + String newTip (findTip (newComp)); + + if (newTip != lastTip) + { + lastTip = newTip; + repaint (0, panel->getBottom(), getWidth(), getHeight()); + } + } + } + +private: + Project& project; + PropertyPanel* panel; + TextLayout layout; + Component* lastComp; + String lastTip; + int tabIndex; + + const String findTip (Component* c) const + { + while (c != 0 && c != this) + { + TooltipClient* tc = dynamic_cast (c); + if (tc != 0) + { + String tip (tc->getTooltip()); + + if (tip.isNotEmpty()) + return tip; + } + + c = c->getParentComponent(); + } + + return String::empty; + } +}; + +//[/MiscUserDefs] + +//============================================================================== +ProjectInformationComponent::ProjectInformationComponent (Project& project_) + : project (project_), + configTabBox (0), + editConfigsButton (0), + openProjectButton (0), + editExportersButton (0) +{ + addAndMakeVisible (configTabBox = new TabbedComponent (TabbedButtonBar::TabsAtTop)); + configTabBox->setTabBarDepth (30); + configTabBox->setCurrentTabIndex (-1); + + addAndMakeVisible (editConfigsButton = new TextButton (String::empty)); + editConfigsButton->setButtonText (T("Add/Remove Configurations...")); + editConfigsButton->addButtonListener (this); + + addAndMakeVisible (openProjectButton = new TextButton (String::empty)); + openProjectButton->setButtonText (T("Open Project in ")); + openProjectButton->addButtonListener (this); + + addAndMakeVisible (editExportersButton = new TextButton (String::empty)); + editExportersButton->setButtonText (T("Add/Remove Exporters...")); + editExportersButton->addButtonListener (this); + + + //[UserPreSize] + rebuildConfigTabs(); + +#if JUCE_MAC || JUCE_WINDOWS + openProjectButton->setCommandToTrigger (commandManager, CommandIDs::openProjectInIDE, true); + openProjectButton->setButtonText (commandManager->getNameOfCommand (CommandIDs::openProjectInIDE)); +#else + openProjectButton->setVisible (false); +#endif + + //[/UserPreSize] + + setSize (600, 400); + + //[Constructor] You can add your own custom stuff here.. + configTabBox->setOutline (1); + configTabBox->setColour (TabbedComponent::outlineColourId, Colours::black); + + editConfigsButton->setTriggeredOnMouseDown (true); + + project.addChangeListener (this); + //[/Constructor] +} + +ProjectInformationComponent::~ProjectInformationComponent() +{ + //[Destructor_pre]. You can add your own custom destruction code here.. + project.removeChangeListener (this); + //[/Destructor_pre] + + deleteAndZero (configTabBox); + deleteAndZero (editConfigsButton); + deleteAndZero (openProjectButton); + deleteAndZero (editExportersButton); + + //[Destructor]. You can add your own custom destruction code here.. + //[/Destructor] +} + +//============================================================================== +void ProjectInformationComponent::paint (Graphics& g) +{ + //[UserPrePaint] Add your own custom painting code here.. + //[/UserPrePaint] + + //[UserPaint] Add your own custom painting code here.. + //[/UserPaint] +} + +void ProjectInformationComponent::resized() +{ + configTabBox->setBounds (8, 0, getWidth() - 16, getHeight() - 36); + editConfigsButton->setBounds (8, getHeight() - 26, 192, 22); + openProjectButton->setBounds (384, getHeight() - 26, 208, 22); + editExportersButton->setBounds (208, getHeight() - 26, 160, 22); + //[UserResized] Add your own custom resize handling here.. + //[/UserResized] +} + +void ProjectInformationComponent::buttonClicked (Button* buttonThatWasClicked) +{ + //[UserbuttonClicked_Pre] + //[/UserbuttonClicked_Pre] + + if (buttonThatWasClicked == editConfigsButton) + { + //[UserButtonCode_editConfigsButton] -- add your button handler code here.. + showConfigMenu(); + //[/UserButtonCode_editConfigsButton] + } + else if (buttonThatWasClicked == openProjectButton) + { + //[UserButtonCode_openProjectButton] -- add your button handler code here.. + //[/UserButtonCode_openProjectButton] + } + else if (buttonThatWasClicked == editExportersButton) + { + //[UserButtonCode_editExportersButton] -- add your button handler code here.. + showExporterMenu(); + //[/UserButtonCode_editExportersButton] + } + + //[UserbuttonClicked_Post] + //[/UserbuttonClicked_Post] +} + + + +//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... +void ProjectInformationComponent::rebuildConfigTabs() +{ + configTabBox->clearTabs(); + + int index = 0; + PropertiesWithHelpComponent* panel = new PropertiesWithHelpComponent (project, index++); + configTabBox->addTab ("Project Settings", Colours::lightslategrey, panel, true, -1); + + panel = new PropertiesWithHelpComponent (project, index++); + configTabBox->addTab ("Juce Flags", Colours::lightblue, panel, true, -1); + + int i; + for (i = 0; i < project.getNumConfigurations(); ++i) + { + panel = new PropertiesWithHelpComponent (project, index++); + Project::BuildConfiguration config (project.getConfiguration (i)); + configTabBox->addTab (config.getName().toString(), Colour::greyLevel (0.65f), panel, true, -1); + } + + for (i = 0; i < project.getNumExporters(); ++i) + { + ScopedPointer exp (project.createExporter (i)); + + if (exp != 0) + { + panel = new PropertiesWithHelpComponent (project, index++); + configTabBox->addTab (exp->getName(), Colours::lightsteelblue, panel, true, -1); + } + } + + lastProjectType = (Project::ProjectType) (int) project.getProjectType().getValue(); +} + +void ProjectInformationComponent::updateConfigTabs() +{ + if (configTabBox->getNumTabs() != project.getNumConfigurations() + project.getNumExporters() + 2 + || lastProjectType != (Project::ProjectType) (int) project.getProjectType().getValue()) + { + rebuildConfigTabs(); + } + else + { + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + configTabBox->setTabName (i + 2, config.getName().toString()); + } + } +} + +void ProjectInformationComponent::showConfigMenu() +{ + PopupMenu m; + m.addItem (1, "Add a new empty configuration"); + + PopupMenu createCopyMenu, removeMenu; + + for (int i = 0; i < project.getNumConfigurations(); ++i) + { + Project::BuildConfiguration config (project.getConfiguration (i)); + createCopyMenu.addItem (i + 10000, "Create a copy of '" + config.getName().toString() + "'"); + removeMenu.addItem (i + 20000, "Delete configuration '" + config.getName().toString() + "'"); + } + + m.addSubMenu ("Add a copy of an existing configuration", createCopyMenu); + m.addSubMenu ("Remove configuration", removeMenu); + + const int r = m.showAt (editConfigsButton); + + if (r >= 20000) + { + project.deleteConfiguration (r - 20000); + } + else if (r >= 10000) + { + Project::BuildConfiguration configToCopy (project.getConfiguration (r - 10000)); + project.addNewConfiguration (&configToCopy); + } + else if (r == 1) + { + project.addNewConfiguration (0); + } +} + +void ProjectInformationComponent::showExporterMenu() +{ + PopupMenu m; + + PopupMenu createMenu, removeMenu; + + int i; + for (i = 0; i < project.getNumExporters(); ++i) + { + ScopedPointer exp (project.createExporter (i)); + + if (exp != 0) + removeMenu.addItem (i + 20000, "Delete " + exp->getName()); + } + + StringArray exporters (ProjectExporter::getExporterNames()); + + for (i = 0; i < exporters.size(); ++i) + createMenu.addItem (i + 10000, "Create a new " + exporters[i] + " target"); + + m.addSubMenu ("Create new export target", createMenu); + m.addSubMenu ("Remove export target", removeMenu); + + const int r = m.showAt (editExportersButton); + + if (r >= 20000) + project.deleteExporter (r - 20000); + else if (r >= 10000) + project.addNewExporter (r - 10000); +} + +void ProjectInformationComponent::changeListenerCallback (void*) +{ + updateConfigTabs(); +} + +//[/MiscUserCode] + + +//============================================================================== +#if 0 +/* -- Jucer information section -- + + This is where the Jucer puts all of its metadata, so don't change anything in here! + +BEGIN_JUCER_METADATA + + + + + + + + + +END_JUCER_METADATA +*/ +#endif diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.h b/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.h new file mode 100644 index 0000000000..cc18e0a7aa --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectInformationComponent.h @@ -0,0 +1,86 @@ +/* + ============================================================================== + + This is an automatically generated file created by the Jucer! + + Creation date: 14 Feb 2010 3:06:06 pm + + Be careful when adding custom code to these files, as only the code within + the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded + and re-saved. + + Jucer version: 1.12 + + ------------------------------------------------------------------------------ + + The Jucer is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-6 by Raw Material Software ltd. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTINFORMATIONCOMPONENT_JUCEHEADER__ +#define __JUCER_PROJECTINFORMATIONCOMPONENT_JUCEHEADER__ + +//[Headers] -- You can add your own extra header files here -- +#include "../jucer_Headers.h" +#include "../model/jucer_Project.h" +//[/Headers] + + + +//============================================================================== +/** + //[Comments] + An auto-generated component, created by the Jucer. + + Describe your class and how it works here! + //[/Comments] +*/ +class ProjectInformationComponent : public Component, + public ChangeListener, + public ButtonListener +{ +public: + //============================================================================== + ProjectInformationComponent (Project& project_); + ~ProjectInformationComponent(); + + //============================================================================== + //[UserMethods] -- You can add your own custom methods in this section. + void changeListenerCallback (void*); + void rebuildConfigTabs(); + //[/UserMethods] + + void paint (Graphics& g); + void resized(); + void buttonClicked (Button* buttonThatWasClicked); + + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + //[UserVariables] -- You can add your own custom variables in this section. + Project& project; + + Project::ProjectType lastProjectType; + void updateConfigTabs(); + void showConfigMenu(); + void showExporterMenu(); + //[/UserVariables] + + //============================================================================== + TabbedComponent* configTabBox; + TextButton* editConfigsButton; + TextButton* openProjectButton; + TextButton* editExportersButton; + + //============================================================================== + // (prevent copy constructor and operator= being generated..) + ProjectInformationComponent (const ProjectInformationComponent&); + const ProjectInformationComponent& operator= (const ProjectInformationComponent&); +}; + + +#endif // __JUCER_PROJECTINFORMATIONCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.cpp b/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.cpp new file mode 100644 index 0000000000..4e49736d49 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.cpp @@ -0,0 +1,490 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_ProjectTreeViewBase.h" +#include "jucer_OpenDocumentManager.h" + + +//============================================================================== +ProjectTreeViewBase::ProjectTreeViewBase (const Project::Item& item_) + : item (item_), isFileMissing (false) +{ + item.getNode().addListener (this); + item.createUIDIfMissing(); +} + +ProjectTreeViewBase::~ProjectTreeViewBase() +{ + item.getNode().removeListener (this); +} + +//============================================================================== +const String ProjectTreeViewBase::getDisplayName() const +{ + return item.getName().toString(); +} + +void ProjectTreeViewBase::setName (const String& newName) +{ + if (item.isMainGroup()) + item.getProject().setTitle (newName); + else + item.getName() = newName; +} + +//============================================================================== +const File ProjectTreeViewBase::getFile() const +{ + return item.getFile(); +} + +void ProjectTreeViewBase::browseToAddExistingFiles() +{ + FileChooser fc ("Add Files to Jucer Project", getFile(), String::empty, false); + + if (fc.browseForMultipleFilesOrDirectories()) + { + StringArray files; + + for (int i = 0; i < fc.getResults().size(); ++i) + files.add (fc.getResults().getReference(i).getFullPathName()); + + addFiles (files, 0); + } +} + +void ProjectTreeViewBase::addFiles (const StringArray& files, int insertIndex) +{ + ProjectTreeViewBase* p = dynamic_cast (getParentItem()); + + if (p != 0) + p->addFiles (files, insertIndex); +} + +void ProjectTreeViewBase::moveSelectedItemsTo (OwnedArray & selectedNodes, int insertIndex) +{ + jassertfalse; +} + +//============================================================================== +ProjectTreeViewBase* ProjectTreeViewBase::findTreeViewItem (const Project::Item& itemToFind) +{ + if (item == itemToFind) + { + return this; + } + else + { + const bool wasOpen = isOpen(); + setOpen (true); + + for (int i = getNumSubItems(); --i >= 0;) + { + ProjectTreeViewBase* pg = dynamic_cast (getSubItem(i)); + + if (pg != 0) + { + pg = pg->findTreeViewItem (itemToFind); + + if (pg != 0) + return pg; + } + } + + setOpen (wasOpen); + } + + return 0; +} + +//============================================================================== +class RenameMessage : public CallbackMessage +{ +public: + RenameMessage (TreeView* const tree_, const Project::Item& itemToRename_) + : tree (tree_), itemToRename (itemToRename_) {} + + ~RenameMessage() throw() {} + + void messageCallback() + { + if (tree->isValidComponent()) + { + ProjectTreeViewBase* pg = dynamic_cast (tree->getRootItem()); + + if (pg != 0) + { + pg = pg->findTreeViewItem (itemToRename); + + if (pg != 0) + pg->showRenameBox(); + } + } + } + + TreeView* tree; + Project::Item itemToRename; +}; + +void ProjectTreeViewBase::triggerAsyncRename (const Project::Item& itemToRename) +{ + (new RenameMessage (getOwnerView(), itemToRename))->post(); +} + +//============================================================================== +void ProjectTreeViewBase::checkFileStatus() +{ + const File file (getFile()); + const bool nowMissing = file != File::nonexistent && ! file.exists(); + + if (nowMissing != isFileMissing) + { + isFileMissing = nowMissing; + repaintItem(); + } +} + +void ProjectTreeViewBase::revealInFinder() const +{ + getFile().revealToUser(); +} + +void ProjectTreeViewBase::deleteItem() +{ + item.removeItemFromProject(); +} + +void ProjectTreeViewBase::deleteAllSelectedItems() +{ + TreeView* tree = getOwnerView(); + const int numSelected = tree->getNumSelectedItems(); + OwnedArray filesToTrash; + OwnedArray itemsToRemove; + + int i; + for (i = 0; i < numSelected; ++i) + { + const ProjectTreeViewBase* const p = dynamic_cast (tree->getSelectedItem (i)); + + if (p != 0) + { + itemsToRemove.add (new Project::Item (p->item)); + + if (p->getFile().existsAsFile()) + filesToTrash.add (new File (p->getFile())); + } + } + + if (filesToTrash.size() > 0) + { + String fileList; + const int maxFilesToList = 10; + for (i = jmin (maxFilesToList, filesToTrash.size()); --i >= 0;) + fileList << filesToTrash.getUnchecked(i)->getFullPathName() << "\n"; + + if (filesToTrash.size() > maxFilesToList) + fileList << "\n...plus " << (filesToTrash.size() - maxFilesToList) << " more files..."; + + int r = AlertWindow::showYesNoCancelBox (AlertWindow::NoIcon, "Delete Project Items", + "As well as removing the selected item(s) from the project, do you also want to move their files to the trash:\n\n" + + fileList, + "Just remove references", + "Also move files to Trash", + "Cancel", + tree->getTopLevelComponent()); + + if (r == 0) + return; + + if (r != 2) + filesToTrash.clear(); + } + + ProjectTreeViewBase* treeRootItem = dynamic_cast (tree->getRootItem()); + jassert (treeRootItem != 0); + + if (treeRootItem != 0) + { + for (i = filesToTrash.size(); --i >= 0;) + { + const File f (*filesToTrash.getUnchecked(i)); + + OpenDocumentManager::getInstance()->closeFile (f, false); + + if (! f.moveToTrash()) + { + // xxx + } + } + + for (i = itemsToRemove.size(); --i >= 0;) + { + ProjectTreeViewBase* item = treeRootItem->findTreeViewItem (*itemsToRemove.getUnchecked(i)); + if (item != 0) + item->deleteItem(); + } + } +} + +static int indexOfNode (const ValueTree& parent, const ValueTree& child) +{ + for (int i = parent.getNumChildren(); --i >= 0;) + if (parent.getChild (i) == child) + return i; + + return -1; +} + +void ProjectTreeViewBase::moveItems (OwnedArray & selectedNodes, + Project::Item destNode, int insertIndex) +{ + int i; + for (i = selectedNodes.size(); --i >= 0;) + { + Project::Item* const n = selectedNodes.getUnchecked(i); + + if (destNode == *n || destNode.getNode().isAChildOf (n->getNode())) // Check for recursion. + return; + + if (! destNode.canContain (*n)) + selectedNodes.remove (i); + } + + // Don't include any nodes that are children of other selected nodes.. + for (i = selectedNodes.size(); --i >= 0;) + { + Project::Item* const n = selectedNodes.getUnchecked(i); + + for (int j = selectedNodes.size(); --j >= 0;) + { + if (j != i && n->getNode().isAChildOf (selectedNodes.getUnchecked(j)->getNode())) + { + selectedNodes.remove (i); + break; + } + } + } + + // Remove and re-insert them one at a time.. + for (int i = 0; i < selectedNodes.size(); ++i) + { + Project::Item* selectedNode = selectedNodes.getUnchecked(i); + + if (selectedNode->getNode().getParent() == destNode.getNode() + && indexOfNode (destNode.getNode(), selectedNode->getNode()) < insertIndex) + --insertIndex; + + selectedNode->removeItemFromProject(); + destNode.addChild (*selectedNode, insertIndex++); + } +} + +//============================================================================== +bool ProjectTreeViewBase::isInterestedInFileDrag (const StringArray& files) +{ + return acceptsFileDrop (files); +} + +void ProjectTreeViewBase::filesDropped (const StringArray& files, int insertIndex) +{ + addFiles (files, insertIndex); +} + +static void getAllSelectedNodesInTree (Component* componentInTree, OwnedArray & selectedNodes) +{ + TreeView* tree = dynamic_cast (componentInTree); + + if (tree == 0) + tree = componentInTree->findParentComponentOfClass ((TreeView*) 0); + + if (tree != 0) + { + const int numSelected = tree->getNumSelectedItems(); + + for (int i = 0; i < numSelected; ++i) + { + const ProjectTreeViewBase* const p = dynamic_cast (tree->getSelectedItem (i)); + + if (p != 0) + selectedNodes.add (new Project::Item (p->item)); + } + } +} + +bool ProjectTreeViewBase::isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent) +{ + if (sourceDescription != String (projectItemDragType)) + return false; + + OwnedArray selectedNodes; + getAllSelectedNodesInTree (sourceComponent, selectedNodes); + + return selectedNodes.size() > 0 && acceptsDragItems (selectedNodes); +} + +void ProjectTreeViewBase::itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex) +{ + OwnedArray selectedNodes; + getAllSelectedNodesInTree (sourceComponent, selectedNodes); + + if (selectedNodes.size() > 0) + { + TreeView* tree = getOwnerView(); + ScopedPointer openness (tree->getOpennessState (false)); + + moveSelectedItemsTo (selectedNodes, insertIndex); + + if (openness != 0) + tree->restoreOpennessState (*openness); + } +} + +//============================================================================== +void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) +{ + if (tree == item.getNode()) + repaintItem(); +} + +void ProjectTreeViewBase::valueTreeChildrenChanged (ValueTree& tree) +{ + if (tree == item.getNode()) + { + refreshSubItems(); + treeHasChanged(); + setOpen (true); + } +} + +void ProjectTreeViewBase::valueTreeParentChanged (ValueTree& tree) +{ +} + +//============================================================================== +bool ProjectTreeViewBase::mightContainSubItems() +{ + return item.getNumChildren() > 0; +} + +const String ProjectTreeViewBase::getUniqueName() const +{ + jassert (item.getID().isNotEmpty()); + return item.getID(); +} + +void ProjectTreeViewBase::itemOpennessChanged (bool isNowOpen) +{ + if (isNowOpen) + refreshSubItems(); +} + +void ProjectTreeViewBase::addSubItems() +{ + for (int i = 0; i < item.getNumChildren(); ++i) + { + ProjectTreeViewBase* p = createSubItem (item.getChild(i)); + + if (p != 0) + addSubItem (p); + } +} + +void ProjectTreeViewBase::refreshSubItems() +{ + ScopedPointer openness (getOpennessState()); + + clearSubItems(); + addSubItems(); + + if (openness != 0) + restoreOpennessState (*openness); +} + +void ProjectTreeViewBase::showMultiSelectionPopupMenu() +{ + PopupMenu m; + m.addItem (6, "Delete"); + + switch (m.show()) + { + case 6: deleteAllSelectedItems(); break; + default: break; + } +} + +void ProjectTreeViewBase::itemClicked (const MouseEvent& e) +{ + if (e.mods.isPopupMenu()) + { + if (getOwnerView()->getNumSelectedItems() > 1) + showMultiSelectionPopupMenu(); + else + showPopupMenu(); + } +} + +void ProjectTreeViewBase::itemDoubleClicked (const MouseEvent& e) +{ + showDocument(); +} + +void ProjectTreeViewBase::itemSelectionChanged (bool isNowSelected) +{ + if (isNowSelected) + showDocument(); +} + +const String ProjectTreeViewBase::getTooltip() +{ + return String::empty; +} + +const String ProjectTreeViewBase::getDragSourceDescription() +{ + return projectItemDragType; +} + +//============================================================================== +ProjectTreeViewBase* ProjectTreeViewBase::getParentProjectItem() const +{ + return dynamic_cast (getParentItem()); +} + +ProjectContentComponent* ProjectTreeViewBase::getProjectContentComponent() const +{ + Component* c = getOwnerView(); + + while (c != 0) + { + ProjectContentComponent* pcc = dynamic_cast (c); + + if (pcc != 0) + return pcc; + + c = c->getParentComponent(); + } + + return 0; +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.h b/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.h new file mode 100644 index 0000000000..b96f38e38b --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_ProjectTreeViewBase.h @@ -0,0 +1,118 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_PROJECTTREEVIEWBASE_JUCEHEADER__ +#define __JUCER_PROJECTTREEVIEWBASE_JUCEHEADER__ + +#include "../jucer_Headers.h" +#include "../model/jucer_Project.h" +#include "../model/jucer_ResourceFile.h" +#include "jucer_ProjectContentComponent.h" +#include "jucer_JucerTreeViewBase.h" + +//============================================================================== +class ProjectTreeViewBase : public JucerTreeViewBase, + public ValueTree::Listener +{ +protected: + //============================================================================== + ProjectTreeViewBase (const Project::Item& item); + ~ProjectTreeViewBase(); + +public: + //============================================================================== + virtual bool isRoot() const { return false; } + virtual bool acceptsFileDrop (const StringArray& files) const = 0; + virtual bool acceptsDragItems (const OwnedArray & selectedNodes) = 0; + + //============================================================================== + virtual const String getDisplayName() const; + virtual const String getRenamingName() const { return getDisplayName(); } + virtual void setName (const String& newName); + virtual bool isMissing() { return isFileMissing; } + virtual const File getFile() const; + + virtual void deleteItem(); + virtual void deleteAllSelectedItems(); + virtual void revealInFinder() const; + virtual void showDocument() = 0; + virtual void browseToAddExistingFiles(); + virtual void checkFileStatus(); // (recursive) + + virtual void addFiles (const StringArray& files, int insertIndex); + virtual void moveSelectedItemsTo (OwnedArray & selectedNodes, int insertIndex); + + virtual void showPopupMenu() = 0; + virtual void showMultiSelectionPopupMenu(); + + virtual ProjectTreeViewBase* findTreeViewItem (const Project::Item& itemToFind); + + //============================================================================== + void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property); + void valueTreeChildrenChanged (ValueTree& tree); + void valueTreeParentChanged (ValueTree& tree); + + //============================================================================== + // TreeViewItem stuff.. + bool mightContainSubItems(); + const String getUniqueName() const; + void itemOpennessChanged (bool isNowOpen); + void refreshSubItems(); + bool canBeSelected() const { return true; } + void itemClicked (const MouseEvent& e); + void itemDoubleClicked (const MouseEvent& e); + void itemSelectionChanged (bool isNowSelected); + const String getTooltip(); + const String getDragSourceDescription(); + + //============================================================================== + // Drag-and-drop stuff.. + bool isInterestedInFileDrag (const StringArray& files); + void filesDropped (const StringArray& files, int insertIndex); + bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent); + void itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex); + + //============================================================================== + Project::Item item; + +protected: + bool isFileMissing; + + //============================================================================== + virtual void addSubItems(); + virtual ProjectTreeViewBase* createSubItem (const Project::Item& node) = 0; + Image* getIcon() const { return item.getIcon(); } + + //============================================================================== + void triggerAsyncRename (const Project::Item& itemToRename); + static void moveItems (OwnedArray & selectedNodes, + Project::Item destNode, int insertIndex); + + ProjectContentComponent* getProjectContentComponent() const; + ProjectTreeViewBase* getParentProjectItem() const; +}; + + +#endif // __JUCER_PROJECTTREEVIEWBASE_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.cpp b/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.cpp new file mode 100644 index 0000000000..e622650394 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.cpp @@ -0,0 +1,66 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_SourceCodeEditor.h" +#include "jucer_OpenDocumentManager.h" + + +//============================================================================== +SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* document, + CodeDocument& codeDocument, + CodeTokeniser* const codeTokeniser) + : DocumentEditorComponent (document) +{ + addAndMakeVisible (editor = new CodeEditorComponent (codeDocument, codeTokeniser)); + +#if JUCE_MAC + Font font (10.6f); + font.setTypefaceName ("Andale Mono"); +#else + Font font (10.0f); + font.setTypefaceName (Font::getDefaultMonospacedFontName()); +#endif + editor->setFont (font); +} + +SourceCodeEditor::~SourceCodeEditor() +{ + deleteAllChildren(); +} + +void SourceCodeEditor::resized() +{ + editor->setBounds (0, 0, getWidth(), getHeight()); +} + +bool SourceCodeEditor::isTextFile (const File& file) +{ + return file.hasFileExtension (textFileExtensions); +} + +bool SourceCodeEditor::isCppFile (const File& file) +{ + return file.hasFileExtension (sourceFileExtensions); +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.h b/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.h new file mode 100644 index 0000000000..f419b00c64 --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_SourceCodeEditor.h @@ -0,0 +1,59 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_SOURCECODEEDITOR_JUCEHEADER__ +#define __JUCER_SOURCECODEEDITOR_JUCEHEADER__ + +#include "../model/jucer_Project.h" +#include "jucer_DocumentEditorComponent.h" + + +//============================================================================== +/** +*/ +class SourceCodeEditor : public DocumentEditorComponent +{ +public: + //============================================================================== + SourceCodeEditor (OpenDocumentManager::Document* document, + CodeDocument& codeDocument, + CodeTokeniser* const codeTokeniser); + + ~SourceCodeEditor(); + + static bool isTextFile (const File& file); + static bool isCppFile (const File& file); + + void resized(); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + CodeEditorComponent* editor; +}; + + +#endif // __JUCER_SOURCECODEEDITOR_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.cpp b/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.cpp new file mode 100644 index 0000000000..9e7009610b --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.cpp @@ -0,0 +1,219 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "jucer_TreeViewTypes.h" +#include "jucer_ProjectInformationComponent.h" +#include "jucer_GroupInformationComponent.h" +#include "jucer_SourceCodeEditor.h" +#include "jucer_OpenDocumentManager.h" +#include "jucer_ItemPreviewComponent.h" +#include "../model/jucer_NewFileWizard.h" + + +//============================================================================== +GroupTreeViewItem::GroupTreeViewItem (const Project::Item& item_) + : ProjectTreeViewBase (item_) +{ +} + +GroupTreeViewItem::~GroupTreeViewItem() +{ +} + +void GroupTreeViewItem::addNewGroup() +{ + Project::Item group (item.getProject().createNewGroup()); + item.addChild (group, 0); + triggerAsyncRename (group); +} + +bool GroupTreeViewItem::acceptsDragItems (const OwnedArray & selectedNodes) +{ + for (int i = selectedNodes.size(); --i >= 0;) + if (item.canContain (*selectedNodes.getUnchecked(i))) + return true; + + return false; +} + +void GroupTreeViewItem::addFiles (const StringArray& files, int insertIndex) +{ + for (int i = 0; i < files.size(); ++i) + { + const File file (files[i]); + + if (item.addFile (file, insertIndex)) + ++insertIndex; + } +} + +void GroupTreeViewItem::moveSelectedItemsTo (OwnedArray & selectedNodes, int insertIndex) +{ + moveItems (selectedNodes, item, insertIndex); +} + +void GroupTreeViewItem::checkFileStatus() +{ + for (int i = 0; i < getNumSubItems(); ++i) + { + ProjectTreeViewBase* p = dynamic_cast (getSubItem(i)); + + if (p != 0) + p->checkFileStatus(); + } +} + +ProjectTreeViewBase* GroupTreeViewItem::createSubItem (const Project::Item& child) +{ + if (child.isGroup()) + return new GroupTreeViewItem (child); + + if (child.isFile()) + return new SourceFileTreeViewItem (child); + + jassertfalse + return 0; +} + +void GroupTreeViewItem::showDocument() +{ + ProjectContentComponent* pcc = getProjectContentComponent(); + + if (pcc != 0) + { + if (isRoot()) + pcc->setEditorComponent (new ProjectInformationComponent (item.getProject()), 0); + else + pcc->setEditorComponent (new GroupInformationComponent (item), 0); + } +} + +void GroupTreeViewItem::showPopupMenu() +{ + PopupMenu m; + addCreateFileMenuItems (m); + m.addSeparator(); + m.addItem (3, "Sort Contents Alphabetically"); + m.addSeparator(); + m.addItem (1, "Rename..."); + + if (! isRoot()) + m.addItem (2, "Delete"); + + const int res = m.show(); + switch (res) + { + case 1: triggerAsyncRename (item); break; + case 2: deleteAllSelectedItems(); break; + case 3: item.sortAlphabetically(); break; + default: processCreateFileMenuItem (res); break; + } +} + +void GroupTreeViewItem::addCreateFileMenuItems (PopupMenu& m) +{ + m.addItem (1001, "Add New Group"); + m.addItem (1002, "Add Existing Files..."); + + m.addSeparator(); + NewFileWizard::addWizardsToMenu (m); +} + +void GroupTreeViewItem::processCreateFileMenuItem (int menuID) +{ + switch (menuID) + { + case 1001: addNewGroup(); break; + case 1002: browseToAddExistingFiles(); break; + + default: + NewFileWizard::runWizardFromMenu (menuID, item); + break; + } +} + +//============================================================================== +//============================================================================== +SourceFileTreeViewItem::SourceFileTreeViewItem (const Project::Item& item_) + : ProjectTreeViewBase (item_) +{ +} + +SourceFileTreeViewItem::~SourceFileTreeViewItem() +{ +} + +ProjectTreeViewBase* SourceFileTreeViewItem::createSubItem (const Project::Item& child) +{ + jassertfalse + return 0; +} + +void SourceFileTreeViewItem::showDocument() +{ + ProjectContentComponent* pcc = getProjectContentComponent(); + const File f (getFile()); + + if (pcc != 0 && f.exists()) + pcc->showEditorForFile (f); +} + +void SourceFileTreeViewItem::showPopupMenu() +{ + GroupTreeViewItem* parentGroup = dynamic_cast (getParentProjectItem()); + + PopupMenu m; + + if (parentGroup != 0) + { + parentGroup->addCreateFileMenuItems (m); + m.addSeparator(); + } + + m.addItem (1, "Open in external editor"); +#if JUCE_MAC + m.addItem (2, "Reveal in Finder"); +#else + m.addItem (2, "Reveal in Explorer"); +#endif + + //m.addItem (4, "Rename..."); + m.addItem (3, "Delete"); + + const int res = m.show(); + switch (res) + { + case 1: getFile().startAsProcess(); break; + case 2: revealInFinder(); break; + case 3: deleteAllSelectedItems(); break; + //case 4: triggerAsyncRename(); break; + + default: + if (parentGroup != 0) + parentGroup->processCreateFileMenuItem (res); + + break; + } +} diff --git a/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.h b/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.h new file mode 100644 index 0000000000..cfe2bfb76d --- /dev/null +++ b/extras/Jucer (experimental)/Source/ui/jucer_TreeViewTypes.h @@ -0,0 +1,70 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_TREEVIEWTYPES_JUCEHEADER__ +#define __JUCER_TREEVIEWTYPES_JUCEHEADER__ + +#include "jucer_ProjectTreeViewBase.h" + + +//============================================================================== +class SourceFileTreeViewItem : public ProjectTreeViewBase +{ +public: + SourceFileTreeViewItem (const Project::Item& item); + ~SourceFileTreeViewItem(); + + bool acceptsFileDrop (const StringArray& files) const { return false; } + bool acceptsDragItems (const OwnedArray & selectedNodes) { return false; } + ProjectTreeViewBase* createSubItem (const Project::Item& child); + void showDocument(); + void showPopupMenu(); +}; + +//============================================================================== +class GroupTreeViewItem : public ProjectTreeViewBase +{ +public: + GroupTreeViewItem (const Project::Item& item); + ~GroupTreeViewItem(); + + bool isRoot() const { return item.isMainGroup(); } + bool acceptsFileDrop (const StringArray& files) const { return true; } + bool acceptsDragItems (const OwnedArray & selectedNodes); + void checkFileStatus(); + void moveSelectedItemsTo (OwnedArray & selectedNodes, int insertIndex); + ProjectTreeViewBase* createSubItem (const Project::Item& child); + void showDocument(); + void showPopupMenu(); + + void addFiles (const StringArray& files, int insertIndex); + void addNewGroup(); + + void addCreateFileMenuItems (PopupMenu& m); + void processCreateFileMenuItem (int item); +}; + + +#endif // __JUCER_TREEVIEWTYPES_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h b/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h new file mode 100644 index 0000000000..c80c9bda6b --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h @@ -0,0 +1,184 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__ +#define __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__ + + +//============================================================================== +/** + A component that shows a colour swatch with hex ARGB value, and which pops up + a colour selector when you click it. +*/ +class ColourEditorComponent : public Component, + public ChangeListener +{ +public: + ColourEditorComponent (const bool canResetToDefault_) + : canResetToDefault (canResetToDefault_) + { + } + + ~ColourEditorComponent() + { + } + + void paint (Graphics& g) + { + g.fillAll (Colours::grey); + + g.fillCheckerBoard (2, 2, getWidth() - 4, getHeight() - 4, + 10, 10, + Colour (0xffdddddd).overlaidWith (colour), + Colour (0xffffffff).overlaidWith (colour)); + + g.setColour (Colours::white.overlaidWith (colour).contrasting()); + g.setFont (getHeight() * 0.6f, Font::bold); + g.drawFittedText (colour.toDisplayString (true), + 2, 1, getWidth() - 4, getHeight() - 1, + Justification::centred, 1); + } + + virtual void setColour (const Colour& newColour) = 0; + virtual void resetToDefault() = 0; + virtual const Colour getColour() const = 0; + + void refresh() + { + const Colour col (getColour()); + + if (col != colour) + { + colour = col; + repaint(); + } + } + + void mouseDown (const MouseEvent& e) + { + ColourSelectorComp colourSelector (this, canResetToDefault); + + PopupMenu m; + m.addCustomItem (1234, &colourSelector, 300, 400, false); + m.showAt (this); + } + + void changeListenerCallback (void* source) + { + const ColourSelector* const cs = (const ColourSelector*) source; + + if (cs->getCurrentColour() != getColour()) + setColour (cs->getCurrentColour()); + } + + juce_UseDebuggingNewOperator + +private: + Colour colour; + bool canResetToDefault; + + class ColourSelectorComp : public Component, + public ButtonListener + { + public: + ColourSelectorComp (ColourEditorComponent* owner_, + const bool canResetToDefault) + : owner (owner_), + defaultButton (0) + { + addAndMakeVisible (selector = new ColourSelectorWithSwatches()); + selector->setName (T("Colour")); + selector->setCurrentColour (owner->getColour()); + selector->addChangeListener (owner); + + if (canResetToDefault) + { + addAndMakeVisible (defaultButton = new TextButton (T("Reset to Default"))); + defaultButton->addButtonListener (this); + } + } + + ~ColourSelectorComp() + { + deleteAllChildren(); + } + + void resized() + { + if (defaultButton != 0) + { + selector->setBounds (0, 0, getWidth(), getHeight() - 30); + defaultButton->changeWidthToFitText (22); + defaultButton->setTopLeftPosition (10, getHeight() - 26); + } + else + { + selector->setBounds (0, 0, getWidth(), getHeight()); + } + } + + void buttonClicked (Button*) + { + owner->resetToDefault(); + owner->refresh(); + selector->setCurrentColour (owner->getColour()); + } + + private: + class ColourSelectorWithSwatches : public ColourSelector + { + public: + ColourSelectorWithSwatches() + { + } + + ~ColourSelectorWithSwatches() + { + } + + int getNumSwatches() const + { + return StoredSettings::getInstance()->swatchColours.size(); + } + + const Colour getSwatchColour (const int index) const + { + return StoredSettings::getInstance()->swatchColours [index]; + } + + void setSwatchColour (const int index, const Colour& newColour) const + { + StoredSettings::getInstance()->swatchColours.set (index, newColour); + } + }; + + ColourEditorComponent* owner; + ColourSelectorWithSwatches* selector; + TextButton* defaultButton; + }; +}; + + +#endif // __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_Colours.h b/extras/Jucer (experimental)/Source/utility/jucer_Colours.h new file mode 100644 index 0000000000..bf01e3b80f --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_Colours.h @@ -0,0 +1,162 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +COL(black) +COL(white) +COL(blue) +COL(grey) +COL(green) +COL(red) +COL(yellow) +COL(aliceblue) +COL(antiquewhite) +COL(aqua) +COL(aquamarine) +COL(azure) +COL(beige) +COL(bisque) +COL(blanchedalmond) +COL(blueviolet) +COL(brown) +COL(burlywood) +COL(cadetblue) +COL(chartreuse) +COL(chocolate) +COL(coral) +COL(cornflowerblue) +COL(cornsilk) +COL(crimson) +COL(cyan) +COL(darkblue) +COL(darkcyan) +COL(darkgoldenrod) +COL(darkgrey) +COL(darkgreen) +COL(darkkhaki) +COL(darkmagenta) +COL(darkolivegreen) +COL(darkorange) +COL(darkorchid) +COL(darkred) +COL(darksalmon) +COL(darkseagreen) +COL(darkslateblue) +COL(darkslategrey) +COL(darkturquoise) +COL(darkviolet) +COL(deeppink) +COL(deepskyblue) +COL(dimgrey) +COL(dodgerblue) +COL(firebrick) +COL(floralwhite) +COL(forestgreen) +COL(fuchsia) +COL(gainsboro) +COL(gold) +COL(goldenrod) +COL(greenyellow) +COL(honeydew) +COL(hotpink) +COL(indianred) +COL(indigo) +COL(ivory) +COL(khaki) +COL(lavender) +COL(lavenderblush) +COL(lemonchiffon) +COL(lightblue) +COL(lightcoral) +COL(lightcyan) +COL(lightgoldenrodyellow) +COL(lightgreen) +COL(lightgrey) +COL(lightpink) +COL(lightsalmon) +COL(lightseagreen) +COL(lightskyblue) +COL(lightslategrey) +COL(lightsteelblue) +COL(lightyellow) +COL(lime) +COL(limegreen) +COL(linen) +COL(magenta) +COL(maroon) +COL(mediumaquamarine) +COL(mediumblue) +COL(mediumorchid) +COL(mediumpurple) +COL(mediumseagreen) +COL(mediumslateblue) +COL(mediumspringgreen) +COL(mediumturquoise) +COL(mediumvioletred) +COL(midnightblue) +COL(mintcream) +COL(mistyrose) +COL(navajowhite) +COL(navy) +COL(oldlace) +COL(olive) +COL(olivedrab) +COL(orange) +COL(orangered) +COL(orchid) +COL(palegoldenrod) +COL(palegreen) +COL(paleturquoise) +COL(palevioletred) +COL(papayawhip) +COL(peachpuff) +COL(peru) +COL(pink) +COL(plum) +COL(powderblue) +COL(purple) +COL(rosybrown) +COL(royalblue) +COL(saddlebrown) +COL(salmon) +COL(sandybrown) +COL(seagreen) +COL(seashell) +COL(sienna) +COL(silver) +COL(skyblue) +COL(slateblue) +COL(slategrey) +COL(snow) +COL(springgreen) +COL(steelblue) +COL(tan) +COL(teal) +COL(thistle) +COL(tomato) +COL(turquoise) +COL(violet) +COL(wheat) +COL(whitesmoke) +COL(yellowgreen) diff --git a/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h new file mode 100644 index 0000000000..70c910c232 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h @@ -0,0 +1,126 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_RELATIVEPATH_JUCEHEADER__ +#define __JUCER_RELATIVEPATH_JUCEHEADER__ + + +//============================================================================== +/** Manipulates a cross-platform partial file path. (Needed because File is designed + for absolute paths on the active OS) +*/ +class RelativePath +{ +public: + //============================================================================== + enum RootFolder + { + unknown, + projectFolder, + buildTargetFolder + }; + + //============================================================================== + RelativePath() + : root (unknown) + {} + + RelativePath (const String& path_, const RootFolder root_) + : path (path_), root (root_) + { + } + + RelativePath (const File& file, const File& rootFolder, const RootFolder root_) + : path (file.getRelativePathFrom (rootFolder)), root (root_) + { + } + + RootFolder getRoot() const { return root; } + + const String toUnixStyle() const { return unixStylePath (path); } + const String toWindowsStyle() const { return windowsStylePath (path); } + + const String getFileName() const { return getFakeFile().getFileName(); } + const String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); } + + const String getFileExtension() const { return getFakeFile().getFileExtension(); } + bool hasFileExtension (const String& extension) const { return getFakeFile().hasFileExtension (extension); } + bool isAbsolute() const { return isAbsolute (path); } + + const RelativePath withFileExtension (const String& extension) const + { + return RelativePath (path.upToLastOccurrenceOf (T("."), ! extension.startsWithChar (T('.')), false) + extension, root); + } + + const RelativePath getParentDirectory() const + { + String p (path); + if (path.endsWithChar (T('/'))) + p = p.dropLastCharacters (1); + + return RelativePath (p.upToLastOccurrenceOf (T("/"), false, false), root); + } + + const RelativePath getChildFile (const String& subpath) const + { + if (isAbsolute (subpath)) + return RelativePath (subpath, root); + + String p (toUnixStyle()); + if (! p.endsWithChar (T('/'))) + p << '/'; + + return RelativePath (p + subpath, root); + } + + const RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const + { + if (isAbsolute()) + return RelativePath (path, newRootType); + + return RelativePath (originalRoot.getChildFile (toUnixStyle()).getRelativePathFrom (newRoot), newRootType); + } + +private: + //============================================================================== + String path; + RootFolder root; + + const File getFakeFile() const + { + return File::getCurrentWorkingDirectory().getChildFile (path); + } + + static bool isAbsolute (const String& path) + { + return File::isAbsolutePath (path) + || path.startsWithChar (T('$')) + || path.startsWithChar (T('~')) + || (CharacterFunctions::isLetter (path[0]) && path[1] == T(':')); + } +}; + + +#endif // __JUCER_RELATIVEPATH_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp new file mode 100644 index 0000000000..c366c5db54 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp @@ -0,0 +1,105 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" +#include "jucer_StoredSettings.h" + + +//============================================================================== +StoredSettings::StoredSettings() + : props (0) +{ + flush(); +} + +StoredSettings::~StoredSettings() +{ + flush(); + deleteAndZero (props); + clearSingletonInstance(); +} + +juce_ImplementSingleton (StoredSettings); + + +//============================================================================== +PropertiesFile& StoredSettings::getProps() +{ + return *props; +} + +void StoredSettings::flush() +{ + if (props != 0) + { + props->setValue (T("recentFiles"), recentFiles.toString()); + + props->removeValue (T("keyMappings")); + + ScopedPointer keys (commandManager->getKeyMappings()->createXml (true)); + + if (keys != 0) + props->setValue (T("keyMappings"), (XmlElement*) keys); + } + + deleteAndZero (props); + + props = PropertiesFile::createDefaultAppPropertiesFile (T("Jucer2"), + T("settings"), + String::empty, + false, 3000, + PropertiesFile::storeAsXML); + + // recent files... + recentFiles.restoreFromString (props->getValue (T("recentFiles"))); + recentFiles.removeNonExistentFiles(); +} + +const File StoredSettings::getLastProject() const +{ + return props->getValue ("lastProject"); +} + +void StoredSettings::setLastProject (const File& file) +{ + props->setValue ("lastProject", file.getFullPathName()); +} + +const File StoredSettings::getLastKnownJuceFolder() const +{ + File defaultJuceFolder (findDefaultJuceFolder()); + File f (props->getValue ("lastJuceFolder", defaultJuceFolder.getFullPathName())); + + if ((! isJuceFolder (f)) && isJuceFolder (defaultJuceFolder)) + f = defaultJuceFolder; + + return f; +} + +void StoredSettings::setLastKnownJuceFolder (const File& file) +{ + jassert (isJuceFolder (file)); + props->setValue ("lastJuceFolder", file.getFullPathName()); +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h new file mode 100644 index 0000000000..60a7816124 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h @@ -0,0 +1,64 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_STOREDSETTINGS_JUCEHEADER__ +#define __JUCER_STOREDSETTINGS_JUCEHEADER__ + + +//============================================================================== +/** + A singleton to hold the jucer's persistent settings, and to save them in a + suitable PropertiesFile. +*/ +class StoredSettings +{ +public: + //============================================================================== + StoredSettings(); + ~StoredSettings(); + + juce_DeclareSingleton (StoredSettings, false); + + PropertiesFile& getProps(); + void flush(); + + //============================================================================== + RecentlyOpenedFilesList recentFiles; + + const File getLastProject() const; + void setLastProject (const File& file); + + const File getLastKnownJuceFolder() const; + void setLastKnownJuceFolder (const File& file); + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + PropertiesFile* props; +}; + + +#endif // __JUCER_STOREDSETTINGS_JUCEHEADER__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp new file mode 100644 index 0000000000..75938fe4d1 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp @@ -0,0 +1,526 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#include "../jucer_Headers.h" + + +//============================================================================== +int64 calculateStreamHashCode (InputStream& in) +{ + int64 t = 0; + + const int bufferSize = 4096; + HeapBlock buffer; + buffer.malloc (bufferSize); + + for (;;) + { + const int num = in.read (buffer, bufferSize); + + if (num <= 0) + break; + + for (int i = 0; i < num; ++i) + t = t * 65599 + buffer[i]; + } + + return t; +} + +int64 calculateFileHashCode (const File& file) +{ + ScopedPointer stream (file.createInputStream()); + return stream != 0 ? calculateStreamHashCode (*stream) : 0; +} + +bool areFilesIdentical (const File& file1, const File& file2) +{ + return file1.getSize() == file2.getSize() + && calculateFileHashCode (file1) == calculateFileHashCode (file2); +} + +bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes) +{ + if (file.getSize() == numBytes) + { + MemoryInputStream newStream (data, numBytes, false); + + if (calculateStreamHashCode (newStream) == calculateFileHashCode (file)) + return true; + } + + TemporaryFile temp (file); + + return temp.getFile().appendData (data, numBytes) + && temp.overwriteTargetFileWithTemporary(); +} + +bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData) +{ + return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize()); +} + +bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData) +{ + return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8())); +} + +bool containsAnyNonHiddenFiles (const File& folder) +{ + DirectoryIterator di (folder, false); + + while (di.next()) + if (! di.getFile().isHidden()) + return true; + + return false; +} + +//============================================================================== +const int64 hashCode64 (const String& s) +{ + return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode(); +} + +const String createAlphaNumericUID() +{ + String uid; + static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random r (Random::getSystemRandom().nextInt64()); + + for (int i = 9; --i >= 0;) + { + r.setSeedRandomly(); + uid << (juce_wchar) chars [r.nextInt (sizeof (chars))]; + } + + return uid; +} + +const String randomHexString (Random& random, int numChars) +{ + String s; + const char hexChars[] = "0123456789ABCDEF"; + + while (--numChars >= 0) + s << hexChars [random.nextInt (16)]; + + return s; +} + +const String hexString8Digits (int value) +{ + String s (String::toHexString (value)); + return String::repeatedString (T("0"), 8 - s.length()) + s; +} + + +const String createGUID (const String& seed) +{ + String guid; + Random r (hashCode64 (seed + "_jucersalt")); + guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution) + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 4); + guid << "-" << randomHexString (r, 12) << "}"; + return guid; +} + +const String unixStylePath (const String& path) +{ + return path.replaceCharacter (T('\\'), T('/')); +} + +const String windowsStylePath (const String& path) +{ + return path.replaceCharacter (T('/'), T('\\')); +} + +const String appendPath (const String& path, const String& subpath) +{ + if (File::isAbsolutePath (subpath) + || subpath.startsWithChar (T('$')) + || subpath.startsWithChar (T('~')) + || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == T(':'))) + return subpath.replaceCharacter (T('\\'), T('/')); + + String path1 (path.replaceCharacter (T('\\'), T('/'))); + if (! path1.endsWithChar (T('/'))) + path1 << '/'; + + return path1 + subpath.replaceCharacter (T('\\'), T('/')); +} + +bool shouldPathsBeRelative (String path1, String path2) +{ + path1 = unixStylePath (path1); + path2 = unixStylePath (path2); + + const int len = jmin (path1.length(), path2.length()); + int commonBitLength = 0; + + for (int i = 0; i < len; ++i) + { + if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i])) + break; + + ++commonBitLength; + } + + return path1.substring (0, commonBitLength).removeCharacters (T("/:")).isNotEmpty(); +} + +const String createIncludeStatement (const File& includeFile, const File& targetFile) +{ + return "#include \"" + unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + + "\""; +} + +const String makeHeaderGuardName (const File& file) +{ + return "__" + file.getFileName().toUpperCase() + .replaceCharacters (T(" ."), T("__")) + .retainCharacters (T("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) + + "_" + + String::toHexString (file.hashCode()).toUpperCase() + + "__"; +} + +//============================================================================== +bool isJuceFolder (const File& folder) +{ + return folder.getFileName().containsIgnoreCase (T("juce")) + && folder.getChildFile ("juce.h").exists() + && folder.getChildFile ("juce_Config.h").exists(); +} + +static const File lookInFolderForJuceFolder (const File& folder) +{ + for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();) + { + if (isJuceFolder (di.getFile())) + return di.getFile(); + } + + return File::nonexistent; +} + +const File findParentJuceFolder (const File& file) +{ + File f (file); + + while (f.exists() && f.getParentDirectory() != f) + { + if (isJuceFolder (f)) + return f; + + File found = lookInFolderForJuceFolder (f); + if (found.exists()) + return found; + + f = f.getParentDirectory(); + } + + return File::nonexistent; +} + +const File findDefaultJuceFolder() +{ + File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile)); + + if (! f.exists()) + f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory)); + + if (! f.exists()) + f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory)); + + return f; +} + +//============================================================================== +const String replaceCEscapeChars (const String& s) +{ + const int len = s.length(); + + String r; + r.preallocateStorage (len + 2); + bool lastWasHexEscapeCode = false; + + for (int i = 0; i < len; ++i) + { + const tchar c = s[i]; + + switch (c) + { + case '\t': + r << T("\\t"); + lastWasHexEscapeCode = false; + break; + case '\r': + r << T("\\r"); + lastWasHexEscapeCode = false; + break; + case '\n': + r << T("\\n"); + lastWasHexEscapeCode = false; + break; + case '\\': + r << T("\\\\"); + lastWasHexEscapeCode = false; + break; + case '\'': + r << T("\\\'"); + lastWasHexEscapeCode = false; + break; + case '\"': + r << T("\\\""); + lastWasHexEscapeCode = false; + break; + + default: + if (c < 128 && + ! (lastWasHexEscapeCode + && String (T("0123456789abcdefABCDEF")).containsChar (c))) // (have to avoid following a hex escape sequence with a valid hex digit) + { + r << c; + lastWasHexEscapeCode = false; + } + else + { + lastWasHexEscapeCode = true; + r << T("\\x") << String::toHexString ((int) c); + } + + break; + } + } + + return r; +} + +//============================================================================== +const String makeValidCppIdentifier (String s, + const bool capitalise, + const bool removeColons, + const bool allowTemplates) +{ + if (removeColons) + s = s.replaceCharacters (T(".,;:/@"), T("______")); + else + s = s.replaceCharacters (T(".,;/@"), T("_____")); + + int i; + for (i = s.length(); --i > 0;) + if (CharacterFunctions::isLetter (s[i]) + && CharacterFunctions::isLetter (s[i - 1]) + && CharacterFunctions::isUpperCase (s[i]) + && ! CharacterFunctions::isUpperCase (s[i - 1])) + s = s.substring (0, i) + T(" ") + s.substring (i); + + String allowedChars (T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789")); + if (allowTemplates) + allowedChars += T("<>"); + + if (! removeColons) + allowedChars += T(":"); + + StringArray words; + words.addTokens (s.retainCharacters (allowedChars), false); + words.trim(); + + String n (words[0]); + + if (capitalise) + n = n.toLowerCase(); + + for (i = 1; i < words.size(); ++i) + { + if (capitalise && words[i].length() > 1) + n << words[i].substring (0, 1).toUpperCase() + << words[i].substring (1).toLowerCase(); + else + n << words[i]; + } + + if (CharacterFunctions::isDigit (n[0])) + n = T("_") + n; + + // make sure it's not a reserved c++ keyword.. + static const tchar* const reservedWords[] = + { + T("auto"), T("const"), T("double"), T("float"), T("int"), T("short"), T("struct"), + T("return"), T("static"), T("union"), T("while"), T("asm"), T("dynamic_cast"), + T("unsigned"), T("break"), T("continue"), T("else"), T("for"), T("long"), T("signed"), + T("switch"), T("void"), T("case"), T("default"), T("enum"), T("goto"), T("register"), + T("sizeof"), T("typedef"), T("volatile"), T("char"), T("do"), T("extern"), T("if"), + T("namespace"), T("reinterpret_cast"), T("try"), T("bool"), T("explicit"), T("new"), + T("static_cast"), T("typeid"), T("catch"), T("false"), T("operator"), T("template"), + T("typename"), T("class"), T("friend"), T("private"), T("this"), T("using"), T("const_cast"), + T("inline"), T("public"), T("throw"), T("virtual"), T("delete"), T("mutable"), T("protected"), + T("true"), T("wchar_t"), T("and"), T("bitand"), T("compl"), T("not_eq"), T("or_eq"), + T("xor_eq"), T("and_eq"), T("bitor"), T("not"), T("or"), T("xor"), T("cin"), T("endl"), + T("INT_MIN"), T("iomanip"), T("main"), T("npos"), T("std"), T("cout"), T("include"), + T("INT_MAX"), T("iostream"), T("MAX_RAND"), T("NULL"), T("string"), T("id") + }; + + for (i = 0; i < numElementsInArray (reservedWords); ++i) + if (n == reservedWords[i]) + n << '_'; + + return n; +} + +//============================================================================== +const String floatToCode (const float v) +{ + String s ((double) (float) v, 4); + + if (s.containsChar (T('.'))) + s << 'f'; + else + s << ".0f"; + + return s; +} + +const String doubleToCode (const double v) +{ + String s (v, 7); + + if (! s.containsChar (T('.'))) + s << ".0"; + + return s; +} + +const String boolToCode (const bool b) +{ + return b ? T("true") : T("false"); +} + +const String colourToCode (const Colour& col) +{ + #define COL(col) Colours::col, + + const Colour colours[] = + { + #include "jucer_Colours.h" + Colours::transparentBlack + }; + + #undef COL + #define COL(col) #col, + static const char* colourNames[] = + { + #include "jucer_Colours.h" + 0 + }; + #undef COL + + for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i) + if (col == colours[i]) + return T("Colours::") + String (colourNames[i]); + + return T("Colour (0x") + hexString8Digits ((int) col.getARGB()) + T(')'); +} + +const String justificationToCode (const Justification& justification) +{ + switch (justification.getFlags()) + { + case Justification::centred: return "Justification::centred"; + case Justification::centredLeft: return "Justification::centredLeft"; + case Justification::centredRight: return "Justification::centredRight"; + case Justification::centredTop: return "Justification::centredTop"; + case Justification::centredBottom: return "Justification::centredBottom"; + case Justification::topLeft: return "Justification::topLeft"; + case Justification::topRight: return "Justification::topRight"; + case Justification::bottomLeft: return "Justification::bottomLeft"; + case Justification::bottomRight: return "Justification::bottomRight"; + case Justification::left: return "Justification::left"; + case Justification::right: return "Justification::right"; + case Justification::horizontallyCentred: return "Justification::horizontallyCentred"; + case Justification::top: return "Justification::top"; + case Justification::bottom: return "Justification::bottom"; + case Justification::verticallyCentred: return "Justification::verticallyCentred"; + case Justification::horizontallyJustified: return "Justification::horizontallyJustified"; + default: jassertfalse; break; + } + + return T("Justification (") + String (justification.getFlags()) + T(")"); +} + +const String castToFloat (const String& expression) +{ + if (expression.containsOnly (T("0123456789.f"))) + { + String s (expression.getFloatValue()); + + if (s.containsChar (T('.'))) + return s + T("f"); + + return s + T(".0f"); + } + + return T("(float) (") + expression + T(")"); +} + +const String indentCode (const String& code, const int numSpaces) +{ + if (numSpaces == 0) + return code; + + const String space (String::repeatedString (T(" "), numSpaces)); + + StringArray lines; + lines.addLines (code); + + for (int i = 1; i < lines.size(); ++i) + { + String s (lines[i].trimEnd()); + if (s.isNotEmpty()) + s = space + s; + + lines.set (i, s); + } + + return lines.joinIntoString (T("\n")); +} + +int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex) +{ + startIndex = jmax (0, startIndex); + + while (startIndex < lines.size()) + { + if (lines[startIndex].trimStart().startsWithIgnoreCase (text)) + return startIndex; + + ++startIndex; + } + + return -1; +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h new file mode 100644 index 0000000000..4ce4478ccd --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h @@ -0,0 +1,110 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + + +//============================================================================== +int64 calculateStreamHashCode (InputStream& stream); +int64 calculateFileHashCode (const File& file); +bool areFilesIdentical (const File& file1, const File& file2); + +bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes); +bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData); +bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData); + +bool containsAnyNonHiddenFiles (const File& folder); + +//============================================================================== +// String::hashCode64 actually hit some dupes, so this is a more powerful version. +const int64 hashCode64 (const String& s); +const String randomHexString (Random& random, int numChars); +const String hexString8Digits (int value); + +const String createAlphaNumericUID(); +const String createGUID (const String& seed); // Turns a seed into a windows GUID + +const String unixStylePath (const String& path); +const String windowsStylePath (const String& path); + +bool shouldPathsBeRelative (String path1, String path2); + +//============================================================================== +bool isJuceFolder (const File& folder); +const File findParentJuceFolder (const File& file); +const File findDefaultJuceFolder(); + +//============================================================================== +const String createIncludeStatement (const File& includeFile, const File& targetFile); +const String makeHeaderGuardName (const File& file); + +const String replaceCEscapeChars (const String& s); + +const String makeValidCppIdentifier (String s, + const bool capitalise, + const bool removeColons, + const bool allowTemplates); + +//============================================================================== +const String boolToCode (const bool b); +const String floatToCode (const float v); +const String doubleToCode (const double v); +const String colourToCode (const Colour& col); +const String justificationToCode (const Justification& justification); +const String castToFloat (const String& expression); + +//============================================================================== +const String indentCode (const String& code, const int numSpaces); + +int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex); + +//============================================================================== +class FileModificationDetector +{ +public: + FileModificationDetector (const File& file_) + : file (file_) + { + } + + const File& getFile() const { return file; } + + bool hasBeenModified() const + { + return fileModificationTime != file.getLastModificationTime() + && (fileSize != file.getSize() + || calculateFileHashCode (file) != fileHashCode); + } + + void updateHash() + { + fileModificationTime = file.getLastModificationTime(); + fileSize = file.getSize(); + fileHashCode = calculateFileHashCode (file); + } + +private: + File file; + Time fileModificationTime; + int64 fileHashCode, fileSize; +}; diff --git a/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h b/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h new file mode 100644 index 0000000000..fd761dd7c7 --- /dev/null +++ b/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h @@ -0,0 +1,107 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__ +#define __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__ + + +//============================================================================== +/** A ValueSource that remaps specific values to new values. +*/ +class ValueRemapperSource : public Value::ValueSource, + public Value::Listener +{ +public: + ValueRemapperSource (const Value& sourceValue_) + : sourceValue (sourceValue_) + { + } + + ValueRemapperSource (const Value& sourceValue_, const char** mappings) + : sourceValue (sourceValue_) + { + addMappings (mappings); + } + + ~ValueRemapperSource() {} + + void addMappings (const char** values) + { + while (values[0] != 0 && values[1] != 0) + { + addMapping (values[0], values[1]); + values += 2; + } + } + + void addMapping (const var& sourceValue, const var& remappedValue) + { + mappings.add (sourceValue); + mappings.add (remappedValue); + } + + const var getValue() const + { + const var sourceVar (sourceValue.getValue()); + + for (int i = 0; i < mappings.size(); i += 2) + if (sourceVar == mappings.getReference(i)) + return mappings.getReference (i + 1); + + return sourceVar; + } + + void setValue (const var& newValue) + { + for (int i = 1; i < mappings.size(); i += 2) + { + if (newValue == mappings.getReference(i)) + { + sourceValue = mappings.getReference (i - 1); + return; + } + } + + sourceValue = newValue; + } + + void valueChanged (Value&) + { + sendChangeMessage (false); + } + + //============================================================================== + juce_UseDebuggingNewOperator + +protected: + Value sourceValue; + Array mappings; + + ValueRemapperSource (const ValueRemapperSource&); + const ValueRemapperSource& operator= (const ValueRemapperSource&); +}; + + +#endif // __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__