diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/http_request.cpp | 72 | ||||
-rw-r--r-- | scene/main/http_request.h | 1 | ||||
-rw-r--r-- | scene/main/node.cpp | 42 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 27 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 5 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 28 |
6 files changed, 119 insertions, 56 deletions
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 672e893f1b..4afdb56f86 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -36,7 +36,6 @@ void HTTPRequest::_redirect_request(const String &p_new_url) { Error HTTPRequest::_request() { - //print_line("Requesting:\n\tURL: "+url+"\n\tString: "+request_string+"\n\tPort: "+itos(port)+"\n\tSSL: "+itos(use_ssl)+"\n\tValidate SSL: "+itos(validate_ssl)); return client->connect_to_host(url, port, use_ssl, validate_ssl); } @@ -54,37 +53,32 @@ Error HTTPRequest::_parse_url(const String &p_url) { downloaded = 0; redirections = 0; - //print_line("1 url: "+url); - if (url.begins_with("http://")) { - + String url_lower = url.to_lower(); + if (url_lower.begins_with("http://")) { url = url.substr(7, url.length() - 7); - //print_line("no SSL"); - - } else if (url.begins_with("https://")) { + } else if (url_lower.begins_with("https://")) { url = url.substr(8, url.length() - 8); use_ssl = true; port = 443; - //print_line("yes SSL"); } else { ERR_EXPLAIN("Malformed URL"); ERR_FAIL_V(ERR_INVALID_PARAMETER); } - //print_line("2 url: "+url); + if (url.length() < 1) { + ERR_EXPLAIN("URL too short"); + ERR_FAIL_V(ERR_INVALID_PARAMETER); + } int slash_pos = url.find("/"); if (slash_pos != -1) { request_string = url.substr(slash_pos, url.length()); url = url.substr(0, slash_pos); - //print_line("request string: "+request_string); } else { request_string = "/"; - //print_line("no request"); } - //print_line("3 url: "+url); - int colon_pos = url.find(":"); if (colon_pos != -1) { port = url.substr(colon_pos + 1, url.length()).to_int(); @@ -92,8 +86,6 @@ Error HTTPRequest::_parse_url(const String &p_url) { ERR_FAIL_COND_V(port < 1 || port > 65535, ERR_INVALID_PARAMETER); } - //print_line("4 url: "+url); - return OK; } @@ -198,10 +190,8 @@ void HTTPRequest::cancel_request() { } client->close(); body.resize(0); - //downloaded=0; got_response = false; response_code = -1; - //body_len=-1; request_sent = false; requesting = false; } @@ -221,12 +211,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) { response_headers.resize(0); downloaded = 0; for (List<String>::Element *E = rheaders.front(); E; E = E->next()) { - //print_line("HEADER: "+E->get()); response_headers.push_back(E->get()); } if (response_code == 301 || response_code == 302) { - //redirect + // Handle redirect + if (max_redirects >= 0 && redirections >= max_redirects) { call_deferred("_request_done", RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PoolByteArray()); @@ -242,15 +232,13 @@ bool HTTPRequest::_handle_response(bool *ret_value) { } } - //print_line("NEW LOCATION: "+new_request); - if (new_request != "") { - //process redirect + // Process redirect client->close(); - int new_redirs = redirections + 1; //because _request() will clear it + int new_redirs = redirections + 1; // Because _request() will clear it Error err; if (new_request.begins_with("http")) { - //new url, request all again + // New url, request all again err = _parse_url(new_request); } else { request_string = new_request; @@ -258,7 +246,6 @@ bool HTTPRequest::_handle_response(bool *ret_value) { err = _request(); - //print_line("new connection: "+itos(err)); if (err == OK) { request_sent = false; got_response = false; @@ -280,11 +267,11 @@ bool HTTPRequest::_update_connection() { switch (client->get_status()) { case HTTPClient::STATUS_DISCONNECTED: { call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); - return true; //end it, since it's doing something + return true; // End it, since it's doing something } break; case HTTPClient::STATUS_RESOLVING: { client->poll(); - //must wait + // Must wait return false; } break; case HTTPClient::STATUS_CANT_RESOLVE: { @@ -294,9 +281,9 @@ bool HTTPRequest::_update_connection() { } break; case HTTPClient::STATUS_CONNECTING: { client->poll(); - //must wait + // Must wait return false; - } break; //connecting to ip + } break; // Connecting to IP case HTTPClient::STATUS_CANT_CONNECT: { call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PoolStringArray(), PoolByteArray()); @@ -309,7 +296,7 @@ bool HTTPRequest::_update_connection() { if (!got_response) { - //no body + // No body bool ret_value; @@ -320,16 +307,16 @@ bool HTTPRequest::_update_connection() { return true; } if (got_response && body_len < 0) { - //chunked transfer is done + // Chunked transfer is done call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); return true; } call_deferred("_request_done", RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PoolByteArray()); return true; - //request migh have been done + // Request migh have been done } else { - //did not request yet, do request + // Did not request yet, do request Error err = client->request(method, request_string, headers, request_data); if (err != OK) { @@ -340,13 +327,13 @@ bool HTTPRequest::_update_connection() { request_sent = true; return false; } - } break; //connected: { } break requests only accepted here + } break; // Connected: break requests only accepted here case HTTPClient::STATUS_REQUESTING: { - //must wait, it's requesting + // Must wait, still requesting client->poll(); return false; - } break; // request in progress + } break; // Request in progress case HTTPClient::STATUS_BODY: { if (!got_response) { @@ -363,7 +350,7 @@ bool HTTPRequest::_update_connection() { } if (client->is_response_chunked()) { - body_len = -1; //no body len because chunked, change your webserver configuration if you want body len + body_len = -1; // No body len because chunked, change your webserver configuration if you want body len } else { body_len = client->get_response_body_length(); @@ -383,7 +370,6 @@ bool HTTPRequest::_update_connection() { } } - //print_line("BODY: "+itos(body.size())); client->poll(); PoolByteArray chunk = client->read_response_body_chunk(); @@ -411,15 +397,11 @@ bool HTTPRequest::_update_connection() { call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body); return true; } - /*if (body.size()>=body_len) { - call_deferred("_request_done",RESULT_BODY_SIZE_MISMATCH,response_code,response_headers,ByteArray()); - return true; - }*/ } return false; - } break; // request resulted in body: { } break which must be read + } break; // Request resulted in body: break which must be read case HTTPClient::STATUS_CONNECTION_ERROR: { call_deferred("_request_done", RESULT_CONNECTION_ERROR, 0, PoolStringArray(), PoolByteArray()); return true; @@ -449,7 +431,7 @@ void HTTPRequest::_notification(int p_what) { if (done) { set_process_internal(false); - //cancel_request(); called from _request done now + // cancel_request(); called from _request done now } } @@ -543,7 +525,7 @@ void HTTPRequest::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,1024"), "set_max_redirects", "get_max_redirects"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::POOL_STRING_ARRAY, "headers"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "body"))); diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 790ff5f7ef..ab5a79c40d 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -42,7 +42,6 @@ class HTTPRequest : public Node { public: enum Result { RESULT_SUCCESS, - //RESULT_NO_BODY, RESULT_CHUNKED_BODY_SIZE_MISMATCH, RESULT_CANT_CONNECT, RESULT_CANT_RESOLVE, diff --git a/scene/main/node.cpp b/scene/main/node.cpp index efc5d269a6..de1ab9959a 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2110,6 +2110,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const StringName script_property_name = CoreStringNames::get_singleton()->_script; + List<const Node *> hidden_roots; List<const Node *> node_tree; node_tree.push_front(this); @@ -2120,11 +2121,16 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) { for (int i = 0; i < N->get()->get_child_count(); ++i) { + Node *descendant = N->get()->get_child(i); // Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later - if (N->get()->get_child(i)->data.owner != this) + // but remember non-instanced nodes that are hidden below instanced ones + if (descendant->data.owner != this) { + if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this) + hidden_roots.push_back(descendant); continue; + } - node_tree.push_back(N->get()->get_child(i)); + node_tree.push_back(descendant); } } } @@ -2156,7 +2162,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const Variant value = N->get()->get(name); // Duplicate dictionaries and arrays, mainly needed for __meta__ if (value.get_type() == Variant::DICTIONARY) { - value = Dictionary(value).copy(); + value = Dictionary(value).duplicate(); } else if (value.get_type() == Variant::ARRAY) { value = Array(value).duplicate(); } @@ -2201,6 +2207,34 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const } node->add_child(dup); + if (i < node->get_child_count() - 1) { + node->move_child(dup, i); + } + } + + for (List<const Node *>::Element *E = hidden_roots.front(); E; E = E->next()) { + + Node *parent = node->get_node(get_path_to(E->get()->data.parent)); + if (!parent) { + + memdelete(node); + return NULL; + } + + Node *dup = E->get()->_duplicate(p_flags, r_duplimap); + if (!dup) { + + memdelete(node); + return NULL; + } + + parent->add_child(dup); + int pos = E->get()->get_position_in_parent(); + + if (pos < parent->get_child_count() - 1) { + + parent->move_child(dup, pos); + } } return node; @@ -2269,7 +2303,7 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p Variant value = get(name); // Duplicate dictionaries and arrays, mainly needed for __meta__ if (value.get_type() == Variant::DICTIONARY) { - value = Dictionary(value).copy(); + value = Dictionary(value).duplicate(); } else if (value.get_type() == Variant::ARRAY) { value = Array(value).duplicate(); } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index deb40800bc..7c31b72bb5 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -38,6 +38,7 @@ #include "os/os.h" #include "print_string.h" #include "project_settings.h" +#include "scene/resources/dynamic_font.h" #include "scene/resources/material.h" #include "scene/resources/mesh.h" #include "scene/resources/packed_scene.h" @@ -495,6 +496,11 @@ bool SceneTree::idle(float p_time) { Size2 win_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height); if (win_size != last_screen_size) { + if (use_font_oversampling) { + DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; + DynamicFont::update_oversampling(); + } + last_screen_size = win_size; _update_root_rect(); @@ -2195,6 +2201,9 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("_connection_failed"), &SceneTree::_connection_failed); ClassDB::bind_method(D_METHOD("_server_disconnected"), &SceneTree::_server_disconnected); + ClassDB::bind_method(D_METHOD("set_use_font_oversampling", "enable"), &SceneTree::set_use_font_oversampling); + ClassDB::bind_method(D_METHOD("is_using_font_oversampling"), &SceneTree::is_using_font_oversampling); + ADD_SIGNAL(MethodInfo("tree_changed")); ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node"))); ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node"))); @@ -2244,6 +2253,20 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) { idle_callbacks[idle_callback_count++] = p_callback; } +void SceneTree::set_use_font_oversampling(bool p_oversampling) { + + use_font_oversampling = p_oversampling; + if (use_font_oversampling) { + DynamicFontAtSize::font_oversampling = OS::get_singleton()->get_window_size().width / root->get_visible_rect().size.width; + } else { + DynamicFontAtSize::font_oversampling = 1.0; + } +} + +bool SceneTree::is_using_font_oversampling() const { + return use_font_oversampling; +} + SceneTree::SceneTree() { singleton = this; @@ -2327,7 +2350,7 @@ SceneTree::SceneTree() { ProjectSettings::get_singleton()->set("rendering/environment/default_environment", ""); } else { //file was erased, notify user. - ERR_PRINTS(RTR("Default Environment as specified in Project Setings (Rendering -> Viewport -> Default Environment) could not be loaded.")); + ERR_PRINTS(RTR("Default Environment as specified in Project Setings (Rendering -> Environment -> Default Environment) could not be loaded.")); } } } @@ -2380,6 +2403,8 @@ SceneTree::SceneTree() { last_send_cache_id = 1; #endif + + use_font_oversampling = false; } SceneTree::~SceneTree() { diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 244fc8da62..9c5b0f69cb 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -122,11 +122,13 @@ private: bool _quit; bool initialized; bool input_handled; + Size2 last_screen_size; StringName tree_changed_name; StringName node_added_name; StringName node_removed_name; + bool use_font_oversampling; int64_t current_frame; int node_count; @@ -420,6 +422,9 @@ public: void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink = 1); + void set_use_font_oversampling(bool p_oversampling); + bool is_using_font_oversampling() const; + //void change_scene(const String& p_path); //Node *get_loaded_scene(); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 4635de81e8..8f431389d8 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1421,7 +1421,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_label->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_TOP)); gui.tooltip_label->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -ttp->get_margin(MARGIN_RIGHT)); gui.tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -ttp->get_margin(MARGIN_BOTTOM)); - gui.tooltip_label->set_text(tooltip); + gui.tooltip_label->set_text(tooltip.strip_edges()); Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_label->get_combined_minimum_size() + ttp->get_minimum_size()); Rect2 vr = gui.tooltip_label->get_viewport_rect(); if (r.size.x + r.position.x > vr.size.x) @@ -1659,6 +1659,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { //cancel event, sorry, modal exclusive EATS UP ALL //alternative, you can't pop out a window the same frame it was made modal (fixes many issues) get_tree()->set_input_as_handled(); + return; // no one gets the event if exclusive NO ONE } @@ -1807,15 +1808,18 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { pos = gui.focus_inv_xform.xform(pos); mb->set_position(pos); - if (gui.mouse_focus->can_process()) { - _gui_call_input(gui.mouse_focus, mb); - } + 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) { gui.mouse_focus = NULL; gui.mouse_focus_button = -1; } + if (mouse_focus->can_process()) { + _gui_call_input(mouse_focus, mb); + } + /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==BUTTON_LEFT) { _propagate_viewport_notification(this,NOTIFICATION_DRAG_END); gui.drag_data=Variant(); //always clear @@ -2348,7 +2352,6 @@ void Viewport::_gui_control_grab_focus(Control *p_control) { //no need for change if (gui.key_focus && gui.key_focus == p_control) return; - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus"); gui.key_focus = p_control; p_control->notification(Control::NOTIFICATION_FOCUS_ENTER); @@ -2370,6 +2373,21 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { else p_control->_modal_set_prev_focus_owner(0); + if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus)) { + 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); + gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb); + + //if (gui.mouse_over == gui.mouse_focus) { + // gui.mouse_focus->notification(Control::NOTIFICATION_MOUSE_EXIT); + //} + gui.mouse_focus = NULL; + } + return gui.modal_stack.back(); } |