Merge pull request #46931 from akien-mga/3.2-cherrypicks
Cherry-picks for the 3.2 branch (future 3.2.4) - 28th batch
This commit is contained in:
commit
e3b16be6cd
|
@ -798,6 +798,8 @@ Dictionary _OS::get_time(bool utc) const {
|
|||
* @return epoch calculated
|
||||
*/
|
||||
int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||
// if datetime is an empty Dictionary throws an error
|
||||
ERR_FAIL_COND_V_MSG(datetime.empty(), 0, "Invalid datetime Dictionary: Dictionary is empty");
|
||||
|
||||
// Bunch of conversion constants
|
||||
static const unsigned int SECONDS_PER_MINUTE = 60;
|
||||
|
|
|
@ -47,7 +47,7 @@ uint64_t Thread::_thread_id_hash(const std::thread::id &p_t) {
|
|||
}
|
||||
|
||||
Thread::ID Thread::main_thread_id = _thread_id_hash(std::this_thread::get_id());
|
||||
thread_local Thread::ID Thread::caller_id = _thread_id_hash(std::this_thread::get_id());
|
||||
thread_local Thread::ID Thread::caller_id = 0;
|
||||
|
||||
void Thread::_set_platform_funcs(
|
||||
Error (*p_set_name_func)(const String &),
|
||||
|
@ -112,6 +112,10 @@ Error Thread::set_name(const String &p_name) {
|
|||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
Thread::Thread() {
|
||||
caller_id = _thread_id_hash(std::this_thread::get_id());
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
if (id != _thread_id_hash(std::thread::id())) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
///< waits until thread is finished, and deallocates it.
|
||||
void wait_to_finish();
|
||||
|
||||
Thread();
|
||||
~Thread();
|
||||
#else
|
||||
_FORCE_INLINE_ ID get_id() const { return 0; }
|
||||
|
|
|
@ -549,6 +549,7 @@
|
|||
<description>
|
||||
Gets an epoch time value from a dictionary of time values.
|
||||
[code]datetime[/code] must be populated with the following keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]hour[/code], [code]minute[/code], [code]second[/code].
|
||||
If the dictionary is empty [code]0[/code] is returned.
|
||||
You can pass the output from [method get_datetime_from_unix_time] directly into this function. Daylight Savings Time ([code]dst[/code]), if present, is ignored.
|
||||
</description>
|
||||
</method>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<return type="RID">
|
||||
</return>
|
||||
<description>
|
||||
Creates an [Area2D].
|
||||
Creates an [Area2D]. After creating an [Area2D] with this method, assign it to a space using [method area_set_space] to use the created [Area2D] in the physics world.
|
||||
</description>
|
||||
</method>
|
||||
<method name="area_get_canvas_instance_id" qualifiers="const">
|
||||
|
|
|
@ -299,6 +299,7 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
|
|||
}
|
||||
|
||||
Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
|
||||
ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export.");
|
||||
|
||||
PackData *pd = (PackData *)p_userdata;
|
||||
|
||||
|
@ -332,6 +333,7 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
|
|||
}
|
||||
|
||||
Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
|
||||
ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export.");
|
||||
|
||||
String path = p_path.replace_first("res://", "");
|
||||
|
||||
|
@ -740,18 +742,26 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
// Ignore import files, since these are automatically added to the jar later with the resources
|
||||
_edit_filter_list(paths, String("*.import"), true);
|
||||
|
||||
Error err = OK;
|
||||
Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
|
||||
|
||||
for (int i = 0; i < export_plugins.size(); i++) {
|
||||
|
||||
export_plugins.write[i]->set_export_preset(p_preset);
|
||||
|
||||
if (p_so_func) {
|
||||
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
|
||||
p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
|
||||
err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
|
||||
p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
|
||||
err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
export_plugins.write[i]->_clear();
|
||||
|
@ -774,7 +784,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
//file is imported, replace by what it imports
|
||||
Ref<ConfigFile> config;
|
||||
config.instance();
|
||||
Error err = config->load(path + ".import");
|
||||
err = config->load(path + ".import");
|
||||
if (err != OK) {
|
||||
ERR_PRINTS("Could not parse: '" + path + "', not exported.");
|
||||
continue;
|
||||
|
@ -841,12 +851,18 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
}
|
||||
if (p_so_func) {
|
||||
for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
|
||||
p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
|
||||
err = p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
|
||||
p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total);
|
||||
err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
if (export_plugins[i]->extra_files[j].remap) {
|
||||
do_export = false; //if remap, do not
|
||||
path_remaps.push_back(path);
|
||||
|
@ -865,7 +881,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
//just store it as it comes
|
||||
if (do_export) {
|
||||
Vector<uint8_t> array = FileAccess::get_file_as_array(path);
|
||||
p_func(p_udata, path, array, idx, total);
|
||||
err = p_func(p_udata, path, array, idx, total);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -902,7 +921,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
new_file.write[j] = utf8[j];
|
||||
}
|
||||
|
||||
p_func(p_udata, from + ".remap", new_file, idx, total);
|
||||
err = p_func(p_udata, from + ".remap", new_file, idx, total);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//old remap mode, will still work, but it's unused because it's not multiple pck export friendly
|
||||
|
@ -915,11 +937,17 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
|
||||
if (icon != String() && FileAccess::exists(icon)) {
|
||||
Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
|
||||
p_func(p_udata, icon, array, idx, total);
|
||||
err = p_func(p_udata, icon, array, idx, total);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (splash != String() && FileAccess::exists(splash) && icon != splash) {
|
||||
Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
|
||||
p_func(p_udata, splash, array, idx, total);
|
||||
err = p_func(p_udata, splash, array, idx, total);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
String config_file = "project.binary";
|
||||
|
@ -928,9 +956,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
|
|||
Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
|
||||
DirAccess::remove_file_or_error(engine_cfb);
|
||||
|
||||
p_func(p_udata, "res://" + config_file, data, idx, total);
|
||||
|
||||
return OK;
|
||||
return p_func(p_udata, "res://" + config_file, data, idx, total);
|
||||
}
|
||||
|
||||
Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObject &p_so) {
|
||||
|
@ -965,6 +991,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
|
|||
|
||||
if (err != OK) {
|
||||
DirAccess::remove_file_or_error(tmppath);
|
||||
ERR_PRINT("Failed to export project files");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -924,9 +924,11 @@ void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_it
|
|||
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
|
||||
CanvasItem *canvas_item = E->get();
|
||||
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
||||
canvas_item->_edit_set_state(se->undo_state);
|
||||
if (restore_bones) {
|
||||
_restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state));
|
||||
if (se) {
|
||||
canvas_item->_edit_set_state(se->undo_state);
|
||||
if (restore_bones) {
|
||||
_restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -951,13 +953,15 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
|
|||
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());
|
||||
undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state);
|
||||
if (commit_bones) {
|
||||
for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) {
|
||||
canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
|
||||
undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
|
||||
undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get());
|
||||
if (se) {
|
||||
undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
|
||||
undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state);
|
||||
if (commit_bones) {
|
||||
for (List<Dictionary>::Element *F = se->pre_drag_bones_undo_state.front(); F; F = F->next()) {
|
||||
canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
|
||||
undo_redo->add_do_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state());
|
||||
undo_redo->add_undo_method(canvas_item, "_edit_set_state", F->get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2126,17 +2130,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
|
|||
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
|
||||
CanvasItem *canvas_item = E->get();
|
||||
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
||||
Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
|
||||
if (se) {
|
||||
Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
|
||||
|
||||
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
|
||||
if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) {
|
||||
real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
_restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
|
||||
real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
|
||||
_solve_IK(node2d, new_pos);
|
||||
} else {
|
||||
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
|
||||
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
|
||||
if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) {
|
||||
real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
_restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
|
||||
real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
|
||||
_solve_IK(node2d, new_pos);
|
||||
} else {
|
||||
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
@ -2258,17 +2264,19 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
|
|||
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
|
||||
CanvasItem *canvas_item = E->get();
|
||||
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
|
||||
Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
|
||||
if (se) {
|
||||
Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform();
|
||||
|
||||
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
|
||||
if (node2d && se->pre_drag_bones_undo_state.size() > 0) {
|
||||
real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
_restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
|
||||
real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
|
||||
_solve_IK(node2d, new_pos);
|
||||
} else {
|
||||
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
|
||||
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
|
||||
if (node2d && se->pre_drag_bones_undo_state.size() > 0) {
|
||||
real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
_restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
|
||||
real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
|
||||
node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
|
||||
_solve_IK(node2d, new_pos);
|
||||
} else {
|
||||
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
|
|
@ -502,7 +502,7 @@
|
|||
showTab('loader');
|
||||
setLoaderEnabled(true);
|
||||
};
|
||||
editor.start({'args': args});
|
||||
editor.start({'args': args, 'persistentDrops': is_project_manager});
|
||||
});
|
||||
}, 0);
|
||||
OnEditorExit = null;
|
||||
|
@ -563,7 +563,7 @@
|
|||
//selectVideoMode();
|
||||
showTab('editor');
|
||||
setLoaderEnabled(false);
|
||||
editor.start({'args': ['--video-driver', video_driver]}).then(function() {
|
||||
editor.start({'args': ['--project-manager', '--video-driver', video_driver], 'persistentDrops': true}).then(function() {
|
||||
setStatusMode('hidden');
|
||||
initializing = false;
|
||||
});
|
||||
|
|
|
@ -53,7 +53,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
// This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!!
|
||||
#ifdef _WIN32
|
||||
#ifdef __GNUC__
|
||||
#define GDN_EXPORT __attribute__((visibility("default")))
|
||||
#elif defined(_WIN32)
|
||||
#define GDN_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define GDN_EXPORT
|
||||
|
|
|
@ -103,6 +103,11 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
|
|||
* @type {Array.<string>}
|
||||
*/
|
||||
persistentPaths: ['/userfs'],
|
||||
/**
|
||||
* @ignore
|
||||
* @type {boolean}
|
||||
*/
|
||||
persistentDrops: false,
|
||||
/**
|
||||
* @ignore
|
||||
* @type {Array.<string>}
|
||||
|
@ -231,6 +236,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
|
|||
this.locale = parse('locale', this.locale);
|
||||
this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
|
||||
this.persistentPaths = parse('persistentPaths', this.persistentPaths);
|
||||
this.persistentDrops = parse('persistentDrops', this.persistentDrops);
|
||||
this.experimentalVK = parse('experimentalVK', this.experimentalVK);
|
||||
this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
|
||||
this.fileSizes = parse('fileSizes', this.fileSizes);
|
||||
|
@ -316,6 +322,7 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
|
|||
'canvas': this.canvas,
|
||||
'canvasResizePolicy': this.canvasResizePolicy,
|
||||
'locale': locale,
|
||||
'persistentDrops': this.persistentDrops,
|
||||
'virtualKeyboard': this.experimentalVK,
|
||||
'onExecute': this.onExecute,
|
||||
'onExit': function (p_code) {
|
||||
|
|
|
@ -192,33 +192,45 @@ const GodotDisplayDragDrop = {
|
|||
GodotDisplayDragDrop.promises = [];
|
||||
GodotDisplayDragDrop.pending_files = [];
|
||||
callback(drops);
|
||||
const dirs = [DROP.substr(0, DROP.length - 1)];
|
||||
// Remove temporary files
|
||||
files.forEach(function (file) {
|
||||
FS.unlink(file);
|
||||
let dir = file.replace(DROP, '');
|
||||
let idx = dir.lastIndexOf('/');
|
||||
while (idx > 0) {
|
||||
dir = dir.substr(0, idx);
|
||||
if (dirs.indexOf(DROP + dir) === -1) {
|
||||
dirs.push(DROP + dir);
|
||||
}
|
||||
idx = dir.lastIndexOf('/');
|
||||
if (GodotConfig.persistent_drops) {
|
||||
// Delay removal at exit.
|
||||
GodotOS.atexit(function (resolve, reject) {
|
||||
GodotDisplayDragDrop.remove_drop(files, DROP);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
GodotDisplayDragDrop.remove_drop(files, DROP);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove_drop: function (files, drop_path) {
|
||||
const dirs = [drop_path.substr(0, drop_path.length - 1)];
|
||||
// Remove temporary files
|
||||
files.forEach(function (file) {
|
||||
FS.unlink(file);
|
||||
let dir = file.replace(drop_path, '');
|
||||
let idx = dir.lastIndexOf('/');
|
||||
while (idx > 0) {
|
||||
dir = dir.substr(0, idx);
|
||||
if (dirs.indexOf(drop_path + dir) === -1) {
|
||||
dirs.push(drop_path + dir);
|
||||
}
|
||||
});
|
||||
// Remove dirs.
|
||||
dirs.sort(function (a, b) {
|
||||
const al = (a.match(/\//g) || []).length;
|
||||
const bl = (b.match(/\//g) || []).length;
|
||||
if (al > bl) {
|
||||
return -1;
|
||||
} else if (al < bl) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}).forEach(function (dir) {
|
||||
FS.rmdir(dir);
|
||||
});
|
||||
idx = dir.lastIndexOf('/');
|
||||
}
|
||||
});
|
||||
// Remove dirs.
|
||||
dirs.sort(function (a, b) {
|
||||
const al = (a.match(/\//g) || []).length;
|
||||
const bl = (b.match(/\//g) || []).length;
|
||||
if (al > bl) {
|
||||
return -1;
|
||||
} else if (al < bl) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}).forEach(function (dir) {
|
||||
FS.rmdir(dir);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -908,6 +920,7 @@ const GodotDisplay = {
|
|||
canvas.style.left = 0;
|
||||
break;
|
||||
}
|
||||
GodotDisplayScreen.updateSize();
|
||||
if (p_fullscreen) {
|
||||
GodotDisplayScreen.requestFullscreen();
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ const GodotConfig = {
|
|||
locale: 'en',
|
||||
canvas_resize_policy: 2, // Adaptive
|
||||
virtual_keyboard: false,
|
||||
persistent_drops: false,
|
||||
on_execute: null,
|
||||
on_exit: null,
|
||||
|
||||
|
@ -68,6 +69,7 @@ const GodotConfig = {
|
|||
GodotConfig.canvas = p_opts['canvas'];
|
||||
GodotConfig.locale = p_opts['locale'] || GodotConfig.locale;
|
||||
GodotConfig.virtual_keyboard = p_opts['virtualKeyboard'];
|
||||
GodotConfig.persistent_drops = !!p_opts['persistentDrops'];
|
||||
GodotConfig.on_execute = p_opts['onExecute'];
|
||||
GodotConfig.on_exit = p_opts['onExit'];
|
||||
},
|
||||
|
@ -80,6 +82,7 @@ const GodotConfig = {
|
|||
GodotConfig.locale = 'en';
|
||||
GodotConfig.canvas_resize_policy = 2;
|
||||
GodotConfig.virtual_keyboard = false;
|
||||
GodotConfig.persistent_drops = false;
|
||||
GodotConfig.on_execute = null;
|
||||
GodotConfig.on_exit = null;
|
||||
},
|
||||
|
|
|
@ -70,7 +70,9 @@ Dictionary Control::_edit_get_state() const {
|
|||
}
|
||||
|
||||
void Control::_edit_set_state(const Dictionary &p_state) {
|
||||
|
||||
ERR_FAIL_COND((p_state.size() <= 0) ||
|
||||
!p_state.has("rotation") || !p_state.has("scale") ||
|
||||
!p_state.has("pivot") || !p_state.has("anchors") || !p_state.has("offsets"));
|
||||
Dictionary state = p_state;
|
||||
|
||||
set_rotation(state["rotation"]);
|
||||
|
|
Loading…
Reference in New Issue