summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml17
-rw-r--r--README.md1
-rw-r--r--core/io/logger.cpp12
-rw-r--r--drivers/unix/os_unix.cpp26
-rw-r--r--editor/animation_track_editor.cpp4
-rw-r--r--editor/editor_file_system.cpp30
-rw-r--r--editor/editor_file_system.h1
-rw-r--r--editor/filesystem_dock.cpp8
-rw-r--r--editor/find_in_files.cpp4
-rw-r--r--editor/icons/icon_godot_docs.svg1
-rw-r--r--editor/icons/icon_particle_attractor_2d.svg1
-rw-r--r--editor/inspector_dock.cpp2
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp19
-rw-r--r--editor/plugins/asset_library_editor_plugin.h1
-rw-r--r--editor/plugins/mesh_instance_editor_plugin.cpp70
-rw-r--r--editor/plugins/mesh_instance_editor_plugin.h4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp4
-rw-r--r--editor/project_manager.cpp36
-rw-r--r--editor/project_settings_editor.cpp38
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h7
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp6
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp3
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp24
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h1
-rw-r--r--modules/visual_script/visual_script_nodes.cpp23
-rw-r--r--platform/iphone/export/export.cpp191
-rw-r--r--platform/osx/os_osx.mm35
-rw-r--r--platform/windows/windows_terminal_logger.cpp68
-rw-r--r--platform/x11/os_x11.cpp98
-rw-r--r--scene/gui/text_edit.cpp73
30 files changed, 588 insertions, 220 deletions
diff --git a/.travis.yml b/.travis.yml
index c8b123c79c..d39d6383ea 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -72,12 +72,20 @@ matrix:
env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang EXTRA_ARGS="warnings=extra werror=yes"
os: osx
compiler: clang
+ addons:
+ homebrew:
+ packages:
+ - scons
- name: iOS export template (debug, Clang)
stage: build
env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang
os: osx
compiler: clang
+ addons:
+ homebrew:
+ packages:
+ - scons
- name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running)
stage: build
@@ -109,16 +117,17 @@ before_install:
fi
install:
- - pip install --user scons;
+ - if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+ pyenv global 3.7.1 system;
+ pip3 install --user scons;
+ fi
+ - scons --version
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$PLATFORM" = "android" ]; then
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64;
export PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/bin:${PATH};
java -version;
misc/travis/android-tools-linux.sh;
fi
- - if [ "$TRAVIS_OS_NAME" = "osx" ]; then
- export PATH=${PATH}:/Users/travis/Library/Python/2.7/bin;
- fi
before_script:
- if [ "$PLATFORM" = "android" ]; then
diff --git a/README.md b/README.md
index 9e772fa89f..1202dabc8c 100644
--- a/README.md
+++ b/README.md
@@ -70,3 +70,4 @@ for more info.
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bfiihqq6byxsjxxh/branch/master?svg=true)](https://ci.appveyor.com/project/akien-mga/godot)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
+[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index c3ea0d024e..4d732332d5 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -58,12 +58,12 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
return;
}
- const char *err_type = "**ERROR**";
+ const char *err_type = "ERROR";
switch (p_type) {
- case ERR_ERROR: err_type = "**ERROR**"; break;
- case ERR_WARNING: err_type = "**WARNING**"; break;
- case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
- case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
+ case ERR_ERROR: err_type = "ERROR"; break;
+ case ERR_WARNING: err_type = "WARNING"; break;
+ case ERR_SCRIPT: err_type = "SCRIPT ERROR"; break;
+ case ERR_SHADER: err_type = "SHADER ERROR"; break;
default: ERR_PRINT("Unknown error type"); break;
}
@@ -74,7 +74,7 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
err_details = p_code;
logf_error("%s: %s\n", err_type, err_details);
- logf_error(" At: %s:%i:%s() - %s\n", p_file, p_line, p_function, p_code);
+ logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code);
}
void Logger::logf(const char *p_format, ...) {
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index c5eb343cc8..2d8d37b2f1 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -559,34 +559,34 @@ void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, i
// This prevents Godot from writing ANSI escape codes when redirecting
// stdout and stderr to a file.
const bool tty = isatty(fileno(stdout));
- const char *red = tty ? "\E[0;31m" : "";
+ const char *gray = tty ? "\E[0;90m" : "";
+ const char *red = tty ? "\E[0;91m" : "";
const char *red_bold = tty ? "\E[1;31m" : "";
- const char *yellow = tty ? "\E[0;33m" : "";
+ const char *yellow = tty ? "\E[0;93m" : "";
const char *yellow_bold = tty ? "\E[1;33m" : "";
- const char *magenta = tty ? "\E[0;35m" : "";
+ const char *magenta = tty ? "\E[0;95m" : "";
const char *magenta_bold = tty ? "\E[1;35m" : "";
- const char *cyan = tty ? "\E[0;36m" : "";
+ const char *cyan = tty ? "\E[0;96m" : "";
const char *cyan_bold = tty ? "\E[1;36m" : "";
const char *reset = tty ? "\E[0m" : "";
- const char *bold = tty ? "\E[1m" : "";
switch (p_type) {
case ERR_WARNING:
- logf_error("%sWARNING: %s: %s%s%s\n", yellow_bold, p_function, reset, bold, err_details);
- logf_error("%s At: %s:%i.%s\n", yellow, p_file, p_line, reset);
+ logf_error("%sWARNING:%s %s\n", yellow_bold, yellow, err_details);
+ logf_error("%s at: %s (%s:%i)%s\n", gray, p_function, p_file, p_line, reset);
break;
case ERR_SCRIPT:
- logf_error("%sSCRIPT ERROR: %s: %s%s%s\n", magenta_bold, p_function, reset, bold, err_details);
- logf_error("%s At: %s:%i.%s\n", magenta, p_file, p_line, reset);
+ logf_error("%sSCRIPT ERROR:%s %s\n", magenta_bold, magenta, err_details);
+ logf_error("%s at: %s (%s:%i)%s\n", gray, p_function, p_file, p_line, reset);
break;
case ERR_SHADER:
- logf_error("%sSHADER ERROR: %s: %s%s%s\n", cyan_bold, p_function, reset, bold, err_details);
- logf_error("%s At: %s:%i.%s\n", cyan, p_file, p_line, reset);
+ logf_error("%sSHADER ERROR:%s %s\n", cyan_bold, cyan, err_details);
+ logf_error("%s at: %s (%s:%i)%s\n", gray, p_function, p_file, p_line, reset);
break;
case ERR_ERROR:
default:
- logf_error("%sERROR: %s: %s%s%s\n", red_bold, p_function, reset, bold, err_details);
- logf_error("%s At: %s:%i.%s\n", red, p_file, p_line, reset);
+ logf_error("%sERROR:%s %s\n", red_bold, red, err_details);
+ logf_error("%s at: %s (%s:%i)%s\n", gray, p_function, p_file, p_line, reset);
break;
}
}
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index e9719f8618..2edfcced60 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1727,7 +1727,7 @@ void AnimationTimelineEdit::update_values() {
time_icon->set_tooltip(TTR("Animation length (frames)"));
} else {
length->set_value(animation->get_length());
- length->set_step(0.01);
+ length->set_step(0.001);
length->set_tooltip(TTR("Animation length (seconds)"));
time_icon->set_tooltip(TTR("Animation length (seconds)"));
}
@@ -1890,7 +1890,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
length = memnew(EditorSpinSlider);
length->set_min(0.001);
length->set_max(36000);
- length->set_step(0.01);
+ length->set_step(0.001);
length->set_allow_greater(true);
length->set_custom_minimum_size(Vector2(70 * EDSCALE, 0));
length->set_hide_slider(true);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index 04fe6e5ce6..107ecac3b0 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -675,9 +675,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
if (f == "")
break;
+ if (da->current_is_hidden())
+ continue;
+
if (da->current_is_dir()) {
- if (f.begins_with(".")) //ignore hidden and . / ..
+ if (f.begins_with(".")) // Ignore special and . / ..
continue;
if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this
@@ -871,9 +874,12 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
if (f == "")
break;
+ if (da->current_is_hidden())
+ continue;
+
if (da->current_is_dir()) {
- if (f.begins_with(".")) //ignore hidden and . / ..
+ if (f.begins_with(".")) // Ignore special and . / ..
continue;
int idx = p_dir->find_dir_index(f);
@@ -1059,8 +1065,12 @@ void EditorFileSystem::get_changed_sources(List<String> *r_changed) {
void EditorFileSystem::scan_changes() {
- if (scanning || scanning_changes || thread)
+ if (first_scan || // Prevent a premature changes scan from inhibiting the first full scan
+ scanning || scanning_changes || thread) {
+ scan_changes_pending = true;
+ set_process(true);
return;
+ }
_update_extensions();
sources_changed.clear();
@@ -1105,15 +1115,17 @@ void EditorFileSystem::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- if (use_threads && thread) {
+ Thread *active_thread = thread ? thread : thread_sources;
+ if (use_threads && active_thread) {
//abort thread if in progress
abort_scan = true;
while (scanning) {
OS::get_singleton()->delay_usec(1000);
}
- Thread::wait_to_finish(thread);
- memdelete(thread);
+ Thread::wait_to_finish(active_thread);
+ memdelete(active_thread);
thread = NULL;
+ thread_sources = NULL;
WARN_PRINT("Scan thread aborted...");
set_process(false);
}
@@ -1164,6 +1176,11 @@ void EditorFileSystem::_notification(int p_what) {
_queue_update_script_classes();
first_scan = false;
}
+
+ if (!is_processing() && scan_changes_pending) {
+ scan_changes_pending = false;
+ scan_changes();
+ }
}
} break;
}
@@ -2138,6 +2155,7 @@ EditorFileSystem::EditorFileSystem() {
scan_total = 0;
update_script_classes_queued = false;
first_scan = true;
+ scan_changes_pending = false;
revalidate_import_files = false;
}
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index ce9936f983..381acc0fe2 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -145,6 +145,7 @@ class EditorFileSystem : public Node {
bool scanning;
bool importing;
bool first_scan;
+ bool scan_changes_pending;
float scan_total;
String filesystem_settings_version_for_import;
bool revalidate_import_files;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 5041441ac3..684942dbad 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1782,6 +1782,14 @@ void FileSystemDock::_resource_created() const {
Resource *r = Object::cast_to<Resource>(c);
ERR_FAIL_COND(!r);
+ PackedScene *scene = Object::cast_to<PackedScene>(r);
+ if (scene) {
+ Node *node = memnew(Node);
+ node->set_name("Node");
+ scene->pack(node);
+ memdelete(node);
+ }
+
REF res(r);
editor->push_item(c);
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index 4ab90ad3e4..b24a5c38f2 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -235,9 +235,11 @@ void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) {
if (file == "")
break;
- // Ignore special dirs and hidden dirs (such as .git and .import)
+ // Ignore special dirs (such as .git and .import)
if (file == "." || file == ".." || file.begins_with("."))
continue;
+ if (dir->current_is_hidden())
+ continue;
if (dir->current_is_dir())
out_folders.append(file);
diff --git a/editor/icons/icon_godot_docs.svg b/editor/icons/icon_godot_docs.svg
deleted file mode 100644
index e38885aed9..0000000000
--- a/editor/icons/icon_godot_docs.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width=".32031" transform="matrix(.017241 0 0 .017241 -.82759 -2.7)"><path d="m0 0s-.325 1.994-.515 1.976l-36.182-3.491c-2.879-.278-5.115-2.574-5.317-5.459l-.994-14.247-27.992-1.997-1.904 12.912c-.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-.994 14.247c-.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-.187.018-.324-1.978-.511-1.978l-.049-7.83 30.658-4.944 1.004-14.374c.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c.146-.01.29-.016.434-.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c.423-2.871 2.93-5.037 5.831-5.037.142 0 .284.005.423.015l38.556 2.75c2.911.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff" transform="matrix(4.1626 0 0 -4.1626 919.24 771.67)"/><path d="m0 0v-59.041c.108-.001.216-.005.323-.015l36.196-3.49c1.896-.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c.107.01.214.014.322.015v4.711l.015.005v54.325h.134c4.795 6.12 9.232 12.569 13.487 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842.642-7.702.88-11.567.926v.006c-.027 0-.052-.006-.075-.006-.024 0-.049.006-.073.006v-.006c-3.872-.046-7.729-.284-11.572-.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17.216-8.34.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.253-6.88 8.693-13.329 13.487-19.449z" fill="#478cbf" transform="matrix(4.1626 0 0 -4.1626 104.7 525.91)"/><path d="m0 0-1.121-16.063c-.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-.094-.007-.188-.01-.281-.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c.015-3.498.06-7.33.06-8.093 0-34.374 43.605-50.896 97.781-51.086h.133c54.176.19 97.766 16.712 97.766 51.086 0 .777.047 4.593.063 8.093z" fill="#478cbf" transform="matrix(4.1626 0 0 -4.1626 784.07 817.24)"/><path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff" transform="matrix(4.1626 0 0 -4.1626 389.21 625.67)"/><path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042" transform="matrix(4.1626 0 0 -4.1626 367.37 631.06)"/><path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff" transform="matrix(4.1626 0 0 -4.1626 511.99 724.74)"/><path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff" transform="matrix(4.1626 0 0 -4.1626 634.79 625.67)"/><path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042" transform="matrix(4.1626 0 0 -4.1626 656.64 631.06)"/></g><path d="m4 5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3h2a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3 3 3 0 0 0 -2.8262 2h-2.3496a3 3 0 0 0 -2.8242-2zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z"/></svg> \ No newline at end of file
diff --git a/editor/icons/icon_particle_attractor_2d.svg b/editor/icons/icon_particle_attractor_2d.svg
deleted file mode 100644
index 85f289dc4b..0000000000
--- a/editor/icons/icon_particle_attractor_2d.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a3 7 0 0 0 -2.0801 1.9668 7 3 45 0 0 -2.8691.083984 7 3 45 0 0 -.080078 2.8633 7 3 0 0 0 -1.9707 2.0859 7 3 0 0 0 1.9668 2.0801 3 7 45 0 0 .083984 2.8691 3 7 45 0 0 2.8633.080078 3 7 0 0 0 2.0859 1.9707 3 7 0 0 0 2.0801-1.9668 7 3 45 0 0 2.8691-.083984 7 3 45 0 0 .080078-2.8633 7 3 0 0 0 1.9707-2.0859 7 3 0 0 0 -1.9668-2.0801 3 7 45 0 0 -.083984-2.8691 3 7 45 0 0 -2.8633-.080078 3 7 0 0 0 -2.0859-1.9707zm0 1a2 6 0 0 1 1.2598 1.3438 3 7 45 0 0 -1.2578.75977 7 3 45 0 0 -1.2637-.75781 2 6 0 0 1 1.2617-1.3457zm-3.6348 1.5293a6 2 45 0 1 1.2344.28906 3 7 0 0 0 -.35352 1.4238 7 3 0 0 0 -1.4297.35742 6 2 45 0 1 -.058594-1.8418 6 2 45 0 1 .60742-.22852zm7.0762.0039062a2 6 45 0 1 .80078.22461 2 6 45 0 1 -.060547 1.8418 7 3 0 0 0 -1.4238-.35352 3 7 0 0 0 -.35742-1.4297 2 6 45 0 1 1.041-.2832zm-4.998.70703a6 2 45 0 1 .74023.4707 3 7 45 0 0 -.41211.33984 7 3 0 0 0 -.52344.048828 2 6 0 0 1 .19531-.85938zm3.1152.0019531a2 6 0 0 1 .18945.85547 7 3 0 0 0 -.5293-.050781 7 3 45 0 0 -.4043-.33594 2 6 45 0 1 .74414-.46875zm-1.5586 1.7578a6 2 0 0 1 .82031.021484 6 2 45 0 1 .59375.56445 6 2 45 0 1 .56445.59375 2 6 0 0 1 .021484.82031 2 6 0 0 1 -.021484.82031 2 6 45 0 1 -.56445.59375 2 6 45 0 1 -.59375.56445 6 2 0 0 1 -.82031.021484 6 2 0 0 1 -.82031-.021484 6 2 45 0 1 -.59375-.56445 6 2 45 0 1 -.56445-.59375 2 6 0 0 1 -.021484-.82031 2 6 0 0 1 .021484-.82031 2 6 45 0 1 .56445-.59375 2 6 45 0 1 .59375-.56445 6 2 0 0 1 .82031-.021484zm2.9004.24805a6 2 0 0 1 .85938.19531 2 6 45 0 1 -.4707.74023 7 3 45 0 0 -.33984-.41211 3 7 0 0 0 -.048828-.52344zm-5.8027.0039062a3 7 0 0 0 -.050781.5293 3 7 45 0 0 -.33594.4043 6 2 45 0 1 -.46875-.74414 6 2 0 0 1 .85547-.18945zm7.5566.48633a6 2 0 0 1 1.3457 1.2617 6 2 0 0 1 -1.3438 1.2598 7 3 45 0 0 -.75977-1.2578 3 7 45 0 0 .75781-1.2637zm-9.3105.0019532a7 3 45 0 0 .75977 1.2578 3 7 45 0 0 -.75781 1.2637 6 2 0 0 1 -1.3457-1.2617 6 2 0 0 1 1.3438-1.2598zm4.6562.25977a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3.2891 1.8145a6 2 45 0 1 .46875.74414 6 2 0 0 1 -.85547.18945 3 7 0 0 0 .050781-.5293 3 7 45 0 0 .33594-.4043zm-6.5781.0019531a7 3 45 0 0 .33984.41211 3 7 0 0 0 .048828.52344 6 2 0 0 1 -.85938-.19531 2 6 45 0 1 .4707-.74023zm-.89258 1.584a7 3 0 0 0 1.4238.35352 3 7 0 0 0 .35742 1.4297 2 6 45 0 1 -1.8418.058594 2 6 45 0 1 .060547-1.8418zm8.3652 0a6 2 45 0 1 .058594 1.8418 6 2 45 0 1 -1.8418-.060547 3 7 0 0 0 .35352-1.4238 7 3 0 0 0 1.4297-.35742zm-2.4316.5a2 6 0 0 1 -.19531.85938 6 2 45 0 1 -.74023-.4707 3 7 45 0 0 .41211-.33984 7 3 0 0 0 .52344-.048828zm-3.5.001953a7 3 0 0 0 .5293.050781 7 3 45 0 0 .4043.33594 2 6 45 0 1 -.74414.46875 2 6 0 0 1 -.18945-.85547zm1.7461.99414a7 3 45 0 0 1.2637.75781 2 6 0 0 1 -1.2617 1.3457 2 6 0 0 1 -1.2598-1.3438 3 7 45 0 0 1.2578-.75977z" fill="#a5b7f3" fill-opacity=".98824"/></svg> \ No newline at end of file
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index b65482cc6b..ecd1e341d1 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -337,6 +337,7 @@ void InspectorDock::_notification(int p_what) {
history_menu->set_icon(get_icon("History", "EditorIcons"));
object_menu->set_icon(get_icon("Tools", "EditorIcons"));
warning->set_icon(get_icon("NodeWarning", "EditorIcons"));
+ warning->add_color_override("font_color", get_color("warning_color", "Editor"));
} break;
}
}
@@ -584,6 +585,7 @@ InspectorDock::InspectorDock(EditorNode *p_editor, EditorData &p_editor_data) {
add_child(warning);
warning->set_text(TTR("Changes may be lost!"));
warning->set_icon(get_icon("NodeWarning", "EditorIcons"));
+ warning->add_color_override("font_color", get_color("warning_color", "Editor"));
warning->set_clip_text(true);
warning->hide();
warning->connect("pressed", this, "_warning_pressed");
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 2428bf82d4..d88a716122 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -31,6 +31,8 @@
#include "asset_library_editor_plugin.h"
#include "core/io/json.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/version.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
@@ -620,6 +622,21 @@ void EditorAssetLibrary::_notification(int p_what) {
}
}
+void EditorAssetLibrary::_unhandled_input(const Ref<InputEvent> &p_event) {
+
+ const Ref<InputEventKey> key = p_event;
+
+ if (key.is_valid() && key->is_pressed()) {
+
+ if (key->get_scancode_with_modifiers() == (KEY_MASK_CMD | KEY_F) && is_visible_in_tree()) {
+
+ filter->grab_focus();
+ filter->select_all();
+ accept_event();
+ }
+ }
+}
+
void EditorAssetLibrary::_install_asset() {
ERR_FAIL_COND(!description);
@@ -1320,6 +1337,7 @@ void EditorAssetLibrary::disable_community_support() {
void EditorAssetLibrary::_bind_methods() {
+ ClassDB::bind_method("_unhandled_input", &EditorAssetLibrary::_unhandled_input);
ClassDB::bind_method("_http_request_completed", &EditorAssetLibrary::_http_request_completed);
ClassDB::bind_method("_select_asset", &EditorAssetLibrary::_select_asset);
ClassDB::bind_method("_select_author", &EditorAssetLibrary::_select_author);
@@ -1502,6 +1520,7 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
description = NULL;
set_process(true);
+ set_process_unhandled_input(true);
downloads_scroll = memnew(ScrollContainer);
downloads_scroll->set_enable_h_scroll(true);
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index aa3c735810..8852125b8b 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -300,6 +300,7 @@ class EditorAssetLibrary : public PanelContainer {
protected:
static void _bind_methods();
void _notification(int p_what);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
public:
void disable_community_support();
diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp
index 25329906a9..6e5307cebe 100644
--- a/editor/plugins/mesh_instance_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_editor_plugin.cpp
@@ -60,10 +60,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
}
switch (p_option) {
- case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY:
- case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: {
-
- bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
+ case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: {
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
@@ -71,9 +68,12 @@ void MeshInstanceEditor::_menu_option(int p_option) {
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.empty()) {
- Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
- if (shape.is_null())
+ Ref<Shape> shape = mesh->create_trimesh_shape();
+ if (shape.is_null()) {
+ err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape."));
+ err_dialog->popup_centered_minsize();
return;
+ }
CollisionShape *cshape = memnew(CollisionShape);
cshape->set_shape(shape);
@@ -82,11 +82,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();
- if (trimesh_shape)
- ur->create_action(TTR("Create Static Trimesh Body"));
- else
- ur->create_action(TTR("Create Static Convex Body"));
-
+ ur->create_action(TTR("Create Static Trimesh Body"));
ur->add_do_method(node, "add_child", body);
ur->add_do_method(body, "set_owner", owner);
ur->add_do_method(cshape, "set_owner", owner);
@@ -108,7 +104,7 @@ void MeshInstanceEditor::_menu_option(int p_option) {
if (m.is_null())
continue;
- Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape();
+ Ref<Shape> shape = m->create_trimesh_shape();
if (shape.is_null())
continue;
@@ -158,10 +154,44 @@ void MeshInstanceEditor::_menu_option(int p_option) {
ur->add_undo_method(node->get_parent(), "remove_child", cshape);
ur->commit_action();
} break;
- case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: {
+ case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE: {
if (node == get_tree()->get_edited_scene_root()) {
- err_dialog->set_text(TTR("This doesn't work on scene root!"));
+ err_dialog->set_text(TTR("Can't create a single convex collision shape for the scene root."));
+ err_dialog->popup_centered_minsize();
+ return;
+ }
+
+ Ref<Shape> shape = mesh->create_convex_shape();
+
+ if (shape.is_null()) {
+ err_dialog->set_text(TTR("Couldn't create a single convex collision shape."));
+ err_dialog->popup_centered_minsize();
+ return;
+ }
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action(TTR("Create Single Convex Shape"));
+
+ CollisionShape *cshape = memnew(CollisionShape);
+ cshape->set_shape(shape);
+ cshape->set_transform(node->get_transform());
+
+ Node *owner = node->get_owner();
+
+ ur->add_do_method(node->get_parent(), "add_child", cshape);
+ ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
+ ur->add_do_method(cshape, "set_owner", owner);
+ ur->add_do_reference(cshape);
+ ur->add_undo_method(node->get_parent(), "remove_child", cshape);
+
+ ur->commit_action();
+
+ } break;
+ case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES: {
+
+ if (node == get_tree()->get_edited_scene_root()) {
+ err_dialog->set_text(TTR("Can't create multiple convex collision shapes for the scene root."));
err_dialog->popup_centered_minsize();
return;
}
@@ -169,13 +199,13 @@ void MeshInstanceEditor::_menu_option(int p_option) {
Vector<Ref<Shape> > shapes = mesh->convex_decompose();
if (!shapes.size()) {
- err_dialog->set_text(TTR("Failed creating shapes!"));
+ err_dialog->set_text(TTR("Couldn't create any collision shapes."));
err_dialog->popup_centered_minsize();
return;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Create Convex Shape(s)"));
+ ur->create_action(TTR("Create Multiple Convex Shapes"));
for (int i = 0; i < shapes.size(); i++) {
@@ -421,13 +451,19 @@ MeshInstanceEditor::MeshInstanceEditor() {
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance", "EditorIcons"));
options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a StaticBody and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection."));
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"), MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);
- options->get_popup()->add_item(TTR("Create Convex Collision Sibling(s)"), MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection."));
+ options->get_popup()->add_item(TTR("Create Single Convex Collision Siblings"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection."));
+ options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between the two above options."));
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH);
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("Create Outline Mesh..."), MENU_OPTION_CREATE_OUTLINE_MESH);
+ options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a static outline mesh. The outline mesh will have its normals flipped automatically.\nThis can be used instead of the SpatialMaterial Grow property when using that property isn't possible."));
options->get_popup()->add_separator();
options->get_popup()->add_item(TTR("View UV1"), MENU_OPTION_DEBUG_UV1);
options->get_popup()->add_item(TTR("View UV2"), MENU_OPTION_DEBUG_UV2);
diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h
index 5c95676fc4..5ca9aa3fec 100644
--- a/editor/plugins/mesh_instance_editor_plugin.h
+++ b/editor/plugins/mesh_instance_editor_plugin.h
@@ -43,9 +43,9 @@ class MeshInstanceEditor : public Control {
enum Menu {
MENU_OPTION_CREATE_STATIC_TRIMESH_BODY,
- MENU_OPTION_CREATE_STATIC_CONVEX_BODY,
MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
- MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE,
+ MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE,
+ MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES,
MENU_OPTION_CREATE_NAVMESH,
MENU_OPTION_CREATE_OUTLINE_MESH,
MENU_OPTION_CREATE_UV2,
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index f889228f87..0c3e29028c 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -2026,13 +2026,13 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
toolbar->add_child(bucket_fill_button);
picker_button = memnew(ToolButton);
- picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_CONTROL));
+ picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_I));
picker_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PICKING));
picker_button->set_toggle_mode(true);
toolbar->add_child(picker_button);
select_button = memnew(ToolButton);
- select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD + KEY_B));
+ select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_M));
select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SELECTING));
select_button->set_toggle_mode(true);
toolbar->add_child(select_button);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index ee434aaac2..9cc2a79399 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -885,7 +885,8 @@ public:
rs_button->set_pressed(true);
rvb->add_child(rs_button);
l = memnew(Label);
- l->set_text(TTR("Higher visual quality\nAll features available\nIncompatible with older hardware\nNot recommended for web games"));
+ l->set_text(TTR("- Higher visual quality\n- All features available\n- Incompatible with older hardware\n- Not recommended for web games"));
+ l->set_modulate(Color(1, 1, 1, 0.7));
rvb->add_child(l);
rshb->add_child(memnew(VSeparator));
@@ -899,12 +900,17 @@ public:
rs_button->set_meta("driver_name", "GLES2");
rvb->add_child(rs_button);
l = memnew(Label);
- l->set_text(TTR("Lower visual quality\nSome features not available\nWorks on most hardware\nRecommended for web games"));
+ l->set_text(TTR("- Lower visual quality\n- Some features not available\n- Works on most hardware\n- Recommended for web games"));
+ l->set_modulate(Color(1, 1, 1, 0.7));
rvb->add_child(l);
l = memnew(Label);
- l->set_text(TTR("Renderer can be changed later, but scenes may need to be adjusted."));
+ l->set_text(TTR("The renderer can be changed later, but scenes may need to be adjusted."));
+ // Add some extra spacing to separate it from the list above and the buttons below.
+ l->set_custom_minimum_size(Size2(0, 40) * EDSCALE);
l->set_align(Label::ALIGN_CENTER);
+ l->set_valign(Label::VALIGN_CENTER);
+ l->set_modulate(Color(1, 1, 1, 0.7));
rasterizer_container->add_child(l);
fdialog = memnew(FileDialog);
@@ -1037,6 +1043,7 @@ public:
void sort_projects();
int get_project_count() const;
void select_project(int p_index);
+ void select_first_visible_project();
void erase_selected_projects();
Vector<Item> get_selected_projects() const;
const Set<String> &get_selected_project_keys() const;
@@ -1629,6 +1636,23 @@ void ProjectList::select_project(int p_index) {
toggle_select(p_index);
}
+void ProjectList::select_first_visible_project() {
+ bool found = false;
+
+ for (int i = 0; i < _projects.size(); i++) {
+ if (_projects[i].control->is_visible()) {
+ select_project(i);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ // Deselect all projects if there are no visible projects in the list.
+ _selected_project_keys.clear();
+ }
+}
+
inline void sort(int &a, int &b) {
if (a > b) {
int temp = a;
@@ -2347,6 +2371,12 @@ void ProjectManager::_on_order_option_changed() {
void ProjectManager::_on_filter_option_changed() {
_project_list->set_search_term(project_filter->get_search_term());
_project_list->sort_projects();
+
+ // Select the first visible project in the list.
+ // This makes it possible to open a project without ever touching the mouse,
+ // as the search field is automatically focused on startup.
+ _project_list->select_first_visible_project();
+ _update_project_buttons();
}
void ProjectManager::_bind_methods() {
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index b656fd647f..6635f5cb47 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -719,9 +719,18 @@ void ProjectSettingsEditor::_update_actions() {
item->set_range(1, action["deadzone"]);
item->set_custom_bg_color(1, get_color("prop_subsection", "Editor"));
+ const bool is_builtin_input = ProjectSettings::get_singleton()->get_input_presets().find(pi.name) != NULL;
+ const String tooltip = is_builtin_input ? TTR("Built-in actions can't be removed as they're used for UI navigation.") : TTR("Remove");
item->add_button(2, get_icon("Add", "EditorIcons"), 1, false, TTR("Add Event"));
- if (!ProjectSettings::get_singleton()->get_input_presets().find(pi.name)) {
- item->add_button(2, get_icon("Remove", "EditorIcons"), 2, false, TTR("Remove"));
+ item->add_button(2, get_icon("Remove", "EditorIcons"), 2, false, tooltip);
+
+ if (is_builtin_input) {
+ // Built-in action (like `ui_up`). Make the action not removable,
+ // but still display the button so the "Add" button is at the same
+ // horizontal position as for custom actions.
+ item->set_button_disabled(2, 1, true);
+ } else {
+ // Not a built-in action. Make the action name editable.
item->set_editable(0, true);
}
@@ -747,10 +756,9 @@ void ProjectSettingsEditor::_update_actions() {
if (jb.is_valid()) {
String str = _get_device_string(jb->get_device()) + ", " + TTR("Button") + " " + itos(jb->get_button_index());
- if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX)
- str += String() + " (" + _button_names[jb->get_button_index()] + ").";
- else
- str += ".";
+ if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX) {
+ str += String() + " (" + _button_names[jb->get_button_index()] + ")";
+ }
action2->set_text(0, str);
action2->set_icon(0, get_icon("JoyButton", "EditorIcons"));
@@ -761,12 +769,12 @@ void ProjectSettingsEditor::_update_actions() {
if (mb.is_valid()) {
String str = _get_device_string(mb->get_device()) + ", ";
switch (mb->get_button_index()) {
- case BUTTON_LEFT: str += TTR("Left Button."); break;
- case BUTTON_RIGHT: str += TTR("Right Button."); break;
- case BUTTON_MIDDLE: str += TTR("Middle Button."); break;
- case BUTTON_WHEEL_UP: str += TTR("Wheel Up."); break;
- case BUTTON_WHEEL_DOWN: str += TTR("Wheel Down."); break;
- default: str += TTR("Button") + " " + itos(mb->get_button_index()) + ".";
+ case BUTTON_LEFT: str += TTR("Left Button"); break;
+ case BUTTON_RIGHT: str += TTR("Right Button"); break;
+ case BUTTON_MIDDLE: str += TTR("Middle Button"); break;
+ case BUTTON_WHEEL_UP: str += TTR("Wheel Up"); break;
+ case BUTTON_WHEEL_DOWN: str += TTR("Wheel Down"); break;
+ default: str += vformat(TTR("%d Button"), mb->get_button_index());
}
action2->set_text(0, str);
@@ -780,7 +788,7 @@ void ProjectSettingsEditor::_update_actions() {
int ax = jm->get_axis();
int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1);
String desc = _axis_names[n];
- String str = _get_device_string(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc + ".";
+ String str = _get_device_string(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc;
action2->set_text(0, str);
action2->set_icon(0, get_icon("JoyAxis", "EditorIcons"));
}
@@ -789,6 +797,10 @@ void ProjectSettingsEditor::_update_actions() {
action2->add_button(2, get_icon("Edit", "EditorIcons"), 3, false, TTR("Edit"));
action2->add_button(2, get_icon("Remove", "EditorIcons"), 2, false, TTR("Remove"));
+ // Fade out the individual event buttons slightly to make the
+ // Add/Remove buttons stand out more.
+ action2->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+ action2->set_button_color(2, 1, Color(1, 1, 1, 0.75));
}
}
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
index e8822fc1ec..210d3f7756 100644
--- a/modules/gdnative/include/pluginscript/godot_pluginscript.h
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -44,13 +44,12 @@ typedef void godot_pluginscript_language_data;
// --- Instance ---
-// TODO: use godot_string_name for faster lookup ?
typedef struct {
godot_pluginscript_instance_data *(*init)(godot_pluginscript_script_data *p_data, godot_object *p_owner);
void (*finish)(godot_pluginscript_instance_data *p_data);
- godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, const godot_variant *p_value);
- godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, godot_variant *r_ret);
+ godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, const godot_variant *p_value);
+ godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, godot_variant *r_ret);
godot_variant (*call_method)(godot_pluginscript_instance_data *p_data,
const godot_string_name *p_method, const godot_variant **p_args,
@@ -136,7 +135,7 @@ typedef struct {
godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line);
- void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value);
+ void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string_name *p_variable, const godot_variant *p_value);
godot_string (*debug_get_error)(godot_pluginscript_language_data *p_data);
int (*debug_get_stack_level_count)(godot_pluginscript_language_data *p_data);
int (*debug_get_stack_level_line)(godot_pluginscript_language_data *p_data, int p_level);
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
index c64a00a4d9..0d6dac3268 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -39,13 +39,11 @@
#include "pluginscript_script.h"
bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) {
- String name = String(p_name);
- return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value);
+ return _desc->set_prop(_data, (const godot_string_name *)&p_name, (const godot_variant *)&p_value);
}
bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
- String name = String(p_name);
- return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret);
+ return _desc->get_prop(_data, (const godot_string_name *)&p_name, (godot_variant *)&r_ret);
}
Ref<Script> PluginScriptInstance::get_script() const {
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index 41f0e34243..421d6e0a89 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -187,8 +187,7 @@ void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int
}
void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
- const String variable = String(p_variable);
- _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value);
+ _desc.add_global_constant(_data, (godot_string_name *)&p_variable, (godot_variant *)&p_value);
}
/* LOADER FUNCTIONS */
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 4aa407f966..28d301ada1 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -840,15 +840,33 @@ void GridMapEditor::_text_changed(const String &p_text) {
void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
- Ref<InputEventKey> k = p_ie;
+ const Ref<InputEventKey> k = p_ie;
if (k.is_valid() && (k->get_scancode() == KEY_UP || k->get_scancode() == KEY_DOWN || k->get_scancode() == KEY_PAGEUP || k->get_scancode() == KEY_PAGEDOWN)) {
+ // Forward the key input to the ItemList so it can be scrolled
mesh_library_palette->call("_gui_input", k);
search_box->accept_event();
}
}
+void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) {
+
+ const Ref<InputEventMouseButton> mb = p_ie;
+
+ // Zoom in/out using Ctrl + mouse wheel
+ if (mb.is_valid() && mb->is_pressed() && mb->get_command()) {
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ size_slider->set_value(size_slider->get_value() + 0.2);
+ }
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ size_slider->set_value(size_slider->get_value() - 0.2);
+ }
+ }
+}
+
void GridMapEditor::_icon_size_changed(float p_value) {
mesh_library_palette->set_icon_scale(p_value);
update_palette();
@@ -1183,6 +1201,7 @@ void GridMapEditor::_bind_methods() {
ClassDB::bind_method("_text_changed", &GridMapEditor::_text_changed);
ClassDB::bind_method("_sbox_input", &GridMapEditor::_sbox_input);
+ ClassDB::bind_method("_mesh_library_palette_input", &GridMapEditor::_mesh_library_palette_input);
ClassDB::bind_method("_icon_size_changed", &GridMapEditor::_icon_size_changed);
ClassDB::bind_method("_menu_option", &GridMapEditor::_menu_option);
ClassDB::bind_method("_configure", &GridMapEditor::_configure);
@@ -1311,7 +1330,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
size_slider = memnew(HSlider);
size_slider->set_h_size_flags(SIZE_EXPAND_FILL);
- size_slider->set_min(0.1f);
+ size_slider->set_min(0.2f);
size_slider->set_max(4.0f);
size_slider->set_step(0.1f);
size_slider->set_value(1.0f);
@@ -1325,6 +1344,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
mesh_library_palette = memnew(ItemList);
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
+ mesh_library_palette->connect("gui_input", this, "_mesh_library_palette_input");
info_message = memnew(Label);
info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index 404e95b74c..5e6221b4f0 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -214,6 +214,7 @@ class GridMapEditor : public VBoxContainer {
void _text_changed(const String &p_text);
void _sbox_input(const Ref<InputEvent> &p_ie);
+ void _mesh_library_palette_input(const Ref<InputEvent> &p_ie);
void _icon_size_changed(float p_value);
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 36cafeec73..dc49ed72d0 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -1935,8 +1935,11 @@ PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) con
}
PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const {
-
- return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));
+ if (name == "") {
+ return PropertyInfo(Variant::INT, String(base_type));
+ } else {
+ return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));
+ }
}
String VisualScriptClassConstant::get_caption() const {
@@ -1958,6 +1961,22 @@ StringName VisualScriptClassConstant::get_class_constant() {
void VisualScriptClassConstant::set_base_type(const StringName &p_which) {
base_type = p_which;
+ List<String> constants;
+ ClassDB::get_integer_constant_list(base_type, &constants, true);
+ if (constants.size() > 0) {
+ bool found_name = false;
+ for (List<String>::Element *E = constants.front(); E; E = E->next()) {
+ if (E->get() == name) {
+ found_name = true;
+ break;
+ }
+ }
+ if (!found_name) {
+ name = constants[0];
+ }
+ } else {
+ name = "";
+ }
_change_notify();
ports_changed_notify();
}
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 104f9e751e..3561be8174 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "export.h"
+#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
#include "core/io/zip_io.h"
@@ -39,6 +40,7 @@
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
+#include "main/splash.gen.h"
#include "platform/iphone/logo.gen.h"
#include "string.h"
@@ -55,6 +57,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
typedef Error (*FileHandler)(String p_file, void *p_userdata);
static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata);
static Error _codesign(String p_file, void *p_userdata);
+ void _blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot);
struct IOSConfigData {
String pkg_name;
@@ -187,21 +190,24 @@ Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_ge
struct LoadingScreenInfo {
const char *preset_key;
const char *export_name;
+ int width;
+ int height;
+ bool rotate;
};
static const LoadingScreenInfo loading_screen_infos[] = {
- { "landscape_launch_screens/iphone_2436x1125", "Default-Landscape-X.png" },
- { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png" },
- { "landscape_launch_screens/ipad_1024x768", "Default-Landscape.png" },
- { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png" },
-
- { "portrait_launch_screens/iphone_640x960", "Default-480h@2x.png" },
- { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png" },
- { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png" },
- { "portrait_launch_screens/iphone_1125x2436", "Default-Portrait-X.png" },
- { "portrait_launch_screens/ipad_768x1024", "Default-Portrait.png" },
- { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png" },
- { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png" }
+ { "landscape_launch_screens/iphone_2436x1125", "Default-Landscape-X.png", 2436, 1125, false },
+ { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png", 2208, 1242, false },
+ { "landscape_launch_screens/ipad_1024x768", "Default-Landscape.png", 1024, 768, false },
+ { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png", 2048, 1536, false },
+
+ { "portrait_launch_screens/iphone_640x960", "Default-480h@2x.png", 640, 960, true },
+ { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png", 640, 1136, true },
+ { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png", 750, 1334, true },
+ { "portrait_launch_screens/iphone_1125x2436", "Default-Portrait-X.png", 1125, 2436, true },
+ { "portrait_launch_screens/ipad_768x1024", "Default-Portrait.png", 768, 1024, true },
+ { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png", 1536, 2048, true },
+ { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png", 1242, 2208, true }
};
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
@@ -247,6 +253,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_right"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_upside_down"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "icons/generate_missing"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone/iPod Touch with retina display
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png"), "")); // App Store
@@ -257,6 +265,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "launch_screens/generate_missing"), false));
+
for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), ""));
}
@@ -434,6 +444,42 @@ String EditorExportPlatformIOS::_get_cpp_code() {
return result;
}
+void EditorExportPlatformIOS::_blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot) {
+
+ ERR_FAIL_COND(p_dst.is_null());
+ ERR_FAIL_COND(p_src.is_null());
+
+ p_dst->lock();
+ p_src->lock();
+
+ int sw = p_rot ? p_src->get_height() : p_src->get_width();
+ int sh = p_rot ? p_src->get_width() : p_src->get_height();
+
+ int x_pos = (p_dst->get_width() - sw) / 2;
+ int y_pos = (p_dst->get_height() - sh) / 2;
+
+ int xs = (x_pos >= 0) ? 0 : -x_pos;
+ int ys = (y_pos >= 0) ? 0 : -y_pos;
+
+ if (sw + x_pos > p_dst->get_width()) sw = p_dst->get_width() - x_pos;
+ if (sh + y_pos > p_dst->get_height()) sh = p_dst->get_height() - y_pos;
+
+ for (int y = ys; y < sh; y++) {
+ for (int x = xs; x < sw; x++) {
+ Color sc = p_rot ? p_src->get_pixel(p_src->get_width() - y - 1, x) : p_src->get_pixel(x, y);
+ Color dc = p_dst->get_pixel(x_pos + x, y_pos + y);
+ dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r);
+ dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g);
+ dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b);
+ dc.a = (double)(sc.a + dc.a * (1.0 - sc.a));
+ p_dst->set_pixel(x_pos + x, y_pos + y, dc);
+ }
+ }
+
+ p_dst->unlock();
+ p_src->unlock();
+}
+
struct IconInfo {
const char *preset_key;
const char *idiom;
@@ -448,8 +494,8 @@ static const IconInfo icon_infos[] = {
{ "required_icons/iphone_120x120", "iphone", "Icon-120.png", "120", "2x", "60x60", true },
{ "required_icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40", true },
- { "required_icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", false },
- { "required_icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", false },
+ { "required_icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", true },
+ { "required_icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", true },
{ "optional_icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60", false },
@@ -473,20 +519,56 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr
for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) {
IconInfo info = icon_infos[i];
+ int side_size = String(info.actual_size_side).to_int();
String icon_path = p_preset->get(info.preset_key);
if (icon_path.length() == 0) {
- if (info.is_required) {
- ERR_PRINT("Required icon is not specified in the preset");
+ if ((bool)p_preset->get("icons/generate_missing")) {
+ // Resize main app icon
+ icon_path = ProjectSettings::get_singleton()->get("application/config/icon");
+ Ref<Image> img = memnew(Image);
+ Error err = ImageLoader::load_image(icon_path, img);
+ if (err != OK) {
+ ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'.");
+ return ERR_UNCONFIGURED;
+ }
+ img->resize(side_size, side_size);
+ err = img->save_png(p_iconset_dir + info.export_name);
+ if (err) {
+ String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'.");
+ ERR_PRINT(err_str.utf8().get_data());
+ return err;
+ }
+ } else {
+ if (info.is_required) {
+ String err_str = String("Required icon (") + info.preset_key + ") is not specified in the preset.";
+ ERR_PRINT(err_str);
+ return ERR_UNCONFIGURED;
+ } else {
+ String err_str = String("Icon (") + info.preset_key + ") is not specified in the preset.";
+ WARN_PRINT(err_str);
+ }
+ continue;
+ }
+ } else {
+ // Load custom icon
+ Ref<Image> img = memnew(Image);
+ Error err = ImageLoader::load_image(icon_path, img);
+ if (err != OK) {
+ ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'.");
return ERR_UNCONFIGURED;
}
- continue;
- }
- Error err = da->copy(icon_path, p_iconset_dir + info.export_name);
- if (err) {
- memdelete(da);
- String err_str = String("Failed to export icon: ") + icon_path;
- ERR_PRINT(err_str.utf8().get_data());
- return err;
+ if (img->get_width() != side_size || img->get_height() != side_size) {
+ ERR_PRINT("Invalid icon size (" + String(info.preset_key) + "): '" + icon_path + "'.");
+ return ERR_UNCONFIGURED;
+ }
+
+ err = da->copy(icon_path, p_iconset_dir + info.export_name);
+ if (err) {
+ memdelete(da);
+ String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'.");
+ ERR_PRINT(err_str.utf8().get_data());
+ return err;
+ }
}
sizes += String(info.actual_size_side) + "\n";
if (i > 0) {
@@ -525,13 +607,72 @@ Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPre
LoadingScreenInfo info = loading_screen_infos[i];
String loading_screen_file = p_preset->get(info.preset_key);
if (loading_screen_file.size() > 0) {
- Error err = da->copy(loading_screen_file, p_dest_dir + info.export_name);
+ // Load custom loading screens
+ Ref<Image> img = memnew(Image);
+ Error err = ImageLoader::load_image(loading_screen_file, img);
+ if (err != OK) {
+ ERR_PRINT("Invalid loading screen (" + String(info.preset_key) + "): '" + loading_screen_file + "'.");
+ return ERR_UNCONFIGURED;
+ }
+ if (img->get_width() != info.width || img->get_height() != info.height) {
+ ERR_PRINT("Invalid loading screen size (" + String(info.preset_key) + "): '" + loading_screen_file + "'.");
+ return ERR_UNCONFIGURED;
+ }
+ err = da->copy(loading_screen_file, p_dest_dir + info.export_name);
if (err) {
memdelete(da);
String err_str = String("Failed to export loading screen (") + info.preset_key + ") from path '" + loading_screen_file + "'.";
ERR_PRINT(err_str.utf8().get_data());
return err;
}
+ } else if ((bool)p_preset->get("launch_screens/generate_missing")) {
+ // Generate loading screen from the splash screen
+ Color boot_bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color");
+ String boot_logo_path = ProjectSettings::get_singleton()->get("application/boot_splash/image");
+ bool boot_logo_scale = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize");
+
+ Ref<Image> img = memnew(Image);
+ img->create(info.width, info.height, false, Image::FORMAT_RGBA8);
+ img->fill(boot_bg_color);
+
+ Ref<Image> img_bs;
+
+ if (boot_logo_path.length() > 0) {
+ img_bs = Ref<Image>(memnew(Image));
+ ImageLoader::load_image(boot_logo_path, img_bs);
+ }
+ if (!img_bs.is_valid()) {
+ img_bs = Ref<Image>(memnew(Image(boot_splash_png)));
+ }
+ if (img_bs.is_valid()) {
+ float aspect_ratio = (float)img_bs->get_width() / (float)img_bs->get_height();
+ if (info.rotate) {
+ if (boot_logo_scale) {
+ if (info.width * aspect_ratio <= info.height) {
+ img_bs->resize(info.width * aspect_ratio, info.width);
+ } else {
+ img_bs->resize(info.height, info.height / aspect_ratio);
+ }
+ }
+ } else {
+ if (boot_logo_scale) {
+ if (info.height * aspect_ratio <= info.width) {
+ img_bs->resize(info.height * aspect_ratio, info.height);
+ } else {
+ img_bs->resize(info.width, info.width / aspect_ratio);
+ }
+ }
+ }
+ _blend_and_rotate(img, img_bs, info.rotate);
+ }
+ Error err = img->save_png(p_dest_dir + info.export_name);
+ if (err) {
+ String err_str = String("Failed to export loading screen (") + info.preset_key + ") from splash screen.";
+ WARN_PRINT(err_str.utf8().get_data());
+ }
+ } else {
+ String err_str = String("No loading screen (") + info.preset_key + ") specified.";
+ WARN_PRINT(err_str.utf8().get_data());
}
}
memdelete(da);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index bc77ac3cfd..314f369dc6 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1724,42 +1724,39 @@ public:
case ERR_WARNING:
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
os_log_info(OS_LOG_DEFAULT,
- "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.",
- p_function, err_details, p_file, p_line);
+ "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
}
- logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function,
- err_details);
- logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
+ logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details);
+ logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_SCRIPT:
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
os_log_error(OS_LOG_DEFAULT,
- "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
- p_function, err_details, p_file, p_line);
+ "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
}
- logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function,
- err_details);
- logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
+ logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details);
+ logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_SHADER:
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
os_log_error(OS_LOG_DEFAULT,
- "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
- p_function, err_details, p_file, p_line);
+ "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
}
- logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function,
- err_details);
- logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
+ logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details);
+ logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_ERROR:
default:
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
os_log_error(OS_LOG_DEFAULT,
- "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
- p_function, err_details, p_file, p_line);
+ "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
}
- logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
+ logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details);
+ logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
}
}
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index 8eb6adc27b..520b654b94 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -85,7 +85,6 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
GetConsoleScreenBufferInfo(hCon, &sbi);
- WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
uint32_t basecol = 0;
@@ -98,53 +97,34 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
basecol |= current_bg;
- if (p_rationale && p_rationale[0]) {
-
- SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
- switch (p_type) {
- case ERR_ERROR: logf("ERROR: "); break;
- case ERR_WARNING: logf("WARNING: "); break;
- case ERR_SCRIPT: logf("SCRIPT ERROR: "); break;
- case ERR_SHADER: logf("SHADER ERROR: "); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
- logf("%s\n", p_rationale);
+ SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
+ switch (p_type) {
+ case ERR_ERROR: logf("ERROR:"); break;
+ case ERR_WARNING: logf("WARNING:"); break;
+ case ERR_SCRIPT: logf("SCRIPT ERROR:"); break;
+ case ERR_SHADER: logf("SHADER ERROR:"); break;
+ }
- SetConsoleTextAttribute(hCon, basecol);
- switch (p_type) {
- case ERR_ERROR: logf(" At: "); break;
- case ERR_WARNING: logf(" At: "); break;
- case ERR_SCRIPT: logf(" At: "); break;
- case ERR_SHADER: logf(" At: "); break;
- }
+ SetConsoleTextAttribute(hCon, basecol);
+ if (p_rationale && p_rationale[0]) {
+ logf(" %s\n", p_rationale);
+ } else {
+ logf(" %s\n", p_code);
+ }
- SetConsoleTextAttribute(hCon, current_fg | current_bg);
- logf("%s:%i\n", p_file, p_line);
+ // `FOREGROUND_INTENSITY` alone results in gray text.
+ SetConsoleTextAttribute(hCon, FOREGROUND_INTENSITY);
+ switch (p_type) {
+ case ERR_ERROR: logf(" at: "); break;
+ case ERR_WARNING: logf(" at: "); break;
+ case ERR_SCRIPT: logf(" at: "); break;
+ case ERR_SHADER: logf(" at: "); break;
+ }
+ if (p_rationale && p_rationale[0]) {
+ logf("(%s:%i)\n", p_file, p_line);
} else {
-
- SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
- switch (p_type) {
- case ERR_ERROR: logf("ERROR: %s: ", p_function); break;
- case ERR_WARNING: logf("WARNING: %s: ", p_function); break;
- case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break;
- case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
- logf("%s\n", p_code);
-
- SetConsoleTextAttribute(hCon, basecol);
- switch (p_type) {
- case ERR_ERROR: logf(" At: "); break;
- case ERR_WARNING: logf(" At: "); break;
- case ERR_SCRIPT: logf(" At: "); break;
- case ERR_SHADER: logf(" At: "); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg);
- logf("%s:%i\n", p_file, p_line);
+ logf("%s (%s:%i)\n", p_function, p_file, p_line);
}
SetConsoleTextAttribute(hCon, sbi.wAttributes);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 55a612eb37..1cd763853c 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -526,19 +526,73 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
"watch",
"left_ptr_watch",
"fleur",
- "hand1",
- "X_cursor",
- "sb_v_double_arrow",
- "sb_h_double_arrow",
+ "dnd-move",
+ "crossed_circle",
+ "v_double_arrow",
+ "h_double_arrow",
"size_bdiag",
"size_fdiag",
- "hand1",
- "sb_v_double_arrow",
- "sb_h_double_arrow",
+ "move",
+ "row_resize",
+ "col_resize",
"question_arrow"
};
img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size);
+ if (!img[i]) {
+ const char *fallback = NULL;
+
+ switch (i) {
+ case CURSOR_POINTING_HAND:
+ fallback = "pointer";
+ break;
+ case CURSOR_CROSS:
+ fallback = "crosshair";
+ break;
+ case CURSOR_WAIT:
+ fallback = "wait";
+ break;
+ case CURSOR_BUSY:
+ fallback = "progress";
+ break;
+ case CURSOR_DRAG:
+ fallback = "grabbing";
+ break;
+ case CURSOR_CAN_DROP:
+ fallback = "hand1";
+ break;
+ case CURSOR_FORBIDDEN:
+ fallback = "forbidden";
+ break;
+ case CURSOR_VSIZE:
+ fallback = "ns-resize";
+ break;
+ case CURSOR_HSIZE:
+ fallback = "ew-resize";
+ break;
+ case CURSOR_BDIAGSIZE:
+ fallback = "fd_double_arrow";
+ break;
+ case CURSOR_FDIAGSIZE:
+ fallback = "bd_double_arrow";
+ break;
+ case CURSOR_MOVE:
+ img[i] = img[CURSOR_DRAG];
+ break;
+ case CURSOR_VSPLIT:
+ fallback = "sb_v_double_arrow";
+ break;
+ case CURSOR_HSPLIT:
+ fallback = "sb_h_double_arrow";
+ break;
+ case CURSOR_HELP:
+ fallback = "help";
+ break;
+ }
+ if (fallback != NULL) {
+ img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size);
+ }
+ }
if (img[i]) {
cursors[i] = XcursorImageLoadCursor(x11_display, img[i]);
} else {
@@ -669,14 +723,8 @@ bool OS_X11::refresh_device_info() {
int range_max_x = 0;
int range_max_y = 0;
int pressure_resolution = 0;
- int pressure_min = 0;
- int pressure_max = 0;
int tilt_resolution_x = 0;
int tilt_resolution_y = 0;
- int tilt_range_min_x = 0;
- int tilt_range_min_y = 0;
- int tilt_range_max_x = 0;
- int tilt_range_max_y = 0;
for (int j = 0; j < dev->num_classes; j++) {
#ifdef TOUCH_ENABLED
if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
@@ -697,17 +745,14 @@ bool OS_X11::refresh_device_info() {
range_max_y = class_info->max;
absolute_mode = true;
} else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) {
- pressure_resolution = class_info->resolution;
- pressure_min = class_info->min;
- pressure_max = class_info->max;
+ pressure_resolution = (class_info->max - class_info->min);
+ if (pressure_resolution == 0) pressure_resolution = 1;
} else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) {
- tilt_resolution_x = class_info->resolution;
- tilt_range_min_x = class_info->min;
- tilt_range_max_x = class_info->max;
+ tilt_resolution_x = (class_info->max - class_info->min);
+ if (tilt_resolution_x == 0) tilt_resolution_x = 1;
} else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) {
- tilt_resolution_y = class_info->resolution;
- tilt_range_min_y = class_info->min;
- tilt_range_max_y = class_info->max;
+ tilt_resolution_y = (class_info->max - class_info->min);
+ if (tilt_resolution_y == 0) tilt_resolution_y = 1;
}
}
}
@@ -728,15 +773,6 @@ bool OS_X11::refresh_device_info() {
print_verbose("XInput: Absolute pointing device: " + String(dev->name));
}
- if (pressure_resolution <= 0) {
- pressure_resolution = (pressure_max - pressure_min);
- }
- if (tilt_resolution_x <= 0) {
- tilt_resolution_x = (tilt_range_max_x - tilt_range_min_x);
- }
- if (tilt_resolution_y <= 0) {
- tilt_resolution_y = (tilt_range_max_y - tilt_range_min_y);
- }
xi.pressure = 0;
xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y);
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 93d0ae080b..9d5e004ed3 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -6530,6 +6530,10 @@ void TextEdit::_update_completion_candidates() {
Vector<float> sim_cache;
bool single_quote = s.begins_with("'");
Vector<ScriptCodeCompletionOption> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_subseq;
+ Vector<ScriptCodeCompletionOption> completion_options_subseq_casei;
+
+ String s_lower = s.to_lower();
for (List<ScriptCodeCompletionOption>::Element *E = completion_sources.front(); E; E = E->next()) {
ScriptCodeCompletionOption &option = E->get();
@@ -6544,31 +6548,68 @@ void TextEdit::_update_completion_candidates() {
option.insert_text = option.insert_text.quote(quote);
}
- if (option.display.begins_with(s)) {
+ if (option.display.length() == 0) {
+ continue;
+ } else if (s.length() == 0) {
completion_options.push_back(option);
- } else if (option.display.to_lower().begins_with(s.to_lower())) {
- completion_options_casei.push_back(option);
- }
- }
+ } else {
- completion_options.append_array(completion_options_casei);
+ // This code works the same as:
+ /*
+ if (option.display.begins_with(s)) {
+ completion_options.push_back(option);
+ } else if (option.display.to_lower().begins_with(s.to_lower())) {
+ completion_options_casei.push_back(option);
+ } else if (s.is_subsequence_of(option.display)) {
+ completion_options_subseq.push_back(option);
+ } else if (s.is_subsequence_ofi(option.display)) {
+ completion_options_subseq_casei.push_back(option);
+ }
+ */
+ // But is more performant due to being inlined and looping over the characters only once
- if (completion_options.size() == 0) {
- for (int i = 0; i < completion_sources.size(); i++) {
- if (s.is_subsequence_of(completion_sources[i].display)) {
- completion_options.push_back(completion_sources[i]);
+ String display_lower = option.display.to_lower();
+
+ const CharType *ssq = &s[0];
+ const CharType *ssq_lower = &s_lower[0];
+
+ const CharType *tgt = &option.display[0];
+ const CharType *tgt_lower = &display_lower[0];
+
+ const CharType *ssq_last_tgt = NULL;
+ const CharType *ssq_lower_last_tgt = NULL;
+
+ for (; *tgt; tgt++, tgt_lower++) {
+ if (*ssq == *tgt) {
+ ssq++;
+ ssq_last_tgt = tgt;
+ }
+ if (*ssq_lower == *tgt_lower) {
+ ssq_lower++;
+ ssq_lower_last_tgt = tgt;
+ }
}
- }
- }
- if (completion_options.size() == 0) {
- for (int i = 0; i < completion_sources.size(); i++) {
- if (s.is_subsequence_ofi(completion_sources[i].display)) {
- completion_options.push_back(completion_sources[i]);
+ if (!*ssq) { // Matched the whole subsequence in s
+ if (ssq_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters
+ completion_options.push_back(option);
+ } else {
+ completion_options_subseq.push_back(option);
+ }
+ } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower
+ if (ssq_lower_last_tgt == &option.display[s.length() - 1]) { // Finished matching in the first s.length() characters
+ completion_options_casei.push_back(option);
+ } else {
+ completion_options_subseq_casei.push_back(option);
+ }
}
}
}
+ completion_options.append_array(completion_options_casei);
+ completion_options.append_array(completion_options_subseq);
+ completion_options.append_array(completion_options_subseq_casei);
+
if (completion_options.size() == 0) {
// No options to complete, cancel.
_cancel_completion();