| @@ -86,6 +86,7 @@ | |||||
| F2F98DA41146390D05A44EAD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectContentComponent.h; path = ../../Source/Project/jucer_ProjectContentComponent.h; sourceTree = SOURCE_ROOT; }; | F2F98DA41146390D05A44EAD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectContentComponent.h; path = ../../Source/Project/jucer_ProjectContentComponent.h; sourceTree = SOURCE_ROOT; }; | ||||
| 296E0498784BF03FA18B164B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectExporter.cpp; path = ../../Source/Project/jucer_ProjectExporter.cpp; sourceTree = SOURCE_ROOT; }; | 296E0498784BF03FA18B164B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ProjectExporter.cpp; path = ../../Source/Project/jucer_ProjectExporter.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 5DE419991013E7C0F203E99F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExporter.h; path = ../../Source/Project/jucer_ProjectExporter.h; sourceTree = SOURCE_ROOT; }; | 5DE419991013E7C0F203E99F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExporter.h; path = ../../Source/Project/jucer_ProjectExporter.h; sourceTree = SOURCE_ROOT; }; | ||||
| AB9EE4734D894FBF1CF62C5F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Android.h; path = ../../Source/Project/jucer_ProjectExport_Android.h; sourceTree = SOURCE_ROOT; }; | |||||
| 889715B0152919B2EAA1F5F9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Make.h; path = ../../Source/Project/jucer_ProjectExport_Make.h; sourceTree = SOURCE_ROOT; }; | 889715B0152919B2EAA1F5F9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_Make.h; path = ../../Source/Project/jucer_ProjectExport_Make.h; sourceTree = SOURCE_ROOT; }; | ||||
| 907F302BB89308CDB2C5FD0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_MSVC.h; path = ../../Source/Project/jucer_ProjectExport_MSVC.h; sourceTree = SOURCE_ROOT; }; | 907F302BB89308CDB2C5FD0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_MSVC.h; path = ../../Source/Project/jucer_ProjectExport_MSVC.h; sourceTree = SOURCE_ROOT; }; | ||||
| D250274734D729D2E0389A20 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_XCode.h; path = ../../Source/Project/jucer_ProjectExport_XCode.h; sourceTree = SOURCE_ROOT; }; | D250274734D729D2E0389A20 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ProjectExport_XCode.h; path = ../../Source/Project/jucer_ProjectExport_XCode.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -165,6 +166,7 @@ | |||||
| F2F98DA41146390D05A44EAD, | F2F98DA41146390D05A44EAD, | ||||
| 296E0498784BF03FA18B164B, | 296E0498784BF03FA18B164B, | ||||
| 5DE419991013E7C0F203E99F, | 5DE419991013E7C0F203E99F, | ||||
| AB9EE4734D894FBF1CF62C5F, | |||||
| 889715B0152919B2EAA1F5F9, | 889715B0152919B2EAA1F5F9, | ||||
| 907F302BB89308CDB2C5FD0E, | 907F302BB89308CDB2C5FD0E, | ||||
| D250274734D729D2E0389A20, | D250274734D729D2E0389A20, | ||||
| @@ -162,6 +162,7 @@ | |||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.cpp"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.cpp"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Android.h"/> | |||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | ||||
| @@ -162,6 +162,7 @@ | |||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.cpp"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.cpp"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExporter.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Android.h"/> | |||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | ||||
| <File RelativePath="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | <File RelativePath="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | ||||
| @@ -167,6 +167,7 @@ | |||||
| <ClInclude Include="..\..\Source\Project\jucer_Project.h"/> | <ClInclude Include="..\..\Source\Project\jucer_Project.h"/> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | <ClInclude Include="..\..\Source\Project\jucer_ProjectContentComponent.h"/> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExporter.h"/> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExporter.h"/> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Android.h"/> | |||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Make.h"/> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_MSVC.h"/> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_XCode.h"/> | ||||
| @@ -183,6 +183,9 @@ | |||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExporter.h"> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExporter.h"> | ||||
| <Filter>The Jucer\Project</Filter> | <Filter>The Jucer\Project</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Android.h"> | |||||
| <Filter>The Jucer\Project</Filter> | |||||
| </ClInclude> | |||||
| <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Make.h"> | <ClInclude Include="..\..\Source\Project\jucer_ProjectExport_Make.h"> | ||||
| <Filter>The Jucer\Project</Filter> | <Filter>The Jucer\Project</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| @@ -90,6 +90,8 @@ | |||||
| file="Source/Project/jucer_ProjectExporter.cpp"/> | file="Source/Project/jucer_ProjectExporter.cpp"/> | ||||
| <FILE id="KFY4Re5" name="jucer_ProjectExporter.h" compile="0" resource="0" | <FILE id="KFY4Re5" name="jucer_ProjectExporter.h" compile="0" resource="0" | ||||
| file="Source/Project/jucer_ProjectExporter.h"/> | file="Source/Project/jucer_ProjectExporter.h"/> | ||||
| <FILE id="N0uQAr" name="jucer_ProjectExport_Android.h" compile="0" | |||||
| resource="0" file="Source/Project/jucer_ProjectExport_Android.h"/> | |||||
| <FILE id="b8ouh7s" name="jucer_ProjectExport_Make.h" compile="0" resource="0" | <FILE id="b8ouh7s" name="jucer_ProjectExport_Make.h" compile="0" resource="0" | ||||
| file="Source/Project/jucer_ProjectExport_Make.h"/> | file="Source/Project/jucer_ProjectExport_Make.h"/> | ||||
| <FILE id="lbo8KcG" name="jucer_ProjectExport_MSVC.h" compile="0" resource="0" | <FILE id="lbo8KcG" name="jucer_ProjectExport_MSVC.h" compile="0" resource="0" | ||||
| @@ -448,6 +448,43 @@ const Image Project::getSmallIcon() | |||||
| return Image(); | return Image(); | ||||
| } | } | ||||
| const Image Project::getBestIconForSize (int size, bool returnNullIfNothingBigEnough) | |||||
| { | |||||
| Image im; | |||||
| const Image im1 (getSmallIcon()); | |||||
| const Image im2 (getBigIcon()); | |||||
| if (im1.isValid() && im2.isValid()) | |||||
| { | |||||
| if (im1.getWidth() >= size && im2.getWidth() >= size) | |||||
| im = im1.getWidth() < im2.getWidth() ? im1 : im2; | |||||
| else if (im1.getWidth() >= size) | |||||
| im = im1; | |||||
| else if (im2.getWidth() >= size) | |||||
| im = im2; | |||||
| else | |||||
| return Image(); | |||||
| } | |||||
| else | |||||
| { | |||||
| im = im1.isValid() ? im1 : im2; | |||||
| } | |||||
| if (size == im.getWidth() && size == im.getHeight()) | |||||
| return im; | |||||
| if (returnNullIfNothingBigEnough && im.getWidth() < size && im.getHeight() < size) | |||||
| return Image::null; | |||||
| Image newIm (Image::ARGB, size, size, true); | |||||
| Graphics g (newIm); | |||||
| g.drawImageWithin (im, 0, 0, size, size, | |||||
| RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); | |||||
| return newIm; | |||||
| } | |||||
| const StringPairArray Project::getPreprocessorDefs() const | const StringPairArray Project::getPreprocessorDefs() const | ||||
| { | { | ||||
| return parsePreprocessorDefs (getProjectPreprocessorDefs().toString()); | return parsePreprocessorDefs (getProjectPreprocessorDefs().toString()); | ||||
| @@ -109,6 +109,7 @@ public: | |||||
| Value getSmallIconImageItemID() const { return getProjectValue ("smallIcon"); } | Value getSmallIconImageItemID() const { return getProjectValue ("smallIcon"); } | ||||
| const Image getBigIcon(); | const Image getBigIcon(); | ||||
| const Image getSmallIcon(); | const Image getSmallIcon(); | ||||
| const Image getBestIconForSize (int size, bool returnNullIfNothingBigEnough); | |||||
| Value shouldBuildVST() const { return getProjectValue ("buildVST"); } | Value shouldBuildVST() const { return getProjectValue ("buildVST"); } | ||||
| Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); } | Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); } | ||||
| @@ -0,0 +1,374 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-10 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ | |||||
| #define __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ | |||||
| #include "jucer_ProjectExporter.h" | |||||
| //============================================================================== | |||||
| class AndroidProjectExporter : public ProjectExporter | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| static const char* getNameAndroid() { return "Android Project"; } | |||||
| static const char* getValueTreeTypeName() { return "ANDROID"; } | |||||
| static AndroidProjectExporter* createForSettings (Project& project, const ValueTree& settings) | |||||
| { | |||||
| if (settings.hasType (getValueTreeTypeName())) | |||||
| return new AndroidProjectExporter (project, settings); | |||||
| return 0; | |||||
| } | |||||
| //============================================================================== | |||||
| AndroidProjectExporter (Project& project_, const ValueTree& settings_) | |||||
| : ProjectExporter (project_, settings_) | |||||
| { | |||||
| name = getNameAndroid(); | |||||
| if (getTargetLocation().toString().isEmpty()) | |||||
| getTargetLocation() = getDefaultBuildsRootFolder() + "Android"; | |||||
| if (getSDKPath().toString().isEmpty()) | |||||
| getSDKPath() = "${user.home}/SDKs/android-sdk-mac_86"; | |||||
| if (getNDKPath().toString().isEmpty()) | |||||
| getNDKPath() = "${user.home}/SDKs/android-ndk-r4-crystax"; | |||||
| } | |||||
| //============================================================================== | |||||
| bool isDefaultFormatForCurrentOS() | |||||
| { | |||||
| #if JUCE_ANDROID | |||||
| return true; | |||||
| #else | |||||
| return false; | |||||
| #endif | |||||
| } | |||||
| bool isPossibleForCurrentProject() { return project.isGUIApplication(); } | |||||
| bool usesMMFiles() const { return false; } | |||||
| void launchProject() | |||||
| { | |||||
| } | |||||
| void createPropertyEditors (Array <PropertyComponent*>& props) | |||||
| { | |||||
| ProjectExporter::createPropertyEditors (props); | |||||
| props.add (new TextPropertyComponent (getSDKPath(), "Android SDK Path", 1024, false)); | |||||
| props.getLast()->setTooltip ("The path to the Android SDK folder on the target build machine"); | |||||
| props.add (new TextPropertyComponent (getNDKPath(), "Android NDK Path", 1024, false)); | |||||
| props.getLast()->setTooltip ("The path to the Android NDK folder on the target build machine"); | |||||
| } | |||||
| Value getSDKPath() const { return getSetting (Ids::androidSDKPath); } | |||||
| Value getNDKPath() const { return getSetting (Ids::androidNDKPath); } | |||||
| //============================================================================== | |||||
| void create() | |||||
| { | |||||
| const File target (getTargetFolder()); | |||||
| const File jniFolder (target.getChildFile ("jni")); | |||||
| createDirectoryOrThrow (target.getChildFile ("src/com")); | |||||
| createDirectoryOrThrow (jniFolder); | |||||
| createDirectoryOrThrow (target.getChildFile ("res/drawable-hdpi")); | |||||
| createDirectoryOrThrow (target.getChildFile ("res/drawable-mdpi")); | |||||
| createDirectoryOrThrow (target.getChildFile ("res/drawable-ldpi")); | |||||
| createDirectoryOrThrow (target.getChildFile ("res/values")); | |||||
| createDirectoryOrThrow (target.getChildFile ("libs")); | |||||
| createDirectoryOrThrow (target.getChildFile ("bin")); | |||||
| { | |||||
| ScopedPointer<XmlElement> manifest (createManifestXML()); | |||||
| writeXmlOrThrow (*manifest, target.getChildFile ("AndroidManifest.xml"), "utf-8", 100); | |||||
| } | |||||
| writeJNIMakefile (jniFolder.getChildFile ("Android.mk")); | |||||
| { | |||||
| ScopedPointer<XmlElement> antBuildXml (createAntBuildXML()); | |||||
| writeXmlOrThrow (*antBuildXml, target.getChildFile ("build.xml"), "UTF-8", 100); | |||||
| } | |||||
| writeBuildPropertiesFile (target.getChildFile ("build.properties")); | |||||
| writeDefaultPropertiesFile (target.getChildFile ("default.properties")); | |||||
| writeLocalPropertiesFile (target.getChildFile ("local.properties")); | |||||
| writeIcon (target.getChildFile ("res/drawable-hdpi/icon.png"), 72); | |||||
| writeIcon (target.getChildFile ("res/drawable-mdpi/icon.png"), 48); | |||||
| writeIcon (target.getChildFile ("res/drawable-ldpi/icon.png"), 36); | |||||
| writeStringsFile (target.getChildFile ("res/values/strings.xml")); | |||||
| } | |||||
| private: | |||||
| //============================================================================== | |||||
| XmlElement* createManifestXML() | |||||
| { | |||||
| XmlElement* manifest = new XmlElement ("manifest"); | |||||
| manifest->setAttribute ("xmlns:android", "http://schemas.android.com/apk/res/android"); | |||||
| manifest->setAttribute ("android:versionCode", "1"); | |||||
| manifest->setAttribute ("android:versionName", "1.0"); | |||||
| manifest->setAttribute ("package", "com.juce"); | |||||
| XmlElement* screens = manifest->createNewChildElement ("supports-screens"); | |||||
| screens->setAttribute ("android:smallScreens", "true"); | |||||
| screens->setAttribute ("android:normalScreens", "true"); | |||||
| screens->setAttribute ("android:largeScreens", "true"); | |||||
| screens->setAttribute ("android:xlargeScreens", "true"); | |||||
| screens->setAttribute ("android:anyDensity", "true"); | |||||
| XmlElement* app = manifest->createNewChildElement ("application"); | |||||
| app->setAttribute ("android:label", "@string/app_name"); | |||||
| app->setAttribute ("android:icon", "@drawable/icon"); | |||||
| XmlElement* act = app->createNewChildElement ("activity"); | |||||
| act->setAttribute ("android:name", "JuceAppActivity"); | |||||
| act->setAttribute ("android:label", "@string/app_name"); | |||||
| XmlElement* intent = act->createNewChildElement ("intent-filter"); | |||||
| intent->createNewChildElement ("action")->setAttribute ("android:name", "android.intent.action.MAIN"); | |||||
| intent->createNewChildElement ("category")->setAttribute ("android:name", "android.intent.category.LAUNCHER"); | |||||
| return manifest; | |||||
| } | |||||
| //============================================================================== | |||||
| void findAllFilesToCompile (const Project::Item& projectItem, Array<RelativePath>& 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 writeJNIMakefile (const File& file) | |||||
| { | |||||
| Array<RelativePath> 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; | |||||
| writeJNIMakefile (mo, files); | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| void writeJNIMakefile (OutputStream& out, const Array<RelativePath>& 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 | |||||
| << "LOCAL_PATH := $(call my-dir)" << newLine | |||||
| << newLine | |||||
| << "include $(CLEAR_VARS)" << newLine | |||||
| << newLine | |||||
| << "LOCAL_CPP_EXTENSION := cpp" << newLine | |||||
| << "LOCAL_MODULE := juce_jni" << newLine | |||||
| << "LOCAL_SRC_FILES := \\" << newLine; | |||||
| for (int i = 0; i < files.size(); ++i) | |||||
| out << " ../" << escapeSpaces (files.getReference(i).toUnixStyle()) << "\\" << newLine; | |||||
| out << newLine | |||||
| << "ifeq ($(CONFIG),Debug)" << newLine | |||||
| << " LOCAL_CFLAGS +=" << createPreprocessorDefs (true) << newLine | |||||
| << "else" << newLine | |||||
| << " LOCAL_CFLAGS +=" << createPreprocessorDefs (false) << newLine | |||||
| << "endif" << newLine | |||||
| << newLine | |||||
| << "include $(BUILD_SHARED_LIBRARY)" << newLine; | |||||
| } | |||||
| const String createPreprocessorDefs (bool forDebug) | |||||
| { | |||||
| StringPairArray defines; | |||||
| defines.set ("JUCE_ANDROID", "1"); | |||||
| if (forDebug) | |||||
| { | |||||
| defines.set ("DEBUG", "1"); | |||||
| defines.set ("_DEBUG", "1"); | |||||
| } | |||||
| else | |||||
| { | |||||
| defines.set ("NDEBUG", "1"); | |||||
| } | |||||
| for (int i = 0; i < project.getNumConfigurations(); ++i) | |||||
| { | |||||
| Project::BuildConfiguration config (project.getConfiguration(i)); | |||||
| if (config.isDebug() == forDebug) | |||||
| { | |||||
| defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); | |||||
| break; | |||||
| } | |||||
| } | |||||
| return createGCCPreprocessorFlags (defines); | |||||
| } | |||||
| //============================================================================== | |||||
| XmlElement* createAntBuildXML() | |||||
| { | |||||
| XmlElement* proj = new XmlElement ("project"); | |||||
| proj->setAttribute ("name", project.getProjectName().toString()); | |||||
| proj->setAttribute ("default", "help"); | |||||
| proj->createNewChildElement ("property")->setAttribute ("file", "local.properties"); | |||||
| proj->createNewChildElement ("property")->setAttribute ("file", "build.properties"); | |||||
| proj->createNewChildElement ("property")->setAttribute ("file", "default.properties"); | |||||
| XmlElement* path = proj->createNewChildElement ("path"); | |||||
| path->setAttribute ("id", "android.antlibs"); | |||||
| path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/anttasks.jar"); | |||||
| path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/sdklib.jar"); | |||||
| path->createNewChildElement ("pathelement")->setAttribute ("path", "${sdk.dir}/tools/lib/androidprefs.jar"); | |||||
| XmlElement* taskdef = proj->createNewChildElement ("taskdef"); | |||||
| taskdef->setAttribute ("name", "setup"); | |||||
| taskdef->setAttribute ("classname", "com.android.ant.SetupTask"); | |||||
| taskdef->setAttribute ("classpathref", "android.antlibs"); | |||||
| addNDKBuildStep (proj, "clean", "clean"); | |||||
| //addLinkStep (proj, "${basedir}/" + rebaseFromProjectFolderToBuildTarget (RelativePath()).toUnixStyle() + "/", "jni/app"); | |||||
| addLinkStep (proj, "${basedir}/" + getJucePathFromTargetFolder().toUnixStyle() + "/src/native/android/java/", "src/com/juce"); | |||||
| addNDKBuildStep (proj, "debug", "CONFIG=Debug"); | |||||
| addNDKBuildStep (proj, "release", "CONFIG=Release"); | |||||
| proj->createNewChildElement ("setup"); | |||||
| return proj; | |||||
| } | |||||
| static void addNDKBuildStep (XmlElement* project, const String& type, const String& arg) | |||||
| { | |||||
| XmlElement* target = project->createNewChildElement ("target"); | |||||
| target->setAttribute ("name", type); | |||||
| XmlElement* executable = target->createNewChildElement ("exec"); | |||||
| executable->setAttribute ("executable", "${ndk.dir}/ndk-build"); | |||||
| executable->setAttribute ("dir", "${basedir}"); | |||||
| executable->setAttribute ("failonerror", "true"); | |||||
| executable->createNewChildElement ("arg")->setAttribute ("value", arg); | |||||
| } | |||||
| static void addLinkStep (XmlElement* project, const String& from, const String& to) | |||||
| { | |||||
| XmlElement* executable = project->createNewChildElement ("exec"); | |||||
| executable->setAttribute ("executable", "ln"); | |||||
| executable->setAttribute ("dir", "${basedir}"); | |||||
| executable->setAttribute ("failonerror", "false"); | |||||
| executable->createNewChildElement ("arg")->setAttribute ("value", "-s"); | |||||
| executable->createNewChildElement ("arg")->setAttribute ("value", from); | |||||
| executable->createNewChildElement ("arg")->setAttribute ("value", to); | |||||
| } | |||||
| void writeBuildPropertiesFile (const File& file) | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo << "# This file is used to override default values used by the Ant build system." << newLine; | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| void writeDefaultPropertiesFile (const File& file) | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo << "# This file is used to override default values used by the Ant build system." << newLine | |||||
| << "# It is automatically generated - DO NOT EDIT IT or your changes will be lost!." << newLine | |||||
| << newLine | |||||
| << "target=android-9" | |||||
| << newLine; | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| void writeLocalPropertiesFile (const File& file) | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| mo << "# This file is used to override default values used by the Ant build system." << newLine | |||||
| << "# It is automatically generated by the Jucer - DO NOT EDIT IT or your changes will be lost!." << newLine | |||||
| << newLine | |||||
| << "sdk.dir=" << escapeSpaces (replacePreprocessorDefs (getAllPreprocessorDefs(), getSDKPath().toString())) << newLine | |||||
| << "ndk.dir=" << escapeSpaces (replacePreprocessorDefs (getAllPreprocessorDefs(), getNDKPath().toString())) << newLine | |||||
| << newLine; | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| void writeIcon (const File& file, int size) | |||||
| { | |||||
| Image im (project.getBestIconForSize (size, false)); | |||||
| if (im.isValid()) | |||||
| { | |||||
| PNGImageFormat png; | |||||
| MemoryOutputStream mo; | |||||
| if (! png.writeImageToStream (im, mo)) | |||||
| throw SaveError ("Can't generate Android icon file"); | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| } | |||||
| void writeStringsFile (const File& file) | |||||
| { | |||||
| XmlElement strings ("resources"); | |||||
| XmlElement* name = strings.createNewChildElement ("string"); | |||||
| name->setAttribute ("name", "app_name"); | |||||
| name->addTextElement (project.getProjectName().toString()); | |||||
| writeXmlOrThrow (strings, file, "utf-8", 100); | |||||
| } | |||||
| //============================================================================== | |||||
| JUCE_DECLARE_NON_COPYABLE (AndroidProjectExporter); | |||||
| }; | |||||
| #endif // __JUCER_PROJECTEXPORT_ANDROID_JUCEHEADER__ | |||||
| @@ -377,59 +377,23 @@ protected: | |||||
| out << dataBlock; | out << dataBlock; | ||||
| } | } | ||||
| static const Image getBestIconImage (const Image& im1, const Image& im2, int size) | |||||
| { | |||||
| Image im; | |||||
| if (im1.isValid() && im2.isValid()) | |||||
| { | |||||
| if (im1.getWidth() >= size && im2.getWidth() >= size) | |||||
| im = im1.getWidth() < im2.getWidth() ? im1 : im2; | |||||
| else if (im1.getWidth() >= size) | |||||
| im = im1; | |||||
| else if (im2.getWidth() >= size) | |||||
| im = im2; | |||||
| else | |||||
| return Image(); | |||||
| } | |||||
| else | |||||
| { | |||||
| im = im1.isValid() ? im1 : im2; | |||||
| } | |||||
| if (size == im.getWidth() && size == im.getHeight()) | |||||
| return im; | |||||
| if (im.getWidth() < size && im.getHeight() < size) | |||||
| return Image(); | |||||
| Image newIm (Image::ARGB, size, size, true); | |||||
| Graphics g (newIm); | |||||
| g.drawImageWithin (im, 0, 0, size, size, | |||||
| RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false); | |||||
| return newIm; | |||||
| } | |||||
| bool createIconFile() | bool createIconFile() | ||||
| { | { | ||||
| Array<Image> images; | Array<Image> images; | ||||
| const Image smallIcon (project.getSmallIcon()); | |||||
| const Image bigIcon (project.getBigIcon()); | |||||
| Image im (getBestIconImage (smallIcon, bigIcon, 16)); | |||||
| Image im (project.getBestIconForSize (16, true)); | |||||
| if (im.isValid()) | if (im.isValid()) | ||||
| images.add (im); | images.add (im); | ||||
| im = getBestIconImage (smallIcon, bigIcon, 32); | |||||
| im = project.getBestIconForSize (32, true); | |||||
| if (im.isValid()) | if (im.isValid()) | ||||
| images.add (im); | images.add (im); | ||||
| im = getBestIconImage (smallIcon, bigIcon, 48); | |||||
| im = project.getBestIconForSize (48, true); | |||||
| if (im.isValid()) | if (im.isValid()) | ||||
| images.add (im); | images.add (im); | ||||
| im = getBestIconImage (smallIcon, bigIcon, 128); | |||||
| im = project.getBestIconForSize (128, true); | |||||
| if (im.isValid()) | if (im.isValid()) | ||||
| images.add (im); | images.add (im); | ||||
| @@ -485,7 +449,7 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String create() | |||||
| void create() | |||||
| { | { | ||||
| createIconFile(); | createIconFile(); | ||||
| @@ -498,23 +462,15 @@ public: | |||||
| { | { | ||||
| XmlElement projectXml ("VisualStudioProject"); | XmlElement projectXml ("VisualStudioProject"); | ||||
| fillInProjectXml (projectXml); | fillInProjectXml (projectXml); | ||||
| MemoryOutputStream mo; | |||||
| projectXml.writeToStream (mo, String::empty, false, true, "UTF-8", 10); | |||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) | |||||
| return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); | |||||
| writeXmlOrThrow (projectXml, getVCProjFile(), "UTF-8", 10); | |||||
| } | } | ||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeSolutionFile (mo, getSolutionVersionString(), getVCProjFile()); | writeSolutionFile (mo, getSolutionVersionString(), getVCProjFile()); | ||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) | |||||
| return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); | |||||
| overwriteFileIfDifferentOrThrow (getSLNFile(), mo); | |||||
| } | } | ||||
| return String::empty; | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -873,25 +829,19 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String create() | |||||
| void create() | |||||
| { | { | ||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeProject (mo); | writeProject (mo); | ||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo)) | |||||
| return "Can't write to the VC project file: " + getDSPFile().getFullPathName(); | |||||
| overwriteFileIfDifferentOrThrow (getDSPFile(), mo); | |||||
| } | } | ||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeDSWFile (mo); | writeDSWFile (mo); | ||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo)) | |||||
| return "Can't write to the VC solution file: " + getDSWFile().getFullPathName(); | |||||
| overwriteFileIfDifferentOrThrow (getDSWFile(), mo); | |||||
| } | } | ||||
| return String::empty; | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -1140,41 +1090,28 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String create() | |||||
| void create() | |||||
| { | { | ||||
| createIconFile(); | createIconFile(); | ||||
| { | { | ||||
| XmlElement projectXml ("Project"); | XmlElement projectXml ("Project"); | ||||
| fillInProjectXml (projectXml); | fillInProjectXml (projectXml); | ||||
| MemoryOutputStream mo; | |||||
| projectXml.writeToStream (mo, String::empty, false, true, "utf-8", 100); | |||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo)) | |||||
| return "Can't write to the VC project file: " + getVCProjFile().getFullPathName(); | |||||
| writeXmlOrThrow (projectXml, getVCProjFile(), "utf-8", 100); | |||||
| } | } | ||||
| { | { | ||||
| XmlElement filtersXml ("Project"); | XmlElement filtersXml ("Project"); | ||||
| fillInFiltersXml (filtersXml); | fillInFiltersXml (filtersXml); | ||||
| MemoryOutputStream mo; | |||||
| filtersXml.writeToStream (mo, String::empty, false, true, "utf-8", 100); | |||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFiltersFile(), mo)) | |||||
| return "Can't write to the VC project file: " + getVCProjFiltersFile().getFullPathName(); | |||||
| writeXmlOrThrow (filtersXml, getVCProjFiltersFile(), "utf-8", 100); | |||||
| } | } | ||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeSolutionFile (mo, "11.00", getVCProjFile()); | writeSolutionFile (mo, "11.00", getVCProjFile()); | ||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo)) | |||||
| return "Can't write to the VC solution file: " + getSLNFile().getFullPathName(); | |||||
| overwriteFileIfDifferentOrThrow (getSLNFile(), mo); | |||||
| } | } | ||||
| return String::empty; | |||||
| } | } | ||||
| protected: | protected: | ||||
| @@ -83,7 +83,7 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String create() | |||||
| void create() | |||||
| { | { | ||||
| Array<RelativePath> files; | Array<RelativePath> files; | ||||
| findAllFilesToCompile (project.getMainGroup(), files); | findAllFilesToCompile (project.getMainGroup(), files); | ||||
| @@ -99,11 +99,7 @@ public: | |||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeMakefile (mo, files); | writeMakefile (mo, files); | ||||
| const File makefile (getTargetFolder().getChildFile ("Makefile")); | |||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (makefile, mo)) | |||||
| return "Can't write to the Makefile: " + makefile.getFullPathName(); | |||||
| return String::empty; | |||||
| overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo); | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -137,17 +133,7 @@ private: | |||||
| defines.set ("NDEBUG", "1"); | defines.set ("NDEBUG", "1"); | ||||
| } | } | ||||
| defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)); | |||||
| for (int i = 0; i < defines.size(); ++i) | |||||
| { | |||||
| String def (defines.getAllKeys()[i]); | |||||
| const String value (defines.getAllValues()[i]); | |||||
| if (value.isNotEmpty()) | |||||
| def << "=" << value; | |||||
| out << " -D " << def.quoted(); | |||||
| } | |||||
| out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config))); | |||||
| } | } | ||||
| void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config) | void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config) | ||||
| @@ -334,11 +320,6 @@ private: | |||||
| out << "-include $(OBJECTS:%.o=%.d)" << newLine; | out << "-include $(OBJECTS:%.o=%.d)" << newLine; | ||||
| } | } | ||||
| static const String escapeSpaces (const String& s) | |||||
| { | |||||
| return s.replace (" ", "\\ "); | |||||
| } | |||||
| const String getObjectFileFor (const RelativePath& file) const | const String getObjectFileFor (const RelativePath& file) const | ||||
| { | { | ||||
| return file.getFileNameWithoutExtension() | return file.getFileNameWithoutExtension() | ||||
| @@ -106,16 +106,14 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String create() | |||||
| void create() | |||||
| { | { | ||||
| infoPlistFile = getTargetFolder().getChildFile ("Info.plist"); | infoPlistFile = getTargetFolder().getChildFile ("Info.plist"); | ||||
| if (! createIconFile()) | |||||
| return "Can't write the icon file"; | |||||
| createIconFile(); | |||||
| File projectBundle (getProjectBundle()); | File projectBundle (getProjectBundle()); | ||||
| if (! projectBundle.createDirectory()) | |||||
| return "Can't write to the target directory"; | |||||
| createDirectoryOrThrow (projectBundle); | |||||
| createObjects(); | createObjects(); | ||||
| @@ -124,15 +122,10 @@ public: | |||||
| { | { | ||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| writeProjectFile (mo); | writeProjectFile (mo); | ||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo)) | |||||
| return "Can't write to file: " + projectFile.getFullPathName(); | |||||
| overwriteFileIfDifferentOrThrow (projectFile, mo); | |||||
| } | } | ||||
| if (! writeInfoPlistFile()) | |||||
| return "Can't write the Info.plist file"; | |||||
| return String::empty; | |||||
| writeInfoPlistFile(); | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -303,7 +296,7 @@ private: | |||||
| out << data; | out << data; | ||||
| } | } | ||||
| bool createIconFile() | |||||
| void createIconFile() | |||||
| { | { | ||||
| Array<Image> images; | Array<Image> images; | ||||
| @@ -315,20 +308,20 @@ private: | |||||
| if (smallIcon.isValid()) | if (smallIcon.isValid()) | ||||
| images.add (smallIcon); | images.add (smallIcon); | ||||
| if (images.size() == 0) | |||||
| return true; | |||||
| MemoryOutputStream mo; | |||||
| writeIcnsFile (images, mo); | |||||
| if (images.size() > 0) | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| writeIcnsFile (images, mo); | |||||
| iconFile = getTargetFolder().getChildFile ("Icon.icns"); | |||||
| return FileHelpers::overwriteFileWithNewDataIfDifferent (iconFile, mo); | |||||
| iconFile = getTargetFolder().getChildFile ("Icon.icns"); | |||||
| overwriteFileIfDifferentOrThrow (iconFile, mo); | |||||
| } | |||||
| } | } | ||||
| bool writeInfoPlistFile() | |||||
| void writeInfoPlistFile() | |||||
| { | { | ||||
| if (! hasPList()) | if (! hasPList()) | ||||
| return true; | |||||
| return; | |||||
| XmlElement plist ("plist"); | XmlElement plist ("plist"); | ||||
| XmlElement* dict = plist.createNewChildElement ("dict"); | XmlElement* dict = plist.createNewChildElement ("dict"); | ||||
| @@ -353,7 +346,7 @@ private: | |||||
| addPlistDictionaryKey (dict, "CFBundleVersion", project.getVersion().toString()); | addPlistDictionaryKey (dict, "CFBundleVersion", project.getVersion().toString()); | ||||
| StringArray documentExtensions; | StringArray documentExtensions; | ||||
| documentExtensions.addTokens (replacePreprocessorDefs (project.getPreprocessorDefs(), getSetting ("documentExtensions").toString()), | |||||
| documentExtensions.addTokens (replacePreprocessorDefs (getAllPreprocessorDefs(), getSetting ("documentExtensions").toString()), | |||||
| ",", String::empty); | ",", String::empty); | ||||
| documentExtensions.trim(); | documentExtensions.trim(); | ||||
| documentExtensions.removeEmptyStrings (true); | documentExtensions.removeEmptyStrings (true); | ||||
| @@ -380,7 +373,7 @@ private: | |||||
| MemoryOutputStream mo; | MemoryOutputStream mo; | ||||
| plist.writeToStream (mo, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); | plist.writeToStream (mo, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); | ||||
| return FileHelpers::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo); | |||||
| overwriteFileIfDifferentOrThrow (infoPlistFile, mo); | |||||
| } | } | ||||
| const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) | const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config) | ||||
| @@ -27,6 +27,7 @@ | |||||
| #include "jucer_ProjectExport_Make.h" | #include "jucer_ProjectExport_Make.h" | ||||
| #include "jucer_ProjectExport_MSVC.h" | #include "jucer_ProjectExport_MSVC.h" | ||||
| #include "jucer_ProjectExport_XCode.h" | #include "jucer_ProjectExport_XCode.h" | ||||
| #include "jucer_ProjectExport_Android.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -55,6 +56,7 @@ const StringArray ProjectExporter::getExporterNames() | |||||
| s.add (MSVCProjectExporterVC2008::getName()); | s.add (MSVCProjectExporterVC2008::getName()); | ||||
| s.add (MSVCProjectExporterVC2010::getName()); | s.add (MSVCProjectExporterVC2010::getName()); | ||||
| s.add (MakefileProjectExporter::getNameLinux()); | s.add (MakefileProjectExporter::getNameLinux()); | ||||
| //s.add (AndroidProjectExporter::getNameAndroid()); | |||||
| return s; | return s; | ||||
| } | } | ||||
| @@ -71,6 +73,7 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int | |||||
| case 4: exp = new MSVCProjectExporterVC2008 (project, ValueTree (MSVCProjectExporterVC2008::getValueTreeTypeName())); break; | case 4: exp = new MSVCProjectExporterVC2008 (project, ValueTree (MSVCProjectExporterVC2008::getValueTreeTypeName())); break; | ||||
| case 5: exp = new MSVCProjectExporterVC2010 (project, ValueTree (MSVCProjectExporterVC2010::getValueTreeTypeName())); break; | case 5: exp = new MSVCProjectExporterVC2010 (project, ValueTree (MSVCProjectExporterVC2010::getValueTreeTypeName())); break; | ||||
| case 6: exp = new MakefileProjectExporter (project, ValueTree (MakefileProjectExporter::getValueTreeTypeName())); break; | case 6: exp = new MakefileProjectExporter (project, ValueTree (MakefileProjectExporter::getValueTreeTypeName())); break; | ||||
| case 7: exp = new AndroidProjectExporter (project, ValueTree (AndroidProjectExporter::getValueTreeTypeName())); break; | |||||
| default: jassertfalse; return 0; | default: jassertfalse; return 0; | ||||
| } | } | ||||
| @@ -93,6 +96,7 @@ ProjectExporter* ProjectExporter::createExporter (Project& project, const ValueT | |||||
| if (exp == 0) exp = MSVCProjectExporterVC2010::createForSettings (project, settings); | if (exp == 0) exp = MSVCProjectExporterVC2010::createForSettings (project, settings); | ||||
| if (exp == 0) exp = XCodeProjectExporter::createForSettings (project, settings); | if (exp == 0) exp = XCodeProjectExporter::createForSettings (project, settings); | ||||
| if (exp == 0) exp = MakefileProjectExporter::createForSettings (project, settings); | if (exp == 0) exp = MakefileProjectExporter::createForSettings (project, settings); | ||||
| if (exp == 0) exp = AndroidProjectExporter::createForSettings (project, settings); | |||||
| jassert (exp != 0); | jassert (exp != 0); | ||||
| return exp; | return exp; | ||||
| @@ -208,6 +212,14 @@ const StringPairArray ProjectExporter::getAllPreprocessorDefs (const Project::Bu | |||||
| return defs; | return defs; | ||||
| } | } | ||||
| const StringPairArray ProjectExporter::getAllPreprocessorDefs() const | |||||
| { | |||||
| StringPairArray defs (mergePreprocessorDefs (project.getPreprocessorDefs(), | |||||
| parsePreprocessorDefs (getExporterPreprocessorDefs().toString()))); | |||||
| defs.set (getExporterIdentifierMacro(), "1"); | |||||
| return defs; | |||||
| } | |||||
| const String ProjectExporter::replacePreprocessorTokens (const Project::BuildConfiguration& config, const String& sourceString) const | const String ProjectExporter::replacePreprocessorTokens (const Project::BuildConfiguration& config, const String& sourceString) const | ||||
| { | { | ||||
| return replacePreprocessorDefs (getAllPreprocessorDefs (config), sourceString); | return replacePreprocessorDefs (getAllPreprocessorDefs (config), sourceString); | ||||
| @@ -53,7 +53,7 @@ public: | |||||
| virtual bool usesMMFiles() const = 0; | virtual bool usesMMFiles() const = 0; | ||||
| virtual void createPropertyEditors (Array <PropertyComponent*>& props); | virtual void createPropertyEditors (Array <PropertyComponent*>& props); | ||||
| virtual void launchProject() = 0; | virtual void launchProject() = 0; | ||||
| virtual const String create() = 0; | |||||
| virtual void create() = 0; // may throw a SaveError | |||||
| virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const; | virtual bool shouldFileBeCompiledByDefault (const RelativePath& path) const; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -78,7 +78,11 @@ public: | |||||
| Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); } | Value getExtraLinkerFlags() const { return getSetting (Ids::extraLinkerFlags); } | ||||
| Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } | Value getExporterPreprocessorDefs() const { return getSetting (Ids::extraDefs); } | ||||
| const StringPairArray getAllPreprocessorDefs (const Project::BuildConfiguration& config) const; // includes inherited ones.. | |||||
| // includes exporter, project + config defs | |||||
| const StringPairArray getAllPreprocessorDefs (const Project::BuildConfiguration& config) const; | |||||
| // includes exporter + project defs.. | |||||
| const StringPairArray getAllPreprocessorDefs() const; | |||||
| const String replacePreprocessorTokens (const Project::BuildConfiguration& config, | const String replacePreprocessorTokens (const Project::BuildConfiguration& config, | ||||
| const String& sourceString) const; | const String& sourceString) const; | ||||
| @@ -95,6 +99,20 @@ public: | |||||
| Array<RelativePath> juceWrapperFiles; | Array<RelativePath> juceWrapperFiles; | ||||
| RelativePath juceWrapperFolder; | RelativePath juceWrapperFolder; | ||||
| // An exception that can be thrown by the create() method. | |||||
| class SaveError | |||||
| { | |||||
| public: | |||||
| SaveError (const String& error) : message (error) | |||||
| {} | |||||
| SaveError (const File& fileThatFailedToWrite) | |||||
| : message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName()) | |||||
| {} | |||||
| String message; | |||||
| }; | |||||
| protected: | protected: | ||||
| //============================================================================== | //============================================================================== | ||||
| Project& project; | Project& project; | ||||
| @@ -103,7 +121,7 @@ protected: | |||||
| const RelativePath getJucePathFromTargetFolder() const; | const RelativePath getJucePathFromTargetFolder() const; | ||||
| const String getDefaultBuildsRootFolder() const { return "Builds/"; } | |||||
| static const String getDefaultBuildsRootFolder() { return "Builds/"; } | |||||
| const Array<RelativePath> getVSTFilesRequired() const; | const Array<RelativePath> getVSTFilesRequired() const; | ||||
| @@ -118,6 +136,26 @@ protected: | |||||
| const RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const; | const RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const; | ||||
| //============================================================================== | |||||
| static void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData) | |||||
| { | |||||
| if (! FileHelpers::overwriteFileWithNewDataIfDifferent (file, newData)) | |||||
| throw SaveError (file); | |||||
| } | |||||
| static void createDirectoryOrThrow (const File& dirToCreate) | |||||
| { | |||||
| if (! dirToCreate.createDirectory()) | |||||
| throw SaveError ("Can't create folder: " + dirToCreate.getFullPathName()); | |||||
| } | |||||
| static void writeXmlOrThrow (const XmlElement& xml, const File& file, const String& encoding, int maxCharsPerLine) | |||||
| { | |||||
| MemoryOutputStream mo; | |||||
| xml.writeToStream (mo, String::empty, false, true, encoding, maxCharsPerLine); | |||||
| overwriteFileIfDifferentOrThrow (file, mo); | |||||
| } | |||||
| private: | private: | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter); | ||||
| }; | }; | ||||
| @@ -515,10 +515,14 @@ private: | |||||
| if (project.isAudioPlugin()) | if (project.isAudioPlugin()) | ||||
| exporter->juceWrapperFiles.add (RelativePath (pluginCharacteristicsFile, targetFolder, RelativePath::buildTargetFolder)); | exporter->juceWrapperFiles.add (RelativePath (pluginCharacteristicsFile, targetFolder, RelativePath::buildTargetFolder)); | ||||
| String error = exporter->create(); | |||||
| if (error.isNotEmpty()) | |||||
| errors.add (error); | |||||
| try | |||||
| { | |||||
| exporter->create(); | |||||
| } | |||||
| catch (ProjectExporter::SaveError& error) | |||||
| { | |||||
| errors.add (error.message); | |||||
| } | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -77,46 +77,45 @@ const String createGUID (const String& seed) | |||||
| return guid; | return guid; | ||||
| } | } | ||||
| //============================================================================== | |||||
| static void skipWhitespace (const String& s, int& i) | |||||
| const String escapeSpaces (const String& s) | |||||
| { | { | ||||
| while (CharacterFunctions::isWhitespace (s[i])) | |||||
| ++i; | |||||
| return s.replace (" ", "\\ "); | |||||
| } | } | ||||
| const StringPairArray parsePreprocessorDefs (const String& s) | |||||
| //============================================================================== | |||||
| const StringPairArray parsePreprocessorDefs (const String& text) | |||||
| { | { | ||||
| StringPairArray result; | StringPairArray result; | ||||
| int i = 0; | |||||
| String::CharPointerType s (text.getCharPointer()); | |||||
| while (s[i] != 0) | |||||
| while (! s.isEmpty()) | |||||
| { | { | ||||
| String token, value; | String token, value; | ||||
| skipWhitespace (s, i); | |||||
| s = s.findEndOfWhitespace(); | |||||
| while (s[i] != 0 && s[i] != '=' && ! CharacterFunctions::isWhitespace (s[i])) | |||||
| token << s[i++]; | |||||
| while ((! s.isEmpty()) && *s != '=' && ! s.isWhitespace()) | |||||
| token << s.getAndAdvance(); | |||||
| skipWhitespace (s, i); | |||||
| s = s.findEndOfWhitespace(); | |||||
| if (s[i] == '=') | |||||
| if (*s == '=') | |||||
| { | { | ||||
| ++i; | |||||
| ++s; | |||||
| skipWhitespace (s, i); | |||||
| s = s.findEndOfWhitespace(); | |||||
| while (s[i] != 0 && ! CharacterFunctions::isWhitespace (s[i])) | |||||
| while ((! s.isEmpty()) && ! s.isWhitespace()) | |||||
| { | { | ||||
| if (s[i] == ',') | |||||
| if (*s == ',') | |||||
| { | { | ||||
| ++i; | |||||
| ++s; | |||||
| break; | break; | ||||
| } | } | ||||
| if (s[i] == '\\' && (s[i + 1] == ' ' || s[i + 1] == ',')) | |||||
| ++i; | |||||
| if (*s == '\\' && (s[1] == ' ' || s[1] == ',')) | |||||
| ++s; | |||||
| value << s[i++]; | |||||
| value << s.getAndAdvance(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -135,6 +134,23 @@ const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, cons | |||||
| return inheritedDefs; | return inheritedDefs; | ||||
| } | } | ||||
| const String createGCCPreprocessorFlags (const StringPairArray& defs) | |||||
| { | |||||
| String s; | |||||
| for (int i = 0; i < defs.size(); ++i) | |||||
| { | |||||
| String def (defs.getAllKeys()[i]); | |||||
| const String value (defs.getAllValues()[i]); | |||||
| if (value.isNotEmpty()) | |||||
| def << "=" << value; | |||||
| s += " -D " + def.quoted(); | |||||
| } | |||||
| return s; | |||||
| } | |||||
| const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString) | const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString) | ||||
| { | { | ||||
| for (int i = 0; i < definitions.size(); ++i) | for (int i = 0; i < definitions.size(); ++i) | ||||
| @@ -33,8 +33,11 @@ const String hexString8Digits (int value); | |||||
| const String createAlphaNumericUID(); | const String createAlphaNumericUID(); | ||||
| const String createGUID (const String& seed); // Turns a seed into a windows GUID | const String createGUID (const String& seed); // Turns a seed into a windows GUID | ||||
| const String escapeSpaces (const String& text); // replaces spaces with blackslash-space | |||||
| const StringPairArray parsePreprocessorDefs (const String& defs); | const StringPairArray parsePreprocessorDefs (const String& defs); | ||||
| const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs); | const StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs); | ||||
| const String createGCCPreprocessorFlags (const StringPairArray& defs); | |||||
| const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString); | const String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString); | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -113,6 +113,8 @@ namespace Ids | |||||
| DECLARE_ID (memberName); | DECLARE_ID (memberName); | ||||
| DECLARE_ID (focusOrder); | DECLARE_ID (focusOrder); | ||||
| DECLARE_ID (hidden); | DECLARE_ID (hidden); | ||||
| DECLARE_ID (androidSDKPath); | |||||
| DECLARE_ID (androidNDKPath); | |||||
| const Identifier class_ ("class"); | const Identifier class_ ("class"); | ||||
| const Identifier id_ ("id"); | const Identifier id_ ("id"); | ||||
| @@ -776,6 +776,7 @@ protected: | |||||
| #include <net/if.h> | #include <net/if.h> | ||||
| #include <sys/sysinfo.h> | #include <sys/sysinfo.h> | ||||
| #include <sys/file.h> | #include <sys/file.h> | ||||
| #include <sys/prctl.h> | |||||
| #include <signal.h> | #include <signal.h> | ||||
| /* Got a build error here? You'll need to install the freetype library... | /* Got a build error here? You'll need to install the freetype library... | ||||
| @@ -2202,6 +2203,16 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() | |||||
| static_jassert (sizeof (uint32) == 4); | static_jassert (sizeof (uint32) == 4); | ||||
| static_jassert (sizeof (int64) == 8); | static_jassert (sizeof (int64) == 8); | ||||
| static_jassert (sizeof (uint64) == 8); | static_jassert (sizeof (uint64) == 8); | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF8 | |||||
| static_jassert (sizeof (wchar_t) == 1); | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| static_jassert (sizeof (wchar_t) == 2); | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| static_jassert (sizeof (wchar_t) == 4); | |||||
| #else | |||||
| #error "native wchar_t size is unknown" | |||||
| #endif | |||||
| } | } | ||||
| JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() | JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() | ||||
| @@ -11142,14 +11153,14 @@ int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* | |||||
| int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() | int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return (int) wcsftime (dest, maxChars, format, tm); | |||||
| #else | |||||
| HeapBlock <char> tempDest; | HeapBlock <char> tempDest; | ||||
| tempDest.calloc (maxChars + 2); | tempDest.calloc (maxChars + 2); | ||||
| int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); | int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); | ||||
| CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); | CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); | ||||
| return result; | return result; | ||||
| #else | |||||
| return (int) wcsftime (dest, maxChars, format, tm); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -11334,6 +11345,14 @@ BEGIN_JUCE_NAMESPACE | |||||
| #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | ||||
| #endif | #endif | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF8 | |||||
| typedef CharPointer_UTF8 CharPointer_wchar_t; | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| typedef CharPointer_UTF16 CharPointer_wchar_t; | |||||
| #else | |||||
| typedef CharPointer_UTF32 CharPointer_wchar_t; | |||||
| #endif | |||||
| NewLine newLine; | NewLine newLine; | ||||
| class StringHolder | class StringHolder | ||||
| @@ -11550,7 +11569,7 @@ String::String (const char* const t) | |||||
| because there's no other way to represent these strings in a way that isn't dependent on | because there's no other way to represent these strings in a way that isn't dependent on | ||||
| the compiler, source code editor and platform. | the compiler, source code editor and platform. | ||||
| */ | */ | ||||
| jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | |||||
| jassert (t == 0 || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | |||||
| } | } | ||||
| String::String (const char* const t, const size_t maxChars) | String::String (const char* const t, const size_t maxChars) | ||||
| @@ -11569,7 +11588,7 @@ String::String (const char* const t, const size_t maxChars) | |||||
| because there's no other way to represent these strings in a way that isn't dependent on | because there's no other way to represent these strings in a way that isn't dependent on | ||||
| the compiler, source code editor and platform. | the compiler, source code editor and platform. | ||||
| */ | */ | ||||
| jassert (CharPointer_ASCII::isValidString (t, (int) maxChars)); | |||||
| jassert (t == 0 || CharPointer_ASCII::isValidString (t, (int) maxChars)); | |||||
| } | } | ||||
| String::String (const juce_wchar* const t) | String::String (const juce_wchar* const t) | ||||
| @@ -11607,14 +11626,16 @@ String::String (const CharPointer_ASCII& t) | |||||
| { | { | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| String::String (const wchar_t* const t) | String::String (const wchar_t* const t) | ||||
| : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) | |||||
| : text (StringHolder::createFromCharPointer | |||||
| (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (t)))) | |||||
| { | { | ||||
| } | } | ||||
| String::String (const wchar_t* const t, size_t maxChars) | String::String (const wchar_t* const t, size_t maxChars) | ||||
| : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t), maxChars)) | |||||
| : text (StringHolder::createFromCharPointer | |||||
| (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (t)), maxChars)) | |||||
| { | { | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -11997,7 +12018,7 @@ String& String::operator+= (const juce_wchar ch) | |||||
| return operator+= (static_cast <const juce_wchar*> (asString)); | return operator+= (static_cast <const juce_wchar*> (asString)); | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| String& String::operator+= (const wchar_t ch) | String& String::operator+= (const wchar_t ch) | ||||
| { | { | ||||
| return operator+= ((juce_wchar) ch); | return operator+= ((juce_wchar) ch); | ||||
| @@ -12065,7 +12086,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar | |||||
| return string1 += string2; | return string1 += string2; | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | ||||
| { | { | ||||
| return string1 += string2; | return string1 += string2; | ||||
| @@ -12073,7 +12094,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) | ||||
| { | { | ||||
| string1.appendCharPointer (CharPointer_UTF16 (string2)); | |||||
| string1.appendCharPointer (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (string2))); | |||||
| return string1; | return string1; | ||||
| } | } | ||||
| @@ -13383,9 +13404,7 @@ const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) | |||||
| const char* String::toCString() const | const char* String::toCString() const | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return toUTF8(); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| if (isEmpty()) | if (isEmpty()) | ||||
| return reinterpret_cast <const char*> (text.getAddress()); | return reinterpret_cast <const char*> (text.getAddress()); | ||||
| @@ -13394,29 +13413,31 @@ const char* String::toCString() const | |||||
| wcstombs (extraSpace, text, len); | wcstombs (extraSpace, text, len); | ||||
| extraSpace [len] = 0; | extraSpace [len] = 0; | ||||
| return extraSpace; | return extraSpace; | ||||
| #else | |||||
| return toUTF8(); | |||||
| #endif | #endif | ||||
| } | } | ||||
| int String::getNumBytesAsCString() const throw() | int String::getNumBytesAsCString() const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return getNumBytesAsUTF8(); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return (int) wcstombs (0, text, 0); | return (int) wcstombs (0, text, 0); | ||||
| #else | |||||
| return getNumBytesAsUTF8(); | |||||
| #endif | #endif | ||||
| } | } | ||||
| int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() | int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return copyToUTF8 (destBuffer, maxBufferSizeBytes); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); | const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); | ||||
| if (destBuffer != 0 && numBytes >= 0) | if (destBuffer != 0 && numBytes >= 0) | ||||
| destBuffer [numBytes] = 0; | destBuffer [numBytes] = 0; | ||||
| return numBytes; | return numBytes; | ||||
| #else | |||||
| return copyToUTF8 (destBuffer, maxBufferSizeBytes); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -253997,8 +254018,13 @@ void Thread::killThread() | |||||
| } | } | ||||
| } | } | ||||
| void Thread::setCurrentThreadName (const String& /*name*/) | |||||
| void Thread::setCurrentThreadName (const String& name) | |||||
| { | { | ||||
| #if JUCE_MAC | |||||
| pthread_setname_np (name.toUTF8()); | |||||
| #elif JUCE_LINUX | |||||
| prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); | |||||
| #endif | |||||
| } | } | ||||
| bool Thread::setThreadPriority (void* handle, int priority) | bool Thread::setThreadPriority (void* handle, int priority) | ||||
| @@ -263904,8 +263930,13 @@ void Thread::killThread() | |||||
| } | } | ||||
| } | } | ||||
| void Thread::setCurrentThreadName (const String& /*name*/) | |||||
| void Thread::setCurrentThreadName (const String& name) | |||||
| { | { | ||||
| #if JUCE_MAC | |||||
| pthread_setname_np (name.toUTF8()); | |||||
| #elif JUCE_LINUX | |||||
| prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); | |||||
| #endif | |||||
| } | } | ||||
| bool Thread::setThreadPriority (void* handle, int priority) | bool Thread::setThreadPriority (void* handle, int priority) | ||||
| @@ -267538,6 +267569,8 @@ END_JUCE_NAMESPACE | |||||
| - (bool) makeActive; | - (bool) makeActive; | ||||
| - (void) makeInactive; | - (void) makeInactive; | ||||
| - (void) reshape; | - (void) reshape; | ||||
| - (void) rightMouseDown: (NSEvent*) ev; | |||||
| - (void) rightMouseUp: (NSEvent*) ev; | |||||
| @end | @end | ||||
| @implementation ThreadSafeNSOpenGLView | @implementation ThreadSafeNSOpenGLView | ||||
| @@ -267606,6 +267639,16 @@ END_JUCE_NAMESPACE | |||||
| needsUpdate = true; | needsUpdate = true; | ||||
| } | } | ||||
| - (void) rightMouseDown: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseDown: ev]; | |||||
| } | |||||
| - (void) rightMouseUp: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseUp: ev]; | |||||
| } | |||||
| @end | @end | ||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| @@ -273176,6 +273219,8 @@ END_JUCE_NAMESPACE | |||||
| - (bool) makeActive; | - (bool) makeActive; | ||||
| - (void) makeInactive; | - (void) makeInactive; | ||||
| - (void) reshape; | - (void) reshape; | ||||
| - (void) rightMouseDown: (NSEvent*) ev; | |||||
| - (void) rightMouseUp: (NSEvent*) ev; | |||||
| @end | @end | ||||
| @implementation ThreadSafeNSOpenGLView | @implementation ThreadSafeNSOpenGLView | ||||
| @@ -273244,6 +273289,16 @@ END_JUCE_NAMESPACE | |||||
| needsUpdate = true; | needsUpdate = true; | ||||
| } | } | ||||
| - (void) rightMouseDown: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseDown: ev]; | |||||
| } | |||||
| - (void) rightMouseUp: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseUp: ev]; | |||||
| } | |||||
| @end | @end | ||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| @@ -278567,7 +278622,6 @@ public: | |||||
| inline operator jobject() const throw() { return obj; } | inline operator jobject() const throw() { return obj; } | ||||
| inline jobject get() const throw() { return obj; } | inline jobject get() const throw() { return obj; } | ||||
| inline JNIEnv* getEnv() const throw() { return env; } | inline JNIEnv* getEnv() const throw() { return env; } | ||||
| #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ | #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ | ||||
| @@ -278601,6 +278655,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| JNIEnv* env; | JNIEnv* env; | ||||
| jobject obj; | jobject obj; | ||||
| @@ -279595,8 +279650,13 @@ void Thread::killThread() | |||||
| } | } | ||||
| } | } | ||||
| void Thread::setCurrentThreadName (const String& /*name*/) | |||||
| void Thread::setCurrentThreadName (const String& name) | |||||
| { | { | ||||
| #if JUCE_MAC | |||||
| pthread_setname_np (name.toUTF8()); | |||||
| #elif JUCE_LINUX | |||||
| prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); | |||||
| #endif | |||||
| } | } | ||||
| bool Thread::setThreadPriority (void* handle, int priority) | bool Thread::setThreadPriority (void* handle, int priority) | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 25 | |||||
| #define JUCE_BUILDNUMBER 26 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -1636,25 +1636,35 @@ inline void ByteOrder::bigEndian24BitToChars (const int value, char* const destB | |||||
| #ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ | #ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ | ||||
| #define __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ | #define __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ | ||||
| #if JUCE_ANDROID && ! DOXYGEN | |||||
| typedef uint32 juce_wchar; | |||||
| #define JUCE_T(stringLiteral) CharPointer_UTF8 (stringLiteral) | |||||
| #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 | |||||
| #elif JUCE_WINDOWS && ! DOXYGEN | |||||
| typedef uint32 juce_wchar; | |||||
| #define JUCE_T(stringLiteral) L##stringLiteral | |||||
| #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 | |||||
| #if JUCE_WINDOWS && ! DOXYGEN | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF8 0 | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF16 1 | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF32 0 | |||||
| #else | #else | ||||
| /** A platform-independent unicode character type. */ | |||||
| typedef wchar_t juce_wchar; | |||||
| #define JUCE_T(stringLiteral) (L##stringLiteral) | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF8 0 | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF16 0 | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF32 1 | |||||
| #endif | #endif | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN | |||||
| /** A platform-independent 32-bit unicode character type. */ | |||||
| typedef wchar_t juce_wchar; | |||||
| #else | |||||
| typedef uint32 juce_wchar; | |||||
| #endif | |||||
| /** This macro is deprecated, but preserved for compatibility with old code.*/ | |||||
| #define JUCE_T(stringLiteral) (L##stringLiteral) | |||||
| #if ! JUCE_DONT_DEFINE_MACROS | #if ! JUCE_DONT_DEFINE_MACROS | ||||
| /** The 'T' macro allows a literal string to be compiled as unicode. | |||||
| /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal. | |||||
| If you write your string literals in the form T("xyz"), it will be compiled as L"xyz" | |||||
| or "xyz", depending on which representation is best for the String class to work with. | |||||
| This macro is deprectated, but kept here for compatibility with old code. The best (i.e. | |||||
| most portable) way to encode your string literals is just as standard 8-bit strings, but | |||||
| using escaped utf-8 character codes for extended characters. | |||||
| Because the 'T' symbol is occasionally used inside 3rd-party library headers which you | Because the 'T' symbol is occasionally used inside 3rd-party library headers which you | ||||
| may need to include after juce.h, you can use the juce_withoutMacros.h file (in | may need to include after juce.h, you can use the juce_withoutMacros.h file (in | ||||
| @@ -2332,7 +2342,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| const Type oldValue (value); | const Type oldValue (value); | ||||
| const Type newValue (oldValue + amountToAdd); | |||||
| const Type newValue (castFrom32Bit (castTo32Bit (oldValue) + castTo32Bit (amountToAdd))); | |||||
| if (compareAndSetBool (newValue, oldValue)) | if (compareAndSetBool (newValue, oldValue)) | ||||
| return newValue; | return newValue; | ||||
| } | } | ||||
| @@ -2357,7 +2367,7 @@ inline Type Atomic<Type>::operator++() throw() | |||||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) | return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) | ||||
| : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); | : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); | ||||
| #elif JUCE_ANDROID | #elif JUCE_ANDROID | ||||
| return (Type) __atomic_inc (&value); | |||||
| return (Type) __atomic_inc ((volatile int*) &value); | |||||
| #elif JUCE_ATOMICS_GCC | #elif JUCE_ATOMICS_GCC | ||||
| return (Type) __sync_add_and_fetch (&value, 1); | return (Type) __sync_add_and_fetch (&value, 1); | ||||
| #endif | #endif | ||||
| @@ -2373,7 +2383,7 @@ inline Type Atomic<Type>::operator--() throw() | |||||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) | return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) | ||||
| : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); | : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); | ||||
| #elif JUCE_ANDROID | #elif JUCE_ANDROID | ||||
| return (Type) __atomic_dec (&value); | |||||
| return (Type) __atomic_dec ((volatile int*) &value); | |||||
| #elif JUCE_ATOMICS_GCC | #elif JUCE_ATOMICS_GCC | ||||
| return (Type) __sync_add_and_fetch (&value, -1); | return (Type) __sync_add_and_fetch (&value, -1); | ||||
| #endif | #endif | ||||
| @@ -2961,7 +2971,7 @@ private: | |||||
| class CharPointer_UTF16 | class CharPointer_UTF16 | ||||
| { | { | ||||
| public: | public: | ||||
| #if JUCE_WINDOWS && ! DOXYGEN | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| typedef wchar_t CharType; | typedef wchar_t CharType; | ||||
| #else | #else | ||||
| typedef int16 CharType; | typedef int16 CharType; | ||||
| @@ -3519,13 +3529,13 @@ public: | |||||
| /** Returns the number of characters in this string. */ | /** Returns the number of characters in this string. */ | ||||
| size_t length() const throw() | size_t length() const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return wcslen (data); | |||||
| #else | |||||
| size_t n = 0; | size_t n = 0; | ||||
| while (data[n] != 0) | while (data[n] != 0) | ||||
| ++n; | ++n; | ||||
| return n; | return n; | ||||
| #else | |||||
| return wcslen (data); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -3613,7 +3623,7 @@ public: | |||||
| return CharacterFunctions::compare (*this, other); | return CharacterFunctions::compare (*this, other); | ||||
| } | } | ||||
| #if ! JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| /** Compares this string with another one. */ | /** Compares this string with another one. */ | ||||
| int compare (const CharPointer_UTF32& other) const throw() | int compare (const CharPointer_UTF32& other) const throw() | ||||
| { | { | ||||
| @@ -4175,7 +4185,7 @@ public: | |||||
| /** Creates a string from an ASCII character string */ | /** Creates a string from an ASCII character string */ | ||||
| String (const CharPointer_ASCII& text); | String (const CharPointer_ASCII& text); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Creates a string from a UTF-16 character string */ | /** Creates a string from a UTF-16 character string */ | ||||
| String (const wchar_t* text); | String (const wchar_t* text); | ||||
| @@ -4221,7 +4231,7 @@ public: | |||||
| String& operator+= (char characterToAppend); | String& operator+= (char characterToAppend); | ||||
| /** Appends a character at the end of this string. */ | /** Appends a character at the end of this string. */ | ||||
| String& operator+= (juce_wchar characterToAppend); | String& operator+= (juce_wchar characterToAppend); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Appends a character at the end of this string. */ | /** Appends a character at the end of this string. */ | ||||
| String& operator+= (wchar_t characterToAppend); | String& operator+= (wchar_t characterToAppend); | ||||
| /** Appends another string at the end of this one. */ | /** Appends another string at the end of this one. */ | ||||
| @@ -5242,7 +5252,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | ||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); | ||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| @@ -12535,7 +12545,8 @@ public: | |||||
| /** Sets the text in a text element. | /** Sets the text in a text element. | ||||
| Note that this is only a valid call if this element is a text element. If it's | Note that this is only a valid call if this element is a text element. If it's | ||||
| not, then no action will be performed. | |||||
| not, then no action will be performed. If you're trying to add text inside a normal | |||||
| element, you probably want to use addTextElement() instead. | |||||
| */ | */ | ||||
| void setText (const String& newText); | void setText (const String& newText); | ||||
| @@ -35101,7 +35112,8 @@ protected: | |||||
| typedef AudioData::Pointer <DestSampleType, DestEndianness, AudioData::Interleaved, AudioData::NonConst> DestType; | typedef AudioData::Pointer <DestSampleType, DestEndianness, AudioData::Interleaved, AudioData::NonConst> DestType; | ||||
| typedef AudioData::Pointer <SourceSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | typedef AudioData::Pointer <SourceSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | ||||
| static void write (void* destData, int numDestChannels, const int** source, int numSamples) throw() | |||||
| static void write (void* destData, int numDestChannels, const int** source, | |||||
| int numSamples, const int sourceOffset = 0) throw() | |||||
| { | { | ||||
| for (int i = 0; i < numDestChannels; ++i) | for (int i = 0; i < numDestChannels; ++i) | ||||
| { | { | ||||
| @@ -35109,7 +35121,7 @@ protected: | |||||
| if (*source != 0) | if (*source != 0) | ||||
| { | { | ||||
| dest.convertSamples (SourceType (*source), numSamples); | |||||
| dest.convertSamples (SourceType (*source + sourceOffset), numSamples); | |||||
| ++source; | ++source; | ||||
| } | } | ||||
| else | else | ||||
| @@ -224,7 +224,8 @@ protected: | |||||
| typedef AudioData::Pointer <DestSampleType, DestEndianness, AudioData::Interleaved, AudioData::NonConst> DestType; | typedef AudioData::Pointer <DestSampleType, DestEndianness, AudioData::Interleaved, AudioData::NonConst> DestType; | ||||
| typedef AudioData::Pointer <SourceSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | typedef AudioData::Pointer <SourceSampleType, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> SourceType; | ||||
| static void write (void* destData, int numDestChannels, const int** source, int numSamples) throw() | |||||
| static void write (void* destData, int numDestChannels, const int** source, | |||||
| int numSamples, const int sourceOffset = 0) throw() | |||||
| { | { | ||||
| for (int i = 0; i < numDestChannels; ++i) | for (int i = 0; i < numDestChannels; ++i) | ||||
| { | { | ||||
| @@ -232,7 +233,7 @@ protected: | |||||
| if (*source != 0) | if (*source != 0) | ||||
| { | { | ||||
| dest.convertSamples (SourceType (*source), numSamples); | |||||
| dest.convertSamples (SourceType (*source + sourceOffset), numSamples); | |||||
| ++source; | ++source; | ||||
| } | } | ||||
| else | else | ||||
| @@ -78,6 +78,16 @@ JUCE_API void JUCE_CALLTYPE initialiseJuce_NonGUI() | |||||
| static_jassert (sizeof (uint32) == 4); | static_jassert (sizeof (uint32) == 4); | ||||
| static_jassert (sizeof (int64) == 8); | static_jassert (sizeof (int64) == 8); | ||||
| static_jassert (sizeof (uint64) == 8); | static_jassert (sizeof (uint64) == 8); | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF8 | |||||
| static_jassert (sizeof (wchar_t) == 1); | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| static_jassert (sizeof (wchar_t) == 2); | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| static_jassert (sizeof (wchar_t) == 4); | |||||
| #else | |||||
| #error "native wchar_t size is unknown" | |||||
| #endif | |||||
| } | } | ||||
| JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() | JUCE_API void JUCE_CALLTYPE shutdownJuce_NonGUI() | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 25 | |||||
| #define JUCE_BUILDNUMBER 26 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -280,7 +280,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| const Type oldValue (value); | const Type oldValue (value); | ||||
| const Type newValue (oldValue + amountToAdd); | |||||
| const Type newValue (castFrom32Bit (castTo32Bit (oldValue) + castTo32Bit (amountToAdd))); | |||||
| if (compareAndSetBool (newValue, oldValue)) | if (compareAndSetBool (newValue, oldValue)) | ||||
| return newValue; | return newValue; | ||||
| } | } | ||||
| @@ -305,7 +305,7 @@ inline Type Atomic<Type>::operator++() throw() | |||||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) | return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value) | ||||
| : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); | : (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value); | ||||
| #elif JUCE_ANDROID | #elif JUCE_ANDROID | ||||
| return (Type) __atomic_inc (&value); | |||||
| return (Type) __atomic_inc ((volatile int*) &value); | |||||
| #elif JUCE_ATOMICS_GCC | #elif JUCE_ATOMICS_GCC | ||||
| return (Type) __sync_add_and_fetch (&value, 1); | return (Type) __sync_add_and_fetch (&value, 1); | ||||
| #endif | #endif | ||||
| @@ -321,7 +321,7 @@ inline Type Atomic<Type>::operator--() throw() | |||||
| return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) | return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value) | ||||
| : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); | : (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value); | ||||
| #elif JUCE_ANDROID | #elif JUCE_ANDROID | ||||
| return (Type) __atomic_dec (&value); | |||||
| return (Type) __atomic_dec ((volatile int*) &value); | |||||
| #elif JUCE_ATOMICS_GCC | #elif JUCE_ATOMICS_GCC | ||||
| return (Type) __sync_add_and_fetch (&value, -1); | return (Type) __sync_add_and_fetch (&value, -1); | ||||
| #endif | #endif | ||||
| @@ -166,11 +166,12 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| //============================================================================== | |||||
| inline operator jobject() const throw() { return obj; } | inline operator jobject() const throw() { return obj; } | ||||
| inline jobject get() const throw() { return obj; } | inline jobject get() const throw() { return obj; } | ||||
| inline JNIEnv* getEnv() const throw() { return env; } | inline JNIEnv* getEnv() const throw() { return env; } | ||||
| //============================================================================== | |||||
| #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ | #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ | ||||
| returnType call##typeName##Method (jmethodID methodID, ... ) \ | returnType call##typeName##Method (jmethodID methodID, ... ) \ | ||||
| { \ | { \ | ||||
| @@ -202,6 +203,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //============================================================================== | |||||
| JNIEnv* env; | JNIEnv* env; | ||||
| jobject obj; | jobject obj; | ||||
| @@ -742,8 +742,13 @@ void Thread::killThread() | |||||
| } | } | ||||
| } | } | ||||
| void Thread::setCurrentThreadName (const String& /*name*/) | |||||
| void Thread::setCurrentThreadName (const String& name) | |||||
| { | { | ||||
| #if JUCE_MAC | |||||
| pthread_setname_np (name.toUTF8()); | |||||
| #elif JUCE_LINUX | |||||
| prctl (PR_SET_NAME, name.toUTF8().getAddress(), 0, 0, 0); | |||||
| #endif | |||||
| } | } | ||||
| bool Thread::setThreadPriority (void* handle, int priority) | bool Thread::setThreadPriority (void* handle, int priority) | ||||
| @@ -56,6 +56,7 @@ | |||||
| #include <net/if.h> | #include <net/if.h> | ||||
| #include <sys/sysinfo.h> | #include <sys/sysinfo.h> | ||||
| #include <sys/file.h> | #include <sys/file.h> | ||||
| #include <sys/prctl.h> | |||||
| #include <signal.h> | #include <signal.h> | ||||
| /* Got a build error here? You'll need to install the freetype library... | /* Got a build error here? You'll need to install the freetype library... | ||||
| @@ -44,6 +44,8 @@ END_JUCE_NAMESPACE | |||||
| - (bool) makeActive; | - (bool) makeActive; | ||||
| - (void) makeInactive; | - (void) makeInactive; | ||||
| - (void) reshape; | - (void) reshape; | ||||
| - (void) rightMouseDown: (NSEvent*) ev; | |||||
| - (void) rightMouseUp: (NSEvent*) ev; | |||||
| @end | @end | ||||
| @implementation ThreadSafeNSOpenGLView | @implementation ThreadSafeNSOpenGLView | ||||
| @@ -112,6 +114,16 @@ END_JUCE_NAMESPACE | |||||
| needsUpdate = true; | needsUpdate = true; | ||||
| } | } | ||||
| - (void) rightMouseDown: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseDown: ev]; | |||||
| } | |||||
| - (void) rightMouseUp: (NSEvent*) ev | |||||
| { | |||||
| [[self superview] rightMouseUp: ev]; | |||||
| } | |||||
| @end | @end | ||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| @@ -36,7 +36,7 @@ | |||||
| class CharPointer_UTF16 | class CharPointer_UTF16 | ||||
| { | { | ||||
| public: | public: | ||||
| #if JUCE_WINDOWS && ! DOXYGEN | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| typedef wchar_t CharType; | typedef wchar_t CharType; | ||||
| #else | #else | ||||
| typedef int16 CharType; | typedef int16 CharType; | ||||
| @@ -159,13 +159,13 @@ public: | |||||
| /** Returns the number of characters in this string. */ | /** Returns the number of characters in this string. */ | ||||
| size_t length() const throw() | size_t length() const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return wcslen (data); | |||||
| #else | |||||
| size_t n = 0; | size_t n = 0; | ||||
| while (data[n] != 0) | while (data[n] != 0) | ||||
| ++n; | ++n; | ||||
| return n; | return n; | ||||
| #else | |||||
| return wcslen (data); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -253,7 +253,7 @@ public: | |||||
| return CharacterFunctions::compare (*this, other); | return CharacterFunctions::compare (*this, other); | ||||
| } | } | ||||
| #if ! JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| /** Compares this string with another one. */ | /** Compares this string with another one. */ | ||||
| int compare (const CharPointer_UTF32& other) const throw() | int compare (const CharPointer_UTF32& other) const throw() | ||||
| { | { | ||||
| @@ -139,14 +139,14 @@ int CharacterFunctions::ftime (char* const dest, const int maxChars, const char* | |||||
| int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() | int CharacterFunctions::ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return (int) wcsftime (dest, maxChars, format, tm); | |||||
| #else | |||||
| HeapBlock <char> tempDest; | HeapBlock <char> tempDest; | ||||
| tempDest.calloc (maxChars + 2); | tempDest.calloc (maxChars + 2); | ||||
| int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); | int result = ftime (tempDest.getData(), maxChars, String (format).toUTF8(), tm); | ||||
| CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); | CharPointer_UTF32 (dest).writeAll (CharPointer_UTF8 (tempDest.getData())); | ||||
| return result; | return result; | ||||
| #else | |||||
| return (int) wcsftime (dest, maxChars, format, tm); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -28,25 +28,35 @@ | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_ANDROID && ! DOXYGEN | |||||
| typedef uint32 juce_wchar; | |||||
| #define JUCE_T(stringLiteral) CharPointer_UTF8 (stringLiteral) | |||||
| #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 | |||||
| #elif JUCE_WINDOWS && ! DOXYGEN | |||||
| typedef uint32 juce_wchar; | |||||
| #define JUCE_T(stringLiteral) L##stringLiteral | |||||
| #define JUCE_NATIVE_WCHAR_IS_NOT_UTF32 1 | |||||
| #if JUCE_WINDOWS && ! DOXYGEN | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF8 0 | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF16 1 | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF32 0 | |||||
| #else | #else | ||||
| /** A platform-independent unicode character type. */ | |||||
| typedef wchar_t juce_wchar; | |||||
| #define JUCE_T(stringLiteral) (L##stringLiteral) | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF8 0 | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF16 0 | |||||
| /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */ | |||||
| #define JUCE_NATIVE_WCHAR_IS_UTF32 1 | |||||
| #endif | #endif | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN | |||||
| /** A platform-independent 32-bit unicode character type. */ | |||||
| typedef wchar_t juce_wchar; | |||||
| #else | |||||
| typedef uint32 juce_wchar; | |||||
| #endif | |||||
| /** This macro is deprecated, but preserved for compatibility with old code.*/ | |||||
| #define JUCE_T(stringLiteral) (L##stringLiteral) | |||||
| #if ! JUCE_DONT_DEFINE_MACROS | #if ! JUCE_DONT_DEFINE_MACROS | ||||
| /** The 'T' macro allows a literal string to be compiled as unicode. | |||||
| /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal. | |||||
| If you write your string literals in the form T("xyz"), it will be compiled as L"xyz" | |||||
| or "xyz", depending on which representation is best for the String class to work with. | |||||
| This macro is deprectated, but kept here for compatibility with old code. The best (i.e. | |||||
| most portable) way to encode your string literals is just as standard 8-bit strings, but | |||||
| using escaped utf-8 character codes for extended characters. | |||||
| Because the 'T' symbol is occasionally used inside 3rd-party library headers which you | Because the 'T' symbol is occasionally used inside 3rd-party library headers which you | ||||
| may need to include after juce.h, you can use the juce_withoutMacros.h file (in | may need to include after juce.h, you can use the juce_withoutMacros.h file (in | ||||
| @@ -42,6 +42,14 @@ BEGIN_JUCE_NAMESPACE | |||||
| #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default." | ||||
| #endif | #endif | ||||
| #if JUCE_NATIVE_WCHAR_IS_UTF8 | |||||
| typedef CharPointer_UTF8 CharPointer_wchar_t; | |||||
| #elif JUCE_NATIVE_WCHAR_IS_UTF16 | |||||
| typedef CharPointer_UTF16 CharPointer_wchar_t; | |||||
| #else | |||||
| typedef CharPointer_UTF32 CharPointer_wchar_t; | |||||
| #endif | |||||
| NewLine newLine; | NewLine newLine; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -265,7 +273,7 @@ String::String (const char* const t) | |||||
| because there's no other way to represent these strings in a way that isn't dependent on | because there's no other way to represent these strings in a way that isn't dependent on | ||||
| the compiler, source code editor and platform. | the compiler, source code editor and platform. | ||||
| */ | */ | ||||
| jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | |||||
| jassert (t == 0 || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | |||||
| } | } | ||||
| String::String (const char* const t, const size_t maxChars) | String::String (const char* const t, const size_t maxChars) | ||||
| @@ -284,7 +292,7 @@ String::String (const char* const t, const size_t maxChars) | |||||
| because there's no other way to represent these strings in a way that isn't dependent on | because there's no other way to represent these strings in a way that isn't dependent on | ||||
| the compiler, source code editor and platform. | the compiler, source code editor and platform. | ||||
| */ | */ | ||||
| jassert (CharPointer_ASCII::isValidString (t, (int) maxChars)); | |||||
| jassert (t == 0 || CharPointer_ASCII::isValidString (t, (int) maxChars)); | |||||
| } | } | ||||
| String::String (const juce_wchar* const t) | String::String (const juce_wchar* const t) | ||||
| @@ -322,14 +330,16 @@ String::String (const CharPointer_ASCII& t) | |||||
| { | { | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| String::String (const wchar_t* const t) | String::String (const wchar_t* const t) | ||||
| : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) | |||||
| : text (StringHolder::createFromCharPointer | |||||
| (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (t)))) | |||||
| { | { | ||||
| } | } | ||||
| String::String (const wchar_t* const t, size_t maxChars) | String::String (const wchar_t* const t, size_t maxChars) | ||||
| : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t), maxChars)) | |||||
| : text (StringHolder::createFromCharPointer | |||||
| (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (t)), maxChars)) | |||||
| { | { | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -717,7 +727,7 @@ String& String::operator+= (const juce_wchar ch) | |||||
| return operator+= (static_cast <const juce_wchar*> (asString)); | return operator+= (static_cast <const juce_wchar*> (asString)); | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| String& String::operator+= (const wchar_t ch) | String& String::operator+= (const wchar_t ch) | ||||
| { | { | ||||
| return operator+= ((juce_wchar) ch); | return operator+= ((juce_wchar) ch); | ||||
| @@ -786,7 +796,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar | |||||
| return string1 += string2; | return string1 += string2; | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | ||||
| { | { | ||||
| return string1 += string2; | return string1 += string2; | ||||
| @@ -794,7 +804,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t string2) | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2) | ||||
| { | { | ||||
| string1.appendCharPointer (CharPointer_UTF16 (string2)); | |||||
| string1.appendCharPointer (CharPointer_wchar_t (reinterpret_cast <const CharPointer_wchar_t::CharType*> (string2))); | |||||
| return string1; | return string1; | ||||
| } | } | ||||
| @@ -2117,9 +2127,7 @@ const String String::fromUTF8 (const char* const buffer, int bufferSizeBytes) | |||||
| //============================================================================== | //============================================================================== | ||||
| const char* String::toCString() const | const char* String::toCString() const | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return toUTF8(); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| if (isEmpty()) | if (isEmpty()) | ||||
| return reinterpret_cast <const char*> (text.getAddress()); | return reinterpret_cast <const char*> (text.getAddress()); | ||||
| @@ -2128,29 +2136,31 @@ const char* String::toCString() const | |||||
| wcstombs (extraSpace, text, len); | wcstombs (extraSpace, text, len); | ||||
| extraSpace [len] = 0; | extraSpace [len] = 0; | ||||
| return extraSpace; | return extraSpace; | ||||
| #else | |||||
| return toUTF8(); | |||||
| #endif | #endif | ||||
| } | } | ||||
| int String::getNumBytesAsCString() const throw() | int String::getNumBytesAsCString() const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return getNumBytesAsUTF8(); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| return (int) wcstombs (0, text, 0); | return (int) wcstombs (0, text, 0); | ||||
| #else | |||||
| return getNumBytesAsUTF8(); | |||||
| #endif | #endif | ||||
| } | } | ||||
| int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() | int String::copyToCString (char* destBuffer, const int maxBufferSizeBytes) const throw() | ||||
| { | { | ||||
| #if JUCE_NATIVE_WCHAR_IS_NOT_UTF32 | |||||
| return copyToUTF8 (destBuffer, maxBufferSizeBytes); | |||||
| #else | |||||
| #if JUCE_NATIVE_WCHAR_IS_UTF32 && ! JUCE_ANDROID | |||||
| const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); | const int numBytes = (int) wcstombs (destBuffer, text, maxBufferSizeBytes); | ||||
| if (destBuffer != 0 && numBytes >= 0) | if (destBuffer != 0 && numBytes >= 0) | ||||
| destBuffer [numBytes] = 0; | destBuffer [numBytes] = 0; | ||||
| return numBytes; | return numBytes; | ||||
| #else | |||||
| return copyToUTF8 (destBuffer, maxBufferSizeBytes); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -126,7 +126,7 @@ public: | |||||
| /** Creates a string from an ASCII character string */ | /** Creates a string from an ASCII character string */ | ||||
| String (const CharPointer_ASCII& text); | String (const CharPointer_ASCII& text); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Creates a string from a UTF-16 character string */ | /** Creates a string from a UTF-16 character string */ | ||||
| String (const wchar_t* text); | String (const wchar_t* text); | ||||
| @@ -175,7 +175,7 @@ public: | |||||
| String& operator+= (char characterToAppend); | String& operator+= (char characterToAppend); | ||||
| /** Appends a character at the end of this string. */ | /** Appends a character at the end of this string. */ | ||||
| String& operator+= (juce_wchar characterToAppend); | String& operator+= (juce_wchar characterToAppend); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Appends a character at the end of this string. */ | /** Appends a character at the end of this string. */ | ||||
| String& operator+= (wchar_t characterToAppend); | String& operator+= (wchar_t characterToAppend); | ||||
| /** Appends another string at the end of this one. */ | /** Appends another string at the end of this one. */ | ||||
| @@ -1219,7 +1219,7 @@ JUCE_API const String JUCE_CALLTYPE operator+ (String string1, const juce_wchar | |||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, char characterToAppend); | ||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend); | ||||
| #if JUCE_WINDOWS | |||||
| #if ! JUCE_NATIVE_WCHAR_IS_UTF32 | |||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); | JUCE_API const String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend); | ||||
| /** Concatenates two strings. */ | /** Concatenates two strings. */ | ||||
| @@ -638,7 +638,8 @@ public: | |||||
| /** Sets the text in a text element. | /** Sets the text in a text element. | ||||
| Note that this is only a valid call if this element is a text element. If it's | Note that this is only a valid call if this element is a text element. If it's | ||||
| not, then no action will be performed. | |||||
| not, then no action will be performed. If you're trying to add text inside a normal | |||||
| element, you probably want to use addTextElement() instead. | |||||
| */ | */ | ||||
| void setText (const String& newText); | void setText (const String& newText); | ||||