diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/canvas_layer.cpp | 4 | ||||
-rw-r--r-- | scene/main/canvas_layer.h | 4 | ||||
-rw-r--r-- | scene/main/http_request.cpp | 7 | ||||
-rw-r--r-- | scene/main/http_request.h | 4 | ||||
-rw-r--r-- | scene/main/instance_placeholder.cpp | 4 | ||||
-rw-r--r-- | scene/main/instance_placeholder.h | 4 | ||||
-rw-r--r-- | scene/main/node.cpp | 134 | ||||
-rw-r--r-- | scene/main/node.h | 6 | ||||
-rw-r--r-- | scene/main/resource_preloader.cpp | 4 | ||||
-rw-r--r-- | scene/main/resource_preloader.h | 4 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 5 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 4 | ||||
-rwxr-xr-x | scene/main/timer.cpp | 4 | ||||
-rwxr-xr-x | scene/main/timer.h | 4 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 151 | ||||
-rw-r--r-- | scene/main/viewport.h | 10 |
16 files changed, 223 insertions, 130 deletions
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp index 89bc8c1226..2b1991ebb0 100644 --- a/scene/main/canvas_layer.cpp +++ b/scene/main/canvas_layer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h index aae23fbb12..5d67245102 100644 --- a/scene/main/canvas_layer.h +++ b/scene/main/canvas_layer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index a9b7fba9c7..8b68b3215c 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -220,13 +220,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) { Error err; if (new_request.begins_with("http")) { // New url, request all again - err = _parse_url(new_request); + _parse_url(new_request); } else { request_string = new_request; } err = _request(); - if (err == OK) { request_sent = false; got_response = false; diff --git a/scene/main/http_request.h b/scene/main/http_request.h index de09d2afda..baabda4010 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp index 0ee5648de2..71addd6fea 100644 --- a/scene/main/instance_placeholder.cpp +++ b/scene/main/instance_placeholder.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h index 2158257c93..3d0e879b2b 100644 --- a/scene/main/instance_placeholder.h +++ b/scene/main/instance_placeholder.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/node.cpp b/scene/main/node.cpp index ae2ab2af80..6aa3891035 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -959,7 +959,9 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) { #ifdef TOOLS_ENABLED String Node::validate_child_name(Node *p_child) { - return _generate_serial_child_name(p_child); + StringName name = p_child->data.name; + _generate_serial_child_name(p_child, name); + return name; } #endif @@ -972,7 +974,9 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { //this approach to autoset node names is human readable but very slow //it's turned on while running in the editor - p_child->data.name = _generate_serial_child_name(p_child); + StringName name = p_child->data.name; + _generate_serial_child_name(p_child, name); + p_child->data.name = name; } else { @@ -1008,74 +1012,120 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) { } } -String Node::_generate_serial_child_name(Node *p_child) { +// Return s + 1 as if it were an integer +String increase_numeric_string(const String &s) { - String name = p_child->data.name; + String res = s; + bool carry = res.length() > 0; - if (name == "") { + for (int i = res.length() - 1; i >= 0; i--) { + if (!carry) { + break; + } + CharType n = s[i]; + if (n == '9') { // keep carry as true: 9 + 1 + res[i] = '0'; + } else { + res[i] = s[i] + 1; + carry = false; + } + } + + if (carry) { + res = "1" + res; + } + + return res; +} + +void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const { + + if (name == StringName()) { + //no name and a new nade is needed, create one. name = p_child->get_class(); // Adjust casing according to project setting. The current type name is expected to be in PascalCase. switch (ProjectSettings::get_singleton()->get("node/name_casing").operator int()) { case NAME_CASING_PASCAL_CASE: break; - case NAME_CASING_CAMEL_CASE: - name[0] = name.to_lower()[0]; - break; + case NAME_CASING_CAMEL_CASE: { + String n = name; + n[0] = n.to_lower()[0]; + name = n; + } break; case NAME_CASING_SNAKE_CASE: - name = name.camelcase_to_underscore(true); + name = String(name).camelcase_to_underscore(true); break; } } + //quickly test if proposed name exists + int cc = data.children.size(); //children count + const Node *const *children_ptr = data.children.ptr(); + + { + + bool exists = false; + + for (int i = 0; i < cc; i++) { + if (children_ptr[i] == p_child) { //exclude self in renaming if its already a child + continue; + } + if (children_ptr[i]->data.name == name) { + exists = true; + } + } + + if (!exists) { + return; //if it does not exist, it does not need validation + } + } + // Extract trailing number + String name_string = name; String nums; - for (int i = name.length() - 1; i >= 0; i--) { - CharType n = name[i]; + for (int i = name_string.length() - 1; i >= 0; i--) { + CharType n = name_string[i]; if (n >= '0' && n <= '9') { - nums = String::chr(name[i]) + nums; + nums = String::chr(name_string[i]) + nums; } else { break; } } String nnsep = _get_name_num_separator(); - int num = 0; - bool explicit_zero = false; - if (nums.length() > 0 && name.substr(name.length() - nnsep.length() - nums.length(), nnsep.length()) == nnsep) { - // Base name + Separator + Number - num = nums.to_int(); - name = name.substr(0, name.length() - nnsep.length() - nums.length()); // Keep base name - if (num == 0) { - explicit_zero = true; - } + int name_last_index = name_string.length() - nnsep.length() - nums.length(); + + // Assign the base name + separator to name if we have numbers preceded by a separator + if (nums.length() > 0 && name_string.substr(name_last_index, nnsep.length()) == nnsep) { + name_string = name_string.substr(0, name_last_index + nnsep.length()); + } else { + nums = ""; } - int num_places = nums.length(); for (;;) { - String attempt = (name + (num > 0 || explicit_zero ? nnsep + itos(num).pad_zeros(num_places) : "")).strip_edges(); - bool found = false; - for (int i = 0; i < data.children.size(); i++) { - if (data.children[i] == p_child) + StringName attempt = name_string + nums; + bool exists = false; + + for (int i = 0; i < cc; i++) { + if (children_ptr[i] == p_child) { continue; - if (data.children[i]->data.name == attempt) { - found = true; - break; + } + if (children_ptr[i]->data.name == attempt) { + exists = true; } } - if (!found) { - return attempt; + + if (!exists) { + name = attempt; + return; } else { - if (num == 0) { - if (explicit_zero) { - // Name ended in separator + 0; user expects to get to separator + 1 - num = 1; - } else { - // Name was undecorated so skip to 2 for a more natural result - num = 2; - } + if (nums.length() == 0) { + // Name was undecorated so skip to 2 for a more natural result + nums = "2"; + name_string += nnsep; // Add separator because nums.length() > 0 was false } else { - num++; + nums = increase_numeric_string(nums); } } } diff --git a/scene/main/node.h b/scene/main/node.h index 78db12dda9..1c451ef567 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -159,7 +159,7 @@ private: void _replace_connections_target(Node *p_new_target); void _validate_child_name(Node *p_child, bool p_force_human_readable = false); - String _generate_serial_child_name(Node *p_child); + void _generate_serial_child_name(const Node *p_child, StringName &name) const; void _propagate_reverse_notification(int p_notification); void _propagate_deferred_notification(int p_notification, bool p_reverse); diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp index dbe7daa604..cb1168b73e 100644 --- a/scene/main/resource_preloader.cpp +++ b/scene/main/resource_preloader.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h index 98c7b21f37..3e3be4ac82 100644 --- a/scene/main/resource_preloader.h +++ b/scene/main/resource_preloader.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 3f664bab10..5acb157279 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -639,6 +639,7 @@ void SceneTree::_notification(int p_notification) { } } break; case NOTIFICATION_OS_MEMORY_WARNING: + case NOTIFICATION_OS_IME_UPDATE: case NOTIFICATION_WM_MOUSE_ENTER: case NOTIFICATION_WM_MOUSE_EXIT: case NOTIFICATION_WM_FOCUS_IN: diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index d59cbe05fb..d6ab8c37b2 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 227840531e..2ae950dad5 100755 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/timer.h b/scene/main/timer.h index 2f42252a7e..c492c6b61c 100755 --- a/scene/main/timer.h +++ b/scene/main/timer.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 86992c38f0..0633d194f7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -148,7 +148,7 @@ void ViewportTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene); ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport"), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "viewport_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Viewport", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT), "set_viewport_path_in_scene", "get_viewport_path_in_scene"); } ViewportTexture::ViewportTexture() { @@ -189,7 +189,7 @@ Viewport::GUI::GUI() { dragging = false; mouse_focus = NULL; mouse_click_grabber = NULL; - mouse_focus_button = -1; + mouse_focus_mask = 0; key_focus = NULL; mouse_over = NULL; @@ -435,7 +435,7 @@ void Viewport::_notification(int p_what) { } } - if (!has_mouse_motion) { + if (!has_mouse_motion && physics_has_last_mousepos) { Ref<InputEventMouseMotion> mm; mm.instance(); mm->set_global_position(physics_last_mousepos); @@ -465,6 +465,7 @@ void Viewport::_notification(int p_what) { pos = mm->get_position(); motion_tested = true; + physics_has_last_mousepos = true; physics_last_mousepos = pos; physics_last_mouse_state.alt = mm->get_alt(); physics_last_mouse_state.shift = mm->get_shift(); @@ -643,7 +644,7 @@ void Viewport::_notification(int p_what) { } } - if (!motion_tested && camera && physics_last_mousepos != Vector2(1e20, 1e20)) { + if (!motion_tested && camera && physics_has_last_mousepos) { //test anyway for mouseenter/exit because objects might move Vector3 from = camera->project_ray_origin(physics_last_mousepos); @@ -671,15 +672,7 @@ void Viewport::_notification(int p_what) { case SceneTree::NOTIFICATION_WM_FOCUS_OUT: { if (gui.mouse_focus) { //if mouse is being pressed, send a release event - Ref<InputEventMouseButton> mb; - mb.instance(); - mb->set_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_global_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - Control *c = gui.mouse_focus; - gui.mouse_focus = NULL; - c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + _drop_mouse_focus(); } } break; } @@ -1686,10 +1679,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (mb->is_pressed()) { Size2 pos = mpos; - if (gui.mouse_focus && mb->get_button_index() != gui.mouse_focus_button) { - - //do not steal mouse focus and stuff + if (gui.mouse_focus_mask) { + //do not steal mouse focus and stuff while a focus mask exists + gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask } else { bool is_handled = false; @@ -1734,7 +1727,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { */ gui.mouse_focus = _gui_find_control(pos); - gui.mouse_focus_button = mb->get_button_index(); + gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1); + gui.last_mouse_focus = gui.mouse_focus; if (!gui.mouse_focus) { return; @@ -1755,7 +1749,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { mb->set_position(pos); #ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton()) { + if (ScriptDebugger::get_singleton() && gui.mouse_focus) { Array arr; arr.push_back(gui.mouse_focus->get_path()); @@ -1788,7 +1782,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } - if (gui.mouse_focus->can_process()) { + if (gui.mouse_focus && gui.mouse_focus->can_process()) { _gui_call_input(gui.mouse_focus, mb); } @@ -1837,6 +1831,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { //change mouse accordingly } + gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); //remove from mask + if (!gui.mouse_focus) { //release event is only sent if a mouse focus (previously pressed button) exists return; @@ -1852,12 +1848,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Control *mouse_focus = gui.mouse_focus; //disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise - if (mb->get_button_index() == gui.mouse_focus_button) { + if (gui.mouse_focus_mask == 0) { gui.mouse_focus = NULL; - gui.mouse_focus_button = -1; } - if (mouse_focus->can_process()) { + if (mouse_focus && mouse_focus->can_process()) { _gui_call_input(mouse_focus, mb); } @@ -1900,7 +1895,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.drag_data.get_type() != Variant::NIL) { gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + break; } else { + if (gui.drag_preview != NULL) { + ERR_PRINT("Don't set a drag preview and return null data. Preview was deleted and drag request ignored."); + memdelete(gui.drag_preview); + gui.drag_preview = NULL; + } gui.dragging = false; } @@ -1955,10 +1957,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { // If the mouse is over a menu button, this menu will open automatically // if there is already a pop-up menu open at the same hierarchical level. - if (popup_menu_parent && menu_button && - popup_menu_parent->get_icon().is_null() && - menu_button->get_icon().is_null() && - (popup_menu->get_parent()->get_parent()->is_a_parent_of(menu_button) || + if (popup_menu_parent && menu_button && popup_menu_parent->is_switch_on_hover() && + !menu_button->is_disabled() && menu_button->is_switch_on_hover() && + (popup_menu_parent->get_parent()->is_a_parent_of(menu_button) || menu_button->get_parent()->is_a_parent_of(popup_menu))) { popup_menu->notification(Control::NOTIFICATION_MODAL_CLOSE); @@ -2065,7 +2066,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape); - if (over->can_process()) { + if (over && over->can_process()) { _gui_call_input(over, mm); } @@ -2115,14 +2116,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { set_input_as_handled(); return; } - } else if (gui.mouse_focus) { + } else if (touch_event->get_index() == 0 && gui.last_mouse_focus) { - if (gui.mouse_focus->can_process()) { + if (gui.last_mouse_focus->can_process()) { touch_event = touch_event->xformed_by(Transform2D()); //make a copy touch_event->set_position(gui.focus_inv_xform.xform(pos)); - _gui_call_input(gui.mouse_focus, touch_event); + _gui_call_input(gui.last_mouse_focus, touch_event); } set_input_as_handled(); return; @@ -2406,7 +2407,7 @@ void Viewport::_gui_unfocus_control(Control *p_control) { void Viewport::_gui_hid_control(Control *p_control) { if (gui.mouse_focus == p_control) { - gui.mouse_focus = NULL; + _drop_mouse_focus(); } /* ??? @@ -2433,8 +2434,10 @@ void Viewport::_gui_hid_control(Control *p_control) { void Viewport::_gui_remove_control(Control *p_control) { - if (gui.mouse_focus == p_control) + if (gui.mouse_focus == p_control) { gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + } if (gui.key_focus == p_control) gui.key_focus = NULL; if (gui.mouse_over == p_control) @@ -2483,6 +2486,27 @@ void Viewport::_gui_accept_event() { set_input_as_handled(); } +void Viewport::_drop_mouse_focus() { + + Control *c = gui.mouse_focus; + int mask = gui.mouse_focus_mask; + gui.mouse_focus = NULL; + gui.mouse_focus_mask = 0; + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + Ref<InputEventMouseButton> mb; + mb.instance(); + mb->set_position(c->get_local_mouse_position()); + mb->set_global_position(c->get_local_mouse_position()); + mb->set_button_index(i + 1); + mb->set_pressed(false); + c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + } + } +} + List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { gui.modal_stack.push_back(p_control); @@ -2492,15 +2516,8 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { p_control->_modal_set_prev_focus_owner(0); if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) { - Ref<InputEventMouseButton> mb; - mb.instance(); - mb->set_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_global_position(gui.mouse_focus->get_local_mouse_position()); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - Control *c = gui.mouse_focus; - gui.mouse_focus = NULL; - c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + + _drop_mouse_focus(); } return gui.modal_stack.back(); @@ -2530,24 +2547,45 @@ void Viewport::_post_gui_grab_click_focus() { if (gui.mouse_focus == focus_grabber) return; - Ref<InputEventMouseButton> mb; - mb.instance(); - - //send unclic + int mask = gui.mouse_focus_mask; Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); - mb->set_position(click); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(false); - gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + + Ref<InputEventMouseButton> mb; + mb.instance(); + + //send unclic + + mb->set_position(click); + mb->set_button_index(i + 1); + mb->set_pressed(false); + gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + } + } gui.mouse_focus = focus_grabber; gui.focus_inv_xform = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse(); click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos); - mb->set_position(click); - mb->set_button_index(gui.mouse_focus_button); - mb->set_pressed(true); - gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + + for (int i = 0; i < 3; i++) { + + if (mask & (1 << i)) { + + Ref<InputEventMouseButton> mb; + mb.instance(); + + //send clic + + mb->set_position(click); + mb->set_button_index(i + 1); + mb->set_pressed(true); + gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + } + } } } @@ -3068,7 +3106,8 @@ Viewport::Viewport() { physics_object_picking = false; physics_object_capture = 0; physics_object_over = 0; - physics_last_mousepos = Vector2(1e20, 1e20); + physics_has_last_mousepos = false; + physics_last_mousepos = Vector2(Math_INF, Math_INF); shadow_atlas_size = 0; for (int i = 0; i < 4; i++) { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 44fb322ae2..0565fd3d18 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -209,6 +209,7 @@ private: Transform physics_last_object_transform; Transform physics_last_camera_transform; ObjectID physics_last_id; + bool physics_has_last_mousepos; Vector2 physics_last_mousepos; struct { @@ -271,8 +272,9 @@ private: bool key_event_accepted; Control *mouse_focus; + Control *last_mouse_focus; Control *mouse_click_grabber; - int mouse_focus_button; + int mouse_focus_mask; Control *key_focus; Control *mouse_over; Control *tooltip; @@ -379,6 +381,8 @@ private: void _canvas_layer_add(CanvasLayer *p_canvas_layer); void _canvas_layer_remove(CanvasLayer *p_canvas_layer); + void _drop_mouse_focus(); + protected: void _notification(int p_what); static void _bind_methods(); |