diff options
129 files changed, 3440 insertions, 537 deletions
diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..e19057f0e8 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = tab + +[.travis.yml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index fbb3ba6cb4..613eff442a 100644 --- a/.gitignore +++ b/.gitignore @@ -281,3 +281,5 @@ cscope.out cscope.in.out cscope.po.out godot.creator.* + +projects/
\ No newline at end of file diff --git a/SConstruct b/SConstruct index 11b35e0b4b..a1a3238305 100644 --- a/SConstruct +++ b/SConstruct @@ -360,6 +360,11 @@ if selected_platform in platform_list: AddToVSProject(env.scene_sources) AddToVSProject(env.servers_sources) AddToVSProject(env.tool_sources) + + #env['MSVS_VERSION']='9.0' + env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes" + env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes" + env['MSVSCLEANCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes" debug_variants = ['Debug|Win32']+['Debug|x64'] release_variants = ['Release|Win32']+['Release|x64'] diff --git a/bin/tests/test_gui.cpp b/bin/tests/test_gui.cpp index 8822febdeb..c404623872 100644 --- a/bin/tests/test_gui.cpp +++ b/bin/tests/test_gui.cpp @@ -109,6 +109,9 @@ public: frame->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END ); frame->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END ); frame->set_end( Point2(0,0) ); + + Ref<Theme> t = memnew( Theme ); + frame->set_theme(t); get_root()->add_child( frame ); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 9fb17bcffb..0f6f8a74b1 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -663,14 +663,18 @@ Error ResourceInteractiveLoaderBinary::poll(){ //maybe it is loaded already String path; + int subindex=0; if (!main) { path=internal_resources[s].path; - if (path.begins_with("local://")) - path=path.replace("local://",res_path+"::"); + if (path.begins_with("local://")) { + path=path.replace_first("local://",""); + subindex = path.to_int(); + path=res_path+"::"+path; + } @@ -709,6 +713,7 @@ Error ResourceInteractiveLoaderBinary::poll(){ RES res = RES( r ); r->set_path(path); + r->set_subindex(subindex); int pc = f->get_32(); @@ -1434,14 +1439,14 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property, save_unicode_string(path); } else { - if (!resource_map.has(res)) { + if (!resource_set.has(res)) { f->store_32(OBJECT_EMPTY); ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); ERR_FAIL(); } f->store_32(OBJECT_INTERNAL_RESOURCE); - f->store_32(resource_map[res]); + f->store_32(res->get_subindex()); //internal resource } @@ -1598,7 +1603,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant } - if (resource_map.has(res)) + if (resource_set.has(res)) return; List<PropertyInfo> property_list; @@ -1613,7 +1618,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant } } - resource_map[ res ] = saved_resources.size(); + resource_set.insert(res); saved_resources.push_back(res); } break; @@ -1846,11 +1851,42 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_ // save internal resource table f->store_32(saved_resources.size()); //amount of internal resources Vector<uint64_t> ofs_pos; + Set<int> used_indices; + + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { + + RES r = E->get(); + if (r->get_path()=="" || r->get_path().find("::")!=-1) { + + if (r->get_subindex()!=0) { + if (used_indices.has(r->get_subindex())) { + r->set_subindex(0); //repeated + } else { + used_indices.insert(r->get_subindex()); + } + } + } + + } + + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { + RES r = E->get(); if (r->get_path()=="" || r->get_path().find("::")!=-1) { - save_unicode_string("local://"+itos(ofs_pos.size())); + if (r->get_subindex()==0) { + int new_subindex=1; + if (used_indices.size()) { + new_subindex=used_indices.back()->get()+1; + } + + r->set_subindex(new_subindex); + used_indices.insert(new_subindex); + + } + + save_unicode_string("local://"+itos(r->get_subindex())); if (takeover_paths) { r->set_path(p_path+"::"+itos(ofs_pos.size()),true); } diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index ab2e640a86..da415d97a5 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -129,7 +129,7 @@ class ResourceFormatSaverBinaryInstance { int bin_meta_idx; FileAccess *f; String magic; - Map<RES,int> resource_map; + Set<RES> resource_set; Map<StringName,int> string_map; Vector<StringName> strings; diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 3c100d375a..36746a4111 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -1466,6 +1466,7 @@ Error ResourceInteractiveLoaderXML::poll() { String type; String path; + int subres=0; if (!main) { //loading resource @@ -1476,11 +1477,15 @@ Error ResourceInteractiveLoaderXML::poll() { ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field."); ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT); path=tag->args["path"]; + error=OK; if (path.begins_with("local://")) { //built-in resource (but really external) - path=path.replace("local://",local_path+"::"); + + path=path.replace("local://",""); + subres=path.to_int(); + path=local_path+"::"+path; } @@ -1519,6 +1524,7 @@ Error ResourceInteractiveLoaderXML::poll() { res = RES( r ); if (path!="") r->set_path(path); + r->set_subindex(subres); //load properties @@ -2029,9 +2035,9 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V //internal resource ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL_COND(!resource_map.has(res)); + ERR_FAIL_COND(!resource_set.has(res)); - params+=" path=\"local://"+itos(resource_map[res])+"\""; + params+=" path=\"local://"+itos(res->get_subindex())+"\""; } } break; @@ -2443,7 +2449,7 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo return; } - if (resource_map.has(res)) + if (resource_set.has(res)) return; List<PropertyInfo> property_list; @@ -2466,7 +2472,7 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo I=I->next(); } - resource_map[ res ] = resource_map.size(); //saved after, so the childs it needs are available when loaded + resource_set.insert( res ); //saved after, so the childs it needs are available when loaded saved_resources.push_back(res); } break; @@ -2537,12 +2543,27 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res write_string("\n",false); } + Set<int> used_indices; + + for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { + + RES res = E->get(); + if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) { + if (res->get_subindex()!=0) { + if (used_indices.has(res->get_subindex())) { + res->set_subindex(0); //repeated + } else { + used_indices.insert(res->get_subindex()); + } + } + } + } for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) { RES res = E->get(); - ERR_CONTINUE(!resource_map.has(res)); + ERR_CONTINUE(!resource_set.has(res)); bool main = (E->next()==NULL); write_tabs(); @@ -2552,7 +2573,18 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res else if (res->get_path().length() && res->get_path().find("::") == -1 ) enter_tag("resource","type=\""+res->get_type()+"\" path=\""+res->get_path()+"\""); //bundled else { - int idx = resource_map[res]; + + if (res->get_subindex()==0) { + int new_subindex=1; + if (used_indices.size()) { + new_subindex=used_indices.back()->get()+1; + } + + res->set_subindex(new_subindex); + used_indices.insert(new_subindex); + } + + int idx = res->get_subindex(); enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(idx)+"\""); if (takeover_paths) { res->set_path(p_path+"::"+itos(idx),true); diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h index 711b607668..d5ba9eb800 100644 --- a/core/io/resource_format_xml.h +++ b/core/io/resource_format_xml.h @@ -123,7 +123,7 @@ class ResourceFormatSaverXMLInstance { bool skip_editor; FileAccess *f; int depth; - Map<RES,int> resource_map; + Set<RES> resource_set; List<RES> saved_resources; List<RES> external_resources; diff --git a/core/object.cpp b/core/object.cpp index 83a6dada80..cdb2c6517a 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -34,6 +34,7 @@ #include "core_string_names.h" #include "translation.h" #include "os/os.h" +#include "resource.h" #ifdef DEBUG_ENABLED @@ -1464,6 +1465,63 @@ StringName Object::tr(const StringName& p_message) const { } + +void Object::_clear_internal_resource_paths(const Variant &p_var) { + + switch(p_var.get_type()) { + + case Variant::OBJECT: { + + RES r = p_var; + if (!r.is_valid()) + return; + + if (!r->get_path().begins_with("res://") || r->get_path().find("::")==-1) + return; //not an internal resource + + Object *object=p_var; + if (!object) + return; + + r->set_path(""); + r->clear_internal_resource_paths(); + } break; + case Variant::ARRAY: { + + Array a=p_var; + for(int i=0;i<a.size();i++) { + _clear_internal_resource_paths(a[i]); + } + + } break; + case Variant::DICTIONARY: { + + Dictionary d=p_var; + List<Variant> keys; + d.get_key_list(&keys); + + for (List<Variant>::Element *E=keys.front();E;E=E->next()) { + + _clear_internal_resource_paths(E->get()); + _clear_internal_resource_paths(d[E->get()]); + } + } break; + } + +} + +void Object::clear_internal_resource_paths() { + + List<PropertyInfo> pinfo; + + get_property_list(&pinfo); + + for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) { + + _clear_internal_resource_paths(get(E->get().name)); + } +} + void Object::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_type"),&Object::get_type); diff --git a/core/object.h b/core/object.h index 8d1f8ebc5a..9680af924a 100644 --- a/core/object.h +++ b/core/object.h @@ -451,6 +451,8 @@ protected: Array _get_property_list_bind() const; Array _get_method_list_bind() const; + void _clear_internal_resource_paths(const Variant &p_var); + public: //should be protected, but bug in clang++ static void initialize_type(); _FORCE_INLINE_ static void register_custom_data_to_otdb() {}; @@ -599,6 +601,9 @@ public: _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } + + void clear_internal_resource_paths(); + Object(); virtual ~Object(); @@ -651,6 +656,8 @@ public: #endif + + }; //needed by macros diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 617e40e92a..1d9ac4e302 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -112,13 +112,6 @@ size_t Memory::get_dynamic_mem_usage() { return MemoryPoolDynamic::get_singleton()->get_total_usage(); } -void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description) { - - void *failptr=0; - ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */ - - return p_pointer; -} diff --git a/core/os/memory.h b/core/os/memory.h index 4497fcc200..0a35c93fdb 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -236,11 +236,11 @@ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_de #endif -_FORCE_INLINE_ void postinitialize_handler(void *) {} +_ALWAYS_INLINE_ void postinitialize_handler(void *) {} template<class T> -_FORCE_INLINE_ T *_post_initialize(T *p_obj) { +_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) { postinitialize_handler(p_obj); return p_obj; @@ -249,19 +249,26 @@ _FORCE_INLINE_ T *_post_initialize(T *p_obj) { #ifdef DEBUG_MEMORY_ENABLED #define memnew(m_class) _post_initialize(new(__FILE__":"__STR(__LINE__)", memnew type: "__STR(m_class)) m_class) -#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),__FILE__":"__STR(__LINE__)", type: "__STR(m_class)) m_class) #else #define memnew(m_class) _post_initialize(new("") m_class) -#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),"") m_class) #endif +_ALWAYS_INLINE_ void * operator new(size_t p_size,void *p_pointer,size_t check, const char *p_description) { +// void *failptr=0; +// ERR_FAIL_COND_V( check < p_size , failptr); /** bug, or strange compiler, most likely */ + + return p_pointer; +} + + #define memnew_allocator(m_class,m_allocator) _post_initialize(new(m_allocator::alloc) m_class) +#define memnew_placement(m_placement,m_class) _post_initialize(new(m_placement,sizeof(m_class),"") m_class) -_FORCE_INLINE_ bool predelete_handler(void *) { return true; } +_ALWAYS_INLINE_ bool predelete_handler(void *) { return true; } template<class T> void memdelete(T *p_class) { diff --git a/core/reference.h b/core/reference.h index 544da41044..65f31f78f3 100644 --- a/core/reference.h +++ b/core/reference.h @@ -294,6 +294,9 @@ public: reference=NULL; } + void instance() { + ref( memnew( T )); + } Ref() { diff --git a/core/resource.cpp b/core/resource.cpp index 6e65693350..6967599f96 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -195,6 +195,17 @@ String Resource::get_path() const { return path_cache; } +void Resource::set_subindex(int p_sub_index) { + + subindex=p_sub_index; +} + +int Resource::get_subindex() const{ + + return subindex; +} + + void Resource::set_name(const String& p_name) { name=p_name; @@ -326,6 +337,7 @@ Resource::Resource() { last_modified_time=0; #endif + subindex=0; } diff --git a/core/resource.h b/core/resource.h index cf7ffcbd2c..9d9c445e1d 100644 --- a/core/resource.h +++ b/core/resource.h @@ -99,6 +99,7 @@ friend class ResourceCache; String name; String path_cache; + int subindex; virtual bool _use_builtin_script() const { return true; } @@ -132,6 +133,9 @@ public: void set_path(const String& p_path,bool p_take_over=false); String get_path() const; + void set_subindex(int p_sub_index); + int get_subindex() const; + Ref<Resource> duplicate(bool p_subresources=false); void set_import_metadata(const Ref<ResourceImportMetadata>& p_metadata); diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index 5e7df3be7e..f565070216 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -282,6 +282,7 @@ void UndoRedo::undo() { return; //nothing to redo _process_operation_list(actions[current_action].undo_ops.front()); current_action--; + version--; } void UndoRedo::clear_history() { @@ -292,7 +293,7 @@ void UndoRedo::clear_history() { while(actions.size()) _pop_history_tail(); - version++; + //version++; } String UndoRedo::get_current_action_name() const { @@ -326,7 +327,7 @@ void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback,void* UndoRedo::UndoRedo() { - version=0; + version=1; action_level=0; current_action=-1; max_steps=-1; @@ -339,3 +340,126 @@ UndoRedo::~UndoRedo() { clear_history(); } + +Variant UndoRedo::_add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) { + + if (p_argcount<2) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=0; + return Variant(); + } + + if (p_args[0]->get_type()!=Variant::OBJECT) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return Variant(); + } + + if (p_args[1]->get_type()!=Variant::STRING) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=1; + r_error.expected=Variant::STRING; + return Variant(); + } + + r_error.error=Variant::CallError::CALL_OK; + + Object* object = *p_args[0]; + String method = *p_args[1]; + + Variant v[VARIANT_ARG_MAX]; + + + for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) { + + v[i]=*p_args[i+2]; + } + + add_do_method(object,method,v[0],v[1],v[2],v[3],v[4]); + return Variant(); +} + +Variant UndoRedo::_add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) { + + if (p_argcount<2) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=0; + return Variant(); + } + + if (p_args[0]->get_type()!=Variant::OBJECT) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + return Variant(); + } + + if (p_args[1]->get_type()!=Variant::STRING) { + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=1; + r_error.expected=Variant::STRING; + return Variant(); + } + + r_error.error=Variant::CallError::CALL_OK; + + Object* object = *p_args[0]; + String method = *p_args[1]; + + Variant v[VARIANT_ARG_MAX]; + + + for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) { + + v[i]=*p_args[i+2]; + } + + add_undo_method(object,method,v[0],v[1],v[2],v[3],v[4]); + return Variant(); +} + +void UndoRedo::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) ); + ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action); + + //ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method); + //ObjectTypeDB::bind_method(_MD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method); + + { + MethodInfo mi; + mi.name="add_do_method"; + mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); + mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); + Vector<Variant> defargs; + for(int i=0;i<VARIANT_ARG_MAX;++i) { + mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); + defargs.push_back(Variant()); + } + + ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi,defargs); + } + + { + MethodInfo mi; + mi.name="add_undo_method"; + mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); + mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); + Vector<Variant> defargs; + for(int i=0;i<VARIANT_ARG_MAX;++i) { + mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); + defargs.push_back(Variant()); + } + + ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi,defargs); + } + + ObjectTypeDB::bind_method(_MD("add_do_property","object", "property", "value:var"),&UndoRedo::add_do_property); + ObjectTypeDB::bind_method(_MD("add_undo_property","object", "property", "value:var"),&UndoRedo::add_undo_property); + ObjectTypeDB::bind_method(_MD("add_do_reference","object"),&UndoRedo::add_do_reference); + ObjectTypeDB::bind_method(_MD("add_undo_reference","object"),&UndoRedo::add_undo_reference); + ObjectTypeDB::bind_method(_MD("clear_history"),&UndoRedo::clear_history); + ObjectTypeDB::bind_method(_MD("get_current_action_name"),&UndoRedo::get_current_action_name); + ObjectTypeDB::bind_method(_MD("get_version"),&UndoRedo::get_version); +} diff --git a/core/undo_redo.h b/core/undo_redo.h index d1b2d3de9e..a9187534c1 100644 --- a/core/undo_redo.h +++ b/core/undo_redo.h @@ -38,9 +38,12 @@ class UndoRedo : public Object { OBJ_TYPE(UndoRedo,Object); + OBJ_SAVE_TYPE( UndoRedo ); public: typedef void (*CommitNotifyCallback)(void *p_ud,const String& p_name); + Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error); + Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error); private: struct Operation { @@ -81,6 +84,10 @@ private: CommitNotifyCallback callback; void* callback_ud; + +protected: + static void _bind_methods(); + public: void create_action(const String& p_name="",bool p_mergeable=false); diff --git a/demos/2d/space_shooter/asteroid.gd b/demos/2d/space_shooter/asteroid.gd new file mode 100644 index 0000000000..f21b9777bb --- /dev/null +++ b/demos/2d/space_shooter/asteroid.gd @@ -0,0 +1,49 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const SPEED=-200 +const Y_RANDOM=10 + +var points=1 + + +var speed_y=0.0 + +func _process(delta): + + translate( Vector2(SPEED,speed_y) * delta ) + +func _ready(): + # Initialization here + speed_y=rand_range(-Y_RANDOM,Y_RANDOM) + pass + +var destroyed=false + +func destroy(): + if (destroyed): + return + destroyed=true + get_node("anim").play("explode") + set_process(false) + get_node("sfx").play("sound_explode") + #accum points + get_node("/root/game_state").points+=1 + +func is_enemy(): + return not destroyed + + +func _on_visibility_enter_screen(): + set_process(true) + #make it spin! + get_node("anim").play("spin") + + +func _on_visibility_exit_screen(): + queue_free() + pass # replace with function body diff --git a/demos/2d/space_shooter/asteroid.scn b/demos/2d/space_shooter/asteroid.scn Binary files differnew file mode 100644 index 0000000000..b881725ea4 --- /dev/null +++ b/demos/2d/space_shooter/asteroid.scn diff --git a/demos/2d/space_shooter/bg_gradient.png b/demos/2d/space_shooter/bg_gradient.png Binary files differnew file mode 100644 index 0000000000..3e71976dc6 --- /dev/null +++ b/demos/2d/space_shooter/bg_gradient.png diff --git a/demos/2d/space_shooter/big_star.png b/demos/2d/space_shooter/big_star.png Binary files differnew file mode 100644 index 0000000000..7726a7aa12 --- /dev/null +++ b/demos/2d/space_shooter/big_star.png diff --git a/demos/2d/space_shooter/enemy1.gd b/demos/2d/space_shooter/enemy1.gd new file mode 100644 index 0000000000..051798742a --- /dev/null +++ b/demos/2d/space_shooter/enemy1.gd @@ -0,0 +1,37 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const SPEED=-200 + +func _process(delta): + get_parent().translate(Vector2(SPEED*delta,0)) + + +var destroyed=false + +func is_enemy(): + return not destroyed + + +func destroy(): + if (destroyed): + return + destroyed=true + get_node("anim").play("explode") + set_process(false) + get_node("sfx").play("sound_explode") + #accum points + get_node("/root/game_state").points+=5 + +func _on_visibility_enter_screen(): + set_process(true) + get_node("anim").play("zigzag") + get_node("anim").seek(randf()*2.0) #make it start from any pos + +func _on_visibility_exit_screen(): + queue_free() + diff --git a/demos/2d/space_shooter/enemy1.png b/demos/2d/space_shooter/enemy1.png Binary files differnew file mode 100644 index 0000000000..242d8f0055 --- /dev/null +++ b/demos/2d/space_shooter/enemy1.png diff --git a/demos/2d/space_shooter/enemy1.scn b/demos/2d/space_shooter/enemy1.scn Binary files differnew file mode 100644 index 0000000000..14298f0a59 --- /dev/null +++ b/demos/2d/space_shooter/enemy1.scn diff --git a/demos/2d/space_shooter/enemy2.gd b/demos/2d/space_shooter/enemy2.gd new file mode 100644 index 0000000000..4f632a053d --- /dev/null +++ b/demos/2d/space_shooter/enemy2.gd @@ -0,0 +1,56 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" +const SPEED=-220 +const SHOOT_INTERVAL=1 +var shoot_timeout=0 + +func _process(delta): + translate( Vector2(SPEED*delta,0) ) + shoot_timeout-=delta + + if (shoot_timeout<0): + + shoot_timeout=SHOOT_INTERVAL + + #instance a shot + var shot = preload("res://enemy_shot.scn").instance() + #set pos as "shoot_from" Position2D node + shot.set_pos( get_node("shoot_from").get_global_pos() ) + #add it to parent, so it has world coordinates + get_parent().add_child(shot) + +var destroyed=false + +func is_enemy(): + return not destroyed + +func destroy(): + if (destroyed): + return + destroyed=true + get_node("anim").play("explode") + set_process(false) + get_node("sfx").play("sound_explode") + #accum points + get_node("/root/game_state").points+=10 + +func _ready(): + set_fixed_process(true) + # Initialization here + pass + + + + +func _on_visibility_enter_screen(): + set_process(true) + pass # replace with function body + + +func _on_visibility_exit_screen(): + queue_free() + pass # replace with function body diff --git a/demos/2d/space_shooter/enemy2.png b/demos/2d/space_shooter/enemy2.png Binary files differnew file mode 100644 index 0000000000..5b63033696 --- /dev/null +++ b/demos/2d/space_shooter/enemy2.png diff --git a/demos/2d/space_shooter/enemy2.scn b/demos/2d/space_shooter/enemy2.scn Binary files differnew file mode 100644 index 0000000000..1d31f9c30e --- /dev/null +++ b/demos/2d/space_shooter/enemy2.scn diff --git a/demos/2d/space_shooter/enemy_shot.gd b/demos/2d/space_shooter/enemy_shot.gd new file mode 100644 index 0000000000..238d24e4a2 --- /dev/null +++ b/demos/2d/space_shooter/enemy_shot.gd @@ -0,0 +1,32 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const SPEED = -800 + +func _process(delta): + translate(Vector2(delta*SPEED,0)) + +func _ready(): + # Initialization here + set_process(true) + + +var hit=false + +func is_enemy(): + return true + +func _hit_something(): + if (hit): + return + hit=true + set_process(false) + get_node("anim").play("splash") + +func _on_visibility_exit_screen(): + queue_free() + diff --git a/demos/2d/space_shooter/enemy_shot.png b/demos/2d/space_shooter/enemy_shot.png Binary files differnew file mode 100644 index 0000000000..04287211a9 --- /dev/null +++ b/demos/2d/space_shooter/enemy_shot.png diff --git a/demos/2d/space_shooter/enemy_shot.scn b/demos/2d/space_shooter/enemy_shot.scn Binary files differnew file mode 100644 index 0000000000..13f5ae89e5 --- /dev/null +++ b/demos/2d/space_shooter/enemy_shot.scn diff --git a/demos/2d/space_shooter/engine.cfg b/demos/2d/space_shooter/engine.cfg new file mode 100644 index 0000000000..8047cebdd3 --- /dev/null +++ b/demos/2d/space_shooter/engine.cfg @@ -0,0 +1,22 @@ +[application] + +name="Simple Shooter" +main_scene="res://main_menu.scn" +icon="res://icon.png" + +[autoload] + +game_state="res://game_state.gd" + +[display] + +width=1024 +height=600 + +[input] + +move_up=[key(Up)] +move_down=[key(Down)] +move_left=[key(Left)] +move_right=[key(Right)] +shoot=[key(Space)] diff --git a/demos/2d/space_shooter/explosion.scn b/demos/2d/space_shooter/explosion.scn Binary files differnew file mode 100644 index 0000000000..4edcf709cb --- /dev/null +++ b/demos/2d/space_shooter/explosion.scn diff --git a/demos/2d/space_shooter/fire.png b/demos/2d/space_shooter/fire.png Binary files differnew file mode 100644 index 0000000000..1c68c36213 --- /dev/null +++ b/demos/2d/space_shooter/fire.png diff --git a/demos/2d/space_shooter/game_state.gd b/demos/2d/space_shooter/game_state.gd new file mode 100644 index 0000000000..26ef086f14 --- /dev/null +++ b/demos/2d/space_shooter/game_state.gd @@ -0,0 +1,24 @@ +extends Node + + +var points = 0 +var max_points = 0 + + +func _ready(): + var f = File.new() + #load high score + if (f.open("user://highscore",File.READ)==OK): + + max_points=f.get_var() + + + +func game_over(): + if (points>max_points): + max_points=points + #save high score + var f = File.new() + f.open("user://highscore",File.WRITE) + f.store_var(max_points) +
\ No newline at end of file diff --git a/demos/2d/space_shooter/icon.png b/demos/2d/space_shooter/icon.png Binary files differnew file mode 100644 index 0000000000..1df2bf5d9d --- /dev/null +++ b/demos/2d/space_shooter/icon.png diff --git a/demos/2d/space_shooter/level.scn b/demos/2d/space_shooter/level.scn Binary files differnew file mode 100644 index 0000000000..12a679f8b6 --- /dev/null +++ b/demos/2d/space_shooter/level.scn diff --git a/demos/2d/space_shooter/level_tiles.res b/demos/2d/space_shooter/level_tiles.res Binary files differnew file mode 100644 index 0000000000..8712b8c799 --- /dev/null +++ b/demos/2d/space_shooter/level_tiles.res diff --git a/demos/2d/space_shooter/level_tiles.scn b/demos/2d/space_shooter/level_tiles.scn Binary files differnew file mode 100644 index 0000000000..4d1feea70f --- /dev/null +++ b/demos/2d/space_shooter/level_tiles.scn diff --git a/demos/2d/space_shooter/main_menu.gd b/demos/2d/space_shooter/main_menu.gd new file mode 100644 index 0000000000..52221aba1b --- /dev/null +++ b/demos/2d/space_shooter/main_menu.gd @@ -0,0 +1,20 @@ + +extends Control + +# member variables here, example: +# var a=2 +# var b="textvar" + +func _ready(): + + get_node("score").set_text( "HIGH SCORE: "+str( get_node("/root/game_state").max_points ) ) + # Initialization here + pass + + + + +func _on_play_pressed(): + get_node("/root/game_state").points=0 + get_tree().change_scene("res://level.scn") + pass # replace with function body diff --git a/demos/2d/space_shooter/main_menu.scn b/demos/2d/space_shooter/main_menu.scn Binary files differnew file mode 100644 index 0000000000..b87cc5d3a8 --- /dev/null +++ b/demos/2d/space_shooter/main_menu.scn diff --git a/demos/2d/space_shooter/meteorite.png b/demos/2d/space_shooter/meteorite.png Binary files differnew file mode 100644 index 0000000000..92fb4387df --- /dev/null +++ b/demos/2d/space_shooter/meteorite.png diff --git a/demos/2d/space_shooter/parallax.scn b/demos/2d/space_shooter/parallax.scn Binary files differnew file mode 100644 index 0000000000..f67277dc01 --- /dev/null +++ b/demos/2d/space_shooter/parallax.scn diff --git a/demos/2d/space_shooter/rail.gd b/demos/2d/space_shooter/rail.gd new file mode 100644 index 0000000000..803a09fe84 --- /dev/null +++ b/demos/2d/space_shooter/rail.gd @@ -0,0 +1,26 @@ + +extends Node2D + + +const SPEED=200 +# member variables here, example: +# var a=2 +# var b="textvar" + +func stop(): + set_process(false) + +var offset=0 + + +func _process(delta): + + offset+=delta*SPEED + set_pos(Vector2(offset,0)) + +func _ready(): + set_process(true) + # Initialization here + + + diff --git a/demos/2d/space_shooter/ship.gd b/demos/2d/space_shooter/ship.gd new file mode 100644 index 0000000000..fa444868a4 --- /dev/null +++ b/demos/2d/space_shooter/ship.gd @@ -0,0 +1,88 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const SPEED = 200 + +var screen_size + +var prev_shooting=false + +func _process(delta): + + var motion = Vector2() + if Input.is_action_pressed("move_up"): + motion+=Vector2(0,-1) + if Input.is_action_pressed("move_down"): + motion+=Vector2(0,1) + if Input.is_action_pressed("move_left"): + motion+=Vector2(-1,0) + if Input.is_action_pressed("move_right"): + motion+=Vector2(1,0) + var shooting = Input.is_action_pressed("shoot") + + var pos = get_pos() + + pos+=motion*delta*SPEED + if (pos.x<0): + pos.x=0 + if (pos.x>screen_size.x): + pos.x=screen_size.x + if (pos.y<0): + pos.y=0 + if (pos.y>screen_size.y): + pos.y=screen_size.y + + set_pos(pos) + + if (shooting and not prev_shooting): + # just pressed + var shot = preload("res://shot.scn").instance() + #use the position3d as reference + shot.set_pos( get_node("shootfrom").get_global_pos() ) + #put it two parents above, so it is not moved by us + get_node("../..").add_child(shot) + #play sound + get_node("sfx").play("shoot") + + + prev_shooting = shooting + + #update points counter + get_node("../hud/score_points").set_text( str(get_node("/root/game_state").points) ) + +func _ready(): + # Initialization here + screen_size = get_viewport().get_rect().size + set_process(true) + pass + +var killed=false + +func _hit_something(): + if (killed): + return + killed=true + get_node("anim").play("explode") + get_node("sfx").play("sound_explode") + get_node("../hud/game_over").show() + get_node("/root/game_state").game_over() + get_parent().stop() + set_process(false) + + +func _on_ship_body_enter( body ): + _hit_something() + + +func _on_ship_area_enter( area ): + if (area.has_method("is_enemy") and area.is_enemy()): + _hit_something() + + +func _on_back_to_menu_pressed(): + get_tree().change_scene("res://main_menu.scn") + pass # replace with function body diff --git a/demos/2d/space_shooter/ship.png b/demos/2d/space_shooter/ship.png Binary files differnew file mode 100644 index 0000000000..a36b833903 --- /dev/null +++ b/demos/2d/space_shooter/ship.png diff --git a/demos/2d/space_shooter/ship.scn b/demos/2d/space_shooter/ship.scn Binary files differnew file mode 100644 index 0000000000..82c710eda7 --- /dev/null +++ b/demos/2d/space_shooter/ship.scn diff --git a/demos/2d/space_shooter/shoot.png b/demos/2d/space_shooter/shoot.png Binary files differnew file mode 100644 index 0000000000..6e80ddab93 --- /dev/null +++ b/demos/2d/space_shooter/shoot.png diff --git a/demos/2d/space_shooter/shot.gd b/demos/2d/space_shooter/shot.gd new file mode 100644 index 0000000000..813587d670 --- /dev/null +++ b/demos/2d/space_shooter/shot.gd @@ -0,0 +1,47 @@ + +extends Area2D + +# member variables here, example: +# var a=2 +# var b="textvar" + +const SPEED = 800 + +func _process(delta): + translate(Vector2(delta*SPEED,0)) + +func _ready(): + # Initialization here + set_process(true) + pass + +var hit=false + +func _hit_something(): + if (hit): + return + hit=true + set_process(false) + get_node("anim").play("splash") + +func _on_visibility_exit_screen(): + queue_free() + pass # replace with function body + + + +func _on_shot_area_enter( area ): + #hit an enemy or asteroid + if (area.has_method("destroy")): + #duck typing at it's best + area.destroy() + _hit_something() + + + pass + + +func _on_shot_body_enter( body ): + #hit the tilemap + _hit_something() + pass # replace with function body diff --git a/demos/2d/space_shooter/shot.scn b/demos/2d/space_shooter/shot.scn Binary files differnew file mode 100644 index 0000000000..64c8c25ebe --- /dev/null +++ b/demos/2d/space_shooter/shot.scn diff --git a/demos/2d/space_shooter/small_star.png b/demos/2d/space_shooter/small_star.png Binary files differnew file mode 100644 index 0000000000..71c3c531cd --- /dev/null +++ b/demos/2d/space_shooter/small_star.png diff --git a/demos/2d/space_shooter/sound_explode.wav b/demos/2d/space_shooter/sound_explode.wav Binary files differnew file mode 100644 index 0000000000..229c85399c --- /dev/null +++ b/demos/2d/space_shooter/sound_explode.wav diff --git a/demos/2d/space_shooter/sound_shoot.wav b/demos/2d/space_shooter/sound_shoot.wav Binary files differnew file mode 100644 index 0000000000..ad74f328cb --- /dev/null +++ b/demos/2d/space_shooter/sound_shoot.wav diff --git a/demos/2d/space_shooter/tile.png b/demos/2d/space_shooter/tile.png Binary files differnew file mode 100644 index 0000000000..d8f41d16f6 --- /dev/null +++ b/demos/2d/space_shooter/tile.png diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 57ca460979..41721647e2 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -8783,7 +8783,7 @@ </description> </method> <method name="get_undo_redo" > - <return type="Object"> + <return type="UndoRedo"> </return> <description> </description> diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index a588643fd9..efc92c5d9f 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4394,7 +4394,7 @@ void RasterizerGLES2::begin_shadow_map( RID p_light_instance, int p_shadow_pass } -void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection) { +void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint) { camera_transform=p_world; if (current_rt && current_rt_vflip) { @@ -4402,10 +4402,11 @@ void RasterizerGLES2::set_camera(const Transform& p_world,const CameraMatrix& p_ } camera_transform_inverse=camera_transform.inverse(); camera_projection=p_projection; - camera_plane = Plane( camera_transform.origin, camera_transform.basis.get_axis(2) ); + camera_plane = Plane( camera_transform.origin, -camera_transform.basis.get_axis(2) ); camera_z_near=camera_projection.get_z_near(); camera_z_far=camera_projection.get_z_far(); camera_projection.get_viewport_size(camera_vp_size.x,camera_vp_size.y); + camera_ortho=p_ortho_hint; } void RasterizerGLES2::add_light( RID p_light_instance ) { @@ -4768,8 +4769,11 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD e->geometry_cmp=p_geometry_cmp; e->material=m; e->instance=p_instance; - //e->depth=camera_plane.distance_to(p_world->origin); - e->depth=camera_transform.origin.distance_to(p_instance->transform.origin); + if (camera_ortho) { + e->depth=camera_plane.distance_to(p_instance->transform.origin); + } else { + e->depth=camera_transform.origin.distance_to(p_instance->transform.origin); + } e->owner=p_owner; e->light_type=0; e->additive=false; @@ -10796,6 +10800,7 @@ void RasterizerGLES2::init() { current_rt=NULL; current_vd=NULL; current_debug=VS::SCENARIO_DEBUG_DISABLED; + camera_ortho=false; glGenBuffers(1,&gui_quad_buffer); glBindBuffer(GL_ARRAY_BUFFER,gui_quad_buffer); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index e83bd39caa..d337ecfb64 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1052,6 +1052,7 @@ class RasterizerGLES2 : public Rasterizer { float camera_z_near; float camera_z_far; Size2 camera_vp_size; + bool camera_ortho; Set<String> extensions; bool texscreen_copied; bool texscreen_used; @@ -1589,7 +1590,7 @@ public: virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass ); - virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection); + virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint); virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls diff --git a/main/main.cpp b/main/main.cpp index a00538a6ae..15f969f466 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -98,6 +98,9 @@ static int video_driver_idx=-1; static int audio_driver_idx=-1; static String locale; +static bool init_maximized=false; +static int init_screen=-1; + static String unescape_cmdline(const String& p_str) { return p_str.replace("%20"," "); @@ -384,7 +387,7 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas } else if (I->get()=="-e" || I->get()=="-editor") { // fonud editor editor=true; - + init_maximized=true; } else if (I->get()=="-nowindow") { // fullscreen OS::get_singleton()->set_no_window_mode(true); @@ -789,6 +792,13 @@ Error Main::setup2() { show_logo=false; #endif + if (init_screen!=-1) { + OS::get_singleton()->set_current_screen(init_screen); + } + if (init_maximized) { + OS::get_singleton()->set_window_maximized(true); + } + if (show_logo) { //boot logo! String boot_logo_path=GLOBAL_DEF("application/boot_splash",String()); bool boot_logo_scale=GLOBAL_DEF("application/boot_splash_fullsize",true); diff --git a/makerel.bat b/makerel.bat new file mode 100644 index 0000000000..7db76e1dd7 --- /dev/null +++ b/makerel.bat @@ -0,0 +1 @@ +"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" && c:\python27\scons p=windows target=debug_release tools=no diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index f59dbd91d3..0edfd6b9a4 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -1195,7 +1195,7 @@ static void _find_identifiers(GDCompletionContext& context,int p_line,bool p_onl } static const char*_type_names[Variant::VARIANT_MAX]={ - "null","bool","int","float","String","Vector2","Rect2","Vector3","Matrix32","Plane","Quat","AABB","Matrix3","Trasnform", + "null","bool","int","float","String","Vector2","Rect2","Vector3","Matrix32","Plane","Quat","AABB","Matrix3","Transform", "Color","Image","NodePath","RID","Object","InputEvent","Dictionary","Array","RawArray","IntArray","FloatArray","StringArray", "Vector2Array","Vector3Array","ColorArray"}; diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 39f83b806a..40dd0603fb 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -61,7 +61,7 @@ void GridMapEditor::_menu_option(int p_option) { case MENU_OPTION_CONFIGURE: { - + } break; case MENU_OPTION_LOCK_VIEW: { @@ -706,9 +706,40 @@ struct _CGMEItemSort { }; +void GridMapEditor::_set_display_mode(int p_mode) { + if (display_mode==p_mode) { + return; + } + + if (p_mode == DISPLAY_LIST) { + mode_list->set_pressed(true); + mode_thumbnail->set_pressed(false); + } else if (p_mode == DISPLAY_THUMBNAIL) { + mode_list->set_pressed(false); + mode_thumbnail->set_pressed(true); + } + + display_mode=p_mode; + + update_pallete(); +} + void GridMapEditor::update_pallete() { + int selected = theme_pallete->get_current(); theme_pallete->clear(); + if (display_mode == DISPLAY_THUMBNAIL) { + theme_pallete->set_max_columns(0); + theme_pallete->set_icon_mode(ItemList::ICON_MODE_TOP); + } else if (display_mode == DISPLAY_LIST){ + theme_pallete->set_max_columns(1); + theme_pallete->set_icon_mode(ItemList::ICON_MODE_LEFT); + } + + float min_size = EDITOR_DEF("grid_map/preview_size",64); + theme_pallete->set_min_icon_size(Size2(min_size, min_size)); + theme_pallete->set_fixed_column_width(min_size*3/2); + theme_pallete->set_max_text_lines(2); Ref<MeshLibrary> theme = node->get_theme(); @@ -720,10 +751,6 @@ void GridMapEditor::update_pallete() { Vector<int> ids; ids = theme->get_item_list(); - TreeItem *root = theme_pallete->create_item(NULL); - theme_pallete->set_hide_root(true); - TreeItem *selected=NULL; - List<_CGMEItemSort> il; for(int i=0;i<ids.size();i++) { @@ -734,45 +761,31 @@ void GridMapEditor::update_pallete() { } il.sort(); - int col=0; - TreeItem *ti=NULL; - int selected_col=0; + int item = 0; for(List<_CGMEItemSort>::Element *E=il.front();E;E=E->next()) { - int id = E->get().id; - if (col==0) { - ti = theme_pallete->create_item(root); - } + theme_pallete->add_item(""); String name=theme->get_item_name(id); Ref<Texture> preview = theme->get_item_preview(id); if (!preview.is_null()) { - - ti->set_cell_mode(col,TreeItem::CELL_MODE_ICON); - ti->set_icon(col,preview); - ti->set_tooltip(col,name); - } else { - - ti->set_text(col,name); + theme_pallete->set_item_icon(item, preview); + theme_pallete->set_item_tooltip(item, name); } - ti->set_metadata(col,id); - - if (selected_pallete==id) { - selected=ti; - selected_col=col; + if (name!="") { + theme_pallete->set_item_text(item,name); } + theme_pallete->set_item_metadata(item, id); - col++; - if (col==theme_pallete->get_columns()) - col=0; - + item++; } - if (selected) - selected->select(selected_col); + if (selected!=-1) { + theme_pallete->select(selected); + } last_theme=theme.operator->(); } @@ -842,6 +855,9 @@ void GridMapEditor::edit(GridMap *p_gridmap) { VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_VISIBLE,false); } + + VisualServer::get_singleton()->instance_geometry_set_flag(cursor_instance, VS::INSTANCE_FLAG_VISIBLE,false); + _clear_areas(); return; @@ -951,7 +967,7 @@ void GridMapEditor::update_grid() { grid_xform.origin.x-=1; //force update in hackish way.. what do i care - VS *vs = VS::get_singleton(); + //VS *vs = VS::get_singleton(); grid_ofs[edit_axis]=edit_floor[edit_axis]*node->get_cell_size(); @@ -976,7 +992,7 @@ void GridMapEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { - theme_pallete->connect("cell_selected", this,"_item_selected_cbk"); + theme_pallete->connect("item_selected", this,"_item_selected_cbk"); edit_mode->connect("item_selected", this,"_edit_mode_changed"); area_list->connect("item_edited", this,"_area_renamed"); area_list->connect("item_selected", this,"_area_selected"); @@ -1014,7 +1030,7 @@ void GridMapEditor::_notification(int p_what) { if (xf!=grid_xform) { for(int i=0;i<3;i++) { - + VS::get_singleton()->instance_set_transform(grid_instance[i],xf * edit_grid_xform); } grid_xform=xf; @@ -1063,18 +1079,8 @@ void GridMapEditor::_update_cursor_instance() { } -void GridMapEditor::_item_selected_cbk() { - - TreeItem *it = theme_pallete->get_selected(); - if (it) { - - selected_pallete=it->get_metadata(theme_pallete->get_selected_column()); - - } else { - - selected_pallete=-1; - - } +void GridMapEditor::_item_selected_cbk(int idx) { + selected_pallete=theme_pallete->get_item_metadata(idx); _update_cursor_instance(); @@ -1179,7 +1185,7 @@ void GridMapEditor::_bind_methods() { ObjectTypeDB::bind_method("_area_selected",&GridMapEditor::_area_selected); ObjectTypeDB::bind_method("_floor_changed",&GridMapEditor::_floor_changed); - + ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"), &GridMapEditor::_set_display_mode); } @@ -1240,6 +1246,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { clip_mode=CLIP_DISABLED; options->get_popup()->connect("item_pressed", this,"_menu_option"); + HBoxContainer *hb = memnew( HBoxContainer ); + add_child(hb); + hb->set_h_size_flags(SIZE_EXPAND_FILL); edit_mode = memnew(OptionButton); edit_mode->set_area_as_parent_rect(); @@ -1247,13 +1256,27 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { edit_mode->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,14);; edit_mode->add_item("Tiles"); edit_mode->add_item("Areas"); - add_child(edit_mode); - + hb->add_child(edit_mode); + edit_mode->set_h_size_flags(SIZE_EXPAND_FILL); + + mode_thumbnail = memnew( ToolButton ); + mode_thumbnail->set_toggle_mode(true); + mode_thumbnail->set_pressed(true); + mode_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons")); + hb->add_child(mode_thumbnail); + mode_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL)); + + mode_list = memnew( ToolButton ); + mode_list->set_toggle_mode(true); + mode_list->set_pressed(false); + mode_list->set_icon(p_editor->get_gui_base()->get_icon("FileList", "EditorIcons")); + hb->add_child(mode_list); + mode_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST)); + + display_mode = DISPLAY_THUMBNAIL; selected_area=-1; - - theme_pallete = memnew( Tree ); - theme_pallete->set_columns(3); + theme_pallete = memnew( ItemList ); add_child(theme_pallete); theme_pallete->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 716ef66f0d..26fe8f20dc 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -40,10 +40,8 @@ class SpatialEditorPlugin; class GridMapEditor : public VBoxContainer { - OBJ_TYPE(GridMapEditor, VBoxContainer ); - enum { GRID_CURSOR_SIZE=50 @@ -66,6 +64,10 @@ class GridMapEditor : public VBoxContainer { CLIP_BELOW }; + enum DisplayMode { + DISPLAY_THUMBNAIL, + DISPLAY_LIST + }; UndoRedo *undo_redo; InputAction input_action; @@ -73,6 +75,8 @@ class GridMapEditor : public VBoxContainer { MenuButton * options; SpinBox *floor; OptionButton *edit_mode; + ToolButton *mode_thumbnail; + ToolButton *mode_list; HBoxContainer *spatial_editor_hb; struct SetItem { @@ -132,6 +136,7 @@ class GridMapEditor : public VBoxContainer { Vector3 cursor_origin; Vector3 last_mouseover; + int display_mode; int selected_pallete; int selected_area; int cursor_rot; @@ -183,9 +188,10 @@ class GridMapEditor : public VBoxContainer { void _configure(); void _menu_option(int); void update_pallete(); - Tree *theme_pallete; + void _set_display_mode(int p_mode); + ItemList *theme_pallete; Tree *area_list; - void _item_selected_cbk(); + void _item_selected_cbk(int idx); void _update_cursor_transform(); void _update_cursor_instance(); void _update_clip(); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 85714c46bb..ff85e286db 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -111,9 +111,9 @@ def configure(env): if (env["target"]=="release"): if (env["debug_release"]=="yes"): - env.Append(CCFLAGS=['-g2','-fomit-frame-pointer']) + env.Append(CCFLAGS=['-g2']) else: - env.Append(CCFLAGS=['-O2','-ffast-math','-fomit-frame-pointer']) + env.Append(CCFLAGS=['-O3','-ffast-math']) elif (env["target"]=="release_debug"): diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index b49426f7e2..e350a34013 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -149,11 +149,11 @@ void AnimatedSprite::_notification(int p_what) { Size2i s; s = texture->get_size(); - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; - Rect2i dst_rect(ofs,s); + Rect2 dst_rect(ofs,s); if (hflip) dst_rect.size.x=-dst_rect.size.x; @@ -284,7 +284,7 @@ Rect2 AnimatedSprite::get_item_rect() const { return Node2D::get_item_rect(); Size2i s = t->get_size(); - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 70b88a6611..49683da226 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -81,43 +81,47 @@ Matrix32 Camera2D::get_camera_transform() { if (!first) { - if (centered) { + if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) { - if (h_drag_enabled) { - camera_pos.x = MIN( camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT])); - camera_pos.x = MAX( camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * drag_margin[MARGIN_LEFT])); - } else { + if (h_drag_enabled) { + camera_pos.x = MIN( camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT])); + camera_pos.x = MAX( camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * drag_margin[MARGIN_LEFT])); + } else { - if (h_ofs<0) { - camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs; - } else { - camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs; - } - } + if (h_ofs<0) { + camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs; + } else { + camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs; + } + } + + if (v_drag_enabled) { - if (v_drag_enabled) { + camera_pos.y = MIN( camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM])); + camera_pos.y = MAX( camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * drag_margin[MARGIN_TOP])); - camera_pos.y = MIN( camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM])); - camera_pos.y = MAX( camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * drag_margin[MARGIN_TOP])); + } else { - } else { + if (v_ofs<0) { + camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; + } else { + camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; + } + } - if (v_ofs<0) { - camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; - } else { - camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; - } - } + } else if (anchor_mode==ANCHOR_MODE_FIXED_TOP_LEFT){ + camera_pos=new_camera_pos; } + if (smoothing>0.0) { float c = smoothing*get_fixed_process_delta_time(); smoothed_camera_pos = ((new_camera_pos-smoothed_camera_pos)*c)+smoothed_camera_pos; ret_camera_pos=smoothed_camera_pos; -// camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; + // camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; } else { ret_camera_pos=smoothed_camera_pos=camera_pos; @@ -132,7 +136,7 @@ Matrix32 Camera2D::get_camera_transform() { } - Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2()); + Point2 screen_offset = (anchor_mode==ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); float angle = get_global_transform().get_rotation(); if(rotating){ @@ -267,15 +271,15 @@ Vector2 Camera2D::get_offset() const{ return offset; } -void Camera2D::set_centered(bool p_centered){ +void Camera2D::set_anchor_mode(AnchorMode p_anchor_mode){ - centered=p_centered; + anchor_mode=p_anchor_mode; _update_scroll(); } -bool Camera2D::is_centered() const { +Camera2D::AnchorMode Camera2D::get_anchor_mode() const { - return centered; + return anchor_mode; } void Camera2D::set_rotating(bool p_rotating){ @@ -439,8 +443,8 @@ void Camera2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_offset","offset"),&Camera2D::set_offset); ObjectTypeDB::bind_method(_MD("get_offset"),&Camera2D::get_offset); - ObjectTypeDB::bind_method(_MD("set_centered","centered"),&Camera2D::set_centered); - ObjectTypeDB::bind_method(_MD("is_centered"),&Camera2D::is_centered); + ObjectTypeDB::bind_method(_MD("set_anchor_mode","anchor_mode"),&Camera2D::set_anchor_mode); + ObjectTypeDB::bind_method(_MD("get_anchor_mode"),&Camera2D::get_anchor_mode); ObjectTypeDB::bind_method(_MD("set_rotating","rotating"),&Camera2D::set_rotating); ObjectTypeDB::bind_method(_MD("is_rotating"),&Camera2D::is_rotating); @@ -487,7 +491,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTYNZ( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_offset"),_SCS("get_offset")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"centered"),_SCS("set_centered"),_SCS("is_centered")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"anchor_mode",PROPERTY_HINT_ENUM,"Fixed TopLeft,Drag Center"),_SCS("set_anchor_mode"),_SCS("get_anchor_mode")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"rotating"),_SCS("set_rotating"),_SCS("is_rotating")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"current"),_SCS("_set_current"),_SCS("is_current")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"smoothing"),_SCS("set_follow_smoothing"),_SCS("get_follow_smoothing") ); @@ -507,6 +511,8 @@ void Camera2D::_bind_methods() { ADD_PROPERTYI( PropertyInfo(Variant::REAL,"drag_margin/bottom",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_drag_margin"),_SCS("get_drag_margin"),MARGIN_BOTTOM); + BIND_CONSTANT( ANCHOR_MODE_DRAG_CENTER ); + BIND_CONSTANT( ANCHOR_MODE_FIXED_TOP_LEFT ); } @@ -514,7 +520,7 @@ Camera2D::Camera2D() { - centered=true; + anchor_mode=ANCHOR_MODE_DRAG_CENTER; rotating=false; current=false; limit[MARGIN_LEFT]=-10000000; diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 8975a2584b..79d84f48d0 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -36,6 +36,12 @@ class Camera2D : public Node2D { OBJ_TYPE( Camera2D, Node2D ); +public: + + enum AnchorMode { + ANCHOR_MODE_FIXED_TOP_LEFT, + ANCHOR_MODE_DRAG_CENTER + }; protected: Point2 camera_pos; @@ -49,7 +55,7 @@ protected: RID canvas; Vector2 offset; Vector2 zoom; - bool centered; + AnchorMode anchor_mode; bool rotating; bool current; float smoothing; @@ -77,8 +83,8 @@ public: void set_offset(const Vector2& p_offset); Vector2 get_offset() const; - void set_centered(bool p_centered); - bool is_centered() const; + void set_anchor_mode(AnchorMode p_anchor_mode); + AnchorMode get_anchor_mode() const; void set_rotating(bool p_rotating); bool is_rotating() const; @@ -120,4 +126,6 @@ public: Camera2D(); }; +VARIANT_ENUM_CAST(Camera2D::AnchorMode); + #endif // CAMERA_2D_H diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 067b4794b4..0485033691 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -82,7 +82,7 @@ void Sprite::_notification(int p_what) { } - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; @@ -265,7 +265,7 @@ Rect2 Sprite::get_item_rect() const { s=s/Point2(hframes,vframes); } - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; @@ -413,11 +413,11 @@ void ViewportSprite::_notification(int p_what) { src_rect.size=s; - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; - Rect2i dst_rect(ofs,s); + Rect2 dst_rect(ofs,s); texture->draw_rect_region(ci,dst_rect,src_rect,modulate); } break; @@ -505,7 +505,7 @@ Rect2 ViewportSprite::get_item_rect() const { Size2i s; s = texture->get_size(); - Point2i ofs=offset; + Point2 ofs=offset; if (centered) ofs-=s/2; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index ea4b1fc7b0..dc72c9a267 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -155,6 +155,11 @@ void VisibilityEnabler2D::_screen_enter() { _change_node_state(E->key(),true); } + if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent()) + get_parent()->set_fixed_process(true); + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + get_parent()->set_process(true); + visible=true; } @@ -165,6 +170,11 @@ void VisibilityEnabler2D::_screen_exit(){ _change_node_state(E->key(),false); } + if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent()) + get_parent()->set_fixed_process(false); + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + get_parent()->set_process(false); + visible=false; } @@ -235,6 +245,12 @@ void VisibilityEnabler2D::_notification(int p_what){ _find_nodes(from); + if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent()) + get_parent()->set_fixed_process(false); + if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) + get_parent()->set_process(false); + + } if (p_what==NOTIFICATION_EXIT_TREE) { @@ -317,10 +333,14 @@ void VisibilityEnabler2D::_bind_methods(){ ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_animations"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_ANIMATIONS ); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/freeze_bodies"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_FREEZE_BODIES); ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_particles"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_PARTICLES); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/process_parent"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PARENT_PROCESS); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/fixed_process_parent"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PARENT_FIXED_PROCESS); BIND_CONSTANT( ENABLER_FREEZE_BODIES ); BIND_CONSTANT( ENABLER_PAUSE_ANIMATIONS ); BIND_CONSTANT( ENABLER_PAUSE_PARTICLES ); + BIND_CONSTANT( ENABLER_PARENT_PROCESS ); + BIND_CONSTANT( ENABLER_PARENT_FIXED_PROCESS ); BIND_CONSTANT( ENABLER_MAX); } @@ -341,6 +361,8 @@ VisibilityEnabler2D::VisibilityEnabler2D() { for(int i=0;i<ENABLER_MAX;i++) enabler[i]=true; + enabler[ENABLER_PARENT_PROCESS]=false; + enabler[ENABLER_PARENT_FIXED_PROCESS]=false; visible=false; diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index ce68724630..1f7e4c6d45 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -74,6 +74,8 @@ public: ENABLER_PAUSE_ANIMATIONS, ENABLER_FREEZE_BODIES, ENABLER_PAUSE_PARTICLES, + ENABLER_PARENT_PROCESS, + ENABLER_PARENT_FIXED_PROCESS, ENABLER_MAX }; diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index 76527c72e6..a00946a07a 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -225,27 +225,56 @@ void Area::_clear_monitoring() { } ERR_FAIL_COND(locked); - Map<ObjectID,BodyState> bmcopy = body_map; - body_map.clear(); - //disconnect all monitored stuff + { + Map<ObjectID,BodyState> bmcopy = body_map; + body_map.clear(); + //disconnect all monitored stuff - for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) { + for (Map<ObjectID,BodyState>::Element *E=bmcopy.front();E;E=E->next()) { - Object *obj = ObjectDB::get_instance(E->key()); - Node *node = obj ? obj->cast_to<Node>() : NULL; - ERR_CONTINUE(!node); - if (!E->get().in_tree) - continue; + Object *obj = ObjectDB::get_instance(E->key()); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_CONTINUE(!node); + if (!E->get().in_tree) + continue; + + for(int i=0;i<E->get().shapes.size();i++) { - for(int i=0;i<E->get().shapes.size();i++) { + emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape); + } - emit_signal(SceneStringNames::get_singleton()->body_exit_shape,E->key(),node,E->get().shapes[i].body_shape,E->get().shapes[i].area_shape); + emit_signal(SceneStringNames::get_singleton()->body_exit,obj); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree); } - emit_signal(SceneStringNames::get_singleton()->body_exit,obj); + } + + { + + Map<ObjectID,AreaState> bmcopy = area_map; + area_map.clear(); + //disconnect all monitored stuff + + for (Map<ObjectID,AreaState>::Element *E=bmcopy.front();E;E=E->next()) { + + Object *obj = ObjectDB::get_instance(E->key()); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_CONTINUE(!node); + if (!E->get().in_tree) + continue; + + for(int i=0;i<E->get().shapes.size();i++) { - node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_body_enter_tree); - node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_body_exit_tree); + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,E->key(),node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); + } + + emit_signal(SceneStringNames::get_singleton()->area_exit,obj); + + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree); + } } } @@ -271,10 +300,127 @@ void Area::set_enable_monitoring(bool p_enable) { if (monitoring) { PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),this,"_body_inout"); + PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),this,"_area_inout"); } else { PhysicsServer::get_singleton()->area_set_monitor_callback(get_rid(),NULL,StringName()); + PhysicsServer::get_singleton()->area_set_area_monitor_callback(get_rid(),NULL,StringName()); _clear_monitoring(); + + } +} + + +void Area::_area_enter_tree(ObjectID p_id) { + + Object *obj = ObjectDB::get_instance(p_id); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_FAIL_COND(!node); + + Map<ObjectID,AreaState>::Element *E=area_map.find(p_id); + ERR_FAIL_COND(!E); + ERR_FAIL_COND(E->get().in_tree); + + E->get().in_tree=true; + emit_signal(SceneStringNames::get_singleton()->area_enter,node); + for(int i=0;i<E->get().shapes.size();i++) { + + emit_signal(SceneStringNames::get_singleton()->area_enter_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); + } + +} + +void Area::_area_exit_tree(ObjectID p_id) { + + Object *obj = ObjectDB::get_instance(p_id); + Node *node = obj ? obj->cast_to<Node>() : NULL; + ERR_FAIL_COND(!node); + Map<ObjectID,AreaState>::Element *E=area_map.find(p_id); + ERR_FAIL_COND(!E); + ERR_FAIL_COND(!E->get().in_tree); + E->get().in_tree=false; + emit_signal(SceneStringNames::get_singleton()->area_exit,node); + for(int i=0;i<E->get().shapes.size();i++) { + + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,p_id,node,E->get().shapes[i].area_shape,E->get().shapes[i].self_shape); } + +} + +void Area::_area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape) { + + + bool area_in = p_status==PhysicsServer::AREA_BODY_ADDED; + ObjectID objid=p_instance; + + Object *obj = ObjectDB::get_instance(objid); + Node *node = obj ? obj->cast_to<Node>() : NULL; + + Map<ObjectID,AreaState>::Element *E=area_map.find(objid); + + ERR_FAIL_COND(!area_in && !E); + + locked=true; + + if (area_in) { + if (!E) { + + E = area_map.insert(objid,AreaState()); + E->get().rc=0; + E->get().in_tree=node && node->is_inside_tree(); + if (node) { + node->connect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree,make_binds(objid)); + node->connect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree,make_binds(objid)); + if (E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_enter,node); + + } + } + + } + E->get().rc++; + if (node) + E->get().shapes.insert(AreaShapePair(p_area_shape,p_self_shape)); + + + if (!node || E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_enter_shape,objid,node,p_area_shape,p_self_shape); + } + + } else { + + E->get().rc--; + + if (node) + E->get().shapes.erase(AreaShapePair(p_area_shape,p_self_shape)); + + bool eraseit=false; + + if (E->get().rc==0) { + + if (node) { + node->disconnect(SceneStringNames::get_singleton()->enter_tree,this,SceneStringNames::get_singleton()->_area_enter_tree); + node->disconnect(SceneStringNames::get_singleton()->exit_tree,this,SceneStringNames::get_singleton()->_area_exit_tree); + if (E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_exit,obj); + } + + } + + eraseit=true; + + } + if (!node || E->get().in_tree) { + emit_signal(SceneStringNames::get_singleton()->area_exit_shape,objid,obj,p_area_shape,p_self_shape); + } + + if (eraseit) + area_map.erase(E); + + } + + locked=false; + + } bool Area::is_monitoring_enabled() const { @@ -302,11 +448,76 @@ Array Area::get_overlapping_bodies() const { return ret; } +void Area::set_monitorable(bool p_enable) { + + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); + + if (p_enable==monitorable) + return; + + monitorable=p_enable; + + PhysicsServer::get_singleton()->area_set_monitorable(get_rid(),monitorable); +} + +bool Area::is_monitorable() const { + + return monitorable; +} + + +Array Area::get_overlapping_areas() const { + + ERR_FAIL_COND_V(!monitoring,Array()); + Array ret; + ret.resize(area_map.size()); + int idx=0; + for (const Map<ObjectID,AreaState>::Element *E=area_map.front();E;E=E->next()) { + Object *obj = ObjectDB::get_instance(E->key()); + if (!obj) { + ret.resize( ret.size() -1 ); //ops + } else { + ret[idx++]=obj; + } + + } + + return ret; +} + +bool Area::overlaps_area(Node* p_area) const { + + ERR_FAIL_NULL_V(p_area,false); + const Map<ObjectID,AreaState>::Element *E=area_map.find(p_area->get_instance_ID()); + if (!E) + return false; + return E->get().in_tree; + + + +} + +bool Area::overlaps_body(Node* p_body) const{ + + ERR_FAIL_NULL_V(p_body,false); + const Map<ObjectID,BodyState>::Element *E=body_map.find(p_body->get_instance_ID()); + if (!E) + return false; + return E->get().in_tree; + +} + void Area::_bind_methods() { ObjectTypeDB::bind_method(_MD("_body_enter_tree","id"),&Area::_body_enter_tree); ObjectTypeDB::bind_method(_MD("_body_exit_tree","id"),&Area::_body_exit_tree); + ObjectTypeDB::bind_method(_MD("_area_enter_tree","id"),&Area::_area_enter_tree); + ObjectTypeDB::bind_method(_MD("_area_exit_tree","id"),&Area::_area_exit_tree); + ObjectTypeDB::bind_method(_MD("set_space_override_mode","enable"),&Area::set_space_override_mode); ObjectTypeDB::bind_method(_MD("get_space_override_mode"),&Area::get_space_override_mode); @@ -328,13 +539,21 @@ void Area::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority); + ObjectTypeDB::bind_method(_MD("set_monitorable","enable"),&Area::set_monitorable); + ObjectTypeDB::bind_method(_MD("is_monitorable"),&Area::is_monitorable); + ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled); ObjectTypeDB::bind_method(_MD("get_overlapping_bodies"),&Area::get_overlapping_bodies); + ObjectTypeDB::bind_method(_MD("get_overlapping_areas"),&Area::get_overlapping_areas); + + ObjectTypeDB::bind_method(_MD("overlaps_body:PhysicsBody","body"),&Area::overlaps_body); + ObjectTypeDB::bind_method(_MD("overlaps_area:Area","area"),&Area::overlaps_area); ObjectTypeDB::bind_method(_MD("_body_inout"),&Area::_body_inout); + ObjectTypeDB::bind_method(_MD("_area_inout"),&Area::_area_inout); ADD_SIGNAL( MethodInfo("body_enter_shape",PropertyInfo(Variant::INT,"body_id"),PropertyInfo(Variant::OBJECT,"body"),PropertyInfo(Variant::INT,"body_shape"),PropertyInfo(Variant::INT,"area_shape"))); @@ -342,6 +561,11 @@ void Area::_bind_methods() { ADD_SIGNAL( MethodInfo("body_enter",PropertyInfo(Variant::OBJECT,"body"))); ADD_SIGNAL( MethodInfo("body_exit",PropertyInfo(Variant::OBJECT,"body"))); + ADD_SIGNAL( MethodInfo("area_enter_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("area_exit_shape",PropertyInfo(Variant::INT,"area_id"),PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"),PropertyInfo(Variant::INT,"area_shape"),PropertyInfo(Variant::INT,"area_shape"))); + ADD_SIGNAL( MethodInfo("area_enter",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"))); + ADD_SIGNAL( MethodInfo("area_exit",PropertyInfo(Variant::OBJECT,"area",PROPERTY_HINT_RESOURCE_TYPE,"Area"))); + ADD_PROPERTY( PropertyInfo(Variant::INT,"space_override",PROPERTY_HINT_ENUM,"Disabled,Combine,Replace"),_SCS("set_space_override_mode"),_SCS("get_space_override_mode")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"gravity_point"),_SCS("set_gravity_is_point"),_SCS("is_gravity_a_point")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"gravity_distance_scale", PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_gravity_distance_scale"),_SCS("get_gravity_distance_scale")); @@ -350,6 +574,7 @@ void Area::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density")); ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitorable"),_SCS("set_monitorable"),_SCS("is_monitorable")); } @@ -366,6 +591,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru monitoring=false; set_ray_pickable(false); set_enable_monitoring(true); + set_monitorable(true); } diff --git a/scene/3d/area.h b/scene/3d/area.h index fb853092f3..fa7500c47c 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -53,6 +53,7 @@ private: real_t density; int priority; bool monitoring; + bool monitorable; bool locked; @@ -84,6 +85,36 @@ private: }; Map<ObjectID,BodyState> body_map; + + + void _area_inout(int p_status,const RID& p_area, int p_instance, int p_area_shape,int p_self_shape); + + void _area_enter_tree(ObjectID p_id); + void _area_exit_tree(ObjectID p_id); + + struct AreaShapePair { + + int area_shape; + int self_shape; + bool operator<(const AreaShapePair& p_sp) const { + if (area_shape==p_sp.area_shape) + return self_shape < p_sp.self_shape; + else + return area_shape < p_sp.area_shape; + } + + AreaShapePair() {} + AreaShapePair(int p_bs, int p_as) { area_shape=p_bs; self_shape=p_as; } + }; + + struct AreaState { + + int rc; + bool in_tree; + VSet<AreaShapePair> shapes; + }; + + Map<ObjectID,AreaState> area_map; void _clear_monitoring(); @@ -117,7 +148,14 @@ public: void set_enable_monitoring(bool p_enable); bool is_monitoring_enabled() const; + void set_monitorable(bool p_enable); + bool is_monitorable() const; + Array get_overlapping_bodies() const; + Array get_overlapping_areas() const; //function for script + + bool overlaps_area(Node* p_area) const; + bool overlaps_body(Node* p_body) const; Area(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 22559c238c..2367c03e99 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -548,15 +548,18 @@ void Control::_notification(int p_notification) { Control * parent = get_parent()->cast_to<Control>(); //make children reference them theme - if (parent && data.theme.is_null() && parent->data.theme_owner) + + if (parent && data.theme.is_null() && parent->data.theme_owner) { _propagate_theme_changed(parent->data.theme_owner); + } } break; case NOTIFICATION_UNPARENTED: { //make children unreference the theme - if (data.theme.is_null() && data.theme_owner) + if (data.theme.is_null() && data.theme_owner) { _propagate_theme_changed(NULL); + } } break; case NOTIFICATION_MOVED_IN_PARENT: { diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 2fd4d810de..c29f6625d3 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -11,6 +11,7 @@ void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool item.selectable=p_selectable; item.selected=false; item.disabled=false; + item.custom_bg=Color(0,0,0,0); items.push_back(item); update(); @@ -26,6 +27,7 @@ void ItemList::add_icon_item(const Ref<Texture>& p_item,bool p_selectable){ item.selectable=p_selectable; item.selected=false; item.disabled=false; + item.custom_bg=Color(0,0,0,0); items.push_back(item); update(); @@ -85,6 +87,23 @@ Ref<Texture> ItemList::get_item_icon(int p_idx) const{ } +void ItemList::set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color) { + + ERR_FAIL_INDEX(p_idx,items.size()); + + items[p_idx].custom_bg=p_custom_bg_color; + +} + +Color ItemList::get_item_custom_bg_color(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,items.size(),Color()); + + return items[p_idx].custom_bg; + +} + + void ItemList::set_item_tag_icon(int p_idx,const Ref<Texture>& p_tag_icon){ @@ -635,6 +654,7 @@ void ItemList::_notification(int p_what) { Ref<Font> font = get_font("font"); Color guide_color = get_color("guide_color"); Color font_color = get_color("font_color"); + Color font_color_selected = get_color("font_color_selected"); int font_height = font->get_height(); Vector<int> line_size_cache; Vector<int> line_limit_cache; @@ -781,6 +801,11 @@ void ItemList::_notification(int p_what) { if (current_columns==1) { rcache.size.width = width-rcache.pos.x; } + if (items[i].custom_bg.a>0.001) { + Rect2 r=rcache; + r.pos+=base_ofs; + draw_rect(r,items[i].custom_bg); + } if (items[i].selected) { Rect2 r=rcache; r.pos+=base_ofs; @@ -864,7 +889,7 @@ void ItemList::_notification(int p_what) { if (line>=max_text_lines) break; } - ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],font_color); + ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],items[i].selected?font_color_selected:font_color); } //special multiline mode @@ -884,7 +909,7 @@ void ItemList::_notification(int p_what) { text_ofs+=base_ofs; text_ofs+=items[i].rect_cache.pos; - draw_string(font,text_ofs,items[i].text,font_color,max_len+1); + draw_string(font,text_ofs,items[i].text,items[i].selected?font_color_selected:font_color,max_len+1); } @@ -954,6 +979,30 @@ String ItemList::get_tooltip(const Point2& p_pos) const { } +void ItemList::sort_items_by_text() { + items.sort(); + update(); + if (select_mode==SELECT_SINGLE) { + for(int i=0;i<items.size();i++) { + if (items[i].selected) { + select(i); + return; + } + } + } +} + +int ItemList::find_metadata(const Variant& p_metadata) const { + + for(int i=0;i<items.size();i++) { + if (items[i].metadata==p_metadata) { + return i; + } + } + + return -1; + +} void ItemList::_bind_methods(){ @@ -972,6 +1021,12 @@ void ItemList::_bind_methods(){ ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&ItemList::set_item_disabled); ObjectTypeDB::bind_method(_MD("is_item_disabled","idx"),&ItemList::is_item_disabled); + ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&ItemList::set_item_metadata); + ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&ItemList::get_item_metadata); + + ObjectTypeDB::bind_method(_MD("set_item_custom_bg_color","idx","custom_bg_color"),&ItemList::set_item_custom_bg_color); + ObjectTypeDB::bind_method(_MD("get_item_custom_bg_color","idx"),&ItemList::get_item_custom_bg_color); + ObjectTypeDB::bind_method(_MD("set_item_tooltip","idx","tooltip"),&ItemList::set_item_tooltip); ObjectTypeDB::bind_method(_MD("get_item_tooltip","idx"),&ItemList::get_item_tooltip); @@ -983,6 +1038,7 @@ void ItemList::_bind_methods(){ ObjectTypeDB::bind_method(_MD("remove_item","idx"),&ItemList::remove_item); ObjectTypeDB::bind_method(_MD("clear"),&ItemList::clear); + ObjectTypeDB::bind_method(_MD("sort_items_by_text"),&ItemList::clear); ObjectTypeDB::bind_method(_MD("set_fixed_column_width","width"),&ItemList::set_fixed_column_width); ObjectTypeDB::bind_method(_MD("get_fixed_column_width"),&ItemList::get_fixed_column_width); diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 6bbb416970..237079c428 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -29,8 +29,12 @@ private: bool disabled; Variant metadata; String tooltip; + Color custom_bg; + Rect2 rect_cache; + + bool operator<(const Item& p_another) const { return text<p_another.text; } }; int current; @@ -85,6 +89,9 @@ public: void set_item_tooltip(int p_idx,const String& p_tooltip); String get_item_tooltip(int p_idx) const; + void set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color); + Color get_item_custom_bg_color(int p_idx) const; + void select(int p_idx,bool p_single=true); void unselect(int p_idx); bool is_selected(int p_idx) const; @@ -118,6 +125,8 @@ public: void ensure_current_is_visible(); + void sort_items_by_text(); + int find_metadata(const Variant& p_metadata) const; virtual String get_tooltip(const Point2& p_pos) const; diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index c73af74426..5ce7e2e0d3 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -84,6 +84,48 @@ void Popup::_fix_size() { } +void Popup::set_as_minsize() { + + Size2 total_minsize; + + for(int i=0;i<get_child_count();i++) { + + Control *c=get_child(i)->cast_to<Control>(); + if (!c) + continue; + if (c->is_hidden()) + continue; + + Size2 minsize = c->get_combined_minimum_size(); + + for(int j=0;j<2;j++) { + + Margin m_beg = Margin(0+j); + Margin m_end = Margin(2+j); + + float margin_begin = c->get_margin(m_beg); + float margin_end = c->get_margin(m_end); + AnchorType anchor_begin = c->get_anchor(m_beg); + AnchorType anchor_end = c->get_anchor(m_end); + + if (anchor_begin == ANCHOR_BEGIN) + minsize[j]+=margin_begin; + if (anchor_end == ANCHOR_END) + minsize[j]+=margin_end; + + } + + 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 ); + } + + set_size(total_minsize); + +} + + void Popup::popup_centered_minsize(const Size2& p_minsize) { diff --git a/scene/gui/popup.h b/scene/gui/popup.h index c2de6c8cf7..6c72a3c82b 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -62,6 +62,7 @@ public: void popup_centered_ratio(float p_screen_ratio=0.75); void popup_centered(const Size2& p_size=Size2()); void popup_centered_minsize(const Size2& p_minsize=Size2()); + void set_as_minsize(); virtual void popup(); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index d02c833be9..d7ee7a6b86 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -345,6 +345,7 @@ void SplitContainer::_input_event(const InputEvent& p_event) { expand_ofs=drag_ofs+((vertical?mm.y:mm.x)-drag_from); queue_sort(); + emit_signal("dragged",get_split_offset()); } } @@ -431,11 +432,13 @@ void SplitContainer::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_dragger_visible","visible"),&SplitContainer::set_dragger_visible); ObjectTypeDB::bind_method(_MD("is_dragger_visible"),&SplitContainer::is_dragger_visible); + ADD_SIGNAL( MethodInfo("dragged",PropertyInfo(Variant::INT,"offset"))); ADD_PROPERTY( PropertyInfo(Variant::INT,"split/offset"),_SCS("set_split_offset"),_SCS("get_split_offset")); ADD_PROPERTY( PropertyInfo(Variant::INT,"split/collapsed"),_SCS("set_collapsed"),_SCS("is_collapsed")); ADD_PROPERTY( PropertyInfo(Variant::INT,"split/dragger_visible"),_SCS("set_dragger_visible"),_SCS("is_dragger_visible")); + } SplitContainer::SplitContainer(bool p_vertical) { diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 1db4998a27..3ed182c017 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -88,7 +88,22 @@ void TabContainer::_input_event(const InputEvent& p_event) { Ref<Font> font = get_font("font"); Ref<Texture> incr = get_icon("increment"); Ref<Texture> decr = get_icon("decrement"); + Ref<Texture> menu = get_icon("menu"); + Ref<Texture> menu_hl = get_icon("menu_hl"); + if (popup && pos.x>get_size().width-menu->get_width()) { + + + emit_signal("pre_popup_pressed"); + Vector2 pp_pos = get_global_pos(); + pp_pos.x+=get_size().width; + pp_pos.x-=popup->get_size().width; + pp_pos.y+=menu->get_height(); + + popup->set_global_pos( pp_pos ); + popup->popup();; + return; + } pos.x-=tabs_ofs_cache; int idx=0; @@ -116,17 +131,17 @@ void TabContainer::_input_event(const InputEvent& p_event) { String s = c->has_meta("_tab_name")?String(XL_MESSAGE(String(c->get_meta("_tab_name")))):String(c->get_name()); int tab_width=font->get_string_size(s).width; - if (c->has_meta("_tab_icon")) { - Ref<Texture> icon = c->get_meta("_tab_icon"); - if (icon.is_valid()) { - tab_width+=icon->get_width(); - if (s!="") - tab_width+=get_constant("hseparation"); + if (c->has_meta("_tab_icon")) { + Ref<Texture> icon = c->get_meta("_tab_icon"); + if (icon.is_valid()) { + tab_width+=icon->get_width(); + if (s!="") + tab_width+=get_constant("hseparation"); - } - } + } + } - if (idx==current) { + if (idx==current) { tab_width+=tab_fg->get_minimum_size().width; } else { @@ -163,7 +178,7 @@ void TabContainer::_input_event(const InputEvent& p_event) { if (found!=-1) { - set_current_tab(found); + set_current_tab(found); } } @@ -194,7 +209,9 @@ void TabContainer::_notification(int p_what) { Ref<Texture> incr = get_icon("increment"); Ref<Texture> incr_hl = get_icon("increment_hilite"); Ref<Texture> decr = get_icon("decrement"); - Ref<Texture> decr_hl = get_icon("decrement_hilite"); + Ref<Texture> decr_hl = get_icon("decrement_hilite"); + Ref<Texture> menu = get_icon("menu"); + Ref<Texture> menu_hl = get_icon("menu_hl"); Ref<Font> font = get_font("font"); Color color_fg = get_color("font_color_fg"); Color color_bg = get_color("font_color_bg"); @@ -209,6 +226,7 @@ void TabContainer::_notification(int p_what) { Size2 top_size = Size2( size.width, top_margin ); + int w=0; int idx=0; for(int i=0;i<get_child_count();i++) { @@ -227,7 +245,7 @@ void TabContainer::_notification(int p_what) { if (icon.is_valid()) { w+=icon->get_width(); if (s!="") - w+=get_constant("hseparation"); + w+=get_constant("hseparation"); } } @@ -245,14 +263,18 @@ void TabContainer::_notification(int p_what) { int ofs; int limit=get_size().width; + if (popup) { + top_size.width-=menu->get_width(); + limit-=menu->get_width(); + } - if (w<=get_size().width) { + if (w<=limit) { switch(align) { case ALIGN_LEFT: ofs = side_margin; break; - case ALIGN_CENTER: ofs = (int(top_size.width) - w)/2; break; - case ALIGN_RIGHT: ofs = int(top_size.width) - w - side_margin; break; + case ALIGN_CENTER: ofs = (int(limit) - w)/2; break; + case ALIGN_RIGHT: ofs = int(limit) - w - side_margin; break; }; tab_display_ofs=0; @@ -364,6 +386,15 @@ void TabContainer::_notification(int p_what) { incr->draw(ci,Point2(limit+incr->get_width(),vofs),Color(1,1,1,notdone?1.0:0.5)); } + if (popup) { + int from = get_size().width-menu->get_width(); + + if (mouse_x_cache > from) + menu_hl->draw(get_canvas_item(),Size2(from,0)); + else + menu->draw(get_canvas_item(),Size2(from,0)); + } + panel->draw(ci, Rect2( 0, top_size.height, size.width, size.height-top_size.height)); } break; @@ -465,6 +496,48 @@ int TabContainer::get_current_tab() const { return current; } +Control* TabContainer::get_tab_control(int p_idx) const { + + int idx=0; + + + for(int i=0;i<get_child_count();i++) { + + Control *c = get_child(i)->cast_to<Control>(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; + if (idx==p_idx) { + return c; + + } + idx++; + } + + return NULL; +} +Control* TabContainer::get_current_tab_control() const { + + int idx=0; + + + for(int i=0;i<get_child_count();i++) { + + Control *c = get_child(i)->cast_to<Control>(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; + if (idx==current) { + return c; + + } + idx++; + } + + return NULL; +} void TabContainer::remove_child_notify(Node *p_child) { @@ -635,12 +708,25 @@ Size2 TabContainer::get_minimum_size() const { return ms; } +void TabContainer::set_popup(Node *p_popup) { + ERR_FAIL_NULL(p_popup); + popup=p_popup->cast_to<Popup>(); + update(); +} + +Popup* TabContainer::get_popup() const { + return popup; +} + + void TabContainer::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&TabContainer::_input_event); ObjectTypeDB::bind_method(_MD("get_tab_count"),&TabContainer::get_tab_count); ObjectTypeDB::bind_method(_MD("set_current_tab","tab_idx"),&TabContainer::set_current_tab); ObjectTypeDB::bind_method(_MD("get_current_tab"),&TabContainer::get_current_tab); + ObjectTypeDB::bind_method(_MD("get_current_tab_control:Control"),&TabContainer::get_current_tab_control); + ObjectTypeDB::bind_method(_MD("get_tab_control:Control","idx"),&TabContainer::get_tab_control); ObjectTypeDB::bind_method(_MD("set_tab_align","align"),&TabContainer::set_tab_align); ObjectTypeDB::bind_method(_MD("get_tab_align"),&TabContainer::get_tab_align); ObjectTypeDB::bind_method(_MD("set_tabs_visible","visible"),&TabContainer::set_tabs_visible); @@ -649,10 +735,13 @@ void TabContainer::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_tab_title","tab_idx"),&TabContainer::get_tab_title); ObjectTypeDB::bind_method(_MD("set_tab_icon","tab_idx","icon:Texture"),&TabContainer::set_tab_icon); ObjectTypeDB::bind_method(_MD("get_tab_icon:Texture","tab_idx"),&TabContainer::get_tab_icon); + ObjectTypeDB::bind_method(_MD("set_popup","popup:Popup"),&TabContainer::set_popup); + ObjectTypeDB::bind_method(_MD("get_popup:Popup"),&TabContainer::get_popup); ObjectTypeDB::bind_method(_MD("_child_renamed_callback"),&TabContainer::_child_renamed_callback); ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab"))); + ADD_SIGNAL(MethodInfo("pre_popup_pressed")); ADD_PROPERTY( PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM,"Left,Center,Right"), _SCS("set_tab_align"), _SCS("get_tab_align") ); ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") ); @@ -669,5 +758,6 @@ TabContainer::TabContainer() { mouse_x_cache=0; align=ALIGN_CENTER; tabs_visible=true; + popup=NULL; } diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index 43314b026d..602d248b46 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -31,7 +31,7 @@ #include "scene/gui/control.h" - +#include "scene/gui/popup.h" class TabContainer : public Control { OBJ_TYPE( TabContainer, Control ); @@ -55,6 +55,8 @@ private: TabAlign align; Control *_get_tab(int idx) const; int _get_top_margin() const; + Popup *popup; + protected: @@ -85,10 +87,17 @@ public: void set_current_tab(int p_current); int get_current_tab() const; + Control* get_tab_control(int p_idx) const; + Control* get_current_tab_control() const; + virtual Size2 get_minimum_size() const; virtual void get_translatable_strings(List<String> *p_strings) const; + void set_popup(Node *p_popup); + Popup* get_popup() const; + + TabContainer(); }; diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 37369a7e6c..40a6e20c37 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -77,8 +77,8 @@ void Tabs::_input_event(const InputEvent& p_event) { for(int i=0;i<tabs.size();i++) { int ofs=tabs[i].ofs_cache; - - if (pos.x < ofs) { + int size = tabs[i].ofs_cache; + if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) { found=i; break; @@ -89,6 +89,7 @@ void Tabs::_input_event(const InputEvent& p_event) { if (found!=-1) { set_current_tab(found); + emit_signal("tab_changed",found); } } @@ -117,8 +118,22 @@ void Tabs::_notification(int p_what) { int w=0; + int mw = get_minimum_size().width; + + if (tab_align==ALIGN_CENTER) { + w=(get_size().width-mw)/2; + } else if (tab_align==ALIGN_RIGHT) { + w=get_size().width-mw; + + } + + if (w<0) { + w=0; + } + for(int i=0;i<tabs.size();i++) { + tabs[i].ofs_cache=w; String s = tabs[i].text; int lsize=0; @@ -171,7 +186,7 @@ void Tabs::_notification(int p_what) { w+=slen+sb->get_margin(MARGIN_RIGHT); - tabs[i].ofs_cache=w; + tabs[i].size_cache=w-tabs[i].ofs_cache; } @@ -195,7 +210,7 @@ void Tabs::set_current_tab(int p_current) { current=p_current; _change_notify("current_tab"); - emit_signal("tab_changed",current); + //emit_signal("tab_changed",current); update(); } @@ -249,6 +264,12 @@ void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) { } +void Tabs::clear_tabs() { + tabs.clear(); + current=0; + update(); +} + void Tabs::remove_tab(int p_idx) { ERR_FAIL_INDEX(p_idx,tabs.size()); @@ -263,8 +284,19 @@ void Tabs::remove_tab(int p_idx) { if (current>=tabs.size()) current=tabs.size()-1; - emit_signal("tab_changed",current); + //emit_signal("tab_changed",current); + +} + +void Tabs::set_tab_align(TabAlign p_align) { + + tab_align=p_align; + update(); +} + +Tabs::TabAlign Tabs::get_tab_align() const { + return tab_align; } @@ -280,15 +312,21 @@ void Tabs::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_tab_icon:Texture","tab_idx"),&Tabs::get_tab_icon); ObjectTypeDB::bind_method(_MD("remove_tab","tab_idx"),&Tabs::remove_tab); ObjectTypeDB::bind_method(_MD("add_tab","title","icon:Texture"),&Tabs::add_tab); + ObjectTypeDB::bind_method(_MD("set_tab_align","align"),&Tabs::set_tab_align); + ObjectTypeDB::bind_method(_MD("get_tab_align"),&Tabs::get_tab_align); ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab"))); ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") ); + BIND_CONSTANT( ALIGN_LEFT ); + BIND_CONSTANT( ALIGN_CENTER ); + BIND_CONSTANT( ALIGN_RIGHT ); } Tabs::Tabs() { current=0; + tab_align=ALIGN_CENTER; } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 4a969928ff..8d4d0123f8 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -34,6 +34,14 @@ class Tabs : public Control { OBJ_TYPE( Tabs, Control ); +public: + + enum TabAlign { + + ALIGN_LEFT, + ALIGN_CENTER, + ALIGN_RIGHT + }; private: @@ -42,12 +50,14 @@ private: String text; Ref<Texture> icon; int ofs_cache; + int size_cache; }; Vector<Tab> tabs; int current; Control *_get_tab(int idx) const; int _get_top_margin() const; + TabAlign tab_align; protected: @@ -65,16 +75,22 @@ public: void set_tab_icon(int p_tab,const Ref<Texture>& p_icon); Ref<Texture> get_tab_icon(int p_tab) const; + void set_tab_align(TabAlign p_align); + TabAlign get_tab_align() const; + int get_tab_count() const; void set_current_tab(int p_current); int get_current_tab() const; void remove_tab(int p_idx); + void clear_tabs(); + Size2 get_minimum_size() const; Tabs(); }; +VARIANT_ENUM_CAST(Tabs::TabAlign); #endif // TABS_H diff --git a/scene/gui/tree.h b/scene/gui/tree.h index f03827f542..8ddddd0630 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -454,6 +454,8 @@ public: void set_cursor_can_exit_tree(bool p_enable); bool can_cursor_exit_tree() const; + VScrollBar *get_vscroll_bar() { return v_scroll; } + Tree(); ~Tree(); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index ab530866bb..b7fa5c8301 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -641,6 +641,7 @@ void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) { p_child->data.pos=data.children.size(); data.children.push_back( p_child ); p_child->data.parent=this; + p_child->notification(NOTIFICATION_PARENTED); if (data.tree) { p_child->_set_tree(data.tree); @@ -649,7 +650,6 @@ void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) { /* Notify */ //recognize childs created in this node constructor p_child->data.parent_owned=data.in_constructor; - p_child->notification(NOTIFICATION_PARENTED); add_child_notify(p_child); @@ -1816,6 +1816,16 @@ void Node::get_argument_options(const StringName& p_function,int p_idx,List<Stri Object::get_argument_options(p_function,p_idx,r_options); } + +void Node::clear_internal_tree_resource_paths() { + + clear_internal_resource_paths(); + for(int i=0;i<data.children.size();i++) { + data.children[i]->clear_internal_tree_resource_paths(); + } + +} + void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name); diff --git a/scene/main/node.h b/scene/main/node.h index a89a6abf33..be91c6e1bb 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -290,6 +290,8 @@ public: void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const; + void clear_internal_tree_resource_paths(); + _FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; } /* CANVAS */ diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 584b40337f..1664a9bea1 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -1108,6 +1108,9 @@ void SceneTree::_bind_methods() { ADD_SIGNAL( MethodInfo("node_removed",PropertyInfo( Variant::OBJECT, "node") ) ); ADD_SIGNAL( MethodInfo("screen_resized") ); + ADD_SIGNAL( MethodInfo("idle_frame")); + ADD_SIGNAL( MethodInfo("fixed_frame")); + BIND_CONSTANT( GROUP_CALL_DEFAULT ); BIND_CONSTANT( GROUP_CALL_REVERSE ); BIND_CONSTANT( GROUP_CALL_REALTIME ); @@ -1166,8 +1169,7 @@ SceneTree::SceneTree() { edited_scene_root=NULL; #endif - ADD_SIGNAL( MethodInfo("idle_frame")); - ADD_SIGNAL( MethodInfo("fixed_frame")); + } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 2267cc9e2f..9a9048e3e5 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -655,6 +655,8 @@ void make_default_theme() { t->set_icon("increment_hilite","TabContainer",make_icon( scroll_button_right_hl_png)); t->set_icon("decrement","TabContainer",make_icon( scroll_button_left_png)); t->set_icon("decrement_hilite","TabContainer",make_icon( scroll_button_left_hl_png)); + t->set_icon("menu","TabContainer",make_icon( tab_menu_png)); + t->set_icon("menu_hilite","TabContainer",make_icon( tab_menu_hl_png)); t->set_font("font","TabContainer", default_font ); diff --git a/scene/resources/default_theme/selection.png b/scene/resources/default_theme/selection.png Binary files differindex 074c7a4d80..3b1c810c40 100644 --- a/scene/resources/default_theme/selection.png +++ b/scene/resources/default_theme/selection.png diff --git a/scene/resources/default_theme/selection_oof.png b/scene/resources/default_theme/selection_oof.png Binary files differindex 17ec977bd6..e8680128cd 100644 --- a/scene/resources/default_theme/selection_oof.png +++ b/scene/resources/default_theme/selection_oof.png diff --git a/scene/resources/default_theme/tab_menu.png b/scene/resources/default_theme/tab_menu.png Binary files differnew file mode 100644 index 0000000000..c5659da11b --- /dev/null +++ b/scene/resources/default_theme/tab_menu.png diff --git a/scene/resources/default_theme/tab_menu_hl.png b/scene/resources/default_theme/tab_menu_hl.png Binary files differnew file mode 100644 index 0000000000..6f68502c07 --- /dev/null +++ b/scene/resources/default_theme/tab_menu_hl.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 8bd0a66271..03d851e749 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -340,12 +340,12 @@ static const unsigned char scroll_grabber_hl_png[]={ static const unsigned char selection_png[]={ -0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x11,0x12,0x2a,0x16,0x85,0x48,0x8b,0x13,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0xba,0x49,0x44,0x41,0x54,0x38,0x8d,0xed,0x93,0x31,0xa,0xc2,0x50,0x10,0x44,0xdf,0x97,0xbf,0x8a,0x3f,0x45,0xd0,0x52,0xbb,0xfc,0x63,0x88,0x88,0xa7,0xd0,0x23,0x9a,0x63,0x84,0x90,0x63,0x24,0x9d,0x9d,0x60,0x95,0x2f,0xb2,0x21,0x5a,0x18,0xb4,0x52,0x3,0x69,0x2c,0x9c,0x6e,0x8b,0x99,0xd9,0x59,0x76,0xc,0x30,0x6,0xa6,0xc0,0x4,0x18,0xd1,0xf,0x2d,0x70,0x5,0x2e,0xb6,0x23,0x2f,0x81,0x19,0x20,0x3d,0x5,0x14,0x38,0x3,0x47,0xdb,0x39,0xcf,0xd7,0xab,0xcd,0xc2,0x27,0xfe,0x20,0x22,0xe6,0x23,0x53,0xf5,0x56,0x56,0xe5,0x3e,0x2f,0x32,0x3,0x9c,0x6c,0xb7,0xb6,0xf5,0x89,0x4f,0x43,0x8,0xd4,0x21,0x7c,0xb4,0x8e,0x9c,0x33,0x3e,0xf1,0x69,0x5e,0x64,0x5b,0x60,0xf4,0xcc,0x2c,0x22,0x5f,0xc9,0x0,0x75,0x8,0x88,0xbc,0x92,0xf6,0x3d,0xda,0x5b,0xfc,0x5,0x7e,0x4a,0x40,0x55,0x89,0x9c,0xfb,0x4a,0x88,0x9c,0x43,0x55,0x9f,0xb3,0xe5,0x51,0x8c,0xa6,0xac,0xca,0x9d,0x4f,0xfc,0x21,0x8e,0xe3,0x5e,0xaf,0xc,0x34,0x40,0x6b,0x80,0x98,0x1,0x65,0x32,0xc,0xac,0xf3,0x1d,0x55,0xc6,0x3e,0x2,0xe2,0x2e,0xc9,0xc8,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x15,0x0,0x15,0x0,0x17,0xc8,0x7d,0x47,0xd1,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0x14,0x14,0x31,0x1a,0x5f,0x97,0xc4,0x56,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xa3,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x93,0xbd,0xa,0xc2,0x40,0x10,0x84,0xbf,0xbb,0x6c,0x72,0x8,0x1,0x51,0x4b,0xdf,0x23,0xc9,0xfb,0x57,0x12,0x9f,0x43,0xb0,0x10,0x2c,0x14,0xe4,0x92,0xcb,0xc5,0x66,0x3,0x36,0x26,0x7,0x69,0x2c,0x9c,0x6e,0x60,0x67,0xf6,0x87,0x1d,0x3,0x14,0xc0,0x6,0x70,0x80,0x25,0xd,0x11,0xf0,0xc0,0x4b,0x54,0x7c,0x4,0x76,0x40,0x9e,0x68,0xd0,0x3,0x77,0xe0,0x22,0xda,0x79,0x3f,0xf4,0x63,0x4b,0xa0,0x56,0x3e,0x7,0x8f,0x70,0xce,0x72,0x53,0x1,0x37,0xd1,0xb1,0x85,0x40,0xc3,0xc8,0xc3,0x47,0xae,0x73,0x6a,0x67,0x29,0x9,0x34,0xaa,0xb3,0x9f,0x3b,0x17,0x3e,0xf2,0x5c,0x9a,0x5d,0x6b,0x8a,0x89,0xa7,0x1e,0xed,0x2b,0xfe,0x6,0xbf,0x66,0xd0,0x39,0x4b,0xb9,0x24,0xd0,0x9a,0x6e,0xe2,0xa2,0xc1,0x8,0x8,0x2d,0x81,0xda,0x65,0x1c,0x12,0x5e,0xf9,0x4,0x54,0x40,0x34,0xc0,0x76,0x4d,0x98,0xcc,0xda,0x38,0xbf,0x1,0xae,0x5a,0x2a,0xba,0xb8,0xa1,0xb8,0x4f,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; static const unsigned char selection_oof_png[]={ -0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x4c,0x0,0x4a,0x0,0x4e,0x88,0x29,0x6a,0xb6,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x10,0x15,0x32,0x22,0x9b,0x14,0x96,0x1f,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0xba,0x49,0x44,0x41,0x54,0x38,0x8d,0xed,0xd3,0xb1,0x4e,0xc3,0x40,0x10,0x84,0xe1,0xef,0xc2,0x4a,0x9c,0x90,0xb,0x6a,0x9f,0xe0,0x9,0x2,0xbc,0x58,0xc2,0xcb,0xc0,0x8b,0x85,0xa4,0xa6,0x41,0x4e,0x4d,0x41,0x71,0x91,0xe,0x99,0x2,0xd7,0x76,0xa4,0x34,0x14,0x6c,0xb9,0xda,0xf9,0x47,0x2b,0xcd,0x24,0xdc,0xe0,0x16,0x1d,0xae,0x90,0xcc,0xcf,0x88,0x6f,0x7c,0xe1,0x33,0x26,0xf1,0x23,0xee,0x90,0xcf,0x4,0x54,0x7c,0xe0,0x2d,0x26,0xe7,0xfb,0x87,0xf5,0xd3,0xba,0xf4,0x65,0x13,0x11,0xb3,0x80,0xd6,0xda,0x38,0x1c,0x87,0xd7,0xfd,0x61,0x97,0xf0,0x1e,0x8,0x5c,0x97,0xbe,0x6c,0x6b,0xad,0x6a,0xad,0xb3,0xf6,0x39,0xe7,0x54,0xfa,0xb2,0xdd,0x1f,0x76,0xcf,0x88,0xd5,0xb4,0x4f,0x11,0xb1,0x28,0x86,0x5a,0xab,0x88,0x60,0x7a,0x75,0x35,0x7f,0xbe,0x3c,0xff,0x80,0xbf,0x4,0x18,0x5b,0x6b,0x72,0xce,0x8b,0x82,0x9c,0xb3,0xd6,0x1a,0xbf,0x91,0x16,0x68,0x38,0xd,0xc7,0xe1,0xa5,0xf4,0x65,0xd3,0x75,0xdd,0x59,0x51,0xc6,0x9,0x2d,0xa1,0x77,0x41,0x99,0x92,0xb,0xeb,0xfc,0x3,0xd0,0xc5,0x44,0x36,0x1d,0x79,0x84,0xde,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x15,0x0,0x15,0x0,0x17,0xc8,0x7d,0x47,0xd1,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0x14,0x14,0x32,0x15,0xe4,0x5,0x8a,0x4,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0xd3,0x41,0x6a,0x2,0x51,0x10,0x4,0xd0,0xf7,0xe7,0xff,0xc1,0x30,0x4,0xe2,0x5a,0x18,0x4f,0x10,0x2,0x9e,0x29,0xe7,0xca,0x99,0x4,0xc9,0xda,0xcd,0x5c,0x20,0x8b,0x20,0x8a,0xfe,0x8c,0x9b,0x76,0xeb,0x8,0xb3,0xc9,0xc2,0x82,0xde,0x34,0x55,0xd5,0x34,0x54,0x25,0x74,0x58,0xe2,0x15,0x19,0xc9,0x7d,0x8c,0xa8,0xf8,0xc5,0x4f,0x9,0xf1,0x7,0x7a,0xbc,0x3c,0x68,0x70,0xc4,0x80,0x5d,0x89,0xcb,0x6b,0xef,0xcd,0x57,0xdd,0xd6,0x1e,0xed,0x84,0xc1,0x39,0x6f,0xf2,0xe0,0xfb,0xef,0x13,0xfb,0x82,0x82,0x45,0x88,0xf,0x31,0xf7,0xd0,0xd5,0x6d,0xed,0x73,0x9b,0x16,0x28,0x4d,0x2c,0x53,0x5c,0x9e,0x12,0xb,0x4e,0x7b,0x7b,0xb5,0x31,0x13,0x4f,0x83,0xff,0x64,0x30,0xe2,0x1c,0xbd,0x98,0x42,0x17,0xdc,0x51,0xa4,0xf0,0x82,0x53,0xde,0xe4,0x21,0xd2,0xf8,0xf6,0x50,0x94,0x39,0xe1,0x92,0xb0,0x9a,0x53,0xa6,0x34,0xb7,0xce,0x57,0x8f,0xdf,0x31,0x5b,0x17,0xde,0x59,0x7e,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; @@ -379,6 +379,16 @@ static const unsigned char tab_current_png[]={ }; +static const unsigned char tab_menu_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0xd,0x3,0x2c,0x7,0xf7,0x85,0x69,0x73,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x54,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x92,0xb1,0xd,0xc0,0x20,0x10,0x3,0x8f,0xec,0x63,0x65,0xff,0x2d,0x40,0x1e,0xe8,0xd3,0x50,0x24,0xd1,0x83,0x48,0x97,0x2,0xb7,0xb6,0x4f,0xd6,0xeb,0x61,0xeb,0x67,0xb2,0x5d,0xbe,0x66,0x4a,0x12,0x88,0x19,0x40,0xd2,0xa3,0x73,0x24,0x99,0x6,0x64,0x90,0xe8,0x1e,0xd3,0x5,0x7d,0x45,0x3,0x74,0xf3,0x3,0xb0,0xa4,0x73,0x9,0xf0,0x82,0x30,0x2a,0xaf,0x1c,0xb5,0xda,0xae,0xfb,0xbd,0xe6,0xba,0x0,0x22,0x30,0x1e,0x2c,0xd7,0x21,0xa8,0x0,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char tab_menu_hl_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0xd,0x3,0x2c,0x15,0x4,0x3c,0x18,0x3b,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x58,0x49,0x44,0x41,0x54,0x38,0xcb,0x63,0x60,0x18,0x5,0x83,0xc,0xbc,0x7c,0xf9,0x92,0x91,0x54,0x35,0x8c,0x58,0x14,0xfc,0xc7,0x67,0x80,0xb8,0xb8,0x38,0x8a,0x1e,0x26,0x2c,0x6a,0x2e,0x32,0x30,0x30,0x60,0x33,0xe4,0x3f,0x54,0x8e,0x1,0xaf,0xb,0xa0,0xae,0xb8,0xc8,0xc0,0xc0,0xa0,0x8b,0x24,0xff,0x9f,0x81,0x81,0xe1,0xb2,0xb8,0xb8,0xb8,0x3e,0x51,0x6,0xa0,0x19,0xc2,0x80,0x4b,0x33,0x31,0x81,0x7a,0xe1,0xe5,0xcb,0x97,0x17,0x46,0x93,0x17,0x7e,0x0,0x0,0xa,0x9a,0x1f,0x34,0xff,0x99,0xf7,0x75,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + static const unsigned char toggle_off_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0xa2,0x9d,0x7e,0x84,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x26,0x0,0x26,0x0,0x26,0x59,0xf,0xde,0x74,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x14,0x17,0x2,0x16,0xe9,0x0,0x17,0x60,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x2,0x45,0x49,0x44,0x41,0x54,0x68,0x81,0xed,0x99,0x5f,0x4f,0xd3,0x50,0x18,0x87,0x9f,0xb3,0x96,0xb5,0xcc,0x3a,0xa6,0xac,0x6d,0xa,0x91,0x84,0x5b,0x8d,0x7e,0x21,0x60,0x2c,0x5c,0x1a,0x63,0xe2,0x27,0x31,0x31,0xc6,0x4b,0x32,0xa7,0x7e,0x20,0x84,0x6b,0x6f,0xc,0x90,0x6d,0x32,0xca,0x6c,0xb0,0x24,0x75,0xc7,0x8b,0xba,0xb9,0x35,0xdd,0x84,0xec,0xe0,0x26,0xed,0x73,0xd7,0xf7,0xed,0xce,0x7b,0x7e,0xbf,0xbe,0x67,0x7f,0xde,0x41,0x4e,0x4e,0xa6,0x11,0x89,0xeb,0x12,0x50,0x1,0x2c,0x40,0x4b,0xc9,0xff,0xaf,0x48,0xe0,0x27,0x10,0x0,0x3e,0x70,0x39,0x48,0xe8,0x89,0x1b,0x2b,0xc0,0x33,0xe0,0x11,0x60,0x72,0xb7,0xc,0x8,0x81,0xaf,0xc0,0x67,0xa6,0x18,0x60,0x1,0x1b,0x4f,0x1e,0x3f,0x7d,0x6d,0x57,0xed,0x65,0x40,0x48,0x64,0xfc,0x72,0x95,0x8,0x10,0x8,0x74,0x5d,0x67,0x69,0x49,0x47,0xd3,0x92,0xdb,0x50,0x4b,0x14,0x45,0xf2,0xf8,0xe4,0xf8,0xc7,0xe1,0xd1,0xc1,0x2b,0xe0,0xcb,0x68,0x2e,0x59,0x59,0x7,0xc,0xbb,0x6a,0x97,0xce,0xba,0x67,0x4,0x41,0x80,0xec,0xf7,0x91,0x8a,0x1d,0x10,0x8,0x44,0xa1,0x80,0x51,0x2c,0x52,0x2a,0xdd,0xa3,0x58,0x2c,0x2a,0x5d,0x3f,0x89,0x69,0x9a,0x62,0x7d,0x6d,0xbd,0x74,0x78,0x74,0x60,0x90,0xd0,0x9c,0x66,0xbd,0x0,0x8,0x82,0xef,0x54,0x2a,0xf,0x70,0x6c,0x7,0xa1,0xf8,0x24,0x48,0x24,0xed,0x4e,0x1b,0xdf,0x3f,0xc7,0x30,0x4c,0xa5,0x6b,0xa7,0x11,0x86,0x21,0x96,0x65,0x41,0xca,0x91,0x4e,0xed,0x3d,0x29,0x25,0xb2,0x2f,0x71,0x1d,0x97,0x30,0xc,0x39,0x6d,0x9d,0x2a,0xdd,0x90,0xe7,0x7a,0xb8,0x8e,0xcb,0x79,0xb7,0xab,0xbc,0xbb,0x6e,0x4a,0x61,0x52,0x62,0x70,0xf6,0x55,0x8b,0x87,0xdf,0x6b,0x4a,0xe6,0x2e,0x1e,0xa6,0x18,0x90,0x15,0x32,0x6f,0xc0,0xed,0x7e,0xfe,0xcc,0x80,0x65,0x59,0xd4,0xf7,0x6a,0x63,0xb1,0xc6,0x7e,0x93,0x20,0x8,0x78,0xf1,0xf2,0xf9,0x58,0xfc,0xed,0x9b,0x77,0xa9,0xb1,0xeb,0xb0,0xb0,0x6,0xc,0xc4,0x7f,0x78,0xff,0x9,0x80,0x9d,0xdd,0x2d,0xea,0x7b,0xb5,0xa1,0xb0,0x34,0x81,0xd7,0x15,0x3d,0xca,0xc2,0x1a,0x0,0xd0,0x6c,0x7c,0xa4,0xd7,0xeb,0x1,0xb1,0x11,0x3b,0xbb,0x5b,0xc3,0xdc,0xe8,0x13,0x1f,0x8,0x4f,0x8b,0xfd,0x8d,0x85,0x36,0x60,0x1a,0xaa,0x3a,0x60,0xa1,0xdf,0x4,0x6b,0xf5,0x6d,0xca,0xe5,0x32,0xe5,0x72,0x79,0xec,0xe9,0xab,0x24,0x69,0x80,0x9,0xac,0xdc,0x4a,0xa5,0x1b,0xd2,0xd8,0x6f,0x2,0xb1,0x9,0xb5,0xfa,0xf6,0x58,0x6c,0x6,0x56,0x88,0x35,0xe,0x49,0x1e,0x81,0x10,0xb8,0x98,0xb5,0x8a,0xa,0x82,0x20,0x98,0xd8,0xd2,0x33,0xb4,0xff,0x5,0xb1,0xc6,0x21,0xb,0x7d,0x4,0xfe,0x5,0xb9,0x1,0xf3,0xde,0xc0,0xbc,0x99,0x68,0x80,0x88,0xa7,0x16,0x78,0xae,0xa7,0xbc,0xa8,0xe7,0x7a,0xc3,0xa1,0xc8,0xbc,0x49,0xfd,0x1e,0x20,0x84,0x40,0x14,0x4,0xad,0x76,0xb,0xc7,0x76,0xd8,0xdc,0xd8,0x54,0x5a,0x54,0x22,0x69,0xb5,0x5b,0x88,0x82,0x98,0xbb,0x9,0x69,0x6,0x48,0x0,0xcb,0xba,0x8f,0xef,0xfb,0xb7,0xf2,0x9b,0xfd,0xcf,0x44,0xc8,0x40,0xd3,0x34,0xa5,0x6b,0xa7,0x61,0x9a,0x26,0x51,0x14,0x41,0xca,0x70,0x2f,0x69,0x40,0x4,0x5c,0x75,0xbe,0x75,0x2e,0xed,0xaa,0xbd,0xbc,0xfa,0x70,0xf5,0x4e,0xcd,0x4,0x81,0x2b,0x62,0x8d,0xa3,0x5b,0x19,0x63,0x8d,0x6c,0x4c,0x85,0x4f,0x6,0x89,0xcc,0xff,0x2f,0x90,0x93,0x93,0x93,0x6d,0x7e,0x1,0x6b,0xe,0xc1,0xdb,0xd6,0xe0,0xc4,0xba,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp index e009bd52cb..3eb96fb681 100644 --- a/servers/physics/area_pair_sw.cpp +++ b/servers/physics/area_pair_sw.cpp @@ -93,3 +93,72 @@ AreaPairSW::~AreaPairSW() { body->remove_constraint(this); area->remove_constraint(this); } + +//////////////////////////////////////////////////// + + + +bool Area2PairSW::setup(float p_step) { + +// bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); + bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),NULL,this); + + if (result!=colliding) { + + if (result) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->add_area_to_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->add_area_to_query(area_b,shape_b,shape_a); + + } else { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + colliding=result; + + } + + return false; //never do any post solving +} + +void Area2PairSW::solve(float p_step) { + + +} + + +Area2PairSW::Area2PairSW(AreaSW *p_area_a,int p_shape_a, AreaSW *p_area_b,int p_shape_b) { + + + area_a=p_area_a; + area_b=p_area_b; + shape_a=p_shape_a; + shape_b=p_shape_b; + colliding=false; + area_a->add_constraint(this); + area_b->add_constraint(this); + +} + +Area2PairSW::~Area2PairSW() { + + if (colliding) { + + if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) + area_b->remove_area_from_query(area_a,shape_a,shape_b); + + if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) + area_a->remove_area_from_query(area_b,shape_b,shape_a); + } + + area_a->remove_constraint(this); + area_b->remove_constraint(this); +} diff --git a/servers/physics/area_pair_sw.h b/servers/physics/area_pair_sw.h index 1c219a05fd..4f8087280a 100644 --- a/servers/physics/area_pair_sw.h +++ b/servers/physics/area_pair_sw.h @@ -49,5 +49,23 @@ public: ~AreaPairSW(); }; + +class Area2PairSW : public ConstraintSW { + + AreaSW *area_a; + AreaSW *area_b; + int shape_a; + int shape_b; + bool colliding; +public: + + bool setup(float p_step); + void solve(float p_step); + + Area2PairSW(AreaSW *p_area_a,int p_shape_a, AreaSW *p_area_b,int p_shape_b); + ~Area2PairSW(); +}; + + #endif // AREA_PAIR__SW_H diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index aa1c530221..83be80f816 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -31,6 +31,7 @@ #include "body_sw.h" AreaSW::BodyKey::BodyKey(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } +AreaSW::BodyKey::BodyKey(AreaSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape) { rid=p_body->get_self(); instance_id=p_body->get_instance_id(); body_shape=p_body_shape; area_shape=p_area_shape; } void AreaSW::_shapes_changed() { @@ -57,6 +58,7 @@ void AreaSW::set_space(SpaceSW *p_space) { } monitored_bodies.clear(); + monitored_areas.clear(); _set_space(p_space); } @@ -76,11 +78,32 @@ void AreaSW::set_monitor_callback(ObjectID p_id, const StringName& p_method) { monitor_callback_method=p_method; monitored_bodies.clear(); + monitored_areas.clear(); + _shape_changed(); } +void AreaSW::set_area_monitor_callback(ObjectID p_id, const StringName& p_method) { + + + if (p_id==area_monitor_callback_id) { + area_monitor_callback_method=p_method; + return; + } + + _unregister_shapes(); + + area_monitor_callback_id=p_id; + area_monitor_callback_method=p_method; + + monitored_bodies.clear(); + monitored_areas.clear(); + + _shape_changed(); + +} void AreaSW::set_space_override_mode(PhysicsServer::AreaSpaceOverrideMode p_mode) { @@ -134,6 +157,15 @@ void AreaSW::_queue_monitor_update() { } +void AreaSW::set_monitorable(bool p_monitorable) { + + if (monitorable==p_monitorable) + return; + + monitorable=p_monitorable; + _set_static(!monitorable); +} + void AreaSW::call_queries() { if (monitor_callback_id && !monitored_bodies.empty()) { @@ -168,6 +200,41 @@ void AreaSW::call_queries() { monitored_bodies.clear(); + if (area_monitor_callback_id && !monitored_areas.empty()) { + + + Variant res[5]; + Variant *resptr[5]; + for(int i=0;i<5;i++) + resptr[i]=&res[i]; + + Object *obj = ObjectDB::get_instance(area_monitor_callback_id); + if (!obj) { + monitored_areas.clear(); + area_monitor_callback_id=0; + return; + } + + + + for (Map<BodyKey,BodyState>::Element *E=monitored_areas.front();E;E=E->next()) { + + if (E->get().state==0) + continue; //nothing happened + + res[0]=E->get().state>0 ? PhysicsServer::AREA_BODY_ADDED : PhysicsServer::AREA_BODY_REMOVED; + res[1]=E->key().rid; + res[2]=E->key().instance_id; + res[3]=E->key().body_shape; + res[4]=E->key().area_shape; + + + Variant::CallError ce; + obj->call(area_monitor_callback_method,(const Variant**)resptr,5,ce); + } + } + + monitored_areas.clear(); //get_space()->area_remove_from_monitor_query_list(&monitor_query_list); } @@ -185,6 +252,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move priority=0; set_ray_pickable(false); monitor_callback_id=0; + area_monitor_callback_id=0; + monitorable=false; } diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index a875472f6b..26d6a177db 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -49,10 +49,14 @@ class AreaSW : public CollisionObjectSW{ float point_attenuation; float density; int priority; + bool monitorable; ObjectID monitor_callback_id; StringName monitor_callback_method; + ObjectID area_monitor_callback_id; + StringName area_monitor_callback_method; + SelfList<AreaSW> monitor_query_list; SelfList<AreaSW> moved_list; @@ -79,6 +83,8 @@ class AreaSW : public CollisionObjectSW{ _FORCE_INLINE_ BodyKey() {} BodyKey(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + BodyKey(AreaSW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + }; struct BodyState { @@ -90,6 +96,7 @@ class AreaSW : public CollisionObjectSW{ }; Map<BodyKey,BodyState> monitored_bodies; + Map<BodyKey,BodyState> monitored_areas; //virtual void shape_changed_notify(ShapeSW *p_shape); //virtual void shape_deleted_notify(ShapeSW *p_shape); @@ -108,9 +115,15 @@ public: void set_monitor_callback(ObjectID p_id, const StringName& p_method); _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id; } + void set_area_monitor_callback(ObjectID p_id, const StringName& p_method); + _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id; } + _FORCE_INLINE_ void add_body_to_query(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); _FORCE_INLINE_ void remove_body_from_query(BodySW *p_body, uint32_t p_body_shape,uint32_t p_area_shape); + _FORCE_INLINE_ void add_area_to_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + _FORCE_INLINE_ void remove_area_from_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape); + void set_param(PhysicsServer::AreaParameter p_param, const Variant& p_value); Variant get_param(PhysicsServer::AreaParameter p_param) const; @@ -142,8 +155,8 @@ public: _FORCE_INLINE_ void remove_constraint( ConstraintSW* p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set<ConstraintSW*>& get_constraints() const { return constraints; } - - + void set_monitorable(bool p_monitorable); + _FORCE_INLINE_ bool is_monitorable() const { return monitorable; } void set_transform(const Transform& p_transform); @@ -172,6 +185,26 @@ void AreaSW::remove_body_from_query(BodySW *p_body, uint32_t p_body_shape,uint32 } +void AreaSW::add_area_to_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].inc(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); + + +} +void AreaSW::remove_area_from_query(AreaSW *p_area, uint32_t p_area_shape,uint32_t p_self_shape) { + + + BodyKey bk(p_area,p_area_shape,p_self_shape); + monitored_areas[bk].dec(); + if (!monitor_query_list.in_list()) + _queue_monitor_update(); +} + + diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 03d5b7afa1..521ffae0ea 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -394,6 +394,14 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const { return area->get_transform(); }; +void PhysicsServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { + + AreaSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_monitorable(p_monitorable); +} + void PhysicsServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { AreaSW *area = area_owner.get(p_area); @@ -423,6 +431,14 @@ bool PhysicsServerSW::area_is_ray_pickable(RID p_area) const{ } +void PhysicsServerSW::area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method) { + + + AreaSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_area_monitor_callback(p_receiver?p_receiver->get_instance_ID():0,p_method); +} /* BODY API */ diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index de2a24a378..80007b8499 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -128,7 +128,10 @@ public: virtual void area_set_ray_pickable(RID p_area,bool p_enable); virtual bool area_is_ray_pickable(RID p_area) const; + virtual void area_set_monitorable(RID p_area,bool p_monitorable); + virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); + virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); /* BODY API */ diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index a7465c57b9..d329a10f04 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -503,15 +503,18 @@ void* SpaceSW::_broadphase_pair(CollisionObjectSW *A,int p_subindex_A,CollisionO if (type_A==CollisionObjectSW::TYPE_AREA) {
-
- ERR_FAIL_COND_V(type_B!=CollisionObjectSW::TYPE_BODY,NULL);
AreaSW *area=static_cast<AreaSW*>(A);
- BodySW *body=static_cast<BodySW*>(B);
-
+ if (type_B==CollisionObjectSW::TYPE_AREA) {
- AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) );
+ AreaSW *area_b=static_cast<AreaSW*>(B);
+ Area2PairSW *area2_pair = memnew(Area2PairSW(area_b,p_subindex_B,area,p_subindex_A) );
+ return area2_pair;
+ } else {
- return area_pair;
+ BodySW *body=static_cast<BodySW*>(B);
+ AreaPairSW *area_pair = memnew(AreaPairSW(body,p_subindex_B,area,p_subindex_A) );
+ return area_pair;
+ }
} else {
diff --git a/servers/physics_server.h b/servers/physics_server.h index 05b64da804..f66ea590b8 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -339,7 +339,10 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const=0; virtual Transform area_get_transform(RID p_area) const=0; + virtual void area_set_monitorable(RID p_area,bool p_monitorable)=0; + virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; + virtual void area_set_area_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; virtual void area_set_ray_pickable(RID p_area,bool p_enable)=0; virtual bool area_is_ray_pickable(RID p_area) const=0; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 79365f7db6..50336e07f4 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -502,7 +502,7 @@ public: virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug)=0; virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass )=0; - virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection)=0; + virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint)=0; virtual void add_light( RID p_light_instance )=0; ///< all "add_light" calls happen before add_geometry calls diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 8db1cbf6e5..e32f47b3d8 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1497,7 +1497,7 @@ void RasterizerDummy::begin_shadow_map( RID p_light_instance, int p_shadow_pass } -void RasterizerDummy::set_camera(const Transform& p_world,const CameraMatrix& p_projection) { +void RasterizerDummy::set_camera(const Transform& p_world, const CameraMatrix& p_projection, bool p_ortho_hint) { } diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 318cf6ff99..cc3c1724a4 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -679,7 +679,7 @@ public: virtual void begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug); virtual void begin_shadow_map( RID p_light_instance, int p_shadow_pass ); - virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection); + virtual void set_camera(const Transform& p_world,const CameraMatrix& p_projection,bool p_ortho_hint); virtual void add_light( RID p_light_instance ); ///< all "add_light" calls happen before add_geometry calls diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 52e5c21272..3fc90fd46d 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -6302,7 +6302,7 @@ void VisualServerRaster::_render_no_camera(Viewport *p_viewport,Camera *p_camera else environment=p_scenario->fallback_environment; - rasterizer->set_camera(Transform(),CameraMatrix()); + rasterizer->set_camera(Transform(),CameraMatrix(),false); rasterizer->begin_scene(p_viewport->viewport_data,environment,p_scenario->debug); rasterizer->set_viewport(viewport_rect); rasterizer->end_scene(); @@ -6318,7 +6318,8 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S /* STEP 1 - SETUP CAMERA */ CameraMatrix camera_matrix; - + bool ortho=false; + switch(p_camera->type) { case Camera::ORTHOGONAL: { @@ -6330,6 +6331,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S p_camera->vaspect ); + ortho=true; } break; case Camera::PERSPECTIVE: { @@ -6341,12 +6343,13 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S p_camera->vaspect ); + ortho=false; } break; } - rasterizer->set_camera(p_camera->transform, camera_matrix); + rasterizer->set_camera(p_camera->transform, camera_matrix,ortho); Vector<Plane> planes = camera_matrix.get_projection_planes(p_camera->transform); diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index f5bef2580d..c0f35a4ac2 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -230,6 +230,11 @@ void CreateDialog::_notification(int p_what) { connect("confirmed",this,"_confirmed"); _update_search(); } + if (p_what==NOTIFICATION_EXIT_TREE) { + + disconnect("confirmed",this,"_confirmed"); + + } if (p_what==NOTIFICATION_VISIBILITY_CHANGED) { diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp index a635034aca..c4808d0cad 100644 --- a/tools/editor/editor_data.cpp +++ b/tools/editor/editor_data.cpp @@ -424,9 +424,182 @@ void EditorData::remove_custom_type(const String& p_type){ } +int EditorData::add_edited_scene(int p_at_pos) { + + if (p_at_pos<0) + p_at_pos=edited_scene.size(); + EditedScene es; + es.root=NULL; + es.history_current=-1; + es.version=0; + + if (p_at_pos==edited_scene.size()) + edited_scene.push_back(es); + else + edited_scene.insert(p_at_pos,es); + + if (current_edited_scene<0) + current_edited_scene=0; + return p_at_pos; +} + +void EditorData::move_edited_scene_index(int p_idx,int p_to_idx){ + + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + ERR_FAIL_INDEX(p_to_idx,edited_scene.size()); + SWAP(edited_scene[p_idx],edited_scene[p_to_idx]); +} +void EditorData::remove_scene(int p_idx){ + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + if (edited_scene[p_idx].root) + memdelete(edited_scene[p_idx].root); + + if (current_edited_scene>p_idx) + current_edited_scene--; + else if (current_edited_scene==p_idx && current_edited_scene>0) { + current_edited_scene--; + } + + edited_scene.remove(p_idx); + +} +int EditorData::get_edited_scene() const { + + return current_edited_scene; +} +void EditorData::set_edited_scene(int p_idx){ + + ERR_FAIL_INDEX(p_idx,edited_scene.size()); + current_edited_scene=p_idx; + //swap +} +Node* EditorData::get_edited_scene_root(){ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),NULL); + + return edited_scene[current_edited_scene].root; +} +void EditorData::set_edited_scene_root(Node* p_root) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].root=p_root; +} + +int EditorData::get_edited_scene_count() const { + + return edited_scene.size(); +} + +void EditorData::set_edited_scene_version(uint64_t version) { + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].version=version; + +} + +uint64_t EditorData::get_edited_scene_version() const{ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),0); + return edited_scene[current_edited_scene].version; + +} +uint64_t EditorData::get_scene_version(int p_idx) const{ + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),false); + return edited_scene[p_idx].version; +} + +String EditorData::get_scene_title(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); + if (!edited_scene[p_idx].root) + return "[empty]"; + if (edited_scene[p_idx].root->get_filename()=="") + return "[unsaved]"; + return edited_scene[p_idx].root->get_filename().get_file(); +} + + +String EditorData::get_scene_path(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String()); + + if (!edited_scene[p_idx].root) + return ""; + return edited_scene[p_idx].root->get_filename(); + +} + +void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary& p_custom) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + + EditedScene &es=edited_scene[current_edited_scene]; + es.selection = p_selection->get_selected_node_list(); + es.history_current=p_history->current; + es.history_stored=p_history->history; + es.editor_states=get_editor_states(); + es.custom_state=p_custom; + +} + +Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) { + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Dictionary()); + + EditedScene &es=edited_scene[current_edited_scene]; + + p_history->current=es.history_current; + p_history->history=es.history_stored; + + + p_selection->clear(); + for(List<Node*>::Element *E=es.selection.front();E;E=E->next()) { + p_selection->add_node(E->get()); + } + set_editor_states(es.editor_states); + + return es.custom_state; +} + + +void EditorData::set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata) { + + ERR_FAIL_INDEX(current_edited_scene,edited_scene.size()); + edited_scene[current_edited_scene].medatata=p_mdata; + +} + +Ref<ResourceImportMetadata> EditorData::get_edited_scene_import_metadata() const{ + + ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Ref<ResourceImportMetadata>()); + return edited_scene[current_edited_scene].medatata; +} + +void EditorData::clear_edited_scenes() { + + for(int i=0;i<edited_scene.size();i++) { + if (edited_scene[i].root) { + memdelete( edited_scene[i].root ); + } + } + edited_scene.clear(); +} + + + +void EditorData::set_plugin_window_layout(Ref<ConfigFile> p_layout) { + for(int i=0;i<editor_plugins.size();i++) { + editor_plugins[i]->set_window_layout(p_layout); + } +} + +void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) { + for(int i=0;i<editor_plugins.size();i++) { + editor_plugins[i]->get_window_layout(p_layout); + } +} EditorData::EditorData() { + current_edited_scene=-1; + // load_imported_scenes_from_globals(); } diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h index 42abb317d1..e3fdd52d01 100644 --- a/tools/editor/editor_data.h +++ b/tools/editor/editor_data.h @@ -55,6 +55,7 @@ class EditorHistory { Vector<Obj> path; int level; }; +friend class EditorData; Vector<History> history; int current; @@ -91,6 +92,8 @@ public: EditorHistory(); }; +class EditorSelection; + class EditorData { public: @@ -117,6 +120,21 @@ private: void _cleanup_history(); + struct EditedScene { + Node* root; + Dictionary editor_states; + Ref<ResourceImportMetadata> medatata; + List<Node*> selection; + Vector<EditorHistory::History> history_stored; + int history_current; + Dictionary custom_state; + uint64_t version; + + + }; + + Vector<EditedScene> edited_scene; + int current_edited_scene; public: @@ -146,6 +164,32 @@ public: void remove_custom_type(const String& p_type); const Map<String,Vector<CustomType> >& get_custom_types() const { return custom_types; } + + int add_edited_scene(int p_at_pos); + void move_edited_scene_index(int p_idx,int p_to_idx); + void remove_scene(int p_idx); + void set_edited_scene(int p_idx); + void set_edited_scene_root(Node* p_root); + void set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata); + Ref<ResourceImportMetadata> get_edited_scene_import_metadata() const; + int get_edited_scene() const; + Node* get_edited_scene_root(); + int get_edited_scene_count() const; + String get_scene_title(int p_idx) const; + String get_scene_path(int p_idx) const; + void set_edited_scene_version(uint64_t version); + uint64_t get_edited_scene_version() const; + uint64_t get_scene_version(int p_idx) const; + void clear_edited_scenes(); + + + void set_plugin_window_layout(Ref<ConfigFile> p_layout); + void get_plugin_window_layout(Ref<ConfigFile> p_layout); + + void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom); + Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history); + + EditorData(); }; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 688604ecfd..f55a3d6894 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -54,7 +54,7 @@ #include "register_exporters.h" #include "bind/core_bind.h" #include "io/zip_io.h" - +#include "io/config_file.h" // plugins #include "plugins/sprite_frames_editor_plugin.h" @@ -105,11 +105,24 @@ EditorNode *EditorNode::singleton=NULL; +void EditorNode::_update_scene_tabs() { + + scene_tabs->clear_tabs(); + for(int i=0;i<editor_data.get_edited_scene_count();i++) { + int current = editor_data.get_edited_scene(); + bool unsaved = (i==current)?saved_version!=editor_data.get_undo_redo().get_version():editor_data.get_scene_version(i)!=0; + scene_tabs->add_tab(editor_data.get_scene_title(i)+(unsaved?"(*)":"")); + } + + scene_tabs->set_current_tab(editor_data.get_edited_scene()); + +} + void EditorNode::_update_title() { String appname = Globals::get_singleton()->get("application/name"); String title = appname.empty()?String(VERSION_FULL_NAME):String(_MKSTR(VERSION_NAME) + String(" - ") + appname); - String edited = edited_scene?edited_scene->get_filename():String(); + String edited = editor_data.get_edited_scene_root()?editor_data.get_edited_scene_root()->get_filename():String(); if (!edited.empty()) title+=" - " + String(edited.get_file()); if (unsaved_cache) @@ -174,6 +187,11 @@ void EditorNode::_notification(int p_what) { _update_title(); } + if (last_checked_version!=editor_data.get_undo_redo().get_version()) { + _update_scene_tabs(); + last_checked_version=editor_data.get_undo_redo().get_version(); + } + //get_root_node()->set_rect(viewport->get_global_rect()); //update the circle @@ -231,6 +249,13 @@ void EditorNode::_notification(int p_what) { //import_monitor->scan_changes(); } + + if (p_what==NOTIFICATION_EXIT_TREE) { + + + editor_data.clear_edited_scenes(); + + } if (p_what==NOTIFICATION_READY) { VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport(),true); @@ -468,7 +493,7 @@ void EditorNode::_dialog_display_file_error(String p_file,Error p_error) { void EditorNode::_get_scene_metadata() { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) return; @@ -495,7 +520,7 @@ void EditorNode::_get_scene_metadata() { void EditorNode::_set_scene_metadata() { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) return; @@ -718,7 +743,7 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed, for(int i=0;i<scene->get_child_count();i++) { Node *n = scene->get_child(i); - if (n->get_owner()!=edited_scene) + if (n->get_owner()!=editor_data.get_edited_scene_root()) continue; _save_edited_subresources(n,processed,flags); } @@ -727,7 +752,7 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed, void EditorNode::_find_node_types(Node* p_node, int&count_2d, int&count_3d) { - if (p_node->is_type("Viewport") || (p_node!=get_edited_scene() && p_node->get_owner()!=get_edited_scene())) + if (p_node->is_type("Viewport") || (p_node!=editor_data.get_edited_scene_root() && p_node->get_owner()!=editor_data.get_edited_scene_root())) return; if (p_node->is_type("CanvasItem")) @@ -748,7 +773,7 @@ void EditorNode::_save_scene_with_preview(String p_file) { EditorProgress save("save","Saving Scene",4); save.step("Analyzing",0); - _find_node_types(get_edited_scene(),c2d,c3d); + _find_node_types(editor_data.get_edited_scene_root(),c2d,c3d); RID viewport; bool is2d; @@ -799,11 +824,11 @@ void EditorNode::_save_scene_with_preview(String p_file) { img.save_png(pfile); Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile); - print_line("img data is "+itos(imgdata.size())); + //print_line("img data is "+itos(imgdata.size())); - if (scene_import_metadata.is_null()) - scene_import_metadata = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ); - scene_import_metadata->set_option("thumbnail",imgdata); + if (editor_data.get_edited_scene_import_metadata().is_null()) + editor_data.set_edited_scene_import_metadata(Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ) ); + editor_data.get_edited_scene_import_metadata()->set_option("thumbnail",imgdata); //tamanio tel thumbnail if (screen!=-1) { @@ -817,7 +842,7 @@ void EditorNode::_save_scene_with_preview(String p_file) { void EditorNode::_save_scene(String p_file) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -851,7 +876,7 @@ void EditorNode::_save_scene(String p_file) { return; } - sdata->set_import_metadata(scene_import_metadata); + sdata->set_import_metadata(editor_data.get_edited_scene_import_metadata()); int flg=0; if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources")) flg|=ResourceSaver::FLAG_COMPRESS; @@ -867,7 +892,7 @@ void EditorNode::_save_scene(String p_file) { if (err==OK) { scene->set_filename( Globals::get_singleton()->localize_path(p_file) ); //EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type()); - saved_version=editor_data.get_undo_redo().get_version(); + set_current_version(editor_data.get_undo_redo().get_version()); _update_title(); } else { @@ -1055,7 +1080,7 @@ void EditorNode::_dialog_action(String p_file) { Node *base = selection.front()->get(); Map<Node*,Node*> reown; - reown[get_edited_scene()]=base; + reown[editor_data.get_edited_scene_root()]=base; Node *copy = base->duplicate_and_reown(reown); if (copy) { @@ -1150,7 +1175,7 @@ void EditorNode::_dialog_action(String p_file) { ml = Ref<MeshLibrary>( memnew( MeshLibrary )); } - MeshLibraryEditor::update_library_file(edited_scene,ml,true); + MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { @@ -1184,7 +1209,7 @@ void EditorNode::_dialog_action(String p_file) { ml = Ref<TileSet>( memnew( TileSet )); } - TileSetEditor::update_library_file(edited_scene,ml,true); + TileSetEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true); Error err = ResourceSaver::save(p_file,ml); if (err) { @@ -1325,15 +1350,15 @@ void EditorNode::_property_editor_back() { void EditorNode::_imported(Node *p_node) { - Node *scene = edited_scene; - set_edited_scene(p_node); - + Node *scene = editor_data.get_edited_scene_root(); +// add_edited_scene(p_node); +/* if (scene) { String path = scene->get_filename(); p_node->set_filename(path); memdelete(scene); } - +*/ } @@ -1377,7 +1402,7 @@ void EditorNode::_edit_current() { object_menu->set_disabled(false); resources_dock->add_resource(Ref<Resource>(current_res)); - top_pallete->set_current_tab(1); + //top_pallete->set_current_tab(1); } @@ -1394,7 +1419,7 @@ void EditorNode::_edit_current() { scene_tree_dock->set_selected(current_node); object_menu->get_popup()->clear(); - top_pallete->set_current_tab(0); + //top_pallete->set_current_tab(0); } @@ -1408,17 +1433,22 @@ void EditorNode::_edit_current() { if (main_plugin!=editor_plugin_screen) { // update screen main_plugin - if (editor_plugin_screen) - editor_plugin_screen->make_visible(false); - editor_plugin_screen=main_plugin; - editor_plugin_screen->edit(current_obj); - editor_plugin_screen->make_visible(true); + if (!changing_scene) { - for(int i=0;i<editor_table.size();i++) { - if (editor_table[i]==main_plugin) { - main_editor_tabs->set_current_tab(i); - break; + if (editor_plugin_screen) + editor_plugin_screen->make_visible(false); + editor_plugin_screen=main_plugin; + editor_plugin_screen->edit(current_obj); + + editor_plugin_screen->make_visible(true); + + + for(int i=0;i<editor_table.size();i++) { + if (editor_table[i]==main_plugin) { + main_editor_tabs->set_current_tab(i); + break; + } } } @@ -1527,10 +1557,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) { - if (p_current || (edited_scene && p_custom==edited_scene->get_filename())) { + if (p_current || (editor_data.get_edited_scene_root() && p_custom==editor_data.get_edited_scene_root()->get_filename())) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1592,7 +1622,7 @@ void EditorNode::_run(bool p_current,const String& p_custom) { if (unsaved_cache) { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene) { //only autosave if there is a scene obviously @@ -1644,8 +1674,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) { void EditorNode::_cleanup_scene() { - - Node *scene = edited_scene; +#if 0 + Node *scene = editor_data.get_edited_scene_root(); editor_selection->clear(); editor_data.clear_editor_states(); editor_history.clear(); @@ -1654,7 +1684,7 @@ void EditorNode::_cleanup_scene() { property_editor->edit(NULL); resources_dock->cleanup(); scene_import_metadata.unref(); - set_edited_scene(NULL); + //set_edited_scene(NULL); if (scene) { if (scene->get_filename()!="") { previous_scenes.push_back(scene->get_filename()); @@ -1680,7 +1710,7 @@ void EditorNode::_cleanup_scene() { } _update_title(); - +#endif } void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { @@ -1693,16 +1723,20 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { switch( p_option ) { case FILE_NEW_SCENE: { + /* if (!p_confirmed) { confirmation->get_ok()->set_text("Yes"); //confirmation->get_cancel()->show(); confirmation->set_text("Start a New Scene? (Current will be lost)"); confirmation->popup_centered_minsize(); break; - } + }*/ - _cleanup_scene(); + int idx = editor_data.add_edited_scene(-1); + _scene_tab_changed(idx); + + //_cleanup_scene(); } break; @@ -1722,7 +1756,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { //file->set_current_path(current_path); - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene) { file->set_current_path(scene->get_filename()); }; @@ -1755,10 +1789,25 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { open_request(previous_scenes.back()->get()); } break; + case FILE_CLOSE: { + + if (!p_confirmed) { + confirmation->get_ok()->set_text("Yes"); + //confirmation->get_cancel()->show(); + confirmation->set_text("Close scene? (Unsaved changes will be lost)"); + confirmation->popup_centered_minsize(); + break; + } + + _remove_edited_scene(); + + + + } break; case FILE_SAVE_SCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (scene && scene->get_filename()!="") { //_save_scene(scene->get_filename()); @@ -1769,7 +1818,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { }; case FILE_SAVE_AS_SCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1831,7 +1880,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_DUMP_STRINGS: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1875,7 +1924,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_SAVE_SUBSCENE: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); if (!scene) { @@ -1902,7 +1951,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { Node *tocopy = selection.front()->get(); - if (tocopy!=edited_scene && tocopy->get_filename()!="") { + if (tocopy!=editor_data.get_edited_scene_root() && tocopy->get_filename()!="") { current_option=-1; @@ -1936,7 +1985,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { file->set_title("Save Sub-Scene As.."); } break; case FILE_SAVE_OPTIMIZED: { - Node *scene = edited_scene; + Node *scene = editor_data.get_edited_scene_root(); #if 0 if (!scene) { @@ -1998,7 +2047,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { case FILE_EXPORT_MESH_LIBRARY: { - if (!edited_scene) { + if (!editor_data.get_edited_scene_root()) { current_option=-1; //confirmation->get_cancel()->hide(); @@ -2043,7 +2092,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { //import_subscene->popup_centered_ratio(); - if (!edited_scene) { + if (!editor_data.get_edited_scene_root()) { current_option=-1; //accept->get_cancel()->hide(); @@ -2569,30 +2618,54 @@ void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_ed _rebuild_import_menu(); } +void EditorNode::_remove_edited_scene() { + int new_index = editor_data.get_edited_scene(); + int old_index=new_index; + + if (new_index>0) { + new_index=new_index-1; + } else if (editor_data.get_edited_scene_count()>1) { + new_index=1; + } else { + editor_data.add_edited_scene(-1); + new_index=1; + } + _scene_tab_changed(new_index); + editor_data.remove_scene(old_index); + editor_data.get_undo_redo().clear_history(); + _update_title(); + _update_scene_tabs(); + + if (editor_data.get_edited_scene_count()==1) { + //make new scene appear saved + set_current_version(editor_data.get_undo_redo().get_version()); + unsaved_cache=false; + } +} void EditorNode::set_edited_scene(Node *p_scene) { - if (edited_scene) { - if (edited_scene->get_parent()==scene_root) - scene_root->remove_child(edited_scene); + if (get_editor_data().get_edited_scene_root()) { + if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root) + scene_root->remove_child(get_editor_data().get_edited_scene_root()); animation_editor->set_root(NULL); } - edited_scene=p_scene; - if (edited_scene && edited_scene->cast_to<Popup>()) - edited_scene->cast_to<Popup>()->show(); //show popups - scene_tree_dock->set_edited_scene(edited_scene); + get_editor_data().set_edited_scene_root(p_scene); + + if (p_scene && p_scene->cast_to<Popup>()) + p_scene->cast_to<Popup>()->show(); //show popups + scene_tree_dock->set_edited_scene(p_scene); if (get_tree()) - get_tree()->set_edited_scene_root(edited_scene); + get_tree()->set_edited_scene_root(p_scene); - if (edited_scene) { + if (p_scene) { if (p_scene->get_parent()!=scene_root) scene_root->add_child(p_scene); animation_editor->set_root(p_scene); } - - } + void EditorNode::_fetch_translatable_strings(const Object *p_object,Set<StringName>& strings) { @@ -2818,6 +2891,115 @@ Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_pres return OK; } + +Dictionary EditorNode::_get_main_scene_state() { + + Dictionary state; + state["main_tab"]=main_editor_tabs->get_current_tab(); + state["scene_tree_offset"]=scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_val(); + state["property_edit_offset"]=get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_val(); + state["saved_version"]=saved_version; + //print_line(" getting main tab: "+itos(state["main_tab"])); + return state; +} + +void EditorNode::_set_main_scene_state(Dictionary p_state) { + + //print_line("set current 7 "); + + if (p_state.has("main_tab")) { + int idx = p_state["main_tab"]; + int current=-1; + for(int i=0;i<editor_table.size();i++) { + if (editor_plugin_screen==editor_table[i]) { + current=i; + break; + } + } + + if (idx<2 && current<2) { + //only set tab for 2D and 3D + _editor_select(p_state["main_tab"]); + //print_line(" setting main tab: "+itos(p_state["main_tab"])); + } + } + + if (p_state.has("scene_tree_offset")) + scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["scene_tree_offset"]); + if (p_state.has("property_edit_offset")) + get_property_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["property_edit_offset"]); + + //print_line("set current 8 "); + + +} + +void EditorNode::set_current_version(uint64_t p_version) { + + saved_version=p_version; + editor_data.set_edited_scene_version(p_version); +} + +bool EditorNode::is_changing_scene() const { + return changing_scene; +} +void EditorNode::set_current_scene(int p_idx) { + + changing_scene=true; + editor_data.save_edited_scene_state(editor_selection,&editor_history,_get_main_scene_state()); + + if (get_editor_data().get_edited_scene_root()) { + if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root) + scene_root->remove_child(get_editor_data().get_edited_scene_root()); + animation_editor->set_root(NULL); + } + + //print_line("set current 2 "); + + editor_selection->clear(); + editor_data.set_edited_scene(p_idx); + + Node* new_scene = editor_data.get_edited_scene_root(); + + if (new_scene && new_scene->cast_to<Popup>()) + new_scene->cast_to<Popup>()->show(); //show popups + + //print_line("set current 3 "); + + scene_tree_dock->set_edited_scene(new_scene); + if (get_tree()) + get_tree()->set_edited_scene_root(new_scene); + + if (new_scene) { + if (new_scene->get_parent()!=scene_root) + scene_root->add_child(new_scene); + animation_editor->set_root(new_scene); + } + //print_line("set current 4 "); + + + Dictionary state = editor_data.restore_edited_scene_state(editor_selection,&editor_history); + _edit_current(); + + /*if (!unsaved) { + saved_version=editor_data.get_undo_redo().get_version(); + if (p_backwards) + saved_version--; + else + saved_version++; + print_line("was saved, updating version"); + } else { + saved_version=state["saved_version"]; + }*/ + //_set_main_scene_state(state); + + call_deferred("_set_main_scene_state",state); //do after everything else is done setting up + //print_line("set current 6 "); + changing_scene=false; + + +} + Error EditorNode::load_scene(const String& p_scene) { if (!is_inside_tree()) { @@ -2826,6 +3008,14 @@ Error EditorNode::load_scene(const String& p_scene) { } + for(int i=0;i<editor_data.get_edited_scene_count();i++) { + + if (editor_data.get_scene_path(i)==p_scene) { + _scene_tab_changed(i); + return OK; + } + } + load_errors->clear(); String lpath = Globals::get_singleton()->localize_path(p_scene); @@ -2841,7 +3031,20 @@ Error EditorNode::load_scene(const String& p_scene) { return ERR_FILE_NOT_FOUND; } - _cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded. + int prev = editor_data.get_edited_scene(); + int idx = editor_data.add_edited_scene(-1); + //print_line("load scene callback"); + //set_current_scene(idx); + + if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count()==2) { + _remove_edited_scene(); + } else { + _scene_tab_changed(idx); + } + + + + //_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded. Ref<PackedScene> sdata = ResourceLoader::load(lpath); if (!sdata.is_valid()) { @@ -2852,6 +3055,11 @@ Error EditorNode::load_scene(const String& p_scene) { accept->set_text("Error loading scene."); accept->popup_centered_minsize(); opening_prev=false; + + if (prev!=-1) { + set_current_scene(prev); + editor_data.remove_scene(idx); + } return ERR_FILE_NOT_FOUND; } @@ -2859,15 +3067,23 @@ Error EditorNode::load_scene(const String& p_scene) { if (!new_scene) { + sdata.unref(); current_option=-1; //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text("Error loading scene."); accept->popup_centered_minsize(); opening_prev=false; + if (prev!=-1) { + set_current_scene(prev); + editor_data.remove_scene(idx); + } return ERR_FILE_NOT_FOUND; } + //guess not needed in the end? + //new_scene->clear_internal_tree_resource_paths(); //make sure no internal tree paths to internal resources exist + /* Node *old_scene = edited_scene; _hide_top_editors(); @@ -2880,16 +3096,23 @@ Error EditorNode::load_scene(const String& p_scene) { memdelete(old_scene); } */ + set_edited_scene(new_scene); _get_scene_metadata(); + /* + editor_data.set_edited_scene_root(new_scene); + scene_tree_dock->set_selected(new_scene, true); property_editor->edit(new_scene); - scene_import_metadata = sdata->get_import_metadata(); + editor_data.set_edited_scene_root(new_scene); +*/ + editor_data.set_edited_scene_import_metadata( sdata->get_import_metadata() ); - editor_data.get_undo_redo().clear_history(); + +// editor_data.get_undo_redo().clear_history(); saved_version=editor_data.get_undo_redo().get_version(); _update_title(); - + _update_scene_tabs(); _add_to_recent_scenes(lpath); if (new_scene->has_meta("__editor_plugin_screen__")) { @@ -2908,7 +3131,7 @@ Error EditorNode::load_scene(const String& p_scene) { prev_scene->set_disabled(previous_scenes.size()==0); opening_prev=false; - top_pallete->set_current_tab(0); //always go to scene + //top_pallete->set_current_tab(0); //always go to scene push_item(new_scene); @@ -2919,8 +3142,9 @@ Error EditorNode::load_scene(const String& p_scene) { void EditorNode::open_request(const String& p_path) { - external_file=p_path; - _menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false); + load_scene(p_path); // as it will be opened in separate tab + //external_file=p_path; + //_menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false); } @@ -2981,15 +3205,15 @@ void EditorNode::_update_keying() { void EditorNode::_close_messages() { // left_split->set_dragger_visible(false); - old_split_ofs = left_split->get_split_offset(); - left_split->set_split_offset(0); + old_split_ofs = center_split->get_split_offset(); + center_split->set_split_offset(0); // scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,0); } void EditorNode::_show_messages() { // left_split->set_dragger_visible(true); - left_split->set_split_offset(old_split_ofs); + center_split->set_split_offset(old_split_ofs); // scene_root_parent->set_anchor_and_margin(MARGIN_BOTTOM,Control::ANCHOR_END,log->get_margin(MARGIN_TOP)); } @@ -3058,15 +3282,16 @@ void EditorNode::_open_recent_scene(int p_idx) { String path = "res://"+rc[p_idx]; - if (unsaved_cache) { + + /*if (unsaved_cache) { _recent_scene=rc[p_idx]; open_recent_confirmation->set_text("Discard current scene and open:\n'"+rc[p_idx]+"'"); open_recent_confirmation->get_label()->set_align(Label::ALIGN_CENTER); open_recent_confirmation->popup_centered(Size2(400,100)); return; - } + }*/ - load_scene(rc[p_idx]); + load_scene(path); } @@ -3110,12 +3335,6 @@ void EditorNode::_save_optimized() { #endif } -void EditorNode::_open_recent_scene_confirm() { - - load_scene(_recent_scene); - -} - void EditorNode::_update_recent_scenes() { String base="_"+Globals::get_singleton()->get_resource_path().replace("\\","::").replace("/","::"); @@ -3236,6 +3455,7 @@ void EditorNode::register_editor_types() { ObjectTypeDB::register_type<EditorScenePostImport>(); ObjectTypeDB::register_type<EditorScript>(); ObjectTypeDB::register_type<EditorFileDialog>(); + ObjectTypeDB::register_type<UndoRedo>(); //ObjectTypeDB::register_type<EditorImporter>(); @@ -3325,7 +3545,7 @@ void EditorNode::_bind_methods() { //ObjectTypeDB::bind_method("_import",&EditorNode::_import); // ObjectTypeDB::bind_method("_import_conflicts_solved",&EditorNode::_import_conflicts_solved); ObjectTypeDB::bind_method("_open_recent_scene",&EditorNode::_open_recent_scene); - ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm); +// ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm); ObjectTypeDB::bind_method("_save_optimized",&EditorNode::_save_optimized); ObjectTypeDB::bind_method(_MD("animation_panel_make_visible","enable"),&EditorNode::animation_panel_make_visible); @@ -3334,6 +3554,22 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_sources_changed",&EditorNode::_sources_changed); ObjectTypeDB::bind_method("_fs_changed",&EditorNode::_fs_changed); + ObjectTypeDB::bind_method("_dock_select_draw",&EditorNode::_dock_select_draw); + ObjectTypeDB::bind_method("_dock_select_input",&EditorNode::_dock_select_input); + ObjectTypeDB::bind_method("_dock_pre_popup",&EditorNode::_dock_pre_popup); + ObjectTypeDB::bind_method("_dock_split_dragged",&EditorNode::_dock_split_dragged); + ObjectTypeDB::bind_method("_save_docks",&EditorNode::_save_docks); + ObjectTypeDB::bind_method("_dock_popup_exit",&EditorNode::_dock_popup_exit); + ObjectTypeDB::bind_method("_dock_move_left",&EditorNode::_dock_move_left); + ObjectTypeDB::bind_method("_dock_move_right",&EditorNode::_dock_move_right); + + ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene); + ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version); + ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed); + ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state); + ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs); + + ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin); ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin); @@ -3414,12 +3650,402 @@ void EditorNode::show_warning(const String& p_text) { warning->popup_centered_minsize(); } +void EditorNode::_dock_select_input(const InputEvent& p_input) { + + if (p_input.type==InputEvent::MOUSE_BUTTON || p_input.type==InputEvent::MOUSE_MOTION) { + + Vector2 point(p_input.mouse_motion.x,p_input.mouse_motion.y); + + int nrect = -1; + for(int i=0;i<DOCK_SLOT_MAX;i++) { + if (dock_select_rect[i].has_point(point)) { + nrect=i; + break; + } + } + + + if (nrect!=dock_select_rect_over) { + dock_select->update(); + dock_select_rect_over=nrect; + + } + + + if (nrect==-1) + return; + + if (p_input.type==InputEvent::MOUSE_BUTTON && p_input.mouse_button.button_index==1 && p_input.mouse_button.pressed && dock_popup_selected!=nrect) { + Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control(); + if (dock) { + dock_slot[dock_popup_selected]->remove_child(dock); + } + if (dock_slot[dock_popup_selected]->get_tab_count()==0) { + dock_slot[dock_popup_selected]->hide(); + + } else { + + dock_slot[dock_popup_selected]->set_current_tab(0); + } + + print_line("performing reparent"); + dock_slot[nrect]->add_child(dock); + dock_popup_selected=nrect; + dock_slot[nrect]->set_current_tab(dock_slot[nrect]->get_tab_count()-1); + dock_slot[nrect]->show(); + dock_select->update(); + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<4;i++) { + bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count(); + if (in_use) + splits[i]->show(); + else + splits[i]->hide(); + } + + _save_docks(); + } + } +} + +void EditorNode::_dock_popup_exit() { + + dock_select_rect_over=-1; + dock_select->update(); +} + +void EditorNode::_dock_pre_popup(int p_which) { + + + dock_popup_selected=p_which; +} + +void EditorNode::_dock_move_left() { + + if (dock_popup_selected<0 || dock_popup_selected>=DOCK_SLOT_MAX) + return; + Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() ); + Control *prev = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()-1 ); + if (!current || !prev) + return; + dock_slot[dock_popup_selected]->move_child(current,prev->get_index()); + dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()-1 ); + dock_select->update(); + _save_docks(); + + +} + +void EditorNode::_dock_move_right() { + + Control *current = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab() ); + Control *next = dock_slot[dock_popup_selected]->get_tab_control( dock_slot[dock_popup_selected]->get_current_tab()+1 ); + if (!current || !next) + return; + dock_slot[dock_popup_selected]->move_child(next,current->get_index()); + dock_slot[dock_popup_selected]->set_current_tab( dock_slot[dock_popup_selected]->get_current_tab()+1 ); + dock_select->update(); + _save_docks(); +} + +void EditorNode::_dock_select_draw(){ + Size2 s = dock_select->get_size(); + s.y/=2.0; + s.x/=6.0; + + Color used=Color(0.6,0.6,0.6,0.8); + Color used_selected=Color(0.8,0.8,0.8,0.8); + Color tab_selected=Color(1,1,1,1); + Color unused=used; + unused.a=0.4; + Color unusable=unused; + unusable.a=0.1; + + Rect2 unr(s.x*2,0,s.x*2,s.y*2); + unr.pos+=Vector2(2,5); + unr.size-=Vector2(4,7); + + dock_select->draw_rect(unr,unusable); + + dock_tab_move_left->set_disabled(true); + dock_tab_move_right->set_disabled(true); + + if (dock_popup_selected!=-1 && dock_slot[dock_popup_selected]->get_tab_count()) { + + dock_tab_move_left->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()==0); + dock_tab_move_right->set_disabled(dock_slot[dock_popup_selected]->get_current_tab()>=dock_slot[dock_popup_selected]->get_tab_count()-1); + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + Vector2 ofs; + + switch(i) { + case DOCK_SLOT_LEFT_UL: { + + } break; + case DOCK_SLOT_LEFT_BL: { + ofs.y+=s.y; + } break; + case DOCK_SLOT_LEFT_UR: { + ofs.x+=s.x; + } break; + case DOCK_SLOT_LEFT_BR: { + ofs+=s; + } break; + case DOCK_SLOT_RIGHT_UL: { + ofs.x+=s.x*4; + } break; + case DOCK_SLOT_RIGHT_BL: { + ofs.x+=s.x*4; + ofs.y+=s.y; + + } break; + case DOCK_SLOT_RIGHT_UR: { + ofs.x+=s.x*4; + ofs.x+=s.x; + + } break; + case DOCK_SLOT_RIGHT_BR: { + ofs.x+=s.x*4; + ofs+=s; + + } break; + } + + Rect2 r(ofs,s); + dock_select_rect[i]=r; + r.pos+=Vector2(2,5); + r.size-=Vector2(4,7); + + + if (i==dock_select_rect_over) { + dock_select->draw_rect(r,used_selected); + } else if (dock_slot[i]->get_child_count()==0) { + dock_select->draw_rect(r,unused); + } else { + + dock_select->draw_rect(r,used); + } + + for(int j=0;j<MIN(3,dock_slot[i]->get_child_count());j++) { + int xofs = (r.size.width/3)*j; + Color c = used; + if (i==dock_popup_selected && (dock_slot[i]->get_current_tab()>3 || dock_slot[i]->get_current_tab()==j)) + c=tab_selected; + dock_select->draw_rect(Rect2(2+ofs.x+xofs,ofs.y,r.size.width/3-1,3),c); + } + + } +} + +void EditorNode::_save_docks() { + + Ref<ConfigFile> config; + config.instance(); + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + String names; + for(int j=0;j<dock_slot[i]->get_tab_count();j++) { + String name = dock_slot[i]->get_tab_control(j)->get_name(); + if (names!="") + names+=","; + names+=name; + } + + if (names!="") { + config->set_value("docks","dock_"+itos(i+1),names); + } + } + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + + if (splits[i]->is_visible()) { + config->set_value("docks","dock_split_"+itos(i+1),splits[i]->get_split_offset()); + } + } + + + HSplitContainer *h_splits[4]={ + left_l_hsplit, + left_r_hsplit, + main_hsplit, + right_hsplit, + }; + + for(int i=0;i<4;i++) { + + config->set_value("docks","dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset()); + } + + editor_data.get_plugin_window_layout(config); + + config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + +} + +void EditorNode::save_layout() { + + dock_drag_timer->start(); +} + +void EditorNode::_dock_split_dragged(int ofs) { + + dock_drag_timer->start(); +} + +void EditorNode::_load_docks() { + + Ref<ConfigFile> config; + config.instance(); + Error err = config->load(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + if (err!=OK) { + return; //no config + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + if (!config->has_section_key("docks","dock_"+itos(i+1))) + continue; + + Vector<String> names = String(config->get_value("docks","dock_"+itos(i+1))).split(","); + + for(int j=0;j<names.size();j++) { + + String name=names[j]; + //find it, in a horribly inefficient way + int atidx=-1; + Control *node=NULL; + for(int k=0;k<DOCK_SLOT_MAX;k++) { + if (!dock_slot[k]->has_node(name)) + continue; + node=dock_slot[k]->get_node(name)->cast_to<Control>(); + if (!node) + continue; + atidx=k; + break; + } + if (atidx==-1) //well, it's not anywhere + continue; + + if (atidx==j) { + node->raise(); + continue; + } + + + dock_slot[atidx]->remove_child(node); + + if (dock_slot[atidx]->get_tab_count()==0) { + dock_slot[atidx]->hide(); + + } + dock_slot[i]->add_child(node); + dock_slot[i]->show(); + } + + } + + VSplitContainer*splits[DOCK_SLOT_MAX/2]={ + left_l_vsplit, + left_r_vsplit, + right_l_vsplit, + right_r_vsplit, + }; + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + + if (!config->has_section_key("docks","dock_split_"+itos(i+1))) + continue; + + int ofs = config->get_value("docks","dock_split_"+itos(i+1)); + splits[i]->set_split_offset(ofs); + } + + HSplitContainer *h_splits[4]={ + left_l_hsplit, + left_r_hsplit, + main_hsplit, + right_hsplit, + }; + + for(int i=0;i<4;i++) { + if (!config->has_section_key("docks","dock_hsplit_"+itos(i+1))) + continue; + int ofs = config->get_value("docks","dock_hsplit_"+itos(i+1)); + h_splits[i]->set_split_offset(ofs); + } + + for(int i=0;i<DOCK_SLOT_MAX/2;i++) { + bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count(); + if (in_use) + splits[i]->show(); + else + splits[i]->hide(); + } + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + + if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) { + dock_slot[i]->set_current_tab(0); + } + } + + editor_data.set_plugin_window_layout(config); + +} + + +void EditorNode::_scene_tab_changed(int p_tab) { + + + //print_line("set current 1 "); + bool unsaved = (saved_version!=editor_data.get_undo_redo().get_version()); + //print_line("version: "+itos(editor_data.get_undo_redo().get_version())+", saved "+itos(saved_version)); + + if (p_tab==editor_data.get_edited_scene()) + return; //pointless + + uint64_t next_scene_version = editor_data.get_scene_version(p_tab); + + + + //print_line("scene tab changed???"); + editor_data.get_undo_redo().create_action("Switch Scene Tab"); + editor_data.get_undo_redo().add_do_method(this,"set_current_version",unsaved?saved_version:0); + editor_data.get_undo_redo().add_do_method(this,"set_current_scene",p_tab); + editor_data.get_undo_redo().add_do_method(scene_tabs,"set_current_tab",p_tab); + editor_data.get_undo_redo().add_do_method(this,"set_current_version",next_scene_version==0?editor_data.get_undo_redo().get_version()+1:next_scene_version); + + editor_data.get_undo_redo().add_undo_method(this,"set_current_version",next_scene_version); + editor_data.get_undo_redo().add_undo_method(this,"set_current_scene",editor_data.get_edited_scene()); + editor_data.get_undo_redo().add_undo_method(scene_tabs,"set_current_tab",editor_data.get_edited_scene()); + editor_data.get_undo_redo().add_undo_method(this,"set_current_version",saved_version); + editor_data.get_undo_redo().commit_action(); + +} EditorNode::EditorNode() { EditorHelp::generate_doc(); //before any editor classes are crated singleton=this; + last_checked_version=0; + changing_scene=false; FileAccess::set_backup_save(true); @@ -3507,26 +4133,162 @@ EditorNode::EditorNode() { gui_base->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END ); gui_base->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END ); gui_base->set_end( Point2(0,0) ); - + main_vbox = memnew( VBoxContainer ); gui_base->add_child(main_vbox); main_vbox->set_area_as_parent_rect(8); - menu_hb = memnew( HBoxContainer ); - main_vbox->add_child(menu_hb); + PanelContainer *top_dark_panel = memnew( PanelContainer ); + Ref<StyleBoxTexture> top_dark_sb; + top_dark_sb.instance();; + top_dark_sb->set_texture(theme->get_icon("PanelTop","EditorIcons")); + for(int i=0;i<4;i++) { + top_dark_sb->set_margin_size(Margin(i),3); + top_dark_sb->set_default_margin(Margin(i),0); + } + top_dark_sb->set_expand_margin_size(MARGIN_LEFT,20); + top_dark_sb->set_expand_margin_size(MARGIN_RIGHT,20); + + top_dark_panel->add_style_override("panel",top_dark_sb); + VBoxContainer *top_dark_vb = memnew( VBoxContainer ); + main_vbox->add_child(top_dark_panel); + top_dark_panel->add_child(top_dark_vb); - main_split = memnew( HSplitContainer ); - main_vbox->add_child(main_split); - main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); - left_split = memnew( VSplitContainer ); - main_split->add_child(left_split); - left_split->set_h_size_flags(Control::SIZE_EXPAND_FILL); - left_split->set_collapsed(false); + + menu_hb = memnew( HBoxContainer ); + top_dark_vb->add_child(menu_hb); + + scene_tabs=memnew( Tabs ); + scene_tabs->add_tab("unsaved"); + scene_tabs->set_tab_align(Tabs::ALIGN_CENTER); + scene_tabs->connect("tab_changed",this,"_scene_tab_changed"); + top_dark_vb->add_child(scene_tabs); + //left + left_l_hsplit = memnew( HSplitContainer ); + main_vbox->add_child(left_l_hsplit); + + left_l_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + left_l_vsplit = memnew( VSplitContainer ); + left_l_hsplit->add_child(left_l_vsplit); + dock_slot[DOCK_SLOT_LEFT_UL]=memnew( TabContainer ); + left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UL]); + dock_slot[DOCK_SLOT_LEFT_BL]=memnew( TabContainer ); + left_l_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BL]); + left_l_vsplit->hide(); + dock_slot[DOCK_SLOT_LEFT_UL]->hide(); + dock_slot[DOCK_SLOT_LEFT_BL]->hide(); + + left_r_hsplit = memnew( HSplitContainer ); + left_l_hsplit->add_child(left_r_hsplit); + left_r_vsplit = memnew( VSplitContainer ); + left_r_hsplit->add_child(left_r_vsplit); + dock_slot[DOCK_SLOT_LEFT_UR]=memnew( TabContainer ); + left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_UR]); + dock_slot[DOCK_SLOT_LEFT_BR]=memnew( TabContainer ); + left_r_vsplit->add_child(dock_slot[DOCK_SLOT_LEFT_BR]); + //left_r_vsplit->hide(); + //dock_slot[DOCK_SLOT_LEFT_UR]->hide(); + //dock_slot[DOCK_SLOT_LEFT_BR]->hide(); + + + main_hsplit = memnew( HSplitContainer ); + left_r_hsplit->add_child(main_hsplit); + //main_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); + + center_split = memnew( VSplitContainer ); + main_hsplit->add_child(center_split); + center_split->set_h_size_flags(Control::SIZE_EXPAND_FILL); + center_split->set_collapsed(false); + + right_hsplit = memnew( HSplitContainer ); + main_hsplit->add_child(right_hsplit); + + right_l_vsplit = memnew( VSplitContainer ); + right_hsplit->add_child(right_l_vsplit); + dock_slot[DOCK_SLOT_RIGHT_UL]=memnew( TabContainer ); + right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UL]); + dock_slot[DOCK_SLOT_RIGHT_BL]=memnew( TabContainer ); + right_l_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BL]); + + right_r_vsplit = memnew( VSplitContainer ); + right_hsplit->add_child(right_r_vsplit); + dock_slot[DOCK_SLOT_RIGHT_UR]=memnew( TabContainer ); + right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_UR]); + dock_slot[DOCK_SLOT_RIGHT_BR]=memnew( TabContainer ); + right_r_vsplit->add_child(dock_slot[DOCK_SLOT_RIGHT_BR]); + right_r_vsplit->hide(); + //dock_slot[DOCK_SLOT_RIGHT_UL]->hide(); + //dock_slot[DOCK_SLOT_RIGHT_BL]->hide(); + + left_l_vsplit->connect("dragged",this,"_dock_split_dragged"); + left_r_vsplit->connect("dragged",this,"_dock_split_dragged"); + right_l_vsplit->connect("dragged",this,"_dock_split_dragged"); + right_r_vsplit->connect("dragged",this,"_dock_split_dragged"); + + left_l_hsplit->connect("dragged",this,"_dock_split_dragged"); + left_r_hsplit->connect("dragged",this,"_dock_split_dragged"); + main_hsplit->connect("dragged",this,"_dock_split_dragged"); + right_hsplit->connect("dragged",this,"_dock_split_dragged"); + + + + dock_select_popoup = memnew( PopupPanel ); + gui_base->add_child(dock_select_popoup); + VBoxContainer *dock_vb = memnew( VBoxContainer ); + dock_select_popoup->add_child(dock_vb); + + HBoxContainer *dock_hb = memnew( HBoxContainer); + dock_tab_move_left = memnew( ToolButton ); + dock_tab_move_left->set_icon(theme->get_icon("Back","EditorIcons")); + dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE); + dock_tab_move_left->connect("pressed",this,"_dock_move_left"); + //dock_tab_move_left->set_h_size_flags(Control::SIZE_EXPAND_FILL); + dock_hb->add_child(dock_tab_move_left); + dock_hb->add_spacer(); + dock_tab_move_right = memnew( ToolButton ); + dock_tab_move_right->set_icon(theme->get_icon("Forward","EditorIcons")); + dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); + dock_tab_move_right->connect("pressed",this,"_dock_move_right"); + + //dock_tab_move_right->set_h_size_flags(Control::SIZE_EXPAND_FILL); + dock_hb->add_child(dock_tab_move_right); + dock_vb->add_child(dock_hb); + + dock_select = memnew( Control ); + dock_select->set_custom_minimum_size(Size2(128,64)); + dock_select->connect("input_event",this,"_dock_select_input"); + dock_select->connect("draw",this,"_dock_select_draw"); + dock_select->connect("mouse_exit",this,"_dock_popup_exit"); + dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL); + dock_vb->add_child(dock_select); + + + dock_select_popoup->set_child_rect(dock_vb); + dock_select_popoup->set_as_minsize(); + dock_select_rect_over=-1; + dock_popup_selected=-1; + //dock_select_popoup->set_(Size2(20,20)); + + for(int i=0;i<DOCK_SLOT_MAX;i++) { + dock_slot[i]->set_custom_minimum_size(Size2(250,250)); + dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL); + dock_slot[i]->set_popup(dock_select_popoup); + dock_slot[i]->connect("pre_popup_pressed",this,"_dock_pre_popup",varray(i)); + + //dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT); + } + + dock_drag_timer = memnew( Timer ); + add_child(dock_drag_timer); + dock_drag_timer->set_wait_time(0.5); + dock_drag_timer->set_one_shot(true); + dock_drag_timer->connect("timeout",this,"_save_docks"); top_split = memnew( VSplitContainer ); - left_split->add_child(top_split); + center_split->add_child(top_split); top_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); top_split->set_collapsed(true); @@ -3661,7 +4423,9 @@ EditorNode::EditorNode() { p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S); p->add_item("Save Scene As..",FILE_SAVE_AS_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_S); p->add_separator(); - p->add_item("Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P); + p->add_item("Close Scene",FILE_CLOSE,KEY_MASK_SHIFT+KEY_MASK_CTRL+KEY_W); + p->add_separator(); + p->add_item("Close Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P); p->add_submenu_item("Open Recent","RecentScenes",FILE_OPEN_RECENT); p->add_separator(); p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O); @@ -3895,45 +4659,47 @@ EditorNode::EditorNode() { - editor_hsplit = memnew( HSplitContainer ); - main_split->add_child(editor_hsplit); - editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //editor_hsplit = memnew( HSplitContainer ); + //main_split->add_child(editor_hsplit); + //editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor_vsplit = memnew( VSplitContainer ); - editor_hsplit->add_child(editor_vsplit); + //editor_vsplit = memnew( VSplitContainer ); + //editor_hsplit->add_child(editor_vsplit); - top_pallete = memnew( TabContainer ); + //top_pallete = memnew( TabContainer ); scene_tree_dock = memnew( SceneTreeDock(this,scene_root,editor_selection,editor_data) ); scene_tree_dock->set_name("Scene"); - top_pallete->add_child(scene_tree_dock); + //top_pallete->add_child(scene_tree_dock); + dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock); resources_dock = memnew( ResourcesDock(this) ); resources_dock->set_name("Resources"); - top_pallete->add_child(resources_dock); - top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //top_pallete->add_child(resources_dock); + dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(resources_dock); + //top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); - Control *editor_spacer = memnew( Control ); + /*Control *editor_spacer = memnew( Control ); editor_spacer->set_custom_minimum_size(Size2(260,200)); editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL); editor_vsplit->add_child( editor_spacer ); editor_spacer->add_child( top_pallete ); - top_pallete->set_area_as_parent_rect(); + top_pallete->set_area_as_parent_rect();*/ - prop_pallete = memnew( TabContainer ); + //prop_pallete = memnew( TabContainer ); - prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); + //prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL); - editor_spacer = memnew( Control ); + /*editor_spacer = memnew( Control ); editor_spacer->set_custom_minimum_size(Size2(260,200)); editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL); editor_vsplit->add_child( editor_spacer ); editor_spacer->add_child( prop_pallete ); - prop_pallete->set_area_as_parent_rect(); + prop_pallete->set_area_as_parent_rect();*/ VBoxContainer *prop_editor_base = memnew( VBoxContainer ); prop_editor_base->set_name("Inspector"); // Properties? - prop_pallete->add_child(prop_editor_base); + dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(prop_editor_base); HBoxContainer *prop_editor_hb = memnew( HBoxContainer ); prop_editor_base->add_child(prop_editor_hb); @@ -3975,14 +4741,15 @@ EditorNode::EditorNode() { scenes_dock = memnew( ScenesDock(this) ); scenes_dock->set_name("FileSystem"); - prop_pallete->add_child(scenes_dock); + dock_slot[DOCK_SLOT_LEFT_BR]->add_child(scenes_dock); + //prop_pallete->add_child(scenes_dock); scenes_dock->connect("open",this,"open_request"); scenes_dock->connect("instance",this,"_instance_request"); log = memnew( EditorLog ); - left_split->add_child(log); + center_split->add_child(log); log->connect("close_request",this,"_close_messages"); log->connect("show_request",this,"_show_messages"); //left_split->set_dragger_visible(false); @@ -3998,7 +4765,7 @@ EditorNode::EditorNode() { animation_vb->add_child(animation_editor); - left_split->connect("resized",this,"_vp_resized"); + center_split->connect("resized",this,"_vp_resized"); animation_editor->hide(); @@ -4348,8 +5115,8 @@ EditorNode::EditorNode() { } - edited_scene=NULL; - saved_version=0; + //edited_scene=NULL; + saved_version=1; unsaved_cache=true; _last_instanced_scene=NULL; @@ -4403,12 +5170,21 @@ EditorNode::EditorNode() { Node::set_human_readable_collision_renaming(true); + + // Ref<ImageTexture> it = gui_base->get_icon("logo","Icons"); // OS::get_singleton()->set_icon( it->get_data() ); for(int i=0;i<_init_callbacks.size();i++) _init_callbacks[i](); + editor_data.add_edited_scene(-1); + editor_data.set_edited_scene(0); + _update_scene_tabs(); + + _load_docks(); + + } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 365dff84ee..293da2031d 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -94,6 +94,8 @@ typedef void (*EditorNodeInitCallback)(); + + class EditorNode : public Node { OBJ_TYPE( EditorNode, Node ); @@ -123,6 +125,7 @@ class EditorNode : public Node { FILE_QUICK_OPEN_SCRIPT, FILE_RUN_SCRIPT, FILE_OPEN_PREV, + FILE_CLOSE, FILE_QUIT, FILE_EXTERNAL_OPEN_SCENE, EDIT_UNDO, @@ -168,19 +171,46 @@ class EditorNode : public Node { OBJECT_METHOD_BASE=500 }; + enum DockSlot { + DOCK_SLOT_LEFT_UL, + DOCK_SLOT_LEFT_BL, + DOCK_SLOT_LEFT_UR, + DOCK_SLOT_LEFT_BR, + DOCK_SLOT_RIGHT_UL, + DOCK_SLOT_RIGHT_BL, + DOCK_SLOT_RIGHT_UR, + DOCK_SLOT_RIGHT_BR, + DOCK_SLOT_MAX + }; - - Node *edited_scene; //scene being edited + //Node *edited_scene; //scene being edited Viewport *scene_root; //root of the scene being edited - Ref<ResourceImportMetadata> scene_import_metadata; + //Ref<ResourceImportMetadata> scene_import_metadata; Control* scene_root_parent; Control *gui_base; VBoxContainer *main_vbox; - HSplitContainer *main_split; - VSplitContainer *left_split; + + //split + + HSplitContainer *left_l_hsplit; + VSplitContainer *left_l_vsplit; + HSplitContainer *left_r_hsplit; + VSplitContainer *left_r_vsplit; + HSplitContainer *main_hsplit; + HSplitContainer *right_hsplit; + VSplitContainer *right_l_vsplit; + VSplitContainer *right_r_vsplit; + + VSplitContainer *center_split; + + //main tabs + + Tabs *scene_tabs; + + int old_split_ofs; VSplitContainer *top_split; HBoxContainer *bottom_hb; @@ -190,8 +220,9 @@ class EditorNode : public Node { TextureButton *anim_close; Panel *menu_panel; - HSplitContainer *editor_hsplit; - VSplitContainer *editor_vsplit; + + //HSplitContainer *editor_hsplit; + //VSplitContainer *editor_vsplit; HBoxContainer *menu_hb; Control *viewport; MenuButton *file_menu; @@ -249,8 +280,8 @@ class EditorNode : public Node { String current_path; MenuButton *update_menu; ToolButton *sources_button; - TabContainer *prop_pallete; - TabContainer *top_pallete; + //TabContainer *prop_pallete; + //TabContainer *top_pallete; String defer_load_scene; String defer_translatable; String defer_optimize; @@ -277,6 +308,16 @@ class EditorNode : public Node { ProgressDialog *progress_dialog; BackgroundProgress *progress_hb; + TabContainer *dock_slot[DOCK_SLOT_MAX]; + Rect2 dock_select_rect[DOCK_SLOT_MAX]; + int dock_select_rect_over; + PopupPanel *dock_select_popoup; + Control *dock_select; + ToolButton *dock_tab_move_left; + ToolButton *dock_tab_move_right; + int dock_popup_selected; + Timer *dock_drag_timer; + String _tmp_import_path; EditorImportExport *editor_import_export; @@ -287,8 +328,10 @@ class EditorNode : public Node { bool reference_resource_mem; bool save_external_resources_mem; uint64_t saved_version; + uint64_t last_checked_version; bool unsaved_cache; String open_navigate; + bool changing_scene; uint32_t circle_step_msec; uint64_t circle_step_frame; @@ -338,6 +381,7 @@ class EditorNode : public Node { void _set_scene_metadata(); void _get_scene_metadata(); void _update_title(); + void _update_scene_tabs(); void _close_messages(); void _show_messages(); void _vp_resized(); @@ -365,7 +409,7 @@ class EditorNode : public Node { void _add_to_recent_scenes(const String& p_scene); void _update_recent_scenes(); void _open_recent_scene(int p_idx); - void _open_recent_scene_confirm(); + //void _open_recent_scene_confirm(); String _recent_scene; bool convert_old; @@ -394,7 +438,7 @@ class EditorNode : public Node { void _cleanup_scene(); - + void _remove_edited_scene(); bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags); bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags); void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags); @@ -417,6 +461,20 @@ class EditorNode : public Node { bool _find_scene_in_use(Node* p_node,const String& p_path) const; + void _dock_select_input(const InputEvent& p_input); + void _dock_move_left(); + void _dock_move_right(); + void _dock_select_draw(); + void _dock_pre_popup(int p_which); + void _dock_split_dragged(int ofs); + void _dock_popup_exit(); + void _scene_tab_changed(int p_tab); + + Dictionary _get_main_scene_state(); + void _set_main_scene_state(Dictionary p_state); + + void _save_docks(); + void _load_docks(); protected: void _notification(int p_what); @@ -451,7 +509,7 @@ public: void open_request(const String& p_path); - void set_edited_scene(Node *p_scene); + bool is_changing_scene() const; static EditorLog *get_log() { return singleton->log; } @@ -464,7 +522,9 @@ public: void hide_animation_player_editors(); void animation_panel_make_visible(bool p_visible); - Node *get_edited_scene() { return edited_scene; } + void set_edited_scene(Node *p_scene); + + Node *get_edited_scene() { return editor_data.get_edited_scene_root(); } Viewport *get_scene_root() { return scene_root; } //root of the scene being edited Error save_optimized_copy(const String& p_scene,const String& p_preset); @@ -473,6 +533,9 @@ public: Error load_scene(const String& p_scene); Error load_resource(const String& p_scene); + void set_current_version(uint64_t p_version); + void set_current_scene(int p_idx); + static EditorData& get_editor_data() { return singleton->editor_data; } static VSplitContainer *get_top_split() { return singleton->top_split; } @@ -519,6 +582,9 @@ public: bool is_scene_in_use(const String& p_path); void scan_import_changes(); + + void save_layout(); + EditorNode(); ~EditorNode(); void get_singleton(const char* arg1, bool arg2); diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp index e6b8ee0993..04c34d9a88 100644 --- a/tools/editor/editor_plugin.cpp +++ b/tools/editor/editor_plugin.cpp @@ -197,6 +197,13 @@ bool EditorPlugin::get_remove_list(List<Node*> *p_list) { void EditorPlugin::restore_global_state() {} void EditorPlugin::save_global_state() {} +void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + +} + +void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + +} void EditorPlugin::_bind_methods() { diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h index a9e6b1be49..0f3a1e2e3c 100644 --- a/tools/editor/editor_plugin.h +++ b/tools/editor/editor_plugin.h @@ -32,7 +32,7 @@ #include "scene/main/node.h" #include "scene/resources/texture.h" #include "undo_redo.h" - +#include "io/config_file.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -90,6 +90,8 @@ public: virtual void apply_changes() ; // if changes are pending in editor, apply them virtual void get_breakpoints(List<String> *p_breakpoints); virtual bool get_remove_list(List<Node*> *p_list); + virtual void set_window_layout(Ref<ConfigFile> p_layout); + virtual void get_window_layout(Ref<ConfigFile> p_layout); virtual void restore_global_state(); virtual void save_global_state(); diff --git a/tools/editor/editor_run_script.cpp b/tools/editor/editor_run_script.cpp index 5f8598d052..90581374f6 100644 --- a/tools/editor/editor_run_script.cpp +++ b/tools/editor/editor_run_script.cpp @@ -18,7 +18,7 @@ void EditorScript::add_root_node(Node *p_node) { return; } - editor->set_edited_scene(p_node); +// editor->set_edited_scene(p_node); } Node *EditorScript::get_scene() { diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 361a86b88e..0df9fcadef 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -433,9 +433,11 @@ void EditorSettings::_load_defaults() { set("text_editor/idle_parse_delay",2); set("text_editor/create_signal_callbacks",true); set("text_editor/autosave_interval_secs",0); + set("text_editor/font",""); hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt"); set("text_editor/auto_brace_complete", false); + set("text_editor/restore_scripts_on_load",true); set("scenetree_editor/duplicate_node_name_num_separator",0); diff --git a/tools/editor/groups_editor.cpp b/tools/editor/groups_editor.cpp index ed76f54562..2e82854014 100644 --- a/tools/editor/groups_editor.cpp +++ b/tools/editor/groups_editor.cpp @@ -39,6 +39,9 @@ void GroupsEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { connect("confirmed", this,"_close"); } + if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("confirmed", this,"_close"); + } } void GroupsEditor::_close() { diff --git a/tools/editor/icons/icon_back_disabled.png b/tools/editor/icons/icon_back_disabled.png Binary files differnew file mode 100644 index 0000000000..31aab496e2 --- /dev/null +++ b/tools/editor/icons/icon_back_disabled.png diff --git a/tools/editor/icons/icon_panel_top.png b/tools/editor/icons/icon_panel_top.png Binary files differnew file mode 100644 index 0000000000..20e67fad1a --- /dev/null +++ b/tools/editor/icons/icon_panel_top.png diff --git a/tools/editor/icons/icon_tab_menu.png b/tools/editor/icons/icon_tab_menu.png Binary files differnew file mode 100644 index 0000000000..29edd02f01 --- /dev/null +++ b/tools/editor/icons/icon_tab_menu.png diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 2e5a6f8a81..2139513025 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -105,7 +105,7 @@ public: _EditorMeshImportOptions() { generate_tangents=true; - generate_normals=true; + generate_normals=false; flip_faces=false; smooth_shading=false; weld_vertices=true; diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index fef5890f11..f2738f0a62 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -150,8 +150,56 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { _tool_select(TOOL_MOVE); if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_E) _tool_select(TOOL_ROTATE); - if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_ALL && can_move_pivot) - drag=DRAG_PIVOT; + if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_V && drag==DRAG_NONE && can_move_pivot) { + if (p_ev.key.mod.shift) { + //move drag pivot + drag=DRAG_PIVOT; + } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) { + + List<Node*> &selection = editor_selection->get_selected_node_list(); + + Vector2 mouse_pos = viewport->get_local_mouse_pos(); + if (selection.size() && viewport->get_rect().has_point(mouse_pos)) { + //just in case, make it work if over viewport + mouse_pos=transform.affine_inverse().xform(mouse_pos); + mouse_pos=snap_point(mouse_pos); + + undo_redo->create_action("Move Pivot"); + + for(List<Node*>::Element *E=selection.front();E;E=E->next()) { + + Node2D *n2d = E->get()->cast_to<Node2D>(); + + if (n2d && n2d->edit_has_pivot()) { + + Vector2 offset = n2d->edit_get_pivot(); + Vector2 gpos = n2d->get_global_pos(); + + Vector2 motion_ofs = gpos-mouse_pos; + + undo_redo->add_do_method(n2d,"set_global_pos",mouse_pos); + undo_redo->add_do_method(n2d,"edit_set_pivot",offset+n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); + undo_redo->add_undo_method(n2d,"set_global_pos",gpos); + undo_redo->add_undo_method(n2d,"edit_set_pivot",offset); + for(int i=0;i<n2d->get_child_count();i++) { + Node2D *n2dc = n2d->get_child(i)->cast_to<Node2D>(); + if (!n2dc) + continue; + + undo_redo->add_do_method(n2dc,"set_global_pos",n2dc->get_global_pos()); + undo_redo->add_undo_method(n2dc,"set_global_pos",n2dc->get_global_pos()); + + } + + } + + } + + undo_redo->commit_action(); + } + + } + } } @@ -1685,7 +1733,7 @@ void CanvasItemEditor::_viewport_draw() { viewport->draw_line(endpoints[i],endpoints[(i+1)%4],c,2); } - if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE)) { //kind of sucks + if (single && (tool==TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE)) { //kind of sucks if (canvas_item->cast_to<Node2D>()) { @@ -2854,7 +2902,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { hb->add_child(select_button); select_button->connect("pressed",this,"_tool_select",make_binds(TOOL_SELECT)); select_button->set_pressed(true); - select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Move Pivot (while moving)"); + select_button->set_tooltip("Select Mode (Q)\n"+keycode_get_string(KEY_MASK_CMD)+"Drag: Rotate\nAlt+Drag: Move\nPress 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."); move_button = memnew( ToolButton ); move_button->set_toggle_mode(true); diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp index d858f3b896..0df906117e 100644 --- a/tools/editor/plugins/multimesh_editor_plugin.cpp +++ b/tools/editor/plugins/multimesh_editor_plugin.cpp @@ -305,7 +305,7 @@ void MultiMeshEditor::edit(MultiMeshInstance *p_multimesh) { void MultiMeshEditor::_browse(bool p_source) { browsing_source=p_source; - std->get_tree()->set_marked(node,false); + std->get_scene_tree()->set_marked(node,false); std->popup_centered_ratio(); if (p_source) std->set_title("Select a Source Mesh:"); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index f5ba6a08e6..71ce040b05 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -38,10 +38,12 @@ #include "os/file_access.h" #include "scene/main/viewport.h" #include "os/keyboard.h" -/*** SCRIPT EDITOR ****/ +#include "os/input.h" +/*** SCRIPT EDITOR ****/ +#define SORT_SCRIPT_LIST void ScriptEditorQuickOpen::popup(const Vector<String>& p_functions, bool p_dontclear) { @@ -118,6 +120,8 @@ void ScriptEditorQuickOpen::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { connect("confirmed",this,"_confirmed"); + + } } @@ -286,8 +290,19 @@ void ScriptTextEditor::reload_text() { ERR_FAIL_COND(script.is_null()) ; - get_text_edit()->set_text(script->get_source_code()); - get_text_edit()->clear_undo_history(); + TextEdit *te = get_text_edit(); + int column = te->cursor_get_column(); + int row = te->cursor_get_line(); + int h = te->get_h_scroll(); + int v = te->get_v_scroll(); + + te->set_text(script->get_source_code()); + te->clear_undo_history(); + te->cursor_set_line(row); + te->cursor_set_column(column); + te->set_h_scroll(h); + te->set_v_scroll(v); + _line_col_changed(); } @@ -296,12 +311,11 @@ void ScriptTextEditor::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { - _update_name(); + //emit_signal("name_changed"); } } -void ScriptTextEditor::_update_name() { - +String ScriptTextEditor::get_name() { String name; if (script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { @@ -314,21 +328,20 @@ void ScriptTextEditor::_update_name() { else name=script->get_type()+"("+itos(script->get_instance_ID())+")"; + return name; - if (name!=String(get_name())) { +} - set_name(name); +Ref<Texture> ScriptTextEditor::get_icon() { + if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) { + return get_parent_control()->get_icon(script->get_type(),"EditorIcons"); } - if (!has_meta("_tab_icon")) { - if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) { - set_meta("_tab_icon",get_parent_control()->get_icon(script->get_type(),"EditorIcons")); - } - } + return Ref<Texture>(); +} -} void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { @@ -344,8 +357,7 @@ void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) { get_text_edit()->tag_saved_version(); - _update_name(); - + emit_signal("name_changed"); _line_col_changed(); } @@ -384,7 +396,7 @@ void ScriptTextEditor::_validate_script() { te->set_line_as_marked(i,line==i); } - _update_name(); + emit_signal("name_changed"); } @@ -418,6 +430,10 @@ void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>* } } +void ScriptTextEditor::_bind_methods() { + + ADD_SIGNAL(MethodInfo("name_changed")); +} ScriptTextEditor::ScriptTextEditor() { @@ -492,11 +508,15 @@ void ScriptEditor::_close_current_tab() { memdelete(current); if (idx>=tab_container->get_child_count()) idx=tab_container->get_child_count()-1; - if (idx>=0) + if (idx>=0) { tab_container->set_current_tab(idx); + //script_list->select(idx); + } - _update_window_menu(); - _save_files_state(); + + + _update_script_names(); + EditorNode::get_singleton()->save_layout(); } @@ -587,10 +607,10 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource>& p_res) { ste->get_text_edit()->tag_saved_version(); } - ste->_update_name(); - } + _update_script_names(); + } bool ScriptEditor::_test_script_times_on_disk() { @@ -1045,7 +1065,7 @@ void ScriptEditor::_menu_option(int p_option) { if (text != "") editor->emit_signal("request_help", text); } break; - case WINDOW_CLOSE: { + case FILE_CLOSE: { if (current->get_text_edit()->get_version()!=current->get_text_edit()->get_saved_version()) { erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\""); erase_tab_confirm->popup_centered_minsize(); @@ -1057,16 +1077,18 @@ void ScriptEditor::_menu_option(int p_option) { if (tab_container->get_current_tab()>0) { tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()-1); + script_list->call_deferred("select",tab_container->get_current_tab()-1); tab_container->move_child(current,tab_container->get_current_tab()-1); - _update_window_menu(); + _update_script_names(); } } break; case WINDOW_MOVE_RIGHT: { if (tab_container->get_current_tab()<tab_container->get_child_count()-1) { tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()+1); + script_list->call_deferred("select",tab_container->get_current_tab()+1); tab_container->move_child(current,tab_container->get_current_tab()+1); - _update_window_menu(); + _update_script_names(); } @@ -1076,6 +1098,8 @@ void ScriptEditor::_menu_option(int p_option) { if (p_option>=WINDOW_SELECT_BASE) { tab_container->set_current_tab(p_option-WINDOW_SELECT_BASE); + script_list->select(p_option-WINDOW_SELECT_BASE); + } } } @@ -1096,6 +1120,8 @@ void ScriptEditor::_notification(int p_what) { editor->connect("stop_pressed",this,"_editor_stop"); editor->connect("script_add_function_request",this,"_add_callback"); editor->connect("resource_saved",this,"_res_saved_callback"); + script_list->connect("item_selected",this,"_script_selected"); + script_split->connect("dragged",this,"_script_split_dragged"); autosave_timer->connect("timeout",this,"_autosave_scripts"); { float autosave_time = EditorSettings::get_singleton()->get("text_editor/autosave_interval_secs"); @@ -1113,7 +1139,8 @@ void ScriptEditor::_notification(int p_what) { } if (p_what==NOTIFICATION_READY) { - _update_window_menu(); + + get_tree()->connect("tree_changed",this,"_tree_changed"); } if (p_what==NOTIFICATION_EXIT_TREE) { @@ -1153,10 +1180,11 @@ static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_ Dictionary ScriptEditor::get_state() const { - apply_scripts(); - Dictionary state; +// apply_scripts(); + Dictionary state; +#if 0 Array paths; int open=-1; @@ -1189,12 +1217,12 @@ Dictionary ScriptEditor::get_state() const { if (open!=-1) state["current"]=open; - +#endif return state; } void ScriptEditor::set_state(const Dictionary& p_state) { - +#if 0 print_line("attempt set state: "+String(Variant(p_state))); if (!p_state.has("sources")) @@ -1231,6 +1259,7 @@ void ScriptEditor::set_state(const Dictionary& p_state) { if (p_state.has("current")) { tab_container->set_current_tab(p_state["current"]); } +#endif } void ScriptEditor::clear() { @@ -1254,68 +1283,17 @@ void ScriptEditor::clear() { int idx = tab_container->get_current_tab(); if (idx>=tab_container->get_child_count()) idx=tab_container->get_child_count()-1; - if (idx>=0) + if (idx>=0) { tab_container->set_current_tab(idx); - - _update_window_menu(); - - -} - -void ScriptEditor::_save_files_state() { - - return; //no thank you - - String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path(); - rpath=rpath.replace("\\","_-_"); - rpath=rpath.replace("/","_-_"); - rpath=rpath.replace(":","_"); - - Vector<String> scripts; - - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - - - Ref<Script> script = ste->get_edited_script(); - if (script->get_path()!="" && script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) { - - - scripts.push_back(script->get_path()); - } + script_list->select( script_list->find_metadata(idx) ); } - EditorSettings::get_singleton()->set(rpath,scripts); - EditorSettings::get_singleton()->save(); - -} - -void ScriptEditor::_load_files_state() { - return; - - String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path(); - rpath=rpath.replace("\\","_-_"); - rpath=rpath.replace("/","_-_"); - rpath=rpath.replace(":","_"); - - if (EditorSettings::get_singleton()->has(rpath)) { - - Vector<String> open_files=EditorSettings::get_singleton()->get("rpath"); - for(int i=0;i<open_files.size();i++) { - Ref<Script> scr = ResourceLoader::load(open_files[i]); - if (!scr.is_valid()) - continue; - editor->edit_resource(scr); - } - } } + void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) { for(int i=0;i<tab_container->get_child_count();i++) { @@ -1360,11 +1338,18 @@ void ScriptEditor::_bind_methods() { ObjectTypeDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip); ObjectTypeDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts); ObjectTypeDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed); + ObjectTypeDB::bind_method("_update_script_names",&ScriptEditor::_update_script_names); + ObjectTypeDB::bind_method("_tree_changed",&ScriptEditor::_tree_changed); + ObjectTypeDB::bind_method("_script_selected",&ScriptEditor::_script_selected); + ObjectTypeDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged); } void ScriptEditor::ensure_focus_current() { + if (!is_inside_tree()) + return; + int cidx = tab_container->get_current_tab(); if (cidx<0 || cidx>=tab_container->get_tab_count()); Control *c = tab_container->get_child(cidx)->cast_to<Control>(); @@ -1376,6 +1361,13 @@ void ScriptEditor::ensure_focus_current() { ste->get_text_edit()->grab_focus(); } +void ScriptEditor::_script_selected(int p_idx) { + + grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing + tab_container->set_current_tab(script_list->get_item_metadata(p_idx)); + grab_focus_block=false; +} + void ScriptEditor::ensure_select_current() { @@ -1386,8 +1378,66 @@ void ScriptEditor::ensure_select_current() { return; Ref<Script> script = ste->get_edited_script(); - ste->get_text_edit()->grab_focus(); + if (!grab_focus_block && is_inside_tree()) + ste->get_text_edit()->grab_focus(); + } + + +} + +void ScriptEditor::_find_scripts(Node* p_base, Node* p_current, Set<Ref<Script> > &used) { + if (p_current!=p_base && p_current->get_owner()!=p_base) + return; + + if (p_current->get_script_instance()) { + Ref<Script> scr = p_current->get_script(); + if (scr.is_valid()) + used.insert(scr); + } + + for(int i=0;i<p_current->get_child_count();i++) { + _find_scripts(p_base,p_current->get_child(i),used); + } + +} + + +void ScriptEditor::_update_script_names() { + + waiting_update_names=false; + Set<Ref<Script> > used; + Node* edited = EditorNode::get_singleton()->get_edited_scene(); + if (edited) { + _find_scripts(edited,edited,used); + } + + script_list->clear(); + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!ste) + continue; + + String script = ste->get_name(); + Ref<Texture> icon = ste->get_icon(); + String path = ste->get_edited_script()->get_path(); + script_list->add_item(script,icon); + + int index = script_list->get_item_count()-1; + + script_list->set_item_tooltip(index,path); + script_list->set_item_metadata(index,i); + if (used.has(ste->get_edited_script())) { + + script_list->set_item_custom_bg_color(index,Color(88/255.0,88/255.0,60/255.0)); + } + if (tab_container->get_current_tab()==index) { + script_list->select(index); + } } + + script_list->sort_items_by_text(); + } void ScriptEditor::edit(const Ref<Script>& p_script) { @@ -1425,9 +1475,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { if (ste->get_edited_script()==p_script) { - if (tab_container->get_current_tab()!=i) - tab_container->set_current_tab(i); - ste->get_text_edit()->grab_focus(); + if (!EditorNode::get_singleton()->is_changing_scene()) { + if (tab_container->get_current_tab()!=i) { + tab_container->set_current_tab(i); + script_list->select( script_list->find_metadata(i) ); + } + ste->get_text_edit()->grab_focus(); + } return; } } @@ -1440,9 +1494,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) { tab_container->add_child(ste); tab_container->set_current_tab(tab_container->get_tab_count()-1); - _update_window_menu(); - _save_files_state(); + + _update_script_names(); + ste->connect("name_changed",this,"_update_script_names"); + if (!restoring_layout) { + EditorNode::get_singleton()->save_layout(); + } } void ScriptEditor::save_external_data() { @@ -1502,51 +1560,6 @@ void ScriptEditor::_editor_stop() { debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); } -void ScriptEditor::_update_window_menu() { - - int idx=0; - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - idx++; - } - - if (idx==0) { - window_menu->set_disabled(true); - edit_menu->set_disabled(true); - search_menu->set_disabled(true); - return; - } else { - - window_menu->set_disabled(false); - edit_menu->set_disabled(false); - search_menu->set_disabled(false); - } - - window_menu->get_popup()->clear(); - window_menu->get_popup()->add_item("Close",WINDOW_CLOSE,KEY_MASK_CMD|KEY_W); - window_menu->get_popup()->add_separator(); - window_menu->get_popup()->add_item("Move Left",WINDOW_MOVE_LEFT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_LEFT); - window_menu->get_popup()->add_item("Move Right",WINDOW_MOVE_RIGHT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_RIGHT); - window_menu->get_popup()->add_separator(); - - idx=0; - for(int i=0;i<tab_container->get_child_count();i++) { - - ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); - if (!ste) - continue; - String n = ste->get_name(); - uint32_t accel=0; - if (idx<9) { - accel=KEY_MASK_ALT|KEY_MASK_CMD|(KEY_1+idx); - } - window_menu->get_popup()->add_item(n,WINDOW_SELECT_BASE+idx,accel); - idx++; - } -} void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const StringArray& p_args) { @@ -1582,6 +1595,8 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const ste->get_text_edit()->cursor_set_line(pos); ste->get_text_edit()->cursor_set_column(1); + script_list->select( script_list->find_metadata(i) ); + break; } @@ -1607,8 +1622,80 @@ void ScriptEditor::_autosave_scripts() { save_external_data(); } +void ScriptEditor::_tree_changed() { + + if (waiting_update_names) + return; + + waiting_update_names=true; + call_deferred("_update_script_names"); +} + +void ScriptEditor::_script_split_dragged(float) { + + EditorNode::get_singleton()->save_layout(); +} + +void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) { + + if (!bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { + return; + } + + if (!p_layout->has_section_key("ScriptEditor","open_scripts")) + return; + + Array scripts = p_layout->get_value("ScriptEditor","open_scripts"); + + restoring_layout=true; + + for(int i=0;i<scripts.size();i++) { + + String path = scripts[i]; + Ref<Script> scr = ResourceLoader::load(path); + if (scr.is_valid()) { + edit(scr); + } + } + + if (p_layout->has_section_key("ScriptEditor","split_offset")) { + script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset")); + } + + + restoring_layout=false; + +} + +void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) { + + Array scripts; + + for(int i=0;i<tab_container->get_child_count();i++) { + + ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>(); + if (!ste) + continue; + + String path = ste->get_edited_script()->get_path(); + if (!path.is_resource_file()) + continue; + + scripts.push_back(path); + + } + + p_layout->set_value("ScriptEditor","open_scripts",scripts); + p_layout->set_value("ScriptEditor","split_offset",script_split->get_split_offset()); + +} + + + ScriptEditor::ScriptEditor(EditorNode *p_editor) { + restoring_layout=false; + waiting_update_names=false; editor=p_editor; menu_hb = memnew( HBoxContainer ); @@ -1618,17 +1705,31 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { add_child(v_split); v_split->set_v_size_flags(SIZE_EXPAND_FILL); + script_split = memnew( HSplitContainer ); + v_split->add_child(script_split); + script_split->set_v_size_flags(SIZE_EXPAND_FILL); + + script_list = memnew( ItemList ); + script_split->add_child(script_list); + script_list->set_custom_minimum_size(Size2(140,0)); + tab_container = memnew( TabContainer ); - v_split->add_child(tab_container); - tab_container->set_v_size_flags(SIZE_EXPAND_FILL); + tab_container->set_tabs_visible(false); + script_split->add_child(tab_container); + + + tab_container->set_h_size_flags(SIZE_EXPAND_FILL); file_menu = memnew( MenuButton ); menu_hb->add_child(file_menu); file_menu->set_text("File"); file_menu->get_popup()->add_item("Open",FILE_OPEN); + file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_item("Save",FILE_SAVE,KEY_MASK_ALT|KEY_MASK_CMD|KEY_S); file_menu->get_popup()->add_item("Save As..",FILE_SAVE_AS); file_menu->get_popup()->add_item("Save All",FILE_SAVE_ALL,KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_S); + file_menu->get_popup()->add_separator(); + file_menu->get_popup()->add_item("Close",FILE_CLOSE,KEY_MASK_CMD|KEY_W); file_menu->get_popup()->connect("item_pressed", this,"_menu_option"); edit_menu = memnew( MenuButton ); @@ -1690,6 +1791,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true ); +#if 0 window_menu = memnew( MenuButton ); menu_hb->add_child(window_menu); window_menu->set_text("Window"); @@ -1700,6 +1802,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { window_menu->get_popup()->add_separator(); window_menu->get_popup()->connect("item_pressed", this,"_menu_option"); +#endif + help_menu = memnew( MenuButton ); menu_hb->add_child(help_menu); help_menu->set_text("Help"); @@ -1762,6 +1866,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { autosave_timer->set_one_shot(false); add_child(autosave_timer); + grab_focus_block=false; + // debugger_gui->hide(); } @@ -1826,20 +1932,24 @@ void ScriptEditorPlugin::apply_changes() { void ScriptEditorPlugin::restore_global_state() { - if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { - script_editor->_load_files_state(); - } } void ScriptEditorPlugin::save_global_state() { - if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) { - script_editor->_save_files_state(); - } +} +void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { + + script_editor->set_window_layout(p_layout); } +void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){ + + script_editor->get_window_layout(p_layout); +} + + void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) { diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index acfdd1e966..635db40c2f 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -38,7 +38,7 @@ #include "script_language.h" #include "tools/editor/code_editor.h" #include "scene/gui/split_container.h" - +#include "scene/gui/item_list.h" class ScriptEditorQuickOpen : public ConfirmationDialog { @@ -88,6 +88,7 @@ protected: virtual void _code_complete_script(const String& p_code, List<String>* r_options); virtual void _load_theme_settings(); void _notification(int p_what); + static void _bind_methods(); public: @@ -97,7 +98,8 @@ public: Vector<String> get_functions() ; void set_edited_script(const Ref<Script>& p_script); void reload_text(); - void _update_name(); + String get_name() ; + Ref<Texture> get_icon() ; ScriptTextEditor(); @@ -115,6 +117,7 @@ class ScriptEditor : public VBoxContainer { FILE_SAVE, FILE_SAVE_AS, FILE_SAVE_ALL, + FILE_CLOSE, EDIT_UNDO, EDIT_REDO, EDIT_CUT, @@ -123,12 +126,12 @@ class ScriptEditor : public VBoxContainer { EDIT_SELECT_ALL, EDIT_COMPLETE, EDIT_AUTO_INDENT, - EDIT_TOGGLE_COMMENT, - EDIT_MOVE_LINE_UP, - EDIT_MOVE_LINE_DOWN, - EDIT_INDENT_RIGHT, - EDIT_INDENT_LEFT, - EDIT_CLONE_DOWN, + EDIT_TOGGLE_COMMENT, + EDIT_MOVE_LINE_UP, + EDIT_MOVE_LINE_DOWN, + EDIT_INDENT_RIGHT, + EDIT_INDENT_LEFT, + EDIT_CLONE_DOWN, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_REPLACE, @@ -140,8 +143,7 @@ class ScriptEditor : public VBoxContainer { DEBUG_BREAK, DEBUG_CONTINUE, DEBUG_SHOW, - HELP_CONTEXTUAL, - WINDOW_CLOSE, + HELP_CONTEXTUAL, WINDOW_MOVE_LEFT, WINDOW_MOVE_RIGHT, WINDOW_SELECT_BASE=100 @@ -151,12 +153,13 @@ class ScriptEditor : public VBoxContainer { MenuButton *file_menu; MenuButton *edit_menu; MenuButton *search_menu; - MenuButton *window_menu; MenuButton *debug_menu; MenuButton *help_menu; Timer *autosave_timer; uint64_t idle; + ItemList *script_list; + HSplitContainer *script_split; TabContainer *tab_container; FindReplaceDialog *find_replace_dialog; GotoLineDialog *goto_line_dialog; @@ -171,6 +174,8 @@ class ScriptEditor : public VBoxContainer { VSplitContainer *v_split; + bool restoring_layout; + String _get_debug_tooltip(const String&p_text,Node *_ste); void _resave_scripts(const String& p_str); @@ -180,6 +185,8 @@ class ScriptEditor : public VBoxContainer { void _close_current_tab(); + bool grab_focus_block; + ScriptEditorQuickOpen *quick_open; @@ -199,6 +206,18 @@ class ScriptEditor : public VBoxContainer { void _editor_settings_changed(); void _autosave_scripts(); + void _update_script_names(); + + void _script_selected(int p_idx); + + void _find_scripts(Node* p_base, Node* p_current,Set<Ref<Script> >& used); + + void _tree_changed(); + + void _script_split_dragged(float); + + bool waiting_update_names; + static ScriptEditor *script_editor; protected: void _notification(int p_what); @@ -206,9 +225,6 @@ protected: public: static ScriptEditor *get_singleton() { return script_editor; } - void _save_files_state(); - void _load_files_state(); - void ensure_focus_current(); void apply_scripts() const; @@ -222,10 +238,13 @@ public: void get_breakpoints(List<String> *p_breakpoints); - void swap_lines(TextEdit *tx, int line1, int line2); + void swap_lines(TextEdit *tx, int line1, int line2); void save_external_data(); + void set_window_layout(Ref<ConfigFile> p_layout); + void get_window_layout(Ref<ConfigFile> p_layout); + ScriptEditor(EditorNode *p_editor); }; @@ -254,6 +273,9 @@ public: virtual void restore_global_state(); virtual void save_global_state(); + virtual void set_window_layout(Ref<ConfigFile> p_layout); + virtual void get_window_layout(Ref<ConfigFile> p_layout); + virtual void get_breakpoints(List<String> *p_breakpoints); diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 5c82973da4..017a26441d 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -71,22 +71,19 @@ void TileMapEditor::_canvas_mouse_exit() { } int TileMapEditor::get_selected_tile() const { - - TreeItem *item = palette->get_selected(); - if (!item) + int item = palette->get_current(); + if (item==-1) return TileMap::INVALID_CELL; - return item->get_metadata(0); + return palette->get_item_metadata(item); } void TileMapEditor::set_selected_tile(int p_tile) { - TreeItem *item = palette->get_root()->get_children(); - while (item) { - if ((int)item->get_metadata(0) == p_tile) { - item->select(0); - palette->ensure_cursor_is_visible(); + for (int i = 0; i < palette->get_item_count(); i++) { + if (palette->get_item_metadata(i).operator int() == p_tile) { + palette->select(i,true); + palette->ensure_current_is_visible(); break; } - item = item->get_next(); } } @@ -95,7 +92,7 @@ void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_f ERR_FAIL_COND(!node); node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose); } - + void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { ERR_FAIL_COND(!node); @@ -120,42 +117,78 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo } +void TileMapEditor::_set_display_mode(int p_mode) { + if (display_mode == p_mode) { + return; + } + + switch (p_mode) { + case DISPLAY_THUMBNAIL: { + button_thumbnail->set_pressed(true); + button_list->set_pressed(false); + } break; + case DISPLAY_LIST: { + button_thumbnail->set_pressed(false); + button_list->set_pressed(true); + } break; + } + + display_mode = p_mode; + + _update_palette(); +} + void TileMapEditor::_update_palette() { if (!node) return; - palette->clear();; + palette->clear(); Ref<TileSet> tileset=node->get_tileset(); if (!tileset.is_valid()) return; - - TreeItem *root = palette->create_item(); - palette->set_hide_root(true); List<int> tiles; tileset->get_tile_list(&tiles); - for(List<int>::Element *E=tiles.front();E;E=E->next()) { + if (display_mode == DISPLAY_THUMBNAIL) { + palette->set_max_columns(0); + palette->set_icon_mode(ItemList::ICON_MODE_TOP); + } else if (display_mode == DISPLAY_LIST) { + palette->set_max_columns(1); + palette->set_icon_mode(ItemList::ICON_MODE_LEFT); + } - TreeItem *tile = palette->create_item(root); + palette->set_max_text_lines(2); + + for(List<int>::Element *E=tiles.front();E;E=E->next()) { + palette->add_item(""); - tile->set_icon_max_width(0,64); Ref<Texture> tex = tileset->tile_get_texture(E->get()); + if (tex.is_valid()) { - tile->set_icon(0,tex); Rect2 region = tileset->tile_get_region(E->get()); - if (region!=Rect2()) - tile->set_icon_region(0,region); - } else if (tileset->tile_get_name(E->get())!="") - tile->set_text(0,tileset->tile_get_name(E->get())); - else - tile->set_text(0,"#"+itos(E->get())); + if (!region.has_no_area()) { + Image data = VS::get_singleton()->texture_get_data(tex->get_rid()); + + Ref<ImageTexture> img = memnew( ImageTexture ); + img->create_from_image(data.get_rect(region)); + + palette->set_item_icon(palette->get_item_count()-1, img); + } else { + palette->set_item_icon(palette->get_item_count()-1,tex); + } + } - tile->set_metadata(0,E->get()); + if (tileset->tile_get_name(E->get())!="") { + palette->set_item_text(palette->get_item_count()-1, tileset->tile_get_name(E->get())); + } else { + palette->set_item_text(palette->get_item_count()-1, "#"+itos(E->get())); + } + palette->set_item_metadata(palette->get_item_count()-1, E->get()); } } @@ -387,7 +420,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } if (tool==TOOL_ERASING) { - Point2i local =over_tile; + Point2i local =over_tile; if (!paint_undo.has(over_tile)) { paint_undo[over_tile]=_get_op_from_cell(over_tile); } @@ -641,7 +674,7 @@ void TileMapEditor::_canvas_draw() { Ref<Texture> t = ts->tile_get_texture(st); if (t.is_valid()) { Vector2 from = node->map_to_world(over_tile)+node->get_cell_draw_offset(); - Rect2 r = ts->tile_get_region(st); + Rect2 r = ts->tile_get_region(st); Size2 sc = xform.get_scale(); if (mirror_x->is_pressed()) sc.x*=-1.0; @@ -755,7 +788,7 @@ void TileMapEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed); ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons); ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false)); - + ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"),&TileMapEditor::_set_display_mode); } TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) @@ -777,7 +810,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { //ERR_FAIL_NULL(p_button); ToolButton *b=p_button->cast_to<ToolButton>(); //ERR_FAIL_COND(!b); - + mirror_x->set_block_signals(true); mirror_y->set_block_signals(true); transpose->set_block_signals(true); @@ -785,7 +818,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { rotate_90->set_block_signals(true); rotate_180->set_block_signals(true); rotate_270->set_block_signals(true); - + if (b == rotate_0) { mirror_x->set_pressed(false); mirror_y->set_pressed(false); @@ -806,7 +839,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) { mirror_y->set_pressed(true); transpose->set_pressed(true); } - + rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed()); rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed()); rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed()); @@ -833,8 +866,27 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { ec->set_custom_minimum_size(Size2(mw,0)); add_child(ec); + HBoxContainer *hb = memnew( HBoxContainer ); + add_child(hb); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + hb->add_spacer(true); + + button_thumbnail = memnew( ToolButton ); + button_thumbnail->set_toggle_mode(true); + button_thumbnail->set_pressed(true); + button_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons")); + hb->add_child(button_thumbnail); + button_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL)); + + button_list = memnew( ToolButton ); + button_list->set_toggle_mode(true); + button_list->set_pressed(false); + button_list->set_icon(p_editor->get_gui_base()->get_icon("FileList","EditorIcons")); + hb->add_child(button_list); + button_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST)); + // Add tile palette - palette = memnew( Tree ); + palette = memnew( ItemList ); palette->set_v_size_flags(SIZE_EXPAND_FILL); add_child(palette); @@ -886,7 +938,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270)); canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); - + rotate_0->set_pressed(true); tool=TOOL_NONE; selection_active=false; diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index eaa5c256d7..74d1573d0f 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -55,10 +55,18 @@ class TileMapEditor : public VBoxContainer { TOOL_PICKING }; + enum DisplayMode { + DISPLAY_THUMBNAIL, + DISPLAY_LIST + }; + Tool tool; Control *canvas_item_editor; - Tree *palette; + int display_mode; + ItemList *palette; + ToolButton *button_thumbnail; + ToolButton *button_list; EditorNode *editor; Panel *panel; TileMap *node; @@ -95,6 +103,7 @@ class TileMapEditor : public VBoxContainer { int get_selected_tile() const; void set_selected_tile(int p_tile); + void _set_display_mode(int p_mode); void _update_palette(); void _canvas_draw(); void _menu_option(int p_option); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 98e0df77f7..2fa8b98ff1 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1633,7 +1633,7 @@ CustomPropertyEditor::CustomPropertyEditor() { scene_tree = memnew( SceneTreeDialog ); add_child(scene_tree); scene_tree->connect("selected", this,"_node_path_selected"); - scene_tree->get_tree()->set_show_enabled_subscene(true); + scene_tree->get_scene_tree()->set_show_enabled_subscene(true); texture_preview = memnew( TextureFrame ); add_child( texture_preview); @@ -1915,6 +1915,7 @@ void PropertyEditor::_notification(int p_what) { } if (p_what==NOTIFICATION_EXIT_TREE) { + get_tree()->disconnect("node_removed",this,"_node_removed"); edit(NULL); } diff --git a/tools/editor/reparent_dialog.cpp b/tools/editor/reparent_dialog.cpp index d35316f67f..6d0c5b867e 100644 --- a/tools/editor/reparent_dialog.cpp +++ b/tools/editor/reparent_dialog.cpp @@ -41,6 +41,11 @@ void ReparentDialog::_notification(int p_what) { connect("confirmed", this,"_reparent"); } + if (p_what==NOTIFICATION_EXIT_TREE) { + + disconnect("confirmed", this,"_reparent"); + } + if (p_what==NOTIFICATION_DRAW) { //RID ci = get_canvas_item(); diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 432f60fa53..49cbebdb43 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -471,8 +471,18 @@ void SceneTreeDock::_notification(int p_what) { switch(p_what) { - case NOTIFICATION_ENTER_TREE: { + case NOTIFICATION_READY: { + + if (!first_enter) + break; + first_enter=false; + CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); + if (canvas_item_plugin) { + canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); + canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); + scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); + } static const char* button_names[TOOL_BUTTON_MAX]={ "New", "Add", @@ -487,19 +497,12 @@ void SceneTreeDock::_notification(int p_what) { "Remove", }; + + for(int i=0;i<TOOL_BUTTON_MAX;i++) tool_buttons[i]->set_icon(get_icon(button_names[i],"EditorIcons")); } break; - case NOTIFICATION_READY: { - - CanvasItemEditorPlugin *canvas_item_plugin = editor_data->get_editor("2D")->cast_to<CanvasItemEditorPlugin>(); - if (canvas_item_plugin) { - canvas_item_plugin->get_canvas_item_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); - canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); - scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); - } - } break; } } @@ -1367,7 +1370,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec add_child(import_subscene_dialog); import_subscene_dialog->connect("subscene_selected",this,"_import_subscene"); - + first_enter=true; } diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 34e8a00739..f0bbbad6be 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -90,6 +90,7 @@ class SceneTreeDock : public VBoxContainer { EditorFileDialog *file; EditorSubScene *import_subscene_dialog; + bool first_enter; void _create(); Node *scene_root; @@ -133,6 +134,7 @@ public: void set_selected(Node *p_node, bool p_emit_selected=false); void fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames); void perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims=NULL); + SceneTreeEditor *get_tree_editor() { return scene_tree; } SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelection *p_editor_selection,EditorData &p_editor_data); }; diff --git a/tools/editor/scene_tree_editor.cpp b/tools/editor/scene_tree_editor.cpp index 94eea969fe..fd841028a2 100644 --- a/tools/editor/scene_tree_editor.cpp +++ b/tools/editor/scene_tree_editor.cpp @@ -498,6 +498,7 @@ void SceneTreeEditor::_notification(int p_what) { get_tree()->disconnect("tree_changed",this,"_tree_changed"); get_tree()->disconnect("node_removed",this,"_node_removed"); + tree->disconnect("item_collapsed",this,"_cell_collapsed"); _update_tree(); } @@ -810,6 +811,11 @@ void SceneTreeDialog::_notification(int p_what) { connect("confirmed", this,"_select"); } + + if (p_what==NOTIFICATION_EXIT_TREE) { + disconnect("confirmed", this,"_select"); + + } if (p_what==NOTIFICATION_DRAW) { RID ci = get_canvas_item(); diff --git a/tools/editor/scene_tree_editor.h b/tools/editor/scene_tree_editor.h index 3e57ffb497..b05a52a2da 100644 --- a/tools/editor/scene_tree_editor.h +++ b/tools/editor/scene_tree_editor.h @@ -125,6 +125,9 @@ public: void update_tree() { _update_tree(); } + + Tree* get_scene_tree() { return tree; } + SceneTreeEditor(bool p_label=true,bool p_can_rename=false, bool p_can_open_instance=false); ~SceneTreeEditor(); @@ -150,7 +153,7 @@ protected: static void _bind_methods(); public: - SceneTreeEditor *get_tree() { return tree; } + SceneTreeEditor *get_scene_tree() { return tree; } SceneTreeDialog(); ~SceneTreeDialog(); diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 9568ccb645..5245f32b82 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -228,7 +228,7 @@ class DaeExporter: # imgpath="images/"+image.name+".png" self.writel(S_IMGS,1,'<image id="'+imgid+'" name="'+image.name+'">') - self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>"/>') + self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>') self.writel(S_IMGS,1,'</image>') self.image_cache[image]=imgid return imgid |