diff options
Diffstat (limited to 'tools/editor')
21 files changed, 651 insertions, 137 deletions
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index 18c0010904..9c921df5c6 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -994,7 +994,7 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) { return OK; } -Error EditorExportPlatformPC::export_project(const String& p_path,bool p_debug,const String& p_password) { +Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug, bool p_dumb) { diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 94fbaba842..0f9068f8b3 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -130,14 +130,14 @@ public: virtual int get_device_count() const { return 0; } virtual String get_device_name(int p_device) const { return ""; } virtual String get_device_info(int p_device) const { return ""; } - virtual Error run(int p_device) { return OK; } + virtual Error run(int p_device,bool p_dumb=false) { return OK; } virtual bool can_export(String *r_error=NULL) const=0; virtual bool requieres_password(bool p_debug) const { return false; } virtual String get_binary_extension() const=0; - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password="")=0; + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false)=0; EditorExportPlatform() {}; }; @@ -187,7 +187,7 @@ public: virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; } virtual String get_binary_extension() const { return binary_extension; } - virtual Error export_project(const String& p_path,bool p_debug,const String& p_password=""); + virtual Error export_project(const String& p_path,bool p_debug,bool p_dumb=false); virtual void set_release_binary32(const String& p_binary) { release_binary32=p_binary; } virtual void set_debug_binary32(const String& p_binary) { debug_binary32=p_binary; } virtual void set_release_binary64(const String& p_binary) { release_binary64=p_binary; } diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 922ad80aa3..ceb5b45a03 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -2204,8 +2204,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; case RUN_DEPLOY_DUMB_CLIENTS: { - bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); - fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); + bool ischecked = fileserver_menu->get_popup()->is_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS)); + fileserver_menu->get_popup()->set_item_checked( fileserver_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked); + run_native->set_deploy_dumb(!ischecked); } break; case SETTINGS_UPDATE_ALWAYS: { @@ -3612,7 +3613,7 @@ EditorNode::EditorNode() { p->set_item_tooltip(p->get_item_index(RUN_FILE_SERVER),"Enable/Disable the File Server."); p->add_separator(); p->add_check_item("Deploy Dumb Clients",RUN_DEPLOY_DUMB_CLIENTS); - p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true ); + //p->set_item_checked( p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),true ); p->set_item_tooltip(p->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),"Deploy dumb clients when the File Server is active."); p->connect("item_pressed",this,"_menu_option"); diff --git a/tools/editor/editor_run_native.cpp b/tools/editor/editor_run_native.cpp index a0e04814a5..be1a124fc2 100644 --- a/tools/editor/editor_run_native.cpp +++ b/tools/editor/editor_run_native.cpp @@ -101,7 +101,7 @@ void EditorRunNative::_run_native(int p_idx,const String& p_platform) { Ref<EditorExportPlatform> eep = EditorImportExport::get_singleton()->get_export_platform(p_platform); ERR_FAIL_COND(eep.is_null()); - eep->run(p_idx); + eep->run(p_idx,deploy_dumb); } void EditorRunNative::_bind_methods() { @@ -109,8 +109,20 @@ void EditorRunNative::_bind_methods() { ObjectTypeDB::bind_method("_run_native",&EditorRunNative::_run_native); } +void EditorRunNative::set_deploy_dumb(bool p_enabled) { + + deploy_dumb=p_enabled; +} + +bool EditorRunNative::is_deploy_dumb_enabled() const{ + + return deploy_dumb; +} + + EditorRunNative::EditorRunNative() { set_process(true); first=true; + deploy_dumb=false; } diff --git a/tools/editor/editor_run_native.h b/tools/editor/editor_run_native.h index ca3d41126f..f4bda2d07d 100644 --- a/tools/editor/editor_run_native.h +++ b/tools/editor/editor_run_native.h @@ -38,6 +38,7 @@ class EditorRunNative : public HBoxContainer { Map<StringName,MenuButton*> menus; bool first; + bool deploy_dumb; void _run_native(int p_idx,const String& p_platform); @@ -46,6 +47,9 @@ protected: static void _bind_methods(); void _notification(int p_what); public: + + void set_deploy_dumb(bool p_enabled); + bool is_deploy_dumb_enabled() const; EditorRunNative(); }; diff --git a/tools/editor/fileserver/editor_file_server.cpp b/tools/editor/fileserver/editor_file_server.cpp index f72498f37f..f21d9b4ec1 100644 --- a/tools/editor/fileserver/editor_file_server.cpp +++ b/tools/editor/fileserver/editor_file_server.cpp @@ -317,12 +317,33 @@ EditorFileServer::EditorFileServer() { cmd=CMD_NONE; thread=Thread::create(_thread_start,this); + List<IP_Address> local_ip; + IP::get_singleton()->get_local_addresses(&local_ip); EDITOR_DEF("file_server/port",6010); + String lip; + String hint; + for(List<IP_Address>::Element *E=local_ip.front();E;E=E->next()) { + + String ip = E->get(); + if (ip=="127.0.0.1") + continue; + + if (lip!="") + lip=ip; + if (hint!="") + hint+=","; + hint+=ip; + + } + + EDITOR_DEF("file_server/host",lip); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"file_server/host",PROPERTY_HINT_ENUM,hint)); EDITOR_DEF("file_server/password",""); } EditorFileServer::~EditorFileServer() { + quit=true; Thread::wait_to_finish(thread); memdelete(wait_mutex); diff --git a/tools/editor/icons/icon_animated_sprite_3d.png b/tools/editor/icons/icon_animated_sprite_3d.png Binary files differnew file mode 100644 index 0000000000..19aa7ea207 --- /dev/null +++ b/tools/editor/icons/icon_animated_sprite_3d.png diff --git a/tools/editor/icons/icon_sprite_3d.png b/tools/editor/icons/icon_sprite_3d.png Binary files differnew file mode 100644 index 0000000000..260f7d4920 --- /dev/null +++ b/tools/editor/icons/icon_sprite_3d.png diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 916bd59360..4da712c7b3 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -44,6 +44,7 @@ static const char *flag_names[]={ "No MipMaps", "Repeat", "Filter (Magnifying)", + "Premultiply Alpha", NULL }; @@ -55,6 +56,7 @@ static const char *flag_short_names[]={ "NoMipMap", "Repeat", "Filter", + "PMAlpha", NULL }; @@ -919,6 +921,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.fix_alpha_edges(); } + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + if (shrink>1) { @@ -972,6 +979,11 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc image.fix_alpha_edges(); } + if (image.get_format()==Image::FORMAT_RGBA && flags&IMAGE_FLAG_PREMULT_ALPHA) { + + image.premultiply_alpha(); + } + int orig_w=image.get_width(); int orig_h=image.get_height(); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index b2950a889c..fcc1bd2d0c 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -91,7 +91,8 @@ public: IMAGE_FLAG_COMPRESS_EXTRA=8, // used for pvrtc2 IMAGE_FLAG_NO_MIPMAPS=16, //normal for 2D games IMAGE_FLAG_REPEAT=32, //usually disabled in 2D - IMAGE_FLAG_FILTER=64 //almost always enabled + IMAGE_FLAG_FILTER=64, //almost always enabled + IMAGE_FLAG_PREMULT_ALPHA=128//almost always enabled }; virtual String get_name() const; diff --git a/tools/editor/plugins/baked_light_editor_plugin.cpp b/tools/editor/plugins/baked_light_editor_plugin.cpp index b1e42e3369..77f9d1ed78 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.cpp +++ b/tools/editor/plugins/baked_light_editor_plugin.cpp @@ -134,6 +134,8 @@ public: void _plot_light(const Vector3& p_plot_pos,const AABB& p_plot_aabb, Octant *p_octant, const AABB& p_aabb,const Color& p_light); + void _plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light); + void _throw_ray(const Vector3& p_from, const Vector3& p_to,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces); @@ -165,7 +167,7 @@ public: } BakedLightBaker() { - octree_depth=8; + octree_depth=6; octree=NULL; bvh=NULL; leaf_list=NULL; @@ -408,7 +410,7 @@ void BakedLightBaker::_make_bvh() { void BakedLightBaker::_octree_insert(const AABB& p_aabb,Octant *p_octant,Triangle* p_triangle, int p_depth) { if (p_octant->leaf) { - +#if 0 if (p_aabb.has_point(p_triangle->vertices[0]) && p_aabb.has_point(p_triangle->vertices[1]) &&p_aabb.has_point(p_triangle->vertices[2])) { //face is completely enclosed, add area p_octant->surface_area+=Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).get_area(); @@ -433,12 +435,18 @@ void BakedLightBaker::_octree_insert(const AABB& p_aabb,Octant *p_octant,Triangl p.d=-p_aabb.pos[i]; poly=Geometry::clip_polygon(poly,p); } + + //calculate area + float clipped_area=0; for(int i=2;i<poly.size();i++) { - p_octant->surface_area+=Face3(poly[0],poly[i-1],poly[i]).get_area(); + clipped_area+=Face3(poly[0],poly[i-1],poly[i]).get_area(); } - } + print_line(itos(poly.size())+" Base: "+rtos(Face3(p_triangle->vertices[0],p_triangle->vertices[1],p_triangle->vertices[2]).get_area())+" clipped: "+rtos(clipped_area)); + p_octant->surface_area+=clipped_area; + } +#endif } else { @@ -500,7 +508,7 @@ void BakedLightBaker::_make_octree() { octree_aabb=base; cell_size=base.size.x; - for(int i=0;i<=octree_depth;i++) + for(int i=0;i<octree_depth;i++) cell_size/=2.0; octree = memnew( Octant ); @@ -526,7 +534,7 @@ void BakedLightBaker::_plot_light(const Vector3& p_plot_pos,const AABB& p_plot_a float d = p_plot_pos.distance_to(center); if (d>r) return; //oh crap! outside radius - float intensity = 1.0 - (d/r)*(d/r); //not gauss but.. + float intensity = 1.0;// - (d/r)*(d/r); //not gauss but.. p_octant->light_accum[0]+=p_light.r*intensity; p_octant->light_accum[1]+=p_light.g*intensity; p_octant->light_accum[2]+=p_light.b*intensity; @@ -558,6 +566,42 @@ void BakedLightBaker::_plot_light(const Vector3& p_plot_pos,const AABB& p_plot_a } } +void BakedLightBaker::_plot_light_point(const Vector3& p_plot_pos, Octant *p_octant, const AABB& p_aabb,const Color& p_light) { + + + if (p_octant->leaf) { + + p_octant->light_accum[0]+=p_light.r; + p_octant->light_accum[1]+=p_light.g; + p_octant->light_accum[2]+=p_light.b; + + } else { + + for(int i=0;i<8;i++) { + + if (!p_octant->children[i]) + continue; + + AABB aabb=p_aabb; + aabb.size*=0.5; + if (i&1) + aabb.pos.x+=aabb.size.x; + if (i&2) + aabb.pos.y+=aabb.size.y; + if (i&4) + aabb.pos.z+=aabb.size.z; + + + if (!aabb.has_point(p_plot_pos)) + continue; + + _plot_light_point(p_plot_pos,p_octant->children[i],aabb,p_light); + + } + + } +} + void BakedLightBaker::_throw_ray(const Vector3& p_begin, const Vector3& p_end,const Color& p_light,float *p_att_curve,float p_att_curve_len,int p_bounces) { @@ -692,6 +736,7 @@ void BakedLightBaker::_throw_ray(const Vector3& p_begin, const Vector3& p_end,co aabb.size=Vector3(2,2,2)*cell_size*plot_size; _plot_light(r_point,aabb,octree,octree_aabb,p_light); +// _plot_light_point(r_point,octree,octree_aabb,p_light); } @@ -772,9 +817,21 @@ void BakedLightBaker::bake(Node* p_node) { +void BakedLightEditor::_end_baking() { + + if (!bake_thread) + return; + + bake_thread_exit=true; + Thread::wait_to_finish(bake_thread); + bake_thread=NULL; + bake_thread_exit=false; +} + void BakedLightEditor::_node_removed(Node *p_node) { if(p_node==node) { + _end_baking(); node=NULL; p_node->remove_child(preview); preview->set_mesh(Ref<Mesh>()); @@ -784,6 +841,79 @@ void BakedLightEditor::_node_removed(Node *p_node) { } +void BakedLightEditor::_bake_thread_func(void *arg) { + + BakedLightEditor *ble = (BakedLightEditor*)arg; + + while(!ble->bake_thread_exit) { + + ble->baker->throw_rays(1000); + } + +} + + + +void BakedLightEditor::_notification(int p_option) { + + + if (p_option==NOTIFICATION_PROCESS) { + + if (bake_thread) { + + update_timeout-=get_process_delta_time(); + if (update_timeout<0) { + + + + float norm = baker->get_normalization(); + float max_lum=0; + { + DVector<Color>::Write cw=colors.write(); + BakedLightBaker::Octant *oct = baker->leaf_list; + int vert_idx=0; + + while(oct) { + + Color color; + + + color.r=oct->light_accum[0]/norm; + color.g=oct->light_accum[1]/norm; + color.b=oct->light_accum[2]/norm; + float lum = color.get_v(); + //if (lum<0.05) + // color.a=0; + if (lum>max_lum) + max_lum=lum; + + for (int i=0;i<36;i++) { + + + cw[vert_idx++]=color; + } + + oct=oct->next_leaf; + + } + } + + + Array a; + a.resize(Mesh::ARRAY_MAX); + a[Mesh::ARRAY_VERTEX]=vertices; + a[Mesh::ARRAY_COLOR]=colors; + while(mesh->get_surface_count()) + mesh->surface_remove(0); + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); + mesh->surface_set_material(0,material); + + update_timeout=1; + } + } + } +} + void BakedLightEditor::_menu_option(int p_option) { @@ -797,13 +927,9 @@ void BakedLightEditor::_menu_option(int p_option) { preview->set_mesh(Ref<Mesh>()); baker->base_inv=node->get_global_transform().affine_inverse(); baker->bake(node); - baker->throw_rays(100000); - float norm = baker->get_normalization(); - float max_lum=0; print_line("CELLS: "+itos(baker->cell_count)); - DVector<Color> colors; - DVector<Vector3> vertices; + print_line("cell size: "+rtos(baker->cell_size)); colors.resize(baker->cell_count*36); vertices.resize(baker->cell_count*36); @@ -817,12 +943,6 @@ void BakedLightEditor::_menu_option(int p_option) { while(oct) { Color color; - color.r=oct->light_accum[0]/norm; - color.g=oct->light_accum[1]/norm; - color.b=oct->light_accum[2]/norm; - float lum = color.get_v(); - if (lum>max_lum) - max_lum=lum; for (int i=0;i<6;i++) { @@ -845,7 +965,7 @@ void BakedLightEditor::_menu_option(int p_option) { } for(int j=0;j<4;j++) { - face_points[j]*=baker->cell_size; + face_points[j]*=baker->cell_size*0.5; face_points[j]+=Vector3(oct->offset[0],oct->offset[1],oct->offset[2]); } @@ -873,25 +993,20 @@ void BakedLightEditor::_menu_option(int p_option) { } - print_line("max lum: "+rtos(max_lum)); Array a; a.resize(Mesh::ARRAY_MAX); a[Mesh::ARRAY_VERTEX]=vertices; a[Mesh::ARRAY_COLOR]=colors; + while(mesh->get_surface_count()) + mesh->surface_remove(0); + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); + mesh->surface_set_material(0,material); - Ref<FixedMaterial> matcol = memnew( FixedMaterial ); - matcol->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); - matcol->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); - matcol->set_flag(FixedMaterial::FLAG_UNSHADED,true); - matcol->set_flag(FixedMaterial::FLAG_DOUBLE_SIDED,true); - matcol->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); - Ref<Mesh> m = memnew( Mesh ); - m->add_surface(Mesh::PRIMITIVE_TRIANGLES,a); - m->surface_set_material(0,matcol); - preview->set_mesh(m); - - - + bake_thread_exit=false; + update_timeout=0; + set_process(true); + bake_thread=Thread::create(_bake_thread_func,this); + preview->set_mesh(mesh); } break; @@ -914,6 +1029,7 @@ void BakedLightEditor::edit(BakedLight *p_baked_light) { } node=p_baked_light; + _end_baking(); if (node) node->add_child(preview); @@ -943,6 +1059,19 @@ BakedLightEditor::BakedLightEditor() { node=NULL; baker = memnew( BakedLightBaker ); preview = memnew( MeshInstance ); + bake_thread=NULL; + update_timeout=0; + + material = Ref<FixedMaterial> ( memnew( FixedMaterial ) ); + material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true); + material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true); + material->set_flag(FixedMaterial::FLAG_UNSHADED,true); + material->set_flag(FixedMaterial::FLAG_DOUBLE_SIDED,true); + material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1)); + + mesh = Ref<Mesh>( memnew( Mesh )); + + } BakedLightEditor::~BakedLightEditor() { diff --git a/tools/editor/plugins/baked_light_editor_plugin.h b/tools/editor/plugins/baked_light_editor_plugin.h index 698d3f825f..9424503a16 100644 --- a/tools/editor/plugins/baked_light_editor_plugin.h +++ b/tools/editor/plugins/baked_light_editor_plugin.h @@ -19,6 +19,15 @@ class BakedLightEditor : public Control { OBJ_TYPE(BakedLightEditor, Control ); + float update_timeout; + DVector<Color> colors; + DVector<Vector3> vertices; + Ref<Mesh> mesh; + Ref<FixedMaterial> material; + + Thread *bake_thread; + bool bake_thread_exit; + MeshInstance *preview; BakedLightBaker *baker; AcceptDialog *err_dialog; @@ -32,12 +41,15 @@ class BakedLightEditor : public Control { MENU_OPTION_CLEAR }; + static void _bake_thread_func(void *arg); + void _end_baking(); void _menu_option(int); friend class BakedLightEditorPlugin; protected: void _node_removed(Node *p_node); static void _bind_methods(); + void _notification(int p_what); public: void edit(BakedLight *p_baked_light); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 5f87b791f7..6540ae9288 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -608,7 +608,14 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { if (b.button_index==BUTTON_WHEEL_DOWN) { + float prev_zoom=zoom; zoom=zoom*0.95; + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_val( h_scroll->get_val() + ofs.x ); + v_scroll->set_val( v_scroll->get_val() + ofs.y ); + } _update_scroll(0); viewport->update(); return; @@ -616,7 +623,15 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) { if (b.button_index==BUTTON_WHEEL_UP) { + float prev_zoom=zoom; zoom=zoom*(1.0/0.95); + { + Point2 ofs(b.x,b.y); + ofs = ofs/prev_zoom - ofs/zoom; + h_scroll->set_val( h_scroll->get_val() + ofs.x ); + v_scroll->set_val( v_scroll->get_val() + ofs.y ); + } + _update_scroll(0); viewport->update(); return; diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 83cf753692..31ccc79d2a 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -688,6 +688,26 @@ void ScriptEditor::_menu_option(int p_option) { current->get_text_edit()->query_code_comple(); } break; + case EDIT_AUTO_INDENT: { + + TextEdit *te = current->get_text_edit(); + String text = te->get_text(); + Ref<Script> scr = current->get_edited_script(); + if (scr.is_null()) + return; + int begin,end; + if (te->is_selection_active()) { + begin=te->get_selection_from_line(); + end=te->get_selection_to_line(); + } else { + begin=0; + end=te->get_line_count()-1; + } + scr->get_language()->auto_indent_code(text,begin,end); + te->set_text(text); + + + } break; case SEARCH_FIND: { find_replace_dialog->set_text_edit(current->get_text_edit()); @@ -1321,6 +1341,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { edit_menu->get_popup()->add_item("Select All",EDIT_SELECT_ALL,KEY_MASK_CMD|KEY_A); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CMD|KEY_SPACE); + edit_menu->get_popup()->add_item("Auto Indent",EDIT_AUTO_INDENT,KEY_MASK_CMD|KEY_I); edit_menu->get_popup()->connect("item_pressed", this,"_menu_option"); diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 97f1702f8f..69b8739d67 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -122,6 +122,7 @@ class ScriptEditor : public VBoxContainer { EDIT_PASTE, EDIT_SELECT_ALL, EDIT_COMPLETE, + EDIT_AUTO_INDENT, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_REPLACE, diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp index f571aba434..aac3837da9 100644 --- a/tools/editor/project_export.cpp +++ b/tools/editor/project_export.cpp @@ -449,7 +449,7 @@ Error ProjectExportDialog::export_platform(const String& p_platform, const Strin ERR_PRINT("Invalid platform for export"); return ERR_INVALID_PARAMETER; } - Error err = exporter->export_project(p_path,p_debug,p_password); + Error err = exporter->export_project(p_path,p_debug); if (err!=OK) { error->set_text("Error exporting project!"); error->popup_centered(Size2(300,70));; diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index c45e7441b8..bd8f1641e2 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -98,22 +98,21 @@ class NewProjectDialog : public ConfirmationDialog { void _path_text_changed(const String& p_path) { - _test_path(); - if (import_mode) { + if ( _test_path() ) { String sp=p_path; sp=sp.replace("\\","/"); int lidx=sp.find_last("/"); + if (lidx!=-1) { sp=sp.substr(lidx+1,sp.length()); } - if (sp=="") + if (sp=="" && import_mode ) sp="Imported Project"; project_name->set_text(sp); } - } void _file_selected(const String& p_path) { @@ -338,21 +337,23 @@ struct ProjectItem { String path; String conf; uint64_t last_modified; + bool favorite; ProjectItem() {} - ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified) { - project = p_project; path = p_path; conf = p_conf; last_modified = p_last_modified; + ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite=false) { + project = p_project; path = p_path; conf = p_conf; last_modified = p_last_modified; favorite=p_favorite; } _FORCE_INLINE_ bool operator <(const ProjectItem& l) const { return last_modified > l.last_modified; } + _FORCE_INLINE_ bool operator ==(const ProjectItem& l) const { return project==l.project; } }; + void ProjectManager::_panel_draw(Node *p_hb) { HBoxContainer *hb = p_hb->cast_to<HBoxContainer>(); hb->draw_line(Point2(0,hb->get_size().y+1),Point2(hb->get_size().x-10,hb->get_size().y+1),get_color("guide_color","Tree")); - if (hb->get_meta("name")==selected) { - + if (selected_list.has(hb->get_meta("name"))) { hb->draw_style_box(get_stylebox("selected","Tree"),Rect2(Point2(),hb->get_size()-Size2(10,0))); } } @@ -361,20 +362,90 @@ void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) { if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - selected = p_hb->get_meta("name"); - selected_main = p_hb->get_meta("main_scene"); + String clicked = p_hb->get_meta("name"); + String clicked_main_scene = p_hb->get_meta("main_scene"); + + if (p_ev.key.mod.shift && selected_list.size()>0 && last_clicked!="" && clicked != last_clicked) { + + int clicked_id = -1; + int last_clicked_id = -1; + for(int i=0;i<scroll_childs->get_child_count();i++) { + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (!hb) continue; + if (hb->get_meta("name") == clicked) clicked_id = i; + if (hb->get_meta("name") == last_clicked) last_clicked_id = i; + } + + if (last_clicked_id!=-1 && clicked_id!=-1) { + int min = clicked_id < last_clicked_id? clicked_id : last_clicked_id; + int max = clicked_id > last_clicked_id? clicked_id : last_clicked_id; + for(int i=0; i<scroll_childs->get_child_count(); ++i) { + HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>(); + if (!hb) continue; + if (i!=clicked_id && (i<min || i>max) && !p_ev.key.mod.control) { + selected_list.erase(hb->get_meta("name")); + } else if (i>=min && i<=max) { + selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene")); + } + } + } + + } else if (selected_list.has(clicked) && p_ev.key.mod.control) { + + selected_list.erase(clicked); + + } else { + + last_clicked = clicked; + if (p_ev.key.mod.control || selected_list.size()==0) { + selected_list.insert(clicked, clicked_main_scene); + } else { + selected_list.clear(); + selected_list.insert(clicked, clicked_main_scene); + } + } + + String single_selected = ""; + if (selected_list.size() == 1) { + single_selected = selected_list.front()->key(); + } + + single_selected_main = ""; for(int i=0;i<scroll_childs->get_child_count();i++) { - scroll_childs->get_child(i)->cast_to<CanvasItem>()->update(); + CanvasItem *item = scroll_childs->get_child(i)->cast_to<CanvasItem>(); + item->update(); + + if (single_selected!="" && single_selected == item->get_meta("name")) + single_selected_main = item->get_meta("main_scene"); } - erase_btn->set_disabled(false); - open_btn->set_disabled(false); - run_btn->set_disabled(selected_main==""); + + erase_btn->set_disabled(selected_list.size()<1); + open_btn->set_disabled(selected_list.size()<1); + run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); if (p_ev.mouse_button.doubleclick) _open_project(); //open if doubleclicked + + } +} + +void ProjectManager::_favorite_pressed(Node *p_hb) { + + String clicked = p_hb->get_meta("name"); + bool favorite = !p_hb->get_meta("favorite"); + String proj=clicked.replace(":::",":/"); + proj=proj.replace("::","/"); + + if (favorite) { + EditorSettings::get_singleton()->set("favorite_projects/"+clicked,proj); + } else { + EditorSettings::get_singleton()->erase("favorite_projects/"+clicked); } + EditorSettings::get_singleton()->save(); + _load_recent_projects(); } + void ProjectManager::_load_recent_projects() { while(scroll_childs->get_child_count()>0) { @@ -387,12 +458,14 @@ void ProjectManager::_load_recent_projects() { Color font_color = get_color("font_color","Tree"); List<ProjectItem> projects; + List<ProjectItem> favorite_projects; for(List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) { String _name = E->get().name; - if (!_name.begins_with("projects/")) + if (!_name.begins_with("projects/") && !_name.begins_with("favorite_projects/")) continue; + bool favorite = (_name.begins_with("favorite_projects/"))?true:false; String project = _name.get_slice("/",1); String path = EditorSettings::get_singleton()->get(_name); @@ -408,11 +481,27 @@ void ProjectManager::_load_recent_projects() { last_modified = cache_modified; } - ProjectItem item(project, path, conf, last_modified); - projects.push_back(item); + ProjectItem item(project, path, conf, last_modified, favorite); + if (favorite) + favorite_projects.push_back(item); + else + projects.push_back(item); } projects.sort(); + favorite_projects.sort(); + + for(List<ProjectItem>::Element *E=projects.front();E;) { + List<ProjectItem>::Element *next = E->next(); + if (favorite_projects.find(E->get()) != NULL) + projects.erase(E->get()); + E=next; + } + for(List<ProjectItem>::Element *E=favorite_projects.back();E;E=E->prev()) { + projects.push_front(E->get()); + } + + Ref<Texture> favorite_icon = get_icon("Favorites","EditorIcons"); for(List<ProjectItem>::Element *E=projects.front();E;E=E->next()) { @@ -420,6 +509,7 @@ void ProjectManager::_load_recent_projects() { String project = item.project; String path = item.path; String conf = item.conf; + bool is_favorite = item.favorite; Ref<ConfigFile> cf = memnew( ConfigFile ); Error err = cf->load(conf); @@ -428,7 +518,6 @@ void ProjectManager::_load_recent_projects() { Ref<Texture> icon; String project_name="Unnamed Project"; - if (cf->has_section_key("application","icon")) { String appicon = cf->get_value("application","icon"); if (appicon!="") { @@ -457,15 +546,27 @@ void ProjectManager::_load_recent_projects() { main_scene = cf->get_value("application","main_scene"); } - HBoxContainer *hb = memnew( HBoxContainer ); hb->set_meta("name",project); hb->set_meta("main_scene",main_scene); + hb->set_meta("favorite",is_favorite); hb->connect("draw",this,"_panel_draw",varray(hb)); hb->connect("input_event",this,"_panel_input",varray(hb)); + + VBoxContainer *favorite_box = memnew( VBoxContainer ); + TextureButton *favorite = memnew( TextureButton ); + favorite->set_normal_texture(favorite_icon); + if (!is_favorite) + favorite->set_opacity(0.2); + favorite->set_v_size_flags(SIZE_EXPAND); + favorite->connect("pressed",this,"_favorite_pressed",varray(hb)); + favorite_box->add_child(favorite); + hb->add_child(favorite_box); + TextureFrame *tf = memnew( TextureFrame ); tf->set_texture(icon); hb->add_child(tf); + VBoxContainer *vb = memnew(VBoxContainer); hb->add_child(vb); EmptyControl *ec = memnew( EmptyControl ); @@ -483,68 +584,92 @@ void ProjectManager::_load_recent_projects() { scroll_childs->add_child(hb); } - erase_btn->set_disabled(selected==""); - open_btn->set_disabled(selected==""); - if (selected=="") - run_btn->set_disabled(true); + erase_btn->set_disabled(selected_list.size()<1); + open_btn->set_disabled(selected_list.size()<1); + run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main=="")); } -void ProjectManager::_open_project() { - +void ProjectManager::_open_project_confirm() { - if (selected=="") { - return; - } + for (Map<String,String>::Element *E=selected_list.front(); E; E=E->next()) { + const String &selected = E->key(); + String path = EditorSettings::get_singleton()->get("projects/"+selected); + print_line("OPENING: "+path+" ("+selected+")"); - String path = EditorSettings::get_singleton()->get("projects/"+selected); - print_line("OPENING: "+path+" ("+selected+")"); + List<String> args; - List<String> args; + args.push_back("-path"); + args.push_back(path); + args.push_back("-editor"); - args.push_back("-path"); - args.push_back(path); + const String &selected_main = E->get(); + if (selected_main!="") { + args.push_back(selected_main); + } - args.push_back("-editor"); + String exec = OS::get_singleton()->get_executable_path(); - if (selected_main!="") { - args.push_back(selected_main); + OS::ProcessID pid=0; + Error err = OS::get_singleton()->execute(exec,args,false,&pid); + ERR_FAIL_COND(err); } - String exec = OS::get_singleton()->get_executable_path(); + get_scene()->quit(); +} - OS::ProcessID pid=0; - Error err = OS::get_singleton()->execute(exec,args,false,&pid); - ERR_FAIL_COND(err); +void ProjectManager::_open_project() { - get_scene()->quit(); + if (selected_list.size()<1) { + return; + } + if (selected_list.size()>1) { + multi_open_ask->set_text("Are you sure to open more than one projects?"); + multi_open_ask->popup_centered(Size2(300,100)); + } else { + _open_project_confirm(); + } } -void ProjectManager::_run_project() { +void ProjectManager::_run_project_confirm() { + for (Map<String,String>::Element *E=selected_list.front(); E; E=E->next()) { - if (selected=="") { - return; - } + const String &selected_main = E->get(); + if (selected_main == "") continue; - String path = EditorSettings::get_singleton()->get("projects/"+selected); - print_line("OPENING: "+path+" ("+selected+")"); + const String &selected = E->key(); + String path = EditorSettings::get_singleton()->get("projects/"+selected); + print_line("OPENING: "+path+" ("+selected+")"); - List<String> args; + List<String> args; + args.push_back("-path"); + args.push_back(path); - args.push_back("-path"); - args.push_back(path); + String exec = OS::get_singleton()->get_executable_path(); - String exec = OS::get_singleton()->get_executable_path(); + OS::ProcessID pid=0; + Error err = OS::get_singleton()->execute(exec,args,false,&pid); + ERR_FAIL_COND(err); + } + // get_scene()->quit(); do not quit +} + +void ProjectManager::_run_project() { - OS::ProcessID pid=0; - Error err = OS::get_singleton()->execute(exec,args,false,&pid); - ERR_FAIL_COND(err); -// get_scene()->quit(); do not quit + if (selected_list.size()<1) { + return; + } + if (selected_list.size()>1) { + multi_run_ask->set_text("Are you sure to run more than one projects?"); + multi_run_ask->popup_centered(Size2(300,100)); + } else { + _run_project_confirm(); + } } void ProjectManager::_scan_dir(DirAccess *da,float pos, float total,List<String> *r_projects) { @@ -619,21 +744,24 @@ void ProjectManager::_import_project() { void ProjectManager::_erase_project_confirm() { - if (selected=="") { + if (selected_list.size()==0) { return; } - - EditorSettings::get_singleton()->erase("projects/"+selected); + for (Map<String,String>::Element *E=selected_list.front(); E; E=E->next()) { + EditorSettings::get_singleton()->erase("projects/"+E->key()); + EditorSettings::get_singleton()->erase("favorite_projects/"+E->key()); + } EditorSettings::get_singleton()->save(); - selected=""; - selected_main=""; + selected_list.clear(); + last_clicked = ""; + single_selected_main=""; _load_recent_projects(); } void ProjectManager::_erase_project() { - if (selected=="") + if (selected_list.size()==0) return; @@ -651,7 +779,9 @@ void ProjectManager::_exit_dialog() { void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_open_project",&ProjectManager::_open_project); + ObjectTypeDB::bind_method("_open_project_confirm",&ProjectManager::_open_project_confirm); ObjectTypeDB::bind_method("_run_project",&ProjectManager::_run_project); + ObjectTypeDB::bind_method("_run_project_confirm",&ProjectManager::_run_project_confirm); ObjectTypeDB::bind_method("_scan_projects",&ProjectManager::_scan_projects); ObjectTypeDB::bind_method("_scan_begin",&ProjectManager::_scan_begin); ObjectTypeDB::bind_method("_import_project",&ProjectManager::_import_project); @@ -662,6 +792,8 @@ void ProjectManager::_bind_methods() { ObjectTypeDB::bind_method("_load_recent_projects",&ProjectManager::_load_recent_projects); ObjectTypeDB::bind_method("_panel_draw",&ProjectManager::_panel_draw); ObjectTypeDB::bind_method("_panel_input",&ProjectManager::_panel_input); + ObjectTypeDB::bind_method("_favorite_pressed",&ProjectManager::_favorite_pressed); + } @@ -712,7 +844,7 @@ ProjectManager::ProjectManager() { scroll->set_enable_h_scroll(false); VBoxContainer *tree_vb = memnew( VBoxContainer); - tree_hb->add_child(tree_vb); + tree_hb->add_child(tree_vb); scroll_childs = memnew( VBoxContainer ); scroll_childs->set_h_size_flags(SIZE_EXPAND_FILL); scroll->add_child(scroll_childs); @@ -792,6 +924,18 @@ ProjectManager::ProjectManager() { add_child(erase_ask); + multi_open_ask = memnew( ConfirmationDialog ); + multi_open_ask->get_ok()->set_text("Edit"); + multi_open_ask->get_ok()->connect("pressed", this, "_open_project_confirm"); + + add_child(multi_open_ask); + + multi_run_ask = memnew( ConfirmationDialog ); + multi_run_ask->get_ok()->set_text("Run"); + multi_run_ask->get_ok()->connect("pressed", this, "_run_project_confirm"); + + add_child(multi_run_ask); + OS::get_singleton()->set_low_processor_usage_mode(true); npdialog = memnew( NewProjectDialog ); @@ -806,6 +950,7 @@ ProjectManager::ProjectManager() { //get_ok()->set_text("Open"); //get_ok()->set_text("Exit"); + last_clicked = ""; } diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index b3ad106cd8..eebfc56a66 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -46,11 +46,14 @@ class ProjectManager : public Control { FileDialog *scan_dir; ConfirmationDialog *erase_ask; + ConfirmationDialog *multi_open_ask; + ConfirmationDialog *multi_run_ask; NewProjectDialog *npdialog; ScrollContainer *scroll; VBoxContainer *scroll_childs; - String selected; - String selected_main; + Map<String, String> selected_list; // name -> main_scene + String last_clicked; + String single_selected_main; bool importing; void _item_doubleclicked(); @@ -59,7 +62,9 @@ class ProjectManager : public Control { void _scan_projects(); void _run_project(); + void _run_project_confirm(); void _open_project(); + void _open_project_confirm(); void _import_project(); void _new_project(); void _erase_project(); @@ -72,6 +77,7 @@ class ProjectManager : public Control { void _panel_draw(Node *p_hb); void _panel_input(const InputEvent& p_ev,Node *p_hb); + void _favorite_pressed(Node *p_hb); protected: diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 2087345888..2197902933 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1566,6 +1566,7 @@ CustomPropertyEditor::CustomPropertyEditor() { add_child(checks20[i]); checks20[i]->hide(); checks20[i]->connect("pressed",this,"_action_pressed",make_binds(i)); + checks20[i]->set_tooltip("Bit "+itos(i)+", val "+itos(1<<i)+"."); } text_edit = memnew( TextEdit ); diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp index 86331faa1d..bc0d48367a 100644 --- a/tools/editor/scenes_dock.cpp +++ b/tools/editor/scenes_dock.cpp @@ -37,12 +37,14 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir) { + String search_term = tree_filter->get_search_term(); + String file_filter = tree_filter->get_file_filter(); + TreeItem *item = tree->create_item(p_parent); item->set_text(0,p_dir->get_name()+"/"); item->set_icon(0,get_icon("Folder","EditorIcons")); item->set_custom_bg_color(0,get_color("prop_subsection","Editor")); - bool has_items=false; for(int i=0;i<p_dir->get_subdir_count();i++) { @@ -53,6 +55,15 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di for (int i=0;i<p_dir->get_file_count();i++) { + String file_name = p_dir->get_file(i); + String extension = file_name.extension(); + + if (search_term!="" && file_name.findn(search_term)==-1) + continue; + + if (file_filter!="*" && extension != file_filter ) + continue; + bool isfave = favorites.has(p_dir->get_file_path(i)); if (button_favorite->is_pressed() && !isfave) continue; @@ -61,7 +72,7 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di fitem->set_cell_mode(0,TreeItem::CELL_MODE_CHECK); fitem->set_editable(0,true); fitem->set_checked(0,isfave); - fitem->set_text(0,p_dir->get_file(i)); + fitem->set_text(0,file_name); Ref<Texture> icon = get_icon( (has_icon(p_dir->get_file_type(i),"EditorIcons")?p_dir->get_file_type(i):String("Object")),"EditorIcons"); fitem->set_icon(0, icon ); @@ -251,45 +262,40 @@ ScenesDock::ScenesDock(EditorNode *p_editor) { editor=p_editor; - tree = memnew( Tree ); - add_child(tree); - tree->set_area_as_parent_rect(); - tree->set_anchor_and_margin(MARGIN_TOP,Control::ANCHOR_BEGIN,25); - tree->connect("item_edited",this,"_favorite_toggled"); - + HBoxContainer *toolbar_hbc = memnew( HBoxContainer ); + add_child(toolbar_hbc); button_reload = memnew( Button ); - button_reload->set_pos(Point2(3,2)); - button_reload->set_size(Point2(20,5)); button_reload->set_flat(true); - add_child(button_reload); - button_reload->connect("pressed",this,"_rescan"); + button_reload->connect("pressed",this,"_rescan"); + toolbar_hbc->add_child(button_reload); button_favorite = memnew( Button ); - button_favorite->set_pos(Point2(28,2)); - button_favorite->set_size(Point2(20,5)); button_favorite->set_flat(true); button_favorite->set_toggle_mode(true); - add_child(button_favorite); button_favorite->connect("toggled",this,"_favorites_toggled"); + toolbar_hbc->add_child(button_favorite); - button_instance = memnew( Button ); - button_instance->set_anchor(MARGIN_LEFT,ANCHOR_END); - button_instance->set_anchor(MARGIN_RIGHT,ANCHOR_END); - button_instance->set_begin(Point2(3+20,2)); - button_instance->set_end(Point2(2+15,5)); - button_instance->set_flat(true); - add_child(button_instance); - button_instance->connect("pressed",this,"_instance_pressed"); + toolbar_hbc->add_spacer(); button_open = memnew( Button ); - button_open->set_anchor(MARGIN_LEFT,ANCHOR_END); - button_open->set_anchor(MARGIN_RIGHT,ANCHOR_END); - button_open->set_begin(Point2(3+45,2)); - button_open->set_end(Point2(2+34,5)); button_open->set_flat(true); - add_child(button_open); button_open->connect("pressed",this,"_open_pressed"); + toolbar_hbc->add_child(button_open); + + button_instance = memnew( Button ); + button_instance->set_flat(true); + button_instance->connect("pressed",this,"_instance_pressed"); + toolbar_hbc->add_child(button_instance); + + tree = memnew( Tree ); + tree_filter=memnew( ScenesDockFilter(tree) ); + tree_filter->connect("filter_changed", this, "_update_tree"); + add_child(tree_filter); + add_child(tree); + + tree->set_v_size_flags(SIZE_EXPAND_FILL); + tree->connect("item_edited",this,"_favorite_toggled"); timer = memnew( Timer ); timer->set_one_shot(true); @@ -300,10 +306,102 @@ ScenesDock::ScenesDock(EditorNode *p_editor) { updating_tree=false; +} +ScenesDock::~ScenesDock() { } -ScenesDock::~ScenesDock() { +void ScenesDockFilter::_setup_filters() { + + file_filter->clear(); + List<String> extensions; + ResourceLoader::get_recognized_extensions_for_type("",&extensions); + + file_filter->add_item("All Files (*)"); + filters.push_back("*"); + + List<String> filter_texts; + for(int i=0;i<extensions.size();i++) { + filter_texts.push_back("*."+extensions[i]+" ; "+extensions[i].to_upper()); + filters.push_back(extensions[i]); + } + for(int i=0;i<filter_texts.size();i++) { + + String flt=filter_texts[i].get_slice(";",0).strip_edges(); + String desc=filter_texts[i].get_slice(";",1).strip_edges(); + if (desc.length()) + file_filter->add_item(desc+" ( "+flt+" )"); + else + file_filter->add_item("( "+flt+" )"); + } +} + +void ScenesDockFilter::_command(int p_command) { + switch (p_command) { + + case CMD_CLEAR_FILTER: { + if (search_box->get_text()!="") { + search_box->clear(); + emit_signal("filter_changed"); + } + }break; + } +} + +void ScenesDockFilter::_search_text_changed(const String &p_newtext) { + emit_signal("filter_changed"); +} + +String ScenesDockFilter::get_search_term() { + return search_box->get_text().strip_edges(); +} + +String ScenesDockFilter::get_file_filter() { + return _current_filter; +} + +void ScenesDockFilter::_file_filter_selected(int p_idx) { + String selected = filters[file_filter->get_selected()]; + if (_current_filter != selected ) { + _current_filter = selected; + emit_signal("filter_changed"); + } } + +void ScenesDockFilter::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("_command"),&ScenesDockFilter::_command); + ObjectTypeDB::bind_method(_MD("_search_text_changed"), &ScenesDockFilter::_search_text_changed); + ObjectTypeDB::bind_method(_MD("_file_filter_selected"), &ScenesDockFilter::_file_filter_selected); + + ADD_SIGNAL( MethodInfo("filter_changed") ); +} + +ScenesDockFilter::ScenesDockFilter(Tree *p_tree) { + + _current_filter = "*"; + + tree = p_tree; + + file_filter = memnew( OptionButton ); + file_filter->set_custom_minimum_size(Size2(90,10)); + file_filter->set_clip_text(true); + file_filter->connect("item_selected", this, "_file_filter_selected"); + add_child(file_filter); + + _setup_filters(); + + search_box = memnew( LineEdit ); + search_box->connect("text_changed",this,"_search_text_changed"); + search_box->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(search_box); + + clear_search_button = memnew( Button ); + clear_search_button->set_text("clear"); + clear_search_button->connect("pressed",this,"_command",make_binds(CMD_CLEAR_FILTER)); + add_child(clear_search_button); + +} + diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h index eab31a5a4d..cf48e2885f 100644 --- a/tools/editor/scenes_dock.h +++ b/tools/editor/scenes_dock.h @@ -34,6 +34,8 @@ #include "scene/gui/tree.h" #include "scene/gui/label.h" #include "scene/gui/button.h" +#include "scene/gui/option_button.h" +#include "scene/gui/box_container.h" #include "os/dir_access.h" #include "os/thread.h" @@ -42,8 +44,9 @@ class EditorNode; -class ScenesDock : public Control { - OBJ_TYPE( ScenesDock, Control ); +class ScenesDockFilter; +class ScenesDock : public VBoxContainer { + OBJ_TYPE( ScenesDock, VBoxContainer ); EditorNode *editor; Set<String> favorites; @@ -54,6 +57,8 @@ class ScenesDock : public Control { Button *button_open; Timer *timer; + ScenesDockFilter *tree_filter; + bool updating_tree; Tree * tree; bool _create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir); @@ -77,4 +82,34 @@ public: ~ScenesDock(); }; +class ScenesDockFilter : public HBoxContainer { + + OBJ_TYPE( ScenesDockFilter, HBoxContainer ); + + enum Command { + CMD_CLEAR_FILTER, + }; + + Tree *tree; + OptionButton *file_filter; + LineEdit *search_box; + Button *clear_search_button; + + String _current_filter; + Vector<String> filters; + + void _command(int p_command); + void _search_text_changed(const String& p_newtext); + void _setup_filters(); + void _file_filter_selected(int p_idx); + +protected: + static void _bind_methods(); + +public: + String get_search_term(); + String get_file_filter(); + ScenesDockFilter(Tree *p_tree); +}; + #endif // SCENES_DOCK_H |