Merge pull request #44947 from akien-mga/3.2-cherrypicks
Cherry-picks for the 3.2 branch (future 3.2.4) - 15th batch
This commit is contained in:
commit
d242f7ad77
@ -1045,10 +1045,7 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
|
||||
List<Ref<Resource> > resources;
|
||||
ResourceCache::get_cached_resources(&resources);
|
||||
|
||||
List<Ref<Resource> > rsrc;
|
||||
ResourceCache::get_cached_resources(&rsrc);
|
||||
|
||||
for (List<Ref<Resource> >::Element *E = rsrc.front(); E; E = E->next()) {
|
||||
for (List<Ref<Resource> >::Element *E = resources.front(); E; E = E->next()) {
|
||||
|
||||
Ref<Resource> r = E->get();
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "core/os/dir_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/print_string.h"
|
||||
#include "core/project_settings.h"
|
||||
|
||||
// va_copy was defined in the C99, but not in C++ standards before C++11.
|
||||
// When you compile C++ without --std=c++<XX> option, compilers still define
|
||||
@ -205,14 +204,15 @@ void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
}
|
||||
va_end(list_copy);
|
||||
file->store_buffer((uint8_t *)buf, len);
|
||||
|
||||
if (len >= static_buf_size) {
|
||||
Memory::free_static(buf);
|
||||
}
|
||||
|
||||
if (p_err || GLOBAL_GET("application/run/flush_stdout_on_print")) {
|
||||
// Don't always flush when printing stdout to avoid performance
|
||||
// issues when `print()` is spammed in release builds.
|
||||
#ifdef DEBUG_ENABLED
|
||||
const bool need_flush = true;
|
||||
#else
|
||||
bool need_flush = p_err;
|
||||
#endif
|
||||
if (need_flush) {
|
||||
file->flush();
|
||||
}
|
||||
}
|
||||
@ -231,11 +231,9 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
vfprintf(stderr, p_format, p_list);
|
||||
} else {
|
||||
vprintf(p_format, p_list);
|
||||
if (GLOBAL_GET("application/run/flush_stdout_on_print")) {
|
||||
// Don't always flush when printing stdout to avoid performance
|
||||
// issues when `print()` is spammed in release builds.
|
||||
fflush(stdout);
|
||||
}
|
||||
#ifdef DEBUG_ENABLED
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
|
||||
|
||||
Vector3 point = p_plane.normal * p_plane.d;
|
||||
Vector3 point_dir = point + p_plane.normal;
|
||||
xform_inv(point);
|
||||
xform_inv(point_dir);
|
||||
point = xform_inv(point);
|
||||
point_dir = xform_inv(point_dir);
|
||||
|
||||
Vector3 normal = point_dir - point;
|
||||
normal.normalize();
|
||||
|
@ -1563,7 +1563,13 @@ void Object::_disconnect(const StringName &p_signal, Object *p_to_object, const
|
||||
|
||||
ERR_FAIL_NULL(p_to_object);
|
||||
Signal *s = signal_map.getptr(p_signal);
|
||||
ERR_FAIL_COND_MSG(!s, vformat("Nonexistent signal '%s' in %s.", p_signal, to_string()));
|
||||
if (!s) {
|
||||
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) ||
|
||||
(!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal));
|
||||
ERR_FAIL_COND_MSG(signal_is_valid, vformat("Attempt to disconnect a nonexistent connection to signal '%s' in %s, with target '%s' in %s.",
|
||||
p_signal, to_string(), p_to_method, p_to_object->to_string()));
|
||||
}
|
||||
ERR_FAIL_COND_MSG(!s, vformat("Disconnecting nonexistent signal '%s' in %s.", p_signal, to_string()));
|
||||
|
||||
Signal::Target target(p_to_object->get_instance_id(), p_to_method);
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
return min(0, abs(u - v) - 1)
|
||||
[/codeblock]
|
||||
[method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) <= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information.
|
||||
If the default [method _estimate_cost] and [method _compute_cost] methods are used, or if the supplied [method _estimate_cost] method returns a lower bound of the cost, then the paths returned by A* will be the lowest cost paths. Here, the cost of a path equals to the sum of the [method _compute_cost] results of all segments in the path multiplied by the [code]weight_scale[/code]s of the end points of the respective segments. If the default methods are used and the [code]weight_scale[/code]s of all points are set to [code]1.0[/code], then this equals to the sum of Euclidean distances of all segments in the path.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
@ -56,7 +57,8 @@
|
||||
<argument index="2" name="weight_scale" type="float" default="1.0">
|
||||
</argument>
|
||||
<description>
|
||||
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
|
||||
Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
|
||||
The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path.
|
||||
[codeblock]
|
||||
var astar = AStar.new()
|
||||
astar.add_point(1, Vector3(1, 0, 0), 4) # Adds the point (1, 0, 0) with weight_scale 4 and id 1
|
||||
@ -315,7 +317,7 @@
|
||||
<argument index="1" name="weight_scale" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Sets the [code]weight_scale[/code] for the point with the given [code]id[/code].
|
||||
Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
@ -43,7 +43,8 @@
|
||||
<argument index="2" name="weight_scale" type="float" default="1.0">
|
||||
</argument>
|
||||
<description>
|
||||
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
|
||||
Adds a new point at the given position with the given identifier. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
|
||||
The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point. Thus, all else being equal, the algorithm prefers points with lower [code]weight_scale[/code]s to form a path.
|
||||
[codeblock]
|
||||
var astar = AStar2D.new()
|
||||
astar.add_point(1, Vector2(1, 0), 4) # Adds the point (1, 0) with weight_scale 4 and id 1
|
||||
@ -298,7 +299,7 @@
|
||||
<argument index="1" name="weight_scale" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Sets the [code]weight_scale[/code] for the point with the given [code]id[/code].
|
||||
Sets the [code]weight_scale[/code] for the point with the given [code]id[/code]. The [code]weight_scale[/code] is multiplied by the result of [method _compute_cost] when determining the overall cost of traveling across a segment from a neighboring point to this point.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
|
@ -15,6 +15,12 @@
|
||||
<link>https://docs.godotengine.org/en/3.2/tutorials/animation/animation_tree.html</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="get_current_length" qualifiers="const">
|
||||
<return type="float">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_current_node" qualifiers="const">
|
||||
<return type="String">
|
||||
</return>
|
||||
@ -22,6 +28,13 @@
|
||||
Returns the currently playing animation state.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_current_play_position" qualifiers="const">
|
||||
<return type="float">
|
||||
</return>
|
||||
<description>
|
||||
Returns the playback position within the current animation state.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_travel_path" qualifiers="const">
|
||||
<return type="PoolStringArray">
|
||||
</return>
|
||||
|
@ -113,7 +113,7 @@
|
||||
<argument index="0" name="delta" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Called each physics frame with the time since the last physics frame as argument (in seconds). Equivalent to [method Node._physics_process].
|
||||
Called each physics frame with the time since the last physics frame as argument ([code]delta[/code], in seconds). Equivalent to [method Node._physics_process].
|
||||
If implemented, the method must return a boolean value. [code]true[/code] ends the main loop, while [code]false[/code] lets it proceed to the next frame.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -9,7 +9,7 @@
|
||||
[b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the [constant NOTIFICATION_ENTER_TREE] notification and its [method _enter_tree] callback is triggered. Child nodes are always added [i]after[/i] their parent node, i.e. the [method _enter_tree] callback of a parent node will be triggered before its child's.
|
||||
Once all nodes have been added in the scene tree, they receive the [constant NOTIFICATION_READY] notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, starting with the children and moving up to the parent nodes.
|
||||
This means that when adding a node to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (recursively for the entire scene tree).
|
||||
[b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
|
||||
[b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] (in seconds) is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
|
||||
Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it.
|
||||
To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with the [member owner] property. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
|
||||
Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
|
||||
@ -65,7 +65,7 @@
|
||||
<argument index="0" name="delta" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant.
|
||||
Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant. [code]delta[/code] is in seconds.
|
||||
It is only called if physics processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_physics_process].
|
||||
Corresponds to the [constant NOTIFICATION_PHYSICS_PROCESS] notification in [method Object._notification].
|
||||
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan).
|
||||
@ -77,7 +77,7 @@
|
||||
<argument index="0" name="delta" type="float">
|
||||
</argument>
|
||||
<description>
|
||||
Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant.
|
||||
Called during the processing step of the main loop. Processing happens at every frame and as fast as possible, so the [code]delta[/code] time since the previous frame is not constant. [code]delta[/code] is in seconds.
|
||||
It is only called if processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process].
|
||||
Corresponds to the [constant NOTIFICATION_PROCESS] notification in [method Object._notification].
|
||||
[b]Note:[/b] This method is only called if the node is present in the scene tree (i.e. if it's not orphan).
|
||||
@ -334,7 +334,7 @@
|
||||
<return type="float">
|
||||
</return>
|
||||
<description>
|
||||
Returns the time elapsed since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second].
|
||||
Returns the time elapsed (in seconds) since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed via [member Engine.iterations_per_second].
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_position_in_parent" qualifiers="const">
|
||||
@ -570,7 +570,7 @@
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree, i.e. the further they are on the node list, the higher they are drawn. After using [code]raise[/code], a Control will be drawn on top of their siblings.
|
||||
Moves this node to the bottom of parent node's children hierarchy. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree. The top Node is drawn first, then any siblings below the top Node in the hierarchy are successively drawn on top of it. After using [code]raise[/code], a Control will be drawn on top of its siblings.
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_and_skip">
|
||||
|
@ -248,14 +248,6 @@
|
||||
<member name="application/run/disable_stdout" type="bool" setter="" getter="" default="false">
|
||||
If [code]true[/code], disables printing to standard output in an exported build.
|
||||
</member>
|
||||
<member name="application/run/flush_stdout_on_print" type="bool" setter="" getter="" default="false">
|
||||
If [code]true[/code], flushes the standard output stream every time a line is printed. This affects both terminal logging and file logging.
|
||||
When running a project, this setting must be enabled if you want logs to be collected by service managers such as systemd/journalctl. This setting is disabled by default on release builds, since flushing on every printed line will negatively affect performance if lots of lines are printed in a rapid succession. Also, if this setting is enabled, logged files will still be written successfully if the application crashes or is otherwise killed by the user (without being closed "normally").
|
||||
[b]Note:[/b] Regardless of this setting, the standard error stream ([code]stderr[/code]) is always flushed when a line is printed to it.
|
||||
</member>
|
||||
<member name="application/run/flush_stdout_on_print.debug" type="bool" setter="" getter="" default="true">
|
||||
Debug build override for [member application/run/flush_stdout_on_print], as performance is less important during debugging.
|
||||
</member>
|
||||
<member name="application/run/frame_delay_msec" type="int" setter="" getter="" default="0">
|
||||
Forces a delay between frames in the main loop (in milliseconds). This may be useful if you plan to disable vertical synchronization.
|
||||
</member>
|
||||
@ -850,6 +842,7 @@
|
||||
If [code]true[/code], logs all output to files.
|
||||
</member>
|
||||
<member name="logging/file_logging/enable_file_logging.pc" type="bool" setter="" getter="" default="true">
|
||||
Desktop override for [member logging/file_logging/enable_file_logging], as log files are not readily accessible on mobile/Web platforms.
|
||||
</member>
|
||||
<member name="logging/file_logging/log_path" type="String" setter="" getter="" default=""user://logs/godot.log"">
|
||||
Path to logs within the project. Using an [code]user://[/code] path is recommended.
|
||||
@ -1105,6 +1098,8 @@
|
||||
Choose between default mode where corner scalings are preserved matching the artwork, and scaling mode.
|
||||
Not available in GLES3 when [member rendering/batching/options/use_batching] is off.
|
||||
</member>
|
||||
<member name="rendering/quality/2d/use_camera_snap" type="bool" setter="" getter="" default="false">
|
||||
</member>
|
||||
<member name="rendering/quality/2d/use_nvidia_rect_flicker_workaround" type="bool" setter="" getter="" default="false">
|
||||
Some NVIDIA GPU drivers have a bug which produces flickering issues for the [code]draw_rect[/code] method, especially as used in [TileMap]. Refer to [url=https://github.com/godotengine/godot/issues/9913]GitHub issue 9913[/url] for details.
|
||||
If [code]true[/code], this option enables a "safe" code path for such NVIDIA GPUs at the cost of performance. This option affects GLES2 and GLES3 rendering, but only on desktop platforms.
|
||||
|
@ -222,7 +222,6 @@ void EditorFileDialog::update_dir() {
|
||||
void EditorFileDialog::_dir_entered(String p_dir) {
|
||||
|
||||
dir_access->change_dir(p_dir);
|
||||
file->set_text("");
|
||||
invalidate();
|
||||
update_dir();
|
||||
_push_history();
|
||||
@ -244,6 +243,14 @@ void EditorFileDialog::_save_confirm_pressed() {
|
||||
void EditorFileDialog::_post_popup() {
|
||||
|
||||
ConfirmationDialog::_post_popup();
|
||||
|
||||
// Check if the current path doesn't exist and correct it.
|
||||
String current = dir_access->get_current_dir();
|
||||
while (!dir_access->dir_exists(current)) {
|
||||
current = current.get_base_dir();
|
||||
}
|
||||
set_current_dir(current);
|
||||
|
||||
if (invalidated) {
|
||||
update_file_list();
|
||||
invalidated = false;
|
||||
@ -279,11 +286,17 @@ void EditorFileDialog::_post_popup() {
|
||||
} else {
|
||||
name = name.get_file() + "/";
|
||||
}
|
||||
|
||||
recent->add_item(name, folder);
|
||||
recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
|
||||
recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
|
||||
bool exists = dir_access->dir_exists(recentd[i]);
|
||||
if (!exists) {
|
||||
// Remove invalid directory from the list of Recent directories.
|
||||
recentd.remove(i--);
|
||||
} else {
|
||||
recent->add_item(name, folder);
|
||||
recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]);
|
||||
recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color);
|
||||
}
|
||||
}
|
||||
EditorSettings::get_singleton()->set_recent_dirs(recentd);
|
||||
|
||||
local_history.clear();
|
||||
local_history_pos = -1;
|
||||
@ -441,10 +454,12 @@ void EditorFileDialog::_action_pressed() {
|
||||
}
|
||||
}
|
||||
|
||||
// Add first extension of filter if no valid extension is found.
|
||||
if (!valid) {
|
||||
|
||||
exterr->popup_centered_minsize(Size2(250, 80) * EDSCALE);
|
||||
return;
|
||||
int idx = filter->get_selected();
|
||||
String flt = filters[idx].get_slice(";", 0);
|
||||
String ext = flt.get_slice(",", 0).strip_edges().get_extension();
|
||||
f += "." + ext;
|
||||
}
|
||||
|
||||
if (dir_access->file_exists(f) && !disable_overwrite_warning) {
|
||||
@ -1735,10 +1750,6 @@ EditorFileDialog::EditorFileDialog() {
|
||||
mkdirerr->set_text(TTR("Could not create folder."));
|
||||
add_child(mkdirerr);
|
||||
|
||||
exterr = memnew(AcceptDialog);
|
||||
exterr->set_text(TTR("Must use a valid extension."));
|
||||
add_child(exterr);
|
||||
|
||||
update_filters();
|
||||
update_dir();
|
||||
|
||||
|
@ -112,7 +112,6 @@ private:
|
||||
LineEdit *file;
|
||||
OptionButton *filter;
|
||||
AcceptDialog *mkdirerr;
|
||||
AcceptDialog *exterr;
|
||||
DirAccess *dir_access;
|
||||
ConfirmationDialog *confirm_save;
|
||||
DependencyRemoveDialog *remove_dialog;
|
||||
|
@ -102,9 +102,6 @@ void EditorLog::copy() {
|
||||
}
|
||||
|
||||
void EditorLog::add_message(const String &p_msg, MessageType p_type) {
|
||||
|
||||
log->add_newline();
|
||||
|
||||
bool restore = p_type != MSG_TYPE_STD;
|
||||
switch (p_type) {
|
||||
case MSG_TYPE_STD: {
|
||||
@ -130,6 +127,7 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
|
||||
}
|
||||
|
||||
log->add_text(p_msg);
|
||||
log->add_newline();
|
||||
|
||||
if (restore)
|
||||
log->pop();
|
||||
|
@ -2280,8 +2280,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
||||
int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing;
|
||||
|
||||
Node *scene = editor_data.get_edited_scene_root(scene_idx);
|
||||
if (scene && scene->get_filename() != "") {
|
||||
|
||||
if (scene && scene->get_filename() != "" && FileAccess::exists(scene->get_filename())) {
|
||||
if (scene_idx != editor_data.get_edited_scene())
|
||||
_save_scene_with_preview(scene->get_filename(), scene_idx);
|
||||
else
|
||||
@ -2326,11 +2325,12 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
|
||||
}
|
||||
|
||||
if (scene->get_filename() != "") {
|
||||
file->set_current_path(scene->get_filename());
|
||||
String path = scene->get_filename();
|
||||
file->set_current_path(path);
|
||||
if (extensions.size()) {
|
||||
String ext = scene->get_filename().get_extension().to_lower();
|
||||
String ext = path.get_extension().to_lower();
|
||||
if (extensions.find(ext) == NULL) {
|
||||
file->set_current_path(scene->get_filename().replacen("." + ext, "." + extensions.front()->get()));
|
||||
file->set_current_path(path.replacen("." + ext, "." + extensions.front()->get()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -64,7 +64,7 @@ void EditorPropertyText::_text_changed(const String &p_string) {
|
||||
if (updating)
|
||||
return;
|
||||
|
||||
emit_changed(get_edited_property(), p_string, "", false);
|
||||
emit_changed(get_edited_property(), p_string, "", true);
|
||||
}
|
||||
|
||||
void EditorPropertyText::update_property() {
|
||||
@ -1917,11 +1917,6 @@ void EditorPropertyColor::_color_changed(const Color &p_color) {
|
||||
emit_changed(get_edited_property(), p_color, "", true);
|
||||
}
|
||||
|
||||
void EditorPropertyColor::_popup_closed() {
|
||||
|
||||
emit_changed(get_edited_property(), picker->get_pick_color(), "", false);
|
||||
}
|
||||
|
||||
void EditorPropertyColor::_picker_created() {
|
||||
// get default color picker mode from editor settings
|
||||
int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
|
||||
@ -1934,7 +1929,6 @@ void EditorPropertyColor::_picker_created() {
|
||||
void EditorPropertyColor::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_color_changed"), &EditorPropertyColor::_color_changed);
|
||||
ClassDB::bind_method(D_METHOD("_popup_closed"), &EditorPropertyColor::_popup_closed);
|
||||
ClassDB::bind_method(D_METHOD("_picker_created"), &EditorPropertyColor::_picker_created);
|
||||
}
|
||||
|
||||
@ -1970,7 +1964,6 @@ EditorPropertyColor::EditorPropertyColor() {
|
||||
add_child(picker);
|
||||
picker->set_flat(true);
|
||||
picker->connect("color_changed", this, "_color_changed");
|
||||
picker->connect("popup_closed", this, "_popup_closed");
|
||||
picker->connect("picker_created", this, "_picker_created");
|
||||
}
|
||||
|
||||
|
@ -493,7 +493,6 @@ class EditorPropertyColor : public EditorProperty {
|
||||
GDCLASS(EditorPropertyColor, EditorProperty);
|
||||
ColorPickerButton *picker;
|
||||
void _color_changed(const Color &p_color);
|
||||
void _popup_closed();
|
||||
void _picker_created();
|
||||
|
||||
protected:
|
||||
|
@ -1331,21 +1331,30 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
|
||||
}
|
||||
} else { // Relative path to an external image file.
|
||||
uri = p_base_path.plus_file(uri).replace("\\", "/"); // Fix for Windows.
|
||||
// The spec says that if mimeType is defined, we should enforce it.
|
||||
// So we should only rely on ResourceLoader::load if mimeType is not defined,
|
||||
// otherwise we should use the same logic as for buffers.
|
||||
if (mimetype == "image/png" || mimetype == "image/jpeg") {
|
||||
// Load data buffer and rely on PNG and JPEG-specific logic below to load the image.
|
||||
// This makes it possible to load a file with a wrong extension but correct MIME type,
|
||||
// e.g. "foo.jpg" containing PNG data and with MIME type "image/png". ResourceLoader would fail.
|
||||
// ResourceLoader will rely on the file extension to use the relevant loader.
|
||||
// The spec says that if mimeType is defined, it should take precedence (e.g.
|
||||
// there could be a `.png` image which is actually JPEG), but there's no easy
|
||||
// API for that in Godot, so we'd have to load as a buffer (i.e. embedded in
|
||||
// the material), so we do this only as fallback.
|
||||
Ref<Texture> texture = ResourceLoader::load(uri);
|
||||
if (texture.is_valid()) {
|
||||
state.images.push_back(texture);
|
||||
continue;
|
||||
} else if (mimetype == "image/png" || mimetype == "image/jpeg") {
|
||||
// Fallback to loading as byte array.
|
||||
// This enables us to support the spec's requirement that we honor mimetype
|
||||
// regardless of file URI.
|
||||
data = FileAccess::get_file_as_array(uri);
|
||||
ERR_FAIL_COND_V_MSG(data.size() == 0, ERR_PARSE_ERROR, "glTF: Couldn't load image file as an array: " + uri);
|
||||
if (data.size() == 0) {
|
||||
WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded as a buffer of MIME type '%s' from URI: %s. Skipping it.", i, mimetype, uri));
|
||||
state.images.push_back(Ref<Texture>()); // Placeholder to keep count.
|
||||
continue;
|
||||
}
|
||||
data_ptr = data.ptr();
|
||||
data_size = data.size();
|
||||
} else {
|
||||
// Good old ResourceLoader will rely on file extension.
|
||||
Ref<Texture> texture = ResourceLoader::load(uri);
|
||||
state.images.push_back(texture);
|
||||
WARN_PRINT(vformat("glTF: Image index '%d' couldn't be loaded from URI: %s. Skipping it.", i, uri));
|
||||
state.images.push_back(Ref<Texture>()); // Placeholder to keep count.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -932,8 +932,23 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it
|
||||
}
|
||||
|
||||
void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones) {
|
||||
undo_redo->create_action(action_name);
|
||||
List<CanvasItem *> modified_canvas_items;
|
||||
for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) {
|
||||
CanvasItem *canvas_item = E->get();
|
||||
Dictionary old_state = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item)->undo_state;
|
||||
Dictionary new_state = canvas_item->_edit_get_state();
|
||||
|
||||
if (old_state.hash() != new_state.hash()) {
|
||||
modified_canvas_items.push_back(canvas_item);
|
||||
}
|
||||
}
|
||||
|
||||
if (modified_canvas_items.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
undo_redo->create_action(action_name);
|
||||
for (List<CanvasItem *>::Element *E = modified_canvas_items.front(); E; E = E->next()) {
|
||||
CanvasItem *canvas_item = E->get();
|
||||
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
||||
undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
|
||||
|
@ -235,6 +235,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
|
||||
}
|
||||
|
||||
editor_data->get_undo_redo().commit_action();
|
||||
editor->push_item(instances[instances.size() - 1]);
|
||||
}
|
||||
|
||||
void SceneTreeDock::_replace_with_branch_scene(const String &p_file, Node *base) {
|
||||
|
@ -369,11 +369,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||
ClassDB::register_class<Performance>();
|
||||
engine->add_singleton(Engine::Singleton("Performance", performance));
|
||||
|
||||
// Only flush stdout in debug builds by default, as spamming `print()` will
|
||||
// decrease performance if this is enabled.
|
||||
GLOBAL_DEF("application/run/flush_stdout_on_print", false);
|
||||
GLOBAL_DEF("application/run/flush_stdout_on_print.debug", true);
|
||||
|
||||
GLOBAL_DEF("debug/settings/crash_handler/message", String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
|
||||
|
||||
MAIN_PRINT("Main: Parse CMDLine");
|
||||
|
@ -804,7 +804,7 @@
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
Converts one or more arguments to strings in the best way possible and prints them to the console.
|
||||
Converts one or more arguments of any type to string in the best way possible and prints them to the console.
|
||||
[codeblock]
|
||||
a = [1, 2, 3]
|
||||
print("a", "=", a) # Prints a=[1, 2, 3]
|
||||
@ -1138,7 +1138,7 @@
|
||||
<return type="String">
|
||||
</return>
|
||||
<description>
|
||||
Converts one or more arguments to string in the best way possible.
|
||||
Converts one or more arguments of any type to string in the best way possible.
|
||||
[codeblock]
|
||||
var a = [10, 20, 30]
|
||||
var b = str(a);
|
||||
|
@ -37,15 +37,15 @@
|
||||
|
||||
#include "thirdparty/misc/open-simplex-noise.h"
|
||||
|
||||
// The maximum number of octaves allowed. Note that these are statically allocated.
|
||||
// Higher values become exponentially slower, so this shouldn't be set too high
|
||||
// to avoid freezing the editor for long periods of time.
|
||||
#define MAX_OCTAVES 9
|
||||
|
||||
class OpenSimplexNoise : public Resource {
|
||||
GDCLASS(OpenSimplexNoise, Resource);
|
||||
OBJ_SAVE_TYPE(OpenSimplexNoise);
|
||||
|
||||
// The maximum number of octaves allowed. Note that these are statically allocated.
|
||||
// Higher values become exponentially slower, so this shouldn't be set too high
|
||||
// to avoid freezing the editor for long periods of time.
|
||||
static const int MAX_OCTAVES = 9;
|
||||
|
||||
osn_context contexts[MAX_OCTAVES];
|
||||
|
||||
int seed;
|
||||
|
@ -90,18 +90,7 @@
|
||||
<link title="How to make a VR game for WebXR with Godot">https://www.snopekgames.com/blog/2020/how-make-vr-game-webxr-godot</link>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="is_session_supported">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="session_mode" type="String">
|
||||
</argument>
|
||||
<description>
|
||||
Checks if the given [code]session_mode[/code] is supported by the user's browser.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
|
||||
This method returns nothing, instead it emits the [signal session_supported] signal with the result.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_controller">
|
||||
<method name="get_controller" qualifiers="const">
|
||||
<return type="ARVRPositionalTracker">
|
||||
</return>
|
||||
<argument index="0" name="controller_id" type="int">
|
||||
@ -118,18 +107,23 @@
|
||||
- [signal squeezestart]
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_session_supported">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="session_mode" type="String">
|
||||
</argument>
|
||||
<description>
|
||||
Checks if the given [code]session_mode[/code] is supported by the user's browser.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
|
||||
This method returns nothing, instead it emits the [signal session_supported] signal with the result.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="session_mode" type="String" setter="set_session_mode" getter="get_session_mode">
|
||||
The session mode used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
|
||||
</member>
|
||||
<member name="required_features" type="String" setter="set_required_features" getter="get_required_features">
|
||||
A comma-seperated list of required features used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
If a user's browser or device doesn't support one of the given features, initialization will fail and [signal session_failed] will be emitted.
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
|
||||
<member name="bounds_geometry" type="PoolVector3Array" setter="" getter="get_bounds_geometry">
|
||||
The vertices of a polygon which defines the boundaries of the user's play area.
|
||||
This will only be available if [member reference_space_type] is [code]"bounded-floor"[/code] and only on certain browsers and devices that support it.
|
||||
The [signal reference_space_reset] signal may indicate when this changes.
|
||||
</member>
|
||||
<member name="optional_features" type="String" setter="set_optional_features" getter="get_optional_features">
|
||||
A comma-seperated list of optional features used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
@ -137,62 +131,38 @@
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
|
||||
</member>
|
||||
<member name="reference_space_type" type="String" setter="" getter="get_reference_space_type">
|
||||
The reference space type (from the list of requested types set in the [member requested_reference_space_types] property), that was ultimately used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
|
||||
</member>
|
||||
<member name="requested_reference_space_types" type="String" setter="set_requested_reference_space_types" getter="get_requested_reference_space_types">
|
||||
A comma-seperated list of reference space types used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
The reference space types are requested in order, and the first on supported by the users device or browser will be used. The [member reference_space_type] property contains the reference space type that was ultimately used.
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
|
||||
</member>
|
||||
<member name="reference_space_type" type="String" setter="" getter="get_reference_space_type">
|
||||
The reference space type (from the list of requested types set in the [member requested_reference_space_types] property), that was ultimately used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
<member name="required_features" type="String" setter="set_required_features" getter="get_required_features">
|
||||
A comma-seperated list of required features used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
If a user's browser or device doesn't support one of the given features, initialization will fail and [signal session_failed] will be emitted.
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpaceType]WebXR's XRReferenceSpaceType[/url]. If you want to use a particular reference space type, it must be listed in either [member required_features] or [member optional_features].
|
||||
</member>
|
||||
<member name="session_mode" type="String" setter="set_session_mode" getter="get_session_mode">
|
||||
The session mode used by [method ARVRInterface.initialize] when setting up the WebXR session.
|
||||
This doesn't have any effect on the interface when already initialized.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRSessionMode]WebXR's XRSessionMode[/url], including: [code]"immersive-vr"[/code], [code]"immersive-ar"[/code], and [code]"inline"[/code].
|
||||
</member>
|
||||
<member name="visibility_state" type="String" setter="" getter="get_visibility_state">
|
||||
Indicates if the WebXR session's imagery is visible to the user.
|
||||
Possible values come from [url=https://developer.mozilla.org/en-US/docs/Web/API/XRVisibilityState]WebXR's XRVisibilityState[/url], including [code]"hidden"[/code], [code]"visible"[/code], and [code]"visible-blurred"[/code].
|
||||
</member>
|
||||
<member name="bounds_geometry" type="PoolVector3Array" setter="" getter="get_bounds_geometry">
|
||||
The vertices of a polygon which defines the boundaries of the user's play area.
|
||||
This will only be available if [member reference_space_type] is [code]"bounded-floor"[/code] and only on certain browsers and devices that support it.
|
||||
The [signal reference_space_reset] signal may indicate when this changes.
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="session_supported">
|
||||
<argument index="0" name="session_mode" type="String">
|
||||
</argument>
|
||||
<argument index="1" name="supported" type="bool">
|
||||
</argument>
|
||||
<signal name="reference_space_reset">
|
||||
<description>
|
||||
Emitted by [method is_session_supported] to indicate if the given [code]session_mode[/code] is supported or not.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_started">
|
||||
<description>
|
||||
Emitted by [method ARVRInterface.initialize] if the session is successfully started.
|
||||
At this point, it's safe to do [code]get_viewport().arvr = true[/code] to instruct Godot to start rendering to the AR/VR device.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_failed">
|
||||
<argument index="0" name="message" type="String">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted by [method ARVRInterface.initialize] if the session fails to start.
|
||||
[code]message[/code] may optionally contain an error message from WebXR, or an empty string if no message is available.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_ended">
|
||||
<description>
|
||||
Emitted when the user ends the WebXR session (which can be done using UI from the browser or device).
|
||||
At this point, you should do [code]get_viewport().arvr = false[/code] to instruct Godot to resume rendering to the screen.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="selectstart">
|
||||
<argument index="0" name="controller_id" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted when one of the "controllers" has started its "primary action".
|
||||
Use [method get_controller] to get more information about the controller.
|
||||
Emitted to indicate that the reference space has been reset or reconfigured.
|
||||
When (or whether) this is emitted depends on the user's browser or device, but may include when the user has changed the dimensions of their play space (which you may be able to access via [member bounds_geometry]) or pressed/held a button to recenter their position.
|
||||
See [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace/reset_event]WebXR's XRReferenceSpace reset event[/url] for more information.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="select">
|
||||
@ -211,14 +181,43 @@
|
||||
Use [method get_controller] to get more information about the controller.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="squeezestart">
|
||||
<signal name="selectstart">
|
||||
<argument index="0" name="controller_id" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted when one of the "controllers" has started its "primary squeeze action".
|
||||
Emitted when one of the "controllers" has started its "primary action".
|
||||
Use [method get_controller] to get more information about the controller.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_ended">
|
||||
<description>
|
||||
Emitted when the user ends the WebXR session (which can be done using UI from the browser or device).
|
||||
At this point, you should do [code]get_viewport().arvr = false[/code] to instruct Godot to resume rendering to the screen.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_failed">
|
||||
<argument index="0" name="message" type="String">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted by [method ARVRInterface.initialize] if the session fails to start.
|
||||
[code]message[/code] may optionally contain an error message from WebXR, or an empty string if no message is available.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_started">
|
||||
<description>
|
||||
Emitted by [method ARVRInterface.initialize] if the session is successfully started.
|
||||
At this point, it's safe to do [code]get_viewport().arvr = true[/code] to instruct Godot to start rendering to the AR/VR device.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="session_supported">
|
||||
<argument index="0" name="session_mode" type="String">
|
||||
</argument>
|
||||
<argument index="1" name="supported" type="bool">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted by [method is_session_supported] to indicate if the given [code]session_mode[/code] is supported or not.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="squeeze">
|
||||
<argument index="0" name="controller_id" type="int">
|
||||
</argument>
|
||||
@ -235,18 +234,19 @@
|
||||
Use [method get_controller] to get more information about the controller.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="squeezestart">
|
||||
<argument index="0" name="controller_id" type="int">
|
||||
</argument>
|
||||
<description>
|
||||
Emitted when one of the "controllers" has started its "primary squeeze action".
|
||||
Use [method get_controller] to get more information about the controller.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="visibility_state_changed">
|
||||
<description>
|
||||
Emitted when [member visibility_state] has changed.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="reference_space_reset">
|
||||
<description>
|
||||
Emitted to indicate that the reference space has been reset or reconfigured.
|
||||
When (or whether) this is emitted depends on the user's browser or device, but may include when the user has changed the dimensions of their play space (which you may be able to access via [member bounds_geometry]) or pressed/held a button to recenter their position.
|
||||
See [url=https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace/reset_event]WebXR's XRReferenceSpace reset event[/url] for more information.
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
<constants>
|
||||
</constants>
|
||||
|
@ -42,7 +42,7 @@ void WebXRInterface::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_reference_space_type"), &WebXRInterface::get_reference_space_type);
|
||||
ClassDB::bind_method(D_METHOD("set_requested_reference_space_types", "requested_reference_space_types"), &WebXRInterface::set_requested_reference_space_types);
|
||||
ClassDB::bind_method(D_METHOD("get_requested_reference_space_types"), &WebXRInterface::get_requested_reference_space_types);
|
||||
ClassDB::bind_method(D_METHOD("get_controller"), &WebXRInterface::get_controller);
|
||||
ClassDB::bind_method(D_METHOD("get_controller", "controller_id"), &WebXRInterface::get_controller);
|
||||
ClassDB::bind_method(D_METHOD("get_visibility_state"), &WebXRInterface::get_visibility_state);
|
||||
ClassDB::bind_method(D_METHOD("get_bounds_geometry"), &WebXRInterface::get_bounds_geometry);
|
||||
|
||||
|
@ -1049,8 +1049,9 @@ void TileMap::update_dirty_bitmask() {
|
||||
void TileMap::fix_invalid_tiles() {
|
||||
|
||||
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open.");
|
||||
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
|
||||
|
||||
Map<PosKey, Cell> temp_tile_map = tile_map;
|
||||
for (Map<PosKey, Cell>::Element *E = temp_tile_map.front(); E; E = E->next()) {
|
||||
if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) {
|
||||
set_cell(E->key().x, E->key().y, INVALID_CELL);
|
||||
}
|
||||
|
@ -506,6 +506,8 @@ void AnimationNodeStateMachinePlayback::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
|
||||
ClassDB::bind_method(D_METHOD("is_playing"), &AnimationNodeStateMachinePlayback::is_playing);
|
||||
ClassDB::bind_method(D_METHOD("get_current_node"), &AnimationNodeStateMachinePlayback::get_current_node);
|
||||
ClassDB::bind_method(D_METHOD("get_current_play_position"), &AnimationNodeStateMachinePlayback::get_current_play_pos);
|
||||
ClassDB::bind_method(D_METHOD("get_current_length"), &AnimationNodeStateMachinePlayback::get_current_length);
|
||||
ClassDB::bind_method(D_METHOD("get_travel_path"), &AnimationNodeStateMachinePlayback::get_travel_path);
|
||||
}
|
||||
|
||||
|
@ -568,9 +568,8 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
|
||||
|
||||
if (handled) {
|
||||
accept_event();
|
||||
} else if (!k->get_command() || (k->get_command() && k->get_alt())) {
|
||||
} else if (!k->get_command()) {
|
||||
if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) {
|
||||
|
||||
if (editable) {
|
||||
selection_delete();
|
||||
CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 };
|
||||
|
@ -3766,7 +3766,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scancode_handled && (!k->get_command() || (k->get_command() && k->get_alt()))) { // For German keyboards.
|
||||
if (!scancode_handled && !k->get_command()) { // For German keyboards.
|
||||
|
||||
if (k->get_unicode() >= 32) {
|
||||
|
||||
|
@ -1590,7 +1590,7 @@ void Viewport::_gui_show_tooltip() {
|
||||
gui.tooltip_control,
|
||||
gui.tooltip_control->get_global_transform().xform_inv(gui.tooltip_pos),
|
||||
&tooltip_owner);
|
||||
tooltip_text.strip_edges();
|
||||
tooltip_text = tooltip_text.strip_edges();
|
||||
if (tooltip_text.empty()) {
|
||||
return; // Nothing to show.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user