diff options
80 files changed, 978 insertions, 333 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 9df31124f8..9cc934bb6f 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -857,7 +857,6 @@ void _OS::print_all_textures_by_size() { for(List<_OSCoreBindImg>::Element *E=imgs.front();E;E=E->next()) { - print_line(E->get().path+" - "+String::humanize_size(E->get().vram)+" ("+E->get().size+") - total:"+String::humanize_size(total) ); total-=E->get().vram; } } @@ -891,19 +890,6 @@ void _OS::print_resources_by_type(const Vector<String>& p_types) { type_count[r->get_type()]++; - - print_line(r->get_type()+": "+r->get_path()); - - List<String> metas; - r->get_meta_list(&metas); - for (List<String>::Element* me = metas.front(); me; me = me->next()) { - print_line(" "+String(me->get()) + ": " + r->get_meta(me->get())); - }; - } - - for(Map<String,int>::Element *E=type_count.front();E;E=E->next()) { - - print_line(E->key()+" count: "+itos(E->get())); } }; @@ -1016,6 +1002,11 @@ void _OS::alert(const String& p_alert,const String& p_title) { OS::get_singleton()->alert(p_alert,p_title); } +Dictionary _OS::get_engine_version() const { + + return OS::get_singleton()->get_engine_version(); +} + _OS *_OS::singleton=NULL; void _OS::_bind_methods() { @@ -1163,6 +1154,8 @@ void _OS::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_use_vsync","enable"),&_OS::set_use_vsync); ObjectTypeDB::bind_method(_MD("is_vsnc_enabled"),&_OS::is_vsnc_enabled); + ObjectTypeDB::bind_method(_MD("get_engine_version"),&_OS::get_engine_version); + BIND_CONSTANT( DAY_SUNDAY ); BIND_CONSTANT( DAY_MONDAY ); BIND_CONSTANT( DAY_TUESDAY ); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 5bd427578a..b43c5246ed 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -315,6 +315,8 @@ public: void set_use_vsync(bool p_enable); bool is_vsnc_enabled() const; + Dictionary get_engine_version() const; + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/globals.cpp b/core/globals.cpp index 9e7b357d73..e760bc00d4 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -1429,7 +1429,7 @@ Globals::Globals() { set("application/name","" ); set("application/main_scene",""); - custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"scn,res,xscn,xml,tscn"); + custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"tscn,scn,xscn,xml,res"); set("application/disable_stdout",false); set("application/use_shared_user_dir",true); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 58f3a4df2b..343a54e0d7 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1105,14 +1105,9 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String for(List<String>::Element *E=extensions.front();E;E=E->next()) { String ext = E->get().to_lower(); - if (ext=="res") - continue; -// p_extensions->push_back("x"+ext); p_extensions->push_back(ext); } - p_extensions->push_back("res"); - } void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_extensions) const{ @@ -1122,12 +1117,9 @@ void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_exten for(List<String>::Element *E=extensions.front();E;E=E->next()) { String ext = E->get().to_lower(); - if (ext=="res") - continue; p_extensions->push_back(ext); } - p_extensions->push_back("res"); } bool ResourceFormatLoaderBinary::handles_type(const String& p_type) const{ @@ -2270,16 +2262,8 @@ bool ResourceFormatSaverBinary::recognize(const RES& p_resource) const { void ResourceFormatSaverBinary::get_recognized_extensions(const RES& p_resource,List<String> *p_extensions) const { - - //here comes the sun, lalalala String base = p_resource->get_base_extension().to_lower(); - if (base!="res") { - - p_extensions->push_back(base); - } - - p_extensions->push_back("res"); - + p_extensions->push_back(base); } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index f414f85df8..08b4139047 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -360,10 +360,18 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ } -void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader) { +void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_loader, bool p_at_front) { ERR_FAIL_COND( loader_count >= MAX_LOADERS ); - loader[loader_count++]=p_format_loader; + if (p_at_front) { + for(int i=loader_count;i>0;i--) { + loader[i]=loader[i-1]; + } + loader[0]=p_format_loader; + loader_count++; + } else { + loader[loader_count++]=p_format_loader; + } } void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types) { diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 6404e6cb13..f976a43d91 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -102,7 +102,7 @@ public: static Ref<ResourceImportMetadata> load_import_metadata(const String &p_path); static void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions); - static void add_resource_format_loader(ResourceFormatLoader *p_format_loader); + static void add_resource_format_loader(ResourceFormatLoader *p_format_loader,bool p_at_front=false); static String get_resource_type(const String &p_path); static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false); static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map); diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index 8d78ecabbf..2ead405440 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -116,10 +116,20 @@ void ResourceSaver::get_recognized_extensions(const RES& p_resource,List<String> } -void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver) { +void ResourceSaver::add_resource_format_saver(ResourceFormatSaver *p_format_saver, bool p_at_front) { ERR_FAIL_COND( saver_count >= MAX_SAVERS ); - saver[saver_count++]=p_format_saver; + + if (p_at_front) { + for(int i=saver_count;i>0;i--) { + saver[i]=saver[i-1]; + } + saver[0]=p_format_saver; + saver_count++; + } else { + saver[saver_count++]=p_format_saver; + } + } diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h index 97500c46f4..b05ae23afc 100644 --- a/core/io/resource_saver.h +++ b/core/io/resource_saver.h @@ -80,7 +80,7 @@ public: static Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0); static void get_recognized_extensions(const RES& p_resource,List<String> *p_extensions); - static void add_resource_format_saver(ResourceFormatSaver *p_format_saver); + static void add_resource_format_saver(ResourceFormatSaver *p_format_saver,bool p_at_front=false); static void set_timestamp_on_save(bool p_timestamp) { timestamp_on_save=p_timestamp; } static void set_save_callback(ResourceSavedCallback p_callback); diff --git a/core/os/input.cpp b/core/os/input.cpp index efbae57950..531db73838 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -66,6 +66,7 @@ void Input::_bind_methods() { ObjectTypeDB::bind_method(_MD("stop_joy_vibration", "device"), &Input::stop_joy_vibration); ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer); ObjectTypeDB::bind_method(_MD("get_magnetometer"),&Input::get_magnetometer); + ObjectTypeDB::bind_method(_MD("get_gyroscope"),&Input::get_gyroscope); //ObjectTypeDB::bind_method(_MD("get_mouse_pos"),&Input::get_mouse_pos); - this is not the function you want ObjectTypeDB::bind_method(_MD("get_mouse_speed"),&Input::get_mouse_speed); ObjectTypeDB::bind_method(_MD("get_mouse_button_mask"),&Input::get_mouse_button_mask); diff --git a/core/os/input.h b/core/os/input.h index d11703470b..16bcc0ff9a 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -82,6 +82,7 @@ public: virtual Vector3 get_accelerometer()=0; virtual Vector3 get_magnetometer()=0; + virtual Vector3 get_gyroscope()=0; virtual void action_press(const StringName& p_action)=0; virtual void action_release(const StringName& p_action)=0; diff --git a/core/os/os.cpp b/core/os/os.cpp index e501bc2eb5..284bcb30cb 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -32,6 +32,8 @@ #include "dir_access.h" #include "globals.h" #include "input.h" +// For get_engine_version, could be removed if it's moved to a new Engine singleton +#include "version.h" OS* OS::singleton=NULL; @@ -548,6 +550,28 @@ bool OS::is_vsnc_enabled() const{ return true; } +Dictionary OS::get_engine_version() const { + + Dictionary dict; + dict["major"] = _MKSTR(VERSION_MAJOR); + dict["minor"] = _MKSTR(VERSION_MINOR); +#ifdef VERSION_PATCH + dict["patch"] = _MKSTR(VERSION_PATCH); +#else + dict["patch"] = ""; +#endif + dict["status"] = _MKSTR(VERSION_STATUS); + dict["revision"] = _MKSTR(VERSION_REVISION); + + String stringver = String(dict["major"]) + "." + String(dict["minor"]); + if (dict["patch"] != "") + stringver += "." + String(dict["patch"]); + stringver += "-" + String(dict["status"]) + " (" + String(dict["revision"]) + ")"; + dict["string"] = stringver; + + return dict; +} + OS::OS() { last_error=NULL; frames_drawn=0; diff --git a/core/os/os.h b/core/os/os.h index c291d09250..40f3989a55 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -186,14 +186,14 @@ public: virtual void set_target_fps(int p_fps); virtual float get_target_fps() const; - virtual float get_frames_per_second() const { return _fps; }; + virtual float get_frames_per_second() const { return _fps; } virtual void set_keep_screen_on(bool p_enabled); virtual bool is_keep_screen_on() const; virtual void set_low_processor_usage_mode(bool p_enabled); virtual bool is_in_low_processor_usage_mode() const; - virtual String get_installed_templates_path() const { return ""; }; + virtual String get_installed_templates_path() const { return ""; } virtual String get_executable_path() const; virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL)=0; virtual Error kill(const ProcessID& p_pid)=0; @@ -363,7 +363,7 @@ public: virtual void set_screen_orientation(ScreenOrientation p_orientation); ScreenOrientation get_screen_orientation() const; - virtual void move_window_to_foreground() {}; + virtual void move_window_to_foreground() {} virtual void debug_break(); @@ -423,6 +423,8 @@ public: virtual void set_use_vsync(bool p_enable); virtual bool is_vsnc_enabled() const; + Dictionary get_engine_version() const; + bool is_hidpi_allowed() const { return _allow_hidpi; } OS(); virtual ~OS(); diff --git a/core/path_db.cpp b/core/path_db.cpp index 0956c4cd3f..d0feda5c82 100644 --- a/core/path_db.cpp +++ b/core/path_db.cpp @@ -53,6 +53,12 @@ uint32_t NodePath::hash() const { } +void NodePath::prepend_period() { + + if (data->path.size() && data->path[0].operator String()!=".") { + data->path.insert(0,"."); + } +} bool NodePath::is_absolute() const { diff --git a/core/path_db.h b/core/path_db.h index 63adb42955..3a550fe1d0 100644 --- a/core/path_db.h +++ b/core/path_db.h @@ -72,6 +72,8 @@ public: NodePath rel_path_to(const NodePath& p_np) const; + void prepend_period(); + StringName get_property() const; NodePath get_parent() const; diff --git a/core/resource.cpp b/core/resource.cpp index b80ec7012d..e8d4069779 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -95,10 +95,9 @@ bool ResourceImportMetadata::has_option(const String& p_key) const { return options.has(p_key); } + Variant ResourceImportMetadata::get_option(const String& p_key) const { - if (!options.has(p_key)) - print_line(p_key); ERR_FAIL_COND_V(!options.has(p_key),Variant()); return options[p_key]; @@ -487,8 +486,6 @@ void ResourceCache::dump(const char* p_file,bool p_short) { if (!p_short) { if (f) f->store_line(r->get_type()+": "+r->get_path()); - else - print_line(r->get_type()+": "+r->get_path()); } } @@ -496,8 +493,6 @@ void ResourceCache::dump(const char* p_file,bool p_short) { if (f) f->store_line(E->key()+" count: "+itos(E->get())); - else - print_line(E->key()+" count: "+itos(E->get())); } if (f) { f->close(); diff --git a/core/translation.cpp b/core/translation.cpp index ee0ef2ea09..01789747ea 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -54,6 +54,9 @@ static const char* locale_list[]={ "be_BY", // Belarusian (Belarus) "bg", // Bulgarian "bg_BG", // Bulgarian (Bulgaria) +"bn", // Bengali +"bn_BD", // Bengali (Bangladesh) +"bn_IN", // Bengali (India) "ca", // Catalan "ca_ES", // Catalan (Spain) "cs", // Czech @@ -178,6 +181,9 @@ static const char* locale_list[]={ "tr_TR", // Turkish (Turkey) "uk", // Ukrainian "uk_UA", // Ukrainian (Ukraine) +"ur", // Urdu +"ur_IN", // Urdu (India) +"ur_PK", // Urdu (Pakistan) "vi", // Vietnamese "vi_VN", // Vietnamese (Vietnam) "zh", // Chinese @@ -211,6 +217,9 @@ static const char* locale_names[]={ "Belarusian (Belarus)", "Bulgarian", "Bulgarian (Bulgaria)", +"Bengali", +"Bengali (Bangladesh)", +"Bengali (India)", "Catalan", "Catalan (Spain)", "Czech", @@ -335,6 +344,9 @@ static const char* locale_names[]={ "Turkish (Turkey)", "Ukrainian", "Ukrainian (Ukraine)", +"Urdu", +"Urdu (India)", +"Urdu (Pakistan)", "Vietnamese", "Vietnamese (Vietnam)", "Chinese", diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 50d550f6b2..9eff657577 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<doc version="2.1.alpha.custom_build" name="Engine Types"> +<doc version="2.1.beta.custom_build" name="Engine Types"> <class name="@GDScript" category="Core"> <brief_description> Built-in GDScript functions. @@ -6687,24 +6687,18 @@ This node is intended to be a simple helper get get things going quickly and it may happen often that more functionality is desired to change how the camera works. To make your own custom camera node, simply inherit from [Node2D] and change the transform of the canvas by calling get_viewport().set_canvas_transform(m) in [Viewport]. </description> <methods> - <method name="clear_current"> - <description> - </description> - </method> - <method name="force_update_scroll"> + <method name="align"> <description> - Force the camera to update scroll immediately. + Align the camera to the tracked node </description> </method> - <method name="reset_smoothing"> + <method name="clear_current"> <description> - Set the camera's position immediately to its current smoothing destination. - This has no effect if smoothing is disabled. </description> </method> - <method name="align"> + <method name="force_update_scroll"> <description> - Align the camera to the tracked node + Force the camera to update scroll immediately. </description> </method> <method name="get_anchor_mode" qualifiers="const"> @@ -6811,6 +6805,12 @@ Make this the current 2D camera for the scene (viewport and layer), in case there's many cameras in the scene. </description> </method> + <method name="reset_smoothing"> + <description> + Set the camera's position immediately to its current smoothing destination. + This has no effect if smoothing is disabled. + </description> + </method> <method name="set_anchor_mode"> <argument index="0" name="anchor_mode" type="int"> </argument> @@ -7281,24 +7281,21 @@ Return true if this CanvasItem is visible. It may be invisible because itself or a parent canvas item is hidden. </description> </method> - <method name="make_input_local" qualifiers="const"> - <return type="InputEvent"> + <method name="make_canvas_pos_local" qualifiers="const"> + <return type="Vector2"> </return> - <argument index="0" name="event" type="InputEvent"> + <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Takes a global input event and convert to this item's coordinate system. </description> </method> - <method name="make_screen_coord_local" qualifiers="const"> - <return type="Vector2"> + <method name="make_input_local" qualifiers="const"> + <return type="InputEvent"> </return> - <argument index="0" name="screen_point" type="Vector2"> + <argument index="0" name="event" type="InputEvent"> </argument> <description> - Take a 2d screen point and convert to 2D local coords relative to this Canvas - item. If this CanvasItem is the root of a Scene, its essentially the - world coords for that scene. + Takes a global input event and convert to this item's coordinate system. </description> </method> <method name="set_as_toplevel"> @@ -8663,7 +8660,7 @@ <return type="bool"> </return> <description> - Returns whether this color picker is in raw mode or not + Returns whether this color picker is in raw mode or not, raw mode will allow the color R, G, B component values to go beyond 1, you have to consider that the max value for color components is 1, going beyond that value will not have effect in the color, but can be used for special operations that require it (like tinting without darkening or rendering sprites in HDR). </description> </method> <method name="set_color"> @@ -8684,7 +8681,7 @@ <argument index="0" name="mode" type="bool"> </argument> <description> - When set to true, every color channel will be represented as a value from 0 to 1, insetead of 0, 255. + Set whether this color picker is using raw mode or not, see [method is_raw_mode]. </description> </method> </methods> @@ -11773,6 +11770,10 @@ Add an unscaled billboard for visualization. Call this function during [method redraw]. </description> </method> + <method name="clear"> + <description> + </description> + </method> <method name="commit_handle" qualifiers="virtual"> <argument index="0" name="index" type="int"> </argument> @@ -13021,6 +13022,11 @@ <description> </description> </method> + <method name="update_changes"> + <description> + After editing a font (changing size, ascent, char rects, etc.). Call this function to propagate changes to controls that might use it. + </description> + </method> </methods> <constants> </constants> @@ -15794,7 +15800,14 @@ <return type="Array"> </return> <description> - Returns an [Array] containing the device IDs of all currently connected joysticks. + Returns an [Array] containing the device IDs of all currently connected joysticks. + </description> + </method> + <method name="get_gyroscope"> + <return type="Vector3"> + </return> + <description> + If the device has a gyroscope, this will return the rate of rotation in rad/s around a device's x, y, and z axis. </description> </method> <method name="get_joy_axis"> @@ -15869,7 +15882,7 @@ <return type="Vector2"> </return> <description> - Returns the mouse speed. + Returns the mouse speed for the last time the cursor was moved, and this until the next frame where the mouse moves. This means that even if the mouse is not moving, this function will still return the value of the last motion. </description> </method> <method name="is_action_pressed"> @@ -18289,6 +18302,12 @@ Return the restricted number of characters to display. Returns -1 if unrestricted. </description> </method> + <method name="get_visible_line_count" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> <method name="has_autowrap" qualifiers="const"> <return type="bool"> </return> @@ -21428,66 +21447,78 @@ </class> <class name="Node" inherits="Object" category="Core"> <brief_description> - Base class for all the "Scene" elements. + Base class for all the [i]scene[/i] elements. </brief_description> <description> - Nodes can be set as children of other nodes, resulting in a tree arrangement. Any tree of nodes is called a "Scene". - Scenes can be saved to disk, and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects. - [SceneTree] contains the "active" tree of nodes, and a node becomes active (receiving NOTIFICATION_ENTER_SCENE) when added to that tree. - A node can contain any number of nodes as a children (but there is only one tree root) with the requirement that no two children with the same name can exist. - Nodes can, optionally, be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group). - Nodes can be set to "process" state, so they constantly receive a callback requesting them to process (do anything). Normal processing ([method _process]) happens as fast as possible and is dependent on the frame rate, so the processing time delta is variable. Fixed processing ([method _fixed_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics. - Nodes can also process input events. When set, the [method _input] function will be called with every input that the program receives. Since this is usually too overkill (unless used for simple projects), an [method _unhandled_input] function is called when the input was not handled by anyone else (usually, GUI [Control] nodes). - To keep track of the scene hierarchy (specially when instancing scenes into scenes) an "owner" can be set to a node. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though. - Finally, when a node is freed, it will free all its children nodes too. + Nodes are the base bricks with which Godot games are developed. They can be set as children of other nodes, resulting in a tree arrangement. A given node can contain any number of nodes as children (but there is only one scene tree root node) with the requirement that all siblings (direct children of a node) should have unique names. + Any tree of nodes is called a [i]scene[/i]. Scenes can be saved to the disk and then instanced into other scenes. This allows for very high flexibility in the architecture and data model of the projects. Nodes can optionally be added to groups. This makes it easy to reach a number of nodes from the code (for example an "enemies" group) to perform grouped actions. + [b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the NOTIFICATION_ENTER_TREE notification and its [method _enter_tree] callback is triggered. Children 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 NOTIFICATION_READY notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, from the children up to the parent nodes. + It means that when adding a scene 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 (and that recursively for the whole scene). + [b]Processing:[/b] Nodes can be set to 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 variable. Fixed processing (callback [method _fixed_process], toggled with [method set_fixed_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics. + Nodes can also process input events. When set, 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 [method set_owner]. 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 free] or [method queue_free], it will also free all its children. </description> <methods> <method name="_enter_tree" qualifiers="virtual"> <description> + Called when the node enters the [SceneTree] (e.g. upon instancing, scene changing or after calling [method add_child] in a script). If the node has children, its [method _enter_tree] callback will be called first, and then that of the children. + Corresponds to the NOTIFICATION_ENTER_TREE notification in [method Object._notification]. </description> </method> <method name="_exit_tree" qualifiers="virtual"> <description> + Called when the node leaves the [SceneTree] (e.g. upon freeing, scene changing or after calling [method remove_child] in a script). If the node has children, its [method _exit_tree] callback will be called last, after all its children have left the tree. + Corresponds to the NOTIFICATION_EXIT_TREE notification in [method Object._notification]. </description> </method> <method name="_fixed_process" qualifiers="virtual"> <argument index="0" name="delta" type="float"> </argument> <description> - Called for fixed processing (synced to the physics). + Called during the fixed processing step of the main loop. Fixed processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant. + It is only called if fixed processing has been enabled with [method set_fixed_process]. + Corresponds to the NOTIFICATION_FIXED_PROCESS notification in [method Object._notification]. </description> </method> <method name="_input" qualifiers="virtual"> <argument index="0" name="event" type="InputEvent"> </argument> <description> - Called when any input happens (also must enable with [method set_process_input] or the property). + Called for every input event. + It has to be enabled with [method set_process_input] or the corresponding property in the inspector. </description> </method> <method name="_process" qualifiers="virtual"> <argument index="0" name="delta" type="float"> </argument> <description> - Called for processing. This is called every frame, with the delta time from the previous frame. + 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. + It is only called if processing has been enabled with [method set_process]. + Corresponds to the NOTIFICATION_PROCESS notification in [method Object._notification]. </description> </method> <method name="_ready" qualifiers="virtual"> <description> - Called when ready (entered scene and children entered too). + Called when the node is "ready", i.e. when both the node and its children have entered the scene tree. If the node has children, their [method _ready] callback gets triggered first, and the node will receive the ready notification only afterwards. + Corresponds to the NOTIFICATION_READY notification in [method Object._notification]. </description> </method> <method name="_unhandled_input" qualifiers="virtual"> <argument index="0" name="event" type="InputEvent"> </argument> <description> - Called when any input happens that was not handled by something else (also must enable with [method set_process_unhandled_input] or the property). + Called for every input event that has not already been handled by another node. + It has to be enabled with [method set_process_unhandled_input] or the corresponding property in the inspector. </description> </method> <method name="_unhandled_key_input" qualifiers="virtual"> <argument index="0" name="key_event" type="InputEvent"> </argument> <description> - Called when any key input happens that was not handled by something else. + Called for every [i]key[/i] input event that has not already been handled by another node. + It has to be enabled with [method set_process_unhandled_key_input] or the corresponding property in the inspector. </description> </method> <method name="add_child"> @@ -21497,7 +21528,7 @@ </argument> <description> Add a child [Node]. Nodes can have as many children as they want, but every child must have a unique name. Children nodes are automatically deleted when the parent node is deleted, so deleting a whole scene is performed by deleting its topmost node. - The optional boolean argument enforces creating child node with human-readable names, based on the name of node being instanced instead of its type only. + The optional boolean argument enforces creating child nodes with human-readable names, based on the name of the node being instanced instead of its type only. </description> </method> <method name="add_to_group"> @@ -21506,14 +21537,14 @@ <argument index="1" name="persistent" type="bool" default="false"> </argument> <description> - Add a node to a group. Groups are helpers to name and organize group of nodes, like for example: "Enemies", "Collectables", etc. A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_tree]). + Add a node to a group. Groups are helpers to name and organize a subset of nodes, like for example "enemies" or "collectables". A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_tree]). </description> </method> <method name="can_process" qualifiers="const"> <return type="bool"> </return> <description> - Return true if the node can process. + Return true if the node can process, i.e. whether its pause mode allows processing while the scene tree is paused (see [method set_pause_mode]). Always returns true if the scene tree is not paused, and false if the node is not in the tree. FIXME: Why FAIL_COND? </description> </method> <method name="duplicate" qualifiers="const"> @@ -21522,6 +21553,7 @@ <argument index="0" name="use_instancing" type="bool" default="false"> </argument> <description> + Duplicate the node, returning a new [Node]. If [code]use_instancing[/code] is true, the duplicated node will be a new instance of the original [PackedScene], if not it will be an independent node. The duplicated node has the same group assignments and signals as the original one. </description> </method> <method name="find_node" qualifiers="const"> @@ -21543,54 +21575,56 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Return a children node by it's index (see [method get_child_count]). This method is often used for iterating all children of a node. + Return a child node by its index (see [method get_child_count]). This method is often used for iterating all children of a node. </description> </method> <method name="get_child_count" qualifiers="const"> <return type="int"> </return> <description> - Return the amount of children nodes. + Return the amount of child nodes. </description> </method> <method name="get_children" qualifiers="const"> <return type="Array"> </return> <description> + Return an array of references ([Node]) to the child nodes. </description> </method> <method name="get_filename" qualifiers="const"> <return type="String"> </return> <description> - Return a filename that may be containedA node can contained by the node. When a scene is instanced from a file, it topmost node contains the filename from where it was loaded (see [method set_filename]). + Return a filename that may be contained by the node. When a scene is instanced from a file, it topmost node contains the filename from where it was loaded (see [method set_filename]). </description> </method> <method name="get_fixed_process_delta_time" qualifiers="const"> <return type="float"> </return> <description> - Return the time elapsed since the last fixed frame. This is always the same in fixed processing unless the frames per second is changed in [OS]. + Return the time elapsed since the last fixed frame (see [method _fixed_process]). This is always the same in fixed processing unless the frames per second is changed in [OS]. </description> </method> <method name="get_groups" qualifiers="const"> <return type="Array"> </return> <description> + Return an array listing the groups that the node is part of. </description> </method> <method name="get_index" qualifiers="const"> <return type="int"> </return> <description> - Get the node index in the parent (assuming it has a parent). + Get the node index, i.e. its position among the siblings of its parent. </description> </method> <method name="get_name" qualifiers="const"> <return type="String"> </return> <description> - Return the name of the [Node]. Name is be unique within parent. + Return the name of the node. This name is unique among the siblings (other child nodes from the same parent). </description> </method> <method name="get_node" qualifiers="const"> @@ -21599,17 +21633,18 @@ <argument index="0" name="path" type="NodePath"> </argument> <description> - Fetch a node. NodePath must be valid (or else error will occur) and can be either the path to child node, a relative path (from the current node to another node), or an absolute path to a node. - Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]). Examples. Assume your current node is Character and following tree: + Fetch a node. The [NodePath] must be valid (or else an error will be raised) and can be either the path to child node, a relative path (from the current node to another node), or an absolute path to a node. + Note: fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]). + [i]Example:[/i] Assume your current node is Character and the following tree: [codeblock] - root/ - root/Character - root/Character/Sword - root/Character/Backpack/Dagger - root/MyGame - root/Swamp/Alligator - root/Swamp/Mosquito - root/Swamp/Goblin + /root + /root/Character + /root/Character/Sword + /root/Character/Backpack/Dagger + /root/MyGame + /root/Swamp/Alligator + /root/Swamp/Mosquito + /root/Swamp/Goblin [/codeblock] Possible paths are: [codeblock] @@ -21639,7 +21674,7 @@ <return type="Node"> </return> <description> - Return the parent [Node] of the current [Node], or an empty Object if the node lacks a parent. + Return the parent node of the current node, or an empty [Node] if the node lacks a parent. </description> </method> <method name="get_path" qualifiers="const"> @@ -21726,12 +21761,6 @@ <description> </description> </method> - <method name="is_displayed_folded" qualifiers="const"> - <return type="bool"> - </return> - <description> - </description> - </method> <method name="is_fixed_processing" qualifiers="const"> <return type="bool"> </return> @@ -21857,12 +21886,6 @@ <description> </description> </method> - <method name="set_display_folded"> - <argument index="0" name="fold" type="bool"> - </argument> - <description> - </description> - </method> <method name="set_filename"> <argument index="0" name="filename" type="String"> </argument> @@ -22414,6 +22437,12 @@ Return the total amount of dynamic memory used (only works in debug). </description> </method> + <method name="get_engine_version" qualifiers="const"> + <return type="Dictionary"> + </return> + <description> + </description> + </method> <method name="get_environment" qualifiers="const"> <return type="String"> </return> @@ -22460,6 +22489,12 @@ Return the amount of fixed iterations per second (for fixed process and physics). </description> </method> + <method name="get_latin_keyboard_variant" qualifiers="const"> + <return type="String"> + </return> + <description> + </description> + </method> <method name="get_locale" qualifiers="const"> <return type="String"> </return> @@ -31616,7 +31651,7 @@ <return type="String"> </return> <description> - Returns the raw text, stripping out the formatting information. + Returns the raw text, stripping out the formatting information. </description> </method> <method name="get_total_character_count" qualifiers="const"> @@ -32862,6 +32897,12 @@ Return the sample from the library matching the given text ID. Return null if the sample is not found. </description> </method> + <method name="get_sample_list" qualifiers="const"> + <return type="Array"> + </return> + <description> + </description> + </method> <method name="has_sample" qualifiers="const"> <return type="bool"> </return> @@ -39220,6 +39261,13 @@ Return the line the editing cursor is at. </description> </method> + <method name="cursor_is_block_mode" qualifiers="const"> + <return type="bool"> + </return> + <description> + Gets whether the text editor caret is in block mode. + </description> + </method> <method name="cursor_set_blink_enabled"> <argument index="0" name="enable" type="bool"> </argument> @@ -39234,6 +39282,13 @@ Set the text editor caret blink speed. Cannot be less then or equal to 0. </description> </method> + <method name="cursor_set_block_mode"> + <argument index="0" name="enable" type="bool"> + </argument> + <description> + Set the text editor caret to block mode. + </description> + </method> <method name="cursor_set_column"> <argument index="0" name="column" type="int"> </argument> @@ -39332,6 +39387,13 @@ Insert a given text at the cursor position. </description> </method> + <method name="is_highlight_all_occurrences_enabled" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns true if highlight all occurrences is enabled. + </description> + </method> <method name="is_selection_active" qualifiers="const"> <return type="bool"> </return> @@ -39339,6 +39401,13 @@ Return true if the selection is active. </description> </method> + <method name="is_show_line_numbers_enabled" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns true if line numbers are enabled. + </description> + </method> <method name="is_syntax_coloring_enabled" qualifiers="const"> <return type="bool"> </return> @@ -39402,6 +39471,13 @@ Set a custom background color. A background color with alpha==0 disables this. </description> </method> + <method name="set_highlight_all_occurrences"> + <argument index="0" name="enable" type="bool"> + </argument> + <description> + Set to enable highlighting all occurrences of the current selection. + </description> + </method> <method name="set_max_chars"> <argument index="0" name="amount" type="int"> </argument> @@ -39416,13 +39492,6 @@ Set the text editor as read-only. Text can be displayed but not edited. </description> </method> - <method name="set_symbol_color"> - <argument index="0" name="color" type="Color"> - </argument> - <description> - Set the color for symbols. - </description> - </method> <method name="set_show_line_numbers"> <argument index="0" name="enable" type="bool"> </argument> @@ -39430,25 +39499,11 @@ Set to enable showing line numbers. </description> </method> - <method name="is_show_line_numbers_enabled" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns true if line numbers are enabled. - </description> - </method> - <method name="set_highlight_all_occurrences"> - <argument index="0" name="enable" type="bool"> + <method name="set_symbol_color"> + <argument index="0" name="color" type="Color"> </argument> <description> - Set to enable highlighting all occurrences of the current selection. - </description> - </method> - <method name="is_highlight_all_occurrences_enabled" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns true if highlight all occurrences is enabled. + Set the color for symbols. </description> </method> <method name="set_syntax_coloring"> @@ -39479,6 +39534,13 @@ </method> </methods> <signals> + <signal name="breakpoint_toggled"> + <argument index="0" name="row" type="int"> + </argument> + <description> + Emitted when a breakpoint is placed via the breakpoint gutter. + </description> + </signal> <signal name="cursor_changed"> <description> Emitted when the cursor changes. @@ -39524,6 +39586,8 @@ </theme_item> <theme_item name="breakpoint_color" type="Color"> </theme_item> + <theme_item name="caret_background_color" type="Color"> + </theme_item> <theme_item name="caret_color" type="Color"> </theme_item> <theme_item name="completion" type="StyleBox"> @@ -40712,6 +40776,8 @@ <constant name="TILE_ORIGIN_CENTER" value="1"> Tile origin at its center. </constant> + <constant name="TILE_ORIGIN_BOTTOM_LEFT" value="2"> + </constant> </constants> </class> <class name="TileSet" inherits="Resource" category="Core"> @@ -42110,6 +42176,16 @@ <description> </description> </method> + <method name="set_button"> + <argument index="0" name="column" type="int"> + </argument> + <argument index="1" name="button_idx" type="int"> + </argument> + <argument index="2" name="button" type="Texture"> + </argument> + <description> + </description> + </method> <method name="set_cell_mode"> <argument index="0" name="column" type="int"> </argument> @@ -44964,6 +45040,8 @@ </argument> <argument index="2" name="arg2" type="int"> </argument> + <argument index="3" name="arg3" type="Rect2"> + </argument> <description> </description> </method> diff --git a/drivers/dds/texture_loader_dds.cpp b/drivers/dds/texture_loader_dds.cpp index 0cef77e638..0cc84f02f7 100644 --- a/drivers/dds/texture_loader_dds.cpp +++ b/drivers/dds/texture_loader_dds.cpp @@ -162,20 +162,20 @@ RES ResourceFormatDDS::load(const String &p_path, const String& p_original_path, DDSFormat dds_format; - if (format_flags&DDPF_FOURCC && format_fourcc=='1TXD') { + if (format_flags&DDPF_FOURCC && format_fourcc==0x31545844) { //'1TXD' dds_format=DDS_DXT1; - } else if (format_flags&DDPF_FOURCC && format_fourcc=='3TXD') { + } else if (format_flags&DDPF_FOURCC && format_fourcc==0x33545844) { //'3TXD' dds_format=DDS_DXT3; - } else if (format_flags&DDPF_FOURCC && format_fourcc=='5TXD') { + } else if (format_flags&DDPF_FOURCC && format_fourcc==0x35545844) { //'5TXD' dds_format=DDS_DXT5; - } else if (format_flags&DDPF_FOURCC && format_fourcc=='1ITA') { + } else if (format_flags&DDPF_FOURCC && format_fourcc==0x31495441) { //'1ITA' dds_format=DDS_ATI1; - } else if (format_flags&DDPF_FOURCC && format_fourcc=='2ITA') { + } else if (format_flags&DDPF_FOURCC && format_fourcc==0x32495441) { //'2ITA' dds_format=DDS_ATI2; diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 8cb7c7b698..fd515d6dd3 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -357,7 +357,6 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo pid_t pid = fork(); ERR_FAIL_COND_V(pid<0,ERR_CANT_FORK); - //print("execute: %s\n",p_path.utf8().get_data()); if (pid==0) { @@ -394,8 +393,6 @@ Error OS_Unix::execute(const String& p_path, const List<String>& p_arguments,boo pid_t rpid = waitpid(pid,&status,0); if (r_exitcode) *r_exitcode=WEXITSTATUS(status); - - print("returned: %i, waiting for: %i\n",rpid,pid); } else { if (r_child_id) @@ -498,7 +495,6 @@ String OS_Unix::get_executable_path() const { char buf[256]; memset(buf,0,256); readlink("/proc/self/exe", buf, sizeof(buf)); - //print_line("Exec path is:"+String(buf)); String b; b.parse_utf8(buf); if (b=="") { diff --git a/main/input_default.cpp b/main/input_default.cpp index 945898f1f3..5e66a8b585 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -259,6 +259,12 @@ Vector3 InputDefault::get_magnetometer() { return magnetometer; } +Vector3 InputDefault::get_gyroscope() { + + _THREAD_SAFE_METHOD_ + return gyroscope; +} + void InputDefault::parse_input_event(const InputEvent& p_event) { _THREAD_SAFE_METHOD_ @@ -386,6 +392,14 @@ void InputDefault::set_magnetometer(const Vector3& p_magnetometer) { } +void InputDefault::set_gyroscope(const Vector3& p_gyroscope) { + + _THREAD_SAFE_METHOD_ + + gyroscope=p_gyroscope; + +} + void InputDefault::set_main_loop(MainLoop *p_main_loop) { main_loop=p_main_loop; diff --git a/main/input_default.h b/main/input_default.h index 644af15e3b..cb71312e22 100644 --- a/main/input_default.h +++ b/main/input_default.h @@ -44,6 +44,7 @@ class InputDefault : public Input { Map<StringName,int> custom_action_press; Vector3 accelerometer; Vector3 magnetometer; + Vector3 gyroscope; Vector2 mouse_pos; MainLoop *main_loop; @@ -179,6 +180,7 @@ public: virtual Vector3 get_accelerometer(); virtual Vector3 get_magnetometer(); + virtual Vector3 get_gyroscope(); virtual Point2 get_mouse_pos() const; virtual Point2 get_mouse_speed() const; @@ -190,6 +192,7 @@ public: void parse_input_event(const InputEvent& p_event); void set_accelerometer(const Vector3& p_accel); void set_magnetometer(const Vector3& p_magnetometer); + void set_gyroscope(const Vector3& p_gyroscope); void set_joy_axis(int p_device,int p_axis,float p_value); virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration=0); diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 304ed6b100..68c3dc98d3 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1436,6 +1436,7 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa p_script->member_functions.clear(); p_script->member_indices.clear(); p_script->member_info.clear(); + p_script->_signals.clear(); p_script->initializer=NULL; p_script->subclasses.clear(); diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index d9783c218a..d1946e2a63 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1643,13 +1643,16 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script>& p_script,bool p_sof } #endif + for(Map<ObjectID,List<Pair<StringName,Variant> > >::Element *F=E->get()->pending_reload_state.front();F;F=F->next()) { + map[F->key()]=F->get(); //pending to reload, use this one instead + } } } for(Map< Ref<GDScript>, Map<ObjectID,List<Pair<StringName,Variant> > > >::Element *E=to_reload.front();E;E=E->next()) { Ref<GDScript> scr = E->key(); - scr->reload(true); + scr->reload(p_soft_reload); //restore state if saved for (Map<ObjectID,List<Pair<StringName,Variant> > >::Element *F=E->get().front();F;F=F->next()) { @@ -1658,13 +1661,24 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script>& p_script,bool p_sof if (!obj) continue; + if (!p_soft_reload) { + //clear it just in case (may be a pending reload state) + obj->set_script(RefPtr()); + } obj->set_script(scr.get_ref_ptr()); - if (!obj->get_script_instance()) + if (!obj->get_script_instance()) { + //failed, save reload state for next time if not saved + if (!scr->pending_reload_state.has(obj->get_instance_ID())) { + scr->pending_reload_state[obj->get_instance_ID()]=F->get(); + } continue; + } for (List<Pair<StringName,Variant> >::Element *G=F->get().front();G;G=G->next()) { obj->get_script_instance()->set(G->get().first,G->get().second); } + + scr->pending_reload_state.erase(obj->get_instance_ID()); //as it reloaded, remove pending state } //if instance states were saved, set them! diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 723761c3a9..f0b6b7103c 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -120,7 +120,11 @@ friend class GDScriptLanguage; virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); #endif +#ifdef DEBUG_ENABLED + + Map<ObjectID,List<Pair<StringName,Variant> > > pending_reload_state; +#endif bool _update_exports(); @@ -265,6 +269,8 @@ class GDScriptLanguage : public ScriptLanguage { Mutex *lock; + + friend class GDScript; SelfList<GDScript>::List script_list; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 83f7292716..f4fafc4fab 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1573,7 +1573,7 @@ void EditorExportPlatformAndroid::_device_poll_thread(void *ud) { String dp; Error err = OS::get_singleton()->execute(adb,args,true,NULL,&dp,&ec); - print_line("RV: "+itos(ec)); + Vector<String> props = dp.split("\n"); String vendor; String device; diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 9f909d7041..2371274d9d 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -314,6 +314,7 @@ struct engine { ASensorManager* sensorManager; const ASensor* accelerometerSensor; const ASensor* magnetometerSensor; + const ASensor* gyroscopeSensor; ASensorEventQueue* sensorEventQueue; bool display_active; @@ -746,6 +747,15 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { engine->magnetometerSensor, (1000L/60)*1000); } + // And the gyroscope. + if (engine->gyroscopeSensor != NULL) { + ASensorEventQueue_enableSensor(engine->sensorEventQueue, + engine->gyroscopeSensor); + // We'd like to get 60 events per second (in us). + ASensorEventQueue_setEventRate(engine->sensorEventQueue, + engine->gyroscopeSensor, (1000L/60)*1000); + + } engine->animating = 1; break; case APP_CMD_LOST_FOCUS: @@ -759,6 +769,10 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { ASensorEventQueue_disableSensor(engine->sensorEventQueue, engine->magnetometerSensor); } + if (engine->gyroscopeSensor != NULL) { + ASensorEventQueue_disableSensor(engine->sensorEventQueue, + engine->gyroscopeSensor); + } // Also stop animating. engine->animating = 0; engine_draw_frame(engine); @@ -788,6 +802,8 @@ void android_main(struct android_app* state) { ASENSOR_TYPE_ACCELEROMETER); engine.magnetometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD); + engine.gyroscopeSensor = ASensorManager_getDefaultSensor(engine.sensorManager, + ASENSOR_TYPE_GYROSCOPE); engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, state->looper, LOOPER_ID_USER, NULL, NULL); @@ -828,7 +844,7 @@ void android_main(struct android_app* state) { // If a sensor has data, process it now. // LOGI("events\n"); if (ident == LOOPER_ID_USER) { - if (engine.accelerometerSensor != NULL || engine.magnetometerSensor != NULL) { + if (engine.accelerometerSensor != NULL || engine.magnetometerSensor != NULL || engine.gyroscopeSensor != NULL) { ASensorEvent event; while (ASensorEventQueue_getEvents(engine.sensorEventQueue, &event, 1) > 0) { @@ -843,6 +859,10 @@ void android_main(struct android_app* state) { engine.os->process_magnetometer(Vector3(event.magnetic.x, event.magnetic.y, event.magnetic.z)); } + if (event.vector != NULL) { + engine.os->process_gyroscope(Vector3(event.vector.x, event.vector.y, + event.vector.z)); + } } } diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index 4c0f4878f5..4b80db7e33 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -217,6 +217,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private SensorManager mSensorManager; private Sensor mAccelerometer; private Sensor mMagnetometer; + private Sensor mGyroscope; public FrameLayout layout; public RelativeLayout adLayout; @@ -387,6 +388,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME); + mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); + mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); result_callback = null; @@ -604,6 +607,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mView.onResume(); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME); + mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); GodotLib.focusin(); if(use_immersive && Build.VERSION.SDK_INT >= 19.0){ // check if the application runs on an android 4.4+ Window window = getWindow(); @@ -670,6 +674,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) { GodotLib.magnetometer(x,y,z); } + if (typeOfSensor == event.sensor.TYPE_GYROSCOPE) { + GodotLib.gyroscope(x,y,z); + } } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index df181ae1bb..9a2ea7df10 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -52,6 +52,7 @@ public class GodotLib { public static native void touch(int what,int pointer,int howmany, int[] arr); public static native void accelerometer(float x, float y, float z); public static native void magnetometer(float x, float y, float z); + public static native void gyroscope(float x, float y, float z); public static native void key(int p_scancode, int p_unicode_char, boolean p_pressed); public static native void joybutton(int p_device, int p_but, boolean p_pressed); public static native void joyaxis(int p_device, int p_axis, float p_value); diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 45d02876ba..b9d178280c 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -653,6 +653,7 @@ static bool quit_request=false; static Size2 new_size; static Vector3 accelerometer; static Vector3 magnetometer; +static Vector3 gyroscope; static HashMap<String,JNISingleton*> jni_singletons; static jobject godot_io; @@ -1093,6 +1094,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv * env, jo os_android->process_magnetometer(magnetometer); + os_android->process_gyroscope(gyroscope); + if (os_android->main_loop_iterate()==true) { jclass cls = env->FindClass("org/godotengine/godot/Godot"); @@ -1501,6 +1504,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv * } +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z) { + + input_mutex->lock(); + gyroscope=Vector3(x,y,z); + input_mutex->unlock(); + +} + JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj){ if (!suspend_mutex) diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index f7916efe2c..ae7ced45ee 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -50,6 +50,7 @@ extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z); + JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_singleton(JNIEnv * env, jobject obj, jstring name,jobject p_object); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 13cdf2a020..3c2b4c22e7 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -614,6 +614,11 @@ void OS_Android::process_magnetometer(const Vector3& p_magnetometer) { input->set_magnetometer(p_magnetometer); } +void OS_Android::process_gyroscope(const Vector3& p_gyroscope) { + + input->set_gyroscope(p_gyroscope); +} + bool OS_Android::has_touchscreen_ui_hint() const { return true; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index e82e08ea49..7f39784a74 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -242,6 +242,7 @@ public: void process_accelerometer(const Vector3& p_accelerometer); void process_magnetometer(const Vector3& p_magnetometer); + void process_gyroscope(const Vector3& p_gyroscope); void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points); void process_joy_event(JoystickEvent p_event); void process_event(InputEvent p_event); diff --git a/platform/windows/godot.manifest b/platform/windows/godot.manifest deleted file mode 100644 index c095f007b0..0000000000 --- a/platform/windows/godot.manifest +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"/> - </requestedPrivileges> - </security> - </trustInfo> - <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> - <application> - <!-- Windows 10 --> - <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> - <!-- Windows 8.1 --> - <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> - <!-- Windows 8 --> - <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> - <!-- Windows 7 --> - <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> - <!-- Windows Vista --> - <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> - </application> - </compatibility> -</assembly> diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index d069ecdc79..5f1e951e0f 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -1,4 +1,3 @@ -#include <winuser.h> #include "core/version.h" #ifndef _STR #define _STR(m_x) #m_x @@ -7,8 +6,6 @@ GODOT_ICON ICON platform/windows/godot.ico -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST platform/windows/godot.manifest - 1 VERSIONINFO FILEVERSION VERSION_MAJOR,VERSION_MINOR,0,0 PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,0,0 diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 3c50e2cf5b..2be8b01dc3 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -182,7 +182,7 @@ def configure(env): print("PulseAudio development libraries not found, disabling driver") env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL']) - env.Append(LIBS=['GL', 'GLU', 'pthread', 'z']) + env.Append(LIBS=['GL', 'pthread', 'z']) if (platform.system() == "Linux"): env.Append(LIBS='dl') #env.Append(CPPFLAGS=['-DMPC_FIXED_POINT']) diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 06f8c27957..c8bd9749df 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -140,14 +140,13 @@ void ColorPicker::_value_changed(double) { if (updating) return; - for(int i=0;i<3;i++) { + for(int i=0;i<4;i++) { color.components[i] = scroll[i]->get_val()/(raw_mode_enabled?1.0:255.0); } - color.components[3] = scroll[3]->get_val()/255.0; set_color(color); - c_text->set_text(color.to_html(edit_alpha && color.a<1)); + _update_text_value(); emit_signal("color_changed",color); @@ -174,22 +173,16 @@ void ColorPicker::_update_color() { for(int i=0;i<4;i++) { scroll[i]->set_max(255); scroll[i]->set_step(0.01); - if (raw_mode_enabled && i != 3) + if (raw_mode_enabled) { + if (i == 3) + scroll[i]->set_max(1); scroll[i]->set_val(color.components[i]); - else - scroll[i]->set_val(color.components[i]*255); + } else { + scroll[i]->set_val(color.components[i] * 255); + } } - if (text_is_constructor) { - String t = "Color("+String::num(color.r)+","+String::num(color.g)+","+String::num(color.b); - if (edit_alpha && color.a<1) - t+=(","+String::num(color.a)+")") ; - else - t+=")"; - c_text->set_text(t); - } else { - c_text->set_text(color.to_html(edit_alpha && color.a<1)); - } + _update_text_value(); sample->update(); updating=false; @@ -262,6 +255,20 @@ bool ColorPicker::is_raw_mode() const { return raw_mode_enabled; } + +void ColorPicker::_update_text_value() { + if (text_is_constructor) { + String t = "Color("+String::num(color.r)+","+String::num(color.g)+","+String::num(color.b); + if (edit_alpha && color.a<1) + t+=(","+String::num(color.a)+")") ; + else + t+=")"; + c_text->set_text(t); + } else { + c_text->set_text(color.to_html(edit_alpha && color.a<1)); + } +} + void ColorPicker::_sample_draw() { sample->draw_rect(Rect2(Point2(),Size2(256,20)),color); } @@ -271,12 +278,12 @@ void ColorPicker::_hsv_draw(int p_wich,Control* c) if (!c) return; if (p_wich==0) { - int x=c->get_size().x*s; - int y=c->get_size().y-c->get_size().y*v; + int x = CLAMP(c->get_size().x * s, 0, c->get_size().x); + int y = CLAMP(c->get_size().y-c->get_size().y * v, 0, c->get_size().y); Color col = color; col.a=1; c->draw_line(Point2(x,0),Point2(x,c->get_size().y),col.inverted()); - c->draw_line(Point2(0,y),Point2(c->get_size().x,y),col.inverted()); + c->draw_line(Point2(0, y),Point2(c->get_size().x, y),col.inverted()); c->draw_line(Point2(x,y),Point2(x,y),Color(1,1,1),2); } else if (p_wich==1) { int y=c->get_size().y-c->get_size().y*h; diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index b9ef1f1e2f..5e2cc57274 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -80,6 +80,7 @@ private: void _update_controls(); void _update_color(); void _update_presets(); + void _update_text_value(); void _text_type_toggled(); void _sample_draw(); void _hsv_draw(int p_wich,Control *c); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index fc27c0d24f..c176e50cee 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1865,7 +1865,7 @@ void Control::_modal_stack_remove() { } -void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner) { +void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner,bool p_assign) { Control *c = p_at->cast_to<Control>(); @@ -1884,15 +1884,30 @@ void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner) { if (c) { - c->data.theme_owner=p_owner; + if (p_assign) { + c->data.theme_owner=p_owner; + } c->_notification(NOTIFICATION_THEME_CHANGED); c->update(); } } + +void Control::_theme_changed() { + + _propagate_theme_changed(this,this,false); +} + void Control::set_theme(const Ref<Theme>& p_theme) { + if (data.theme==p_theme) + return; + + if (data.theme.is_valid()) { + data.theme->disconnect("changed",this,"_theme_changed"); + } + data.theme=p_theme; if (!p_theme.is_null()) { @@ -1909,6 +1924,9 @@ void Control::set_theme(const Ref<Theme>& p_theme) { } + if (data.theme.is_valid()) { + data.theme->connect("changed",this,"_theme_changed"); + } } @@ -2448,6 +2466,10 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("minimum_size_changed"), &Control::minimum_size_changed); + ObjectTypeDB::bind_method(_MD("_theme_changed"), &Control::_theme_changed); + + + ObjectTypeDB::bind_method(_MD("_font_changed"), &Control::_font_changed); BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"))); diff --git a/scene/gui/control.h b/scene/gui/control.h index 830ebd1620..1337cbc4b9 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -172,7 +172,9 @@ private: float _get_range(int p_idx) const; float _s2a(float p_val, AnchorType p_anchor,float p_range) const; float _a2s(float p_val, AnchorType p_anchor,float p_range) const; - void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner); + void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign=true); + void _theme_changed(); + void _change_notify_margins(); void _update_minimum_size(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 0431d824fa..4c025e92df 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -356,6 +356,21 @@ int Label::get_line_count() const { return line_count; } +int Label::get_visible_line_count() const { + + int line_spacing = get_constant("line_spacing"); + int font_h = get_font("font")->get_height()+line_spacing; + int lines_visible = (get_size().y+line_spacing)/font_h; + + if (lines_visible > line_count) + lines_visible = line_count; + + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) + lines_visible = max_lines_visible; + + return lines_visible; +} + void Label::regenerate_word_cache() { while (word_cache) { @@ -640,6 +655,7 @@ void Label::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_uppercase"),&Label::is_uppercase); ObjectTypeDB::bind_method(_MD("get_line_height"),&Label::get_line_height); ObjectTypeDB::bind_method(_MD("get_line_count"),&Label::get_line_count); + ObjectTypeDB::bind_method(_MD("get_visible_line_count"),&Label::get_visible_line_count); ObjectTypeDB::bind_method(_MD("get_total_character_count"),&Label::get_total_character_count); ObjectTypeDB::bind_method(_MD("set_visible_characters","amount"),&Label::set_visible_characters); ObjectTypeDB::bind_method(_MD("get_visible_characters"),&Label::get_visible_characters); diff --git a/scene/gui/label.h b/scene/gui/label.h index 3c14add60d..b472eca1a2 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -132,6 +132,7 @@ public: int get_line_height() const; int get_line_count() const; + int get_visible_line_count() const; Label(const String& p_text=String()); ~Label(); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 6c47072b33..89c235e101 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -118,7 +118,7 @@ void LineEdit::_input_event(InputEvent p_event) { const InputEventMouseMotion& m=p_event.mouse_motion; - if (m.button_mask&1) { + if (m.button_mask&BUTTON_LEFT) { if (selection.creating) { set_cursor_at_pixel_pos(m.x); @@ -616,11 +616,11 @@ void LineEdit::_notification(int p_what) { } break; case ALIGN_CENTER: { - x_ofs=x_ofs=int(size.width-(cached_width))/2; + x_ofs=int(size.width-(cached_width))/2; } break; case ALIGN_RIGHT: { - x_ofs=x_ofs=int(size.width-style->get_offset().x-(cached_width)); + x_ofs=int(size.width-style->get_offset().x-(cached_width)); } break; } @@ -811,6 +811,9 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { if ( (pixel_ofs-p_x) < (char_w >> 1 ) ) { ofs+=1; + } else if ( (pixel_ofs-p_x) > (char_w >> 1 ) ) { + + ofs-=1; } break; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 28d67287d5..725f1ddf17 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -28,6 +28,7 @@ /*************************************************************************/ #include "menu_button.h" #include "os/keyboard.h" +#include "scene/main/viewport.h" void MenuButton::_unhandled_key_input(InputEvent p_event) { @@ -38,8 +39,12 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) { if (!get_parent() || !is_visible() || is_disabled()) return; + if (get_viewport()->get_modal_stack_top() && !get_viewport()->get_modal_stack_top()->is_a_parent_of(this)) + return; //ignore because of modal window - int item = popup->activate_item_by_event(p_event); + + if (popup->activate_item_by_event(p_event)) + accept_event(); } } diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 8d02d0e4e5..5b83c3f8b8 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -125,8 +125,6 @@ void Popup::set_as_minsize() { } - print_line(String(c->get_type())+": "+minsize); - total_minsize.width = MAX( total_minsize.width, minsize.width ); total_minsize.height = MAX( total_minsize.height, minsize.height ); } @@ -168,8 +166,6 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) { } - print_line(String(c->get_type())+": "+minsize); - total_minsize.width = MAX( total_minsize.width, minsize.width ); total_minsize.height = MAX( total_minsize.height, minsize.height ); } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index b4fa463cde..73a3cda5f3 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -662,7 +662,9 @@ void RichTextLabel::_notification(int p_what) { } break; case NOTIFICATION_ENTER_TREE: { - set_bbcode(bbcode); + if (bbcode != "") + set_bbcode(bbcode); + main->first_invalid_line=0; //invalidate ALL update(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a680d5d873..50b44c55a9 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -999,34 +999,39 @@ void TextEdit::_notification(int p_what) { } } - - if (str[j]>=32) - cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); - - else if (draw_tabs && str[j]=='\t') { - int yofs= (get_row_height() - cache.tab_icon->get_height())/2; - cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color); - } - - if (cursor.column==j && cursor.line==line) { cursor_pos = Point2i( char_ofs+char_margin, ofs_y ); if (insert_mode) { - cursor_pos.y += get_row_height(); + cursor_pos.y += (get_row_height() - 3); } + int caret_w = (str[j]=='\t') ? cache.font->get_char_size(' ').width : char_w; if (draw_caret) { if (insert_mode) { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); + int caret_h = (block_caret) ? 4 : 1; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(caret_w,caret_h)),cache.caret_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); + caret_w = (block_caret) ? caret_w : 1; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(caret_w,get_row_height())),cache.caret_color); } } } - char_ofs+=char_w; + if (cursor.column==j && cursor.line==line && block_caret && draw_caret && !insert_mode) { + color = cache.caret_background_color; + } + + if (str[j]>=32) + cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); + + else if (draw_tabs && str[j]=='\t') { + int yofs= (get_row_height() - cache.tab_icon->get_height())/2; + cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color); + } + + char_ofs+=char_w; } if (cursor.column==str.length() && cursor.line==line && (char_ofs+char_margin)>=xmargin_beg) { @@ -1034,15 +1039,18 @@ void TextEdit::_notification(int p_what) { cursor_pos=Point2i( char_ofs+char_margin, ofs_y ); if (insert_mode) { - cursor_pos.y += get_row_height(); + cursor_pos.y += (get_row_height() - 3); } if (draw_caret) { if (insert_mode) { int char_w = cache.font->get_char_size(' ').width; - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); + int caret_h = (block_caret) ? 4 : 1; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,caret_h)),cache.caret_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); + int char_w = cache.font->get_char_size(' ').width; + int caret_w = (block_caret) ? char_w : 1; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(caret_w,get_row_height())),cache.caret_color); } } } @@ -1502,6 +1510,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { int gutter=cache.style_normal->get_margin(MARGIN_LEFT); if (mb.x > gutter && mb.x <= gutter + cache.breakpoint_gutter_width + 3) { set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row)); + emit_signal("breakpoint_toggled", row); return; } } @@ -3074,6 +3083,15 @@ void TextEdit::cursor_set_blink_speed(const float p_speed) { caret_blink_timer->set_wait_time(p_speed); } +void TextEdit::cursor_set_block_mode(const bool p_enable){ + block_caret = p_enable; + update(); +} + +bool TextEdit::cursor_is_block_mode() const { + return block_caret; +} + void TextEdit::_scroll_moved(double p_to_val) { @@ -3315,6 +3333,7 @@ void TextEdit::_update_caches() { cache.completion_font_color=get_color("completion_font_color"); cache.font=get_font("font"); cache.caret_color=get_color("caret_color"); + cache.caret_background_color=get_color("caret_background_color"); cache.line_number_color=get_color("line_number_color"); cache.font_color=get_color("font_color"); cache.font_selected_color=get_color("font_selected_color"); @@ -4417,6 +4436,8 @@ void TextEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("cursor_get_blink_enabled"),&TextEdit::cursor_get_blink_enabled); ObjectTypeDB::bind_method(_MD("cursor_set_blink_speed", "blink_speed"),&TextEdit::cursor_set_blink_speed); ObjectTypeDB::bind_method(_MD("cursor_get_blink_speed"),&TextEdit::cursor_get_blink_speed); + ObjectTypeDB::bind_method(_MD("cursor_set_block_mode", "enable"), &TextEdit::cursor_set_block_mode); + ObjectTypeDB::bind_method(_MD("cursor_is_block_mode"), &TextEdit::cursor_is_block_mode); ObjectTypeDB::bind_method(_MD("set_readonly","enable"),&TextEdit::set_readonly); ObjectTypeDB::bind_method(_MD("set_wrap","enable"),&TextEdit::set_wrap); @@ -4462,12 +4483,14 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), _SCS("set_show_line_numbers"), _SCS("is_show_line_numbers_enabled")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), _SCS("set_highlight_all_occurrences"), _SCS("is_highlight_all_occurrences_enabled")); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret/block_caret"), _SCS("cursor_set_block_mode"), _SCS("cursor_is_block_mode")); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret/caret_blink"), _SCS("cursor_set_blink_enabled"), _SCS("cursor_get_blink_enabled")); ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "caret/caret_blink_speed",PROPERTY_HINT_RANGE,"0.1,10,0.1"), _SCS("cursor_set_blink_speed"),_SCS("cursor_get_blink_speed") ); ADD_SIGNAL(MethodInfo("cursor_changed")); ADD_SIGNAL(MethodInfo("text_changed")); ADD_SIGNAL(MethodInfo("request_completion")); + ADD_SIGNAL(MethodInfo("breakpoint_toggled", PropertyInfo( Variant::INT, "row"))); BIND_CONSTANT( MENU_CUT ); BIND_CONSTANT( MENU_COPY ); @@ -4527,6 +4550,7 @@ TextEdit::TextEdit() { selection.active=false; syntax_coloring=false; + block_caret=false; caret_blink_enabled=false; caret_blink_timer = memnew(Timer); add_child(caret_blink_timer); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 270a1723b1..65e9615911 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -79,6 +79,7 @@ class TextEdit : public Control { Color completion_existing_color; Color completion_font_color; Color caret_color; + Color caret_background_color; Color line_number_color; Color font_color; Color font_selected_color; @@ -222,6 +223,7 @@ class TextEdit : public Control { bool caret_blink_enabled; bool draw_caret; bool window_has_focus; + bool block_caret; bool setting_row; bool wrap; @@ -406,6 +408,9 @@ public: float cursor_get_blink_speed() const; void cursor_set_blink_speed(const float p_speed); + void cursor_set_block_mode(const bool p_enable); + bool cursor_is_block_mode() const; + void set_readonly(bool p_readonly); void set_max_chars(int p_max_chars); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 305a3920da..82459ba0ab 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -693,6 +693,7 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_button","column","button:Texture","button_idx","disabled"),&TreeItem::add_button,DEFVAL(-1),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_button_count","column"),&TreeItem::get_button_count); ObjectTypeDB::bind_method(_MD("get_button:Texture","column","button_idx"),&TreeItem::get_button); + ObjectTypeDB::bind_method(_MD("set_button","column","button_idx","button:Texture"),&TreeItem::set_button); ObjectTypeDB::bind_method(_MD("erase_button","column","button_idx"),&TreeItem::erase_button); ObjectTypeDB::bind_method(_MD("is_button_disabled","column","button_idx"),&TreeItem::is_button_disabled); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 55106f5ee7..a53c19d2e7 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1121,6 +1121,38 @@ Node *Node::get_owner() const { return data.owner; } + +Node* Node::find_common_parent_with(const Node *p_node) const { + + if (this==p_node) + return const_cast<Node*>(p_node); + + Set<const Node*> visited; + + const Node *n=this; + + while(n) { + + visited.insert(n); + n=n->data.parent; + } + + const Node *common_parent=p_node; + + while(common_parent) { + + if (visited.has(common_parent)) + break; + common_parent=common_parent->data.parent; + } + + if (!common_parent) + return NULL; + + return const_cast<Node*>(common_parent); + +} + NodePath Node::get_path_to(const Node *p_node) const { ERR_FAIL_NULL_V(p_node,NodePath()); diff --git a/scene/main/node.h b/scene/main/node.h index 10cfc5f9e6..18e403cd61 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -215,6 +215,7 @@ public: NodePath get_path() const; NodePath get_path_to(const Node *p_node) const; + Node* find_common_parent_with(const Node *p_node) const; void add_to_group(const StringName& p_identifier,bool p_persistent=false); void remove_from_group(const StringName& p_identifier); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index bb6e6e289b..bdb2754e5e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1346,13 +1346,21 @@ Matrix32 Viewport::_get_input_pre_xform() const { void Viewport::_make_input_local(InputEvent& ev) { + switch(ev.type) { case InputEvent::MOUSE_BUTTON: { + Vector2 vp_ofs; + if (parent_control) { + vp_ofs = (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); + } + Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y)); - Vector2 l = ai.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y)); + Vector2 l = ai.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y)-vp_ofs); + + ev.mouse_button.x=l.x; ev.mouse_button.y=l.y; ev.mouse_button.global_x=g.x; @@ -1361,11 +1369,18 @@ void Viewport::_make_input_local(InputEvent& ev) { } break; case InputEvent::MOUSE_MOTION: { + Vector2 vp_ofs; + if (parent_control) { + vp_ofs = (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); + } + Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y)); - Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)); + Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)-vp_ofs); Vector2 r = ai.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y)); Vector2 s = ai.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y)); + + ev.mouse_motion.x=l.x; ev.mouse_motion.y=l.y; ev.mouse_motion.global_x=g.x; @@ -1378,16 +1393,28 @@ void Viewport::_make_input_local(InputEvent& ev) { } break; case InputEvent::SCREEN_TOUCH: { + Vector2 vp_ofs; + if (parent_control) { + vp_ofs = (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); + } + Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); - Vector2 t = ai.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)); + Vector2 t = ai.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)-vp_ofs); + + ev.screen_touch.x=t.x; ev.screen_touch.y=t.y; } break; case InputEvent::SCREEN_DRAG: { + Vector2 vp_ofs; + if (parent_control) { + vp_ofs = (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin(); + } + Matrix32 ai = get_final_transform().affine_inverse() * _get_input_pre_xform(); - Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)); + Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)-vp_ofs); Vector2 r = ai.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y)); Vector2 s = ai.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y)); ev.screen_drag.x=t.x; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index c83ab88c73..bc0951e436 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -637,10 +637,10 @@ void register_scene_types() { resource_saver_text = memnew( ResourceFormatSaverText ); - ResourceSaver::add_resource_format_saver(resource_saver_text); + ResourceSaver::add_resource_format_saver(resource_saver_text,true); resource_loader_text = memnew( ResourceFormatLoaderText ); - ResourceLoader::add_resource_format_loader(resource_loader_text); + ResourceLoader::add_resource_format_loader(resource_loader_text,true); } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 182bc5dabc..499cf0a169 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -54,8 +54,10 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src,float p_left, float p_top, flo texture = Ref<ImageTexture>( memnew( ImageTexture ) ); Image img(p_src); - if (scale>1) + if (scale>1) { + img.convert(Image::FORMAT_RGBA); img.expand_x2_hq2x(); + } texture->create_from_image( img,ImageTexture::FLAG_FILTER ); (*tex_cache)[p_src]=texture; } @@ -92,8 +94,10 @@ static Ref<Texture> make_icon(T p_src) { Ref<ImageTexture> texture( memnew( ImageTexture ) ); Image img = Image(p_src); - if (scale>1) + if (scale>1) { + img.convert(Image::FORMAT_RGBA); img.expand_x2_hq2x(); + } texture->create_from_image( img,ImageTexture::FLAG_FILTER ); return texture; @@ -481,6 +485,7 @@ void fill_default_theme(Ref<Theme>& t,const Ref<Font> & default_font,const Ref<F t->set_color("breakpoint_color","TextEdit", Color(0.8,0.8,0.4,0.2) ); t->set_color("current_line_color","TextEdit", Color(0.25,0.25,0.26,0.8) ); t->set_color("caret_color","TextEdit", control_font_color ); + t->set_color("caret_background_color", "TextEdit", Color::html("000000")); t->set_color("symbol_color","TextEdit", control_font_color_hover ); t->set_color("brace_mismatch_color","TextEdit", Color(1,0.2,0.2) ); t->set_color("line_number_color","TextEdit",Color::html("66aaaaaa")); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 6ad8a95565..1afa3fec19 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -71,6 +71,11 @@ void Font::draw(RID p_canvas_item, const Point2& p_pos, const String& p_text, co } } +void Font::update_changes() { + + emit_changed(); +} + void Font::_bind_methods() { ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","string","modulate","clip_w"),&Font::draw,DEFVAL(Color(1,1,1)),DEFVAL(-1)); @@ -80,6 +85,7 @@ void Font::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_distance_field_hint"),&Font::is_distance_field_hint); ObjectTypeDB::bind_method(_MD("get_string_size","string"),&Font::get_string_size); ObjectTypeDB::bind_method(_MD("draw_char","canvas_item","pos","char","next","modulate"),&Font::draw_char,DEFVAL(-1),DEFVAL(Color(1,1,1))); + ObjectTypeDB::bind_method(_MD("update_changes"),&Font::update_changes); } diff --git a/scene/resources/font.h b/scene/resources/font.h index 67836564cd..fe4558f9e3 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -61,6 +61,7 @@ public: void draw_halign(RID p_canvas_item, const Point2& p_pos, HAlign p_align,float p_width,const String& p_text,const Color& p_modulate=Color(1,1,1)) const; virtual float draw_char(RID p_canvas_item, const Point2& p_pos, CharType p_char, CharType p_next=0,const Color& p_modulate=Color(1,1,1)) const=0; + void update_changes(); Font(); }; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index f6213f74e8..9dc54ef0e4 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -68,7 +68,7 @@ void Material::set_flag(Flag p_flag,bool p_enabled) { void Material::set_blend_mode(BlendMode p_blend_mode) { - ERR_FAIL_INDEX(p_blend_mode,3); + ERR_FAIL_INDEX(p_blend_mode,4); blend_mode=p_blend_mode; VisualServer::get_singleton()->material_set_blend_mode(material,(VS::MaterialBlendMode)p_blend_mode); _change_notify(); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index c36480420b..f16d68a521 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -732,22 +732,62 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, // only connections that originate or end into main saved scene are saved // everything else is discarded - Node *n=c.target->cast_to<Node>(); - if (!n) { + + Node *target=c.target->cast_to<Node>(); + + + if (!target) { continue; } - //source node is outside saved scene? - bool src_is_out = p_node!=p_owner && (p_node->get_filename()!=String() || p_node->get_owner()!=p_owner); - //target node is outside saved scene? - bool dst_is_out = n!=p_owner && (n->get_filename()!=String() || n->get_owner()!=p_owner); + //find if this connection already exists + Node *common_parent = target->find_common_parent_with(p_node); + + ERR_CONTINUE(!common_parent); + + if (common_parent!=p_owner && common_parent->get_filename()==String()) { + common_parent=common_parent->get_owner(); + } + + bool exists=false; + + //go through ownership chain to see if this exists + while(common_parent) { + + + + Ref<SceneState> ps; + + if (common_parent==p_owner) + ps=common_parent->get_scene_inherited_state(); + else + ps=common_parent->get_scene_instance_state(); - //if both are out, ignore connection - if (src_is_out && dst_is_out) { + + if (ps.is_valid()) { + + NodePath signal_from = common_parent->get_path_to(p_node); + NodePath signal_to = common_parent->get_path_to(target); + + if (ps->has_connection(signal_from,c.signal,signal_to,c.method)) { + exists=true; + break; + } + + } + + if (common_parent==p_owner) + break; + else + common_parent=common_parent->get_owner(); + } + + if (exists) { //already exists (comes from instance or inheritance), so don't save continue; } + { Node *nl=p_node; @@ -760,7 +800,7 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, Ref<SceneState> state = nl->get_scene_inherited_state(); if (state.is_valid()) { int from_node = state->find_node_by_path(nl->get_path_to(p_node)); - int to_node = state->find_node_by_path(nl->get_path_to(n)); + int to_node = state->find_node_by_path(nl->get_path_to(target)); if (from_node>=0 && to_node>=0) { //this one has state for this node, save @@ -778,7 +818,7 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, Ref<SceneState> state = nl->get_scene_instance_state(); if (state.is_valid()) { int from_node = state->find_node_by_path(nl->get_path_to(p_node)); - int to_node = state->find_node_by_path(nl->get_path_to(n)); + int to_node = state->find_node_by_path(nl->get_path_to(target)); if (from_node>=0 && to_node>=0) { //this one has state for this node, save @@ -819,14 +859,14 @@ Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map<StringName, int target_id; - if (node_map.has(n)) { - target_id=node_map[n]; + if (node_map.has(target)) { + target_id=node_map[target]; } else { - if (nodepath_map.has(n)) { - target_id=FLAG_ID_IS_PATH|nodepath_map[n]; + if (nodepath_map.has(target)) { + target_id=FLAG_ID_IS_PATH|nodepath_map[target]; } else { int sidx=nodepath_map.size(); - nodepath_map[n]=sidx; + nodepath_map[target]=sidx; target_id=FLAG_ID_IS_PATH|sidx; } } @@ -1478,6 +1518,8 @@ StringName SceneState::get_connection_method(int p_idx) const{ return names[connections[p_idx].method]; } + + int SceneState::get_connection_flags(int p_idx) const{ ERR_FAIL_INDEX_V(p_idx,connections.size(),-1); @@ -1494,6 +1536,38 @@ Array SceneState::get_connection_binds(int p_idx) const { return binds; } +bool SceneState::has_connection(const NodePath& p_node_from, const StringName& p_signal, const NodePath& p_node_to, const StringName& p_method) const { + + for(int i=0;i<connections.size();i++) { + const ConnectionData &c = connections[i]; + + NodePath np_from; + + if (c.from&FLAG_ID_IS_PATH) { + np_from=node_paths[c.from&FLAG_MASK]; + } else { + np_from=get_node_path(c.from); + } + + NodePath np_to; + + if (c.to&FLAG_ID_IS_PATH) { + np_to=node_paths[c.to&FLAG_MASK]; + } else { + np_to=get_node_path(c.to); + } + + StringName sn_signal=names[c.signal]; + StringName sn_method=names[c.method]; + + if (np_from==p_node_from && sn_signal==p_signal && np_to==p_node_to && sn_method==p_method) { + return true; + } + } + + return false; +} + Vector<NodePath> SceneState::get_editable_instances() const { return editable_instances; } @@ -1505,6 +1579,16 @@ int SceneState::add_name(const StringName& p_name) { return names.size()-1; } +int SceneState::find_name(const StringName& p_name) const { + + for(int i=0;i<names.size();i++) { + if (names[i]==p_name) + return i; + } + + return -1; +} + int SceneState::add_value(const Variant& p_value) { variants.push_back(p_value); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 3b6c0898e0..f0e530f88a 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -163,11 +163,14 @@ public: int get_connection_flags(int p_idx) const; Array get_connection_binds(int p_idx) const; + bool has_connection(const NodePath &p_node_from, const StringName& p_signal, const NodePath &p_node_to, const StringName& p_method) const; + Vector<NodePath> get_editable_instances() const; //build API int add_name(const StringName& p_name); + int find_name(const StringName& p_name) const; int add_value(const Variant& p_value); int add_node_path(const NodePath& p_path); int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance); diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index 95645107d4..7bb9ca90ae 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -404,7 +404,9 @@ Error ResourceInteractiveLoaderText::poll() { } if (next_tag.fields.has("parent")) { - parent=packed_scene->get_state()->add_node_path(next_tag.fields["parent"]); + NodePath np = next_tag.fields["parent"]; + np.prepend_period(); //compatible to how it manages paths internally + parent=packed_scene->get_state()->add_node_path(np); } diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 92a6f0c0b9..b351167e10 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -219,7 +219,22 @@ Ref<Theme> Theme::get_default() { void Theme::set_default_theme_font( const Ref<Font>& p_default_font ) { + if (default_theme_font==p_default_font) + return; + + if (default_theme_font.is_valid()) { + _unref_font(default_theme_font); + } + default_theme_font=p_default_font; + + if (default_theme_font.is_valid()) { + _ref_font(default_theme_font); + } + + _change_notify(); + emit_changed();; + } Ref<Font> Theme::get_default_theme_font() const { diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index 35f19605df..ba0358a1f2 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -298,19 +298,17 @@ bool BodyPair2DSW::setup(float p_step) { if (A->is_using_one_way_collision()) { Vector2 direction = A->get_one_way_collision_direction(); bool valid=false; - for(int i=0;i<contact_count;i++) { - Contact& c = contacts[i]; - - if (c.normal.dot(direction)<0) - continue; - if (B->get_linear_velocity().dot(direction)<0) - continue; - - if (!c.reused) { - continue; + if (B->get_linear_velocity().dot(direction)>=0){ + for(int i=0;i<contact_count;i++) { + Contact& c = contacts[i]; + if (!c.reused) + continue; + if (c.normal.dot(direction)<0) + continue; + + valid=true; + break; } - - valid=true; } if (!valid) { @@ -323,20 +321,17 @@ bool BodyPair2DSW::setup(float p_step) { if (B->is_using_one_way_collision()) { Vector2 direction = B->get_one_way_collision_direction(); bool valid=false; - for(int i=0;i<contact_count;i++) { - - Contact& c = contacts[i]; - - if (c.normal.dot(direction)<0) - continue; - if (A->get_linear_velocity().dot(direction)<0) - continue; - - if (!c.reused) { - continue; + if (A->get_linear_velocity().dot(direction)>=0){ + for(int i=0;i<contact_count;i++) { + Contact& c = contacts[i]; + if (!c.reused) + continue; + if (c.normal.dot(direction)<0) + continue; + + valid=true; + break; } - - valid=true; } if (!valid) { collided=false; diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index 210b799f3d..07d1566ab8 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -154,6 +154,9 @@ void CreateDialog::_update_search() { TreeItem *root = search_options->create_item(); root->set_text(0,base_type); + if (has_icon(base_type,"EditorIcons")) { + root->set_icon(0,get_icon(base_type,"EditorIcons")); + } List<StringName>::Element *I=type_list.front(); TreeItem *to_select=NULL; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 81f9927b92..d843b6ef6a 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -704,7 +704,7 @@ void EditorNode::_get_scene_metadata(const String& p_file) { cf.instance(); Error err = cf->load(path); - if (err!=OK) + if (err!=OK || !cf->has_section("editor_states")) return; //must not exist List<String> esl; @@ -740,7 +740,14 @@ void EditorNode::_set_scene_metadata(const String& p_file, int p_idx) { Ref<ConfigFile> cf; cf.instance(); - Dictionary md = editor_data.get_edited_scene()==p_idx?editor_data.get_editor_states():editor_data.get_scene_editor_states(p_idx); + Dictionary md; + + if (p_idx<0 || editor_data.get_edited_scene()==p_idx) { + md = editor_data.get_editor_states(); + } else { + md = editor_data.get_scene_editor_states(p_idx); + } + List<Variant> keys; md.get_key_list(&keys); @@ -1168,6 +1175,8 @@ void EditorNode::_dialog_action(String p_file) { case SETTINGS_PICK_MAIN_SCENE: { Globals::get_singleton()->set("application/main_scene",p_file); + Globals::get_singleton()->set_persisting("application/main_scene",true); + Globals::get_singleton()->save(); //would be nice to show the project manager opened with the hilighted field.. } break; case FILE_SAVE_OPTIMIZED: { @@ -2154,7 +2163,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { String existing; if (extensions.size()) { String root_name(get_edited_scene()->get_name()); - existing=root_name+".tscn";//+extensions.front()->get().to_lower(); + existing=root_name+"."+extensions.front()->get().to_lower(); } file->set_current_path(existing); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 7f496d0e22..c150e62754 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -554,6 +554,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("text_editor/create_signal_callbacks",true); set("text_editor/autosave_interval_secs",0); + set("text_editor/block_caret", false); set("text_editor/caret_blink", false); set("text_editor/caret_blink_speed", 0.65); hints["text_editor/caret_blink_speed"]=PropertyInfo(Variant::REAL,"text_editor/caret_blink_speed",PROPERTY_HINT_RANGE,"0.1, 10, 0.1"); @@ -685,6 +686,7 @@ void EditorSettings::_load_default_text_editor_theme() { set("text_editor/completion_scroll_color", Color::html("ffffff")); set("text_editor/completion_font_color", Color::html("aaaaaa")); set("text_editor/caret_color",Color::html("aaaaaa")); + set("text_editor/caret_background_color", Color::html("000000")); set("text_editor/line_number_color",Color::html("66aaaaaa")); set("text_editor/text_color",Color::html("aaaaaa")); set("text_editor/text_selected_color",Color::html("000000")); @@ -922,6 +924,7 @@ bool EditorSettings::_save_text_editor_theme(String p_file) { cf->set_value(theme_section, "completion_scroll_color", ((Color)get("text_editor/completion_scroll_color")).to_html()); cf->set_value(theme_section, "completion_font_color", ((Color)get("text_editor/completion_font_color")).to_html()); cf->set_value(theme_section, "caret_color", ((Color)get("text_editor/caret_color")).to_html()); + cf->set_value(theme_section, "caret_background_color", ((Color)get("text_editor/caret_background_color")).to_html()); cf->set_value(theme_section, "line_number_color", ((Color)get("text_editor/line_number_color")).to_html()); cf->set_value(theme_section, "text_color", ((Color)get("text_editor/text_color")).to_html()); cf->set_value(theme_section, "text_selected_color", ((Color)get("text_editor/text_selected_color")).to_html()); diff --git a/tools/editor/icons/SCsub b/tools/editor/icons/SCsub index 7132968c88..f2f5dcca48 100644 --- a/tools/editor/icons/SCsub +++ b/tools/editor/icons/SCsub @@ -65,7 +65,7 @@ def make_editor_icons_action(target, source, env): s.write("static Ref<ImageTexture> make_icon(const uint8_t* p_png,const uint8_t* p_hidpi_png) {\n") s.write("\tRef<ImageTexture> texture( memnew( ImageTexture ) );\n") s.write("\tImage img((editor_is_hidpi()&&p_hidpi_png)?p_hidpi_png:p_png);\n") - s.write("\tif (editor_is_hidpi() && !p_hidpi_png) img.expand_x2_hq2x();\n") + s.write("\tif (editor_is_hidpi() && !p_hidpi_png) { img.convert(Image::FORMAT_RGBA); img.expand_x2_hq2x(); }\n") s.write("\ttexture->create_from_image( img,ImageTexture::FLAG_FILTER );\n") s.write("\treturn texture;\n") s.write("}\n\n") diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index e24412d4ef..fa62283e37 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -756,6 +756,8 @@ void EditorSceneImportDialog::_import(bool p_and_open) { } + // Scenes should always be imported as binary format since vertex data is large and would take + // up a lot of space and time to load if imported as text format (GH-5778) String save_file = save_path->get_text().plus_file(import_path->get_text().get_file().basename()+".scn"); print_line("Saving to: "+save_file); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 1d8319d460..60642999f2 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -147,8 +147,6 @@ void EditorImportTextureOptions::_changed() { void EditorImportTextureOptions::_bind_methods() { - print_line("bind toptions"); - ObjectTypeDB::bind_method("_changed",&EditorImportTextureOptions::_changed); ObjectTypeDB::bind_method("_changedp",&EditorImportTextureOptions::_changedp); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 0c9bb1eef0..ec5ac8592b 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -3403,7 +3403,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_set", TTR("Zoom Set..")), ZOOM_SET); p->add_separator(); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_CMD | KEY_F), VIEW_FRAME_TO_SELECTION); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION); anchor_menu = memnew( MenuButton ); anchor_menu->set_text(TTR("Anchor")); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index fc5f552723..4032a790d8 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -317,6 +317,7 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/text_color",Color(0,0,0))); get_text_edit()->add_color_override("line_number_color",EDITOR_DEF("text_editor/line_number_color",Color(0,0,0))); get_text_edit()->add_color_override("caret_color",EDITOR_DEF("text_editor/caret_color",Color(0,0,0))); + get_text_edit()->add_color_override("caret_background_color",EDITOR_DEF("text_editor/caret_background_color",Color(0,0,0))); get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/text_selected_color",Color(1,1,1))); get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/selection_color",Color(0.2,0.2,1))); get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/brace_mismatch_color",Color(1,0.2,0.2))); @@ -818,7 +819,7 @@ void ScriptEditor::_close_tab(int p_idx) { _update_script_names(); - EditorNode::get_singleton()->save_layout(); + _save_layout(); } void ScriptEditor::_close_current_tab() { @@ -827,6 +828,22 @@ void ScriptEditor::_close_current_tab() { } +void ScriptEditor::_close_docs_tab() { + + int child_count = tab_container->get_child_count(); + for (int i = child_count-1; i>=0; i--) { + + EditorHelp *ste = tab_container->get_child(i)->cast_to<EditorHelp>(); + + if (ste) { + _close_tab(i); + } + + } + +} + + void ScriptEditor::_resave_scripts(const String& p_str) { @@ -1012,6 +1029,18 @@ void ScriptEditor::swap_lines(TextEdit *tx, int line1, int line2) tx->cursor_set_line(line2); } +void ScriptEditor::_breakpoint_toggled(const int p_row) { + int selected = tab_container->get_current_tab(); + if (selected<0 || selected>=tab_container->get_child_count()) { + return; + } + + ScriptTextEditor *current = tab_container->get_child(selected)->cast_to<ScriptTextEditor>(); + if (current) { + get_debugger()->set_breakpoint(current->get_edited_script()->get_path(),p_row+1,current->get_text_edit()->is_line_set_as_breakpoint(p_row)); + } +} + void ScriptEditor::_file_dialog_action(String p_file) { switch (file_dialog_option) { @@ -1468,7 +1497,9 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; scr->set_source_code(te->get_text()); - scr->get_language()->reload_tool_script(scr,p_option==FILE_TOOL_RELOAD_SOFT); + bool soft = p_option==FILE_TOOL_RELOAD_SOFT || scr->get_instance_base_type()=="EditorPlugin"; //always soft-reload editor plugins + + scr->get_language()->reload_tool_script(scr,soft); } break; case EDIT_TRIM_TRAILING_WHITESAPCE: { _trim_trailing_whitespace(current->get_text_edit()); @@ -1598,6 +1629,9 @@ void ScriptEditor::_menu_option(int p_option) { _close_current_tab(); } } break; + case CLOSE_DOCS: { + _close_docs_tab(); + } break; case WINDOW_MOVE_LEFT: { if (tab_container->get_current_tab()>0) { @@ -1645,6 +1679,9 @@ void ScriptEditor::_menu_option(int p_option) { case FILE_CLOSE: { _close_current_tab(); } break; + case CLOSE_DOCS: { + _close_docs_tab(); + } break; } @@ -2044,6 +2081,9 @@ void ScriptEditor::_update_script_colors() { void ScriptEditor::_update_script_names() { + if (restoring_layout) + return; + waiting_update_names=false; Set<Ref<Script> > used; Node* edited = EditorNode::get_singleton()->get_edited_scene(); @@ -2195,9 +2235,11 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { ste->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/caret_blink")); ste->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/caret_blink_speed")); ste->get_text_edit()->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/show_breakpoint_gutter")); + ste->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/block_caret")); ste->get_text_edit()->set_callhint_settings( EditorSettings::get_singleton()->get("text_editor/put_callhint_tooltip_below_current_line"), EditorSettings::get_singleton()->get("text_editor/callhint_tooltip_offset")); + ste->get_text_edit()->connect("breakpoint_toggled", this, "_breakpoint_toggled"); tab_container->add_child(ste); _go_to_tab(tab_container->get_tab_count()-1); @@ -2205,10 +2247,8 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { _update_script_names(); + _save_layout(); ste->connect("name_changed",this,"_update_script_names"); - if (!restoring_layout) { - EditorNode::get_singleton()->save_layout(); - } //test for modification, maybe the script was not edited but was loaded @@ -2328,6 +2368,15 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const } +void ScriptEditor::_save_layout() { + + if (restoring_layout) { + return; + } + + editor->save_layout(); +} + void ScriptEditor::_editor_settings_changed() { trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/trim_trailing_whitespace_on_save"); @@ -2362,6 +2411,7 @@ void ScriptEditor::_editor_settings_changed() { ste->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/caret_blink")); ste->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/caret_blink_speed")); ste->get_text_edit()->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/show_breakpoint_gutter")); + ste->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/block_caret")); } ScriptServer::set_reload_scripts_on_save(EDITOR_DEF("text_editor/auto_reload_and_parse_scripts_on_save",true)); @@ -2384,7 +2434,7 @@ void ScriptEditor::_tree_changed() { void ScriptEditor::_script_split_dragged(float) { - EditorNode::get_singleton()->save_layout(); + _save_layout(); } void ScriptEditor::_unhandled_input(const InputEvent& p_event) { @@ -2430,7 +2480,6 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { } } - for(int i=0;i<helps.size();i++) { String path = helps[i]; @@ -2446,9 +2495,9 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset")); } - restoring_layout=false; + _update_script_names(); } void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { @@ -2508,7 +2557,7 @@ void ScriptEditor::_help_class_open(const String& p_class) { eh->go_to_class(p_class,0); eh->connect("go_to_help",this,"_help_class_goto"); _update_script_names(); - + _save_layout(); } void ScriptEditor::_help_class_goto(const String& p_desc) { @@ -2537,7 +2586,7 @@ void ScriptEditor::_help_class_goto(const String& p_desc) { eh->go_to_help(p_desc); eh->connect("go_to_help",this,"_help_class_goto"); _update_script_names(); - + _save_layout(); } void ScriptEditor::_update_history_pos(int p_new_pos) { @@ -2662,6 +2711,7 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_tab_changed",&ScriptEditor::_tab_changed); ObjectTypeDB::bind_method("_menu_option",&ScriptEditor::_menu_option); ObjectTypeDB::bind_method("_close_current_tab",&ScriptEditor::_close_current_tab); + ObjectTypeDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab); ObjectTypeDB::bind_method("_editor_play",&ScriptEditor::_editor_play); ObjectTypeDB::bind_method("_editor_pause",&ScriptEditor::_editor_pause); ObjectTypeDB::bind_method("_editor_stop",&ScriptEditor::_editor_stop); @@ -2671,6 +2721,7 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_res_saved_callback",&ScriptEditor::_res_saved_callback); ObjectTypeDB::bind_method("_goto_script_line",&ScriptEditor::_goto_script_line); ObjectTypeDB::bind_method("_goto_script_line2",&ScriptEditor::_goto_script_line2); + ObjectTypeDB::bind_method("_breakpoint_toggled", &ScriptEditor::_breakpoint_toggled); ObjectTypeDB::bind_method("_breaked",&ScriptEditor::_breaked); ObjectTypeDB::bind_method("_show_debugger",&ScriptEditor::_show_debugger); ObjectTypeDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); @@ -2743,7 +2794,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), FILE_SAVE_THEME); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As")), FILE_SAVE_THEME_AS); file_menu->get_popup()->add_separator(); - file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD|KEY_W), FILE_CLOSE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE); file_menu->get_popup()->connect("item_pressed", this,"_menu_option"); edit_menu = memnew( MenuButton ); diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 2e6e2c035c..2f079b9fc7 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -127,6 +127,7 @@ class ScriptEditor : public VBoxContainer { FILE_SAVE_THEME, FILE_SAVE_THEME_AS, FILE_CLOSE, + CLOSE_DOCS, EDIT_UNDO, EDIT_REDO, EDIT_CUT, @@ -237,6 +238,7 @@ class ScriptEditor : public VBoxContainer { void _close_tab(int p_idx); void _close_current_tab(); + void _close_docs_tab(); bool grab_focus_block; @@ -268,6 +270,7 @@ class ScriptEditor : public VBoxContainer { void _update_window_menu(); void _script_created(Ref<Script> p_script); + void _save_layout(); void _editor_settings_changed(); void _autosave_scripts(); @@ -321,6 +324,7 @@ public: void get_breakpoints(List<String> *p_breakpoints); void swap_lines(TextEdit *tx, int line1, int line2); + void _breakpoint_toggled(const int p_row); void save_all_scripts(); diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp index 9ef84af260..b3317e8313 100644 --- a/tools/editor/plugins/shader_editor_plugin.cpp +++ b/tools/editor/plugins/shader_editor_plugin.cpp @@ -86,6 +86,7 @@ void ShaderTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/text_color",Color(0,0,0))); get_text_edit()->add_color_override("line_number_color",EDITOR_DEF("text_editor/line_number_color",Color(0,0,0))); get_text_edit()->add_color_override("caret_color",EDITOR_DEF("text_editor/caret_color",Color(0,0,0))); + get_text_edit()->add_color_override("caret_background_color",EDITOR_DEF("text_editor/caret_background_color",Color(0,0,0))); get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/text_selected_color",Color(1,1,1))); get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/selection_color",Color(0.2,0.2,1))); get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/brace_mismatch_color",Color(1,0.2,0.2))); @@ -381,6 +382,7 @@ void ShaderEditor::_editor_settings_changed() { vertex_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/caret_blink")); vertex_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/caret_blink_speed")); vertex_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/line_spacing")); + vertex_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/block_caret")); fragment_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/auto_brace_complete")); fragment_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/scroll_past_end_of_file")); @@ -392,6 +394,7 @@ void ShaderEditor::_editor_settings_changed() { fragment_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/caret_blink")); fragment_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/caret_blink_speed")); fragment_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/line_spacing")); + fragment_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/block_caret")); light_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/auto_brace_complete")); light_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/scroll_past_end_of_file")); @@ -403,6 +406,7 @@ void ShaderEditor::_editor_settings_changed() { light_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/caret_blink")); light_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/caret_blink_speed")); light_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/line_spacing")); + light_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/block_caret")); } void ShaderEditor::_bind_methods() { diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 52c8ca4d6c..b7d3abfd5b 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -203,14 +203,15 @@ private: } else { f->store_line("; Engine configuration file."); - f->store_line("; It's best to edit using the editor UI, not directly,"); - f->store_line("; becausethe parameters that go here are not obvious."); + f->store_line("; It's best edited using the editor UI and not directly,"); + f->store_line("; since the parameters that go here are not all obvious."); f->store_line("; "); f->store_line("; Format: "); f->store_line("; [section] ; section goes between []"); f->store_line("; param=value ; assign values to parameters"); f->store_line("\n"); f->store_line("[application]"); + f->store_line("\n"); f->store_line("name=\""+project_name->get_text()+"\""); f->store_line("icon=\"res://icon.png\""); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index ceb62d5ff0..54d197f10d 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -4232,19 +4232,32 @@ String SectionedPropertyEditor::get_full_item_path(const String& p_item) { void SectionedPropertyEditor::edit(Object* p_object) { - if (p_object) { - obj=p_object->get_instance_ID(); - update_category_list(); - } else { + if (!p_object) { + obj = -1; sections->clear(); + + filter->set_edited(NULL); + editor->edit(NULL); + + return; } - filter->set_edited(p_object); - editor->edit(filter); + ObjectID id = p_object->get_instance_ID(); + + if (obj != id) { + + obj = id; + update_category_list(); - sections->select(0); - _section_selected(0); + filter->set_edited(p_object); + editor->edit(filter); + sections->select(0); + _section_selected(0); + } else { + + update_category_list(); + } } void SectionedPropertyEditor::update_category_list() { @@ -4300,6 +4313,8 @@ PropertyEditor *SectionedPropertyEditor::get_property_editor() { SectionedPropertyEditor::SectionedPropertyEditor() { + obj = -1; + VBoxContainer *left_vb = memnew( VBoxContainer); left_vb->set_custom_minimum_size(Size2(160,0)*EDSCALE); add_child(left_vb); diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 2e7d65eadc..e4dfcc0f62 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1574,14 +1574,12 @@ void SceneTreeDock::_normalize_drop(Node*& to_node, int &to_pos, int p_type) { to_pos=-1; - if (p_type==1 && to_node==EditorNode::get_singleton()->get_edited_scene()) { - //if at lower sibling of root node - to_pos=0; //just insert at begining of root node - } else if (p_type==-1) { + if (p_type==-1) { //drop at above selected node if (to_node==EditorNode::get_singleton()->get_edited_scene()) { to_node=NULL; - ERR_FAIL_COND(to_node==EditorNode::get_singleton()->get_edited_scene()); + ERR_EXPLAIN("Cannot perform drop above the root node!"); + ERR_FAIL(); } Node* upper_sibling=NULL; @@ -1617,8 +1615,9 @@ void SceneTreeDock::_normalize_drop(Node*& to_node, int &to_pos, int p_type) { } else if (p_type==1) { //drop at below selected node if (to_node==EditorNode::get_singleton()->get_edited_scene()) { - to_node=NULL; - ERR_FAIL_COND(to_node==EditorNode::get_singleton()->get_edited_scene()); + //if at lower sibling of root node + to_pos=0; //just insert at begining of root node + return; } diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp index f174bc2f1b..73358e805d 100644 --- a/tools/editor/scene_tree_editor.cpp +++ b/tools/editor/scene_tree_editor.cpp @@ -260,13 +260,21 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id) } else if (p_id==BUTTON_SIGNALS) { - item->select(0); + editor_selection->clear(); + editor_selection->add_node(n); + + set_selected(n); + NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); NodeDock::singleton->show_connections(); } else if (p_id==BUTTON_GROUPS) { - item->select(0); + editor_selection->clear(); + editor_selection->add_node(n); + + set_selected(n); + NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index()); NodeDock::singleton->show_groups(); } @@ -975,6 +983,14 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_da if (!d.has("type")) return false; + TreeItem *item = tree->get_item_at_pos(p_point); + if (!item) + return false; + + int section = tree->get_drop_section_at_pos(p_point); + if (section<-1 || (section==-1 && !item->get_parent())) + return false; + if (String(d["type"])=="files") { Vector<String> files = d["files"]; @@ -997,15 +1013,7 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_da if (String(d["type"])=="nodes") { - TreeItem *item = tree->get_item_at_pos(p_point); - if (!item) - return false; - int section = tree->get_drop_section_at_pos(p_point); - if (section<-1 || (section==-1 && !item->get_parent())) - return false; - return true; - } return false; diff --git a/tools/editor/script_editor_debugger.cpp b/tools/editor/script_editor_debugger.cpp index fc746bc21d..b6390e5aae 100644 --- a/tools/editor/script_editor_debugger.cpp +++ b/tools/editor/script_editor_debugger.cpp @@ -338,8 +338,9 @@ void ScriptEditorDebugger::_parse_message(const String& p_msg,const Array& p_dat docontinue->set_disabled(false); emit_signal("breaked",true,can_continue); OS::get_singleton()->move_window_to_foreground(); - if (!profiler->is_seeking()) + if (error!="") { tabs->set_current_tab(0); + } profiler->set_enabled(false); diff --git a/tools/editor/settings_config_dialog.cpp b/tools/editor/settings_config_dialog.cpp index f436e369af..50989ea5cb 100644 --- a/tools/editor/settings_config_dialog.cpp +++ b/tools/editor/settings_config_dialog.cpp @@ -46,9 +46,18 @@ void EditorSettingsDialog::ok_pressed() { void EditorSettingsDialog::_settings_changed() { - timer->start(); - property_editor->get_property_editor()->update_tree(); // else color's won't update when theme is selected. +} + +void EditorSettingsDialog::_settings_property_edited(const String& p_name) { + + String full_name = property_editor->get_full_item_path(p_name); + + // Small usability workaround to update the text color settings when the + // color theme is changed + if (full_name == "text_editor/color_theme") { + property_editor->get_property_editor()->update_tree(); + } } void EditorSettingsDialog::_settings_save() { @@ -281,6 +290,7 @@ void EditorSettingsDialog::_bind_methods() { ObjectTypeDB::bind_method(_MD("_settings_save"),&EditorSettingsDialog::_settings_save); ObjectTypeDB::bind_method(_MD("_settings_changed"),&EditorSettingsDialog::_settings_changed); + ObjectTypeDB::bind_method(_MD("_settings_property_edited"),&EditorSettingsDialog::_settings_property_edited); ObjectTypeDB::bind_method(_MD("_clear_search_box"),&EditorSettingsDialog::_clear_search_box); ObjectTypeDB::bind_method(_MD("_clear_shortcut_search_box"),&EditorSettingsDialog::_clear_shortcut_search_box); ObjectTypeDB::bind_method(_MD("_shortcut_button_pressed"),&EditorSettingsDialog::_shortcut_button_pressed); @@ -325,6 +335,7 @@ EditorSettingsDialog::EditorSettingsDialog() { property_editor->get_property_editor()->register_text_enter(search_box); property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(property_editor); + property_editor->get_property_editor()->connect("property_edited", this, "_settings_property_edited"); vbc = memnew( VBoxContainer ); tabs->add_child(vbc); diff --git a/tools/editor/settings_config_dialog.h b/tools/editor/settings_config_dialog.h index 68a2b008f0..3b91c7f019 100644 --- a/tools/editor/settings_config_dialog.h +++ b/tools/editor/settings_config_dialog.h @@ -64,6 +64,7 @@ class EditorSettingsDialog : public AcceptDialog { virtual void ok_pressed(); void _settings_changed(); + void _settings_property_edited(const String& p_name); void _settings_save(); void _notification(int p_what); diff --git a/tools/editor_fonts/LICENSE.DroidSans.txt b/tools/editor_fonts/LICENSE.DroidSans.txt new file mode 100644 index 0000000000..636f1e2975 --- /dev/null +++ b/tools/editor_fonts/LICENSE.DroidSans.txt @@ -0,0 +1,13 @@ +Copyright (C) 2008 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/tools/editor_fonts/LICENSE.SourceCodePro.txt b/tools/editor_fonts/LICENSE.SourceCodePro.txt new file mode 100644 index 0000000000..f430ee5dbe --- /dev/null +++ b/tools/editor_fonts/LICENSE.SourceCodePro.txt @@ -0,0 +1,94 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + |