diff options
26 files changed, 704 insertions, 67 deletions
diff --git a/demos/3d/inverse_kinematics/engine.cfg b/demos/3d/inverse_kinematics/engine.cfg new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/demos/3d/inverse_kinematics/engine.cfg diff --git a/demos/3d/inverse_kinematics/main.scn b/demos/3d/inverse_kinematics/main.scn Binary files differnew file mode 100644 index 0000000000..918fd09a3a --- /dev/null +++ b/demos/3d/inverse_kinematics/main.scn diff --git a/modules/ik/SCsub b/modules/ik/SCsub new file mode 100644 index 0000000000..211a043468 --- /dev/null +++ b/modules/ik/SCsub @@ -0,0 +1,3 @@ +Import('env') + +env.add_source_files(env.modules_sources,"*.cpp") diff --git a/modules/ik/config.py b/modules/ik/config.py new file mode 100644 index 0000000000..f9bd7da08d --- /dev/null +++ b/modules/ik/config.py @@ -0,0 +1,11 @@ + + +def can_build(platform): + return True + + +def configure(env): + pass + + + diff --git a/modules/ik/ik.cpp b/modules/ik/ik.cpp new file mode 100644 index 0000000000..6c383fdb55 --- /dev/null +++ b/modules/ik/ik.cpp @@ -0,0 +1,326 @@ +/*************************************************************************/ +/* ik.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* This file is Copyright (c) 2016 Sergey Lapin <slapinid@gmail.com> */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "ik.h" + +bool InverseKinematics::_get(const StringName& p_name,Variant &r_ret) const +{ + + if (String(p_name)=="ik_bone") { + + r_ret=get_bone_name(); + return true; + } + + return false; +} + +bool InverseKinematics::_set(const StringName& p_name, const Variant& p_value) +{ + + if (String(p_name)=="ik_bone") { + + set_bone_name(p_value); + changed = true; + return true; + } + + return false; +} + +void InverseKinematics::_get_property_list( List<PropertyInfo>* p_list ) const +{ + + Skeleton *parent=NULL; + if(get_parent()) + parent=get_parent()->cast_to<Skeleton>(); + + if (parent) { + + String names; + for(int i=0;i<parent->get_bone_count();i++) { + if(i>0) + names+=","; + names+=parent->get_bone_name(i); + } + + p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone",PROPERTY_HINT_ENUM,names)); + } else { + + p_list->push_back(PropertyInfo(Variant::STRING,"ik_bone")); + + } + +} + +void InverseKinematics::_check_bind() +{ + + if (get_parent() && get_parent()->cast_to<Skeleton>()) { + Skeleton *sk = get_parent()->cast_to<Skeleton>(); + int idx = sk->find_bone(ik_bone); + if (idx!=-1) { + ik_bone_no = idx; + bound=true; + } + skel = sk; + } +} + +void InverseKinematics::_check_unbind() +{ + + if (bound) { + + if (get_parent() && get_parent()->cast_to<Skeleton>()) { + Skeleton *sk = get_parent()->cast_to<Skeleton>(); + int idx = sk->find_bone(ik_bone); + if (idx!=-1) + ik_bone_no = idx; + else + ik_bone_no = 0; + skel = sk; + + } + bound=false; + } +} + + +void InverseKinematics::set_bone_name(const String& p_name) +{ + + if (is_inside_tree()) + _check_unbind(); + + ik_bone=p_name; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +String InverseKinematics::get_bone_name() const +{ + + return ik_bone; +} + +void InverseKinematics::set_iterations(int itn) +{ + + if (is_inside_tree()) + _check_unbind(); + + iterations=itn; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +int InverseKinematics::get_iterations() const +{ + + return iterations; +} + +void InverseKinematics::set_chain_size(int cs) +{ + if (is_inside_tree()) + _check_unbind(); + + chain_size=cs; + chain.clear(); + if (bound) + update_parameters(); + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +int InverseKinematics::get_chain_size() const +{ + + return chain_size; +} + +void InverseKinematics::set_precision(float p) +{ + + if (is_inside_tree()) + _check_unbind(); + + precision=p; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +float InverseKinematics::get_precision() const +{ + + return precision; +} + +void InverseKinematics::set_speed(float p) +{ + + if (is_inside_tree()) + _check_unbind(); + + speed=p; + + if (is_inside_tree()) + _check_bind(); + changed = true; +} + +float InverseKinematics::get_speed() const +{ + + return speed; +} + +void InverseKinematics::update_parameters() +{ + tail_bone = -1; + for (int i = 0; i < skel->get_bone_count(); i++) + if (skel->get_bone_parent(i) == ik_bone_no) + tail_bone = i; + int cur_bone = ik_bone_no; + int its = chain_size; + while (its > 0 && cur_bone >= 0) { + chain.push_back(cur_bone); + cur_bone = skel->get_bone_parent(cur_bone); + its--; + } +} + +void InverseKinematics::_notification(int p_what) +{ + + switch(p_what) { + + case NOTIFICATION_ENTER_TREE: { + + _check_bind(); + if (bound) { + update_parameters(); + changed = false; + set_process(true); + } + } break; + case NOTIFICATION_PROCESS: { + float delta = get_process_delta_time(); + Spatial *sksp = skel->cast_to<Spatial>(); + if (!bound) + break; + if (!sksp) + break; + if (changed) { + update_parameters(); + changed = false; + } + Vector3 to = get_translation(); + for (int hump = 0; hump < iterations; hump++) { + int depth = 0; + float olderr = 1000.0; + float psign = 1.0; + bool reached = false; + + for (List<int>::Element *b = chain.front(); b; b = b->next()) { + int cur_bone = b->get(); + Vector3 d = skel->get_bone_global_pose(tail_bone).origin; + Vector3 rg = to; + float err = d.distance_squared_to(rg); + if (err < precision) { + if (!reached && err < precision) + reached = true; + break; + } else + if (reached) + reached = false; + if (err > olderr) + psign = -psign; + Transform mod = skel->get_bone_global_pose(cur_bone); + Quat q1 = Quat(mod.basis).normalized(); + Transform mod2 = mod.looking_at(to, Vector3(0.0, 1.0, 0.0)); + Quat q2 = Quat(mod2.basis).normalized(); + if (psign < 0.0) + q2 = q2.inverse(); + Quat q = q1.slerp(q2, speed / (1.0 + 500.0 * depth)).normalized(); + Transform fin = Transform(q); + fin.origin = mod.origin; + skel->set_bone_global_pose(cur_bone, fin); + depth++; + } + if (reached) + break; + + } + + } break; + case NOTIFICATION_EXIT_TREE: { + set_process(false); + + _check_unbind(); + } break; + } +} +void InverseKinematics::_bind_methods() { + ObjectTypeDB::bind_method(_MD("set_bone_name","ik_bone"),&InverseKinematics::set_bone_name); + ObjectTypeDB::bind_method(_MD("get_bone_name"),&InverseKinematics::get_bone_name); + ObjectTypeDB::bind_method(_MD("set_iterations","iterations"),&InverseKinematics::set_iterations); + ObjectTypeDB::bind_method(_MD("get_iterations"),&InverseKinematics::get_iterations); + ObjectTypeDB::bind_method(_MD("set_chain_size","chain_size"),&InverseKinematics::set_chain_size); + ObjectTypeDB::bind_method(_MD("get_chain_size"),&InverseKinematics::get_chain_size); + ObjectTypeDB::bind_method(_MD("set_precision","precision"),&InverseKinematics::set_precision); + ObjectTypeDB::bind_method(_MD("get_precision"),&InverseKinematics::get_precision); + ObjectTypeDB::bind_method(_MD("set_speed","speed"),&InverseKinematics::set_speed); + ObjectTypeDB::bind_method(_MD("get_speed"),&InverseKinematics::get_speed); + ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations"), _SCS("set_iterations"), _SCS("get_iterations")); + ADD_PROPERTY(PropertyInfo(Variant::INT, "chain_size"), _SCS("set_chain_size"), _SCS("get_chain_size")); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "precision"), _SCS("set_precision"), _SCS("get_precision")); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), _SCS("set_speed"), _SCS("get_speed")); +} + +InverseKinematics::InverseKinematics() +{ + bound=false; + chain_size = 2; + iterations = 100; + precision = 0.001; + speed = 0.2; + +} + diff --git a/modules/ik/ik.h b/modules/ik/ik.h new file mode 100644 index 0000000000..9daddb229d --- /dev/null +++ b/modules/ik/ik.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* ik.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* This file is (c) 2016 Sergey Lapin <slapinid@gmail.com> */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef IK_H +#define IK_H + +#include "scene/3d/skeleton.h" +class InverseKinematics : public Spatial { + OBJ_TYPE(InverseKinematics, Spatial); + bool bound; + String ik_bone; + int ik_bone_no; + int tail_bone; + int chain_size; + Skeleton *skel; + List<int> chain; + void _check_bind(); + void _check_unbind(); + int iterations; + float precision; + float speed; + bool changed; + +protected: + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List<PropertyInfo> *p_list) const; + + void _notification(int p_what); + static void _bind_methods(); + void update_parameters(); +public: + Skeleton *get_skeleton(); + void set_bone_name(const String& p_name); + String get_bone_name() const; + void set_iterations(int itn); + int get_iterations() const; + void set_chain_size(int cs); + int get_chain_size() const; + void set_precision(float p); + float get_precision() const; + void set_speed(float p); + float get_speed() const; + InverseKinematics(); +}; + +#endif + diff --git a/modules/ik/register_types.cpp b/modules/ik/register_types.cpp new file mode 100644 index 0000000000..e7df7f55b2 --- /dev/null +++ b/modules/ik/register_types.cpp @@ -0,0 +1,47 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "register_types.h" +#ifndef _3D_DISABLED +#include "object_type_db.h" +#include "ik.h" +#endif + +void register_ik_types() { + +#ifndef _3D_DISABLED + ObjectTypeDB::register_type<InverseKinematics>(); +#endif +} + + + +void unregister_ik_types() { + + +} diff --git a/modules/ik/register_types.h b/modules/ik/register_types.h new file mode 100644 index 0000000000..828917ade7 --- /dev/null +++ b/modules/ik/register_types.h @@ -0,0 +1,30 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +void register_ik_types(); +void unregister_ik_types(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index cc2e5c0d72..dc038f010c 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -544,7 +544,10 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_block_transform_notify(false); // want it back @@ -934,6 +937,7 @@ void RigidBody2D::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 1a2665b6ad..bc637eed44 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -419,7 +419,10 @@ void RigidBody::_direct_state_changed(Object *p_state) { set_global_transform(state->get_transform()); linear_velocity=state->get_linear_velocity(); angular_velocity=state->get_angular_velocity(); - sleeping=state->is_sleeping(); + if(sleeping!=state->is_sleeping()) { + sleeping=state->is_sleeping(); + emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed); + } if (get_script_instance()) get_script_instance()->call("_integrate_forces",state); set_ignore_transform_notification(false); @@ -811,6 +814,7 @@ void RigidBody::_bind_methods() { ADD_SIGNAL( MethodInfo("body_exit_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"local_shape"))); ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("sleeping_state_changed")); BIND_CONSTANT( MODE_STATIC ); BIND_CONSTANT( MODE_KINEMATIC ); diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index cb8806e2ef..0f415f013d 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -53,23 +53,7 @@ void MenuButton::_unhandled_key_input(InputEvent p_event) { code|=KEY_MASK_SHIFT; - int item = popup->find_item_by_accelerator(code); - - - if (item>=0 && ! popup->is_item_disabled(item)) - popup->activate_item(item); - /* - for(int i=0;i<items.size();i++) { - - - if (items[i].accel==0) - continue; - - if (items[i].accel==code) { - - emit_signal("item_pressed",items[i].ID); - } - }*/ + int item = popup->activate_item_by_accelerator(code); } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 3329d24890..819885809b 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -740,15 +740,33 @@ int PopupMenu::get_item_count() const { return items.size(); } -int PopupMenu::find_item_by_accelerator(uint32_t p_accel) const { +bool PopupMenu::activate_item_by_accelerator(uint32_t p_accel) { int il=items.size(); for(int i=0;i<il;i++) { + if (is_item_disabled(i)) + continue; - if (items[i].accel==p_accel) - return i; + if (items[i].accel==p_accel) { + activate_item(i); + return true; + } + + if (items[i].submenu!="") { + Node* n = get_node(items[i].submenu); + if(!n) + continue; + + PopupMenu* pm = n->cast_to<PopupMenu>(); + if(!pm) + continue; + + if(pm->activate_item_by_accelerator(p_accel)) { + return true; + } + } } - return -1; + return false; } void PopupMenu::activate_item(int p_item) { diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 72f8795067..0e98765dc4 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -117,7 +117,7 @@ public: int get_item_count() const; - int find_item_by_accelerator(uint32_t p_accel) const; + bool activate_item_by_accelerator(uint32_t p_accel); void activate_item(int p_item); void remove_item(int p_idx); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c3657d79d7..a0887ffacd 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -672,6 +672,7 @@ void TextEdit::_notification(int p_what) { bool in_keyword=false; bool in_word = false; bool in_function_name = false; + bool in_member_variable = false; Color keyword_color; // check if line contains highlighted word @@ -803,14 +804,28 @@ void TextEdit::_notification(int p_what) { } } + if (!in_function_name && !in_member_variable && !in_keyword && !is_number && in_word) { + int k = j; + while(k > 0 && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') { + k--; + } + + if (str[k] == '.') { + in_member_variable = true; + } + } + if (is_symbol) { in_function_name = false; + in_member_variable = false; } if (in_region>=0) color=color_regions[in_region].color; else if (in_keyword) color=keyword_color; + else if (in_member_variable) + color=cache.member_variable_color; else if (in_function_name) color=cache.function_color; else if (is_symbol) @@ -910,9 +925,9 @@ void TextEdit::_notification(int p_what) { cursor_pos = Point2i( char_ofs+char_margin, ofs_y ); if (insert_mode) { cursor_pos.y += get_row_height(); - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.font_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); } @@ -927,9 +942,9 @@ void TextEdit::_notification(int p_what) { if (insert_mode) { cursor_pos.y += get_row_height(); 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.font_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(char_w,1)),cache.caret_color); } else { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.caret_color); } } } @@ -3067,10 +3082,12 @@ void TextEdit::_update_caches() { cache.style_normal=get_stylebox("normal"); cache.style_focus=get_stylebox("focus"); cache.font=get_font("font"); + cache.caret_color=get_color("caret_color"); cache.font_color=get_color("font_color"); cache.font_selected_color=get_color("font_selected_color"); cache.keyword_color=get_color("keyword_color"); cache.function_color=get_color("function_color"); + cache.member_variable_color=get_color("member_variable_color"); cache.number_color=get_color("number_color"); cache.selection_color=get_color("selection_color"); cache.mark_color=get_color("mark_color"); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index e676aff694..899ce533c4 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -73,11 +73,13 @@ class TextEdit : public Control { Ref<StyleBox> style_normal; Ref<StyleBox> style_focus; Ref<Font> font; + Color caret_color; Color font_color; Color font_selected_color; Color keyword_color; Color number_color; Color function_color; + Color member_variable_color; Color selection_color; Color mark_color; Color breakpoint_color; diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 57bde00de4..f47b61001c 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -48,6 +48,7 @@ SceneStringNames::SceneStringNames() { item_rect_changed=StaticCString::create("item_rect_changed"); size_flags_changed=StaticCString::create("size_flags_changed"); minimum_size_changed=StaticCString::create("minimum_size_changed"); + sleeping_state_changed=StaticCString::create("sleeping_state_changed"); finished=StaticCString::create("finished"); animation_changed=StaticCString::create("animation_changed"); diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index b2c0e9abf0..fc45351c33 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -62,6 +62,7 @@ public: StringName exit_tree; StringName size_flags_changed; StringName minimum_size_changed; + StringName sleeping_state_changed; StringName idle; StringName iteration; StringName update; diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index f78ab93c30..8bb2d60cab 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -260,6 +260,16 @@ EditorPlugin* EditorData::get_subeditor(Object *p_object) { return NULL; } +Vector<EditorPlugin*> EditorData::get_subeditors(Object* p_object) { + Vector<EditorPlugin*> sub_plugins; + for (int i = 0; i < editor_plugins.size(); i++) { + if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) { + sub_plugins.push_back(editor_plugins[i]); + } + } + return sub_plugins; +} + EditorPlugin* EditorData::get_editor(String p_name) { for(int i=0;i<editor_plugins.size();i++) { diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h index 5814ae8f5c..79843c4df5 100644 --- a/tools/editor/editor_data.h +++ b/tools/editor/editor_data.h @@ -150,6 +150,7 @@ public: EditorPlugin* get_editor(Object *p_object); EditorPlugin* get_subeditor(Object *p_object); + Vector<EditorPlugin*> get_subeditors(Object *p_object); EditorPlugin* get_editor(String p_name); void copy_object_params(Object *p_object); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 6d033a5c25..aa47e97622 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -1571,15 +1571,27 @@ void EditorNode::_imported(Node *p_node) { } +void EditorNode::_hide_top_editors() { + _display_top_editors(false); -void EditorNode::_hide_top_editors() { + editor_plugins_over->clear(); +} + +void EditorNode::_display_top_editors(bool p_display) { + editor_plugins_over->make_visible(p_display); +} + +void EditorNode::_set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over) { + editor_plugins_over->set_plugins_list(p_editor_plugins_over); +} - if (editor_plugin_over) - editor_plugin_over->make_visible(false); - editor_plugin_over=NULL; +void EditorNode::_set_editing_top_editors(Object* p_current_object) { + editor_plugins_over->edit(p_current_object); } + + void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); @@ -1598,8 +1610,7 @@ void EditorNode::_edit_current() { property_editor->edit( NULL ); object_menu->set_disabled(true); - if (editor_plugin_over) - editor_plugin_over->make_visible(false); + _display_top_editors(false); return; } @@ -1679,20 +1690,18 @@ void EditorNode::_edit_current() { } - EditorPlugin *sub_plugin = editor_data.get_subeditor(current_obj); - - if (sub_plugin) { + Vector<EditorPlugin*> sub_plugins = editor_data.get_subeditors(current_obj); + if (!sub_plugins.empty()) { + _display_top_editors(false); - if (editor_plugin_over) - editor_plugin_over->make_visible(false); - editor_plugin_over=sub_plugin; - editor_plugin_over->edit(current_obj); - editor_plugin_over->make_visible(true); - } else if (editor_plugin_over) { + _set_top_editors(sub_plugins); + _set_editing_top_editors(current_obj); + _display_top_editors(true); + + } else if (!editor_plugins_over->get_plugins_list().empty()) { - editor_plugin_over->make_visible(false); - editor_plugin_over=NULL; + _hide_top_editors(); } /* @@ -2583,10 +2592,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } editor_data.get_undo_redo().clear_history(); - if (editor_plugin_over) { //reload editor plugin - editor_plugin_over->edit(NULL); - editor_plugin_over->edit(current); - } + + _set_editing_top_editors(NULL); + _set_editing_top_editors(current); } break; case OBJECT_CALL_METHOD: { @@ -6138,7 +6146,7 @@ EditorNode::EditorNode() { _rebuild_import_menu(); editor_plugin_screen=NULL; - editor_plugin_over=NULL; + editor_plugins_over = memnew(EditorPluginList); // force_top_viewport(true); _edit_current(); @@ -6270,12 +6278,72 @@ EditorNode::EditorNode() { EditorNode::~EditorNode() { - - + memdelete( EditorHelp::get_doc_data() ); memdelete(editor_selection); + memdelete(editor_plugins_over); memdelete(file_server); EditorSettings::destroy(); } +/* + * EDITOR PLUGIN LIST + */ + + +void EditorPluginList::make_visible(bool p_visible) { + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->make_visible(p_visible); + } + } +} + +void EditorPluginList::edit(Object* p_object) { + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + plugins_list[i]->edit(p_object); + } + } +} + +bool EditorPluginList::forward_input_event(const InputEvent& p_event) { + bool discard = false; + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + if (plugins_list[i]->forward_input_event(p_event)) { + discard = true; + } + } + } + return discard; +} + +bool EditorPluginList::forward_spatial_input_event(Camera* p_camera, const InputEvent& p_event) { + bool discard = false; + if (!plugins_list.empty()) { + for (int i = 0; i < plugins_list.size(); i++) { + if (plugins_list[i]->forward_spatial_input_event(p_camera, p_event)) { + discard = true; + } + } + } + return discard; +} + +bool EditorPluginList::empty() { + return plugins_list.empty(); +} + +void EditorPluginList::clear() { + plugins_list.clear(); +} + +EditorPluginList::EditorPluginList() { +} + +EditorPluginList::~EditorPluginList() { +} + + diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index b8fabb4c55..e4939afd34 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -95,7 +95,7 @@ typedef void (*EditorNodeInitCallback)(); - +class EditorPluginList; class EditorNode : public Node { @@ -372,7 +372,7 @@ private: Vector<EditorPlugin*> editor_plugins; EditorPlugin *editor_plugin_screen; - EditorPlugin *editor_plugin_over; + EditorPluginList *editor_plugins_over; EditorHistory editor_history; EditorData editor_data; @@ -449,6 +449,10 @@ private: void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); void _hide_top_editors(); + void _display_top_editors(bool p_display); + void _set_top_editors(Vector<EditorPlugin*> p_editor_plugins_over); + void _set_editing_top_editors(Object * p_current_object); + void _quick_opened(); void _quick_run(); @@ -575,7 +579,7 @@ public: EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; } - EditorPlugin *get_editor_plugin_over() { return editor_plugin_over; } + EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; } PropertyEditor *get_property_editor() { return property_editor; } static void add_editor_plugin(EditorPlugin *p_editor); @@ -710,6 +714,32 @@ struct EditorProgress { ~EditorProgress() { EditorNode::progress_end_task(task); } }; +class EditorPluginList : public Object { +private: + Vector<EditorPlugin*> plugins_list; + +public: + + void set_plugins_list(Vector<EditorPlugin*> p_plugins_list) { + plugins_list = p_plugins_list; + } + + Vector<EditorPlugin*> get_plugins_list() { + return plugins_list; + } + + void make_visible(bool p_visible); + void edit(Object *p_object); + bool forward_input_event(const InputEvent& p_event); + bool forward_spatial_input_event(Camera* p_camera, const InputEvent& p_event); + void clear(); + bool empty(); + + EditorPluginList(); + ~EditorPluginList(); + +} ; + struct EditorProgressBG { String task; diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index a7c01e0f6f..255ad40bce 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -392,12 +392,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["global/default_project_export_path"]=PropertyInfo(Variant::STRING,"global/default_project_export_path",PROPERTY_HINT_GLOBAL_DIR); set("global/show_script_in_scene_tabs",false); set("text_editor/background_color",Color::html("3b000000")); + set("text_editor/caret_color",Color::html("aaaaaa")); set("text_editor/text_color",Color::html("aaaaaa")); set("text_editor/text_selected_color",Color::html("000000")); set("text_editor/keyword_color",Color::html("ffffb3")); set("text_editor/base_type_color",Color::html("a4ffd4")); set("text_editor/engine_type_color",Color::html("83d3ff")); set("text_editor/function_color",Color::html("66a2ce")); + set("text_editor/member_variable_color",Color::html("e64e59")); set("text_editor/comment_color",Color::html("983d1b")); set("text_editor/string_color",Color::html("ef6ebe")); set("text_editor/number_color",Color::html("EB9532")); @@ -407,6 +409,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15)); set("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15)); + set("text_editor/syntax_highlighting", true); + set("text_editor/highlight_all_occurrences", true); set("text_editor/scroll_past_end_of_file", false); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 6eb26542be..7a3f563734 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -1037,10 +1037,10 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin) { - bool discard = over_plugin->forward_input_event(p_event); + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_input_event(p_event); if (discard) { accept_event(); return; @@ -3345,7 +3345,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { PopupMenu *p2 = memnew(PopupMenu); p->add_child(p2); p2->set_name("skeleton"); - p2->add_item("Make Bones",SKELETON_MAKE_BONES,KEY_MASK_CMD|KEY_SHIFT|KEY_B); + p2->add_item("Make Bones",SKELETON_MAKE_BONES,KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_B); p2->add_item("Clear Bones",SKELETON_CLEAR_BONES); p2->add_separator(); p2->add_item("Make IK Chain",SKELETON_SET_IK_CHAIN); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index a94b020518..5f2efc8f03 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -288,6 +288,7 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->set_custom_bg_color(EDITOR_DEF("text_editor/background_color",Color(0,0,0,0))); get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/text_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("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))); @@ -295,10 +296,10 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("word_highlighted_color",EDITOR_DEF("text_editor/word_highlighted_color",Color(0.8,0.9,0.9,0.15))); get_text_edit()->add_color_override("number_color",EDITOR_DEF("text_editor/number_color",Color(0.9,0.6,0.0,2))); get_text_edit()->add_color_override("function_color",EDITOR_DEF("text_editor/function_color",Color(0.4,0.6,0.8))); + get_text_edit()->add_color_override("member_variable_color",EDITOR_DEF("text_editor/member_variable_color",Color(0.9,0.3,0.3))); Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2)); - get_text_edit()->set_syntax_coloring(true); List<String> keywords; script->get_language()->get_reserved_words(&keywords); for(List<String>::Element *E=keywords.front();E;E=E->next()) { @@ -1924,6 +1925,7 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { ste->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/tab_size")); ste->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/draw_tabs")); ste->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/show_line_numbers")); + ste->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/syntax_highlighting")); ste->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlight_all_occurrences")); ste->get_text_edit()->set_callhint_settings( EditorSettings::get_singleton()->get("text_editor/put_callhint_tooltip_below_current_line"), @@ -2065,6 +2067,7 @@ void ScriptEditor::_editor_settings_changed() { ste->get_text_edit()->set_tab_size(EditorSettings::get_singleton()->get("text_editor/tab_size")); ste->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/draw_tabs")); ste->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/show_line_numbers")); + ste->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/syntax_highlighting")); ste->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlight_all_occurrences")); } diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index c78b3086ea..9ab7aafeb2 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -834,10 +834,10 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin) { - bool discard = over_plugin->forward_spatial_input_event(camera,p_event); + if (!over_plugin_list->empty()) { + bool discard = over_plugin_list->forward_spatial_input_event(camera,p_event); if (discard) return; } @@ -3576,9 +3576,9 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) { { EditorNode *en = editor; - EditorPlugin *over_plugin = en->get_editor_plugin_over(); + EditorPluginList *over_plugin_list = en->get_editor_plugins_over(); - if (over_plugin && over_plugin->forward_input_event(p_event)) { + if (!over_plugin_list->empty() && over_plugin_list->forward_input_event(p_event)) { return; //ate the over input event } diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 5877ce1a43..6b2961ea72 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -1098,8 +1098,7 @@ void SceneTreeDock::_delete_confirm() { return; - if (editor->get_editor_plugin_over()) - editor->get_editor_plugin_over()->make_visible(false); + editor->get_editor_plugins_over()->make_visible(false); editor_data->get_undo_redo().create_action("Remove Node(s)"); |