@@ -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); | ||||