summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/editor/animation_editor.cpp36
-rw-r--r--tools/editor/animation_editor.h6
-rw-r--r--tools/editor/array_property_edit.cpp231
-rw-r--r--tools/editor/array_property_edit.h36
-rw-r--r--tools/editor/dependency_editor.cpp512
-rw-r--r--tools/editor/dependency_editor.h94
-rw-r--r--tools/editor/editor_data.cpp29
-rw-r--r--tools/editor/editor_data.h9
-rw-r--r--tools/editor/editor_file_dialog.cpp5
-rw-r--r--tools/editor/editor_file_system.cpp44
-rw-r--r--tools/editor/editor_file_system.h9
-rw-r--r--tools/editor/editor_import_export.cpp46
-rw-r--r--tools/editor/editor_import_export.h3
-rw-r--r--tools/editor/editor_node.cpp411
-rw-r--r--tools/editor/editor_node.h34
-rw-r--r--tools/editor/editor_path.cpp6
-rw-r--r--tools/editor/editor_run.cpp66
-rw-r--r--tools/editor/editor_settings.cpp9
-rw-r--r--tools/editor/icons/icon_anchor.pngbin0 -> 428 bytes
-rw-r--r--tools/editor/icons/icon_control_align_bottom_center.pngbin0 -> 174 bytes
-rw-r--r--tools/editor/icons/icon_control_align_bottom_left.pngbin0 -> 172 bytes
-rw-r--r--tools/editor/icons/icon_control_align_bottom_right.pngbin0 -> 174 bytes
-rw-r--r--tools/editor/icons/icon_control_align_bottom_wide.pngbin0 -> 174 bytes
-rw-r--r--tools/editor/icons/icon_control_align_center.pngbin0 -> 181 bytes
-rw-r--r--tools/editor/icons/icon_control_align_center_left.pngbin0 -> 172 bytes
-rw-r--r--tools/editor/icons/icon_control_align_center_right.pngbin0 -> 171 bytes
-rw-r--r--tools/editor/icons/icon_control_align_left_center.pngbin0 -> 183 bytes
-rw-r--r--tools/editor/icons/icon_control_align_left_wide.pngbin0 -> 166 bytes
-rw-r--r--tools/editor/icons/icon_control_align_right_center.pngbin0 -> 181 bytes
-rw-r--r--tools/editor/icons/icon_control_align_right_wide.pngbin0 -> 167 bytes
-rw-r--r--tools/editor/icons/icon_control_align_top_center.pngbin0 -> 181 bytes
-rw-r--r--tools/editor/icons/icon_control_align_top_left.pngbin0 -> 176 bytes
-rw-r--r--tools/editor/icons/icon_control_align_top_right.pngbin0 -> 183 bytes
-rw-r--r--tools/editor/icons/icon_control_align_top_wide.pngbin0 -> 179 bytes
-rw-r--r--tools/editor/icons/icon_control_align_wide.pngbin0 -> 165 bytes
-rw-r--r--tools/editor/icons/icon_control_hcenter_wide.pngbin0 -> 182 bytes
-rw-r--r--tools/editor/icons/icon_control_vcenter_wide.pngbin0 -> 171 bytes
-rw-r--r--tools/editor/icons/icon_file_list.pngbin260 -> 288 bytes
-rw-r--r--tools/editor/icons/icon_filesystem.pngbin0 -> 241 bytes
-rw-r--r--tools/editor/icons/icon_history.pngbin0 -> 572 bytes
-rw-r--r--tools/editor/icons/icon_multi_node_edit.pngbin0 -> 576 bytes
-rw-r--r--tools/editor/icons/icon_non_favorite.pngbin0 -> 469 bytes
-rw-r--r--tools/editor/icons/icon_patch_9_frame.pngbin0 -> 431 bytes
-rw-r--r--tools/editor/inspector_dock.cpp22
-rw-r--r--tools/editor/inspector_dock.h35
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp245
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp85
-rw-r--r--tools/editor/multi_node_edit.cpp118
-rw-r--r--tools/editor/multi_node_edit.h32
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.cpp44
-rw-r--r--tools/editor/plugins/animation_player_editor_plugin.h7
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp120
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.h20
-rw-r--r--tools/editor/plugins/mesh_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/multimesh_editor_plugin.cpp2
-rw-r--r--tools/editor/plugins/particles_2d_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/particles_editor_plugin.cpp1
-rw-r--r--tools/editor/plugins/spatial_editor_plugin.cpp17
-rw-r--r--tools/editor/project_export.cpp5
-rw-r--r--tools/editor/project_export.h3
-rw-r--r--tools/editor/project_settings.cpp49
-rw-r--r--tools/editor/property_editor.cpp173
-rw-r--r--tools/editor/property_editor.h6
-rw-r--r--tools/editor/quick_open.cpp42
-rw-r--r--tools/editor/quick_open.h10
-rw-r--r--tools/editor/scene_tree_dock.cpp35
-rw-r--r--tools/editor/scene_tree_dock.h2
-rw-r--r--tools/editor/scenes_dock.cpp1160
-rw-r--r--tools/editor/scenes_dock.h130
-rw-r--r--tools/editor/spatial_editor_gizmos.h4
-rw-r--r--tools/html_fs/godot.html1317
-rw-r--r--tools/html_fs/godotfs.js (renamed from tools/html_fs/filesystem.js)0
72 files changed, 4829 insertions, 444 deletions
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index d431af6c8d..96bd1ed27d 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -33,6 +33,7 @@
#include "io/resource_saver.h"
#include "pair.h"
#include "scene/gui/separator.h"
+#include "editor_node.h"
/* Missing to fix:
*Set
@@ -634,9 +635,14 @@ void AnimationKeyEditor::_menu_track(int p_type) {
last_menu_track_opt=p_type;
switch(p_type) {
- case TRACK_MENU_ADD_VALUE_TRACK:
- case TRACK_MENU_ADD_TRANSFORM_TRACK:
case TRACK_MENU_ADD_CALL_TRACK: {
+ if (root) {
+ call_select->popup_centered_ratio();
+ break;
+ }
+ } break;
+ case TRACK_MENU_ADD_VALUE_TRACK:
+ case TRACK_MENU_ADD_TRANSFORM_TRACK: {
undo_redo->create_action("Anim Add Track");
undo_redo->add_do_method(animation.ptr(),"add_track",p_type);
@@ -2735,6 +2741,7 @@ void AnimationKeyEditor::_notification(int p_what) {
}
+ call_select->connect("selected",this,"_add_call_track");
// rename_anim->set_icon( get_icon("Rename","EditorIcons") );
/*
edit_anim->set_icon( get_icon("Edit","EditorIcons") );
@@ -3456,6 +3463,26 @@ void AnimationKeyEditor::_scale() {
}
+void AnimationKeyEditor::_add_call_track(const NodePath& p_base) {
+
+ print_line("BASE IS "+String(p_base));
+ Node* base = EditorNode::get_singleton()->get_edited_scene();
+ if (!base)
+ return;
+ Node* from=base->get_node(p_base);
+ if (!from || !root)
+ return;
+
+ NodePath path = root->get_path_to(from);
+
+ undo_redo->create_action("Anim Add Call Track");
+ undo_redo->add_do_method(animation.ptr(),"add_track",Animation::TYPE_METHOD);
+ undo_redo->add_do_method(animation.ptr(),"track_set_path",animation->get_track_count(),path);
+ undo_redo->add_undo_method(animation.ptr(),"remove_track",animation->get_track_count());
+ undo_redo->commit_action();
+
+}
+
void AnimationKeyEditor::cleanup() {
set_animation(Ref<Animation>());
@@ -3503,6 +3530,7 @@ void AnimationKeyEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize);
ObjectTypeDB::bind_method(_MD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed);
ObjectTypeDB::bind_method(_MD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves);
+ ObjectTypeDB::bind_method(_MD("_add_call_track"),&AnimationKeyEditor::_add_call_track);
ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) );
@@ -3815,7 +3843,9 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
scale_dialog->connect("confirmed",this,"_scale");
add_child(scale_dialog);
-
+ call_select = memnew( SceneTreeDialog );
+ add_child(call_select);
+ call_select->set_title("Call Functions in Which Node?");
}
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 35053fb6a3..4a1cc21154 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -44,7 +44,7 @@
#include "scene_tree_editor.h"
#include "editor_data.h"
#include "property_editor.h"
-
+#include "scene_tree_editor.h"
class AnimationKeyEdit;
class AnimationCurveEdit;
@@ -206,6 +206,8 @@ class AnimationKeyEditor : public VBoxContainer {
PropertyEditor *key_editor;
+ SceneTreeDialog *call_select;
+
Ref<Animation> animation;
void _update_paths();
@@ -299,6 +301,8 @@ class AnimationKeyEditor : public VBoxContainer {
void _toggle_edit_curves();
void _animation_len_update();
+ void _add_call_track(const NodePath& p_base);
+
void _root_removed();
protected:
diff --git a/tools/editor/array_property_edit.cpp b/tools/editor/array_property_edit.cpp
new file mode 100644
index 0000000000..9cd443270b
--- /dev/null
+++ b/tools/editor/array_property_edit.cpp
@@ -0,0 +1,231 @@
+#include "array_property_edit.h"
+
+#include "editor_node.h"
+
+#define ITEMS_PER_PAGE 100
+
+Variant ArrayPropertyEdit::get_array() const{
+
+ Object*o = ObjectDB::get_instance(obj);
+ if (!o)
+ return Array();
+ Variant arr=o->get(property);
+ if (!arr.is_array()) {
+ Variant::CallError ce;
+ arr=Variant::construct(default_type,NULL,0,ce);
+ }
+ return arr;
+}
+
+void ArrayPropertyEdit::_notif_change() {
+ _change_notify();
+}
+void ArrayPropertyEdit::_notif_changev(const String& p_v) {
+
+ _change_notify(p_v.utf8().get_data());
+}
+
+void ArrayPropertyEdit::_set_size(int p_size) {
+
+ Variant arr = get_array();
+ arr.call("resize",p_size);
+ Object*o = ObjectDB::get_instance(obj);
+ if (!o)
+ return;
+
+ o->set(property,arr);
+
+}
+
+void ArrayPropertyEdit::_set_value(int p_idx,const Variant& p_value) {
+
+ Variant arr = get_array();
+ arr.set(p_idx,p_value);
+ Object*o = ObjectDB::get_instance(obj);
+ if (!o)
+ return;
+
+ o->set(property,arr);
+}
+
+bool ArrayPropertyEdit::_set(const StringName& p_name, const Variant& p_value){
+
+ String pn=p_name;
+
+ if (pn.begins_with("array/")) {
+
+ if (pn=="array/size") {
+
+ Variant arr = get_array();
+ int size = arr.call("size");
+
+ int newsize=p_value;
+ if (newsize==size)
+ return true;
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action("Resize Array");
+ ur->add_do_method(this,"_set_size",newsize);
+ ur->add_undo_method(this,"_set_size",size);
+ if (newsize<size) {
+ for(int i=newsize;i<size;i++) {
+ ur->add_undo_method(this,"_set_value",i,arr.get(i));
+
+ }
+ }
+ ur->add_do_method(this,"_notif_change");
+ ur->add_undo_method(this,"_notif_change");
+ ur->commit_action();
+ return true;
+ }
+ if (pn=="array/page") {
+ page=p_value;
+ _change_notify();
+ return true;
+ }
+ } else if (pn.begins_with("indices")) {
+
+ if (pn.find("_")!=-1) {
+ //type
+ int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
+
+ int type = p_value;
+
+ Variant arr = get_array();
+
+ Variant value = arr.get(idx);
+ if (value.get_type()!=type && type>=0 && type<Variant::VARIANT_MAX) {
+ Variant::CallError ce;
+ Variant new_value=Variant::construct(Variant::Type(type),NULL,0,ce);
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action("Change Array Value Type");
+ ur->add_do_method(this,"_set_value",idx,new_value);
+ ur->add_undo_method(this,"_set_value",idx,value);
+ ur->add_do_method(this,"_notif_change");
+ ur->add_undo_method(this,"_notif_change");
+ ur->commit_action();
+
+ }
+ return true;
+
+ } else {
+ int idx=pn.get_slicec('/',1).to_int();
+ Variant arr = get_array();
+
+ Variant value = arr.get(idx);
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action("Change Array Value");
+ ur->add_do_method(this,"_set_value",idx,p_value);
+ ur->add_undo_method(this,"_set_value",idx,value);
+ ur->add_do_method(this,"_notif_changev",p_name);
+ ur->add_undo_method(this,"_notif_changev",p_name);
+ ur->commit_action();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ArrayPropertyEdit::_get(const StringName& p_name,Variant &r_ret) const {
+
+ Variant arr = get_array();
+ //int size = arr.call("size");
+
+ String pn=p_name;
+ if (pn.begins_with("array/")) {
+
+ if (pn=="array/size") {
+ r_ret=arr.call("size");
+ return true;
+ }
+ if (pn=="array/page") {
+ r_ret=page;
+ return true;
+ }
+ } else if (pn.begins_with("indices")) {
+
+ if (pn.find("_")!=-1) {
+ //type
+ int idx=pn.get_slicec('/',1).get_slicec('_',0).to_int();
+ bool valid;
+ r_ret=arr.get(idx,&valid);
+ if (valid)
+ r_ret=r_ret.get_type();
+ return valid;
+
+ } else {
+ int idx=pn.get_slicec('/',1).to_int();
+ bool valid;
+ r_ret=arr.get(idx,&valid);
+ return valid;
+ }
+ }
+
+ return false;
+}
+
+void ArrayPropertyEdit::_get_property_list( List<PropertyInfo> *p_list) const{
+
+ Variant arr = get_array();
+ int size = arr.call("size");
+
+ p_list->push_back( PropertyInfo(Variant::INT,"array/size",PROPERTY_HINT_RANGE,"0,100000,1") );
+ int pages = size/ITEMS_PER_PAGE;
+ if (pages>0)
+ p_list->push_back( PropertyInfo(Variant::INT,"array/page",PROPERTY_HINT_RANGE,"0,"+itos(pages)+",1") );
+
+ int offset=page*ITEMS_PER_PAGE;
+
+ int items=MIN(size-offset,ITEMS_PER_PAGE);
+
+
+ for(int i=0;i<items;i++) {
+
+ Variant v=arr.get(i+offset);
+ if (arr.get_type()==Variant::ARRAY) {
+ p_list->push_back(PropertyInfo(Variant::INT,"indices/"+itos(i+offset)+"_type",PROPERTY_HINT_ENUM,vtypes));
+ }
+ if (arr.get_type()!=Variant::ARRAY || v.get_type()!=Variant::NIL) {
+ PropertyInfo pi(v.get_type(),"indices/"+itos(i+offset));
+ if (v.get_type()==Variant::OBJECT) {
+ pi.hint=PROPERTY_HINT_RESOURCE_TYPE;
+ pi.hint_string="Resource";
+ }
+ p_list->push_back(pi);
+ }
+ }
+
+}
+
+void ArrayPropertyEdit::edit(Object* p_obj,const StringName& p_prop,Variant::Type p_deftype) {
+
+ page=0;
+ property=p_prop;
+ obj=p_obj->get_instance_ID();
+ default_type=p_deftype;
+
+}
+
+void ArrayPropertyEdit::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_set_size"),&ArrayPropertyEdit::_set_size);
+ ObjectTypeDB::bind_method(_MD("_set_value"),&ArrayPropertyEdit::_set_value);
+ ObjectTypeDB::bind_method(_MD("_notif_change"),&ArrayPropertyEdit::_notif_change);
+ ObjectTypeDB::bind_method(_MD("_notif_changev"),&ArrayPropertyEdit::_notif_changev);
+}
+
+ArrayPropertyEdit::ArrayPropertyEdit()
+{
+ page=0;
+ for(int i=0;i<Variant::VARIANT_MAX;i++) {
+
+ if (i>0)
+ vtypes+=",";
+ vtypes+=Variant::get_type_name( Variant::Type(i) );
+ }
+ default_type=Variant::NIL;
+
+}
diff --git a/tools/editor/array_property_edit.h b/tools/editor/array_property_edit.h
new file mode 100644
index 0000000000..acfb8e68ed
--- /dev/null
+++ b/tools/editor/array_property_edit.h
@@ -0,0 +1,36 @@
+#ifndef ARRAY_PROPERTY_EDIT_H
+#define ARRAY_PROPERTY_EDIT_H
+
+#include "scene/main/node.h"
+
+class ArrayPropertyEdit : public Reference {
+
+ OBJ_TYPE(ArrayPropertyEdit,Reference);
+
+ int page;
+ ObjectID obj;
+ StringName property;
+ String vtypes;
+ Variant get_array() const;
+ Variant::Type default_type;
+
+ void _notif_change();
+ void _notif_changev(const String& p_v);
+ void _set_size(int p_size);
+ void _set_value(int p_idx,const Variant& p_value);
+
+protected:
+
+ static void _bind_methods();
+ bool _set(const StringName& p_name, const Variant& p_value);
+ bool _get(const StringName& p_name,Variant &r_ret) const;
+ void _get_property_list( List<PropertyInfo> *p_list) const;
+
+public:
+
+ void edit(Object* p_obj, const StringName& p_prop, Variant::Type p_deftype);
+
+ ArrayPropertyEdit();
+};
+
+#endif // ARRAY_PROPERTY_EDIT_H
diff --git a/tools/editor/dependency_editor.cpp b/tools/editor/dependency_editor.cpp
new file mode 100644
index 0000000000..c04e82a08a
--- /dev/null
+++ b/tools/editor/dependency_editor.cpp
@@ -0,0 +1,512 @@
+#include "dependency_editor.h"
+#include "os/file_access.h"
+#include "scene/gui/margin_container.h"
+#include "io/resource_loader.h"
+#include "editor_node.h"
+
+void DependencyEditor::_notification(int p_what){
+
+
+}
+
+void DependencyEditor::_searched(const String& p_path) {
+
+ Map<String,String> dep_rename;
+ dep_rename[replacing]=p_path;
+
+
+ ResourceLoader::rename_dependencies(editing,dep_rename);
+
+ _update_list();
+ _update_file();
+}
+
+void DependencyEditor::_load_pressed(Object* p_item,int p_cell,int p_button){
+
+ TreeItem *ti=p_item->cast_to<TreeItem>();
+ String fname = ti->get_text(0);
+ replacing = ti->get_text(1);
+
+ search->set_title("Search Replacement For: "+replacing.get_file());
+
+ search->clear_filters();
+ List<String> ext;
+ ResourceLoader::get_recognized_extensions_for_type(ti->get_metadata(0),&ext);
+ for (List<String>::Element *E=ext.front();E;E=E->next()) {
+ search->add_filter("*"+E->get());
+ }
+ search->popup_centered_ratio();
+
+}
+
+void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String,Map<String,String> >& candidates){
+
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+ _fix_and_find(efsd->get_subdir(i),candidates);
+ }
+
+ for(int i=0;i<efsd->get_file_count();i++) {
+
+ String file = efsd->get_file(i);
+ if (!candidates.has(file))
+ continue;
+
+ String path = efsd->get_file_path(i);
+ Map<String,String> &ss = candidates[file];
+
+
+ for(Map<String,String>::Element *E=candidates[file].front();E;E=E->next()) {
+
+ if (E->get()==String()) {
+ E->get()=path;
+ continue;
+ }
+
+ //must match the best, using subdirs
+ String existing=E->get().replace_first("res://","");
+ String current=path.replace_first("res://","");
+ String lost=E->key().replace_first("res://","");
+
+ Vector<String> existingv=existing.split("/");
+ existingv.invert();
+ Vector<String> currentv=current.split("/");
+ currentv.invert();
+ Vector<String> lostv=lost.split("/");
+ lostv.invert();
+
+ int existing_score=0;
+ int current_score=0;
+
+ for(int j=0;j<lostv.size();j++) {
+
+ if (j<existingv.size() && lostv[j]==existingv[j]) {
+ existing_score++;
+ }
+ if (j<currentv.size() && lostv[j]==currentv[j]) {
+ current_score++;
+ }
+ }
+
+ if (current_score > existing_score) {
+
+ //if it was the same, could track distance to new path but..
+
+ E->get()=path; //replace by more accurate
+ }
+
+ }
+
+ }
+
+}
+
+
+void DependencyEditor::_fix_all(){
+
+ if (!EditorFileSystem::get_singleton()->get_filesystem())
+ return;
+
+ Map<String,Map<String,String> > candidates;
+
+ for (List<String>::Element *E=missing.front();E;E=E->next()) {
+
+ String base = E->get().get_file();
+ if (!candidates.has(base)) {
+ candidates[base]=Map<String,String>();
+ }
+
+ candidates[base][E->get()]="";
+ }
+
+ _fix_and_find(EditorFileSystem::get_singleton()->get_filesystem(),candidates);
+
+ Map<String,String> remaps;
+
+ for (Map<String,Map<String,String> >::Element *E=candidates.front();E;E=E->next()) {
+
+ for (Map<String,String>::Element *F=E->get().front();F;F=F->next()) {
+
+ if (F->get()!=String()) {
+ remaps[F->key()]=F->get();
+ }
+ }
+
+ }
+
+ if (remaps.size()) {
+
+ ResourceLoader::rename_dependencies(editing,remaps);
+
+ _update_list();
+ _update_file();
+ }
+}
+
+void DependencyEditor::_update_file() {
+
+ EditorFileSystem::get_singleton()->update_file(editing);
+
+}
+
+void DependencyEditor::_update_list() {
+
+ List<String> deps;
+ ResourceLoader::get_dependencies(editing,&deps,true);
+
+ tree->clear();
+ missing.clear();
+
+ TreeItem *root = tree->create_item();
+
+ Ref<Texture> folder = get_icon("folder","FileDialog");
+
+ bool broken=false;
+
+ for(List<String>::Element *E=deps.front();E;E=E->next()) {
+
+ TreeItem *item = tree->create_item(root);
+
+ String n = E->get();
+ String path;
+ String type;
+
+ if (n.find("::")!=-1) {
+ path = n.get_slice("::",0);
+ type = n.get_slice("::",1);
+ } else {
+ path=n;
+ type="Resource";
+ }
+ String name = path.get_file();
+
+ Ref<Texture> icon;
+ if (has_icon(type,"EditorIcons")) {
+ icon=get_icon(type,"EditorIcons");
+ } else {
+ icon=get_icon("Object","EditorIcons");
+ }
+ item->set_text(0,name);
+ item->set_icon(0,icon);
+ item->set_metadata(0,type);
+ item->set_text(1,path);
+
+ if (!FileAccess::exists(path)) {
+ item->set_custom_color(1,Color(1,0.4,0.3));
+ missing.push_back(path);
+ broken=true;
+ }
+
+ item->add_button(1,folder,0);
+ }
+
+ fixdeps->set_disabled(!broken);
+
+}
+
+
+
+void DependencyEditor::edit(const String& p_path) {
+
+
+ editing=p_path;
+ set_title("Dependencies For: "+p_path.get_file());
+
+ _update_list();
+ popup_centered_ratio();
+
+ if (EditorNode::get_singleton()->is_scene_open(p_path)) {
+ EditorNode::get_singleton()->show_warning("Scene '"+p_path.get_file()+"' is currently being edited.\nChanges will not take effect unless reloaded.");
+ } else if (ResourceCache::has(p_path)) {
+ EditorNode::get_singleton()->show_warning("Resource '"+p_path.get_file()+"' is in use.\nChanges will take effect when reloaded.");
+ }
+}
+
+
+void DependencyEditor::_bind_methods() {
+
+ ObjectTypeDB::bind_method(_MD("_searched"),&DependencyEditor::_searched);
+ ObjectTypeDB::bind_method(_MD("_load_pressed"),&DependencyEditor::_load_pressed);
+ ObjectTypeDB::bind_method(_MD("_fix_all"),&DependencyEditor::_fix_all);
+
+}
+
+DependencyEditor::DependencyEditor() {
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ vb->set_name("Dependencies");
+ add_child(vb);
+ set_child_rect(vb);
+
+ tree = memnew( Tree );
+ tree->set_columns(2);
+ tree->set_column_titles_visible(true);
+ tree->set_column_title(0,"Resource");
+ tree->set_column_title(1,"Path");
+ tree->set_hide_root(true);
+ tree->connect("button_pressed",this,"_load_pressed");
+
+ HBoxContainer *hbc = memnew( HBoxContainer );
+ Label *label = memnew( Label("Dependencies:"));
+ hbc->add_child(label);
+ hbc->add_spacer();
+ fixdeps = memnew( Button("Fix Broken"));
+ hbc->add_child(fixdeps);
+ fixdeps->connect("pressed",this,"_fix_all");
+
+ vb->add_child(hbc);
+
+ MarginContainer *mc = memnew( MarginContainer );
+ mc->set_v_size_flags(SIZE_EXPAND_FILL);
+
+ mc->add_child(tree);
+ vb->add_child(mc);
+
+ set_title("Dependency Editor");
+ search = memnew( EditorFileDialog );
+ search->connect("file_selected",this,"_searched");
+ search->set_mode(EditorFileDialog::MODE_OPEN_FILE);
+ search->set_title("Search Replacement Resource:");
+ add_child(search);
+
+}
+
+/////////////////////////////////////
+
+
+
+void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
+
+ if (!efsd)
+ return;
+
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+ _fill_owners(efsd->get_subdir(i));
+ }
+
+ for(int i=0;i<efsd->get_file_count();i++) {
+
+ Vector<String> deps = efsd->get_file_deps(i);
+ //print_line(":::"+efsd->get_file_path(i));
+ bool found=false;
+ for(int j=0;j<deps.size();j++) {
+ //print_line("\t"+deps[j]+" vs "+editing);
+ if (deps[j]==editing) {
+ //print_line("found");
+ found=true;
+ break;
+ }
+ }
+ if (!found)
+ continue;
+
+ Ref<Texture> icon;
+ String type=efsd->get_file_type(i);
+ if (!has_icon(type,"EditorIcons")) {
+ icon=get_icon("Object","EditorIcons");
+ } else {
+ icon=get_icon(type,"EditorIcons");
+ }
+
+ owners->add_item(efsd->get_file_path(i),icon);
+ }
+
+}
+
+void DependencyEditorOwners::show(const String& p_path) {
+
+ editing=p_path;
+ owners->clear();
+ _fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
+ popup_centered_ratio();
+
+ set_title("Owners Of: "+p_path.get_file());
+
+}
+
+DependencyEditorOwners::DependencyEditorOwners() {
+
+
+ owners = memnew( ItemList );
+ add_child(owners);
+ set_child_rect(owners);
+
+
+}
+
+///////////////////////
+
+
+void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) {
+
+ if (!efsd)
+ return;
+
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+ _fill_owners(efsd->get_subdir(i));
+ }
+
+ for(int i=0;i<efsd->get_file_count();i++) {
+
+ Vector<String> deps = efsd->get_file_deps(i);
+ //print_line(":::"+efsd->get_file_path(i));
+ Set<String> met;
+ for(int j=0;j<deps.size();j++) {
+ if (files.has(deps[j])) {
+ met.insert(deps[j]);
+ }
+ }
+ if (!met.size())
+ continue;
+
+ exist=true;
+
+ Ref<Texture> icon;
+ String type=efsd->get_file_type(i);
+ if (!has_icon(type,"EditorIcons")) {
+ icon=get_icon("Object","EditorIcons");
+ } else {
+ icon=get_icon(type,"EditorIcons");
+ }
+
+
+ for(Set<String>::Element *E=met.front();E;E=E->next()) {
+
+ String which = E->get();
+ if (!files[which]) {
+ TreeItem *ti=owners->create_item(owners->get_root());
+ ti->set_text(0,which.get_file());
+ files[which]=ti;
+
+ }
+ TreeItem *ti=owners->create_item(files[which]);
+ ti->set_text(0,efsd->get_file_path(i));
+ ti->set_icon(0,icon);
+ }
+
+ }
+
+}
+
+void DependencyRemoveDialog::show(const Vector<String> &to_erase) {
+
+ exist=false;
+ owners->clear();
+ files.clear();
+ TreeItem *root=owners->create_item();
+ for(int i=0;i<to_erase.size();i++) {
+ files[to_erase[i]]=NULL;
+ }
+
+ _fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
+
+ if (exist) {
+ owners->show();
+ text->set_text("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)");
+ popup_centered_minsize(Size2(500,220));
+ } else {
+ owners->hide();
+ text->set_text("Remove selected files from the project? (no undo)");
+ popup_centered_minsize(Size2(400,100));
+ }
+
+}
+
+void DependencyRemoveDialog::ok_pressed() {
+
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ for (Map<String,TreeItem*>::Element *E=files.front();E;E=E->next()) {
+
+ da->remove(E->key());
+ EditorFileSystem::get_singleton()->update_file(E->key());
+ }
+ memdelete(da);
+
+}
+
+DependencyRemoveDialog::DependencyRemoveDialog() {
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ add_child(vb);
+ set_child_rect(vb);
+
+ text = memnew( Label );
+ vb->add_child(text);
+
+ owners = memnew( Tree );
+ owners->set_hide_root(true);
+ vb->add_child(owners);
+ owners->set_v_size_flags(SIZE_EXPAND_FILL);
+ get_ok()->set_text("Remove");
+}
+
+
+//////////////
+
+
+void DependencyErrorDialog::show(const String& p_for_file,const Vector<String> &report) {
+
+
+ for_file=p_for_file;
+ set_title("Error loading: "+p_for_file.get_file());
+ files->clear();
+
+ TreeItem *root = files->create_item(NULL);
+ for(int i=0;i<report.size();i++) {
+
+ String dep;
+ String type="Object";
+ dep=report[i].get_slice("::",0);
+ if (report[i].get_slice_count("::")>0)
+ type=report[i].get_slice("::",1);
+
+ Ref<Texture> icon;
+ if (!has_icon(type,"EditorIcons")) {
+ icon=get_icon("Object","EditorIcons");
+ } else {
+ icon=get_icon(type,"EditorIcons");
+ }
+
+ TreeItem *ti=files->create_item(root);
+ ti->set_text(0,dep);
+ ti->set_icon(0,icon);
+
+ }
+
+ popup_centered_minsize(Size2(500,220));
+
+}
+
+void DependencyErrorDialog::ok_pressed() {
+
+ EditorNode::get_singleton()->load_scene(for_file,true);
+}
+
+void DependencyErrorDialog::custom_action(const String&) {
+
+ EditorNode::get_singleton()->fix_dependencies(for_file);
+}
+
+DependencyErrorDialog::DependencyErrorDialog() {
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ add_child(vb);
+ set_child_rect(vb);
+
+
+ files = memnew( Tree );
+ files->set_hide_root(true);
+ vb->add_margin_child("Scene failed to load due to missing dependencies:",files,true);
+ files->set_v_size_flags(SIZE_EXPAND_FILL);
+ get_ok()->set_text("Open Anyway");
+
+ text = memnew( Label );
+ vb->add_child(text);
+ text->set_text("Which action should be taken?");
+
+
+ fdep=add_button("Fix Dependencies",true,"fixdeps");
+
+ set_title("Errors loading!");
+
+}
diff --git a/tools/editor/dependency_editor.h b/tools/editor/dependency_editor.h
new file mode 100644
index 0000000000..1c328e7a93
--- /dev/null
+++ b/tools/editor/dependency_editor.h
@@ -0,0 +1,94 @@
+#ifndef DEPENDENCY_EDITOR_H
+#define DEPENDENCY_EDITOR_H
+
+#include "scene/gui/dialogs.h"
+#include "scene/gui/tree.h"
+#include "scene/gui/tab_container.h"
+#include "editor_file_dialog.h"
+
+class EditorFileSystemDirectory;
+
+class DependencyEditor : public AcceptDialog {
+ OBJ_TYPE(DependencyEditor,AcceptDialog);
+
+
+ Tree *tree;
+ Button *fixdeps;
+
+ EditorFileDialog *search;
+
+ String replacing;
+ String editing;
+ List<String> missing;
+
+
+ void _fix_and_find(EditorFileSystemDirectory *efsd, Map<String,Map<String,String> >& candidates);
+
+ void _searched(const String& p_path);
+ void _load_pressed(Object* p_item,int p_cell,int p_button);
+ void _fix_all();
+ void _update_list();
+
+ void _update_file();
+
+protected:
+
+ static void _bind_methods();
+ void _notification(int p_what);
+public:
+
+
+ void edit(const String& p_path);
+ DependencyEditor();
+};
+
+class DependencyEditorOwners : public AcceptDialog {
+ OBJ_TYPE(DependencyEditorOwners,AcceptDialog);
+
+ ItemList *owners;
+ String editing;
+ void _fill_owners(EditorFileSystemDirectory *efsd);
+
+public:
+
+ void show(const String& p_path);
+ DependencyEditorOwners();
+};
+
+class DependencyRemoveDialog : public ConfirmationDialog {
+ OBJ_TYPE(DependencyRemoveDialog,ConfirmationDialog);
+
+
+ Label *text;
+ Tree *owners;
+ bool exist;
+ Map<String,TreeItem*> files;
+ void _fill_owners(EditorFileSystemDirectory *efsd);
+
+ void ok_pressed();
+
+public:
+
+ void show(const Vector<String> &to_erase);
+ DependencyRemoveDialog();
+};
+
+
+class DependencyErrorDialog : public ConfirmationDialog {
+ OBJ_TYPE(DependencyErrorDialog,ConfirmationDialog);
+
+
+ String for_file;
+ Button *fdep;
+ Label *text;
+ Tree *files;
+ void ok_pressed();
+ void custom_action(const String&);
+
+public:
+
+ void show(const String& p_for,const Vector<String> &report);
+ DependencyErrorDialog();
+};
+
+#endif // DEPENDENCY_EDITOR_H
diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp
index 7f42f19a9b..673ee30adb 100644
--- a/tools/editor/editor_data.cpp
+++ b/tools/editor/editor_data.cpp
@@ -39,7 +39,7 @@ void EditorHistory::_cleanup_history() {
bool fail=false;
for(int j=0;j<history[i].path.size();j++) {
- if (!history[i].path[j].res.is_null())
+ if (!history[i].path[j].ref.is_null())
continue;
if (ObjectDB::get_instance(history[i].path[j].object))
@@ -70,10 +70,10 @@ void EditorHistory::_add_object(ObjectID p_object,const String& p_property,int p
Object *obj = ObjectDB::get_instance(p_object);
ERR_FAIL_COND(!obj);
- Resource *r = obj->cast_to<Resource>();
+ Reference *r = obj->cast_to<Reference>();
Obj o;
if (r)
- o.res=RES(r);
+ o.ref=REF(r);
o.object=p_object;
o.property=p_property;
@@ -123,6 +123,27 @@ void EditorHistory::add_object(ObjectID p_object,int p_relevel){
_add_object(p_object,"",p_relevel);
}
+int EditorHistory::get_history_len() {
+ return history.size();
+}
+int EditorHistory::get_history_pos() {
+ return current;
+}
+
+ObjectID EditorHistory::get_history_obj(int p_obj) const {
+ ERR_FAIL_INDEX_V(p_obj,history.size(),0);
+ ERR_FAIL_INDEX_V(history[p_obj].level,history[p_obj].path.size(),0);
+ return history[p_obj].path[history[p_obj].level].object;
+}
+
+bool EditorHistory::is_at_begining() const {
+ return current<=0;
+}
+bool EditorHistory::is_at_end() const {
+
+ return ((current+1)>=history.size());
+}
+
bool EditorHistory::next() {
@@ -523,7 +544,7 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
if (!edited_scene[p_idx].root)
return Ref<Script>();
Ref<Script> s=edited_scene[p_idx].root->get_script();
- if (!s.is_valid()) {
+ if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) {
Node *n = edited_scene[p_idx].root->get_child(0);
while(!s.is_valid() && n && n->get_filename()==String()) {
s=n->get_script();
diff --git a/tools/editor/editor_data.h b/tools/editor/editor_data.h
index cbec2295f6..c5ee83ae63 100644
--- a/tools/editor/editor_data.h
+++ b/tools/editor/editor_data.h
@@ -45,7 +45,7 @@ class EditorHistory {
struct Obj {
- RES res;
+ REF ref;
ObjectID object;
String property;
};
@@ -75,10 +75,17 @@ friend class EditorData;
public:
+ bool is_at_begining() const;
+ bool is_at_end() const;
+
void add_object(ObjectID p_object);
void add_object(ObjectID p_object,const String& p_subprop);
void add_object(ObjectID p_object,int p_relevel);
+ int get_history_len();
+ int get_history_pos();
+ ObjectID get_history_obj(int p_obj) const;
+
bool next();
bool previous();
ObjectID get_current();
diff --git a/tools/editor/editor_file_dialog.cpp b/tools/editor/editor_file_dialog.cpp
index b1bbd71f7b..c62347d129 100644
--- a/tools/editor/editor_file_dialog.cpp
+++ b/tools/editor/editor_file_dialog.cpp
@@ -190,7 +190,7 @@ void EditorFileDialog::_thumbnail_done(const String& p_path,const Ref<Texture>&
void EditorFileDialog::_request_single_thumbnail(const String& p_path) {
EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",p_path);
- print_line("want file "+p_path);
+ //print_line("want file "+p_path);
set_process(true);
preview_waiting=true;
preview_wheel_timeout=0;
@@ -359,7 +359,7 @@ void EditorFileDialog::_item_dc_selected(int p_item) {
if (d["dir"]) {
- print_line("change dir: "+String(d["name"]));
+ //print_line("change dir: "+String(d["name"]));
dir_access->change_dir(d["name"]);
if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
file->set_text("");
@@ -536,6 +536,7 @@ void EditorFileDialog::update_file_list() {
if (get_icon_func) {
+
Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
//ti->set_icon(0,icon);
if (display_mode==DISPLAY_THUMBNAILS) {
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp
index d741087a9f..33e4a15c85 100644
--- a/tools/editor/editor_file_system.cpp
+++ b/tools/editor/editor_file_system.cpp
@@ -94,6 +94,12 @@ bool EditorFileSystemDirectory::get_file_meta(int p_idx) const {
return files[p_idx].meta.enabled;
}
+Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {
+
+ ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
+ return files[p_idx].meta.deps;
+
+}
Vector<String> EditorFileSystemDirectory::get_missing_sources(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
@@ -118,7 +124,7 @@ bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const {
return false;
}
-String EditorFileSystemDirectory::get_file_type(int p_idx) const {
+StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),"");
return files[p_idx].type;
@@ -198,6 +204,13 @@ EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String&
}
m.import_editor=imd->get_editor();
}
+
+ List<String> deps;
+ ResourceLoader::get_dependencies(p_path,&deps);
+ for(List<String>::Element *E=deps.front();E;E=E->next()) {
+ m.deps.push_back(E->get());
+ }
+
return m;
}
@@ -358,7 +371,7 @@ void EditorFileSystem::_scan_scenes() {
String project=Globals::get_singleton()->get_resource_path();
- String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("file_cache");
+ String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache");
FileAccess *f =FileAccess::open(fscache,FileAccess::READ);
if (f) {
@@ -397,7 +410,7 @@ void EditorFileSystem::_scan_scenes() {
} else {
Vector<String> split = l.split("::");
- ERR_CONTINUE( split.size() != 4);
+ ERR_CONTINUE( split.size() != 5);
String name = split[0];
String file;
@@ -429,6 +442,15 @@ void EditorFileSystem::_scan_scenes() {
}
}
+ String deps = split[4].strip_edges();
+ if (deps.length()) {
+ Vector<String> dp = deps.split("<>");
+ for(int i=0;i<dp.size();i++) {
+ String path=dp[i];
+ fc.meta.deps.push_back(path);
+ }
+ }
+
file_cache[name]=fc;
ERR_CONTINUE(!dc);
@@ -530,6 +552,7 @@ void EditorFileSystem::scan() {
thread = Thread::create(_thread_func,this,s);
//tree->hide();
//progress->show();
+
}
@@ -798,6 +821,14 @@ void EditorFileSystem::_save_type_cache_fs(DirItem *p_dir,FileAccess *p_file) {
}
}
+ s+="::";
+ for(int j=0;j<p_dir->files[i]->meta.deps.size();j++) {
+
+ if (j>0)
+ s+="<>";
+ s+=p_dir->files[i]->meta.deps[j];
+ }
+
p_file->store_line(s);
}
@@ -1037,6 +1068,13 @@ void EditorFileSystem::update_file(const String& p_file) {
return;
}
+ if (!FileAccess::exists(p_file)) {
+ //was removed
+ fs->files.remove(cpos);
+ call_deferred("emit_signal","filesystem_changed"); //update later
+ return;
+
+ }
String type = ResourceLoader::get_resource_type(p_file);
diff --git a/tools/editor/editor_file_system.h b/tools/editor/editor_file_system.h
index 3f413292fe..f79dd209ef 100644
--- a/tools/editor/editor_file_system.h
+++ b/tools/editor/editor_file_system.h
@@ -59,13 +59,14 @@ class EditorFileSystemDirectory : public Object {
Vector<Source> sources;
String import_editor;
+ Vector<String> deps;
bool enabled;
};
struct FileInfo {
String file;
- String type;
+ StringName type;
uint64_t modified_time;
ImportMeta meta;
@@ -87,10 +88,11 @@ public:
int get_file_count() const;
String get_file(int p_idx) const;
String get_file_path(int p_idx) const;
- String get_file_type(int p_idx) const;
+ StringName get_file_type(int p_idx) const;
bool get_file_meta(int p_idx) const;
bool is_missing_sources(int p_idx) const;
Vector<String> get_missing_sources(int p_idx) const;
+ Vector<String> get_file_deps(int p_idx) const;
EditorFileSystemDirectory *get_parent();
@@ -120,7 +122,7 @@ class EditorFileSystem : public Node {
String path;
String name;
Vector<DirItem*> dirs;
- Vector<SceneItem*> files;
+ Vector<SceneItem*> files;
~DirItem();
};
@@ -149,6 +151,7 @@ class EditorFileSystem : public Node {
String type;
uint64_t modification_time;
EditorFileSystemDirectory::ImportMeta meta;
+ Vector<String> deps;
};
struct DirCache {
diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp
index b28b349c86..84fc14d2ec 100644
--- a/tools/editor/editor_import_export.cpp
+++ b/tools/editor/editor_import_export.cpp
@@ -255,7 +255,16 @@ static void _add_filter_to_list(Set<StringName>& r_list,const String& p_filter)
}
+Vector<uint8_t> EditorExportPlatform::get_exported_file_default(String& p_fname) const {
+ FileAccess *f = FileAccess::open(p_fname,FileAccess::READ);
+ ERR_FAIL_COND_V(!f,Vector<uint8_t>());
+ Vector<uint8_t> ret;
+ ret.resize(f->get_len());
+ int rbs = f->get_buffer(ret.ptr(),ret.size());
+ memdelete(f);
+ return ret;
+}
Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const {
@@ -270,13 +279,9 @@ Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const {
}
- FileAccess *f = FileAccess::open(p_fname,FileAccess::READ);
- ERR_FAIL_COND_V(!f,Vector<uint8_t>());
- Vector<uint8_t> ret;
- ret.resize(f->get_len());
- int rbs = f->get_buffer(ret.ptr(),ret.size());
- memdelete(f);
- return ret;
+ return get_exported_file_default(p_fname);
+
+
}
Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const {
@@ -557,6 +562,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
group_shrink*=EditorImportExport::get_singleton()->get_export_image_shrink();
switch(EditorImportExport::get_singleton()->image_export_group_get_image_action(E->get())) {
+ case EditorImportExport::IMAGE_ACTION_KEEP:
case EditorImportExport::IMAGE_ACTION_NONE: {
switch(EditorImportExport::get_singleton()->get_export_image_action()) {
@@ -581,7 +587,7 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
} break; //use default
case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
- } break; //use default
+ } break; //use default
}
String image_list_md5;
@@ -825,13 +831,32 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
StringName engine_cfg="res://engine.cfg";
+ StringName boot_splash;
+ {
+ String splash=Globals::get_singleton()->get("application/boot_splash"); //avoid splash from being converted
+ splash=splash.strip_edges();
+ if (splash!=String()) {
+ if (!splash.begins_with("res://"))
+ splash="res://"+splash;
+ splash=splash.simplify_path();
+ boot_splash=splash;
+ }
+ }
+
+
+
for(int i=0;i<files.size();i++) {
if (remap_files.has(files[i]) || files[i]==engine_cfg) //gonna be remapped (happened before!)
continue; //from atlas?
String src=files[i];
- Vector<uint8_t> buf = get_exported_file(src);
+ Vector<uint8_t> buf;
+
+ if (src==boot_splash)
+ buf = get_exported_file_default(src); //bootsplash must be kept if used
+ else
+ buf = get_exported_file(src);
ERR_CONTINUE( saved.has(src) );
@@ -1608,6 +1633,8 @@ void EditorImportExport::load_config() {
g.action=IMAGE_ACTION_COMPRESS_RAM;
else if (action=="compress_disk")
g.action=IMAGE_ACTION_COMPRESS_DISK;
+ else if (action=="keep")
+ g.action=IMAGE_ACTION_KEEP;
}
if (d.has("atlas"))
@@ -1735,6 +1762,7 @@ void EditorImportExport::save_config() {
case IMAGE_ACTION_NONE: d["action"]="default"; break;
case IMAGE_ACTION_COMPRESS_RAM: d["action"]="compress_ram"; break;
case IMAGE_ACTION_COMPRESS_DISK: d["action"]="compress_disk"; break;
+ case IMAGE_ACTION_KEEP: d["action"]="keep"; break;
}
diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h
index f134a479a4..d8601929cf 100644
--- a/tools/editor/editor_import_export.h
+++ b/tools/editor/editor_import_export.h
@@ -83,6 +83,7 @@ public:
typedef Error (*EditorExportSaveFunction)(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total);
protected:
+ Vector<uint8_t> get_exported_file_default(String& p_fname) const;
virtual Vector<uint8_t> get_exported_file(String& p_fname) const;
virtual Vector<StringName> get_dependencies(bool p_bundles) const;
@@ -227,6 +228,8 @@ public:
IMAGE_ACTION_NONE,
IMAGE_ACTION_COMPRESS_DISK,
IMAGE_ACTION_COMPRESS_RAM,
+ IMAGE_ACTION_KEEP //for group
+
};
enum ScriptAction {
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index b0a2c568de..63684dcc93 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -93,7 +93,7 @@
#include "plugins/light_occluder_2d_editor_plugin.h"
#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/collision_shape_2d_editor_plugin.h"
-
+#include "os/input.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
@@ -459,17 +459,74 @@ void EditorNode::open_resource(const String& p_type) {
current_option=RESOURCE_LOAD;
}
-void EditorNode::save_resource(const Ref<Resource>& p_resource) {
+void EditorNode::save_resource_in_path(const Ref<Resource>& p_resource,const String& p_path) {
- ERR_FAIL_COND(p_resource.is_null() || p_resource->get_path()=="" || p_resource->get_path().find("::")!=-1);
- resources_dock->save_resource(p_resource->get_path(),p_resource);
+ editor_data.apply_changes_in_editors();
+ int flg=0;
+ if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources"))
+ flg|=ResourceSaver::FLAG_COMPRESS;
+ if (EditorSettings::get_singleton()->get("on_save/save_paths_as_relative"))
+ flg|=ResourceSaver::FLAG_RELATIVE_PATHS;
+
+ String path = Globals::get_singleton()->localize_path(p_path);
+ Error err = ResourceSaver::save(path,p_resource,flg|ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
+
+ if (err!=OK) {
+ accept->set_text("Error saving resource!");
+ accept->popup_centered_minsize();
+ return;
+ }
+// EditorFileSystem::get_singleton()->update_file(path,p_resource->get_type());
+
+ ((Resource*)p_resource.ptr())->set_path(path);
+ emit_signal("resource_saved",p_resource);
+
+}
+
+void EditorNode::save_resource(const Ref<Resource>& p_resource) {
+
+ if (p_resource->get_path().is_resource_file()) {
+ save_resource_in_path(p_resource,p_resource->get_path());
+ } else {
+ save_resource_as(p_resource);
+ }
}
void EditorNode::save_resource_as(const Ref<Resource>& p_resource) {
- resources_dock->save_resource_as(p_resource);
+ file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ bool relpaths = (p_resource->has_meta("__editor_relpaths__") && p_resource->get_meta("__editor_relpaths__").operator bool());
+
+ List<String> extensions;
+ Ref<PackedScene> sd = memnew( PackedScene );
+ ResourceSaver::get_recognized_extensions(p_resource,&extensions);
+ file->clear_filters();
+ for(int i=0;i<extensions.size();i++) {
+
+ file->add_filter("*."+extensions[i]+" ; "+extensions[i].to_upper());
+ }
+ //file->set_current_path(current_path);
+ if (p_resource->get_path()!="") {
+ file->set_current_path(p_resource->get_path());
+ if (extensions.size()) {
+ String ext=p_resource->get_path().extension().to_lower();
+ if (extensions.find(ext)==NULL) {
+ file->set_current_path(p_resource->get_path().replacen("."+ext,"."+extensions.front()->get()));
+ }
+ }
+ } else {
+
+ String existing;
+ if (extensions.size()) {
+ existing="new_"+p_resource->get_type().to_lower()+"."+extensions.front()->get().to_lower();
+ }
+ file->set_current_path(existing);
+
+ }
+ file->popup_centered_ratio();
+ file->set_title("Save Resource As..");
}
@@ -1049,7 +1106,7 @@ void EditorNode::_dialog_action(String p_file) {
push_item(res.operator->() );
- } break;
+ } break;
case FILE_OPEN_SCENE: {
@@ -1320,7 +1377,20 @@ void EditorNode::_dialog_action(String p_file) {
unzClose(pkg);
} break;
+ case RESOURCE_SAVE:
+ case RESOURCE_SAVE_AS: {
+
+ uint32_t current = editor_history.get_current();
+ Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+
+ ERR_FAIL_COND(!current_obj->cast_to<Resource>())
+
+ RES current_res = RES(current_obj->cast_to<Resource>());
+
+ save_resource_in_path(current_res,p_file);
+
+ } break;
default: { //save scene?
@@ -1358,6 +1428,67 @@ void EditorNode::push_item(Object *p_object,const String& p_property) {
}
+void EditorNode::_select_history(int p_idx) {
+
+ //push it to the top, it is not correct, but it's more useful
+ ObjectID id=editor_history.get_history_obj(p_idx);
+ Object* obj=ObjectDB::get_instance(id);
+ if (!obj)
+ return;
+ push_item(obj);
+}
+
+void EditorNode::_prepare_history() {
+
+ int history_to = MAX(0,editor_history.get_history_len()-25);
+
+ editor_history_menu->get_popup()->clear();
+
+ Ref<Texture> base_icon = gui_base->get_icon("Object","EditorIcons");
+ Set<ObjectID> already;
+ for(int i=editor_history.get_history_len()-1;i>=history_to;i--) {
+
+
+ ObjectID id=editor_history.get_history_obj(i);
+ Object* obj=ObjectDB::get_instance(id);
+ if (!obj || already.has(id)) {
+ if (history_to>0) {
+ history_to--;
+ }
+ continue;
+ }
+
+ already.insert(id);
+
+ Ref<Texture> icon = gui_base->get_icon("Object","EditorIcons");
+ if (gui_base->has_icon(obj->get_type(),"EditorIcons"))
+ icon=gui_base->get_icon(obj->get_type(),"EditorIcons");
+ else
+ icon=base_icon;
+
+ String text;
+ if (obj->cast_to<Resource>()) {
+ Resource *r=obj->cast_to<Resource>();
+ if (r->get_path().is_resource_file())
+ text=r->get_path().get_file();
+ else if (r->get_name()!=String()) {
+ text=r->get_name();
+ } else {
+ text=r->get_type();
+ }
+ } else if (obj->cast_to<Node>()) {
+ text=obj->cast_to<Node>()->get_name();
+ } else {
+ text=obj->get_type();
+ }
+
+ if (i==editor_history.get_history_pos()) {
+ text="["+text+"]";
+ }
+ editor_history_menu->get_popup()->add_icon_item(icon,text,i);
+ }
+}
+
void EditorNode::_property_editor_forward() {
if (editor_history.next())
@@ -1402,6 +1533,9 @@ void EditorNode::_edit_current() {
uint32_t current = editor_history.get_current();
Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+ property_back->set_disabled( editor_history.is_at_begining() );
+ property_forward->set_disabled( editor_history.is_at_end() );
+
this->current=current_obj;
editor_path->update_path();
@@ -1416,7 +1550,10 @@ void EditorNode::_edit_current() {
object_menu->set_disabled(true);
- if (current_obj->is_type("Resource")) {
+ bool is_resource = current_obj->is_type("Resource");
+ resource_save_button->set_disabled(!is_resource);
+
+ if (is_resource) {
Resource *current_res = current_obj->cast_to<Resource>();
@@ -1425,12 +1562,11 @@ void EditorNode::_edit_current() {
property_editor->edit( current_res );
object_menu->set_disabled(false);
- resources_dock->add_resource(Ref<Resource>(current_res));
- //top_pallete->set_current_tab(1);
- }
+ //resources_dock->add_resource(Ref<Resource>(current_res));
- if (current_obj->is_type("Node")) {
+ //top_pallete->set_current_tab(1);
+ } else if (current_obj->is_type("Node")) {
Node * current_node = current_obj->cast_to<Node>();
ERR_FAIL_COND(!current_node);
@@ -1445,6 +1581,12 @@ void EditorNode::_edit_current() {
//top_pallete->set_current_tab(0);
+ } else {
+
+ property_editor->edit( current_obj );
+ //scene_tree_dock->set_selected(current_node);
+ //object_menu->get_popup()->clear();
+
}
/* Take care of PLUGIN EDITOR */
@@ -1517,7 +1659,13 @@ void EditorNode::_edit_current() {
p->add_item("Copy Params",OBJECT_COPY_PARAMS);
p->add_item("Set Params",OBJECT_PASTE_PARAMS);
p->add_separator();
- p->add_item("Make Resources Unique",OBJECT_UNIQUE_RESOURCES);
+ p->add_item("Paste Resource",RESOURCE_PASTE);
+ if (is_resource) {
+ p->add_item("Copy Resource",RESOURCE_COPY);
+ p->add_item("Make Built-In",RESOURCE_UNREF);
+ }
+ p->add_separator();
+ p->add_item("Make Sub-Resources Unique",OBJECT_UNIQUE_RESOURCES);
p->add_separator();
p->add_icon_item(gui_base->get_icon("Help","EditorIcons"),"Class Reference",OBJECT_REQUEST_HELP);
List<MethodInfo> methods;
@@ -1550,6 +1698,20 @@ void EditorNode::_edit_current() {
_update_keying();
}
+void EditorNode::_resource_created() {
+
+ Object *c = create_dialog->instance_selected();
+
+ ERR_FAIL_COND(!c);
+ Resource *r = c->cast_to<Resource>();
+ ERR_FAIL_COND(!r);
+
+ REF res( r );
+
+ push_item(c);
+
+}
+
void EditorNode::_resource_selected(const RES& p_res,const String& p_property) {
@@ -1762,6 +1924,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
int idx = editor_data.add_edited_scene(-1);
_scene_tab_changed(idx);
+ editor_data.clear_editor_states();
//_cleanup_scene();
@@ -1804,6 +1967,13 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
quick_open->set_title("Quick Open Script..");
} break;
+ case FILE_QUICK_OPEN_FILE: {
+
+
+ quick_open->popup("Resource",false,true);
+ quick_open->set_title("Quick Search File..");
+
+ } break;
case FILE_RUN_SCRIPT: {
file_script->popup_centered_ratio();
@@ -2266,7 +2436,70 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
#endif
-
+ case RESOURCE_NEW: {
+
+ create_dialog->popup_centered_ratio();
+ } break;
+ case RESOURCE_LOAD: {
+
+ open_resource();
+ } break;
+ case RESOURCE_SAVE: {
+
+
+ uint32_t current = editor_history.get_current();
+ Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+
+ ERR_FAIL_COND(!current_obj->cast_to<Resource>())
+
+ RES current_res = RES(current_obj->cast_to<Resource>());
+
+ save_resource(current_res);
+
+ } break;
+ case RESOURCE_SAVE_AS: {
+
+ uint32_t current = editor_history.get_current();
+ Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+
+ ERR_FAIL_COND(!current_obj->cast_to<Resource>())
+
+ RES current_res = RES(current_obj->cast_to<Resource>());
+
+ save_resource_as(current_res);
+
+ } break;
+ case RESOURCE_UNREF: {
+
+ uint32_t current = editor_history.get_current();
+ Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+
+ ERR_FAIL_COND(!current_obj->cast_to<Resource>())
+
+ RES current_res = RES(current_obj->cast_to<Resource>());
+ current_res->set_path("");
+ _edit_current();
+ } break;
+ case RESOURCE_COPY: {
+
+ uint32_t current = editor_history.get_current();
+ Object *current_obj = current>0 ? ObjectDB::get_instance(current) : NULL;
+
+ ERR_FAIL_COND(!current_obj->cast_to<Resource>())
+
+ RES current_res = RES(current_obj->cast_to<Resource>());
+
+ EditorSettings::get_singleton()->set_resource_clipboard(current_res);
+
+ } break;
+ case RESOURCE_PASTE: {
+
+ RES r = EditorSettings::get_singleton()->get_resource_clipboard();
+ if (r.is_valid()) {
+ push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(),String());
+ }
+
+ } break;
case OBJECT_REQUEST_HELP: {
if (current) {
@@ -3050,7 +3283,21 @@ void EditorNode::set_current_scene(int p_idx) {
}
-Error EditorNode::load_scene(const String& p_scene) {
+bool EditorNode::is_scene_open(const String& p_path) {
+
+ for(int i=0;i<editor_data.get_edited_scene_count();i++) {
+ if (editor_data.get_scene_path(i)==p_path)
+ return true;
+ }
+
+ return false;
+}
+
+void EditorNode::fix_dependencies(const String& p_for_file) {
+ dependency_fixer->edit(p_for_file);
+}
+
+Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
if (!is_inside_tree()) {
defer_load_scene = p_scene;
@@ -3096,6 +3343,8 @@ Error EditorNode::load_scene(const String& p_scene) {
//_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded.
+ dependency_errors.clear();
+
Ref<PackedScene> sdata = ResourceLoader::load(lpath,"",true);
if (!sdata.is_valid()) {
@@ -3113,6 +3362,35 @@ Error EditorNode::load_scene(const String& p_scene) {
return ERR_FILE_NOT_FOUND;
}
+ if (!p_ignore_broken_deps && dependency_errors.has(lpath)) {
+
+ current_option=-1;
+ Vector<String> errors;
+ for(Set<String>::Element *E=dependency_errors[lpath].front();E;E=E->next()) {
+
+ errors.push_back(E->get());
+ }
+ dependency_error->show(lpath,errors);
+ opening_prev=false;
+
+ if (prev!=-1) {
+ set_current_scene(prev);
+ editor_data.remove_scene(idx);
+ }
+ return ERR_FILE_MISSING_DEPENDENCIES;
+ }
+
+ dependency_errors.erase(lpath); //at least not self path
+
+ for (Map<String,Set<String> >::Element *E=dependency_errors.front();E;E=E->next()) {
+
+ String txt="Scene '"+E->key()+"' has broken dependencies:\n";
+ for(Set<String>::Element *F=E->get().front();F;F=F->next()) {
+ txt+="\t"+F->get()+"\n";
+ }
+ add_io_error(txt);
+ }
+
sdata->set_path(lpath,true); //take over path
Node*new_scene=sdata->instance(true);
@@ -3408,9 +3686,12 @@ void EditorNode::hide_animation_player_editors() {
void EditorNode::_quick_opened(const String& p_resource) {
- print_line("quick_opened");
- if (quick_open->get_base_type()=="PackedScene") {
+ if (current_option==FILE_QUICK_OPEN_FILE) {
+ scenes_dock->open(p_resource);
+ return;
+ }
+ if (quick_open->get_base_type()=="PackedScene") {
open_request(p_resource);
} else {
load_resource(p_resource);
@@ -3595,6 +3876,8 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_quick_opened",&EditorNode::_quick_opened);
ObjectTypeDB::bind_method("_quick_run",&EditorNode::_quick_run);
+ ObjectTypeDB::bind_method("_resource_created",&EditorNode::_resource_created);
+
ObjectTypeDB::bind_method("_import_action",&EditorNode::_import_action);
//ObjectTypeDB::bind_method("_import",&EditorNode::_import);
// ObjectTypeDB::bind_method("_import_conflicts_solved",&EditorNode::_import_conflicts_solved);
@@ -3624,6 +3907,8 @@ void EditorNode::_bind_methods() {
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("_prepare_history",&EditorNode::_prepare_history);
+ ObjectTypeDB::bind_method("_select_history",&EditorNode::_select_history);
ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin);
@@ -4105,6 +4390,14 @@ EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
+ if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
+ //only if no touchscreen ui hint, set emulation
+ InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
+ if (id)
+ id->set_emulate_touch(false); //just disable just in case
+ }
+
+
singleton=this;
last_checked_version=0;
changing_scene=false;
@@ -4120,6 +4413,7 @@ EditorNode::EditorNode() {
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
ResourceLoader::set_error_notify_func(this,_load_error_notify);
+ ResourceLoader::set_dependency_error_notify_func(this,_dependency_error_report);
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
@@ -4493,6 +4787,7 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O);
p->add_item("Quick Open Script..",FILE_QUICK_OPEN_SCRIPT,KEY_MASK_ALT+KEY_MASK_CMD+KEY_O);
+ p->add_item("Quick Search File..",FILE_QUICK_OPEN_FILE,KEY_MASK_ALT+KEY_MASK_CMD+KEY_P);
p->add_separator();
PopupMenu *pm_export = memnew(PopupMenu );
@@ -4735,13 +5030,14 @@ EditorNode::EditorNode() {
scene_tree_dock->set_name("Scene");
//top_pallete->add_child(scene_tree_dock);
dock_slot[DOCK_SLOT_LEFT_UR]->add_child(scene_tree_dock);
-
+#if 0
resources_dock = memnew( ResourcesDock(this) );
resources_dock->set_name("Resources");
//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);
-
+#endif
+ dock_slot[DOCK_SLOT_RIGHT_BL]->hide();
/*Control *editor_spacer = memnew( Control );
editor_spacer->set_custom_minimum_size(Size2(260,200));
editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -4766,27 +5062,40 @@ EditorNode::EditorNode() {
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);
- editor_path = memnew( EditorPath(&editor_history) );
- editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- prop_editor_hb->add_child(editor_path);
-
- property_editor = memnew( PropertyEditor );
- property_editor->set_autoclear(true);
- property_editor->set_show_categories(true);
- property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- property_editor->hide_top_label();
- prop_editor_base->add_child( property_editor );
- property_editor->set_undo_redo(&editor_data.get_undo_redo());
+ prop_editor_base->add_child(prop_editor_hb);
+ resource_new_button = memnew( ToolButton );
+ resource_new_button->set_tooltip("Create a new resource in memory and edit it");
+ resource_new_button->set_icon(gui_base->get_icon("New","EditorIcons"));
+ prop_editor_hb->add_child(resource_new_button);
+ resource_new_button->connect("pressed",this,"_menu_option",varray(RESOURCE_NEW));
+ resource_new_button->set_focus_mode(Control::FOCUS_NONE);
+
+ resource_load_button = memnew( ToolButton );
+ resource_load_button->set_tooltip("Load an existing resource from disk and edit it");
+ resource_load_button->set_icon(gui_base->get_icon("Load","EditorIcons"));
+ prop_editor_hb->add_child(resource_load_button);
+ resource_load_button->connect("pressed",this,"_menu_option",varray(RESOURCE_LOAD));
+ resource_load_button->set_focus_mode(Control::FOCUS_NONE);
+
+ resource_save_button = memnew( MenuButton );
+ resource_save_button->set_tooltip("Save the currently edited resource");
+ resource_save_button->set_icon(gui_base->get_icon("Save","EditorIcons"));
+ prop_editor_hb->add_child(resource_save_button);
+ resource_save_button->get_popup()->add_item("Save",RESOURCE_SAVE);
+ resource_save_button->get_popup()->add_item("Save As..",RESOURCE_SAVE_AS);
+ resource_save_button->get_popup()->connect("item_pressed",this,"_menu_option");
+ resource_save_button->set_focus_mode(Control::FOCUS_NONE);
+ resource_save_button->set_disabled(true);
+
+ prop_editor_hb->add_spacer();
-
property_back = memnew( ToolButton );
property_back->set_icon( gui_base->get_icon("Back","EditorIcons") );
property_back->set_flat(true);
property_back->set_tooltip("Go to the previous edited object in history.");
+ property_back->set_disabled(true);
prop_editor_hb->add_child( property_back );
@@ -4794,14 +5103,48 @@ EditorNode::EditorNode() {
property_forward->set_icon( gui_base->get_icon("Forward","EditorIcons") );
property_forward->set_flat(true);
property_forward->set_tooltip("Go to the next edited object in history.");
+ property_forward->set_disabled(true);
prop_editor_hb->add_child( property_forward );
+
+ editor_history_menu = memnew( MenuButton );
+ editor_history_menu->set_icon( gui_base->get_icon("History","EditorIcons"));
+ prop_editor_hb->add_child(editor_history_menu);
+ editor_history_menu->connect("about_to_show",this,"_prepare_history");
+ editor_history_menu->get_popup()->connect("item_pressed",this,"_select_history");
+
+
+ prop_editor_hb = memnew( HBoxContainer ); //again...
+
+ prop_editor_base->add_child(prop_editor_hb);
+ editor_path = memnew( EditorPath(&editor_history) );
+ editor_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ prop_editor_hb->add_child(editor_path);
+
+
object_menu = memnew( MenuButton );
object_menu->set_icon(gui_base->get_icon("Tools","EditorIcons"));
prop_editor_hb->add_child( object_menu );
object_menu->set_tooltip("Object properties.");
+ create_dialog = memnew( CreateDialog );
+ gui_base->add_child(create_dialog);
+ create_dialog->set_base_type("Resource");
+ create_dialog->connect("create",this,"_resource_created");
+
+
+ property_editor = memnew( PropertyEditor );
+ property_editor->set_autoclear(true);
+ property_editor->set_show_categories(true);
+ property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ property_editor->set_use_doc_hints(true);
+
+ property_editor->hide_top_label();
+
+ prop_editor_base->add_child( property_editor );
+ property_editor->set_undo_redo(&editor_data.get_undo_redo());
+
scenes_dock = memnew( ScenesDock(this) );
scenes_dock->set_name("FileSystem");
@@ -4929,7 +5272,11 @@ EditorNode::EditorNode() {
+ dependency_error = memnew( DependencyErrorDialog );
+ gui_base->add_child(dependency_error);
+ dependency_fixer = memnew( DependencyEditor );
+ gui_base->add_child( dependency_fixer );
settings_config_dialog = memnew( EditorSettingsDialog );
gui_base->add_child(settings_config_dialog);
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index d40658a056..dba2b7b86c 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -123,6 +123,7 @@ class EditorNode : public Node {
FILE_OPEN_OLD_SCENE,
FILE_QUICK_OPEN_SCENE,
FILE_QUICK_OPEN_SCRIPT,
+ FILE_QUICK_OPEN_FILE,
FILE_RUN_SCRIPT,
FILE_OPEN_PREV,
FILE_CLOSE,
@@ -137,6 +138,7 @@ class EditorNode : public Node {
RESOURCE_SAVE_AS,
RESOURCE_UNREF,
RESOURCE_COPY,
+ RESOURCE_PASTE,
OBJECT_COPY_PARAMS,
OBJECT_PASTE_PARAMS,
OBJECT_UNIQUE_RESOURCES,
@@ -256,11 +258,13 @@ class EditorNode : public Node {
Button *property_back;
Button *property_forward;
SceneTreeDock *scene_tree_dock;
- ResourcesDock *resources_dock;
+ //ResourcesDock *resources_dock;
PropertyEditor *property_editor;
ScenesDock *scenes_dock;
EditorRunNative *run_native;
+ CreateDialog *create_dialog;
+
CallDialog *call_dialog;
ConfirmationDialog *confirmation;
ConfirmationDialog *import_confirmation;
@@ -298,6 +302,10 @@ class EditorNode : public Node {
HBoxContainer *animation_panel_hb;
VBoxContainer *animation_vb;
EditorPath *editor_path;
+ ToolButton *resource_new_button;
+ ToolButton *resource_load_button;
+ MenuButton *resource_save_button;
+ MenuButton *editor_history_menu;
AnimationKeyEditor *animation_editor;
EditorLog *log;
CenterContainer *tabs_center;
@@ -312,6 +320,9 @@ class EditorNode : public Node {
ProgressDialog *progress_dialog;
BackgroundProgress *progress_hb;
+ DependencyErrorDialog *dependency_error;
+ DependencyEditor *dependency_fixer;
+
TabContainer *dock_slot[DOCK_SLOT_MAX];
Rect2 dock_select_rect[DOCK_SLOT_MAX];
int dock_select_rect_over;
@@ -367,6 +378,7 @@ class EditorNode : public Node {
int current_option;
//void _animation_visibility_toggle();
+ void _resource_created();
void _resource_selected(const RES& p_res,const String& p_property="");
void _menu_option(int p_option);
void _menu_confirm_current();
@@ -375,6 +387,9 @@ class EditorNode : public Node {
void _property_editor_forward();
void _property_editor_back();
+ void _select_history(int p_idx);
+ void _prepare_history();
+
void _fs_changed();
void _sources_changed(bool p_exist);
@@ -451,6 +466,16 @@ class EditorNode : public Node {
void _save_scene_with_preview(String p_file);
+ Map<String,Set<String> > dependency_errors;
+
+ static void _dependency_error_report(void *ud,const String& p_path,const String& p_dep,const String& p_type) {
+ EditorNode*en=(EditorNode*)ud;
+ if (!en->dependency_errors.has(p_path))
+ en->dependency_errors[p_path]=Set<String>();
+ en->dependency_errors[p_path].insert(p_dep+"::"+p_type);
+
+ }
+
struct ExportDefer {
String platform;
String path;
@@ -503,6 +528,8 @@ public:
void edit_node(Node *p_node);
void edit_resource(const Ref<Resource>& p_resource);
void open_resource(const String& p_type="");
+
+ void save_resource_in_path(const Ref<Resource>& p_resource,const String& p_path);
void save_resource(const Ref<Resource>& p_resource);
void save_resource_as(const Ref<Resource>& p_resource);
@@ -534,10 +561,13 @@ public:
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);
+ void fix_dependencies(const String& p_for_file);
void clear_scene() { _cleanup_scene(); }
- Error load_scene(const String& p_scene);
+ Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false);
Error load_resource(const String& p_scene);
+ bool is_scene_open(const String& p_path);
+
void set_current_version(uint64_t p_version);
void set_current_scene(int p_idx);
diff --git a/tools/editor/editor_path.cpp b/tools/editor/editor_path.cpp
index 86fd79d014..94e2efe346 100644
--- a/tools/editor/editor_path.cpp
+++ b/tools/editor/editor_path.cpp
@@ -73,7 +73,11 @@ void EditorPath::_notification(int p_what) {
if (obj->cast_to<Resource>()) {
Resource *r = obj->cast_to<Resource>();
- name=r->get_name();
+ if (r->get_path().is_resource_file())
+ name=r->get_path().get_file();
+ else
+ name=r->get_name();
+
if (name=="")
name=r->get_type();
} else if (obj->cast_to<Node>()) {
diff --git a/tools/editor/editor_run.cpp b/tools/editor/editor_run.cpp
index 77c5f419b1..4d07463b21 100644
--- a/tools/editor/editor_run.cpp
+++ b/tools/editor/editor_run.cpp
@@ -28,7 +28,7 @@
/*************************************************************************/
#include "editor_run.h"
#include "globals.h"
-
+#include "editor_settings.h"
EditorRun::Status EditorRun::get_status() const {
@@ -61,6 +61,70 @@ Error EditorRun::run(const String& p_scene,const String p_custom_args,const List
}
}
+
+ int screen = EditorSettings::get_singleton()->get("game_window_placement/screen");
+
+ if (screen==0) {
+ screen=OS::get_singleton()->get_current_screen();
+ } else {
+ screen--;
+ }
+
+ Rect2 screen_rect;
+ screen_rect.pos=OS::get_singleton()->get_screen_position(screen);
+ screen_rect.size=OS::get_singleton()->get_screen_size(screen);
+
+
+ Size2 desired_size;
+
+ desired_size.x=Globals::get_singleton()->get("display/width");
+ desired_size.y=Globals::get_singleton()->get("display/height");
+
+ Size2 test_size;
+ test_size.x=Globals::get_singleton()->get("display/test_width");
+ test_size.y=Globals::get_singleton()->get("display/test_height");
+ if (test_size.x>0 && test_size.y>0) {
+
+ desired_size=test_size;
+ }
+
+
+ int window_placement=EditorSettings::get_singleton()->get("game_window_placement/rect");
+
+ switch(window_placement) {
+ case 0: { // default
+
+ args.push_back("-p");
+ args.push_back(itos(screen_rect.pos.x)+"x"+itos(screen_rect.pos.y));
+ } break;
+ case 1: { // centered
+ Vector2 pos=screen_rect.pos+((screen_rect.size-desired_size)/2).floor();
+ args.push_back("-p");
+ args.push_back(itos(pos.x)+"x"+itos(pos.y));
+ } break;
+ case 2: { // custom pos
+ Vector2 pos = EditorSettings::get_singleton()->get("game_window_placement/rect_custom_position");
+ pos+=screen_rect.pos;
+ args.push_back("-p");
+ args.push_back(itos(pos.x)+"x"+itos(pos.y));
+ } break;
+ case 3: { // force maximized
+ Vector2 pos=screen_rect.pos;
+ args.push_back("-p");
+ args.push_back(itos(pos.x)+"x"+itos(pos.y));
+ args.push_back("-mx");
+
+ } break;
+ case 4: { // force fullscreen
+
+ Vector2 pos=screen_rect.pos;
+ args.push_back("-p");
+ args.push_back(itos(pos.x)+"x"+itos(pos.y));
+ args.push_back("-f");
+ } break;
+ }
+
+
if (p_breakpoints.size()) {
args.push_back("-bp");
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 2f61d4f09d..a771893bdd 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -496,6 +496,15 @@ void EditorSettings::_load_defaults() {
set("2d_editor/bone_selected_color",Color(0.9,0.45,0.45,0.9));
set("2d_editor/bone_ik_color",Color(0.9,0.9,0.45,0.9));
+ set("game_window_placement/rect",0);
+ hints["game_window_placement/rect"]=PropertyInfo(Variant::INT,"game_window_placement/rect",PROPERTY_HINT_ENUM,"Default,Centered,Custom Position,Force Maximized,Force Full Screen");
+ String screen_hints="Default (Same as Editor)";
+ for(int i=0;i<OS::get_singleton()->get_screen_count();i++) {
+ screen_hints+=",Monitor "+itos(i+1);
+ }
+ set("game_window_placement/rect_custom_position",Vector2());
+ set("game_window_placement/screen",0);
+ hints["game_window_placement/screen"]=PropertyInfo(Variant::INT,"game_window_placement/screen",PROPERTY_HINT_ENUM,screen_hints);
set("on_save/compress_binary_resources",true);
set("on_save/save_modified_external_resources",true);
diff --git a/tools/editor/icons/icon_anchor.png b/tools/editor/icons/icon_anchor.png
new file mode 100644
index 0000000000..1f9f9fa139
--- /dev/null
+++ b/tools/editor/icons/icon_anchor.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_bottom_center.png b/tools/editor/icons/icon_control_align_bottom_center.png
new file mode 100644
index 0000000000..5ce9fe5c1c
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_bottom_center.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_bottom_left.png b/tools/editor/icons/icon_control_align_bottom_left.png
new file mode 100644
index 0000000000..6c5129bf95
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_bottom_left.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_bottom_right.png b/tools/editor/icons/icon_control_align_bottom_right.png
new file mode 100644
index 0000000000..8857f4e940
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_bottom_right.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_bottom_wide.png b/tools/editor/icons/icon_control_align_bottom_wide.png
new file mode 100644
index 0000000000..56f009b8e4
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_bottom_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_center.png b/tools/editor/icons/icon_control_align_center.png
new file mode 100644
index 0000000000..acd42525fa
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_center.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_center_left.png b/tools/editor/icons/icon_control_align_center_left.png
new file mode 100644
index 0000000000..997074b097
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_center_left.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_center_right.png b/tools/editor/icons/icon_control_align_center_right.png
new file mode 100644
index 0000000000..b5cae63f7a
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_center_right.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_left_center.png b/tools/editor/icons/icon_control_align_left_center.png
new file mode 100644
index 0000000000..7bb4dfb567
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_left_center.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_left_wide.png b/tools/editor/icons/icon_control_align_left_wide.png
new file mode 100644
index 0000000000..1b0a6cff95
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_left_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_right_center.png b/tools/editor/icons/icon_control_align_right_center.png
new file mode 100644
index 0000000000..cf12d44c6a
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_right_center.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_right_wide.png b/tools/editor/icons/icon_control_align_right_wide.png
new file mode 100644
index 0000000000..406ed25aed
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_right_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_top_center.png b/tools/editor/icons/icon_control_align_top_center.png
new file mode 100644
index 0000000000..da7ede984a
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_top_center.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_top_left.png b/tools/editor/icons/icon_control_align_top_left.png
new file mode 100644
index 0000000000..84a224fbbe
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_top_left.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_top_right.png b/tools/editor/icons/icon_control_align_top_right.png
new file mode 100644
index 0000000000..3b58eead9c
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_top_right.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_top_wide.png b/tools/editor/icons/icon_control_align_top_wide.png
new file mode 100644
index 0000000000..869ae26134
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_top_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_align_wide.png b/tools/editor/icons/icon_control_align_wide.png
new file mode 100644
index 0000000000..57a2933b25
--- /dev/null
+++ b/tools/editor/icons/icon_control_align_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_hcenter_wide.png b/tools/editor/icons/icon_control_hcenter_wide.png
new file mode 100644
index 0000000000..739ea5baeb
--- /dev/null
+++ b/tools/editor/icons/icon_control_hcenter_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_control_vcenter_wide.png b/tools/editor/icons/icon_control_vcenter_wide.png
new file mode 100644
index 0000000000..44cbb8f344
--- /dev/null
+++ b/tools/editor/icons/icon_control_vcenter_wide.png
Binary files differ
diff --git a/tools/editor/icons/icon_file_list.png b/tools/editor/icons/icon_file_list.png
index e5e9213e61..ab790a85a5 100644
--- a/tools/editor/icons/icon_file_list.png
+++ b/tools/editor/icons/icon_file_list.png
Binary files differ
diff --git a/tools/editor/icons/icon_filesystem.png b/tools/editor/icons/icon_filesystem.png
new file mode 100644
index 0000000000..6841f9a792
--- /dev/null
+++ b/tools/editor/icons/icon_filesystem.png
Binary files differ
diff --git a/tools/editor/icons/icon_history.png b/tools/editor/icons/icon_history.png
new file mode 100644
index 0000000000..5c306c3ac9
--- /dev/null
+++ b/tools/editor/icons/icon_history.png
Binary files differ
diff --git a/tools/editor/icons/icon_multi_node_edit.png b/tools/editor/icons/icon_multi_node_edit.png
new file mode 100644
index 0000000000..357c062cbd
--- /dev/null
+++ b/tools/editor/icons/icon_multi_node_edit.png
Binary files differ
diff --git a/tools/editor/icons/icon_non_favorite.png b/tools/editor/icons/icon_non_favorite.png
new file mode 100644
index 0000000000..edd806fbe8
--- /dev/null
+++ b/tools/editor/icons/icon_non_favorite.png
Binary files differ
diff --git a/tools/editor/icons/icon_patch_9_frame.png b/tools/editor/icons/icon_patch_9_frame.png
new file mode 100644
index 0000000000..c8f38fa61a
--- /dev/null
+++ b/tools/editor/icons/icon_patch_9_frame.png
Binary files differ
diff --git a/tools/editor/inspector_dock.cpp b/tools/editor/inspector_dock.cpp
new file mode 100644
index 0000000000..57d19c3ec8
--- /dev/null
+++ b/tools/editor/inspector_dock.cpp
@@ -0,0 +1,22 @@
+#include "inspector_dock.h"
+
+#if 0
+void InspectorDock::_go_next() {
+
+
+}
+
+void InspectorDock::_go_prev() {
+
+
+}
+
+void InspectorDock::_bind_methods() {
+
+}
+
+InspectorDock::InspectorDock() {
+
+
+}
+#endif
diff --git a/tools/editor/inspector_dock.h b/tools/editor/inspector_dock.h
new file mode 100644
index 0000000000..90f043aba8
--- /dev/null
+++ b/tools/editor/inspector_dock.h
@@ -0,0 +1,35 @@
+#ifndef INSPECTOR_DOCK_H
+#define INSPECTOR_DOCK_H
+
+#include "scene/gui/box_container.h"
+#include "property_editor.h"
+
+
+//this is for now bundled in EditorNode, will be moved away here eventually
+
+#if 0
+class InspectorDock : public VBoxContainer
+{
+ OBJ_TYPE(InspectorDock,VBoxContainer);
+
+ PropertyEditor *property_editor;
+
+ EditorHistory editor_history;
+
+ void _go_next();
+ void _go_prev();
+
+protected:
+
+ static void _bind_methods();
+public:
+
+ EditorHistory &get_editor_history();
+
+ PropertyEditor *get_property_editor();
+
+ InspectorDock();
+};
+
+#endif
+#endif // INSPECTOR_DOCK_H
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index d510333a32..d57cff850e 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -710,10 +710,126 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
//find largest source..
+ /************************/
+ /* ADD WEIGHTS IF EXIST */
+ /************************/
+
+ Map<int,Vector<Collada::Vertex::Weight> > pre_weights;
+
+ bool has_weights=false;
+
+ if (skin_controller) {
+
+ const Collada::SkinControllerData::Source *weight_src=NULL;
+ int weight_ofs=0;
+
+ if (skin_controller->weights.sources.has("WEIGHT")) {
+
+ String weight_id = skin_controller->weights.sources["WEIGHT"].source;
+ weight_ofs = skin_controller->weights.sources["WEIGHT"].offset;
+ if (skin_controller->sources.has(weight_id)) {
+
+ weight_src = &skin_controller->sources[weight_id];
+
+ }
+ }
+
+ int joint_ofs=0;
+
+ if (skin_controller->weights.sources.has("JOINT")) {
+
+ joint_ofs = skin_controller->weights.sources["JOINT"].offset;
+ }
+
+ //should be OK, given this was pre-checked.
+
+ int index_ofs=0;
+ int wstride = skin_controller->weights.sources.size();
+ for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) {
+
+ int amount = skin_controller->weights.sets[w_i];
+
+ Vector<Collada::Vertex::Weight> weights;
+
+ for (int a_i=0;a_i<amount;a_i++) {
+
+ Collada::Vertex::Weight w;
+
+ int read_from = index_ofs+a_i*wstride;
+ ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA);
+ int weight_index = skin_controller->weights.indices[read_from+weight_ofs];
+ ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA);
+
+ w.weight = weight_src->array[weight_index];
+
+ int bone_index = skin_controller->weights.indices[read_from+joint_ofs];
+ if (bone_index==-1)
+ continue; //ignore this weight (refers to bind shape)
+ ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA);
+
+ w.bone_idx=bone_remap[bone_index];
+
+
+ weights.push_back(w);
+ }
+
+ /* FIX WEIGHTS */
+
+
+
+ weights.sort();
+
+ if (weights.size()>4) {
+ //cap to 4 and make weights add up 1
+ weights.resize(4);
+
+ }
+
+ //make sure weights allways add up to 1
+ float total=0;
+ for(int i=0;i<weights.size();i++)
+ total+=weights[i].weight;
+ if (total)
+ for(int i=0;i<weights.size();i++)
+ weights[i].weight/=total;
+
+ if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0
+ //no weights assigned
+ Collada::Vertex::Weight w;
+ w.bone_idx=0;
+ w.weight=1.0;
+ weights.clear();
+ weights.push_back(w);
+
+ }
+
+ pre_weights[w_i]=weights;
+
+ /*
+ for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) {
+
+ int dst = E->get();
+ ERR_EXPLAIN("invalid vertex index in array");
+ ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA);
+ vertex_array[dst].weights=weights;
+
+ }*/
+
+
+
+
+ index_ofs+=wstride*amount;
+
+ }
+
+ //vertices need to be localized
+ has_weights=true;
+
+ }
Set<Collada::Vertex> vertex_set; //vertex set will be the vertices
List<int> indices_list; //indices will be the indices
- Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph)
+ //Map<int,Set<int> > vertex_map; //map vertices (for setting skinning/morph)
/**************************/
/* CREATE PRIMITIVE ARRAY */
@@ -753,11 +869,16 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
if (!p_optimize)
vertex.uid=vertidx++;
+
+
int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers)
int vertex_pos = (vertex_src->stride?vertex_src->stride:3) * vertex_index;
ERR_FAIL_INDEX_V(vertex_pos,vertex_src->array.size(),ERR_INVALID_DATA);
vertex.vertex=Vector3(vertex_src->array[vertex_pos+0],vertex_src->array[vertex_pos+1],vertex_src->array[vertex_pos+2]);
+ if (pre_weights.has(vertex_index)) {
+ vertex.weights=pre_weights[vertex_index];
+ }
if (normal_src) {
@@ -836,9 +957,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
vertex_set.insert(vertex);
}
- if (!vertex_map.has(vertex_index))
+ /* if (!vertex_map.has(vertex_index))
vertex_map[vertex_index]=Set<int>();
- vertex_map[vertex_index].insert(index); //should be outside..
+ vertex_map[vertex_index].insert(index); //should be outside..*/
//build triangles if needed
if (j==0)
prev2[0]=index;
@@ -874,120 +995,10 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
vertex_array[F->get().idx]=F->get();
}
- /************************/
- /* ADD WEIGHTS IF EXIST */
- /************************/
-
-
- bool has_weights=false;
-
- if (skin_controller) {
-
- const Collada::SkinControllerData::Source *weight_src=NULL;
- int weight_ofs=0;
-
- if (skin_controller->weights.sources.has("WEIGHT")) {
-
- String weight_id = skin_controller->weights.sources["WEIGHT"].source;
- weight_ofs = skin_controller->weights.sources["WEIGHT"].offset;
- if (skin_controller->sources.has(weight_id)) {
-
- weight_src = &skin_controller->sources[weight_id];
-
- }
- }
-
- int joint_ofs=0;
-
- if (skin_controller->weights.sources.has("JOINT")) {
-
- joint_ofs = skin_controller->weights.sources["JOINT"].offset;
- }
-
- //should be OK, given this was pre-checked.
-
- int index_ofs=0;
- int wstride = skin_controller->weights.sources.size();
- for(int w_i=0;w_i<skin_controller->weights.sets.size();w_i++) {
-
- int amount = skin_controller->weights.sets[w_i];
-
- if (vertex_map.has(w_i)) { //vertex may no longer be here, don't bother converting
- Vector<Collada::Vertex::Weight> weights;
-
- for (int a_i=0;a_i<amount;a_i++) {
-
- Collada::Vertex::Weight w;
-
- int read_from = index_ofs+a_i*wstride;
- ERR_FAIL_INDEX_V(read_from+wstride-1,skin_controller->weights.indices.size(),ERR_INVALID_DATA);
- int weight_index = skin_controller->weights.indices[read_from+weight_ofs];
- ERR_FAIL_INDEX_V(weight_index,weight_src->array.size(),ERR_INVALID_DATA);
-
- w.weight = weight_src->array[weight_index];
-
- int bone_index = skin_controller->weights.indices[read_from+joint_ofs];
- if (bone_index==-1)
- continue; //ignore this weight (refers to bind shape)
- ERR_FAIL_INDEX_V(bone_index,bone_remap.size(),ERR_INVALID_DATA);
-
- w.bone_idx=bone_remap[bone_index];
-
-
- weights.push_back(w);
- }
-
- /* FIX WEIGHTS */
-
-
-
- weights.sort();
-
- if (weights.size()>4) {
- //cap to 4 and make weights add up 1
- weights.resize(4);
-
- }
-
- //make sure weights allways add up to 1
- float total=0;
- for(int i=0;i<weights.size();i++)
- total+=weights[i].weight;
- if (total)
- for(int i=0;i<weights.size();i++)
- weights[i].weight/=total;
-
- if (weights.size()==0 || total==0) { //if nothing, add a weight to bone 0
- //no weights assigned
- Collada::Vertex::Weight w;
- w.bone_idx=0;
- w.weight=1.0;
- weights.clear();
- weights.push_back(w);
-
- }
-
-
- for(Set<int>::Element *E=vertex_map[w_i].front();E;E=E->next()) {
-
- int dst = E->get();
- ERR_EXPLAIN("invalid vertex index in array");
- ERR_FAIL_INDEX_V(dst,vertex_array.size(),ERR_INVALID_DATA);
- vertex_array[dst].weights=weights;
-
- }
-
- } else {
- //zzprint_line("no vertex found for index "+itos(w_i));
- }
-
- index_ofs+=wstride*amount;
-
- }
-
- //vertices need to be localized
+ if (has_weights) {
+ //if skeleton, localize
Transform local_xform = p_local_xform;
for(int i=0;i<vertex_array.size();i++) {
@@ -1000,11 +1011,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,con
//vertex_array[i].tangent.normal*=-1.0;
}
}
-
- has_weights=true;
-
}
+
DVector<int> index_array;
index_array.resize(indices_list.size());
DVector<int>::Write index_arrayw = index_array.write();
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
index 4f7ec1839a..436725f6fb 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -1068,12 +1068,14 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
//prepare atlas!
Vector< Image > sources;
+ Vector< Image > tsources;
bool alpha=false;
bool crop = from->get_option("crop");
EditorProgress ep("make_atlas","Build Atlas For: "+p_path.get_file(),from->get_source_count()+3);
print_line("sources: "+itos(from->get_source_count()));
+
for(int i=0;i<from->get_source_count();i++) {
String path = EditorImportPlugin::expand_source_path(from->get_source_path(i));
@@ -1091,17 +1093,57 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
if (src.detect_alpha())
alpha=true;
- sources.push_back(src);
+ tsources.push_back(src);
}
ep.step("Converting Images",sources.size());
- for(int i=0;i<sources.size();i++) {
+ int base_index=0;
+
+
+ Map<uint64_t,int> source_md5;
+ Map<int,List<int> > source_map;
+
+ for(int i=0;i<tsources.size();i++) {
+
+ Image src = tsources[i];
if (alpha) {
- sources[i].convert(Image::FORMAT_RGBA);
+ src.convert(Image::FORMAT_RGBA);
+ } else {
+ src.convert(Image::FORMAT_RGB);
+ }
+
+ DVector<uint8_t> data = src.get_data();
+ MD5_CTX md5;
+ DVector<uint8_t>::Read r=data.read();
+ MD5Init(&md5);
+ int len=data.size();
+ for(int j=0;j<len;j++) {
+ uint8_t b = r[j];
+ b>>=2; //to aid in comparing
+ MD5Update(&md5,(unsigned char*)&b,1);
+ }
+ MD5Final(&md5);
+ uint64_t *cmp = (uint64_t*)md5.digest; //less bits, but still useful for this
+
+ tsources[i]=Image(); //clear
+
+ if (source_md5.has(*cmp)) {
+ int sidx=source_md5[*cmp];
+ source_map[sidx].push_back(i);
+ print_line("REUSING "+from->get_source_path(i));
+
} else {
- sources[i].convert(Image::FORMAT_RGB);
+ int sidx=sources.size();
+ source_md5[*cmp]=sidx;
+ sources.push_back(src);
+ List<int> sm;
+ sm.push_back(i);
+ source_map[sidx]=sm;
+
}
+
+
}
//texturepacker is not really good for optimizing, so..
@@ -1141,28 +1183,44 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
Image atlas;
atlas.create(nearest_power_of_2(dst_size.width),nearest_power_of_2(dst_size.height),0,alpha?Image::FORMAT_RGBA:Image::FORMAT_RGB);
+
+ atlases.resize(from->get_source_count());
+
for(int i=0;i<sources.size();i++) {
int x=dst_positions[i].x;
int y=dst_positions[i].y;
- Ref<AtlasTexture> at = memnew( AtlasTexture );
Size2 sz = Size2(sources[i].get_width(),sources[i].get_height());
+
+ Rect2 region;
+ Rect2 margin;
+
if (crop && sz!=crops[i].size) {
Rect2 rect = crops[i];
rect.size=sz-rect.size;
- at->set_region(Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height));
- at->set_margin(rect);
+ region=Rect2(x+border,y+border,crops[i].size.width,crops[i].size.height);
+ margin=rect;
atlas.blit_rect(sources[i],crops[i],Point2(x+border,y+border));
} else {
- at->set_region(Rect2(x+border,y+border,sz.x,sz.y));
+ region=Rect2(x+border,y+border,sz.x,sz.y);
atlas.blit_rect(sources[i],Rect2(0,0,sources[i].get_width(),sources[i].get_height()),Point2(x+border,y+border));
}
- String apath = p_path.get_base_dir().plus_file(from->get_source_path(i).get_file().basename()+".atex");
- print_line("Atlas Tex: "+apath);
- at->set_path(apath);
- atlases.push_back(at);
+ ERR_CONTINUE( !source_map.has(i) );
+ for (List<int>::Element *E=source_map[i].front();E;E=E->next()) {
+
+ Ref<AtlasTexture> at = memnew( AtlasTexture );
+
+
+ at->set_region(region);
+ at->set_margin(margin);
+ String apath = p_path.get_base_dir().plus_file(from->get_source_path(E->get()).get_file().basename()+".atex");
+ at->set_path(apath);
+ atlases[E->get()]=at;
+ print_line("Atlas Tex: "+apath);
+
+ }
}
if (ResourceCache::has(p_path)) {
texture = Ref<ImageTexture> ( ResourceCache::get(p_path)->cast_to<ImageTexture>() );
@@ -1414,6 +1472,9 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c
case EditorImportExport::IMAGE_ACTION_COMPRESS_RAM: {
group_format=EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM;
} break; //use default
+ case EditorImportExport::IMAGE_ACTION_KEEP: {
+ return Vector<uint8_t>();
+ } break; //use default
}
diff --git a/tools/editor/multi_node_edit.cpp b/tools/editor/multi_node_edit.cpp
new file mode 100644
index 0000000000..cfa998bee9
--- /dev/null
+++ b/tools/editor/multi_node_edit.cpp
@@ -0,0 +1,118 @@
+#include "multi_node_edit.h"
+#include "editor_node.h"
+
+bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){
+
+ Node *es = EditorNode::get_singleton()->get_edited_scene();
+ if (!es)
+ return false;
+
+ UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action("MultiNode Set "+String(p_name));
+ for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+ if (!es->has_node(E->get()))
+ continue;
+
+ Node*n=es->get_node(E->get());
+ if (!n)
+ continue;
+
+ ur->add_do_property(n,p_name,p_value);
+ ur->add_undo_property(n,p_name,n->get(p_name));
+
+ }
+
+ ur->commit_action();
+ return true;
+}
+
+bool MultiNodeEdit::_get(const StringName& p_name,Variant &r_ret) const {
+
+ Node *es = EditorNode::get_singleton()->get_edited_scene();
+ if (!es)
+ return false;
+
+ for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+ if (!es->has_node(E->get()))
+ continue;
+
+ const Node*n=es->get_node(E->get());
+ if (!n)
+ continue;
+
+ bool found;
+ r_ret=n->get(p_name,&found);
+ if (found)
+ return true;
+
+ }
+
+ return false;
+}
+
+void MultiNodeEdit::_get_property_list( List<PropertyInfo> *p_list) const{
+
+ HashMap<String,PLData> usage;
+
+ Node *es = EditorNode::get_singleton()->get_edited_scene();
+ if (!es)
+ return;
+
+ int nc=0;
+
+ List<PLData*> datas;
+
+ for (const List<NodePath>::Element *E=nodes.front();E;E=E->next()) {
+
+ if (!es->has_node(E->get()))
+ continue;
+
+ Node*n=es->get_node(E->get());
+ if (!n)
+ continue;
+
+ List<PropertyInfo> plist;
+ n->get_property_list(&plist,true);
+
+ for(List<PropertyInfo>::Element *F=plist.front();F;F=F->next()) {
+
+ if (!usage.has(F->get().name)) {
+ PLData pld;
+ pld.uses=0;
+ pld.info=F->get();
+ usage[F->get().name]=pld;
+ datas.push_back(usage.getptr(F->get().name));
+ }
+
+ usage[F->get().name].uses++;
+ }
+
+ nc++;
+ }
+
+ for (List<PLData*>::Element *E=datas.front();E;E=E->next()) {
+
+ if (nc==E->get()->uses) {
+ p_list->push_back(E->get()->info);
+ }
+ }
+
+
+}
+
+void MultiNodeEdit::clear_nodes() {
+
+ nodes.clear();
+}
+
+void MultiNodeEdit::add_node(const NodePath& p_node){
+
+ nodes.push_back(p_node);
+}
+
+MultiNodeEdit::MultiNodeEdit()
+{
+}
diff --git a/tools/editor/multi_node_edit.h b/tools/editor/multi_node_edit.h
new file mode 100644
index 0000000000..5a0cabf4be
--- /dev/null
+++ b/tools/editor/multi_node_edit.h
@@ -0,0 +1,32 @@
+#ifndef MULTI_NODE_EDIT_H
+#define MULTI_NODE_EDIT_H
+
+#include "scene/main/node.h"
+
+class MultiNodeEdit : public Reference {
+
+ OBJ_TYPE(MultiNodeEdit,Reference);
+
+ List<NodePath> nodes;
+ struct PLData {
+ int uses;
+ PropertyInfo info;
+ };
+
+protected:
+
+ bool _set(const StringName& p_name, const Variant& p_value);
+ bool _get(const StringName& p_name,Variant &r_ret) const;
+ void _get_property_list( List<PropertyInfo> *p_list) const;
+
+public:
+
+
+
+ void clear_nodes();
+ void add_node(const NodePath& p_node);
+
+ MultiNodeEdit();
+};
+
+#endif // MULTI_NODE_EDIT_H
diff --git a/tools/editor/plugins/animation_player_editor_plugin.cpp b/tools/editor/plugins/animation_player_editor_plugin.cpp
index 05b12543d2..f8c484e886 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.cpp
+++ b/tools/editor/plugins/animation_player_editor_plugin.cpp
@@ -549,6 +549,49 @@ void AnimationPlayerEditor::ensure_visibility() {
_animation_edit();
}
+Dictionary AnimationPlayerEditor::get_state() const {
+
+ Dictionary d;
+
+ d["visible"]=is_visible();
+ if (is_visible() && player) {
+ d["player"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(player);
+ d["animation"]=player->get_current_animation();
+ d["editing"]=edit_anim->is_pressed();
+ }
+
+ return d;
+
+}
+void AnimationPlayerEditor::set_state(const Dictionary& p_state) {
+
+ if (p_state.has("visible") && p_state["visible"]) {
+
+ Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
+ if (n && n->cast_to<AnimationPlayer>()) {
+ player=n->cast_to<AnimationPlayer>();
+ _update_player();
+ show();
+ set_process(true);
+ ensure_visibility();
+ EditorNode::get_singleton()->animation_panel_make_visible(true);
+
+ if (p_state.has("animation")) {
+ String anim = p_state["animation"];
+ _select_anim_by_name(anim);
+ if (p_state.has("editing") && p_state["editing"]) {
+
+ edit_anim->set_pressed(true);
+ _animation_edit();
+ }
+ }
+
+ }
+ }
+
+}
+
+
void AnimationPlayerEditor::_animation_resource_edit() {
if (animation->get_item_count()) {
@@ -1350,6 +1393,7 @@ AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) {
editor=p_node;
anim_editor = memnew( AnimationPlayerEditor(editor) );
+ anim_editor->set_undo_redo(editor->get_undo_redo());
editor->get_animation_panel()->add_child(anim_editor);
/*
editor->get_viewport()->add_child(anim_editor);
diff --git a/tools/editor/plugins/animation_player_editor_plugin.h b/tools/editor/plugins/animation_player_editor_plugin.h
index 9f0413088d..5705742565 100644
--- a/tools/editor/plugins/animation_player_editor_plugin.h
+++ b/tools/editor/plugins/animation_player_editor_plugin.h
@@ -151,6 +151,10 @@ protected:
static void _bind_methods();
public:
+ Dictionary get_state() const;
+ void set_state(const Dictionary& p_state);
+
+
void ensure_visibility();
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo=p_undo_redo; }
@@ -167,6 +171,9 @@ class AnimationPlayerEditorPlugin : public EditorPlugin {
public:
+ virtual Dictionary get_state() const { return anim_editor->get_state(); }
+ virtual void set_state(const Dictionary& p_state) { anim_editor->set_state(p_state); }
+
virtual String get_name() const { return "Anim"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index f2738f0a62..8fc2945450 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1910,12 +1910,20 @@ void CanvasItemEditor::_notification(int p_what) {
List<Node*> &selection = editor_selection->get_selected_node_list();
+ bool all_control=true;
+ bool has_control=false;
+
for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
if (!canvas_item || !canvas_item->is_visible())
continue;
+ if (canvas_item->cast_to<Control>())
+ has_control=true;
+ else
+ all_control=false;
+
CanvasItemEditorSelectedItem *se=editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
if (!se)
continue;
@@ -1932,6 +1940,13 @@ void CanvasItemEditor::_notification(int p_what) {
}
+ bool show_anchor = all_control && has_control;
+ if (show_anchor != !anchor_menu->is_hidden()) {
+ if (show_anchor)
+ anchor_menu->show();
+ else
+ anchor_menu->hide();
+ }
for(Map<ObjectID,BoneList>::Element *E=bone_list.front();E;E=E->next()) {
@@ -1974,6 +1989,32 @@ void CanvasItemEditor::_notification(int p_what) {
ungroup_button->set_icon(get_icon("Ungroup","EditorIcons"));
key_insert_button->set_icon(get_icon("Key","EditorIcons"));
+
+ //anchor_menu->add_icon_override("Align Top Left");
+ anchor_menu->set_icon(get_icon("Anchor","EditorIcons"));
+ PopupMenu *p=anchor_menu->get_popup();
+
+ p->add_icon_item(get_icon("ControlAlignTopLeft","EditorIcons"),"Top Left",ANCHOR_ALIGN_TOP_LEFT);
+ p->add_icon_item(get_icon("ControlAlignTopRight","EditorIcons"),"Top Right",ANCHOR_ALIGN_TOP_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomRight","EditorIcons"),"Bottom Right",ANCHOR_ALIGN_BOTTOM_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomLeft","EditorIcons"),"Bottom Left",ANCHOR_ALIGN_BOTTOM_LEFT);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignLeftCenter","EditorIcons"),"Center Left",ANCHOR_ALIGN_CENTER_LEFT);
+ p->add_icon_item(get_icon("ControlAlignTopCenter","EditorIcons"),"Center Top",ANCHOR_ALIGN_CENTER_TOP);
+ p->add_icon_item(get_icon("ControlAlignRightCenter","EditorIcons"),"Center Right",ANCHOR_ALIGN_CENTER_RIGHT);
+ p->add_icon_item(get_icon("ControlAlignBottomCenter","EditorIcons"),"Center Bottom",ANCHOR_ALIGN_CENTER_BOTTOM);
+ p->add_icon_item(get_icon("ControlAlignCenter","EditorIcons"),"Center",ANCHOR_ALIGN_CENTER);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignLeftWide","EditorIcons"),"Left Wide",ANCHOR_ALIGN_LEFT_WIDE);
+ p->add_icon_item(get_icon("ControlAlignTopWide","EditorIcons"),"Top Wide",ANCHOR_ALIGN_TOP_WIDE);
+ p->add_icon_item(get_icon("ControlAlignRightWide","EditorIcons"),"Right Wide",ANCHOR_ALIGN_RIGHT_WIDE);
+ p->add_icon_item(get_icon("ControlAlignBottomWide","EditorIcons"),"Bottom Wide",ANCHOR_ALIGN_BOTTOM_WIDE);
+ p->add_icon_item(get_icon("ControlVcenterWide","EditorIcons"),"VCenter Wide ",ANCHOR_ALIGN_VCENTER_WIDE);
+ p->add_icon_item(get_icon("ControlHcenterWide","EditorIcons"),"HCenter Wide ",ANCHOR_ALIGN_HCENTER_WIDE);
+ p->add_separator();
+ p->add_icon_item(get_icon("ControlAlignWide","EditorIcons"),"Full Rect",ANCHOR_ALIGN_WIDE);
+
+
}
if (p_what==NOTIFICATION_READY) {
@@ -2179,6 +2220,27 @@ void CanvasItemEditor::_update_scroll(float) {
}
+void CanvasItemEditor::_set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom) {
+ List<Node*> &selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action("Change Anchors");
+ for(List<Node*>::Element *E=selection.front();E;E=E->next()) {
+
+ Control *c = E->get()->cast_to<Control>();
+
+ undo_redo->add_do_method(c,"set_anchor",MARGIN_LEFT,p_left);
+ undo_redo->add_do_method(c,"set_anchor",MARGIN_TOP,p_top);
+ undo_redo->add_do_method(c,"set_anchor",MARGIN_RIGHT,p_right);
+ undo_redo->add_do_method(c,"set_anchor",MARGIN_BOTTOM,p_bottom);
+ undo_redo->add_undo_method(c,"set_anchor",MARGIN_LEFT,c->get_anchor(MARGIN_LEFT));
+ undo_redo->add_undo_method(c,"set_anchor",MARGIN_TOP,c->get_anchor(MARGIN_TOP));
+ undo_redo->add_undo_method(c,"set_anchor",MARGIN_RIGHT,c->get_anchor(MARGIN_RIGHT));
+ undo_redo->add_undo_method(c,"set_anchor",MARGIN_BOTTOM,c->get_anchor(MARGIN_BOTTOM));
+ }
+
+ undo_redo->commit_action();
+
+}
void CanvasItemEditor::_popup_callback(int p_op) {
@@ -2381,6 +2443,56 @@ void CanvasItemEditor::_popup_callback(int p_op) {
case SPACE_VERTICAL: {
//space_selected_items< proj_vector2_y, compare_items_y >();
} break;
+ case ANCHOR_ALIGN_TOP_LEFT: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN);
+ } break;
+ case ANCHOR_ALIGN_TOP_RIGHT: {
+ _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN);
+ } break;
+ case ANCHOR_ALIGN_BOTTOM_LEFT: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_BOTTOM_RIGHT: {
+ _set_anchor(ANCHOR_END,ANCHOR_END,ANCHOR_END,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_CENTER_LEFT: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER);
+ } break;
+ case ANCHOR_ALIGN_CENTER_RIGHT: {
+
+ _set_anchor(ANCHOR_END,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER);
+ } break;
+ case ANCHOR_ALIGN_CENTER_TOP: {
+ _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_BEGIN);
+ } break;
+ case ANCHOR_ALIGN_CENTER_BOTTOM: {
+ _set_anchor(ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_CENTER: {
+ _set_anchor(ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER,ANCHOR_CENTER);
+ } break;
+ case ANCHOR_ALIGN_TOP_WIDE: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_BEGIN);
+ } break;
+ case ANCHOR_ALIGN_LEFT_WIDE: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_RIGHT_WIDE: {
+ _set_anchor(ANCHOR_END,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_BOTTOM_WIDE: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_VCENTER_WIDE: {
+ _set_anchor(ANCHOR_CENTER,ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END);
+ } break;
+ case ANCHOR_ALIGN_HCENTER_WIDE: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_CENTER,ANCHOR_END,ANCHOR_CENTER);
+ } break;
+ case ANCHOR_ALIGN_WIDE: {
+ _set_anchor(ANCHOR_BEGIN,ANCHOR_BEGIN,ANCHOR_END,ANCHOR_END);
+ } break;
+
case ANIM_INSERT_KEY:
case ANIM_INSERT_KEY_EXISTING: {
@@ -2999,6 +3111,14 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_item("Center Selection", VIEW_CENTER_TO_SELECTION, KEY_F);
p->add_item("Frame Selection", VIEW_FRAME_TO_SELECTION, KEY_MASK_CMD|KEY_F);
+ anchor_menu = memnew( MenuButton );
+ anchor_menu->set_text("Anchor");
+ hb->add_child(anchor_menu);
+ anchor_menu->get_popup()->connect("item_pressed", this,"_popup_callback");
+ anchor_menu->hide();
+
+ //p = anchor_menu->get_popup();
+
animation_hb = memnew( HBoxContainer );
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h
index 48a34e2d07..485422028e 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.h
+++ b/tools/editor/plugins/canvas_item_editor_plugin.h
@@ -90,6 +90,23 @@ class CanvasItemEditor : public VBoxContainer {
UNGROUP_SELECTED,
ALIGN_HORIZONTAL,
ALIGN_VERTICAL,
+ ANCHOR_ALIGN_TOP_LEFT,
+ ANCHOR_ALIGN_TOP_RIGHT,
+ ANCHOR_ALIGN_BOTTOM_LEFT,
+ ANCHOR_ALIGN_BOTTOM_RIGHT,
+ ANCHOR_ALIGN_CENTER_LEFT,
+ ANCHOR_ALIGN_CENTER_RIGHT,
+ ANCHOR_ALIGN_CENTER_TOP,
+ ANCHOR_ALIGN_CENTER_BOTTOM,
+ ANCHOR_ALIGN_CENTER,
+ ANCHOR_ALIGN_TOP_WIDE,
+ ANCHOR_ALIGN_LEFT_WIDE,
+ ANCHOR_ALIGN_RIGHT_WIDE,
+ ANCHOR_ALIGN_BOTTOM_WIDE,
+ ANCHOR_ALIGN_VCENTER_WIDE,
+ ANCHOR_ALIGN_HCENTER_WIDE,
+ ANCHOR_ALIGN_WIDE,
+
SPACE_HORIZONTAL,
SPACE_VERTICAL,
EXPAND_TO_PARENT,
@@ -225,6 +242,7 @@ class CanvasItemEditor : public VBoxContainer {
MenuButton *view_menu;
HBoxContainer *animation_hb;
MenuButton *animation_menu;
+ MenuButton *anchor_menu;
Button *key_loc_button;
Button *key_rot_button;
@@ -305,6 +323,8 @@ class CanvasItemEditor : public VBoxContainer {
void _viewport_input_event(const InputEvent& p_event);
void _viewport_draw();
+ void _set_anchor(Control::AnchorType p_left,Control::AnchorType p_top,Control::AnchorType p_right,Control::AnchorType p_bottom);
+
HSplitContainer *palette_split;
VSplitContainer *bottom_split;
diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp
index 2c64b2eb6b..13d4c8db5a 100644
--- a/tools/editor/plugins/mesh_editor_plugin.cpp
+++ b/tools/editor/plugins/mesh_editor_plugin.cpp
@@ -216,6 +216,8 @@ MeshInstanceEditor::MeshInstanceEditor() {
SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
options->set_text("Mesh");
+ options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance","EditorIcons"));
+
options->get_popup()->add_item("Create Trimesh Static Body",MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
options->get_popup()->add_item("Create Convex Static Body",MENU_OPTION_CREATE_STATIC_CONVEX_BODY);
options->get_popup()->add_separator();
diff --git a/tools/editor/plugins/multimesh_editor_plugin.cpp b/tools/editor/plugins/multimesh_editor_plugin.cpp
index 0df906117e..3c88b1d3a8 100644
--- a/tools/editor/plugins/multimesh_editor_plugin.cpp
+++ b/tools/editor/plugins/multimesh_editor_plugin.cpp
@@ -330,6 +330,8 @@ MultiMeshEditor::MultiMeshEditor() {
options->set_area_as_parent_rect();
options->set_text("MultiMesh");
+ options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MultiMeshInstance","EditorIcons"));
+
options->get_popup()->add_item("Populate Surface");
options->get_popup()->connect("item_pressed", this,"_menu_option");
diff --git a/tools/editor/plugins/particles_2d_editor_plugin.cpp b/tools/editor/plugins/particles_2d_editor_plugin.cpp
index fdf534a3a8..dadfa8bfdc 100644
--- a/tools/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/particles_2d_editor_plugin.cpp
@@ -146,6 +146,7 @@ void Particles2DEditorPlugin::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
menu->get_popup()->connect("item_pressed",this,"_menu_callback");
+ menu->set_icon(menu->get_popup()->get_icon("Particles2D","EditorIcons"));
file->connect("file_selected",this,"_file_selected");
}
}
diff --git a/tools/editor/plugins/particles_editor_plugin.cpp b/tools/editor/plugins/particles_editor_plugin.cpp
index f6f01d82ca..5c84d9a86a 100644
--- a/tools/editor/plugins/particles_editor_plugin.cpp
+++ b/tools/editor/plugins/particles_editor_plugin.cpp
@@ -111,6 +111,7 @@ void ParticlesEditor::_populate() {
void ParticlesEditor::_notification(int p_notification) {
if (p_notification==NOTIFICATION_ENTER_TREE) {
+ options->set_icon(options->get_popup()->get_icon("Particles","EditorIcons"));
}
}
diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp
index 77663f39c0..8fc6a6931e 100644
--- a/tools/editor/plugins/spatial_editor_plugin.cpp
+++ b/tools/editor/plugins/spatial_editor_plugin.cpp
@@ -2168,7 +2168,18 @@ void SpatialEditorViewport::set_state(const Dictionary& p_state) {
view_menu->get_popup()->set_item_checked( idx, listener );
}
-
+ if (p_state.has("previewing")) {
+ Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]);
+ if (pv && pv->cast_to<Camera>()) {
+ previewing=pv->cast_to<Camera>();
+ previewing->connect("exit_tree",this,"_preview_exited_scene");
+ VS::get_singleton()->viewport_attach_camera( viewport->get_viewport(), previewing->get_camera() ); //replace
+ view_menu->hide();
+ surface->update();
+ preview_camera->set_pressed(true);
+ preview_camera->show();
+ }
+ }
}
Dictionary SpatialEditorViewport::get_state() const {
@@ -2181,6 +2192,10 @@ Dictionary SpatialEditorViewport::get_state() const {
d["use_environment"]=camera->get_environment().is_valid();
d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL;
d["listener"]=viewport->is_audio_listener();
+ if (previewing) {
+ d["previewing"]=EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing);
+ }
+
return d;
}
diff --git a/tools/editor/project_export.cpp b/tools/editor/project_export.cpp
index a087f23c25..9f871fd3ab 100644
--- a/tools/editor/project_export.cpp
+++ b/tools/editor/project_export.cpp
@@ -80,7 +80,7 @@ bool ProjectExportDialog::_create_tree(TreeItem *p_parent,EditorFileSystemDirect
String path = p_dir->get_file_path(i);
fitem->set_tooltip(0,path);
fitem->set_metadata(0,path);
- Ref<Texture> icon = get_icon( (has_icon(p_dir->get_file_type(i),"EditorIcons")?p_dir->get_file_type(i):String("Object")),"EditorIcons");
+ Ref<Texture> icon = get_icon( (has_icon(p_dir->get_file_type(i),ei)?p_dir->get_file_type(i):ot),ei);
fitem->set_icon(0,icon);
fitem->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
@@ -1216,6 +1216,7 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
group_image_action->add_item("Default");
group_image_action->add_item("Compress Disk");
group_image_action->add_item("Compress RAM");
+ group_image_action->add_item("Keep Original");
group_options->add_margin_child("Compress Mode:",group_image_action);
group_image_action->connect("item_selected",this,"_group_changed");
@@ -1372,6 +1373,8 @@ ProjectExportDialog::ProjectExportDialog(EditorNode *p_editor) {
button_export = add_button("Export..",!OS::get_singleton()->get_swap_ok_cancel(),"export_pck");
updating_script=false;
+ ei="EditorIcons";
+ ot="Object";
}
diff --git a/tools/editor/project_export.h b/tools/editor/project_export.h
index c88233ae01..d85e688e58 100644
--- a/tools/editor/project_export.h
+++ b/tools/editor/project_export.h
@@ -78,6 +78,9 @@ private:
HBoxContainer *plat_errors;
Label *platform_error_string;
+ StringName ei;
+ StringName ot;
+
Tree * tree;
EditorFileDialog *pck_export;
diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp
index fea9c705ef..25a2750166 100644
--- a/tools/editor/project_settings.cpp
+++ b/tools/editor/project_settings.cpp
@@ -771,18 +771,47 @@ void ProjectSettings::_autoload_add() {
void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button) {
+
TreeItem *ti=p_item->cast_to<TreeItem>();
String name = "autoload/"+ti->get_text(0);
- undo_redo->create_action("Remove Autoload");
- undo_redo->add_do_property(Globals::get_singleton(),name,Variant());
- undo_redo->add_undo_property(Globals::get_singleton(),name,Globals::get_singleton()->get(name));
- undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,true);
- undo_redo->add_do_method(this,"_update_autoload");
- undo_redo->add_undo_method(this,"_update_autoload");
- undo_redo->add_do_method(this,"_settings_changed");
- undo_redo->add_undo_method(this,"_settings_changed");
- undo_redo->commit_action();
+ if (p_button==0) {
+ //delete
+ undo_redo->create_action("Remove Autoload");
+ undo_redo->add_do_property(Globals::get_singleton(),name,Variant());
+ undo_redo->add_undo_property(Globals::get_singleton(),name,Globals::get_singleton()->get(name));
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,true);
+ undo_redo->add_do_method(this,"_update_autoload");
+ undo_redo->add_undo_method(this,"_update_autoload");
+ undo_redo->add_do_method(this,"_settings_changed");
+ undo_redo->add_undo_method(this,"_settings_changed");
+ undo_redo->commit_action();
+ } else {
+
+ TreeItem *swap;
+
+ if (p_button==1) {
+ swap=ti->get_prev();
+ } else if (p_button==2) {
+ swap=ti->get_next();
+ }
+ if (!swap)
+ return;
+
+ String swap_name= "autoload/"+swap->get_text(0);
+
+ undo_redo->create_action("Move Autoload");
+ undo_redo->add_do_method(Globals::get_singleton(),"set_order",swap_name,Globals::get_singleton()->get_order(name));
+ undo_redo->add_do_method(Globals::get_singleton(),"set_order",name,Globals::get_singleton()->get_order(swap_name));
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",swap_name,Globals::get_singleton()->get_order(swap_name));
+ undo_redo->add_undo_method(Globals::get_singleton(),"set_order",name,Globals::get_singleton()->get_order(name));
+ undo_redo->add_do_method(this,"_update_autoload");
+ undo_redo->add_undo_method(this,"_update_autoload");
+ undo_redo->add_do_method(this,"_settings_changed");
+ undo_redo->add_undo_method(this,"_settings_changed");
+ undo_redo->commit_action();
+
+ }
}
@@ -1134,6 +1163,8 @@ void ProjectSettings::_update_autoload() {
TreeItem *t = autoload_list->create_item(root);
t->set_text(0,name);
t->set_text(1,Globals::get_singleton()->get(pi.name));
+ t->add_button(1,get_icon("MoveUp","EditorIcons"),1);
+ t->add_button(1,get_icon("MoveDown","EditorIcons"),2);
t->add_button(1,get_icon("Del","EditorIcons"),0);
}
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 955c426d2b..b513e32c13 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -39,6 +39,9 @@
#include "editor_settings.h"
#include "editor_import_export.h"
#include "editor_node.h"
+#include "multi_node_edit.h"
+#include "array_property_edit.h"
+#include "editor_help.h"
void CustomPropertyEditor::_notification(int p_what) {
@@ -2212,6 +2215,23 @@ void PropertyEditor::update_tree() {
sep->set_selectable(1,false);
sep->set_custom_bg_color(0,get_color("prop_category","Editor"));
sep->set_custom_bg_color(1,get_color("prop_category","Editor"));
+
+ if (use_doc_hints) {
+ StringName type=p.name;
+ if (!class_descr_cache.has(type)) {
+
+ String descr;
+ DocData *dd=EditorHelp::get_doc_data();
+ Map<String,DocData::ClassDoc>::Element *E=dd->class_list.find(type);
+ if (E) {
+ descr=E->get().brief_description;
+ }
+ class_descr_cache[type]=descr.world_wrap(80);
+
+ }
+
+ sep->set_tooltip(0,"Class: "+p.name+":\n\n"+class_descr_cache[type]);
+ }
//sep->set_custom_color(0,Color(1,1,1));
@@ -2265,6 +2285,42 @@ void PropertyEditor::update_tree() {
item->set_tooltip(0, p.name);
+ if (use_doc_hints) {
+ StringName setter;
+ StringName type;
+ if (ObjectTypeDB::get_setter_and_type_for_property(obj->get_type_name(),p.name,type,setter)) {
+
+ String descr;
+ bool found=false;
+ Map<StringName,Map<StringName,String> >::Element *E=descr_cache.find(type);
+ if (E) {
+
+ Map<StringName,String>::Element *F=E->get().find(setter);
+ if (F) {
+ found=true;
+ descr=F->get();
+ }
+ }
+ if (!found) {
+
+ DocData *dd=EditorHelp::get_doc_data();
+ Map<String,DocData::ClassDoc>::Element *E=dd->class_list.find(type);
+ if (E) {
+ for(int i=0;i<E->get().methods.size();i++) {
+ if (E->get().methods[i].name==setter.operator String()) {
+ descr=E->get().methods[i].description.strip_edges().world_wrap(80);
+ }
+ }
+ }
+
+ descr_cache[type][setter]=descr;
+ }
+
+ item->set_tooltip(0, "Property: "+p.name+"\n\n"+descr);
+ }
+ }
+ //EditorHelp::get_doc_data();
+
Dictionary d;
d["name"]=p.name;
d["type"]=(int)p.type;
@@ -2347,8 +2403,10 @@ void PropertyEditor::update_tree() {
item->set_cell_mode( 1, TreeItem::CELL_MODE_RANGE );
+ if (p.hint==PROPERTY_HINT_SPRITE_FRAME) {
+ item->set_range_config(1,0,99999,1);
- if (p.hint==PROPERTY_HINT_RANGE || p.hint==PROPERTY_HINT_EXP_RANGE) {
+ } else if (p.hint==PROPERTY_HINT_RANGE || p.hint==PROPERTY_HINT_EXP_RANGE) {
int c = p.hint_string.get_slice_count(",");
float min=0,max=100,step=1;
@@ -2449,11 +2507,32 @@ void PropertyEditor::update_tree() {
}
} break;
+ case Variant::ARRAY: {
+
+ item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"Array["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"Array[]");
+ item->set_icon( 0, get_icon("ArrayData","EditorIcons") );
+
+
+ } break;
+
case Variant::INT_ARRAY: {
item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
- item->set_editable( 1, !read_only );
- item->set_text(1,"[IntArray]");
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"IntArray["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"IntArray[]");
item->set_icon( 0, get_icon("ArrayInt","EditorIcons") );
@@ -2461,26 +2540,86 @@ void PropertyEditor::update_tree() {
case Variant::REAL_ARRAY: {
item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
- item->set_editable( 1, !read_only );
- item->set_text(1,"[RealArray]");
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"FloatArray["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"FloatArray[]");
item->set_icon( 0, get_icon("ArrayReal","EditorIcons") );
+
} break;
case Variant::STRING_ARRAY: {
item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
- item->set_editable( 1, !read_only );
- item->set_text(1,"[StringArray]");
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"String["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"String[]");
item->set_icon( 0, get_icon("ArrayString","EditorIcons") );
+
} break;
case Variant::RAW_ARRAY: {
item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
- item->set_editable( 1, !read_only );
- item->set_text(1,"[Raw Data]");
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"Byte["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"Byte[]");
item->set_icon( 0, get_icon("ArrayData","EditorIcons") );
+
+ } break;
+ case Variant::VECTOR2_ARRAY: {
+
+ item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"Vector2["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"Vector2[]");
+ item->set_icon( 0, get_icon("Vector2","EditorIcons") );
+
+
+ } break;
+ case Variant::VECTOR3_ARRAY: {
+
+ item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"Vector3["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"Vector3[]");
+ item->set_icon( 0, get_icon("Vector","EditorIcons") );
+
+
+ } break;
+ case Variant::COLOR_ARRAY: {
+
+ item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM );
+ item->add_button(1,get_icon("EditResource","EditorIcons"));
+
+ Variant v = obj->get(p.name);
+ if (v.is_array())
+ item->set_text(1,"Color["+itos(v.call("size"))+"]");
+ else
+ item->set_text(1,"Color[]");
+ item->set_icon( 0, get_icon("Color","EditorIcons") );
+
+
} break;
case Variant::VECTOR2: {
@@ -2676,7 +2815,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
}
}
- if (!undo_redo) {
+ if (!undo_redo || obj->cast_to<MultiNodeEdit>() || obj->cast_to<ArrayPropertyEdit>()) { //kind of hacky
obj->set(p_name,p_value);
_changed_callbacks(obj,p_name);
@@ -2996,6 +3135,19 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
emit_signal("resource_selected",r,n);
}
+ } else if (t==Variant::ARRAY || t==Variant::INT_ARRAY || t==Variant::REAL_ARRAY || t==Variant::STRING_ARRAY || t==Variant::VECTOR2_ARRAY || t==Variant::VECTOR3_ARRAY || t==Variant::COLOR_ARRAY || t==Variant::RAW_ARRAY) {
+
+ Variant v = obj->get(n);
+
+ if (v.get_type()!=t) {
+ Variant::CallError ce;
+ v=Variant::construct(Variant::Type(t),NULL,0,ce);
+ }
+
+ Ref<ArrayPropertyEdit> ape = memnew( ArrayPropertyEdit );
+ ape->edit(obj,n,Variant::Type(t));
+
+ EditorNode::get_singleton()->push_item(ape.ptr());
}
}
}
@@ -3181,6 +3333,7 @@ PropertyEditor::PropertyEditor() {
read_only=false;
show_categories=false;
refresh_countdown=0;
+ use_doc_hints=false;
}
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index de5cac8711..36ecc794ed 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -95,6 +95,7 @@ class CustomPropertyEditor : public Popup {
Button *checks20[20];
+
Control *easing_draw;
Object* owner;
@@ -157,9 +158,13 @@ class PropertyEditor : public Control {
bool read_only;
bool show_categories;
float refresh_countdown;
+ bool use_doc_hints;
HashMap<String,String> pending;
String selected_property;
+
+ Map<StringName,Map<StringName,String> > descr_cache;
+ Map<StringName,String > class_descr_cache;
CustomPropertyEditor *custom_editor;
@@ -217,6 +222,7 @@ public:
void set_autoclear(bool p_enable);
void set_show_categories(bool p_show);
+ void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; }
PropertyEditor();
~PropertyEditor();
diff --git a/tools/editor/quick_open.cpp b/tools/editor/quick_open.cpp
index 749318386c..6135a4ab64 100644
--- a/tools/editor/quick_open.cpp
+++ b/tools/editor/quick_open.cpp
@@ -30,8 +30,9 @@
#include "os/keyboard.h"
-void EditorQuickOpen::popup(const String& p_base, bool p_dontclear) {
+void EditorQuickOpen::popup(const StringName &p_base, bool p_dontclear, bool p_add_dirs) {
+ add_directories=p_add_dirs;
popup_centered_ratio(0.6);
if (p_dontclear)
search_box->select_all();
@@ -66,27 +67,53 @@ void EditorQuickOpen::_sbox_input(const InputEvent& p_ie) {
void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd) {
- for(int i=0;i<efsd->get_subdir_count();i++) {
+ if (!add_directories) {
+ for(int i=0;i<efsd->get_subdir_count();i++) {
- _parse_fs(efsd->get_subdir(i));
+ _parse_fs(efsd->get_subdir(i));
+ }
}
+ TreeItem *root = search_options->get_root();
+
+ if (add_directories) {
+ String path = efsd->get_path();
+ if (!path.ends_with("/"))
+ path+="/";
+ if (path!="res://") {
+ path=path.substr(6,path.length());
+ if (path.findn(search_box->get_text())!=-1) {
+ TreeItem *ti = search_options->create_item(root);
+ ti->set_text(0,path);
+ Ref<Texture> icon = get_icon("folder","FileDialog");
+ ti->set_icon(0,icon);
+ }
+ }
+ }
for(int i=0;i<efsd->get_file_count();i++) {
String file = efsd->get_file_path(i);
file=file.substr(6,file.length());
if (ObjectTypeDB::is_type(efsd->get_file_type(i),base_type) && (search_box->get_text()=="" || file.findn(search_box->get_text())!=-1)) {
- TreeItem *root = search_options->get_root();
TreeItem *ti = search_options->create_item(root);
ti->set_text(0,file);
- Ref<Texture> icon = get_icon( (has_icon(efsd->get_file_type(i),"EditorIcons")?efsd->get_file_type(i):String("Object")),"EditorIcons");
+ Ref<Texture> icon = get_icon( (has_icon(efsd->get_file_type(i),ei)?efsd->get_file_type(i):ot),ei);
ti->set_icon(0,icon);
if (root->get_children()==ti)
ti->select(0);
}
}
+
+
+ if (add_directories) {
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+
+ _parse_fs(efsd->get_subdir(i));
+ }
+ }
+
}
void EditorQuickOpen::_update_search() {
@@ -118,7 +145,7 @@ void EditorQuickOpen::_notification(int p_what) {
}
-String EditorQuickOpen::get_base_type() const {
+StringName EditorQuickOpen::get_base_type() const {
return base_type;
}
@@ -152,4 +179,7 @@ EditorQuickOpen::EditorQuickOpen() {
set_hide_on_ok(false);
search_options->connect("item_activated",this,"_confirmed");
search_options->set_hide_root(true);
+ ei="EditorIcons";
+ ot="Object";
+ add_directories=false;
}
diff --git a/tools/editor/quick_open.h b/tools/editor/quick_open.h
index 63652a442a..8b38256d39 100644
--- a/tools/editor/quick_open.h
+++ b/tools/editor/quick_open.h
@@ -38,7 +38,11 @@ class EditorQuickOpen : public ConfirmationDialog {
LineEdit *search_box;
Tree *search_options;
- String base_type;
+ StringName base_type;
+ StringName ei;
+ StringName ot;
+ bool add_directories;
+
void _update_search();
@@ -55,9 +59,9 @@ protected:
static void _bind_methods();
public:
- String get_base_type() const;
+ StringName get_base_type() const;
- void popup(const String& p_base,bool p_dontclear=false);
+ void popup(const StringName& p_base,bool p_dontclear=false,bool p_add_dirs=false);
EditorQuickOpen();
};
diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp
index ae0b58a665..276f2dea33 100644
--- a/tools/editor/scene_tree_dock.cpp
+++ b/tools/editor/scene_tree_dock.cpp
@@ -35,7 +35,7 @@
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
#include "script_editor_debugger.h"
#include "tools/editor/plugins/script_editor_plugin.h"
-
+#include "multi_node_edit.h"
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
@@ -450,6 +450,19 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
reparent_dialog->set_current( nodeset );
} break;
+ case TOOL_MULTI_EDIT: {
+
+ Node*root=EditorNode::get_singleton()->get_edited_scene();
+ if (!root)
+ break;
+ Ref<MultiNodeEdit> mne = memnew( MultiNodeEdit );
+ for (const Map<Node*,Object*>::Element *E=EditorNode::get_singleton()->get_editor_selection()->get_selection().front();E;E=E->next()) {
+ mne->add_node(root->get_path_to(E->key()));
+ }
+
+ EditorNode::get_singleton()->push_item(mne.ptr());
+
+ } break;
case TOOL_ERASE: {
List<Node*> remove_list = editor_selection->get_selected_node_list();
@@ -507,6 +520,7 @@ void SceneTreeDock::_notification(int p_what) {
"MoveDown",
"Duplicate",
"Reparent",
+ "MultiNodeEdit",
"Remove",
};
@@ -515,6 +529,8 @@ void SceneTreeDock::_notification(int p_what) {
for(int i=0;i<TOOL_BUTTON_MAX;i++)
tool_buttons[i]->set_icon(get_icon(button_names[i],"EditorIcons"));
+ EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed",this,"_selection_changed");
+
} break;
}
}
@@ -1075,9 +1091,19 @@ void SceneTreeDock::_update_tool_buttons() {
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);
tool_buttons[TOOL_REPARENT]->set_disabled(disable_root);
tool_buttons[TOOL_ERASE]->set_disabled(disable);
+ tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
+
}
+
+void SceneTreeDock::_selection_changed() {
+
+ tool_buttons[TOOL_MULTI_EDIT]->set_disabled(EditorNode::get_singleton()->get_editor_selection()->get_selection().size()<2);
+
+}
+
+
void SceneTreeDock::_create() {
@@ -1262,6 +1288,7 @@ void SceneTreeDock::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_delete_confirm"),&SceneTreeDock::_delete_confirm);
ObjectTypeDB::bind_method(_MD("_node_prerenamed"),&SceneTreeDock::_node_prerenamed);
ObjectTypeDB::bind_method(_MD("_import_subscene"),&SceneTreeDock::_import_subscene);
+ ObjectTypeDB::bind_method(_MD("_selection_changed"),&SceneTreeDock::_selection_changed);
ObjectTypeDB::bind_method(_MD("instance"),&SceneTreeDock::instance);
}
@@ -1365,6 +1392,12 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
hbc_bottom->add_spacer();
tb = memnew( ToolButton );
+ tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_MULTI_EDIT, false));
+ tb->set_tooltip("Multi-Edit Selected Nodes");
+ hbc_bottom->add_child(tb);
+ tool_buttons[TOOL_MULTI_EDIT]=tb;
+
+ tb = memnew( ToolButton );
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_ERASE, false));
tb->set_tooltip("Erase Selected Node(s)");
hbc_bottom->add_child(tb);
diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h
index f0bbbad6be..b1c53d2ff9 100644
--- a/tools/editor/scene_tree_dock.h
+++ b/tools/editor/scene_tree_dock.h
@@ -62,6 +62,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_MOVE_DOWN,
TOOL_DUPLICATE,
TOOL_REPARENT,
+ TOOL_MULTI_EDIT,
TOOL_ERASE,
TOOL_BUTTON_MAX
};
@@ -119,6 +120,7 @@ class SceneTreeDock : public VBoxContainer {
void _import_subscene();
bool _validate_no_foreign();
+ void _selection_changed();
void _fill_path_renames(Vector<StringName> base_path,Vector<StringName> new_base_path,Node * p_node, List<Pair<NodePath,NodePath> > *p_renames);
diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp
index 9153616775..7d9c5b24b2 100644
--- a/tools/editor/scenes_dock.cpp
+++ b/tools/editor/scenes_dock.cpp
@@ -35,15 +35,30 @@
#include "os/os.h"
#include "editor_node.h"
+#include "editor_settings.h"
+
bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir) {
- String search_term = tree_filter->get_search_term();
- ScenesDockFilter::FilterOption file_filter = tree_filter->get_file_filter();
TreeItem *item = tree->create_item(p_parent);
- item->set_text(0,p_dir->get_name()+"/");
+ String dname=p_dir->get_name();
+ if (dname=="")
+ dname="res://";
+
+ item->set_text(0,dname);
item->set_icon(0,get_icon("Folder","EditorIcons"));
- item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
+ item->set_selectable(0,true);
+ String lpath = p_dir->get_path();
+ if (lpath!="res://" && lpath.ends_with("/")) {
+ lpath=lpath.substr(0,lpath.length()-1);
+ }
+ item->set_metadata(0,lpath);
+ if (lpath==path) {
+ item->select(0);
+ }
+
+
+ //item->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
bool has_items=false;
@@ -52,7 +67,7 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di
if (_create_tree(item,p_dir->get_subdir(i)))
has_items=true;
}
-
+#if 0
for (int i=0;i<p_dir->get_file_count();i++) {
String file_name = p_dir->get_file(i);
@@ -89,13 +104,13 @@ bool ScenesDock::_create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_di
has_items=true;
}
-
- if (!has_items) {
+#endif
+ /*if (!has_items) {
memdelete(item);
return false;
- }
+ }*/
return true;
}
@@ -105,7 +120,28 @@ void ScenesDock::_update_tree() {
tree->clear();
updating_tree=true;
- _create_tree(NULL,EditorFileSystem::get_singleton()->get_filesystem());
+ TreeItem *root = tree->create_item();
+ TreeItem *favorites = tree->create_item(root);
+ favorites->set_icon(0, get_icon("Favorites","EditorIcons") );
+ favorites->set_text(0,"Favorites:");
+ favorites->set_selectable(0,false);
+ Vector<String> faves = EditorSettings::get_singleton()->get_favorite_dirs();
+ for(int i=0;i<faves.size();i++) {
+ if (!faves[i].begins_with("res://"))
+ continue;
+
+ TreeItem *ti = tree->create_item(favorites);
+ String fv = faves[i];
+ if (fv=="res://")
+ ti->set_text(0,"/");
+ else
+ ti->set_text(0,faves[i].get_file());
+ ti->set_icon(0,get_icon("Folder","EditorIcons"));
+ ti->set_selectable(0,true);
+ ti->set_metadata(0,faves[i]);
+ }
+
+ _create_tree(root,EditorFileSystem::get_singleton()->get_filesystem());
updating_tree=false;
}
@@ -117,68 +153,192 @@ void ScenesDock::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
+ if (initialized)
+ return;
+ initialized=false;
- EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"_update_tree");
+ EditorFileSystem::get_singleton()->connect("filesystem_changed",this,"_fs_changed");
button_reload->set_icon( get_icon("Reload","EditorIcons"));
button_favorite->set_icon( get_icon("Favorites","EditorIcons"));
+ button_fav_up->set_icon( get_icon("MoveUp","EditorIcons"));
+ button_fav_down->set_icon( get_icon("MoveDown","EditorIcons"));
button_instance->set_icon( get_icon("Add","EditorIcons"));
button_open->set_icon( get_icon("Folder","EditorIcons"));
+ button_back->set_icon( get_icon("Filesystem","EditorIcons"));
+ display_mode->set_icon( get_icon("FileList","EditorIcons"));
+ display_mode->connect("pressed",this,"_change_file_display");
+ file_options->set_icon( get_icon("Tools","EditorIcons"));
+ files->connect("item_activated",this,"_select_file");
+ button_hist_next->connect("pressed",this,"_fw_history");
+ button_hist_prev->connect("pressed",this,"_bw_history");
- String path = Globals::get_singleton()->get_resource_path()+"/favorites.cfg";
- FileAccess *f=FileAccess::open(path,FileAccess::READ);
- if (f) {
+ button_hist_next->set_icon( get_icon("Forward","EditorIcons"));
+ button_hist_prev->set_icon( get_icon("Back","EditorIcons"));
+ file_options->get_popup()->connect("item_pressed",this,"_file_option");
- String l = f->get_line();
- while(l!="") {
- favorites.insert(l);
- l = f->get_line();
-
- }
+ button_back->connect("pressed",this,"_go_to_tree",varray(),CONNECT_DEFERRED);
+ current_path->connect("text_entered",this,"_go_to_dir");
+ _update_tree(); //maybe it finished already
- f->close();
- memdelete(f);
+ if (EditorFileSystem::get_singleton()->is_scanning()) {
+ _set_scannig_mode();
}
-
-
- _update_tree(); //maybe it finished already
+ } break;
+ case NOTIFICATION_PROCESS: {
+ if (EditorFileSystem::get_singleton()->is_scanning()) {
+ scanning_progress->set_val(EditorFileSystem::get_singleton()->get_scanning_progress()*100);
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
} break;
- case NOTIFICATION_PROCESS: {
- } break;
}
}
-void ScenesDock::_favorite_toggled() {
- if (updating_tree)
+
+
+void ScenesDock::_dir_selected() {
+
+ TreeItem *ti = tree->get_selected();
+ if (!ti)
return;
+ String dir = ti->get_metadata(0);
+ bool found=false;
+ Vector<String> favorites = EditorSettings::get_singleton()->get_favorite_dirs();
+ for(int i=0;i<favorites.size();i++) {
+
+ if (favorites[i]==dir) {
+ found=true;
+ break;
+ }
+ }
+
+
+ button_favorite->set_pressed(found);
+ if (ti->get_parent() && ti->get_parent()->get_parent()==tree->get_root() && !ti->get_parent()->get_prev()) {
+
+ //a favorite!!!
+ button_fav_up->set_disabled(!ti->get_prev());
+ button_fav_down->set_disabled(!ti->get_next());
+ } else {
+ button_fav_up->set_disabled(true);
+ button_fav_down->set_disabled(true);
+
+ }
+}
+
+void ScenesDock::_fav_up_pressed() {
TreeItem *sel = tree->get_selected();
if (!sel)
- return; //?
+ return ;
- bool faved = sel->is_checked(0);
- String path = sel->get_metadata(0);
- if (faved)
- favorites.insert(path);
- else
- favorites.erase(path);
+ if (!sel->get_prev())
+ return;
+
+ String sw = sel->get_prev()->get_metadata(0);
+ String txt = sel->get_metadata(0);
+
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+
+ int a_idx=favorited.find(sw);
+ int b_idx=favorited.find(txt);
+
+ if (a_idx==-1 || b_idx==-1)
+ return;
+ SWAP(favorited[a_idx],favorited[b_idx]);
+
+ EditorSettings::get_singleton()->set_favorite_dirs(favorited);
+
+ _update_tree();
- timer->start();
+ if (!tree->get_root() || !tree->get_root()->get_children() || !tree->get_root()->get_children()->get_children())
+ return;
+ sel = tree->get_root()->get_children()->get_children();
+ while(sel) {
+ String t = sel->get_metadata(0);
+ if (t==txt) {
+ sel->select(0);
+ return;
+ }
+ sel=sel->get_next();
+ }
}
-void ScenesDock::_favorites_toggled(bool p_toggled) {
+void ScenesDock::_fav_down_pressed() {
+
+ TreeItem *sel = tree->get_selected();
+ if (!sel)
+ return ;
+
+ if (!sel->get_next())
+ return;
+
+ String sw = sel->get_next()->get_metadata(0);
+ String txt = sel->get_metadata(0);
+
+ Vector<String> favorited = EditorSettings::get_singleton()->get_favorite_dirs();
+
+ int a_idx=favorited.find(sw);
+ int b_idx=favorited.find(txt);
+
+ if (a_idx==-1 || b_idx==-1)
+ return;
+ SWAP(favorited[a_idx],favorited[b_idx]);
+
+ EditorSettings::get_singleton()->set_favorite_dirs(favorited);
_update_tree();
+
+ if (!tree->get_root() || !tree->get_root()->get_children() || !tree->get_root()->get_children()->get_children())
+ return;
+ sel = tree->get_root()->get_children()->get_children();
+ while(sel) {
+
+ String t = sel->get_metadata(0);
+ if (t==txt) {
+ sel->select(0);
+ return;
+ }
+ sel=sel->get_next();
+ }
+}
+
+void ScenesDock::_favorites_pressed() {
+
+ TreeItem *sel = tree->get_selected();
+ if (!sel)
+ return ;
+ String dir = sel->get_metadata(0);
+
+ int idx = -1;
+ Vector<String> favorites = EditorSettings::get_singleton()->get_favorite_dirs();
+ for(int i=0;i<favorites.size();i++) {
+
+ if (favorites[i]==dir) {
+ idx=i;
+ break;
+ }
+ }
+
+ if (button_favorite->is_pressed() && idx==-1) {
+ favorites.push_back(dir);
+ EditorSettings::get_singleton()->set_favorite_dirs(favorites);
+ _update_tree();
+ } else if (!button_favorite->is_pressed() && idx!=-1) {
+ favorites.remove(idx);
+ EditorSettings::get_singleton()->set_favorite_dirs(favorites);
+ _update_tree();
+ }
+
}
String ScenesDock::get_selected_path() const {
@@ -199,65 +359,712 @@ void ScenesDock::_instance_pressed() {
emit_signal("instance",path);
}
-void ScenesDock::_open_pressed(){
+void ScenesDock::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) {
- TreeItem *sel = tree->get_selected();
- if (!sel) {
+ if (p_preview.is_valid() && path==p_path.get_base_dir()) {
+
+ int idx=p_udata;
+ if (idx>=files->get_item_count())
+ return;
+ String fpath = files->get_item_metadata(idx);
+ if (fpath!=p_path)
+ return;
+ files->set_item_icon(idx,p_preview);
+
+ }
+
+}
+
+void ScenesDock::_change_file_display() {
+
+ if (display_mode->is_pressed()) {
+ display_mode->set_icon( get_icon("FileThumbnail","EditorIcons"));
+
+ } else {
+ display_mode->set_icon( get_icon("FileList","EditorIcons"));
+ }
+
+ _update_files(true);
+}
+
+void ScenesDock::_update_files(bool p_keep_selection) {
+
+ Set<String> cselection;
+
+ if (p_keep_selection) {
+
+ for(int i=0;i<files->get_item_count();i++) {
+
+ if (files->is_selected(i))
+ cselection.insert(files->get_item_text(i));
+ }
+ }
+
+ files->clear();
+
+ EditorFileSystemDirectory *efd = EditorFileSystem::get_singleton()->get_path(path);
+ if (!efd)
return;
+
+ int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
+ Ref<Texture> folder_thumbnail;
+ Ref<Texture> file_thumbnail;
+
+ bool use_thumbnails=!display_mode->is_pressed();
+
+ if (use_thumbnails) { //thumbnails
+
+ files->set_max_columns(0);
+ files->set_icon_mode(ItemList::ICON_MODE_TOP);
+ files->set_fixed_column_width(thumbnail_size*3/2);
+ files->set_max_text_lines(2);
+ files->set_min_icon_size(Size2(thumbnail_size,thumbnail_size));
+
+ if (!has_icon("ResizedFolder","EditorIcons")) {
+ Ref<ImageTexture> folder = get_icon("FolderBig","EditorIcons");
+ Image img = folder->get_data();
+ img.resize(thumbnail_size,thumbnail_size);
+ Ref<ImageTexture> resized_folder = Ref<ImageTexture>( memnew( ImageTexture));
+ resized_folder->create_from_image(img,0);
+ Theme::get_default()->set_icon("ResizedFolder","EditorIcons",resized_folder);
+ }
+
+ folder_thumbnail = get_icon("ResizedFolder","EditorIcons");
+
+ if (!has_icon("ResizedFile","EditorIcons")) {
+ Ref<ImageTexture> file = get_icon("FileBig","EditorIcons");
+ Image img = file->get_data();
+ img.resize(thumbnail_size,thumbnail_size);
+ Ref<ImageTexture> resized_file = Ref<ImageTexture>( memnew( ImageTexture));
+ resized_file->create_from_image(img,0);
+ Theme::get_default()->set_icon("ResizedFile","EditorIcons",resized_file);
+ }
+
+ file_thumbnail = get_icon("ResizedFile","EditorIcons");
+
+ } else {
+
+ files->set_icon_mode(ItemList::ICON_MODE_LEFT);
+ files->set_max_columns(1);
+ files->set_max_text_lines(1);
+ files->set_fixed_column_width(0);
+ files->set_min_icon_size(Size2());
+
}
- String path = sel->get_metadata(0);
- if (ResourceLoader::get_resource_type(path)=="PackedScene") {
- editor->open_request(path);
+ if (path!="res://") {
+
+ if (use_thumbnails) {
+ files->add_item("..",folder_thumbnail,true);
+ } else {
+ files->add_item("..",get_icon("folder","FileDialog"),true);
+ }
+
+ String bd = path.get_base_dir();
+ if (bd!="res://" && !bd.ends_with("/"))
+ bd+="/";
+
+ files->set_item_metadata(files->get_item_count()-1,bd);
+ }
+
+ for(int i=0;i<efd->get_subdir_count();i++) {
+
+ String dname=efd->get_subdir(i)->get_name();
+
+
+ if (use_thumbnails) {
+ files->add_item(dname,folder_thumbnail,true);
+ } else {
+ files->add_item(dname,get_icon("folder","FileDialog"),true);
+ }
+
+ files->set_item_metadata(files->get_item_count()-1,path.plus_file(dname)+"/");
+
+ if (cselection.has(dname))
+ files->select(files->get_item_count()-1,false);
+ }
+
+ for(int i=0;i<efd->get_file_count();i++) {
+
+ String fname=efd->get_file(i);
+ String fp = path.plus_file(fname);
+
+
+ String type = efd->get_file_type(i);
+ Ref<Texture> type_icon;
+
+ if (has_icon(type,"EditorIcons")) {
+ type_icon=get_icon(type,"EditorIcons");
+ } else {
+ type_icon=get_icon("Object","EditorIcons");
+ }
+
+ if (use_thumbnails) {
+ files->add_item(fname,file_thumbnail,true);
+ files->set_item_metadata(files->get_item_count()-1,fp);
+ files->set_item_tag_icon(files->get_item_count()-1,type_icon);
+ EditorResourcePreview::get_singleton()->queue_resource_preview(fp,this,"_thumbnail_done",files->get_item_count()-1);
+ } else {
+ files->add_item(fname,type_icon,true);
+ files->set_item_metadata(files->get_item_count()-1,fp);
+
+ }
+
+ if (cselection.has(fname))
+ files->select(files->get_item_count()-1,false);
+
+ }
+
+
+}
+
+void ScenesDock::_select_file(int p_idx) {
+
+ files->select(p_idx,true);
+ _open_pressed();
+}
+
+void ScenesDock::_go_to_tree() {
+
+ tree->show();
+ files->hide();
+ path_hb->hide();
+ _update_tree();
+ tree->grab_focus();
+ tree->ensure_cursor_is_visible();
+ button_favorite->show();
+ button_fav_up->show();
+ button_fav_down->show();
+ button_open->hide();
+ button_instance->hide();
+ button_open->hide();
+ file_options->hide();
+ tree_mode=true;
+}
+
+void ScenesDock::_go_to_dir(const String& p_dir){
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (da->change_dir(p_dir)==OK) {
+ path=da->get_current_dir();
+ _update_files(false);
+ }
+ current_path->set_text(path);
+ memdelete(da);
+
+
+}
+void ScenesDock::_fs_changed() {
+
+ button_hist_prev->set_disabled(history_pos==0);
+ button_hist_next->set_disabled(history_pos+1==history.size());
+ scanning_vb->hide();
+
+ if (tree_mode) {
+
+ tree->show();
+ button_favorite->show();
+ button_fav_up->show();
+ button_fav_down->show();
+ _update_tree();
+ } else {
+ files->show();
+ path_hb->show();
+ button_instance->show();
+ button_open->show();
+ file_options->show();
+ _update_files(true);
+ }
+
+ set_process(false);
+}
+
+void ScenesDock::_set_scannig_mode() {
+
+ tree->hide();
+ button_favorite->hide();
+ button_fav_up->hide();
+ button_fav_down->hide();
+ button_instance->hide();
+ button_open->hide();
+ file_options->hide();
+ button_hist_prev->set_disabled(true);
+ button_hist_next->set_disabled(true);
+ scanning_vb->show();
+ path_hb->hide();
+ files->hide();
+ set_process(true);
+ if (EditorFileSystem::get_singleton()->is_scanning()) {
+ scanning_progress->set_val(EditorFileSystem::get_singleton()->get_scanning_progress()*100);
+ } else {
+ scanning_progress->set_val(0);
+ }
+
+}
+
+void ScenesDock::_fw_history() {
+
+ if (history_pos<history.size()-1)
+ history_pos++;
+
+ path=history[history_pos];
+
+ if (tree_mode) {
+ _update_tree();
+ tree->grab_focus();
+ tree->ensure_cursor_is_visible();
+ } else {
+ _update_files(false);
+ current_path->set_text(path);
+ }
+
+ button_hist_prev->set_disabled(history_pos==0);
+ button_hist_next->set_disabled(history_pos+1==history.size());
+
+}
+
+void ScenesDock::_bw_history() {
+
+ if (history_pos>0)
+ history_pos--;
+
+ path=history[history_pos];
+
+ if (tree_mode) {
+ _update_tree();
+ tree->grab_focus();
+ tree->ensure_cursor_is_visible();
} else {
+ _update_files(false);
+ current_path->set_text(path);
+ }
+
+ button_hist_prev->set_disabled(history_pos==0);
+ button_hist_next->set_disabled(history_pos+1==history.size());
+
+}
+
+void ScenesDock::_push_to_history() {
- /*
+ history.resize(history_pos+1);
+ if (history[history_pos]!=path) {
+ history.push_back(path);
+ history_pos++;
+ }
+
+ button_hist_prev->set_disabled(history_pos==0);
+ button_hist_next->set_disabled(history_pos+1==history.size());
+
+}
+
+
+void ScenesDock::_find_inside_move_files(EditorFileSystemDirectory *efsd,Vector<String>& files) {
- RES res = ResourceLoader::load(path);
- if (res.is_null()) {
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+ _find_inside_move_files(efsd->get_subdir(i),files);
+ }
+ for(int i=0;i<efsd->get_file_count();i++) {
+ files.push_back(efsd->get_file_path(i));
+ }
+
+}
+void ScenesDock::_find_remaps(EditorFileSystemDirectory *efsd,Map<String,String> &renames,List<String>& to_remaps) {
+ for(int i=0;i<efsd->get_subdir_count();i++) {
+ _find_remaps(efsd->get_subdir(i),renames,to_remaps);
+ }
+ for(int i=0;i<efsd->get_file_count();i++) {
+ Vector<String> deps=efsd->get_file_deps(i);
+ for(int j=0;j<deps.size();j++) {
+ if (renames.has(deps[j])) {
+ to_remaps.push_back(efsd->get_file_path(i));
+ break;
+ }
+ }
+ }
+}
+
+
+void ScenesDock::_rename_operation(const String& p_to_path) {
+
+ if (move_files[0]==p_to_path) {
+ EditorNode::get_singleton()->show_warning("Same source and destination files, doing nothing.");
+ return;
+ }
+ if (FileAccess::exists(p_to_path)) {
+ EditorNode::get_singleton()->show_warning("Target file exists, can't overwrite. Delete first.");
+ return;
+ }
+
+ Map<String,String> renames;
+ renames[move_files[0]]=p_to_path;
+
+ List<String> remap;
+
+ _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(),renames,remap);
+ print_line("found files to remap: "+itos(remap.size()));
+
+ //perform remaps
+ for(List<String>::Element *E=remap.front();E;E=E->next()) {
+
+ Error err = ResourceLoader::rename_dependencies(E->get(),renames);
+ print_line("remapping: "+E->get());
+
+ if (err!=OK) {
+ EditorNode::get_singleton()->add_io_error("Can't rename deps for:\n"+E->get()+"\n");
+ }
+ }
+
+ //finally, perform moves
+
+ DirAccess *da=DirAccess::create(DirAccess::ACCESS_RESOURCES);
+
+ Error err = da->rename(move_files[0],p_to_path);
+ print_line("moving file "+move_files[0]+" to "+p_to_path);
+ if (err!=OK) {
+ EditorNode::get_singleton()->add_io_error("Error moving file:\n"+move_files[0]+"\n");
+ }
+
+ //rescan everything
+ memdelete(da);
+ print_line("call rescan!");
+ _rescan();
+}
+
+
+void ScenesDock::_move_operation(const String& p_to_path) {
+
+ if (p_to_path==path) {
+ EditorNode::get_singleton()->show_warning("Same source and destination paths, doing nothing.");
+ return;
+ }
+
+ //find files inside dirs to be moved
+
+ Vector<String> inside_files;
+
+ for(int i=0;i<move_dirs.size();i++) {
+ if (p_to_path.begins_with(move_dirs[i])) {
+ EditorNode::get_singleton()->show_warning("Can't move directories to within themselves");
return;
- }*/
+ }
- editor->load_resource(path);
+ EditorFileSystemDirectory *efsd=EditorFileSystem::get_singleton()->get_path(move_dirs[i]);
+ if (!efsd)
+ continue;
+ _find_inside_move_files(efsd,inside_files);
}
-// emit_signal("open",path);
+ //make list of remaps
+ Map<String,String> renames;
+ String repfrom=path=="res://"?path:String(path+"/");
+ String repto=p_to_path=="res://"?p_to_path:String(p_to_path+"/");
+
+ for(int i=0;i<move_files.size();i++) {
+ renames[move_files[i]]=move_files[i].replace_first(repfrom,repto);
+ print_line("move file "+move_files[i]+" -> "+renames[move_files[i]]);
+ }
+ for(int i=0;i<inside_files.size();i++) {
+ renames[inside_files[i]]=inside_files[i].replace_first(repfrom,repto);
+ print_line("inside file "+inside_files[i]+" -> "+renames[inside_files[i]]);
+ }
+
+ //make list of files that will be run the remapping
+ List<String> remap;
+ _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(),renames,remap);
+ print_line("found files to remap: "+itos(remap.size()));
+
+ //perform remaps
+ for(List<String>::Element *E=remap.front();E;E=E->next()) {
+
+ Error err = ResourceLoader::rename_dependencies(E->get(),renames);
+ print_line("remapping: "+E->get());
+
+ if (err!=OK) {
+ EditorNode::get_singleton()->add_io_error("Can't rename deps for:\n"+E->get()+"\n");
+ }
+ }
+
+ //finally, perform moves
+
+ DirAccess *da=DirAccess::create(DirAccess::ACCESS_RESOURCES);
+
+ for(int i=0;i<move_files.size();i++) {
+
+ String to = move_files[i].replace_first(repfrom,repto);
+ Error err = da->rename(move_files[i],to);
+ print_line("moving file "+move_files[i]+" to "+to);
+ if (err!=OK) {
+ EditorNode::get_singleton()->add_io_error("Error moving file:\n"+move_files[i]+"\n");
+ }
+ }
+
+ for(int i=0;i<move_dirs.size();i++) {
+
+ String to = p_to_path.plus_file(move_dirs[i].get_file());
+ Error err = da->rename(move_dirs[i],to);
+ print_line("moving dir "+move_dirs[i]+" to "+to);
+ if (err!=OK) {
+ EditorNode::get_singleton()->add_io_error("Error moving dir:\n"+move_dirs[i]+"\n");
+ }
+ }
+
+ memdelete(da);
+ //rescan everything
+ print_line("call rescan!");
+ _rescan();
+
+}
+
+void ScenesDock::_file_option(int p_option) {
+
+ switch(p_option) {
+
+ case FILE_DEPENDENCIES: {
+
+ int idx = files->get_current();
+ if (idx<0 || idx>=files->get_item_count())
+ break;
+ String path = files->get_item_metadata(idx);
+ deps_editor->edit(path);
+ } break;
+ case FILE_OWNERS: {
+
+ int idx = files->get_current();
+ if (idx<0 || idx>=files->get_item_count())
+ break;
+ String path = files->get_item_metadata(idx);
+ owners_editor->show(path);
+ } break;
+ case FILE_MOVE: {
+
+ move_dirs.clear();;
+ move_files.clear();
+
+ for(int i=0;i<files->get_item_count();i++) {
+
+ String path = files->get_item_metadata(i);
+ if (!files->is_selected(i))
+ continue;
+
+ if (files->get_item_text(i)=="..") {
+ EditorNode::get_singleton()->show_warning("Can't operate on '..'");
+ return;
+ }
+
+ if (path.ends_with("/")) {
+ move_dirs.push_back(path.substr(0,path.length()-1));
+ } else {
+ move_files.push_back(path);
+ }
+ }
+
+
+ if (move_dirs.empty() && move_files.size()==1) {
+
+ rename_dialog->clear_filters();
+ rename_dialog->add_filter("*."+move_files[0].extension());
+ rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ rename_dialog->set_current_path(move_files[0]);
+ rename_dialog->popup_centered_ratio();
+ rename_dialog->set_title("Pick New Name and Location For: "+move_files[0].get_file());
+
+
+ } else {
+ //just move
+ move_dialog->popup_centered_ratio();
+ }
+
+
+ } break;
+ case FILE_REMOVE: {
+
+ Vector<String> torem;
+
+ for(int i=0;i<files->get_item_count();i++) {
+
+ String path = files->get_item_metadata(i);
+ if (path.ends_with("/") || !files->is_selected(i))
+ continue;
+ torem.push_back(path);
+ }
+
+ if (torem.empty()) {
+ EditorNode::get_singleton()->show_warning("No files selected!");
+ break;
+ }
+
+ remove_dialog->show(torem);
+ //1) find if used
+ //2) warn
+
+ } break;
+ case FILE_INFO: {
+
+ } break;
+
+ }
}
-void ScenesDock::_save_favorites() {
+void ScenesDock::_open_pressed(){
+
+
+ if (tree_mode) {
+
+ TreeItem *sel = tree->get_selected();
+ if (!sel) {
+ return;
+ }
+ path = sel->get_metadata(0);
+ /*if (path!="res://" && path.ends_with("/")) {
+ path=path.substr(0,path.length()-1);
+ }*/
+
+ tree_mode=false;
+
+ tree->hide();
+ files->show();
+ path_hb->show();
+ button_favorite->hide();
+ button_fav_up->hide();
+ button_fav_down->hide();
+ button_instance->show();
+ button_open->show();
+ file_options->show();
+
+ _update_files(false);
- String path = Globals::get_singleton()->get_resource_path()+"/favorites.cfg";
- FileAccess *f=FileAccess::open(path,FileAccess::WRITE);
- ERR_FAIL_COND(!f);
- for(Set<String>::Element *E=favorites.front();E;E=E->next() ) {
+ current_path->set_text(path);
- CharString utf8f = E->get().utf8();
- f->store_buffer((const uint8_t*)utf8f.get_data(),utf8f.length());
- f->store_8('\n');
+ _push_to_history();
+
+
+ } else {
+
+ int idx=-1;
+ for(int i=0;i<files->get_item_count();i++) {
+ if (files->is_selected(i)) {
+ idx=i;
+ break;
+ }
+ }
+
+ if (idx<0)
+ return;
+
+
+
+ String path = files->get_item_metadata(idx);
+
+ if (path.ends_with("/")) {
+ if (path!="res://") {
+ path=path.substr(0,path.length()-1);
+ }
+ this->path=path;
+ _update_files(false);
+ current_path->set_text(path);
+ _push_to_history();
+ } else {
+
+ if (ResourceLoader::get_resource_type(path)=="PackedScene") {
+
+ editor->open_request(path);
+ } else {
+
+ editor->load_resource(path);
+ }
+ }
}
- f->close();
- memdelete(f);
+// emit_signal("open",path);
+
}
+
void ScenesDock::_rescan() {
+ _set_scannig_mode();
EditorFileSystem::get_singleton()->scan();
+
+}
+
+void ScenesDock::fix_dependencies(const String& p_for_file) {
+ deps_editor->edit(p_for_file);
+}
+
+void ScenesDock::open(const String& p_path) {
+
+
+ String npath;
+ String nfile;
+
+ if (p_path.ends_with("/")) {
+
+ if (p_path!="res://")
+ npath=p_path.substr(0,p_path.length()-1);
+ else
+ npath="res://";
+ } else {
+ nfile=p_path.get_file();
+ npath=p_path.get_base_dir();
+ }
+
+ path=npath;
+
+ if (tree_mode && nfile=="") {
+ _update_tree();
+ tree->grab_focus();
+ tree->call_deferred("ensure_cursor_is_visible");
+ _push_to_history();
+ return;
+ } else if (tree_mode){
+ _update_tree();
+ tree->grab_focus();
+ tree->ensure_cursor_is_visible();
+ _open_pressed();
+ current_path->set_text(path);
+ } else {
+ _update_files(false);
+ _push_to_history();
+ }
+
+ for(int i=0;i<files->get_item_count();i++) {
+
+ String md = files->get_item_metadata(i);
+ if (md==p_path) {
+ files->select(i,true);
+ files->ensure_current_is_visible();
+ break;
+ }
+ }
+
}
void ScenesDock::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_update_tree"),&ScenesDock::_update_tree);
ObjectTypeDB::bind_method(_MD("_rescan"),&ScenesDock::_rescan);
- ObjectTypeDB::bind_method(_MD("_favorites_toggled"),&ScenesDock::_favorites_toggled);
- ObjectTypeDB::bind_method(_MD("_favorite_toggled"),&ScenesDock::_favorite_toggled);
+ ObjectTypeDB::bind_method(_MD("_favorites_pressed"),&ScenesDock::_favorites_pressed);
ObjectTypeDB::bind_method(_MD("_instance_pressed"),&ScenesDock::_instance_pressed);
ObjectTypeDB::bind_method(_MD("_open_pressed"),&ScenesDock::_open_pressed);
- ObjectTypeDB::bind_method(_MD("_save_favorites"),&ScenesDock::_save_favorites);
+
+ ObjectTypeDB::bind_method(_MD("_thumbnail_done"),&ScenesDock::_thumbnail_done);
+ ObjectTypeDB::bind_method(_MD("_select_file"), &ScenesDock::_select_file);
+ ObjectTypeDB::bind_method(_MD("_go_to_tree"), &ScenesDock::_go_to_tree);
+ ObjectTypeDB::bind_method(_MD("_go_to_dir"), &ScenesDock::_go_to_dir);
+ ObjectTypeDB::bind_method(_MD("_change_file_display"), &ScenesDock::_change_file_display);
+ ObjectTypeDB::bind_method(_MD("_fw_history"), &ScenesDock::_fw_history);
+ ObjectTypeDB::bind_method(_MD("_bw_history"), &ScenesDock::_bw_history);
+ ObjectTypeDB::bind_method(_MD("_fs_changed"), &ScenesDock::_fs_changed);
+ ObjectTypeDB::bind_method(_MD("_dir_selected"), &ScenesDock::_dir_selected);
+ ObjectTypeDB::bind_method(_MD("_fav_up_pressed"), &ScenesDock::_fav_up_pressed);
+ ObjectTypeDB::bind_method(_MD("_fav_down_pressed"), &ScenesDock::_fav_down_pressed);
+ ObjectTypeDB::bind_method(_MD("_file_option"), &ScenesDock::_file_option);
+ ObjectTypeDB::bind_method(_MD("_move_operation"), &ScenesDock::_move_operation);
+ ObjectTypeDB::bind_method(_MD("_rename_operation"), &ScenesDock::_rename_operation);
ADD_SIGNAL(MethodInfo("instance"));
ADD_SIGNAL(MethodInfo("open"));
@@ -271,153 +1078,156 @@ ScenesDock::ScenesDock(EditorNode *p_editor) {
HBoxContainer *toolbar_hbc = memnew( HBoxContainer );
add_child(toolbar_hbc);
+ button_hist_prev = memnew( ToolButton );
+ toolbar_hbc->add_child(button_hist_prev);
+ button_hist_prev->set_disabled(true);
+ button_hist_prev->set_tooltip("Previous Directory");
+
+ button_hist_next = memnew( ToolButton );
+ toolbar_hbc->add_child(button_hist_next);
+ button_hist_next->set_disabled(true);
+ button_hist_prev->set_focus_mode(FOCUS_NONE);
+ button_hist_next->set_focus_mode(FOCUS_NONE);
+ button_hist_next->set_tooltip("Next Directory");
+
button_reload = memnew( Button );
button_reload->set_flat(true);
button_reload->connect("pressed",this,"_rescan");
toolbar_hbc->add_child(button_reload);
+ button_reload->set_focus_mode(FOCUS_NONE);
+ button_reload->set_tooltip("Re-Scan Filesystem");
+
+ toolbar_hbc->add_spacer();
+
+ button_fav_up = memnew( ToolButton );
+ button_fav_up->set_flat(true);
+ toolbar_hbc->add_child(button_fav_up);
+ button_fav_up->set_disabled(true);
+ button_fav_up->connect("pressed",this,"_fav_up_pressed");
+ button_fav_up->set_tooltip("Move Favorite Up");
+
+ button_fav_down = memnew( ToolButton );
+ button_fav_down->set_flat(true);
+ toolbar_hbc->add_child(button_fav_down);
+ button_fav_down->set_disabled(true);
+ button_fav_down->connect("pressed",this,"_fav_down_pressed");
+ button_fav_down->set_tooltip("Move Favorite Down");
button_favorite = memnew( Button );
button_favorite->set_flat(true);
button_favorite->set_toggle_mode(true);
- button_favorite->connect("toggled",this,"_favorites_toggled");
+ button_favorite->connect("pressed",this,"_favorites_pressed");
toolbar_hbc->add_child(button_favorite);
+ button_favorite->set_tooltip("Toggle folder status as Favorite");
+
+ button_favorite->set_focus_mode(FOCUS_NONE);
+ button_fav_up->set_focus_mode(FOCUS_NONE);
+ button_fav_down->set_focus_mode(FOCUS_NONE);
- toolbar_hbc->add_spacer();
button_open = memnew( Button );
button_open->set_flat(true);
button_open->connect("pressed",this,"_open_pressed");
toolbar_hbc->add_child(button_open);
+ button_open->hide();
+ button_open->set_focus_mode(FOCUS_NONE);
+ button_open->set_tooltip("Open the selected file.\nOpen as scene if a scene, or as resource otherwise.");
+
button_instance = memnew( Button );
button_instance->set_flat(true);
button_instance->connect("pressed",this,"_instance_pressed");
toolbar_hbc->add_child(button_instance);
+ button_instance->hide();
+ button_instance->set_focus_mode(FOCUS_NONE);
+ button_instance->set_tooltip("Instance the selected scene(s) as child of the selected node.");
+
+
+ file_options = memnew( MenuButton );
+ toolbar_hbc->add_child(file_options);
+ file_options->get_popup()->add_item("Rename or Move",FILE_MOVE);
+ file_options->get_popup()->add_item("Delete",FILE_REMOVE);
+ file_options->get_popup()->add_separator();
+ file_options->get_popup()->add_item("Edit Dependencies",FILE_DEPENDENCIES);
+ file_options->get_popup()->add_item("View Owners",FILE_OWNERS);
+ //file_options->get_popup()->add_item("Info",FILE_INFO);
+ file_options->hide();
+ file_options->set_focus_mode(FOCUS_NONE);
+ file_options->set_tooltip("Miscenaneous options related to resources on disk.");
tree = memnew( Tree );
- tree_filter=memnew( ScenesDockFilter() );
- tree_filter->connect("filter_changed", this, "_update_tree");
- add_child(tree_filter);
+
+ tree->set_hide_root(true);
add_child(tree);
+
tree->set_v_size_flags(SIZE_EXPAND_FILL);
tree->connect("item_edited",this,"_favorite_toggled");
tree->connect("item_activated",this,"_open_pressed");
-
- timer = memnew( Timer );
- timer->set_one_shot(true);
- timer->set_wait_time(2);
- timer->connect("timeout",this,"_save_favorites");
- add_child(timer);
-
+ tree->connect("cell_selected",this,"_dir_selected");
+
+ files = memnew( ItemList );
+ files->set_v_size_flags(SIZE_EXPAND_FILL);
+ files->set_select_mode(ItemList::SELECT_MULTI);
+
+ path_hb = memnew( HBoxContainer );
+ button_back = memnew( ToolButton );
+ path_hb->add_child(button_back);
+ current_path=memnew( LineEdit );
+ current_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ path_hb->add_child(current_path);
+ display_mode = memnew( ToolButton );
+ path_hb->add_child(display_mode);
+ display_mode->set_toggle_mode(true);
+ add_child(path_hb);
+ path_hb->hide();
+
+
+ add_child(files);
+ files->hide();
+
+ scanning_vb = memnew( VBoxContainer );
+ Label *slabel = memnew( Label );
+ slabel->set_text("Scanning Files,\nPlease Wait..");
+ slabel->set_align(Label::ALIGN_CENTER);
+ scanning_vb->add_child(slabel);
+ scanning_progress = memnew( ProgressBar );
+ scanning_vb->add_child(scanning_progress);
+ add_child(scanning_vb);
+ scanning_vb->hide();
+
+
+
+ deps_editor = memnew( DependencyEditor );
+ add_child(deps_editor);
+
+ owners_editor = memnew( DependencyEditorOwners);
+ add_child(owners_editor);
+
+ remove_dialog = memnew( DependencyRemoveDialog);
+ add_child(remove_dialog);
+
+ move_dialog = memnew( EditorDirDialog );
+ add_child(move_dialog);
+ move_dialog->connect("dir_selected",this,"_move_operation");
+ move_dialog->get_ok()->set_text("Move");
+
+ rename_dialog = memnew( EditorFileDialog );
+ rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
+ rename_dialog->connect("file_selected",this,"_rename_operation");
+ add_child(rename_dialog);
updating_tree=false;
+ initialized=false;
-}
-
-ScenesDock::~ScenesDock() {
-
-}
-
-void ScenesDockFilter::_setup_filters() {
-
- filter_option->clear();
- filter_option->add_item("Path");
- filter_option->add_item("Name");
- filter_option->add_item("Folder");
-#if 0
- 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+" )");
- }
-#endif
-}
-
-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();
-}
-
-ScenesDockFilter::FilterOption ScenesDockFilter::get_file_filter() {
- return _current_filter;
-}
-
-void ScenesDockFilter::_file_filter_selected(int p_idx) {
- FilterOption selected = (FilterOption)(filter_option->get_selected());
- if (_current_filter != selected ) {
- _current_filter = selected;
- emit_signal("filter_changed");
- }
-}
-
-void ScenesDockFilter::_notification(int p_what) {
- switch(p_what) {
- case NOTIFICATION_ENTER_TREE: {
- clear_search_button->set_icon(get_icon("CloseHover","EditorIcons"));
- } break;
- }
-}
-
-void ScenesDockFilter::_bind_methods() {
+ history.push_back("res://");
+ history_pos=0;
+ tree_mode=true;
- 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() {
-
- _current_filter = FILTER_PATH;
-
- filter_option = memnew( OptionButton );
- filter_option->set_custom_minimum_size(Size2(60,10));
- filter_option->set_clip_text(true);
- filter_option->connect("item_selected", this, "_file_filter_selected");
- add_child(filter_option);
-
- _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( ToolButton );
- clear_search_button->connect("pressed",this,"_command",make_binds(CMD_CLEAR_FILTER));
- add_child(clear_search_button);
+ScenesDock::~ScenesDock() {
}
diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h
index de7ab51edc..d045124bf7 100644
--- a/tools/editor/scenes_dock.h
+++ b/tools/editor/scenes_dock.h
@@ -36,40 +36,112 @@
#include "scene/gui/tool_button.h"
#include "scene/gui/option_button.h"
#include "scene/gui/box_container.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/item_list.h"
+#include "scene/gui/progress_bar.h"
+
#include "os/dir_access.h"
#include "os/thread.h"
#include "editor_file_system.h"
-
+#include "editor_dir_dialog.h"
+#include "dependency_editor.h"
class EditorNode;
-class ScenesDockFilter;
+
class ScenesDock : public VBoxContainer {
OBJ_TYPE( ScenesDock, VBoxContainer );
+ enum FileMenu {
+ FILE_DEPENDENCIES,
+ FILE_OWNERS,
+ FILE_MOVE,
+ FILE_REMOVE,
+ FILE_REIMPORT,
+ FILE_INFO
+ };
+
+
+ VBoxContainer *scanning_vb;
+ ProgressBar *scanning_progress;
+
EditorNode *editor;
Set<String> favorites;
Button *button_reload;
Button *button_instance;
Button *button_favorite;
+ Button *button_fav_up;
+ Button *button_fav_down;
Button *button_open;
- Timer *timer;
+ Button *button_back;
+ Button *display_mode;
+ Button *button_hist_next;
+ Button *button_hist_prev;
+ LineEdit *current_path;
+ HBoxContainer *path_hb;
+
+ MenuButton *file_options;
+
+
+ DependencyEditor *deps_editor;
+ DependencyEditorOwners *owners_editor;
+ DependencyRemoveDialog *remove_dialog;
+
+ EditorDirDialog *move_dialog;
+ EditorFileDialog *rename_dialog;
- ScenesDockFilter *tree_filter;
+ Vector<String> move_dirs;
+ Vector<String> move_files;
+
+
+ Vector<String> history;
+ int history_pos;
+
+ String path;
+
+ bool initialized;
bool updating_tree;
- Tree * tree;
+ Tree * tree; //directories
+ ItemList *files;
+
+ bool tree_mode;
+
+ void _go_to_tree();
+ void _go_to_dir(const String& p_dir);
+ void _select_file(int p_idx);
+
bool _create_tree(TreeItem *p_parent,EditorFileSystemDirectory *p_dir);
+ void _thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata);
+ void _find_inside_move_files(EditorFileSystemDirectory *efsd,Vector<String>& files);
+ void _find_remaps(EditorFileSystemDirectory *efsd,Map<String,String> &renames,List<String>& to_remaps);
+
+ void _rename_operation(const String& p_to_path);
+ void _move_operation(const String& p_to_path);
+
+
+ void _file_option(int p_option);
+ void _update_files(bool p_keep_selection);
+ void _change_file_display();
+ void _fs_changed();
+ void _fw_history();
+ void _bw_history();
+ void _push_to_history();
+
+ void _fav_up_pressed();
+ void _fav_down_pressed();
+ void _dir_selected();
void _update_tree();
void _rescan();
- void _favorites_toggled(bool);
- void _favorite_toggled();
+ void _set_scannig_mode();
+
+ void _favorites_pressed();
void _instance_pressed();
void _open_pressed();
- void _save_favorites();
+
protected:
void _notification(int p_what);
@@ -77,48 +149,14 @@ protected:
public:
String get_selected_path() const;
+ void open(const String& p_path);
+
+ void fix_dependencies(const String& p_for_file);
+
ScenesDock(EditorNode *p_editor);
~ScenesDock();
};
-class ScenesDockFilter : public HBoxContainer {
-
- OBJ_TYPE( ScenesDockFilter, HBoxContainer );
-
-private:
- friend class ScenesDock;
-
- enum Command {
- CMD_CLEAR_FILTER,
- };
-
- Tree *tree;
- OptionButton *filter_option;
- LineEdit *search_box;
- ToolButton *clear_search_button;
-
- enum FilterOption {
- FILTER_PATH, // NAME or Folder
- FILTER_NAME,
- FILTER_FOLDER,
- };
- FilterOption _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:
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- String get_search_term();
- FilterOption get_file_filter();
- ScenesDockFilter();
-};
#endif // SCENES_DOCK_H
diff --git a/tools/editor/spatial_editor_gizmos.h b/tools/editor/spatial_editor_gizmos.h
index 8d6730e2f1..02f60db7f8 100644
--- a/tools/editor/spatial_editor_gizmos.h
+++ b/tools/editor/spatial_editor_gizmos.h
@@ -201,6 +201,8 @@ public:
};
+
+
class SpatialPlayerSpatialGizmo : public SpatialGizmoTool {
OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool);
@@ -214,6 +216,8 @@ public:
};
+
+
class TestCubeSpatialGizmo : public SpatialGizmoTool {
OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool);
diff --git a/tools/html_fs/godot.html b/tools/html_fs/godot.html
new file mode 100644
index 0000000000..36761deb90
--- /dev/null
+++ b/tools/html_fs/godot.html
@@ -0,0 +1,1317 @@
+<!doctype html>
+<html lang="en-us">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>Emscripten-Generated Code</title>
+ <style>
+ body {
+ font-family: arial;
+ margin: 0;
+ padding: none;
+ }
+
+ .emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
+ div.emscripten { text-align: center; }
+ div.emscripten_border { border: 1px solid black; }
+ /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
+ canvas.emscripten { border: 0px none; }
+
+ #emscripten_logo {
+ display: inline-block;
+ margin: 0;
+ }
+
+ .spinner {
+ height: 30px;
+ width: 30px;
+ margin: 0;
+ margin-top: 20px;
+ margin-left: 20px;
+ display: inline-block;
+ vertical-align: top;
+
+ -webkit-animation: rotation .8s linear infinite;
+ -moz-animation: rotation .8s linear infinite;
+ -o-animation: rotation .8s linear infinite;
+ animation: rotation 0.8s linear infinite;
+
+ border-left: 5px solid rgb(235, 235, 235);
+ border-right: 5px solid rgb(235, 235, 235);
+ border-bottom: 5px solid rgb(235, 235, 235);
+ border-top: 5px solid rgb(120, 120, 120);
+
+ border-radius: 100%;
+ background-color: rgb(189, 215, 46);
+ }
+
+ @-webkit-keyframes rotation {
+ from {-webkit-transform: rotate(0deg);}
+ to {-webkit-transform: rotate(360deg);}
+ }
+ @-moz-keyframes rotation {
+ from {-moz-transform: rotate(0deg);}
+ to {-moz-transform: rotate(360deg);}
+ }
+ @-o-keyframes rotation {
+ from {-o-transform: rotate(0deg);}
+ to {-o-transform: rotate(360deg);}
+ }
+ @keyframes rotation {
+ from {transform: rotate(0deg);}
+ to {transform: rotate(360deg);}
+ }
+
+ #status {
+ display: inline-block;
+ vertical-align: top;
+ margin-top: 30px;
+ margin-left: 20px;
+ font-weight: bold;
+ color: rgb(120, 120, 120);
+ }
+
+ #progress {
+ height: 20px;
+ width: 30px;
+ }
+
+ #controls {
+ display: inline-block;
+ float: right;
+ vertical-align: top;
+ margin-top: 30px;
+ margin-right: 20px;
+ }
+
+ #output {
+ width: 100%;
+ height: 200px;
+ margin: 0 auto;
+ margin-top: 10px;
+ display: block;
+ background-color: black;
+ color: white;
+ font-family: 'Lucida Console', Monaco, monospace;
+ outline: none;
+ }
+ </style>
+ </head>
+ <body>
+ <a href="http://emscripten.org">
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?><svg
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ width="296px"
+ height="78px"
+ viewBox="420 120 100 170"
+ enable-background="new 0 0 900 400"
+ xml:space="preserve"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="emscripten_powered_by_logo.svg"><metadata
+ id="metadata345"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs343"><linearGradient
+ y2="247.6265"
+ x2="225.1929"
+ y1="152.499"
+ x1="225.1929"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5104"><stop
+ id="stop5106"
+ style="stop-color:#C1D72F"
+ offset="0.3227531" /><stop
+ id="stop5108"
+ style="stop-color:#BCD631"
+ offset="0.45119295" /><stop
+ id="stop5110"
+ style="stop-color:#AFD136"
+ offset="0.64491969" /><stop
+ id="stop5112"
+ style="stop-color:#ABD037"
+ offset="1" /><a:midPointStop
+ style="stop-color:#C1D72F"
+ offset="0.0123" /><a:midPointStop
+ style="stop-color:#C1D72F"
+ offset="0.3086" /><a:midPointStop
+ style="stop-color:#ABD037"
+ offset="1" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#SVGID_2_"
+ id="linearGradient5120"
+ x1="397.56918"
+ y1="128.12726"
+ x2="397.56918"
+ y2="166.25996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103059,0,0,1.103059,-38.997823,3.1312145)" /><filter
+ inkscape:collect="always"
+ id="filter5126"><feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.56377237"
+ id="feGaussianBlur5128" /></filter><linearGradient
+ inkscape:collect="always"
+ xlink:href="#SVGID_2_"
+ id="linearGradient5134"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103059,0,0,1.103059,-38.997823,3.1312145)"
+ x1="397.56918"
+ y1="128.12726"
+ x2="397.56918"
+ y2="166.25996" /></defs><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1440"
+ inkscape:window-height="838"
+ id="namedview341"
+ showgrid="false"
+ inkscape:zoom="0.63555556"
+ inkscape:cx="224.82424"
+ inkscape:cy="-52.085109"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><g
+ id="g5130"
+ transform="matrix(0.91591318,0,0,0.91591318,28.176953,14.143571)"><path
+ transform="matrix(1.103059,0,0,1.103059,-35.073492,-16.03923)"
+ id="path5122"
+ style="fill:#383838;fill-opacity:0.34705882;stroke:none;filter:url(#filter5126)"
+ d="m 494.39333,173.6323 c 0.57407,0.28703 1.87073,1.00226 2.89426,1.02855 0.55732,0.0143 1.14006,-0.1672 1.60262,-0.4784 1.20466,-0.81046 2.23561,-2.03031 2.72683,-3.39661 0.19424,-0.54027 0.0238,-1.72222 0.0238,-1.72222 l -3.82713,-14.06478 -1.98533,0 0.50231,-2.67891 6.36261,0 2.55939,12.22285 4.78392,-9.68746 -2.00924,0 0,-2.65498 7.19979,0 -11.00301,22.38875 -1.69829,1.91358 -2.29628,1.3395 -2.46371,0.26312 -2.29628,-0.21528 -2.79859,-1.36342 z m -12.0637,-14.56445 c -0.93698,1.88565 -1.70261,4.35262 -0.81842,6.26333 0.36549,0.78976 1.35098,1.19428 2.192,1.41737 0.60934,0.16133 1.29167,0.0999 1.88775,-0.10468 0.48126,-0.1655 0.8829,-0.5224 1.255,-0.8697 0.40341,-0.3768 0.77723,-0.80461 1.03505,-1.29262 0.21864,-0.41395 0.40236,-0.84786 0.49325,-1.30698 0.20667,-1.0485 0.35879,-2.1079 0.33583,-3.17631 -0.0184,-0.87403 -0.0789,-1.87107 -0.47711,-2.64959 -0.26344,-0.51379 -0.77017,-0.71849 -1.33113,-0.85633 -0.42395,-0.10479 -0.81432,-0.0626 -1.21773,0.10517 -0.65479,0.27273 -1.2544,0.5311 -1.82112,0.95764 -0.57331,0.4317 -1.21403,0.86959 -1.53337,1.5127 z m 0.65588,-4.31208 c 0,0 2.19341,-1.80738 3.45549,-2.27082 0.71718,-0.26365 3.45363,-0.65258 4.15,-0.3378 1.47292,0.66633 2.26103,1.57529 2.7222,2.60001 0.46118,1.02472 0.69944,2.59956 0.79701,3.73627 0.13278,1.55027 -0.13682,3.77629 -0.53404,5.74843 -0.30079,1.49256 -1.01883,2.74423 -1.83478,3.92156 -1.06526,1.5373 -1.82382,2.15116 -3.66756,2.46594 -0.98864,0.16889 -1.93845,0.46787 -3.25466,0.0928 -1.4384,-0.40963 -2.35273,-0.81244 -3.39599,-1.63337 -0.72524,-0.57054 -1.16043,-1.54043 -1.16043,-1.54043 l 0,2.82636 -4.8903,0 3.39872,-23.01602 -1.92242,-0.85888 0.0403,-2.38127 7.25847,0.0534 z m -23.77803,2.20447 c 0.29175,1.49273 0.0813,4.83252 -0.86111,6.69751 -0.3062,0.60617 -0.94813,1.32967 -1.55479,1.6983 -1.01515,0.61713 -2.21688,1.21322 -3.3966,1.07639 -0.47944,-0.0541 -0.97036,-0.34348 -1.24383,-0.74151 -0.47686,-0.69328 -0.43621,-1.55032 -0.45448,-2.39198 -0.024,-1.06873 0.13137,-2.23775 0.38272,-3.277 0.18705,-0.7744 0.4229,-1.58254 0.86111,-2.24844 0.39037,-0.59323 0.92628,-1.12617 1.55478,-1.45909 0.54854,-0.29014 1.19695,-0.38467 1.81791,-0.40664 0.63637,-0.0231 1.3031,0.0385 1.88966,0.28704 0.3875,0.16453 0.92361,0.3524 1.00463,0.76542 z m 1.29312,-9.69052 -0.64254,6.12262 c 0,0 -1.68393,-0.96858 -2.605,-1.25148 -0.73032,-0.22434 -1.50312,-0.36654 -2.26624,-0.33838 -0.97069,0.0345 -1.91182,0.22099 -2.81751,0.57088 -0.9185,0.35497 -1.78344,0.94565 -2.49338,1.62792 -0.88025,0.84538 -1.51404,1.90455 -2.02977,3.0106 -0.39653,0.84993 -0.69517,1.75284 -0.87975,2.67232 -0.22875,1.14241 -0.44415,2.38719 -0.43937,3.55197 0.01,1.44865 0.0623,2.89489 0.54092,4.26214 0.25525,0.72907 0.71643,1.40578 1.28572,1.9283 0.56835,0.52207 1.29566,0.87604 2.02935,1.11621 0.41072,0.13491 0.85346,0.17274 1.28579,0.16935 1.00285,-0.01 2.03715,-0.0883 2.97671,-0.43999 0.66497,-0.2489 1.21759,-0.73399 1.79298,-1.1502 0.75304,-0.54475 2.16476,-1.86006 2.16476,-1.86006 l 0,1.62374 -0.5751,0 0,1.48807 6.86709,0 0,-2.84135 -1.92841,0 3.21374,-23.57782 -7.37422,0 0,2.33412 z m -93.60062,7.55781 2.33363,15.57933 6.23084,0 4.04243,-11.34169 1.62654,11.34169 5.88425,0 7.05633,-16.38872 0,-2.0141 -6.1713,0 0,2.82349 1.88966,0 -4.04243,10.16973 -0.74151,0 -1.29167,-12.55773 -5.38194,0 -4.7361,12.50989 -1.55478,-12.94538 -6.86496,0 0,2.82349 z m -12.15,0.72146 c -0.56264,0.0892 -1.03524,0.17358 -1.53086,0.45447 -0.737,0.41808 -1.46132,0.95771 -1.91357,1.67437 -0.44123,0.70048 -0.53204,1.57581 -0.66975,2.39196 -0.1751,1.04003 -0.20064,2.10306 -0.19136,3.15741 0.01,0.81614 -0.0138,1.66577 0.35879,2.39197 0.1904,0.37315 0.52874,0.80945 0.88503,1.02855 0.56015,0.34453 1.06632,0.55494 1.72222,0.598 0.72597,0.0483 1.48801,-0.18852 2.10493,-0.57408 0.59422,-0.37072 1.03334,-0.97401 1.38735,-1.5787 0.46117,-0.78744 0.70905,-1.69257 0.90895,-2.58334 0.20377,-0.90704 0.33579,-1.84565 0.28703,-2.77468 -0.0491,-0.92714 -0.18211,-1.88434 -0.57407,-2.72684 -0.2728,-0.58681 -0.70954,-1.00753 -1.29166,-1.29165 -0.44403,-0.21628 -0.99455,-0.24402 -1.48303,-0.16744 z m -6.62442,-0.73581 c 0.65404,-0.6664 1.4072,-1.25479 2.23273,-1.69161 1.0305,-0.54505 2.16429,-0.92749 3.31518,-1.11604 1.51307,-0.24806 3.09342,-0.2847 4.60036,0 0.88055,0.16632 1.78322,0.44742 2.50307,0.98113 0.77409,0.57312 1.35279,1.40936 1.79291,2.26639 0.42901,0.83457 0.6828,1.77223 0.77798,2.70605 0.16564,1.61985 0.024,3.29135 -0.37201,4.87103 -0.33328,1.33759 -0.88436,2.64754 -1.65745,3.78889 -0.67549,0.99679 -1.52894,1.91262 -2.53721,2.5709 -0.89957,0.58746 -1.9718,0.87641 -3.01035,1.15006 -0.87153,0.22963 -1.77166,0.4095 -2.67235,0.40576 -1.21068,-0.01 -2.47998,-0.0817 -3.58589,-0.57511 -1.09854,-0.48896 -1.89728,-1.32739 -2.60455,-2.30013 -0.61123,-0.83995 -1.02561,-1.59975 -1.31932,-2.87516 -0.2125,-0.9233 -0.40006,-2.19912 -0.37215,-3.14592 0.0335,-1.16537 0.3568,-2.74121 0.83416,-3.80434 0.52547,-1.17098 1.17609,-2.3161 2.07489,-3.2319 z m 94.95184,13.82318 c -2.20516,1.01761 -4.61429,1.69636 -7.02343,1.69636 -5.32726,0 -7.22678,-3.12145 -7.22678,-7.22678 0,-7.1251 4.54685,-11.19645 10.0772,-11.19645 3.7324,0 5.56453,1.69625 5.56453,4.47856 0,4.85189 -5.12329,6.27735 -10.41633,6.82001 0.10168,1.73076 0.81446,3.32485 3.3592,3.32485 1.2218,0 2.88401,-0.37315 4.91982,-1.22099 z m -3.22292,-11.77374 c 0,-0.81423 -0.57695,-1.28891 -1.62876,-1.28891 -1.89988,0 -3.46041,1.66212 -3.96978,4.34287 1.45897,-0.20368 5.59854,-0.91613 5.59854,-3.05396 z m -30.33408,11.77374 c -2.2054,1.01761 -4.61457,1.69636 -7.02371,1.69636 -5.32653,0 -7.22671,-3.12145 -7.22671,-7.22678 0,-7.1251 4.54679,-11.19645 10.07785,-11.19645 3.73175,0 5.56382,1.69625 5.56382,4.47856 0,4.85189 -5.12273,6.27735 -10.41568,6.82001 0.10142,1.73076 0.81422,3.32485 3.35884,3.32485 1.22158,0 2.8842,-0.37315 4.91994,-1.22099 z m -3.22305,-11.77374 c 0,-0.81423 -0.57638,-1.28891 -1.62883,-1.28891 -1.89959,0 -3.46023,1.66212 -3.96971,4.34287 1.4591,-0.20368 5.59854,-0.91613 5.59854,-3.05396 z m -82.36051,20.5268 -0.0679,-0.13571 0.98406,-5.66614 2.10303,-15.16698 c 0.0687,-0.40664 -0.0332,-0.61046 -0.30522,-0.71214 l -1.66259,-0.61111 0.37379,-2.57855 6.78556,0 -0.40663,2.71427 0.10142,0.0335 c 2.0016,-1.86631 4.10566,-3.08743 6.24306,-3.08743 2.91821,0 4.95366,1.86577 4.95366,6.78561 0,4.68241 -1.83206,11.6379 -8.14271,11.6379 -2.20534,0 -3.42694,-0.84825 -4.68256,-1.73039 l -0.74621,5.08917 c -0.0341,0.37361 0.0326,0.50898 0.47457,0.54273 l 3.42697,0.33969 -0.37385,2.5447 -9.0589,0 z m 6.78613,-12.04485 c 0.84787,0.71258 1.96788,1.32305 3.22348,1.32305 2.74798,0 3.76601,-3.86811 3.76601,-6.85368 0,-2.002 -0.47476,-3.32542 -1.76432,-3.32542 -1.35696,0 -3.08763,1.4591 -4.30913,2.54506 z m 81.08934,4.85147 0.33969,-2.54464 1.56064,-0.2038 c 0.47498,-0.0683 0.5429,-0.1695 0.61084,-0.67837 l 1.42466,-10.34864 c 0.0335,-0.37315 -0.0335,-0.61046 -0.33914,-0.71214 l -1.69691,-0.61111 0.37365,-2.57855 6.71797,0 -0.44097,3.05395 0.10191,0.0679 c 1.32326,-1.89982 3.22359,-3.46042 5.39485,-3.46042 0.7463,0 2.0359,0.13582 2.61295,0.30538 l -0.84863,6.17508 -3.96972,-0.13582 -0.10157,-1.76443 c -0.0335,-0.30537 -0.10223,-0.40701 -0.37391,-0.40701 -0.64452,0 -1.69636,0.78027 -2.64651,1.76455 l -1.18674,8.61817 c -0.0687,0.54303 -0.0334,0.64474 0.47477,0.67874 l 3.22351,0.27142 -0.37384,2.51081 -10.8575,0 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cssscccccccccccccccccssssssssccssscssssscsssccccccccsssssssssccsccsssssssssscsscccccccccccccccccccccccccccccccsssscsssssscscsssssssscsssssssssscsssscsccsscscsssscsccsscsccccccccccsssccccccccssscccccccccccccsccccsccccccc" /><path
+ sodipodi:nodetypes="cssscccccccccccccccccssssssssccssscssssscsssccccccccsssssssssccsccsssssssssscsscccccccccccccccccccccccccccccccsssscsssssscscsssssssscsssssssssscsssscsccsscscsssscsccsscsccccccccccsssccccccccssscccccccccccccsccccsccccccc"
+ inkscape:connector-curvature="0"
+ d="m 509.55935,174.26011 c 0.63327,0.31663 2.06355,1.10555 3.19256,1.13455 0.61476,0.0158 1.25757,-0.18443 1.76781,-0.5277 1.3288,-0.89397 2.46618,-2.23946 3.00784,-3.74661 0.21419,-0.59598 0.0258,-1.89972 0.0258,-1.89972 l -4.22153,-15.51428 -2.18993,0 0.55406,-2.95501 7.01835,0 2.82313,13.48255 5.27696,-10.68586 -2.21631,0 0,-2.92858 7.94179,0 -12.13698,24.69605 -1.87332,2.11078 -2.5329,1.4776 -2.71762,0.29022 -2.53295,-0.23748 -3.08699,-1.50392 z m -13.30698,-16.06545 c -1.0335,2.08005 -1.87803,4.80122 -0.90274,6.90883 0.4032,0.87116 1.49018,1.31738 2.4179,1.56347 0.67214,0.17793 1.42477,0.1102 2.08233,-0.11548 0.53084,-0.1826 0.97383,-0.5762 1.38432,-0.9593 0.44502,-0.4157 0.85733,-0.8875 1.14176,-1.42582 0.24113,-0.45665 0.44375,-0.93526 0.54404,-1.44168 0.22797,-1.1566 0.3958,-2.3252 0.37043,-3.50371 -0.0204,-0.96413 -0.0869,-2.06387 -0.52631,-2.92259 -0.29054,-0.56679 -0.84946,-0.79259 -1.46826,-0.94463 -0.46761,-0.11559 -0.89829,-0.0686 -1.34322,0.11597 -0.72226,0.30083 -1.38368,0.5859 -2.00879,1.05634 -0.63242,0.4762 -1.33915,0.9593 -1.69146,1.6686 z m 0.72346,-4.75648 c 0,0 2.41951,-1.99358 3.81169,-2.50482 0.79109,-0.29085 3.80953,-0.71977 4.57766,-0.3726 1.6247,0.73503 2.49408,1.73759 3.00274,2.86791 0.50868,1.13043 0.77154,2.86756 0.87911,4.12137 0.14648,1.71007 -0.15092,4.16549 -0.58904,6.34083 -0.33179,1.64636 -1.12383,3.02703 -2.02388,4.32576 -1.17506,1.6957 -2.01178,2.37286 -4.04556,2.72004 -1.09051,0.18629 -2.13814,0.51607 -3.59006,0.10268 -1.5866,-0.45183 -2.59522,-0.89615 -3.74599,-1.8017 -0.79994,-0.62933 -1.28003,-1.6992 -1.28003,-1.6992 l 0,3.11766 -5.39426,0 3.74898,-25.38802 -2.12052,-0.94738 0.0443,-2.62669 8.00657,0.0587 z m -26.22853,2.43167 c 0.32185,1.64663 0.0893,5.33062 -0.9498,7.38781 -0.33781,0.66857 -1.04588,1.46667 -1.7151,1.8733 -1.11975,0.68073 -2.44527,1.33822 -3.7466,1.18729 -0.52883,-0.0601 -1.07036,-0.37888 -1.37203,-0.81791 -0.52601,-0.76478 -0.48121,-1.71012 -0.50128,-2.63848 -0.0263,-1.17893 0.14487,-2.46835 0.42212,-3.6147 0.20635,-0.8543 0.4665,-1.74564 0.94981,-2.48024 0.43067,-0.65433 1.02178,-1.24217 1.71508,-1.60939 0.60504,-0.32004 1.32025,-0.42437 2.00521,-0.44854 0.70197,-0.0251 1.4374,0.0425 2.08446,0.31654 0.4274,0.18153 1.01882,0.3888 1.10813,0.84432 z m 1.42642,-10.68922 -0.70874,6.75362 c 0,0 -1.85753,-1.06838 -2.8735,-1.38048 -0.80562,-0.24744 -1.65802,-0.40424 -2.49984,-0.37318 -1.07069,0.0382 -2.10882,0.24369 -3.1078,0.62968 -1.01321,0.39157 -1.96724,1.04315 -2.75039,1.79572 -0.97095,0.93248 -1.67003,2.10085 -2.23897,3.3208 -0.43738,0.93753 -0.76677,1.93354 -0.9704,2.94777 -0.2523,1.26016 -0.4899,2.63324 -0.48461,3.91802 0.011,1.59795 0.0683,3.19329 0.59661,4.70144 0.28155,0.80417 0.79028,1.55058 1.41822,2.127 0.62695,0.57587 1.4292,0.96634 2.23856,1.23121 0.45301,0.14881 0.94135,0.19054 1.41828,0.18685 1.10615,-0.011 2.24705,-0.0973 3.28346,-0.48539 0.73352,-0.2745 1.34304,-0.80959 1.97773,-1.2687 0.83064,-0.60085 2.38786,-2.05176 2.38786,-2.05176 l 0,1.79104 -0.63429,0 0,1.64147 7.57478,0 0,-3.13415 -2.12721,0 3.54494,-26.00772 -8.13411,0 0,2.57462 z m -103.24702,8.33671 2.57413,17.18493 6.87304,0 4.45903,-12.51049 1.79414,12.51049 6.49065,0 7.78353,-18.07772 0,-2.2217 -6.8073,0 0,3.11449 2.08446,0 -4.45903,11.21783 -0.8179,0 -1.42488,-13.85193 -5.93654,0 -5.2242,13.79919 -1.71497,-14.27958 -7.57246,0 0,3.11449 z m -13.4021,0.79586 c -0.62064,0.0982 -1.14194,0.19148 -1.68866,0.50127 -0.813,0.46118 -1.61192,1.05641 -2.11077,1.84697 -0.48673,0.77268 -0.58683,1.73821 -0.73875,2.63846 -0.1932,1.14723 -0.22134,2.31976 -0.21116,3.48281 0.011,0.90024 -0.0148,1.83747 0.39579,2.63847 0.21,0.41165 0.58324,0.89285 0.97623,1.13455 0.61796,0.38003 1.17622,0.61214 1.89972,0.6596 0.80077,0.0533 1.64141,-0.20792 2.32189,-0.63318 0.65546,-0.40892 1.13978,-1.07441 1.53029,-1.7414 0.50878,-0.86864 0.78215,-1.86707 1.00265,-2.84964 0.22477,-1.00044 0.37039,-2.03585 0.31663,-3.06058 -0.0541,-1.02274 -0.20091,-2.07854 -0.63327,-3.00784 -0.3009,-0.64731 -0.78264,-1.11143 -1.42476,-1.42485 -0.48983,-0.23858 -1.09705,-0.26912 -1.63583,-0.18464 z m -7.30711,-0.81171 c 0.72143,-0.735 1.55219,-1.38409 2.46282,-1.86591 1.1367,-0.60125 2.38729,-1.02309 3.65678,-1.23104 1.66908,-0.27366 3.41222,-0.314 5.07446,0 0.97135,0.18342 1.96702,0.49352 2.76107,1.08223 0.85389,0.63222 1.49219,1.55466 1.97771,2.49999 0.47321,0.92057 0.7531,1.95483 0.85808,2.98495 0.18274,1.78675 0.0263,3.63055 -0.41031,5.37303 -0.36757,1.47539 -0.97545,2.92034 -1.82825,4.17929 -0.74509,1.09959 -1.68654,2.10982 -2.79871,2.8359 -0.99227,0.64796 -2.175,0.96671 -3.32055,1.26856 -0.96139,0.25333 -1.95426,0.4517 -2.94774,0.44756 -1.33549,-0.011 -2.73559,-0.0897 -3.9555,-0.63431 -1.21174,-0.53936 -2.09278,-1.46419 -2.87295,-2.53723 -0.67423,-0.92645 -1.13131,-1.76457 -1.45532,-3.17146 -0.2344,-1.0184 -0.44126,-2.42572 -0.41044,-3.47012 0.0365,-1.28547 0.39349,-3.02371 0.92005,-4.19644 0.57967,-1.29168 1.29729,-2.5548 2.2888,-3.565 z m 104.73744,15.24778 c -2.43247,1.12251 -5.0899,1.87126 -7.74734,1.87126 -5.87626,0 -7.97147,-3.44315 -7.97147,-7.97158 0,-7.8594 5.0154,-12.35035 11.11569,-12.35035 4.11711,0 6.13803,1.87105 6.13803,4.94016 0,5.35189 -5.65129,6.92425 -11.48983,7.52281 0.11219,1.90916 0.89836,3.66755 3.7054,3.66755 1.3477,0 3.18121,-0.41165 5.42682,-1.34689 z m -3.55513,-12.98704 c 0,-0.89823 -0.63635,-1.42181 -1.79655,-1.42181 -2.09568,0 -3.81712,1.83342 -4.37899,4.79047 1.60937,-0.22468 6.17554,-1.01053 6.17554,-3.36866 z m -33.46028,12.98704 c -2.4327,1.12251 -5.09006,1.87126 -7.74751,1.87126 -5.87553,0 -7.97151,-3.44315 -7.97151,-7.97158 0,-7.8594 5.01539,-12.35035 11.11645,-12.35035 4.11635,0 6.13722,1.87105 6.13722,4.94016 0,5.35189 -5.65062,6.92425 -11.48908,7.52281 0.11182,1.90916 0.89812,3.66755 3.70494,3.66755 1.34748,0 3.1815,-0.41165 5.42704,-1.34689 z m -3.55514,-12.98704 c 0,-0.89823 -0.63578,-1.42181 -1.79674,-1.42181 -2.09539,0 -3.81683,1.83342 -4.37881,4.79047 1.60951,-0.22468 6.17555,-1.01053 6.17555,-3.36866 z m -90.84852,22.6422 -0.0749,-0.14971 1.08546,-6.25004 2.31984,-16.73008 c 0.0757,-0.44854 -0.0367,-0.67336 -0.33673,-0.78554 l -1.83388,-0.67411 0.41228,-2.84425 7.48486,0 -0.44853,2.99397 0.11182,0.0371 c 2.2079,-2.05871 4.52887,-3.40563 6.88646,-3.40563 3.21901,0 5.46427,2.05807 5.46427,7.48491 0,5.16501 -2.02094,12.8373 -8.98192,12.8373 -2.43264,0 -3.78014,-0.93565 -5.16516,-1.90869 l -0.82311,5.61357 c -0.0376,0.41212 0.0356,0.56148 0.52347,0.59873 l 3.78017,0.37469 -0.41234,2.8069 -9.9925,0 z m 7.48553,-13.28615 c 0.93528,0.78598 2.17068,1.45946 3.55568,1.45946 3.03118,0 4.15411,-4.26682 4.15411,-7.56009 0,-2.2083 -0.52366,-3.66812 -1.94612,-3.66812 -1.49686,0 -3.40583,1.6095 -4.75323,2.80736 z m 89.44624,5.35147 0.37469,-2.80694 1.72154,-0.2248 c 0.52388,-0.0753 0.5988,-0.1869 0.67374,-0.74827 l 1.57152,-11.41514 c 0.0365,-0.41155 -0.0368,-0.67336 -0.3741,-0.78554 l -1.87181,-0.67411 0.41215,-2.84425 7.41037,0 -0.48647,3.36865 0.11241,0.0749 c 1.45966,-2.09562 3.55581,-3.81702 5.95085,-3.81702 0.8232,0 2.2457,0.14982 2.88225,0.33688 l -0.93613,6.81148 -4.37882,-0.14982 -0.11196,-1.94633 c -0.0371,-0.33677 -0.11284,-0.44891 -0.41252,-0.44891 -0.71092,0 -1.87116,0.86067 -2.91921,1.94635 l -1.30904,9.50637 c -0.0757,0.59903 -0.0368,0.71124 0.52367,0.74874 l 3.55571,0.29932 -0.41234,2.76961 -11.9765,0 z"
+ style="fill:url(#linearGradient5134);fill-opacity:1;stroke:none"
+ id="path5080" /></g><path
+ fill="#E2E2E2"
+ d="M256.023,135.437H196.36c-16.432,0-29.8,13.368-29.8,29.8v73.527c0,16.432,13.368,29.8,29.8,29.8h59.663 c16.433,0,29.801-13.368,29.801-29.8v-73.527C285.824,148.805,272.456,135.437,256.023,135.437z M191.561,165.236 c0-2.646,2.153-4.8,4.8-4.8h59.663c2.647,0,4.801,2.153,4.801,4.8v73.527c0,2.646-2.153,4.8-4.801,4.8H196.36 c-2.646,0-4.8-2.153-4.8-4.8V165.236z"
+ id="path3" /><path
+ d="m 531.664,250.155 h 18.498 l -2.809,18.064 h 5.59 37.586 l 2.6,-17.718 c 4.98,-1.091 9.133,-3.455 12.512,-6.693 3.084,4.075 8.566,7.37 18.252,7.37 6.338,0 12.775,-1.807 17.174,-3.687 4.254,2.399 9.463,3.687 15.459,3.687 3.088,0 6.236,-0.355 9.426,-1.023 h 67.135 l 3.354,-24.827 -5.445,-0.764 1.879,-13.356 c 0.371,-2.386 0.449,-4.66 0.449,-6.156 l -0.008,-0.375 c -0.457,-12.191 -8.139,-19.765 -20.045,-19.765 -2.404,0 -4.623,0.314 -6.676,0.852 h -34.189 l -0.035,0.244 c -2.527,-0.701 -5.41,-1.096 -8.686,-1.096 -3.801,0 -7.406,0.555 -10.76,1.598 l 0.105,-0.746 h -12.467 l 1.826,-12.951 H 615.08 l -1.846,7.658 c -1.373,5.704 -2.213,5.793 -4.453,6.03 l -4.508,0.477 c -3.049,-1.424 -6.357,-2.065 -9.602,-2.065 -2.135,0 -4.275,0.284 -6.416,0.852 h -19.291 c 0.502,-1.772 0.775,-3.674 0.775,-5.678 0,-9.601 -6.846,-16.305 -16.646,-16.305 -11.055,0 -18.775,7.721 -18.775,18.776 0,0.951 0.082,1.869 0.219,2.764 -2.135,-0.288 -4.277,-0.409 -5.553,-0.409 -2.053,0 -4.072,0.288 -6.045,0.852 h -31.342 c -2.74,-0.553 -5.641,-0.852 -8.537,-0.852 -7.138,0 -13.492,1.674 -18.808,4.723 l -3.451,-1.461 c -3.711,-1.571 -11.232,-3.262 -18.979,-3.262 -8.933,0 -16.383,2.56 -21.576,7.016 -3.265,-4.473 -8.523,-7.016 -15.228,-7.016 -4.822,0 -9.021,1.477 -12.572,3.44 -2.996,-2.204 -6.796,-3.44 -11.115,-3.44 -2.327,0 -4.48,0.315 -6.476,0.852 h -33.963 l -0.035,0.245 c -2.526,-0.702 -5.41,-1.097 -8.687,-1.097 -20.458,0 -35.307,16.031 -35.307,38.117 0,17.363 10.785,28.149 28.148,28.149 3.087,0 6.236,-0.356 9.426,-1.023 h 88.816 c 3.706,0.676 7.669,1.023 11.154,1.023 8.907,0 16.278,-2.375 21.51,-6.593 4.872,4.252 11.585,6.593 19.728,6.593 3.053,0 6.206,-0.368 9.286,-1.023 h 44.664 2.069 z"
+ id="path5"
+ inkscape:connector-curvature="0"
+ style="fill:#e2e2e2" /><path
+ fill="#F5F5F5"
+ d="M255.023,133.437H195.36c-16.432,0-29.8,13.368-29.8,29.8v73.527c0,16.432,13.368,29.8,29.8,29.8h59.663 c16.433,0,29.801-13.368,29.801-29.8v-73.527C284.824,146.805,271.456,133.437,255.023,133.437z M190.561,163.236 c0-2.646,2.153-4.8,4.8-4.8h59.663c2.647,0,4.801,2.153,4.801,4.8v73.527c0,2.646-2.153,4.8-4.801,4.8H195.36 c-2.646,0-4.8-2.153-4.8-4.8V163.236z"
+ id="path7" /><g
+ id="g9"><g
+ id="g11"><path
+ fill="#FBFDF8"
+ d="M195.361,251.626c-8.161,0-14.8-6.64-14.8-14.8v-73.527c0-8.161,6.639-14.8,14.8-14.8h59.663 c8.161,0,14.8,6.639,14.8,14.8v73.527c0,8.16-6.639,14.8-14.8,14.8H195.361z"
+ id="path13" /><path
+ fill="#F0F4E1"
+ d="M255.024,152.499c5.964,0,10.8,4.835,10.8,10.8v73.527c0,5.965-4.835,10.8-10.8,10.8h-59.663 c-5.964,0-10.8-4.835-10.8-10.8v-73.527c0-5.964,4.835-10.8,10.8-10.8H255.024 M255.024,144.499h-59.663 c-10.366,0-18.8,8.434-18.8,18.8v73.527c0,10.366,8.434,18.8,18.8,18.8h59.663c10.366,0,18.8-8.434,18.8-18.8v-73.527 C273.824,152.933,265.391,144.499,255.024,144.499L255.024,144.499z"
+ id="path15" /></g><defs
+ id="defs17"><filter
+ id="Adobe_OpacityMaskFilter"
+ filterUnits="userSpaceOnUse"
+ x="176.562"
+ y="144.499"
+ width="97.263"
+ height="111.127"><feColorMatrix
+ type="matrix"
+ values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
+ color-interpolation-filters="sRGB"
+ result="source"
+ id="feColorMatrix20" /></filter></defs><mask
+ maskUnits="userSpaceOnUse"
+ x="176.562"
+ y="144.499"
+ width="97.263"
+ height="111.127"
+ id="SVGID_1_"><g
+ filter="url(#Adobe_OpacityMaskFilter)"
+ id="g23"><image
+ overflow="visible"
+ width="422"
+ height="480"
+ xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEBLAEsAAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA EAMCAwYAAAg2AAAQ4QAAF1b/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAeMBqQMBIgACEQEDEQH/ xACjAAEAAgMBAQAAAAAAAAAAAAAABQYBAwQHAgEBAQAAAAAAAAAAAAAAAAAAAAEQAAEDAQQKAwAC AwEAAAAAAAABAwQCMRMUBRBQEjMVJQYWNgcgESEwI5AiMkARAAEBAwsEAQIFAwUBAAAAAAABMQID EFAycqOz0wQ0RaURIXGRIEFRMGEiExRAgRKh0SMzQxUSAQAAAAAAAAAAAAAAAAAAAJD/2gAMAwEA AhEDEQAAANUJsrZYFfFgV8WBXxYEL0ki5fo6GjJuaRuaRuaRuaRuaRuaRuaRuaRuaRuaRuaRuaRu aRuaMHQ5dR3ojnJ9XxYFfFgV8WD0jxf2AodbslbAD6mDhlpLvI/qkuiovZL7CGzNfRCJwQacEGnB Bp0QSdEEnRBJ0QSdEEnRBJ3BBpwQacEHidwQXzPfBA6bBqK5w2nlKVH3iJitt+gAeweP+wFDrdkr Y+vmaN02k6+e3d2Gjo6N0c2zoyaM7xozuGluGluGluGluGluGluGluGluGluGluGluGnG8c/z1YO PVIfJF80xoIGPsfBVVrl6hIrD7+B7B4/7AUOt2StnXaYyxHTJ6ZKvrqb4x9MgAAAAAAAAAAAAAAA DGR8692Dh4pbkIKJscTVNiLdVY1+weP+wFDgJ+JLJORs3XbIc3dGz6ZAAAAAAAAAAAAAAAAAAAPn R0ayMi5uLqv1S51eIT2Dx/2AofB38Ra5uIm6kOzm6o+gAAAAAAAAAAAAAAAAAAAPj7+TkjJWNIOt 2et1WfYPH/YIofH2cZcJyEnKkenn6IyAAAAAAAAAAAAAAAAAAABjODmjZONIWt2WtVWPYPH/AGCK Hx9nIXGcg5ypLfo3xkAAAAAAAAAAAAAAAAAAADGcHPGyUaQ1astaqseweP8AsEUPk6+QuM7BTtSW 7TujIAAAAAAAAAAAAAAAAAAAGM4OeOkY4hqzZqzVY9g8f9gih8nXyFxnYKdqS3ad0ZAAAAAAAAAA AAAAAAAAAAxnBzx0jHENWbNWarHsHj/sEUPk6+QuM7BTtSW7TujIAAAAAAAAAAAAAAAAAAAGM4Oe OkY4hqzZqzVY9g8f9gih8nXyFxnYKdqS3ad0ZAAAAAAAAAAAAAAAAAAAAxnBzx0jHENWbNWarHsH j/sEUPk6+QuM7BTtSW7TujIAAAAAAAAAAAAAAAAAAAGM4OeOkY4hqzZqzVY9g8f9gih8nXyFxnYK dqS3ad0ZAAAAAAAAAAAAAAAAAAAAxnBzx0jHENWbNWarHsHj/sEUPk6+QuM7BTtSW7TujIAAAAAA AAAAAAAAAAAAAGM4OeOkY4hqzZqzVY9g8f8AYIofJ18hcZ2Cnakt2ndGQAAAAAAAAAAAAAAAAAAA MZwc8dIxxDVmzVmqx7B4/wCwRQ+Tr5C4zsFO1JbtO6MgAAAAAAAAAAAAAAAAAAAYzg546RjiGrNm rNVj2Dx/2CKHydfIXGdgp2pLdp3RkAAAAAAAAAAAAAAAAAAADGcHPHSMcQ1Zs1ZqseweP+wRQ+Tr 5C4zsFO1JbtO6MgAAAAAAAAAAAAAAAAAAAYzg546RjiGrNmrNVj2Dx/2CKHydfIXGdgp2pLdp3Rk AAAAAAAAAAAAAAAAAAADGcHPHSMcQ1Zs1ZqseweP+wRQ+Tr5C4zsFO1JbtO6MgAAAAAAAAAAAAAA AAAAAYzg546RjiGrNmrNVj2Dx/2CKHydfIXGdgp2pLdp3RkAAAAAAAAAAAAAAAAAAADGcHPHSMcQ 1Zs1ZqseweP+wRQ+Tr4y5TkHOVJb9G+MgAAAAAAAAAAAAAAAAAAAYzg542SjSGrVlrVVj2Dx/wBg ih8fZxlxnIKcqT6ObpjIAAAAAAAAAAAAAAAAAAAGM4OeNkY0h61Za1VY9g8f9gih8Xbwlxm4GbqW 6uLrj7AAAAAAAAAAAAAAAAAAAA+fr5OaNkI0ia1Y61Vb9g8f9gihxknCl1m65N1OdsZ3x0ZxkAAA AAAAAAAAAAAAAAAAx8fek5ozui6jazYKsRPsHj/sEUOu2Ktlqn6XZ6scjBSRLbOPpjYxkAAAAAAA AAAAAAAAAAYfJjm+uM0xXVE1xVOZr0Y9g8f9gKHW7JWz7s1W6i9SdYlasXXB9pLbI7fHY5/s3NeT 7fGT6fI+nyPp8j6fI+nyPp8j6fI+nyPp8j6fI+nyPp8D7x8fJtxp1m7Tp5jbw/MfWIjbXTk5SHsH j/sBQ63ZK2AdthqO8vXbUZWrJ0V/oJ7ZB7Sa+ofJMIkS6IySyJRLIkSyJEsiRLIkSyJEsiRLIkSy JVLYiRLYicEr8xfwSemN0kjy8PIdkfxQp0xWEAPYPH/YCh1uyVsAAz08ome2si37qZkumaULspIu 2aRkuyki7KSLspIuyki7KSLspIuyki7KSLtilC6qSLtilC6fNNFu5qz8k7wcI+vkAAHsHj/sBWoQ AAAAAAAAAAAAAAAAAAAAAAAAAHpAf//aAAgBAgABBQD/ACi//9oACAEDAAEFAP8AKL//2gAIAQEA AQUA6w6rz/LM+776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvv qs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qz vvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++qzvvqs776rO++ qzvvqs776rMfLPYHlHyRFUbivuDeUv1FOSVKJkRwE4CcAOAHADgBwA4AcAOAHADgBwA4AcAOAHAD gBwA4AcAOAHADgBwA4AcAOAnARciFyRUK8ndQcgyGxaaqf4fYHlHwRFUjZe68RsqbpGoKIUQkKYY kISEYJDAmBMCYEwJgTAmBMCYEwJgTAmBMCYEwJgTAmBMCYEwJgTAmCQWELCKoSFcNByEhIyxusk5 VVQV0VUL8vYHlGltupyqDlaIMREQaijcUoilMUSKgkZDDIYZDDIYZDDIYZDDIYZDDIYZDDIYZDDI YZDDIYZDDIYZDDIYZDDIYZDDIYZDDIYZDDILGQWKVRSuKORR2KPRCZltDiSYrjFXx9geUaG26nKs vy9KEjxhmONRxuOUMFLAjIjJdF0XRdIXSF0hdF0XRdF0XRdF0XRdF0XRdF0XRdIXSF0hdIXRdCsi sisFTBXHHY49GH4xMhU10y4tTFfw9geUCJ9rlcL6SNHGGBlgbZKGilsShDZQ+kPr/wBX0fSGygtC CtoVNDjI6wPsElgzCGjlLrdTden2B5QZfGvnYbCIkdkYZGmihsSn61ItJXQOtD7JIZJTBm0X6+Hs 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 DNdYwcM11jBwzXWMHDNdYwcM11jBwzXWMHDNdYwcM11jBwzXWMHDP+z/AEd/2MzUhXbvz7H6XVO/ Y7vFJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkpSUpKUlKSlJSkp+le p3d6ndOn4OZqQrt349EOqp0QT9PVfzGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGC9X RVh9/wAjo8nRfnmakK7d+H+LqdVEefTqonYYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBgwYMGDBg wYMGDBeqd/uKip2+/wAszUhXbsqOutURVT9SidhgwYMlZ/XsGDBgvYVFQVOnb6fHM1IV27J0QR95 O6idhOwyaWC9hU6d/oK6v0+GZqQrt2RFVOyCdhBJrUU/cRO6N+GZqQrt06CL07qIJNiijydGjzsu ZqQrt0dd/MRBBJsUUU/y+8uZqQrt06/YQQSbFFFOv2WXM1IV26KIJNyij0uZqQrt0e8iCTcoo/Lm akK7dHvIggk2KKKPy5mpCu3R7yIJNyij8uZqQrt0e8iCTcoo/LmakK7dHvIgk3KKPy5mpCu3R7yI JNyij8uZqQrt0e8iCTaooo/LmakK7dHvIgk3KKPy5mpCu3R7yIJNyij8uZqQrt0e8iCCTaoo/Lma kK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7y IIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo /LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu 3R7yIIJNqij8uZqQrt0e8iCCTaoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCC Taoo/LmakK7dHvIggk2qKPy5mpCu3R7yIIJNqij8uZqQrt0e8iCTcoo/LmakK7dHvIgk2qKKPy5m pCu3R7yIJNyij8uZqQrt0e8iCTcoo/LmakK7dHvIgk3KKPy5mpCu3R7yIJNyij8uZqQrt0e8iCCT aoo/LmakK7dHvIgk3KKPy5mpCu3R4QSblFHpczUhXboqfcQQSbVFFT7y5mpCu3RPzEEEmxRRRHZc zUhXbojyfRR1RBJsUUUX7JLmakK7dk/bVfAgk2KKL37qwVV+suZqQrt2RHk+giook2L3F7i9GJ8M zUhXbsqItFRFRRO40aNmVo0aL3FhuL5+OZqQrt34I69REVFGjRo0aNGjf6po0aNGjRo0XuK5DXv9 zqrV+OZqQrt349UXt9hEVeijRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRo0Xq9/YVH V6OnVflmakK7d+XVOw3qh0e7FM7PJ7KQ0aNGjRo0aNGjRo0aNGjRo0aNGjRo0aNGjRpSKaH6V6nR 3sh1eXr+BmakK7d/C7KqFJfZTX2U19lNfZTX2U19lN72U3vZTe9lN72U3vZTe9lN72U3vZTe9lN7 2U3vZTe9lN72U3vZTe9lN72U3vZTe9lN72U19lNfZTX2U19lNfZSX2d3l/Ej/wAj/wCf+7/jD6/y f5/7tBOnX+L/AMfr+5tPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPK m08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptP Km08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKm08qbTyptPKn/jan//Z"
+ transform="matrix(0.24 0 0 0.24 174.5615 142.499)"
+ id="image25"></image></g></mask><g
+ opacity="0.09"
+ mask="url(#SVGID_1_)"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ id="g27"><path
+ fill="#1D2915"
+ a:adobe-blending-mode="normal"
+ a:adobe-opacity-share="0"
+ d="M195.361,251.626 c-8.161,0-14.8-6.64-14.8-14.8v-73.527c0-8.161,6.639-14.8,14.8-14.8h59.663c8.161,0,14.8,6.639,14.8,14.8v73.527 c0,8.16-6.639,14.8-14.8,14.8H195.361z"
+ id="path29" /><path
+ fill="#1D2915"
+ a:adobe-blending-mode="normal"
+ a:adobe-opacity-share="0"
+ d="M255.024,152.499 c5.964,0,10.8,4.835,10.8,10.8v73.527c0,5.965-4.835,10.8-10.8,10.8h-59.663c-5.964,0-10.8-4.835-10.8-10.8v-73.527 c0-5.964,4.835-10.8,10.8-10.8H255.024 M255.024,144.499h-59.663c-10.366,0-18.8,8.434-18.8,18.8v73.527 c0,10.366,8.434,18.8,18.8,18.8h59.663c10.366,0,18.8-8.434,18.8-18.8v-73.527C273.824,152.933,265.391,144.499,255.024,144.499 L255.024,144.499z"
+ id="path31" /></g></g><g
+ id="g33"><g
+ id="g35"><linearGradient
+ id="SVGID_2_"
+ gradientUnits="userSpaceOnUse"
+ x1="225.1929"
+ y1="152.499"
+ x2="225.1929"
+ y2="247.6265"><stop
+ offset="0.0123"
+ style="stop-color:#C1D72F"
+ id="stop38" /><stop
+ offset="0.1394"
+ style="stop-color:#BCD631"
+ id="stop40" /><stop
+ offset="0.5859"
+ style="stop-color:#AFD136"
+ id="stop42" /><stop
+ offset="1"
+ style="stop-color:#ABD037"
+ id="stop44" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#C1D72F" /><a:midPointStop
+ offset="0.3086"
+ style="stop-color:#C1D72F" /><a:midPointStop
+ offset="1"
+ style="stop-color:#ABD037" /></linearGradient><path
+ d="M184.562,236.826c0,5.965,4.835,10.8,10.8,10.8h59.663c5.964,0,10.8-4.835,10.8-10.8v-73.527 c0-5.964-4.835-10.8-10.8-10.8h-59.663c-5.964,0-10.8,4.835-10.8,10.8V236.826z"
+ id="path46"
+ fill="url(#SVGID_2_)" /></g><defs
+ id="defs48"><filter
+ id="Adobe_OpacityMaskFilter_1_"
+ filterUnits="userSpaceOnUse"
+ x="184.562"
+ y="152.499"
+ width="81.263"
+ height="95.127"><feColorMatrix
+ type="matrix"
+ values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0"
+ color-interpolation-filters="sRGB"
+ result="source"
+ id="feColorMatrix51" /></filter></defs><mask
+ maskUnits="userSpaceOnUse"
+ x="184.562"
+ y="152.499"
+ width="81.263"
+ height="95.127"
+ id="SVGID_3_"><g
+ filter="url(#Adobe_OpacityMaskFilter_1_)"
+ id="g54"><image
+ overflow="visible"
+ width="356"
+ height="414"
+ xlink:href="data:image/jpeg;base64,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 zFhO7bfhcyUttpzKJlCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZ RMoUbMWE7tt+FzJS22nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzKJlCjZiwndtvwuZK W205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZRMoUbMWE7tt+FzJS22nMomUKNmLCd22 /C5kpbbTmUTKFGzFhO7bfhcyUttpzKJlCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2Y sJ3bb8LmSlttOZRMoUbMWE7tt+FzJS22nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzKJ lCjZiwndtvwuZKW205lEyhRsxYTu234XMlLbacyiZQo2YsJ3bb8LmSlttOZRMoUbMWE7tt+FzJS2 2nMomUKNmLCd22/C5kpbbTmUTKFGzFhO7bfhcyUttpzCZQo38SwndtvwuZKW20dTVfvQQ+cmUXiI xFhxUsJ3bb8LmSlttGVPp8/C/go1fkTjky8RyqsB9T6KvD8CwndtvwuZKW23BKNR3wqftX+qCcRO JwyLiLxF4i0Ka8V/cuFhO7bfhcyUttuCKi/CpBRtOs74cnBF/qJ+oiRIkSJEiRIkSJEiRIkSJEiR IkSJEiRIkSJEiRIkReIv6hadFfl31d9EFc5flViuFhO7bfhcyUttv2ERrvzNT/VT4qIrf+TqIdVD qodVDqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTqpqdVNTq pqdVNTqpqdVNTqpqdVDqodVDqC/xorl0F/O74av+qfYsJ3bb8LmSlttyywndtvzD/9k="
+ transform="matrix(0.24 0 0 0.24 182.5615 150.499)"
+ id="image56"></image></g></mask><g
+ opacity="0.35"
+ mask="url(#SVGID_3_)"
+ a:adobe-opacity-share="1"
+ id="g58"><path
+ a:adobe-opacity-share="0"
+ d="M184.562,236.826c0,5.965,4.835,10.8,10.8,10.8h59.663 c5.964,0,10.8-4.835,10.8-10.8v-73.527c0-5.964-4.835-10.8-10.8-10.8h-59.663c-5.964,0-10.8,4.835-10.8,10.8V236.826z"
+ id="path60"
+ fill="#1D2915" /></g></g><linearGradient
+ id="SVGID_4_"
+ gradientUnits="userSpaceOnUse"
+ x1="226.1924"
+ y1="159.7139"
+ x2="226.1924"
+ y2="200"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop63" /><stop
+ offset="0.3788"
+ style="stop-color:#F8FBF3"
+ id="stop65" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop67" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.4383"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></linearGradient><polygon
+ fill="url(#SVGID_4_)"
+ points="221.189,159.714 214.142,180.951 224.048,180.951 214.142,200 238.243,173.61 227.655,173.61 236.978,159.714 "
+ id="polygon69" /><g
+ id="g71"><g
+ id="g73"><g
+ id="g75"><image
+ overflow="visible"
+ opacity="0.75"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="392"
+ height="242"
+ xlink:href="data:image/png;base64,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 SUVORK5CYII="
+ transform="matrix(0.24 0 0 0.24 179.2061 198.1514)"
+ id="image77"></image><g
+ id="g79"><radialGradient
+ id="SVGID_5_"
+ cx="225.1929"
+ cy="226.1387"
+ r="30.8299"
+ gradientTransform="matrix(1 0 0 0.75 0 56.5347)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop82" /><stop
+ offset="0.4828"
+ style="stop-color:#FDFEFB"
+ id="stop84" /><stop
+ offset="0.7611"
+ style="stop-color:#F8FBF3"
+ id="stop86" /><stop
+ offset="0.989"
+ style="stop-color:#F2F8E8"
+ id="stop88" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop90" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.8025"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><path
+ fill="url(#SVGID_5_)"
+ d="M186.706,235.825c0,5.965,4.835,10.801,10.799,10.801h55.374c5.965,0,10.801-4.836,10.801-10.801 v-19.373c0-5.965-4.836-10.801-10.801-10.801h-55.374c-5.964,0-10.799,4.836-10.799,10.801V235.825z"
+ id="path92" /><path
+ fill="none"
+ stroke="#EDF5E5"
+ stroke-width="5"
+ stroke-miterlimit="10"
+ d="M186.706,235.825 c0,5.965,4.835,10.801,10.799,10.801h55.374c5.965,0,10.801-4.836,10.801-10.801v-19.373c0-5.965-4.836-10.801-10.801-10.801 h-55.374c-5.964,0-10.799,4.836-10.799,10.801V235.825z"
+ id="path94" /></g></g><path
+ opacity="0.74"
+ fill="#FFFFFF"
+ a:adobe-blending-mode="lighten"
+ d="M263.623,229.595c0.037-0.364,0.057-0.734,0.057-1.107 v-13.375c0-5.965-4.836-10.799-10.801-10.799h-55.374c-5.964,0-10.799,4.834-10.799,10.799v7.324 c7.545-1.012,15.699-1.566,24.213-1.566C231.959,220.87,250.812,224.252,263.623,229.595z"
+ id="path96" /><linearGradient
+ id="SVGID_6_"
+ gradientUnits="userSpaceOnUse"
+ x1="225.1929"
+ y1="204.3135"
+ x2="225.1929"
+ y2="246.626"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF;stop-opacity:0"
+ id="stop99" /><stop
+ offset="0.0141"
+ style="stop-color:#FDFDFC;stop-opacity:2.231669e-04"
+ id="stop101" /><stop
+ offset="0.1344"
+ style="stop-color:#BEBEAF;stop-opacity:0.0148"
+ id="stop103" /><stop
+ offset="0.2565"
+ style="stop-color:#94957C;stop-opacity:0.0297"
+ id="stop105" /><stop
+ offset="0.3796"
+ style="stop-color:#747759;stop-opacity:0.0446"
+ id="stop107" /><stop
+ offset="0.5029"
+ style="stop-color:#5D633F;stop-opacity:0.0596"
+ id="stop109" /><stop
+ offset="0.6263"
+ style="stop-color:#4D552E;stop-opacity:0.0746"
+ id="stop111" /><stop
+ offset="0.75"
+ style="stop-color:#414B23;stop-opacity:0.0896"
+ id="stop113" /><stop
+ offset="0.8742"
+ style="stop-color:#3B461E;stop-opacity:0.1047"
+ id="stop115" /><stop
+ offset="1"
+ style="stop-color:#38441C;stop-opacity:0.12"
+ id="stop117" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF;stop-opacity:0" /><a:midPointStop
+ offset="0.2901"
+ style="stop-color:#FFFFFF;stop-opacity:0" /><a:midPointStop
+ offset="1"
+ style="stop-color:#38441C;stop-opacity:0.12" /></linearGradient><path
+ fill="url(#SVGID_6_)"
+ a:adobe-blending-mode="darken"
+ d="M263.68,221.954v13.871c0,5.965-4.836,10.801-10.801,10.801 h-55.374c-5.964,0-10.799-4.836-10.799-10.801v-13.871l0.038-7.704c0,0,0.923-9.937,11.173-9.937h54.962 c0,0,10.063,0.328,10.801,10.799V221.954z"
+ id="path119" /></g><g
+ id="g121"><g
+ id="g123"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAuJJREFUeNrsl9trE0EUxjO7m5vW tKFN1RqLCmqlIvjgkz5I/cOFIqLggw9KsRHxUo1IdEtactG9+A1+A8dxNrsxK/rgwI9lt5ueb875 ZuZspfJ//Bhqjvc0AfCIHClIQEzSMkUoBqyCJbAKWrxXQoBmBL6AQzChmGQREWbmNQY/DS6Aa6AL mtZvdcDPoEcOQEgxUV5mVMYzH5wCZ8FFcJ0CLoN1UHeIGII34AV4BvbBW4qbzsqKctzruq+ALXAL 3ABXwAafNyjS9sQ3cAwG4BXYA0/AU/AejLOE+I4MtME22AH3wE2wyedNivSFQT3eB/y79kwHnGE2 v4IjinCaNrBEtJiBu2SLs686VkRWGRt8/wTL5jFwxIxMbSGB+Ac1qtcluEMBbWslFDV7QBFdlmBE bwxZtthVDn1dpgF3WIIOhakF9iCf2ajQK32W5hcRJgvnmYHb9ECzQAnyhif8o7PxkWImsiQeRSyJ fWCjJAGy5G2usKtgzc6wx5dWxT6wYhm2jKNBm/UcV90m/aLsdLVoonX+QJV8RvmcXNflNVOOKktQ Fz4p+6AMrBg/GUeeFWUHd51HyuXevz7+GRELNSRzjMwYnmhI5Laa/gEBYxEjskVE7Ih67AeOi3ZE BYc55j+xxzjgpBMpImZL1mNDMuDxm5aYBT2x1+wx+vZJ6lt94kl2Ux1uWl4JWZhy9g/AQ/DOPjt8 q0ULuLebhiRYYO8wPUTIdm+X1zDrKE/FKjH95TL3eP83MiIF7FHAY2ZkYpfadxhoRE80WJ66EKIK BE9YAiPgPkW8dPUSFUfDGnMpHVmKvQJCEoofcsamBLs0fOgSUMnomo2QQ66UAbMTi4+hmOk2mGZW B39OE+rgj5iBcNb3h5qxk9boDb1SLrEh2c75+NlnCfT1A4OP8nZiVeAT0IhZY0Ni+gHP8oEpQ59Z HHP2uRtfkeUnxTj7AWHqMU0ZiRVX2ld5kZ4jnSewHN8FGACSOOKkAlOGAAAAAABJRU5ErkJggg=="
+ transform="matrix(0.24 0 0 0.24 199.0298 216.5547)"
+ id="image125"></image><g
+ id="g127"><radialGradient
+ id="SVGID_7_"
+ cx="202.6289"
+ cy="219.7041"
+ r="2.9995"
+ gradientTransform="matrix(1 0 0 0.75 0 54.926)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop130" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop132" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop134" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_7_)"
+ cx="202.629"
+ cy="219.704"
+ r="2.999"
+ id="circle136" /></g></g><g
+ id="g138"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtFJREFUeNrsmP1LFEEYx292Ts3V 9ujFrCiwFyPShH4I+imoiPqbhYKIoKigN0W8SulNIrOU63S921u/A9+BYdm9mbndg4IGPiynuzOf eea52WeuVvvf/Joo8VwA6rxm+0lBD3R5TYctpu6XYBRE4DiYzMhpqRbYBDtgHyQ+gsIzQmMUOg3O gzkwzciZTUXqO1gCH8E3CsauERSOUiOgAc6AC2ABXAYXwZECsV/gPVgBb8AH8AVsg45NTjhKTYGr 4Aa4AmYZqYjLmpdj+4ySilwTLIOn4C34YZOTjlLXwH1wC8xzKSMureQym0g+O85ITxP1uU3hPS6r t5j63zFK3QM3uYwNQ0g45KUSPMSJNLjsLS71blHUZJ9Ox5lDSuo2k32SHYsBvslKcAIc5jJvUK7r I1ZntK6Du8yryBJhW9P73hi3jg2ym7ek0hKtO0z4E5xx2RYYOany7DPYyotaUPCwyoVL3KemKpLS TX+h5jhGI88jT0x9/U9yrzoHwoL7ykQtZN8LHGvURUxy05xhntWH8I7WOTzDsaSLmOAMQl6DIYgF mTGEi5iWEyWqD9dtpHCMoPaXtn9KrHSR59CsYxSJ6SKv1e9FW6L1MmM4iXWMIu8ri7u04mjF7HuJ Y3VcxLqciaqfVlnYJRWKJexzlWNs5r2SZMGMNOp1cRYc5atEVBCtPVazD8AzHzHdQUKZUyzywoIT kY9Uh9XrC4o1WTimPmI9ouv9iAXfIHKm1GtKvSyKlq2C1Una5sMTLBRHPN4MOvIxpV6BRfCEJU/s W8Ganf4xzoaCf5dGaS36JHnMKnWNUg/BY35uD1rza7ku5bY4658cMDHkEt6nUZP4TQG1dI/Ic/CJ /SVVHHglS2J94pnluXLecuB9x3Nlk5+3jUlV9hOBMAQjCpn1lMikgFrCdQrtGEKp62CDlCtaMLQc eNu+QmV/7XGp2cyN2rsdCDAAoyXZx8WJpTUAAAAASUVORK5CYII="
+ transform="matrix(0.24 0 0 0.24 213.9448 216.5547)"
+ id="image140"></image><g
+ id="g142"><radialGradient
+ id="SVGID_8_"
+ cx="217.5439"
+ cy="219.7041"
+ r="2.9995"
+ gradientTransform="matrix(1 0 0 0.75 0 54.926)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop145" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop147" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop149" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_8_)"
+ cx="217.544"
+ cy="219.704"
+ r="2.999"
+ id="circle151" /></g></g><g
+ id="g153"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAttJREFUeNrsmO9r00Acxptc1m6d Fn9M125sU4RVpyjiSwXB/9wXulciiE4dhpUMpwzFUa02XdP4HDwHR7hcLk0mCh58WOnI9548973k uTYa/0e54c15nQ8E8TJ1UpKQ2Z8QJgUtgDa4CC6AliZOiYrBCfgGfoLTsgK9OQStgE2wDa6DDv+v hhQwBAdgH0TgS1mBLsIEBV0F18BNcJvC1sCyQdgIHFHYG/AODMAxBSZVhQXgHJ15AO5T2Aa4TMHC 0GMJBXwFhxT2Erygkz/AtGhim1NS1A3wCDwGO+AKBS3QKS+nrlp6eQProKe5G4LvNucCS0+1uXQP wRNwj6JaFkH6SgitNxeJ0BwNueSzMsIC3ulduiX/roJmpp9cWkVQ1CrrqB17ws+TPGdM3y3Rftnk fTpVVlS2ZpN1+qy7znl8V2HSrUvcdbKnutryVRk+63RZd5vzBC7ClFvyMXALbHEDiJreNGpDbbH+ Wp5rJmEd7sQ+n13NCq8uU881WbfPeTquwtq0u1ezW1nXepyn7SJM9dgSCc4oPBTO4Rus9jKJwatZ lGeZy+rYXzH+GWEpXxEq5Kl8VecwBcnURVjMgCcZn5GwsTZH7CJMD3khL5zWLGzKuiHnGZpe5CZh I6bO9wx7v+bN7YYxY70j1o/yEoZpKSdMmntMoMq1tIYlVG7ts/4x50tddmXCEDfgxRETZ1JRWMI6 EesObGFRWCyfaa+oDl8jQd4DscApJUr21S54Dj7wu1JBUW2Ct1rybDDRntditUtPnWor8Aw8Zd2h rXdFQdGYd6WfbPTYnOeeEiSv/cTDyC5FvbL1luspSSXPFUYUmaHu8KS0yfjdMpySYp6QIop6TZdC njEnRTvdpVc8Lt0yBW4wS+04HHj3+Fg4pKARnUxdJnVNBL7hSNal4OxPBFLAZ/CRzumn8NR1wrKR xdfy1KLlwDvmw3RaRlDVX3s8h8dGWiUE/BZgAMf82R9IYLF+AAAAAElFTkSuQmCC"
+ transform="matrix(0.24 0 0 0.24 228.8599 216.5547)"
+ id="image155"></image><g
+ id="g157"><radialGradient
+ id="SVGID_9_"
+ cx="232.459"
+ cy="219.7041"
+ r="2.9995"
+ gradientTransform="matrix(1 0 0 0.75 0 54.926)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop160" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop162" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop164" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_9_)"
+ cx="232.459"
+ cy="219.704"
+ r="2.999"
+ id="circle166" /></g></g><g
+ id="g168"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAt9JREFUeNrsl91rE0EUxTOzm69a 05YmVWsUFdRKRfDBJ32Q+ocLRUTBBx+UYiOitlqRaEos2UT3w3P1jIzrbHZNVuiDAz9CNru5Z+69 M3O2Uvk/fg414zOCDzSxRwJiEJGkTBGKAatgEayCFr8rS4AwAp/BIRhTTDyPCDPzGoOfAhfANdAF zdT/SMBPoEf2wYBiQldmVAEBHjgJzoCL4DoFXAZroO4QMQRvwAvwDOyCtxQ3SWdF5QiQui+DDXAL 3ABXwDqvNygy3RPfwBHog1dgBzwBT8E7ENhCvJwMrIBNsAXugZvgPK83KdKzGlTzu8/fpWc64DSz +RV8oYhfTetPEdFiBu6SDc6+6lgRWZNo8P4Flk0zcMiMSGkSP+MPalQvJbhDASuplVB0RfkU0WUJ RuyNIcsWucoh15bYgFssQYfC1Bz7kcdsVNgrByzNHyJMFs4xA7fZA80CJcgb2uofycYHihlrh4hF ax9YL0mAGT7LKivsKmjLpLXjplVrH1ie0ryzlkWa9SxXnWR5QTv6ocUmWuMDqlLu8Di5ruk1Vzmq LEGdD5QtQln7yI8YespZUXbwzBi6cgzGsRTx14ZkxvFbDJeI9Laa/AMBgRUjTIsI6Yh69ANH0xzR DMMc8x/pMcTwjNIiIlqyHg1Jn8dvUmIWZGKv6THk/Jh4GWqFE3RTHW5auoQsTDj7B+Ah2JOzI8vU RNxQ2pYh8efYO4yHGNDubfNzkHWUJ9YqMf5yiZ7AmyEjtoAdCnjMjIj5TbycBhqxJxosT90SogoE j1kCI+A+Rbw0XmKaxzQlCXjz2GpOXUBITPFDztiUYJsNPzAC8kQklpBDrpQ+sxNZL0MR020wZlaC P2cTSvBHzMAg/f6hCu6qNfaGrJRLNCSbOS8/uyyBfL5n8JFrJy7a7Solpk1DYrynTvWBKcMBsxhw 9nEZL8S2GNtzuJo6YFOG1oor7a28iOdI8gLb47sAAwCDFN6m03jgxgAAAABJRU5ErkJggg=="
+ transform="matrix(0.24 0 0 0.24 243.7749 216.5547)"
+ id="image170"></image><g
+ id="g172"><radialGradient
+ id="SVGID_10_"
+ cx="247.374"
+ cy="219.7041"
+ r="2.9995"
+ gradientTransform="matrix(1 0 0 0.75 0 54.926)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop175" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop177" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop179" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_10_)"
+ cx="247.374"
+ cy="219.704"
+ r="2.999"
+ id="circle181" /></g></g><g
+ id="g183"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAn9JREFUeNrsl+lrE0EYxvdKjSZW YxEPxBsVrNdHQTxA/KMFBRGPDwoVVIpoq3jUeJUG25qk2fVZ+A28WTabxG4lHzrwgxw78z7zzMw7 73reBDR/jOcCUREhn21LRCy6osfn0kT4BN0h9oiDoiGmTN8Efoum+CHWEBRvRoSbeZXgR8QZcVEc F7syfTcI/kq8Fgviu1jlv3hcET627xXHxFlxWZwXJ8RMxgmPIKkTn8UbMSdeinfiq1hnmUYS4QTs F5fENQSc4rfUgahgT7TFivgk5sVj8VQs4kqukGiAgCviDiKOijr/BUOWL7t/9uGaVyTEighYggsI uI79NQYfdY9FPF8x/WL2xiJLk9hOoelcJehtcYslqI8hYNDGrvP9G5t1PbtRQ+NIg/W/KWaxNNpk DnK5JZ35TzbuCq70ibAu3BBXxWHW1i8hGbpc0+akNLNuBDAtTopz4kBJAuxEC8cPzIlI88BpOoQl Xw1TuDtLsqvZkxbwUA2FjZxEVJYbdROj4mWOpVuzCMoWYGPlxggm4SrfFmFFJOTzDUi2KFY8KIYT sUoSWRadLRDSM0XPMgVPn4guOT0tSN6KVtHd/w8tYWJfqDHeM+m+jBkTeIEaoEmKTUp0oXD80Kjt kU4PkVSqJWTOhIDpFf5APBFLOOPliYhxZgYR00MKmVEEuKWeQ8Q8ruRe5Xb3po7s5CqvDSjnxhVw XzzjFu3k5XTbuuziNYLvZolCk+KHBU8n8QcBL8Rd8VB8yCto8kTEDNBCTIdBg4wQvyD4L6rsdOb3 xKNhhW44IKm4wZaghSAnoIdrHWhz/m3wlOfiI86OXPJPzMvPxLwG/tcX4u3m2l8BBgBQ/dU5d1Za tAAAAABJRU5ErkJggg=="
+ transform="matrix(0.24 0 0 0.24 199.0298 230.2217)"
+ id="image185"></image><g
+ id="g187"><radialGradient
+ id="SVGID_11_"
+ cx="202.6289"
+ cy="233.3711"
+ r="2.999"
+ gradientTransform="matrix(1 0 0 0.75 0 58.3428)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop190" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop192" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop194" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_11_)"
+ cx="202.629"
+ cy="233.37"
+ r="2.999"
+ id="circle196" /></g></g><g
+ id="g198"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNrsmM9r1EAUx3cz2XW1 il2wLLagIh5aeilUBC967EX/XA/1It5aUaiC2JNY/EWp0lZkG3c3id+Bz0AIaXayibKHDnzIJfPm s29eZl/Sas3paNeYZ0SHaz5OKmIx5pr+azF7fyh6oi+WxXURZGJZiUScim/iWERiUkWwXTFDlxG6 I1bFBnKd3P1jpPbEvviE4JlvBtueUl1xQ9wVa2ITsdtkzOTmxGTsALE34oP4KH6I0TS5tofUJXFT PBCPxToZ67OlZTUWkSmbsffipXglvos/ZXLGI1N2qx6Kp+KRuFcgVYRh/oJYEgNxle08EUNqsbJY SDAnZa8r1FlYoQzc02sFF5n/W/wskzMlAReopydkaoVtDWocL1bqGtv8Bblx0YSgJFt9xNbJXLfG uZctjQEx11gj9M2YDXCFiVviflmAGeQCYtlt/MxTOvbJmEFkFZqSyu9GNr7xEXNP4gbnVK/mFhZl rUdsd0B3fcQCDs3lcw7PJobJrRH4iE37g24qa6VrBK05HRdiTYjVbvI8xtQ1isSyTd4pE5secW6N xEdslGnyDmhd0oazFRF7j7VGPmIxPdQ+HNMWNzUmBfFj3+7C1YDtMG7RT3UaONMS+jErtC1e05tV EksyPdkAyToHbsqW2e51R7ygs42qNooJaU/oPF2TF8wgl2SkdsVz8Y5sJVXFUvryX6TfNXld5HwE U37cWUbqGdfDsto1njVxQjscQ8jc8+SckO25jqipHTK1i+Ro1peR7FM6pKH7StAhC7uam7CQI+J+ J7RNTb0lU7Vf3+b6hXeuPxH8948qF6Pq+CvAAGGezDColMK7AAAAAElFTkSuQmCC"
+ transform="matrix(0.24 0 0 0.24 213.9448 230.2217)"
+ id="image200"></image><g
+ id="g202"><radialGradient
+ id="SVGID_12_"
+ cx="217.5439"
+ cy="233.3711"
+ r="2.999"
+ gradientTransform="matrix(1 0 0 0.75 0 58.3428)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop205" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop207" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop209" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_12_)"
+ cx="217.544"
+ cy="233.37"
+ r="2.999"
+ id="circle211" /></g></g><g
+ id="g213"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAhCAYAAAC1ONkWAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlRJREFUeNrsmM9LG0EUx5PdjTTW otDYWmoOQm2M/YGXnrxI/3IvnnoRW7TagocotqjQtLYp5pffgc/CECc7u+uGpuDAB2Y32Tff9+bN 7Jstlaa0lXM+E4gIAsd/BqIHpj+cpLBY0Ix4JBbhwYg4I+SvOIdf4jqrwHIOQUvihXgtVsWCQ9gP 8UV8El/Ft6wCyyl+DxH0XLwUb8UbxD0V1RE7ZtCO+I6oj2JPHIlTBPZ94sqe3yIi0hCb4h1Reibm iOK4HDPRuRJnRO+D2BGHRLSXJC7yRGpeNMV7sYXAeQSFCU6FRHIGB56IGveMI/uIGxu5JGFzTN0W wpqIijIsmpDFYZ55hah4xRpxP7MIM4NWWHEbTGGDKY1ybi8VKyVM/l2wYjtM+S1xrvww9x6KulgX K0QqvOOeGafGCnbrjOPScOtmnPA1Hm7Sr+TcjF2Rq2F3nb4zNVzCZsWyWMOr2XFe5WgB9urYX+ba KywkF1bJh8d4WWSrYLdhbdBhmohVrddNtYApLOUZI0jxgp6EMO8YQWlK272wuwobFlHkeVqqMVzC OlaR15mQMO8Yo8L6VpFnypNL0S1YWBe7h4wTVxneiP0RJ+KzaHE9KEjUAHst7J9wnWoqe7z9TVly QL9bwJQOsXOB3X36vbTVhfHqN16Zh49F2xXujK2PnWPsthhnkLYeiz0ziblrVZ55CkV7Ftrk1Q52 z5NmIkowdsUBIrIqz7SltR2la0vUNhxhP3PNP7RCf4CouPIs4jDS9p2U/svj21QfeKf6E8E/+ahy 37K2GwEGAJb/2mQI89WQAAAAAElFTkSuQmCC"
+ transform="matrix(0.24 0 0 0.24 228.8599 230.2217)"
+ id="image215"></image><g
+ id="g217"><radialGradient
+ id="SVGID_13_"
+ cx="232.459"
+ cy="233.3711"
+ r="2.999"
+ gradientTransform="matrix(1 0 0 0.75 0 58.3428)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop220" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop222" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop224" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_13_)"
+ cx="232.459"
+ cy="233.37"
+ r="2.999"
+ id="circle226" /></g></g><g
+ id="g228"><image
+ overflow="visible"
+ opacity="0.25"
+ a:adobe-blending-mode="multiply"
+ a:adobe-opacity-share="1"
+ width="30"
+ height="30"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAnpJREFUeNrsl2lrE1EUhmdLjSZ2 sYgL4lqsYN0+CuIC4o8WFERcPii0YEsQtYpL3cVgW7PMjO+F55ZhmMlMzATyoRceSDKZc957zplz zzjOBCz3P+/xRE34fE6uWESiJ0I+VybCxekeMSMOizkxlbATwx/xRXwXWwiKRhFhd17H+TFxVlwU J8W+lJ0+zlfFmngjvolNrkXDinAJ+6w4IRbFZXFenBLzqUg4ODGR+CheimXxQrwWn8U2aSolwgo4 KC6Jawg4w28mAsGAmuiI3+KDaInH4qlYJyo7QoISAq6IO4g4Lppc8wrSl66fA0TNSQvJE+GRggsI uE74GxgvW8gB/68l7ouojXVSE/s5N9dxelvcIgXNIQTkFXaT718pViMiyjIa8OiZ/N8US4Q0GLEf 2d5iauYHhWtqpu8PiMINcVUcJbduBY3R9poOT4rpJdteRi1Mi9PinDhUkQC7/Cz7aRH2iTB9YIEb /IqPiSmiu0Sza3gZf2qgcC6jEVUVjWbCR83LOR8CqFpAMu07PrxJOMp3ReSJiOnnfYjH5DdK+sgS sUkT+SW6YxASJoYe46OXFtGjp5uB5JVop8/+EVfMxj4xY7w1m/YywtRmGmqhtlNhNMIs+36O2pB2 fYSmUq+gc8ZsyBzhD8QTsWEikyciomjnETFdMMiUEWBTvYyIFlGJ/ILqNRHZy1HeyBnnhhVwXzzj FO06BSHuUcVbON9Piuy7hlvCudnEXwSsiLvioXhnB5oiEREG2ojpYtRLCXEHOP/JlG12fk88yhp0 /RJNxRrbgDaCrICQqHWhw/OfdG54Lt4T2dIj/8S8/EzMa+DYX4h3l13/BBgABM7SO70ZkkMAAAAA SUVORK5CYII="
+ transform="matrix(0.24 0 0 0.24 243.7749 230.2217)"
+ id="image230"></image><g
+ id="g232"><radialGradient
+ id="SVGID_14_"
+ cx="247.374"
+ cy="233.3711"
+ r="2.999"
+ gradientTransform="matrix(1 0 0 0.75 0 58.3428)"
+ gradientUnits="userSpaceOnUse"><stop
+ offset="0.0123"
+ style="stop-color:#FFFFFF"
+ id="stop235" /><stop
+ offset="0.4235"
+ style="stop-color:#FAFCF6"
+ id="stop237" /><stop
+ offset="1"
+ style="stop-color:#F2F7E8"
+ id="stop239" /><a:midPointStop
+ offset="0.0123"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="0.6235"
+ style="stop-color:#FFFFFF" /><a:midPointStop
+ offset="1"
+ style="stop-color:#F2F7E8" /></radialGradient><circle
+ fill="url(#SVGID_14_)"
+ cx="247.374"
+ cy="233.37"
+ r="2.999"
+ id="circle241" /></g></g></g></g><path
+ d="m 529.664,248.155 h 18.498 l -2.809,18.064 h 5.59 37.586 l 2.6,-17.718 c 4.98,-1.091 9.133,-3.455 12.512,-6.693 3.084,4.075 8.566,7.37 18.252,7.37 6.338,0 12.775,-1.807 17.174,-3.687 4.254,2.399 9.463,3.687 15.459,3.687 3.088,0 6.236,-0.355 9.426,-1.023 h 67.135 l 3.354,-24.827 -5.445,-0.764 1.879,-13.356 c 0.371,-2.386 0.449,-4.66 0.449,-6.156 l -0.008,-0.375 c -0.457,-12.191 -8.139,-19.765 -20.045,-19.765 -2.404,0 -4.623,0.314 -6.676,0.852 h -34.189 l -0.035,0.244 c -2.527,-0.701 -5.41,-1.096 -8.686,-1.096 -3.801,0 -7.406,0.555 -10.76,1.598 l 0.105,-0.746 h -12.467 l 1.826,-12.951 H 613.08 l -1.846,7.658 c -1.373,5.704 -2.213,5.793 -4.453,6.03 l -4.508,0.477 c -3.049,-1.424 -6.357,-2.065 -9.602,-2.065 -2.135,0 -4.275,0.284 -6.416,0.852 h -19.291 c 0.502,-1.772 0.775,-3.674 0.775,-5.678 0,-9.601 -6.846,-16.305 -16.646,-16.305 -11.055,0 -18.775,7.721 -18.775,18.776 0,0.951 0.082,1.869 0.219,2.764 -2.135,-0.288 -4.277,-0.409 -5.553,-0.409 -2.053,0 -4.072,0.288 -6.045,0.852 h -31.342 c -2.74,-0.553 -5.641,-0.852 -8.537,-0.852 -7.138,0 -13.492,1.674 -18.808,4.723 l -3.451,-1.461 c -3.711,-1.571 -11.232,-3.262 -18.979,-3.262 -8.933,0 -16.383,2.56 -21.576,7.016 -3.265,-4.473 -8.523,-7.016 -15.228,-7.016 -4.822,0 -9.021,1.477 -12.572,3.44 -2.996,-2.204 -6.796,-3.44 -11.115,-3.44 -2.327,0 -4.48,0.315 -6.476,0.852 h -33.963 l -0.035,0.245 c -2.526,-0.702 -5.41,-1.097 -8.687,-1.097 -20.458,0 -35.307,16.031 -35.307,38.117 0,17.363 10.785,28.149 28.148,28.149 3.087,0 6.236,-0.356 9.426,-1.023 h 88.816 c 3.706,0.676 7.669,1.023 11.154,1.023 8.907,0 16.278,-2.375 21.51,-6.593 4.872,4.252 11.585,6.593 19.728,6.593 3.053,0 6.206,-0.368 9.286,-1.023 h 44.664 2.069 z"
+ id="path243"
+ inkscape:connector-curvature="0"
+ style="fill:#f5f5f5" /><g
+ id="g245"
+ transform="translate(0,16)"><g
+ id="g247"><path
+ d="m 340.308,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.095,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z"
+ id="path249"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 394.07,221.7 -0.171,-0.255 1.789,-10.055 2.642,-18.063 c 0.512,-3.749 0.341,-5.623 -1.96,-5.623 -2.642,0 -5.794,2.727 -9.372,5.879 l -2.727,19.512 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 -0.852,6.305 h -18.404 l -0.171,-0.341 1.875,-10.82 2.471,-17.212 c 0.512,-3.237 0.682,-5.453 -1.789,-5.453 -3.238,0 -7.413,3.664 -9.714,5.709 l -2.642,19.512 c -0.17,1.363 -0.17,1.534 1.108,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.767,-1.789 l -4.176,-1.534 0.938,-6.476 h 16.871 l -0.938,6.987 0.256,0.085 c 4.43,-3.749 9.116,-7.924 15.592,-7.924 4.687,0 7.839,2.641 8.18,7.753 l 0.256,0.086 c 4.175,-3.664 9.202,-7.839 15.252,-7.839 6.22,0 8.775,3.152 8.946,9.202 0,1.618 -0.171,3.493 -0.426,5.538 l -3.067,21.897 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.175,0.597 -0.852,6.305 H 394.07 z"
+ id="path251"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 443.995,190.771 -0.17,-4.431 c 0,-0.682 -0.085,-1.108 -1.022,-1.363 -1.022,-0.256 -2.642,-0.427 -4.771,-0.427 -3.579,0 -6.391,1.108 -6.391,4.09 0,2.727 2.982,3.749 6.731,5.027 6.05,2.045 13.888,4.431 13.888,13.463 0,11.076 -9.372,15.592 -20.193,15.592 -8.009,0 -14.91,-1.959 -16.273,-2.981 l 1.618,-12.355 8.691,0.512 0.255,4.941 c 0,0.597 0.171,1.108 0.938,1.363 1.278,0.427 3.238,0.768 6.05,0.768 4.687,0 7.327,-1.79 7.327,-4.687 0,-3.408 -3.152,-4.175 -8.009,-5.624 -6.135,-1.874 -12.78,-4.26 -12.78,-13.206 0,-10.48 9.116,-14.996 19.597,-14.996 6.646,0 12.866,1.533 15.081,2.471 l -1.704,12.354 -8.863,-0.511 z"
+ id="path253"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 489.748,218.548 c -4.175,2.386 -10.395,4.175 -16.444,4.175 -13.036,0 -18.575,-7.583 -18.575,-18.574 0,-18.83 11.588,-27.691 25.988,-27.691 6.475,0 11.843,1.874 14.229,3.578 l -1.874,13.377 -8.691,-0.426 -0.255,-5.794 c 0,-0.597 -0.086,-0.938 -0.597,-1.192 -1.022,-0.427 -2.557,-0.597 -4.175,-0.597 -5.624,0 -11.418,4.601 -11.418,17.382 0,7.839 3.493,10.395 8.436,10.395 4.346,0 8.436,-1.448 11.247,-2.556 l 2.129,7.923 z"
+ id="path255"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 491.364,221.7 0.853,-6.39 3.919,-0.512 c 1.193,-0.17 1.363,-0.426 1.534,-1.704 l 3.578,-25.987 c 0.086,-0.938 -0.085,-1.534 -0.852,-1.789 l -4.261,-1.534 0.938,-6.476 h 16.87 l -1.107,7.669 0.256,0.17 c 3.323,-4.771 8.095,-8.69 13.548,-8.69 1.874,0 5.112,0.341 6.561,0.767 l -2.13,15.507 -9.969,-0.341 -0.256,-4.431 c -0.086,-0.767 -0.256,-1.022 -0.938,-1.022 -1.619,0 -4.26,1.96 -6.646,4.431 l -2.981,21.643 c -0.171,1.363 -0.085,1.619 1.192,1.704 l 8.095,0.682 -0.938,6.305 h -27.266 z"
+ id="path257"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 536.094,221.7 -0.17,-0.426 2.045,-11.503 3.152,-22.749 c 0.17,-0.938 -0.086,-1.534 -0.853,-1.79 l -4.175,-1.448 0.852,-6.476 h 18.149 l -5.027,35.786 c -0.171,1.363 -0.085,1.534 1.192,1.704 l 4.09,0.597 -0.852,6.305 h -18.403 z m 5.879,-57.598 c 0,-5.453 3.238,-8.775 8.776,-8.775 4.175,0 6.646,2.215 6.646,6.305 0,5.368 -3.322,8.861 -8.861,8.861 -4.176,-0.001 -6.561,-2.387 -6.561,-6.391 z"
+ id="path259"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 556.796,239.764 -0.17,-0.341 2.471,-14.229 5.282,-38.087 c 0.171,-1.022 -0.085,-1.534 -0.767,-1.789 l -4.175,-1.534 0.938,-6.476 h 17.041 l -1.022,6.816 0.255,0.085 c 5.027,-4.686 10.311,-7.753 15.678,-7.753 7.328,0 12.44,4.686 12.44,17.041 0,11.758 -4.601,29.225 -20.449,29.225 -5.538,0 -8.605,-2.13 -11.759,-4.345 l -1.874,12.78 c -0.085,0.938 0.085,1.278 1.192,1.363 l 8.606,0.853 -0.938,6.39 h -22.749 z m 17.041,-30.247 c 2.13,1.789 4.942,3.322 8.095,3.322 6.901,0 9.458,-9.713 9.458,-17.211 0,-5.027 -1.193,-8.351 -4.431,-8.351 -3.408,0 -7.754,3.664 -10.821,6.391 l -2.301,15.849 z"
+ id="path261"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 635.777,219.4 c -3.749,1.789 -9.458,3.322 -14.229,3.322 -8.521,0 -12.099,-2.981 -12.099,-9.969 0,-1.107 0.085,-2.386 0.256,-3.749 l 3.066,-22.323 c 0.086,-0.512 0.086,-0.853 -0.511,-0.853 h -5.879 l 1.107,-7.839 c 7.242,-0.767 10.906,-4.431 13.122,-13.633 h 7.924 l -1.704,12.1 c -0.085,0.596 -0.085,0.852 0.597,0.852 h 11.758 l -1.193,8.521 h -12.439 l -2.812,20.364 c -0.171,1.107 -0.256,1.96 -0.256,2.727 0,2.982 1.278,4.26 4.942,4.26 2.385,0 4.771,-0.596 6.816,-1.363 l 1.534,7.583 z"
+ id="path263"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 671.817,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.094,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z"
+ id="path265"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /><path
+ d="m 703.596,221.7 -0.17,-0.255 1.874,-10.396 2.471,-17.723 c 0.512,-3.578 0.341,-5.879 -2.215,-5.879 -3.664,0 -8.18,3.578 -11.077,6.135 l -2.641,19.512 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.768,-1.789 l -4.175,-1.534 0.938,-6.476 h 16.87 l -0.937,6.987 0.255,0.085 c 4.771,-4.09 9.373,-7.924 16.02,-7.924 6.475,0 9.798,3.322 10.054,10.139 0,1.363 -0.085,3.067 -0.341,4.687 l -3.067,21.812 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 L 722,221.7 h -18.404 z"
+ id="path267"
+ inkscape:connector-curvature="0"
+ style="fill:#383838" /></g><g
+ id="g269"><linearGradient
+ id="SVGID_15_"
+ gradientUnits="userSpaceOnUse"
+ x1="324.1611"
+ y1="239.7637"
+ x2="324.1611"
+ y2="155.3275"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop272" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop274" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 340.308,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.095,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z"
+ id="path276"
+ style="fill:url(#SVGID_15_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_16_"
+ gradientUnits="userSpaceOnUse"
+ x1="377.45459"
+ y1="239.7637"
+ x2="377.45459"
+ y2="155.3277"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop279" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop281" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 394.07,221.7 -0.171,-0.255 1.789,-10.055 2.642,-18.063 c 0.512,-3.749 0.341,-5.623 -1.96,-5.623 -2.642,0 -5.794,2.727 -9.372,5.879 l -2.727,19.512 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 -0.852,6.305 h -18.404 l -0.171,-0.341 1.875,-10.82 2.471,-17.212 c 0.512,-3.237 0.682,-5.453 -1.789,-5.453 -3.238,0 -7.413,3.664 -9.714,5.709 l -2.642,19.512 c -0.17,1.363 -0.17,1.534 1.108,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.767,-1.789 l -4.176,-1.534 0.938,-6.476 h 16.871 l -0.938,6.987 0.256,0.085 c 4.43,-3.749 9.116,-7.924 15.592,-7.924 4.687,0 7.839,2.641 8.18,7.753 l 0.256,0.086 c 4.175,-3.664 9.202,-7.839 15.252,-7.839 6.22,0 8.775,3.152 8.946,9.202 0,1.618 -0.171,3.493 -0.426,5.538 l -3.067,21.897 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.175,0.597 -0.852,6.305 H 394.07 z"
+ id="path283"
+ style="fill:url(#SVGID_16_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_17_"
+ gradientUnits="userSpaceOnUse"
+ x1="435.17719"
+ y1="239.7637"
+ x2="435.17719"
+ y2="155.3275"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop286" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop288" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 443.995,190.771 -0.17,-4.431 c 0,-0.682 -0.085,-1.108 -1.022,-1.363 -1.022,-0.256 -2.642,-0.427 -4.771,-0.427 -3.579,0 -6.391,1.108 -6.391,4.09 0,2.727 2.982,3.749 6.731,5.027 6.05,2.045 13.888,4.431 13.888,13.463 0,11.076 -9.372,15.592 -20.193,15.592 -8.009,0 -14.91,-1.959 -16.273,-2.981 l 1.618,-12.355 8.691,0.512 0.255,4.941 c 0,0.597 0.171,1.108 0.938,1.363 1.278,0.427 3.238,0.768 6.05,0.768 4.687,0 7.327,-1.79 7.327,-4.687 0,-3.408 -3.152,-4.175 -8.009,-5.624 -6.135,-1.874 -12.78,-4.26 -12.78,-13.206 0,-10.48 9.116,-14.996 19.597,-14.996 6.646,0 12.866,1.533 15.081,2.471 l -1.704,12.354 -8.863,-0.511 z"
+ id="path290"
+ style="fill:url(#SVGID_17_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_18_"
+ gradientUnits="userSpaceOnUse"
+ x1="474.83691"
+ y1="239.7637"
+ x2="474.83691"
+ y2="155.3275"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop293" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop295" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 489.748,218.548 c -4.175,2.386 -10.395,4.175 -16.444,4.175 -13.036,0 -18.575,-7.583 -18.575,-18.574 0,-18.83 11.588,-27.691 25.988,-27.691 6.475,0 11.843,1.874 14.229,3.578 l -1.874,13.377 -8.691,-0.426 -0.255,-5.794 c 0,-0.597 -0.086,-0.938 -0.597,-1.192 -1.022,-0.427 -2.557,-0.597 -4.175,-0.597 -5.624,0 -11.418,4.601 -11.418,17.382 0,7.839 3.493,10.395 8.436,10.395 4.346,0 8.436,-1.448 11.247,-2.556 l 2.129,7.923 z"
+ id="path297"
+ style="fill:url(#SVGID_18_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_19_"
+ gradientUnits="userSpaceOnUse"
+ x1="512.28223"
+ y1="239.7637"
+ x2="512.28223"
+ y2="155.3277"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop300" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop302" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 491.364,221.7 0.853,-6.39 3.919,-0.512 c 1.193,-0.17 1.363,-0.426 1.534,-1.704 l 3.578,-25.987 c 0.086,-0.938 -0.085,-1.534 -0.852,-1.789 l -4.261,-1.534 0.938,-6.476 h 16.87 l -1.107,7.669 0.256,0.17 c 3.323,-4.771 8.095,-8.69 13.548,-8.69 1.874,0 5.112,0.341 6.561,0.767 l -2.13,15.507 -9.969,-0.341 -0.256,-4.431 c -0.086,-0.767 -0.256,-1.022 -0.938,-1.022 -1.619,0 -4.26,1.96 -6.646,4.431 l -2.981,21.643 c -0.171,1.363 -0.085,1.619 1.192,1.704 l 8.095,0.682 -0.938,6.305 h -27.266 z"
+ id="path304"
+ style="fill:url(#SVGID_19_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_20_"
+ gradientUnits="userSpaceOnUse"
+ x1="546.65918"
+ y1="239.7637"
+ x2="546.65918"
+ y2="155.32719"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop307" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop309" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 536.094,221.7 -0.17,-0.426 2.045,-11.503 3.152,-22.749 c 0.17,-0.938 -0.086,-1.534 -0.853,-1.79 l -4.175,-1.448 0.852,-6.476 h 18.149 l -5.027,35.786 c -0.171,1.363 -0.085,1.534 1.192,1.704 l 4.09,0.597 -0.852,6.305 h -18.403 z m 5.879,-57.598 c 0,-5.453 3.238,-8.775 8.776,-8.775 4.175,0 6.646,2.215 6.646,6.305 0,5.368 -3.322,8.861 -8.861,8.861 -4.176,-0.001 -6.561,-2.387 -6.561,-6.391 z"
+ id="path311"
+ style="fill:url(#SVGID_20_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_21_"
+ gradientUnits="userSpaceOnUse"
+ x1="580.69629"
+ y1="239.7637"
+ x2="580.69629"
+ y2="155.32719"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop314" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop316" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 556.796,239.764 -0.17,-0.341 2.471,-14.229 5.282,-38.087 c 0.171,-1.022 -0.085,-1.534 -0.767,-1.789 l -4.175,-1.534 0.938,-6.476 h 17.041 l -1.022,6.816 0.255,0.085 c 5.027,-4.686 10.311,-7.753 15.678,-7.753 7.328,0 12.44,4.686 12.44,17.041 0,11.758 -4.601,29.225 -20.449,29.225 -5.538,0 -8.605,-2.13 -11.759,-4.345 l -1.874,12.78 c -0.085,0.938 0.085,1.278 1.192,1.363 l 8.606,0.853 -0.938,6.39 h -22.749 z m 17.041,-30.247 c 2.13,1.789 4.942,3.322 8.095,3.322 6.901,0 9.458,-9.713 9.458,-17.211 0,-5.027 -1.193,-8.351 -4.431,-8.351 -3.408,0 -7.754,3.664 -10.821,6.391 l -2.301,15.849 z"
+ id="path318"
+ style="fill:url(#SVGID_21_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_22_"
+ gradientUnits="userSpaceOnUse"
+ x1="622.7832"
+ y1="239.7637"
+ x2="622.7832"
+ y2="155.3268"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop321" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop323" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 635.777,219.4 c -3.749,1.789 -9.458,3.322 -14.229,3.322 -8.521,0 -12.099,-2.981 -12.099,-9.969 0,-1.107 0.085,-2.386 0.256,-3.749 l 3.066,-22.323 c 0.086,-0.512 0.086,-0.853 -0.511,-0.853 h -5.879 l 1.107,-7.839 c 7.242,-0.767 10.906,-4.431 13.122,-13.633 h 7.924 l -1.704,12.1 c -0.085,0.596 -0.085,0.852 0.597,0.852 h 11.758 l -1.193,8.521 h -12.439 l -2.812,20.364 c -0.171,1.107 -0.256,1.96 -0.256,2.727 0,2.982 1.278,4.26 4.942,4.26 2.385,0 4.771,-0.596 6.816,-1.363 l 1.534,7.583 z"
+ id="path325"
+ style="fill:url(#SVGID_22_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_23_"
+ gradientUnits="userSpaceOnUse"
+ x1="655.6709"
+ y1="239.7637"
+ x2="655.6709"
+ y2="155.3275"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop328" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop330" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 671.817,218.463 c -5.538,2.556 -11.588,4.26 -17.638,4.26 -13.377,0 -18.148,-7.839 -18.148,-18.148 0,-17.893 11.418,-28.117 25.307,-28.117 9.372,0 13.973,4.26 13.973,11.247 0,12.184 -12.865,15.763 -26.157,17.126 0.255,4.346 2.045,8.35 8.435,8.35 3.068,0 7.243,-0.937 12.355,-3.067 l 1.873,8.349 z m -8.094,-29.567 c 0,-2.045 -1.448,-3.237 -4.09,-3.237 -4.771,0 -8.69,4.175 -9.969,10.906 3.664,-0.511 14.059,-2.3 14.059,-7.669 z"
+ id="path332"
+ style="fill:url(#SVGID_23_)"
+ inkscape:connector-curvature="0" /><linearGradient
+ id="SVGID_24_"
+ gradientUnits="userSpaceOnUse"
+ x1="697.92969"
+ y1="239.7637"
+ x2="697.92969"
+ y2="155.3277"><stop
+ offset="0"
+ style="stop-color:#000000"
+ id="stop335" /><stop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0"
+ id="stop337" /><a:midPointStop
+ offset="0"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="0.6933"
+ style="stop-color:#000000" /><a:midPointStop
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0" /></linearGradient><path
+ d="m 703.596,221.7 -0.17,-0.255 1.874,-10.396 2.471,-17.723 c 0.512,-3.578 0.341,-5.879 -2.215,-5.879 -3.664,0 -8.18,3.578 -11.077,6.135 l -2.641,19.512 c -0.171,1.363 -0.171,1.534 1.107,1.704 l 4.26,0.597 -0.852,6.305 h -23.347 l 0.853,-6.39 3.749,-0.512 c 1.107,-0.17 1.363,-0.426 1.533,-1.704 l 3.579,-25.987 c 0.17,-0.938 0,-1.534 -0.768,-1.789 l -4.175,-1.534 0.938,-6.476 h 16.87 l -0.937,6.987 0.255,0.085 c 4.771,-4.09 9.373,-7.924 16.02,-7.924 6.475,0 9.798,3.322 10.054,10.139 0,1.363 -0.085,3.067 -0.341,4.687 l -3.067,21.812 c -0.171,1.363 -0.171,1.534 1.022,1.704 l 4.26,0.597 L 722,221.7 h -18.404 z"
+ id="path339"
+ style="fill:url(#SVGID_24_)"
+ inkscape:connector-curvature="0" /></g></g><g
+ id="g4141"
+ transform="matrix(0.81856441,0,0,0.81856441,79.234731,-94.128741)"><g
+ id="g4143"></g><g
+ id="g4165"><linearGradient
+ y2="155.3275"
+ x2="324.1611"
+ y1="239.7637"
+ x1="324.1611"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4167"><stop
+ id="stop4169"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4171"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3277"
+ x2="377.45459"
+ y1="239.7637"
+ x1="377.45459"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4175"><stop
+ id="stop4177"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4179"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3275"
+ x2="435.17719"
+ y1="239.7637"
+ x1="435.17719"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4183"><stop
+ id="stop4185"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4187"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3275"
+ x2="474.83691"
+ y1="239.7637"
+ x1="474.83691"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4191"><stop
+ id="stop4193"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4195"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3277"
+ x2="512.28223"
+ y1="239.7637"
+ x1="512.28223"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4199"><stop
+ id="stop4201"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4203"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.32719"
+ x2="546.65918"
+ y1="239.7637"
+ x1="546.65918"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4207"><stop
+ id="stop4209"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4211"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.32719"
+ x2="580.69629"
+ y1="239.7637"
+ x1="580.69629"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4215"><stop
+ id="stop4217"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4219"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3268"
+ x2="622.7832"
+ y1="239.7637"
+ x1="622.7832"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4223"><stop
+ id="stop4225"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4227"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3275"
+ x2="655.6709"
+ y1="239.7637"
+ x1="655.6709"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4231"><stop
+ id="stop4233"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4235"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient><linearGradient
+ y2="155.3277"
+ x2="697.92969"
+ y1="239.7637"
+ x1="697.92969"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4239"><stop
+ id="stop4241"
+ style="stop-color:#000000"
+ offset="0" /><stop
+ id="stop4243"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0" /><a:midPointStop
+ style="stop-color:#000000"
+ offset="0.6933" /><a:midPointStop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" /></linearGradient></g></g></svg>
+ </a>
+
+ <div class="spinner" id='spinner'></div>
+ <div class="emscripten" id="status">Downloading...</div>
+
+<span id='controls'>
+ <span><input type="checkbox" id="resize">Resize canvas</span>
+ <span><input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer &nbsp;&nbsp;&nbsp;</span>
+ <span><input type="button" value="Fullscreen" onclick="Module.requestFullScreen(document.getElementById('pointerLock').checked,
+ document.getElementById('resize').checked)">
+ </span>
+</span>
+
+ <div class="emscripten">
+ <progress value="0" max="100" id="progress" hidden=1></progress>
+ </div>
+
+
+ <div class="emscripten_border">
+ <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
+ </div>
+ <textarea id="output" rows="8"></textarea>
+
+ <script type='text/javascript'>
+ var statusElement = document.getElementById('status');
+ var progressElement = document.getElementById('progress');
+ var spinnerElement = document.getElementById('spinner');
+
+ var Module = {
+ TOTAL_MEMORY: $GODOTTMEM,
+ preRun: [],
+ postRun: [],
+ print: (function() {
+ var element = document.getElementById('output');
+ if (element) element.value = ''; // clear browser cache
+ return function(text) {
+ if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
+ // These replacements are necessary if you render to raw HTML
+ //text = text.replace(/&/g, "&amp;");
+ //text = text.replace(/</g, "&lt;");
+ //text = text.replace(/>/g, "&gt;");
+ //text = text.replace('\n', '<br>', 'g');
+ console.log(text);
+ if (element) {
+ element.value += text + "\n";
+ element.scrollTop = element.scrollHeight; // focus on bottom
+ }
+ };
+ })(),
+ printErr: function(text) {
+ if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
+ if (0) { // XXX disabled for safety typeof dump == 'function') {
+ dump(text + '\n'); // fast, straight to the real console
+ } else {
+ console.error(text);
+ }
+ },
+ canvas: (function() {
+ var canvas = document.getElementById('canvas');
+
+ // As a default initial behavior, pop up an alert when webgl context is lost. To make your
+ // application robust, you may want to override this behavior before shipping!
+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
+ canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false);
+
+ return canvas;
+ })(),
+ setStatus: function(text) {
+ if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };
+ if (text === Module.setStatus.text) return;
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var now = Date.now();
+ if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soon
+ if (m) {
+ text = m[1];
+ progressElement.value = parseInt(m[2])*100;
+ progressElement.max = parseInt(m[4])*100;
+ progressElement.hidden = false;
+ spinnerElement.hidden = false;
+ } else {
+ progressElement.value = null;
+ progressElement.max = null;
+ progressElement.hidden = true;
+ if (!text) spinnerElement.style.display = 'none';
+ }
+ statusElement.innerHTML = text;
+ },
+ totalDependencies: 0,
+ monitorRunDependencies: function(left) {
+ this.totalDependencies = Math.max(this.totalDependencies, left);
+ Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
+ }
+ };
+ Module.setStatus('Downloading...');
+ window.onerror = function(event) {
+ // TODO: do not warn on ok events like simulating an infinite loop or exitStatus
+ Module.setStatus('Exception thrown, see JavaScript console');
+ spinnerElement.style.display = 'none';
+ Module.setStatus = function(text) {
+ if (text) Module.printErr('[post-exception status] ' + text);
+ };
+ };
+ </script>
+ <script type="text/javascript" src="$GODOTFS"></script>
+ <script>
+
+ (function() {
+ var memoryInitializer = '$GODOTMEM';
+ if (typeof Module['locateFile'] === 'function') {
+ memoryInitializer = Module['locateFile'](memoryInitializer);
+ } else if (Module['memoryInitializerPrefixURL']) {
+ memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer;
+ }
+ var xhr = Module['memoryInitializerRequest'] = new XMLHttpRequest();
+ xhr.open('GET', memoryInitializer, true);
+ xhr.responseType = 'arraybuffer';
+ xhr.send(null);
+ })();
+
+ var script = document.createElement('script');
+ script.src = "$GODOTJS";
+ document.body.appendChild(script);
+
+</script>
+ </body>
+</html>
diff --git a/tools/html_fs/filesystem.js b/tools/html_fs/godotfs.js
index 93cc30556b..93cc30556b 100644
--- a/tools/html_fs/filesystem.js
+++ b/tools/html_fs/godotfs.js