diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-05-14 23:48:23 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-05-14 23:48:45 -0300 |
commit | bed3efb17ede58a2bfc177b47cb3a49091aea30a (patch) | |
tree | 81708b952559e76d38902afac2663a77f8974688 /tools/editor | |
parent | 7913e792acd656469b29fb90be1dbb7c06a855ba (diff) |
New reworked AnimatedSprite!
-New SpriteFrames editor, with support for drag&drop, multiple animation
sets, animation speed and loop.
-New AnimatedSprite, with support for all the new features!
AnimatedSprite3D has not been updated yet.
-Added support for drag&drop to other editors, such as resourcepreload,
sample library, etc.
Diffstat (limited to 'tools/editor')
-rw-r--r-- | tools/editor/plugins/resource_preloader_editor_plugin.cpp | 108 | ||||
-rw-r--r-- | tools/editor/plugins/resource_preloader_editor_plugin.h | 5 | ||||
-rw-r--r-- | tools/editor/plugins/sample_library_editor_plugin.cpp | 124 | ||||
-rw-r--r-- | tools/editor/plugins/sample_library_editor_plugin.h | 4 | ||||
-rw-r--r-- | tools/editor/plugins/sprite_frames_editor_plugin.cpp | 537 | ||||
-rw-r--r-- | tools/editor/plugins/sprite_frames_editor_plugin.h | 32 | ||||
-rw-r--r-- | tools/editor/property_editor.cpp | 1 |
7 files changed, 734 insertions, 77 deletions
diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.cpp b/tools/editor/plugins/resource_preloader_editor_plugin.cpp index 01bb82834d..cc9aca1a25 100644 --- a/tools/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/tools/editor/plugins/resource_preloader_editor_plugin.cpp @@ -279,6 +279,106 @@ void ResourcePreloaderEditor::edit(ResourcePreloader* p_preloader) { +Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + TreeItem*ti =tree->get_item_at_pos(p_point); + if (!ti) + return Variant(); + + String name = ti->get_metadata(0); + + RES res = preloader->get_resource(name); + if (!res.is_valid()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(res,p_from); + +} + +bool ResourcePreloaderEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { + + + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + return r.is_valid(); + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + return true; + + } + return false; +} + +void ResourcePreloaderEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + if (r.is_valid()) { + + String basename; + if (r->get_name()!="") { + basename=r->get_name(); + } else if (r->get_path().is_resource_file()) { + basename = r->get_path().basename(); + } else { + basename="Resource"; + } + + String name=basename; + int counter=0; + while(preloader->has_resource(name)) { + counter++; + name=basename+"_"+itos(counter); + } + + undo_redo->create_action(TTR("Add Resource")); + undo_redo->add_do_method(preloader,"add_resource",name,r); + undo_redo->add_undo_method(preloader,"remove_resource",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + _files_load_request(files); + } +} + + + void ResourcePreloaderEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&ResourcePreloaderEditor::_input_event); @@ -289,6 +389,13 @@ void ResourcePreloaderEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_delete_confirm_pressed"),&ResourcePreloaderEditor::_delete_confirm_pressed); ObjectTypeDB::bind_method(_MD("_files_load_request"),&ResourcePreloaderEditor::_files_load_request); ObjectTypeDB::bind_method(_MD("_update_library"),&ResourcePreloaderEditor::_update_library); + + + ObjectTypeDB::bind_method(_MD("get_drag_data_fw"), &ResourcePreloaderEditor::get_drag_data_fw); + ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &ResourcePreloaderEditor::can_drop_data_fw); + ObjectTypeDB::bind_method(_MD("drop_data_fw"), &ResourcePreloaderEditor::drop_data_fw); + + } ResourcePreloaderEditor::ResourcePreloaderEditor() { @@ -326,6 +433,7 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() { tree->set_column_expand(1,true); tree->set_v_size_flags(SIZE_EXPAND_FILL); + tree->set_drag_forwarding(this); vbc->add_child(tree); dialog = memnew( AcceptDialog ); diff --git a/tools/editor/plugins/resource_preloader_editor_plugin.h b/tools/editor/plugins/resource_preloader_editor_plugin.h index 0bc94079a5..4f0cb4be37 100644 --- a/tools/editor/plugins/resource_preloader_editor_plugin.h +++ b/tools/editor/plugins/resource_preloader_editor_plugin.h @@ -67,6 +67,11 @@ class ResourcePreloaderEditor : public PanelContainer { UndoRedo *undo_redo; + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + + protected: void _notification(int p_what); void _input_event(InputEvent p_event); diff --git a/tools/editor/plugins/sample_library_editor_plugin.cpp b/tools/editor/plugins/sample_library_editor_plugin.cpp index 0ab45b45c4..8b03c4651d 100644 --- a/tools/editor/plugins/sample_library_editor_plugin.cpp +++ b/tools/editor/plugins/sample_library_editor_plugin.cpp @@ -290,6 +290,123 @@ void SampleLibraryEditor::edit(Ref<SampleLibrary> p_sample_library) { } +Variant SampleLibraryEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + TreeItem*ti =tree->get_item_at_pos(p_point); + if (!ti) + return Variant(); + + String name = ti->get_metadata(0); + + RES res = sample_library->get_sample(name); + if (!res.is_valid()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(res,p_from); + + +} + +bool SampleLibraryEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const { + + + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Sample> sample = r; + + if (sample.is_valid()) { + + return true; + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + for(int i=0;i<files.size();i++) { + String file = files[0]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (ftype!="Sample") { + return false; + } + + } + + return true; + + } + return false; +} + +void SampleLibraryEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) { + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Sample> sample = r; + + if (sample.is_valid()) { + + String basename; + if (sample->get_name()!="") { + basename=sample->get_name(); + } else if (sample->get_path().is_resource_file()) { + basename = sample->get_path().basename(); + } else { + basename="Sample"; + } + + String name=basename; + int counter=0; + while(sample_library->has_sample(name)) { + counter++; + name=basename+"_"+itos(counter); + } + + undo_redo->create_action(TTR("Add Sample")); + undo_redo->add_do_method(sample_library.operator->(),"add_sample",name,sample); + undo_redo->add_undo_method(sample_library.operator->(),"remove_sample",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + } + } + + + if (String(d["type"])=="files") { + + DVector<String> files = d["files"]; + + _file_load_request(files); + + } + +} void SampleLibraryEditor::_bind_methods() { @@ -301,6 +418,11 @@ void SampleLibraryEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_file_load_request"),&SampleLibraryEditor::_file_load_request); ObjectTypeDB::bind_method(_MD("_update_library"),&SampleLibraryEditor::_update_library); ObjectTypeDB::bind_method(_MD("_button_pressed"),&SampleLibraryEditor::_button_pressed); + + ObjectTypeDB::bind_method(_MD("get_drag_data_fw"), &SampleLibraryEditor::get_drag_data_fw); + ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &SampleLibraryEditor::can_drop_data_fw); + ObjectTypeDB::bind_method(_MD("drop_data_fw"), &SampleLibraryEditor::drop_data_fw); + } SampleLibraryEditor::SampleLibraryEditor() { @@ -349,6 +471,8 @@ SampleLibraryEditor::SampleLibraryEditor() { tree->set_column_expand(4,false); tree->set_column_expand(5,false); + tree->set_drag_forwarding(this); + dialog = memnew( ConfirmationDialog ); add_child( dialog ); diff --git a/tools/editor/plugins/sample_library_editor_plugin.h b/tools/editor/plugins/sample_library_editor_plugin.h index b46b9a7f3d..f9fb184b7c 100644 --- a/tools/editor/plugins/sample_library_editor_plugin.h +++ b/tools/editor/plugins/sample_library_editor_plugin.h @@ -68,6 +68,10 @@ class SampleLibraryEditor : public Panel { void _button_pressed(Object *p_item,int p_column, int p_id); + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + protected: void _notification(int p_what); void _input_event(InputEvent p_event); diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.cpp b/tools/editor/plugins/sprite_frames_editor_plugin.cpp index 796fc23d9a..b2f10ccaae 100644 --- a/tools/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/tools/editor/plugins/sprite_frames_editor_plugin.cpp @@ -49,6 +49,9 @@ void SpriteFramesEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { load->set_icon( get_icon("Folder","EditorIcons") ); _delete->set_icon( get_icon("Del","EditorIcons") ); + new_anim->set_icon( get_icon("New","EditorIcons") ); + remove_anim->set_icon( get_icon("Del","EditorIcons") ); + } if (p_what==NOTIFICATION_READY) { @@ -61,8 +64,9 @@ void SpriteFramesEditor::_notification(int p_what) { } } -void SpriteFramesEditor::_file_load_request(const DVector<String>& p_path) { +void SpriteFramesEditor::_file_load_request(const DVector<String>& p_path,int p_at_pos) { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); List< Ref<Texture> > resources; @@ -85,28 +89,32 @@ void SpriteFramesEditor::_file_load_request(const DVector<String>& p_path) { if (resources.empty()) { - print_line("added frames!"); + //print_line("added frames!"); return; } undo_redo->create_action(TTR("Add Frame")); - int fc=frames->get_frame_count(); + int fc=frames->get_frame_count(edited_anim); + + int count=0; for(List< Ref<Texture> >::Element *E=resources.front();E;E=E->next() ) { - undo_redo->add_do_method(frames,"add_frame",E->get()); - undo_redo->add_undo_method(frames,"remove_frame",fc++); + undo_redo->add_do_method(frames,"add_frame",edited_anim,E->get(),p_at_pos==-1?-1:p_at_pos+count); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,p_at_pos==-1?fc:p_at_pos); + count++; } undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); - print_line("added frames!"); + //print_line("added frames!"); } void SpriteFramesEditor::_load_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); loading_scene=false; file->clear_filters(); @@ -160,19 +168,21 @@ void SpriteFramesEditor::_item_edited() { void SpriteFramesEditor::_delete_confirm_pressed() { - if (!tree->get_selected()) + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) return; sel-=1; - if (sel<0 && frames->get_frame_count()) + if (sel<0 && frames->get_frame_count(edited_anim)) sel=0; - int to_remove = tree->get_selected()->get_metadata(0); + int to_remove = tree->get_current(); sel=to_remove; - Ref<Texture> r = frames->get_frame(to_remove); + Ref<Texture> r = frames->get_frame(edited_anim,to_remove); undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"remove_frame",to_remove); - undo_redo->add_undo_method(frames,"add_frame",r,to_remove); + undo_redo->add_do_method(frames,"remove_frame",edited_anim,to_remove); + undo_redo->add_undo_method(frames,"add_frame",edited_anim,r,to_remove); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -182,6 +192,8 @@ void SpriteFramesEditor::_delete_confirm_pressed() { void SpriteFramesEditor::_paste_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + Ref<Texture> r=EditorSettings::get_singleton()->get_resource_clipboard(); if (!r.is_valid()) { dialog->set_text(TTR("Resource clipboard is empty or not a texture!")); @@ -194,8 +206,8 @@ void SpriteFramesEditor::_paste_pressed() { undo_redo->create_action(TTR("Paste Frame")); - undo_redo->add_do_method(frames,"add_frame",r); - undo_redo->add_undo_method(frames,"remove_frame",frames->get_frame_count()); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,frames->get_frame_count(edited_anim)); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -204,16 +216,17 @@ void SpriteFramesEditor::_paste_pressed() { void SpriteFramesEditor::_empty_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); int from=-1; - if (tree->get_selected()) { + if (tree->get_current()>=0) { - from = tree->get_selected()->get_metadata(0); + from = tree->get_current(); sel=from; } else { - from=frames->get_frame_count(); + from=frames->get_frame_count(edited_anim); } @@ -221,8 +234,8 @@ void SpriteFramesEditor::_empty_pressed() { Ref<Texture> r; undo_redo->create_action(TTR("Add Empty")); - undo_redo->add_do_method(frames,"add_frame",r,from); - undo_redo->add_undo_method(frames,"remove_frame",from); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -231,16 +244,17 @@ void SpriteFramesEditor::_empty_pressed() { void SpriteFramesEditor::_empty2_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); int from=-1; - if (tree->get_selected()) { + if (tree->get_current()>=0) { - from = tree->get_selected()->get_metadata(0); + from = tree->get_current(); sel=from; } else { - from=frames->get_frame_count(); + from=frames->get_frame_count(edited_anim); } @@ -248,8 +262,8 @@ void SpriteFramesEditor::_empty2_pressed() { Ref<Texture> r; undo_redo->create_action(TTR("Add Empty")); - undo_redo->add_do_method(frames,"add_frame",r,from+1); - undo_redo->add_undo_method(frames,"remove_frame",from+1); + undo_redo->add_do_method(frames,"add_frame",edited_anim,r,from+1); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,from+1); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -258,21 +272,24 @@ void SpriteFramesEditor::_empty2_pressed() { void SpriteFramesEditor::_up_pressed() { - if (!tree->get_selected()) + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) return; - int to_move = tree->get_selected()->get_metadata(0); + + int to_move = tree->get_current(); if (to_move<1) return; sel=to_move; sel-=1; - Ref<Texture> r = frames->get_frame(to_move); + Ref<Texture> r = frames->get_frame(edited_anim,to_move); undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"set_frame",to_move,frames->get_frame(to_move-1)); - undo_redo->add_do_method(frames,"set_frame",to_move-1,frames->get_frame(to_move)); - undo_redo->add_undo_method(frames,"set_frame",to_move,frames->get_frame(to_move)); - undo_redo->add_undo_method(frames,"set_frame",to_move-1,frames->get_frame(to_move-1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move-1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move-1,frames->get_frame(edited_anim,to_move-1)); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -281,21 +298,24 @@ void SpriteFramesEditor::_up_pressed() { void SpriteFramesEditor::_down_pressed() { - if (!tree->get_selected()) + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + + if (tree->get_current()<0) return; - int to_move = tree->get_selected()->get_metadata(0); - if (to_move<0 || to_move>=frames->get_frame_count()-1) + + int to_move = tree->get_current(); + if (to_move<0 || to_move>=frames->get_frame_count(edited_anim)-1) return; sel=to_move; sel+=1; - Ref<Texture> r = frames->get_frame(to_move); + Ref<Texture> r = frames->get_frame(edited_anim,to_move); undo_redo->create_action(TTR("Delete Resource")); - undo_redo->add_do_method(frames,"set_frame",to_move,frames->get_frame(to_move+1)); - undo_redo->add_do_method(frames,"set_frame",to_move+1,frames->get_frame(to_move)); - undo_redo->add_undo_method(frames,"set_frame",to_move,frames->get_frame(to_move)); - undo_redo->add_undo_method(frames,"set_frame",to_move+1,frames->get_frame(to_move+1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move+1)); + undo_redo->add_do_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move,frames->get_frame(edited_anim,to_move)); + undo_redo->add_undo_method(frames,"set_frame",edited_anim,to_move+1,frames->get_frame(edited_anim,to_move+1)); undo_redo->add_do_method(this,"_update_library"); undo_redo->add_undo_method(this,"_update_library"); undo_redo->commit_action(); @@ -308,7 +328,7 @@ void SpriteFramesEditor::_down_pressed() { void SpriteFramesEditor::_delete_pressed() { - if (!tree->get_selected()) + if (tree->get_current()<0) return; _delete_confirm_pressed(); //it has undo.. why bother with a dialog.. @@ -323,39 +343,211 @@ void SpriteFramesEditor::_delete_pressed() { } -void SpriteFramesEditor::_update_library() { +void SpriteFramesEditor::_animation_select() { + + if (updating) + return; + + TreeItem *selected = animations->get_selected(); + ERR_FAIL_COND(!selected); + edited_anim=selected->get_text(0); + _update_library(true); + +} + +void SpriteFramesEditor::_animation_name_edited(){ + + if (updating) + return; + + if (!frames->has_animation(edited_anim)) + return; + + TreeItem *edited = animations->get_edited(); + if (!edited) + return; + + String new_name = edited->get_text(0); + + if (new_name==String(edited_anim)) + return; + + new_name=new_name.replace("/","_").replace(","," "); + + String name=new_name; + int counter=0; + while(frames->has_animation(name)) { + counter++; + name=new_name+" "+itos(counter); + } + + undo_redo->create_action(TTR("Rename Animation")); + undo_redo->add_do_method(frames,"rename_animation",edited_anim,name); + undo_redo->add_undo_method(frames,"rename_animation",name,edited_anim); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + edited_anim=new_name; + + undo_redo->commit_action(); + + + +} +void SpriteFramesEditor::_animation_add(){ + + + String new_name = "New Anim"; + + String name=new_name; + int counter=0; + while(frames->has_animation(name)) { + counter++; + name=new_name+" "+itos(counter); + } + + undo_redo->create_action(TTR("Add Animation")); + undo_redo->add_do_method(frames,"add_animation",name); + undo_redo->add_undo_method(frames,"remove_animation",name); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + edited_anim=new_name; + + undo_redo->commit_action(); + +} +void SpriteFramesEditor::_animation_remove(){ + + //fuck everything + if (updating) + return; + + if (!frames->has_animation(edited_anim)) + return; + + undo_redo->create_action(TTR("Remove Animation")); + undo_redo->add_do_method(frames,"remove_animation",edited_anim); + undo_redo->add_undo_method(frames,"add_animation",edited_anim); + undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); + undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); + int fc = frames->get_frame_count(edited_anim); + for(int i=0;i<fc;i++) { + Ref<Texture> frame = frames->get_frame(edited_anim,i); + undo_redo->add_undo_method(frames,"add_frame",edited_anim,frame); + } + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + + undo_redo->commit_action(); + +} + + +void SpriteFramesEditor::_animation_loop_changed() { + + if (updating) + return; + + undo_redo->create_action(TTR("Change Animation Loop")); + undo_redo->add_do_method(frames,"set_animation_loop",edited_anim,anim_loop->is_pressed()); + undo_redo->add_undo_method(frames,"set_animation_loop",edited_anim,frames->get_animation_loop(edited_anim)); + undo_redo->add_do_method(this,"_update_library",true); + undo_redo->add_undo_method(this,"_update_library",true); + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_animation_fps_changed(double p_value) { + + if (updating) + return; + + undo_redo->create_action(TTR("Change Animation FPS"),true); + undo_redo->add_do_method(frames,"set_animation_speed",edited_anim,p_value); + undo_redo->add_undo_method(frames,"set_animation_speed",edited_anim,frames->get_animation_speed(edited_anim)); + undo_redo->add_do_method(this,"_update_library",true); + undo_redo->add_undo_method(this,"_update_library",true); + + undo_redo->commit_action(); + +} + +void SpriteFramesEditor::_update_library(bool p_skip_selector) { + + updating=true; + + if (!p_skip_selector) { + animations->clear(); + + TreeItem *anim_root=animations->create_item(); + + List<StringName> anim_names; + + anim_names.sort_custom<StringName::AlphCompare>(); + + frames->get_animation_list(&anim_names); + + anim_names.sort_custom<StringName::AlphCompare>(); + + for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) { + + String name = E->get(); + + TreeItem *it = animations->create_item(anim_root); + + it->set_metadata(0,name); + + it->set_text(0,name); + it->set_editable(0,true); + + if (E->get()==edited_anim) { + it->select(0); + } + } + } + tree->clear(); - tree->set_hide_root(true); - TreeItem *root = tree->create_item(NULL); - if (sel>=frames->get_frame_count()) - sel=frames->get_frame_count()-1; - else if (sel<0 && frames->get_frame_count()) + if (!frames->has_animation(edited_anim)) { + updating=false; + return; + } + + + if (sel>=frames->get_frame_count(edited_anim)) + sel=frames->get_frame_count(edited_anim)-1; + else if (sel<0 && frames->get_frame_count(edited_anim)) sel=0; - for(int i=0;i<frames->get_frame_count();i++) { + for(int i=0;i<frames->get_frame_count(edited_anim);i++) { + + + String name; + Ref<Texture> icon; - TreeItem *ti = tree->create_item(root); - ti->set_cell_mode(0,TreeItem::CELL_MODE_STRING); - ti->set_selectable(0,true); - if (frames->get_frame(i).is_null()) { + if (frames->get_frame(edited_anim,i).is_null()) { - ti->set_text(0,TTR("Frame ")+itos(i)+" (empty)"); + name=itos(i)+TTR(": (empty)"); } else { - ti->set_text(0,TTR("Frame ")+itos(i)+" ("+frames->get_frame(i)->get_name()+")"); - ti->set_icon(0,frames->get_frame(i)); + name=itos(i)+": "+frames->get_frame(edited_anim,i)->get_name(); + icon=frames->get_frame(edited_anim,i); } - if (frames->get_frame(i).is_valid()) - ti->set_tooltip(0,frames->get_frame(i)->get_path()); - ti->set_metadata(0,i); - ti->set_icon_max_width(0,96); + + tree->add_item(name,icon); + if (frames->get_frame(edited_anim,i).is_valid()) + tree->set_item_tooltip(tree->get_item_count()-1,frames->get_frame(edited_anim,i)->get_path()); if (sel==i) - ti->select(0); + tree->select(tree->get_item_count()-1); } + anim_speed->set_val(frames->get_animation_speed(edited_anim)); + anim_loop->set_pressed(frames->get_animation_loop(edited_anim)); + + updating=false; //player->add_resource("default",resource); } @@ -363,10 +555,27 @@ void SpriteFramesEditor::_update_library() { void SpriteFramesEditor::edit(SpriteFrames* p_frames) { + if (frames==p_frames) + return; + frames=p_frames; if (p_frames) { + + if (!p_frames->has_animation(edited_anim)) { + + List<StringName> anim_names; + frames->get_animation_list(&anim_names); + anim_names.sort_custom<StringName::AlphCompare>(); + if (anim_names.size()) { + edited_anim=anim_names.front()->get(); + } else { + edited_anim=StringName(); + } + + } + _update_library(); } else { @@ -377,6 +586,110 @@ void SpriteFramesEditor::edit(SpriteFrames* p_frames) { } +Variant SpriteFramesEditor::get_drag_data_fw(const Point2& p_point,Control* p_from) { + + if (!frames->has_animation(edited_anim)) + return false; + + int idx = tree->get_item_at_pos(p_point,true); + + if (idx<0 || idx>=frames->get_frame_count(edited_anim)) + return Variant(); + + RES frame = frames->get_frame(edited_anim,idx); + + if (frame.is_null()) + return Variant(); + + return EditorNode::get_singleton()->drag_resource(frame,p_from); + + +} + +bool SpriteFramesEditor::can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const{ + + Dictionary d = p_data; + + if (!d.has("type")) + return false; + + if (d.has("from") && (Object*)(d["from"])==tree) + return false; + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Texture> texture = r; + + if (texture.is_valid()) { + + return true; + } + } + + + if (String(d["type"])=="files") { + + Vector<String> files = d["files"]; + + if (files.size()==0) + return false; + + for(int i=0;i<files.size();i++) { + String file = files[0]; + String ftype = EditorFileSystem::get_singleton()->get_file_type(file); + + if (!ObjectTypeDB::is_type(ftype,"Texture")) { + return false; + } + + } + + return true; + + } + return false; +} + +void SpriteFramesEditor::drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from){ + + if (!can_drop_data_fw(p_point,p_data,p_from)) + return; + + Dictionary d = p_data; + + if (!d.has("type")) + return; + + int at_pos = tree->get_item_at_pos(p_point,true); + + if (String(d["type"])=="resource" && d.has("resource")) { + RES r=d["resource"]; + + Ref<Texture> texture = r; + + if (texture.is_valid()) { + + undo_redo->create_action(TTR("Add Frame")); + undo_redo->add_do_method(frames,"add_frame",edited_anim,texture,at_pos==-1?-1:at_pos); + undo_redo->add_undo_method(frames,"remove_frame",edited_anim,at_pos==-1?frames->get_frame_count(edited_anim):at_pos); + undo_redo->add_do_method(this,"_update_library"); + undo_redo->add_undo_method(this,"_update_library"); + undo_redo->commit_action(); + + } + } + + + if (String(d["type"])=="files") { + + DVector<String> files = d["files"]; + + _file_load_request(files,at_pos); + } + +} + void SpriteFramesEditor::_bind_methods() { @@ -388,29 +701,94 @@ void SpriteFramesEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_delete_pressed"),&SpriteFramesEditor::_delete_pressed); ObjectTypeDB::bind_method(_MD("_paste_pressed"),&SpriteFramesEditor::_paste_pressed); ObjectTypeDB::bind_method(_MD("_delete_confirm_pressed"),&SpriteFramesEditor::_delete_confirm_pressed); - ObjectTypeDB::bind_method(_MD("_file_load_request"),&SpriteFramesEditor::_file_load_request); - ObjectTypeDB::bind_method(_MD("_update_library"),&SpriteFramesEditor::_update_library); + ObjectTypeDB::bind_method(_MD("_file_load_request","files","atpos"),&SpriteFramesEditor::_file_load_request,DEFVAL(-1)); + ObjectTypeDB::bind_method(_MD("_update_library","skipsel"),&SpriteFramesEditor::_update_library,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("_up_pressed"),&SpriteFramesEditor::_up_pressed); ObjectTypeDB::bind_method(_MD("_down_pressed"),&SpriteFramesEditor::_down_pressed); + ObjectTypeDB::bind_method(_MD("_animation_select"),&SpriteFramesEditor::_animation_select); + ObjectTypeDB::bind_method(_MD("_animation_name_edited"),&SpriteFramesEditor::_animation_name_edited); + ObjectTypeDB::bind_method(_MD("_animation_add"),&SpriteFramesEditor::_animation_add); + ObjectTypeDB::bind_method(_MD("_animation_remove"),&SpriteFramesEditor::_animation_remove); + ObjectTypeDB::bind_method(_MD("_animation_loop_changed"),&SpriteFramesEditor::_animation_loop_changed); + ObjectTypeDB::bind_method(_MD("_animation_fps_changed"),&SpriteFramesEditor::_animation_fps_changed); + ObjectTypeDB::bind_method(_MD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw); + ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw); + ObjectTypeDB::bind_method(_MD("drop_data_fw"), &SpriteFramesEditor::drop_data_fw); + + } + SpriteFramesEditor::SpriteFramesEditor() { //add_style_override("panel", get_stylebox("panel","Panel")); + split = memnew( HSplitContainer ); + add_child(split); + + VBoxContainer *vbc_animlist = memnew( VBoxContainer ); + split->add_child(vbc_animlist); + vbc_animlist->set_custom_minimum_size(Size2(150,0)); + //vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL); + + + VBoxContainer *sub_vb = memnew( VBoxContainer ); + vbc_animlist->add_margin_child(TTR("Animations"),sub_vb,true); + sub_vb->set_v_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *hbc_animlist = memnew( HBoxContainer ); + sub_vb->add_child(hbc_animlist); + + new_anim = memnew( Button ); + hbc_animlist->add_child(new_anim); + new_anim->connect("pressed",this,"_animation_add"); + + + hbc_animlist->add_spacer(); + + remove_anim = memnew( Button ); + hbc_animlist->add_child(remove_anim); + remove_anim->connect("pressed",this,"_animation_remove"); + + animations = memnew( Tree ); + sub_vb->add_child(animations); + animations->set_v_size_flags(SIZE_EXPAND_FILL); + animations->set_hide_root(true); + animations->connect("cell_selected",this,"_animation_select"); + animations->connect("item_edited",this,"_animation_name_edited"); + animations->set_single_select_cell_editing_only_when_already_selected(true); + + + anim_speed = memnew( SpinBox); + vbc_animlist->add_margin_child(TTR("Speed (FPS):"),anim_speed); + anim_speed->set_min(0); + anim_speed->set_max(100); + anim_speed->set_step(0.01); + anim_speed->connect("value_changed",this,"_animation_fps_changed"); + + anim_loop = memnew( CheckButton ); + anim_loop->set_text(TTR("Loop")); + vbc_animlist->add_child(anim_loop); + anim_loop->connect("pressed",this,"_animation_loop_changed"); + VBoxContainer *vbc = memnew( VBoxContainer ); - add_child(vbc); + split->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + + sub_vb = memnew( VBoxContainer ); + vbc->add_margin_child(TTR("Animation Frames"),sub_vb,true); + HBoxContainer *hbc = memnew( HBoxContainer ); - vbc->add_child(hbc); + sub_vb->add_child(hbc); + + //animations = memnew( ItemList ); + load = memnew( Button ); load->set_tooltip(TTR("Load Resource")); hbc->add_child(load); - - - paste = memnew( Button ); paste->set_text(TTR("Paste")); hbc->add_child(paste); @@ -438,15 +816,22 @@ SpriteFramesEditor::SpriteFramesEditor() { add_child(file); - tree = memnew( Tree ); - tree->set_columns(2); - tree->set_column_min_width(0,3); - tree->set_column_min_width(1,1); - tree->set_column_expand(0,true); - tree->set_column_expand(1,true); + tree = memnew( ItemList ); tree->set_v_size_flags(SIZE_EXPAND_FILL); + tree->set_icon_mode(ItemList::ICON_MODE_TOP); + + int thumbnail_size = 96; + tree->set_max_columns(0); + tree->set_icon_mode(ItemList::ICON_MODE_TOP); + tree->set_fixed_column_width(thumbnail_size*3/2); + tree->set_max_text_lines(2); + tree->set_max_icon_size(Size2(thumbnail_size,thumbnail_size)); + //tree->set_min_icon_size(Size2(thumbnail_size,thumbnail_size)); + tree->set_drag_forwarding(this); + - vbc->add_child(tree); + + sub_vb->add_child(tree); dialog = memnew( AcceptDialog ); add_child( dialog ); @@ -460,10 +845,14 @@ SpriteFramesEditor::SpriteFramesEditor() { move_down->connect("pressed", this,"_down_pressed"); file->connect("files_selected", this,"_file_load_request"); //dialog->connect("confirmed", this,"_delete_confirm_pressed"); - tree->connect("item_edited", this,"_item_edited"); + //tree->connect("item_selected", this,"_item_edited"); loading_scene=false; sel=-1; + updating=false; + + edited_anim="default"; + } diff --git a/tools/editor/plugins/sprite_frames_editor_plugin.h b/tools/editor/plugins/sprite_frames_editor_plugin.h index 5d0a6cb035..f0aa84c23a 100644 --- a/tools/editor/plugins/sprite_frames_editor_plugin.h +++ b/tools/editor/plugins/sprite_frames_editor_plugin.h @@ -36,6 +36,7 @@ #include "scene/2d/animated_sprite.h" #include "scene/gui/file_dialog.h" #include "scene/gui/dialogs.h" +#include "scene/gui/split_container.h" class SpriteFramesEditor : public PanelContainer { @@ -49,10 +50,18 @@ class SpriteFramesEditor : public PanelContainer { Button *empty2; Button *move_up; Button *move_down; - Tree *tree; + ItemList *tree; bool loading_scene; int sel; + HSplitContainer *split; + Button *new_anim; + Button *remove_anim; + + + Tree *animations; + SpinBox *anim_speed; + CheckButton *anim_loop; EditorFileDialog *file; @@ -60,10 +69,11 @@ class SpriteFramesEditor : public PanelContainer { SpriteFrames *frames; + StringName edited_anim; void _load_pressed(); void _load_scene_pressed(); - void _file_load_request(const DVector<String>& p_path); + void _file_load_request(const DVector<String>& p_path, int p_at_pos=-1); void _paste_pressed(); void _empty_pressed(); void _empty2_pressed(); @@ -71,11 +81,27 @@ class SpriteFramesEditor : public PanelContainer { void _delete_confirm_pressed(); void _up_pressed(); void _down_pressed(); - void _update_library(); + void _update_library(bool p_skip_selector=false); void _item_edited(); + + + void _animation_select(); + void _animation_name_edited(); + void _animation_add(); + void _animation_remove(); + void _animation_loop_changed(); + void _animation_fps_changed(double p_value); + + bool updating; + UndoRedo *undo_redo; + bool _is_drop_valid(const Dictionary& p_drag_data, const Dictionary& p_item_data) const; + Variant get_drag_data_fw(const Point2& p_point,Control* p_from); + bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; + void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + protected: void _notification(int p_what); void _input_event(InputEvent p_event); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 6f80910150..c4f54e04cb 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -2287,6 +2287,7 @@ bool PropertyEditor::_is_drop_valid(const Dictionary& p_drag_data, const Diction } } + if (drag_data.has("type") && String(drag_data["type"])=="files") { Vector<String> files = drag_data["files"]; |