summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--CONTRIBUTING.md60
-rw-r--r--ISSUE_TEMPLATE10
-rw-r--r--LICENSE.md48
-rw-r--r--README.md6
-rw-r--r--core/bind/core_bind.cpp11
-rw-r--r--core/bind/core_bind.h2
-rw-r--r--core/color.cpp12
-rw-r--r--core/error_macros.h5
-rw-r--r--core/global_constants.cpp3
-rw-r--r--core/io/http_client.cpp8
-rw-r--r--core/io/resource_format_xml.cpp1
-rw-r--r--core/math/aabb.h18
-rw-r--r--core/math/octree.h12
-rw-r--r--core/os/keyboard.cpp2
-rw-r--r--core/os/keyboard.h2
-rw-r--r--core/os/memory.h8
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h1
-rw-r--r--core/range_iterator.cpp169
-rw-r--r--core/range_iterator.h72
-rw-r--r--core/register_core_types.cpp4
-rw-r--r--core/typedefs.h32
-rw-r--r--core/ustring.cpp31
-rw-r--r--core/ustring.h2
-rw-r--r--core/vector.h35
-rw-r--r--demos/2d/normalmaps/diffuse.jpgbin535660 -> 309334 bytes
-rw-r--r--demos/2d/normalmaps/diffuse.pngbin2392221 -> 0 bytes
-rw-r--r--demos/2d/normalmaps/normal.jpgbin0 -> 501428 bytes
-rw-r--r--demos/2d/normalmaps/normal.pngbin2301245 -> 0 bytes
-rw-r--r--demos/2d/normalmaps/normal_material.resbin503 -> 508 bytes
-rw-r--r--demos/2d/normalmaps/normalmap.scnbin3168 -> 2829 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/burano.jpgbin246589 -> 265390 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/burano.pngbin974437 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/forest.jpgbin0 -> 314190 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/forest.pngbin1199433 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/mountains.jpgbin0 -> 214974 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/mountains.pngbin927435 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/platformer.jpgbin0 -> 116815 bytes
-rw-r--r--demos/2d/screen_space_shaders/art/platformer.pngbin44102 -> 0 bytes
-rw-r--r--demos/2d/screen_space_shaders/engine.cfg2
-rw-r--r--demos/2d/screen_space_shaders/screen_shaders.scnbin7562 -> 7897 bytes
-rw-r--r--demos/3d/polygon_path_finder/engine.cfg5
-rw-r--r--demos/3d/polygon_path_finder/icon.pngbin712 -> 0 bytes
-rw-r--r--demos/3d/polygon_path_finder/poly_with_holes.scnbin2974 -> 0 bytes
-rw-r--r--demos/3d/polygon_path_finder/polygonpathfinder.gd77
-rw-r--r--demos/gui/translation/main.scnbin2939 -> 2119 bytes
-rw-r--r--demos/gui/translation/notosans.otfbin16426032 -> 0 bytes
-rw-r--r--demos/plugins/custom_dock/custom_dock.scnbin0 -> 1494 bytes
-rw-r--r--demos/plugins/custom_dock/dock_plugin.gd23
-rw-r--r--demos/plugins/custom_dock/plugin.cfg14
-rw-r--r--demos/plugins/custom_import_plugin/import_plugin.gd81
-rw-r--r--demos/plugins/custom_import_plugin/material_dialog.gd67
-rw-r--r--demos/plugins/custom_import_plugin/material_dialog.tscn111
-rw-r--r--demos/plugins/custom_import_plugin/material_import.gd22
-rw-r--r--demos/plugins/custom_import_plugin/plugin.cfg14
-rw-r--r--demos/plugins/custom_import_plugin/test.mtxt1
-rw-r--r--demos/plugins/custom_node/heart.gd12
-rw-r--r--demos/plugins/custom_node/heart.pngbin0 -> 12584 bytes
-rw-r--r--demos/plugins/custom_node/heart_icon.pngbin0 -> 809 bytes
-rw-r--r--demos/plugins/custom_node/heart_plugin.gd18
-rw-r--r--demos/plugins/custom_node/plugin.cfg14
-rw-r--r--demos/plugins/readme.txt13
-rw-r--r--doc/base/classes.xml1325
-rw-r--r--doc/tools/makerst.py49
-rw-r--r--drivers/unix/memory_pool_static_malloc.cpp27
-rw-r--r--godot_icon.pngbin12574 -> 0 bytes
-rw-r--r--godot_icon.svg133
-rw-r--r--icon.pngbin0 -> 12525 bytes
-rw-r--r--icon.svg132
-rw-r--r--logo.svg (renamed from godot_logo.svg)0
-rw-r--r--main/input_default.cpp29
-rw-r--r--main/main.cpp7
-rw-r--r--modules/gdscript/gd_editor.cpp1
-rw-r--r--modules/gdscript/gd_functions.cpp83
-rw-r--r--modules/gdscript/gd_functions.h1
-rw-r--r--modules/gdscript/gd_parser.cpp16
-rw-r--r--modules/gdscript/gd_script.cpp5
-rw-r--r--platform/android/export/export.cpp10
-rw-r--r--platform/haiku/key_mapping_haiku.cpp2
-rwxr-xr-xplatform/iphone/gl_view.mm71
-rw-r--r--platform/iphone/os_iphone.cpp22
-rw-r--r--platform/iphone/os_iphone.h8
-rw-r--r--platform/iphone/xcode/godot_xcode/data.pck0
-rwxr-xr-xplatform/iphone/xcode/godot_xcode/godot_debug.iphone0
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj370
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.pngbin0 -> 529 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.pngbin0 -> 648 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.pngbin0 -> 782 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.pngbin0 -> 1641 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.pngbin0 -> 2547 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.pngbin0 -> 2547 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.pngbin0 -> 3096 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.pngbin0 -> 599 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.pngbin0 -> 3035 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.pngbin0 -> 554 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.pngbin0 -> 480 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.pngbin0 -> 274 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json128
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.pngbin0 -> 215 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.pngbin0 -> 218 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.pngbin0 -> 218 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.pngbin0 -> 224 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.pngbin0 -> 225 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.pngbin0 -> 230 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.pngbin0 -> 207 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.pngbin0 -> 205 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.pngbin0 -> 208 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.pngbin0 -> 209 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.pngbin0 -> 209 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.pngbin0 -> 211 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.pngbin0 -> 210 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.pngbin0 -> 227 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.pngbin0 -> 212 bytes
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes17
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings2
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist50
-rw-r--r--platform/iphone/xcode/godot_xcode/godot_ios/main.m39
-rwxr-xr-xplatform/iphone/xcode/godot_xcode/godot_opt.iphone0
-rw-r--r--platform/nacl/nacl_keycodes.h2
-rw-r--r--platform/osx/os_osx.mm2
-rw-r--r--platform/server/detect.py1
-rw-r--r--platform/windows/key_mapping_win.cpp2
-rw-r--r--platform/x11/detect.py18
-rw-r--r--platform/x11/joystick_linux.cpp35
-rw-r--r--platform/x11/joystick_linux.h8
-rw-r--r--platform/x11/key_mapping_x11.cpp2
-rw-r--r--scene/2d/navigation_polygon.cpp4
-rw-r--r--scene/2d/tile_map.cpp6
-rw-r--r--scene/3d/particles.cpp4
-rw-r--r--scene/audio/event_player.cpp2
-rw-r--r--scene/main/viewport.cpp5
-rw-r--r--scene/resources/packed_scene.cpp29
-rw-r--r--scene/resources/packed_scene.h11
-rw-r--r--scene/resources/scene_format_text.cpp32
-rw-r--r--tools/doc/doc_data.cpp8
-rw-r--r--tools/docker/Dockerfile13
-rw-r--r--tools/docker/README.md40
-rw-r--r--tools/docker/scripts/install-android-tools90
-rw-r--r--tools/editor/create_dialog.cpp29
-rw-r--r--tools/editor/editor_data.cpp27
-rw-r--r--tools/editor/editor_data.h4
-rw-r--r--tools/editor/editor_help.cpp82
-rw-r--r--tools/editor/editor_import_export.cpp115
-rw-r--r--tools/editor/editor_import_export.h11
-rw-r--r--tools/editor/editor_node.cpp229
-rw-r--r--tools/editor/editor_node.h41
-rw-r--r--tools/editor/editor_plugin.cpp99
-rw-r--r--tools/editor/editor_plugin.h39
-rw-r--r--tools/editor/editor_plugin_settings.cpp188
-rw-r--r--tools/editor/editor_plugin_settings.h35
-rw-r--r--tools/editor/editor_settings.cpp298
-rw-r--r--tools/editor/editor_settings.h17
-rw-r--r--tools/editor/io_plugins/editor_font_import_plugin.cpp2
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp11
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h2
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp14
-rw-r--r--tools/editor/plugins/baked_light_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/color_ramp_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/path_editor_plugin.cpp12
-rw-r--r--tools/editor/plugins/path_editor_plugin.h6
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/shader_editor_plugin.cpp4
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp49
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.h4
-rw-r--r--tools/editor/project_manager.cpp6
-rw-r--r--tools/editor/project_settings.cpp139
-rw-r--r--tools/editor/project_settings.h17
-rw-r--r--tools/editor/settings_config_dialog.cpp201
-rw-r--r--tools/editor/settings_config_dialog.h14
-rw-r--r--tools/editor/spatial_editor_gizmos.cpp63
-rw-r--r--tools/editor/spatial_editor_gizmos.h93
-rw-r--r--tools/scripts/sort-demos.sh29
-rw-r--r--tools/steam/community_capsule.jpgbin0 -> 5571 bytes
-rw-r--r--tools/steam/community_capsule.pngbin0 -> 7263 bytes
-rw-r--r--tools/steam/header.pngbin0 -> 18980 bytes
-rw-r--r--tools/steam/icon32.icns41
-rw-r--r--tools/steam/icon32.icobin0 -> 4286 bytes
-rw-r--r--tools/steam/icons.zipbin0 -> 41307 bytes
-rw-r--r--tools/steam/large_capsule.pngbin0 -> 19020 bytes
-rw-r--r--tools/steam/main_capsule.pngbin0 -> 25359 bytes
-rw-r--r--tools/steam/make_icons.sh5
-rw-r--r--tools/steam/small_capsule.pngbin0 -> 9144 bytes
-rw-r--r--version.py2
188 files changed, 4503 insertions, 1321 deletions
diff --git a/.travis.yml b/.travis.yml
index a8ecc62c58..032e6aa0b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,10 +32,14 @@ matrix:
env: GODOT_TARGET=windows
- compiler: gcc
env: GODOT_TARGET=iphone
+ - compiler: gcc
+ env: GODOT_TARGET=osx
- compiler: clang
env: GODOT_TARGET=android
- compiler: clang
env: GODOT_TARGET=windows
+ - compiler: clang
+ env: GODOT_TARGET=x11
before_script:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 97ce9c1403..887fe93779 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,37 +1,59 @@
-## PLEASE READ:
+# How to contribute efficiently
-### Reporting Bugs:
+**Please read the first section before reporting a bug!**
-If you are reporting a new issue, you will make our life much simpler (and the fix come much sooner):
+## Reporting bugs or proposing features
-#### Specify the Platform
+The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
+
+Everything refered to hereafter as "bug" also applies for feature requests.
+
+If you are reporting a new issue, you will make our life much simpler (and the fix come much sooner) by following those guidelines:
+
+#### Search first in the existing database
+
+Issues are often reported several times by various users. It's a good practice to **search first** in the issues database before reporting your issue. If you don't find a relevant match or if you are unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
+
+#### Specify the platform
-Godot runs on a large variety of platforms and operating systems and devices. If you believe your issue is device/platform dependent, please specify:
-* Operating System
-* Device
-* GPU Model
+Godot runs on a large variety of platforms and operating systems and devices. If you believe your issue is device/platform dependent (for example if it is related to the rendering, crashes or compilation errors), please specify:
+* Operating system
+* Device (including architecture, e.g. x86, x86_64, arm, etc.)
+* GPU model (and driver in use if you know it)
-#### Specify Reproduction Steps
+#### Specify steps to reproduce
-Many bugs can't be reproduced unless specific steps are taken. Please **specify the exact steps** that must be taken to reproduce the condition.
+Many bugs can't be reproduced unless specific steps are taken. Please **specify the exact steps** that must be taken to reproduce the condition, and try to keep them as minimal as possible.
-#### Provide a Simple, Example Project
+#### Provide a simple, example project
-Sometimes an unexpected behavior happens in your project. In such case understand that:
+Sometimes an unexpected behavior happens in your project. In such case, understand that:
* What happens to you may not happen to other users.
-* We can't take the time a look at your project, learn it and then figure out why it's failing.
+* We can't take the time to look at your project, understand how it is set up and then figure out why it's failing.
-To speed up our work, prepare for us **a simple project** that isolates and reproduces the issue. This is always the **the best way for us to fix it**.
+To speed up our work, please prepare for us **a simple project** that isolates and reproduces the issue. This is always the **the best way for us to fix it**. You can attach a zip file with the minimal project directly to the bug report, by drag and dropping the file in the GitHub edition field.
-### Contributing Pull Requests
+## Contributing pull requests
-If you are adding new engine funcitonality, please make sure that:
+If you want to add new engine functionalities, please make sure that:
* This functionality is desired.
-* You talked to other developers on how to implement it best.
-* Even if it won't be merged, your PR is useful for future work on another developer.
+* You talked to other developers on how to implement it best (on either communication channel, and maybe in a GitHub issue first before making your PR).
+* Even if it does not get merged, your PR is useful for future work by another developer.
+
+Similar rules can be applied when contributing bug fixes - it's always best to discuss the implementation in the bug report first if you are not 100% about what would be the best fix.
+
+#### Be nice to the git history
+
+Try to make simple PRs with that handle one specific topic. Just like for reporting issues, it's better to open 3 different PRs that each address a different issue than one big PR with three commits.
+
+When updating your fork with upstream changes, please use ``git pull --rebase`` to avoid creating "merge commits". Those commits unnecessarily pollute the git history when coming from PRs.
+
+Also try to make commits that bring the engine from one stable state to another stable state, i.e. if your first commit has a bug that you fixed in the second commit, try to merge them together before making your pull request (see ``git rebase -i`` and relevant help about rebasing or ammending commits on the Internet).
+
+This git style guide has some good practices to have in mind: https://github.com/agis-/git-style-guide
Thanks!
-The Godot Development Team
+The Godot development team
diff --git a/ISSUE_TEMPLATE b/ISSUE_TEMPLATE
new file mode 100644
index 0000000000..06fa7b316d
--- /dev/null
+++ b/ISSUE_TEMPLATE
@@ -0,0 +1,10 @@
+**Operating system or device:**
+
+
+**Issue description** (what happened, and what was expected):
+
+
+**Steps to reproduce:**
+
+
+**Link to minimal example project** (optional but very welcome):
diff --git a/LICENSE.md b/LICENSE.md
index 2f78f0e37d..2f3e879c8c 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,27 +1,27 @@
- GODOT ENGINE
- http://www.godotengine.org
-**********************************************************************
- Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ GODOT ENGINE
+ http://www.godotengine.org
+
+************************************************************************
+
+ Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
-**********************************************************************
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+************************************************************************
diff --git a/README.md b/README.md
index 20d1367762..2586a5ea0d 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
![GODOT](/logo.png)
+http://www.godotengine.org
+
### The Engine
Godot is a fully featured, open source, MIT licensed, game engine. It focuses on having great tools, and a visual oriented workflow that can export to PC, Mobile and Web platforms with no hassle.
@@ -11,7 +13,7 @@ Godot has been developed by Juan Linietsky and Ariel Manzur for several years, a
### Documentation
-Documentation has been moved to the [OpenProject Wiki](http://godotengine.org/projects/godot-engine/wiki/Documentation).
+Documentation has been moved to [ReadTheDocs](http://docs.godotengine.org).
### Binary Downloads, Community, etc.
@@ -22,6 +24,6 @@ http://www.godotengine.org
### Compiling from Source
Compilation instructions for every platform can be found in the Wiki:
-http://godotengine.org/projects/godot-engine/wiki/Advanced_topics
+http://docs.godotengine.org/en/latest/reference/_compiling.html
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index b291ee396b..aff047177c 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -55,11 +55,17 @@ bool _ResourceLoader::has(const String &p_path) {
return ResourceCache::has(local_path);
};
+Ref<ResourceImportMetadata> _ResourceLoader::load_import_metadata(const String& p_path) {
+
+ return ResourceLoader::load_import_metadata(p_path);
+}
+
void _ResourceLoader::_bind_methods() {
ObjectTypeDB::bind_method(_MD("load_interactive:ResourceInteractiveLoader","path","type_hint"),&_ResourceLoader::load_interactive,DEFVAL(""));
ObjectTypeDB::bind_method(_MD("load:Resource","path","type_hint", "p_no_cache"),&_ResourceLoader::load,DEFVAL(""), DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("load_import_metadata:ResourceImportMetadata","path"),&_ResourceLoader::load_import_metadata);
ObjectTypeDB::bind_method(_MD("get_recognized_extensions_for_type","type"),&_ResourceLoader::get_recognized_extensions_for_type);
ObjectTypeDB::bind_method(_MD("set_abort_on_missing_resources","abort"),&_ResourceLoader::set_abort_on_missing_resources);
ObjectTypeDB::bind_method(_MD("get_dependencies","path"),&_ResourceLoader::get_dependencies);
@@ -689,6 +695,10 @@ void _OS::native_video_pause() {
OS::get_singleton()->native_video_pause();
};
+void _OS::native_video_unpause() {
+ OS::get_singleton()->native_video_unpause();
+};
+
void _OS::native_video_stop() {
OS::get_singleton()->native_video_stop();
@@ -874,6 +884,7 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("native_video_is_playing"),&_OS::native_video_is_playing);
ObjectTypeDB::bind_method(_MD("native_video_stop"),&_OS::native_video_stop);
ObjectTypeDB::bind_method(_MD("native_video_pause"),&_OS::native_video_pause);
+ ObjectTypeDB::bind_method(_MD("native_video_unpause"),&_OS::native_video_unpause);
ObjectTypeDB::bind_method(_MD("get_scancode_string","code"),&_OS::get_scancode_string);
ObjectTypeDB::bind_method(_MD("is_scancode_unicode","code"),&_OS::is_scancode_unicode);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 30cc93fa11..2c43390d3c 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -26,6 +26,7 @@ public:
void set_abort_on_missing_resources(bool p_abort);
StringArray get_dependencies(const String& p_path);
bool has(const String& p_path);
+ Ref<ResourceImportMetadata> load_import_metadata(const String& p_path);
_ResourceLoader();
};
@@ -131,6 +132,7 @@ public:
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
void native_video_pause();
+ void native_video_unpause();
void native_video_stop();
void set_iterations_per_second(int p_ips);
diff --git a/core/color.cpp b/core/color.cpp
index c53de360bc..56a550c024 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -117,29 +117,31 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
p_h *=6.0;
+ p_h = Math::fmod(p_h,6);
i = Math::floor( p_h );
+
f = p_h - i;
p = p_v * ( 1 - p_s );
q = p_v * ( 1 - p_s * f );
t = p_v * ( 1 - p_s * ( 1 - f ) );
switch( i ) {
- case 0:
+ case 0: // Red is the dominant color
r = p_v;
g = t;
b = p;
break;
- case 1:
+ case 1: // Green is the dominant color
r = q;
g = p_v;
b = p;
break;
- case 2:
+ case 2:
r = p;
g = p_v;
b = t;
break;
- case 3:
+ case 3: // Blue is the dominant color
r = p;
g = q;
b = p_v;
@@ -149,7 +151,7 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
g = p;
b = p_v;
break;
- default: // cap_se 5:
+ default: // (5) Red is the dominant color
r = p_v;
g = p;
b = q;
diff --git a/core/error_macros.h b/core/error_macros.h
index cafbf0c16e..47b1de5df3 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -223,5 +223,10 @@ extern bool _err_error_exists;
} \
+#define WARN_PRINTS(m_string) \
+ { \
+ _err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data(),ERR_HANDLER_WARNING); \
+ _err_error_exists=false;\
+ } \
#endif
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index c306744d35..130fca1b2a 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -106,7 +106,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( KEY_KP_ENTER ),
BIND_GLOBAL_CONSTANT( KEY_KP_MULTIPLY ),
BIND_GLOBAL_CONSTANT( KEY_KP_DIVIDE ),
- BIND_GLOBAL_CONSTANT( KEY_KP_SUBSTRACT ),
+ BIND_GLOBAL_CONSTANT( KEY_KP_SUBTRACT ),
BIND_GLOBAL_CONSTANT( KEY_KP_PERIOD ),
BIND_GLOBAL_CONSTANT( KEY_KP_ADD ),
BIND_GLOBAL_CONSTANT( KEY_KP_0 ),
@@ -432,6 +432,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),
+ BIND_GLOBAL_CONSTANT( ERR_PARSE_ERROR ),
BIND_GLOBAL_CONSTANT( ERROR_QUERY_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_ALREADY_IN_USE ),
BIND_GLOBAL_CONSTANT( ERR_LOCKED ), ///< resource is locked
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 19a7286dcf..b070e52f0a 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -306,8 +306,8 @@ Error HTTPClient::poll(){
for(int i=0;i<responses.size();i++) {
- String s = responses[i].strip_edges();
- s = s.to_lower();
+ String header = responses[i].strip_edges();
+ String s = header.to_lower();
if (s.length()==0)
continue;
if (s.begins_with("content-length:")) {
@@ -316,7 +316,7 @@ Error HTTPClient::poll(){
}
if (s.begins_with("transfer-encoding:")) {
- String encoding = s.substr(s.find(":")+1,s.length()).strip_edges();
+ String encoding = header.substr(header.find(":")+1,header.length()).strip_edges();
//print_line("TRANSFER ENCODING: "+encoding);
if (encoding=="chunked") {
chunked=true;
@@ -330,7 +330,7 @@ Error HTTPClient::poll(){
response_num=num.to_int();
} else {
- response_headers.push_back(s);
+ response_headers.push_back(header);
}
}
diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp
index 8c8d79948a..03b77a4aab 100644
--- a/core/io/resource_format_xml.cpp
+++ b/core/io/resource_format_xml.cpp
@@ -1796,6 +1796,7 @@ Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const S
fw->store_8(c);
c=f->get_8();
}
+ f->close();
bool all_ok = fw->get_error()==OK;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 7c9c3081ac..0fada859c0 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -66,6 +66,7 @@ public:
bool operator!=(const AABB& p_rval) const;
_FORCE_INLINE_ bool intersects(const AABB& p_aabb) const; /// Both AABBs overlap
+ _FORCE_INLINE_ bool intersects_inclusive(const AABB& p_aabb) const; /// Both AABBs (or their faces) overlap
_FORCE_INLINE_ bool encloses(const AABB & p_aabb) const; /// p_aabb is completely inside this
AABB merge(const AABB& p_with) const;
@@ -126,6 +127,23 @@ inline bool AABB::intersects(const AABB& p_aabb) const {
return true;
}
+inline bool AABB::intersects_inclusive(const AABB& p_aabb) const {
+
+ if ( pos.x > (p_aabb.pos.x + p_aabb.size.x) )
+ return false;
+ if ( (pos.x+size.x) < p_aabb.pos.x )
+ return false;
+ if ( pos.y > (p_aabb.pos.y + p_aabb.size.y) )
+ return false;
+ if ( (pos.y+size.y) < p_aabb.pos.y )
+ return false;
+ if ( pos.z > (p_aabb.pos.z + p_aabb.size.z) )
+ return false;
+ if ( (pos.z+size.z) < p_aabb.pos.z )
+ return false;
+
+ return true;
+}
inline bool AABB::encloses(const AABB & p_aabb) const {
diff --git a/core/math/octree.h b/core/math/octree.h
index b51c4bcba7..69edf80e09 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -201,7 +201,7 @@ private:
_FORCE_INLINE_ void _pair_check(PairData *p_pair) {
- bool intersect=p_pair->A->aabb.intersects( p_pair->B->aabb );
+ bool intersect=p_pair->A->aabb.intersects_inclusive( p_pair->B->aabb );
if (intersect!=p_pair->intersect) {
@@ -480,7 +480,7 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
if (p_octant->children[i]) {
/* element exists, go straight to it */
- if (p_octant->children[i]->aabb.intersects( p_element->aabb ) ) {
+ if (p_octant->children[i]->aabb.intersects_inclusive( p_element->aabb ) ) {
_insert_element( p_element, p_octant->children[i] );
splits++;
}
@@ -497,7 +497,7 @@ void Octree<T,use_pairs,AL>::_insert_element(Element *p_element,Octant *p_octant
if (i&4)
aabb.pos.z+=aabb.size.z;
- if (aabb.intersects( p_element->aabb) ) {
+ if (aabb.intersects_inclusive( p_element->aabb) ) {
/* if actually intersects, create the child */
Octant *child = memnew_allocator( Octant, AL );
@@ -1146,7 +1146,7 @@ void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T**
continue;
e->last_pass=pass;
- if (p_aabb.intersects(e->aabb)) {
+ if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx<p_result_max) {
@@ -1175,7 +1175,7 @@ void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T**
continue;
e->last_pass=pass;
- if (p_aabb.intersects(e->aabb)) {
+ if (p_aabb.intersects_inclusive(e->aabb)) {
if (*p_result_idx<p_result_max) {
@@ -1193,7 +1193,7 @@ void Octree<T,use_pairs,AL>::_cull_AABB(Octant *p_octant,const AABB& p_aabb, T**
for (int i=0;i<8;i++) {
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects(p_aabb)) {
+ if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
_cull_AABB(p_octant->children[i],p_aabb, p_result_array,p_result_idx,p_result_max,p_subindex_array,p_mask);
}
}
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index 633aa06a9a..4c0a074a07 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -82,7 +82,7 @@ static const _KeyCodeText _keycodes[]={
{KEY_KP_ENTER ,"Kp Enter"},
{KEY_KP_MULTIPLY ,"Kp Multiply"},
{KEY_KP_DIVIDE ,"Kp Divide"},
- {KEY_KP_SUBSTRACT ,"Kp Substract"},
+ {KEY_KP_SUBTRACT ,"Kp Subtract"},
{KEY_KP_PERIOD ,"Kp Period"},
{KEY_KP_ADD ,"Kp Add"},
{KEY_KP_0 ,"Kp 0"},
diff --git a/core/os/keyboard.h b/core/os/keyboard.h
index 69e74d1252..0848f8c28e 100644
--- a/core/os/keyboard.h
+++ b/core/os/keyboard.h
@@ -98,7 +98,7 @@ enum KeyList {
KEY_KP_ENTER=SPKEY | 0x80,
KEY_KP_MULTIPLY=SPKEY | 0x81,
KEY_KP_DIVIDE=SPKEY | 0x82,
- KEY_KP_SUBSTRACT=SPKEY | 0x83,
+ KEY_KP_SUBTRACT=SPKEY | 0x83,
KEY_KP_PERIOD=SPKEY | 0x84,
KEY_KP_ADD=SPKEY | 0x85,
KEY_KP_0=SPKEY | 0x86,
diff --git a/core/os/memory.h b/core/os/memory.h
index 98b973bc06..8eb5ceccb6 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -308,11 +308,11 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
same strategy used by std::vector, and the DVector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
- unsigned int *mem = (unsigned int*)Memory::alloc_static( len + DEFAULT_ALIGNMENT, p_descr );
+ unsigned int *mem = (unsigned int*)Memory::alloc_static( len + MAX(sizeof(size_t), DEFAULT_ALIGNMENT), p_descr );
T *failptr=0; //get rid of a warning
ERR_FAIL_COND_V( !mem, failptr );
*mem=p_elements;
- mem = (unsigned int *)( ((uint8_t*)mem) + DEFAULT_ALIGNMENT);
+ mem = (unsigned int *)( ((uint8_t*)mem) + MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
T* elems = (T*)mem;
/* call operator new */
@@ -331,14 +331,14 @@ T* memnew_arr_template(size_t p_elements,const char *p_descr="") {
template<typename T>
size_t memarr_len(const T *p_class) {
- uint8_t* ptr = ((uint8_t*)p_class) - DEFAULT_ALIGNMENT;
+ uint8_t* ptr = ((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT);
return *(size_t*)ptr;
}
template<typename T>
void memdelete_arr(T *p_class) {
- unsigned int * elems = (unsigned int*)(((uint8_t*)p_class) - DEFAULT_ALIGNMENT);
+ unsigned int * elems = (unsigned int*)(((uint8_t*)p_class) - MAX(sizeof(size_t), DEFAULT_ALIGNMENT));
for (unsigned int i=0;i<*elems;i++) {
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 0bc06c8375..1aee6d9aa2 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -478,6 +478,10 @@ void OS::native_video_pause() {
};
+void OS::native_video_unpause() {
+
+};
+
void OS::native_video_stop() {
};
diff --git a/core/os/os.h b/core/os/os.h
index 0d4edb035d..a80b81bfa2 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -376,6 +376,7 @@ public:
virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
virtual bool native_video_is_playing() const;
virtual void native_video_pause();
+ virtual void native_video_unpause();
virtual void native_video_stop();
virtual bool can_use_threads() const;
diff --git a/core/range_iterator.cpp b/core/range_iterator.cpp
new file mode 100644
index 0000000000..9534e011d7
--- /dev/null
+++ b/core/range_iterator.cpp
@@ -0,0 +1,169 @@
+/*************************************************************************/
+/* range_iterator.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "range_iterator.h"
+#include "object_type_db.h"
+
+void RangeIterator::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("_iter_init","arg"),&RangeIterator::_iter_init);
+ ObjectTypeDB::bind_method(_MD("_iter_next","arg"),&RangeIterator::_iter_next);
+ ObjectTypeDB::bind_method(_MD("_iter_get","arg"),&RangeIterator::_iter_get);
+ ObjectTypeDB::bind_method(_MD("is_finished"),&RangeIterator::is_finished);
+ ObjectTypeDB::bind_method(_MD("to_array"),&RangeIterator::to_array);
+ ObjectTypeDB::bind_method(_MD("set_range","arg1","arg2","arg3"),&RangeIterator::_set_range,DEFVAL(Variant()),DEFVAL(Variant()));
+}
+
+bool RangeIterator::_iter_init(Variant arg) {
+ return !is_finished();
+}
+
+bool RangeIterator::_iter_next(Variant arg) {
+ current += step;
+ return !is_finished();
+}
+
+Variant RangeIterator::_iter_get(Variant arg) {
+ return Variant(current);
+}
+
+bool RangeIterator::is_finished() {
+ if(step > 0)
+ {
+ return current >= stop;
+ }
+ else
+ {
+ return current <= stop;
+ }
+}
+
+Array RangeIterator::to_array() {
+ if (step==0) {
+ ERR_EXPLAIN("step is zero!");
+ ERR_FAIL_V(Array());
+ }
+
+ Array arr(true);
+ if (current >= stop && step > 0) {
+ return arr;
+ }
+ if (current <= stop && step < 0) {
+ return arr;
+ }
+
+ //calculate how many
+ int count=0;
+ if (step > 0) {
+ count=((stop-current-1)/step)+1;
+ } else {
+ count=((current-stop-1)/-step)+1;
+ }
+
+ arr.resize(count);
+
+ if (step > 0) {
+ int idx=0;
+ for(int i=current;i<stop;i+=step) {
+ arr[idx++]=i;
+ }
+ } else {
+ int idx=0;
+ for(int i=current;i>stop;i+=step) {
+ arr[idx++]=i;
+ }
+ }
+
+ return arr;
+}
+
+void RangeIterator::set_range(int stop) {
+ this->current = 0;
+ this->stop = stop;
+ this->step = (stop > 0)?(1):(-1);
+}
+
+void RangeIterator::set_range(int start, int stop) {
+ this->current = start;
+ this->stop = stop;
+ this->step = (stop > start)?(1):(-1);
+}
+
+void RangeIterator::set_range(int start, int stop, int step) {
+ if(step == 0)
+ {
+ ERR_EXPLAIN("step is zero!");
+ ERR_FAIL();
+ }
+
+ this->current = start;
+ this->stop = stop;
+ this->step = step;
+}
+
+Ref<RangeIterator> RangeIterator::_set_range(Variant arg1, Variant arg2, Variant arg3)
+{
+ bool valid = true;
+ if(arg1.get_type() == Variant::INT)
+ {
+ if(arg2.get_type() == Variant::INT)
+ {
+ if(arg3.get_type() == Variant::INT) set_range((int)arg1, (int)arg2, (int)arg3); // (start, end, step)
+ else if(arg3.get_type() == Variant::NIL) set_range((int)arg1, (int)arg2); // (start, end)
+ else valid = false;
+ }
+ else if(arg2.get_type() == Variant::NIL) set_range((int)arg1); // (end)
+ else valid = false;
+ }
+ else valid = false;
+
+ if(!valid)
+ {
+ ERR_EXPLAIN("Invalid type in function 'set_range' in base 'RangeIterator'. Expected 1, 2, or 3 ints.");
+ ERR_FAIL_V(Ref<RangeIterator>());
+ }
+ return Ref<RangeIterator>(this);
+}
+
+RangeIterator::RangeIterator() {
+ current = 0;
+ stop = 0;
+ step = 0;
+}
+
+RangeIterator::RangeIterator(int stop) {
+ set_range(stop);
+}
+
+RangeIterator::RangeIterator(int start, int stop) {
+ set_range(start, stop);
+}
+
+RangeIterator::RangeIterator(int start, int stop, int step) {
+ set_range(start, stop, step);
+}
diff --git a/core/range_iterator.h b/core/range_iterator.h
new file mode 100644
index 0000000000..c3e38a9094
--- /dev/null
+++ b/core/range_iterator.h
@@ -0,0 +1,72 @@
+/*************************************************************************/
+/* range_iterator.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef RANGE_ITERATOR_H
+#define RANGE_ITERATOR_H
+
+#include "reference.h"
+#include "variant.h"
+#include "array.h"
+
+class RangeIterator : public Reference
+{
+protected:
+ OBJ_TYPE( RangeIterator, Reference );
+
+ static void _bind_methods();
+
+private:
+ int current;
+ int stop;
+ int step;
+
+ bool _iter_init(Variant arg);
+ bool _iter_next(Variant arg);
+ Variant _iter_get(Variant arg);
+
+public:
+
+ bool is_finished();
+
+ Array to_array();
+
+ void set_range(int stop);
+ void set_range(int start, int stop);
+ void set_range(int start, int stop, int step);
+
+ Ref<RangeIterator> _set_range(Variant arg1, Variant arg2 = Variant(), Variant arg3 = Variant());
+
+ void _init(Variant arg1, Variant arg2, Variant arg3);
+
+ RangeIterator();
+ RangeIterator(int stop);
+ RangeIterator(int start, int stop);
+ RangeIterator(int start, int stop, int step);
+};
+
+#endif // RANGE_ITERATOR_H
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index d977ea3e18..c516059cfb 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -51,6 +51,8 @@
#include "packed_data_container.h"
#include "func_ref.h"
#include "input_map.h"
+#include "undo_redo.h"
+#include "range_iterator.h"
#ifdef XML_ENABLED
static ResourceFormatSaverXML *resource_saver_xml=NULL;
@@ -128,6 +130,8 @@ void register_core_types() {
// ObjectTypeDB::register_type<OptimizedSaver>();
ObjectTypeDB::register_type<Translation>();
ObjectTypeDB::register_type<PHashTranslation>();
+ ObjectTypeDB::register_type<UndoRedo>();
+ ObjectTypeDB::register_type<RangeIterator>();
ObjectTypeDB::register_type<HTTPClient>();
diff --git a/core/typedefs.h b/core/typedefs.h
index 1ca7a4f66d..48acca326e 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -74,7 +74,7 @@
#endif
#ifndef DEFAULT_ALIGNMENT
-#define DEFAULT_ALIGNMENT 16
+#define DEFAULT_ALIGNMENT 1
#endif
@@ -154,6 +154,23 @@ inline void __swap_tmpl(T &x, T &y ) {
((m_hex>='A' && m_hex<='F')?(10+m_hex-'A'):\
((m_hex>='a' && m_hex<='f')?(10+m_hex-'a'):0)))
+// Macro to check whether we are compiled by clang
+// and we have a specific builtin
+#if defined(__llvm__) && defined(__has_builtin)
+ #define _llvm_has_builtin(x) __has_builtin(x)
+#else
+ #define _llvm_has_builtin(x) 0
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_mul_overflow)
+# define _mul_overflow __builtin_mul_overflow
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ >= 5)) || _llvm_has_builtin(__builtin_add_overflow)
+# define _add_overflow __builtin_add_overflow
+#endif
+
+
@@ -167,6 +184,19 @@ static _FORCE_INLINE_ unsigned int nearest_power_of_2(unsigned int x) {
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
+
+ return ++x;
+}
+
+template<class T>
+static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
+
+ --x;
+ // If the compiler is smart, it unrolls this loop
+ // If its dumb, this is a bit slow.
+ for (size_t i = 0; i < sizeof(T); i++)
+ x |= x >> (1 << i);
+
return ++x;
}
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ee750c39e5..1017fc0ca3 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -507,26 +507,35 @@ String String::capitalize() const {
return cap;
}
-String String::camelcase_to_underscore() const {
+String String::camelcase_to_underscore(bool lowercase) const {
const CharType * cstr = c_str();
- String newString;
+ String new_string;
const char A = 'A', Z = 'Z';
- int startIndex = 0;
+ const char a = 'a', z = 'z';
+ int start_index = 0;
- for ( int i = 1; i < this->size()-1; i++ ) {
- bool isCapital = cstr[i] >= A && cstr[i] <= Z;
+ for ( size_t i = 1; i < this->size(); i++ ) {
+ bool is_upper = cstr[i] >= A && cstr[i] <= Z;
+ bool are_next_2_lower = false;
+ bool was_precedent_upper = cstr[i-1] >= A && cstr[i-1] <= Z;
- if ( isCapital ) {
- newString += "_" + this->substr(startIndex, i-startIndex);
- startIndex = i;
+ if (i+2 < this->size()) {
+ are_next_2_lower = cstr[i+1] >= a && cstr[i+1] <= z && cstr[i+2] >= a && cstr[i+2] <= z;
}
- }
- newString += "_" + this->substr(startIndex, this->size()-startIndex);
+ bool should_split = ((is_upper && !was_precedent_upper) || (was_precedent_upper && is_upper && are_next_2_lower));
+ if (should_split) {
+ new_string += this->substr(start_index, i - start_index) + "_";
+ start_index = i;
+ }
+ }
- return newString;
+ new_string += this->substr(start_index, this->size() - start_index);
+ return lowercase ? new_string.to_lower() : new_string;
}
+
+
int String::get_slice_count(String p_splitter) const{
if (empty())
diff --git a/core/ustring.h b/core/ustring.h
index 9276afa0f7..e65103ff99 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -149,7 +149,7 @@ public:
static double to_double(const CharType* p_str, const CharType **r_end=NULL);
static int64_t to_int(const CharType* p_str,int p_len=-1);
String capitalize() const;
- String camelcase_to_underscore() const;
+ String camelcase_to_underscore(bool lowercase=true) const;
int get_slice_count(String p_splitter) const;
String get_slice(String p_splitter,int p_slice) const;
diff --git a/core/vector.h b/core/vector.h
index 641721f401..398d7f1bd5 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -68,11 +68,26 @@ class Vector {
return reinterpret_cast<T*>(_ptr);
}
-
- _FORCE_INLINE_ int _get_alloc_size(int p_elements) const {
-
- return nearest_power_of_2(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
- }
+
+ _FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
+ return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+ }
+
+ _FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
+#if defined(_add_overflow) && defined(_mul_overflow)
+ size_t o;
+ size_t p;
+ if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
+ if (_add_overflow(o, sizeof(SafeRefCount)+sizeof(int), &p)) return false;
+ *out = nearest_power_of_2_templated(p);
+ return true;
+#else
+ // Speed is more important than correctness here, do the operations unchecked
+ // and hope the best
+ *out = _get_alloc_size(p_elements);
+ return true;
+#endif
+ }
void _unref(void *p_data);
@@ -257,19 +272,21 @@ Error Vector<T>::resize(int p_size) {
// possibly changing size, copy on write
_copy_on_write();
+ size_t alloc_size;
+ ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
+
if (p_size>size()) {
if (size()==0) {
// alloc from scratch
- void* ptr=memalloc(_get_alloc_size(p_size));
+ void* ptr=memalloc(alloc_size);
ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount));
_get_refcount()->init(); // init refcount
*_get_size()=0; // init size (currently, none)
} else {
-
- void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size);
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
}
@@ -293,7 +310,7 @@ Error Vector<T>::resize(int p_size) {
t->~T();
}
- void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
+ void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount), alloc_size);
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
diff --git a/demos/2d/normalmaps/diffuse.jpg b/demos/2d/normalmaps/diffuse.jpg
index 87bc9cf158..b6f32fd825 100644
--- a/demos/2d/normalmaps/diffuse.jpg
+++ b/demos/2d/normalmaps/diffuse.jpg
Binary files differ
diff --git a/demos/2d/normalmaps/diffuse.png b/demos/2d/normalmaps/diffuse.png
deleted file mode 100644
index 634d955f8d..0000000000
--- a/demos/2d/normalmaps/diffuse.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/normalmaps/normal.jpg b/demos/2d/normalmaps/normal.jpg
new file mode 100644
index 0000000000..848ee9a9cd
--- /dev/null
+++ b/demos/2d/normalmaps/normal.jpg
Binary files differ
diff --git a/demos/2d/normalmaps/normal.png b/demos/2d/normalmaps/normal.png
deleted file mode 100644
index d5b3d53a24..0000000000
--- a/demos/2d/normalmaps/normal.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/normalmaps/normal_material.res b/demos/2d/normalmaps/normal_material.res
index 34129cccdc..27928519f8 100644
--- a/demos/2d/normalmaps/normal_material.res
+++ b/demos/2d/normalmaps/normal_material.res
Binary files differ
diff --git a/demos/2d/normalmaps/normalmap.scn b/demos/2d/normalmaps/normalmap.scn
index cf5fc05ce1..4501e7116a 100644
--- a/demos/2d/normalmaps/normalmap.scn
+++ b/demos/2d/normalmaps/normalmap.scn
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/burano.jpg b/demos/2d/screen_space_shaders/art/burano.jpg
index cdab993ec1..3017616384 100644
--- a/demos/2d/screen_space_shaders/art/burano.jpg
+++ b/demos/2d/screen_space_shaders/art/burano.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/burano.png b/demos/2d/screen_space_shaders/art/burano.png
deleted file mode 100644
index 6eec09d585..0000000000
--- a/demos/2d/screen_space_shaders/art/burano.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/forest.jpg b/demos/2d/screen_space_shaders/art/forest.jpg
new file mode 100644
index 0000000000..705acf8a5d
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/forest.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/forest.png b/demos/2d/screen_space_shaders/art/forest.png
deleted file mode 100644
index f5a2fb9bfb..0000000000
--- a/demos/2d/screen_space_shaders/art/forest.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/mountains.jpg b/demos/2d/screen_space_shaders/art/mountains.jpg
new file mode 100644
index 0000000000..d75baf530c
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/mountains.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/mountains.png b/demos/2d/screen_space_shaders/art/mountains.png
deleted file mode 100644
index b8435bb1a8..0000000000
--- a/demos/2d/screen_space_shaders/art/mountains.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/platformer.jpg b/demos/2d/screen_space_shaders/art/platformer.jpg
new file mode 100644
index 0000000000..e6197cd62b
--- /dev/null
+++ b/demos/2d/screen_space_shaders/art/platformer.jpg
Binary files differ
diff --git a/demos/2d/screen_space_shaders/art/platformer.png b/demos/2d/screen_space_shaders/art/platformer.png
deleted file mode 100644
index 21c1cb4c4b..0000000000
--- a/demos/2d/screen_space_shaders/art/platformer.png
+++ /dev/null
Binary files differ
diff --git a/demos/2d/screen_space_shaders/engine.cfg b/demos/2d/screen_space_shaders/engine.cfg
index 383ca7bf11..f7caa7abbc 100644
--- a/demos/2d/screen_space_shaders/engine.cfg
+++ b/demos/2d/screen_space_shaders/engine.cfg
@@ -6,7 +6,7 @@ icon="res://icon.png"
[display]
-width=780
+width=800
height=600
stretch_mode="2d"
stretch_aspect="keep"
diff --git a/demos/2d/screen_space_shaders/screen_shaders.scn b/demos/2d/screen_space_shaders/screen_shaders.scn
index be12cef02d..00c7fe8eba 100644
--- a/demos/2d/screen_space_shaders/screen_shaders.scn
+++ b/demos/2d/screen_space_shaders/screen_shaders.scn
Binary files differ
diff --git a/demos/3d/polygon_path_finder/engine.cfg b/demos/3d/polygon_path_finder/engine.cfg
deleted file mode 100644
index 47450408af..0000000000
--- a/demos/3d/polygon_path_finder/engine.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[application]
-
-name="Polygon Pathfinder"
-main_scene="res://poly_with_holes.scn"
-icon="res://icon.png"
diff --git a/demos/3d/polygon_path_finder/icon.png b/demos/3d/polygon_path_finder/icon.png
deleted file mode 100644
index 643f5595ee..0000000000
--- a/demos/3d/polygon_path_finder/icon.png
+++ /dev/null
Binary files differ
diff --git a/demos/3d/polygon_path_finder/poly_with_holes.scn b/demos/3d/polygon_path_finder/poly_with_holes.scn
deleted file mode 100644
index 6b340377b7..0000000000
--- a/demos/3d/polygon_path_finder/poly_with_holes.scn
+++ /dev/null
Binary files differ
diff --git a/demos/3d/polygon_path_finder/polygonpathfinder.gd b/demos/3d/polygon_path_finder/polygonpathfinder.gd
deleted file mode 100644
index 1e843043da..0000000000
--- a/demos/3d/polygon_path_finder/polygonpathfinder.gd
+++ /dev/null
@@ -1,77 +0,0 @@
-
-extends Spatial
-
-
-func _ready():
- var pf = PolygonPathFinder.new()
-
- var points = Vector2Array()
- var connections = IntArray()
-
- # Poly 1
- points.push_back(Vector2(0, 0)) # 0
- points.push_back(Vector2(10, 0)) # 1
- points.push_back(Vector2(10, 10)) # 2
- points.push_back(Vector2(0, 10)) # 3
-
- connections.push_back(0) # Connect vertex 0...
- connections.push_back(1) # ... to 1
- drawLine(points[0], points[1], get_node("/root/Spatial/Polys"))
- connections.push_back(1) # Connect vertex 1...
- connections.push_back(2) # ... to 2
- drawLine(points[1], points[2], get_node("/root/Spatial/Polys"))
- connections.push_back(2) # Etc.
- connections.push_back(3)
- drawLine(points[2], points[3], get_node("/root/Spatial/Polys"))
- connections.push_back(3) # Connect vertex 3...
- connections.push_back(0) # ... back to vertex 0, to close the polygon
- drawLine(points[3], points[0], get_node("/root/Spatial/Polys"))
-
- # Poly 2, as obstacle inside poly 1
- points.push_back(Vector2(2, 0.5)) # 4
- points.push_back(Vector2(4, 0.5)) # 5
- points.push_back(Vector2(4, 9.5)) # 6
- points.push_back(Vector2(2, 9.5)) # 7
-
- connections.push_back(4)
- connections.push_back(5)
- drawLine(points[4], points[5], get_node("/root/Spatial/Polys"))
- connections.push_back(5)
- connections.push_back(6)
- drawLine(points[5], points[6], get_node("/root/Spatial/Polys"))
- connections.push_back(6)
- connections.push_back(7)
- drawLine(points[6], points[7], get_node("/root/Spatial/Polys"))
- connections.push_back(7)
- connections.push_back(4)
- drawLine(points[7], points[4], get_node("/root/Spatial/Polys"))
-
- print("points: ", points)
- print("connections: ", connections)
-
- pf.setup(points, connections)
-
- var path = pf.find_path(Vector2(1, 5), Vector2(8, 5))
-
- var lastStep = null
- print("path: ", path)
- for step in path:
- print("step: ", step)
- if (lastStep != null):
- var currPathSegment = Vector2Array()
- drawLine(lastStep, step, get_node("/root/Spatial/Path"))
- lastStep = step
-
-
-func drawLine(pointA, pointB, immediateGeo):
- var drawPosY = 0.1
- var im = immediateGeo
-
- im.begin(Mesh.PRIMITIVE_POINTS, null)
- im.add_vertex(Vector3(pointA.x, drawPosY, pointA.y))
- im.add_vertex(Vector3(pointB.x, drawPosY, pointB.y))
- im.end()
- im.begin(Mesh.PRIMITIVE_LINE_STRIP, null)
- im.add_vertex(Vector3(pointA.x, drawPosY, pointA.y))
- im.add_vertex(Vector3(pointB.x, drawPosY, pointB.y))
- im.end()
diff --git a/demos/gui/translation/main.scn b/demos/gui/translation/main.scn
index 8fc0b4ffb2..be833fcdb8 100644
--- a/demos/gui/translation/main.scn
+++ b/demos/gui/translation/main.scn
Binary files differ
diff --git a/demos/gui/translation/notosans.otf b/demos/gui/translation/notosans.otf
deleted file mode 100644
index 6443f9023e..0000000000
--- a/demos/gui/translation/notosans.otf
+++ /dev/null
Binary files differ
diff --git a/demos/plugins/custom_dock/custom_dock.scn b/demos/plugins/custom_dock/custom_dock.scn
new file mode 100644
index 0000000000..0e32ece264
--- /dev/null
+++ b/demos/plugins/custom_dock/custom_dock.scn
Binary files differ
diff --git a/demos/plugins/custom_dock/dock_plugin.gd b/demos/plugins/custom_dock/dock_plugin.gd
new file mode 100644
index 0000000000..ce8a3bcd09
--- /dev/null
+++ b/demos/plugins/custom_dock/dock_plugin.gd
@@ -0,0 +1,23 @@
+tool
+extends EditorPlugin
+
+var dock = null
+
+func _enter_tree():
+ # When this plugin node enters tree, add the custom type
+
+ dock = preload("res://addons/custom_dock/custom_dock.scn").instance()
+
+ add_control_to_dock( DOCK_SLOT_LEFT_UL, dock )
+
+func _exit_tree():
+
+ # Remove from docks (must be called so layout is updated and saved)
+ remove_control_from_docks(dock)
+ # Remove the node
+ dock.free()
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_dock/plugin.cfg b/demos/plugins/custom_dock/plugin.cfg
new file mode 100644
index 0000000000..e295384c25
--- /dev/null
+++ b/demos/plugins/custom_dock/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Custom Dock"
+description="Adds a new Customizable Dock"
+author="Juan Linietsky"
+version="1.0"
+script="dock_plugin.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/custom_import_plugin/import_plugin.gd b/demos/plugins/custom_import_plugin/import_plugin.gd
new file mode 100644
index 0000000000..2cf8a0302f
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/import_plugin.gd
@@ -0,0 +1,81 @@
+tool
+
+extends EditorImportPlugin
+
+
+# Simple plugin that imports a text file with extension .mtxt
+# which contains 3 integers in format R,G,B (0-255)
+# (see example .mtxt in this folder)
+# Imported file is converted to a material
+
+var dialog = null
+
+func get_name():
+ return "silly_material"
+
+func get_visible_name():
+ return "Silly Material"
+
+func import_dialog(path):
+ var md = null
+ if (path!=""):
+ md = ResourceLoader.load_import_metadata(path)
+ dialog.configure(self,path,md)
+ dialog.popup_centered()
+
+func import(path,metadata):
+
+ assert(metadata.get_source_count() == 1)
+
+ var source = metadata.get_source_path(0)
+ var use_red_anyway = metadata.get_option("use_red_anyway")
+
+ var f = File.new()
+ var err = f.open(source,File.READ)
+ if (err!=OK):
+ return ERR_CANT_OPEN
+
+ var l = f.get_line()
+
+ f.close()
+
+ var channels = l.split(",")
+ if (channels.size()!=3):
+ return ERR_PARSE_ERROR
+
+ var color = Color8(int(channels[0]),int(channels[1]),int(channels[2]))
+
+ var material
+
+ if (ResourceLoader.has(path)):
+ # Material is in use, update it
+ material = ResourceLoader.load(path)
+ else:
+ # Material not in use, create
+ material = FixedMaterial.new()
+
+ if (use_red_anyway):
+ color=Color8(255,0,0)
+
+ material.set_parameter(FixedMaterial.PARAM_DIFFUSE,color)
+
+ # Make sure import metadata links to this plugin
+
+ metadata.set_editor("silly_material")
+
+ # Update the import metadata
+
+ material.set_import_metadata(metadata)
+
+
+ # Save
+ err = ResourceSaver.save(path,material)
+
+ return err
+
+
+func config(base_control):
+
+ dialog = preload("res://addons/custom_import_plugin/material_dialog.tscn").instance()
+ base_control.add_child(dialog)
+
diff --git a/demos/plugins/custom_import_plugin/material_dialog.gd b/demos/plugins/custom_import_plugin/material_dialog.gd
new file mode 100644
index 0000000000..1022743254
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_dialog.gd
@@ -0,0 +1,67 @@
+tool
+extends ConfirmationDialog
+
+var src_fs
+var dst_fs
+var import_plugin
+
+func configure(p_import_plugin,path,metadata):
+ import_plugin=p_import_plugin
+ if (metadata):
+ # metadata from previous import exists, fill in fields
+ assert( metadata.get_source_count() > 0 )
+ # Always expand the source paths
+ var src_path = import_plugin.expand_source_path( metadata.get_source_path(0) )
+ get_node("src_file").set_text(src_path)
+ get_node("dst_file").set_text(path)
+ # Fill in from metadata options
+ get_node("use_red_anyway").set_pressed( metadata.get_option("use_red_anyway") )
+
+
+func _ready():
+
+ src_fs = FileDialog.new()
+ src_fs.set_mode(FileDialog.MODE_OPEN_FILE)
+ src_fs.set_access(FileDialog.ACCESS_FILESYSTEM) #access all filesystem, not only res://
+ src_fs.add_filter("*.mtxt")
+ src_fs.connect("file_selected",self,"_on_src_selected")
+
+ add_child(src_fs)
+
+ dst_fs = EditorFileDialog.new()
+ dst_fs.set_mode(EditorFileDialog.MODE_SAVE_FILE)
+ dst_fs.add_filter("*.mtl") # Use binary extension always, text can't save metadata
+ dst_fs.connect("file_selected",self,"_on_dst_selected")
+
+ add_child(dst_fs)
+
+ set_hide_on_ok(true)
+ get_ok().set_text("Import!")
+
+
+func _on_src_browse_pressed():
+ src_fs.popup_centered_ratio()
+
+func _on_dst_browse_pressed():
+ dst_fs.popup_centered_ratio()
+
+func _on_src_selected(path):
+ get_node("src_file").set_text(path)
+
+func _on_dst_selected(path):
+ get_node("dst_file").set_text(path)
+
+func _on_MaterialImport_confirmed():
+ # Create an import metadata
+ var imd = ResourceImportMetadata.new()
+ # Add the source files, always validate the source path
+ imd.add_source( import_plugin.validate_source_path( get_node("src_file").get_text() ))
+ # Add the options
+ imd.set_option( "use_red_anyway", get_node("use_red_anyway").is_pressed() )
+ # Perform regular import
+ var err = import_plugin.import( get_node("dst_file").get_text(), imd )
+ # Warn if error
+ if (err!=OK):
+ get_node("error").set_text("Error Importing!")
+ get_node("error").popup_centered_minsize()
+
diff --git a/demos/plugins/custom_import_plugin/material_dialog.tscn b/demos/plugins/custom_import_plugin/material_dialog.tscn
new file mode 100644
index 0000000000..9ad6f492fd
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_dialog.tscn
@@ -0,0 +1,111 @@
+[gd_scene load_steps=2 format=1]
+
+[ext_resource path="res://addons/custom_import_plugin/material_dialog.gd" type="Script" id=1]
+
+[node name="MaterialImport" type="ConfirmationDialog"]
+
+margin/right = 276.0
+margin/bottom = 154.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+popup/exclusive = false
+window/title = "Silly Material Import"
+dialog/hide_on_ok = true
+script/script = ExtResource( 1 )
+__meta__ = { "__editor_plugin_screen__":"Script" }
+
+[node name="src_file" type="LineEdit" parent="."]
+
+margin/left = 19.0
+margin/top = 6.0
+margin/right = 190.0
+margin/bottom = 29.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+text = ""
+max_length = 0
+editable = true
+secret = false
+
+[node name="src_browse" type="Button" parent="."]
+
+margin/left = 195.0
+margin/top = 7.0
+margin/right = 249.0
+margin/bottom = 29.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = false
+text = "browse"
+flat = false
+
+[node name="dst_browse" type="Button" parent="."]
+
+margin/left = 195.0
+margin/top = 47.0
+margin/right = 249.0
+margin/bottom = 69.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = false
+text = "browse"
+flat = false
+
+[node name="dst_file" type="LineEdit" parent="."]
+
+margin/left = 19.0
+margin/top = 46.0
+margin/right = 190.0
+margin/bottom = 69.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+text = ""
+max_length = 0
+editable = true
+secret = false
+
+[node name="use_red_anyway" type="CheckBox" parent="."]
+
+margin/left = 20.0
+margin/top = 84.0
+margin/right = 144.0
+margin/bottom = 106.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+toggle_mode = true
+text = "Use Red Anyway"
+flat = false
+align = 0
+
+[node name="error" type="AcceptDialog" parent="."]
+
+visibility/visible = false
+margin/right = 40.0
+margin/bottom = 40.0
+focus/ignore_mouse = false
+focus/stop_mouse = true
+size_flags/horizontal = 2
+size_flags/vertical = 2
+popup/exclusive = false
+window/title = "Alert!"
+dialog/hide_on_ok = true
+
+[connection signal="confirmed" from="." to="." method="_on_MaterialImport_confirmed"]
+
+[connection signal="pressed" from="src_browse" to="." method="_on_src_browse_pressed"]
+
+[connection signal="pressed" from="dst_browse" to="." method="_on_dst_browse_pressed"]
+
+
diff --git a/demos/plugins/custom_import_plugin/material_import.gd b/demos/plugins/custom_import_plugin/material_import.gd
new file mode 100644
index 0000000000..f9859251af
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/material_import.gd
@@ -0,0 +1,22 @@
+tool
+extends EditorPlugin
+
+var import_plugin
+
+func _enter_tree():
+
+ import_plugin = preload("res://addons/custom_import_plugin/import_plugin.gd").new()
+
+ # pass the GUI base control, so the dialog has a parent node
+ import_plugin.config( get_base_control() )
+
+ add_import_plugin( import_plugin)
+
+func _exit_tree():
+
+ remove_import_plugin( import_plugin )
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_import_plugin/plugin.cfg b/demos/plugins/custom_import_plugin/plugin.cfg
new file mode 100644
index 0000000000..a002ad680d
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Silly Material Importer"
+description="Imports a 3D Material from an external text file"
+author="Juan Linietsky"
+version="1.0"
+script="material_import.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/custom_import_plugin/test.mtxt b/demos/plugins/custom_import_plugin/test.mtxt
new file mode 100644
index 0000000000..546ea2af20
--- /dev/null
+++ b/demos/plugins/custom_import_plugin/test.mtxt
@@ -0,0 +1 @@
+0,0,255
diff --git a/demos/plugins/custom_node/heart.gd b/demos/plugins/custom_node/heart.gd
new file mode 100644
index 0000000000..d53c92d800
--- /dev/null
+++ b/demos/plugins/custom_node/heart.gd
@@ -0,0 +1,12 @@
+tool
+extends Node2D
+
+
+var heart = preload("res://addons/custom_node/heart.png")
+
+func _draw():
+ draw_texture(heart,-heart.get_size()/2)
+
+func _get_item_rect():
+ #override
+ return Rect2(-heart.get_size()/2,heart.get_size())
diff --git a/demos/plugins/custom_node/heart.png b/demos/plugins/custom_node/heart.png
new file mode 100644
index 0000000000..1dfd14a456
--- /dev/null
+++ b/demos/plugins/custom_node/heart.png
Binary files differ
diff --git a/demos/plugins/custom_node/heart_icon.png b/demos/plugins/custom_node/heart_icon.png
new file mode 100644
index 0000000000..2eb819aa24
--- /dev/null
+++ b/demos/plugins/custom_node/heart_icon.png
Binary files differ
diff --git a/demos/plugins/custom_node/heart_plugin.gd b/demos/plugins/custom_node/heart_plugin.gd
new file mode 100644
index 0000000000..01a6177c9b
--- /dev/null
+++ b/demos/plugins/custom_node/heart_plugin.gd
@@ -0,0 +1,18 @@
+tool
+extends EditorPlugin
+
+
+func _enter_tree():
+ # When this plugin node enters tree, add the custom type
+
+ add_custom_type("Heart","Node2D",preload("res://addons/custom_node/heart.gd"),preload("res://addons/custom_node/heart_icon.png"))
+
+func _exit_tree():
+ # When the plugin node exits the tree, remove the custom type
+
+ remove_custom_type("Heart")
+
+
+
+
+ \ No newline at end of file
diff --git a/demos/plugins/custom_node/plugin.cfg b/demos/plugins/custom_node/plugin.cfg
new file mode 100644
index 0000000000..ebb4b56499
--- /dev/null
+++ b/demos/plugins/custom_node/plugin.cfg
@@ -0,0 +1,14 @@
+[plugin]
+
+name="Heart"
+description="Adds a new Heart node in 2D"
+author="Juan Linietsky"
+version="1.0"
+script="heart_plugin.gd"
+
+
+
+
+
+
+
diff --git a/demos/plugins/readme.txt b/demos/plugins/readme.txt
new file mode 100644
index 0000000000..963850dcbb
--- /dev/null
+++ b/demos/plugins/readme.txt
@@ -0,0 +1,13 @@
+
+To install these, copy each of these folders to a folder:
+
+addons/
+
+inside your projects, example:
+
+addons/custom_node
+
+To distribute and install from UI, make a zip that contains the folder,
+example:
+
+zip -r custom_node.zip custom_node/* \ No newline at end of file
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index b1871632d0..12948d4489 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<doc version="2.0.beta.custom_build" name="Engine Types">
+<doc version="2.0.stable.custom_build" name="Engine Types">
<class name="@GDScript" category="Core">
<brief_description>
Built-in GDScript functions.
@@ -556,6 +556,15 @@
Return an array with the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial,final-1,increment).
</description>
</method>
+ <method name="xrange">
+ <return type="Object">
+ </return>
+ <argument index="0" name="..." type="Variant">
+ </argument>
+ <description>
+ Return an iterator over the given range. Range can be 1 argument N (0 to N-1), two arguments (initial, final-1) or three arguments (initial,final-1,increment).
+ </description>
+ </method>
<method name="load">
<return type="Resource">
</return>
@@ -621,6 +630,32 @@
<description>
</description>
</method>
+ <method name="preload">
+ <return type="Resource">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="yield">
+ <return type="Nil">
+ </return>
+ <argument index="0" name="object" type="Object">
+ </argument>
+ <argument index="1" name="signal" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="assert">
+ <return type="Nil">
+ </return>
+ <argument index="0" name="condition" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
<constant name="PI" value="3.141593">
@@ -825,7 +860,7 @@
</constant>
<constant name="KEY_KP_DIVIDE" value="16777346">
</constant>
- <constant name="KEY_KP_SUBSTRACT" value="16777347">
+ <constant name="KEY_KP_SUBTRACT" value="16777347">
</constant>
<constant name="KEY_KP_PERIOD" value="16777348">
</constant>
@@ -1450,6 +1485,8 @@
</constant>
<constant name="ERR_CANT_CREATE" value="20">
</constant>
+ <constant name="ERR_PARSE_ERROR" value="43">
+ </constant>
<constant name="ERROR_QUERY_FAILED" value="21">
</constant>
<constant name="ERR_ALREADY_IN_USE" value="22">
@@ -2201,7 +2238,7 @@
</argument>
<argument index="1" name="time" type="float">
</argument>
- <argument index="2" name="key" type="var">
+ <argument index="2" name="key" type="Variant">
</argument>
<argument index="3" name="transition" type="float" default="1">
</argument>
@@ -2232,7 +2269,7 @@
</argument>
<argument index="1" name="key" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
Set the value of an existing key.
@@ -4206,7 +4243,7 @@
</argument>
<description>
Set the sample data for a given sample as an array of bytes. The length must be equal to the sample length expected in bytes or an error will be produced. The byte length can be calculated as follows:
- Get the sample length ([method get_sample_length]).
+ Get the sample length ([method sample_get_length]).
If the sample format is SAMPLE_FORMAT_PCM16, multiply it by 2.
If the sample format is SAMPLE_FORMAT_IMA_ADPCM, divide it by 2 (rounding any fraction up), then add 4.
If the sample is stereo ([method sample_is_stereo]), multiply it by 2.
@@ -5407,7 +5444,7 @@
Standard themed Button.
</brief_description>
<description>
- Button is just the standard themed button: [image src="images/button_example.png"/] It can contain text and an icon, and will display them according to the current [Theme].
+ Button is the standard themed button. It can contain text and an icon, and will display them according to the current [Theme].
</description>
<methods>
<method name="set_text">
@@ -5686,7 +5723,7 @@
Camera node, displays from a point of view.
</brief_description>
<description>
- Camera is a special node that displays what is visible from its current location. Cameras register themselves in the nearest [Viewport] node (when ascending the tree). Only one camera can be active per viewport. If no viewport is available ascending the tree, the Camera will register in the global viewport. In other words, a Camera just provides [i]3D[/i] display capabilities to a [Viewport], and, without one, a [Scene] registered in that [Viewport] (or higher viewports) can't be displayed.
+ Camera is a special node that displays what is visible from its current location. Cameras register themselves in the nearest [Viewport] node (when ascending the tree). Only one camera can be active per viewport. If no viewport is available ascending the tree, the Camera will register in the global viewport. In other words, a Camera just provides [i]3D[/i] display capabilities to a [Viewport], and, without one, a scene registered in that [Viewport] (or higher viewports) can't be displayed.
</description>
<methods>
<method name="project_ray_normal" qualifiers="const">
@@ -6080,7 +6117,7 @@
</brief_description>
<description>
Base class of anything 2D. Canvas items are laid out in a tree and children inherit and extend the transform of their parent. CanvasItem is extended by [Control], for anything GUI related, and by [Node2D] for anything 2D engine related.
- Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significan'tly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrides function, though.
+ Any CanvasItem can draw. For this, the "update" function must be called, then NOTIFICATION_DRAW will be received on idle time to request redraw. Because of this, canvas items don't need to be redraw on every frame, improving the performance significantly. Several functions for drawing on the CanvasItem are provided (see draw_* functions). They can only be used inside the notification, signal or _draw() overrides function, though.
Canvas items are draw in tree order. By default, children are on top of their parents so a root CanvasItem will be drawn behind everything (this can be changed per item though).
Canvas items can also be hidden (hiding also their subtree). They provide many means for changing standard parameters such as opacity (for it and the subtree) and self opacity, blend mode.
Ultimately, a transform notification can be requested, which will notify the node that its global position changed in case the parent tree changed.
@@ -6092,7 +6129,7 @@
</description>
</method>
<method name="edit_set_state">
- <argument index="0" name="state" type="var">
+ <argument index="0" name="state" type="Variant">
</argument>
<description>
Used for editing, returns an opaque value representing the transform state.
@@ -6536,7 +6573,7 @@
Additive blending mode.
</constant>
<constant name="BLEND_MODE_SUB" value="2">
- Substractive blending mode.
+ Subtractive blending mode.
</constant>
<constant name="BLEND_MODE_MUL" value="3">
Multiplicative blending mode.
@@ -6582,7 +6619,7 @@
<method name="set_shader_param">
<argument index="0" name="param" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -7353,14 +7390,14 @@
<argument index="0" name="build_mode" type="int">
</argument>
<description>
- Set whether the polygon is to be a [ConvexPolygon2D] ([code]build_mode==0[/code]), or a [ConcavePolygon2D] ([code]build_mode==1[/code]).
+ Set whether the polygon is to be a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
<method name="get_build_mode" qualifiers="const">
<return type="int">
</return>
<description>
- Return whether the polygon is a [ConvexPolygon2D] ([code]build_mode==0[/code]), or a [ConcavePolygon2D] ([code]build_mode==1[/code]).
+ Return whether the polygon is a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
<method name="set_trigger">
@@ -8033,7 +8070,7 @@
</argument>
<argument index="1" name="key" type="String">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -8043,7 +8080,7 @@
</argument>
<argument index="1" name="key" type="String">
</argument>
- <argument index="2" name="default" type="var" default="NULL">
+ <argument index="2" name="default" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -8164,10 +8201,10 @@
Control is the base class Node for all the GUI components. Every GUI component inherits from it, directly or indirectly. In this way, sections of the scene tree made of contiguous control nodes, become user interfaces.
Controls are relative to the parent position and size by using anchors and margins. This ensures that they can adapt easily in most situation to changing dialog and screen sizes. When more flexibility is desired, [Container] derived nodes can be used.
Anchors work by defining which margin do they follow, and a value relative to it. Allowed anchoring modes are ANCHOR_BEGIN, where the margin is relative to the top or left margins of the parent (in pixels), ANCHOR_END for the right and bottom margins of the parent and ANCHOR_RATIO, which is a ratio from 0 to 1 in the parent range.
- Input device events ([InputEvent]) are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method Node._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
+ Input device events ([InputEvent]) are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method MainLoop._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
Only one control can hold the keyboard focus (receiving keyboard events), for that the control must define the focus mode with [method set_focus_mode]. Focus is lost when another control gains it, or the current focus owner is hidden.
It is sometimes desired for a control to ignore mouse/pointer events. This is often the case when placing other controls on top of a button, in such cases. Calling [method set_ignore_mouse] enables this function.
- Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overrided per each control by calling the add_*_override functions, or from the editor.
+ Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overridden per each control by calling the add_*_override functions, or from the editor.
</description>
<methods>
<method name="_input_event" qualifiers="virtual">
@@ -8182,7 +8219,7 @@
</return>
<argument index="0" name="pos" type="Vector2">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -8190,7 +8227,7 @@
<method name="drop_data" qualifiers="virtual">
<argument index="0" name="pos" type="Vector2">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -8411,7 +8448,7 @@
<argument index="0" name="exclusive" type="bool" default="false">
</argument>
<description>
- Display a Control as modal. Control must be a subwindow (see [method set_as_subwindow]). Modal controls capture the input signals until closed or the area outside them is accessed. When a modal control loses focus, or the ESC key is pressed, they automatically hide. Modal controls are used extensively for popup dialogs and menus.
+ Display a Control as modal. Control must be a subwindow. Modal controls capture the input signals until closed or the area outside them is accessed. When a modal control loses focus, or the ESC key is pressed, they automatically hide. Modal controls are used extensively for popup dialogs and menus.
</description>
</method>
<method name="set_focus_mode">
@@ -8681,7 +8718,7 @@
</description>
</method>
<method name="force_drag">
- <argument index="0" name="data" type="var">
+ <argument index="0" name="data" type="Variant">
</argument>
<argument index="1" name="preview" type="Object">
</argument>
@@ -9386,7 +9423,7 @@ This approximation makes straight segments between each point, then subdivides t
Damped spring constraint for 2D physics.
</brief_description>
<description>
- Damped spring constraint for 2D physics. This resembles a spring joint that always want to go back to a given length.
+ Damped spring constraint for 2D physics. This resembles a spring joint that always wants to go back to a given length.
</description>
<methods>
<method name="set_length">
@@ -9421,28 +9458,28 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="stiffness" type="float">
</argument>
<description>
- Set the stiffness of the spring joint.
+ Set the stiffness of the spring joint. The joint applies a force equal to the stiffness times the distance from its resting length.
</description>
</method>
<method name="get_stiffness" qualifiers="const">
<return type="float">
</return>
<description>
- Return the stiffness of the spring joint.
+ Return the stiffness of the spring joint. The joint applies a force equal to the stiffness times the distance from its resting length.
</description>
</method>
<method name="set_damping">
<argument index="0" name="damping" type="float">
</argument>
<description>
- Set the damping of the spring joint.
+ Set the damping ratio of the spring joint. A value of 0 indicates an undamped spring, while 1 causes the system to reach equilibrium as fast as possible (critical damping).
</description>
</method>
<method name="get_damping" qualifiers="const">
<return type="float">
</return>
<description>
- Return the damping of the spring joint.
+ Return the damping ratio of the spring joint. A value of 0 indicates an undamped spring, while 1 causes the system to reach equilibrium as fast as possible (critical damping).
</description>
</method>
</methods>
@@ -9529,7 +9566,7 @@ This approximation makes straight segments between each point, then subdivides t
Directional Light, such as the Sun or the Moon.
</brief_description>
<description>
- A DirectionalLight is a type of [Light] node that emits light constantly in one direction (the negative z axis of the node). It is used lights with strong intensity that are located far away from the scene to model sunlight or moonlight. The worldpace location of the DirectionalLight transform (origin) is ignored, only the basis is used do determine light direction.
+ A DirectionalLight is a type of [Light] node that emits light constantly in one direction (the negative z axis of the node). It is used lights with strong intensity that are located far away from the scene to model sunlight or moonlight. The worldspace location of the DirectionalLight transform (origin) is ignored, only the basis is used do determine light direction.
</description>
<methods>
<method name="set_shadow_mode">
@@ -9580,8 +9617,26 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="Directory" inherits="Reference" category="Core">
<brief_description>
+ Type used to handle the filesystem.
</brief_description>
<description>
+ Directory type. Is used to manage directories and their content (not restricted to the project folder).
+ Example for how to iterate through the files of a directory:
+ [codeblock]
+ func dir(path):
+ var d = Directory.new()
+ if d.open( path )==0:
+ d.list_dir_begin()
+ var file_name = d.get_next()
+ while(file_name!=""):
+ if d.current_is_dir():
+ print("Found directory: " + file_name)
+ else:
+ print("Found file:" + file_name)
+ file_name = d.get_next()
+ else:
+ print("Some open Error, maybe directory not found?")
+ [/codeblock]
</description>
<methods>
<method name="open">
@@ -9590,28 +9645,34 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="path" type="String">
</argument>
<description>
+ Opens a directory to work with. Needs a path, example "res://folder"
</description>
</method>
<method name="list_dir_begin">
<return type="bool">
</return>
<description>
+ Loads all file names of the current directory (prepares the get_next() function).
</description>
</method>
<method name="get_next">
<return type="String">
</return>
<description>
+ Is used to iterate through the files of the current directory. Returns the name(no path) of the current file/directory, it also contains "." and ".." .
+Returns an empty String "" at the end of the list.
</description>
</method>
<method name="current_is_dir" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if the current file you are looking at with get_next() is a directory or "." or ".." otherwise false.
</description>
</method>
<method name="list_dir_end">
<description>
+ Run this to empty the list of remaining files in get_next(). You can use it to end the iteration, as soon as your goal is reached.
</description>
</method>
<method name="get_drive_count">
@@ -9634,12 +9695,14 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="todir" type="String">
</argument>
<description>
+ Needs a path or name to the next directory. When the target directory is in the current directory you can use "newfolder" otherwise you need the full path "res://currentfolder/newfolder"
</description>
</method>
<method name="get_current_dir">
<return type="String">
</return>
<description>
+ Returns a path to the current directory, example: "res://folder"
</description>
</method>
<method name="make_dir">
@@ -9672,6 +9735,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="name" type="String">
</argument>
<description>
+ Returns true if directory exists otherwise false. Needs a path, example: "res://folder"
</description>
</method>
<method name="get_space_left">
@@ -9712,6 +9776,47 @@ This approximation makes straight segments between each point, then subdivides t
<constants>
</constants>
</class>
+<class name="EditorExportPlugin" inherits="Reference" category="Core">
+ <brief_description>
+ Editor plugin to control the export process.
+ </brief_description>
+ <description>
+ This plugin is added into EditorImportExport and allows to modify
+ the behavior of the export process for individual files.
+ </description>
+ <methods>
+ <method name="custom_export" qualifiers="virtual">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="platform" type="EditorExportPlatform">
+ </argument>
+ <description>
+ This function is called for each file exported and
+ depending from the return value one of many things
+ might happen.
+
+ 1) If returned value is null, the file is exported
+ as is.
+
+ 2) If the returned value is a RawAray (array of
+ bytes), the content of that array becomes the new
+ file being exported.
+
+ 3) If the file must also change it's name when
+ exported, then a [Dictionary] must be returned with
+ two fields: 'name' with the new filename and 'data'
+ with a [RawArray] containing the raw contents of the
+ file. Even if the name is changed, the run-time will
+ redirect the old file to the new file automatically
+ when accessed.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="EditorFileDialog" inherits="ConfirmationDialog" category="Core">
<brief_description>
</brief_description>
@@ -9862,8 +9967,14 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorImportPlugin" inherits="Reference" category="Core">
<brief_description>
+ Import plugin for editor
</brief_description>
<description>
+ Import plugins make it easy to handle importing of external assets
+ into a project.
+
+ They way they work is not that obvious though, so please make sure
+ to read the documentation, tutorials and examples.
</description>
<methods>
<method name="custom_export" qualifiers="virtual">
@@ -9871,19 +9982,35 @@ This approximation makes straight segments between each point, then subdivides t
</return>
<argument index="0" name="path" type="String">
</argument>
+ <argument index="1" name="platform" type="EditorExportPlatform">
+ </argument>
<description>
+ Generally, files that are imported stay the same
+ when exported. The only exception is in some cases
+ when the file must be re-imported for different
+ platforms (ie. texture compression).
+
+ If you want to customize the export process, it's
+ recommended to use [EditorExportPlugin.custom_export]
+ instead.
</description>
</method>
<method name="get_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Get the name of the import plugin, which will be
+ used to identify content imported by this plugin.
+
+ Try to use lowecase and underscores if possible.
</description>
</method>
<method name="get_visible_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Visible name for this plugin, which will be shown on
+ the import menu.
</description>
</method>
<method name="import" qualifiers="virtual">
@@ -9891,15 +10018,70 @@ This approximation makes straight segments between each point, then subdivides t
</return>
<argument index="0" name="path" type="String">
</argument>
- <argument index="1" name="from" type="ResourceImportMetaData">
- </argument>
- <description>
+ <argument index="1" name="from" type="ResourceImportMetadata">
+ </argument>
+ <description>
+ Perform an import of an external resources into the
+ project. This function is both called on import
+ (from the dialog) or re-import
+ (manual or automatic when external source files
+ changed).
+
+ An import process generally works like this:
+
+ 1) Check the metadata for source files and options.
+ Metadata is either generated in the import dialog or
+ taken from an existing resource upon reimport.
+
+ 2) Perform the import process into a new resource.
+ Some times the resource being re-imported may be already loaded
+ and in use, so checking for this by using
+ [ResourceLoader.has] is recommended. Otherwise
+ create a new resource.
+
+ 3) Set the metadata from the argument into the existing or new
+ resource being created using
+ [Resource.set_import_metadata].
+
+ 4) Save the resource into 'path' (function argument)
</description>
</method>
<method name="import_dialog" qualifiers="virtual">
<argument index="0" name="from" type="String">
</argument>
<description>
+ This function is called when either the user chooses
+ to import a resource of this type (Import menu), or
+ when the user chooses to re-import the resource
+ (from filesystem). In the later case, the path for
+ the existing file is supplied in the argument.
+
+ If the path is supplied, it is recommended to read
+ the import metadata with
+ [ResourceLoader.load_import_metadata] and fill in
+ the fields with the values contained there.
+
+ The dialog can be shown in any way (just use a
+ ConfirmationDialog and pop it up). Upon
+ confirmation, fill up a ResourceImportMetadata and
+ call the [EditorImportPlugin.import] function with
+ this information.
+ </description>
+ </method>
+ <method name="validate_source_path">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="expand_source_path">
+ <return type="String">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
</description>
</method>
</methods>
@@ -9908,22 +10090,52 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorPlugin" inherits="Node" category="Core">
<brief_description>
+ Used by the editor to extend it's functionality.
</brief_description>
<description>
+ Plugins are used by the editor to extend functionality. The most
+ common types of plugins are those which edit a given node or
+ resource type, import plugins and export plugins.
</description>
<methods>
<method name="apply_changes" qualifiers="virtual">
<description>
+ This method is called when the editor is about to
+ save the project, switch to another tab, etc. It
+ asks the plugin to apply any pending state changes
+ to ensure consistency.
+
+ This is used, for example, in shader editors to let
+ the plugin know that it must apply the shader code
+ being written by the user to the object.
</description>
</method>
<method name="clear" qualifiers="virtual">
<description>
+ Clear all the state and reset the object being
+ edited to zero. This ensures your plugin does not
+ keep editing a currently existing node, or a node
+ fromt the wrong scene.
+ </description>
+ </method>
+ <method name="create_spatial_gizmo" qualifiers="virtual">
+ <return type="EditorSpatialGizmo">
+ </return>
+ <argument index="0" name="for_spatial" type="Spatial">
+ </argument>
+ <description>
+ This is used for plugins that create gizmos used by
+ the spatial editor. Just check that the node passed
+ in the "for_spatial" argument matches your plugin.
</description>
</method>
<method name="edit" qualifiers="virtual">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ This function is used for plugins that edit specific
+ object types (nodes or resources). It requests the
+ editor to edit the given object.
</description>
</method>
<method name="forward_input_event" qualifiers="virtual">
@@ -9932,6 +10144,13 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
+ This is a low level function for plugins that edit a given
+ object type derived from CanvasItem to capture the input in the 2D editor
+ viewport. The function is only being called if your
+ object is being edited.
+
+ Return true if you want to capture the input,
+ otherwise false.
</description>
</method>
<method name="forward_spatial_input_event" qualifiers="virtual">
@@ -9942,24 +10161,45 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="1" name="event" type="InputEvent">
</argument>
<description>
+ This is a low level function for plugins that edit a
+ given objet type derived from Spatial to capture the
+ input of the viewport. The function is only being
+ called if your object is being edited.
+
+ By using the [InputEvent] and the [Camera] arguments
+ it's pretty easy to do raycasts into space using
+ Camera functions.
+
+ Return true if you want to capture the input,
+ otherwise false.
</description>
</method>
<method name="get_breakpoints" qualifiers="virtual">
<return type="StringArray">
</return>
<description>
+ This is for editors that edit script based objects.
+ You can return a list of breakpoints in the format
+ (script:line), for example: res://path_to_script.gd:25
</description>
</method>
<method name="get_name" qualifiers="virtual">
<return type="String">
</return>
<description>
+ Get the name of the editor plugin. For main scren
+ plugins this is what will appear in the selector
+ (which by default is 2D, 3D, Script).
</description>
</method>
<method name="get_state" qualifiers="virtual">
<return type="Dictionary">
</return>
<description>
+ Get the state of your plugin editor. This is used
+ when saving the scene (so state is kept when opening
+ it again) and for switching tabs (so state can be
+ restored when the tab returns).
</description>
</method>
<method name="handles" qualifiers="virtual">
@@ -9968,38 +10208,101 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Implement this function if your plugin edits a
+ specific type of object (Resource or Node). If you
+ return true, then you will get the functions
+ [EditorPlugin.edit] and [EditorPlugin.make_visible]
+ called when the editor requests them.
</description>
</method>
<method name="has_main_screen" qualifiers="virtual">
<return type="bool">
</return>
<description>
+ Return true if this is a main screen editor plugin
+ (it goes in the main screen selector together with
+ 2D, 3D, Script).
</description>
</method>
<method name="make_visible" qualifiers="virtual">
<argument index="0" name="visible" type="bool">
</argument>
<description>
+ This function will be called when the editor is
+ requested to become visible. It is used for plugins
+ that edit a specific object type.
+
+ Remember that you have to manage the visibility of
+ all your editor controls manually.
</description>
</method>
<method name="set_state" qualifiers="virtual">
<argument index="0" name="state" type="Dictionary">
</argument>
<description>
+ Restore the state saved by [EditorPlugin.get_state].
</description>
</method>
- <method name="get_undo_redo">
- <return type="Object">
- </return>
+ <method name="add_control_to_container">
+ <argument index="0" name="container" type="int">
+ </argument>
+ <argument index="1" name="control" type="Control">
+ </argument>
<description>
+ Add a custom control to a container (see
+ CONTAINER_* enum). There are many locations where
+ custom controls can be added in the editor UI.
+
+ Please remember that you have to manage the
+ visibility of your custom controls yourself (and likely
+ hide it after adding it).
+
+ If your plugin is being removed, also make sure to
+ remove your custom controls too.
</description>
</method>
- <method name="add_custom_control">
- <argument index="0" name="container" type="int">
+ <method name="add_control_to_bottom_dock">
+ <argument index="0" name="control" type="Control">
</argument>
- <argument index="1" name="control" type="Object">
+ <argument index="1" name="title" type="String">
</argument>
<description>
+ Add a control to the bottom dock (together with
+ Output, Debug, Animation, etc).
+
+ Please remember that you have to manage the
+ visibility of your custom controls yourself (and likely
+ hide it after adding it).
+
+ If your plugin is being removed, also make sure to
+ remove your custom controls too.
+ </description>
+ </method>
+ <method name="add_control_to_dock">
+ <argument index="0" name="slot" type="int">
+ </argument>
+ <argument index="1" name="control" type="Control">
+ </argument>
+ <description>
+ Add the control to a specific dock slot (see DOCK_*
+ enum for options).
+
+ If the dock is repositioned and as long as the
+ plugin is active, the editor will save the dock
+ position on further sessions.
+
+ If your plugin is being removed, also make sure to
+ remove your control by calling [method
+ remove_control_from_docks].
+ </description>
+ </method>
+ <method name="remove_control_from_docks">
+ <argument index="0" name="control" type="Control">
+ </argument>
+ <description>
+ Remove the control from the dock. Don't forget to
+ call this if you added one, so the editor can save
+ the layout and remove it cleanly.
</description>
</method>
<method name="add_custom_type">
@@ -10012,12 +10315,102 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="3" name="icon" type="Texture">
</argument>
<description>
+ Add a custom type, which will appear in the list of
+ nodes or resources. An icon can be optionally
+ passed.
+
+ When given node or resource is selected, the base
+ type will be instanced (ie, "Spatial", "Control",
+ "Resource"), then the script will be loaded and set
+ to this object.
+
+ You can use the [EditorPlugin.handles] to check if
+ your custom object is being edited by checking the
+ script or using 'extends' keyword.
+
+ During run-time, this will be a simple object with a
+ script so this function does not need to be called
+ then.
</description>
</method>
<method name="remove_custom_type">
<argument index="0" name="type" type="String">
</argument>
<description>
+ Remove a custom type added by
+ [EditorPlugin.add_custom_type]
+ </description>
+ </method>
+ <method name="add_import_plugin">
+ <argument index="0" name="plugin" type="EditorImportPlugin">
+ </argument>
+ <description>
+ Add an import plugin. These plugins manage importing
+ external content (from outside the project) into
+ formats the engine can understand.
+
+ On exit, don't forget to remove the plugin by
+ calling [method remove_import_plugin]
+ </description>
+ </method>
+ <method name="remove_import_plugin">
+ <argument index="0" name="plugin" type="EditorImportPlugin">
+ </argument>
+ <description>
+ Remove the import plugin, don't forget to call this
+ on exit.
+ </description>
+ </method>
+ <method name="add_export_plugin">
+ <argument index="0" name="plugin" type="EditorExportPlugin">
+ </argument>
+ <description>
+ Add an export plugin. Plugins of this kind can
+ change files being exported. On exit don't forget to
+ call [method remove_export_plugin].
+ </description>
+ </method>
+ <method name="remove_export_plugin">
+ <argument index="0" name="plugin" type="EditorExportPlugin">
+ </argument>
+ <description>
+ Remove the export plugin, don't forget to call this
+ on exit.
+ </description>
+ </method>
+ <method name="get_base_control">
+ <return type="Control">
+ </return>
+ <description>
+ Get a base control where it's safe to place dialogs.
+ Many plugins open dialogs and they need a control as
+ a base to make sure they use the editor icons and
+ theme.
+ </description>
+ </method>
+ <method name="get_undo_redo">
+ <return type="UndoRedo">
+ </return>
+ <description>
+ Get the undo/redo object. Most actions in the editor
+ can be undoable, so use this object to make sure
+ this happens when it's worth it.
+ </description>
+ </method>
+ <method name="get_selection">
+ <return type="EditorSelection">
+ </return>
+ <description>
+ Get the object that handles the selection of nodes
+ in the Scene Tree editor.
+ </description>
+ </method>
+ <method name="get_editor_settings">
+ <return type="EditorSettings">
+ </return>
+ <description>
+ Get the general settings for the editor (the same
+ window that appears in the Settings menu).
</description>
</method>
</methods>
@@ -10034,18 +10427,45 @@ This approximation makes straight segments between each point, then subdivides t
</constant>
<constant name="CONTAINER_CANVAS_EDITOR_SIDE" value="5">
</constant>
+ <constant name="DOCK_SLOT_LEFT_UL" value="0">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_BL" value="1">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_UR" value="2">
+ </constant>
+ <constant name="DOCK_SLOT_LEFT_BR" value="3">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_UL" value="4">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_BL" value="5">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_UR" value="6">
+ </constant>
+ <constant name="DOCK_SLOT_RIGHT_BR" value="7">
+ </constant>
+ <constant name="DOCK_SLOT_MAX" value="8">
+ </constant>
</constants>
</class>
<class name="EditorScenePostImport" inherits="Reference" category="Core">
<brief_description>
+ Base script for post-processing scenes being imported.
</brief_description>
<description>
+ These scripts can modify scenes after being imported by the 3D Scene
+ import option of the Import menu.
</description>
<methods>
<method name="post_import" qualifiers="virtual">
<argument index="0" name="scene" type="Object">
</argument>
<description>
+ This function is called upon import with the
+ imported scene.
+
+ Just do any changes desired to the scene and return
+ it. If null is returned, import will fail and throw
+ an error to the user.
</description>
</method>
</methods>
@@ -10054,8 +10474,10 @@ This approximation makes straight segments between each point, then subdivides t
</class>
<class name="EditorScript" inherits="Reference" category="Core">
<brief_description>
+ Simple script to perform changes in the currently edited scene.
</brief_description>
<description>
+ This script can be run from the Scene -&gt; Run Script menu option.
</description>
<methods>
<method name="_run" qualifiers="virtual">
@@ -10078,6 +10500,300 @@ This approximation makes straight segments between each point, then subdivides t
<constants>
</constants>
</class>
+<class name="EditorSelection" inherits="Object" category="Core">
+ <brief_description>
+ Manages the SceneTree selection in the editor.
+ </brief_description>
+ <description>
+ This object manages the SceneTree selection in the editor.
+ </description>
+ <methods>
+ <method name="clear">
+ <description>
+ Clear the selection.
+ </description>
+ </method>
+ <method name="add_node">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ Add a node to the selection.
+ </description>
+ </method>
+ <method name="remove_node">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ Remove a node from the selection.
+ </description>
+ </method>
+ <method name="get_selected_nodes">
+ <return type="Array">
+ </return>
+ <description>
+ Get the list of selectes nodes.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="selection_changed">
+ <description>
+ Emitted when the selection changes.
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="EditorSettings" inherits="Resource" category="Core">
+ <brief_description>
+ Object that holds the project-independent editor settings.
+ </brief_description>
+ <description>
+ Object that holds the project-independent editor settings. These
+ settings are generally visible in the Editor Settings menu.
+
+ Accessing the settings is done by using the regular [Object] API,
+ such as.
+
+ settings.set(prop,value)
+
+ settings.get(prop)
+
+ list_of_settings = settings.get_property_list()
+ </description>
+ <methods>
+ <method name="erase">
+ <argument index="0" name="property" type="String">
+ </argument>
+ <description>
+ Erase a given setting (pass full property path).
+ </description>
+ </method>
+ <method name="get_settings_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Get the global settings path for the engine. Inside
+ this path you can find some standard paths such as:
+
+ settings/tmp - used for temporary storage of files
+
+ settings/templates - where export templates are
+ located
+ </description>
+ </method>
+ <method name="get_project_settings_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ Get the specific project settings path. Projects all
+ have an unique sub-directory inside the settings
+ path where project specific settings are saved.
+ </description>
+ </method>
+ <method name="set_favorite_dirs">
+ <argument index="0" name="dirs" type="StringArray">
+ </argument>
+ <description>
+ Set the list of favorite directories for this
+ project.
+ </description>
+ </method>
+ <method name="get_favorite_dirs" qualifiers="const">
+ <return type="StringArray">
+ </return>
+ <description>
+ Get the list of favorite directories for this
+ project.
+ </description>
+ </method>
+ <method name="set_recent_dirs">
+ <argument index="0" name="dirs" type="StringArray">
+ </argument>
+ <description>
+ Set the list of recently visited folders in the file
+ dialog for this project.
+ </description>
+ </method>
+ <method name="get_recent_dirs" qualifiers="const">
+ <return type="StringArray">
+ </return>
+ <description>
+ Get the list of recently visited folders in the file
+ dialog for this project.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="settings_changed">
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="EditorSpatialGizmo" inherits="SpatialGizmo" category="Core">
+ <brief_description>
+ Custom gizmo for editing Spatial objects.
+ </brief_description>
+ <description>
+ Custom gizmo that is used for providing custom visualization and
+ editing (handles) for 3D Spatial objects. These are created by
+ [method EditorPlugin.create_spatial_gizmo].
+ </description>
+ <methods>
+ <method name="commit_handle" qualifiers="virtual">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="restore" type="Variant">
+ </argument>
+ <argument index="2" name="cancel" type="bool">
+ </argument>
+ <description>
+ Commit a handle being edited (handles must have been
+ prevously added by [method add_handles]).
+
+ If the cancel parameter is true, an option to
+ restore the edited value to the original is
+ provided.
+ </description>
+ </method>
+ <method name="get_handle_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ Get the name of an edited handle (handles must have
+ been previously added by [method add_handles]).
+
+ Handles can be named for reference to the user when editing.
+ </description>
+ </method>
+ <method name="get_handle_value" qualifiers="virtual">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ Get actual value of a handle. This value can be
+ anything and used for eventually undoing the motion
+ when calling [method commit_handle]
+ </description>
+ </method>
+ <method name="redraw" qualifiers="virtual">
+ <description>
+ This function is called when the Spatial this gizmo
+ refers to changes (the [method Spatial.update_gizmo]
+ is called).
+ </description>
+ </method>
+ <method name="set_handle" qualifiers="virtual">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="camera" type="Camera">
+ </argument>
+ <argument index="2" name="point" type="Vector2">
+ </argument>
+ <description>
+ This function is used when the user drags a gizmo
+ handle (previously added with [method add_handles])
+ in screen coordinates.
+
+ The [Camera] is also provided
+ so screen coordinates can be converted to raycasts.
+ </description>
+ </method>
+ <method name="add_lines">
+ <argument index="0" name="lines" type="Vector3Array">
+ </argument>
+ <argument index="1" name="material" type="Material">
+ </argument>
+ <argument index="2" name="billboard" type="bool" default="false">
+ </argument>
+ <description>
+ Add lines to the gizmo (as sets of 2 points), with a
+ given material. The lines are used for visualizing
+ the gizmo.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_mesh">
+ <argument index="0" name="mesh" type="Mesh">
+ </argument>
+ <argument index="1" name="billboard" type="bool" default="false">
+ </argument>
+ <argument index="2" name="skeleton" type="RID" default="RID()">
+ </argument>
+ <description>
+ Add a mesh to the gizmo, this is used for
+ visualization.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_collision_segments">
+ <argument index="0" name="segments" type="Vector3Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="add_collision_triangles">
+ <argument index="0" name="triangles" type="TriangleMesh">
+ </argument>
+ <description>
+ Add collision triangles to the gizmo for picking. A
+ [TriangleMesh] can be generated from a regular
+ [Mesh] too.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_unscaled_billboard">
+ <argument index="0" name="material" type="Material">
+ </argument>
+ <argument index="1" name="default_scale" type="float" default="1">
+ </argument>
+ <description>
+ Add an unscaled billboard for visualization.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="add_handles">
+ <argument index="0" name="handles" type="Vector3Array">
+ </argument>
+ <argument index="1" name="billboard" type="bool" default="false">
+ </argument>
+ <argument index="2" name="secondary" type="bool" default="false">
+ </argument>
+ <description>
+ Add a list of handles (points) which can be used to
+ deform the object being edited.
+
+ There are virtual functions which will be called
+ upon editing of these handles.
+
+ Call this function during [method redraw].
+ </description>
+ </method>
+ <method name="set_spatial_node">
+ <argument index="0" name="node" type="Spatial">
+ </argument>
+ <description>
+ Call this function once and upon creation of the
+ gizmo, otherwise no other function will work.
+
+ The argument is the node being edited by the gizmo.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="Environment" inherits="Resource" category="Core">
<brief_description>
</brief_description>
@@ -10099,7 +10815,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="set_background_param">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10129,7 +10845,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="fx_set_param">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10729,7 +11445,7 @@ This approximation makes straight segments between each point, then subdivides t
</description>
</method>
<method name="store_var">
- <argument index="0" name="value" type="var">
+ <argument index="0" name="value" type="Variant">
</argument>
<description>
</description>
@@ -10935,7 +11651,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="set_parameter">
<argument index="0" name="param" type="int">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set a parameter, parameters are defined in the PARAM_* enum. The type of each parameter may change, so it's best to check the enum.
@@ -11004,14 +11720,14 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="0" name="transform" type="Transform">
</argument>
<description>
- Sets a special transform used to post-transform UV coordinates of the uv_xfrom tecoord mode: TEXCOORD_UV_TRANSFORM.
+ Sets a special transform used to post-transform UV coordinates of the uv_xform texcoord mode: TEXCOORD_UV_TRANSFORM.
</description>
</method>
<method name="get_uv_transform" qualifiers="const">
<return type="Transform">
</return>
<description>
- Returns the special transform used to post-transform UV coordinates of the uv_xfrom tecoord mode: TEXCOORD_UV_TRANSFORM.
+ Returns the special transform used to post-transform UV coordinates of the uv_xform texcoord mode: TEXCOORD_UV_TRANSFORM.
</description>
</method>
<method name="set_light_shader">
@@ -11270,7 +11986,7 @@ This approximation makes straight segments between each point, then subdivides t
<argument index="4" name="modulate" type="Color" default="Color(1,1,1,1)">
</argument>
<description>
- Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is apassed. clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character.
+ Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is passed. clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character.
</description>
</method>
<method name="set_fallback">
@@ -11296,25 +12012,25 @@ This approximation makes straight segments between each point, then subdivides t
</description>
<methods>
<method name="call_func">
- <argument index="0" name="arg0" type="var" default="NULL">
+ <argument index="0" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="1" name="arg1" type="var" default="NULL">
+ <argument index="1" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg2" type="var" default="NULL">
+ <argument index="2" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg3" type="var" default="NULL">
+ <argument index="3" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg4" type="var" default="NULL">
+ <argument index="4" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg5" type="var" default="NULL">
+ <argument index="5" name="arg5" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg6" type="var" default="NULL">
+ <argument index="6" name="arg6" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg7" type="var" default="NULL">
+ <argument index="7" name="arg7" type="Variant" default="NULL">
</argument>
- <argument index="8" name="arg8" type="var" default="NULL">
+ <argument index="8" name="arg8" type="Variant" default="NULL">
</argument>
- <argument index="9" name="arg9" type="var" default="NULL">
+ <argument index="9" name="arg9" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -11344,7 +12060,7 @@ This approximation makes straight segments between each point, then subdivides t
<method name="resume">
<return type="Variant">
</return>
- <argument index="0" name="arg" type="var" default="NULL">
+ <argument index="0" name="arg" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -12127,6 +12843,16 @@ This approximation makes straight segments between each point, then subdivides t
</signals>
<constants>
</constants>
+ <theme_items>
+ <theme_item name="more" type="Texture">
+ </theme_item>
+ <theme_item name="reset" type="Texture">
+ </theme_item>
+ <theme_item name="minus" type="Texture">
+ </theme_item>
+ <theme_item name="bg" type="StyleBox">
+ </theme_item>
+ </theme_items>
</class>
<class name="GraphNode" inherits="Container" category="Core">
<brief_description>
@@ -12806,7 +13532,7 @@ This approximation makes straight segments between each point, then subdivides t
Horizontal separator.
</brief_description>
<description>
- Horizontal separator. See [Separator]. It is used to separate objects vertiacally, though (but it looks horizontal!).
+ Horizontal separator. See [Separator]. It is used to separate objects vertically, though (but it looks horizontal!).
</description>
<methods>
</methods>
@@ -12886,9 +13612,8 @@ This approximation makes straight segments between each point, then subdivides t
</argument>
<description>
Connect to a host. This needs to be done before any requests are sent.
-The host should not have http:// prepended but will strip the protocol identifier if provided.
-
-verify_host will check the SSL identity of the host if set to true.
+ The host should not have http:// prepended but will strip the protocol identifier if provided.
+ verify_host will check the SSL identity of the host if set to true.
</description>
</method>
<method name="set_connection">
@@ -12911,11 +13636,13 @@ verify_host will check the SSL identity of the host if set to true.
<description>
Sends a request to the connected host. The url is what is normally behind the hostname, i.e. in [code]http://somehost.com/index.php[/code], url would be "index.php".
Headers are HTTP request headers.
- To create a POST request with query strings to push to the server, do::
- var fields = {"username" : "user", "password" : "pass"}
- var queryString = httpClient.query_string_from_dict(fields)
- var headers = ["Content-Type: application/x-www-form-urlencoded", "Content-Length: " + str(queryString.length())]
- var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, queryString)
+ To create a POST request with query strings to push to the server, do:
+ [codeblock]
+ var fields = {"username" : "user", "password" : "pass"}
+ var queryString = httpClient.query_string_from_dict(fields)
+ var headers = ["Content-Type: application/x-www-form-urlencoded", "Content-Length: " + str(queryString.length())]
+ var result = httpClient.request(httpClient.METHOD_POST, "index.php", headers, queryString)
+ [/codeblock]
</description>
</method>
<method name="send_body_text">
@@ -12968,6 +13695,9 @@ verify_host will check the SSL identity of the host if set to true.
<return type="Dictionary">
</return>
<description>
+ Returns all response headers as dictionary where the case-sensitivity of the keys and values is kept like the server delivers it. A value is a simple String, this string can have more than one value where "; " is used as separator.
+Structure: ("key":"value1; value2")
+Example: (content-length:12), (Content-Type:application/json; charset=UTF-8)
</description>
</method>
<method name="get_response_body_length" qualifiers="const">
@@ -13022,10 +13752,12 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="fields" type="Dictionary">
</argument>
<description>
- Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary, e.g.::
- var fields = {"username": "user", "password": "pass"}
- String queryString = httpClient.query_string_from_dict(fields)
- returns:= "username=user&amp;password=pass"
+ Generates a GET/POST application/x-www-form-urlencoded style query string from a provided dictionary, e.g.:
+ [codeblock]
+ var fields = {"username": "user", "password": "pass"}
+ String queryString = httpClient.query_string_from_dict(fields)
+ returns:= "username=user&amp;password=pass"
+ [/codeblock]
</description>
</method>
</methods>
@@ -13239,7 +13971,7 @@ verify_host will check the SSL identity of the host if set to true.
IP Protocol support functions.
</brief_description>
<description>
- IP contains some support functions for the IPv4 protocol. TCP/IP support is in different classes (see [TCP_Client], [TCP_Server]). IP provides hostname resolution support, both blocking and threaded.
+ IP contains some support functions for the IPv4 protocol. TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides hostname resolution support, both blocking and threaded.
</description>
<methods>
<method name="resolve_hostname">
@@ -14080,7 +14812,7 @@ verify_host will check the SSL identity of the host if set to true.
</constant>
</constants>
</class>
-<class name="InputEventJoyButton" category="Built-In Types">
+<class name="InputEventJoystickButton" category="Built-In Types">
<brief_description>
</brief_description>
<description>
@@ -14166,7 +14898,7 @@ verify_host will check the SSL identity of the host if set to true.
</constant>
</constants>
</class>
-<class name="InputEventJoyMotion" category="Built-In Types">
+<class name="InputEventJoystickMotion" category="Built-In Types">
<brief_description>
</brief_description>
<description>
@@ -15070,7 +15802,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -15355,10 +16087,10 @@ verify_host will check the SSL identity of the host if set to true.
</class>
<class name="Joint2D" inherits="Node2D" category="Core">
<brief_description>
- Base node for all joint constraints in 2D phyisics.
+ Base node for all joint constraints in 2D physics.
</brief_description>
<description>
- Base node for all joint constraints in 2D phyisics. Joints take 2 bodies and apply a custom constraint.
+ Base node for all joint constraints in 2D physics. Joints take 2 bodies and apply a custom constraint.
</description>
<methods>
<method name="set_node_a">
@@ -16561,7 +17293,7 @@ verify_host will check the SSL identity of the host if set to true.
Main loop is the abstract main loop base class.
</brief_description>
<description>
- Main loop is the abstract main loop base class. All other main loop classes are derived from it. Upon application start, a [MainLoop] has to be provided to OS, else the application will exit. This happens automatically (and a [SceneMainLoop] is created), unless a main [Script] is supplied, which may or not create and return a [MainLoop].
+ Main loop is the abstract main loop base class. All other main loop classes are derived from it. Upon application start, a [MainLoop] has to be provided to OS, else the application will exit. This happens automatically (and a [SceneTree] is created), unless a main [Script] is supplied, which may or not create and return a [MainLoop].
</description>
<methods>
<method name="_finalize" qualifiers="virtual">
@@ -16675,7 +17407,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="variant_to_base64">
<return type="String">
</return>
- <argument index="0" name="variant" type="var">
+ <argument index="0" name="variant" type="Variant">
</argument>
<description>
</description>
@@ -16828,7 +17560,7 @@ verify_host will check the SSL identity of the host if set to true.
Use additive blending equation, often used for particle effects such as fire or light decals.
</constant>
<constant name="BLEND_MODE_SUB" value="2">
- Use substractive blending equation, often used for some smoke effects or types of glass.
+ Use subtractive blending equation, often used for some smoke effects or types of glass.
</constant>
<constant name="BLEND_MODE_MUL" value="3">
</constant>
@@ -17653,7 +18385,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_vertex_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17701,7 +18433,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_edge_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17735,7 +18467,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_face_meta">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -17772,10 +18504,10 @@ verify_host will check the SSL identity of the host if set to true.
</class>
<class name="MeshInstance" inherits="GeometryInstance" category="Core">
<brief_description>
- Node that instances meshes into a [Scenario].
+ Node that instances meshes into a scenario.
</brief_description>
<description>
- MeshInstance is a [Node] that takes a [Mesh] resource and adds it to the current [Scenario] by creating an instance of it. This is the class most often used to get 3D geometry rendered and can be used to instance a single [Mesh] in many places. This allows to reuse geometry and save on resources. When a [Mesh] has to be instanced more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance] instead.
+ MeshInstance is a [Node] that takes a [Mesh] resource and adds it to the current scenario by creating an instance of it. This is the class most often used to get 3D geometry rendered and can be used to instance a single [Mesh] in many places. This allows to reuse geometry and save on resources. When a [Mesh] has to be instanced more than thousands of times at close proximity, consider using a [MultiMesh] in a [MultiMeshInstance] instead.
</description>
<methods>
<method name="set_mesh">
@@ -17928,7 +18660,7 @@ verify_host will check the SSL identity of the host if set to true.
<description>
MultiMesh provides low level mesh instancing. If the amount of [Mesh] instances needed goes from hundreds to thousands (and most need to be visible at close proximity) creating such a large amount of [MeshInstance] nodes may affect performance by using too much CPU or video memory.
For this case a MultiMesh becomes very useful, as it can draw thousands of instances with little API overhead.
- As a drawback, if the instances are too far away of each other, performance may be reduced as every single instance will always rendered (they are spatially indexed as one, for the whole object).
+ As a drawback, if the instances are too far away of each other, performance may be reduced as every single instance will always rendered (they are spatially indexed as one, for the whole object).
Since instances may have any behavior, the AABB used for visibility must be provided by the user, or generated with [method generate_aabb].
</description>
<methods>
@@ -18024,7 +18756,7 @@ verify_host will check the SSL identity of the host if set to true.
Node that instances a [MultiMesh].
</brief_description>
<description>
- MultiMeshInstance is a [Node] that takes a [MultiMesh] resource and adds it to the current [Scenario] by creating an instance of it (yes, this is an instance of instances).
+ MultiMeshInstance is a [Node] that takes a [MultiMesh] resource and adds it to the current scenario by creating an instance of it (yes, this is an instance of instances).
</description>
<methods>
<method name="set_multimesh">
@@ -18412,13 +19144,13 @@ verify_host will check the SSL identity of the host if set to true.
</description>
<methods>
<method name="set_navigation_polygon">
- <argument index="0" name="navpoly" type="Object">
+ <argument index="0" name="navpoly" type="NavigationPolygon">
</argument>
<description>
</description>
</method>
<method name="get_navigation_polygon" qualifiers="const">
- <return type="Object">
+ <return type="NavigationPolygon">
</return>
<description>
</description>
@@ -18624,7 +19356,7 @@ verify_host will check the SSL identity of the host if set to true.
<description>
Nodes can be set as children of other nodes, resulting in a tree arrangement. Any tree of nodes is called a "Scene".
Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects.
- [SceneMainLoop] contains the "active" tree of nodes, and a node becomes active (receiving NOTIFICATION_ENTER_SCENE) when added to that tree.
+ [SceneTree] contains the "active" tree of nodes, and a node becomes active (receiving NOTIFICATION_ENTER_SCENE) when added to that tree.
A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two children with the same name can exist.
Nodes can, optionally, be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group).
Nodes can be set to "process" state, so they constantly receive a callback requesting them to process (do anything). Normal processing ([method _process]) happens as fast as possible and is dependent on the frame rate, so the processing time delta is variable. Fixed processing ([method _fixed_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics.
@@ -18749,7 +19481,7 @@ verify_host will check the SSL identity of the host if set to true.
</argument>
<description>
Fetch a node. NodePath must be valid (or else error will occur) and can be either the path to child node, a relative path (from the current node to another node), or an absolute path to a node.
- Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_scene]). Examples. Assume your current node is Character and following tree:[br]
+ Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]). Examples. Assume your current node is Character and following tree:[br]
root/
root/Character
root/Character/Sword
@@ -18829,7 +19561,7 @@ verify_host will check the SSL identity of the host if set to true.
<return type="NodePath">
</return>
<description>
- Return the absolute path of the current node. This only works if the current node is inside the scene tree (see [method is_inside_scene]).
+ Return the absolute path of the current node. This only works if the current node is inside the scene tree (see [method is_inside_tree]).
</description>
</method>
<method name="get_path_to" qualifiers="const">
@@ -18847,7 +19579,7 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="1" name="persistent" type="bool" default="false">
</argument>
<description>
- Add a node to a group. Groups are helpers to name and organize group of nodes, like for example: "Enemies", "Collectables", etc. A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_scene]).
+ Add a node to a group. Groups are helpers to name and organize group of nodes, like for example: "Enemies", "Collectables", etc. A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_tree]).
</description>
</method>
<method name="remove_from_group">
@@ -18896,7 +19628,7 @@ verify_host will check the SSL identity of the host if set to true.
<return type="Node">
</return>
<description>
- Get the node owner (see [method set_node_owner]).
+ Get the node owner (see [method set_owner]).
</description>
</method>
<method name="remove_and_skip">
@@ -18941,7 +19673,7 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disables node fixed framerate processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS at a fixed (usually 60 fps, check [OS] to change that) interval (and the [method _fixed_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_fixed_process_time].
+ Enables or disables node fixed framerate processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS at a fixed (usually 60 fps, check [OS] to change that) interval (and the [method _fixed_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_fixed_process_delta_time].
</description>
</method>
<method name="get_fixed_process_delta_time" qualifiers="const">
@@ -18962,7 +19694,7 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disables node processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS on every drawn frame (and the [method _process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_process_time].
+ Enables or disables node processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS on every drawn frame (and the [method _process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_process_delta_time].
</description>
</method>
<method name="get_process_delta_time" qualifiers="const">
@@ -19316,10 +20048,12 @@ verify_host will check the SSL identity of the host if set to true.
</class>
<class name="NodePath" category="Built-In Types">
<brief_description>
- Built-in type optimized for path traversing.
+ Pre-parsed scene tree path.
</brief_description>
<description>
- Built-in type optimized for path traversing. A Node path is an optimized compiled path used for traversing the scene tree. It references nodes and can reference properties in that node, or even reference properties inside the resources of the node.
+ A pre-parsed relative or absolute path in a scene tree, for use with [method Node.get_node] and similar functions. It can reference a node, a resource within a node, or a property of a node or resource. For instance, [code]"Path2D/PathFollow2D/Sprite:texture:size"[/code] would refer to the size property of the texture resource on the node named "Sprite" which is a child of the other named nodes in the path. Note that if you want to get a resource, you must end the path with a colon, otherwise the last element will be used as a property name.
+ You will usually just pass a string to [method Node.get_node] and it will be automatically converted, but you may occasionally want to parse a path ahead of time with [NodePath] or the literal syntax [code]@"path"[/code]. Exporting a [NodePath] variable will give you a node selection widget in the properties panel of the editor, which can often be useful.
+ A [NodePath] is made up of a list of node names, a list of "subnode" (resource) names, and the name of a property in the final node or resource.
</description>
<methods>
<method name="get_name">
@@ -19328,21 +20062,21 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return a path level name.
+ Get the node name indicated by [code]idx[/code] (0 to [method get_name_count])
</description>
</method>
<method name="get_name_count">
<return type="int">
</return>
<description>
- Return the path level count.
+ Get the number of node names which make up the path.
</description>
</method>
<method name="get_property">
<return type="String">
</return>
<description>
- Return the property associated (empty if none).
+ Get the path's property name, or an empty string if the path doesn't have a property.
</description>
</method>
<method name="get_subname">
@@ -19351,14 +20085,14 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return the subname level name.
+ Get the resource name indicated by [code]idx[/code] (0 to [method get_subname_count])
</description>
</method>
<method name="get_subname_count">
<return type="int">
</return>
<description>
- Return the subname count.
+ Get the number of resource names in the path.
</description>
</method>
<method name="is_absolute">
@@ -19381,6 +20115,7 @@ verify_host will check the SSL identity of the host if set to true.
<argument index="0" name="from" type="String">
</argument>
<description>
+ Create a NodePath from a string, e.g. "Path2D/PathFollow2D/Sprite:texture:size". A path is absolute if it starts with a slash. Absolute paths are only valid in the global scene tree, not within individual scenes. In a relative path, [code]"."[/code] and [code]".."[/code] indicate the current node and its parent.
</description>
</method>
</methods>
@@ -19735,7 +20470,7 @@ verify_host will check the SSL identity of the host if set to true.
<return type="String">
</return>
<description>
- Return the name of the host OS.
+ Return the name of the host OS. Possible values are: "Android", "BlackBerry 10", "Flash", "Haiku", "iOS", "HTML5", "OSX", "Server", "Windows", "WinRT", "X11"
</description>
</method>
<method name="get_cmdline_args">
@@ -19985,6 +20720,10 @@ verify_host will check the SSL identity of the host if set to true.
<description>
</description>
</method>
+ <method name="native_video_unpause">
+ <description>
+ </description>
+ </method>
<method name="get_scancode_string" qualifiers="const">
<return type="String">
</return>
@@ -20111,7 +20850,7 @@ verify_host will check the SSL identity of the host if set to true.
Base class for all non built-in types. Everything not a built-in type starts the inheritance chain from this class.
Objects do not manage memory, if inheriting from one the object will most likely have to be deleted manually (call the [method free] function from the script or delete from C++).
Some derivates add memory management, such as [Reference] (which keeps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
- Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simper means to export them.
+ Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them.
Objects also receive notifications ([method _notification]). Notifications are a simple way to notify the object about simple events, so they can all be handled together.
</description>
<methods>
@@ -20143,7 +20882,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="_set" qualifiers="virtual">
<argument index="0" name="property" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set a property. Return true if the property was found.
@@ -20172,7 +20911,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set">
<argument index="0" name="property" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set property into the object.
@@ -20231,7 +20970,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_meta">
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
Set a metadata into the object. Metadata is serialized. Metadata can be [i]anything[/i].
@@ -20280,15 +21019,15 @@ verify_host will check the SSL identity of the host if set to true.
<method name="emit_signal">
<argument index="0" name="signal" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
<description>
Emit a signal. Arguments are passed in an array.
@@ -20297,25 +21036,25 @@ verify_host will check the SSL identity of the host if set to true.
<method name="call">
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg5" type="var" default="NULL">
+ <argument index="6" name="arg5" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg6" type="var" default="NULL">
+ <argument index="7" name="arg6" type="Variant" default="NULL">
</argument>
- <argument index="8" name="arg7" type="var" default="NULL">
+ <argument index="8" name="arg7" type="Variant" default="NULL">
</argument>
- <argument index="9" name="arg8" type="var" default="NULL">
+ <argument index="9" name="arg8" type="Variant" default="NULL">
</argument>
- <argument index="10" name="arg9" type="var" default="NULL">
+ <argument index="10" name="arg9" type="Variant" default="NULL">
</argument>
<description>
Call a function in the object, result is returned.
@@ -20324,15 +21063,15 @@ verify_host will check the SSL identity of the host if set to true.
<method name="call_deferred">
<argument index="0" name="method" type="String">
</argument>
- <argument index="1" name="arg0" type="var" default="NULL">
+ <argument index="1" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="2" name="arg1" type="var" default="NULL">
+ <argument index="2" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg2" type="var" default="NULL">
+ <argument index="3" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg3" type="var" default="NULL">
+ <argument index="4" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg4" type="var" default="NULL">
+ <argument index="5" name="arg4" type="Variant" default="NULL">
</argument>
<description>
Create and store a function in the object. The call will take place on idle time.
@@ -20623,7 +21362,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -20822,7 +21561,7 @@ verify_host will check the SSL identity of the host if set to true.
<method name="pack">
<return type="Error">
</return>
- <argument index="0" name="value" type="var">
+ <argument index="0" name="value" type="Variant">
</argument>
<description>
</description>
@@ -21031,7 +21770,7 @@ verify_host will check the SSL identity of the host if set to true.
Provides an opaque background for [Control] children.
</brief_description>
<description>
- Panel is a [Control] that displays an opaque background. It's commonly used as a parent and container for other types of [Control] nodes. [center][img]images/panel_example.png[/img][/center]
+ Panel is a [Control] that displays an opaque background. It's commonly used as a parent and container for other types of [Control] nodes.
</description>
<methods>
</methods>
@@ -22719,7 +23458,7 @@ This method controls whether the position between two cached points is interpola
<method name="shape_set_data">
<argument index="0" name="shape" type="RID">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -22919,7 +23658,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="param" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -23051,7 +23790,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="shape_idx" type="int">
</argument>
- <argument index="2" name="metadata" type="var">
+ <argument index="2" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -23215,7 +23954,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="state" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -23333,7 +24072,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="var" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -23836,7 +24575,7 @@ This method controls whether the position between two cached points is interpola
Base class for all objects affected by physics.
</brief_description>
<description>
- PhysicsBody2D is an abstract base class for implementing a physics body. All [i]x[/i]Body2D types inherit from it.
+ PhysicsBody2D is an abstract base class for implementing a physics body. All *Body2D types inherit from it.
</description>
<methods>
<method name="set_layer_mask">
@@ -23923,7 +24662,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="depth" type="float">
</argument>
<description>
- Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_detection]).
+ Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_direction]).
</description>
</method>
<method name="get_one_way_collision_max_depth" qualifiers="const">
@@ -24252,7 +24991,7 @@ This method controls whether the position between two cached points is interpola
<method name="shape_set_data">
<argument index="0" name="shape" type="RID">
</argument>
- <argument index="1" name="data" type="var">
+ <argument index="1" name="data" type="Variant">
</argument>
<description>
</description>
@@ -24436,7 +25175,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="param" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -24678,7 +25417,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="state" type="int">
</argument>
- <argument index="2" name="value" type="var">
+ <argument index="2" name="value" type="Variant">
</argument>
<description>
</description>
@@ -24780,7 +25519,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="userdata" type="var" default="NULL">
+ <argument index="3" name="userdata" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -25921,7 +26660,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="ratio" type="float" default="0.75">
</argument>
<description>
- Popup (show the control in modal form) in the center of the screen, scalled at a ratio of size of the screen.
+ Popup (show the control in modal form) in the center of the screen, scaled at a ratio of size of the screen.
</description>
</method>
<method name="popup_centered_minsize">
@@ -26073,7 +26812,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_item_metadata">
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="metadata" type="var">
+ <argument index="1" name="metadata" type="Variant">
</argument>
<description>
</description>
@@ -26306,35 +27045,35 @@ This method controls whether the position between two cached points is interpola
Portals provide virtual openings to rooms.
</brief_description>
<description>
- Portals provide virtual openings to [RoomInstance] nodes, so cameras can look at them from the outside. Note that portals are a visibility optimization technique, and are in no way related to the game of the same name (as in, they are not used for teleportation). For more information on how rooms and portals work, see [RoomInstance]. Portals are represented as 2D convex polygon shapes (in the X,Y local plane), and are placed on the surface of the areas occupied by a [RoomInstance], to indicate that the room can be accessed or looked-at through them. If two rooms are next to each other, and two similar portals in each of them share the same world position (and are parallel and opposed to each other), they will automatically "connect" and form "doors" (for example, the portals that connect a kitchen to a living room are placed in the door they share). Portals must always have a [RoomInstance] node as a parent, grandparent or far parent, or else they will not be active.
+ Portals provide virtual openings to [VisualInstance] nodes, so cameras can look at them from the outside. Note that portals are a visibility optimization technique, and are in no way related to the game of the same name (as in, they are not used for teleportation). For more information on how rooms and portals work, see [VisualInstance]. Portals are represented as 2D convex polygon shapes (in the X,Y local plane), and are placed on the surface of the areas occupied by a [VisualInstance], to indicate that the room can be accessed or looked-at through them. If two rooms are next to each other, and two similar portals in each of them share the same world position (and are parallel and opposed to each other), they will automatically "connect" and form "doors" (for example, the portals that connect a kitchen to a living room are placed in the door they share). Portals must always have a [VisualInstance] node as a parent, grandparent or far parent, or else they will not be active.
</description>
<methods>
<method name="set_shape">
<argument index="0" name="points" type="Vector2Array">
</argument>
<description>
- Set the portal shape. The shape is an array of [Point2] points, representing a convex polygon in the X,Y plane.
+ Set the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
</description>
</method>
<method name="get_shape" qualifiers="const">
<return type="Vector2Array">
</return>
<description>
- Return the portal shape. The shape is an array of [Point2] points, representing a convex polygon in the X,Y plane.
+ Return the portal shape. The shape is an array of [Vector2] points, representing a convex polygon in the X,Y plane.
</description>
</method>
<method name="set_enabled">
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enable the portal (it is enabled by default though), disabling it will cause the parent [RoomInstance] to not be visible any longer when looking through the portal.
+ Enable the portal (it is enabled by default though), disabling it will cause the parent [VisualInstance] to not be visible any longer when looking through the portal.
</description>
</method>
<method name="is_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether the portal is active. When disabled it causes the parent [RoomInstance] to not be visible any longer when looking through the portal.
+ Return whether the portal is active. When disabled it causes the parent [VisualInstance] to not be visible any longer when looking through the portal.
</description>
</method>
<method name="set_disable_distance">
@@ -26460,7 +27199,7 @@ This method controls whether the position between two cached points is interpola
<method name="broadcast">
<argument index="0" name="name" type="String">
</argument>
- <argument index="1" name="parameters" type="var">
+ <argument index="1" name="parameters" type="Variant">
</argument>
<description>
</description>
@@ -26867,6 +27606,40 @@ This method controls whether the position between two cached points is interpola
<constants>
</constants>
</class>
+<class name="RangeIterator" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="is_finished">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="to_array">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_range">
+ <return type="Object">
+ </return>
+ <argument index="0" name="arg1" type="var">
+ </argument>
+ <argument index="1" name="arg2" type="var" default="NULL">
+ </argument>
+ <argument index="2" name="arg3" type="var" default="NULL">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="RawArray" category="Built-In Types">
<brief_description>
Raw byte array.
@@ -27503,6 +28276,14 @@ This method controls whether the position between two cached points is interpola
Returns a captured group. A captured group is the part of a string that matches a part of the pattern delimited by parentheses (unless they are non-capturing parentheses [i](?:)[/i]).
</description>
</method>
+ <method name="get_capture_start" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="capture" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_captures" qualifiers="const">
<return type="StringArray">
</return>
@@ -27682,7 +28463,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_option">
<argument index="0" name="key" type="String">
</argument>
- <argument index="1" name="value" type="var">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
</description>
@@ -27780,6 +28561,14 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
+ <method name="load_import_metadata">
+ <return type="ResourceImportMetadata">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_recognized_extensions_for_type">
<return type="StringArray">
</return>
@@ -27979,7 +28768,7 @@ This method controls whether the position between two cached points is interpola
</description>
</method>
<method name="push_meta">
- <argument index="0" name="data" type="var">
+ <argument index="0" name="data" type="Variant">
</argument>
<description>
</description>
@@ -28522,7 +29311,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="state" type="Physics2DDirectBodyState">
</argument>
<description>
- Override this function to use a custom force integrator. This allows to hook up to the physics processing and alter the simulation state for the object on every frame.
+ Called during physics processing, allowing you to read and safely modify the simulation state for the object. By default it works in addition to the usual physics behavior, but [method set_use_custom_integrator] allows you to disable the default behavior and do fully custom force integration for a body.
</description>
</method>
<method name="set_mode">
@@ -28683,7 +29472,7 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Set to true if the body shall not do any internal force integration at all (like gravity or air friction). Only the [method _integrate_forces] will be able to integrate them if overrided.
+ Pass true to disable the internal force integration (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined.
</description>
</method>
<method name="is_using_custom_integrator">
@@ -28875,7 +29664,7 @@ This method controls whether the position between two cached points is interpola
Room data resource.
</brief_description>
<description>
- Room contains the data to define the bounds of a scene (using a BSP Tree). It is instanced by a [RoomInstance] node to create rooms. See that class documentation for more information about rooms.
+ Room contains the data to define the bounds of a scene (using a BSP Tree). It is instanced by a [VisualInstance] node to create rooms. See that class documentation for more information about rooms.
</description>
<methods>
<method name="set_room">
@@ -29825,6 +30614,22 @@ This method controls whether the position between two cached points is interpola
<description>
</description>
</method>
+ <method name="is_node_instance_placeholder" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_node_instance_placeholder" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_node_instance" qualifiers="const">
<return type="PackedScene">
</return>
@@ -29948,7 +30753,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="property" type="String">
</argument>
- <argument index="3" name="value" type="var">
+ <argument index="3" name="value" type="Variant">
</argument>
<description>
</description>
@@ -30084,15 +30889,15 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="arg0" type="var" default="NULL">
+ <argument index="3" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg1" type="var" default="NULL">
+ <argument index="4" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg2" type="var" default="NULL">
+ <argument index="5" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg3" type="var" default="NULL">
+ <argument index="6" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg4" type="var" default="NULL">
+ <argument index="7" name="arg4" type="Variant" default="NULL">
</argument>
<description>
</description>
@@ -30544,7 +31349,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="param_id" type="int">
</argument>
- <argument index="3" name="value" type="var">
+ <argument index="3" name="value" type="Variant">
</argument>
<description>
</description>
@@ -31096,7 +31901,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="id" type="int">
</argument>
- <argument index="2" name="state" type="var">
+ <argument index="2" name="state" type="Variant">
</argument>
<description>
</description>
@@ -31949,7 +32754,7 @@ This method controls whether the position between two cached points is interpola
<return type="Transform">
</return>
<description>
- Return the gloal transform, relative to worldspace.
+ Return the global transform, relative to worldspace.
</description>
</method>
<method name="get_parent_spatial" qualifiers="const">
@@ -32128,6 +32933,16 @@ This method controls whether the position between two cached points is interpola
</constant>
</constants>
</class>
+<class name="SpatialGizmo" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="SpatialPlayer" inherits="Spatial" category="Core">
<brief_description>
</brief_description>
@@ -32599,7 +33414,7 @@ This method controls whether the position between two cached points is interpola
</class>
<class name="SpotLight" inherits="Light" category="Core">
<brief_description>
- Spotlight [Light], such as a reflector spotlight or a latern.
+ Spotlight [Light], such as a reflector spotlight or a lantern.
</brief_description>
<description>
A SpotLight light is a type of [Light] node that emits lights in a specific direction, in the shape of a cone. The light is attenuated through the distance and this attenuation can be configured by changing the energy, radius and attenuation parameters of [Light]. TODO: Image of a spotlight.
@@ -32656,7 +33471,7 @@ This method controls whether the position between two cached points is interpola
<return type="Vector2">
</return>
<description>
- Return sprite draw offst.
+ Return sprite draw offset.
</description>
</method>
<method name="set_flip_h">
@@ -33143,7 +33958,7 @@ This method controls whether the position between two cached points is interpola
Static body for 2D Physics.
</brief_description>
<description>
- Static body for 2D Physics. A static body is a simple body that is not intended to move. They don't consume any CPU resources in contrast to a [RigidBody2D] so they are great for scenaro collision.
+ Static body for 2D Physics. A static body is a simple body that is not intended to move. They don't consume any CPU resources in contrast to a [RigidBody2D] so they are great for scenario collision.
A static body can also be animated by using simulated motion mode. This is useful for implementing functionalities such as moving platforms. When this mode is active the body can be animated and automatically computes linear and angular velocity to apply in that frame and to influence other bodies.
Alternatively, a constant linear or angular velocity can be set for the static body, so even if it doesn't move, it affects other bodies as if it was moving (this is useful for simulating conveyor belts or conveyor wheels).
</description>
@@ -34272,7 +35087,7 @@ This method controls whether the position between two cached points is interpola
<return type="Vector2">
</return>
<description>
- Return the "offset" of a stylebox, this is a helper function, like writing Point2( style.get_margin(MARGIN_LEFT), style.get_margin(MARGIN_TOP) )
+ Return the "offset" of a stylebox, this is a helper function, like writing [code]Vector2(style.get_margin(MARGIN_LEFT), style.get_margin(MARGIN_TOP))[/code].
</description>
</method>
<method name="draw" qualifiers="const">
@@ -35998,7 +36813,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="userdata" type="var" default="NULL">
+ <argument index="2" name="userdata" type="Variant" default="NULL">
</argument>
<argument index="3" name="priority" type="int" default="1">
</argument>
@@ -36349,6 +37164,17 @@ This method controls whether the position between two cached points is interpola
Return whether the referenced cell is flipped over the Y axis.
</description>
</method>
+ <method name="is_cell_transposed" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <description>
+ Return whether the referenced cell is transposed, i.e. the X and Y axes are swapped (mirroring with regard to the (1,1) vector).
+ </description>
+ </method>
<method name="clear">
<description>
Clear all cells.
@@ -37609,7 +38435,7 @@ This method controls whether the position between two cached points is interpola
<method name="set_metadata">
<argument index="0" name="column" type="int">
</argument>
- <argument index="1" name="meta" type="var">
+ <argument index="1" name="meta" type="Variant">
</argument>
<description>
</description>
@@ -37862,62 +38688,85 @@ This method controls whether the position between two cached points is interpola
</class>
<class name="Tween" inherits="Node" category="Core">
<brief_description>
+ Node useful for animations with unknown start and end points.
</brief_description>
<description>
+ Node useful for animations with unknown start and end points, procedural animations, making one node follow another, and other simple behavior.
+
+ Because it is easy to get it wrong, here is a quick usage example:
+
+ [codeblock]
+ var tween = get_node("Tween")
+ tween.interpolate_property(get_node("Node2D_to_move"), "transform/pos", Vector2(0,0), Vector2(100,100), Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
+ tween.start()
+ [/codeblock]
+
+ Some of the methods of this class require a property name. You can get the property name by hovering over the property in the inspector of the editor.
+
+ Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an TRANS_* constant, and refers to the way the timing of the animation is handled (you might want to see [code]http://easings.net/[/code] for some examples). The second accepts an EASE_* constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the begining, the end, or both). If you don't know which transision and easing to pick, you can try different TRANS_* constants with EASE_IN_OUT, and use the one that looks best.
</description>
<methods>
<method name="is_active" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if any tweens are currently running, and false otherwise. Note that this method doesn't consider tweens that have ended.
</description>
</method>
<method name="set_active">
<argument index="0" name="active" type="bool">
</argument>
<description>
+ Activate/deactivate the tween. You can use this for pausing animations, though [method stop_all] and [method resume_all] might be more fit for this.
</description>
</method>
<method name="is_repeat" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns true if repeat has been set from editor GUI or [method set_repeat].
</description>
</method>
<method name="set_repeat">
<argument index="0" name="repeat" type="bool">
</argument>
<description>
+ Make the tween repeat after all tweens have finished.
</description>
</method>
<method name="set_speed">
<argument index="0" name="speed" type="float">
</argument>
<description>
+ Set the speed multiplier of the tween. Set it to 1 for normal speed, 2 for two times nromal speed, and 0.5 for half of the normal speed. Setting it to 0 would pause the animation, but you might consider using [method set_active] or [method stop_all] and [method resume_all] for this.
</description>
</method>
<method name="get_speed" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the speed that has been set from editor GUI or [method set_repeat].
</description>
</method>
<method name="set_tween_process_mode">
<argument index="0" name="mode" type="int">
</argument>
<description>
+ Set whether the Tween uses [code]_process[/code] or [code]_fixed_process[/code] (accepts TWEEN_PROCESS_IDLE and TWEEN_PROCESS_FIXED constants, respectively).
</description>
</method>
<method name="get_tween_process_mode" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the process mode that has been set from editor GUI or [method set_tween_process_mode]
</description>
</method>
<method name="start">
<return type="bool">
</return>
<description>
+ Start the tween node. You can define tweens both before and after this.
</description>
</method>
<method name="reset">
@@ -37928,12 +38777,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Resets a tween to the initial value (the one given, not the one before the tween), given its object and property/method pair.
</description>
</method>
<method name="reset_all">
<return type="bool">
</return>
<description>
+ Resets all tweens to their initial values (the ones given, not those before the tween).
</description>
</method>
<method name="stop">
@@ -37944,12 +38795,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Stop animating a tween, given its object and property/method pair.
</description>
</method>
<method name="stop_all">
<return type="bool">
</return>
<description>
+ Stop animating all tweens.
</description>
</method>
<method name="resume">
@@ -37960,12 +38813,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Continue animating a stopped tween, given its object and property/method pair.
</description>
</method>
<method name="resume_all">
<return type="bool">
</return>
<description>
+ Continue animating all stopped tweens.
</description>
</method>
<method name="remove">
@@ -37976,12 +38831,14 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ Stop animating and completely remove a tween, given its object and property/method pair.
</description>
</method>
<method name="remove_all">
<return type="bool">
</return>
<description>
+ Stop animating and completely remove all tweens.
</description>
</method>
<method name="seek">
@@ -37990,18 +38847,21 @@ This method controls whether the position between two cached points is interpola
<argument index="0" name="time" type="float">
</argument>
<description>
+ Seek the animation to the given [code]time[/code] in seconds.
</description>
</method>
<method name="tell" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the current time of the tween.
</description>
</method>
<method name="get_runtime" qualifiers="const">
<return type="float">
</return>
<description>
+ Returns the time needed for all tweens to end in seconds, measured from the start. Thus, if you have two tweens, one ending 10 seconds after the start and the other - 20 seconds, it would return 20 seconds, as by that time all tweens would have finished.
</description>
</method>
<method name="interpolate_property">
@@ -38011,9 +38871,9 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="property" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
- <argument index="3" name="final_val" type="var">
+ <argument index="3" name="final_val" type="Variant">
</argument>
<argument index="4" name="times_in_sec" type="float">
</argument>
@@ -38024,6 +38884,9 @@ This method controls whether the position between two cached points is interpola
<argument index="7" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]property[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="interpolate_method">
@@ -38033,9 +38896,9 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
- <argument index="3" name="final_val" type="var">
+ <argument index="3" name="final_val" type="Variant">
</argument>
<argument index="4" name="times_in_sec" type="float">
</argument>
@@ -38046,6 +38909,9 @@ This method controls whether the position between two cached points is interpola
<argument index="7" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]method[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="interpolate_callback">
@@ -38057,17 +38923,18 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg5" type="var" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="NULL">
</argument>
<description>
+ Call [code]callback[/code] of [code]object[/code] after [code]times_in_sec[/code]. [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
</description>
</method>
<method name="interpolate_deferred_callback">
@@ -38079,17 +38946,18 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="2" name="callback" type="String">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
- <argument index="7" name="arg5" type="var" default="NULL">
+ <argument index="7" name="arg5" type="Variant" default="NULL">
</argument>
<description>
+ Call [code]callback[/code] of [code]object[/code] after [code]times_in_sec[/code] on the main thread (similar to [methog Object.call_deferred). [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
</description>
</method>
<method name="follow_property">
@@ -38099,7 +38967,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="property" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
<argument index="3" name="target" type="Object">
</argument>
@@ -38114,6 +38982,9 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Follow [code]property[/code] of [code]object[/code] and apply it on [code]target_property[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Note that [code]target:target_property[/code] would equal [code]object:property[/code] at the end of the tween.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="follow_method">
@@ -38123,7 +38994,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="initial_val" type="var">
+ <argument index="2" name="initial_val" type="Variant">
</argument>
<argument index="3" name="target" type="Object">
</argument>
@@ -38138,6 +39009,9 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Follow [code]method[/code] of [code]object[/code] and apply the returned value on [code]target_method[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] later. Methods are animated by calling them with consequitive values.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="targeting_property">
@@ -38151,7 +39025,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="3" name="initial_val" type="String">
</argument>
- <argument index="4" name="final_val" type="var">
+ <argument index="4" name="final_val" type="Variant">
</argument>
<argument index="5" name="times_in_sec" type="float">
</argument>
@@ -38162,6 +39036,9 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]property[/code] of [code]object[/code] from the current value of the [code]initial_val[/code] property of [code]initial[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
<method name="targeting_method">
@@ -38175,7 +39052,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="3" name="initial_method" type="String">
</argument>
- <argument index="4" name="final_val" type="var">
+ <argument index="4" name="final_val" type="Variant">
</argument>
<argument index="5" name="times_in_sec" type="float">
</argument>
@@ -38186,6 +39063,9 @@ This method controls whether the position between two cached points is interpola
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
+ Animate [code]method[/code] of [code]object[/code] from the value returned by [code]initial.initial_method[/code] to [code]final_val[/code] for [code]times_in_sec[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+
+ [code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the begining, the end, or both). You can read more about them in the class description.
</description>
</method>
</methods>
@@ -38196,6 +39076,7 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ This signal is emitted when a tween ends.
</description>
</signal>
<signal name="tween_step">
@@ -38208,6 +39089,7 @@ This method controls whether the position between two cached points is interpola
<argument index="3" name="value" type="Object">
</argument>
<description>
+ This signal is emitted each step of the tweening.
</description>
</signal>
<signal name="tween_start">
@@ -38216,50 +39098,74 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="key" type="String">
</argument>
<description>
+ This signal is emitted when a tween starts.
</description>
</signal>
</signals>
<constants>
<constant name="TWEEN_PROCESS_FIXED" value="0">
+ The [Tween] should use [code]_fixed_process[/code] for timekeeping when this is enabled.
</constant>
<constant name="TWEEN_PROCESS_IDLE" value="1">
+ The [Tween] should use [code]_process[/code] for timekeeping when this is enabled (default).
</constant>
<constant name="TRANS_LINEAR" value="0">
+ Means that the animation is interpolated linearly.
</constant>
<constant name="TRANS_SINE" value="1">
+ Means that the animation is interpolated using a sine wave.
</constant>
<constant name="TRANS_QUINT" value="2">
+ Means that the animation is interpolated with a quinary (to the power of 5) function.
</constant>
<constant name="TRANS_QUART" value="3">
+ Means that the animation is interpolated with a quartic (to the power of 4) function.
</constant>
<constant name="TRANS_QUAD" value="4">
+ Means that the animation is interpolated with a quadratic (to the power of 2) function.
</constant>
<constant name="TRANS_EXPO" value="5">
+ Means that the animation is interpolated with a exponential (some number to the power of x) function.
</constant>
<constant name="TRANS_ELASTIC" value="6">
+ Means that the animation is interpolated with elasticity, wiggling around the edges.
</constant>
<constant name="TRANS_CUBIC" value="7">
+ Means that the animation is interpolated with a cubic (to the power of 3) function.
</constant>
<constant name="TRANS_CIRC" value="8">
+ Means that the animation is interpolated with a function using square roots.
</constant>
<constant name="TRANS_BOUNCE" value="9">
+ Means that the animation is interpolated by bouncing at, but never surpassing, the end.
</constant>
<constant name="TRANS_BACK" value="10">
+ Means that the animation is interpolated backing out at edges.
</constant>
<constant name="EASE_IN" value="0">
+ Signifies that the interpolation should be focused in the beginning.
</constant>
<constant name="EASE_OUT" value="1">
+ Signifies that the interpolation should be focused in the end.
</constant>
<constant name="EASE_IN_OUT" value="2">
+ Signifies that the interpolation should be focused in both ends.
</constant>
<constant name="EASE_OUT_IN" value="3">
+ Signifies that the interpolation should be focused in both ends, but they should be switched (a bit hard to explain, try it for yourself to be sure).
</constant>
</constants>
</class>
<class name="UndoRedo" inherits="Object" category="Core">
<brief_description>
+ Helper to manage UndoRedo in the editor or custom tools.
</brief_description>
<description>
+ Helper to maange UndoRedo in the editor or custom tools. It works by
+ storing calls to functions in both 'do' an 'undo' lists.
+
+ Common behavior is to create an action, then add do/undo calls to
+ functions or property changes, then commiting the action.
</description>
<methods>
<method name="create_action">
@@ -38268,10 +39174,16 @@ This method controls whether the position between two cached points is interpola
<argument index="1" name="mergeable" type="bool" default="false">
</argument>
<description>
+ Create a new action. After this is called, do all
+ your calls to [method add_do_method],
+ [method add_undo_method], [method add_do_property]
+ and [method add_undo_property].
</description>
</method>
<method name="commit_action">
<description>
+ Commit the action. All 'do' methods/properties are
+ called/set when this function is called.
</description>
</method>
<method name="add_do_method">
@@ -38279,17 +39191,19 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="arg0" type="var" default="NULL">
+ <argument index="2" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
<description>
+ Add a call to a method in a given object with custom
+ arguments.
</description>
</method>
<method name="add_undo_method">
@@ -38297,17 +39211,20 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="method" type="String">
</argument>
- <argument index="2" name="arg0" type="var" default="NULL">
+ <argument index="2" name="arg0" type="Variant" default="NULL">
</argument>
- <argument index="3" name="arg1" type="var" default="NULL">
+ <argument index="3" name="arg1" type="Variant" default="NULL">
</argument>
- <argument index="4" name="arg2" type="var" default="NULL">
+ <argument index="4" name="arg2" type="Variant" default="NULL">
</argument>
- <argument index="5" name="arg3" type="var" default="NULL">
+ <argument index="5" name="arg3" type="Variant" default="NULL">
</argument>
- <argument index="6" name="arg4" type="var" default="NULL">
+ <argument index="6" name="arg4" type="Variant" default="NULL">
</argument>
<description>
+ Add a call to an undo method in a given object with
+ custom arguments. Undo calls are used to revert 'do'
+ calls.
</description>
</method>
<method name="add_do_property">
@@ -38318,6 +39235,7 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Set a property with a custom value.
</description>
</method>
<method name="add_undo_property">
@@ -38328,34 +39246,51 @@ This method controls whether the position between two cached points is interpola
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Undo setting of a property with a custom value.
</description>
</method>
<method name="add_do_reference">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Add a 'do' reference that will be erased if the 'do'
+ history is lost. This is useful mostly for new nodes
+ created for the 'do' call. Do not use for resources.
</description>
</method>
<method name="add_undo_reference">
<argument index="0" name="object" type="Object">
</argument>
<description>
+ Add an 'undo' reference that will be erased if the
+ 'undo' history is lost. This is useful mostly for
+ nodes rmoved with the 'do' call (not the 'undo'
+ call!).
</description>
</method>
<method name="clear_history">
<description>
+ Clear the undo/redo history and associated
+ references.
</description>
</method>
<method name="get_current_action_name" qualifiers="const">
<return type="String">
</return>
<description>
+ Get the name of the current action.
</description>
</method>
<method name="get_version" qualifiers="const">
<return type="int">
</return>
<description>
+ Get the version, each time a new action is commited,
+ the version number of the UndoRedo is increased
+ automatically.
+
+ This is useful mostly to check if something changed
+ from a saved version.
</description>
</method>
</methods>
@@ -40080,7 +41015,7 @@ This method controls whether the position between two cached points is interpola
</argument>
<argument index="1" name="arg1" type="String">
</argument>
- <argument index="2" name="arg2" type="var">
+ <argument index="2" name="arg2" type="Variant">
</argument>
<description>
</description>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 1e2d276fb3..6311be767c 100644
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -100,7 +100,7 @@ def make_class_list(class_list, columns):
def rstize_text(text,cclass):
- # Linebreak + tabs in the XML should become two line breaks
+ # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock"
pos = 0
while True:
pos = text.find('\n', pos)
@@ -112,8 +112,40 @@ def rstize_text(text,cclass):
pos += 1
post_text = text[pos+1:]
- text = pre_text + "\n\n" + post_text
- pos += 2
+ # Handle codeblocks
+ if post_text.startswith("[codeblock]"):
+ end_pos = post_text.find("[/codeblock]")
+ if end_pos == -1:
+ sys.exit("ERROR! [codeblock] without a closing tag!")
+
+ code_text = post_text[len("[codeblock]"):end_pos]
+ post_text = post_text[end_pos:]
+
+ # Remove extraneous tabs
+ code_pos = 0
+ while True:
+ code_pos = code_text.find('\n', code_pos)
+ if code_pos == -1:
+ break
+
+ to_skip = 0
+ while code_pos+to_skip+1 < len(code_text) and code_text[code_pos+to_skip+1] == '\t':
+ to_skip += 1
+
+ if len(code_text[code_pos+to_skip+1:])==0:
+ code_text = code_text[:code_pos] + "\n"
+ code_pos += 1
+ else:
+ code_text = code_text[:code_pos] + "\n " + code_text[code_pos+to_skip+1:]
+ code_pos += 5 - to_skip
+
+ text = pre_text + "\n[codeblock]" + code_text + post_text
+ pos += len("\n[codeblock]" + code_text)
+
+ # Handle normal text
+ else:
+ text = pre_text + "\n\n" + post_text
+ pos += 2
# Escape * character to avoid interpreting it as emphasis
pos = 0
@@ -179,6 +211,13 @@ def rstize_text(text,cclass):
tag_text = ''
elif cmd == '/center':
tag_text = ''
+ elif cmd == 'codeblock':
+ tag_text = '\n::\n'
+ elif cmd == '/codeblock':
+ tag_text = ''
+ # Strip newline if the tag was alone on one
+ if pre_text[-1] == '\n':
+ pre_text = pre_text[:-1]
elif cmd == 'br':
# Make a new paragraph instead of a linebreak, rst is not so linebreak friendly
tag_text = '\n\n'
@@ -310,6 +349,10 @@ def make_rst_class(node):
f = open("class_"+name.lower() + '.rst', 'wb')
+ # Warn contributors not to edit this file directly
+ f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n")
+ f.write(".. DO NOT EDIT THIS FILE, but the doc/base/classes.xml source instead.\n\n")
+
f.write(".. _class_"+name+":\n\n")
f.write(make_heading(name, '='))
diff --git a/drivers/unix/memory_pool_static_malloc.cpp b/drivers/unix/memory_pool_static_malloc.cpp
index e75b682c19..f89b55de12 100644
--- a/drivers/unix/memory_pool_static_malloc.cpp
+++ b/drivers/unix/memory_pool_static_malloc.cpp
@@ -48,7 +48,12 @@ void* MemoryPoolStaticMalloc::alloc(size_t p_bytes,const char *p_description) {
#else
- int total = p_bytes + DEFAULT_ALIGNMENT;
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
+ #else
+ total = p_bytes + DEFAULT_ALIGNMENT;
+ #endif
uint8_t* ptr = (uint8_t*)_alloc(total, p_description);
ERR_FAIL_COND_V( !ptr, ptr );
int ofs = (DEFAULT_ALIGNMENT - ((uintptr_t)ptr & (DEFAULT_ALIGNMENT - 1)));
@@ -64,11 +69,18 @@ void* MemoryPoolStaticMalloc::_alloc(size_t p_bytes,const char *p_description) {
MutexLock lock(mutex);
#ifdef DEBUG_MEMORY_ENABLED
- void *mem=malloc(p_bytes+sizeof(RingPtr)); /// add for size and ringlist
+
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, sizeof(RingPtr), &total)) return NULL;
+ #else
+ total = p_bytes + sizeof(RingPtr);
+ #endif
+ void *mem=malloc(total); /// add for size and ringlist
if (!mem) {
- printf("**ERROR: out of memory while allocating %i bytes by %s?\n",(int) p_bytes, p_description);
- printf("**ERROR: memory usage is %i\n", (int)get_total_usage());
+ printf("**ERROR: out of memory while allocating %lu bytes by %s?\n", (unsigned long) p_bytes, p_description);
+ printf("**ERROR: memory usage is %lu\n", (unsigned long) get_total_usage());
};
ERR_FAIL_COND_V(!mem,0); //out of memory, or unreasonable request
@@ -129,7 +141,12 @@ void* MemoryPoolStaticMalloc::realloc(void *p_memory,size_t p_bytes) {
if (!p_memory)
return alloc(p_bytes);
- int total = p_bytes + DEFAULT_ALIGNMENT;
+ size_t total;
+ #if defined(_add_overflow)
+ if (_add_overflow(p_bytes, DEFAULT_ALIGNMENT, &total)) return NULL;
+ #else
+ total = p_bytes + DEFAULT_ALIGNMENT;
+ #endif
uint8_t* mem = (uint8_t*)p_memory;
int ofs = *(mem-1);
mem = mem - ofs;
diff --git a/godot_icon.png b/godot_icon.png
deleted file mode 100644
index 013632ddf1..0000000000
--- a/godot_icon.png
+++ /dev/null
Binary files differ
diff --git a/godot_icon.svg b/godot_icon.svg
deleted file mode 100644
index 6e32074d89..0000000000
--- a/godot_icon.svg
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="1024"
- height="1024"
- id="svg3030"
- version="1.1"
- inkscape:version="0.48.4 r9939"
- sodipodi:docname="godot_icon.svg">
- <defs
- id="defs3032" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.24748737"
- inkscape:cx="340.91041"
- inkscape:cy="224.06536"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1366"
- inkscape:window-height="748"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
- inkscape:window-maximized="1" />
- <metadata
- id="metadata3035">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-28.362183)">
- <rect
- style="fill:#a39f9f;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4009"
- width="990"
- height="990"
- x="20"
- y="47.362183"
- ry="187.81349" />
- <path
- style="fill:#ffffff;fill-opacity:1;stroke:none"
- d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
- id="path3239"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc" />
- <g
- id="g3412"
- transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3414" />
- </g>
- <g
- id="g3416"
- transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3418" />
- </g>
- <g
- id="g3420"
- transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3422" />
- </g>
- <g
- id="g3424"
- transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3426" />
- </g>
- <g
- id="g3428"
- transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3430" />
- </g>
- <g
- id="g3432"
- transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3434" />
- </g>
- <g
- id="g3436"
- transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3438" />
- </g>
- </g>
-</svg>
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000000..e334f5fa78
--- /dev/null
+++ b/icon.png
Binary files differ
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000000..34747d34fe
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1024"
+ height="1024"
+ id="svg3030"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="icon.svg"
+ inkscape:export-filename="/home/akien/Projects/godot/godot.git/icon.png"
+ inkscape:export-xdpi="22.5"
+ inkscape:export-ydpi="22.5">
+ <defs
+ id="defs3032" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.35"
+ inkscape:cx="-560.15123"
+ inkscape:cy="190.62119"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1015"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata3035">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-28.362183)">
+ <g
+ id="g4149"
+ transform="matrix(1.0688992,0,0,1.1334985,-45.061194,-81.689066)">
+ <path
+ sodipodi:nodetypes="cccccccccc"
+ inkscape:connector-curvature="0"
+ id="path3239"
+ d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
+ style="fill:#ffffff;fill-opacity:1;stroke:none" />
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)"
+ id="g3412">
+ <path
+ id="path3414"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 Z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)"
+ id="g3416">
+ <path
+ id="path3418"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 Z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)"
+ id="g3420">
+ <path
+ id="path3422"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)"
+ id="g3424">
+ <path
+ id="path3426"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)"
+ id="g3428">
+ <path
+ id="path3430"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)"
+ id="g3432">
+ <path
+ id="path3434"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)"
+ id="g3436">
+ <path
+ id="path3438"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/godot_logo.svg b/logo.svg
index 98dcddfd2b..98dcddfd2b 100644
--- a/godot_logo.svg
+++ b/logo.svg
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 260af7528b..734fdf5afa 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -102,6 +102,18 @@ bool InputDefault::is_action_pressed(const StringName& p_action) {
if (joy_buttons_pressed.has(c))
return true;
} break;
+ case InputEvent::JOYSTICK_MOTION: {
+
+ const InputEventJoystickMotion &iejm=E->get().joy_motion;
+ int c = _combine_device(iejm.axis,device);
+ if (_joy_axis.has(c)) {
+ if (iejm.axis_value < 0) {
+ if (_joy_axis[c] < -0.5f) return true;
+ }
+ else
+ if (_joy_axis[c] > 0.5f) return true;
+ }
+ } break;
}
}
@@ -449,7 +461,7 @@ static const char *s_ControllerMappings [] =
"03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,",
"03000000280400000140000000010000,Gravis GamePad Pro USB ,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,",
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
- "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
+ "030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,",
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,",
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
@@ -475,6 +487,7 @@ static const char *s_ControllerMappings [] =
"030000006f0e00001304000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,",
"030000006f0e00001f01000000010000,Generic X-Box pad,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
+ "030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,",
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,",
"03000000790000001100000010010000,RetroLink Saturn Classic Controller,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,",
@@ -486,11 +499,14 @@ static const char *s_ControllerMappings [] =
"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,",
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,",
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
+ "03000000c9110000f055000011010000,HJC Game GAMEPAD,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b4,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
+ "03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,",
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,",
- "05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
- "05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
+ "05000000362800000100000002010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
+ "05000000362800000100000003010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
+ "05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"050000004c050000c405000000010000,PS4 Controller (Bluetooth),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,",
@@ -500,7 +516,12 @@ static const char *s_ControllerMappings [] =
#if defined(__ANDROID__)
"Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,",
+ "47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,",
+ "484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,",
+ "4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,",
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
+ "532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,",
+ "506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,",
#endif
#ifdef JAVASCRIPT_ENABLED
@@ -902,7 +923,7 @@ String InputDefault::get_joy_guid(int p_device) const {
//platforms that use the remapping system can override and call to these ones
bool InputDefault::is_joy_mapped(int p_device) {
int mapping = joy_names[p_device].mapping;
- return mapping != -1 ? (mapping == fallback_mapping) : false;
+ return mapping != -1 ? (mapping != fallback_mapping) : false;
}
String InputDefault::get_joy_guid_remapped(int p_device) const {
diff --git a/main/main.cpp b/main/main.cpp
index 68c40a6f2b..8c0c31835f 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1011,6 +1011,7 @@ bool Main::start() {
bool noquit=false;
bool convert_old=false;
bool export_debug=false;
+ bool project_manager_request = false;
List<String> args = OS::get_singleton()->get_cmdline_args();
for (int i=0;i<args.size();i++) {
//parameters that do not have an argument to the right
@@ -1022,6 +1023,8 @@ bool Main::start() {
convert_old=true;
} else if (args[i]=="-editor" || args[i]=="-e") {
editor=true;
+ } else if (args[i] == "-pm" || args[i] == "-project_manager") {
+ project_manager_request = true;
} else if (args[i].length() && args[i][0] != '-' && game_path == "") {
game_path=args[i];
}
@@ -1255,7 +1258,7 @@ bool Main::start() {
}
- if (game_path!="") {
+ if (game_path!="" && !project_manager_request) {
String local_game_path=game_path.replace("\\","/");
@@ -1462,7 +1465,7 @@ bool Main::start() {
};
}
*/
- if (script=="" && test=="" && game_path=="" && !editor) {
+ if (project_manager_request || (script=="" && test=="" && game_path=="" && !editor)) {
ProjectManager *pmanager = memnew( ProjectManager );
sml->get_root()->add_child(pmanager);
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index b4e5c04c95..ff19518ad5 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -52,6 +52,7 @@ String GDScriptLanguage::get_template(const String& p_class_name, const String&
"# var a=2\n"+
"# var b=\"textvar\"\n\n"+
"func _ready():\n"+
+ "\t# Called every time the node is added to the scene.\n"+
"\t# Initialization here\n"+
"\tpass\n"+
"\n"+
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp
index 9b7d8eeac4..e5689d8865 100644
--- a/modules/gdscript/gd_functions.cpp
+++ b/modules/gdscript/gd_functions.cpp
@@ -32,6 +32,7 @@
#include "reference.h"
#include "gd_script.h"
#include "func_ref.h"
+#include "range_iterator.h"
#include "os/os.h"
#include "variant_parser.h"
#include "io/marshalls.h"
@@ -98,6 +99,7 @@ const char *GDFunctions::get_func_name(Function p_func) {
"var2bytes",
"bytes2var",
"range",
+ "xrange",
"load",
"inst2dict",
"dict2inst",
@@ -816,6 +818,81 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
}
} break;
+ case GEN_XRANGE: {
+
+ switch(p_arg_count) {
+ case 0: {
+ r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument=1;
+ } break;
+ case 1: {
+
+ VALIDATE_ARG_NUM(0);
+
+ int count=*p_args[0];
+
+ Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) );
+ if (!*itr) {
+ ERR_EXPLAIN("Couldn't allocate iterator!");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ ERR_FAIL();
+ }
+ (*itr)->set_range(count);
+ r_ret=Variant(itr);
+ return;
+ } break;
+ case 2: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+
+ int from=*p_args[0];
+ int to=*p_args[1];
+
+ Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) );
+ if (!*itr) {
+ ERR_EXPLAIN("Couldn't allocate iterator!");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ ERR_FAIL();
+ }
+ (*itr)->set_range(from, to);
+ r_ret=Variant(itr);
+ return;
+ } break;
+ case 3: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+
+ int from=*p_args[0];
+ int to=*p_args[1];
+ int incr=*p_args[2];
+
+ if (incr==0) {
+ ERR_EXPLAIN("step argument is zero!");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ ERR_FAIL();
+ }
+
+ Ref<RangeIterator> itr = Ref<RangeIterator>( memnew(RangeIterator) );
+ if (!*itr) {
+ ERR_EXPLAIN("Couldn't allocate iterator!");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ ERR_FAIL();
+ }
+ (*itr)->set_range(from, to, incr);
+ r_ret=Variant(itr);
+ return;
+ } break;
+ default: {
+
+ r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument=3;
+ } break;
+ }
+
+ } break;
case RESOURCE_LOAD: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type()!=Variant::STRING) {
@@ -1433,6 +1510,12 @@ MethodInfo GDFunctions::get_info(Function p_func) {
mi.return_val.type=Variant::ARRAY;
return mi;
} break;
+ case GEN_XRANGE: {
+
+ MethodInfo mi("xrange",PropertyInfo(Variant::NIL,"..."));
+ mi.return_val.type=Variant::OBJECT;
+ return mi;
+ } break;
case RESOURCE_LOAD: {
MethodInfo mi("load",PropertyInfo(Variant::STRING,"path"));
diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h
index 8c88472567..3a993cc038 100644
--- a/modules/gdscript/gd_functions.h
+++ b/modules/gdscript/gd_functions.h
@@ -92,6 +92,7 @@ public:
VAR_TO_BYTES,
BYTES_TO_VAR,
GEN_RANGE,
+ GEN_XRANGE,
RESOURCE_LOAD,
INST2DICT,
DICT2INST,
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index b6e8478846..4b0164d8a2 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -1779,6 +1779,20 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
return;
}
+ // Little optimisation for common usage "for i in range(...):":
+ // don't create and initialize a possibly huge array as range()
+ // would do, but instead create an iterator using xrange()
+ if (container->type == Node::TYPE_OPERATOR) {
+ OperatorNode *op = static_cast<OperatorNode *>(container);
+ if (op->arguments.size() > 0 &&
+ op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION) {
+ BuiltInFunctionNode *c = static_cast<BuiltInFunctionNode *>(op->arguments[0]);
+ if (c->function == GDFunctions::GEN_RANGE) {
+ c->function = GDFunctions::GEN_XRANGE;
+ }
+ }
+ }
+
ControlFlowNode *cf_for = alloc_node<ControlFlowNode>();
cf_for->cf_type=ControlFlowNode::CF_FOR;
@@ -1790,7 +1804,7 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
p_block->sub_blocks.push_back(cf_for->body);
if (!_enter_indent_block(cf_for->body)) {
- _set_error("Expected indented block after 'while'");
+ _set_error("Expected indented block after 'for'");
p_block->end_line=tokenizer->get_token_line();
return;
}
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 1b2ed670ad..c1ee148ef3 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -1481,6 +1481,11 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError&
/* STEP 1, CREATE */
+ if (!valid) {
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+
r_error.error=Variant::CallError::CALL_OK;
REF ref;
Object *owner=NULL;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index d4755f4ed6..6fc78e3264 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1493,6 +1493,16 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) {
OS::get_singleton()->delay_usec(3000000);
}
+ if (EditorSettings::get_singleton()->get("android/shutdown_adb_on_exit")) {
+ String adb=EditorSettings::get_singleton()->get("android/adb");
+ if (!FileAccess::exists(adb)) {
+ return; //adb not configured
+ }
+
+ List<String> args;
+ args.push_back("kill-server");
+ OS::get_singleton()->execute(adb,args,true);
+ };
}
Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp
index d7bde9a727..1c0584523a 100644
--- a/platform/haiku/key_mapping_haiku.cpp
+++ b/platform/haiku/key_mapping_haiku.cpp
@@ -160,7 +160,7 @@ unsigned int KeyMappingHaiku::get_keysym(int32 raw_char, int32 key) {
if (raw_char == B_UP_ARROW && key == 0x38) { return KEY_KP_8; }
if (raw_char == B_PAGE_UP && key == 0x39) { return KEY_KP_9; }
if (raw_char == 0x2F && key == 0x23) { return KEY_KP_DIVIDE; }
- if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBSTRACT; }
+ if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBTRACT; }
if (raw_char == B_DELETE && key == 0x65) { return KEY_KP_PERIOD; }
if (raw_char == 0x10) {
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 88361e87e4..94fbb9e174 100755
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -58,6 +58,7 @@ void _show_keyboard(String);
void _hide_keyboard();
bool _play_video(String, float, String, String);
bool _is_video_playing();
+void _pause_video();
void _focus_out_video();
void _unpause_video();
void _stop_video();
@@ -74,64 +75,30 @@ void _hide_keyboard() {
keyboard_text = "";
};
-/*
-bool _play_video(String p_path, float p_volume) {
-
- float player_volume = p_volume * AudioServer::get_singleton()->get_singleton()->get_stream_global_volume_scale();
- video_previous_volume = [[MPMusicPlayerController applicationMusicPlayer] volume];
-
- //[[MPMusicPlayerController applicationMusicPlayer] setVolume: player_volume];
-
- p_path = Globals::get_singleton()->globalize_path(p_path);
-
- NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
- NSURL *file_url = [NSURL fileURLWithPath:file_path];
-
- _instance.moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:file_url];
- _instance.moviePlayerController.controlStyle = MPMovieControlStyleNone;
- [_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFit];
- //[_instance.moviePlayerController setScalingMode:MPMovieScalingModeAspectFill];
-
- [[NSNotificationCenter defaultCenter] addObserver:_instance
- selector:@selector(moviePlayBackDidFinish:)
- name:MPMoviePlayerPlaybackDidFinishNotification
- object:_instance.moviePlayerController];
-
- [_instance.moviePlayerController.view setFrame:_instance.bounds];
- _instance.moviePlayerController.view.userInteractionEnabled = NO;
- [_instance addSubview:_instance.moviePlayerController.view];
- [_instance.moviePlayerController play];
-
- video_playing = true;
-
- return true;
-}
-*/
-
bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
p_path = Globals::get_singleton()->globalize_path(p_path);
NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
- //NSURL *file_url = [NSURL fileURLWithPath:file_path];
_instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]];
+
_instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset];
[_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
- _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
+ _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
+ _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
- [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- [[NSNotificationCenter defaultCenter] addObserver:_instance
+ [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:_instance
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_instance.avPlayer currentItem]];
[_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0];
- [_instance.avPlayerLayer setFrame:_instance.bounds];
- [_instance.layer addSublayer:_instance.avPlayerLayer];
- [_instance.avPlayer play];
+ [_instance.avPlayerLayer setFrame:_instance.bounds];
+ [_instance.layer addSublayer:_instance.avPlayerLayer];
+ [_instance.avPlayer play];
AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible];
@@ -173,23 +140,19 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
}
}
- video_playing = true;
+ video_playing = true;
return true;
}
bool _is_video_playing() {
- //NSInteger playback_state = _instance.moviePlayerController.playbackState;
- //return video_playing || _instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying;
- //if (video_found_error)
- // return false;
- //return (_instance.moviePlayerController.playbackState == MPMoviePlaybackStatePlaying);
-
- return video_playing || (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error);
+ if (_instance.avPlayer.error) {
+ printf("Error during playback\n");
+ }
+ return (_instance.avPlayer.rate > 0 && !_instance.avPlayer.error);
}
void _pause_video() {
- //[_instance.moviePlayerController pause];
video_current_time = _instance.avPlayer.currentTime;
[_instance.avPlayer pause];
video_playing = false;
@@ -204,15 +167,9 @@ void _unpause_video() {
[_instance.avPlayer play];
video_playing = true;
-
- //video_current_time = kCMTimeZero;
};
void _stop_video() {
- //[_instance.moviePlayerController stop];
- //[_instance.moviePlayerController.view removeFromSuperview];
- //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
-
[_instance.avPlayer pause];
[_instance.avPlayerLayer removeFromSuperlayer];
_instance.avPlayer = nil;
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index ec62cb5c26..9f6b8433aa 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -41,6 +41,7 @@
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
+#include "core/io/file_access_pack.h"
#include "core/globals.h"
#include "sem_iphone.h"
@@ -517,12 +518,25 @@ extern void _focus_out_video();
Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
FileAccess* f = FileAccess::open(p_path, FileAccess::READ);
bool exists = f && f->is_open();
- printf("file exists for %ls, %i, %p\n", p_path.c_str(), (int)exists, f);
- if (f)
- memdelete(f);
+
+ String tempFile = get_data_dir();
if (!exists)
return FAILED;
- if ( _play_video(p_path, p_volume, p_audio_track, p_subtitle_track) )
+
+ if (p_path.begins_with("res://")) {
+ if (PackedData::get_singleton()->has_path(p_path)) {
+ print("Unable to play %S using the native player as it resides in a .pck file\n", p_path.c_str());
+ return ERR_INVALID_PARAMETER;
+ } else {
+ p_path = p_path.replace("res:/", Globals::get_singleton()->get_resource_path());
+ }
+ } else if (p_path.begins_with("user://"))
+ p_path = p_path.replace("user:/", get_data_dir());
+
+ memdelete(f);
+
+ print("Playing video: %S\n", p_path.c_str());
+ if (_play_video(p_path, p_volume, p_audio_track, p_subtitle_track) )
return OK;
return FAILED;
}
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index abe797fed1..d34e8bfe95 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -195,12 +195,12 @@ public:
void set_unique_ID(String p_ID);
String get_unique_ID() const;
- virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
- virtual bool native_video_is_playing() const;
- virtual void native_video_pause();
+ virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
+ virtual bool native_video_is_playing() const;
+ virtual void native_video_pause();
virtual void native_video_unpause();
virtual void native_video_focus_out();
- virtual void native_video_stop();
+ virtual void native_video_stop();
OSIPhone(int width, int height);
~OSIPhone();
diff --git a/platform/iphone/xcode/godot_xcode/data.pck b/platform/iphone/xcode/godot_xcode/data.pck
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/data.pck
diff --git a/platform/iphone/xcode/godot_xcode/godot_debug.iphone b/platform/iphone/xcode/godot_xcode/godot_debug.iphone
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_debug.iphone
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..bdba8488c8
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.pbxproj
@@ -0,0 +1,370 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */; };
+ D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4341C5D573600B7FB28 /* Default-667h.png */; };
+ D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */; };
+ D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4361C5D573600B7FB28 /* Default-736h.png */; };
+ D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */; };
+ D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */; };
+ D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */; };
+ D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */; };
+ D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */; };
+ D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */; };
+ D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */; };
+ D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D07CD43E1C5D573600B7FB28 /* Default~iphone.png */; };
+ D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; };
+ D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */; };
+ D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */; };
+ D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */; };
+ D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */; };
+ D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */; };
+ D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; };
+ D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* data.pck */; };
+ D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; };
+ D07CD4341C5D573600B7FB28 /* Default-667h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h.png"; sourceTree = "<group>"; };
+ D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-667h@2x.png"; sourceTree = "<group>"; };
+ D07CD4361C5D573600B7FB28 /* Default-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h.png"; sourceTree = "<group>"; };
+ D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-736h@3x.png"; sourceTree = "<group>"; };
+ D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape-736h.png"; sourceTree = "<group>"; };
+ D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = "<group>"; };
+ D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
+ D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; };
+ D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
+ D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = "<group>"; };
+ D07CD43E1C5D573600B7FB28 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = "<group>"; };
+ D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+ D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = godot_ios.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; };
+ D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "godot_ios-Info.plist"; sourceTree = "<group>"; };
+ D0BCFE4518AEBDA2004A7AAE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "godot_ios-Prefix.pch"; sourceTree = "<group>"; };
+ D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
+ D0BCFE7718AEBFEB004A7AAE /* data.pck */ = {isa = PBXFileReference; lastKnownFileType = text; path = data.pck; sourceTree = "<group>"; };
+ D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = godot_opt.iphone; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D0BCFE3118AEBDA2004A7AAE /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D0BCFE4018AEBDA2004A7AAE /* OpenGLES.framework in Frameworks */,
+ D0BCFE3A18AEBDA2004A7AAE /* CoreGraphics.framework in Frameworks */,
+ D0BCFE3C18AEBDA2004A7AAE /* UIKit.framework in Frameworks */,
+ D0BCFE3E18AEBDA2004A7AAE /* GLKit.framework in Frameworks */,
+ D0BCFE3818AEBDA2004A7AAE /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D0BCFE2B18AEBDA2004A7AAE = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE7918AEC06A004A7AAE /* godot_opt.iphone */,
+ D0BCFE7718AEBFEB004A7AAE /* data.pck */,
+ D0BCFE4118AEBDA2004A7AAE /* godot_ios */,
+ D0BCFE3618AEBDA2004A7AAE /* Frameworks */,
+ D0BCFE3518AEBDA2004A7AAE /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ D0BCFE3518AEBDA2004A7AAE /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE3718AEBDA2004A7AAE /* Foundation.framework */,
+ D0BCFE3918AEBDA2004A7AAE /* CoreGraphics.framework */,
+ D0BCFE3B18AEBDA2004A7AAE /* UIKit.framework */,
+ D0BCFE3D18AEBDA2004A7AAE /* GLKit.framework */,
+ D0BCFE3F18AEBDA2004A7AAE /* OpenGLES.framework */,
+ D0BCFE6118AEBDA3004A7AAE /* XCTest.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ D0BCFE4118AEBDA2004A7AAE /* godot_ios */ = {
+ isa = PBXGroup;
+ children = (
+ D07CD4331C5D573600B7FB28 /* Default-568h@2x~iphone.png */,
+ D07CD4341C5D573600B7FB28 /* Default-667h.png */,
+ D07CD4351C5D573600B7FB28 /* Default-667h@2x.png */,
+ D07CD4361C5D573600B7FB28 /* Default-736h.png */,
+ D07CD4371C5D573600B7FB28 /* Default-736h@3x.png */,
+ D07CD4381C5D573600B7FB28 /* Default-Landscape-736h.png */,
+ D07CD4391C5D573600B7FB28 /* Default-Landscape@2x~ipad.png */,
+ D07CD43A1C5D573600B7FB28 /* Default-Landscape~ipad.png */,
+ D07CD43B1C5D573600B7FB28 /* Default-Portrait@2x~ipad.png */,
+ D07CD43C1C5D573600B7FB28 /* Default-Portrait~ipad.png */,
+ D07CD43D1C5D573600B7FB28 /* Default@2x~iphone.png */,
+ D07CD43E1C5D573600B7FB28 /* Default~iphone.png */,
+ D07CD44D1C5D589C00B7FB28 /* Images.xcassets */,
+ D0BCFE4218AEBDA2004A7AAE /* Supporting Files */,
+ );
+ path = godot_ios;
+ sourceTree = "<group>";
+ };
+ D0BCFE4218AEBDA2004A7AAE /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ D0BCFE4318AEBDA2004A7AAE /* godot_ios-Info.plist */,
+ D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */,
+ D0BCFE4918AEBDA2004A7AAE /* godot_ios-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ D0BCFE3318AEBDA2004A7AAE /* godot_ios */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */;
+ buildPhases = (
+ D0BCFE3018AEBDA2004A7AAE /* Sources */,
+ D0BCFE3118AEBDA2004A7AAE /* Frameworks */,
+ D0BCFE3218AEBDA2004A7AAE /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = godot_ios;
+ productName = godot_ios;
+ productReference = D0BCFE3418AEBDA2004A7AAE /* godot_ios.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D0BCFE2C18AEBDA2004A7AAE /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0500;
+ ORGANIZATIONNAME = GodotEngine;
+ };
+ buildConfigurationList = D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = D0BCFE2B18AEBDA2004A7AAE;
+ productRefGroup = D0BCFE3518AEBDA2004A7AAE /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D0BCFE3318AEBDA2004A7AAE /* godot_ios */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D0BCFE3218AEBDA2004A7AAE /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D07CD4471C5D573600B7FB28 /* Default-Portrait@2x~ipad.png in Resources */,
+ D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */,
+ D0BCFE7818AEBFEB004A7AAE /* data.pck in Resources */,
+ D07CD4461C5D573600B7FB28 /* Default-Landscape~ipad.png in Resources */,
+ D07CD4411C5D573600B7FB28 /* Default-667h@2x.png in Resources */,
+ D07CD4401C5D573600B7FB28 /* Default-667h.png in Resources */,
+ D07CD4431C5D573600B7FB28 /* Default-736h@3x.png in Resources */,
+ D07CD43F1C5D573600B7FB28 /* Default-568h@2x~iphone.png in Resources */,
+ D07CD4451C5D573600B7FB28 /* Default-Landscape@2x~ipad.png in Resources */,
+ D07CD44A1C5D573600B7FB28 /* Default~iphone.png in Resources */,
+ D07CD4491C5D573600B7FB28 /* Default@2x~iphone.png in Resources */,
+ D07CD4441C5D573600B7FB28 /* Default-Landscape-736h.png in Resources */,
+ D07CD4421C5D573600B7FB28 /* Default-736h.png in Resources */,
+ D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */,
+ D0BCFE7A18AEC06A004A7AAE /* godot_opt.iphone in Resources */,
+ D07CD4481C5D573600B7FB28 /* Default-Portrait~ipad.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D0BCFE3018AEBDA2004A7AAE /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ D0BCFE4518AEBDA2004A7AAE /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ D0BCFE6F18AEBDA3004A7AAE /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ D0BCFE7018AEBDA3004A7AAE /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ D0BCFE7218AEBDA3004A7AAE /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD)";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch";
+ INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 armv7s";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ D0BCFE7318AEBDA3004A7AAE /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD)";
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Distribution: Ariel Manzur (BYC57PA2Q5)";
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "godot_ios/godot_ios-Prefix.pch";
+ INFOPLIST_FILE = "godot_ios/godot_ios-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ PRODUCT_BUNDLE_IDENTIFIER = org.godotengine.game.ios;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALID_ARCHS = "armv7 armv7s";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "godot_ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D0BCFE6F18AEBDA3004A7AAE /* Debug */,
+ D0BCFE7018AEBDA3004A7AAE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "godot_ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D0BCFE7218AEBDA3004A7AAE /* Debug */,
+ D0BCFE7318AEBDA3004A7AAE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = D0BCFE2C18AEBDA2004A7AAE /* Project object */;
+}
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..3c9ba38bbe
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:godot_ios.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png
new file mode 100644
index 0000000000..1341174454
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-568h@2x~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png
new file mode 100644
index 0000000000..c480d2e3c0
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png
new file mode 100644
index 0000000000..3cc1dfa290
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-667h@2x.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png
new file mode 100644
index 0000000000..813d689162
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png
new file mode 100644
index 0000000000..7707005e76
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-736h@3x.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png
new file mode 100644
index 0000000000..b02873323e
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape-736h.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png
new file mode 100644
index 0000000000..d86c4a2510
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape@2x~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png
new file mode 100644
index 0000000000..e4f6cef02b
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Landscape~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png
new file mode 100644
index 0000000000..f306652a31
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait@2x~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png
new file mode 100644
index 0000000000..71a16db6df
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default-Portrait~ipad.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png
new file mode 100644
index 0000000000..5305cb9bdb
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default@2x~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png
new file mode 100644
index 0000000000..91c62d1e43
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Default~iphone.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..a458b67873
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,128 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "1x",
+ "filename": "Icon-29.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x",
+ "filename": "Icon-58.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x",
+ "filename": "icon-87.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x",
+ "filename": "Icon-80.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x",
+ "filename": "Icon-120.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "1x",
+ "filename": "Icon-57.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "57x57",
+ "scale" : "2x",
+ "filename": "Icon-114.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x",
+ "filename": "Icon-120.png",
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x",
+ "filename": "Icon-180.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x",
+ "filename": "Icon-29.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x",
+ "filename": "Icon-58.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x",
+ "filename": "Icon-40.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x",
+ "filename": "Icon-80.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "1x",
+ "filename": "Icon-50.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "50x50",
+ "scale" : "2x",
+ "filename": "Icon-100.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "1x",
+ "filename": "Icon-72.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "72x72",
+ "scale" : "2x",
+ "filename": "Icon-144.png",
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-76.png",
+ "scale" : "1x",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x",
+ "filename": "Icon-152.png",
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x",
+ "filename": "icon-167.png",
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png
new file mode 100644
index 0000000000..f9dca1ab57
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-100.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png
new file mode 100644
index 0000000000..e7f9bd7388
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-114.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png
new file mode 100644
index 0000000000..4faa0f28e2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-120.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png
new file mode 100644
index 0000000000..1c4cb51d56
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-144.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png
new file mode 100644
index 0000000000..e99b11c519
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-152.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png
new file mode 100644
index 0000000000..3edbcadfc5
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-180.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png
new file mode 100644
index 0000000000..0ae5893203
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-29.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png
new file mode 100644
index 0000000000..bb4ffa70ad
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-40.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png
new file mode 100644
index 0000000000..7a4b7107e7
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-50.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png
new file mode 100644
index 0000000000..b00bd79091
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-57.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png
new file mode 100644
index 0000000000..46335efdf6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-58.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png
new file mode 100644
index 0000000000..2c9c2b61dc
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-60.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png
new file mode 100644
index 0000000000..d711958ef1
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-72.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png
new file mode 100644
index 0000000000..464e7e7289
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-76.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png
new file mode 100644
index 0000000000..1151bc6b4b
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/Icon-80.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png
new file mode 100644
index 0000000000..487c8326be
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-167.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png
new file mode 100644
index 0000000000..e54cee23a6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/icon-87.png
Binary files differ
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes
new file mode 100644
index 0000000000..e328a62cb6
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/Images.xcassets/AppIcon.appiconset/sizes
@@ -0,0 +1,17 @@
+100
+114
+120
+144
+152
+167
+180
+29
+40
+50
+57
+58
+60
+72
+76
+80
+87
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000000..477b28ff8f
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist
new file mode 100644
index 0000000000..f97b0fca36
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/godot_ios-Info.plist
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>Insert Name Here</string>
+ <key>CFBundleExecutable</key>
+ <string>godot_opt.iphone</string>
+ <key>CFBundleIcons</key>
+ <dict/>
+ <key>CFBundleIcons~ipad</key>
+ <dict/>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UIRequiresFullScreen</key>
+ <true/>
+ <key>UIStatusBarHidden</key>
+ <true/>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/platform/iphone/xcode/godot_xcode/godot_ios/main.m b/platform/iphone/xcode/godot_xcode/godot_ios/main.m
new file mode 100644
index 0000000000..3e4ea5e129
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_ios/main.m
@@ -0,0 +1,39 @@
+/*************************************************************************/
+/* main.m */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/platform/iphone/xcode/godot_xcode/godot_opt.iphone b/platform/iphone/xcode/godot_xcode/godot_opt.iphone
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/platform/iphone/xcode/godot_xcode/godot_opt.iphone
diff --git a/platform/nacl/nacl_keycodes.h b/platform/nacl/nacl_keycodes.h
index 45dba075db..a0642fc3b7 100644
--- a/platform/nacl/nacl_keycodes.h
+++ b/platform/nacl/nacl_keycodes.h
@@ -286,7 +286,7 @@ static uint32_t godot_key(uint32_t p_key, bool& is_char) {
case VKEY_MULTIPLY: return KEY_KP_MULTIPLY;
case VKEY_ADD: return KEY_KP_ADD;
// case VKEY_SEPARATOR: return KEY_SEPARATOR;
- case VKEY_SUBTRACT: return KEY_KP_SUBSTRACT;
+ case VKEY_SUBTRACT: return KEY_KP_SUBTRACT;
case VKEY_DECIMAL: return KEY_KP_PERIOD;
case VKEY_DIVIDE: return KEY_KP_DIVIDE;
case VKEY_F1: return KEY_F1;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index d808fb67a2..bb99e6ade7 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -650,7 +650,7 @@ static int translateKey(unsigned int key)
/* 4b */ KEY_KP_DIVIDE,
/* 4c */ KEY_KP_ENTER,
/* 4d */ KEY_UNKNOWN,
- /* 4e */ KEY_KP_SUBSTRACT,
+ /* 4e */ KEY_KP_SUBTRACT,
/* 4f */ KEY_UNKNOWN,
/* 50 */ KEY_UNKNOWN,
/* 51 */ KEY_EQUAL, //wtf equal?
diff --git a/platform/server/detect.py b/platform/server/detect.py
index e2d64c6545..15c5982b14 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -28,7 +28,6 @@ def get_flags():
return [
('builtin_zlib', 'no'),
- ('theora','no'), #use builtin openssl
]
diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp
index 07d5f32253..23fa29d68f 100644
--- a/platform/windows/key_mapping_win.cpp
+++ b/platform/windows/key_mapping_win.cpp
@@ -145,7 +145,7 @@ static _WinTranslatePair _vk_to_keycode[]={
{ KEY_KP_MULTIPLY,VK_MULTIPLY},// (0x6A)
{ KEY_KP_ADD,VK_ADD},// (0x6B)
//VK_SEPARATOR (0x6C)
-{ KEY_KP_SUBSTRACT,VK_SUBTRACT},// (0x6D)
+{ KEY_KP_SUBTRACT,VK_SUBTRACT},// (0x6D)
{ KEY_KP_PERIOD,VK_DECIMAL},// (0x6E)
{ KEY_KP_DIVIDE,VK_DIVIDE},// (0x6F)
{ KEY_F1,VK_F1},// (0x70)
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index f49475a2d5..6b147db130 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -56,7 +56,7 @@ def get_opts():
('use_sanitizer','Use llvm compiler sanitize address','no'),
('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'),
('pulseaudio','Detect & Use pulseaudio','yes'),
- ('gamepad','Gamepad support, requires libudev and libevdev','yes'),
+ ('udev','Use udev for gamepad connection callbacks','no'),
('new_wm_api', 'Use experimental window management API','no'),
('debug_release', 'Add debug symbols to release version','no'),
]
@@ -156,20 +156,18 @@ def configure(env):
else:
print("ALSA libraries not found, disabling driver")
- if (env["gamepad"]=="yes" and platform.system() == "Linux"):
+ if (platform.system() == "Linux"):
+ env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+ if (env["udev"]=="yes"):
# pkg-config returns 0 when the lib exists...
found_udev = not os.system("pkg-config --exists libudev")
-
+
if (found_udev):
- print("Enabling gamepad support with udev")
- env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+ print("Enabling udev support")
+ env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
env.ParseConfig('pkg-config libudev --cflags --libs')
else:
- print("libudev development libraries not found")
-
- print("Some libraries are missing for the required gamepad support, aborting!")
- print("Install the mentioned libraries or build with 'gamepad=no' to disable gamepad support.")
- sys.exit(255)
+ print("libudev development libraries not found, disabling udev support")
if (env["pulseaudio"]=="yes"):
if not os.system("pkg-config --exists libpulse-simple"):
diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp
index ef866d5d3a..9a52c4ff36 100644
--- a/platform/x11/joystick_linux.cpp
+++ b/platform/x11/joystick_linux.cpp
@@ -33,11 +33,14 @@
#include "joystick_linux.h"
#include <linux/input.h>
-#include <libudev.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#ifdef UDEV_ENABLED
+#include <libudev.h>
+#endif
+
#define LONG_BITS (sizeof(long) * 8)
#define test_bit(nr, addr) (((1UL << ((nr) % LONG_BITS)) & ((addr)[(nr) / LONG_BITS])) != 0)
#define NBITS(x) ((((x)-1)/LONG_BITS)+1)
@@ -99,14 +102,18 @@ void joystick_linux::joy_thread_func(void *p_user) {
}
void joystick_linux::run_joystick_thread() {
-
+#ifdef UDEV_ENABLED
udev *_udev = udev_new();
ERR_FAIL_COND(!_udev);
enumerate_joysticks(_udev);
monitor_joysticks(_udev);
udev_unref(_udev);
+#else
+ monitor_joysticks();
+#endif
}
+#ifdef UDEV_ENABLED
void joystick_linux::enumerate_joysticks(udev *p_udev) {
udev_enumerate *enumerate;
@@ -192,6 +199,23 @@ void joystick_linux::monitor_joysticks(udev *p_udev) {
//printf("exit udev\n");
udev_monitor_unref(mon);
}
+#endif
+
+void joystick_linux::monitor_joysticks() {
+
+ while (!exit_udev) {
+ joy_mutex->lock();
+ for (int i = 0; i < 32; i++) {
+ char fname[64];
+ sprintf(fname, "/dev/input/event%d", i);
+ if (attached_devices.find(fname) == -1) {
+ open_joystick(fname);
+ }
+ }
+ joy_mutex->unlock();
+ usleep(1000000); // 1s
+ }
+}
int joystick_linux::get_free_joy_slot() const {
@@ -229,6 +253,7 @@ void joystick_linux::close_joystick(int p_id) {
close(joy.fd);
joy.fd = -1;
+ attached_devices.remove(attached_devices.find(joy.devpath));
input->joy_connection_changed(p_id, false, "");
};
};
@@ -302,6 +327,9 @@ void joystick_linux::open_joystick(const char *p_path) {
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
+ // add to attached devices so we don't try to open it again
+ attached_devices.push_back(String(p_path));
+
if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
(ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
(ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) {
@@ -446,6 +474,9 @@ uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) {
p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]);
}
}
+ if (len == 0 || (len < 0 && errno != EAGAIN)) {
+ close_joystick(i);
+ };
}
joy_mutex->unlock();
return p_event_id;
diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h
index 7f96e3451f..4f0533721b 100644
--- a/platform/x11/joystick_linux.h
+++ b/platform/x11/joystick_linux.h
@@ -49,13 +49,11 @@ private:
JOYSTICKS_MAX = 16,
MAX_ABS = 63,
MAX_KEY = 767, // Hack because <linux/input.h> can't be included here
- BT_MISC = 256,
- HAT_MAX = 4,
};
struct Joystick {
InputDefault::JoyAxis curr_axis[MAX_ABS];
- int key_map[MAX_KEY - BT_MISC];
+ int key_map[MAX_KEY];
int abs_map[MAX_ABS];
int dpad;
int fd;
@@ -73,6 +71,7 @@ private:
Thread *joy_thread;
InputDefault *input;
Joystick joysticks[JOYSTICKS_MAX];
+ Vector<String> attached_devices;
static void joy_thread_func(void *p_user);
@@ -81,8 +80,11 @@ private:
void setup_joystick_properties(int p_id);
void close_joystick(int p_id = -1);
+#ifdef UDEV_ENABLED
void enumerate_joysticks(struct udev *_udev);
void monitor_joysticks(struct udev *_udev);
+#endif
+ void monitor_joysticks();
void run_joystick_thread();
void open_joystick(const char* path);
diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp
index 48f415a730..46f1483767 100644
--- a/platform/x11/key_mapping_x11.cpp
+++ b/platform/x11/key_mapping_x11.cpp
@@ -97,7 +97,7 @@ static _XTranslatePair _xkeysym_to_keycode[]={
{ XK_KP_Enter, KEY_KP_ENTER },
{ XK_KP_Multiply, KEY_KP_MULTIPLY},
{ XK_KP_Divide, KEY_KP_DIVIDE},
- { XK_KP_Subtract, KEY_KP_SUBSTRACT},
+ { XK_KP_Subtract, KEY_KP_SUBTRACT},
{ XK_KP_Add, KEY_KP_ADD},
{ XK_KP_0, KEY_KP_0},
{ XK_KP_1, KEY_KP_1},
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 4c00d8cec9..376aeb2d85 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -429,8 +429,8 @@ void NavigationPolygonInstance::_navpoly_changed() {
void NavigationPolygonInstance::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly"),&NavigationPolygonInstance::set_navigation_polygon);
- ObjectTypeDB::bind_method(_MD("get_navigation_polygon"),&NavigationPolygonInstance::get_navigation_polygon);
+ ObjectTypeDB::bind_method(_MD("set_navigation_polygon","navpoly:NavigationPolygon"),&NavigationPolygonInstance::set_navigation_polygon);
+ ObjectTypeDB::bind_method(_MD("get_navigation_polygon:NavigationPolygon"),&NavigationPolygonInstance::get_navigation_polygon);
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&NavigationPolygonInstance::set_enabled);
ObjectTypeDB::bind_method(_MD("is_enabled"),&NavigationPolygonInstance::is_enabled);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 5c298e96f6..1cd6399962 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -450,6 +450,7 @@ void TileMap::_update_dirty_quadrants() {
_fix_cell_transform(xform,c,shape_ofs+center_ofs,s);
if (debug_canvas_item) {
+ vs->canvas_item_add_set_transform(debug_canvas_item,xform);
shape->draw(debug_canvas_item,debug_collision_color);
}
@@ -459,6 +460,10 @@ void TileMap::_update_dirty_quadrants() {
}
}
+ if (debug_canvas_item) {
+ vs->canvas_item_add_set_transform(debug_canvas_item,Matrix32());
+ }
+
if (navigation) {
Ref<NavigationPolygon> navpoly = tile_set->tile_get_navigation_polygon(c.id);
if (navpoly.is_valid()) {
@@ -1205,6 +1210,7 @@ void TileMap::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_cellv","pos"),&TileMap::get_cellv);
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
+ ObjectTypeDB::bind_method(_MD("is_cell_transposed","x","y"),&TileMap::is_cell_transposed);
ObjectTypeDB::bind_method(_MD("clear"),&TileMap::clear);
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index dfd5c38266..47662bcccb 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -95,7 +95,7 @@ DVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const {
void Particles::set_amount(int p_amount) {
- ERR_FAIL_INDEX(p_amount,4096);
+ ERR_FAIL_INDEX(p_amount,1024);
amount=p_amount;
VisualServer::get_singleton()->particles_set_amount(particles,p_amount);
}
@@ -441,7 +441,7 @@ void Particles::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material" ), _SCS("set_material"), _SCS("get_material") );
- ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,4096,1" ), _SCS("set_amount"), _SCS("get_amount") );
+ ADD_PROPERTY( PropertyInfo( Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1024,1" ), _SCS("set_amount"), _SCS("get_amount") );
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "emitting" ), _SCS("set_emitting"), _SCS("is_emitting") );
ADD_PROPERTY( PropertyInfo( Variant::_AABB, "visibility" ), _SCS("set_visibility_aabb"), _SCS("get_visibility_aabb") );
ADD_PROPERTY( PropertyInfo( Variant::VECTOR3, "emission_extents" ), _SCS("set_emission_half_extents"), _SCS("get_emission_half_extents") );
diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp
index eabe84a8ee..f43c3c2a59 100644
--- a/scene/audio/event_player.cpp
+++ b/scene/audio/event_player.cpp
@@ -54,6 +54,8 @@ void EventPlayer::set_stream(const Ref<EventStream> &p_stream) {
stream=p_stream;
if (stream.is_valid())
playback=stream->instance_playback();
+ else
+ playback.unref();
if (playback.is_valid()) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 104806d891..550bae6306 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1803,6 +1803,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
+
if (gui.drag_data.get_type()==Variant::NIL && over && !gui.modal_stack.empty()) {
Control *top = gui.modal_stack.back()->get();
@@ -1836,7 +1837,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
- Matrix32 localizer = over->get_canvas_transform().affine_inverse();
+ Matrix32 localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(mpos);
Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x,p_event.mouse_motion.speed_y));
Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x,p_event.mouse_motion.relative_y));
@@ -1871,7 +1872,7 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
- pos = gui.focus_inv_xform.xform(pos);
+ //pos = gui.focus_inv_xform.xform(pos);
p_event.mouse_motion.x = pos.x;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 4c23ddbaf7..a9010e79a2 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1316,11 +1316,23 @@ StringName SceneState::get_node_name(int p_idx) const {
return names[nodes[p_idx].name];
}
+
+bool SceneState::is_node_instance_placeholder(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,nodes.size(),false);
+
+ return nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER;
+
+}
+
Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,nodes.size(),Ref<PackedScene>());
if (nodes[p_idx].instance>=0) {
- return variants[nodes[p_idx].instance];
+ if (nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER)
+ return Ref<PackedScene>();
+ else
+ return variants[nodes[p_idx].instance&FLAG_MASK];
} else if (nodes[p_idx].parent<0 || nodes[p_idx].parent==NO_PARENT_SAVED) {
if (base_scene_idx>=0) {
@@ -1334,6 +1346,19 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
}
+
+String SceneState::get_node_instance_placeholder(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,nodes.size(),String());
+
+ if (nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER) {
+ return variants[nodes[p_idx].instance&FLAG_MASK];
+ }
+
+ return String();
+
+}
+
Vector<StringName> SceneState::get_node_groups(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,nodes.size(),Vector<StringName>());
Vector<StringName> groups;
@@ -1577,6 +1602,8 @@ void SceneState::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_node_name","idx"),&SceneState::get_node_name);
ObjectTypeDB::bind_method(_MD("get_node_path","idx","for_parent"),&SceneState::get_node_path,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("get_node_owner_path","idx"),&SceneState::get_node_owner_path);
+ ObjectTypeDB::bind_method(_MD("is_node_instance_placeholder","idx"),&SceneState::is_node_instance_placeholder);
+ ObjectTypeDB::bind_method(_MD("get_node_instance_placeholder","idx"),&SceneState::get_node_instance_placeholder);
ObjectTypeDB::bind_method(_MD("get_node_instance:PackedScene","idx"),&SceneState::get_node_instance);
ObjectTypeDB::bind_method(_MD("get_node_groups","idx"),&SceneState::_get_node_groups);
ObjectTypeDB::bind_method(_MD("get_node_property_count","idx"),&SceneState::get_node_property_count);
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 7fda4392d8..6a26cc472c 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -48,11 +48,7 @@ class SceneState : public Reference {
int base_scene_idx;
enum {
- FLAG_ID_IS_PATH=(1<<30),
- FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
- FLAG_MASK=(1<<24)-1,
NO_PARENT_SAVED=0x7FFFFFFF,
-
};
struct NodeData {
@@ -115,7 +111,10 @@ protected:
public:
enum {
- TYPE_INSTANCED=0x7FFFFFFF
+ FLAG_ID_IS_PATH=(1<<30),
+ TYPE_INSTANCED=0x7FFFFFFF,
+ FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
+ FLAG_MASK=(1<<24)-1,
};
static void set_disable_placeholders(bool p_disable);
@@ -148,6 +147,8 @@ public:
NodePath get_node_path(int p_idx,bool p_for_parent=false) const;
NodePath get_node_owner_path(int p_idx) const;
Ref<PackedScene> get_node_instance(int p_idx) const;
+ String get_node_instance_placeholder(int p_idx) const;
+ bool is_node_instance_placeholder(int p_idx) const;
Vector<StringName> get_node_groups(int p_idx) const;
int get_node_property_count(int p_idx) const;
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index d9f6beabc0..6bd5f520d2 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -389,6 +389,22 @@ Error ResourceInteractiveLoaderText::poll() {
}
}
+ if (next_tag.fields.has("instance_placeholder")) {
+
+ String path=next_tag.fields["instance_placeholder"];
+
+ int path_v = packed_scene->get_state()->add_value(path);
+
+ if (packed_scene->get_state()->get_node_count()==0) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Instance Placeholder can't be used for inheritance.";
+ _printerr();
+ return error;
+ }
+
+ instance=path_v|SceneState::FLAG_INSTANCE_IS_PLACEHOLDER;
+ }
+
if (next_tag.fields.has("owner")) {
owner=packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
} else {
@@ -720,6 +736,7 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
fw->store_8(c);
c=f->get_8();
}
+ f->close();
bool all_ok = fw->get_error()==OK;
@@ -1124,7 +1141,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
if (packed_scene.is_valid()) {
//add instances to external resources if saving a packed scene
for(int i=0;i<packed_scene->get_state()->get_node_count();i++) {
- Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i);
+ if (packed_scene->get_state()->is_node_instance_placeholder(i))
+ continue;
+
+ Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i);
if (instance.is_valid() && !external_resources.has(instance)) {
int index = external_resources.size();
external_resources[instance]=index;
@@ -1268,8 +1288,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
NodePath path = state->get_node_path(i,true);
NodePath owner = state->get_node_owner_path(i);
Ref<PackedScene> instance = state->get_node_instance(i);
+ String instance_placeholder = state->get_node_instance_placeholder(i);
Vector<StringName> groups = state->get_node_groups(i);
+
if (instance.is_valid())
print_line("for path "+String(path)+" instance "+instance->get_path());
@@ -1298,6 +1320,14 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
f->store_string(header);
+ if (instance_placeholder!=String()) {
+
+ String vars;
+ f->store_string(" instance_placeholder=");
+ VariantWriter::write_to_string(instance_placeholder,vars,_write_resources,this);
+ f->store_string(vars);
+ }
+
if (instance.is_valid()) {
String vars;
diff --git a/tools/doc/doc_data.cpp b/tools/doc/doc_data.cpp
index 3836fa710b..2d0d7617c2 100644
--- a/tools/doc/doc_data.cpp
+++ b/tools/doc/doc_data.cpp
@@ -190,7 +190,11 @@ void DocData::generate(bool p_basic_types) {
#ifdef DEBUG_METHODS_ENABLED
if (m && m->get_return_type()!=StringName())
method.return_type=m->get_return_type();
- else if (arginfo.type!=Variant::NIL) // {
+ else if (method.name.find(":")!=-1) {
+ method.return_type=method.name.get_slice(":",1);
+ method.name=method.name.get_slice(":",0);
+
+ } else if (arginfo.type!=Variant::NIL) // {
#endif
method.return_type=(arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE)?arginfo.hint_string:Variant::get_type_name(arginfo.type);
// }
@@ -210,7 +214,7 @@ void DocData::generate(bool p_basic_types) {
} else if (arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE) {
type_name=arginfo.hint_string;
} else if (arginfo.type==Variant::NIL)
- type_name="var";
+ type_name="Variant";
else
type_name=Variant::get_type_name(arginfo.type);
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
new file mode 100644
index 0000000000..428de9d1a7
--- /dev/null
+++ b/tools/docker/Dockerfile
@@ -0,0 +1,13 @@
+FROM ubuntu:14.04
+MAINTAINER Mohammad Rezai, https://github.com/mrezai
+WORKDIR /godot-dev
+COPY scripts/install-android-tools /godot-dev/
+ENV DEBIAN_FRONTEND noninteractive
+RUN dpkg --add-architecture i386 && \
+ apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install --no-install-recommends -y -q \
+ build-essential gcc-multilib g++-multilib mingw32 mingw-w64 scons pkg-config libx11-dev libxcursor-dev \
+ libasound2-dev libfreetype6-dev libgl1-mesa-dev libglu-dev libssl-dev libxinerama-dev libudev-dev \
+ git wget openjdk-7-jdk libbcprov-java libc6:i386 libncurses5:i386 libstdc++6:i386 zlib1g:i386 lib32z1
+
diff --git a/tools/docker/README.md b/tools/docker/README.md
new file mode 100644
index 0000000000..7f10b46ad8
--- /dev/null
+++ b/tools/docker/README.md
@@ -0,0 +1,40 @@
+## A Docker image to build Linux, Windows and Android godot binaries.
+
+The main reason to write this, is to provide a simple way in all platforms to integrate external godot modules and build a custom version of godot.
+
+## usage
+1. Install docker on Linux or docker toolbox on Windows or Mac.
+2. Open a terminal on linux or "Docker Quickstart Terminal" on Windows or Mac.
+3. Run command:
+ - Linux: `cd`
+ - Windows: `cd /c/Users/YOUR_USERNAME`
+ - Mac: `cd /Users/YOUR_USERNAME`
+4. Get godot source code: `git clone https://github.com/godotengine/godot.git`
+5. Run command: `cd godot/tools/docker`
+6. Run command: `docker build -t godot .`(In Linux run Docker commands with `sudo` or add your user to docker group before run the Docker commands). The godot docker image will be build after a while.
+7. Run command:
+ - Linux: `docker run -it --name=godot-dev -v /home/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ - Windows: `docker run -it --name=godot-dev -v /c/Users/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ - Mac: `docker run -it --name=godot-dev -v /Users/YOUR_USERNAME/godot:/godot-dev/godot godot`
+ You are in the godot-dev container and /godot-dev directory now.
+8. Run `./install-android-tools` to download and install all android development tools.
+9. Run command: `source ~/.bashrc`
+10. Run command: `cd godot`
+11. Run command: `scons p=android target=release` to test everything is ok. You can set platform to x11, windows, android, haiku and server.
+
+After use and exit, you can use this environment again by open terminal and type commands: `docker start godot-dev && docker attach godot-dev`.
+
+### Windows and Mac stuffs:
+
+- Speed up compilation:
+ - Exit from container.
+ - Run command: `docker-machine stop`
+ - Open "Oracle VM VirtualBox".
+ - In settings of default VM increase CPU cores and RAM to suitable values.
+ - Run command: `docker-machine start`
+ - Run command: `docker start godot-dev && docker attach godot-dev`
+
+- ssh to VM(can be useful sometimes):
+ - `docker-machine ssh`
+
+Check docker and boot2docker projects for more details.
diff --git a/tools/docker/scripts/install-android-tools b/tools/docker/scripts/install-android-tools
new file mode 100644
index 0000000000..8a617d9942
--- /dev/null
+++ b/tools/docker/scripts/install-android-tools
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+BASH_RC=~/.bashrc
+GODOT_BUILD_TOOLS_PATH=/godot-dev/build-tools
+mkdir -p $GODOT_BUILD_TOOLS_PATH
+cd $GODOT_BUILD_TOOLS_PATH
+
+ANDROID_BASE_URL=http://dl.google.com/android
+
+ANDROID_SDK_RELEASE=android-sdk_r24.4.1
+ANDROID_SDK_DIR=android-sdk-linux
+ANDROID_SDK_FILENAME=$ANDROID_SDK_RELEASE-linux.tgz
+ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME
+ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR
+ANDROID_SDK_SHA1=725bb360f0f7d04eaccff5a2d57abdd49061326d
+
+ANDROID_NDK_RELEASE=android-ndk-r10e
+ANDROID_NDK_DIR=$ANDROID_NDK_RELEASE
+ANDROID_NDK_FILENAME=$ANDROID_NDK_RELEASE-linux-x86_64.bin
+ANDROID_NDK_URL=$ANDROID_BASE_URL/ndk/$ANDROID_NDK_FILENAME
+ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR
+ANDROID_NDK_MD5=19af543b068bdb7f27787c2bc69aba7f
+
+echo
+echo "Download and install Android development tools ..."
+echo
+
+if [ ! -e $ANDROID_SDK_FILENAME ]; then
+ echo "Downloading: Android SDK ..."
+ wget $ANDROID_SDK_URL
+else
+ echo $ANDROID_SDK_SHA1 $ANDROID_SDK_FILENAME > $ANDROID_SDK_FILENAME.sha1
+ sha1sum --check --strict $ANDROID_SDK_FILENAME.sha1
+ if [ ! $? -eq 0 ]; then
+ echo "Downloading: Android SDK ..."
+ wget $ANDROID_SDK_URL
+ fi
+fi
+
+if [ ! -d $ANDROID_SDK_DIR ]; then
+ tar -xvzf $ANDROID_SDK_FILENAME
+fi
+
+if [ ! -e $ANDROID_NDK_FILENAME ]; then
+ echo "Downloading: Android NDK ..."
+ wget $ANDROID_NDK_URL
+else
+ echo $ANDROID_NDK_MD5 $ANDROID_NDK_FILENAME > $ANDROID_NDK_FILENAME.md5
+ md5sum --check --strict $ANDROID_NDK_FILENAME.md5
+ if [ ! $? -eq 0 ]; then
+ echo "Downloading: Android NDK ..."
+ wget $ANDROID_NDK_URL
+ fi
+fi
+
+if [ ! -d $ANDROID_NDK_DIR ]; then
+ chmod a+x $ANDROID_NDK_FILENAME
+ ./$ANDROID_NDK_FILENAME
+ echo
+fi
+
+cd $ANDROID_SDK_DIR/tools
+chmod a+x android
+
+if ! ./android list target | grep -q 'android-19'; then
+ echo "Installing: Android Tools ..."
+ echo y | ./android update sdk --no-ui --all --filter "platform-tools,android-19,build-tools-19.1.0,\
+ extra-android-m2repository,extra-android-support,extra-google-google_play_services,extra-google-m2repository,\
+ extra-google-play_apk_expansion,extra-google-play_billing,extra-google-play_licensing"
+fi
+
+EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH"
+if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+
+EXPORT_VAL="export ANDROID_NDK_ROOT=$ANDROID_NDK_PATH"
+if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+EXPORT_VAL="export PATH=$PATH:$ANDROID_SDK_PATH/tools"
+if ! grep -q "^export PATH=.*$ANDROID_SDK_PATH/tools.*" $BASH_RC; then
+ echo $EXPORT_VAL >> ~/.bashrc
+fi
+
+echo
+echo "Done!"
+echo \ No newline at end of file
diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp
index 0f39d72308..23b8cad9ce 100644
--- a/tools/editor/create_dialog.cpp
+++ b/tools/editor/create_dialog.cpp
@@ -171,6 +171,7 @@ void CreateDialog::_update_search() {
if (EditorNode::get_editor_data().get_custom_types().has(type)) {
//there are custom types based on this... cool.
+ //print_line("there are custom types");
const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
@@ -259,7 +260,33 @@ Object *CreateDialog::instance_selected() {
TreeItem *selected = search_options->get_selected();
if (selected) {
- return ObjectTypeDB::instance(selected->get_text(0));
+ String custom = selected->get_metadata(0);
+ if (custom!=String()) {
+ if (EditorNode::get_editor_data().get_custom_types().has(custom)) {
+
+ for(int i=0;i<EditorNode::get_editor_data().get_custom_types()[custom].size();i++) {
+ if (EditorNode::get_editor_data().get_custom_types()[custom][i].name==selected->get_text(0)) {
+ Ref<Texture> icon = EditorNode::get_editor_data().get_custom_types()[custom][i].icon;
+ Ref<Script> script = EditorNode::get_editor_data().get_custom_types()[custom][i].script;
+ String name = selected->get_text(0);
+
+ Object *ob = ObjectTypeDB::instance(custom);
+ ERR_FAIL_COND_V(!ob,NULL);
+ if (ob->is_type("Node")) {
+ ob->call("set_name",name);
+ }
+ ob->set_script(script.get_ref_ptr());
+ if (icon.is_valid())
+ ob->set_meta("_editor_icon",icon);
+ return ob;
+
+ }
+ }
+
+ }
+ } else {
+ return ObjectTypeDB::instance(selected->get_text(0));
+ }
}
return NULL;
diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp
index c872b1c3ca..6c1fc2ef05 100644
--- a/tools/editor/editor_data.cpp
+++ b/tools/editor/editor_data.cpp
@@ -422,6 +422,14 @@ void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
editor_plugins.push_back(p_plugin);
}
+int EditorData::get_editor_plugin_count() const {
+ return editor_plugins.size();
+}
+EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
+
+ ERR_FAIL_INDEX_V(p_idx,editor_plugins.size(),NULL);
+ return editor_plugins[p_idx];
+}
void EditorData::add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ) {
@@ -791,6 +799,8 @@ void EditorSelection::_node_removed(Node *p_node) {
void EditorSelection::add_node(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+
if (selection.has(p_node))
return;
@@ -814,6 +824,8 @@ void EditorSelection::add_node(Node *p_node) {
void EditorSelection::remove_node(Node *p_node) {
+ ERR_FAIL_NULL(p_node);
+
if (!selection.has(p_node))
return;
@@ -832,12 +844,25 @@ bool EditorSelection::is_selected(Node * p_node) const {
}
+Array EditorSelection::_get_selected_nodes() {
+
+ Array ret;
+
+ for (List<Node*>::Element *E=selected_node_list.front();E;E=E->next()) {
+
+ ret.push_back(E->get());
+ }
+
+ return ret;
+}
void EditorSelection::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_node_removed"),&EditorSelection::_node_removed);
ObjectTypeDB::bind_method(_MD("clear"),&EditorSelection::clear);
- ObjectTypeDB::bind_method(_MD("add_node"),&EditorSelection::add_node);
+ ObjectTypeDB::bind_method(_MD("add_node","node:Node"),&EditorSelection::add_node);
+ ObjectTypeDB::bind_method(_MD("remove_node","node:Node"),&EditorSelection::remove_node);
+ ObjectTypeDB::bind_method(_MD("get_selected_nodes"),&EditorSelection::_get_selected_nodes);
ADD_SIGNAL( MethodInfo("selection_changed") );
}
diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h
index fcc8ccef06..5814ae8f5c 100644
--- a/tools/editor/editor_data.h
+++ b/tools/editor/editor_data.h
@@ -165,6 +165,9 @@ public:
void add_editor_plugin(EditorPlugin *p_plugin);
void remove_editor_plugin(EditorPlugin *p_plugin);
+ int get_editor_plugin_count() const;
+ EditorPlugin *get_editor_plugin(int p_idx);
+
UndoRedo &get_undo_redo();
void save_editor_global_states();
@@ -228,6 +231,7 @@ public:
List<Node*> selected_node_list;
void _update_nl();
+ Array _get_selected_nodes();
protected:
static void _bind_methods();
diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp
index 2ece518f8d..110e06f25b 100644
--- a/tools/editor/editor_help.cpp
+++ b/tools/editor/editor_help.cpp
@@ -1123,35 +1123,87 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->push_indent(1);*/
int pos = 0;
+ String bbcode=p_bbcode.replace("\t"," ").replace("\r"," ").strip_edges();
+
+ //find double newlines, keep them
+ for(int i=0;i<bbcode.length();i++) {
+
+ //find valid newlines (double)
+ if (bbcode[i]=='\n') {
+ bool dnl=false;
+ int j=i+1;
+ for(;j<p_bbcode.length();j++) {
+ if (bbcode[j]==' ')
+ continue;
+ if (bbcode[j]=='\n') {
+ dnl=true;
+ break;
+ }
+ break;
+ }
+
+ if (dnl) {
+ bbcode[i]=0xFFFF;
+ i=j;
+ } else {
+ bbcode[i]=' ';
+ i=j-1;
+ }
+ }
+ }
+
+ //remove double spaces or spaces after newlines
+ for(int i=0;i<bbcode.length();i++) {
+
+ if (bbcode[i]==' ' || bbcode[i]==0xFFFF) {
+
+ for(int j=i+1;j<p_bbcode.length();j++) {
+ if (bbcode[j]==' ') {
+ bbcode.remove(j);
+ j--;
+ continue;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ //change newlines to double newlines
+
+ CharType dnls[2]={0xFFFF,0};
+ bbcode=bbcode.replace(dnls,"\n");
+
+
List<String> tag_stack;
- while(pos < p_bbcode.length()) {
+ while(pos < bbcode.length()) {
- int brk_pos = p_bbcode.find("[",pos);
+ int brk_pos = bbcode.find("[",pos);
if (brk_pos<0)
- brk_pos=p_bbcode.length();
+ brk_pos=bbcode.length();
if (brk_pos > pos) {
- class_desc->add_text(p_bbcode.substr(pos,brk_pos-pos));
+ class_desc->add_text(bbcode.substr(pos,brk_pos-pos));
}
- if (brk_pos==p_bbcode.length())
+ if (brk_pos==bbcode.length())
break; //nothing else o add
- int brk_end = p_bbcode.find("]",brk_pos+1);
+ int brk_end = bbcode.find("]",brk_pos+1);
if (brk_end==-1) {
//no close, add the rest
- class_desc->add_text(p_bbcode.substr(brk_pos,p_bbcode.length()-brk_pos));
+ class_desc->add_text(bbcode.substr(brk_pos,bbcode.length()-brk_pos));
break;
}
- String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
+ String tag = bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
if (tag.begins_with("/")) {
@@ -1201,7 +1253,7 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->push_font(get_font("italic","Fonts"));
pos=brk_end+1;
tag_stack.push_front(tag);
- } else if (tag=="code") {
+ } else if (tag=="code" || tag=="codeblock") {
//use monospace font
class_desc->push_font(get_font("source","EditorFonts"));
@@ -1234,10 +1286,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="url") {
//use strikethrough (not supported underline instead)
- int end=p_bbcode.find("[",brk_end);
+ int end=bbcode.find("[",brk_end);
if (end==-1)
- end=p_bbcode.length();
- String url = p_bbcode.substr(brk_end+1,end-brk_end-1);
+ end=bbcode.length();
+ String url = bbcode.substr(brk_end+1,end-brk_end-1);
class_desc->push_meta(url);
pos=brk_end+1;
@@ -1251,10 +1303,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="img") {
//use strikethrough (not supported underline instead)
- int end=p_bbcode.find("[",brk_end);
+ int end=bbcode.find("[",brk_end);
if (end==-1)
- end=p_bbcode.length();
- String image = p_bbcode.substr(brk_end+1,end-brk_end-1);
+ end=bbcode.length();
+ String image = bbcode.substr(brk_end+1,end-brk_end-1);
Ref<Texture> texture = ResourceLoader::load(base_path+"/"+image,"Texture");
if (texture.is_valid())
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index b845eba66b..39182bfd69 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -63,13 +63,30 @@ String EditorImportPlugin::expand_source_path(const String& p_path) {
}
}
+
+String EditorImportPlugin::_validate_source_path(const String& p_path) {
+
+ return validate_source_path(p_path);
+}
+
+String EditorImportPlugin::_expand_source_path(const String& p_path) {
+
+ return expand_source_path(p_path);
+}
+
void EditorImportPlugin::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("validate_source_path","path"),&EditorImportPlugin::_validate_source_path);
+ ObjectTypeDB::bind_method(_MD("expand_source_path","path"),&EditorImportPlugin::_expand_source_path);
+
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_visible_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from")));
- ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetaData")));
- ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path")));
+ ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata")));
+ ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform")));
+
+// BIND_VMETHOD( mi );
}
String EditorImportPlugin::get_name() const {
@@ -113,8 +130,8 @@ Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportM
Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) {
- if (get_script_instance() && get_script_instance()->has_method("custom_export")) {
- get_script_instance()->call("custom_export",p_path);
+ if (get_script_instance() && get_script_instance()->has_method("_custom_export")) {
+ get_script_instance()->call("_custom_export",p_path,p_platform);
}
return Vector<uint8_t>();
@@ -130,7 +147,10 @@ EditorImportPlugin::EditorImportPlugin() {
void EditorExportPlugin::_bind_methods() {
- BIND_VMETHOD( MethodInfo("custom_export:Dictionary",PropertyInfo(Variant::STRING,"name",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatformPC")) );
+ MethodInfo mi = MethodInfo("custom_export:Variant",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"));
+ mi.return_val.type=Variant::RAW_ARRAY;
+
+ BIND_VMETHOD( mi );
}
@@ -141,6 +161,9 @@ Vector<uint8_t> EditorExportPlugin::custom_export(String& p_path,const Ref<Edito
Variant d = get_script_instance()->call("custom_export",p_path,p_platform);
if (d.get_type()==Variant::NIL)
return Vector<uint8_t>();
+ if (d.get_type()==Variant::RAW_ARRAY)
+ return d;
+
ERR_FAIL_COND_V(d.get_type()!=Variant::DICTIONARY,Vector<uint8_t>());
Dictionary dict=d;
ERR_FAIL_COND_V(!dict.has("name"),Vector<uint8_t>());
@@ -1455,9 +1478,17 @@ Ref<EditorImportPlugin> EditorImportExport::get_import_plugin_by_name(const Stri
void EditorImportExport::add_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
+ ERR_FAIL_COND( p_plugin.is_null() );
+
export_plugins.push_back(p_plugin);
}
+void EditorImportExport::remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
+
+ ERR_FAIL_COND( p_plugin.is_null() );
+ export_plugins.erase(p_plugin);
+}
+
int EditorImportExport::get_export_plugin_count() const{
return export_plugins.size();
@@ -2068,9 +2099,61 @@ bool EditorImportExport::sample_get_trim() const{
return sample_action_trim;
}
+DVector<String> EditorImportExport::_get_export_file_list() {
+
+ DVector<String> fl;
+ for (Map<StringName,FileAction>::Element *E=files.front();E;E=E->next()) {
+
+ fl.push_back(E->key());
+ }
+
+ return fl;
+}
+
+DVector<String> EditorImportExport::_get_export_platforms() {
+
+ DVector<String> ep;
+ for (Map<StringName,Ref<EditorExportPlatform> >::Element *E=exporters.front();E;E=E->next()) {
+
+ ep.push_back(E->key());
+ }
+
+ return ep;
+
+}
void EditorImportExport::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::add_import_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorImportExport::remove_import_plugin);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin_count"),&EditorImportExport::get_import_plugin_count);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin:EditorImportPlugin","idx"),&EditorImportExport::get_import_plugin);
+ ObjectTypeDB::bind_method(_MD("get_import_plugin_by_name:EditorImportPlugin","name"),&EditorImportExport::get_import_plugin_by_name);
+
+ ObjectTypeDB::bind_method(_MD("add_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::add_export_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorImportExport::remove_export_plugin);
+ ObjectTypeDB::bind_method(_MD("get_export_plugin_count"),&EditorImportExport::get_export_plugin_count);
+ ObjectTypeDB::bind_method(_MD("get_export_plugin:EditorExportPlugin","idx"),&EditorImportExport::get_export_plugin);
+
+ ObjectTypeDB::bind_method(_MD("set_export_file_action","file","action"),&EditorImportExport::set_export_file_action);
+ ObjectTypeDB::bind_method(_MD("get_export_file_action","file"),&EditorImportExport::get_export_file_action);
+ ObjectTypeDB::bind_method(_MD("get_export_file_list"),&EditorImportExport::_get_export_file_list);
+
+ ObjectTypeDB::bind_method(_MD("add_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform);
+ //ObjectTypeDB::bind_method(_MD("remove_export_platform","platform:EditorExportplatform"),&EditorImportExport::add_export_platform);
+ ObjectTypeDB::bind_method(_MD("get_export_platform:EditorExportPlatform","name"),&EditorImportExport::get_export_platform);
+ ObjectTypeDB::bind_method(_MD("get_export_platforms"),&EditorImportExport::_get_export_platforms);
+
+ ObjectTypeDB::bind_method(_MD("set_export_filter","filter"),&EditorImportExport::set_export_filter);
+ ObjectTypeDB::bind_method(_MD("get_export_filter"),&EditorImportExport::get_export_filter);
+
+ ObjectTypeDB::bind_method(_MD("set_export_custom_filter","filter"),&EditorImportExport::set_export_custom_filter);
+ ObjectTypeDB::bind_method(_MD("get_export_custom_filter"),&EditorImportExport::get_export_custom_filter);
+
+ ObjectTypeDB::bind_method(_MD("set_export_custom_filter_exclude","filter_exclude"),&EditorImportExport::set_export_custom_filter_exclude);
+ ObjectTypeDB::bind_method(_MD("get_export_custom_filter_exclude"),&EditorImportExport::get_export_custom_filter_exclude);
+
+
ObjectTypeDB::bind_method(_MD("image_export_group_create"),&EditorImportExport::image_export_group_create);
ObjectTypeDB::bind_method(_MD("image_export_group_remove"),&EditorImportExport::image_export_group_remove);
ObjectTypeDB::bind_method(_MD("image_export_group_set_image_action"),&EditorImportExport::image_export_group_set_image_action);
@@ -2085,7 +2168,27 @@ void EditorImportExport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("script_get_action"),&EditorImportExport::script_get_action);
ObjectTypeDB::bind_method(_MD("script_get_encryption_key"),&EditorImportExport::script_get_encryption_key);
-}
+
+
+ BIND_CONSTANT( ACTION_NONE );
+ BIND_CONSTANT( ACTION_COPY );
+ BIND_CONSTANT( ACTION_BUNDLE );
+
+ BIND_CONSTANT( EXPORT_SELECTED );
+ BIND_CONSTANT( EXPORT_RESOURCES );
+ BIND_CONSTANT( EXPORT_ALL );
+
+ BIND_CONSTANT( IMAGE_ACTION_NONE );
+ BIND_CONSTANT( IMAGE_ACTION_COMPRESS_DISK );
+ BIND_CONSTANT( IMAGE_ACTION_COMPRESS_RAM );
+ BIND_CONSTANT( IMAGE_ACTION_KEEP );
+
+ BIND_CONSTANT( SCRIPT_ACTION_NONE );
+ BIND_CONSTANT( SCRIPT_ACTION_COMPILE );
+ BIND_CONSTANT( SCRIPT_ACTION_ENCRYPT );
+};
+
+
EditorImportExport::EditorImportExport() {
diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h
index 60b7f919d8..fc8ad58bd9 100644
--- a/tools/editor/editor_import_export.h
+++ b/tools/editor/editor_import_export.h
@@ -46,6 +46,10 @@ protected:
static void _bind_methods();
+ String _validate_source_path(const String& p_path);
+ String _expand_source_path(const String& p_path);
+
+
public:
@@ -303,6 +307,9 @@ protected:
static EditorImportExport* singleton;
+ DVector<String> _get_export_file_list();
+ DVector<String> _get_export_platforms();
+
static void _bind_methods();
public:
@@ -315,6 +322,7 @@ public:
Ref<EditorImportPlugin> get_import_plugin_by_name(const String& p_string) const;
void add_export_plugin(const Ref<EditorExportPlugin>& p_plugin);
+ void remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin);
int get_export_plugin_count() const;
Ref<EditorExportPlugin> get_export_plugin(int p_idx) const;
@@ -391,7 +399,10 @@ public:
~EditorImportExport();
};
+VARIANT_ENUM_CAST(EditorImportExport::FileAction);
+VARIANT_ENUM_CAST(EditorImportExport::ExportFilter);
VARIANT_ENUM_CAST(EditorImportExport::ImageAction);
VARIANT_ENUM_CAST(EditorImportExport::ScriptAction);
+VARIANT_ENUM_CAST(EditorImportExport::SampleAction);
#endif // EDITOR_IMPORT_EXPORT_H
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index b39a1b5350..4666a49655 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -380,6 +380,10 @@ void EditorNode::_notification(int p_what) {
_menu_option_confirm(FILE_QUIT, false);
};
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ scene_tabs->set_tab_close_display_policy( (bool(EDITOR_DEF("global/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY) );
+ }
+
}
void EditorNode::_fs_changed() {
@@ -1795,6 +1799,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
//pause_button->set_pressed(false);
play_scene_button->set_pressed(false);
play_scene_button->set_icon(gui_base->get_icon("PlayScene","EditorIcons"));
+ play_custom_scene_button->set_pressed(false);
+ play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom","EditorIcons"));
String current_filename;
String run_filename;
@@ -1804,7 +1810,6 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
if (p_current || (editor_data.get_edited_scene_root() && p_custom==editor_data.get_edited_scene_root()->get_filename())) {
-
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
@@ -1913,6 +1918,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
if (p_current) {
play_scene_button->set_pressed(true);
play_scene_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
+ } else if (p_custom!="") {
+ run_custom_filename=run_filename;
+ play_custom_scene_button->set_pressed(true);
+ play_custom_scene_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
} else {
play_button->set_pressed(true);
play_button->set_icon(gui_base->get_icon("Reload","EditorIcons"));
@@ -2595,9 +2604,16 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY_CUSTOM_SCENE: {
- _menu_option_confirm(RUN_STOP,true);
- quick_run->popup("PackedScene",true);
- quick_run->set_title("Quick Run Scene..");
+ if (run_custom_filename.empty() || editor_run.get_status()==EditorRun::STATUS_STOP) {
+ _menu_option_confirm(RUN_STOP,true);
+ quick_run->popup("PackedScene",true);
+ quick_run->set_title("Quick Run Scene..");
+ play_custom_scene_button->set_pressed(false);
+ } else {
+ String last_custom_scene=run_custom_filename;
+ _menu_option_confirm(RUN_STOP,true);
+ _run(false,last_custom_scene);
+ }
} break;
case RUN_PAUSE: {
@@ -2611,10 +2627,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
editor_run.stop();
+ run_custom_filename.clear();
play_button->set_pressed(false);
play_button->set_icon(gui_base->get_icon("MainPlay","EditorIcons"));
play_scene_button->set_pressed(false);
play_scene_button->set_icon(gui_base->get_icon("PlayScene","EditorIcons"));
+ play_custom_scene_button->set_pressed(false);
+ play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom","EditorIcons"));
//pause_button->set_pressed(false);
emit_signal("stop_pressed");
@@ -2652,8 +2671,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
String exec = OS::get_singleton()->get_executable_path();
List<String> args;
- args.push_back ( "-path" );
- args.push_back (exec.get_base_dir() );
+ //args.push_back ( "-path" );
+ //args.push_back (exec.get_base_dir() );
+ args.push_back("-pm");
OS::ProcessID pid=0;
Error err = OS::get_singleton()->execute(exec,args,false,&pid);
@@ -2932,16 +2952,109 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
void EditorNode::add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+ ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->add_import_plugin(p_editor_import);
_rebuild_import_menu();
}
void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+ ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->remove_import_plugin(p_editor_import);
_rebuild_import_menu();
}
+
+void EditorNode::_update_addon_config() {
+
+ if (_initializing_addons)
+ return;
+
+ Vector<String> enabled_addons;
+
+ for(Map<String,EditorPlugin*>::Element *E=plugin_addons.front();E;E=E->next()) {
+ enabled_addons.push_back(E->key());
+ }
+
+ if (enabled_addons.size()==0) {
+ Globals::get_singleton()->set("editor_plugins/enabled",Variant());
+ Globals::get_singleton()->set_persisting("editor_plugins/enabled",false);
+ } else {
+ Globals::get_singleton()->set("editor_plugins/enabled",enabled_addons);
+ Globals::get_singleton()->set_persisting("editor_plugins/enabled",true);
+ }
+
+ project_settings->queue_save();
+
+}
+
+void EditorNode::set_addon_plugin_enabled(const String& p_addon,bool p_enabled) {
+
+ ERR_FAIL_COND(p_enabled && plugin_addons.has(p_addon));
+ ERR_FAIL_COND(!p_enabled && !plugin_addons.has(p_addon));
+
+ if (!p_enabled) {
+
+ EditorPlugin *addon = plugin_addons[p_addon];
+ memdelete(addon); //bye
+ plugin_addons.erase(p_addon);
+ _update_addon_config();
+ return;
+ }
+
+
+ Ref<ConfigFile> cf;
+ cf.instance();
+ String addon_path = "res://addons/"+p_addon+"/plugin.cfg";
+ Error err = cf->load(addon_path);
+ if (err!=OK) {
+ show_warning("Unable to enable addon plugin at: '"+addon_path+"' parsing of config failed.");
+ return;
+ }
+
+ if (!cf->has_section_key("plugin","script")) {
+ show_warning("Unable to find script field for addon plugin at: 'res://addons/"+p_addon+"''.");
+ return;
+ }
+
+ String path = cf->get_value("plugin","script");
+ path="res://addons/"+p_addon+"/"+path;
+
+ Ref<Script> script = ResourceLoader::load(path);
+
+
+ if (script.is_null()) {
+ show_warning("Unable to load addon script from path: '"+path+"'.");
+ return;
+ }
+
+ //could check inheritance..
+ if (String(script->get_instance_base_type())!="EditorPlugin") {
+ show_warning("Unable to load addon script from path: '"+path+"' Base type is not EditorPlugin.");
+ return;
+ }
+
+ if (!script->is_tool()) {
+ show_warning("Unable to load addon script from path: '"+path+"' Script is does not support tool mode.");
+ return;
+ }
+
+ EditorPlugin *ep = memnew( EditorPlugin );
+ ep->set_script(script.get_ref_ptr());
+ plugin_addons[p_addon]=ep;
+ add_editor_plugin(ep);
+
+ _update_addon_config();
+
+
+}
+
+bool EditorNode::is_addon_plugin_enabled(const String& p_addon) const {
+
+ return plugin_addons.has(p_addon);
+}
+
+
void EditorNode::_remove_edited_scene() {
int new_index = editor_data.get_edited_scene();
int old_index=new_index;
@@ -3843,9 +3956,9 @@ void EditorNode::_quick_opened() {
}
}
-void EditorNode::_quick_run(const String& p_resource) {
+void EditorNode::_quick_run() {
- _run(false,p_resource);
+ _run(false,quick_run->get_selected());
}
@@ -3930,10 +4043,14 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorPlugin>();
ObjectTypeDB::register_type<EditorImportPlugin>();
+ ObjectTypeDB::register_type<EditorExportPlugin>();
ObjectTypeDB::register_type<EditorScenePostImport>();
ObjectTypeDB::register_type<EditorScript>();
+ ObjectTypeDB::register_type<EditorSelection>();
ObjectTypeDB::register_type<EditorFileDialog>();
- ObjectTypeDB::register_type<UndoRedo>();
+ //ObjectTypeDB::register_type<EditorImportExport>();
+ ObjectTypeDB::register_type<EditorSettings>();
+ ObjectTypeDB::register_type<EditorSpatialGizmo>();
//ObjectTypeDB::register_type<EditorImporter>();
@@ -4336,6 +4453,51 @@ void EditorNode::_load_docks() {
}
+
+void EditorNode::_update_dock_slots_visibility() {
+
+ VSplitContainer*splits[DOCK_SLOT_MAX/2]={
+ left_l_vsplit,
+ left_r_vsplit,
+ right_l_vsplit,
+ right_r_vsplit,
+ };
+
+
+ HSplitContainer*h_splits[4]={
+ left_l_hsplit,
+ left_r_hsplit,
+ main_hsplit,
+ right_hsplit,
+ };
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (dock_slot[i]->get_tab_count())
+ dock_slot[i]->show();
+ else
+ dock_slot[i]->hide();
+
+ }
+
+
+ for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
+ bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
+ if (in_use)
+ splits[i]->show();
+ else
+ splits[i]->hide();
+ }
+
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+
+ if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) {
+ dock_slot[i]->set_current_tab(0);
+ }
+ }
+}
+
+
void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section) {
for(int i=0;i<DOCK_SLOT_MAX;i++) {
@@ -4520,7 +4682,7 @@ void EditorNode::_scene_tab_closed(int p_tab) {
}
else {
_remove_scene(p_tab);
- //_update_scene_tabs();
+ _update_scene_tabs();
}
}
@@ -4673,6 +4835,31 @@ void EditorNode::_bottom_panel_switch(bool p_enable,int p_idx) {
}
}
+
+void EditorNode::add_control_to_dock(DockSlot p_slot,Control* p_control) {
+ ERR_FAIL_INDEX(p_slot,DOCK_SLOT_MAX);
+ dock_slot[p_slot]->add_child(p_control);
+ _update_dock_slots_visibility();
+
+}
+
+void EditorNode::remove_control_from_dock(Control* p_control) {
+
+ Control *dock=NULL;
+ for(int i=0;i<DOCK_SLOT_MAX;i++) {
+ if (p_control->get_parent()==dock_slot[i]) {
+ dock=dock_slot[i];
+ break;
+ }
+ }
+
+ ERR_EXPLAIN("Control was not in dock");
+ ERR_FAIL_COND(!dock);
+
+ dock->remove_child(p_control);
+ _update_dock_slots_visibility();
+}
+
void EditorNode::_bind_methods() {
@@ -4763,6 +4950,7 @@ EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
+
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
if (id) {
@@ -4778,6 +4966,7 @@ EditorNode::EditorNode() {
singleton=this;
last_checked_version=0;
changing_scene=false;
+ _initializing_addons=false;
FileAccess::set_backup_save(true);
@@ -5044,7 +5233,7 @@ EditorNode::EditorNode() {
scene_tabs=memnew( Tabs );
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_CENTER);
- scene_tabs->set_tab_close_display_policy(Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY);
+ scene_tabs->set_tab_close_display_policy( (bool(EDITOR_DEF("global/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY) );
scene_tabs->connect("tab_changed",this,"_scene_tab_changed");
scene_tabs->connect("right_button_pressed",this,"_scene_tab_script_edited");
scene_tabs->connect("tab_close", this, "_scene_tab_closed");
@@ -5866,7 +6055,8 @@ EditorNode::EditorNode() {
// Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
// _scene_import->add_importer(_fbxconv_import);
editor_import_export->add_import_plugin( _scene_import);
- editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
+ // TODO: This plugin has no code, it should be either implemented or dropped (GH-3667)
+ // editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorMeshImportPlugin>( memnew(EditorMeshImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorFontImportPlugin>( memnew(EditorFontImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorSampleImportPlugin>( memnew(EditorSampleImportPlugin(this))));
@@ -6036,7 +6226,7 @@ EditorNode::EditorNode() {
}
- EditorSettings::get_singleton()->enable_plugins();
+
Node::set_human_readable_collision_renaming(true);
@@ -6052,6 +6242,19 @@ EditorNode::EditorNode() {
editor_data.set_edited_scene(0);
_update_scene_tabs();
+ {
+
+ _initializing_addons=true;
+ Vector<String> addons = Globals::get_singleton()->get("editor_plugins/enabled");
+
+ for(int i=0;i<addons.size();i++) {
+ set_addon_plugin_enabled(addons[i],true);
+ }
+ _initializing_addons=false;
+ }
+
+
+
_load_docks();
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index a8aa6ac1f4..b5d3e536db 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -101,6 +101,19 @@ class EditorNode : public Node {
OBJ_TYPE( EditorNode, Node );
+public:
+ enum DockSlot {
+ DOCK_SLOT_LEFT_UL,
+ DOCK_SLOT_LEFT_BL,
+ DOCK_SLOT_LEFT_UR,
+ DOCK_SLOT_LEFT_BR,
+ DOCK_SLOT_RIGHT_UL,
+ DOCK_SLOT_RIGHT_BL,
+ DOCK_SLOT_RIGHT_UR,
+ DOCK_SLOT_RIGHT_BR,
+ DOCK_SLOT_MAX
+ };
+private:
enum {
HISTORY_SIZE=64
};
@@ -182,17 +195,6 @@ class EditorNode : public Node {
OBJECT_METHOD_BASE=500
};
- enum DockSlot {
- DOCK_SLOT_LEFT_UL,
- DOCK_SLOT_LEFT_BL,
- DOCK_SLOT_LEFT_UR,
- DOCK_SLOT_LEFT_BR,
- DOCK_SLOT_RIGHT_UL,
- DOCK_SLOT_RIGHT_BL,
- DOCK_SLOT_RIGHT_UR,
- DOCK_SLOT_RIGHT_BR,
- DOCK_SLOT_MAX
- };
//Node *edited_scene; //scene being edited
@@ -355,6 +357,7 @@ class EditorNode : public Node {
Object *current;
bool _playing_edited;
+ String run_custom_filename;
bool reference_resource_mem;
bool save_external_resources_mem;
uint64_t saved_version;
@@ -447,7 +450,7 @@ class EditorNode : public Node {
void _hide_top_editors();
void _quick_opened();
- void _quick_run(const String& p_resource);
+ void _quick_run();
void _run(bool p_current=false, const String &p_custom="");
@@ -478,6 +481,10 @@ class EditorNode : public Node {
Map<String,Ref<Texture> > icon_type_cache;
+ bool _initializing_addons;
+ Map<String,EditorPlugin*> plugin_addons;
+
+
static Ref<Texture> _file_dialog_get_icon(const String& p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
@@ -540,6 +547,8 @@ class EditorNode : public Node {
void _load_docks();
void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section);
void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section);
+ void _update_dock_slots_visibility();
+
void _update_layouts_menu();
void _layout_menu_option(int p_idx);
@@ -548,6 +557,9 @@ class EditorNode : public Node {
void _clear_search_box();
void _clear_undo_history();
+ void _update_addon_config();
+
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -569,9 +581,14 @@ public:
static void add_editor_plugin(EditorPlugin *p_editor);
static void remove_editor_plugin(EditorPlugin *p_editor);
+ void add_control_to_dock(DockSlot p_slot,Control* p_control);
+ void remove_control_from_dock(Control* p_control);
+
void add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+ void set_addon_plugin_enabled(const String& p_addon,bool p_enabled);
+ bool is_addon_plugin_enabled(const String &p_addon) const;
void edit_node(Node *p_node);
void edit_resource(const Ref<Resource>& p_resource);
diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp
index b7ccb452e9..89b9c59287 100644
--- a/tools/editor/editor_plugin.cpp
+++ b/tools/editor/editor_plugin.cpp
@@ -29,6 +29,8 @@
#include "editor_plugin.h"
#include "plugins/canvas_item_editor_plugin.h"
#include "plugins/spatial_editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "tools/editor/editor_settings.h"
void EditorPlugin::add_custom_type(const String& p_type, const String& p_base,const Ref<Script>& p_script, const Ref<Texture>& p_icon) {
@@ -41,8 +43,26 @@ void EditorPlugin::remove_custom_type(const String& p_type){
}
+void EditorPlugin::add_control_to_bottom_dock(Control *p_control, const String &p_title) {
-void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control *p_control) {
+ EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control);
+}
+
+void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) {
+
+ ERR_FAIL_NULL(p_control);
+ EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot),p_control);
+
+}
+
+void EditorPlugin::remove_control_from_docks(Control *p_control) {
+
+ ERR_FAIL_NULL(p_control);
+ EditorNode::get_singleton()->remove_control_from_dock(p_control);
+
+}
+
+void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) {
switch(p_location) {
@@ -50,6 +70,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
EditorNode::get_menu_hb()->add_child(p_control);
} break;
+
case CONTAINER_SPATIAL_EDITOR_MENU: {
SpatialEditor::get_singleton()->add_control_to_menu_panel(p_control);
@@ -86,9 +107,13 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
}
}
-bool EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
+Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
//??
- return false;
+ if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) {
+ return get_script_instance()->call("create_spatial_gizmo",p_spatial);
+ }
+
+ return Ref<SpatialEditorGizmo>();
}
bool EditorPlugin::forward_input_event(const InputEvent& p_event) {
@@ -206,15 +231,69 @@ void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){
}
+EditorSelection* EditorPlugin::get_selection() {
+ return EditorNode::get_singleton()->get_editor_selection();
+}
+
+
+EditorSettings *EditorPlugin::get_editor_settings() {
+ return EditorSettings::get_singleton();
+}
+
+void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
+
+ EditorNode::get_singleton()->add_editor_import_plugin(p_editor_import);
+}
+
+void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import){
+
+ EditorNode::get_singleton()->remove_editor_import_plugin(p_editor_import);
+
+}
+
+void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
+
+ EditorImportExport::get_singleton()->add_export_plugin(p_editor_export);
+}
+void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
+
+ EditorImportExport::get_singleton()->remove_export_plugin(p_editor_export);
+
+}
+
+Control *EditorPlugin::get_base_control() {
+
+ return EditorNode::get_singleton()->get_gui_base();
+}
+
+
void EditorPlugin::_bind_methods() {
- ObjectTypeDB::bind_method(_MD("get_undo_redo"),&EditorPlugin::_get_undo_redo);
- ObjectTypeDB::bind_method(_MD("add_custom_control","container","control"),&EditorPlugin::add_custom_control);
+ ObjectTypeDB::bind_method(_MD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container);
+ ObjectTypeDB::bind_method(_MD("add_control_to_bottom_dock","control:Control","title"),&EditorPlugin::add_control_to_bottom_dock);
+ ObjectTypeDB::bind_method(_MD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock);
+ ObjectTypeDB::bind_method(_MD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks);
ObjectTypeDB::bind_method(_MD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type);
ObjectTypeDB::bind_method(_MD("remove_custom_type","type"),&EditorPlugin::remove_custom_type);
+ ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::add_import_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::remove_import_plugin);
+
+ ObjectTypeDB::bind_method(_MD("add_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::add_export_plugin);
+ ObjectTypeDB::bind_method(_MD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::remove_export_plugin);
+
+
+ ObjectTypeDB::bind_method(_MD("get_base_control:Control"),&EditorPlugin::get_base_control);
+ ObjectTypeDB::bind_method(_MD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo);
+ ObjectTypeDB::bind_method(_MD("get_selection:EditorSelection"),&EditorPlugin::get_selection);
+ ObjectTypeDB::bind_method(_MD("get_editor_settings:EditorSettings"),&EditorPlugin::get_editor_settings);
+
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_spatial_input_event",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera"),PropertyInfo(Variant::INPUT_EVENT,"event")));
+ MethodInfo gizmo = MethodInfo(Variant::OBJECT,"create_spatial_gizmo",PropertyInfo(Variant::OBJECT,"for_spatial:Spatial"));
+ gizmo.return_val.hint=PROPERTY_HINT_RESOURCE_TYPE;
+ gizmo.return_val.hint_string="EditorSpatialGizmo";
+ ObjectTypeDB::add_virtual_method(get_type_static(),gizmo);
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"has_main_screen"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("make_visible",PropertyInfo(Variant::BOOL,"visible")));
@@ -233,6 +312,16 @@ void EditorPlugin::_bind_methods() {
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU );
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_UL );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_BL );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_UR );
+ BIND_CONSTANT( DOCK_SLOT_LEFT_BR );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_UL );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_BL );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_UR );
+ BIND_CONSTANT( DOCK_SLOT_RIGHT_BR );
+ BIND_CONSTANT( DOCK_SLOT_MAX );
+
}
EditorPlugin::EditorPlugin()
diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h
index bf1e185a37..75a3b3b26f 100644
--- a/tools/editor/editor_plugin.h
+++ b/tools/editor/editor_plugin.h
@@ -40,6 +40,12 @@
class EditorNode;
class Spatial;
class Camera;
+class EditorSelection;
+class EditorImportExport;
+class EditorSettings;
+class SpatialEditorGizmo;
+class EditorImportPlugin;
+class EditorExportPlugin;
class EditorPlugin : public Node {
@@ -70,11 +76,26 @@ public:
CONTAINER_CANVAS_EDITOR_BOTTOM
};
+ enum DockSlot {
+ DOCK_SLOT_LEFT_UL,
+ DOCK_SLOT_LEFT_BL,
+ DOCK_SLOT_LEFT_UR,
+ DOCK_SLOT_LEFT_BR,
+ DOCK_SLOT_RIGHT_UL,
+ DOCK_SLOT_RIGHT_BL,
+ DOCK_SLOT_RIGHT_UR,
+ DOCK_SLOT_RIGHT_BR,
+ DOCK_SLOT_MAX
+ };
+
//TODO: send a resoucre for editing to the editor node?
- void add_custom_control(CustomControlContainer p_location,Control *p_control);
+ void add_control_to_container(CustomControlContainer p_location, Control *p_control);
+ void add_control_to_bottom_dock(Control *p_control, const String &p_title);
+ void add_control_to_dock(DockSlot p_slot,Control *p_control);
+ void remove_control_from_docks(Control *p_control);
- virtual bool create_spatial_gizmo(Spatial* p_spatial);
+ virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual bool forward_input_event(const InputEvent& p_event);
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
virtual String get_name() const;
@@ -94,6 +115,19 @@ public:
virtual void get_window_layout(Ref<ConfigFile> p_layout);
virtual void edited_scene_changed(){}; // if changes are pending in editor, apply them
+
+ Control *get_base_control();
+
+ void add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+ void remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
+
+ void add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
+ void remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
+
+ EditorSelection* get_selection();
+ //EditorImportExport *get_import_export();
+ EditorSettings *get_editor_settings();
+
virtual void restore_global_state();
virtual void save_global_state();
@@ -103,6 +137,7 @@ public:
};
VARIANT_ENUM_CAST( EditorPlugin::CustomControlContainer );
+VARIANT_ENUM_CAST( EditorPlugin::DockSlot );
typedef EditorPlugin* (*EditorPluginCreateFunc)(EditorNode *);
diff --git a/tools/editor/editor_plugin_settings.cpp b/tools/editor/editor_plugin_settings.cpp
new file mode 100644
index 0000000000..d78e43c578
--- /dev/null
+++ b/tools/editor/editor_plugin_settings.cpp
@@ -0,0 +1,188 @@
+#include "editor_plugin_settings.h"
+#include "scene/gui/margin_container.h"
+#include "io/config_file.h"
+#include "os/file_access.h"
+#include "os/main_loop.h"
+#include "globals.h"
+#include "editor_node.h"
+
+void EditorPluginSettings::_notification(int p_what) {
+
+ if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) {
+ update_plugins();
+ }
+}
+
+void EditorPluginSettings::update_plugins() {
+
+
+ plugin_list->clear();
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ Error err = da->change_dir("res://addons");
+ if (err!=OK) {
+ memdelete(da);
+ return;
+ }
+
+ updating=true;
+
+ TreeItem *root = plugin_list->create_item();
+
+ da->list_dir_begin();
+
+ String d = da->get_next();
+
+ Vector<String> plugins;
+
+ while(d!=String()) {
+
+ bool dir = da->current_is_dir();
+ String path = "res://addons/"+d+"/plugin.cfg";
+
+ if (dir && FileAccess::exists(path)) {
+
+ plugins.push_back(d);
+ }
+
+ d = da->get_next();
+ }
+
+ da->list_dir_end();
+ memdelete(da);
+
+ plugins.sort();
+
+ Vector<String> active_plugins = Globals::get_singleton()->get("plugins/active");
+
+ for(int i=0;i<plugins.size();i++) {
+
+ Ref<ConfigFile> cf;
+ cf.instance();
+ String path = "res://addons/"+plugins[i]+"/plugin.cfg";
+
+ Error err = cf->load(path);
+
+ if (err!=OK) {
+ WARN_PRINTS("Can't load plugin config: "+path);
+ } else if (!cf->has_section_key("plugin","name")) {
+ WARN_PRINTS("Plugin misses plugin/name: "+path);
+ } else if (!cf->has_section_key("plugin","author")) {
+ WARN_PRINTS("Plugin misses plugin/author: "+path);
+ } else if (!cf->has_section_key("plugin","version")) {
+ WARN_PRINTS("Plugin misses plugin/version: "+path);
+ } else if (!cf->has_section_key("plugin","description")) {
+ WARN_PRINTS("Plugin misses plugin/description: "+path);
+ } else if (!cf->has_section_key("plugin","script")) {
+ WARN_PRINTS("Plugin misses plugin/script: "+path);
+ } else {
+
+ String d = plugins[i];
+ String name = cf->get_value("plugin","name");
+ String author = cf->get_value("plugin","author");
+ String version = cf->get_value("plugin","version");
+ String description = cf->get_value("plugin","description");
+ String script = cf->get_value("plugin","script");
+
+ TreeItem *item = plugin_list->create_item(root);
+ item->set_text(0,name);
+ item->set_tooltip(0,"Name: "+name+"\nPath: "+path+"\nMain Script: "+script);
+ item->set_metadata(0,d);
+ item->set_text(1,version);
+ item->set_metadata(1,script);
+ item->set_text(2,author);
+ item->set_metadata(2,description);
+ item->set_cell_mode(3,TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(3,0,1,1);
+ item->set_text(3,"Inactive,Active");
+ item->set_editable(3,true);
+
+ if (EditorNode::get_singleton()->is_addon_plugin_enabled(d)) {
+ item->set_custom_color(3,Color(0.2,1,0.2));
+ item->set_range(3,1);
+ } else {
+ item->set_custom_color(3,Color(1,0.2,0.2));
+ item->set_range(3,0);
+ }
+ }
+
+ }
+
+ updating=false;
+
+}
+
+
+void EditorPluginSettings::_plugin_activity_changed() {
+
+ if (updating)
+ return;
+
+ TreeItem *ti=plugin_list->get_edited();
+ ERR_FAIL_COND(!ti);
+ bool active = ti->get_range(3);
+ String name = ti->get_metadata(0);
+
+ EditorNode::get_singleton()->set_addon_plugin_enabled(name,active);
+
+ bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(name);
+
+ if (is_active!=active) {
+ updating=true;
+ ti->set_range(3,is_active?1:0);
+ updating=false;
+ }
+
+ if (is_active)
+ ti->set_custom_color(3,Color(0.2,1,0.2));
+ else
+ ti->set_custom_color(3,Color(1,0.2,0.2));
+
+
+}
+
+void EditorPluginSettings::_bind_methods() {
+
+ ObjectTypeDB::bind_method("update_plugins",&EditorPluginSettings::update_plugins);
+ ObjectTypeDB::bind_method("_plugin_activity_changed",&EditorPluginSettings::_plugin_activity_changed);
+}
+
+EditorPluginSettings::EditorPluginSettings() {
+
+ HBoxContainer *title_hb = memnew( HBoxContainer );
+ title_hb->add_child(memnew( Label("Installed Plugins:")));
+ title_hb->add_spacer();
+ update_list = memnew( Button("Update") );
+ update_list->connect("pressed",this,"update_plugins");
+ title_hb->add_child(update_list);
+ add_child(title_hb);
+
+ plugin_list = memnew( Tree );
+ plugin_list->set_v_size_flags(SIZE_EXPAND_FILL);
+ plugin_list->set_columns(4);
+ plugin_list->set_column_titles_visible(true);
+ plugin_list->set_column_title(0,"Name:");
+ plugin_list->set_column_title(1,"Version:");
+ plugin_list->set_column_title(2,"Author:");
+ plugin_list->set_column_title(3,"Status:");
+ plugin_list->set_column_expand(0,true);
+ plugin_list->set_column_expand(1,false);
+ plugin_list->set_column_expand(2,false);
+ plugin_list->set_column_expand(3,false);
+ plugin_list->set_column_min_width(1,100);
+ plugin_list->set_column_min_width(2,250);
+ plugin_list->set_column_min_width(3,80);
+ plugin_list->set_hide_root(true);
+ plugin_list->connect("item_edited",this,"_plugin_activity_changed");
+
+
+ MarginContainer *mc = memnew( MarginContainer );
+ mc->add_child(plugin_list);
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ add_child(mc);
+
+ updating=false;
+
+}
+
diff --git a/tools/editor/editor_plugin_settings.h b/tools/editor/editor_plugin_settings.h
new file mode 100644
index 0000000000..4f3c5b8268
--- /dev/null
+++ b/tools/editor/editor_plugin_settings.h
@@ -0,0 +1,35 @@
+#ifndef EDITORPLUGINSETTINGS_H
+#define EDITORPLUGINSETTINGS_H
+
+
+#include "scene/gui/dialogs.h"
+#include "property_editor.h"
+#include "optimized_save_dialog.h"
+#include "undo_redo.h"
+#include "editor_data.h"
+
+class EditorPluginSettings : public VBoxContainer {
+
+ OBJ_TYPE(EditorPluginSettings,VBoxContainer);
+
+ Button* update_list;
+ Tree *plugin_list;
+ bool updating;
+
+
+ void _plugin_activity_changed();
+protected:
+
+ void _notification(int p_what);
+
+ static void _bind_methods();
+
+
+public:
+
+ void update_plugins();
+
+ EditorPluginSettings();
+};
+
+#endif // EDITORPLUGINSETTINGS_H
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 4195ba97e6..47ef87cfb1 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -165,22 +165,33 @@ void EditorSettings::create() {
return; //pointless
DirAccess *dir=NULL;
- Object *object;
Variant meta;
String config_path;
String config_dir;
String config_file="editor_settings.xml";
+ Ref<ConfigFile> extra_config = memnew(ConfigFile);
- if (OS::get_singleton()->has_environment("APPDATA")) {
- // Most likely under windows, save here
- config_path=OS::get_singleton()->get_environment("APPDATA");
- config_dir=String(_MKSTR(VERSION_SHORT_NAME)).capitalize();
- } else if (OS::get_singleton()->has_environment("HOME")) {
+ String exe_path = OS::get_singleton()->get_executable_path().get_base_dir();
+ DirAccess* d = DirAccess::create_for_path(exe_path);
+ if (d->file_exists(exe_path + "/._sc_")) {
- config_path=OS::get_singleton()->get_environment("HOME");
- config_dir="."+String(_MKSTR(VERSION_SHORT_NAME)).to_lower();
- }
+ // editor is self contained
+ config_path = exe_path;
+ config_dir = "editor_data";
+ extra_config->load(exe_path + "/._sc_");
+ } else {
+
+ if (OS::get_singleton()->has_environment("APPDATA")) {
+ // Most likely under windows, save here
+ config_path=OS::get_singleton()->get_environment("APPDATA");
+ config_dir=String(_MKSTR(VERSION_SHORT_NAME)).capitalize();
+ } else if (OS::get_singleton()->has_environment("HOME")) {
+
+ config_path=OS::get_singleton()->get_environment("HOME");
+ config_dir="."+String(_MKSTR(VERSION_SHORT_NAME)).to_lower();
+ }
+ };
ObjectTypeDB::register_type<EditorSettings>(); //otherwise it can't be unserialized
String config_file_path;
@@ -217,13 +228,6 @@ void EditorSettings::create() {
dir->change_dir("..");
}
- if (dir->change_dir("plugins")!=OK) {
- dir->make_dir("plugins");
- } else {
-
- dir->change_dir("..");
- }
-
if (dir->change_dir("config")!=OK) {
dir->make_dir("config");
} else {
@@ -276,7 +280,6 @@ void EditorSettings::create() {
singleton->setup_network();
singleton->load_favorites();
- singleton->scan_plugins();
return;
@@ -286,12 +289,21 @@ void EditorSettings::create() {
fail:
+ // patch init projects
+ if (extra_config->has_section("init_projects")) {
+ Vector<String> list = extra_config->get_value("init_projects", "list");
+ for (int i=0; i<list.size(); i++) {
+
+ list[i] = exe_path + "/" + list[i];
+ };
+ extra_config->set_value("init_projects", "list", list);
+ };
+
singleton = Ref<EditorSettings>( memnew( EditorSettings ) );
singleton->config_file_path=config_file_path;
singleton->settings_path=config_path+"/"+config_dir;
- singleton->_load_defaults();
+ singleton->_load_defaults(extra_config);
singleton->setup_network();
- singleton->scan_plugins();
}
@@ -302,35 +314,6 @@ String EditorSettings::get_settings_path() const {
}
-Error EditorSettings::_load_plugin(const String& p_path, Plugin &plugin) {
-
- if (!FileAccess::exists(p_path))
- return ERR_FILE_NOT_FOUND;
-
- Ref<ConfigFile> cf = memnew(ConfigFile);
- Error err = cf->load(p_path);
- ERR_EXPLAIN("Error loading plugin description for: "+p_path);
- ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN);
-
- plugin.instance=NULL;
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","name"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","installs"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","author"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","version"),ERR_INVALID_DATA);
- ERR_FAIL_COND_V(!cf->has_section_key("plugin","script"),ERR_INVALID_DATA);
- plugin.name=cf->get_value("plugin","name");
- plugin.author=cf->get_value("plugin","author");
- plugin.version=cf->get_value("plugin","version");
- plugin.script=cf->get_value("plugin","script");
-
- if (cf->has_section_key("plugin","description"))
- plugin.description=cf->get_value("plugin","description");
- plugin.installs=cf->get_value("plugin","installs");
- if (cf->has_section_key("plugin","install_files"))
- plugin.install_files=cf->get_value("plugin","install_files");
-
- return OK;
-}
void EditorSettings::setup_network() {
@@ -361,46 +344,6 @@ void EditorSettings::setup_network() {
}
-void EditorSettings::scan_plugins() {
-
- Map<String,Plugin> new_plugins;
-
- new_plugins.clear();
- DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- Error err = d->change_dir(get_settings_path().plus_file("plugins"));
- if (err!=OK) {
- memdelete(d);
- ERR_EXPLAIN("Plugin dir does not exist!")
- ERR_FAIL_COND(err!=OK);
- }
- d->list_dir_begin();
-
- String base = d->get_current_dir();
- //print_line("list diring on: "+base);
- while(true) {
- String p = d->get_next();
- if (p=="")
- break;
- if (!d->current_is_dir() || p.begins_with("."))
- continue;
-
- String cfpath=d->get_current_dir().plus_file(p+"/plugin.cfg");
-
- Plugin plugin;
- Error err = _load_plugin(cfpath,plugin);
- ERR_CONTINUE(err!=OK);
-
- if (plugins.has(p))
- plugin.instance=plugins[p].instance;
-
- new_plugins[p]=plugin;
- }
-
-
- plugins=new_plugins;
-
- memdelete(d);
-}
void EditorSettings::save() {
@@ -435,7 +378,7 @@ void EditorSettings::destroy() {
singleton=Ref<EditorSettings>();
}
-void EditorSettings::_load_defaults() {
+void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_THREAD_SAFE_METHOD_
@@ -490,6 +433,7 @@ void EditorSettings::_load_defaults() {
hints["3d_editor/pan_modifier"]=PropertyInfo(Variant::INT,"3d_editor/pan_modifier",PROPERTY_HINT_ENUM,"None,Shift,Alt,Meta,Ctrl");
set("3d_editor/zoom_modifier",4);
hints["3d_editor/zoom_modifier"]=PropertyInfo(Variant::INT,"3d_editor/zoom_modifier",PROPERTY_HINT_ENUM,"None,Shift,Alt,Meta,Ctrl");
+ set("3d_editor/emulate_numpad",false);
set("2d_editor/bone_width",5);
set("2d_editor/bone_color1",Color(1.0,1.0,1.0,0.9));
@@ -541,6 +485,33 @@ void EditorSettings::_load_defaults() {
set("run/auto_save_before_running",true);
set("resources/save_compressed_resources",true);
set("resources/auto_reload_modified_images",true);
+
+ if (p_extra_config.is_valid()) {
+
+ if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) {
+
+ Vector<String> list = p_extra_config->get_value("init_projects", "list");
+ for (int i=0; i<list.size(); i++) {
+
+ String name = list[i].replace("/", "::");
+ set("projects/"+name, list[i]);
+ };
+ };
+
+ if (p_extra_config->has_section("presets")) {
+
+ List<String> keys;
+ p_extra_config->get_section_keys("presets", &keys);
+
+ for (List<String>::Element *E=keys.front();E;E=E->next()) {
+
+ String key = E->get();
+ Variant val = p_extra_config->get_value("presets", key);
+ set(key, val);
+ };
+ };
+ };
+
}
void EditorSettings::notify_changes() {
@@ -574,148 +545,9 @@ void EditorSettings::add_property_hint(const PropertyInfo& p_hint) {
}
-bool EditorSettings::is_plugin_enabled(const String& p_plugin) {
-
- if (!has("_plugins/enabled"))
- return false;
-
- StringArray sa=get("_plugins/enabled");
-
- for(int i=0;i<sa.size();i++) {
-
- String plugin = sa[i];
- if (!plugins.has(plugin))
- continue;
- if (plugin==p_plugin)
- return true;
- }
-
- return false;
-}
-void EditorSettings::enable_plugins() {
- // editor plugins
- if (has("_plugins/enabled")) {
- StringArray sa=get("_plugins/enabled");
-
- for(int i=0;i<sa.size();i++) {
-
- String plugin = sa[i];
- if (!plugins.has(plugin))
- continue;
- if (plugins[plugin].installs)
- continue; //not configured here
- set_plugin_enabled(plugin,true);
- }
- }
-
- // installed plugins
- List<PropertyInfo> pi;
- Globals::get_singleton()->get_property_list(&pi);
- for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) {
-
- String p = E->get().name;
-
- if (p.begins_with("plugins/")) {
- load_installed_plugin(p.replace_first("plugins/",""));
- }
- }
-
-}
-
-void EditorSettings::load_installed_plugin(const String& p_plugin) {
-
- ERR_FAIL_COND( !Globals::get_singleton()->has("plugins/"+p_plugin) );
- String path = Globals::get_singleton()->get("plugins/"+p_plugin);
-
- Plugin plugin;
- Error err = _load_plugin(path.plus_file("plugin.cfg"),plugin);
-
- if (err)
- return;
-
- print_line("installing plugin...");
- EditorPlugin *ep=_load_plugin_editor(path.plus_file(plugin.script));
- ERR_FAIL_COND(!ep);
- print_line("load!");
- EditorNode::add_editor_plugin(ep);
-
-}
-
-
-EditorPlugin *EditorSettings::_load_plugin_editor(const String& p_path) {
-
- Ref<Script> script = ResourceLoader::load(p_path);
- ERR_EXPLAIN("Invalid Script for plugin: "+p_path);
- ERR_FAIL_COND_V(script.is_null(),NULL);
- ERR_EXPLAIN("Script has errors: "+p_path);
- ERR_FAIL_COND_V(!script->can_instance(),NULL);
- ERR_EXPLAIN("Script does not inherit EditorPlugin: "+p_path);
- ERR_FAIL_COND_V(script->get_instance_base_type().operator String()!="EditorPlugin",NULL);
-
- EditorPlugin *ep = memnew( EditorPlugin );
- ep->set_script(script.get_ref_ptr());
- if (!ep->get_script_instance()) {
- memdelete(ep);
- ERR_EXPLAIN("Script could't load: "+p_path);
- ERR_FAIL_V(NULL);
- }
-
-
- return ep;
-}
-
-void EditorSettings::set_plugin_enabled(const String& p_plugin, bool p_enabled) {
-
- ERR_FAIL_COND(!plugins.has(p_plugin));
- if (p_enabled == (plugins[p_plugin].instance!=NULL)) //already enabled or disabled
- return;
-
- print_line("REQUEST "+p_plugin+" to "+itos(p_enabled));
- StringArray sa;
- if (has("_plugins/enabled"))
- sa=get("_plugins/enabled");
-
- int idx=-1;
- for(int i=0;i<sa.size();i++) {
-
- if (sa[i]==p_plugin) {
- idx=i;
- break;
- }
- }
-
- if (p_enabled) {
-
-
- String ppath = get_settings_path().plus_file("plugins/"+p_plugin+"/"+plugins[p_plugin].script);
- EditorPlugin *ep=_load_plugin_editor(ppath);
- if (!ep)
- return;
- plugins[p_plugin].instance=ep;
- EditorNode::add_editor_plugin(ep);
-
- if (idx==-1)
- sa.push_back(p_plugin);
- } else {
-
- print_line("DISABLING");
- EditorNode::remove_editor_plugin(plugins[p_plugin].instance);
- memdelete(plugins[p_plugin].instance);
- plugins[p_plugin].instance=NULL;
- if (idx!=-1)
- sa.remove(idx);
-
- }
-
- if (sa.size()==0)
- set("_plugins/enabled",Variant());
- else
- set("_plugins/enabled",sa);
-
-}
void EditorSettings::set_favorite_dirs(const Vector<String>& p_favorites) {
@@ -785,6 +617,16 @@ void EditorSettings::load_favorites() {
void EditorSettings::_bind_methods() {
+ ObjectTypeDB::bind_method(_MD("erase","property"),&EditorSettings::erase);
+ ObjectTypeDB::bind_method(_MD("get_settings_path"),&EditorSettings::get_settings_path);
+ ObjectTypeDB::bind_method(_MD("get_project_settings_path"),&EditorSettings::get_project_settings_path);
+
+ ObjectTypeDB::bind_method(_MD("set_favorite_dirs","dirs"),&EditorSettings::set_favorite_dirs);
+ ObjectTypeDB::bind_method(_MD("get_favorite_dirs"),&EditorSettings::get_favorite_dirs);
+
+ ObjectTypeDB::bind_method(_MD("set_recent_dirs","dirs"),&EditorSettings::set_recent_dirs);
+ ObjectTypeDB::bind_method(_MD("get_recent_dirs"),&EditorSettings::get_recent_dirs);
+
ADD_SIGNAL(MethodInfo("settings_changed"));
}
diff --git a/tools/editor/editor_settings.h b/tools/editor/editor_settings.h
index d1a11360af..ae5bbcca89 100644
--- a/tools/editor/editor_settings.h
+++ b/tools/editor/editor_settings.h
@@ -33,6 +33,7 @@
#include "resource.h"
#include "os/thread_safe.h"
+#include "core/io/config_file.h"
class EditorPlugin;
@@ -56,7 +57,6 @@ public:
Vector<String> install_files;
};
private:
- Map<String,Plugin> plugins;
struct VariantContainer {
int order;
@@ -83,10 +83,7 @@ private:
Ref<Resource> clipboard;
- EditorPlugin *_load_plugin_editor(const String& p_path);
- Error _load_plugin(const String& p_path,Plugin& plugin);
-
- void _load_defaults();
+ void _load_defaults(Ref<ConfigFile> p_extra_config = NULL);
String project_config_path;
@@ -107,13 +104,10 @@ public:
static EditorSettings *get_singleton();
void erase(String p_var);
String get_settings_path() const;
- String get_global_settings_path() const;
+ //String get_global_settings_path() const;
String get_project_settings_path() const;
- const Map<String,Plugin>& get_plugins() const { return plugins; }
- void scan_plugins();
- void enable_plugins();
void setup_network();
void raise_order(const String& p_name);
@@ -123,11 +117,6 @@ public:
void notify_changes();
- void set_plugin_enabled(const String& p_plugin,bool p_enabled);
- bool is_plugin_enabled(const String& p_plugin);
-
- void load_installed_plugin(const String& p_plugin);
-
void set_resource_clipboard(const Ref<Resource>& p_resource) { clipboard=p_resource; }
Ref<Resource> get_resource_clipboard() const { return clipboard; }
diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp
index 9b4ca246e7..ff126a8e8c 100644
--- a/tools/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp
@@ -540,7 +540,7 @@ class EditorFontImportDialog : public ConfirmationDialog {
return;
}
- //_import_inc(dest->get_line_edit()->get_text());
+ _import_inc(dest->get_line_edit()->get_text());
hide();
}
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index a3b6827cd4..322320780d 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -57,11 +57,12 @@ void EditorScenePostImport::_bind_methods() {
}
-Error EditorScenePostImport::post_import(Node* p_scene) {
+Node *EditorScenePostImport::post_import(Node* p_scene) {
if (get_script_instance())
- return Error(int(get_script_instance()->call("post_import",p_scene)));
- return OK;
+ return get_script_instance()->call("post_import",p_scene);
+
+ return p_scene;
}
EditorScenePostImport::EditorScenePostImport() {
@@ -2748,8 +2749,8 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
if (post_import_script.is_valid()) {
- err = post_import_script->post_import(scene);
- if (err) {
+ scene = post_import_script->post_import(scene);
+ if (!scene) {
EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
return err;
}
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index 1f3b73fe7f..a1a090de7e 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -87,7 +87,7 @@ protected:
static void _bind_methods();
public:
- virtual Error post_import(Node* p_scene);
+ virtual Node* post_import(Node* p_scene);
EditorScenePostImport();
};
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 32afd86970..010753e88c 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -621,10 +621,11 @@ void AnimationPlayerEditor::ensure_visibility() {
Dictionary AnimationPlayerEditor::get_state() const {
+
Dictionary d;
d["visible"]=is_visible();
- if (is_visible() && player) {
+ if (EditorNode::get_singleton()->get_edited_scene() && is_visible() && player) {
d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player);
d["animation"]=player->get_current_animation();
@@ -637,6 +638,9 @@ void AnimationPlayerEditor::set_state(const Dictionary& p_state) {
if (p_state.has("visible") && p_state["visible"]) {
+ if (!EditorNode::get_singleton()->get_edited_scene())
+ return;
+
Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
if (n && n->cast_to<AnimationPlayer>()) {
player=n->cast_to<AnimationPlayer>();
@@ -942,6 +946,14 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value) {
anim=player->get_animation(current);
float pos = anim->get_length() * (p_value / frame->get_max());
+ float step = anim->get_step();
+ if (step) {
+ pos=Math::stepify(pos, step);
+ if (pos<0)
+ pos=0;
+ if (pos>=anim->get_length())
+ pos=anim->get_length();
+ }
if (player->is_valid()) {
float cpos = player->get_current_animation_pos();
diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp
index 26524b2437..22a188bce4 100644
--- a/tools/editor/plugins/baked_light_editor_plugin.cpp
+++ b/tools/editor/plugins/baked_light_editor_plugin.cpp
@@ -332,7 +332,7 @@ BakedLightEditorPlugin::BakedLightEditorPlugin(EditorNode *p_node) {
editor=p_node;
baked_light_editor = memnew( BakedLightEditor );
editor->get_viewport()->add_child(baked_light_editor);
- add_custom_control(CONTAINER_SPATIAL_EDITOR_MENU,baked_light_editor->bake_hbox);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU,baked_light_editor->bake_hbox);
baked_light_editor->hide();
baked_light_editor->bake_hbox->hide();
}
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index f3ff001d84..f8bc97a433 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1560,7 +1560,7 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
Matrix32 rot;
rot.elements[1] = (dfrom - center).normalized();
rot.elements[0] = rot.elements[1].tangent();
- node->set_rot(snap_angle(rot.xform_inv(dto-center).angle(), node->get_rot()));
+ node->set_rot(snap_angle(rot.xform_inv(dto-center).angle() + node->get_rot(), node->get_rot()));
display_rotate_to = dto;
display_rotate_from = center;
viewport->update();
diff --git a/tools/editor/plugins/color_ramp_editor_plugin.cpp b/tools/editor/plugins/color_ramp_editor_plugin.cpp
index 42ff1b1de9..133775115d 100644
--- a/tools/editor/plugins/color_ramp_editor_plugin.cpp
+++ b/tools/editor/plugins/color_ramp_editor_plugin.cpp
@@ -13,9 +13,9 @@ ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node, bool p_2d) {
_2d=p_2d;
if (p_2d)
- add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
else
- add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
ramp_editor->set_custom_minimum_size(Size2(100, 48));
ramp_editor->hide();
diff --git a/tools/editor/plugins/path_editor_plugin.cpp b/tools/editor/plugins/path_editor_plugin.cpp
index b99e632604..3c4428bdb0 100644
--- a/tools/editor/plugins/path_editor_plugin.cpp
+++ b/tools/editor/plugins/path_editor_plugin.cpp
@@ -267,17 +267,15 @@ PathSpatialGizmo::PathSpatialGizmo(Path* p_path){
}
-bool PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
+Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
- if (p_spatial->cast_to<Path>()) {
+ if (p_spatial->cast_to<Path>()) {
- Ref<PathSpatialGizmo> psg = memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
- p_spatial->set_gizmo(psg);
- return true;
+ return memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
}
- return false;
+ return Ref<SpatialEditorGizmo>();
}
bool PathEditorPlugin::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
@@ -538,7 +536,7 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
- SpatialEditor::get_singleton()->add_gizmo_plugin(this);
+// SpatialEditor::get_singleton()->add_gizmo_plugin(this);
sep = memnew( VSeparator);
sep->hide();
diff --git a/tools/editor/plugins/path_editor_plugin.h b/tools/editor/plugins/path_editor_plugin.h
index 18bad23bd1..0afd957af7 100644
--- a/tools/editor/plugins/path_editor_plugin.h
+++ b/tools/editor/plugins/path_editor_plugin.h
@@ -32,9 +32,9 @@
#include "tools/editor/spatial_editor_gizmos.h"
#include "scene/3d/path.h"
-class PathSpatialGizmo : public SpatialGizmoTool {
+class PathSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PathSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PathSpatialGizmo,EditorSpatialGizmo);
Path* path;
mutable Vector3 original;
@@ -83,7 +83,7 @@ public:
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
// virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
- virtual bool create_spatial_gizmo(Spatial* p_spatial);
+ virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual String get_name() const { return "Path"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 18f3787cff..8d0527cff7 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -609,7 +609,7 @@ void ScriptEditor::_breaked(bool p_breaked,bool p_can_debug) {
void ScriptEditor::_show_debugger(bool p_show) {
- debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show);
+// debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(DEBUG_SHOW), p_show);
}
void ScriptEditor::_script_created(Ref<Script> p_script) {
@@ -979,7 +979,7 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case SEARCH_WEBSITE: {
- OS::get_singleton()->shell_open("http://www.godotengine.org/projects/godot-engine/wiki/Documentation#Tutorials");
+ OS::get_singleton()->shell_open("http://docs.godotengine.org/");
} break;
case WINDOW_NEXT: {
diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp
index 18d8f5efc0..7161033111 100644
--- a/tools/editor/plugins/shader_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_editor_plugin.cpp
@@ -578,9 +578,9 @@ ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node, bool p_2d) {
shader_editor = memnew( ShaderEditor );
_2d=p_2d;
if (p_2d)
- add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor);
+ add_control_to_container(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor);
else
- add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor);
// editor->get_viewport()->add_child(shader_editor);
// shader_editor->set_area_as_parent_rect();
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index cf92473919..1f264a2337 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -1631,8 +1631,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
_edit.snap=true;
}
} break;
+ case KEY_7:
case KEY_KP_7: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_7)
+ return;
cursor.y_rot=0;
if (k.mod.shift) {
cursor.x_rot=-Math_PI/2.0;
@@ -1647,8 +1650,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
_update_name();
}
} break;
+ case KEY_1:
case KEY_KP_1: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_1)
+ return;
cursor.x_rot=0;
if (k.mod.shift) {
cursor.y_rot=Math_PI;
@@ -1664,8 +1670,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
} break;
+ case KEY_3:
case KEY_KP_3: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_3)
+ return;
cursor.x_rot=0;
if (k.mod.shift) {
cursor.y_rot=Math_PI/2.0;
@@ -1680,8 +1689,11 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
}
} break;
+ case KEY_5:
case KEY_KP_5: {
-
+ bool emulate_numpad = EditorSettings::get_singleton()->get("3d_editor/emulate_numpad");
+ if (!emulate_numpad && k.scancode==KEY_5)
+ return;
//orthogonal = !orthogonal;
_menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL);
@@ -3643,35 +3655,32 @@ void SpatialEditor::_request_gizmo(Object* p_obj) {
Spatial *sp=p_obj->cast_to<Spatial>();
if (!sp)
return;
- if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene())) {
-
- Ref<SpatialEditorGizmo> seg = gizmos->get_gizmo(sp);
+ if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene() || editor->get_edited_scene()->is_editable_instance(sp->get_owner()))) {
- if (seg.is_valid()) {
- sp->set_gizmo(seg);
- }
+ Ref<SpatialEditorGizmo> seg;
- for (List<EditorPlugin*>::Element *E=gizmo_plugins.front();E;E=E->next()) {
+ for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count();i++) {
- if (E->get()->create_spatial_gizmo(sp)) {
+ seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp);
+ if (seg.is_valid())
+ break;
+ }
- seg = sp->get_gizmo();
- if (sp==selected && seg.is_valid()) {
+ if (!seg.is_valid()) {
+ seg = gizmos->get_gizmo(sp);
+ }
- seg->set_selected(true);
- selected->update_gizmo();
- }
- return;
- }
+ if (seg.is_valid()) {
+ sp->set_gizmo(seg);
}
+
if (seg.is_valid() && sp==selected) {
seg->set_selected(true);
selected->update_gizmo();
}
}
-
}
void SpatialEditor::_toggle_maximize_view(Object* p_viewport) {
diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h
index b0e366b140..af1b6919a2 100644
--- a/tools/editor/plugins/spatial_editor_plugin.h
+++ b/tools/editor/plugins/spatial_editor_plugin.h
@@ -457,8 +457,6 @@ private:
Ref<Environment> viewport_environment;
- List<EditorPlugin*> gizmo_plugins;
-
Spatial *selected;
void _request_gizmo(Object* p_obj);
@@ -518,8 +516,6 @@ public:
UndoRedo *get_undo_redo() { return undo_redo; }
- void add_gizmo_plugin(EditorPlugin* p_plugin) { gizmo_plugins.push_back(p_plugin); }
-
void add_control_to_menu_panel(Control *p_control);
VSplitContainer *get_shader_split();
diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp
index 589d9d3d99..579eb8c7c7 100644
--- a/tools/editor/project_manager.cpp
+++ b/tools/editor/project_manager.cpp
@@ -788,7 +788,7 @@ void ProjectManager::_erase_project() {
return;
- erase_ask->set_text("Erase project from list?? (Folder contents will not be modified)");
+ erase_ask->set_text("Remove project from list?? (Folder contents will not be modified)");
erase_ask->popup_centered_minsize();
}
@@ -943,7 +943,7 @@ ProjectManager::ProjectManager() {
Button* erase = memnew( Button );
- erase->set_text("Erase");
+ erase->set_text("Remove");
tree_vb->add_child(erase);
erase->connect("pressed", this,"_erase_project");
erase_btn=erase;
@@ -970,7 +970,7 @@ ProjectManager::ProjectManager() {
erase_ask = memnew( ConfirmationDialog );
- erase_ask->get_ok()->set_text("Erase");
+ erase_ask->get_ok()->set_text("Remove");
erase_ask->get_ok()->connect("pressed", this,"_erase_project_confirm");
add_child(erase_ask);
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index 22e93c5a95..69e09d6053 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -97,26 +97,63 @@ void ProjectSettings::_notification(int p_what) {
}
}
-void ProjectSettings::_action_persist_toggle() {
+void ProjectSettings::_action_selected() {
+ TreeItem *ti=input_editor->get_selected();
+ if (!ti || !ti->is_editable(0))
+ return;
+
+ add_at="input/"+ti->get_text(0);
+}
+
+void ProjectSettings::_action_edited() {
TreeItem *ti=input_editor->get_selected();
if (!ti)
return;
- String name="input/"+ti->get_text(0);
+ String new_name=ti->get_text(0);
+ String old_name=add_at.substr(add_at.find("/")+1,add_at.length());
+
+ if (new_name==old_name)
+ return;
+
+ if (new_name.find("/")!=-1 || new_name.find(":")!=-1 || new_name=="") {
+
+ ti->set_text(0,old_name);
+ add_at="input/"+old_name;
- bool prev = Globals::get_singleton()->is_persisting(name);
- print_line("prev persist: "+itos(prev));
- print_line("new persist: "+itos(ti->is_checked(0)));
- if (prev==ti->is_checked(0))
+ message->set_text("Invalid Action (Anything goes but / or :).");
+ message->popup_centered(Size2(300,100));
return;
+ }
+
+ String action_prop="input/"+new_name;
+
+ if (Globals::get_singleton()->has(action_prop)) {
+ ti->set_text(0,old_name);
+ add_at="input/"+old_name;
+
+ message->set_text("Action '"+new_name+"' already exists!.");
+ message->popup_centered(Size2(300,100));
+ return;
+ }
+
+ int order = Globals::get_singleton()->get_order(add_at);
+ Array va = Globals::get_singleton()->get(add_at);
+ bool persisting = Globals::get_singleton()->is_persisting(add_at);
setting=true;
- undo_redo->create_action("Change Input Action Persistence");
- undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,ti->is_checked(0));
- undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,prev);
+ undo_redo->create_action("Rename Input Action Event");
+ undo_redo->add_do_method(Globals::get_singleton(),"clear",add_at);
+ undo_redo->add_do_method(Globals::get_singleton(),"set",action_prop,va);
+ undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",action_prop,persisting);
+ undo_redo->add_do_method(Globals::get_singleton(),"set_order",action_prop,order);
+ undo_redo->add_undo_method(Globals::get_singleton(),"clear",action_prop);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set",add_at,va);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",add_at,persisting);
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",add_at,order);
undo_redo->add_do_method(this,"_update_actions");
undo_redo->add_undo_method(this,"_update_actions");
undo_redo->add_do_method(this,"_settings_changed");
@@ -124,6 +161,8 @@ void ProjectSettings::_action_persist_toggle() {
undo_redo->commit_action();
setting=false;
+ add_at=action_prop;
+
}
@@ -356,15 +395,6 @@ void ProjectSettings::_action_button_pressed(Object* p_obj, int p_column,int p_i
add_at="input/"+ti->get_text(0);
} else if (p_id==2) {
- //rename
-
- add_at="input/"+ti->get_text(0);
- rename_action->popup_centered();
- rename_action->get_line_edit()->set_text(ti->get_text(0));
- rename_action->get_line_edit()->set_cursor_pos(ti->get_text(0).length());
- rename_action->get_line_edit()->select_all();
-
- } else if (p_id==3) {
//remove
if (ti->get_parent()==input_editor->get_root()) {
@@ -446,15 +476,13 @@ void ProjectSettings::_update_actions() {
item->set_text(0,name);
item->add_button(0,get_icon("Add","EditorIcons"),1);
if (!Globals::get_singleton()->get_input_presets().find(pi.name)) {
- item->add_button(0,get_icon("Rename","EditorIcons"),2);
- item->add_button(0,get_icon("Remove","EditorIcons"),3);
+ item->add_button(0,get_icon("Remove","EditorIcons"),2);
+ item->set_editable(0,true);
}
item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
- item->set_editable(0,true);
//item->set_checked(0,pi.usage&PROPERTY_USAGE_CHECKED);
-
Array actions=Globals::get_singleton()->get(pi.name);
for(int i=0;i<actions.size();i++) {
@@ -527,7 +555,7 @@ void ProjectSettings::_update_actions() {
action->set_icon(0,get_icon("JoyAxis","EditorIcons"));
} break;
}
- action->add_button(0,get_icon("Remove","EditorIcons"),3);
+ action->add_button(0,get_icon("Remove","EditorIcons"),2);
action->set_metadata(0,i);
}
}
@@ -542,6 +570,7 @@ void ProjectSettings::popup_project_settings() {
globals_editor->edit(Globals::get_singleton());
_update_translations();
_update_autoload();
+ plugin_settings->update_plugins();
}
@@ -658,45 +687,6 @@ void ProjectSettings::_action_add() {
}
-void ProjectSettings::_action_rename(const String &p_name) {
-
-
- if (p_name.find("/")!=-1 || p_name.find(":")!=-1 || p_name=="") {
- message->set_text("Invalid Action (Anything goes but / or :).");
- message->popup_centered(Size2(300,100));
- return;
- }
-
- String new_name = "input/"+p_name;
-
- if (Globals::get_singleton()->has(new_name)) {
- message->set_text("Action '"+p_name+"' already exists!.");
- message->popup_centered(Size2(300,100));
- return;
- }
-
- int order = Globals::get_singleton()->get_order(add_at);
- Array va = Globals::get_singleton()->get(add_at);
- bool persisting = Globals::get_singleton()->is_persisting(add_at);
-
- undo_redo->create_action("Rename Input Action Event");
- undo_redo->add_do_method(Globals::get_singleton(),"clear",add_at);
- undo_redo->add_do_method(Globals::get_singleton(),"set",new_name,va);
- undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",new_name,persisting);
- undo_redo->add_do_method(Globals::get_singleton(),"set_order",new_name,order);
- undo_redo->add_undo_method(Globals::get_singleton(),"clear",new_name);
- undo_redo->add_undo_method(Globals::get_singleton(),"set",add_at,va);
- undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",add_at,persisting);
- undo_redo->add_undo_method(Globals::get_singleton(),"set_order",add_at,order);
- undo_redo->add_do_method(this,"_update_actions");
- undo_redo->add_undo_method(this,"_update_actions");
- undo_redo->add_do_method(this,"_settings_changed");
- undo_redo->add_undo_method(this,"_settings_changed");
- undo_redo->commit_action();
-
- rename_action->hide();
-}
-
void ProjectSettings::_item_checked(const String& p_item, bool p_check) {
@@ -750,6 +740,10 @@ void ProjectSettings::_settings_changed() {
timer->start();
}
+void ProjectSettings::queue_save() {
+ _settings_changed();
+}
+
void ProjectSettings::_copy_to_platform(int p_which) {
@@ -1403,9 +1397,9 @@ void ProjectSettings::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_save"),&ProjectSettings::_save);
ObjectTypeDB::bind_method(_MD("_action_add"),&ProjectSettings::_action_add);
ObjectTypeDB::bind_method(_MD("_action_adds"),&ProjectSettings::_action_adds);
- ObjectTypeDB::bind_method(_MD("_action_persist_toggle"),&ProjectSettings::_action_persist_toggle);
+ ObjectTypeDB::bind_method(_MD("_action_selected"),&ProjectSettings::_action_selected);
+ ObjectTypeDB::bind_method(_MD("_action_edited"),&ProjectSettings::_action_edited);
ObjectTypeDB::bind_method(_MD("_action_button_pressed"),&ProjectSettings::_action_button_pressed);
- ObjectTypeDB::bind_method(_MD("_action_rename"),&ProjectSettings::_action_rename);
ObjectTypeDB::bind_method(_MD("_update_actions"),&ProjectSettings::_update_actions);
ObjectTypeDB::bind_method(_MD("_wait_for_key"),&ProjectSettings::_wait_for_key);
ObjectTypeDB::bind_method(_MD("_add_item"),&ProjectSettings::_add_item);
@@ -1620,19 +1614,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
input_editor->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END, 35 );
input_editor->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN, 5 );
input_editor->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END, 5 );
- input_editor->connect("item_edited",this,"_action_persist_toggle");
+ input_editor->connect("item_edited",this,"_action_edited");
+ input_editor->connect("cell_selected",this,"_action_selected");
input_editor->connect("button_pressed",this,"_action_button_pressed");
popup_add = memnew( PopupMenu );
add_child(popup_add);
popup_add->connect("item_pressed",this,"_add_item");
- rename_action = memnew( EditorNameDialog );
- add_child(rename_action);
- rename_action->set_hide_on_ok(false);
- rename_action->set_size(Size2(200, 70));
- rename_action->set_title("Rename Input Action");
- rename_action->connect("name_confirmed", this,"_action_rename");
-
press_a_key = memnew( ConfirmationDialog );
press_a_key->set_focus_mode(FOCUS_ALL);
add_child(press_a_key);
@@ -1847,6 +1835,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
}
+ {
+
+ plugin_settings = memnew( EditorPluginSettings );
+ plugin_settings->set_name("Plugins");
+ tab_container->add_child(plugin_settings);
+ }
+
timer = memnew( Timer );
timer->set_wait_time(1.5);
timer->connect("timeout",Globals::get_singleton(),"save");
diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h
index b689340fdf..922608fb9a 100644
--- a/tools/editor/project_settings.h
+++ b/tools/editor/project_settings.h
@@ -34,7 +34,9 @@
#include "optimized_save_dialog.h"
#include "undo_redo.h"
#include "editor_data.h"
-#include "editor_name_dialog.h"
+
+#include "editor_plugin_settings.h"
+
//#include "project_export_settings.h"
class ProjectSettings : public AcceptDialog {
@@ -67,8 +69,6 @@ class ProjectSettings : public AcceptDialog {
Label *device_index_label;
MenuButton *popup_platform;
- EditorNameDialog *rename_action;
-
LineEdit *action_name;
Tree *input_editor;
bool setting;
@@ -92,6 +92,9 @@ class ProjectSettings : public AcceptDialog {
LineEdit *autoload_add_name;
LineEdit *autoload_add_path;
+
+ EditorPluginSettings *plugin_settings;
+
void _update_autoload();
void _autoload_file_callback(const String& p_path);
void _autoload_add();
@@ -111,11 +114,11 @@ class ProjectSettings : public AcceptDialog {
void _action_adds(String);
void _action_add();
- void _action_rename(const String& p_name);
void _device_input_add();
void _item_checked(const String& p_item, bool p_check);
- void _action_persist_toggle();
+ void _action_selected();
+ void _action_edited();
void _action_button_pressed(Object* p_obj, int p_column,int p_id);
void _wait_for_key(const InputEvent& p_event);
void _press_a_key_confirm();
@@ -145,6 +148,8 @@ class ProjectSettings : public AcceptDialog {
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
+
+
ProjectSettings();
@@ -160,6 +165,8 @@ public:
static ProjectSettings *get_singleton() { return singleton; }
void popup_project_settings();
+ void queue_save();
+
ProjectSettings(EditorData *p_data);
};
diff --git a/tools/editor/settings_config_dialog.cpp b/tools/editor/settings_config_dialog.cpp
index 86a3ab7001..6b7c2eb9b7 100644
--- a/tools/editor/settings_config_dialog.cpp
+++ b/tools/editor/settings_config_dialog.cpp
@@ -80,173 +80,6 @@ void EditorSettingsDialog::popup_edit_settings() {
}
-void EditorSettingsDialog::_plugin_install() {
-
- EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[plugin_setting_edit];
-
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- da->change_dir("res://");
- if (da->change_dir("plugins")!=OK) {
-
- Error err = da->make_dir("plugins");
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- err = da->change_dir("plugins");
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- }
-
- if (da->change_dir(plugin_setting_edit)!=OK) {
-
- Error err = da->make_dir(plugin_setting_edit);
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- err = da->change_dir(plugin_setting_edit);
- if (err)
- memdelete(da);
- ERR_FAIL_COND(err!=OK);
- }
-
- Vector<String> ifiles=plugin.install_files;
-
- if (ifiles.find("plugin.cfg")==-1) {
- ifiles.push_back("plugin.cfg");
- }
-
- if (ifiles.find(plugin.script)==-1) {
- ifiles.push_back(plugin.script);
- }
-
- for(int i=0;i<ifiles.size();i++) {
-
- String target = "res://plugins/"+plugin_setting_edit+"/"+ifiles[i];
- Error err = da->copy(EditorSettings::get_singleton()->get_settings_path().plus_file("plugins/"+plugin_setting_edit+"/"+ifiles[i]),target);
- if (err)
- memdelete(da);
- ERR_EXPLAIN("Error copying to file "+target);
- ERR_FAIL_COND(err!=OK);
- EditorFileSystem::get_singleton()->update_file(target);
- }
-
- memdelete(da);
-
- Globals::get_singleton()->set("plugins/"+plugin_setting_edit,"res://plugins/"+plugin_setting_edit);
- Globals::get_singleton()->set_persisting("plugins/"+plugin_setting_edit,true);
- EditorSettings::get_singleton()->load_installed_plugin(plugin_setting_edit);
- Globals::get_singleton()->save();
-
-
- _update_plugins();
-}
-
-void EditorSettingsDialog::_rescan_plugins() {
-
- EditorSettings::get_singleton()->scan_plugins();
- _update_plugins();
-}
-
-void EditorSettingsDialog::_plugin_edited() {
-
- if (updating)
- return;
-
- TreeItem *ti=plugins->get_edited();
- if (!ti)
- return;
-
- String plugin = ti->get_metadata(0);
- bool enabled = ti->is_checked(0);
-
- EditorSettings::get_singleton()->set_plugin_enabled(plugin,enabled);
-}
-
-void EditorSettingsDialog::_plugin_settings(Object *p_obj,int p_cell,int p_index) {
-
- TreeItem *ti=p_obj->cast_to<TreeItem>();
-
- EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[ti->get_metadata(0)];
-
- plugin_description->clear();
- plugin_description->parse_bbcode(plugin.description);
- plugin_setting_edit = ti->get_metadata(0);
- if (plugin.installs) {
- if (Globals::get_singleton()->has("plugins/"+plugin_setting_edit))
- plugin_setting->get_ok()->set_text("Re-Install to Project");
- else
- plugin_setting->get_ok()->set_text("Install to Project");
- plugin_setting->get_ok()->show();
- plugin_setting->get_cancel()->set_text("Close");
- } else {
- plugin_setting->get_ok()->hide();
- plugin_setting->get_cancel()->set_text("Close");
- }
-
- plugin_setting->set_title(plugin.name);
- plugin_setting->popup_centered(Size2(300,200));
-}
-
-void EditorSettingsDialog::_update_plugins() {
-
-
- updating=true;
-
- plugins->clear();
- TreeItem *root = plugins->create_item(NULL);
- plugins->set_hide_root(true);
-
- Color sc = get_color("prop_subsection","Editor");
- TreeItem *editor = plugins->create_item(root);
- editor->set_text(0,"Editor Plugins");
- editor->set_custom_bg_color(0,sc);
- editor->set_custom_bg_color(1,sc);
- editor->set_custom_bg_color(2,sc);
-
- TreeItem *install = plugins->create_item(root);
- install->set_text(0,"Installable Plugins");
- install->set_custom_bg_color(0,sc);
- install->set_custom_bg_color(1,sc);
- install->set_custom_bg_color(2,sc);
-
- for (const Map<String,EditorSettings::Plugin>::Element *E=EditorSettings::get_singleton()->get_plugins().front();E;E=E->next()) {
-
-
- TreeItem *ti = plugins->create_item(E->get().installs?install:editor);
- if (!E->get().installs) {
- ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
- ti->set_editable(0,true);
- if (EditorSettings::get_singleton()->is_plugin_enabled(E->key()))
- ti->set_checked(0,true);
-
- ti->set_text(0,E->get().name);
- } else {
-
- if (Globals::get_singleton()->has("plugins/"+E->key())) {
-
- ti->set_text(0,E->get().name+" (Installed)");
- } else {
- ti->set_text(0,E->get().name);
- }
- }
-
-
- ti->add_button(0,get_icon("Tools","EditorIcons"),0);
- ti->set_text(1,E->get().author);
- ti->set_text(2,E->get().version);
- ti->set_metadata(0,E->key());
-
- }
-
- if (!editor->get_children())
- memdelete(editor);
- if (!install->get_children())
- memdelete(install);
-
- updating=false;
-
-}
void EditorSettingsDialog::_clear_search_box() {
@@ -261,9 +94,7 @@ void EditorSettingsDialog::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
- rescan_plugins->set_icon(get_icon("Reload","EditorIcons"));
clear_button->set_icon(get_icon("Close","EditorIcons"));
- _update_plugins();
}
}
@@ -271,10 +102,6 @@ void EditorSettingsDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_settings_save"),&EditorSettingsDialog::_settings_save);
ObjectTypeDB::bind_method(_MD("_settings_changed"),&EditorSettingsDialog::_settings_changed);
- ObjectTypeDB::bind_method(_MD("_rescan_plugins"),&EditorSettingsDialog::_rescan_plugins);
- ObjectTypeDB::bind_method(_MD("_plugin_settings"),&EditorSettingsDialog::_plugin_settings);
- ObjectTypeDB::bind_method(_MD("_plugin_edited"),&EditorSettingsDialog::_plugin_edited);
- ObjectTypeDB::bind_method(_MD("_plugin_install"),&EditorSettingsDialog::_plugin_install);
ObjectTypeDB::bind_method(_MD("_clear_search_box"),&EditorSettingsDialog::_clear_search_box);
}
@@ -324,32 +151,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
//Button *load = memnew( Button );
//load->set_text("Load..");
//hbc->add_child(load);
- Button *rescan = memnew( Button );
- rescan_plugins=rescan;
- rescan_plugins->connect("pressed",this,"_rescan_plugins");
- hbc->add_child(rescan);
- plugins = memnew( Tree );
- MarginContainer *mc = memnew( MarginContainer);
- vbc->add_child(mc);
- mc->add_child(plugins);
- mc->set_v_size_flags(SIZE_EXPAND_FILL);
- plugins->set_columns(3);
- plugins->set_column_title(0,"Name");
- plugins->set_column_title(1,"Author");
- plugins->set_column_title(2,"Version");
- plugins->set_column_expand(2,false);
- plugins->set_column_min_width(2,100);
- plugins->set_column_titles_visible(true);
- plugins->connect("button_pressed",this,"_plugin_settings");
- plugins->connect("item_edited",this,"_plugin_edited");
-
- plugin_setting = memnew( ConfirmationDialog );
- add_child(plugin_setting);
- plugin_description = memnew( RichTextLabel );
- plugin_setting->add_child(plugin_description);
- plugin_setting->set_child_rect(plugin_description);
- plugin_setting->connect("confirmed",this,"_plugin_install");
-
//get_ok()->set_text("Apply");
@@ -363,8 +164,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
add_child(timer);
EditorSettings::get_singleton()->connect("settings_changed",this,"_settings_changed");
get_ok()->set_text("Close");
- install_confirm = memnew( ConfirmationDialog );
- add_child(install_confirm);
updating=false;
diff --git a/tools/editor/settings_config_dialog.h b/tools/editor/settings_config_dialog.h
index e1c3238a64..5085132108 100644
--- a/tools/editor/settings_config_dialog.h
+++ b/tools/editor/settings_config_dialog.h
@@ -40,17 +40,10 @@ class EditorSettingsDialog : public AcceptDialog {
- ConfirmationDialog *install_confirm;
bool updating;
- ConfirmationDialog *plugin_setting;
- String plugin_setting_edit;
-
- RichTextLabel *plugin_description;
TabContainer *tabs;
- Button *rescan_plugins;
- Tree *plugins;
LineEdit *search_box;
ToolButton *clear_button;
SectionedPropertyEditor *property_editor;
@@ -60,18 +53,11 @@ class EditorSettingsDialog : public AcceptDialog {
virtual void cancel_pressed();
virtual void ok_pressed();
- void _plugin_edited();
-
- void _plugin_settings(Object *p_obj,int p_cell,int p_index);
void _settings_changed();
void _settings_save();
- void _plugin_install();
-
void _notification(int p_what);
- void _rescan_plugins();
- void _update_plugins();
void _clear_search_box();
diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp
index 320b0c3a70..de35672278 100644
--- a/tools/editor/spatial_editor_gizmos.cpp
+++ b/tools/editor/spatial_editor_gizmos.cpp
@@ -43,7 +43,7 @@
#define HANDLE_HALF_SIZE 0.05
-void SpatialGizmoTool::clear() {
+void EditorSpatialGizmo::clear() {
for(int i=0;i<instances.size();i++) {
@@ -61,7 +61,15 @@ void SpatialGizmoTool::clear() {
secondary_handles.clear();
}
-void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
+void EditorSpatialGizmo::redraw() {
+
+ if (get_script_instance() && get_script_instance()->has_method("redraw"))
+ get_script_instance()->call("redraw");
+
+
+}
+
+void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
instance = VS::get_singleton()->instance_create2(mesh->get_rid(),p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_ID(instance,p_base->get_instance_ID());
@@ -80,7 +88,7 @@ void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
-void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
+void EditorSpatialGizmo::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -97,7 +105,7 @@ void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const
}
-void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
+void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -150,7 +158,7 @@ void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Mater
}
-void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
+void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -201,12 +209,12 @@ void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,fl
}
-void SpatialGizmoTool::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
+void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
collision_mesh=p_tmesh;
}
-void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
+void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
int from=collision_segments.size();
collision_segments.resize(from+p_lines.size());
@@ -217,7 +225,7 @@ void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
}
-void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
+void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
billboard_handle=p_billboard;
@@ -354,13 +362,14 @@ void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_bill
}
-void SpatialGizmoTool::set_spatial_node(Spatial *p_node){
+void EditorSpatialGizmo::set_spatial_node(Spatial *p_node){
+ ERR_FAIL_NULL(p_node);
spatial_node=p_node;
}
-bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
+bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@@ -401,7 +410,7 @@ bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Pla
}
-bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
+bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@@ -631,7 +640,7 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
-void SpatialGizmoTool::create() {
+void EditorSpatialGizmo::create() {
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(valid);
@@ -646,7 +655,7 @@ void SpatialGizmoTool::create() {
}
-void SpatialGizmoTool::transform(){
+void EditorSpatialGizmo::transform(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@@ -657,7 +666,7 @@ void SpatialGizmoTool::transform(){
}
-void SpatialGizmoTool::free(){
+void EditorSpatialGizmo::free(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@@ -675,19 +684,39 @@ void SpatialGizmoTool::free(){
}
+void EditorSpatialGizmo::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("add_lines","lines","material:Material","billboard"),&EditorSpatialGizmo::add_lines,DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("add_mesh","mesh:Mesh","billboard","skeleton"),&EditorSpatialGizmo::add_mesh,DEFVAL(false),DEFVAL(RID()));
+ ObjectTypeDB::bind_method(_MD("add_collision_segments","segments"),&EditorSpatialGizmo::add_collision_segments);
+ ObjectTypeDB::bind_method(_MD("add_collision_triangles","triangles:TriangleMesh"),&EditorSpatialGizmo::add_collision_triangles);
+ ObjectTypeDB::bind_method(_MD("add_unscaled_billboard","material:Material","default_scale"),&EditorSpatialGizmo::add_unscaled_billboard,DEFVAL(1));
+ ObjectTypeDB::bind_method(_MD("add_handles","handles","billboard","secondary"),&EditorSpatialGizmo::add_handles,DEFVAL(false),DEFVAL(false));
+ ObjectTypeDB::bind_method(_MD("set_spatial_node","node:Spatial"),&EditorSpatialGizmo::_set_spatial_node);
+
+ BIND_VMETHOD( MethodInfo("redraw"));
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"get_handle_name",PropertyInfo(Variant::INT,"index")));
+ {
+ BIND_VMETHOD( MethodInfo("get_handle_value:Variant",PropertyInfo(Variant::INT,"index")));
+ }
+ BIND_VMETHOD( MethodInfo("set_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::OBJECT,"camera:Camera"),PropertyInfo(Variant::VECTOR2,"point")));
+ MethodInfo cm = MethodInfo("commit_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::NIL,"restore:Variant"),PropertyInfo(Variant::BOOL,"cancel"));
+ cm.default_arguments.push_back(false);
+ BIND_VMETHOD( cm );
+}
-SpatialGizmoTool::SpatialGizmoTool() {
+EditorSpatialGizmo::EditorSpatialGizmo() {
valid=false;
billboard_handle=false;
}
-SpatialGizmoTool::~SpatialGizmoTool(){
+EditorSpatialGizmo::~EditorSpatialGizmo(){
clear();
}
-Vector3 SpatialGizmoTool::get_handle_pos(int p_idx) const {
+Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,handles.size(),Vector3());
diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h
index 669d3e2380..346e360225 100644
--- a/tools/editor/spatial_editor_gizmos.h
+++ b/tools/editor/spatial_editor_gizmos.h
@@ -52,9 +52,9 @@
class Camera;
-class SpatialGizmoTool : public SpatialEditorGizmo {
+class EditorSpatialGizmo : public SpatialEditorGizmo {
- OBJ_TYPE(SpatialGizmoTool,SpatialGizmo);
+ OBJ_TYPE(EditorSpatialGizmo,SpatialGizmo);
struct Instance{
@@ -93,6 +93,8 @@ class SpatialGizmoTool : public SpatialEditorGizmo {
Spatial *base;
Vector<Instance> instances;
Spatial *spatial_node;
+
+ void _set_spatial_node(Node *p_node) { set_spatial_node(p_node->cast_to<Spatial>()); }
protected:
void add_lines(const Vector<Vector3> &p_lines,const Ref<Material>& p_material,bool p_billboard=false);
void add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard=false,const RID& p_skeleton=RID());
@@ -103,6 +105,7 @@ protected:
void set_spatial_node(Spatial *p_node);
+ static void _bind_methods();
public:
virtual Vector3 get_handle_pos(int p_idx) const;
@@ -112,18 +115,18 @@ public:
void clear();
void create();
void transform();
- //void redraw();
+ virtual void redraw();
void free();
- SpatialGizmoTool();
- ~SpatialGizmoTool();
+ EditorSpatialGizmo();
+ ~EditorSpatialGizmo();
};
-class LightSpatialGizmo : public SpatialGizmoTool {
+class LightSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(LightSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(LightSpatialGizmo,EditorSpatialGizmo);
Light* light;
@@ -140,9 +143,9 @@ public:
};
-class CameraSpatialGizmo : public SpatialGizmoTool {
+class CameraSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CameraSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CameraSpatialGizmo,EditorSpatialGizmo);
Camera* camera;
@@ -161,9 +164,9 @@ public:
-class MeshInstanceSpatialGizmo : public SpatialGizmoTool {
+class MeshInstanceSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(MeshInstanceSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(MeshInstanceSpatialGizmo,EditorSpatialGizmo);
MeshInstance* mesh;
@@ -174,9 +177,9 @@ public:
};
-class Position3DSpatialGizmo : public SpatialGizmoTool {
+class Position3DSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(Position3DSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(Position3DSpatialGizmo,EditorSpatialGizmo);
Position3D* p3d;
@@ -187,9 +190,9 @@ public:
};
-class SkeletonSpatialGizmo : public SpatialGizmoTool {
+class SkeletonSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SkeletonSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SkeletonSpatialGizmo,EditorSpatialGizmo);
Skeleton* skel;
@@ -203,9 +206,9 @@ public:
-class SpatialPlayerSpatialGizmo : public SpatialGizmoTool {
+class SpatialPlayerSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SpatialPlayerSpatialGizmo,EditorSpatialGizmo);
SpatialPlayer* splayer;
@@ -218,9 +221,9 @@ public:
-class TestCubeSpatialGizmo : public SpatialGizmoTool {
+class TestCubeSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(TestCubeSpatialGizmo,EditorSpatialGizmo);
TestCube* tc;
@@ -231,9 +234,9 @@ public:
};
-class RoomSpatialGizmo : public SpatialGizmoTool {
+class RoomSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(RoomSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(RoomSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@@ -256,9 +259,9 @@ public:
};
-class PortalSpatialGizmo : public SpatialGizmoTool {
+class PortalSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PortalSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PortalSpatialGizmo,EditorSpatialGizmo);
Portal* portal;
@@ -270,9 +273,9 @@ public:
};
-class VisibilityNotifierGizmo : public SpatialGizmoTool {
+class VisibilityNotifierGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(VisibilityNotifierGizmo ,SpatialGizmoTool);
+ OBJ_TYPE(VisibilityNotifierGizmo ,EditorSpatialGizmo);
VisibilityNotifier* notifier;
@@ -291,9 +294,9 @@ public:
-class CollisionShapeSpatialGizmo : public SpatialGizmoTool {
+class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CollisionShapeSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CollisionShapeSpatialGizmo,EditorSpatialGizmo);
CollisionShape* cs;
@@ -308,9 +311,9 @@ public:
};
-class CollisionPolygonSpatialGizmo : public SpatialGizmoTool {
+class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(CollisionPolygonSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(CollisionPolygonSpatialGizmo,EditorSpatialGizmo);
CollisionPolygon* polygon;
@@ -322,9 +325,9 @@ public:
};
-class RayCastSpatialGizmo : public SpatialGizmoTool {
+class RayCastSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(RayCastSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(RayCastSpatialGizmo,EditorSpatialGizmo);
RayCast* raycast;
@@ -337,9 +340,9 @@ public:
-class VehicleWheelSpatialGizmo : public SpatialGizmoTool {
+class VehicleWheelSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(VehicleWheelSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(VehicleWheelSpatialGizmo,EditorSpatialGizmo);
VehicleWheel* car_wheel;
@@ -351,9 +354,9 @@ public:
};
-class NavigationMeshSpatialGizmo : public SpatialGizmoTool {
+class NavigationMeshSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(NavigationMeshSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(NavigationMeshSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@@ -376,9 +379,9 @@ public:
};
-class PinJointSpatialGizmo : public SpatialGizmoTool {
+class PinJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(PinJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(PinJointSpatialGizmo,EditorSpatialGizmo);
PinJoint* p3d;
@@ -390,9 +393,9 @@ public:
};
-class HingeJointSpatialGizmo : public SpatialGizmoTool {
+class HingeJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(HingeJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(HingeJointSpatialGizmo,EditorSpatialGizmo);
HingeJoint* p3d;
@@ -403,9 +406,9 @@ public:
};
-class SliderJointSpatialGizmo : public SpatialGizmoTool {
+class SliderJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(SliderJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(SliderJointSpatialGizmo,EditorSpatialGizmo);
SliderJoint* p3d;
@@ -416,9 +419,9 @@ public:
};
-class ConeTwistJointSpatialGizmo : public SpatialGizmoTool {
+class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(ConeTwistJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(ConeTwistJointSpatialGizmo,EditorSpatialGizmo);
ConeTwistJoint* p3d;
@@ -430,9 +433,9 @@ public:
};
-class Generic6DOFJointSpatialGizmo : public SpatialGizmoTool {
+class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo {
- OBJ_TYPE(Generic6DOFJointSpatialGizmo,SpatialGizmoTool);
+ OBJ_TYPE(Generic6DOFJointSpatialGizmo,EditorSpatialGizmo);
Generic6DOFJoint* p3d;
diff --git a/tools/scripts/sort-demos.sh b/tools/scripts/sort-demos.sh
new file mode 100644
index 0000000000..d4770b337e
--- /dev/null
+++ b/tools/scripts/sort-demos.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# When scanning for demos, the project manager sorts them based on their
+# timestamp, i.e. last modification date. This can make for a pretty
+# messy output, so this script 'touches' each engine.cfg file in reverse
+# alphabetical order to ensure a nice listing.
+#
+# It's good practice to run it once before packaging demos on the build
+# server.
+
+if [ ! -d "demos" ]; then
+ echo "Run this script from the root directory where 'demos/' is contained."
+ exit 1
+fi
+
+if [ -e demos.list ]; then
+ rm -f demos.list
+fi
+
+for dir in 2d 3d gui misc viewport; do
+ find "demos/$dir" -name "engine.cfg" |sort >> demos.list
+done
+cat demos.list |sort -r > demos_r.list
+
+while read line; do
+ touch $line
+ sleep 0.2
+done < demos_r.list
+
+#rm -f demos.list demos_r.list
diff --git a/tools/steam/community_capsule.jpg b/tools/steam/community_capsule.jpg
new file mode 100644
index 0000000000..abbc4793f7
--- /dev/null
+++ b/tools/steam/community_capsule.jpg
Binary files differ
diff --git a/tools/steam/community_capsule.png b/tools/steam/community_capsule.png
new file mode 100644
index 0000000000..ec9fa0a930
--- /dev/null
+++ b/tools/steam/community_capsule.png
Binary files differ
diff --git a/tools/steam/header.png b/tools/steam/header.png
new file mode 100644
index 0000000000..547b28df8d
--- /dev/null
+++ b/tools/steam/header.png
Binary files differ
diff --git a/tools/steam/icon32.icns b/tools/steam/icon32.icns
new file mode 100644
index 0000000000..ad8e642d51
--- /dev/null
+++ b/tools/steam/icon32.icns
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32" enable-background="new 0 0 32 32" xml:space="preserve"> <image id="image0" width="32" height="32" x="0" y="0"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJN
+AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAA
+CXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AIcEDAUYyVLmwAABuxJREFUWMPFl9tvVNcVxn/7
+nLnfgRl7xpdggrGxja2SpuXSEEUkVNCHqqmqpoJETatGkVpV6gP5L/rQ20vyVpFWLUilTUmhTeSQ
+0DjUYCOgYGxMmfFtbOzx3K9nztl9OJ7xDbBDFXVJo9E+Z+29vr0u31pHSCkl/0dRNqtY1Q0mEgX6
+R+aIp4vr3sfTRfpH5phIFKjqxqYBWDZSkMC1WJLzN2a4NZ0mka/w8jMtvPlCO0Is6Uj4y/A0Z4en
+2Oq2safZz7G+JvZu34L4Xz2gVQ3ODE7QPzJHIlcBCZfG5okl8nWdWCLPpbF5kLCYq9A/MseZwQm0
+6sae2NADiiKwWhQUIeo3TuTKvHNxnJDXAcB8tkQiV66/V8TSHmWj+28CgKoIvI71aleji9TSVwjT
+6ErxOiyomwCwKgRlTSdZqNTXEhiNZ4glCqw5H0UIVMX8rTUuBMQSBUbjGVaWWLJQoazpq3VrZWhI
+yenBCT4Zneebe5s51BFiYHyB3/7zPg+ypXVGNhJDShq8Dr7/3A4Otge5NDbPe9emeb4zxHe/+lT9
+vDqAgfEFfn7hDtmihsOq0t7oIbZQIFfWPrfxlSA8divbgy7G53KUNB2v08rJo7s52B5cDsFcpsS7
+A1FyJQ1VEWi6wa3pNPlK9YmN18KUr1S5NZ1G0w1URZArabw7EGUuU1oGMBrPEF3IrzKmCLFhDW9G
+BKw7N7qQZzSeWQbQ1xqgu9mHYXzxrGwYku5mH32tgWUAAZeNE/vbCLhtrO0MhpTohsT4HC1DStAN
+c59c8zzgXrLlsi0DANjT4qcj7F1lSBGC3RE/R/ZE6GoKbCofpIRwwMnh7jD7dwbx2C31SxlS0hH2
+sqfFX9e3rDRmUVbH6uUvt/DtvRFS87Ng9dF/38fZoak6yNp/DZghJb0tW/jBgSZslTRbt4W5k4jw
+mw/HSOZNfrGs4Y2HMqEhJTsbPHzrSxH+9Iffce7c+4RCQV5/8ydcb/AyNptGEYL9O4M0B5ycvxmn
+WNFx2iwc3e3nvVPv8Nnlf9HR0cHJt07yYk+YM4Oxh3rsoc1ISmjd5qaQTnDhwt9Jp9OMjo5xZeAT
+mgIOpDQp+ht9TRw/sJ0Grx1DSvwuG7m5CT7++BK5XJ6hoWGGh66yq9GH+ojwPbIbpgoaQrXidrvR
+dR1FUXC5vWRKVcAsrxoN15pOqaJjqDYcDju6rmOxWPB4vCzmyzyqwB4aAkUR3JlJcy/TyBtv/Ij3
+z/2VxnCELZ37uHA9uSKGZpZLTP5PFyvcr4R45cRrDA9epq+vl6ZdvZzuj7K6Hh4BwJCm+wVQrOi8
+ffEeR3qaef74T5lMljh7e55CuYoQUDUkd+JZpIRMQUNgEtfFsQT7nu7m0PGvoKPyq4tRxueyKEJQ
+lXKdJ4SUUuqGpFjR+eDWLGeuTJiDhzBJw5ASVVEAaRpZEUqrqmBRBcXK6g5nSFNXlxIpJRZFAQF2
+i8J3nm3llX3bsapm+ISUUs6kivz6wzGe2xViOlnk9JUJXtjdwI6gm9hCnqlkkelUsd5K5VIOyKWF
+EMvPWMqNBp+Dli1OntrmRgB/vjZNe4OH7+3bzkcjc7x+aAcRv9MMgW5IxmazuG0W2kJuFAHdER9C
+CHaEPBzZE+bTuwv87foMiiI43NVIT5OfqmHUeSBVqHB2aIpcucrOBg8/PPQ0k4sFUgWNzrCX8zfj
+eOwWJhfzDMeSvHqwbTkHAi4rDT4HD7IlXuoJ8+PDu2jZ6uL3n0W5NpHiaG+EoMdO1ZBYBHQ3+ZhM
+Fogt5FEEOKwqL3aHcVhVUkUNp1Ullsjz9kf3cNtV3jrWxasH2gj7HQz+J0HIayfgsi4D8DqsfK09
+yKmBKL/8YJSuiI+SZpDMa6jCnJT6WgOUtFYSuTI+p5Xb/57l9oxJSC6byvOdDTzTtgVVCHpa/GSK
+ZrlWDcnITIZcucq569PMpIqc2N+G17ECAMDR3ghDsUVuTqVZyM7z6d0FhABVVbg5lQKg0e+gp9lP
+oayTKWpYFAUhzOqZThboiviZz5W4MZliZCYDAipVgz9emcAwzITsbQ1wtDeyugpqi7tzWX7xj1HG
+ZrOrBkoJ9VZdmwXXdkdFiHrnhPWDqm6YjehnX+9kV6P34QAAJhcLnBqIMjC+QFnTUZQnH0xqwO1W
+hYPtQV47uIPWra71PLB2Y0nTuXwvwfkbM9yZzVIoV+u33KgjSwlSmrznslvYHfZyrK+J/Tu34bCq
+6/TF4z5OCxWd0XiGq9FFRmYyxNNFcqUqmm6YIajtXHK3VVXwOCxE/E66mnw827aVzogPl019lInH
+A1gpxYpOIlfmQbZMIlcmU9QoL3162S0KPqeVbR47Ia+doMeO8zFGnwjAFyX/BYjmM60If3mlAAAA
+JXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAyLTI4VDE2OjQ4OjIwKzAxOjAwv25h8wAAACV0RVh0ZGF0
+ZTptb2RpZnkAMjAxNi0wMi0yOFQxNjo0ODoyMCswMTowMM4z2U8AAAAZdEVYdFNvZnR3YXJlAHd3
+dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC" />
+</svg>
diff --git a/tools/steam/icon32.ico b/tools/steam/icon32.ico
new file mode 100644
index 0000000000..f52b1466ea
--- /dev/null
+++ b/tools/steam/icon32.ico
Binary files differ
diff --git a/tools/steam/icons.zip b/tools/steam/icons.zip
new file mode 100644
index 0000000000..54d6697e4e
--- /dev/null
+++ b/tools/steam/icons.zip
Binary files differ
diff --git a/tools/steam/large_capsule.png b/tools/steam/large_capsule.png
new file mode 100644
index 0000000000..14c8ff86d7
--- /dev/null
+++ b/tools/steam/large_capsule.png
Binary files differ
diff --git a/tools/steam/main_capsule.png b/tools/steam/main_capsule.png
new file mode 100644
index 0000000000..5af9406d11
--- /dev/null
+++ b/tools/steam/main_capsule.png
Binary files differ
diff --git a/tools/steam/make_icons.sh b/tools/steam/make_icons.sh
new file mode 100644
index 0000000000..71037cd1c3
--- /dev/null
+++ b/tools/steam/make_icons.sh
@@ -0,0 +1,5 @@
+convert -resize 32x32 ../../icon.svg icon32.ico
+convert -resize 32x32 ../../icon.svg icon32.icns
+for s in 16 24 32 64 96 128 256; do convert -resize ${s}x$s ../../icon.svg icon$s.png; done
+zip icons.zip icon*.png
+rm icon*.png
diff --git a/tools/steam/small_capsule.png b/tools/steam/small_capsule.png
new file mode 100644
index 0000000000..991896728d
--- /dev/null
+++ b/tools/steam/small_capsule.png
Binary files differ
diff --git a/version.py b/version.py
index 0fa26cfc16..86e28ec51d 100644
--- a/version.py
+++ b/version.py
@@ -2,7 +2,7 @@ short_name="godot"
name="Godot Engine"
major=2
minor=0
-status="rc1"
+status="stable"