Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into TSH-ATOMIC-MONACOEDITOR

Shaddock Heath 9 лет назад
Родитель
Сommit
4666ca7282
57 измененных файлов с 803 добавлено и 399 удалено
  1. 2 2
      AUTHORS.md
  2. 11 0
      BACKERS.md
  3. 1 1
      Build/CIScripts/BuildLinux.js
  4. 37 0
      Build/CMake/Modules/AtomicPlatform.cmake
  5. 134 72
      Build/Scripts/BuildCommon.js
  6. 2 6
      Build/Scripts/BuildLinux.js
  7. 1 16
      Build/Scripts/BuildMac.js
  8. 1 14
      Build/Scripts/BuildWindows.js
  9. 0 1
      Build/Scripts/Windows/CompileAtomicEditor.bat
  10. 1 1
      Build/Scripts/Windows/GenerateVS2015.bat
  11. 3 3
      Build_AtomicEditor.sh
  12. 1 25
      CMakeLists.txt
  13. 18 0
      CMake_Makefile.sh
  14. 12 4
      CMake_VS2015.bat
  15. 4 2
      CMake_XCode.sh
  16. 10 7
      README.md
  17. 31 18
      Resources/EditorData/AtomicEditor/editor/ui/buildsettings_android.tb.txt
  18. BIN
      Resources/EditorData/AtomicEditor/resources/default_skin_light/checkbox_mark.png
  19. BIN
      Resources/EditorData/AtomicEditor/resources/default_skin_light/checkbox_mark_grey.png
  20. 2 2
      Script/AtomicEditor/ui/MainToolbar.ts
  21. 2 2
      Script/AtomicEditor/ui/Shortcuts.ts
  22. 1 1
      Script/AtomicEditor/ui/frames/ProjectFrame.ts
  23. 1 1
      Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts
  24. 1 1
      Script/AtomicEditor/ui/frames/inspector/MaterialInspector.ts
  25. 5 0
      Script/AtomicEditor/ui/frames/inspector/ModelInspector.ts
  26. 1 1
      Script/AtomicEditor/ui/frames/menus/MainFrameMenu.ts
  27. 1 1
      Script/AtomicEditor/ui/modal/About.ts
  28. 75 57
      Script/AtomicEditor/ui/modal/build/platforms/AndroidSettingsWidget.ts
  29. 1 1
      Script/AtomicEditor/ui/modal/license/NewBuildWindow.ts
  30. 34 0
      Script/ToolCore/build/BuildSettings.ts
  31. 2 0
      Source/AtomicEditor/CMakeLists.txt
  32. 43 48
      Source/AtomicEditor/Utils/FileUtils.cpp
  33. 3 3
      Source/AtomicEditor/Utils/FileUtils.h
  34. 2 0
      Source/AtomicJS/CMakeLists.txt
  35. 2 0
      Source/AtomicPlayerJS/CMakeLists.txt
  36. 10 13
      Source/AtomicTool/CMakeLists.txt
  37. 2 0
      Source/AtomicWebView/CMakeLists.txt
  38. 64 18
      Source/AtomicWebView/WebKeyboardLinux.cpp
  39. 21 0
      Source/ToolCore/Assets/ModelImporter.cpp
  40. 3 0
      Source/ToolCore/Assets/ModelImporter.h
  41. 95 13
      Source/ToolCore/Build/AndroidProjectGenerator.cpp
  42. 4 1
      Source/ToolCore/Build/AndroidProjectGenerator.h
  43. 43 21
      Source/ToolCore/Build/BuildAndroid.cpp
  44. 30 0
      Source/ToolCore/Build/BuildBase.cpp
  45. 4 0
      Source/ToolCore/Build/BuildBase.h
  46. 13 9
      Source/ToolCore/Build/BuildIOS.cpp
  47. 1 1
      Source/ToolCore/Build/BuildMac.cpp
  48. 16 10
      Source/ToolCore/Build/BuildWeb.cpp
  49. 1 1
      Source/ToolCore/Build/BuildWindows.cpp
  50. 2 2
      Source/ToolCore/Import/ImportConfig.cpp
  51. 12 4
      Source/ToolCore/Import/OpenAssetImporter.cpp
  52. 5 1
      Source/ToolCore/Import/OpenAssetImporter.h
  53. 2 0
      Source/ToolCore/Project/ProjectBuildSettings.cpp
  54. 3 0
      Source/ToolCore/Project/ProjectBuildSettings.h
  55. 20 13
      Source/ToolCore/ToolPrefs.cpp
  56. 6 1
      Source/ToolCore/ToolPrefs.h
  57. 1 1
      Source/ToolCoreJS/CMakeLists.txt

+ 2 - 2
AUTHORS.md

@@ -3,9 +3,9 @@
 
 #### THUNDERBEAST GAMES LLC:
 
-- Josh Engebretson (Technical Director)
+- Josh Engebretson (https://github.com/JoshEngebretson)
 
-- Lara Engebretson
+- Lara Engebretson (https://github.com/LaraEngebretson)
 
 ### Contributors:
 

+ 11 - 0
BACKERS.md

@@ -0,0 +1,11 @@
+### Atomic Game Engine - Development Fund
+------------------
+
+Thanks to the following backers who have contributed to the Atomic Development Fund: [http://atomicgameengine.com/funding/](http://atomicgameengine.com/funding/)
+
+Brandon Lamb: https://github.com/brandonlamb  
+Todd Wahoske: http://www.toddwahoske.com/  
+c.trauma: https://github.com/CTrauma  
+Keith Johnston https://github.com/KeithJohnston  
+BenWolf  
+dragonCASTjosh https://github.com/dragonCASTjosh  

+ 1 - 1
Build/CIScripts/BuildLinux.js

@@ -57,7 +57,7 @@ namespace('build', function() {
       atomicTool + " bind " + bcommon.atomicRoot + " Script/Packages/Editor/ LINUX",
       atomicTool + " bind " + bcommon.atomicRoot + " Script/Packages/WebView/ LINUX",
       "cmake -DATOMIC_DEV_BUILD=0 -DLINUX=1 ../../../../",
-      "make"
+      "make -j4"
     ];
 
     jake.exec(cmds, function() {

+ 37 - 0
Build/CMake/Modules/AtomicPlatform.cmake

@@ -0,0 +1,37 @@
+
+if (MSVC)
+
+    include(AtomicWindows)
+
+elseif(APPLE)
+
+    if (IOS)
+        include(AtomicIOS)
+    else()
+        include(AtomicMac)
+    endif()
+
+elseif(LINUX)
+
+  include(AtomicLinux)
+
+elseif(ANDROID)
+
+    include(AtomicAndroid)
+
+elseif(EMSCRIPTEN)
+
+	include(AtomicWeb)
+
+endif()
+
+set (JAVASCRIPT_BINDINGS_PLATFORM_ROOT "${CMAKE_SOURCE_DIR}/Artifacts/Build/Source/Generated/${JAVASCRIPT_BINDINGS_PLATFORM}")
+
+if(NOT EXISTS "${JAVASCRIPT_BINDINGS_PLATFORM_ROOT}/Javascript")
+
+execute_process ( COMMAND ${ATOMIC_NODE_JAKE};build:precreateScriptBindings[${JAVASCRIPT_BINDINGS_PLATFORM}]
+                  WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" )
+
+endif()
+
+file (GLOB_RECURSE JAVASCRIPT_BINDINGS_NATIVE_FILENAMES ${JAVASCRIPT_BINDINGS_PLATFORM_ROOT}/*.cpp ${JAVASCRIPT_BINDINGS_PLATFORM_ROOT}/*.h)

+ 134 - 72
Build/Scripts/BuildCommon.js

@@ -9,48 +9,110 @@ var Tslint = require("tslint");
 
 namespace('build', function() {
 
-  // Linting task
-  task('lint_typescript', {
-      async: true
-  }, function(fileMask, failOnError) {
-
-    console.log("TSLINT: Linting files in " + fileMask);
-    var lintConfig = JSON.parse(fs.readFileSync("./Script/tslint.json"));
-    var options = {
-        configuration: lintConfig,
-        formatter: "prose"
-    };
-
-    // lint
-    // Since TSLint does not yet support recursively searching for files, then we need to
-    // create a command per file.  The main issue with this is that it will abort on the first error instead
-    // of listing out all lint errors
-    glob(fileMask, function(err, results) {
-      var lintErrors = [];
-      results.forEach(function(filename) {
-
-        var contents = fs.readFileSync(filename, "utf8");
-
-        var ll = new Tslint(filename, contents, options);
-        var result = ll.lint();
-        if (result.failureCount > 0) {
-            lintErrors.push(result.output);
+    // Linting task
+    task('lint_typescript', {
+        async: true
+    }, function(fileMask, failOnError) {
+
+        console.log("TSLINT: Linting files in " + fileMask);
+        var lintConfig = JSON.parse(fs.readFileSync("./Script/tslint.json"));
+        var options = {
+            configuration: lintConfig,
+            formatter: "prose"
+        };
+
+        // lint
+        // Since TSLint does not yet support recursively searching for files, then we need to
+        // create a command per file.  The main issue with this is that it will abort on the first error instead
+        // of listing out all lint errors
+        glob(fileMask, function(err, results) {
+            var lintErrors = [];
+            results.forEach(function(filename) {
+
+                var contents = fs.readFileSync(filename, "utf8");
+
+                var ll = new Tslint(filename, contents, options);
+                var result = ll.lint();
+                if (result.failureCount > 0) {
+                    lintErrors.push(result.output);
+                }
+            });
+            if (lintErrors.length > 0) {
+                console.warn("TSLINT: WARNING - Lint errors detected");
+                console.warn(lintErrors.join(''));
+                if (failOnError) {
+                    fail("TSLint errors detected");
+                }
+            }
+            complete();
+        });
+    });
+
+    // precreate script bindgs so they can be picked up by CMake
+    task('precreateScriptBindings', {
+        async: true
+    }, function(platform, clean) {
+
+        if (clean === undefined) {
+            clean = true;
         }
-      });
-      if (lintErrors.length > 0) {
-          console.warn("TSLINT: WARNING - Lint errors detected");
-          console.warn(lintErrors.join(''));
-          if (failOnError) {
-              fail("TSLint errors detected");
-          }
-      }
-      complete();
+        console.log("Precreating script bindings for platorm: " + platform);
+
+        if (clean) {
+            common.cleanCreateDir(common.getGenScriptRootDir(platform))
+        }
+
+        common.createGenScriptFiles(platform);
+
+        complete();
     });
-  });
 
-  task('genscripts', {
-    async: true
-  }, function(platform) {
+    function fileExists(filePath)
+    {
+        try
+        {
+            return fs.statSync(filePath).isFile();
+        }
+        catch (err)
+        {
+            return false;
+        }
+    }
+
+    task('genscripts', {
+        async: true
+    }, function(platform, force) {
+
+        // default to true
+        if (force != "true" && force != "false") {
+            force = "true";
+        }
+
+        var anyZero = false;
+        if (force != "true") {
+
+            var filenames = common.getGenScriptFilenames(platform);
+            for (var i in filenames) {
+
+                if (!fileExists(filenames[i]))
+                {
+                    console.log("genscripts: file missing, regenerating script bindings: " + filenames[i]);
+                    anyZero = true;
+                    break;
+                }
+
+                var stats = fs.statSync(filenames[i]);
+                if (stats["size"] == 0) {
+                    console.log("genscripts: file zero size, regenerating script bindings: " + filenames[i]);
+                    anyZero = true;
+                    break;
+                }
+            }
+
+            if (!anyZero)
+                return;
+        }
+
 
         process.chdir(atomicRoot);
 
@@ -63,14 +125,14 @@ namespace('build', function() {
 
         switch(os.platform()) {
             case "win32":
-                node = "Build\\Windows\\node\\node.exe";
-                break;
+            node = "Build\\Windows\\node\\node.exe";
+            break;
             case "darwin":
-                node = "Build/Mac/node/node";
-                break;
+            node = "Build/Mac/node/node";
+            break;
             case "linux":
-                node = "Build/Linux/node/node";
-                break;
+            node = "Build/Linux/node/node";
+            break;
         }
 
         var cmds = [];
@@ -79,49 +141,49 @@ namespace('build', function() {
         }
 
         if (node) {
-          // compile
-          cmds.push(node + " " + tsc + " -p ./Script");
-          cmds.push(node + " " + tsc + " -p ./Script/AtomicWebViewEditor");
+            // compile
+            cmds.push(node + " " + tsc + " -p ./Script");
+            cmds.push(node + " " + tsc + " -p ./Script/AtomicWebViewEditor");
 
-          // generate combined atomic.d.ts
-          cmds.push(node + " " + dtsGenerator + " --name Atomic --project ./Script/TypeScript --out ./Script/TypeScript/dist/Atomic.d.ts");
+            // generate combined atomic.d.ts
+            cmds.push(node + " " + dtsGenerator + " --name Atomic --project ./Script/TypeScript --out ./Script/TypeScript/dist/Atomic.d.ts");
 
-          var lintTask = jake.Task['build:lint_typescript'];
+            var lintTask = jake.Task['build:lint_typescript'];
 
-          lintTask.addListener('complete', function () {
-            console.log("\n\nLint: Typescript linting complete.\n\n");
-            jake.exec(cmds, function() {
+            lintTask.addListener('complete', function () {
+                console.log("\n\nLint: Typescript linting complete.\n\n");
+                jake.exec(cmds, function() {
 
-                // copy some external dependencies into the editor modules directory
-               var editorModulesDir = "./Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts/AtomicEditor/modules";
-               var webeditorModulesDir = "./Data/AtomicEditor/CodeEditor/source/editorCore/modules";
-               var nodeModulesDir = "./Build/node_modules";
-               fs.mkdirsSync(editorModulesDir);
-               // TypeScript
-               fs.copySync(nodeModulesDir + "/typescript/lib/typescript.js", webeditorModulesDir + "/typescript.js")
+                    // copy some external dependencies into the editor modules directory
+                    var editorModulesDir = "./Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts/AtomicEditor/modules";
+                    var webeditorModulesDir = "./Data/AtomicEditor/CodeEditor/source/editorCore/modules";
+                    var nodeModulesDir = "./Build/node_modules";
+                    fs.mkdirsSync(editorModulesDir);
+                    // TypeScript
+                    fs.copySync(nodeModulesDir + "/typescript/lib/typescript.js", webeditorModulesDir + "/typescript.js")
 
-               // copy lib.core.d.ts into the tool data directory
-               fs.mkdirsSync("./Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts/AtomicEditor/TypeScriptSupport");
-               fs.copySync("./Build/node_modules/typescript/lib/lib.core.d.ts","./Data/AtomicEditor/TypeScriptSupport/lib.core.d.ts")
+                    // copy lib.core.d.ts into the tool data directory
+                    fs.mkdirsSync("./Artifacts/Build/Resources/EditorData/AtomicEditor/EditorScripts/AtomicEditor/TypeScriptSupport");
+                    fs.copySync("./Build/node_modules/typescript/lib/lib.core.d.ts","./Data/AtomicEditor/TypeScriptSupport/lib.core.d.ts")
 
-               // copy the combined Atomic.d.ts to the tool data directory
-               fs.copySync("./Script/TypeScript/dist/Atomic.d.ts","./Data/AtomicEditor/TypeScriptSupport/Atomic.d.ts")
+                    // copy the combined Atomic.d.ts to the tool data directory
+                    fs.copySync("./Script/TypeScript/dist/Atomic.d.ts","./Data/AtomicEditor/TypeScriptSupport/Atomic.d.ts")
 
-               complete();
+                    complete();
 
-            }, {
-              printStdout: true
+                }, {
+                    printStdout: true
+                });
             });
-          });
 
-          lintTask.invoke("{./Script/AtomicEditor/**/*.ts,./Script/AtomicWebViewEditor/**/*.ts}", false);
+            lintTask.invoke("{./Script/AtomicEditor/**/*.ts,./Script/AtomicWebViewEditor/**/*.ts}", false);
 
         } else {
             throw new Error("Node not configured for this platform: " + os.platform());
         }
 
 
-  });
+    });
 
 
 }); // end of build namespace

+ 2 - 6
Build/Scripts/BuildLinux.js

@@ -21,16 +21,12 @@ namespace('build', function() {
             common.cleanCreateDir(host.getGenScriptRootDir("LINUX"));
         }
 
-        // create the generated script files, so they will be picked up by cmake
-        host.createGenScriptFiles("LINUX");
-
         process.chdir(buildDir);
 
         var cmds = [];
 
         cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -DCMAKE_BUILD_TYPE=Release");
-        cmds.push("make -j4 GenerateScriptBindings")
-        cmds.push("make -j4 AtomicEditor AtomicPlayer")
+        cmds.push("make -j2")
 
         jake.exec(cmds, function() {
 
@@ -86,5 +82,5 @@ namespace('build', function() {
         });
 
     });
-    
+
 });

+ 1 - 16
Build/Scripts/BuildMac.js

@@ -21,15 +21,11 @@ task('atomiceditor', {
     common.cleanCreateDir(host.getGenScriptRootDir("MACOSX"));
   }
 
-  // create the generated script files, so they will be picked up by cmake
-  host.createGenScriptFiles("MACOSX");
-
   process.chdir(buildDir);
 
   var cmds = [];
 
   cmds.push("cmake ../../../ -DATOMIC_DEV_BUILD=0 -G Xcode");
-  cmds.push("xcodebuild -target GenerateScriptBindings -configuration Release -parallelizeTargets -jobs 4")
   cmds.push("xcodebuild -target AtomicEditor -target AtomicPlayer -configuration Release -parallelizeTargets -jobs 4")
 
   jake.exec(cmds, function() {
@@ -81,26 +77,15 @@ task('genxcode', {
       jake.mkdirP(xcodeRoot);
   }
 
-  // create the generated script files, so they will be picked up by cmake
-  host.createGenScriptFiles("MACOSX");
-
   process.chdir(xcodeRoot);
 
   var cmds = [];
 
   cmds.push("cmake ../AtomicGameEngine -DATOMIC_DEV_BUILD=1 -G Xcode");
-  cmds.push("xcodebuild -target GenerateScriptBindings -configuration Debug")
 
   jake.exec(cmds, function() {
 
-    var task = jake.Task['build:genscripts']
-
-    task.addListener('complete', function () {
-        console.log("\n\nXCode workspace generated in " +  xcodeRoot + "\n\n");
-        complete();
-      });
-
-    task.invoke("MACOSX");
+    complete();
 
   }, {
     printStdout: true

+ 1 - 14
Build/Scripts/BuildWindows.js

@@ -21,9 +21,6 @@ namespace('build', function() {
       common.cleanCreateDir(host.getGenScriptRootDir("WINDOWS"));
     }
 
-    // create the generated script files, so they will be picked up by cmake
-    host.createGenScriptFiles("WINDOWS");
-
     process.chdir(buildDir);
 
     var cmds = [];
@@ -80,9 +77,6 @@ namespace('build', function() {
         jake.mkdirP(slnRoot);
     }
 
-    // create the generated script files, so they will be picked up by cmake
-    host.createGenScriptFiles("WINDOWS");
-
     process.chdir(slnRoot);
 
     var cmds = [];
@@ -91,14 +85,7 @@ namespace('build', function() {
 
     jake.exec(cmds, function() {
 
-      var task = jake.Task['build:genscripts']
-
-      task.addListener('complete', function () {
-          console.log("\n\nVisual Studio Solution generated in ", slnRoot);
-          complete();
-        });
-
-      task.invoke("WINDOWS");
+      complete();
 
     }, {
       printStdout: true

+ 0 - 1
Build/Scripts/Windows/CompileAtomicEditor.bat

@@ -1,4 +1,3 @@
 call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
 cmake ..\\..\\..\\ -DATOMIC_DEV_BUILD=0 -G "Visual Studio 14 2015 Win64"
-msbuild /m /p:Configuration=Release /p:Platform=x64 Source\AtomicTool\GenerateScriptBindings.vcxproj
 msbuild /m Atomic.sln /t:AtomicEditor /t:AtomicPlayer /p:Configuration=Release /p:Platform=x64

+ 1 - 1
Build/Scripts/Windows/GenerateVS2015.bat

@@ -1,3 +1,3 @@
 call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
 cmake %1 -DATOMIC_DEV_BUILD=1 -G "Visual Studio 14 2015 Win64"
-msbuild Atomic.sln /m /p:Configuration=Debug /p:Platform=x64 /t:AtomicTool
+

+ 3 - 3
Build_AtomicEditor.sh

@@ -1,9 +1,9 @@
 #!/usr/bin/env sh
 
 if [ "$(uname)" = "Darwin" ]; then
-	./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
 elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then
-	./Build/Linux/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Linux/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
 elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then
-  ./Build/Windows/node/node.exe ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
+    ./Build/Windows/node/node.exe ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:atomiceditor
 fi

+ 1 - 25
CMakeLists.txt

@@ -39,31 +39,7 @@ endif()
 
 add_definitions( -DATOMIC_WEB )
 
-if (MSVC)
-
-    include(AtomicWindows)
-
-elseif(APPLE)
-
-    if (IOS)
-        include(AtomicIOS)
-    else()
-        include(AtomicMac)
-    endif()
-
-elseif(LINUX)
-
-  include(AtomicLinux)
-
-elseif(ANDROID)
-
-    include(AtomicAndroid)
-
-elseif(EMSCRIPTEN)
-
-	include(AtomicWeb)
-
-endif()
+include (AtomicPlatform)
 
 find_program(CLDOC cldoc)
 if(CLDOC)

+ 18 - 0
CMake_Makefile.sh

@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+PLATFORM=""
+if [ "$(uname)" = "Darwin" ]; then
+    PLATFORM="MacOS"
+elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then
+    PLATFORM="Linux"
+elif [ "$(expr substr $(uname -s) 1 7)" = "MSYS_NT" ]; then
+    PLATFORM="MSYS"
+else
+    exit "Unknown platform"
+fi
+
+SOURCE=$(cd ${0%/*}; pwd)
+FOLDERNAME=${PWD##*/}
+if [ -d "$SOURCE/Artifacts/Build/Source/Generated/" ]; then rm -Rf "$SOURCE/Artifacts/Build/Source/Generated/"; fi
+cmake -E make_directory ../$FOLDERNAME-Build-$PLATFORM && cmake -E chdir ../$FOLDERNAME-Build-$PLATFORM cmake -DCMAKE_BUILD_TYPE=Debug "$SOURCE"
+echo "makefile written to ../$FOLDERNAME-Build-$PLATFORM"

+ 12 - 4
CMake_VS2015.bat

@@ -1,11 +1,19 @@
 @ECHO OFF
 @echo:
 @echo:
-ECHO Generating Visual Studio Solution, this process will take a few minutes
+ECHO Generating Visual Studio Solution (64 bit)
 @echo:
 @echo:
-PAUSE
-Build\Windows\node\node.exe Build\node_modules\jake\bin\cli.js -f ./Build/Scripts/Bootstrap.js build:genvs2015
+call "%VS140COMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
+:: remove any generated sources
+if exist "%~p0Artifacts\Build\Source\Generated\WINDOWS\" rd /q /s "%~p0Artifacts\Build\Source\Generated\WINDOWS"
+:: get current foldername
+set "cdir=%~dp0"
+:: for loop requires removing trailing backslash from %~dp0 output
+set "cdir=%cdir:~0,-1%"
+for %%i IN ("%cdir%") do set "foldername=%%~nxi"
+:: run cmake
+cmake -E make_directory "..\%foldername%-VS2015" && cmake -E chdir "..\%foldername%-VS2015" cmake %~dp0 -G "Visual Studio 14 2015 Win64"
 @echo:
+ECHO Solution created in ..\%foldername%-VS2015
 @echo:
-PAUSE

+ 4 - 2
CMake_XCode.sh

@@ -1,2 +1,4 @@
-#!/bin/sh
-./Build/Mac/node/node ./Build/node_modules/jake/bin/cli.js -f ./Build/Scripts/Bootstrap.js build:genxcode --trace
+#!/usr/bin/env bash
+SOURCE=$(cd ${0%/*}; pwd)
+cmake -E make_directory ../AtomicGameEngine-XCode && cmake -E chdir ../AtomicGameEngine-XCode cmake "$SOURCE" -G Xcode
+echo "XCode project written to ../AtomicGameEngine-XCode"

+ 10 - 7
README.md

@@ -10,18 +10,22 @@ The Atomic Game Engine source code is released under the permissive **[MIT licen
 
 ####Documentation and Downloads
 
-**[Getting Started Documentation](http://atomicgameengine.com/learn/)** 
+**[Download the Atomic Editor](http://atomicgameengine.com/download/)**
 
-**[Download the Atomic Editor](http://atomicgameengine.com/download/)** 
+**[Getting Started Documentation](http://atomicgameengine.com/learn/)**
 
 ####Community
 
-**Facebook Group:** [https://www.facebook.com/groups/AtomicGameEngine/](https://www.facebook.com/groups/AtomicGameEngine/)
+**Atomic Q&A:** [https://qa.atomicgameengine.com/](https://qa.atomicgameengine.com/)
 
-**Forums:** [Atomic Forums](http://atomicgameengine.com/forum/)
+**Facebook Group:** [https://www.facebook.com/groups/AtomicGameEngine/](https://www.facebook.com/groups/AtomicGameEngine/)
 
 **Gitter Chat:** [![Join the chat at https://gitter.im/AtomicGameEngine/AtomicGameEngine](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AtomicGameEngine/AtomicGameEngine?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- 
+
+####Atomic Development Fund
+
+Atomic Backers:  Please see [BACKERS.md](https://github.com/AtomicGameEngine/AtomicGameEngine/blob/master/BACKERS.md) for a list of contributors to the [Atomic Development Fund](http://atomicgameengine.com/funding/)
+
 ####Screenshots
 
 #####Atomic Editor
@@ -38,7 +42,7 @@ The Atomic Game Engine source code is released under the permissive **[MIT licen
 
 #####Atomic Build Settings
 [AndroidBuildSettings]: https://github.com/AtomicGameEngine/AtomicGameEngine/wiki/images/repo/AndroidBuildSettings.png
-![alt text][AndroidBuildSettings] 
+![alt text][AndroidBuildSettings]
 
 ####Looking for the Javascript and TypeScript examples?
 
@@ -47,4 +51,3 @@ They are over here: <a href="https://github.com/AtomicGameEngine/AtomicExamples"
 ###Building the Atomic Editor from Source
 
 Please see [Building the Atomic Editor from Source](https://github.com/AtomicGameEngine/AtomicGameEngine/wiki/Building-the-Atomic-Editor-from-Source) for Visual Studio 2015, XCode, and QtCreator build instructions.
-

+ 31 - 18
Resources/EditorData/AtomicEditor/editor/ui/buildsettings_android.tb.txt

@@ -10,6 +10,7 @@ TBLayout: axis: y, distribution: gravity, position: left
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBEditField: id: app_package, autofocus: 1
 				lp: min-width: 220
+				tooltip The naming convention is : com.companyname.appname
 	TBLayout: distribution: gravity
 		TBTextField: text: "Company Name:"
 		TBLayout: gravity: left right, distribution-position: right bottom
@@ -20,40 +21,52 @@ TBLayout: axis: y, distribution: gravity, position: left
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBEditField: id: product_name, autofocus: 1
 				lp: min-width: 220
+	TBLayout: axis: y, position: left, distribution: gravity
+		TBLayout: gravity: left right, distribution-position: right bottom
+			TBButton: id: choose_icon, lp: min-width: 48, min-height: 48, max-width: 48, max-height: 48
+				tooltip Location of the drawable folders for app icons
+				TBImageWidget: id: and_icon, filename: "Resources/ToolData/Deployment/Android/res/drawable-ldpi/icon.png"
+					lp: min-width: 36, min-height: 36, max-width: 36, max-height: 36
+			TBWidget: gravity: left right
+				lp: min-width: 36, min-height: 36, max-width: 36, max-height: 36
+			TBEditField: id: icon_root, autofocus: 0
+				lp: min-width: 220
 	TBSeparator: gravity: left right, skin: AESeparator
 	TBLayout: axis: y, position: left, distribution: gravity
 		TBTextField: text: "Android SDK Path:", skin: DarkGrayText
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBEditField: id: sdk_path, autofocus: 0
 				lp: min-width: 250
-			TBButton: text: "Choose" id: choose_sdk_path
+			TBButton: text: "Choose", id: choose_sdk_path
+				tooltip Location of the Android SDK folder
 	TBLayout: axis: y, position: left, distribution: gravity
 		TBTextField: text: "Android API Level:", skin: DarkGrayText
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBSelectDropdown: id: sdk_target_select
 				lp: min-width: 250
-			TBButton: text: "Refresh" id: refresh_sdk_targets
+			TBButton: text: "Refresh", id: refresh_sdk_targets
 	TBLayout: axis: y, position: left, distribution: gravity
-		TBTextField: text: "Ant Path:" id: ant_path_text, skin: DarkGrayText
+		TBTextField: text: "Ant Path:", id: ant_path_text, skin: DarkGrayText
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBEditField: id: ant_path, autofocus: 0
 				lp: min-width: 250
-			TBButton: text: "Choose" id: choose_ant_path
+				tooltip May be left blank if installed locally
+			TBButton: text: "Choose", id: choose_ant_path
+				tooltip May be left blank if installed locally
 	TBLayout: axis: y, position: left, distribution: gravity
-		TBTextField: text: "JDK Root:" id: jdk_root_text, skin: DarkGrayText
+		TBTextField: text: "JDK Root:", id: jdk_root_text, skin: DarkGrayText
 		TBLayout: gravity: left right, distribution-position: right bottom
 			TBEditField: id: jdk_root, autofocus: 0
 				lp: min-width: 250
-			TBButton: text: "Choose" id: choose_jdk_root
-	TBSeparator: gravity: left right, skin: AESeparator
-	TBLayout:
-		TBLayout: axis: y
-			TBTextField: text: "Icon:"
-			TBLayout: gravity: left right, distribution-position: right bottom
-				TBSkinImage: skin: LogoAtomic64
-					lp: min-width: 64, min-height:64
-		TBLayout: axis: y
-			TBTextField: text: "Splash Screen:"
-			TBLayout: gravity: left right, distribution-position: right bottom
-				TBSkinImage: skin: LogoAtomic64
-					lp: min-width: 64, min-height:64
+			TBButton: text: "Choose", id: choose_jdk_root
+				tooltip May be left blank if installed locally
+	TBLayout: axis: y, position: left, distribution: gravity
+		TBLayout: gravity: left, distribution-position: right bottom
+			TBClickLabel: text: "Release Path", skin: DarkGrayText
+				TBCheckBox: id: and_auth_check, lp: min-height: 20
+		TBLayout: gravity: left right, distribution-position: right bottom
+			TBEditField: id: auth_root, autofocus: 0
+				lp: min-width: 250
+				tooltip Select Release Path for a release version APK
+			TBButton: text: "Choose", id: choose_and_auth
+				tooltip Directory containing the ant.properties

BIN
Resources/EditorData/AtomicEditor/resources/default_skin_light/checkbox_mark.png


BIN
Resources/EditorData/AtomicEditor/resources/default_skin_light/checkbox_mark_grey.png


+ 2 - 2
Script/AtomicEditor/ui/MainToolbar.ts

@@ -63,13 +63,13 @@ class MainToolbar extends Atomic.UIWidget {
         this.subscribeToEvent(EditorEvents.PlayerStarted, (data) => {
             var skin = <Atomic.UISkinImage> this.playButton.getWidget("skin_image");
             skin.setSkinBg("StopButton");
-            var skin = <Atomic.UISkinImage> this.pauseButton.getWidget("skin_image");
+            skin = <Atomic.UISkinImage> this.pauseButton.getWidget("skin_image");
             skin.setSkinBg("PauseButton");
         });
         this.subscribeToEvent(EditorEvents.PlayerStopped, (data) => {
             var skin = <Atomic.UISkinImage> this.playButton.getWidget("skin_image");
             skin.setSkinBg("PlayButton");
-            var skin = <Atomic.UISkinImage> this.pauseButton.getWidget("skin_image");
+            skin = <Atomic.UISkinImage> this.pauseButton.getWidget("skin_image");
             skin.setSkinBg("PauseButton");
         });
         this.subscribeToEvent(EditorEvents.PlayerPaused, (data) => {

+ 2 - 2
Script/AtomicEditor/ui/Shortcuts.ts

@@ -209,7 +209,7 @@ class Shortcuts extends Atomic.ScriptObject {
                     EditorUI.getModelOps().showBuildSettings();
                 } else {
                     EditorUI.getModelOps().showBuild();
-                }            
+                }
             }
             else if (ev.key == Atomic.KEY_U) {
                 if (ev.qualifiers & Atomic.QUAL_SHIFT) {
@@ -217,7 +217,7 @@ class Shortcuts extends Atomic.ScriptObject {
                 } else {
                     this.invokePauseOrResumePlayer();
                 }
-            } 
+            }
 
         }
 

+ 1 - 1
Script/AtomicEditor/ui/frames/ProjectFrame.ts

@@ -75,7 +75,7 @@ class ProjectFrame extends ScriptWidget {
         this.subscribeToEvent("ResourceAdded", (ev: ToolCore.ResourceAddedEvent) => this.handleResourceAdded(ev));
         this.subscribeToEvent("ResourceRemoved", (ev: ToolCore.ResourceRemovedEvent) => this.handleResourceRemoved(ev));
         this.subscribeToEvent("AssetRenamed", (ev: ToolCore.AssetRenamedEvent) => this.handleAssetRenamed(ev));
-        this.subscribeToEvent(EditorEvents.InspectorProjectReference, (ev: EditorEvents.InspectorProjectReferenceEvent) => { this.handleInspectorProjectReferenceHighlight(ev.path) });
+        this.subscribeToEvent(EditorEvents.InspectorProjectReference, (ev: EditorEvents.InspectorProjectReferenceEvent) => { this.handleInspectorProjectReferenceHighlight(ev.path); });
 
         folderList.subscribeToEvent("UIListViewSelectionChanged", (event: Atomic.UIListViewSelectionChangedEvent) => this.handleFolderListSelectionChangedEvent(event));
 

+ 1 - 1
Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts

@@ -735,7 +735,7 @@ class ResourceRefAttributeEdit extends AttributeInfoEdit {
 
                         } else if (resource instanceof Atomic.Animation) {
 
-                             var animCacheReferenceName = resource.name.replace("_"+(<Atomic.Animation>resource).animationName, "");
+                             var animCacheReferenceName = resource.name.replace( "_" + (<Atomic.Animation>resource).animationName, "");
                              var asset = ToolCore.assetDatabase.getAssetByCachePath(animCacheReferenceName);
                              this.sendEvent(EditorEvents.InspectorProjectReference, { "path": asset.getRelativePath() });
 

+ 1 - 1
Script/AtomicEditor/ui/frames/inspector/MaterialInspector.ts

@@ -83,7 +83,7 @@ class MaterialInspector extends ScriptWidget {
 
     currentTexture: Atomic.UITextureWidget = null;
     tunit: number;
-    textureWidget: Atomic.UITextureWidget
+    textureWidget: Atomic.UITextureWidget;
 
     constructor() {
 

+ 5 - 0
Script/AtomicEditor/ui/frames/inspector/ModelInspector.ts

@@ -46,6 +46,7 @@ class ModelInspector extends InspectorWidget {
         this.importer.scale = Number(this.scaleEdit.text);
 
         this.importer.importAnimations = this.importAnimationBox.value ? true : false;
+        this.importer.setImportMaterials(this.importMaterials.value ? true : false);
 
         for (var i = 0; i < this.importer.animationCount; i++) {
 
@@ -103,6 +104,9 @@ class ModelInspector extends InspectorWidget {
         this.scaleEdit = InspectorUtils.createAttrEditField("Scale", modelLayout);
         this.scaleEdit.text = this.importer.scale.toString();
 
+        this.importMaterials = this.createAttrCheckBox("Import Materials", modelLayout);
+        this.importMaterials.value = this.importer.getImportMaterials() ? 1 : 0;
+
         // Animations Section
         var animationLayout = this.createSection(rootLayout, "Animation", 1);
 
@@ -192,6 +196,7 @@ class ModelInspector extends InspectorWidget {
 
     // animation
     importAnimationBox: Atomic.UICheckBox;
+    importMaterials: Atomic.UICheckBox;
     importAnimationArray: ArrayEditWidget;
     animationInfoLayout: Atomic.UILayout;
 

+ 1 - 1
Script/AtomicEditor/ui/frames/menus/MainFrameMenu.ts

@@ -47,7 +47,7 @@ class MainFrameMenu extends Atomic.ScriptObject {
     createPluginMenuItemSource(id: string, items: any): Atomic.UIMenuItemSource {
         if (!this.pluginMenuItemSource) {
             var developerMenuItemSource = MenuItemSources.getMenuItemSource("menu developer");
-            this.pluginMenuItemSource = MenuItemSources.createSubMenuItemSource(developerMenuItemSource ,"Plugins", {});
+            this.pluginMenuItemSource = MenuItemSources.createSubMenuItemSource(developerMenuItemSource, "Plugins", {});
         }
 
         return MenuItemSources.createSubMenuItemSource(this.pluginMenuItemSource , id, items);

+ 1 - 1
Script/AtomicEditor/ui/modal/About.ts

@@ -86,7 +86,7 @@ class About extends ModalWindow {
         var text = "";
 
         text += "<widget TBImageWidget: filename: 'AtomicEditor/editor/images/atomic_logo.png'>\n\n";
-        text += "<color #D4FB79>Git SHA: " + Atomic.getGitRevision() +"</color>\n\n";
+        text += "<color #D4FB79>Git SHA: " + Atomic.getGitRevision() + "</color>\n\n";
         text += "(c) 2014-2016 THUNDERBEAST GAMES LLC\n\n\n";
 
         text += "<color #D4FB79>Installed platforms and modules:</color>\n\n";

+ 75 - 57
Script/AtomicEditor/ui/modal/build/platforms/AndroidSettingsWidget.ts

@@ -32,6 +32,7 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
 
         this.settings = ToolCore.toolSystem.project.buildSettings.androidBuildSettings;
 
+        this.sdkPathEdit = <Atomic.UIEditField>this.getWidget("sdk_path");
         this.sdkTargetSelect = <Atomic.UISelectDropdown>this.getWidget("sdk_target_select");
         this.appNameEdit = <Atomic.UIEditField>this.getWidget("app_name");
         this.packageNameEdit = <Atomic.UIEditField>this.getWidget("app_package");
@@ -45,17 +46,18 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
         var jdkRootText = <Atomic.UITextField>this.getWidget("jdk_root_text");
         var antPathText = <Atomic.UITextField>this.getWidget("ant_path_text");
 
+        this.releaseChooseButton = <Atomic.UIButton>this.getWidget("choose_and_auth");
+        this.releaseNameEdit = <Atomic.UIEditField>this.getWidget("auth_root");
+        this.releaseCheck = <Atomic.UICheckBox>this.getWidget("and_auth_check");
+        this.iconNameEdit = <Atomic.UIEditField>this.getWidget("icon_root");
+        this.iconChooseButton = <Atomic.UIButton>this.getWidget("choose_icon");
+        this.iconImage = <Atomic.UIImageWidget>this.getWidget("and_icon");
+
         if (Atomic.platform == "Windows") {
 
             jdkRootText.text = "JDK Root: (Ex. C:\\Program Files\\Java\\jdk1.8.0_31)";
             antPathText.text = "Ant Path: (The folder that contains ant.bat)";
 
-        } else {
-
-            jdkRootText.visibility = Atomic.UI_WIDGET_VISIBILITY_GONE;
-            this.jdkRootChooseButton.visibility = Atomic.UI_WIDGET_VISIBILITY_GONE;
-            this.jdkRootEdit.visibility = Atomic.UI_WIDGET_VISIBILITY_GONE;
-
         }
 
         this.antPathEdit = <Atomic.UIEditField>this.getWidget("ant_path");
@@ -73,19 +75,9 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
             if (ev.target.id == "choose_sdk_path") {
 
                 var fileUtils = new Editor.FileUtils();
-                var path = fileUtils.getAndroidSDKPath("");
-
-                if (path.length) {
-
-                    var toolPrefs = ToolCore.toolEnvironment.toolPrefs;
-                    if (toolPrefs.androidSDKPath != path) {
-                        toolPrefs.androidSDKPath = path;
-                        toolPrefs.save();
-                    }
-
-                    this.refreshWidgets();
-
-                }
+                var path = fileUtils.findPath("Please choose the root folder of your Android SDK" , "");
+                if ( path.length > 0 )
+                    this.sdkPathEdit.text = path;
 
                 return true;
 
@@ -93,37 +85,17 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
 
                 var fileUtils = new Editor.FileUtils();
                 var path = fileUtils.getAntPath("");
-
-                if (path.length) {
-
-                    var toolPrefs = ToolCore.toolEnvironment.toolPrefs;
-                    if (toolPrefs.antPath != path) {
-                        toolPrefs.antPath = path;
-                        toolPrefs.save();
-                    }
-
-                    this.refreshWidgets();
-
-                }
+                if ( path.length > 0 )
+                    this.antPathEdit.text = path;
 
                 return true;
 
             }  else if (ev.target.id == "choose_jdk_root") {
 
                 var fileUtils = new Editor.FileUtils();
-                var path = fileUtils.getJDKRootPath("");
-
-                if (path.length) {
-
-                    var toolPrefs = ToolCore.toolEnvironment.toolPrefs;
-                    if (toolPrefs.jDKRootPath != path) {
-                        toolPrefs.jDKRootPath = path;
-                        toolPrefs.save();
-                    }
-
-                    this.refreshWidgets();
-
-                }
+                var path = fileUtils.findPath("Please choose the root folder of your JDK" , "");
+                if ( path.length > 0 )
+                    this.jdkRootEdit.text = path;
 
                 return true;
 
@@ -131,7 +103,23 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
 
                 this.refreshAndroidTargets();
 
-            }
+            }  else if (ev.target.id == "choose_and_auth") {
+                var fileUtils = new Editor.FileUtils();
+                var path = fileUtils.findPath( "Please choose the folder of your ant.properties", "");
+                if ( path.length > 0 )
+                    this.releaseNameEdit.text = path;
+                return true;
+
+            }  else if (ev.target.id == "choose_icon") {
+                var fileUtils = new Editor.FileUtils();
+                var path = fileUtils.findPath("Please choose the folder with drawable folders" , "");
+                if ( path.length > 0 ) {
+                    this.iconNameEdit.text = path;
+                    this.updateIconButton();
+               }
+                return true;
+
+           }
 
         }
 
@@ -165,25 +153,45 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
 
     }
 
-    refreshWidgets() {
+    updateIconButton() {
+
+        var fileSystem = Atomic.getFileSystem();
+
+        if ( this.iconNameEdit.text.length > 0 ) {
+
+            let myicon = this.iconNameEdit.text + "/drawable-ldpi/icon.png";
+            if ( fileSystem.fileExists(myicon) ) {
+
+                this.iconImage.setImage( myicon );
+                return;
+            }
+        }
 
-        var sdkPathEdit = <Atomic.UIEditField>this.getWidget("sdk_path");
-        var antPathEdit = <Atomic.UIEditField>this.getWidget("ant_path");
-        var jdkRootEdit = <Atomic.UIEditField>this.getWidget("jdk_root");
+        let defaulticon = fileSystem.getProgramDir() + "Resources/ToolData/Deployment/Android/res/drawable-ldpi/icon.png";
+        this.iconImage.setImage( defaulticon );
+
+    }
+
+
+    refreshWidgets() {
 
         var toolPrefs = ToolCore.toolEnvironment.toolPrefs;
 
-        sdkPathEdit.text = toolPrefs.androidSDKPath;
-        antPathEdit.text = toolPrefs.antPath;
-        jdkRootEdit.text = toolPrefs.jDKRootPath;
+        this.sdkPathEdit.text = toolPrefs.androidSDKPath;
+        this.antPathEdit.text = toolPrefs.antPath;
+        this.jdkRootEdit.text = toolPrefs.jDKRootPath;
+        this.releaseNameEdit.text = toolPrefs.releasePath;
+        this.releaseCheck.value = toolPrefs.releaseCheck;
 
         this.appNameEdit.text = this.settings.appName;
         this.packageNameEdit.text = this.settings.packageName;
         this.productNameEdit.text = this.settings.productName;
         this.companyNameEdit.text = this.settings.companyName;
+        this.iconNameEdit.text = this.settings.iconPath;
 
         this.sdkTargetSelect.text = this.settings.sDKVersion;
 
+        this.updateIconButton();
     }
 
     storeValues() {
@@ -192,17 +200,22 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
         this.settings.packageName = this.packageNameEdit.text;
         this.settings.productName = this.productNameEdit.text;
         this.settings.companyName = this.companyNameEdit.text;
-
-        if (this.antPathEdit.text.length && this.antPathEdit.text != ToolCore.toolEnvironment.toolPrefs.antPath)
-            ToolCore.toolEnvironment.toolPrefs.antPath = this.antPathEdit.text;
-
         this.settings.sDKVersion = this.sdkTargetSelect.text;
+        this.settings.iconPath = this.iconNameEdit.text;
 
+        ToolCore.toolEnvironment.toolPrefs.antPath = this.antPathEdit.text;
+        ToolCore.toolEnvironment.toolPrefs.androidSDKPath = this.sdkPathEdit.text;
+        ToolCore.toolEnvironment.toolPrefs.jDKRootPath = this.jdkRootEdit.text;
+        ToolCore.toolEnvironment.toolPrefs.releasePath = this.releaseNameEdit.text;
+        ToolCore.toolEnvironment.toolPrefs.releaseCheck = this.releaseCheck.value;
+
+        ToolCore.toolEnvironment.saveToolPrefs();
     }
 
     settings: ToolCore.AndroidBuildSettings;
     sdkTargetSource: Atomic.UISelectItemSource = new Atomic.UISelectItemSource();
     sdkTargetSelect: Atomic.UISelectDropdown;
+    sdkPathEdit: Atomic.UIEditField;
 
     jdkRootChooseButton: Atomic.UIButton;
     jdkRootEdit: Atomic.UIEditField;
@@ -214,7 +227,12 @@ class AndroidSettingsWidget extends Atomic.UIWidget implements BuildSettingsWind
     productNameEdit: Atomic.UIEditField;
     companyNameEdit: Atomic.UIEditField;
 
-
+    releaseNameEdit : Atomic.UIEditField;
+    releaseChooseButton : Atomic.UIButton;
+    releaseCheck : Atomic.UICheckBox;
+    iconNameEdit : Atomic.UIEditField;
+    iconChooseButton : Atomic.UIButton;
+    iconImage : Atomic.UIImageWidget;
 }
 
 export = AndroidSettingsWidget;

+ 1 - 1
Script/AtomicEditor/ui/modal/license/NewBuildWindow.ts

@@ -56,7 +56,7 @@ class NewBuildWindow extends ModalWindow {
 
             if (id == "cfi") {
 
-                Atomic.fileSystem.systemOpen("http://www.atomicgameengine.com/funding/")
+                Atomic.fileSystem.systemOpen("http://www.atomicgameengine.com/funding/");
             }
 
             if (id == "ok") {

+ 34 - 0
Script/ToolCore/build/BuildSettings.ts

@@ -37,4 +37,38 @@ class MacBuildSettings {
 
 }
 
+class WindowsBuildSettings {   
+    appName: string;
+    packageName: string;
+    companyName: string;
+    productName: string;
+}
+
+class WebBuildSettings {
+    appName: string;
+    packageName: string;
+    companyName: string;
+    productName: string;
+}
+
+class AndroidBuildSettings {
+    appName: string;
+    packageName: string;
+    companyName: string;
+    productName: string;
+    sDKVersion: string;
+    minSDKVersion: string;
+    activityName: string;
+    iconPath: string;
+}
+
+class IOSBuildSettings {
+    appName: string;
+    packageName: string;
+    companyName: string;
+    productName: string;
+    provisionFile: string;
+    appIDPrefix: string;
+}
+
 export = BuildSettings;

+ 2 - 0
Source/AtomicEditor/CMakeLists.txt

@@ -197,6 +197,8 @@ if (TARGET_PROPERTIES)
     set_target_properties (AtomicEditor PROPERTIES ${TARGET_PROPERTIES})
 endif ()
 
+add_dependencies(${CEF_TARGET} AtomicToolCheckScripts)
+
 GroupSources("Application")
 GroupSources("EditorMode")
 GroupSources("Editors")

+ 43 - 48
Source/AtomicEditor/Utils/FileUtils.cpp

@@ -127,30 +127,6 @@ String FileUtils::GetBuildPath(const String& defaultPath)
 
 }
 
-String FileUtils::GetAndroidSDKPath(const String& defaultPath)
-{
-    String sdkPath;
-
-    nfdchar_t *outPath = NULL;
-
-    nfdresult_t result = NFD_ChooseDirectory( "Please choose the root folder of your Android SDK",
-                                defaultPath.Length() ? defaultPath.CString() : NULL,
-                                &outPath);
-
-    if (outPath && result == NFD_OKAY)
-    {
-        sdkPath = outPath;
-    }
-
-    if (outPath)
-        free(outPath);
-
-    GetSubsystem<Graphics>()->RaiseWindow();
-
-    return GetInternalPath(sdkPath);
-
-}
-
 String FileUtils::GetAntPath(const String& defaultPath)
 {
     String antPath;
@@ -180,30 +156,6 @@ String FileUtils::GetAntPath(const String& defaultPath)
     return GetInternalPath(antPath);
 }
 
-String FileUtils::GetJDKRootPath(const String& defaultPath)
-{
-    String jdkPath;
-
-    nfdchar_t *outPath = NULL;
-
-    nfdresult_t result = NFD_ChooseDirectory("Please choose the root folder of your JDK",
-        defaultPath.Length() ? defaultPath.CString() : NULL,
-        &outPath);
-
-    if (outPath && result == NFD_OKAY)
-    {
-        jdkPath = outPath;
-    }
-
-    if (outPath)
-        free(outPath);
-
-    GetSubsystem<Graphics>()->RaiseWindow();
-
-    return GetInternalPath(jdkPath);
-
-}
-
 String FileUtils::GetMobileProvisionPath()
 {
     nfdchar_t *outPath = NULL;
@@ -239,5 +191,48 @@ void FileUtils::RevealInFinder(const String& fullpath)
         fs->SystemOpen(GetPath(fullpath));
 }
 
+String FileUtils::FindPath(const String& title, const String& defaultPath)
+{
+    String resultPath;
+    nfdchar_t *outPath = NULL;
+
+    nfdresult_t result = NFD_ChooseDirectory(title.CString(),
+        defaultPath.Length() ? defaultPath.CString() : NULL,
+        &outPath);
+
+    if (outPath && result == NFD_OKAY)
+    {
+        resultPath = outPath;
+    }
+
+    if (outPath)
+        free(outPath);
+
+    GetSubsystem<Graphics>()->RaiseWindow();
+
+    return GetInternalPath(resultPath);
+}
+
+String FileUtils::FindFile (const String& filterlist, const String& defaultPath)
+{
+    String fullpath;
+    nfdchar_t *outPath = NULL;
+
+    nfdresult_t result = NFD_OpenDialog( filterlist.CString(),
+        defaultPath.Length() ? defaultPath.CString() : NULL,
+        &outPath);
+
+    if (outPath && result == NFD_OKAY)
+    {
+        fullpath = outPath;
+    }
+
+    GetSubsystem<Graphics>()->RaiseWindow();
+
+    if (outPath)
+        free(outPath);
+
+    return fullpath;
+}
 
 }

+ 3 - 3
Source/AtomicEditor/Utils/FileUtils.h

@@ -43,13 +43,13 @@ public:
     bool CreateDirs(const String& folder);
 
     String GetMobileProvisionPath();
-    String GetAndroidSDKPath(const String& defaultPath);
     String GetAntPath(const String& defaultPath);
-    String GetJDKRootPath(const String& defaultPath);
     String OpenProjectFileDialog();
     String NewProjectFileDialog();
     String GetBuildPath(const String& defaultPath);
-    void RevealInFinder(const String& fullpath);
+    void RevealInFinder(const String& fullpath);    
+    String FindPath (const String& title, const String& defaultPath );
+    String FindFile (const String& filterlist, const String& defaultPath );
 
 private:
 

+ 2 - 0
Source/AtomicJS/CMakeLists.txt

@@ -20,3 +20,5 @@ file (GLOB JAVASCRIPT_BINDINGS_SOURCE ${CMAKE_SOURCE_DIR}/Artifacts/Build/Source
 set (SOURCE_FILES ${JAVASCRIPT_SOURCE} ${JAVASCRIPT_BINDINGS_SOURCE})
 
 add_library(AtomicJS ${SOURCE_FILES})
+
+add_dependencies(AtomicJS AtomicToolCheckScripts)

+ 2 - 0
Source/AtomicPlayerJS/CMakeLists.txt

@@ -9,3 +9,5 @@ set (SOURCE_FILES ${SOURCE_FILES} ${JAVASCRIPT_BINDINGS_SOURCE} )
 add_library(AtomicPlayerJS ${SOURCE_FILES})
 
 target_link_libraries(AtomicPlayerJS AtomicPlayerLib)
+
+add_dependencies(AtomicPlayerJS AtomicToolCheckScripts)

+ 10 - 13
Source/AtomicTool/CMakeLists.txt

@@ -10,27 +10,24 @@ target_link_libraries(AtomicTool ToolCore Poco ${ATOMIC_LINK_LIBRARIES})
 
 if (MSVC)
     target_link_libraries(AtomicTool libcurl Iphlpapi Wldap32)
-
-    # pre-Windows 8 can't count on D3DCompiler_47.dll being on system
-    # TODO: Remove this dependency
-    add_custom_command (TARGET AtomicTool POST_BUILD
-    COMMAND ${CMAKE_COMMAND}
-    ARGS -E copy_if_different \"${D3DCOMPILER_47_DLL}\" \"$<TARGET_FILE_DIR:AtomicTool>/D3DCompiler_47.dll\")
-
 else()
     target_link_libraries(AtomicTool libcurl)
 endif()
 
-add_custom_command( TARGET AtomicTool POST_BUILD
-                   COMMAND ${CMAKE_COMMAND}
-                   ARGS -E make_directory ${CMAKE_SOURCE_DIR}/Artifacts/Build/AtomicTool
-                   COMMAND ${CMAKE_COMMAND}
-                   ARGS -E copy_if_different $<TARGET_FILE:AtomicTool> \"${CMAKE_SOURCE_DIR}/Artifacts/Build/AtomicTool/\" )
+add_custom_target( AtomicToolCheckScripts
+                   WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+                   COMMAND "${CMAKE_COMMAND}" -E make_directory \"${CMAKE_SOURCE_DIR}/Artifacts/Build/AtomicTool\"
+                   COMMAND "${CMAKE_COMMAND}" -E copy_if_different \"$<TARGET_FILE:AtomicTool>\" \"${CMAKE_SOURCE_DIR}/Artifacts/Build/AtomicTool/\"
+                   COMMAND ${ATOMIC_NODE_JAKE};build:genscripts[${JAVASCRIPT_BINDINGS_PLATFORM},false] )
+
+add_dependencies (AtomicToolCheckScripts AtomicTool)
 
 if (MSVC)
 
 # Copy the D3D shader compiler
 add_custom_command( TARGET AtomicTool POST_BUILD
+                    COMMAND ${CMAKE_COMMAND}
+                    ARGS -E copy_if_different \"${D3DCOMPILER_47_DLL}\" \"$<TARGET_FILE_DIR:AtomicTool>/D3DCompiler_47.dll\"
                     COMMAND ${CMAKE_COMMAND}
                     ARGS -E copy_if_different \"${D3DCOMPILER_47_DLL}\" \"${CMAKE_SOURCE_DIR}/Artifacts/Build/AtomicTool/D3DCompiler_47.dll\"
                     COMMENT "Copying AtomicTool to Build Artifacts" )
@@ -38,5 +35,5 @@ endif(MSVC)
 
 add_custom_target ( GenerateScriptBindings
                     WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
-                    COMMAND ${ATOMIC_NODE_JAKE};build:genscripts[${JAVASCRIPT_BINDINGS_PLATFORM}]
+                    COMMAND ${ATOMIC_NODE_JAKE};build:genscripts[${JAVASCRIPT_BINDINGS_PLATFORM},true]
                     DEPENDS AtomicTool )

+ 2 - 0
Source/AtomicWebView/CMakeLists.txt

@@ -12,3 +12,5 @@ endif()
 set (SOURCE_FILES ${SOURCE_FILES} ${JAVASCRIPT_BINDINGS_SOURCE} ${PLATFORM_SOURCE} )
 
 add_library(AtomicWebView ${SOURCE_FILES})
+
+add_dependencies(AtomicWebView AtomicToolCheckScripts)

+ 64 - 18
Source/AtomicWebView/WebKeyboardLinux.cpp

@@ -123,26 +123,72 @@ static bool SDLScanCodeToWindowsScanCode(SDL_Scancode code, long int& lParam, lo
         lParam = windowsScanCode << 16;
     }
 
+    if ( code >= SDL_SCANCODE_A && code < SDL_SCANCODE_1 )
+    {
+        wParam = code + 61;
+        lParam = wParam << 16;
+        return wParam != 0 || lParam != 0;
+    }
+   
     switch (code)
     {
-    case SDL_SCANCODE_RIGHT:
-        wParam = VKEY_RIGHT;
-        break;
-    case SDL_SCANCODE_LEFT:
-        wParam = VKEY_LEFT;
-        break;
-    case SDL_SCANCODE_UP:
-        wParam = VKEY_UP;
-        break;
-    case SDL_SCANCODE_DOWN:
-        wParam = VKEY_DOWN;
-        break;
-    case SDL_SCANCODE_DELETE:
-        wParam = VKEY_DELETE;
-        break;
-    case SDL_SCANCODE_BACKSPACE:
-        wParam = VKEY_BACK;
-        break;
+    case SDL_SCANCODE_RIGHT: wParam = VKEY_RIGHT; break;
+    case SDL_SCANCODE_LEFT: wParam = VKEY_LEFT; break;
+    case SDL_SCANCODE_UP: wParam = VKEY_UP; break;
+    case SDL_SCANCODE_DOWN: wParam = VKEY_DOWN; break;
+    case SDL_SCANCODE_DELETE: wParam = VKEY_DELETE; break;
+    case SDL_SCANCODE_BACKSPACE: wParam = VKEY_BACK; break;
+    case SDL_SCANCODE_F1: wParam = VKEY_F1; break;
+    case SDL_SCANCODE_F2: wParam = VKEY_F2; break;
+    case SDL_SCANCODE_F3: wParam = VKEY_F3; break;
+    case SDL_SCANCODE_F4: wParam = VKEY_F4; break;
+    case SDL_SCANCODE_F5: wParam = VKEY_F5; break;
+    case SDL_SCANCODE_F6: wParam = VKEY_F6; break;
+    case SDL_SCANCODE_F7: wParam = VKEY_F7; break;
+    case SDL_SCANCODE_F8: wParam = VKEY_F8; break;
+    case SDL_SCANCODE_F9: wParam = VKEY_F9; break;
+    case SDL_SCANCODE_F10: wParam = VKEY_F10; break;
+    case SDL_SCANCODE_F11: wParam = VKEY_F11; break;
+    case SDL_SCANCODE_F12: wParam = VKEY_F12; break;
+    case SDL_SCANCODE_PRINTSCREEN: wParam = VKEY_SNAPSHOT; break;
+    case SDL_SCANCODE_SCROLLLOCK: wParam = VKEY_SCROLL; break;
+    case SDL_SCANCODE_PAUSE: wParam = VKEY_PAUSE; break;
+    case SDL_SCANCODE_INSERT: wParam = VKEY_INSERT; break;
+    case SDL_SCANCODE_HOME: wParam = VKEY_HOME; break;
+    case SDL_SCANCODE_PAGEUP: wParam = VKEY_PRIOR; break;
+    case SDL_SCANCODE_END: wParam = VKEY_END; break;
+    case SDL_SCANCODE_PAGEDOWN: wParam = VKEY_NEXT; break;
+    case SDL_SCANCODE_1: wParam = VKEY_1; break;
+    case SDL_SCANCODE_2: wParam = VKEY_2; break;
+    case SDL_SCANCODE_3: wParam = VKEY_3; break;
+    case SDL_SCANCODE_4: wParam = VKEY_4; break;
+    case SDL_SCANCODE_5: wParam = VKEY_5; break;
+    case SDL_SCANCODE_6: wParam = VKEY_6; break;
+    case SDL_SCANCODE_7: wParam = VKEY_7; break;
+    case SDL_SCANCODE_8: wParam = VKEY_8; break;
+    case SDL_SCANCODE_9: wParam = VKEY_9; break;
+    case SDL_SCANCODE_0: wParam = VKEY_0; break;
+    case SDL_SCANCODE_SEMICOLON: wParam = VKEY_OEM_1; break;
+    case SDL_SCANCODE_APOSTROPHE: wParam = VKEY_OEM_7; break;
+    case SDL_SCANCODE_GRAVE: wParam = VKEY_OEM_3; break;
+    case SDL_SCANCODE_KP_DIVIDE: wParam = VKEY_DIVIDE; break;
+    case SDL_SCANCODE_KP_MULTIPLY: wParam = VKEY_MULTIPLY; break;
+    case SDL_SCANCODE_KP_MINUS: wParam = VKEY_SUBTRACT; break;
+    case SDL_SCANCODE_KP_PLUS: wParam = VKEY_ADD; break;
+    case SDL_SCANCODE_KP_ENTER: wParam = VKEY_SEPARATOR; break;
+    case SDL_SCANCODE_KP_1: wParam = VKEY_NUMPAD1; break;
+    case SDL_SCANCODE_KP_2: wParam = VKEY_NUMPAD2; break;
+    case SDL_SCANCODE_KP_3: wParam = VKEY_NUMPAD3; break;
+    case SDL_SCANCODE_KP_4: wParam = VKEY_NUMPAD4; break;
+    case SDL_SCANCODE_KP_5: wParam = VKEY_NUMPAD5; break;
+    case SDL_SCANCODE_KP_6: wParam = VKEY_NUMPAD6; break;
+    case SDL_SCANCODE_KP_7: wParam = VKEY_NUMPAD7; break;
+    case SDL_SCANCODE_KP_8: wParam = VKEY_NUMPAD8; break;
+    case SDL_SCANCODE_KP_9: wParam = VKEY_NUMPAD9; break;
+    case SDL_SCANCODE_KP_0: wParam = VKEY_NUMPAD0; break;
+    case SDL_SCANCODE_KP_PERIOD: wParam = VKEY_DECIMAL; break;
+    case SDL_SCANCODE_NUMLOCKCLEAR: wParam = VKEY_NUMLOCK; break;
+    case SDL_SCANCODE_CAPSLOCK: wParam = VKEY_CAPITAL; break;
     }
 
     return wParam != 0 || lParam != 0;

+ 21 - 0
Source/ToolCore/Assets/ModelImporter.cpp

@@ -58,9 +58,11 @@ ModelImporter::~ModelImporter()
 void ModelImporter::SetDefaults()
 {
     AssetImporter::SetDefaults();
+    SharedPtr<OpenAssetImporter> importer(new OpenAssetImporter(context_));
 
     scale_ = 1.0;
     importAnimations_ = false;
+    importMaterials_ = importer->GetImportMaterialsDefault();
     animationInfo_.Clear();
 
 }
@@ -77,6 +79,7 @@ bool ModelImporter::ImportModel()
     importer->SetScale(scale_);
     importer->SetExportAnimations(false);
     importer->SetImportNode(importNode_);
+    importer->SetImportMaterials(importMaterials_);
 
     if (importer->Load(asset_->GetPath()))
     {
@@ -92,6 +95,13 @@ bool ModelImporter::ImportModel()
     return false;
 }
 
+/*void ModelImporter::SetImportMaterials(bool importMat)
+{
+    LOGDEBUGF("Importing Materials of: %s", asset_->GetPath().CString());
+    SharedPtr<OpenAssetImporter> importer(new OpenAssetImporter(context_));
+    importer->SetImportMaterials(importMat);
+}*/
+
 bool ModelImporter::ImportAnimation(const String& filename, const String& name, float startTime, float endTime)
 {
     SharedPtr<OpenAssetImporter> importer(new OpenAssetImporter(context_));
@@ -257,6 +267,7 @@ bool ModelImporter::Import()
                 ImportAnimations();
             }
 
+            SetImportMaterials(importMaterials_);
         }
     }
 
@@ -339,6 +350,15 @@ bool ModelImporter::LoadSettingsInternal(JSONValue& jsonRoot)
     if (import.Get("importAnimations").IsBool())
         importAnimations_ = import.Get("importAnimations").GetBool();
 
+    if (import.Get("importMaterials").IsBool())
+    {
+        importMaterials_ = import.Get("importMaterials").GetBool();
+    }
+    else
+    {
+
+    }
+
     if (import.Get("animInfo").IsArray())
     {
         JSONArray animInfo = import.Get("animInfo").GetArray();
@@ -368,6 +388,7 @@ bool ModelImporter::SaveSettingsInternal(JSONValue& jsonRoot)
     JSONValue save;
     save.Set("scale", scale_);
     save.Set("importAnimations", importAnimations_);
+    save.Set("importMaterials", importMaterials_);
 
     JSONArray animInfo;
 

+ 3 - 0
Source/ToolCore/Assets/ModelImporter.h

@@ -81,6 +81,8 @@ public:
 
     bool GetImportAnimations() { return importAnimations_; }
     void SetImportAnimations(bool importAnimations) { importAnimations_ = importAnimations; }
+    bool GetImportMaterials() { return importMaterials_; }
+    void SetImportMaterials(bool importMat) { importMaterials_ = importMat; };
 
     unsigned GetAnimationCount();
     void SetAnimationCount(unsigned count);
@@ -108,6 +110,7 @@ protected:
 
     double scale_;
     bool importAnimations_;
+    bool importMaterials_;
     Vector<SharedPtr<AnimationImportInfo>> animationInfo_;
 
     SharedPtr<Node> importNode_;

+ 95 - 13
Source/ToolCore/Build/AndroidProjectGenerator.cpp

@@ -37,8 +37,9 @@
 namespace ToolCore
 {
 
-AndroidProjectGenerator::AndroidProjectGenerator(Context* context) :
-    Object(context)
+AndroidProjectGenerator::AndroidProjectGenerator(Context* context, BuildBase* buildBase) :
+    Object(context),
+    buildBase_(buildBase)
 {
 
 }
@@ -65,6 +66,9 @@ bool AndroidProjectGenerator::Generate()
     if (!GenerateActivitySource())
         return false;
 
+    if (!CopyUserIcons())
+        return false;
+
     return true;
 }
 
@@ -78,7 +82,7 @@ bool AndroidProjectGenerator::GenerateActivitySource()
 
     if (!packageName.Length())
     {
-        errorText_ = "Invalid Package Name";
+        errorText_ = "Invalid App Package name. The general naming convention is com.company.appname";
         return false;
     }
 
@@ -93,7 +97,7 @@ bool AndroidProjectGenerator::GenerateActivitySource()
 
     if (!dirs.exists())
     {
-        errorText_ = "Unable to create ";
+        errorText_ = "Project generator unable to create dirs " + path;
         return false;
     }
 
@@ -109,15 +113,17 @@ bool AndroidProjectGenerator::GenerateActivitySource()
     File file(context_, path + "/AtomicGameEngine.java", FILE_WRITE);
 
     if (!file.IsOpen())
+    {
+        errorText_ = "Project generator unable to open file " + path + "/AtomicGameEngine.java";
         return false;
-
+    }
     file.Write(source.CString(), source.Length());
 
     return true;
 
 }
 
-bool AndroidProjectGenerator::GenerateLocalProperties()
+bool AndroidProjectGenerator::GenerateLocalProperties( )
 {
     ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
     ToolPrefs* prefs = tenv->GetToolPrefs();
@@ -125,7 +131,7 @@ bool AndroidProjectGenerator::GenerateLocalProperties()
 
     if (!sdkPath.Length())
     {
-        errorText_ = "Invalid Android SDK Path";
+        errorText_ = "Invalid Android SDK Path, select the path in Build Settings.";
         return false;
     }
 
@@ -135,10 +141,35 @@ bool AndroidProjectGenerator::GenerateLocalProperties()
     File file(context_, buildPath_ + "/local.properties", FILE_WRITE);
 
     if (!file.IsOpen())
+    {
+        errorText_ = "Project generator unable to open file " + buildPath_ + "/local.properties ";
         return false;
-
+    }
+    
     file.Write(props.CString(), props.Length());
 
+
+    if ( prefs->GetReleaseCheck() > 0 ) // if release flag is set ...
+    {
+        FileSystem* fileSystem = GetSubsystem<FileSystem>();
+        String Reldir = prefs->GetReleasePath();
+        if (!fileSystem->DirExists(Reldir))
+        {
+            errorText_ = "Invalid Release Path, select the path in Build Settings.";
+            return false;
+        }
+        
+        String antname = Reldir + "/ant.properties";
+        if ( !fileSystem->FileExists ( antname) ) 
+        {
+            errorText_ = "The file ant.properties not found in " + Reldir + ", unable to generate Release APK.";
+            return false;
+        }
+
+        if ( !buildBase_->BuildCopyFile ( antname, buildPath_ + "/ant.properties" ))
+            return false;
+
+    }
     return true;
 
 }
@@ -153,7 +184,7 @@ bool AndroidProjectGenerator::GenerateProjectProperties()
 
     if (!apiString.Length())
     {
-        errorText_ = "Invalid Android API";
+        errorText_ = "Invalid Android API level, Press Refresh and select a valid level.";
         return false;
     }
 
@@ -164,8 +195,10 @@ bool AndroidProjectGenerator::GenerateProjectProperties()
     File file(context_, buildPath_ + "/project.properties", FILE_WRITE);
 
     if (!file.IsOpen())
+    {
+        errorText_ = "Project generator unable to open file project.properties in " + buildPath_;
         return false;
-
+    }
     file.Write(props.CString(), props.Length());
 
     return true;
@@ -183,7 +216,7 @@ bool AndroidProjectGenerator::GenerateStringXML()
 
     if (!appName.Length())
     {
-        errorText_ = "Invalid App Name";
+        errorText_ = "Invalid App Name, select the App Name in Build Settings.";
         return false;
     }
 
@@ -233,11 +266,11 @@ bool AndroidProjectGenerator::GenerateAndroidManifest()
 
     if (!package.Length())
     {
-        errorText_ = "Invalid Package Name";
+        errorText_ = "Invalid App Package name. The general naming convention is com.company.appname";
         return false;
     }
 
-    // TODO: from settings
+    // TODO: from settings -- should this be ProductName ?
     String activityName = "AtomicGameEngine";
     if (!activityName.Length())
     {
@@ -281,6 +314,55 @@ bool AndroidProjectGenerator::GenerateAndroidManifest()
 
 }
 
+bool AndroidProjectGenerator::CopyUserIcons()
+{
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+    ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
+    Project* project = toolSystem->GetProject();
+    AndroidBuildSettings* settings = project->GetBuildSettings()->GetAndroidBuildSettings();
+
+    String userIconPath = settings->GetIconPath();
+    if (!fileSystem->DirExists(userIconPath))               // dont do anything if there is no path defined.
+        return true;
+            
+    String userIconDir = userIconPath + "/drawable";        // 1st target dir 
+    String userIconFile = userIconDir + "/logo_large.png";  // 1st target file
+    String destDir = buildPath_ + "/res/drawable";          // where it should be in the build
+    if ( fileSystem->FileExists (userIconFile) )            // is there a file there?
+    {
+        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/logo_large.png" ))
+            return false;
+    }
+
+    userIconDir = userIconPath + "/drawable-ldpi"; 
+    userIconFile = userIconDir + "/icon.png"; 
+    destDir = buildPath_ + "/res/drawable-ldpi";
+    if ( fileSystem->FileExists (userIconFile) )
+    {
+        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png"))
+            return false;
+    } 
+
+    userIconDir = userIconPath + "/drawable-mdpi"; 
+    userIconFile = userIconDir + "/icon.png"; 
+    destDir = buildPath_ + "/res/drawable-mdpi";
+    {
+        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png" ))
+            return false;
+    } 
+
+    userIconDir = userIconPath + "/drawable-hdpi"; 
+    userIconFile = userIconDir + "/icon.png"; 
+    destDir = buildPath_ + "/res/drawable-hdpi";
+    if ( fileSystem->FileExists (userIconFile) )
+    {
+        if ( !buildBase_->BuildCopyFile ( userIconFile, destDir + "/icon.png" ))
+            return false;
+    }
+
+    return true;
+}
+
 }
 
 /*

+ 4 - 1
Source/ToolCore/Build/AndroidProjectGenerator.h

@@ -31,6 +31,7 @@ using namespace Atomic;
 
 namespace ToolCore
 {
+class BuildBase;
 
 class AndroidProjectGenerator : public Object
 {
@@ -39,7 +40,7 @@ class AndroidProjectGenerator : public Object
 
 public:
 
-    AndroidProjectGenerator(Context* context);
+    AndroidProjectGenerator(Context* context, BuildBase *buildBase);
     virtual ~AndroidProjectGenerator();
 
     void SetBuildPath(const String& buildpath) { buildPath_ = buildpath; }
@@ -55,7 +56,9 @@ private:
     bool GenerateLocalProperties();
     bool GenerateProjectProperties();
     bool GenerateActivitySource();
+    bool CopyUserIcons( );
 
+    WeakPtr<BuildBase> buildBase_;
     String buildPath_;
     String errorText_;
 

+ 43 - 21
Source/ToolCore/Build/BuildAndroid.cpp

@@ -82,7 +82,7 @@ void BuildAndroid::RunADBStartActivity()
     Subprocess* subprocess = subs->Launch(adbCommand, args, buildPath_);
     if (!subprocess)
     {
-        FailBuild("BuildFailed::RunStartActivity");
+        FailBuild("StartActivity operation did not launch successfully.");
         return;
     }
 
@@ -114,18 +114,23 @@ void BuildAndroid::HandleRunADBInstallComplete(StringHash eventType, VariantMap&
 
 void BuildAndroid::RunADBInstall()
 {
-
+    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
+    ToolPrefs* prefs = tenv->GetToolPrefs();
     SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
     String adbCommand = platformAndroid_->GetADBCommand();
 
-    Vector<String> args = String("install -r ./bin/Atomic-debug-unaligned.apk").Split(' ');
+    Vector<String> args;
+
+    if ( prefs->GetReleaseCheck() > 0 ) // install release apk
+        args = String("install -r ./bin/Atomic-release.apk").Split(' ');
+    else
+        args = String("install -r ./bin/Atomic-debug-unaligned.apk").Split(' ');
 
     currentBuildPhase_ = ADBInstall;
     Subprocess* subprocess = subs->Launch(adbCommand, args, buildPath_);
-
     if (!subprocess)
     {
-        FailBuild("BuildFailed::RunADBInstall");
+        FailBuild("APK Device Installation operation did not launch successfully.");
         return;
     }
 
@@ -209,7 +214,7 @@ void BuildAndroid::RunADBListDevices()
 
     if (!subprocess)
     {
-        FailBuild("BuildFailed::RunADBListDevices");
+        FailBuild("Android List Device operation did not launch successfully.");
         return;
     }
 
@@ -245,10 +250,16 @@ void BuildAndroid::RunAntDebug()
 
     Poco::Process::Env env;
 
+    String buildApk = "debug";  // the default
+
+    if ( tprefs->GetReleaseCheck() > 0 ) // create release apk
+        buildApk = "release";
+
+
 #ifdef ATOMIC_PLATFORM_OSX
     String antCommand = tprefs->GetAntPath();
     Vector<String> args;
-    args.Push("debug");
+    args.Push(buildApk);
 #endif
 #ifdef ATOMIC_PLATFORM_WINDOWS
     // C:\ProgramData\Oracle\Java\javapath;
@@ -259,7 +270,7 @@ void BuildAndroid::RunAntDebug()
     // ant is a batch file on windows, so have to run with cmd /c
     args.Push("/c");
     args.Push("\"" + antPath + "\"");
-    args.Push("debug");
+    args.Push(buildApk);
 #endif
 #ifdef ATOMIC_PLATFORM_LINUX 
 
@@ -275,10 +286,10 @@ void BuildAndroid::RunAntDebug()
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     if ( !fileSystem->FileExists ( antCommand) ) 
     {
-        FailBuild("BuildFailed ant program not installed");
+        FailBuild("The ant program can not be found, check the Ant Path in Build Settings.");
     }
     Vector<String> args;
-    args.Push("debug");
+    args.Push(buildApk);
 #endif
 
     currentBuildPhase_ = AntBuildDebug;
@@ -286,12 +297,12 @@ void BuildAndroid::RunAntDebug()
 
     if (!subprocess)
     {
-        FailBuild("BuildFailed::RunAntDebug");
+        FailBuild("The ant build operation did not launch successfully.");
         return;
     }
 
     VariantMap buildOutput;
-    buildOutput[BuildOutput::P_TEXT] = "<color #D4FB79>Starting Android Deployment</color>\n\n";
+    buildOutput[BuildOutput::P_TEXT] = "<color #D4FB79>Starting Android " + buildApk + " Deployment</color>\n\n";
     SendEvent(E_BUILDOUTPUT, buildOutput);
 
     SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildAndroid, HandleAntDebugComplete));
@@ -329,6 +340,9 @@ void BuildAndroid::Build(const String& buildPath)
     buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();
 
     Initialize();
+ 
+    if (!BuildClean(buildPath_))
+        return;
 
     //generate manifest file
     String manifest;
@@ -340,16 +354,14 @@ void BuildAndroid::Build(const String& buildPath)
             manifest += ";";
     }
 
-    FileSystem* fileSystem = GetSubsystem<FileSystem>();
-    if (fileSystem->DirExists(buildPath_))
-        fileSystem->RemoveDir(buildPath_, true);
-
     String buildSourceDir = tenv->GetToolDataDir();
 
     String androidProject = buildSourceDir + "Deployment/Android";
 
     // Copy the base android project
-    fileSystem->CopyDir(androidProject, buildPath_);
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+    if( !BuildCopyDir(androidProject, buildPath_))
+        return;
 
     Vector<String> defaultResourcePaths;
     GetDefaultResourcePaths(defaultResourcePaths);
@@ -357,18 +369,28 @@ void BuildAndroid::Build(const String& buildPath)
 
     for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
     {
-        fileSystem->CopyDir(defaultResourcePaths[i], buildPath_ + "/assets/" + GetFileName(RemoveTrailingSlash(defaultResourcePaths[i])));
+        if ( !BuildCopyDir(defaultResourcePaths[i], buildPath_ + "/assets/" + GetFileName(RemoveTrailingSlash(defaultResourcePaths[i]))))
+            return;
     }
 
-    fileSystem->CopyDir(project->GetProjectPath() + "Cache/", buildPath_ + "/assets/Cache");
-    fileSystem->CopyDir(projectResources, buildPath_ + "/assets/AtomicResources");
+    if( !BuildCopyDir(project->GetProjectPath() + "Cache/", buildPath_ + "/assets/Cache"))
+        return;
+    if( !BuildCopyDir(projectResources, buildPath_ + "/assets/AtomicResources"))
+        return;
 
     // write the manifest
     SharedPtr<File> mfile(new File(context_, buildPath_ + "/assets/AtomicManifest", FILE_WRITE));
     mfile->WriteString(manifest);
     mfile->Close();
 
-    AndroidProjectGenerator gen(context_);
+    //check for Deployment/Android/libs/armeabi-v7a/libAtomicPlayer.so
+    if ( !fileSystem->FileExists(androidProject + "/libs/armeabi-v7a/libAtomicPlayer.so")  )
+    {
+        FailBuild( "The file libAtomicPlayer.so is not found. This is required for APK generation." );
+        return;
+    }
+
+    AndroidProjectGenerator gen(context_, this);
     gen.SetBuildPath(buildPath_);
 
     if (!gen.Generate())

+ 30 - 0
Source/ToolCore/Build/BuildBase.cpp

@@ -19,6 +19,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 //
+#include <Poco/File.h>
 
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/FileSystem.h>
@@ -164,6 +165,27 @@ bool BuildBase::BuildCopyFile(const String& srcFileName, const String& destFileN
     return true;
 }
 
+bool BuildBase::BuildCopyDir(const String& srcDir, const String& destDir)
+{
+    if (buildFailed_)
+    {
+        LOGERRORF("BuildBase::BuildCopyDir - Attempt to copy directory of failed build, %s", srcDir.CString());
+        return false;
+    }
+
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+
+    bool result = fileSystem->CopyDir(srcDir, destDir);
+
+    if (!result)
+    {
+        FailBuild(ToString("BuildBase::BuildCopyDir: Unable to copy dir %s -> %s", srcDir.CString(), destDir.CString()));
+        return false;
+    }
+
+    return true;
+}
+
 bool BuildBase::CheckIncludeResourceFile(const String & resourceDir, const String & fileName)
 {
     return (GetExtension(fileName) != ".psd");
@@ -181,7 +203,15 @@ bool BuildBase::BuildRemoveDirectory(const String& path)
     if (!fileSystem->DirExists(path))
         return true;
 
+#ifdef ATOMIC_PLATFORM_LINUX
+    bool result = true;   // fileSystem->RemoveDir(path, true); crashes on linux
+    Poco::File dirs(buildPath_.CString());
+    dirs.remove(true);
+    if (fileSystem->DirExists(buildPath_))
+        result = false;
+#else
     bool result = fileSystem->RemoveDir(path, true);
+#endif
 
     if (!result)
     {

+ 4 - 0
Source/ToolCore/Build/BuildBase.h

@@ -38,6 +38,8 @@ class BuildBase : public Object
 {
     OBJECT(BuildBase);
 
+friend class AndroidProjectGenerator;
+
 public:
 
     BuildBase(Context* context, Project* project, PlatformID platform);
@@ -70,6 +72,8 @@ protected:
     bool BuildRemoveDirectory(const String& path);
     bool BuildCreateDirectory(const String& path);
     bool BuildCopyFile(const String& srcFileName, const String& destFileName);
+    bool BuildCopyDir(const String& srcDir, const String& destDir);
+
     virtual bool CheckIncludeResourceFile(const String& resourceDir, const String& fileName);
 
     void GenerateResourcePackage(const String& resourcePackagePath);

+ 13 - 9
Source/ToolCore/Build/BuildIOS.cpp

@@ -311,27 +311,31 @@ void BuildIOS::Build(const String& buildPath)
 
     Initialize();
 
-    if (fileSystem->DirExists(buildPath_))
-        fileSystem->RemoveDir(buildPath_, true);
+    if (!BuildClean(buildPath_))
+        return;
 
     String buildSourceDir = tenv->GetToolDataDir();
 
     String buildAppSourceDir = buildSourceDir + "Deployment/IOS/AtomicPlayer.app";
 
-    fileSystem->CreateDir(buildPath_);
+    if (!BuildCreateDirectory(buildPath_))
+        return;
 
     String buildDestDist = buildPath_ + "/AtomicPlayer.app";
 
-    fileSystem->CreateDir(buildDestDist);
+    if (!BuildCreateDirectory(buildDestDist))
+        return;
 
     String resourcePackagePath = buildDestDist + "/AtomicResources" + PAK_EXTENSION;
     GenerateResourcePackage(resourcePackagePath);
 
-    fileSystem->Copy(buildAppSourceDir + "/AtomicPlayer", buildDestDist + "/AtomicPlayer");
-    fileSystem->Copy(buildAppSourceDir + "/PkgInfo", buildDestDist + "/PkgInfo");
-
-    fileSystem->Copy(iosSettings->GetProvisionFile(), buildDestDist + "/embedded.mobileprovision");
-
+    if (!BuildCopyFile(buildAppSourceDir + "/AtomicPlayer", buildDestDist + "/AtomicPlayer"))
+        return;
+    if (!BuildCopyFile(buildAppSourceDir + "/PkgInfo", buildDestDist + "/PkgInfo"))
+        return;
+    if (!BuildCopyFile(iosSettings->GetProvisionFile(), buildDestDist + "/embedded.mobileprovision"))
+        return;
+        
     String entitlements = GenerateEntitlements();
     String plist = GenerateInfoPlist();
 

+ 1 - 1
Source/ToolCore/Build/BuildMac.cpp

@@ -102,7 +102,7 @@ void BuildMac::Build(const String& buildPath)
 
     BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
 
-    if (!BuildRemoveDirectory(buildPath_))
+    if (!BuildClean(buildPath_))
         return;
 
     FileSystem* fileSystem = GetSubsystem<FileSystem>();

+ 16 - 10
Source/ToolCore/Build/BuildWeb.cpp

@@ -79,25 +79,31 @@ void BuildWeb::Build(const String& buildPath)
 
     Initialize();
 
-    FileSystem* fileSystem = GetSubsystem<FileSystem>();
-    if (fileSystem->DirExists(buildPath_))
-        fileSystem->RemoveDir(buildPath_, true);
+    if (!BuildClean(buildPath_))
+        return;
 
     String dataPath = tenv->GetToolDataDir();
 
     String buildSourceDir  = dataPath + "Deployment/Web";
 
-    fileSystem->CreateDir(buildPath_);
+    if (!BuildCreateDirectory(buildPath_))
+        return;
 
     String resourcePackagePath = buildPath_ + "/AtomicResources.data";
     GenerateResourcePackage(resourcePackagePath);
 
-    fileSystem->Copy(buildSourceDir + "/AtomicPlayer.html", buildPath_ + "/AtomicPlayer.html");
-    fileSystem->Copy(buildSourceDir + "/AtomicPlayer.html.mem", buildPath_ + "/AtomicPlayer.html.mem");
-    fileSystem->Copy(buildSourceDir + "/AtomicPlayer.js", buildPath_ + "/AtomicPlayer.js");
-    fileSystem->Copy(buildSourceDir + "/AtomicLoader.js", buildPath_ + "/AtomicLoader.js");
-    fileSystem->Copy(buildSourceDir + "/index.html", buildPath_ + "/index.html");
-    fileSystem->Copy(buildSourceDir + "/Atomic_Logo_Header.png", buildPath_ + "/Atomic_Logo_Header.png");
+    if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.html", buildPath_ + "/AtomicPlayer.html"))
+        return;
+    if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.html.mem", buildPath_ + "/AtomicPlayer.html.mem"))
+        return;
+    if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.js", buildPath_ + "/AtomicPlayer.js"))
+        return;
+    if (!BuildCopyFile(buildSourceDir + "/AtomicLoader.js", buildPath_ + "/AtomicLoader.js"))
+        return;
+    if (!BuildCopyFile(buildSourceDir + "/index.html", buildPath_ + "/index.html"))
+        return;
+    if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header.png", buildPath_ + "/Atomic_Logo_Header.png"))
+        return;
 
     File file(context_, buildSourceDir + "/AtomicResources_js.template", FILE_READ);
     unsigned size = file.GetSize();

+ 1 - 1
Source/ToolCore/Build/BuildWindows.cpp

@@ -86,7 +86,7 @@ bool BuildWindows::CheckIncludeResourceFile(const String& resourceDir, const Str
         }
     }
     // #623 END TODO
-    
+
     return BuildBase::CheckIncludeResourceFile(resourceDir, fileName);
 }
 

+ 2 - 2
Source/ToolCore/Import/ImportConfig.cpp

@@ -58,8 +58,6 @@ bool ImportConfig::LoadModelImporterConfig(const JSONValue& jModelImporterConfig
             valueMap_["aiProcess_ImproveCacheLocality"] = GetBoolValue(jvalue, true);
         else if (key == "fixInFacingNormals")
             valueMap_["aiProcess_FixInfacingNormals"] = GetBoolValue(jvalue, true);
-        else if (key == "fixInfacingNormals")
-            valueMap_["aiProcess_FixInfacingNormals"] = GetBoolValue(jvalue, true);
         else if (key == "findInvalidData")
             valueMap_["aiProcess_FindInvalidData"] = GetBoolValue(jvalue, true);
         else if (key == "genUVCoords")
@@ -68,6 +66,8 @@ bool ImportConfig::LoadModelImporterConfig(const JSONValue& jModelImporterConfig
             valueMap_["aiProcess_FindInstances"] = GetBoolValue(jvalue, true);
         else if (key == "optimizeMeshes")
             valueMap_["aiProcess_OptimizeMeshes"] = GetBoolValue(jvalue, true);
+        else if (key == "importMaterials")
+            valueMap_["ImportMaterials"] = GetBoolValue(jvalue, true);
     }
 
     return true;

+ 12 - 4
Source/ToolCore/Import/OpenAssetImporter.cpp

@@ -53,6 +53,8 @@ OpenAssetImporter::OpenAssetImporter(Context* context) : Object(context) ,
     scene_(0),
     rootNode_(0),
     useSubdirs_(true),
+    importMaterials_(true),
+    importMaterialsDefault_(true),
     localIDs_(false),
     saveBinary_(false),
     createZone_(true),
@@ -902,6 +904,8 @@ void OpenAssetImporter::SetOveriddenFlags(VariantMap& aiFlagParameters)
             ApplyFlag(aiProcess_FindInstances, itr->second_.GetBool());
         else if (itr->first_ == "aiProcess_OptimizeMeshes")
             ApplyFlag(aiProcess_OptimizeMeshes, itr->second_.GetBool());
+        else if (itr->first_ == "ImportMaterials")
+            importMaterialsDefault_ = itr->second_.GetBool();
 
         itr++;
     }
@@ -1184,13 +1188,17 @@ bool OpenAssetImporter::BuildAndSaveAnimations(OutModel* model, const String &an
 // Materials
 void OpenAssetImporter::ExportMaterials(HashSet<String>& usedTextures)
 {
-    if (useSubdirs_)
+    if (importMaterials_ )
     {
-        context_->GetSubsystem<FileSystem>()->CreateDir(sourceAssetPath_ + "Materials");
+        if (useSubdirs_)
+        {
+            context_->GetSubsystem<FileSystem>()->CreateDir(sourceAssetPath_ + "Materials");
+        }
+
+        for (unsigned i = 0; i < scene_->mNumMaterials; ++i)
+            BuildAndSaveMaterial(scene_->mMaterials[i], usedTextures);
     }
 
-    for (unsigned i = 0; i < scene_->mNumMaterials; ++i)
-        BuildAndSaveMaterial(scene_->mMaterials[i], usedTextures);
 }
 
 bool OpenAssetImporter::BuildAndSaveMaterial(aiMaterial* material, HashSet<String>& usedTextures)

+ 5 - 1
Source/ToolCore/Import/OpenAssetImporter.h

@@ -60,9 +60,11 @@ public:
     void SetEndTime(float endTime) { endTime_ = endTime; }
     void SetScale(float scale) { scale_ = scale; }
     void SetExportAnimations(bool exportAnimations) { noAnimations_ = !exportAnimations; }
-
+    void SetImportMaterials(bool importMaterials) { importMaterials_ = importMaterials; }
     void SetVerboseLog(bool verboseLog) { verboseLog_ = verboseLog; }
 
+    bool GetImportMaterialsDefault() { return importMaterialsDefault_; }
+
     const Vector<AnimationInfo>& GetAnimationInfos() { return animationInfos_; }
 
 private:
@@ -106,6 +108,8 @@ private:
     String resourcePath_;
     String outPath_;
     bool useSubdirs_;
+    bool importMaterials_;
+    bool importMaterialsDefault_;
     bool localIDs_;
     bool saveBinary_;
     bool createZone_;

+ 2 - 0
Source/ToolCore/Project/ProjectBuildSettings.cpp

@@ -123,6 +123,7 @@ void AndroidBuildSettings::Write(JSONValue& parent)
     json.Set("targetSDKVersion", targetSDKVersion_);
     json.Set("minSDKVersion", minSDKVersion_);
     json.Set("activityName", activityName_);
+    json.Set("iconPath", iconPath_);
 
     parent.Set("AndroidBuildSettings", json);
 
@@ -144,6 +145,7 @@ void AndroidBuildSettings::Read(JSONValue& parent)
     targetSDKVersion_ = json.Get("targetSDKVersion").GetString();
     minSDKVersion_ = json.Get("minSDKVersion").GetString();
     activityName_ = json.Get("activityName").GetString();
+    iconPath_ = json.Get("iconPath").GetString();
 
 }
 

+ 3 - 0
Source/ToolCore/Project/ProjectBuildSettings.h

@@ -133,6 +133,7 @@ public:
     const String& GetSDKVersion() const { return targetSDKVersion_; }
     const String& GetMinSDKVersion() const { return minSDKVersion_; }
     const String& GetActivityName() const { return activityName_; }
+    const String& GetIconPath() const { return iconPath_; }
 
     void SetAppName(const String& name) { appName_ = name; }
     void SetPackageName(const String& packageName) { packageName_ = packageName; }
@@ -142,6 +143,7 @@ public:
     void SetSDKVersion(const String& value) { targetSDKVersion_ = value; }
     void SetMinSDKVersion(const String& value) { minSDKVersion_ = value; }
     void SetActivityName(const String& value) { activityName_ = value; }
+    void SetIconPath(const String& value) { iconPath_ = value; }
 
     void Write(JSONValue& parent);
     void Read(JSONValue& parent);
@@ -156,6 +158,7 @@ private:
     String targetSDKVersion_;
     String minSDKVersion_;
     String activityName_;
+    String iconPath_;
 };
 
 class IOSBuildSettings : public RefCounted

+ 20 - 13
Source/ToolCore/ToolPrefs.cpp

@@ -31,7 +31,12 @@
 namespace ToolCore
 {
 
-ToolPrefs::ToolPrefs(Context* context) : Object(context)
+ToolPrefs::ToolPrefs(Context* context) : Object(context),
+    androidSDKPath_(),
+    jdkRootPath_(),
+    antPath_(),
+    releasePath_(),
+    releaseCheck_(false)
 {
 
 }
@@ -94,6 +99,8 @@ void ToolPrefs::Load()
         androidSDKPath_ = androidRoot.Get("androidSDKPath").GetString();
         jdkRootPath_ = androidRoot.Get("jdkRootPath").GetString();
         antPath_ = androidRoot.Get("antPath").GetString();
+        releasePath_ = androidRoot.Get("releasePath").GetString();
+        releaseCheck_ = androidRoot.Get("releaseCheck").GetInt();
     }
 
 }
@@ -101,21 +108,21 @@ void ToolPrefs::Load()
 void ToolPrefs::Save()
 {
     String path = GetPrefsPath();
-
+ 
     SharedPtr<JSONFile> jsonFile(new JSONFile(context_));
-
-    JSONValue root = jsonFile->GetRoot();
+    JSONValue& root = jsonFile->GetRoot();
+    root.Clear();
+    
+    JSONValue androidRoot; 
+    androidRoot["androidSDKPath"] = androidSDKPath_;
+    androidRoot["jdkRootPath"] = jdkRootPath_;
+    androidRoot["antPath"] = antPath_;
+    androidRoot["releasePath"] = releasePath_;
+    androidRoot["releaseCheck"] = releaseCheck_;
+   root["android"] = androidRoot;
 
     SharedPtr<File> file(new File(context_, path, FILE_WRITE));
-
-    JSONValue androidRoot;
-    androidRoot.Set("androidSDKPath", androidSDKPath_);
-    androidRoot.Set("jdkRootPath", jdkRootPath_);
-    androidRoot.Set("antPath", antPath_);
-    root.Set("android", androidRoot);
-
-    jsonFile->Save(*file, String("   "));
-
+    jsonFile->Save(*file, "   ");
     file->Close();
 
 }

+ 6 - 1
Source/ToolCore/ToolPrefs.h

@@ -41,10 +41,14 @@ public:
     const String& GetAndroidSDKPath() { return androidSDKPath_; }
     const String& GetJDKRootPath() { return jdkRootPath_; }
     const String& GetAntPath();
+    const String& GetReleasePath() { return releasePath_; }
+    const int GetReleaseCheck() { return releaseCheck_; }
 
     void SetAndroidSDKPath(const String& path) { androidSDKPath_ = path; }
     void SetJDKRootPath(const String& path) { jdkRootPath_ = path; }
     void SetAntPath(const String& path) { antPath_ = path; }
+    void SetReleasePath(const String& path) { releasePath_ = path; }
+    void SetReleaseCheck(const int value) { releaseCheck_ = value; }
 
     String GetPrefsPath();
     void Load();
@@ -55,7 +59,8 @@ private:
     String androidSDKPath_;
     String jdkRootPath_;
     String antPath_;
-
+    String releasePath_;
+    int releaseCheck_;
 };
 
 }

+ 1 - 1
Source/ToolCoreJS/CMakeLists.txt

@@ -10,4 +10,4 @@ add_library(ToolCoreJS ${SOURCE_FILES})
 
 target_link_libraries(ToolCoreJS ToolCore)
 
-add_dependencies(ToolCoreJS AtomicTool)
+add_dependencies(ToolCoreJS AtomicToolCheckScripts)