summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/SCsub35
-rw-r--r--editor/animation_editor.cpp17
-rw-r--r--editor/code_editor.cpp6
-rw-r--r--editor/create_dialog.cpp39
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/doc/doc_data.cpp132
-rw-r--r--editor/doc/doc_data.h8
-rw-r--r--editor/editor_audio_buses.cpp111
-rw-r--r--editor/editor_audio_buses.h19
-rw-r--r--editor/editor_dir_dialog.cpp4
-rw-r--r--editor/editor_export.cpp159
-rw-r--r--editor/editor_export.h49
-rw-r--r--editor/editor_file_dialog.cpp34
-rw-r--r--editor/editor_fonts.cpp23
-rw-r--r--editor/editor_help.cpp319
-rw-r--r--editor/editor_help.h5
-rw-r--r--editor/editor_log.cpp31
-rw-r--r--editor/editor_log.h3
-rw-r--r--editor/editor_node.cpp119
-rw-r--r--editor/editor_node.h5
-rw-r--r--editor/editor_plugin.cpp10
-rw-r--r--editor/editor_plugin.h3
-rw-r--r--editor/editor_profiler.cpp11
-rw-r--r--editor/editor_run.cpp4
-rw-r--r--editor/editor_settings.cpp32
-rw-r--r--editor/editor_themes.cpp688
-rw-r--r--editor/filesystem_dock.cpp70
-rw-r--r--editor/filesystem_dock.h1
-rw-r--r--editor/icons/SCsub26
-rw-r--r--editor/icons/icon_GUI_hslider_bg.svg5
-rw-r--r--editor/icons/icon_GUI_tab.svg5
-rw-r--r--editor/icons/icon_GUI_vslider_bg.svg5
-rw-r--r--editor/icons/icon_a_r_v_r_camera.svg3
-rw-r--r--editor/icons/icon_area.svg2
-rw-r--r--editor/icons/icon_error.svg2
-rw-r--r--editor/icons/icon_error_sign.svg5
-rw-r--r--editor/icons/icon_file.svg7
-rw-r--r--editor/icons/icon_file_big_thumb.svg (renamed from editor/icons/icon_file_big.svg)0
-rw-r--r--editor/icons/icon_file_broken.svg2
-rw-r--r--editor/icons/icon_file_broken_big_thumb.svg (renamed from editor/icons/icon_file_big_broken.svg)2
-rw-r--r--editor/icons/icon_file_dead.svg2
-rw-r--r--editor/icons/icon_file_dead_big_thumb.svg (renamed from editor/icons/icon_file_big_dead.svg)2
-rw-r--r--editor/icons/icon_file_dead_medium_thumb.svg7
-rw-r--r--editor/icons/icon_file_medium_thumb.svg7
-rw-r--r--editor/icons/icon_folder_big.svg5
-rw-r--r--editor/icons/icon_folder_big_thumb.svg5
-rw-r--r--editor/icons/icon_folder_medium_thumb.svg5
-rw-r--r--editor/icons/icon_godot.svg3
-rw-r--r--editor/icons/icon_godot_docs.svg31
-rw-r--r--editor/icons/icon_gui_close_customizable.svg5
-rw-r--r--editor/icons/icon_gui_graph_node_port.svg5
-rw-r--r--editor/icons/icon_gui_resizer.svg3
-rw-r--r--editor/icons/icon_import_check.svg2
-rw-r--r--editor/icons/icon_import_fail.svg2
-rw-r--r--editor/icons/icon_key_invalid.svg2
-rw-r--r--editor/icons/icon_key_move_disabled.svg4
-rw-r--r--editor/icons/icon_key_move_enabled.svg4
-rw-r--r--editor/icons/icon_key_rotate_disabled.svg4
-rw-r--r--editor/icons/icon_key_rotate_enabled.svg4
-rw-r--r--editor/icons/icon_key_scale_disabled.svg4
-rw-r--r--editor/icons/icon_key_scale_enabled.svg4
-rw-r--r--editor/icons/icon_logo.svg7
-rw-r--r--editor/icons/icon_node_warning.svg2
-rw-r--r--editor/icons/icon_sample_library.svg5
-rw-r--r--editor/icons/icon_slider_joint.svg7
-rw-r--r--editor/icons/icon_snap.svg101
-rw-r--r--editor/icons/icon_snap_grid.svg92
-rw-r--r--editor/icons/icon_warning.svg2
-rw-r--r--editor/import/resource_importer_scene.cpp14
-rw-r--r--editor/import/resource_importer_scene.h8
-rw-r--r--editor/import/resource_importer_texture.cpp7
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp1439
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h119
-rw-r--r--editor/plugins/navigation_mesh_editor_plugin.cpp165
-rw-r--r--editor/plugins/navigation_mesh_editor_plugin.h86
-rw-r--r--editor/plugins/navigation_mesh_generator.cpp311
-rw-r--r--editor/plugins/navigation_mesh_generator.h65
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp76
-rw-r--r--editor/plugins/script_editor_plugin.h6
-rw-r--r--editor/plugins/script_text_editor.cpp147
-rw-r--r--editor/plugins/shader_editor_plugin.cpp115
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp134
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp36
-rw-r--r--editor/plugins/tile_map_editor_plugin.h3
-rw-r--r--editor/project_export.cpp4
-rw-r--r--editor/project_manager.cpp371
-rw-r--r--editor/project_manager.h3
-rw-r--r--editor/property_editor.cpp8
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/scene_tree_dock.cpp1
-rw-r--r--editor/script_editor_debugger.cpp1
-rw-r--r--editor/script_editor_debugger.h2
95 files changed, 3946 insertions, 1516 deletions
diff --git a/editor/SCsub b/editor/SCsub
index 0e690cf465..315865ad32 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -41,11 +41,8 @@ def make_doc_header(target, source, env):
src = s.srcnode().abspath
f = open_utf8(src, "r")
content = f.read()
- buf += content[content.find("<class"): content.rfind("</doc>")]
- if len(docbegin) == 0:
- docbegin = content[0: content.find("<class")]
- if len(docend) == 0:
- docend = content[content.rfind("</doc>"): len(buf)]
+ buf+=content
+
buf = encode_utf8(docbegin + buf + docend)
decomp_size = len(buf)
import zlib
@@ -60,6 +57,7 @@ def make_doc_header(target, source, env):
for i in range(len(buf)):
g.write(byte_to_str(buf[i]) + ",\n")
g.write("};\n")
+
g.write("#endif")
@@ -385,6 +383,18 @@ def make_license_header(target, source, env):
g.write("#endif\n")
+
+def _make_doc_data_class_path(to_path):
+ g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w")
+ g.write("static const int _doc_data_class_path_count="+str(len(env.doc_class_path))+";\n")
+ g.write("struct _DocDataClassPath { const char* name; const char* path; };\n")
+
+ g.write("static const _DocDataClassPath _doc_data_class_paths["+str(len(env.doc_class_path)+1)+"]={\n");
+ for c in env.doc_class_path:
+ g.write("{\""+c+"\",\""+env.doc_class_path[c]+"\"},\n")
+ g.write("{NULL,NULL}\n")
+ g.write("};\n")
+
if (env["tools"] == "yes"):
# Register exporters
@@ -401,16 +411,15 @@ if (env["tools"] == "yes"):
f.close()
# API documentation
- docs = ["#doc/base/classes.xml"]
- moduledir = os.path.join(os.getcwd(), "..", "modules")
- for m in os.listdir(moduledir):
- curmodle = os.path.join(moduledir, m)
- docfile = os.path.join(curmodle, "classes.xml")
- if os.path.isdir(curmodle) and os.path.isfile(docfile):
- docs.append(docfile)
+ docs=[]
+ print("cdir is: "+env.Dir('#').abspath)
+ for f in os.listdir(os.path.join(env.Dir('#').abspath,"doc/classes")):
+ docs.append("#doc/classes/"+f)
+
+ _make_doc_data_class_path(os.path.join(env.Dir('#').abspath,"editor/doc"))
+
env.Depends("#editor/doc_data_compressed.gen.h", docs)
env.Command("#editor/doc_data_compressed.gen.h", docs, make_doc_header)
-
# Certificates
env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt")
env.Command("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header)
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp
index f4e3bf4894..96e5627bef 100644
--- a/editor/animation_editor.cpp
+++ b/editor/animation_editor.cpp
@@ -1038,7 +1038,7 @@ void AnimationKeyEditor::_track_pos_draw() {
//draw position
int pixel = (timeline_pos - h_scroll->get_value()) * zoom_scale;
pixel += name_limit;
- track_pos->draw_line(ofs + Point2(pixel, 0), ofs + Point2(pixel, size.height), get_color("highlight_color", "Editor"));
+ track_pos->draw_line(ofs + Point2(pixel, 0), ofs + Point2(pixel, size.height), get_color("accent_color", "Editor"));
}
}
@@ -1101,7 +1101,7 @@ void AnimationKeyEditor::_track_editor_draw() {
Color select_color = color;
select_color.a = 0.1;
Color invalid_path_color = get_color("error_color", "Editor");
- Color track_select_color = get_color("highlight_color", "Editor");
+ Color track_select_color = get_color("accent", "Editor");
Ref<Texture> remove_icon = get_icon("Remove", "EditorIcons");
Ref<Texture> move_up_icon = get_icon("MoveUp", "EditorIcons");
@@ -1487,7 +1487,7 @@ void AnimationKeyEditor::_track_editor_draw() {
switch (click.click) {
case ClickOver::CLICK_SELECT_KEYS: {
- Color box_color = get_color("highlight_color", "Editor");
+ Color box_color = get_color("accent_color", "Editor");
box_color.a = 0.35;
te->draw_rect(Rect2(click.at, click.to - click.at), box_color);
@@ -2898,10 +2898,6 @@ void AnimationKeyEditor::_notification(int p_what) {
zoomicon->set_custom_minimum_size(Size2(24 * EDSCALE, 0));
zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
- menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue", "EditorIcons"), "Add Normal Track", ADD_TRACK_MENU_ADD_VALUE_TRACK);
- menu_add_track->get_popup()->add_icon_item(get_icon("KeyXform", "EditorIcons"), "Add Transform Track", ADD_TRACK_MENU_ADD_TRANSFORM_TRACK);
- menu_add_track->get_popup()->add_icon_item(get_icon("KeyCall", "EditorIcons"), "Add Call Func Track", ADD_TRACK_MENU_ADD_CALL_TRACK);
-
menu_track->set_icon(get_icon("Tools", "EditorIcons"));
menu_track->get_popup()->add_item(TTR("Scale Selection"), TRACK_MENU_SCALE);
menu_track->get_popup()->add_item(TTR("Scale From Cursor"), TRACK_MENU_SCALE_PIVOT);
@@ -3817,6 +3813,9 @@ AnimationKeyEditor::AnimationKeyEditor() {
hb->add_child(menu_add_track);
menu_add_track->get_popup()->connect("id_pressed", this, "_menu_add_track");
menu_add_track->set_tooltip(TTR("Add new tracks."));
+ menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue", "EditorIcons"), "Add Normal Track", ADD_TRACK_MENU_ADD_VALUE_TRACK);
+ menu_add_track->get_popup()->add_icon_item(get_icon("KeyXform", "EditorIcons"), "Add Transform Track", ADD_TRACK_MENU_ADD_TRANSFORM_TRACK);
+ menu_add_track->get_popup()->add_icon_item(get_icon("KeyCall", "EditorIcons"), "Add Call Func Track", ADD_TRACK_MENU_ADD_CALL_TRACK);
move_up_button = memnew(ToolButton);
hb->add_child(move_up_button);
@@ -3934,7 +3933,7 @@ AnimationKeyEditor::AnimationKeyEditor() {
key_editor_tab = memnew(TabContainer);
key_editor_tab->set_tab_align(TabContainer::ALIGN_LEFT);
hb->add_child(key_editor_tab);
- key_editor_tab->set_custom_minimum_size(Size2(200, 0));
+ key_editor_tab->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
key_editor = memnew(PropertyEditor);
key_editor->set_area_as_parent_rect();
@@ -4052,8 +4051,6 @@ AnimationKeyEditor::AnimationKeyEditor() {
cleanup_dialog->connect("confirmed", this, "_menu_track", varray(TRACK_MENU_CLEAN_UP_CONFIRM));
- add_constant_override("separation", get_constant("separation", "VBoxContainer"));
-
track_editor->set_clip_contents(true);
}
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 8c153d2745..5dd8b8a800 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1023,8 +1023,10 @@ void CodeTextEditor::_line_col_changed() {
void CodeTextEditor::_text_changed() {
- code_complete_timer->start();
- idle->start();
+ if (text_editor->is_insert_text_operation()) {
+ code_complete_timer->start();
+ idle->start();
+ }
}
void CodeTextEditor::_code_complete_timer_timeout() {
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 344cb87aa6..33734957e2 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -54,12 +54,7 @@ void CreateDialog::popup_create(bool p_dontclear) {
TreeItem *ti = recent->create_item(root);
ti->set_text(0, l);
- if (has_icon(l, "EditorIcons")) {
-
- ti->set_icon(0, get_icon(l, "EditorIcons"));
- } else {
- ti->set_icon(0, get_icon("Object", "EditorIcons"));
- }
+ ti->set_icon(0, _get_editor_icon(l));
}
}
@@ -122,6 +117,29 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
}
}
+Ref<Texture> CreateDialog::_get_editor_icon(const String &p_type) const {
+
+ if (has_icon(p_type, "EditorIcons")) {
+ return get_icon(p_type, "EditorIcons");
+ }
+
+ const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types();
+ for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) {
+ const Vector<EditorData::CustomType> &ct = E->value();
+ for (int i = 0; i < ct.size(); ++i) {
+ if (ct[i].name == p_type) {
+ if (ct[i].icon.is_valid()) {
+ return ct[i].icon;
+ } else {
+ return get_icon("Object", "EditorIcons");
+ }
+ }
+ }
+ }
+
+ return get_icon("Object", "EditorIcons");
+}
+
void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) {
if (p_types.has(p_type))
@@ -457,13 +475,7 @@ void CreateDialog::_update_favorite_list() {
TreeItem *ti = favorites->create_item(root);
String l = favorite_list[i];
ti->set_text(0, l);
-
- if (has_icon(l, "EditorIcons")) {
-
- ti->set_icon(0, get_icon(l, "EditorIcons"));
- } else {
- ti->set_icon(0, get_icon("Object", "EditorIcons"));
- }
+ ti->set_icon(0, _get_editor_icon(l));
}
}
@@ -625,6 +637,7 @@ CreateDialog::CreateDialog() {
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
search_hb->add_child(search_box);
favorite = memnew(Button);
+ favorite->set_flat(true);
favorite->set_toggle_mode(true);
search_hb->add_child(favorite);
favorite->connect("pressed", this, "_favorite_toggled");
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index 31f106ea22..a523539ba0 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -74,6 +74,8 @@ class CreateDialog : public ConfirmationDialog {
void _confirmed();
void _text_changed(const String &p_newtext);
+ Ref<Texture> _get_editor_icon(const String &p_type) const;
+
void add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 6848c43b68..d35dc53ae1 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -32,6 +32,7 @@
#include "global_constants.h"
#include "io/compression.h"
#include "io/marshalls.h"
+#include "os/dir_access.h"
#include "project_settings.h"
#include "scene/resources/theme.h"
#include "script_language.h"
@@ -50,6 +51,8 @@ void DocData::merge_from(const DocData &p_data) {
c.description = cf.description;
c.brief_description = cf.brief_description;
+ c.tutorials = cf.tutorials;
+ c.demos = cf.demos;
for (int i = 0; i < c.methods.size(); i++) {
@@ -167,6 +170,8 @@ static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const Property
if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_method.return_enum = p_retinfo.class_name;
+ if (p_method.return_enum.begins_with("_")) //proxy class
+ p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
p_method.return_type = "int";
} else if (p_retinfo.class_name != StringName()) {
p_method.return_type = p_retinfo.class_name;
@@ -187,6 +192,8 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr
if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_argument.enumeration = p_arginfo.class_name;
+ if (p_argument.enumeration.begins_with("_")) //proxy class
+ p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
p_argument.type = "int";
} else if (p_arginfo.class_name != StringName()) {
p_argument.type = p_arginfo.class_name;
@@ -675,36 +682,72 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
return OK;
}
-Error DocData::load(const String &p_path) {
+Error DocData::load_classes(const String &p_dir) {
- Ref<XMLParser> parser = memnew(XMLParser);
- Error err = parser->open(p_path);
- if (err)
+ Error err;
+ DirAccessRef da = DirAccess::open(p_dir, &err);
+ if (!da) {
return err;
- return _load(parser);
-}
-Error DocData::_load(Ref<XMLParser> parser) {
+ }
- Error err = OK;
+ da->list_dir_begin();
+ String path;
+ bool isdir;
+ path = da->get_next(&isdir);
+ while (path != String()) {
+ if (!isdir && path.ends_with("xml")) {
+ Ref<XMLParser> parser = memnew(XMLParser);
+ Error err = parser->open(p_dir.plus_file(path));
+ if (err)
+ return err;
+
+ _load(parser);
+ }
+ path = da->get_next(&isdir);
+ }
- while ((err = parser->read()) == OK) {
+ da->list_dir_end();
- if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
+ return OK;
+}
+Error DocData::erase_classes(const String &p_dir) {
- if (parser->get_node_name() == "doc") {
- break;
- } else if (!parser->is_empty())
- parser->skip_section(); // unknown section, likely headers
+ Error err;
+ DirAccessRef da = DirAccess::open(p_dir, &err);
+ if (!da) {
+ return err;
+ }
+
+ List<String> to_erase;
+
+ da->list_dir_begin();
+ String path;
+ bool isdir;
+ path = da->get_next(&isdir);
+ while (path != String()) {
+ if (!isdir && path.ends_with("xml")) {
+ to_erase.push_back(path);
}
+ path = da->get_next(&isdir);
+ }
+ da->list_dir_end();
+
+ while (to_erase.size()) {
+ da->remove(to_erase.front()->get());
+ to_erase.pop_front();
}
- if (parser->has_attribute("version"))
- version = parser->get_attribute_value("version");
+ return OK;
+}
+Error DocData::_load(Ref<XMLParser> parser) {
+
+ Error err = OK;
while ((err = parser->read()) == OK) {
- if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "doc")
- break; //end of <doc>
+ if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "?xml") {
+ parser->skip_section();
+ }
if (parser->get_node_type() != XMLParser::NODE_ELEMENT)
continue; //no idea what this may be, but skipping anyway
@@ -739,6 +782,14 @@ Error DocData::_load(Ref<XMLParser> parser) {
parser->read();
if (parser->get_node_type() == XMLParser::NODE_TEXT)
c.description = parser->get_node_data().strip_edges();
+ } else if (name == "tutorials") {
+ parser->read();
+ if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ c.tutorials = parser->get_node_data().strip_edges();
+ } else if (name == "demos") {
+ parser->read();
+ if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ c.demos = parser->get_node_data().strip_edges();
} else if (name == "methods") {
Error err = _parse_methods(parser, c.methods);
@@ -768,8 +819,6 @@ Error DocData::_load(Ref<XMLParser> parser) {
prop.setter = parser->get_attribute_value("setter");
if (parser->has_attribute("getter"))
prop.getter = parser->get_attribute_value("getter");
- if (parser->has_attribute("brief"))
- prop.brief_description = parser->get_attribute_value("brief").xml_unescape();
if (parser->has_attribute("enum"))
prop.enumeration = parser->get_attribute_value("enum");
parser->read();
@@ -867,23 +916,29 @@ static void _write_string(FileAccess *f, int p_tablevel, const String &p_string)
f->store_string(tab + p_string + "\n");
}
-Error DocData::save(const String &p_path) {
+Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) {
- Error err;
- FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) {
- if (err) {
- ERR_EXPLAIN("Can't write doc file: " + p_path);
+ ClassDoc &c = E->get();
- ERR_FAIL_V(err);
- }
+ String save_path;
+ if (p_class_path.has(c.name)) {
+ save_path = p_class_path[c.name];
+ } else {
+ save_path = p_default_path;
+ }
- _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
- _write_string(f, 0, "<doc version=\"" + String(VERSION_MKSTRING) + "\" name=\"Engine Types\">");
+ Error err;
+ String save_file = save_path.plus_file(c.name + ".xml");
+ FileAccessRef f = FileAccess::open(save_file, FileAccess::WRITE, &err);
+ if (err) {
+ ERR_EXPLAIN("Can't write doc file: " + save_file);
- for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) {
+ ERR_FAIL_V(err);
+ }
- ClassDoc &c = E->get();
+ _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
String header = "<class name=\"" + c.name + "\"";
if (c.inherits != "")
@@ -893,6 +948,7 @@ Error DocData::save(const String &p_path) {
if (c.category == "")
category = "Core";
header += " category=\"" + category + "\"";
+ header += " version=\"" + String(VERSION_MKSTRING) + "\"";
header += ">";
_write_string(f, 0, header);
_write_string(f, 1, "<brief_description>");
@@ -903,6 +959,14 @@ Error DocData::save(const String &p_path) {
if (c.description != "")
_write_string(f, 2, c.description.xml_escape());
_write_string(f, 1, "</description>");
+ _write_string(f, 1, "<tutorials>");
+ if (c.tutorials != "")
+ _write_string(f, 2, c.tutorials.xml_escape());
+ _write_string(f, 1, "</tutorials>");
+ _write_string(f, 1, "<demos>");
+ if (c.demos != "")
+ _write_string(f, 2, c.demos.xml_escape());
+ _write_string(f, 1, "</demos>");
_write_string(f, 1, "<methods>");
c.methods.sort();
@@ -966,7 +1030,7 @@ Error DocData::save(const String &p_path) {
enum_text = " enum=\"" + c.properties[i].enumeration + "\"";
}
PropertyDoc &p = c.properties[i];
- _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" brief=\"" + p.brief_description.xml_escape(true) + "\"" + enum_text + ">");
+ _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + enum_text + ">");
if (p.description != "")
_write_string(f, 3, p.description.xml_escape());
_write_string(f, 2, "</member>");
@@ -1035,10 +1099,6 @@ Error DocData::save(const String &p_path) {
_write_string(f, 0, "</class>");
}
- _write_string(f, 0, "</doc>");
- f->close();
- memdelete(f);
-
return OK;
}
diff --git a/editor/doc/doc_data.h b/editor/doc/doc_data.h
index efb4ea3040..68d30d8237 100644
--- a/editor/doc/doc_data.h
+++ b/editor/doc/doc_data.h
@@ -70,7 +70,6 @@ public:
String name;
String type;
String enumeration;
- String brief_description;
String description;
String setter, getter;
bool operator<(const PropertyDoc &p_prop) const {
@@ -85,6 +84,8 @@ public:
String category;
String brief_description;
String description;
+ String tutorials;
+ String demos;
Vector<MethodDoc> methods;
Vector<MethodDoc> signals;
Vector<ConstantDoc> constants;
@@ -101,8 +102,9 @@ public:
void merge_from(const DocData &p_data);
void remove_from(const DocData &p_data);
void generate(bool p_basic_types = false);
- Error load(const String &p_path);
- Error save(const String &p_path);
+ Error load_classes(const String &p_dir);
+ static Error erase_classes(const String &p_dir);
+ Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path);
Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size);
};
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 29159c7ad5..a36faeb0de 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -39,10 +39,13 @@ void EditorAudioBus::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
- vu_l->set_under_texture(get_icon("BusVuEmpty", "EditorIcons"));
- vu_l->set_progress_texture(get_icon("BusVuFull", "EditorIcons"));
- vu_r->set_under_texture(get_icon("BusVuEmpty", "EditorIcons"));
- vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons"));
+ for (int i = 0; i < cc; i++) {
+ channel[i].vu_l->set_under_texture(get_icon("BusVuEmpty", "EditorIcons"));
+ channel[i].vu_l->set_progress_texture(get_icon("BusVuFull", "EditorIcons"));
+ channel[i].vu_r->set_under_texture(get_icon("BusVuEmpty", "EditorIcons"));
+ channel[i].vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons"));
+ channel[i].prev_active = true;
+ }
scale->set_texture(get_icon("BusVuDb", "EditorIcons"));
disabled_vu = get_icon("BusVuFrozen", "EditorIcons");
@@ -53,7 +56,6 @@ void EditorAudioBus::_notification(int p_what) {
bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
- prev_active = true;
update_bus();
set_process(true);
}
@@ -67,60 +69,52 @@ void EditorAudioBus::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
- float real_peak[2] = { -100, -100 };
- bool activity_found = false;
-
- int cc = 0;
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
- case AudioServer::SPEAKER_MODE_STEREO: cc = 1; break;
- case AudioServer::SPEAKER_SURROUND_51: cc = 4; break;
- case AudioServer::SPEAKER_SURROUND_71: cc = 5; break;
- default:
- ERR_PRINT("Unknown speaker_mode");
- break;
- }
-
for (int i = 0; i < cc; i++) {
+ float real_peak[2] = { -100, -100 };
+ bool activity_found = false;
+
if (AudioServer::get_singleton()->is_bus_channel_active(get_index(), i)) {
activity_found = true;
real_peak[0] = MAX(real_peak[0], AudioServer::get_singleton()->get_bus_peak_volume_left_db(get_index(), i));
real_peak[1] = MAX(real_peak[1], AudioServer::get_singleton()->get_bus_peak_volume_right_db(get_index(), i));
}
- }
- if (real_peak[0] > peak_l) {
- peak_l = real_peak[0];
- } else {
- peak_l -= get_process_delta_time() * 60.0;
- }
-
- if (real_peak[1] > peak_r) {
- peak_r = real_peak[1];
- } else {
- peak_r -= get_process_delta_time() * 60.0;
- }
-
- vu_l->set_value(peak_l);
- vu_r->set_value(peak_r);
+ if (real_peak[0] > channel[i].peak_l) {
+ channel[i].peak_l = real_peak[0];
+ } else {
+ channel[i].peak_l -= get_process_delta_time() * 60.0;
+ }
- if (activity_found != prev_active) {
- if (activity_found) {
- vu_l->set_over_texture(Ref<Texture>());
- vu_r->set_over_texture(Ref<Texture>());
+ if (real_peak[1] > channel[i].peak_r) {
+ channel[i].peak_r = real_peak[1];
} else {
- vu_l->set_over_texture(disabled_vu);
- vu_r->set_over_texture(disabled_vu);
+ channel[i].peak_r -= get_process_delta_time() * 60.0;
}
- prev_active = activity_found;
+ channel[i].vu_l->set_value(channel[i].peak_l);
+ channel[i].vu_r->set_value(channel[i].peak_r);
+
+ if (activity_found != channel[i].prev_active) {
+ if (activity_found) {
+ channel[i].vu_l->set_over_texture(Ref<Texture>());
+ channel[i].vu_r->set_over_texture(Ref<Texture>());
+ } else {
+ channel[i].vu_l->set_over_texture(disabled_vu);
+ channel[i].vu_r->set_over_texture(disabled_vu);
+ }
+
+ channel[i].prev_active = activity_found;
+ }
}
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
- peak_l = -100;
- peak_r = -100;
- prev_active = true;
+ for (int i = 0; i < 4; i++) {
+ channel[i].peak_l = -100;
+ channel[i].peak_r = -100;
+ channel[i].prev_active = true;
+ }
set_process(is_visible_in_tree());
}
@@ -683,19 +677,24 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses) {
slider->connect("value_changed", this, "_volume_db_changed");
hb->add_child(slider);
- vu_l = memnew(TextureProgress);
- vu_l->set_fill_mode(TextureProgress::FILL_BOTTOM_TO_TOP);
- hb->add_child(vu_l);
- vu_l->set_min(-80);
- vu_l->set_max(24);
- vu_l->set_step(0.1);
-
- vu_r = memnew(TextureProgress);
- vu_r->set_fill_mode(TextureProgress::FILL_BOTTOM_TO_TOP);
- hb->add_child(vu_r);
- vu_r->set_min(-80);
- vu_r->set_max(24);
- vu_r->set_step(0.1);
+
+ cc = AudioServer::get_singleton()->get_channel_count();
+
+ for (int i = 0; i < cc; i++) {
+ channel[i].vu_l = memnew(TextureProgress);
+ channel[i].vu_l->set_fill_mode(TextureProgress::FILL_BOTTOM_TO_TOP);
+ hb->add_child(channel[i].vu_l);
+ channel[i].vu_l->set_min(-80);
+ channel[i].vu_l->set_max(24);
+ channel[i].vu_l->set_step(0.1);
+
+ channel[i].vu_r = memnew(TextureProgress);
+ channel[i].vu_r->set_fill_mode(TextureProgress::FILL_BOTTOM_TO_TOP);
+ hb->add_child(channel[i].vu_r);
+ channel[i].vu_r->set_min(-80);
+ channel[i].vu_r->set_max(24);
+ channel[i].vu_r->set_step(0.1);
+ }
scale = memnew(TextureRect);
hb->add_child(scale);
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index 2c61228bde..dba1b73295 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -52,16 +52,23 @@ class EditorAudioBus : public PanelContainer {
GDCLASS(EditorAudioBus, PanelContainer)
- bool prev_active;
- float peak_l;
- float peak_r;
-
Ref<Texture> disabled_vu;
LineEdit *track_name;
MenuButton *bus_options;
VSlider *slider;
- TextureProgress *vu_l;
- TextureProgress *vu_r;
+
+ int cc;
+
+ struct {
+ bool prev_active;
+
+ float peak_l;
+ float peak_r;
+
+ TextureProgress *vu_l;
+ TextureProgress *vu_r;
+ } channel[4];
+
TextureRect *scale;
OptionButton *send;
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index cfb3abfd1d..658c12d4d0 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -64,7 +64,7 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p
}
}
-void EditorDirDialog::reload(const String &p_with_path) {
+void EditorDirDialog::reload(const String &p_path) {
if (!is_visible_in_tree()) {
must_reload = true;
@@ -73,7 +73,7 @@ void EditorDirDialog::reload(const String &p_with_path) {
tree->clear();
TreeItem *root = tree->create_item();
- _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path);
+ _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_path);
_item_collapsed(root);
must_reload = false;
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 8623b9acdb..ad9bc4a662 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -476,19 +476,77 @@ void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &
memdelete(da);
}
-Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata) {
+void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) {
+
+ ExtraFile ef;
+ ef.data = p_file;
+ ef.path = p_path;
+ ef.remap = p_remap;
+ extra_files.push_back(ef);
+}
+
+void EditorExportPlugin::add_shared_object(const String &p_path) {
+
+ shared_objects.push_back(p_path);
+}
+
+void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const PoolVector<String> &p_features) {
+
+ if (get_script_instance()) {
+ get_script_instance()->call("_export_file", p_path, p_type, p_features);
+ }
+}
+
+void EditorExportPlugin::_export_begin_script(const PoolVector<String> &p_features) {
+
+ if (get_script_instance()) {
+ get_script_instance()->call("_export_begin", p_features);
+ }
+}
+
+void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
+}
+
+void EditorExportPlugin::_export_begin(const Set<String> &p_features) {
+}
+
+void EditorExportPlugin::skip() {
+
+ skipped = true;
+}
+
+void EditorExportPlugin::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("add_shared_object", "path"), &EditorExportPlugin::add_shared_object);
+ ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
+ ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
+
+ BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::POOL_STRING_ARRAY, "features")));
+ BIND_VMETHOD(MethodInfo("_export_begin", PropertyInfo(Variant::POOL_STRING_ARRAY, "features")));
+}
+
+EditorExportPlugin::EditorExportPlugin() {
+ skipped = false;
+}
+
+Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
Ref<EditorExportPlatform> platform = p_preset->get_platform();
List<String> feature_list;
platform->get_preset_features(p_preset, &feature_list);
//figure out features
Set<String> features;
+ PoolVector<String> features_pv;
for (List<String>::Element *E = feature_list.front(); E; E = E->next()) {
features.insert(E->get());
+ features_pv.push_back(E->get());
}
+ Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
+
//figure out paths of files that will be exported
Set<String> paths;
+ Vector<String> path_remaps;
if (p_preset->get_export_filter() == EditorExportPreset::EXPORT_ALL_RESOURCES) {
//find stuff
@@ -508,6 +566,25 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
_edit_filter_list(paths, p_preset->get_include_filter(), false);
_edit_filter_list(paths, p_preset->get_exclude_filter(), true);
+ //initial export plugin callback
+ for (int i = 0; i < export_plugins.size(); i++) {
+ if (export_plugins[i]->get_script_instance()) { //script based
+ export_plugins[i]->_export_begin_script(features_pv);
+ } else {
+ export_plugins[i]->_export_begin(features);
+ }
+ if (p_so_func) {
+ for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
+ p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ }
+ }
+ for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
+ p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
+ }
+
+ export_plugins[i]->_clear();
+ }
+
//store everything in the export medium
int idx = 0;
int total = paths.size();
@@ -515,6 +592,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
String path = E->get();
+ String type = ResourceLoader::get_resource_type(path);
if (FileAccess::exists(path + ".import")) {
//file is imported, replace by what it imports
@@ -551,9 +629,42 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
p_func(p_udata, path + ".import", array, idx, total);
} else {
+
+ bool do_export = true;
+ for (int i = 0; i < export_plugins.size(); i++) {
+ if (export_plugins[i]->get_script_instance()) { //script based
+ export_plugins[i]->_export_file_script(path, type, features_pv);
+ } else {
+ export_plugins[i]->_export_file(path, type, features);
+ }
+ if (p_so_func) {
+ for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
+ p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
+ }
+ }
+
+ for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
+ p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total);
+ if (export_plugins[i]->extra_files[j].remap) {
+ do_export = false; //if remap, do not
+ path_remaps.push_back(path);
+ path_remaps.push_back(export_plugins[i]->extra_files[j].path);
+ }
+ }
+
+ if (export_plugins[i]->skipped) {
+ do_export = false;
+ }
+ export_plugins[i]->_clear();
+
+ if (!do_export)
+ break; //apologies, not exporting
+ }
//just store it as it comes
- Vector<uint8_t> array = FileAccess::get_file_as_array(path);
- p_func(p_udata, path, array, idx, total);
+ if (do_export) {
+ Vector<uint8_t> array = FileAccess::get_file_as_array(path);
+ p_func(p_udata, path, array, idx, total);
+ }
}
idx++;
@@ -575,9 +686,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
}
+ ProjectSettings::CustomMap custom_map;
+ if (path_remaps.size()) {
+ custom_map["path_remap/remapped_paths"] = path_remaps;
+ }
+
String config_file = "project.binary";
String engine_cfb = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp" + config_file;
- ProjectSettings::get_singleton()->save_custom(engine_cfb, ProjectSettings::CustomMap(), custom_list);
+ ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list);
Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);
p_func(p_udata, "res://" + config_file, data, idx, total);
@@ -867,6 +983,23 @@ void EditorExport::remove_export_preset(int p_idx) {
export_presets.remove(p_idx);
}
+void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
+
+ if (export_plugins.find(p_plugin) == 1) {
+ export_plugins.push_back(p_plugin);
+ }
+}
+
+void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
+
+ export_plugins.erase(p_plugin);
+}
+
+Vector<Ref<EditorExportPlugin> > EditorExport::get_export_plugins() {
+
+ return export_plugins;
+}
+
void EditorExport::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -1113,9 +1246,13 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
}
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->copy(template_path, p_path);
+ Error err = da->copy(template_path, p_path, get_chmod_flags());
memdelete(da);
+ if (err != OK) {
+ return err;
+ }
+
String pck_path = p_path.get_basename() + ".pck";
return save_pack(p_preset, pck_path);
@@ -1169,5 +1306,17 @@ void EditorExportPlatformPC::get_platform_features(List<String> *r_features) {
}
}
+int EditorExportPlatformPC::get_chmod_flags() const {
+
+ return chmod_flags;
+}
+
+void EditorExportPlatformPC::set_chmod_flags(int p_flags) {
+
+ chmod_flags = p_flags;
+}
+
EditorExportPlatformPC::EditorExportPlatformPC() {
+
+ chmod_flags = -1;
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index 3b99c68c85..50379b9683 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -124,6 +124,7 @@ class EditorExportPlatform : public Reference {
public:
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
+ typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const String &p_path);
private:
struct SavedData {
@@ -189,7 +190,7 @@ public:
virtual String get_name() const = 0;
virtual Ref<Texture> get_logo() const = 0;
- Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata);
+ Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = NULL);
Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path);
@@ -219,11 +220,49 @@ public:
EditorExportPlatform();
};
+class EditorExportPlugin : public Reference {
+ GDCLASS(EditorExportPlugin, Reference)
+
+ friend class EditorExportPlatform;
+
+ Vector<String> shared_objects;
+ struct ExtraFile {
+ String path;
+ Vector<uint8_t> data;
+ bool remap;
+ };
+ Vector<ExtraFile> extra_files;
+ bool skipped;
+
+ _FORCE_INLINE_ void _clear() {
+ shared_objects.clear();
+ extra_files.clear();
+ skipped = false;
+ }
+
+ void _export_file_script(const String &p_path, const String &p_type, const PoolVector<String> &p_features);
+ void _export_begin_script(const PoolVector<String> &p_features);
+
+protected:
+ void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap);
+ void add_shared_object(const String &p_path);
+ void skip();
+
+ virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
+ virtual void _export_begin(const Set<String> &p_features);
+
+ static void _bind_methods();
+
+public:
+ EditorExportPlugin();
+};
+
class EditorExport : public Node {
GDCLASS(EditorExport, Node);
Vector<Ref<EditorExportPlatform> > export_platforms;
Vector<Ref<EditorExportPreset> > export_presets;
+ Vector<Ref<EditorExportPlugin> > export_plugins;
Timer *save_timer;
bool block_save;
@@ -251,6 +290,10 @@ public:
Ref<EditorExportPreset> get_export_preset(int p_idx);
void remove_export_preset(int p_idx);
+ void add_export_plugin(const Ref<EditorExportPlugin> &p_plugin);
+ void remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin);
+ Vector<Ref<EditorExportPlugin> > get_export_plugins();
+
void load_config();
bool poll_export_platforms();
@@ -276,6 +319,7 @@ class EditorExportPlatformPC : public EditorExportPlatform {
Set<String> extra_features;
bool use64;
+ int chmod_flags;
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
@@ -304,6 +348,9 @@ public:
void add_platform_feature(const String &p_feature);
virtual void get_platform_features(List<String> *r_features);
+ int get_chmod_flags() const;
+ void set_chmod_flags(int p_flags);
+
EditorExportPlatformPC();
};
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index abcdc0b64c..8d13153128 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -107,8 +107,6 @@ void EditorFileDialog::_notification(int p_what) {
fav_down->set_icon(get_icon("MoveDown", "EditorIcons"));
fav_rm->set_icon(get_icon("RemoveSmall", "EditorIcons"));
- Theme::get_default()->clear_icon("ResizedFile", "EditorIcons");
- Theme::get_default()->clear_icon("ResizedFolder", "EditorIcons");
update_file_list();
}
}
@@ -506,30 +504,14 @@ void EditorFileDialog::update_file_list() {
item_list->set_max_text_lines(2);
item_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
- if (!has_icon("ResizedFolder", "EditorIcons")) {
- Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
- Ref<Image> img = folder->get_data();
- img = img->duplicate();
- 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");
- Ref<Image> img = file->get_data();
- img = img->duplicate();
- 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);
+ if (thumbnail_size < 64) {
+ folder_thumbnail = get_icon("FolderMediumThumb", "EditorIcons");
+ file_thumbnail = get_icon("FileMediumThumb", "EditorIcons");
+ } else {
+ folder_thumbnail = get_icon("FolderBigThumb", "EditorIcons");
+ file_thumbnail = get_icon("FileBigThumb", "EditorIcons");
}
- file_thumbnail = get_icon("ResizedFile", "EditorIcons");
-
preview_vb->hide();
} else {
@@ -1214,6 +1196,9 @@ void EditorFileDialog::_bind_methods() {
BIND_ENUM_CONSTANT(ACCESS_RESOURCES);
BIND_ENUM_CONSTANT(ACCESS_USERDATA);
BIND_ENUM_CONSTANT(ACCESS_FILESYSTEM);
+
+ BIND_ENUM_CONSTANT(DISPLAY_THUMBNAILS);
+ BIND_ENUM_CONSTANT(DISPLAY_LIST);
}
void EditorFileDialog::set_show_hidden_files(bool p_show) {
@@ -1314,6 +1299,7 @@ EditorFileDialog::EditorFileDialog() {
pathhb->add_child(refresh);
favorite = memnew(ToolButton);
+ favorite->set_flat(true);
favorite->set_toggle_mode(true);
favorite->connect("toggled", this, "_favorite_toggled");
pathhb->add_child(favorite);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 3ab3f05906..345c7b1f65 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -73,13 +73,13 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
m_name->add_fallback(FontFallback);
// the custom spacings might only work with Noto Sans
-#define MAKE_DEFAULT_FONT(m_name, m_size) \
- Ref<DynamicFont> m_name; \
- m_name.instance(); \
- m_name->set_size(m_size); \
- m_name->set_font_data(DefaultFont); \
- m_name->set_spacing(DynamicFont::SPACING_TOP, -1); \
- m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -1); \
+#define MAKE_DEFAULT_FONT(m_name, m_size) \
+ Ref<DynamicFont> m_name; \
+ m_name.instance(); \
+ m_name->set_size(m_size); \
+ m_name->set_font_data(DefaultFont); \
+ m_name->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE); \
+ m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE); \
MAKE_FALLBACKS(m_name);
void editor_register_fonts(Ref<Theme> p_theme) {
@@ -119,7 +119,7 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<DynamicFontData> dfmono;
dfmono.instance();
- dfmono->set_font_ptr(_font_source_code_pro, _font_source_code_pro_size);
+ dfmono->set_font_ptr(_font_mononoki_Regular, _font_mononoki_Regular_size);
//dfd->set_force_autohinter(true); //just looks better..i think?
MAKE_DEFAULT_FONT(df, int(EditorSettings::get_singleton()->get("interface/font_size")) * EDSCALE);
@@ -137,6 +137,9 @@ void editor_register_fonts(Ref<Theme> p_theme) {
p_theme->set_font("doc", "EditorFonts", df_doc);
p_theme->set_font("doc_title", "EditorFonts", df_title);
+ MAKE_DEFAULT_FONT(df_rulers, int(EDITOR_DEF("canvas_item_editor/rulers", 8)) * EDSCALE);
+ p_theme->set_font("rulers", "EditorFonts", df_rulers);
+
Ref<DynamicFont> df_code;
df_code.instance();
df_code->set_size(int(EditorSettings::get_singleton()->get("interface/source_font_size")) * EDSCALE);
@@ -147,7 +150,9 @@ void editor_register_fonts(Ref<Theme> p_theme) {
Ref<DynamicFont> df_doc_code;
df_doc_code.instance();
- df_doc_code->set_size(int(EDITOR_DEF("text_editor/help/help_source_font_size", 14)) * EDSCALE);
+ df_doc_code->set_size(int(EDITOR_DEF("text_editor/help/help_source_font_size", 18)) * EDSCALE);
+ df_doc_code->set_spacing(DynamicFont::SPACING_TOP, -EDSCALE);
+ df_doc_code->set_spacing(DynamicFont::SPACING_BOTTOM, -EDSCALE);
df_doc_code->set_font_data(dfmono);
MAKE_FALLBACKS(df_doc_code);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 7fa2c53275..6c8bd0f14b 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -35,6 +35,8 @@
#include "editor_settings.h"
#include "os/keyboard.h"
+#define CONTRIBUTE_URL "http://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html"
+
void EditorHelpSearch::popup() {
popup_centered(Size2(700, 600) * EDSCALE);
@@ -575,6 +577,8 @@ void EditorHelp::_class_desc_select(const String &p_select) {
return;
class_desc->scroll_to_line(method_line[m]);
}
+ } else if (p_select.begins_with("http")) {
+ OS::get_singleton()->shell_open(p_select);
}
}
@@ -603,7 +607,9 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
t = p_enum.get_slice(".", 0);
}
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+ const Color text_color = get_color("default_color", "RichTextLabel");
+ const Color type_color = get_color("accent_color", "Editor").linear_interpolate(text_color, 0.5);
+ class_desc->push_color(type_color);
if (can_ref) {
if (p_enum == "") {
class_desc->push_meta("#" + t); //class
@@ -638,23 +644,32 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->clear();
method_line.clear();
+ section_line.clear();
edited_class = p_class;
//edited_class->show();
- DocData::ClassDoc cd = doc->class_list[p_class]; //make a copy, so we can sort without worrying
+ // Colors
+ const Color title_color = get_color("accent_color", "Editor");
+ const Color text_color = get_color("font_color", "RichTextLabel");
+ const Color highlight_color = get_color("highlight_color", "RichTextLabel");
+ const Color base_type_color = title_color.linear_interpolate(text_color, 0.5);
+ const Color comment_color = Color(text_color.r, text_color.g, text_color.b, 0.6);
+ const Color symbol_color = comment_color;
+ const Color value_color = Color(text_color.r, text_color.g, text_color.b, 0.4);
+ const Color qualifier_color = Color(text_color.r, text_color.g, text_color.b, 0.8);
- Color h_color;
+ DocData::ClassDoc cd = doc->class_list[p_class]; //make a copy, so we can sort without worrying
Ref<Font> doc_font = get_font("doc", "EditorFonts");
Ref<Font> doc_title_font = get_font("doc_title", "EditorFonts");
Ref<Font> doc_code_font = get_font("doc_source", "EditorFonts");
+ String link_color_text = title_color.to_html(false);
- h_color = Color(1, 1, 1, 1);
-
+ section_line.push_back(Pair<String, int>(TTR("Top"), 0));
class_desc->push_font(doc_title_font);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->add_text(TTR("Class:") + " ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+ class_desc->push_color(highlight_color);
_add_text(p_class);
class_desc->pop();
class_desc->pop();
@@ -663,7 +678,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (cd.inherits != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Inherits:") + " ");
class_desc->pop();
@@ -697,7 +712,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (E->get().inherits == cd.name) {
if (!found) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Inherited by:") + " ");
class_desc->pop();
@@ -725,10 +740,11 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
class_desc->add_newline();
+ class_desc->add_newline();
if (cd.brief_description != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Brief Description:"));
class_desc->pop();
@@ -736,7 +752,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
//class_desc->add_newline();
class_desc->add_newline();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
_add_text(cd.brief_description);
@@ -745,6 +761,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
+ class_desc->add_newline();
}
Set<String> skip_methods;
@@ -752,7 +769,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (cd.properties.size()) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Members"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Members:"));
class_desc->pop();
@@ -770,7 +788,6 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_font(doc_code_font);
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
- class_desc->add_text(" ");
class_desc->pop();
class_desc->pop();
class_desc->pop();
@@ -795,23 +812,11 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
class_desc->push_font(doc_code_font);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(highlight_color);
_add_text(cd.properties[i].name);
if (describe) {
class_desc->pop();
- }
-
- if (cd.properties[i].brief_description != "") {
- class_desc->push_font(doc_font);
- class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
- _add_text(cd.properties[i].description);
- class_desc->pop();
- class_desc->pop();
- }
-
- if (describe) {
property_descr = true;
}
@@ -842,7 +847,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (sort_methods)
methods.sort();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Public Methods"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Public Methods:"));
class_desc->pop();
@@ -859,9 +865,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
bool is_vararg = methods[i].qualifiers.find("vararg") != -1;
- class_desc->push_cell();
-
method_line[methods[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
+
+ class_desc->push_cell();
class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_font(doc_code_font);
_add_type(methods[i].return_type, methods[i].return_enum);
@@ -869,6 +875,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->pop(); //align
class_desc->pop(); //font
class_desc->pop(); //cell
+
class_desc->push_cell();
class_desc->push_font(doc_code_font);
@@ -876,16 +883,16 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
method_descr = true;
class_desc->push_meta("@" + methods[i].name);
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(highlight_color);
_add_text(methods[i].name);
class_desc->pop();
if (methods[i].description != "")
- class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->pop(); // pop meta
+ class_desc->push_color(symbol_color);
class_desc->add_text(methods[i].arguments.size() || is_vararg ? "( " : "(");
class_desc->pop();
for (int j = 0; j < methods[i].arguments.size(); j++) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
if (j > 0)
class_desc->add_text(", ");
_add_type(methods[i].arguments[j].type, methods[i].arguments[j].enumeration);
@@ -893,7 +900,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
_add_text(methods[i].arguments[j].name);
if (methods[i].arguments[j].default_value != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text("=");
class_desc->pop();
_add_text(methods[i].arguments[j].default_value);
@@ -903,21 +910,21 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
if (is_vararg) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
if (methods[i].arguments.size())
class_desc->add_text(", ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text("...");
class_desc->pop();
class_desc->pop();
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(methods[i].arguments.size() || is_vararg ? " )" : ")");
class_desc->pop();
if (methods[i].qualifiers != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(qualifier_color);
class_desc->add_text(" ");
_add_text(methods[i].qualifiers);
class_desc->pop();
@@ -934,24 +941,35 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (cd.theme_properties.size()) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("GUI Theme Items"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("GUI Theme Items:"));
class_desc->pop();
class_desc->pop();
- class_desc->add_newline();
+ // class_desc->add_newline();
class_desc->push_indent(1);
+ class_desc->push_table(2);
+ class_desc->set_table_column_expand(1, 1);
//class_desc->add_newline();
for (int i = 0; i < cd.theme_properties.size(); i++) {
theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
+
+ class_desc->push_cell();
+ class_desc->push_align(RichTextLabel::ALIGN_RIGHT);
class_desc->push_font(doc_code_font);
_add_type(cd.theme_properties[i].type);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
- class_desc->add_text(" ");
+ class_desc->pop();
+ class_desc->pop();
+ class_desc->pop();
+
+ class_desc->push_cell();
+ class_desc->push_font(doc_code_font);
+ class_desc->push_color(highlight_color);
_add_text(cd.theme_properties[i].name);
class_desc->pop();
class_desc->pop();
@@ -959,17 +977,18 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (cd.theme_properties[i].description != "") {
class_desc->push_font(doc_font);
class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+ class_desc->push_color(comment_color);
_add_text(cd.theme_properties[i].description);
class_desc->pop();
class_desc->pop();
}
-
- class_desc->add_newline();
+ class_desc->pop(); // cell
}
+ class_desc->pop(); // table
class_desc->pop();
class_desc->add_newline();
+ class_desc->add_newline();
}
if (cd.signals.size()) {
@@ -977,7 +996,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (sort_methods) {
cd.signals.sort();
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+
+ section_line.push_back(Pair<String, int>(TTR("Signals"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Signals:"));
class_desc->pop();
@@ -994,14 +1015,14 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_font(doc_code_font); // monofont
//_add_type("void");
//class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(highlight_color);
_add_text(cd.signals[i].name);
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(cd.signals[i].arguments.size() ? "( " : "(");
class_desc->pop();
for (int j = 0; j < cd.signals[i].arguments.size(); j++) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
if (j > 0)
class_desc->add_text(", ");
_add_type(cd.signals[i].arguments[j].type);
@@ -1009,7 +1030,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
_add_text(cd.signals[i].arguments[j].name);
if (cd.signals[i].arguments[j].default_value != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text("=");
class_desc->pop();
_add_text(cd.signals[i].arguments[j].default_value);
@@ -1018,13 +1039,13 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->pop();
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(cd.signals[i].arguments.size() ? " )" : ")");
class_desc->pop();
class_desc->pop(); // end monofont
if (cd.signals[i].description != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+ class_desc->push_color(comment_color);
class_desc->add_text(" ");
_add_text(cd.signals[i].description);
class_desc->pop();
@@ -1057,7 +1078,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (enums.size()) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Enumerations:"));
class_desc->pop();
@@ -1071,7 +1093,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
enum_line[E->key()] = class_desc->get_line_count() - 2;
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->add_text(TTR("enum "));
class_desc->pop();
class_desc->push_font(doc_code_font);
@@ -1080,9 +1102,11 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
e = e.get_slice(".", 1);
}
+ class_desc->push_color(highlight_color);
class_desc->add_text(e);
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->pop();
+ class_desc->push_color(symbol_color);
class_desc->add_text(":");
class_desc->pop();
class_desc->add_newline();
@@ -1093,20 +1117,20 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
for (int i = 0; i < enum_list.size(); i++) {
class_desc->push_font(doc_code_font);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+ class_desc->push_color(highlight_color);
_add_text(enum_list[i].name);
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(value_color);
_add_text(enum_list[i].value);
class_desc->pop();
class_desc->pop();
if (enum_list[i].description != "") {
class_desc->push_font(doc_font);
class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+ class_desc->push_color(comment_color);
_add_text(enum_list[i].description);
class_desc->pop();
class_desc->pop();
@@ -1126,7 +1150,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (constants.size()) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Constants:"));
class_desc->pop();
@@ -1140,20 +1165,20 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
constant_line[constants[i].name] = class_desc->get_line_count() - 2;
class_desc->push_font(doc_code_font);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/base_type_color"));
+ class_desc->push_color(highlight_color);
_add_text(constants[i].name);
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(value_color);
_add_text(constants[i].value);
class_desc->pop();
class_desc->pop();
if (constants[i].description != "") {
class_desc->push_font(doc_font);
class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/comment_color"));
+ class_desc->push_color(comment_color);
_add_text(constants[i].description);
class_desc->pop();
class_desc->pop();
@@ -1169,16 +1194,16 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (cd.description != "") {
+ section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_line_count() - 2));
description_line = class_desc->get_line_count() - 2;
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Description:"));
class_desc->pop();
class_desc->pop();
class_desc->add_newline();
- class_desc->add_newline();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
_add_text(cd.description);
@@ -1187,11 +1212,13 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
+ class_desc->add_newline();
}
if (property_descr) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Property Description:"));
class_desc->pop();
@@ -1208,7 +1235,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
_add_type(cd.properties[i].type, cd.properties[i].enumeration);
class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(highlight_color);
_add_text(cd.properties[i].name);
class_desc->pop(); //color
@@ -1221,11 +1248,11 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_font(doc_font);
class_desc->push_indent(2);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(comment_color);
class_desc->add_text("Setter: ");
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->add_text(cd.properties[i].setter + "(value)");
class_desc->pop(); //color
@@ -1239,11 +1266,11 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->push_font(doc_font);
class_desc->push_indent(2);
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(comment_color);
class_desc->add_text("Getter: ");
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->add_text(cd.properties[i].getter + "()");
class_desc->pop(); //color
@@ -1254,10 +1281,18 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->add_newline();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
- _add_text(cd.properties[i].description);
+ if (cd.properties[i].description.strip_edges() != String()) {
+ _add_text(cd.properties[i].description);
+ } else {
+ class_desc->add_image(get_icon("Error", "EditorIcons"));
+ class_desc->add_text(" ");
+ class_desc->push_color(comment_color);
+ class_desc->append_bbcode(TTR("There is currently no description for this property. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text));
+ class_desc->pop();
+ }
class_desc->pop();
class_desc->pop();
class_desc->pop();
@@ -1269,7 +1304,8 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
if (method_descr) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_line_count() - 2));
+ class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
class_desc->add_text(TTR("Method Description:"));
class_desc->pop();
@@ -1288,14 +1324,14 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
_add_type(methods[i].return_type, methods[i].return_enum);
class_desc->add_text(" ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(highlight_color);
_add_text(methods[i].name);
class_desc->pop();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(methods[i].arguments.size() || is_vararg ? "( " : "(");
class_desc->pop();
for (int j = 0; j < methods[i].arguments.size(); j++) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
if (j > 0)
class_desc->add_text(", ");
_add_type(methods[i].arguments[j].type, methods[i].arguments[j].enumeration);
@@ -1303,7 +1339,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
_add_text(methods[i].arguments[j].name);
if (methods[i].arguments[j].default_value != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text("=");
class_desc->pop();
_add_text(methods[i].arguments[j].default_value);
@@ -1313,21 +1349,21 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
if (is_vararg) {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
if (methods[i].arguments.size())
class_desc->add_text(", ");
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text("...");
class_desc->pop();
class_desc->pop();
}
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color"));
+ class_desc->push_color(symbol_color);
class_desc->add_text(methods[i].arguments.size() || is_vararg ? " )" : ")");
class_desc->pop();
if (methods[i].qualifiers != "") {
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ class_desc->push_color(qualifier_color);
class_desc->add_text(" ");
_add_text(methods[i].qualifiers);
class_desc->pop();
@@ -1336,10 +1372,19 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
class_desc->pop();
class_desc->add_newline();
- class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
+ class_desc->push_color(text_color);
class_desc->push_font(doc_font);
class_desc->push_indent(1);
- _add_text(methods[i].description);
+ if (methods[i].description.strip_edges() != String()) {
+ _add_text(methods[i].description);
+ } else {
+ class_desc->add_image(get_icon("Error", "EditorIcons"));
+ class_desc->add_text(" ");
+ class_desc->push_color(comment_color);
+ class_desc->append_bbcode(TTR("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text));
+ class_desc->pop();
+ }
+
class_desc->pop();
class_desc->pop();
class_desc->pop();
@@ -1409,70 +1454,16 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
DocData *doc = EditorHelp::get_doc_data();
String base_path;
- /*p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/text_color"));
- p_rt->push_font( get_font("normal","Fonts") );
- p_rt->push_indent(1);*/
- int pos = 0;
-
Ref<Font> doc_font = p_rt->get_font("doc", "EditorFonts");
Ref<Font> doc_code_font = p_rt->get_font("doc_source", "EditorFonts");
+ Color font_color_hl = p_rt->get_color("highlight_color", "RichTextLabel");
+ Color link_color = p_rt->get_color("accent_color", "Editor").linear_interpolate(font_color_hl, 0.8);
String bbcode = p_bbcode.replace("\t", " ").replace("\r", " ").strip_edges();
- //change newlines for double newlines
- for (int i = 0; i < bbcode.length(); i++) {
-
- //find valid newlines (double)
- if (bbcode[i] == '\n') {
- bool dnl = false;
- int j = i + 1;
- for (; j < p_bbcode.length(); j++) {
- if (bbcode[j] == ' ')
- continue;
- if (bbcode[j] == '\n') {
- dnl = true;
- break;
- }
- break;
- }
-
- if (dnl) {
- bbcode[i] = 0xFFFF;
- //keep
- i = j;
- } else {
- bbcode = bbcode.insert(i, "\n");
- i++;
- //bbcode[i]=' ';
- //i=j-1;
- }
- }
- }
-
- //remove double spaces or spaces after newlines
- for (int i = 0; i < bbcode.length(); i++) {
-
- if (bbcode[i] == ' ' || bbcode[i] == '\n' || bbcode[i] == 0xFFFF) {
-
- for (int j = i + 1; j < p_bbcode.length(); j++) {
- if (bbcode[j] == ' ') {
- bbcode.remove(j);
- j--;
- continue;
- } else {
- break;
- }
- }
- }
- }
-
- //change newlines to double newlines
-
- CharType dnls[2] = { 0xFFFF, 0 };
- bbcode = bbcode.replace(dnls, "\n");
-
List<String> tag_stack;
+ int pos = 0;
while (pos < bbcode.length()) {
int brk_pos = bbcode.find("[", pos);
@@ -1490,7 +1481,6 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
int brk_end = bbcode.find("]", brk_pos + 1);
if (brk_end == -1) {
- //no close, add the rest
p_rt->add_text(bbcode.substr(brk_pos, bbcode.length() - brk_pos));
break;
@@ -1502,6 +1492,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
if (tag_stack.size()) {
}
+
if (!tag_ok) {
p_rt->add_text("[");
@@ -1517,7 +1508,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
} else if (tag.begins_with("method ")) {
String m = tag.substr(7, tag.length());
- p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ p_rt->push_color(link_color);
p_rt->push_meta("@" + m);
p_rt->add_text(m + "()");
p_rt->pop();
@@ -1526,7 +1517,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
} else if (doc->class_list.has(tag)) {
- p_rt->push_color(EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color"));
+ p_rt->push_color(link_color);
p_rt->push_meta("#" + tag);
p_rt->add_text(tag);
p_rt->pop();
@@ -1542,13 +1533,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
} else if (tag == "i") {
//use italics font
- Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color");
- //no italics so emphasize with color
- text_color.r *= 1.1;
- text_color.g *= 1.1;
- text_color.b *= 1.1;
- p_rt->push_color(text_color);
- //p_rt->push_font(get_font("italic","Fonts"));
+ p_rt->push_color(font_color_hl);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "code" || tag == "codeblock") {
@@ -1709,11 +1694,16 @@ void EditorHelp::_notification(int p_what) {
//forward->set_icon(get_icon("Forward","EditorIcons"));
//back->set_icon(get_icon("Back","EditorIcons"));
_update_doc();
+
+ class_desc->add_style_override("normal", class_desc->get_stylebox("code_normal", "RichTextLabel"));
+ class_desc->add_style_override("focus", class_desc->get_stylebox("code_focus", "RichTextLabel"));
+
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
+
} break;
default: break;
@@ -1730,9 +1720,23 @@ void EditorHelp::go_to_class(const String &p_class, int p_scroll) {
_goto_desc(p_class, p_scroll);
}
+Vector<Pair<String, int> > EditorHelp::get_sections() {
+ Vector<Pair<String, int> > sections;
+
+ for (int i = 0; i < section_line.size(); i++) {
+ sections.push_back(Pair<String, int>(section_line[i].first, i));
+ }
+ return sections;
+}
+
+void EditorHelp::scroll_to_section(int p_section_index) {
+ int line = section_line[p_section_index].second;
+ class_desc->scroll_to_line(line);
+}
+
void EditorHelp::popup_search() {
- search_dialog->popup_centered(Size2(250, 80));
+ search_dialog->popup_centered(Size2(250, 80) * EDSCALE);
search->grab_focus();
}
@@ -1784,12 +1788,10 @@ EditorHelp::EditorHelp() {
//class_list->set_selection_enabled(true);
{
- background_panel = memnew(Panel);
- background_panel->set_v_size_flags(SIZE_EXPAND_FILL);
- vbc->add_child(background_panel);
class_desc = memnew(RichTextLabel);
- background_panel->add_child(class_desc);
+ vbc->add_child(class_desc);
class_desc->set_area_as_parent_rect();
+ class_desc->set_v_size_flags(SIZE_EXPAND_FILL);
class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
class_desc->connect("meta_clicked", this, "_class_desc_select");
class_desc->connect("gui_input", this, "_class_desc_input");
@@ -1813,7 +1815,6 @@ EditorHelp::EditorHelp() {
search_dialog->get_ok()->set_text(TTR("Find"));
search_dialog->connect("confirmed", this, "_search_cbk");
search_dialog->set_hide_on_ok(false);
- search_dialog->set_self_modulate(Color(1, 1, 1, 0.8));
/*class_search = memnew( EditorHelpSearch(editor) );
editor->get_gui_base()->add_child(class_search);
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 30a535a535..92c0e2f4d1 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -118,6 +118,7 @@ class EditorHelp : public VBoxContainer {
String edited_class;
+ Vector<Pair<String, int> > section_line;
Map<String, int> method_line;
Map<String, int> signal_line;
Map<String, int> property_line;
@@ -130,7 +131,6 @@ class EditorHelp : public VBoxContainer {
HSplitContainer *h_split;
static DocData *doc;
- Panel *background_panel;
ConfirmationDialog *search_dialog;
LineEdit *search;
@@ -169,6 +169,9 @@ public:
void go_to_help(const String &p_help);
void go_to_class(const String &p_class, int p_scroll = 0);
+ Vector<Pair<String, int> > get_sections();
+ void scroll_to_section(int p_section_index);
+
void popup_search();
void search_again();
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 35291f8f9e..481f2aaecf 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -61,9 +61,6 @@ void EditorLog::_notification(int p_what) {
//button->set_icon(get_icon("Console","EditorIcons"));
}
- if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- _override_logger_styles();
- }
/*if (p_what==NOTIFICATION_DRAW) {
@@ -88,7 +85,11 @@ void EditorLog::clear() {
void EditorLog::add_message(const String &p_msg, bool p_error) {
+ Ref<Font> doc_code_font = get_font("doc_source", "EditorFonts");
+ log->push_font(doc_code_font);
+
log->add_newline();
+
if (p_error) {
log->push_color(get_color("error_color", "Editor"));
Ref<Texture> icon = get_icon("Error", "EditorIcons");
@@ -103,6 +104,8 @@ void EditorLog::add_message(const String &p_msg, bool p_error) {
if (p_error)
log->pop();
+
+ log->pop(); // pop font;
}
/*
@@ -129,7 +132,6 @@ void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) {
void EditorLog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_clear_request"), &EditorLog::_clear_request);
- ClassDB::bind_method("_override_logger_styles", &EditorLog::_override_logger_styles);
//ClassDB::bind_method(D_METHOD("_dragged"),&EditorLog::_dragged );
ADD_SIGNAL(MethodInfo("clear_request"));
}
@@ -151,21 +153,15 @@ EditorLog::EditorLog() {
clearbutton->set_text(TTR("Clear"));
clearbutton->connect("pressed", this, "_clear_request");
- ec = memnew(Control);
- vb->add_child(ec);
- ec->set_custom_minimum_size(Size2(0, 180) * EDSCALE);
- ec->set_v_size_flags(SIZE_EXPAND_FILL);
-
- pc = memnew(PanelContainer);
- ec->add_child(pc);
- pc->set_area_as_parent_rect();
- pc->connect("tree_entered", this, "_override_logger_styles");
-
log = memnew(RichTextLabel);
log->set_scroll_follow(true);
log->set_selection_enabled(true);
log->set_focus_mode(FOCUS_CLICK);
- pc->add_child(log);
+ log->set_custom_minimum_size(Size2(0, 180) * EDSCALE);
+ log->set_area_as_parent_rect();
+ log->set_v_size_flags(SIZE_EXPAND_FILL);
+ log->set_h_size_flags(SIZE_EXPAND_FILL);
+ vb->add_child(log);
add_message(VERSION_FULL_NAME " (c) 2008-2017 Juan Linietsky, Ariel Manzur.");
//log->add_text("Initialization Complete.\n"); //because it looks cool.
@@ -183,10 +179,5 @@ void EditorLog::deinit() {
remove_error_handler(&eh);
}
-void EditorLog::_override_logger_styles() {
-
- pc->add_style_override("panel", get_stylebox("normal", "TextEdit"));
-}
-
EditorLog::~EditorLog() {
}
diff --git a/editor/editor_log.h b/editor/editor_log.h
index fd919fd692..e551623140 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -50,8 +50,6 @@ class EditorLog : public VBoxContainer {
RichTextLabel *log;
HBoxContainer *title_hb;
//PaneDrag *pd;
- Control *ec;
- PanelContainer *pc;
static void _error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type);
@@ -66,7 +64,6 @@ class EditorLog : public VBoxContainer {
protected:
static void _bind_methods();
void _notification(int p_what);
- void _override_logger_styles();
public:
void add_message(const String &p_msg, bool p_error = false);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index b4412014e7..1a89d6ef6e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -84,6 +84,7 @@
#include "editor/plugins/mesh_editor_plugin.h"
#include "editor/plugins/mesh_instance_editor_plugin.h"
#include "editor/plugins/multimesh_editor_plugin.h"
+#include "editor/plugins/navigation_mesh_editor_plugin.h"
#include "editor/plugins/navigation_polygon_editor_plugin.h"
#include "editor/plugins/particles_2d_editor_plugin.h"
#include "editor/plugins/particles_editor_plugin.h"
@@ -253,6 +254,7 @@ void EditorNode::_notification(int p_what) {
get_tree()->get_root()->set_as_audio_listener_2d(false);
get_tree()->set_auto_accept_quit(false);
get_tree()->connect("files_dropped", this, "_dropped_files");
+ property_editable_warning->set_icon(gui_base->get_icon("NodeWarning", "EditorIcons"));
}
if (p_what == NOTIFICATION_EXIT_TREE) {
@@ -1386,6 +1388,11 @@ static bool overrides_external_editor(Object *p_object) {
return script->get_language()->overrides_external_editor();
}
+void EditorNode::_property_editable_warning_pressed() {
+
+ property_editable_warning_dialog->popup_centered_minsize();
+}
+
void EditorNode::_edit_current() {
uint32_t current = editor_history.get_current();
@@ -1397,6 +1404,9 @@ void EditorNode::_edit_current() {
this->current = current_obj;
editor_path->update_path();
+ String editable_warning; //none by default
+ property_editable_warning->hide(); //hide by default
+
if (!current_obj) {
scene_tree_dock->set_selected(NULL);
@@ -1424,6 +1434,22 @@ void EditorNode::_edit_current() {
node_dock->set_node(NULL);
object_menu->set_disabled(false);
EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path());
+
+ int subr_idx = current_res->get_path().find("::");
+ if (subr_idx != -1) {
+ String base_path = current_res->get_path().substr(0, subr_idx);
+ if (FileAccess::exists(base_path + ".import")) {
+ editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
+ } else {
+ if (!get_edited_scene() || get_edited_scene()->get_filename() != base_path) {
+ editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene.");
+ }
+ }
+ } else if (current_res->get_path().is_resource_file()) {
+ if (FileAccess::exists(current_res->get_path() + ".import")) {
+ editable_warning = TTR("This resource was imported, so it's not editable. Change it's settings in the import panel and re-import.");
+ }
+ }
} else if (is_node) {
Node *current_node = Object::cast_to<Node>(current_obj);
@@ -1439,12 +1465,24 @@ void EditorNode::_edit_current() {
}
object_menu->get_popup()->clear();
+ if (get_edited_scene() && get_edited_scene()->get_filename() != String()) {
+ String source_scene = get_edited_scene()->get_filename();
+ if (FileAccess::exists(source_scene + ".import")) {
+ editable_warning = TTR("This scene was imported, so changes to it will not be kept.\nInstancing it or inheriting will allow making changes to it.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
+ }
+ }
+
} else {
property_editor->edit(current_obj);
node_dock->set_node(NULL);
}
+ if (editable_warning != String()) {
+ property_editable_warning->show(); //hide by default
+ property_editable_warning_dialog->set_text(editable_warning);
+ }
+
/* Take care of PLUGIN EDITOR */
EditorPlugin *main_plugin = editor_data.get_editor(current_obj);
@@ -2742,14 +2780,6 @@ Dictionary EditorNode::_get_main_scene_state() {
state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
state["saved_version"] = saved_version;
state["node_filter"] = scene_tree_dock->get_filter();
- int current = -1;
- for (int i = 0; i < editor_table.size(); i++) {
- if (editor_plugin_screen == editor_table[i]) {
- current = i;
- break;
- }
- }
- state["editor_index"] = current;
return state;
}
@@ -2760,29 +2790,32 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
changing_scene = false;
- if (p_state.has("editor_index")) {
-
- int index = p_state["editor_index"];
- int current = -1;
- for (int i = 0; i < editor_table.size(); i++) {
- if (editor_plugin_screen == editor_table[i]) {
- current = i;
- break;
- }
+ int current = -1;
+ for (int i = 0; i < editor_table.size(); i++) {
+ if (editor_plugin_screen == editor_table[i]) {
+ current = i;
+ break;
}
+ }
+ if (p_state.has("editor_index")) {
+ int index = p_state["editor_index"];
if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there
if (index < 2 || !get_edited_scene()) {
_editor_select(index);
- } else {
- //use heuristic instead
- int n2d = 0, n3d = 0;
- _find_node_types(get_edited_scene(), n2d, n3d);
- if (n2d > n3d) {
- _editor_select(EDITOR_2D);
- } else if (n3d > n2d) {
- _editor_select(EDITOR_3D);
- }
+ }
+ }
+ }
+
+ if (get_edited_scene()) {
+ if (current < 2) {
+ //use heuristic instead
+ int n2d = 0, n3d = 0;
+ _find_node_types(get_edited_scene(), n2d, n3d);
+ if (n2d > n3d) {
+ _editor_select(EDITOR_2D);
+ } else if (n3d > n2d) {
+ _editor_select(EDITOR_3D);
}
}
}
@@ -3213,9 +3246,9 @@ void EditorNode::register_editor_types() {
ClassDB::register_class<EditorFileSystemDirectory>();
ClassDB::register_virtual_class<ScriptEditor>();
ClassDB::register_virtual_class<EditorInterface>();
+ ClassDB::register_class<EditorExportPlugin>();
// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
- //ClassDB::register_class<EditorExportPlugin>();
//ClassDB::register_class<EditorScenePostImport>();
//ClassDB::register_type<EditorImportExport>();
}
@@ -3305,9 +3338,9 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
-Error EditorNode::export_preset(const String &preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) {
+Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after) {
- export_defer.preset = preset;
+ export_defer.preset = p_preset;
export_defer.path = p_path;
export_defer.debug = p_debug;
export_defer.password = p_password;
@@ -4028,6 +4061,13 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
ERR_FAIL_INDEX(p_idx, bottom_panel_items.size());
if (p_enable) {
+ // this is the debug panel wich uses tabs, so the top section should be smaller
+ if (ScriptEditor::get_singleton()->get_debugger() == bottom_panel_items[p_idx].control) {
+ Ref<StyleBoxFlat> style_panel_invisible_top = gui_base->get_stylebox("debugger_panel", "EditorStyles");
+ bottom_panel->add_style_override("panel", style_panel_invisible_top);
+ } else {
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
+ }
for (int i = 0; i < bottom_panel_items.size(); i++) {
bottom_panel_items[i].button->set_pressed(i == p_idx);
@@ -4036,11 +4076,14 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE);
center_split->set_collapsed(false);
} else {
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
+
for (int i = 0; i < bottom_panel_items.size(); i++) {
bottom_panel_items[i].button->set_pressed(false);
bottom_panel_items[i].control->set_visible(false);
}
+
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
center_split->set_collapsed(true);
}
@@ -4128,7 +4171,7 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
{
//todo make proper previews
- Ref<ImageTexture> pic = gui_base->get_icon("FileBig", "EditorIcons");
+ Ref<ImageTexture> pic = gui_base->get_icon("FileBigThumb", "EditorIcons");
Ref<Image> img = pic->get_data();
img = img->duplicate();
img->resize(48, 48); //meh
@@ -4470,6 +4513,7 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history);
ClassDB::bind_method("_dropped_files", &EditorNode::_dropped_files);
ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode);
+ ClassDB::bind_method("_property_editable_warning_pressed", &EditorNode::_property_editable_warning_pressed);
ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base);
ClassDB::bind_method(D_METHOD("_bottom_panel_switch"), &EditorNode::_bottom_panel_switch);
@@ -4815,7 +4859,7 @@ EditorNode::EditorNode() {
scene_root_parent = memnew(PanelContainer);
scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
-
+ scene_root_parent->set_draw_behind_parent(true);
srt->add_child(scene_root_parent);
scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -4872,6 +4916,7 @@ EditorNode::EditorNode() {
gui_base->add_child(dependency_fixer);
settings_config_dialog = memnew(EditorSettingsDialog);
+ // settings_config_dialog->add_style_override("panel", gui_base->get_stylebox("EditorSettingsDialog", "EditorStyles"));
gui_base->add_child(settings_config_dialog);
project_settings = memnew(ProjectSettingsEditor(&editor_data));
@@ -5029,7 +5074,7 @@ EditorNode::EditorNode() {
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Issue Tracker"), HELP_ISSUES);
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Community"), HELP_COMMUNITY);
p->add_separator();
- p->add_icon_item(gui_base->get_icon("GodotDocs", "EditorIcons"), TTR("About"), HELP_ABOUT);
+ p->add_icon_item(gui_base->get_icon("Godot", "EditorIcons"), TTR("About"), HELP_ABOUT);
play_cc = memnew(CenterContainer);
play_cc->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
@@ -5230,6 +5275,14 @@ EditorNode::EditorNode() {
search_bar->add_child(clear_button);
clear_button->connect("pressed", this, "_clear_search_box");
+ property_editable_warning = memnew(Button);
+ property_editable_warning->set_text(TTR("Changes may be lost!"));
+ prop_editor_base->add_child(property_editable_warning);
+ property_editable_warning_dialog = memnew(AcceptDialog);
+ gui_base->add_child(property_editable_warning_dialog);
+ property_editable_warning->hide();
+ property_editable_warning->connect("pressed", this, "_property_editable_warning_pressed");
+
property_editor = memnew(PropertyEditor);
property_editor->set_autoclear(true);
property_editor->set_show_categories(true);
@@ -5242,6 +5295,7 @@ EditorNode::EditorNode() {
property_editor->hide_top_label();
property_editor->register_text_enter(search_box);
+ Button *property_editable_warning;
prop_editor_base->add_child(property_editor);
property_editor->set_undo_redo(&editor_data.get_undo_redo());
@@ -5439,6 +5493,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(TextureEditorPlugin(this)));
add_editor_plugin(memnew(MeshEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
+ add_editor_plugin(memnew(NavigationMeshEditorPlugin(this)));
// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored.
diff --git a/editor/editor_node.h b/editor/editor_node.h
index ea74bcbd9d..33031e5634 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -262,6 +262,9 @@ private:
Button *property_forward;
SceneTreeDock *scene_tree_dock;
PropertyEditor *property_editor;
+ Button *property_editable_warning;
+ AcceptDialog *property_editable_warning_dialog;
+ void _property_editable_warning_pressed();
NodeDock *node_dock;
ImportDock *import_dock;
VBoxContainer *prop_editor_vb;
@@ -712,7 +715,7 @@ public:
void show_warning(const String &p_text, const String &p_title = "Warning!");
- Error export_preset(const String &p_platform, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false);
+ Error export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false);
static void register_editor_types();
static void unregister_editor_types();
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 86acfcc50e..246599be11 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -530,6 +530,14 @@ void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importe
EditorFileSystem::get_singleton()->scan();
}
+void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin> &p_exporter) {
+ EditorExport::get_singleton()->add_export_plugin(p_exporter);
+}
+
+void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter) {
+ EditorExport::get_singleton()->remove_export_plugin(p_exporter);
+}
+
void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) {
@@ -585,6 +593,8 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout);
ClassDB::bind_method(D_METHOD("add_import_plugin", "importer"), &EditorPlugin::add_import_plugin);
ClassDB::bind_method(D_METHOD("remove_import_plugin", "importer"), &EditorPlugin::remove_import_plugin);
+ ClassDB::bind_method(D_METHOD("add_export_plugin", "exporter"), &EditorPlugin::add_export_plugin);
+ ClassDB::bind_method(D_METHOD("remove_export_plugin", "exporter"), &EditorPlugin::remove_export_plugin);
ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled);
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorPlugin::get_editor_interface);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 99328f8149..18530e9ce4 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -191,6 +191,9 @@ public:
void add_import_plugin(const Ref<EditorImportPlugin> &p_importer);
void remove_import_plugin(const Ref<EditorImportPlugin> &p_importer);
+ void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
+ void remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
+
EditorPlugin();
virtual ~EditorPlugin();
};
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index 6b972262b9..247775fa1d 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "editor_profiler.h"
+#include "editor_scale.h"
#include "editor_settings.h"
#include "os/os.h"
@@ -656,14 +657,14 @@ EditorProfiler::EditorProfiler() {
hb->add_child(cursor_metric_edit);
cursor_metric_edit->connect("value_changed", this, "_cursor_metric_changed");
- hb->add_constant_override("separation", 8);
+ hb->add_constant_override("separation", 8 * EDSCALE);
h_split = memnew(HSplitContainer);
add_child(h_split);
h_split->set_v_size_flags(SIZE_EXPAND_FILL);
variables = memnew(Tree);
- variables->set_custom_minimum_size(Size2(300, 0));
+ variables->set_custom_minimum_size(Size2(300, 0) * EDSCALE);
variables->set_hide_folding(true);
h_split->add_child(variables);
variables->set_hide_root(true);
@@ -674,10 +675,10 @@ EditorProfiler::EditorProfiler() {
variables->set_column_min_width(0, 60);
variables->set_column_title(1, "Time");
variables->set_column_expand(1, false);
- variables->set_column_min_width(1, 60);
+ variables->set_column_min_width(1, 60 * EDSCALE);
variables->set_column_title(2, "Calls");
variables->set_column_expand(2, false);
- variables->set_column_min_width(2, 60);
+ variables->set_column_min_width(2, 60 * EDSCALE);
variables->connect("item_edited", this, "_item_edited");
graph = memnew(TextureRect);
@@ -691,8 +692,6 @@ EditorProfiler::EditorProfiler() {
h_split->add_child(graph);
graph->set_h_size_flags(SIZE_EXPAND_FILL);
- add_constant_override("separation", 3);
-
int metric_size = CLAMP(int(EDITOR_DEF("debugger/profiler_frame_history_size", 600)), 60, 1024);
frame_metrics.resize(metric_size);
last_metric = -1;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index e377fa1a8e..90cbabcc4f 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -72,6 +72,10 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
screen--;
}
+ if (OS::get_singleton()->is_disable_crash_handler()) {
+ args.push_back("--disable-crash-handler");
+ }
+
Rect2 screen_rect;
screen_rect.position = OS::get_singleton()->get_screen_position(screen);
screen_rect.size = OS::get_singleton()->get_screen_size(screen);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 50cee6d892..eb72fdf64b 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -460,7 +460,7 @@ void EditorSettings::setup_network() {
List<IP_Address> local_ip;
IP::get_singleton()->get_local_addresses(&local_ip);
- String lip;
+ String lip = "127.0.0.1";
String hint;
String current = has("network/debug/remote_host") ? get("network/debug/remote_host") : "";
int port = has("network/debug/remote_port") ? (int)get("network/debug/remote_port") : 6007;
@@ -469,8 +469,9 @@ void EditorSettings::setup_network() {
String ip = E->get();
- if (lip == "")
- lip = ip;
+ // link-local IPv6 addresses don't work, skipping them
+ if (ip.begins_with("fe80:0:0:0:")) // fe80::/64
+ continue;
if (ip == current)
lip = current; //so it saves
if (hint != "")
@@ -574,13 +575,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/theme/icon_and_font_color", 0);
hints["interface/theme/icon_and_font_color"] = PropertyInfo(Variant::INT, "interface/theme/icon_and_font_color", PROPERTY_HINT_ENUM, "Auto,Dark,Light", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/base_color", Color::html("#323b4f"));
- hints["interface/theme/highlight_color"] = PropertyInfo(Variant::COLOR, "interface/theme/highlight_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("interface/theme/highlight_color", Color::html("#699ce8"));
+ hints["interface/theme/accent_color"] = PropertyInfo(Variant::COLOR, "interface/theme/accent_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ set("interface/theme/accent_color", Color::html("#699ce8"));
hints["interface/theme/base_color"] = PropertyInfo(Variant::COLOR, "interface/theme/base_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("interface/theme/contrast", 0.2);
+ set("interface/theme/contrast", 0.25);
hints["interface/theme/contrast"] = PropertyInfo(Variant::REAL, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01");
set("interface/theme/highlight_tabs", false);
set("interface/theme/border_size", 1);
+ set("interface/theme/use_graph_node_headers", false);
hints["interface/theme/border_size"] = PropertyInfo(Variant::INT, "interface/theme/border_size", PROPERTY_HINT_RANGE, "0,2,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/custom_theme", "");
hints["interface/theme/custom_theme"] = PropertyInfo(Variant::STRING, "interface/theme/custom_theme", PROPERTY_HINT_GLOBAL_FILE, "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
@@ -599,8 +601,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["global/default_project_export_path"] = PropertyInfo(Variant::STRING, "global/default_project_export_path", PROPERTY_HINT_GLOBAL_DIR);
set("interface/show_script_in_scene_tabs", false);
- set("text_editor/theme/color_theme", "Default");
- hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default");
+ set("text_editor/theme/color_theme", "Adaptive");
+ hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Adaptive,Default");
set("text_editor/theme/line_spacing", 4);
@@ -729,6 +731,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
set("docks/filesystem/thumbnail_size", 64);
hints["docks/filesystem/thumbnail_size"] = PropertyInfo(Variant::INT, "docks/filesystem/thumbnail_size", PROPERTY_HINT_RANGE, "32,128,16");
+ set("docks/filesystem/display_mode", 0);
+ hints["docks/filesystem/display_mode"] = PropertyInfo(Variant::INT, "docks/filesystem/display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List");
+ set("docks/filesystem/always_show_folders", true);
set("editors/animation/autorename_animation_tracks", true);
set("editors/animation/confirm_insert_track", true);
@@ -736,6 +741,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("docks/property_editor/texture_preview_width", 48);
set("docks/property_editor/auto_refresh_interval", 0.3);
set("text_editor/help/doc_path", "");
+ set("text_editor/help/show_help_index", true);
set("filesystem/import/ask_save_before_reimport", false);
@@ -920,13 +926,13 @@ void EditorSettings::load_favorites() {
}
void EditorSettings::list_text_editor_themes() {
- String themes = "Default";
+ String themes = "Adaptive,Default";
DirAccess *d = DirAccess::open(settings_path + "/text_editor_themes");
if (d) {
d->list_dir_begin();
String file = d->get_next();
while (file != String()) {
- if (file.get_extension() == "tet" && file.get_basename().to_lower() != "default") {
+ if (file.get_extension() == "tet" && file.get_basename().to_lower() != "default" && file.get_basename().to_lower() != "adaptive") {
themes += "," + file.get_basename();
}
file = d->get_next();
@@ -938,7 +944,7 @@ void EditorSettings::list_text_editor_themes() {
}
void EditorSettings::load_text_editor_theme() {
- if (get("text_editor/theme/color_theme") == "Default") {
+ if (get("text_editor/theme/color_theme") == "Default" || get("text_editor/theme/color_theme") == "Adaptive") {
_load_default_text_editor_theme(); // sorry for "Settings changed" console spam
return;
}
@@ -995,7 +1001,7 @@ bool EditorSettings::save_text_editor_theme() {
String p_file = get("text_editor/theme/color_theme");
- if (p_file.get_file().to_lower() == "default") {
+ if (p_file.get_file().to_lower() == "default" || p_file.get_file().to_lower() == "adaptive") {
return false;
}
String theme_path = get_settings_path() + "/text_editor_themes/" + p_file + ".tet";
@@ -1007,7 +1013,7 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) {
p_file += ".tet";
}
- if (p_file.get_file().to_lower() == "default.tet") {
+ if (p_file.get_file().to_lower() == "default.tet" || p_file.get_file().to_lower() == "adaptive.tet") {
return false;
}
if (_save_text_editor_theme(p_file)) {
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index ff0e794a20..4aa1ccaa81 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -86,7 +86,7 @@ static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_
return style;
}
-Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dictionary *p_colors = NULL) {
+Ref<ImageTexture> editor_generate_icon(int p_index, bool convert_color, float p_scale = EDSCALE, bool force_filter = false) {
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
@@ -94,9 +94,9 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dict
// dumb gizmo check
bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo");
- ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], EDSCALE, true, dark_theme ? NULL : p_colors);
+ ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, true, convert_color);
- if ((EDSCALE - (float)((int)EDSCALE)) > 0.0 || is_gizmo)
+ if ((p_scale - (float)((int)p_scale)) > 0.0 || is_gizmo || force_filter)
icon->create_from_image(img); // in this case filter really helps
else
icon->create_from_image(img, 0);
@@ -108,46 +108,53 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dict
#define ADD_CONVERT_COLOR(dictionary, old_color, new_color) dictionary[Color::html(old_color)] = Color::html(new_color)
#endif
-void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = true) {
+void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = true, int p_thumb_size = 32, bool only_thumbs = false) {
#ifdef SVG_ENABLED
-
Dictionary dark_icon_color_dictionary;
- //convert color: FROM TO
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#4f4f4f"); // common icon color
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#000000"); // white
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#000000"); // script darker color
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#bb6dff"); // animation
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#ff5f5f"); // spatial
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#6d90ff"); // 2d
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#0843ff"); // 2d dark
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#29d739"); // control
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff3333"); // error
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00db50"); // success
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#ffad07"); // warning
-
- // rainbow
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff7070", "#ff2929"); // red
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffeb70", "#ffe337"); // yellow
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9dff70", "#74ff34"); // green
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70ffb9", "#2cff98"); // aqua
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70deff", "#22ccff"); // blue
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9f70ff", "#702aff"); // purple
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff70ac", "#ff2781"); // pink
-
- // audio gradient
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff4040"); // red
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1dc7a", "#d6cf4b"); // yellow
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00f010"); // green
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#fea900"); // mesh (orange)
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#40a2ff", "#68b6ff"); // shape (blue)
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84c2ff", "#5caeff"); // selection (blue)
-
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#e3383d"); // key xform (red)
+ if (!dark_theme) {
+ //convert color: FROM TO
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#4f4f4f"); // common icon color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#000000"); // white
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#000000"); // script darker color
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cea4f1", "#bb6dff"); // animation
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fc9c9c", "#ff5f5f"); // spatial
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5b7f3", "#6d90ff"); // 2d
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#708cea", "#0843ff"); // 2d dark
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a5efac", "#29d739"); // control
+
+ // rainbow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff7070", "#ff2929"); // red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffeb70", "#ffe337"); // yellow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9dff70", "#74ff34"); // green
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70ffb9", "#2cff98"); // aqua
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#70deff", "#22ccff"); // blue
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#9f70ff", "#702aff"); // purple
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff70ac", "#ff2781"); // pink
+
+ // audio gradient
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff4040"); // red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1dc7a", "#d6cf4b"); // yellow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00f010"); // green
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffd684", "#fea900"); // mesh (orange)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#40a2ff", "#68b6ff"); // shape (blue)
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff8484", "#ff3333"); // remove (red)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffb1", "#00db50"); // add (green)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84c2ff", "#5caeff"); // selection (blue)
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#e3383d"); // key xform (red)
+ }
+
+ // these ones should be converted even if we are using a dark theme
+ const Color error_color = p_theme->get_color("error_color", "Editor");
+ const Color success_color = p_theme->get_color("success_color", "Editor");
+ const Color warning_color = p_theme->get_color("warning_color", "Editor");
+ dark_icon_color_dictionary[Color::html("#ff5d5d")] = error_color;
+ dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color;
+ dark_icon_color_dictionary[Color::html("#ffdd65")] = warning_color;
List<String> exceptions;
exceptions.push_back("EditorPivot");
@@ -158,18 +165,47 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = tr
exceptions.push_back("ProceduralSky");
exceptions.push_back("EditorControlAnchor");
exceptions.push_back("DefaultProjectIcon");
+ exceptions.push_back("GuiCloseCustomizable");
+ exceptions.push_back("GuiGraphNodePort");
+ exceptions.push_back("GuiResizer");
clock_t begin_time = clock();
- for (int i = 0; i < editor_icons_count; i++) {
- List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
- if (is_exception) {
- exceptions.erase(is_exception);
+ ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary);
+
+ // generate icons
+ if (!only_thumbs)
+ for (int i = 0; i < editor_icons_count; i++) {
+ List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
+ if (is_exception) exceptions.erase(is_exception);
+ Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception);
+ p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
+ }
+
+ // generate thumb files with the given thumb size
+ bool force_filter = !(p_thumb_size == 64 && p_thumb_size == 32); // we dont need filter with original resolution
+ if (p_thumb_size >= 64) {
+ float scale = (float)p_thumb_size / 64.0 * EDSCALE;
+ for (int i = 0; i < editor_bg_thumbs_count; i++) {
+ int index = editor_bg_thumbs_indices[i];
+ List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
+ if (is_exception) exceptions.erase(is_exception);
+ Ref<ImageTexture> icon = editor_generate_icon(index, !dark_theme && !is_exception, scale, force_filter);
+ p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
+ }
+ } else {
+ float scale = (float)p_thumb_size / 32.0 * EDSCALE;
+ for (int i = 0; i < editor_md_thumbs_count; i++) {
+ int index = editor_md_thumbs_indices[i];
+ List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
+ if (is_exception) exceptions.erase(is_exception);
+ Ref<ImageTexture> icon = editor_generate_icon(index, !dark_theme && !is_exception, scale, force_filter);
+ p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
}
- Ref<ImageTexture> icon = editor_generate_icon(i, dark_theme, is_exception ? NULL : &dark_icon_color_dictionary);
- p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
}
+ ImageLoaderSVG::set_convert_colors(NULL);
+
clock_t end_time = clock();
double time_d = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
@@ -179,9 +215,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = tr
#endif
}
-#define HIGHLIGHT_COLOR_FONT highlight_color.linear_interpolate(dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1), 0.5)
-#define HIGHLIGHT_COLOR_BG highlight_color.linear_interpolate(dark_theme ? Color(0, 0, 0, 1) : Color(1, 1, 1, 1), 0.5)
-
Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Ref<Theme> theme = Ref<Theme>(memnew(Theme));
@@ -189,7 +222,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const float default_contrast = 0.25;
//Theme settings
- Color highlight_color = EDITOR_DEF("interface/theme/highlight_color", Color::html("#000000"));
+ Color accent_color = EDITOR_DEF("interface/theme/accent_color", Color::html("#000000"));
Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#000000"));
float contrast = EDITOR_DEF("interface/theme/contrast", default_contrast);
@@ -198,31 +231,33 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false);
int border_size = EDITOR_DEF("interface/theme/border_size", 1);
+ bool use_gn_headers = EDITOR_DEF("interface/theme/use_graph_node_headers", false);
+
Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
switch (preset) {
case 0: { // Default
- highlight_color = Color::html("#699ce8");
+ accent_color = Color::html("#699ce8");
base_color = Color::html("#323b4f");
contrast = default_contrast;
} break;
case 1: { // Grey
- highlight_color = Color::html("#3e3e3e");
+ accent_color = Color::html("#3e3e3e");
base_color = Color::html("#3d3d3d");
contrast = 0.2;
} break;
case 2: { // Godot 2
- highlight_color = Color::html("#86ace2");
+ accent_color = Color::html("#86ace2");
base_color = Color::html("#3C3A44");
contrast = 0.25;
} break;
case 3: { // Arc
- highlight_color = Color::html("#5294e2");
+ accent_color = Color::html("#5294e2");
base_color = Color::html("#383c4a");
contrast = 0.25;
} break;
case 4: { // Light
- highlight_color = Color::html("#2070ff");
+ accent_color = Color::html("#2070ff");
base_color = Color::html("#ffffff");
contrast = 0.08;
} break;
@@ -233,22 +268,29 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
int LIGHT_COLOR = 2;
bool dark_theme = (icon_font_color_setting == AUTO_COLOR && ((base_color.r + base_color.g + base_color.b) / 3.0) < 0.5) || icon_font_color_setting == LIGHT_COLOR;
- Color dark_color_1 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast);
- Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
- Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
+ const Color dark_color_1 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast);
+ const Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
+ const Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
- Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast, default_contrast));
- Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast * 1.5, default_contrast * 1.5));
+ const Color background_color = dark_color_2;
- Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
- Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45);
+ // white (dark theme) or black (light theme), will be used to generate the rest of the colors
+ const Color mono_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
- Color separator_color = dark_theme ? Color(1, 1, 1, 0.1) : Color(0, 0, 0, 0.1);
+ const Color contrast_color_1 = base_color.linear_interpolate(mono_color, MAX(contrast, default_contrast));
+ const Color contrast_color_2 = base_color.linear_interpolate(mono_color, MAX(contrast * 1.5, default_contrast * 1.5));
- Color tab_color = highlight_tabs ? base_color.linear_interpolate(font_color, contrast) : base_color;
- const int border_width = CLAMP(border_size, 0, 3) * EDSCALE;
+ const Color font_color = mono_color.linear_interpolate(base_color, 0.25);
+ const Color font_color_hl = mono_color.linear_interpolate(base_color, 0.15);
+ const Color font_color_disabled = Color(mono_color.r, mono_color.g, mono_color.b, 0.3);
+ const Color color_disabled = mono_color.inverted().linear_interpolate(base_color, 0.7);
+ const Color color_disabled_bg = mono_color.inverted().linear_interpolate(base_color, 0.9);
+
+ const Color separator_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.1);
+
+ const Color highlight_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.2);
- theme->set_color("highlight_color", "Editor", highlight_color);
+ theme->set_color("accent_color", "Editor", accent_color);
theme->set_color("base_color", "Editor", base_color);
theme->set_color("dark_color_1", "Editor", dark_color_1);
theme->set_color("dark_color_2", "Editor", dark_color_2);
@@ -256,14 +298,18 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("contrast_color_1", "Editor", contrast_color_1);
theme->set_color("contrast_color_2", "Editor", contrast_color_2);
- Color success_color = highlight_color.linear_interpolate(Color(.6, 1, .6), 0.8);
- Color warning_color = highlight_color.linear_interpolate(Color(1, 1, .2), 0.8);
- Color error_color = highlight_color.linear_interpolate(Color(1, .2, .2), 0.8);
+ theme->set_color("font_color", "Editor", font_color);
+
+ Color success_color = accent_color.linear_interpolate(Color(.6, 1, .6), 0.8);
+ Color warning_color = accent_color.linear_interpolate(Color(1, 1, .2), 0.8);
+ Color error_color = accent_color.linear_interpolate(Color(1, .2, .2), 0.8);
theme->set_color("success_color", "Editor", success_color);
theme->set_color("warning_color", "Editor", warning_color);
theme->set_color("error_color", "Editor", error_color);
+ const int thumb_size = EDITOR_DEF("filesystem/file_dialog/thumbnail_size", 64);
theme->set_constant("scale", "Editor", EDSCALE);
+ theme->set_constant("thumb_size", "Editor", thumb_size);
theme->set_constant("dark_theme", "Editor", dark_theme);
//Register icons + font
@@ -275,23 +321,90 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon(editor_icons_names[i], "EditorIcons", p_theme->get_icon(editor_icons_names[i], "EditorIcons"));
}
} else {
- editor_register_and_generate_icons(theme, dark_theme);
+ editor_register_and_generate_icons(theme, dark_theme, thumb_size);
+ }
+ // thumbnail size has changed, so we regenerate the medium sizes
+ if (p_theme != NULL && fabs(p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) {
+ editor_register_and_generate_icons(p_theme, dark_theme, thumb_size, true);
}
editor_register_fonts(theme);
+ // Highlighted tabs and border width
+ Color tab_color = highlight_tabs ? base_color.linear_interpolate(font_color, contrast) : base_color;
+ const int border_width = CLAMP(border_size, 0, 3) * EDSCALE;
+
+ const int default_margin_size = 4;
+ const int margin_size_extra = default_margin_size + CLAMP(border_size, 0, 3);
+
+ // styleboxes
+ // this is the most commonly used stylebox, variations should be made as duplicate of this
+ Ref<StyleBoxFlat> style_default = make_flat_stylebox(base_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size);
+ style_default->set_border_width_all(border_width);
+ style_default->set_border_color_all(base_color);
+ style_default->set_draw_center(true);
+
+ // Button and widgets
+ Ref<StyleBoxFlat> style_widget = style_default->duplicate();
+
+ style_widget->set_bg_color(dark_color_1);
+ style_widget->set_default_margin(MARGIN_LEFT, 6 * EDSCALE);
+ style_widget->set_default_margin(MARGIN_RIGHT, 6 * EDSCALE);
+ style_widget->set_border_color_all(dark_color_2);
+
+ Ref<StyleBoxFlat> style_widget_disabled = style_widget->duplicate();
+ style_widget_disabled->set_border_color_all(color_disabled);
+ style_widget_disabled->set_bg_color(color_disabled_bg);
+
+ Ref<StyleBoxFlat> style_widget_focus = style_widget->duplicate();
+ style_widget_focus->set_border_color_all(accent_color);
+
+ Ref<StyleBoxFlat> style_widget_pressed = style_widget->duplicate();
+ style_widget_pressed->set_border_color_all(accent_color);
+
+ Ref<StyleBoxFlat> style_widget_hover = style_widget->duplicate();
+ style_widget_hover->set_border_color_all(contrast_color_1);
+
+ // style for windows, popups, etc..
+ Ref<StyleBoxFlat> style_popup = style_default->duplicate();
+ style_popup->set_default_margin(MARGIN_LEFT, default_margin_size * EDSCALE * 2);
+ style_popup->set_default_margin(MARGIN_TOP, default_margin_size * EDSCALE * 2);
+ style_popup->set_default_margin(MARGIN_RIGHT, default_margin_size * EDSCALE * 2);
+ style_popup->set_default_margin(MARGIN_BOTTOM, default_margin_size * EDSCALE * 2);
+ style_popup->set_border_color_all(contrast_color_1);
+ style_popup->set_border_width_all(MAX(EDSCALE, border_width));
+ const Color shadow_color = Color(0, 0, 0, dark_theme ? 0.3 : 0.1);
+ style_popup->set_shadow_color(shadow_color);
+ style_popup->set_shadow_size(4 * EDSCALE);
+
+ Ref<StyleBoxEmpty> style_empty = make_empty_stylebox(default_margin_size, default_margin_size, default_margin_size, default_margin_size);
+
+ // Tabs
+ const int tab_default_margin_side = 10 * EDSCALE;
+ Ref<StyleBoxFlat> style_tab_selected = style_default->duplicate();
+ style_tab_selected->set_border_width_all(border_width);
+ style_tab_selected->set_border_width(MARGIN_BOTTOM, 0);
+ style_tab_selected->set_border_color_all(dark_color_3);
+ style_tab_selected->set_expand_margin_size(MARGIN_BOTTOM, border_width);
+ style_tab_selected->set_default_margin(MARGIN_LEFT, tab_default_margin_side);
+ style_tab_selected->set_default_margin(MARGIN_RIGHT, tab_default_margin_side);
+ style_tab_selected->set_bg_color(tab_color);
+
+ Ref<StyleBoxFlat> style_tab_unselected = style_tab_selected->duplicate();
+ style_tab_unselected->set_bg_color(Color(0.0, 0.0, 0.0, 0.0));
+ style_tab_unselected->set_border_color_all(Color(0.0, 0.0, 0.0, 0.0));
+
// Editor background
- theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
+ theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(background_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size));
// Focus
- Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4);
- focus_sbt->set_draw_center(false);
- focus_sbt->set_border_width_all(1 * EDSCALE);
- focus_sbt = change_border_color(focus_sbt, contrast_color_2);
- theme->set_stylebox("Focus", "EditorStyles", focus_sbt);
+ Ref<StyleBoxFlat> style_focus = style_default->duplicate();
+ style_focus->set_draw_center(false);
+ style_focus->set_border_color_all(contrast_color_2);
+ theme->set_stylebox("Focus", "EditorStyles", style_focus);
// Menu
- Ref<StyleBoxEmpty> style_menu = make_empty_stylebox(4, 4, 4, 4);
+ Ref<StyleBoxEmpty> style_menu = style_empty;
theme->set_stylebox("panel", "PanelContainer", style_menu);
theme->set_stylebox("MenuPanel", "EditorStyles", style_menu);
@@ -300,15 +413,18 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0));
// Play button group
- theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_empty_stylebox(8, 4, 8, 4)); //make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
+ theme->set_stylebox("PlayButtonPanel", "EditorStyles", style_empty); //make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
//MenuButton
- Ref<StyleBoxFlat> style_menu_hover_border = make_flat_stylebox(highlight_color, 4, 4, 4, 4);
- Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
-
+ Ref<StyleBoxFlat> style_menu_hover_border = style_default->duplicate();
style_menu_hover_border->set_draw_center(false);
- style_menu_hover_border->set_border_width(MARGIN_BOTTOM, 2 * EDSCALE);
- style_menu_hover_border->set_border_color_all(highlight_color);
+ style_menu_hover_border->set_border_width_all(0);
+ style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width);
+ style_menu_hover_border->set_border_color_all(accent_color);
+
+ Ref<StyleBoxFlat> style_menu_hover_bg = style_default->duplicate();
+ style_menu_hover_bg->set_border_width_all(0);
+ style_menu_hover_bg->set_bg_color(dark_color_1);
theme->set_stylebox("normal", "MenuButton", style_menu);
theme->set_stylebox("hover", "MenuButton", style_menu);
@@ -329,72 +445,53 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("disabled", "ToolButton", style_menu);
theme->set_color("font_color", "MenuButton", font_color);
- theme->set_color("font_color_hover", "MenuButton", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("font_color_hover", "MenuButton", font_color_hl);
theme->set_color("font_color", "ToolButton", font_color);
- theme->set_color("font_color_hover", "ToolButton", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_pressed", "ToolButton", highlight_color);
+ theme->set_color("font_color_hover", "ToolButton", font_color_hl);
+ theme->set_color("font_color_pressed", "ToolButton", accent_color);
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
- // Content of each tab
- Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 4, 4, 4);
- style_content_panel->set_border_color_all(base_color);
- style_content_panel->set_border_width_all(border_width);
- Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 4, border_width, border_width);
- style_content_panel_vp->set_border_color_all(base_color);
- style_content_panel_vp->set_border_width_all(border_width);
- theme->set_stylebox("panel", "TabContainer", style_content_panel);
- theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
-
- Ref<StyleBoxFlat> style_button_type = make_flat_stylebox(dark_color_1, 6, 4, 6, 4);
- style_button_type->set_draw_center(true);
- style_button_type->set_border_width_all(border_width);
- style_button_type->set_border_color_all(contrast_color_2);
-
- Ref<StyleBoxFlat> style_button_type_disabled = change_border_color(style_button_type, contrast_color_1);
-
- Color button_font_color = contrast_color_1.linear_interpolate(font_color, .6);
-
- // Button
- theme->set_stylebox("normal", "Button", style_button_type);
- theme->set_stylebox("hover", "Button", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT));
- theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color));
- theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color));
- theme->set_stylebox("disabled", "Button", style_button_type_disabled);
+ // Buttons
+ theme->set_stylebox("normal", "Button", style_widget);
+ theme->set_stylebox("hover", "Button", style_widget_hover);
+ theme->set_stylebox("pressed", "Button", style_widget_pressed);
+ theme->set_stylebox("focus", "Button", style_widget_focus);
+ theme->set_stylebox("disabled", "Button", style_widget_disabled);
- theme->set_color("font_color", "Button", button_font_color);
- theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_pressed", "Button", highlight_color);
+ theme->set_color("font_color", "Button", font_color);
+ theme->set_color("font_color_hover", "Button", font_color_hl);
+ theme->set_color("font_color_pressed", "Button", accent_color);
theme->set_color("font_color_disabled", "Button", font_color_disabled);
- theme->set_color("icon_color_hover", "Button", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("icon_color_hover", "Button", font_color_hl);
// make icon color value bigger because icon image is not complete white
- theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a));
+ theme->set_color("icon_color_pressed", "Button", Color(accent_color.r * 1.15, accent_color.g * 1.15, accent_color.b * 1.15, accent_color.a));
// OptionButton
- theme->set_stylebox("normal", "OptionButton", style_button_type);
- theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1));
- theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT));
- theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color));
- theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled);
-
- theme->set_color("font_color", "OptionButton", button_font_color);
- theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_pressed", "OptionButton", highlight_color);
+ theme->set_stylebox("normal", "OptionButton", style_widget);
+ theme->set_stylebox("hover", "OptionButton", style_widget_hover);
+ theme->set_stylebox("pressed", "OptionButton", style_widget_pressed);
+ theme->set_stylebox("focus", "OptionButton", style_widget_focus);
+ theme->set_stylebox("disabled", "OptionButton", style_widget_disabled);
+
+ theme->set_color("font_color", "OptionButton", font_color);
+ theme->set_color("font_color_hover", "OptionButton", font_color_hl);
+ theme->set_color("font_color_pressed", "OptionButton", accent_color);
theme->set_color("font_color_disabled", "OptionButton", font_color_disabled);
- theme->set_color("icon_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("icon_color_hover", "OptionButton", font_color_hl);
theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons"));
- theme->set_constant("arrow_margin", "OptionButton", 4);
+ theme->set_constant("arrow_margin", "OptionButton", 4 * EDSCALE);
theme->set_constant("modulate_arrow", "OptionButton", true);
// CheckButton
theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons"));
theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons"));
- theme->set_color("font_color", "CheckButton", button_font_color);
- theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_pressed", "CheckButton", highlight_color);
+ theme->set_color("font_color", "CheckButton", font_color);
+ theme->set_color("font_color_hover", "CheckButton", font_color_hl);
+ theme->set_color("font_color_pressed", "CheckButton", accent_color);
theme->set_color("font_color_disabled", "CheckButton", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("icon_color_hover", "CheckButton", font_color_hl);
// Checkbox
theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons"));
@@ -402,21 +499,19 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("radio_checked", "CheckBox", theme->get_icon("GuiRadioChecked", "EditorIcons"));
theme->set_icon("radio_unchecked", "CheckBox", theme->get_icon("GuiRadioUnchecked", "EditorIcons"));
- theme->set_color("font_color", "CheckBox", button_font_color);
- theme->set_color("font_color_hover", "CheckBox", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_pressed", "CheckBox", highlight_color);
+ theme->set_color("font_color", "CheckBox", font_color);
+ theme->set_color("font_color_hover", "CheckBox", font_color_hl);
+ theme->set_color("font_color_pressed", "CheckBox", accent_color);
theme->set_color("font_color_disabled", "CheckBox", font_color_disabled);
- theme->set_color("icon_color_hover", "CheckBox", HIGHLIGHT_COLOR_FONT);
+ theme->set_color("icon_color_hover", "CheckBox", font_color_hl);
// PopupMenu
- Ref<StyleBoxFlat> style_popup_menu = make_flat_stylebox(dark_color_1, 8, 8, 8, 8);
- style_popup_menu->set_border_width_all(MAX(EDSCALE, border_width));
- style_popup_menu->set_border_color_all(contrast_color_1);
+ Ref<StyleBoxFlat> style_popup_menu = style_popup;
theme->set_stylebox("panel", "PopupMenu", style_popup_menu);
theme->set_stylebox("separator", "PopupMenu", make_line_stylebox(separator_color, MAX(EDSCALE, border_width), 8 - MAX(EDSCALE, border_width)));
theme->set_color("font_color", "PopupMenu", font_color);
- theme->set_color("font_color_hover", "PopupMenu", HIGHLIGHT_COLOR_FONT);
- theme->set_color("font_color_accel", "PopupMenu", font_color);
+ theme->set_color("font_color_hover", "PopupMenu", font_color_hl);
+ theme->set_color("font_color_accel", "PopupMenu", font_color_disabled);
theme->set_color("font_color_disabled", "PopupMenu", font_color_disabled);
theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
@@ -424,8 +519,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("radio_unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
// Tree & ItemList background
- Ref<StyleBoxFlat> style_tree_bg = make_flat_stylebox(dark_color_1, 2, 4, 2, 4);
- style_tree_bg->set_border_width_all(border_width);
+ Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate();
+ style_tree_bg->set_bg_color(dark_color_1);
style_tree_bg->set_border_color_all(dark_color_3);
theme->set_stylebox("bg", "Tree", style_tree_bg);
@@ -435,121 +530,148 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons"));
- theme->set_stylebox("bg_focus", "Tree", focus_sbt);
+ theme->set_stylebox("bg_focus", "Tree", style_focus);
theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
- theme->set_stylebox("custom_button_hover", "Tree", style_button_type);
- theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT);
+ theme->set_stylebox("custom_button_hover", "Tree", style_widget);
+ theme->set_color("custom_button_font_highlight", "Tree", font_color_hl);
theme->set_color("font_color", "Tree", font_color);
theme->set_color("font_color_selected", "Tree", font_color);
- Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4);
+ Ref<StyleBoxFlat> style_tree_btn = style_default->duplicate();
+ style_tree_btn->set_bg_color(contrast_color_1);
+ style_tree_btn->set_border_width_all(0);
theme->set_stylebox("button_pressed", "Tree", style_tree_btn);
- Ref<StyleBoxFlat> style_tree_focus = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 2, 2, 2, 2);
+ Ref<StyleBoxFlat> style_tree_focus = style_default->duplicate();
+ style_tree_focus->set_bg_color(highlight_color);
+ style_tree_focus->set_border_width_all(0);
theme->set_stylebox("selected_focus", "Tree", style_tree_focus);
- Ref<StyleBoxFlat> style_tree_selected = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 2, 2, 2, 2);
+ Ref<StyleBoxFlat> style_tree_selected = style_tree_focus->duplicate();
theme->set_stylebox("selected", "Tree", style_tree_selected);
- Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_BG, 4, 4, 4, 4);
+ Ref<StyleBoxFlat> style_tree_cursor = style_default->duplicate();
style_tree_cursor->set_draw_center(false);
style_tree_cursor->set_border_width_all(border_width);
style_tree_cursor->set_border_color_all(contrast_color_1);
- Ref<StyleBoxFlat> style_tree_title = make_flat_stylebox(dark_color_3, 4, 4, 4, 4);
+ Ref<StyleBoxFlat> style_tree_title = style_default->duplicate();
+ style_tree_title->set_bg_color(dark_color_3);
+ style_tree_title->set_border_width_all(0);
theme->set_stylebox("cursor", "Tree", style_tree_cursor);
theme->set_stylebox("cursor_unfocused", "Tree", style_tree_cursor);
theme->set_stylebox("title_button_normal", "Tree", style_tree_title);
theme->set_stylebox("title_button_hover", "Tree", style_tree_title);
theme->set_stylebox("title_button_pressed", "Tree", style_tree_title);
- Color prop_category_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.12) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.2);
- Color prop_section_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.09) : dark_color_1.linear_interpolate(Color(0, 1, 0, 1), 0.1);
- Color prop_subsection_color = dark_theme ? dark_color_1.linear_interpolate(Color(1, 1, 1, 1), 0.06) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.1);
+ // Color prop_category_color = dark_color_1.linear_interpolate(mono_color, 0.12) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.2);
+ // Color prop_section_color = dark_color_1.linear_interpolate(mono_color, 0.09) : dark_color_1.linear_interpolate(Color(0, 1, 0, 1), 0.1);
+ // Color prop_subsection_color = dark_color_1.linear_interpolate(mono_color, 0.06) : dark_color_1.linear_interpolate(Color(0, 0, 0, 1), 0.1);
+ Color prop_category_color = dark_color_1.linear_interpolate(mono_color, 0.12);
+ Color prop_section_color = dark_color_1.linear_interpolate(mono_color, 0.09);
+ Color prop_subsection_color = dark_color_1.linear_interpolate(mono_color, 0.06);
theme->set_color("prop_category", "Editor", prop_category_color);
theme->set_color("prop_section", "Editor", prop_section_color);
theme->set_color("prop_subsection", "Editor", prop_subsection_color);
- theme->set_color("drop_position_color", "Tree", highlight_color);
+ theme->set_color("drop_position_color", "Tree", accent_color);
// ItemList
- Ref<StyleBoxFlat> style_itemlist_bg = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
+ Ref<StyleBoxFlat> style_itemlist_bg = style_default->duplicate();
+ style_itemlist_bg->set_bg_color(dark_color_1);
style_itemlist_bg->set_border_width_all(border_width);
style_itemlist_bg->set_border_color_all(dark_color_3);
- Ref<StyleBoxFlat> style_itemlist_cursor = make_flat_stylebox(highlight_color, 0, 0, 0, 0);
+ Ref<StyleBoxFlat> style_itemlist_cursor = style_default->duplicate();
style_itemlist_cursor->set_draw_center(false);
style_itemlist_cursor->set_border_width_all(border_width);
- style_itemlist_cursor->set_border_color_all(HIGHLIGHT_COLOR_BG);
+ style_itemlist_cursor->set_border_color_all(highlight_color);
theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor);
theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor);
theme->set_stylebox("selected_focus", "ItemList", style_tree_focus);
theme->set_stylebox("selected", "ItemList", style_tree_selected);
- theme->set_stylebox("bg_focus", "ItemList", focus_sbt);
+ theme->set_stylebox("bg_focus", "ItemList", style_focus);
theme->set_stylebox("bg", "ItemList", style_itemlist_bg);
theme->set_constant("vseparation", "ItemList", 5 * EDSCALE);
theme->set_color("font_color", "ItemList", font_color);
- Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(tab_color, 15, 5, 15, 5);
- Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(tab_color, 15, 5, 15, 5);
- style_tab_bg->set_draw_center(false);
-
// Tabs & TabContainer
- theme->set_stylebox("tab_fg", "TabContainer", style_tab_fg);
- theme->set_stylebox("tab_bg", "TabContainer", style_tab_bg);
- theme->set_stylebox("tab_fg", "Tabs", style_tab_fg);
- theme->set_stylebox("tab_bg", "Tabs", style_tab_bg);
+ theme->set_stylebox("tab_fg", "TabContainer", style_tab_selected);
+ theme->set_stylebox("tab_bg", "TabContainer", style_tab_unselected);
+ theme->set_stylebox("tab_fg", "Tabs", style_tab_selected);
+ theme->set_stylebox("tab_bg", "Tabs", style_tab_unselected);
theme->set_color("font_color_fg", "TabContainer", font_color);
theme->set_color("font_color_bg", "TabContainer", font_color_disabled);
theme->set_color("font_color_fg", "Tabs", font_color);
theme->set_color("font_color_bg", "Tabs", font_color_disabled);
theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
theme->set_icon("menu_hl", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
- theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(base_color, 10, 5, 10, 5));
- theme->set_stylebox("SceneTabBG", "EditorStyles", make_empty_stylebox(6, 5, 6, 5));
+ theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected);
+ theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected);
theme->set_icon("close", "Tabs", theme->get_icon("GuiClose", "EditorIcons"));
theme->set_stylebox("button_pressed", "Tabs", style_menu);
theme->set_stylebox("button", "Tabs", style_menu);
+ // Content of each tab
+ Ref<StyleBoxFlat> style_content_panel = style_default->duplicate();
+ style_content_panel->set_border_color_all(dark_color_3);
+ style_content_panel->set_border_width_all(border_width);
+ // compensate the border
+ style_content_panel->set_default_margin(MARGIN_TOP, margin_size_extra * EDSCALE);
+ style_content_panel->set_default_margin(MARGIN_RIGHT, margin_size_extra * EDSCALE);
+ style_content_panel->set_default_margin(MARGIN_BOTTOM, margin_size_extra * EDSCALE);
+ style_content_panel->set_default_margin(MARGIN_LEFT, margin_size_extra * EDSCALE);
+
+ // this is the stylebox used in 3d and 2d viewports (no borders)
+ Ref<StyleBoxFlat> style_content_panel_vp = style_content_panel->duplicate();
+ style_content_panel_vp->set_default_margin(MARGIN_LEFT, border_width * 2);
+ style_content_panel_vp->set_default_margin(MARGIN_TOP, default_margin_size * EDSCALE);
+ style_content_panel_vp->set_default_margin(MARGIN_RIGHT, border_width * 2);
+ style_content_panel_vp->set_default_margin(MARGIN_BOTTOM, border_width * 2);
+ theme->set_stylebox("panel", "TabContainer", style_content_panel);
+ theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
+
// Separators (no separators)
theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, border_width));
theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, border_width, 0, true));
- // Debugger
- Ref<StyleBoxFlat> style_panel_debugger = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger);
-
- Ref<StyleBoxFlat> style_tab_fg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
- Ref<StyleBoxFlat> style_tab_bg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
- style_tab_bg_debugger->set_draw_center(false);
+ // HACK Debuger panel
+ Ref<StyleBoxFlat> style_panel_debugger = style_content_panel->duplicate();
+ const int v_offset = theme->get_font("font", "Tabs")->get_height() + style_tab_selected->get_minimum_size().height + default_margin_size * EDSCALE;
+ style_panel_debugger->set_expand_margin_size(MARGIN_TOP, -v_offset);
+ theme->set_stylebox("debugger_panel", "EditorStyles", style_panel_debugger);
+ // Debugger
+ Ref<StyleBoxFlat> style_debugger_contents = style_content_panel->duplicate();
+ style_debugger_contents->set_default_margin(MARGIN_LEFT, 0);
+ style_debugger_contents->set_default_margin(MARGIN_BOTTOM, 0);
+ style_debugger_contents->set_default_margin(MARGIN_RIGHT, 0);
+ style_debugger_contents->set_border_width_all(0);
+ style_debugger_contents->set_expand_margin_size(MARGIN_TOP, -v_offset);
+ theme->set_constant("extra_margin", "DebuggerPanel", default_margin_size * EDSCALE + border_width);
+ theme->set_stylebox("DebuggerPanel", "EditorStyles", style_debugger_contents);
+ Ref<StyleBoxFlat> style_tab_fg_debugger = style_tab_selected->duplicate();
+ style_tab_fg_debugger->set_expand_margin_size(MARGIN_LEFT, default_margin_size * EDSCALE + border_width);
+ style_tab_fg_debugger->set_default_margin(MARGIN_LEFT, tab_default_margin_side - default_margin_size * EDSCALE);
theme->set_stylebox("DebuggerTabFG", "EditorStyles", style_tab_fg_debugger);
+ Ref<StyleBoxFlat> style_tab_bg_debugger = style_tab_unselected->duplicate();
+ style_tab_bg_debugger->set_expand_margin_size(MARGIN_LEFT, default_margin_size * EDSCALE + border_width);
+ style_tab_bg_debugger->set_default_margin(MARGIN_LEFT, tab_default_margin_side - default_margin_size * EDSCALE);
theme->set_stylebox("DebuggerTabBG", "EditorStyles", style_tab_bg_debugger);
// LineEdit
- Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4);
- style_line_edit->set_border_width_all(border_width);
- style_line_edit = change_border_color(style_line_edit, contrast_color_1);
- Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1);
- style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1));
- Ref<StyleBoxFlat> style_line_edit_focus = change_border_color(style_line_edit, highlight_color);
- theme->set_stylebox("normal", "LineEdit", style_line_edit);
- theme->set_stylebox("focus", "LineEdit", style_line_edit_focus);
- theme->set_stylebox("read_only", "LineEdit", style_line_edit_disabled);
+ theme->set_stylebox("normal", "LineEdit", style_widget);
+ theme->set_stylebox("focus", "LineEdit", style_widget_focus);
+ theme->set_stylebox("read_only", "LineEdit", style_widget_disabled);
theme->set_color("read_only", "LineEdit", font_color_disabled);
theme->set_color("font_color", "LineEdit", font_color);
theme->set_color("cursor_color", "LineEdit", font_color);
// TextEdit
- Ref<StyleBoxFlat> style_textedit_normal(memnew(StyleBoxFlat));
- style_textedit_normal->set_bg_color(dark_color_2);
- style_textedit_normal->set_default_margin(MARGIN_LEFT, 0);
- style_textedit_normal->set_default_margin(MARGIN_RIGHT, 0);
- style_textedit_normal->set_default_margin(MARGIN_BOTTOM, 0);
- style_textedit_normal->set_default_margin(MARGIN_TOP, 0);
- theme->set_stylebox("normal", "TextEdit", style_textedit_normal);
- theme->set_stylebox("focus", "TextEdit", focus_sbt);
+ theme->set_stylebox("normal", "TextEdit", style_widget);
+ theme->set_stylebox("focus", "TextEdit", style_widget_hover);
theme->set_constant("side_margin", "TabContainer", 0);
+ theme->set_icon("tab", "TextEdit", theme->get_icon("GuiTab", "EditorIcons"));
// H/VSplitContainer
theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1));
@@ -558,13 +680,23 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("grabber", "VSplitContainer", theme->get_icon("GuiVsplitter", "EditorIcons"));
theme->set_icon("grabber", "HSplitContainer", theme->get_icon("GuiHsplitter", "EditorIcons"));
- theme->set_constant("separation", "HSplitContainer", 8 * EDSCALE);
- theme->set_constant("separation", "VSplitContainer", 8 * EDSCALE);
+ theme->set_constant("separation", "HSplitContainer", default_margin_size * 2 * EDSCALE);
+ theme->set_constant("separation", "VSplitContainer", default_margin_size * 2 * EDSCALE);
+
+ // Containers
+ theme->set_constant("separation", "BoxContainer", default_margin_size * EDSCALE);
+ theme->set_constant("separation", "HBoxContainer", default_margin_size * EDSCALE);
+ theme->set_constant("separation", "VBoxContainer", default_margin_size * EDSCALE);
+ theme->set_constant("margin_left", "MarginContainer", 0);
+ theme->set_constant("margin_top", "MarginContainer", 0);
+ theme->set_constant("margin_right", "MarginContainer", 0);
+ theme->set_constant("margin_bottom", "MarginContainer", 0);
+ theme->set_constant("hseparation", "GridContainer", default_margin_size * EDSCALE);
+ theme->set_constant("vseparation", "GridContainer", default_margin_size * EDSCALE);
// WindowDialog
- Ref<StyleBoxFlat> style_window = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- style_window->set_border_width_all(MAX(EDSCALE, border_width));
- style_window->set_border_color_all(base_color);
+ Ref<StyleBoxFlat> style_window = style_popup->duplicate();
+ style_window->set_border_color_all(tab_color);
style_window->set_border_width(MARGIN_TOP, 24 * EDSCALE);
style_window->set_expand_margin_size(MARGIN_TOP, 24 * EDSCALE);
theme->set_stylebox("panel", "WindowDialog", style_window);
@@ -575,6 +707,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("close_v_ofs", "WindowDialog", 20 * EDSCALE);
theme->set_constant("title_height", "WindowDialog", 24 * EDSCALE);
+ // complex window, for now only Editor settings and Project settings
+ Ref<StyleBoxFlat> style_complex_window = style_window->duplicate();
+ style_complex_window->set_bg_color(dark_color_2);
+ style_complex_window->set_border_color_all(highlight_tabs ? tab_color : dark_color_2);
+ theme->set_stylebox("panel", "EditorSettingsDialog", style_complex_window);
+ theme->set_stylebox("panel", "ProjectSettingsEditor", style_complex_window);
+ theme->set_stylebox("panel", "EditorAbout", style_complex_window);
+
// HScrollBar
Ref<Texture> empty_icon = memnew(ImageTexture);
@@ -602,21 +742,33 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("decrement_highlight", "VScrollBar", empty_icon);
// HSlider
- theme->set_stylebox("slider", "HSlider", make_stylebox(theme->get_icon("GuiHsliderBg", "EditorIcons"), 4, 4, 4, 4));
- theme->set_icon("grabber", "HSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
theme->set_icon("grabber_highlight", "HSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
+ theme->set_icon("grabber", "HSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
+ theme->set_stylebox("slider", "HSlider", make_flat_stylebox(dark_color_3, 0, default_margin_size / 2, 0, default_margin_size / 2));
+ theme->set_stylebox("grabber_area", "HSlider", make_flat_stylebox(contrast_color_1, 0, default_margin_size / 2, 0, default_margin_size / 2));
// VSlider
- theme->set_stylebox("slider", "VSlider", make_stylebox(theme->get_icon("GuiVsliderBg", "EditorIcons"), 4, 4, 4, 4));
theme->set_icon("grabber", "VSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
+ theme->set_stylebox("slider", "VSlider", make_flat_stylebox(dark_color_3, default_margin_size / 2, 0, default_margin_size / 2, 0));
+ theme->set_stylebox("grabber_area", "VSlider", make_flat_stylebox(contrast_color_1, default_margin_size / 2, 0, default_margin_size / 2, 0));
//RichTextLabel
Color rtl_combined_bg_color = dark_color_1.linear_interpolate(script_bg_color, script_bg_color.a);
- Color rtl_font_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 0.5 * 3) ? Color(0, 0, 0) : Color(1, 1, 1);
+ Color rtl_mono_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 1.5) ? Color(0, 0, 0) : Color(1, 1, 1);
+ Color rtl_font_color = rtl_mono_color.linear_interpolate(rtl_combined_bg_color, 0.25);
theme->set_color("default_color", "RichTextLabel", rtl_font_color);
theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox());
- theme->set_stylebox("normal", "RichTextLabel", make_flat_stylebox(script_bg_color, 6, 6, 6, 6));
+ theme->set_stylebox("normal", "RichTextLabel", style_tree_bg);
+ Ref<StyleBoxFlat> style_code = style_tree_bg->duplicate();
+ style_code->set_bg_color(rtl_combined_bg_color);
+ theme->set_stylebox("code_normal", "RichTextLabel", style_code);
+ Ref<StyleBoxFlat> style_code_focus = style_tree_focus->duplicate();
+ style_code_focus->set_bg_color(rtl_combined_bg_color);
+ theme->set_stylebox("code_focus", "RichTextLabel", style_code_focus);
+
+ theme->set_color("font_color", "RichTextLabel", rtl_font_color);
+ theme->set_color("highlight_color", "RichTextLabel", rtl_mono_color);
// Panel
theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4));
@@ -625,18 +777,15 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color", "Label", font_color);
// TooltipPanel
- Ref<StyleBoxFlat> style_tooltip = make_flat_stylebox(Color(1, 1, 1, 0.8), 8, 8, 8, 8);
+ Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate();
+ style_tooltip->set_bg_color(Color(mono_color.r, mono_color.g, mono_color.b, 0.9));
style_tooltip->set_border_width_all(border_width);
- style_tooltip->set_border_color_all(HIGHLIGHT_COLOR_FONT);
+ style_tooltip->set_border_color_all(mono_color);
theme->set_color("font_color", "TooltipPanel", font_color);
theme->set_stylebox("panel", "TooltipPanel", style_tooltip);
// PopupPanel
- Ref<StyleBoxFlat> style_dock_select = make_flat_stylebox(base_color);
- style_dock_select->set_border_color_all(contrast_color_1);
- style_dock_select->set_expand_margin_size_all(2);
- style_dock_select->set_border_width_all(2);
- theme->set_stylebox("panel", "PopupPanel", style_dock_select);
+ theme->set_stylebox("panel", "PopupPanel", style_popup);
// SpinBox
theme->set_icon("updown", "SpinBox", theme->get_icon("GuiSpinboxUpdown", "EditorIcons"));
@@ -647,39 +796,126 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color", "ProgressBar", font_color);
// GraphEdit
- theme->set_stylebox("bg", "GraphEdit", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
- theme->set_color("grid_major", "GraphEdit", Color(font_color.r, font_color.g, font_color.b, 0.2));
- theme->set_color("grid_minor", "GraphEdit", Color(font_color_disabled.r, font_color_disabled.g, font_color_disabled.b, 0.2));
+ theme->set_stylebox("bg", "GraphEdit", style_tree_bg);
+ theme->set_color("grid_major", "GraphEdit", Color(font_color.r, font_color.g, font_color.b, 0.1));
+ theme->set_color("grid_minor", "GraphEdit", Color(font_color_disabled.r, font_color_disabled.g, font_color_disabled.b, 0.05));
theme->set_icon("minus", "GraphEdit", theme->get_icon("ZoomLess", "EditorIcons"));
theme->set_icon("more", "GraphEdit", theme->get_icon("ZoomMore", "EditorIcons"));
theme->set_icon("reset", "GraphEdit", theme->get_icon("ZoomReset", "EditorIcons"));
// GraphNode
- Ref<StyleBoxFlat> graphsb = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
+
+ const int gn_margin_side = 28;
+ Ref<StyleBoxFlat> graphsb = make_flat_stylebox(Color(0, 0, 0, 0.3), gn_margin_side, 24, gn_margin_side, 5);
graphsb->set_border_width_all(border_width);
- graphsb->set_border_color_all(Color(1, 1, 1, 0.6));
- graphsb->set_border_width(MARGIN_TOP, 22 * EDSCALE + border_width);
- Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
+ graphsb->set_border_color_all(Color(1, 1, 1, 0.9));
+ Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(Color(0, 0, 0, 0.4), gn_margin_side, 24, gn_margin_side, 5);
graphsbselected->set_border_width_all(border_width);
- graphsbselected->set_border_color_all(Color(1, 1, 1, 0.9));
- graphsbselected->set_border_width(MARGIN_TOP, 22 * EDSCALE + border_width);
- Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
+ graphsbselected->set_border_color_all(Color(accent_color.r, accent_color.g, accent_color.b, 0.9));
+ graphsbselected->set_shadow_size(8 * EDSCALE);
+ graphsbselected->set_shadow_color(shadow_color);
+ Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(Color(0, 0, 0, 0.3), gn_margin_side, 24, gn_margin_side, 5);
graphsbcomment->set_border_width_all(border_width);
- graphsbcomment->set_border_color_all(Color(1, 1, 1, 0.6));
- graphsbcomment->set_border_width(MARGIN_TOP, 22 * EDSCALE + border_width);
- Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
+ graphsbcomment->set_border_color_all(Color(1, 1, 1, 0.9));
+ Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(Color(0, 0, 0, 0.4), gn_margin_side, 24, gn_margin_side, 5);
graphsbcommentselected->set_border_width_all(border_width);
graphsbcommentselected->set_border_color_all(Color(1, 1, 1, 0.9));
- graphsbcommentselected->set_border_width(MARGIN_TOP, 22 * EDSCALE + border_width);
+
+ if (use_gn_headers) {
+ graphsb->set_border_width(MARGIN_TOP, 24 * EDSCALE);
+ graphsbselected->set_border_width(MARGIN_TOP, 24 * EDSCALE);
+ graphsbcomment->set_border_width(MARGIN_TOP, 24 * EDSCALE);
+ graphsbcommentselected->set_border_width(MARGIN_TOP, 24 * EDSCALE);
+ }
+
theme->set_stylebox("frame", "GraphNode", graphsb);
theme->set_stylebox("selectedframe", "GraphNode", graphsbselected);
theme->set_stylebox("comment", "GraphNode", graphsbcomment);
theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected);
+ theme->set_constant("port_offset", "GraphNode", 14 * EDSCALE);
+ theme->set_constant("title_h_offset", "GraphNode", -16 * EDSCALE);
+ theme->set_constant("close_h_offset", "GraphNode", 20 * EDSCALE);
+ theme->set_constant("close_offset", "GraphNode", 20 * EDSCALE);
+ theme->set_icon("close", "GraphNode", theme->get_icon("GuiCloseCustomizable", "EditorIcons"));
+ theme->set_icon("resizer", "GraphNode", theme->get_icon("GuiResizer", "EditorIcons"));
+ theme->set_icon("port", "GraphNode", theme->get_icon("GuiGraphNodePort", "EditorIcons"));
// FileDialog
- Color disable_color = contrast_color_2;
- disable_color.a = 0.7;
- theme->set_color("files_disabled", "FileDialog", disable_color);
+ theme->set_color("files_disabled", "FileDialog", font_color_disabled);
+
+ // adaptive script theme constants
+ // for comments and elements with lower relevance
+ const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5);
+
+ const float mono_value = mono_color.r;
+ const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.1);
+ const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.3);
+ const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.5);
+ const Color alpha4 = Color(mono_value, mono_value, mono_value, 0.7);
+
+ // editor main color
+ const Color main_color = Color::html(dark_theme ? "#57b3ff" : "#0480ff");
+
+ const Color symbol_color = Color::html("#5792ff").linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color keyword_color = main_color.linear_interpolate(mono_color, 0.4);
+ const Color basetype_color = Color::html(dark_theme ? "#42ffc2" : "#00c161");
+ const Color type_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.7 : 0.5);
+ const Color comment_color = dim_color;
+ const Color string_color = Color::html(dark_theme ? "#ffd942" : "#ffd118").linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+
+ const Color te_background_color = Color(0, 0, 0, 0);
+ const Color completion_background_color = base_color;
+ const Color completion_selected_color = alpha1;
+ const Color completion_existing_color = alpha2;
+ const Color completion_scroll_color = alpha1;
+ const Color completion_font_color = font_color;
+ const Color text_color = font_color;
+ const Color line_number_color = dim_color;
+ const Color caret_color = mono_color;
+ const Color caret_background_color = mono_color.inverted();
+ const Color text_selected_color = dark_color_3;
+ const Color selection_color = alpha3;
+ const Color brace_mismatch_color = error_color;
+ const Color current_line_color = alpha1;
+ const Color line_length_guideline_color = warning_color;
+ const Color word_highlighted_color = alpha1;
+ const Color number_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color function_color = main_color;
+ const Color member_variable_color = mono_color;
+ const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3);
+ const Color breakpoint_color = error_color;
+ const Color search_result_color = alpha1;
+ const Color search_result_border_color = alpha4;
+
+ theme->set_color("text_editor/theme/symbol_color", "Editor", symbol_color);
+ theme->set_color("text_editor/theme/keyword_color", "Editor", keyword_color);
+ theme->set_color("text_editor/theme/basetype_color", "Editor", basetype_color);
+ theme->set_color("text_editor/theme/type_color", "Editor", type_color);
+ theme->set_color("text_editor/theme/comment_color", "Editor", comment_color);
+ theme->set_color("text_editor/theme/string_color", "Editor", string_color);
+ theme->set_color("text_editor/theme/background_color", "Editor", te_background_color);
+ theme->set_color("text_editor/theme/completion_background_color", "Editor", completion_background_color);
+ theme->set_color("text_editor/theme/completion_selected_color", "Editor", completion_selected_color);
+ theme->set_color("text_editor/theme/completion_existing_color", "Editor", completion_existing_color);
+ theme->set_color("text_editor/theme/completion_scroll_color", "Editor", completion_scroll_color);
+ theme->set_color("text_editor/theme/completion_font_color", "Editor", completion_font_color);
+ theme->set_color("text_editor/theme/text_color", "Editor", text_color);
+ theme->set_color("text_editor/theme/line_number_color", "Editor", line_number_color);
+ theme->set_color("text_editor/theme/caret_color", "Editor", caret_color);
+ theme->set_color("text_editor/theme/caret_background_color", "Editor", caret_background_color);
+ theme->set_color("text_editor/theme/text_selected_color", "Editor", text_selected_color);
+ theme->set_color("text_editor/theme/selection_color", "Editor", selection_color);
+ theme->set_color("text_editor/theme/brace_mismatch_color", "Editor", brace_mismatch_color);
+ theme->set_color("text_editor/theme/current_line_color", "Editor", current_line_color);
+ theme->set_color("text_editor/theme/line_length_guideline_color", "Editor", line_length_guideline_color);
+ theme->set_color("text_editor/theme/word_highlighted_color", "Editor", word_highlighted_color);
+ theme->set_color("text_editor/theme/number_color", "Editor", number_color);
+ theme->set_color("text_editor/theme/function_color", "Editor", function_color);
+ theme->set_color("text_editor/theme/member_variable_color", "Editor", member_variable_color);
+ theme->set_color("text_editor/theme/mark_color", "Editor", mark_color);
+ theme->set_color("text_editor/theme/breakpoint_color", "Editor", breakpoint_color);
+ theme->set_color("text_editor/theme/search_result_color", "Editor", search_result_color);
+ theme->set_color("text_editor/theme/search_result_border_color", "Editor", search_result_border_color);
return theme;
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index a66d1724a1..526a8fe810 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -143,11 +143,7 @@ void FileSystemDock::_notification(int p_what) {
//button_instance->set_icon( get_icon("Add","EditorIcons"));
//button_open->set_icon( get_icon("Folder","EditorIcons"));
button_back->set_icon(get_icon("Filesystem", "EditorIcons"));
- if (display_mode == DISPLAY_THUMBNAILS) {
- button_display_mode->set_icon(get_icon("FileList", "EditorIcons"));
- } else {
- button_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons"));
- }
+ _update_file_display_toggle_button();
button_display_mode->connect("pressed", this, "_change_file_display");
//file_options->set_icon( get_icon("Tools","EditorIcons"));
files->connect("item_activated", this, "_select_file");
@@ -204,20 +200,13 @@ void FileSystemDock::_notification(int p_what) {
button_reload->set_icon(get_icon("Reload", "EditorIcons"));
button_favorite->set_icon(get_icon("Favorites", "EditorIcons"));
button_back->set_icon(get_icon("Filesystem", "EditorIcons"));
- if (display_mode == DISPLAY_THUMBNAILS) {
- button_display_mode->set_icon(get_icon("FileList", "EditorIcons"));
- } else {
- button_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons"));
- }
+ _update_file_display_toggle_button();
search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons"));
button_hist_next->set_icon(get_icon("Forward", "EditorIcons"));
button_hist_prev->set_icon(get_icon("Back", "EditorIcons"));
- Theme::get_default()->clear_icon("ResizedFolder", "EditorIcons");
- Theme::get_default()->clear_icon("ResizedFile", "EditorIcons");
-
if (new_mode != display_mode) {
set_display_mode(new_mode);
} else {
@@ -354,15 +343,22 @@ void FileSystemDock::_thumbnail_done(const String &p_path, const Ref<Texture> &p
}
}
-void FileSystemDock::_change_file_display() {
+void FileSystemDock::_update_file_display_toggle_button() {
if (button_display_mode->is_pressed()) {
display_mode = DISPLAY_LIST;
button_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons"));
+ button_display_mode->set_tooltip(TTR("View items as a grid of thumbnails"));
} else {
display_mode = DISPLAY_THUMBNAILS;
button_display_mode->set_icon(get_icon("FileList", "EditorIcons"));
+ button_display_mode->set_tooltip(TTR("View items as a list"));
}
+}
+
+void FileSystemDock::_change_file_display() {
+
+ _update_file_display_toggle_button();
EditorSettings::get_singleton()->set("docks/filesystem/display_mode", display_mode);
@@ -426,8 +422,10 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
Ref<Texture> file_thumbnail;
Ref<Texture> file_thumbnail_broken;
+ bool always_show_folders = EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders");
+
bool use_thumbnails = (display_mode == DISPLAY_THUMBNAILS);
- bool use_folders = search_box->get_text().length() == 0 && split_mode;
+ bool use_folders = search_box->get_text().length() == 0 && (split_mode || always_show_folders);
if (use_thumbnails) { //thumbnails
@@ -437,39 +435,15 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
files->set_max_text_lines(2);
files->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
- if (!has_icon("ResizedFolder", "EditorIcons")) {
- Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
- Ref<Image> img = folder->get_data();
- img = img->duplicate();
- 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");
- Ref<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);
- }
-
- if (!has_icon("ResizedFileBroken", "EditorIcons")) {
- Ref<ImageTexture> file = get_icon("FileBigBroken", "EditorIcons");
- Ref<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("ResizedFileBroken", "EditorIcons", resized_file);
+ if (thumbnail_size < 64) {
+ folder_thumbnail = get_icon("FolderMediumThumb", "EditorIcons");
+ file_thumbnail = get_icon("FileMediumThumb", "EditorIcons");
+ file_thumbnail_broken = get_icon("FileDeadMediumThumb", "EditorIcons");
+ } else {
+ folder_thumbnail = get_icon("FolderBigThumb", "EditorIcons");
+ file_thumbnail = get_icon("FileBigThumb", "EditorIcons");
+ file_thumbnail_broken = get_icon("FileDeadBigThumb", "EditorIcons");
}
-
- file_thumbnail = get_icon("ResizedFile", "EditorIcons");
-
- file_thumbnail_broken = get_icon("ResizedFileBroken", "EditorIcons");
} else {
files->set_icon_mode(ItemList::ICON_MODE_LEFT);
@@ -1838,8 +1812,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
display_mode = DISPLAY_THUMBNAILS;
path = "res://";
-
- add_constant_override("separation", 4);
}
FileSystemDock::~FileSystemDock() {
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index a35b145085..aec049ba43 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -144,6 +144,7 @@ private:
void _file_option(int p_option);
void _folder_option(int p_option);
void _update_files(bool p_keep_selection);
+ void _update_file_display_toggle_button();
void _change_file_display();
void _fs_changed();
diff --git a/editor/icons/SCsub b/editor/icons/SCsub
index 534a8186a5..e28c229a38 100644
--- a/editor/icons/SCsub
+++ b/editor/icons/SCsub
@@ -39,18 +39,44 @@ def make_editor_icons_action(target, source, env):
s.write(icons_string.getvalue())
s.write('};\n\n')
s.write("static const char *editor_icons_names[] = {\n")
+
+ # this is used to store the indices of thumbnail icons
+ thumb_medium_indices = [];
+ thumb_big_indices = [];
+ index = 0
for f in svg_icons:
fname = str(f)
icon_name = os.path.basename(fname)[5:-4].title().replace("_", "")
+ if icon_name.endswith("MediumThumb"): # dont know a better way to handle this
+ thumb_medium_indices.append(str(index))
+ if icon_name.endswith("BigThumb"): # dont know a better way to handle this
+ thumb_big_indices.append(str(index))
s.write('\t"%s"' % icon_name)
if fname != svg_icons[-1]:
s.write(",")
s.write('\n')
+
+ index += 1
+
s.write('};\n')
+
+ if thumb_medium_indices:
+ s.write("\n\n")
+ s.write("static const int editor_md_thumbs_count = %s;\n" % len(thumb_medium_indices))
+ s.write("static const int editor_md_thumbs_indices[] = {")
+ s.write(", ".join(thumb_medium_indices))
+ s.write("};\n")
+ if thumb_big_indices:
+ s.write("\n\n")
+ s.write("static const int editor_bg_thumbs_count = %s;\n" % len(thumb_big_indices))
+ s.write("static const int editor_bg_thumbs_indices[] = {")
+ s.write(", ".join(thumb_big_indices))
+ s.write("};\n")
+
s.write("#endif\n")
diff --git a/editor/icons/icon_GUI_hslider_bg.svg b/editor/icons/icon_GUI_hslider_bg.svg
deleted file mode 100644
index e298d06c4c..0000000000
--- a/editor/icons/icon_GUI_hslider_bg.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="1" y="1041.4" width="14" height="6" ry="0" fill-opacity=".39216" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_GUI_tab.svg b/editor/icons/icon_GUI_tab.svg
new file mode 100644
index 0000000000..3eed0680c0
--- /dev/null
+++ b/editor/icons/icon_GUI_tab.svg
@@ -0,0 +1,5 @@
+<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1044.4)">
+<path transform="translate(0 1044.4)" d="m6 0v8h2v-8h-2zm-5.0137 0.0019531a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l2.293 2.293-2.293 2.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l3-3a1.0001 1.0001 0 0 0 0 -1.4141l-3-3a1 1 0 0 0 -0.7207 -0.29102z" fill="#fff" fill-opacity=".19608"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_GUI_vslider_bg.svg b/editor/icons/icon_GUI_vslider_bg.svg
deleted file mode 100644
index 99d01420b6..0000000000
--- a/editor/icons/icon_GUI_vslider_bg.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="6" y="1037.4" width="4" height="14" ry="0" fill-opacity=".39216" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".32549" stroke-width="2"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_a_r_v_r_camera.svg b/editor/icons/icon_a_r_v_r_camera.svg
new file mode 100644
index 0000000000..a02b4d983c
--- /dev/null
+++ b/editor/icons/icon_a_r_v_r_camera.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m2 1c-0.55401 0-1 0.446-1 1v7c0 0.554 0.44599 1 1 1h4l1-2c0.24699-0.494 0.44772-1 1-1s0.75301 0.506 1 1l1 2h4c0.55401 0 1-0.446 1-1v-7c0-0.554-0.44599-1-1-1h-12zm2 3a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-8 7v4h2c0.502 4e-4 0.9265-0.37144 0.99219-0.86914 0.0059-0.047 0.0085325-0.094025 0.0078125-0.14062v-2.9902h-1v3h-1v-3h-1zm5 0v4h1v-1h1v1h1v-1c-7.73e-4 -0.1811-0.05073-0.35867-0.14453-0.51367 0.08369-0.1462 0.14453-0.30573 0.14453-0.48633v-1c0-0.5523-0.4485-1.0293-1-1h-2zm1 1h1v1h-1v-1z" fill="#fc9c9c"/>
+</svg>
diff --git a/editor/icons/icon_area.svg b/editor/icons/icon_area.svg
index 22348d50c1..ac673d10fc 100644
--- a/editor/icons/icon_area.svg
+++ b/editor/icons/icon_area.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c" fill-opacity=".99608"/>
+<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c"/>
</g>
</svg>
diff --git a/editor/icons/icon_error.svg b/editor/icons/icon_error.svg
index 771a418cfa..846bd88cb1 100644
--- a/editor/icons/icon_error.svg
+++ b/editor/icons/icon_error.svg
@@ -1,5 +1,5 @@
<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1044.4)">
-<rect x="2.2204e-16" y="1044.4" width="8" height="8" ry="4" fill="#ff8484"/>
+<rect x="2.2204e-16" y="1044.4" width="8" height="8" ry="4" fill="#ff5d5d"/>
</g>
</svg>
diff --git a/editor/icons/icon_error_sign.svg b/editor/icons/icon_error_sign.svg
index a2d714c31a..bde0494a93 100644
--- a/editor/icons/icon_error_sign.svg
+++ b/editor/icons/icon_error_sign.svg
@@ -1,7 +1,6 @@
<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1020.4)">
-<path d="m10 1048.4h12l6-6v-12l-6-6h-12l-6 6v12z" fill="#ff8484" fill-rule="evenodd"/>
-<rect x="14" y="1028.4" width="4" height="9" fill="#fff"/>
-<rect x="14" y="1040.4" width="4" height="4" fill="#fff"/>
+<path d="m10 1048.4h12l6-6v-12l-6-6h-12l-6 6v12z" fill="#ff5d5d" fill-rule="evenodd"/>
+<path transform="translate(0 1020.4)" d="m14 8l1 10h2l1-10h-4zm2 12a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" fill="#fff"/>
</g>
</svg>
diff --git a/editor/icons/icon_file.svg b/editor/icons/icon_file.svg
new file mode 100644
index 0000000000..67a081a704
--- /dev/null
+++ b/editor/icons/icon_file.svg
@@ -0,0 +1,7 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<g transform="translate(0 -1.6949e-5)">
+<path transform="translate(0 1036.4)" d="m2 1v14h12v-9h-5v-5zm8 0v4h4z" fill="#e0e0e0"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_file_big.svg b/editor/icons/icon_file_big_thumb.svg
index 569b449a59..569b449a59 100644
--- a/editor/icons/icon_file_big.svg
+++ b/editor/icons/icon_file_big_thumb.svg
diff --git a/editor/icons/icon_file_broken.svg b/editor/icons/icon_file_broken.svg
index f352eeb001..7b05ab625e 100644
--- a/editor/icons/icon_file_broken.svg
+++ b/editor/icons/icon_file_broken.svg
@@ -1,7 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 1036.4)" d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 0.69141 -0.29102 1.0001 1.0001 0 0 1 0.72266 0.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4l-4-4zm-6 9.4141l-2 2v2.5859h12v-2.5859l-0.29297 0.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff8484"/>
+<path transform="translate(0 1036.4)" d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 0.69141 -0.29102 1.0001 1.0001 0 0 1 0.72266 0.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4l-4-4zm-6 9.4141l-2 2v2.5859h12v-2.5859l-0.29297 0.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff5d5d"/>
</g>
</g>
</svg>
diff --git a/editor/icons/icon_file_big_broken.svg b/editor/icons/icon_file_broken_big_thumb.svg
index 167bb1bb5f..5e8fa607c1 100644
--- a/editor/icons/icon_file_big_broken.svg
+++ b/editor/icons/icon_file_broken_big_thumb.svg
@@ -1,7 +1,7 @@
<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -988.36)">
<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 988.36)" d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707 0.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 0.29297 -0.70703v-11.172a1.0001 1.0001 0 0 0 -0.29297 -0.70703l-16-16a1.0001 1.0001 0 0 0 -0.70703 -0.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253 0.87473-2 2-2zm0.98438 28.83a1.0001 1.0001 0 0 0 -0.69141 0.29297l-4 4a1.0001 1.0001 0 0 0 -0.29297 0.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707 -0.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -0.72266 -0.29297zm0.015625 2.4141l9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-0.87473 2-2 2h-36c-1.1253 0-2-0.87473-2-2v-13.756l3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff8484" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path transform="translate(0 988.36)" d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707 0.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 0.29297 -0.70703v-11.172a1.0001 1.0001 0 0 0 -0.29297 -0.70703l-16-16a1.0001 1.0001 0 0 0 -0.70703 -0.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253 0.87473-2 2-2zm0.98438 28.83a1.0001 1.0001 0 0 0 -0.69141 0.29297l-4 4a1.0001 1.0001 0 0 0 -0.29297 0.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707 -0.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -0.72266 -0.29297zm0.015625 2.4141l9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-0.87473 2-2 2h-36c-1.1253 0-2-0.87473-2-2v-13.756l3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff5d5d" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="filter-blend-mode:normal;filter-gaussianBlur-deviation:0;font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</g>
</svg>
diff --git a/editor/icons/icon_file_dead.svg b/editor/icons/icon_file_dead.svg
index e0aee6fd90..ec13e7087f 100644
--- a/editor/icons/icon_file_dead.svg
+++ b/editor/icons/icon_file_dead.svg
@@ -1,7 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 1036.4)" d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c0.1353-0.0020779 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091882 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm6 0c0.1353-0.00208 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091883 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm-6.4922 4h9c0.277 0 0.5 0.223 0.5 0.5s-0.223 0.5-0.5 0.5h-4.5c0 1.1046-0.89543 2-2 2s-2-0.8954-2-2h-0.5c-0.277 0-0.5-0.223-0.5-0.5s0.223-0.5 0.5-0.5zm1.5 1c-1.9e-5 0.5523 0.44771 1 1 1s1-0.4477 1-1z" fill="#ff8484"/>
+<path transform="translate(0 1036.4)" d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c0.1353-0.0020779 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091882 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm6 0c0.1353-0.00208 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091883 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm-6.4922 4h9c0.277 0 0.5 0.223 0.5 0.5s-0.223 0.5-0.5 0.5h-4.5c0 1.1046-0.89543 2-2 2s-2-0.8954-2-2h-0.5c-0.277 0-0.5-0.223-0.5-0.5s0.223-0.5 0.5-0.5zm1.5 1c-1.9e-5 0.5523 0.44771 1 1 1s1-0.4477 1-1z" fill="#ff5d5d"/>
</g>
</g>
</svg>
diff --git a/editor/icons/icon_file_big_dead.svg b/editor/icons/icon_file_dead_big_thumb.svg
index c8aab912f1..2ac8d1e9df 100644
--- a/editor/icons/icon_file_big_dead.svg
+++ b/editor/icons/icon_file_dead_big_thumb.svg
@@ -1,7 +1,7 @@
<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -988.36)">
<g transform="translate(0 -1.6949e-5)">
-<path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-0.0078c2e-3 -0.2483-0.0793-0.501-0.28516-0.707l-16-16c-0.18788-0.18693-0.44247-0.28939-0.70704-0.28907v-4e-3zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-0.87472 2-2 2h-36c-1.1253 0-2-0.8747-2-2v-46c0-1.1253 0.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm23 0a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff8484" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-0.0078c2e-3 -0.2483-0.0793-0.501-0.28516-0.707l-16-16c-0.18788-0.18693-0.44247-0.28939-0.70704-0.28907v-4e-3zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-0.87472 2-2 2h-36c-1.1253 0-2-0.8747-2-2v-46c0-1.1253 0.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm23 0a1 1 0 0 0 -0.60938 0.2461 1 1 0 0 0 -0.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 0.09375 1.4121 1 1 0 0 0 1.4102 -0.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102 0.094 1 1 0 0 0 0.09375 -1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -0.09375 -1.4121 1 1 0 0 0 -0.63867 -0.2461 1 1 0 0 0 -0.77148 0.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -0.80078 -0.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff5d5d" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</g>
</svg>
diff --git a/editor/icons/icon_file_dead_medium_thumb.svg b/editor/icons/icon_file_dead_medium_thumb.svg
new file mode 100644
index 0000000000..010019ae03
--- /dev/null
+++ b/editor/icons/icon_file_dead_medium_thumb.svg
@@ -0,0 +1,7 @@
+<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1020.4)">
+<g transform="translate(0 -1.6949e-5)">
+<path transform="translate(0 1020.4)" d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-5.1e-5 -0.2652-0.10543-0.51952-0.29297-0.70703l-9.1816-9.1895c-0.18719-0.18825-0.44155-0.29435-0.70703-0.29492h-14.818zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 0.5713-0.42868 1-1 1h-22c-0.57133 0-1-0.4287-1-1v-24c0-0.5713 0.42867-1 1-1zm1.9863 11.002a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -0.7207 -0.29102 1 1 0 0 0 -0.69336 0.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -0.7207 -0.29102zm14 0a1 1 0 0 0 -0.69336 0.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0 -1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0 -1.4141 1 1 0 0 0 -0.7207 -0.29102 1 1 0 0 0 -0.69336 0.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -0.7207 -0.29102zm-13.986 7.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h1a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2 -3.4648h9a1 1 0 0 0 1 -1 1 1 0 0 0 -1 -1h-18zm3 2h4a2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ff5d5d" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_file_medium_thumb.svg b/editor/icons/icon_file_medium_thumb.svg
new file mode 100644
index 0000000000..a143aa5c8f
--- /dev/null
+++ b/editor/icons/icon_file_medium_thumb.svg
@@ -0,0 +1,7 @@
+<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1020.4)">
+<g transform="translate(0 -1.6949e-5)">
+<path transform="translate(0 1020.4)" d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-5.1e-5 -0.2652-0.10543-0.51952-0.29297-0.70703l-9.1816-9.1895c-0.18719-0.18825-0.44155-0.29435-0.70703-0.29492zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 0.5713-0.42868 1-1 1h-22c-0.57133 0-1-0.4287-1-1v-24c0-0.5713 0.42867-1 1-1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fff" fill-opacity=".58824" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_folder_big.svg b/editor/icons/icon_folder_big.svg
deleted file mode 100644
index 1c0cd3584e..0000000000
--- a/editor/icons/icon_folder_big.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -988.36)">
-<path transform="translate(0 988.36)" d="m13 11.996a5.0039 5.0039 0 0 0 -5.0039 5.0039 5.0039 5.0039 0 0 0 0.0039062 0.11719v2.8828 8 22.92a5.0039 5.0039 0 0 0 -0.0039062 0.076172 5.0039 5.0039 0 0 0 5.0039 5.0039h37.996a5.0039 5.0039 0 0 0 5.0039 -5.0039v-25.916a5.0039 5.0039 0 0 0 0.003906 -0.076172 5.0039 5.0039 0 0 0 -5.0039 -5.0039h-11v-0.039062a3.5 3.5 0 0 1 -0.5 0.039062 3.5 3.5 0 0 1 -3.5 -3.5v0.38281a5.0039 5.0039 0 0 0 -5 -4.8867 5.0039 5.0039 0 0 0 -0.11719 0.003906h-17.807a5.0039 5.0039 0 0 0 -0.076172 -0.003906zm23 4.5039a3.5 3.5 0 0 1 0.041016 -0.5h-0.041016v0.5z" fill="#e0e0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_folder_big_thumb.svg b/editor/icons/icon_folder_big_thumb.svg
new file mode 100644
index 0000000000..a7e830b019
--- /dev/null
+++ b/editor/icons/icon_folder_big_thumb.svg
@@ -0,0 +1,5 @@
+<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -988.36)">
+<path transform="translate(0 988.36)" d="m12 10c-2.2091 0-4 1.7909-4 4v37h0.13086c0.45564 1.7647 2.0466 2.9982 3.8691 3h40c2.2091 0 4-1.7909 4-4v-28c0-2.2091-1.7909-4-4-4h-16l-2-4c-0.98796-1.9759-1.7909-4-4-4z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_folder_medium_thumb.svg b/editor/icons/icon_folder_medium_thumb.svg
new file mode 100644
index 0000000000..23b9ffc25c
--- /dev/null
+++ b/editor/icons/icon_folder_medium_thumb.svg
@@ -0,0 +1,5 @@
+<svg width="32" height="32" version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1020.4)">
+<path d="m6 1025.4c-1.1046 0-2 0.8954-2 2v18.5h0.06543c0.22782 0.8823 1.0233 1.4991 1.9346 1.5h20c1.1046 0 2-0.8954 2-2v-14c0-1.1046-0.89543-2-2-2h-8l-1-2c-0.49398-0.988-0.89543-2-2-2z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_godot.svg b/editor/icons/icon_godot.svg
index 32a1eeb6ec..b8bdfcc023 100644
--- a/editor/icons/icon_godot.svg
+++ b/editor/icons/icon_godot.svg
@@ -26,8 +26,5 @@
<path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042"/>
</g>
</g>
-<path d="m4 1041.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
-<path d="m12 1041.4a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
-<rect x="6" y="1043.4" width="4" height="1" ry="0"/>
</g>
</svg>
diff --git a/editor/icons/icon_godot_docs.svg b/editor/icons/icon_godot_docs.svg
new file mode 100644
index 0000000000..9caa09066d
--- /dev/null
+++ b/editor/icons/icon_godot_docs.svg
@@ -0,0 +1,31 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<g transform="matrix(.017241 0 0 .017241 -.82759 1033.7)" stroke-width=".32031">
+<g transform="matrix(4.1626 0 0 -4.1626 919.24 771.67)">
+<path d="m0 0s-0.325 1.994-0.515 1.976l-36.182-3.491c-2.879-0.278-5.115-2.574-5.317-5.459l-0.994-14.247-27.992-1.997-1.904 12.912c-0.424 2.872-2.932 5.037-5.835 5.037h-38.188c-2.902 0-5.41-2.165-5.834-5.037l-1.905-12.912-27.992 1.997-0.994 14.247c-0.202 2.886-2.438 5.182-5.317 5.46l-36.2 3.49c-0.187 0.018-0.324-1.978-0.511-1.978l-0.049-7.83 30.658-4.944 1.004-14.374c0.203-2.91 2.551-5.263 5.463-5.472l38.551-2.75c0.146-0.01 0.29-0.016 0.434-0.016 2.897 0 5.401 2.166 5.825 5.038l1.959 13.286h28.005l1.959-13.286c0.423-2.871 2.93-5.037 5.831-5.037 0.142 0 0.284 5e-3 0.423 0.015l38.556 2.75c2.911 0.209 5.26 2.562 5.463 5.472l1.003 14.374 30.645 4.966z" fill="#fff"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 104.7 525.91)">
+<path d="m0 0v-59.041c0.108-1e-3 0.216-5e-3 0.323-0.015l36.196-3.49c1.896-0.183 3.382-1.709 3.514-3.609l1.116-15.978 31.574-2.253 2.175 14.747c0.282 1.912 1.922 3.329 3.856 3.329h38.188c1.933 0 3.573-1.417 3.855-3.329l2.175-14.747 31.575 2.253 1.115 15.978c0.133 1.9 1.618 3.425 3.514 3.609l36.182 3.49c0.107 0.01 0.214 0.014 0.322 0.015v4.711l0.015 5e-3v54.325h0.134c4.795 6.12 9.232 12.569 13.487 19.449-5.651 9.62-12.575 18.217-19.976 26.182-6.864-3.455-13.531-7.369-19.828-11.534-3.151 3.132-6.7 5.694-10.186 8.372-3.425 2.751-7.285 4.768-10.946 7.118 1.09 8.117 1.629 16.108 1.846 24.448-9.446 4.754-19.519 7.906-29.708 10.17-4.068-6.837-7.788-14.241-11.028-21.479-3.842 0.642-7.702 0.88-11.567 0.926v6e-3c-0.027 0-0.052-6e-3 -0.075-6e-3 -0.024 0-0.049 6e-3 -0.073 6e-3v-6e-3c-3.872-0.046-7.729-0.284-11.572-0.926-3.238 7.238-6.956 14.642-11.03 21.479-10.184-2.264-20.258-5.416-29.703-10.17 0.216-8.34 0.755-16.331 1.848-24.448-3.668-2.35-7.523-4.367-10.949-7.118-3.481-2.678-7.036-5.24-10.188-8.372-6.297 4.165-12.962 8.079-19.828 11.534-7.401-7.965-14.321-16.562-19.974-26.182 4.253-6.88 8.693-13.329 13.487-19.449z" fill="#478cbf"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 784.07 817.24)">
+<path d="m0 0-1.121-16.063c-0.135-1.936-1.675-3.477-3.611-3.616l-38.555-2.751c-0.094-7e-3 -0.188-0.01-0.281-0.01-1.916 0-3.569 1.406-3.852 3.33l-2.211 14.994h-31.459l-2.211-14.994c-0.297-2.018-2.101-3.469-4.133-3.32l-38.555 2.751c-1.936 0.139-3.476 1.68-3.611 3.616l-1.121 16.063-32.547 3.138c0.015-3.498 0.06-7.33 0.06-8.093 0-34.374 43.605-50.896 97.781-51.086h0.133c54.176 0.19 97.766 16.712 97.766 51.086 0 0.777 0.047 4.593 0.063 8.093z" fill="#478cbf"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 389.21 625.67)">
+<path d="m0 0c0-12.052-9.765-21.815-21.813-21.815-12.042 0-21.81 9.763-21.81 21.815 0 12.044 9.768 21.802 21.81 21.802 12.048 0 21.813-9.758 21.813-21.802" fill="#fff"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 367.37 631.06)">
+<path d="m0 0c0-7.994-6.479-14.473-14.479-14.473-7.996 0-14.479 6.479-14.479 14.473s6.483 14.479 14.479 14.479c8 0 14.479-6.485 14.479-14.479" fill="#414042"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 511.99 724.74)">
+<path d="m0 0c-3.878 0-7.021 2.858-7.021 6.381v20.081c0 3.52 3.143 6.381 7.021 6.381s7.028-2.861 7.028-6.381v-20.081c0-3.523-3.15-6.381-7.028-6.381" fill="#fff"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 634.79 625.67)">
+<path d="m0 0c0-12.052 9.765-21.815 21.815-21.815 12.041 0 21.808 9.763 21.808 21.815 0 12.044-9.767 21.802-21.808 21.802-12.05 0-21.815-9.758-21.815-21.802" fill="#fff"/>
+</g>
+<g transform="matrix(4.1626 0 0 -4.1626 656.64 631.06)">
+<path d="m0 0c0-7.994 6.477-14.473 14.471-14.473 8.002 0 14.479 6.479 14.479 14.473s-6.477 14.479-14.479 14.479c-7.994 0-14.471-6.485-14.471-14.479" fill="#414042"/>
+</g>
+</g>
+<path transform="translate(0 1036.4)" d="m4 5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3h2a3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3 3 3 0 0 0 -2.8262 2h-2.3496a3 3 0 0 0 -2.8242 -2zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gui_close_customizable.svg b/editor/icons/icon_gui_close_customizable.svg
new file mode 100644
index 0000000000..ac023b7030
--- /dev/null
+++ b/editor/icons/icon_gui_close_customizable.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m3.7578 2.3438l-1.4141 1.4141 4.2422 4.2422-4.2422 4.2422 1.4141 1.4141 4.2422-4.2422 4.2422 4.2422 1.4141-1.4141-4.2422-4.2422 4.2422-4.2422-1.4141-1.4141-4.2422 4.2422-4.2422-4.2422z" fill="#fff" fill-opacity=".89804"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gui_graph_node_port.svg b/editor/icons/icon_gui_graph_node_port.svg
new file mode 100644
index 0000000000..1120218844
--- /dev/null
+++ b/editor/icons/icon_gui_graph_node_port.svg
@@ -0,0 +1,5 @@
+<svg width="10" height="10" version="1.1" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1042.4)">
+<circle cx="5" cy="1047.4" r="5" fill="#fff" fill-rule="evenodd"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_gui_resizer.svg b/editor/icons/icon_gui_resizer.svg
new file mode 100644
index 0000000000..d9af047213
--- /dev/null
+++ b/editor/icons/icon_gui_resizer.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m11 3c-0.55228 0-1 0.44772-1 1v6h-6c-0.55228 0-1 0.44772-1 1s0.44772 1 1 1h7c0.55226-5.5e-5 0.99994-0.44774 1-1v-7c0-0.55228-0.44772-1-1-1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fff" fill-opacity=".58824" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+</svg>
diff --git a/editor/icons/icon_import_check.svg b/editor/icons/icon_import_check.svg
index e3ad9ec37e..c9f51bb6e0 100644
--- a/editor/icons/icon_import_check.svg
+++ b/editor/icons/icon_import_check.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path d="m2 1044.4 4 4 8-8" fill="none" stroke="#84ffb1" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
+<path d="m2 1044.4 4 4 8-8" fill="none" stroke="#45ff8b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>
diff --git a/editor/icons/icon_import_fail.svg b/editor/icons/icon_import_fail.svg
index e088126043..f4aa212c20 100644
--- a/editor/icons/icon_import_fail.svg
+++ b/editor/icons/icon_import_fail.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -0.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141 -1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -0.72656 -1.7148 1.0001 1.0001 0 0 0 -0.6875 0.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" fill="#ff8484" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
+<path transform="translate(0 1036.4)" d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -0.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141 -1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -0.72656 -1.7148 1.0001 1.0001 0 0 0 -0.6875 0.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -0.7168 -0.30273z" color="#000000" color-rendering="auto" fill="#ff5d5d" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_key_invalid.svg b/editor/icons/icon_key_invalid.svg
index f1df51f7c3..742859bac5 100644
--- a/editor/icons/icon_key_invalid.svg
+++ b/editor/icons/icon_key_invalid.svg
@@ -1,5 +1,5 @@
<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1044.4)">
-<path d="m0.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142l2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff8484"/>
+<path d="m0.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142l2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff5d5d"/>
</g>
</svg>
diff --git a/editor/icons/icon_key_move_disabled.svg b/editor/icons/icon_key_move_disabled.svg
new file mode 100644
index 0000000000..05c158dc3c
--- /dev/null
+++ b/editor/icons/icon_key_move_disabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7.984 1.002c-0.259 4e-3 -0.507 0.108-0.691 0.291l-2 2 1.414 1.414 1.293-1.293 1.293 1.293 1.414-1.414-2-2c-0.191-0.191-0.452-0.296-0.722-0.291h-1e-3zm-4.691 4.291l-2 2c-0.39 0.391-0.39 1.024 0 1.414l2 2 1.414-1.414-1.293-1.293 1.293-1.293-1.414-1.414zm9.414 0l-1.414 1.414 1.293 1.293-1.293 1.293 1.414 1.414 2-2c0.39-0.39 0.39-1.023 0-1.414l-2-2zm-6 6l-1.414 1.414 2 2c0.391 0.391 1.024 0.391 1.414 0l2-2-1.414-1.414-1.293 1.293-1.293-1.293z" fill="#e0e0e0" fill-opacity=".5" fill-rule="evenodd"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84c2ff" fill-opacity=".5"/>
+</svg>
diff --git a/editor/icons/icon_key_move_enabled.svg b/editor/icons/icon_key_move_enabled.svg
new file mode 100644
index 0000000000..2d455f2d81
--- /dev/null
+++ b/editor/icons/icon_key_move_enabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7.984 1.002c-0.259 4e-3 -0.507 0.108-0.691 0.291l-2 2 1.414 1.414 1.293-1.293 1.293 1.293 1.414-1.414-2-2c-0.191-0.191-0.452-0.296-0.722-0.291h-1e-3zm-4.691 4.291l-2 2c-0.39 0.391-0.39 1.024 0 1.414l2 2 1.414-1.414-1.293-1.293 1.293-1.293-1.414-1.414zm9.414 0l-1.414 1.414 1.293 1.293-1.293 1.293 1.414 1.414 2-2c0.39-0.39 0.39-1.023 0-1.414l-2-2zm-6 6l-1.414 1.414 2 2c0.391 0.391 1.024 0.391 1.414 0l2-2-1.414-1.414-1.293 1.293-1.293-1.293z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84C2FF"/>
+</svg>
diff --git a/editor/icons/icon_key_rotate_disabled.svg b/editor/icons/icon_key_rotate_disabled.svg
new file mode 100644
index 0000000000..6394bfd82d
--- /dev/null
+++ b/editor/icons/icon_key_rotate_disabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m8.088 1.001c-0.102-1e-3 -0.203 0-0.305 2e-3 -0.233 8e-3 -0.466 0.027-0.697 0.057-2.973 0.392-5.366 2.633-5.951 5.574-0.46 2.319 0.281 4.712 1.97 6.365h-1.105v2h4c0.308 1e-3 0.599-0.141 0.788-0.384 0.19-0.243 0.257-0.559 0.183-0.858l-1-4-1.942 0.487 0.281 1.121c-0.84-0.92-1.308-2.12-1.31-3.366 0-2.761 2.239-5 5-5 1.326 0 2.598 0.527 3.536 1.465 0.937 0.938 1.464 2.209 1.464 3.535-1e-3 1.326-0.529 2.597-1.467 3.534l1.416 1.416c2.12-2.121 2.654-5.356 1.328-8.045-1.165-2.362-3.556-3.869-6.189-3.903z" fill="#e0e0e0" fill-opacity=".5"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84c2ff" fill-opacity=".5"/>
+</svg>
diff --git a/editor/icons/icon_key_rotate_enabled.svg b/editor/icons/icon_key_rotate_enabled.svg
new file mode 100644
index 0000000000..1dcb12c8ab
--- /dev/null
+++ b/editor/icons/icon_key_rotate_enabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m8.088 1.001c-0.102-1e-3 -0.203 0-0.305 2e-3 -0.233 8e-3 -0.466 0.027-0.697 0.057-2.973 0.392-5.366 2.633-5.951 5.574-0.46 2.319 0.281 4.712 1.97 6.365h-1.105v2h4c0.308 1e-3 0.599-0.141 0.788-0.384 0.19-0.243 0.257-0.559 0.183-0.858l-1-4-1.942 0.487 0.281 1.121c-0.84-0.92-1.308-2.12-1.31-3.366 0-2.761 2.239-5 5-5 1.326 0 2.598 0.527 3.536 1.465 0.937 0.938 1.464 2.209 1.464 3.535-1e-3 1.326-0.529 2.597-1.467 3.534l1.416 1.416c2.12-2.121 2.654-5.356 1.328-8.045-1.165-2.362-3.556-3.869-6.189-3.903z" fill="#e0e0e0" fill-opacity=".99608"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84C2FF"/>
+</svg>
diff --git a/editor/icons/icon_key_scale_disabled.svg b/editor/icons/icon_key_scale_disabled.svg
new file mode 100644
index 0000000000..9601e4925b
--- /dev/null
+++ b/editor/icons/icon_key_scale_disabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m9 1c-0.552 0-1 0.448-1 1s0.448 1 1 1h2.586l-1.293 1.293 1.414 1.414 1.293-1.293v2.586c0 0.552 0.448 1 1 1s1-0.448 1-1v-5c0-0.552-0.448-1-1-1h-5zm-7 7c-0.552 0-1 0.448-1 1v5c0 0.552 0.448 1 1 1h5c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2.586l1.293-1.293-1.414-1.414-1.293 1.293v-2.586c0-0.552-0.448-1-1-1z" fill="#e0e0e0" fill-opacity=".5" fill-rule="evenodd"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84c2ff" fill-opacity=".5"/>
+</svg>
diff --git a/editor/icons/icon_key_scale_enabled.svg b/editor/icons/icon_key_scale_enabled.svg
new file mode 100644
index 0000000000..f00f3db35f
--- /dev/null
+++ b/editor/icons/icon_key_scale_enabled.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" style="isolation:isolate" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m9 1c-0.552 0-1 0.448-1 1s0.448 1 1 1h2.586l-1.293 1.293 1.414 1.414 1.293-1.293v2.586c0 0.552 0.448 1 1 1s1-0.448 1-1v-5c0-0.552-0.448-1-1-1h-5zm-7 7c-0.552 0-1 0.448-1 1v5c0 0.552 0.448 1 1 1h5c0.552 0 1-0.448 1-1s-0.448-1-1-1h-2.586l1.293-1.293-1.414-1.414-1.293 1.293v-2.586c0-0.552-0.448-1-1-1z" fill="#e0e0e0" fill-opacity=".99608" fill-rule="evenodd"/>
+<path d="m5.168 7.595l2.427-2.427c0.224-0.224 0.586-0.224 0.81 0l2.427 2.427c0.224 0.224 0.224 0.586 0 0.81l-2.427 2.427c-0.224 0.224-0.586 0.224-0.81 0l-2.427-2.427c-0.224-0.224-0.224-0.586 0-0.81z" fill="#84C2FF"/>
+</svg>
diff --git a/editor/icons/icon_logo.svg b/editor/icons/icon_logo.svg
new file mode 100644
index 0000000000..269fe1b245
--- /dev/null
+++ b/editor/icons/icon_logo.svg
@@ -0,0 +1,7 @@
+<svg width="187" height="69" version="1.1" viewBox="0 0 187 69" xmlns="http://www.w3.org/2000/svg">
+<path d="m91.912 19.51c-3.5233 0-6.278 1.1097-8.2676 3.3281-1.9911 2.2193-2.9844 5.1004-2.9844 8.6465 0 4.1636 1.0165 7.3207 3.0508 9.4707 2.0379 2.1497 4.7123 3.2227 8.0293 3.2227 1.7838 0 3.3686-0.15384 4.752-0.46289 1.3848-0.30784 2.3038-0.62367 2.7617-0.94336l0.13867-10.736c0-0.62388-1.6471-0.90785-3.4941-0.93945-1.847-0.02857-3.9609 0.35742-3.9609 0.35742v3.6055h2.125l-0.023438 1.6055c0 0.59532-0.59062 0.89453-1.7676 0.89453-1.1785 0-2.2182-0.4989-3.1211-1.4941-0.90498-0.99645-1.3555-2.4517-1.3555-4.3711 0-1.9233 0.43964-3.3428 1.3203-4.2578 0.87885-0.9141 2.0322-1.3711 3.4492-1.3711 0.59532 0 1.2107 0.095008 1.8516 0.29102 0.64121 0.19418 1.0686 0.37639 1.2871 0.54688 0.21667 0.17534 0.42435 0.25781 0.61914 0.25781 0.19388 0 0.50715-0.22698 0.94141-0.68555 0.43487-0.45735 0.82427-1.1501 1.168-2.0742 0.34218-0.92899 0.51367-1.6414 0.51367-2.1465 0-0.50111-0.011023-0.84501-0.033203-1.0273-0.48045-0.52573-1.3668-0.94394-2.6602-1.2539-1.2909-0.30906-2.7387-0.46289-4.3398-0.46289zm21.049 0c-3.2367 0-5.8788 1.0413-7.9258 3.1211-2.0464 2.0826-3.0703 5.1404-3.0703 9.1797 0 4.0369 1.0128 7.1085 3.0352 9.2129 2.0251 2.1026 4.6444 3.1543 7.8574 3.1543 3.2145 0 5.8383-1.0111 7.875-3.0332 2.0367-2.0263 3.0527-5.1142 3.0527-9.2656 0-4.1484-0.99433-7.2508-2.9863-9.2969-1.9884-2.05-4.6018-3.0723-7.8379-3.0723zm45.504 0c-3.2379 0-5.8792 1.0413-7.9277 3.1211-2.0461 2.0826-3.0684 5.1404-3.0684 9.1797 0 4.0369 1.0104 7.1085 3.0352 9.2129 2.0233 2.1026 4.6432 3.1543 7.8574 3.1543 3.213 0 5.8373-1.0111 7.873-3.0332 2.0364-2.0263 3.0547-5.1142 3.0547-9.2656 0-4.1484-0.9939-7.2508-2.9844-9.2969-1.9908-2.05-4.6031-3.0723-7.8398-3.0723zm-30.105 0.30859c-0.45888 0-0.82988 0.16637-1.1152 0.49609-0.28717 0.33489-0.42969 0.78715-0.42969 1.3594v20.584c0 1.053 0.58624 1.5781 1.752 1.5781h5.8652c7.1824-1e-6 10.773-4.2092 10.773-12.627 0-3.9348-0.94335-6.8151-2.832-8.6445-1.8853-1.83-4.6472-2.7461-8.2832-2.7461h-5.7305zm42.807 0c-0.38928 0-0.66468 0.52801-0.82422 1.5801-0.0687 0.50294-0.10157 1.0191-0.10157 1.543 0 0.52694 0.03287 1.0409 0.10157 1.543 0.15954 1.0548 0.43494 1.5801 0.82422 1.5801h4.1152v17.225c0 0.45462 1.1351 0.68555 3.3984 0.68555 2.2655 0 3.3965-0.23093 3.3965-0.68555v-17.225h4.0137c0.38868 0 0.66225-0.52528 0.82422-1.5801 0.0672-0.50202 0.10156-1.016 0.10156-1.543 1e-5 -0.52391-0.03436-1.04-0.10156-1.543-0.16197-1.0521-0.43554-1.5801-0.82422-1.5801h-14.924zm-58.291 6.2793c1.0989 0 2.0193 0.49244 2.7617 1.4746 0.74331 0.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-0.35955 3.2363-1.0801 4.2188-0.72053 0.98612-1.6597 1.4785-2.8145 1.4785-1.1554 0-2.0859-0.48441-2.7949-1.459-0.71019-0.97154-1.0644-2.3663-1.0644-4.1875 0-1.8173 0.37148-3.2302 1.1133-4.2363 0.74574-1.0053 1.6663-1.5098 2.7637-1.5098zm45.504 0c1.0989 0 2.0181 0.49244 2.7617 1.4746 0.74331 0.98339 1.1152 2.3913 1.1152 4.2207 0 1.8309-0.3612 3.2363-1.082 4.2188-0.71961 0.98612-1.6574 1.4785-2.8125 1.4785-1.1554 0-2.0888-0.48441-2.7969-1.459-0.70806-0.97154-1.0625-2.3663-1.0625-4.1875 0-1.8173 0.37179-3.2302 1.1133-4.2363 0.74453-1.0053 1.666-1.5098 2.7637-1.5098zm-24.977 0.23828h0.34375c1.4638 0 2.5334 0.33466 3.209 0.99805 0.6722 0.66157 1.0098 2.0859 1.0098 4.2715 0 2.1847-0.32289 3.7447-0.97656 4.6816-0.65214 0.9378-1.6059 1.4082-2.8652 1.4082-0.34218 0-0.54909-0.063339-0.61719-0.18945-0.06873-0.12672-0.10352-0.42897-0.10352-0.9082v-10.262z" fill="#fff"/>
+<path d="m137.91 48.551v1.2109h0.85938v-1.2109h-0.85938zm-52.396 0.58984c-0.99736 0-1.7963 0.32424-2.3926 0.96484-0.59745 0.64576-0.89453 1.5712-0.89453 2.7773v3.0742c0 1.2329 0.31639 2.1765 0.94727 2.832 0.6333 0.66066 1.467 0.98828 2.5039 0.98828 0.78586 0 1.4321-0.16147 1.9414-0.48633 0.50993-0.32273 0.8592-0.67938 1.0488-1.0684v-3.6875h-3.0059v0.74805h2.1465v2.6934c-0.13766 0.30115-0.38143 0.55386-0.73242 0.76172-0.34978 0.2109-0.8171 0.31445-1.3984 0.31445-0.79619 0-1.4265-0.2632-1.8945-0.78711-0.46799-0.52786-0.70312-1.2936-0.70312-2.2988v-3.0918c0-0.96941 0.21778-1.7078 0.65234-2.2168 0.43578-0.51023 1.0297-0.76367 1.7812-0.76367 0.74271 0 1.3056 0.19019 1.6836 0.56641 0.38017 0.37925 0.58276 0.91542 0.61133 1.6113h0.79492l0.013672-0.041016c-0.024311-0.90802-0.30456-1.6179-0.83789-2.127-0.53484-0.50719-1.2907-0.76367-2.2656-0.76367zm7.6133 2.6641c-0.719 0-1.3111 0.22524-1.7715 0.67773-0.46222 0.45371-0.68069 0.96571-0.6582 1.5449l0.013672 0.041015 0.79688 0.007813c0-0.42696 0.14768-0.78487 0.44336-1.0781 0.2966-0.29508 0.67455-0.44141 1.1328-0.44141 0.4926 0 0.87459 0.15388 1.1523 0.45898 0.27198 0.30906 0.41016 0.73655 0.41016 1.2793v0.94531h-1.3418c-0.85666 0-1.5379 0.21084-2.0391 0.63477-0.50142 0.42392-0.75195 0.99502-0.75195 1.707 0 0.67372 0.17358 1.2075 0.51758 1.6035 0.34613 0.39445 0.83497 0.5918 1.4707 0.5918 0.45462 0 0.86723-0.12355 1.2383-0.37305 0.37166-0.24767 0.67317-0.56424 0.90625-0.94531 0 0.17413 0.01089 0.34527 0.03125 0.51758 0.02097 0.16927 0.053163 0.38614 0.095703 0.65234h0.88867c-0.062302-0.24767-0.10234-0.49621-0.12695-0.75391-0.02401-0.25436-0.037109-0.52051-0.037109-0.79492v-3.7676c0-0.80622-0.21809-1.4265-0.65234-1.8613-0.43669-0.43061-1.0083-0.64648-1.7188-0.64648zm7.1152 0c-0.45462 0-0.85109 0.11505-1.1875 0.3457-0.33519 0.23369-0.60486 0.56357-0.80664 0.99023l-0.074219-1.1934h-0.75195v7.6816h0.85352v-5.5293c0.11791-0.47346 0.31244-0.84655 0.58594-1.1191 0.27168-0.27107 0.63379-0.4082 1.082-0.4082 0.4689 0 0.83314 0.19466 1.0957 0.58789 0.26378 0.39323 0.39258 1.0508 0.39258 1.9707v4.498h0.85351v-4.6211-0.19922c0.0623-0.64455 0.23396-1.1785 0.51172-1.6055 0.27927-0.42696 0.66855-0.63672 1.166-0.63672 0.47285 0 0.83879 0.19223 1.0938 0.57422 0.25345 0.38138 0.38281 1.0443 0.38281 1.9863v4.502h0.85742v-4.4863c0-1.1332-0.18468-1.9728-0.55664-2.5195-0.37044-0.54548-0.89268-0.81836-1.5664-0.81836-0.48897 0-0.91182 0.1465-1.2598 0.43945-0.34796 0.29234-0.61537 0.69589-0.80469 1.207-0.148-0.55369-0.38151-0.966-0.69726-1.2383-0.31543-0.2732-0.70589-0.4082-1.1699-0.4082zm10.316 0c-0.74423-1e-6 -1.3797 0.32125-1.9082 0.96094-0.52725 0.64273-0.78906 1.4505-0.78906 2.4199v1.2754c0 0.96758 0.26259 1.762 0.7871 2.3828 0.52604 0.62206 1.2032 0.93359 2.0312 0.93359 0.5157 0 0.95833-0.090281 1.3242-0.26562 0.36679-0.17626 0.66658-0.41287 0.89844-0.70703l-0.34961-0.60547c-0.21728 0.27441-0.4784 0.4836-0.7832 0.63281-0.3048 0.14586-0.66987 0.2207-1.0898 0.2207-0.60443 0-1.0864-0.24489-1.4414-0.74023-0.35433-0.49412-0.53321-1.1138-0.53321-1.8574v-0.63867h4.3965v-0.84375c0-0.96667-0.22381-1.7371-0.66992-2.3105-0.44519-0.57253-1.0684-0.85742-1.873-0.85742zm9.4727 0c-0.74423-1e-6 -1.3782 0.32125-1.9082 0.96094-0.52603 0.64273-0.79101 1.4505-0.79101 2.4199v1.2754c0 0.96758 0.26241 1.762 0.78906 2.3828 0.52512 0.62206 1.2028 0.93359 2.0312 0.93359 0.51601 0 0.95639-0.090281 1.3223-0.26562 0.36741-0.17626 0.66822-0.41287 0.90039-0.70703l-0.34766-0.60547c-0.21972 0.27441-0.4811 0.4836-0.78711 0.63281-0.30389 0.14586-0.66639 0.2207-1.0879 0.2207-0.60656 0-1.0883-0.24489-1.4414-0.74023-0.35646-0.49412-0.5332-1.1138-0.5332-1.8574v-0.63867h4.3945v-0.84375c0-0.96667-0.22338-1.7371-0.66797-2.3105-0.44398-0.57253-1.0699-0.85742-1.873-0.85742zm6.8672 0c-0.45614 0-0.85274 0.12451-1.1894 0.36914-0.33975 0.24342-0.60962 0.5923-0.81445 1.043l-0.07031-1.2695h-0.76172v7.6816h0.85351v-5.4824c0.14617-0.47923 0.36569-0.85918 0.66016-1.1445 0.29325-0.28809 0.65767-0.42969 1.0938-0.42969 0.48622 0 0.85922 0.17765 1.1133 0.5332 0.25557 0.35555 0.38477 0.96807 0.38477 1.8457v4.6777h0.85937v-4.6855c0-1.0736-0.18381-1.866-0.55273-2.375-0.36497-0.50993-0.89-0.76367-1.5762-0.76367zm6.2539 0c-0.77674 0-1.386 0.32888-1.8242 0.98437-0.44186 0.65883-0.66211 1.5326-0.66211 2.6211l0.00196 1.0508c0 1.0031 0.21834 1.8072 0.65625 2.4102 0.43699 0.60413 1.0429 0.90625 1.8144 0.90625 0.41602 0 0.78387-0.091234 1.0996-0.27539 0.31695-0.18324 0.58484-0.4491 0.80273-0.79492v0.92969c0 0.75881-0.14785 1.3303-0.4414 1.7266-0.29235 0.39111-0.74301 0.58789-1.3535 0.58789-0.30359 0-0.59763-0.04082-0.88086-0.125-0.28565-0.081443-0.54279-0.19619-0.77344-0.3457l-0.23632 0.74805c0.27047 0.15164 0.57916 0.27315 0.92773 0.36523 0.34795 0.092075 0.67388 0.13867 0.97656 0.13867 0.84208 0 1.494-0.27297 1.9531-0.81055 0.45857-0.53971 0.68554-1.3009 0.68554-2.2852v-7.6895h-0.72265l-0.08399 1.0684c-0.21485-0.38533-0.48269-0.68758-0.80664-0.89453-0.32334-0.2109-0.70159-0.31641-1.1328-0.31641zm10.467 0c-0.45401 0-0.85062 0.12451-1.1895 0.36914-0.33914 0.24342-0.60902 0.5923-0.81445 1.043l-0.07031-1.2695h-0.75977v7.6816h0.85352v-5.4824c0.14556-0.47923 0.3663-0.85918 0.66016-1.1445 0.29295-0.28809 0.65797-0.42969 1.0937-0.42969 0.48775 0 0.85711 0.17765 1.1133 0.5332 0.25496 0.35555 0.38476 0.96807 0.38476 1.8457v4.6777h0.85742v-4.6855c0-1.0736-0.18081-1.866-0.54882-2.375-0.36588-0.50993-0.8939-0.76367-1.5801-0.76367zm6.4043 0c-0.74271-1e-6 -1.3778 0.32125-1.9062 0.96094-0.52724 0.64273-0.79101 1.4505-0.79101 2.4199v1.2754c0 0.96758 0.26334 1.762 0.78906 2.3828 0.52361 0.62206 1.2007 0.93359 2.0312 0.93359 0.5154 0 0.9567-0.090281 1.3223-0.26562 0.3668-0.17626 0.6667-0.41287 0.90039-0.70703l-0.34961-0.60547c-0.2194 0.27441-0.47958 0.4836-0.78711 0.63281-0.30359 0.14586-0.66597 0.2207-1.0859 0.2207-0.60717 0-1.089-0.24489-1.4434-0.74023-0.35464-0.49412-0.5332-1.1138-0.5332-1.8574v-0.63867h4.3965v-0.84375c0-0.96667-0.22369-1.7371-0.66797-2.3105-0.44551-0.57253-1.0709-0.85742-1.875-0.85742zm-12.113 0.14258v7.6816h0.85938v-7.6816h-0.85938zm-27.352 0.60938c0.53029 0 0.9445 0.20789 1.2441 0.62695 0.29781 0.41876 0.44531 0.94616 0.44531 1.5801v0.33008h-3.543c0.01429-0.71688 0.19281-1.3186 0.53711-1.8066 0.34401-0.48622 0.78217-0.73047 1.3164-0.73047zm9.4727 0c0.52998 0 0.94406 0.20789 1.2422 0.62695 0.29963 0.41876 0.44727 0.94616 0.44727 1.5801v0.33008h-3.543c0.0155-0.71688 0.19298-1.3186 0.53516-1.8066 0.3437-0.48622 0.7826-0.73047 1.3184-0.73047zm29.992 0c0.53089 0 0.94602 0.20789 1.2441 0.62695 0.29902 0.41876 0.44532 0.94616 0.44532 1.5801v0.33008h-3.543c0.01519-0.71688 0.19402-1.3186 0.53711-1.8066 0.34218-0.48622 0.78064-0.73047 1.3164-0.73047zm-16.686 0.015625c0.42119 0 0.77033 0.1246 1.0469 0.375 0.27684 0.25466 0.4967 0.58706 0.65625 0.99609v3.8047c-0.16593 0.39718-0.39 0.70872-0.67383 0.93359-0.28475 0.22488-0.63089 0.33594-1.043 0.33594-0.6014 0-1.0536-0.22975-1.3496-0.69531-0.29964-0.4613-0.44727-1.0819-0.44727-1.8613v-1.0508c0-0.84177 0.15149-1.527 0.45508-2.0527 0.30146-0.52482 0.75528-0.78516 1.3555-0.78516zm-40.057 3.3281h1.3652v1.6621c-0.15286 0.42089-0.40964 0.76752-0.77734 1.041-0.3671 0.27228-0.78783 0.40625-1.2598 0.40625-0.39262 0-0.69782-0.12824-0.91602-0.38867-0.2185-0.25952-0.32617-0.59591-0.32617-1.0059 0-0.48531 0.17262-0.89402 0.52148-1.2207 0.34795-0.32881 0.81215-0.49414 1.3926-0.49414z" fill="#e0e0e0"/>
+<path d="m27 3c-3.0948 0.68801-6.1571 1.6452-9.0273 3.0898 0.06564 2.5344 0.23035 4.963 0.5625 7.4297-1.1147 0.71414-2.287 1.3281-3.3281 2.1641-1.0578 0.81382-2.1378 1.5912-3.0957 2.543-1.9136-1.2657-3.9389-2.454-6.0254-3.5039-2.2491 2.4205-4.3524 5.0317-6.0703 7.9551 1.2924 2.0908 2.6428 4.0523 4.0996 5.9121h0.041016v14.438 1.834 1.6699c0.03282 3.04e-4 0.06514 8.06e-4 0.097656 0.003906l11 1.0605c0.57617 0.05561 1.0282 0.52027 1.0684 1.0977l0.33789 4.8555 9.5957 0.68359 0.66016-4.4805c0.0857-0.58104 0.58415-1.0117 1.1719-1.0117h11.605c0.58742 0 1.0862 0.43068 1.1719 1.0117l0.66016 4.4805 9.5957-0.68359 0.33789-4.8555c0.04042-0.57739 0.49219-1.0417 1.0684-1.0977l10.996-1.0605c0.032519-3e-3 0.064836-0.003606 0.097656-0.003906v-1.4316l0.003906-0.001953v-16.508h0.041016c1.4571-1.8598 2.8066-3.8214 4.0996-5.9121-1.7173-2.9234-3.8232-5.5346-6.0723-7.9551-2.0859 1.0499-4.1118 2.2382-6.0254 3.5039-0.95756-0.95178-2.0363-1.7292-3.0957-2.543-1.0408-0.836-2.2136-1.4499-3.3262-2.1641 0.33124-2.4667 0.49656-4.8952 0.5625-7.4297-2.8706-1.4447-5.933-2.4018-9.0293-3.0898-1.2362 2.0777-2.367 4.3278-3.3516 6.5273-1.1675-0.1951-2.3391-0.26727-3.5137-0.28125v-0.0019532c-0.0082 0-0.016447 0.0019531-0.023437 0.0019532-0.0073 0-0.014194-0.0019532-0.021484-0.0019532v0.0019532c-1.1767 0.013979-2.3497 0.086153-3.5176 0.28125-0.98399-2.1996-2.1135-4.4497-3.3516-6.5273zm-22.863 45.904c0.0045599 1.063 0.019531 2.2271 0.019531 2.459 0 10.446 13.251 15.468 29.715 15.525h0.019531 0.019531c16.464-0.05774 29.711-5.0795 29.711-15.525 0-0.23612 0.014661-1.3954 0.019531-2.459l-9.8867 0.95312-0.3418 4.8809c-0.04102 0.58833-0.50933 1.0574-1.0977 1.0996l-11.717 0.83594c-0.02857 0.0021-0.055724 0.003906-0.083984 0.003906-0.58225 0-1.0859-0.42704-1.1719-1.0117l-0.67188-4.5566h-9.5586l-0.67188 4.5566c-0.09025 0.61325-0.63836 1.0531-1.2559 1.0078l-11.717-0.83594c-0.58833-0.04224-1.0566-0.51128-1.0977-1.0996l-0.3418-4.8809-9.8906-0.95312z" fill="#478cbf"/>
+<path d="m18.299 29.246c-3.6594 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.9695 6.6289 6.6289 6.6289 3.6613 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9657-6.627-6.627-6.627zm31.186 0c-3.6619 0-6.6289 2.9669-6.6289 6.627 0 3.6625 2.967 6.6289 6.6289 6.6289 3.6591 0 6.627-2.9664 6.627-6.6289 0-3.66-2.9678-6.627-6.627-6.627zm-15.594 3.8789c-1.1785 0-2.1348 0.86781-2.1348 1.9375v6.1035c0 1.0706 0.95628 1.9395 2.1348 1.9395s2.1348-0.86885 2.1348-1.9395v-6.1035c0-1.0697-0.95628-1.9375-2.1348-1.9375z" fill="#f6f6f6"/>
+<path d="m18.932 31.865c-2.4299 0-4.4004 1.9711-4.4004 4.4004s1.9705 4.3984 4.4004 4.3984c2.4311 0 4.4004-1.9691 4.4004-4.3984s-1.9693-4.4004-4.4004-4.4004zm29.916 0c-2.4293 0-4.3984 1.9711-4.3984 4.4004s1.9691 4.3984 4.3984 4.3984c2.4317 0 4.4004-1.9691 4.4004-4.3984s-1.9687-4.4004-4.4004-4.4004z" fill="#414042"/>
+</svg>
diff --git a/editor/icons/icon_node_warning.svg b/editor/icons/icon_node_warning.svg
index 5c03bad343..66663f7d62 100644
--- a/editor/icons/icon_node_warning.svg
+++ b/editor/icons/icon_node_warning.svg
@@ -1,7 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
<g transform="translate(0 -1.6949e-5)">
-<path transform="translate(0 1036.4)" d="m8.0293 2.002a1.0001 1.0001 0 0 0 -0.88672 0.48438l-6 10a1.0001 1.0001 0 0 0 0.85742 1.5137h12a1.0001 1.0001 0 0 0 0.85742 -1.5137l-6-10a1.0001 1.0001 0 0 0 -0.82812 -0.48438zm-1.0293 2.998h2v5h-2v-5zm0 6h2v2h-2v-2z" color="#000000" color-rendering="auto" fill="#ffd684" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
+<path transform="translate(0 1036.4)" d="m8.0293 2.002a1.0001 1.0001 0 0 0 -0.88672 0.48438l-6 10a1.0001 1.0001 0 0 0 0.85742 1.5137h12a1.0001 1.0001 0 0 0 0.85742 -1.5137l-6-10a1.0001 1.0001 0 0 0 -0.82812 -0.48438zm-1.0293 2.998h2v5h-2v-5zm0 6h2v2h-2v-2z" color="#000000" color-rendering="auto" fill="#ffdd65" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
</g>
</g>
</svg>
diff --git a/editor/icons/icon_sample_library.svg b/editor/icons/icon_sample_library.svg
index b5ec2bb43c..403ea5ff42 100644
--- a/editor/icons/icon_sample_library.svg
+++ b/editor/icons/icon_sample_library.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#ff8484">
-<path transform="translate(0 1036.4)" d="m9 8v1 5 1h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4z"/>
-<path d="m7.0215 1037.4a1.0001 1.0001 0 0 0 -1 0.875l-0.58984 4.7226-0.52344-1.0468a1.0001 1.0001 0 0 0 -0.89453 -0.5528h-2a1.0001 1.0001 0 1 0 0 2h1.3828l1.7227 3.4473a1.0001 1.0001 0 0 0 1.8867 -0.3223l0.58984-4.7226 0.52344 1.0449a1.0001 1.0001 0 0 0 0.89453 0.5527h3a1.0001 1.0001 0 1 0 0 -2h-2.3809l-1.7246-3.4472a1.0001 1.0001 0 0 0 -0.88672 -0.5508z" color="#000000" color-rendering="auto" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="block-progression:tb;isolation:auto;mix-blend-mode:normal;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-transform:none;white-space:normal"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m7.0215 1.002a1.0001 1.0001 0 0 0 -1 0.875l-0.58984 4.7227-0.52344-1.0469a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-2a1.0001 1.0001 0 1 0 0 2h1.3828l1.7227 3.4473a1.0001 1.0001 0 0 0 1.8867 -0.32227l0.58984-4.7227 0.52344 1.0449a1.0001 1.0001 0 0 0 0.89453 0.55273h3a1.0001 1.0001 0 1 0 0 -2h-2.3809l-1.7246-3.4473a1.0001 1.0001 0 0 0 -0.88672 -0.55078zm1.9785 6.998v1 5 1h5c0.55228 0 1-0.44772 1-1v-5c0-0.55228-0.44772-1-1-1v4l-1-1-1 1v-4h-3z" fill="#ff8484"/>
</g>
</svg>
diff --git a/editor/icons/icon_slider_joint.svg b/editor/icons/icon_slider_joint.svg
index 479323bf9a..d1469058d1 100644
--- a/editor/icons/icon_slider_joint.svg
+++ b/editor/icons/icon_slider_joint.svg
@@ -1,10 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path d="m3 1051.4h5l-1-4z" fill="#fc9c9c" fill-opacity=".99608"/>
-<path d="m6 1048.4 9-9v3l-8 8z" fill="#fb9b9b"/>
-<path d="m10 1040.4-9 9v-3l8-8z" fill="#fb9b9b"/>
-<path d="m13 1037.4h-5l1 4z" fill="#fc9c9c" fill-opacity=".99608"/>
-<path d="m10 1038.4h-5" fill="none" stroke="#fb9b9b" stroke-linecap="round" stroke-width="2"/>
-<path d="m11 1050.4h-5" fill="none" stroke="#fb9b9b" stroke-linecap="round" stroke-width="2"/>
+<path transform="translate(0 1036.4)" d="m5 1c-0.55228 0-1 0.44772-1 1s0.44772 1 1 1h3l-7 7v3l12-12zm10 2-12 12h8c0.55228 0 1-0.44772 1-1s-0.44772-1-1-1h-3l7-7z" fill="#fc9c9c"/>
</g>
</svg>
diff --git a/editor/icons/icon_snap.svg b/editor/icons/icon_snap.svg
index b1f36cfe43..0195f7cfc6 100644
--- a/editor/icons/icon_snap.svg
+++ b/editor/icons/icon_snap.svg
@@ -1,10 +1,93 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path d="m3 1036.4v3h-3v2h3v4h-3v2h3v3h2v-3-2-4h4 2 3v-2h-3v-3h-2v3h-4v-3h-2z" fill="#f3f3f3"/>
-<path d="m11 1043.4a4 4 0 0 0 -4 4h2a2 2 0 0 1 2 -2 2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z" fill="#ff8484"/>
-<rect x="7" y="1047.4" width="2" height="2" fill="#ff8484"/>
-<rect x="13" y="1047.4" width="2" height="2" fill="#ff8484"/>
-<rect x="7" y="1049.4" width="2" height="2" fill="#fff"/>
-<rect x="13" y="1049.4" width="2" height="2" fill="#fff"/>
-</g>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg848"
+ sodipodi:docname="icon_snap.svg"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06">
+ <metadata
+ id="metadata854">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs852" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2558"
+ inkscape:window-height="1422"
+ id="namedview850"
+ showgrid="true"
+ inkscape:pagecheckerboard="true"
+ inkscape:zoom="26.317631"
+ inkscape:cx="-14.078109"
+ inkscape:cy="-1.3201296"
+ inkscape:window-x="1366"
+ inkscape:window-y="16"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg848">
+ <inkscape:grid
+ type="xygrid"
+ id="grid862" />
+ </sodipodi:namedview>
+ <path
+ style="fill:#ff8484;stroke-width:1.48039925"
+ inkscape:connector-curvature="0"
+ id="path836"
+ d="m 3.9501321,14.20668 a 5.9215969,5.9215969 0 0 0 8.0890509,-2.167455 l -2.5641252,-1.4804 A 2.9607985,2.9607985 0 0 1 5.4305313,11.642553 2.9607985,2.9607985 0 0 1 4.3468039,7.5980268 L 1.7826772,6.1176278 A 5.9215969,5.9215969 0 0 0 3.9501321,14.20668 Z" />
+ <rect
+ style="fill:#ff8484;stroke-width:1.48039925"
+ id="rect838"
+ height="2.9607985"
+ width="2.9607985"
+ y="-4.4066463"
+ x="-16.44585"
+ transform="rotate(-150)" />
+ <rect
+ style="fill:#ff8484;stroke-width:1.48039925"
+ id="rect840"
+ height="2.9607985"
+ width="2.9607985"
+ y="-4.4066463"
+ x="-7.5634551"
+ transform="rotate(-150)" />
+ <rect
+ style="fill:#ffffff;stroke-width:1.48039925"
+ id="rect842"
+ height="2.9607985"
+ width="2.9607985"
+ y="-1.4458472"
+ x="-16.44585"
+ transform="rotate(-150)" />
+ <rect
+ style="fill:#ffffff;stroke-width:1.48039925"
+ id="rect844"
+ height="2.9607985"
+ width="2.9607985"
+ y="-1.4458472"
+ x="-7.5634551"
+ transform="rotate(-150)" />
</svg>
diff --git a/editor/icons/icon_snap_grid.svg b/editor/icons/icon_snap_grid.svg
new file mode 100644
index 0000000000..b479496327
--- /dev/null
+++ b/editor/icons/icon_snap_grid.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ version="1.1"
+ viewBox="0 0 16 16"
+ id="svg913"
+ sodipodi:docname="icon_snap_grid.svg"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06">
+ <metadata
+ id="metadata919">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs917" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2558"
+ inkscape:window-height="1422"
+ id="namedview915"
+ showgrid="false"
+ inkscape:pagecheckerboard="true"
+ inkscape:zoom="52.635261"
+ inkscape:cx="6.4374987"
+ inkscape:cy="5.7074131"
+ inkscape:window-x="1366"
+ inkscape:window-y="16"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg913" />
+ <g
+ transform="translate(0 -1036.4)"
+ id="g911">
+ <path
+ d="m3 1036.4v3h-3v2h3v4h-3v2h3v3h2v-3-2-4h4 2 3v-2h-3v-3h-2v3h-4v-3h-2z"
+ fill="#f3f3f3"
+ id="path899" />
+ <path
+ d="m11 1043.4a4 4 0 0 0 -4 4h2a2 2 0 0 1 2 -2 2 2 0 0 1 2 2h2a4 4 0 0 0 -4 -4z"
+ fill="#ff8484"
+ id="path901" />
+ <rect
+ x="7"
+ y="1047.4"
+ width="2"
+ height="2"
+ fill="#ff8484"
+ id="rect903" />
+ <rect
+ x="13"
+ y="1047.4"
+ width="2"
+ height="2"
+ fill="#ff8484"
+ id="rect905" />
+ <rect
+ x="7"
+ y="1049.4"
+ width="2"
+ height="2"
+ fill="#fff"
+ id="rect907" />
+ <rect
+ x="13"
+ y="1049.4"
+ width="2"
+ height="2"
+ fill="#fff"
+ id="rect909" />
+ </g>
+</svg>
diff --git a/editor/icons/icon_warning.svg b/editor/icons/icon_warning.svg
index 455e7b1877..8f6bf2184a 100644
--- a/editor/icons/icon_warning.svg
+++ b/editor/icons/icon_warning.svg
@@ -1,5 +1,5 @@
<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1044.4)">
-<rect y="1044.4" width="8" height="8" ry="4" fill="#ffd684"/>
+<rect y="1044.4" width="8" height="8" ry="4" fill="#ffdd65"/>
</g>
</svg>
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index cc519c1c4b..b448ab8920 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -120,13 +120,13 @@ String ResourceImporterScene::get_preset_name(int p_idx) const {
switch (p_idx) {
case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene");
- case PRESET_SEPERATE_ANIMATIONS: return TTR("Import with Seperate Animations");
+ case PRESET_SEPARATE_ANIMATIONS: return TTR("Import with Separate Animations");
case PRESET_SEPARATE_MATERIALS: return TTR("Import with Separate Materials");
case PRESET_SEPARATE_MESHES: return TTR("Import with Separate Objects");
case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import with Separate Objects+Materials");
- case PRESET_SEPARATE_MESHES_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Animations");
- case PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Materials+Animations");
- case PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Materials+Animations");
+ case PRESET_SEPARATE_MESHES_AND_ANIMATIONS: return TTR("Import with Separate Objects+Animations");
+ case PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS: return TTR("Import with Separate Materials+Animations");
+ case PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS: return TTR("Import with Separate Objects+Materials+Animations");
case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes");
case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials");
}
@@ -954,10 +954,10 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
script_ext_hint += "*." + E->get();
}
- bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS;
- bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS;
+ bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS || p_preset == PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS;
+ bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS;
bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS;
- bool animations_out = p_preset == PRESET_SEPERATE_ANIMATIONS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS;
+ bool animations_out = p_preset == PRESET_SEPARATE_ANIMATIONS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS;
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0));
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index a483c3776f..c3a66aa8b8 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -85,14 +85,14 @@ class ResourceImporterScene : public ResourceImporter {
enum Presets {
PRESET_SEPARATE_MATERIALS,
PRESET_SEPARATE_MESHES,
- PRESET_SEPERATE_ANIMATIONS,
+ PRESET_SEPARATE_ANIMATIONS,
PRESET_SINGLE_SCENE,
PRESET_SEPARATE_MESHES_AND_MATERIALS,
PRESET_SEPARATE_MESHES_AND_ANIMATIONS,
- PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS,
- PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS,
+ PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS,
+ PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS,
PRESET_MULTIPLE_SCENES,
PRESET_MULTIPLE_SCENES_AND_MATERIALS,
@@ -119,7 +119,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animation, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
+ void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map);
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index f29bdde634..3e3f1d1e19 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -30,10 +30,11 @@
#include "resource_importer_texture.h"
#include "editor/editor_file_system.h"
+#include "editor/editor_node.h"
#include "io/config_file.h"
#include "io/image_loader.h"
#include "scene/resources/texture.h"
-#include "editor/editor_node.h"
+
void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) {
singleton->mutex->lock();
@@ -412,13 +413,13 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
//must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
//Android, GLES 2.x
- bool ok_on_pc=false;
+ bool ok_on_pc = false;
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
_save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("s3tc");
- ok_on_pc=true;
+ ok_on_pc = true;
}
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index d7762a66df..c8db1763ab 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -103,13 +103,11 @@ void AnimationPlayerEditor::_notification(int p_what) {
get_tree()->connect("node_removed", this, "_node_removed");
add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel"));
- add_constant_override("separation", get_constant("separation", "VBoxContainer"));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel"));
- add_constant_override("separation", get_constant("separation", "VBoxContainer"));
} break;
case NOTIFICATION_THEME_CHANGED: {
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index 054124da8f..414b091475 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -476,7 +476,7 @@ void AnimationTreeEditor::_draw_node(const StringName &p_node) {
Color font_color = get_color("font_color", "PopupMenu");
Color font_color_title = get_color("font_color_hover", "PopupMenu");
font_color_title.a *= 0.8;
- Ref<Texture> slot_icon = get_icon("NodeRealSlot", "EditorIcons");
+ Ref<Texture> slot_icon = get_icon("VisualShaderPort", "EditorIcons");
Size2 size = get_node_size(p_node);
Point2 pos = anim_tree->node_get_pos(p_node);
@@ -599,7 +599,7 @@ void AnimationTreeEditor::_draw_node(const StringName &p_node) {
if (editable) {
- Ref<Texture> arrow = get_icon("arrow", "Tree");
+ Ref<Texture> arrow = get_icon("GuiDropdown", "EditorIcons");
Point2 arrow_ofs(w - arrow->get_width(), Math::floor((h - arrow->get_height()) / 2));
arrow->draw(ci, ofs + arrow_ofs);
}
@@ -671,7 +671,7 @@ Point2 AnimationTreeEditor::_get_slot_pos(const StringName &p_node_id, bool p_in
Ref<StyleBox> style = get_stylebox("panel", "PopupMenu");
Ref<Font> font = get_font("font", "PopupMenu");
- Ref<Texture> slot_icon = get_icon("NodeRealSlot", "EditorIcons");
+ Ref<Texture> slot_icon = get_icon("VisualShaderPort", "EditorIcons");
Size2 size = get_node_size(p_node_id);
Point2 pos = anim_tree->node_get_pos(p_node_id);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 2b2358f3d0..27dad7756e 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -53,6 +53,8 @@
#define MIN_ZOOM 0.01
#define MAX_ZOOM 100
+#define RULER_WIDTH 15 * EDSCALE
+
class SnapDialog : public ConfirmationDialog {
GDCLASS(SnapDialog, ConfirmationDialog);
@@ -109,13 +111,13 @@ public:
label->set_h_size_flags(SIZE_EXPAND_FILL);
grid_step_x = memnew(SpinBox);
- grid_step_x->set_min(-SPIN_BOX_GRID_RANGE);
+ grid_step_x->set_min(0.01);
grid_step_x->set_max(SPIN_BOX_GRID_RANGE);
grid_step_x->set_suffix("px");
child_container->add_child(grid_step_x);
grid_step_y = memnew(SpinBox);
- grid_step_y->set_min(-SPIN_BOX_GRID_RANGE);
+ grid_step_y->set_min(0.01);
grid_step_y->set_max(SPIN_BOX_GRID_RANGE);
grid_step_y->set_suffix("px");
child_container->add_child(grid_step_y);
@@ -149,7 +151,7 @@ public:
child_container->add_child(rotation_step);
}
- void set_fields(const Point2 p_grid_offset, const Size2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) {
+ void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const float p_rotation_offset, const float p_rotation_step) {
grid_offset_x->set_value(p_grid_offset.x);
grid_offset_y->set_value(p_grid_offset.y);
grid_step_x->set_value(p_grid_step.x);
@@ -158,11 +160,9 @@ public:
rotation_step->set_value(p_rotation_step * (180 / Math_PI));
}
- void get_fields(Point2 &p_grid_offset, Size2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) {
- p_grid_offset.x = grid_offset_x->get_value();
- p_grid_offset.y = grid_offset_y->get_value();
- p_grid_step.x = grid_step_x->get_value();
- p_grid_step.y = grid_step_y->get_value();
+ void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, float &p_rotation_offset, float &p_rotation_step) {
+ p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
+ p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
}
@@ -222,6 +222,135 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2 &mouse_pos) {
undo_redo->commit_action();
}
+void CanvasItemEditor::_snap_if_closer(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) {
+ float radius = p_radius / zoom;
+ float dist;
+
+ Transform2D rot_trans = Transform2D(rotation, Point2());
+ p_value = rot_trans.inverse().xform(p_value);
+ p_target_snap = rot_trans.inverse().xform(p_target_snap);
+ r_current_snap = rot_trans.inverse().xform(r_current_snap);
+
+ dist = Math::abs(p_value.x - p_target_snap.x);
+ if (p_radius < 0 || dist < radius && (!r_snapped[0] || dist < Math::abs(r_current_snap.x - p_value.x))) {
+ r_current_snap.x = p_target_snap.x;
+ r_snapped[0] = true;
+ }
+
+ dist = Math::abs(p_value.y - p_target_snap.y);
+ if (p_radius < 0 || dist < radius && (!r_snapped[1] || dist < Math::abs(r_current_snap.y - p_value.y))) {
+ r_current_snap.y = p_target_snap.y;
+ r_snapped[1] = true;
+ }
+
+ r_current_snap = rot_trans.xform(r_current_snap);
+}
+
+void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap) {
+ const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_current);
+ if (canvas_item && p_current != p_to_snap) {
+ Transform2D ci_transform = canvas_item->get_global_transform_with_canvas();
+ Transform2D to_snap_transform = p_to_snap->get_global_transform_with_canvas();
+ if (ci_transform.get_rotation() == to_snap_transform.get_rotation()) {
+ Point2 begin = ci_transform.xform(canvas_item->get_item_rect().get_position());
+ Point2 end = ci_transform.xform(canvas_item->get_item_rect().get_position() + canvas_item->get_item_rect().get_size());
+
+ _snap_if_closer(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation());
+ _snap_if_closer(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation());
+ }
+ }
+ for (int i = 0; i < p_current->get_child_count(); i++) {
+ _snap_other_nodes(p_value, r_current_snap, r_snapped, p_current->get_child(i), p_to_snap);
+ }
+}
+
+Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) {
+ Point2 dist[2];
+ bool snapped[2] = { false, false };
+
+ // Smart snap using the canvas position
+ Vector2 output = p_target;
+ real_t rotation = 0.0;
+
+ if (p_canvas_item) {
+ Point2 begin;
+ Point2 end;
+ rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation();
+
+ if ((snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) {
+ // Parent sides and center
+ bool can_snap = false;
+ if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
+ begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0)));
+ end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1)));
+ can_snap = true;
+ } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) {
+ begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position());
+ end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position() + parent_ci->get_item_rect().get_size());
+ can_snap = true;
+ }
+
+ if (can_snap) {
+ _snap_if_closer(p_target, begin, output, snapped, rotation);
+ _snap_if_closer(p_target, (begin + end) / 2.0, output, snapped, rotation);
+ _snap_if_closer(p_target, end, output, snapped, rotation);
+ }
+ }
+
+ // Self anchors (for sides)
+ if ((snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) {
+ if (const Control *c = Object::cast_to<Control>(p_canvas_item)) {
+ begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP))));
+ end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM))));
+ _snap_if_closer(p_target, begin, output, snapped, rotation);
+ _snap_if_closer(p_target, end, output, snapped, rotation);
+ }
+ }
+
+ // Self sides (for anchors)
+ if ((snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) {
+ begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position());
+ end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position() + p_canvas_item->get_item_rect().get_size());
+ _snap_if_closer(p_target, begin, output, snapped, rotation);
+ _snap_if_closer(p_target, end, output, snapped, rotation);
+ }
+
+ // Other nodes sides
+ if ((snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) {
+ _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item);
+ }
+ }
+
+ if (((snap_active && snap_grid && (p_modes & SNAP_GRID)) || (p_forced_modes & SNAP_GRID)) && rotation == 0.0) {
+ // Grid
+ Point2 offset = grid_offset;
+ if (snap_relative) {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0])) {
+ offset = Object::cast_to<Node2D>(selection[0])->get_global_position();
+ } else {
+ offset = _find_topleftmost_point();
+ }
+ }
+ Point2 grid_output;
+ grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x;
+ grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y;
+ _snap_if_closer(p_target, grid_output, output, snapped, 0.0, -1.0);
+ }
+
+ if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) {
+ // Pixel
+ output = output.snapped(Size2(1, 1));
+ }
+
+ return output;
+}
+
+float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
+ float offset = snap_relative ? p_start : p_target;
+ return (snap_rotation && snap_rotation_step != 0) ? Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset : p_target;
+}
+
void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventKey> k = p_ev;
@@ -232,22 +361,34 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
if (k->get_control())
return;
- if (k->is_pressed() && !k->is_echo() && k->get_scancode() == KEY_V && drag == DRAG_NONE && can_move_pivot) {
-
- if (k->get_shift()) {
+ if (k->is_pressed() && !k->is_echo()) {
+ if (drag_pivot_shortcut.is_valid() && drag_pivot_shortcut->is_shortcut(p_ev) && drag == DRAG_NONE && can_move_pivot) {
//move drag pivot
drag = DRAG_PIVOT;
- } else if (!Input::get_singleton()->is_mouse_button_pressed(0)) {
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
- Vector2 mouse_pos = viewport->get_local_mouse_pos();
- if (selection.size() && viewport->get_rect().has_point(mouse_pos)) {
- //just in case, make it work if over viewport
- mouse_pos = transform.affine_inverse().xform(mouse_pos);
- mouse_pos = snap_point(mouse_pos);
-
- _edit_set_pivot(mouse_pos);
+ } else if (set_pivot_shortcut.is_valid() && set_pivot_shortcut->is_shortcut(p_ev) && drag == DRAG_NONE && can_move_pivot) {
+ if (!Input::get_singleton()->is_mouse_button_pressed(0)) {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ Vector2 mouse_pos = viewport->get_local_mouse_pos();
+ if (selection.size() && viewport->get_rect().has_point(mouse_pos)) {
+ //just in case, make it work if over viewport
+ mouse_pos = transform.affine_inverse().xform(mouse_pos);
+ mouse_pos = snap_point(mouse_pos, SNAP_DEFAULT, _get_single_item());
+
+ _edit_set_pivot(mouse_pos);
+ }
}
+ } else if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) {
+ // Multiply the grid size
+ grid_step_multiplier = MIN(grid_step_multiplier + 1, 12);
+ viewport_base->update();
+ viewport->update();
+ } else if ((snap_grid || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) {
+ // Divide the grid size
+ Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1);
+ if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0)
+ grid_step_multiplier--;
+ viewport_base->update();
+ viewport->update();
}
}
}
@@ -272,38 +413,25 @@ Object *CanvasItemEditor::_get_editor_data(Object *p_what) {
return memnew(CanvasItemEditorSelectedItem);
}
-inline float _snap_scalar(float p_offset, float p_step, bool p_snap_relative, float p_target, float p_start) {
- float offset = p_snap_relative ? p_start : p_offset;
- return p_step != 0 ? Math::stepify(p_target - offset, p_step) + offset : p_target;
-}
-
-Vector2 CanvasItemEditor::snap_point(Vector2 p_target, Vector2 p_start) const {
- if (snap_grid) {
- p_target.x = _snap_scalar(snap_offset.x, snap_step.x, snap_relative, p_target.x, p_start.x);
- p_target.y = _snap_scalar(snap_offset.y, snap_step.y, snap_relative, p_target.y, p_start.y);
- }
- if (snap_pixel)
- p_target = p_target.snapped(Size2(1, 1));
-
- return p_target;
-}
-
-float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
- return snap_rotation ? _snap_scalar(snap_rotation_offset, snap_rotation_step, snap_relative, p_target, p_start) : p_target;
-}
-
Dictionary CanvasItemEditor::get_state() const {
Dictionary state;
state["zoom"] = zoom;
state["ofs"] = Point2(h_scroll->get_value(), v_scroll->get_value());
//state["ofs"]=-transform.get_origin();
- state["snap_offset"] = snap_offset;
- state["snap_step"] = snap_step;
+ state["grid_offset"] = grid_offset;
+ state["grid_step"] = grid_step;
state["snap_rotation_offset"] = snap_rotation_offset;
state["snap_rotation_step"] = snap_rotation_step;
+ state["snap_active"] = snap_active;
+ state["snap_node_parent"] = snap_node_parent;
+ state["snap_node_anchors"] = snap_node_anchors;
+ state["snap_node_sides"] = snap_node_sides;
+ state["snap_other_nodes"] = snap_other_nodes;
state["snap_grid"] = snap_grid;
- state["snap_show_grid"] = snap_show_grid;
+ state["show_grid"] = show_grid;
+ state["show_rulers"] = show_rulers;
+ state["show_helpers"] = show_helpers;
state["snap_rotation"] = snap_rotation;
state["snap_relative"] = snap_relative;
state["snap_pixel"] = snap_pixel;
@@ -324,12 +452,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
v_scroll->set_value(ofs.y);
}
- if (state.has("snap_step")) {
- snap_step = state["snap_step"];
+ if (state.has("grid_offset")) {
+ grid_offset = state["grid_offset"];
}
- if (state.has("snap_offset")) {
- snap_offset = state["snap_offset"];
+ if (state.has("grid_step")) {
+ grid_step = state["grid_step"];
}
if (state.has("snap_rotation_step")) {
@@ -340,40 +468,81 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_rotation_offset = state["snap_rotation_offset"];
}
+ if (state.has("snap_active")) {
+ snap_active = state["snap_active"];
+ snap_button->set_pressed(snap_active);
+ }
+
+ if (state.has("snap_node_parent")) {
+ snap_node_parent = state["snap_node_parent"];
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_parent);
+ }
+
+ if (state.has("snap_node_anchors")) {
+ snap_node_anchors = state["snap_node_anchors"];
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_anchors);
+ }
+
+ if (state.has("snap_node_sides")) {
+ snap_node_sides = state["snap_node_sides"];
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_sides);
+ }
+
+ if (state.has("snap_other_nodes")) {
+ snap_other_nodes = state["snap_other_nodes"];
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES);
+ smartsnap_config_popup->set_item_checked(idx, snap_other_nodes);
+ }
+
if (state.has("snap_grid")) {
snap_grid = state["snap_grid"];
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE);
- edit_menu->get_popup()->set_item_checked(idx, snap_grid);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_grid);
+ }
+
+ if (state.has("show_grid")) {
+ show_grid = state["show_grid"];
+ int idx = view_menu->get_popup()->get_item_index(SHOW_GRID);
+ view_menu->get_popup()->set_item_checked(idx, show_grid);
}
- if (state.has("snap_show_grid")) {
- snap_show_grid = state["snap_show_grid"];
- int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID);
- edit_menu->get_popup()->set_item_checked(idx, snap_show_grid);
+ if (state.has("show_rulers")) {
+ show_rulers = state["show_rulers"];
+ int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
+ view_menu->get_popup()->set_item_checked(idx, show_rulers);
+ }
+
+ if (state.has("show_helpers")) {
+ show_helpers = state["show_helpers"];
+ int idx = view_menu->get_popup()->get_item_index(SHOW_HELPERS);
+ view_menu->get_popup()->set_item_checked(idx, show_helpers);
}
if (state.has("snap_rotation")) {
snap_rotation = state["snap_rotation"];
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
- edit_menu->get_popup()->set_item_checked(idx, snap_rotation);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
}
if (state.has("snap_relative")) {
snap_relative = state["snap_relative"];
- int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE);
- edit_menu->get_popup()->set_item_checked(idx, snap_relative);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_relative);
}
if (state.has("snap_pixel")) {
snap_pixel = state["snap_pixel"];
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
- edit_menu->get_popup()->set_item_checked(idx, snap_pixel);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
}
if (state.has("skeleton_show_bones")) {
skeleton_show_bones = state["skeleton_show_bones"];
- int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES);
- skeleton_menu->set_item_checked(idx, skeleton_show_bones);
+ int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES);
+ skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones);
}
viewport->update();
@@ -495,6 +664,7 @@ void CanvasItemEditor::_select_click_on_empty_area(Point2 p_click_pos, bool p_ap
if (!p_append) {
editor_selection->clear();
viewport->update();
+ viewport_base->update();
};
if (p_box_selection) {
@@ -534,6 +704,7 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
}
viewport->update();
+ viewport_base->update();
return still_selected;
}
@@ -566,7 +737,7 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE
Vector2 drag = p_dir;
if (p_snap)
- drag *= snap_step;
+ drag *= grid_step * Math::pow(2.0, grid_step_multiplier);
undo_redo->add_undo_method(canvas_item, "edit_set_state", canvas_item->edit_get_state());
@@ -649,7 +820,7 @@ int CanvasItemEditor::get_item_count() {
return ic;
}
-CanvasItem *CanvasItemEditor::get_single_item() {
+CanvasItem *CanvasItemEditor::_get_single_item() {
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -674,7 +845,7 @@ CanvasItem *CanvasItemEditor::get_single_item() {
CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const Point2 &p_click, Vector2 &r_point) {
// Returns a drag type if a resize handle is clicked
- CanvasItem *canvas_item = get_single_item();
+ CanvasItem *canvas_item = _get_single_item();
ERR_FAIL_COND_V(!canvas_item, DRAG_NONE);
@@ -738,35 +909,7 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const
return DRAG_NONE;
}
-float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_opposite_anchor) {
- bool snapped = false;
- float dist, dist_min = 0.0;
- float radius = 0.05 / zoom;
- float basic_anchors[3] = { 0.0, 0.5, 1.0 };
- for (int i = 0; i < 3; i++) {
- dist = fabs(p_anchor - basic_anchors[i]);
- if (dist < radius) {
- if (!snapped || dist <= dist_min) {
- p_anchor = basic_anchors[i];
- dist_min = dist;
- snapped = true;
- }
- }
- }
- dist = fabs(p_anchor - p_opposite_anchor);
- if (p_opposite_anchor >= 0 && dist < radius) {
- if (!snapped || dist <= dist_min) {
- p_anchor = p_opposite_anchor;
- dist_min = dist;
- snapped = true;
- }
- }
- if (p_snapped)
- *p_snapped = snapped;
- return p_anchor;
-}
-
-Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) {
+Vector2 CanvasItemEditor::_anchor_to_position(const Control *p_control, Vector2 anchor) {
ERR_FAIL_COND_V(!p_control, Vector2());
Transform2D parent_transform = p_control->get_transform().affine_inverse();
@@ -775,7 +918,7 @@ Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor
return parent_transform.xform(Vector2(parent_size.x * anchor.x, parent_size.y * anchor.y));
}
-Vector2 CanvasItemEditor::_position_to_anchor(Control *p_control, Vector2 position) {
+Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 position) {
ERR_FAIL_COND_V(!p_control, Vector2());
Size2 parent_size = p_control->get_parent_area_size();
@@ -784,7 +927,7 @@ Vector2 CanvasItemEditor::_position_to_anchor(Control *p_control, Vector2 positi
CanvasItemEditor::DragType CanvasItemEditor::_get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point) {
// Returns a drag type if an anchor handle is clicked
- CanvasItem *canvas_item = get_single_item();
+ CanvasItem *canvas_item = _get_single_item();
ERR_FAIL_COND_V(!canvas_item, DRAG_NONE);
Control *control = Object::cast_to<Control>(canvas_item);
@@ -845,6 +988,8 @@ void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) {
se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
if (Object::cast_to<Control>(canvas_item))
se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
+
+ se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
}
if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0])) {
@@ -918,28 +1063,12 @@ void CanvasItemEditor::_append_canvas_item(CanvasItem *p_item) {
}
void CanvasItemEditor::_snap_changed() {
- ((SnapDialog *)snap_dialog)->get_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, snap_rotation_offset, snap_rotation_step);
+ grid_step_multiplier = 0;
+ viewport_base->update();
viewport->update();
}
-void CanvasItemEditor::_dialog_value_changed(double) {
-
- if (updating_value_dialog)
- return;
-
- switch (last_option) {
-
- case ZOOM_SET: {
-
- zoom = dialog_val->get_value() / 100.0;
- _update_scroll(0);
- viewport->update();
-
- } break;
- default: {}
- }
-}
-
void CanvasItemEditor::_selection_result_pressed(int p_result) {
if (selection_results.size() <= p_result)
@@ -960,7 +1089,7 @@ void CanvasItemEditor::_selection_menu_hide() {
void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) {
- Point2 click = b->get_position();
+ Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
Node *scene = editor->get_edited_scene();
if (!scene)
@@ -1068,7 +1197,7 @@ void CanvasItemEditor::_update_cursor() {
viewport->set_default_cursor_shape(c);
}
-void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
+void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event) {
{
EditorNode *en = editor;
@@ -1101,7 +1230,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
float prev_zoom = zoom;
zoom = zoom * (1 - (0.05 * b->get_factor()));
{
- Point2 ofs = b->get_position();
+ Point2 ofs = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
ofs = ofs / prev_zoom - ofs / zoom;
h_scroll->set_value(h_scroll->get_value() + ofs.x);
v_scroll->set_value(v_scroll->get_value() + ofs.y);
@@ -1125,7 +1254,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
float prev_zoom = zoom;
zoom = zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95);
{
- Point2 ofs = b->get_position();
+ Point2 ofs = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
ofs = ofs / prev_zoom - ofs / zoom;
h_scroll->set_value(h_scroll->get_value() + ofs.x);
v_scroll->set_value(v_scroll->get_value() + ofs.y);
@@ -1214,9 +1343,9 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) {
if (b->is_pressed()) {
// Set the pivot point
- Point2 mouse_pos = b->get_position();
+ Point2 mouse_pos = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
mouse_pos = transform.affine_inverse().xform(mouse_pos);
- mouse_pos = snap_point(mouse_pos);
+ mouse_pos = snap_point(mouse_pos, SNAP_DEFAULT, _get_single_item());
_edit_set_pivot(mouse_pos);
}
return;
@@ -1337,8 +1466,8 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
E->get().to
};
- Vector2 p = Geometry::get_closest_point_to_segment_2d(b->get_position(), s);
- float d = p.distance_to(b->get_position());
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()), s);
+ float d = p.distance_to(viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()));
if (d < bone_width && d < closest_dist) {
Cbone = E;
closest_dist = d;
@@ -1395,12 +1524,12 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
}
// Single selected item
- CanvasItem *canvas_item = get_single_item();
+ CanvasItem *canvas_item = _get_single_item();
if (canvas_item) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
ERR_FAIL_COND(!se);
- Point2 click = b->get_position();
+ Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
// Rotation
if ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
@@ -1411,6 +1540,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
if (Object::cast_to<Control>(canvas_item))
se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
+ se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
return;
}
@@ -1432,15 +1562,18 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot();
if (Object::cast_to<Control>(canvas_item))
se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
+ se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
return;
}
// Drag anchor handles
- if (Object::cast_to<Control>(canvas_item)) {
+ Control *control = Object::cast_to<Control>(canvas_item);
+ if (control && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
drag = _get_anchor_handle_drag_type(click, drag_point_from);
if (drag != DRAG_NONE) {
drag_from = transform.affine_inverse().xform(click);
se->undo_state = canvas_item->edit_get_state();
+ se->pre_drag_xform = canvas_item->get_global_transform_with_canvas();
return;
}
}
@@ -1448,7 +1581,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
}
// Multiple selected items
- Point2 click = b->get_position();
+ Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
if ((b->get_alt() || tool == TOOL_MOVE) && get_item_count()) {
// Drag the nodes
@@ -1508,12 +1641,12 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
// Mouse motion event
_update_cursor();
- if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
- viewport->call_deferred("grab_focus");
+ if (!viewport_base->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
+ viewport_base->call_deferred("grab_focus");
if (box_selecting) {
// Update box selection
- box_selecting_to = transform.affine_inverse().xform(m->get_position());
+ box_selecting_to = transform.affine_inverse().xform(viewport_scrollable->get_transform().affine_inverse().xform(m->get_position()));
viewport->update();
return;
}
@@ -1559,7 +1692,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
}
Vector2 dfrom = drag_from;
- Vector2 dto = transform.affine_inverse().xform(m->get_position());
+ Vector2 dto = transform.affine_inverse().xform(viewport_scrollable->get_transform().affine_inverse().xform(m->get_position()));
if (canvas_item->has_meta("_edit_lock_"))
continue;
@@ -1593,60 +1726,74 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
continue;
}
+ bool uniform = m->get_shift();
+ bool symmetric = m->get_alt();
+
+ Vector2 drag_vector =
+ canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) -
+ canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom);
+
+ switch (drag) {
+ case DRAG_ALL:
+ case DRAG_NODE_2D:
+ dto -= drag_from - drag_point_from;
+ if (uniform) {
+ if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) {
+ dto.y = drag_point_from.y;
+ } else {
+ dto.x = drag_point_from.x;
+ }
+ }
+ break;
+ }
+
Control *control = Object::cast_to<Control>(canvas_item);
if (control) {
// Drag and snap the anchor
- Vector2 anchor = _position_to_anchor(control, canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto - drag_from + drag_point_from));
+ Transform2D c_trans_rev = canvas_item->get_global_transform_with_canvas().affine_inverse();
+
+ Vector2 anchor = c_trans_rev.xform(dto - drag_from + drag_point_from);
+ anchor = _position_to_anchor(control, anchor);
+
+ Vector2 anchor_snapped = c_trans_rev.xform(snap_point(dto - drag_from + drag_point_from, SNAP_GRID | SNAP_OTHER_NODES, _get_single_item(), SNAP_NODE_PARENT | SNAP_NODE_SIDES));
+ anchor_snapped = _position_to_anchor(control, anchor_snapped).snapped(Vector2(0.00001, 0.00001));
+
+ bool use_y = Math::abs(drag_vector.y) > Math::abs(drag_vector.x);
switch (drag) {
case DRAG_ANCHOR_TOP_LEFT:
- control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT)), false, false);
- control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM)), false, false);
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
continue;
break;
case DRAG_ANCHOR_TOP_RIGHT:
- control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT)), false, false);
- control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM)), false, false);
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
continue;
break;
case DRAG_ANCHOR_BOTTOM_RIGHT:
- control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT)), false, false);
- control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP)), false, false);
- continue;
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
break;
case DRAG_ANCHOR_BOTTOM_LEFT:
- control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT)), false, false);
- control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP)), false, false);
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
continue;
break;
case DRAG_ANCHOR_ALL:
- control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x));
- control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x));
- control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y));
- control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y));
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_LEFT, anchor_snapped.x);
+ if (!uniform || (uniform && !use_y)) control->set_anchor(MARGIN_RIGHT, anchor_snapped.x);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_TOP, anchor_snapped.y);
+ if (!uniform || (uniform && use_y)) control->set_anchor(MARGIN_BOTTOM, anchor_snapped.y);
continue;
break;
}
}
- bool uniform = m->get_shift();
- bool symmetric = m->get_alt();
-
- if (drag == DRAG_ALL || drag == DRAG_NODE_2D)
- dto -= drag_from - drag_point_from;
-
- if (uniform && (drag == DRAG_ALL || drag == DRAG_NODE_2D)) {
- if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) {
- dto.y = drag_point_from.y;
- } else {
- dto.x = drag_point_from.x;
- }
- }
-
dfrom = drag_point_from;
- dto = snap_point(dto, drag_point_from);
+ dto = snap_point(dto, SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, _get_single_item());
- Vector2 drag_vector =
+ drag_vector =
canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) -
canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom);
@@ -1896,56 +2043,148 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
}
}
+void CanvasItemEditor::_draw_text_at_position(Point2 p_position, String p_string, Margin p_side) {
+ Color color = Color(0.8, 0.8, 0.8, 0.5);
+ Ref<Font> font = get_font("font", "Label");
+ Size2 text_size = font->get_string_size(p_string);
+ switch (p_side) {
+ case MARGIN_LEFT:
+ p_position += Vector2(-text_size.x - 5, text_size.y / 2);
+ break;
+ case MARGIN_TOP:
+ p_position += Vector2(-text_size.x / 2, -5);
+ break;
+ case MARGIN_RIGHT:
+ p_position += Vector2(5, text_size.y / 2);
+ break;
+ case MARGIN_BOTTOM:
+ p_position += Vector2(-text_size.x / 2, text_size.y + 5);
+ break;
+ }
+ viewport->draw_string(font, p_position, p_string, color);
+}
+
+void CanvasItemEditor::_draw_margin_at_position(int p_value, Point2 p_position, Margin p_side) {
+ String str = vformat("%d px", p_value);
+ if (p_value != 0) {
+ _draw_text_at_position(p_position, str, p_side);
+ }
+}
+
void CanvasItemEditor::_draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side) {
+ String str = vformat("%.1f %%", p_value * 100.0);
if (p_value != 0) {
- Color color = Color(0.8, 0.8, 0.8, 0.5);
- Ref<Font> font = get_font("font", "Label");
- String str = vformat("%.1f %%", p_value * 100.0);
- Size2 text_size = font->get_string_size(str);
- switch (p_side) {
- case MARGIN_LEFT:
- p_position += Vector2(-text_size.x - 5, text_size.y / 2);
- break;
- case MARGIN_TOP:
- p_position += Vector2(-text_size.x / 2, -5);
- break;
- case MARGIN_RIGHT:
- p_position += Vector2(5, text_size.y / 2);
- break;
- case MARGIN_BOTTOM:
- p_position += Vector2(-text_size.x / 2, text_size.y + 5);
- break;
- }
- viewport->draw_string(font, p_position, str, color);
+ _draw_text_at_position(p_position, str, p_side);
}
}
-void CanvasItemEditor::_viewport_draw() {
+void CanvasItemEditor::_draw_rulers() {
+ Color graduation_color = Color(0.5, 0.5, 0.5, 1);
+ Color bg_color = get_color("dark_color_2", "Editor");
+ Color font_color = Color(0.8, 0.8, 0.8, 1);
+ Ref<Font> font = get_font("rulers", "EditorFonts");
+
+ // The rule transform
+ Transform2D ruler_transform;
+ if (show_grid || snap_grid) {
+ ruler_transform = Transform2D();
+ if (snap_relative && get_item_count() > 0) {
+ ruler_transform.translate(_find_topleftmost_point());
+ ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier));
+ } else {
+ ruler_transform.translate(grid_offset);
+ ruler_transform.scale_basis(grid_step * Math::pow(2.0, grid_step_multiplier));
+ }
+ while ((transform * ruler_transform).get_scale().x < 50 || (transform * ruler_transform).get_scale().y < 50) {
- // TODO fetch the viewport?
+ ruler_transform.scale_basis(Point2(2, 2));
+ }
+ } else {
+ float basic_rule = 100;
+ for (int i = 0; basic_rule * zoom > 100; i++) {
+ basic_rule /= (i % 2) ? 5.0 : 2.0;
+ }
+ for (int i = 0; basic_rule * zoom < 100; i++) {
+ basic_rule *= (i % 2) ? 2.0 : 5.0;
+ }
+ ruler_transform = Transform2D();
+ ruler_transform.scale(Size2(basic_rule, basic_rule));
+ }
- Ref<Texture> pivot = get_icon("EditorPivot", "EditorIcons");
- _update_scrollbars();
- RID ci = viewport->get_canvas_item();
+ // Subdivisions
+ int major_subdivision = 2;
+ Transform2D major_subdivide = Transform2D();
+ major_subdivide.scale(Size2(1.0 / major_subdivision, 1.0 / major_subdivision));
+
+ int minor_subdivision = 5;
+ Transform2D minor_subdivide = Transform2D();
+ minor_subdivide.scale(Size2(1.0 / minor_subdivision, 1.0 / minor_subdivision));
+
+ // First and last graduations to draw (in the ruler space)
+ Point2 first = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(Point2());
+ Point2 last = (transform * ruler_transform * major_subdivide * minor_subdivide).affine_inverse().xform(viewport->get_size());
+
+ // Draw top ruler
+ viewport_base->draw_rect(Rect2(Point2(RULER_WIDTH, 0), Size2(viewport->get_size().x, RULER_WIDTH)), bg_color);
+ for (int i = Math::ceil(first.x); i < last.x; i++) {
+ Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0));
+ if (i % (major_subdivision * minor_subdivision) == 0) {
+ viewport_base->draw_line(Point2(position.x + RULER_WIDTH, 0), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
+ float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x;
+ viewport_base->draw_string(font, Point2(position.x + RULER_WIDTH + 2, font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
+ } else {
+ if (i % minor_subdivision == 0) {
+ viewport_base->draw_line(Point2(position.x + RULER_WIDTH, RULER_WIDTH * 0.33), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
+ } else {
+ viewport_base->draw_line(Point2(position.x + RULER_WIDTH, RULER_WIDTH * 0.66), Point2(position.x + RULER_WIDTH, RULER_WIDTH), graduation_color);
+ }
+ }
+ }
- if (snap_show_grid) {
+ // Draw left ruler
+ viewport_base->draw_rect(Rect2(Point2(0, RULER_WIDTH), Size2(RULER_WIDTH, viewport->get_size().y)), bg_color);
+ for (int i = Math::ceil(first.y); i < last.y; i++) {
+ Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i));
+ if (i % (major_subdivision * minor_subdivision) == 0) {
+ viewport_base->draw_line(Point2(0, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
+ float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y;
+ viewport_base->draw_string(font, Point2(2, position.y + RULER_WIDTH + 2 + font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
+ } else {
+ if (i % minor_subdivision == 0) {
+ viewport_base->draw_line(Point2(RULER_WIDTH * 0.33, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
+ } else {
+ viewport_base->draw_line(Point2(RULER_WIDTH * 0.66, position.y + RULER_WIDTH), Point2(RULER_WIDTH, position.y + RULER_WIDTH), graduation_color);
+ }
+ }
+ }
+ viewport_base->draw_rect(Rect2(Point2(), Size2(RULER_WIDTH, RULER_WIDTH)), graduation_color);
+}
+
+void CanvasItemEditor::_draw_focus() {
+ if (viewport_base->has_focus()) {
+ get_stylebox("Focus", "EditorStyles")->draw(viewport_base->get_canvas_item(), Rect2(Point2(), viewport_base->get_size()));
+ }
+}
+
+void CanvasItemEditor::_draw_grid() {
+ if (show_grid) {
//Draw the grid
Size2 s = viewport->get_size();
int last_cell = 0;
Transform2D xform = transform.affine_inverse();
- Vector2 grid_offset;
- if (snap_relative && snap_grid && get_item_count() > 0) {
+ Vector2 real_grid_offset;
+ if (snap_relative && get_item_count() > 0) {
Vector2 topleft = _find_topleftmost_point();
- grid_offset.x = fmod(topleft.x, snap_step.x);
- grid_offset.y = fmod(topleft.y, snap_step.y);
+ real_grid_offset.x = fmod(topleft.x, grid_step.x * Math::pow(2.0, grid_step_multiplier));
+ real_grid_offset.y = fmod(topleft.y, grid_step.y * Math::pow(2.0, grid_step_multiplier));
} else {
- grid_offset = snap_offset;
+ real_grid_offset = grid_offset;
}
- if (snap_step.x != 0) {
+ if (grid_step.x != 0) {
for (int i = 0; i < s.width; i++) {
- int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(i, 0)).x - grid_offset.x) / snap_step.x));
+ int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(i, 0)).x - real_grid_offset.x) / (grid_step.x * Math::pow(2.0, grid_step_multiplier))));
if (i == 0)
last_cell = cell;
if (last_cell != cell)
@@ -1954,9 +2193,9 @@ void CanvasItemEditor::_viewport_draw() {
}
}
- if (snap_step.y != 0) {
+ if (grid_step.y != 0) {
for (int i = 0; i < s.height; i++) {
- int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(0, i)).y - grid_offset.y) / snap_step.y));
+ int cell = Math::fast_ftoi(Math::floor((xform.xform(Vector2(0, i)).y - real_grid_offset.y) / (grid_step.y * Math::pow(2.0, grid_step_multiplier))));
if (i == 0)
last_cell = cell;
if (last_cell != cell)
@@ -1965,21 +2204,15 @@ void CanvasItemEditor::_viewport_draw() {
}
}
}
+}
- if (viewport->has_focus()) {
- Size2 size = viewport->get_size();
- get_stylebox("Focus", "EditorStyles")->draw(ci, Rect2(Point2(), size));
- }
-
- Ref<Texture> lock = get_icon("Lock", "EditorIcons");
- Ref<Texture> group = get_icon("Group", "EditorIcons");
-
- bool single = get_single_item() != NULL;
-
- Map<Node *, Object *> &selection = editor_selection->get_selection();
-
+void CanvasItemEditor::_draw_selection() {
bool pivot_found = false;
+ Ref<Texture> pivot_icon = get_icon("EditorPivot", "EditorIcons");
+ bool single = _get_single_item() != NULL;
+ RID ci = viewport->get_canvas_item();
+ Map<Node *, Object *> &selection = editor_selection->get_selection();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
@@ -1993,6 +2226,23 @@ void CanvasItemEditor::_viewport_draw() {
Rect2 rect = canvas_item->get_item_rect();
+ if (drag != DRAG_NONE && drag != DRAG_PIVOT) {
+ const Transform2D pre_drag_xform = transform * se->pre_drag_xform;
+ const Color pre_drag_color = Color(0.4, 0.6, 1, 0.7);
+
+ Vector2 pre_drag_endpoints[4] = {
+
+ pre_drag_xform.xform(rect.position),
+ pre_drag_xform.xform(rect.position + Vector2(rect.size.x, 0)),
+ pre_drag_xform.xform(rect.position + rect.size),
+ pre_drag_xform.xform(rect.position + Vector2(0, rect.size.y))
+ };
+
+ for (int i = 0; i < 4; i++) {
+ viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2);
+ }
+ }
+
Transform2D xform = transform * canvas_item->get_global_transform_with_canvas();
VisualServer::get_singleton()->canvas_item_add_set_transform(ci, xform);
@@ -2014,10 +2264,10 @@ void CanvasItemEditor::_viewport_draw() {
if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
- if (Object::cast_to<Node2D>(canvas_item)) {
-
- if (Object::cast_to<Node2D>(canvas_item)->edit_has_pivot()) {
- viewport->draw_texture(pivot, xform.get_origin() + (-pivot->get_size() / 2).floor());
+ Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
+ if (node2d) {
+ if (node2d->edit_has_pivot()) {
+ viewport->draw_texture(pivot_icon, xform.get_origin() + (-pivot_icon->get_size() / 2).floor());
can_move_pivot = true;
pivot_found = true;
}
@@ -2027,12 +2277,15 @@ void CanvasItemEditor::_viewport_draw() {
if (control) {
Vector2 pivot_ofs = control->get_pivot_offset();
if (pivot_ofs != Vector2()) {
- viewport->draw_texture(pivot, xform.xform(pivot_ofs) + (-pivot->get_size() / 2).floor());
+ viewport->draw_texture(pivot_icon, xform.xform(pivot_ofs) + (-pivot_icon->get_size() / 2).floor());
}
can_move_pivot = true;
pivot_found = true;
- if (tool == TOOL_SELECT) {
+ if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
+ // Draw the helpers
+ Color color_base = Color(0.8, 0.8, 0.8, 0.5);
+
float anchors_values[4];
anchors_values[0] = control->get_anchor(MARGIN_LEFT);
anchors_values[1] = control->get_anchor(MARGIN_TOP);
@@ -2047,6 +2300,7 @@ void CanvasItemEditor::_viewport_draw() {
anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i]));
}
+ Map<Node *, Object *> &selection = editor_selection->get_selection();
// Get which anchor is dragged
int dragged_anchor = -1;
switch (drag) {
@@ -2069,7 +2323,6 @@ void CanvasItemEditor::_viewport_draw() {
// Draw the 4 lines when dragged
bool snapped;
Color color_snapped = Color(0.64, 0.93, 0.67, 0.5);
- Color color_base = Color(0.8, 0.8, 0.8, 0.5);
Vector2 corners_pos[4];
for (int i = 0; i < 4; i++) {
@@ -2082,7 +2335,7 @@ void CanvasItemEditor::_viewport_draw() {
float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val);
line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val);
- _anchor_snap(anchors_values[i], &snapped);
+ snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
}
@@ -2114,6 +2367,83 @@ void CanvasItemEditor::_viewport_draw() {
for (int i = 0; i < 4; i++) {
anchor_handle->draw_rect(ci, anchor_rects[i]);
}
+
+ // Draw the margin values and the node width/height when dragging control side
+ float ratio = 0.33;
+ Transform2D parent_transform = xform * control->get_transform().affine_inverse();
+ float node_pos_in_parent[4];
+
+ node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * control->get_parent_area_size().width + control->get_margin(MARGIN_LEFT);
+ node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * control->get_parent_area_size().height + control->get_margin(MARGIN_TOP);
+ node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * control->get_parent_area_size().width + control->get_margin(MARGIN_RIGHT);
+ node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * control->get_parent_area_size().height + control->get_margin(MARGIN_BOTTOM);
+
+ switch (drag) {
+ case DRAG_LEFT:
+ case DRAG_TOP_LEFT:
+ case DRAG_BOTTOM_LEFT:
+ _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
+ case DRAG_ALL:
+ Point2 start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio));
+ Point2 end = start - Vector2(control->get_margin(MARGIN_LEFT), 0);
+ _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ }
+ switch (drag) {
+ case DRAG_RIGHT:
+ case DRAG_TOP_RIGHT:
+ case DRAG_BOTTOM_RIGHT:
+ _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
+ case DRAG_ALL:
+ Point2 start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio));
+ Point2 end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0);
+ _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ }
+ switch (drag) {
+ case DRAG_TOP:
+ case DRAG_TOP_LEFT:
+ case DRAG_TOP_RIGHT:
+ _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT);
+ case DRAG_ALL:
+ Point2 start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]);
+ Point2 end = start - Vector2(0, control->get_margin(MARGIN_TOP));
+ _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ }
+ switch (drag) {
+ case DRAG_BOTTOM:
+ case DRAG_BOTTOM_LEFT:
+ case DRAG_BOTTOM_RIGHT:
+ _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT);
+ case DRAG_ALL:
+ Point2 start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]);
+ Point2 end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM));
+ _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ }
+
+ switch (drag) {
+ //Draw the ghost rect if the node if rotated/scaled
+ case DRAG_LEFT:
+ case DRAG_TOP_LEFT:
+ case DRAG_TOP:
+ case DRAG_TOP_RIGHT:
+ case DRAG_RIGHT:
+ case DRAG_BOTTOM_RIGHT:
+ case DRAG_BOTTOM:
+ case DRAG_BOTTOM_LEFT:
+ case DRAG_ALL:
+ if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) {
+ Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size());
+ viewport->draw_rect(parent_transform.xform(rect), color_base, false);
+ }
+ break;
+ }
}
}
@@ -2136,33 +2466,32 @@ void CanvasItemEditor::_viewport_draw() {
}
}
}
-
- //DRAW_EMPTY_RECT( Rect2( current_window->get_scroll()-Point2(1,1), get_size()+Size2(2,2)), Color(0.8,0.8,1.0,0.8) );
- //E->get().last_rect = rect;
}
-
pivot_button->set_disabled(!pivot_found);
- VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
-
- Color x_axis_color(1.0, 0.4, 0.4, 0.6);
- Color y_axis_color(0.4, 1.0, 0.4, 0.6);
- Color area_axis_color(0.4, 0.4, 1.0, 0.4);
- Color rotate_color(0.4, 0.7, 1.0, 0.8);
-
- VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(h_scroll->get_min(), 0) + transform.get_origin(), Point2(h_scroll->get_max(), 0) + transform.get_origin(), x_axis_color);
- VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(0, v_scroll->get_min()) + transform.get_origin(), Point2(0, v_scroll->get_max()) + transform.get_origin(), y_axis_color);
if (box_selecting) {
-
Point2 bsfrom = transform.xform(drag_from);
Point2 bsto = transform.xform(box_selecting_to);
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(bsfrom, bsto - bsfrom), Color(0.7, 0.7, 1.0, 0.3));
}
+ Color rotate_color(0.4, 0.7, 1.0, 0.8);
if (drag == DRAG_ROTATE) {
VisualServer::get_singleton()->canvas_item_add_line(ci, transform.xform(display_rotate_from), transform.xform(display_rotate_to), rotate_color);
}
+}
+
+void CanvasItemEditor::_draw_axis() {
+ RID ci = viewport->get_canvas_item();
+
+ Color x_axis_color(1.0, 0.4, 0.4, 0.6);
+ Color y_axis_color(0.4, 1.0, 0.4, 0.6);
+ Color area_axis_color(0.4, 0.4, 1.0, 0.4);
+
+ Point2 origin = transform.get_origin();
+ VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(0, origin.y), Point2(viewport->get_size().x, origin.y), x_axis_color);
+ VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(origin.x, 0), Point2(origin.x, viewport->get_size().y), y_axis_color);
Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
@@ -2174,34 +2503,12 @@ void CanvasItemEditor::_viewport_draw() {
};
for (int i = 0; i < 4; i++) {
-
VisualServer::get_singleton()->canvas_item_add_line(ci, screen_endpoints[i], screen_endpoints[(i + 1) % 4], area_axis_color);
}
+}
- for (List<LockList>::Element *E = lock_list.front(); E; E = E->next()) {
-
- Vector2 ofs = transform.xform(E->get().pos);
- if (E->get().lock) {
-
- lock->draw(ci, ofs);
- ofs.x += lock->get_width();
- }
- if (E->get().group) {
-
- group->draw(ci, ofs);
- }
- }
-
- {
-
- EditorNode *en = editor;
- EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
-
- if (!over_plugin_list->empty()) {
-
- over_plugin_list->forward_draw_over_canvas(transform, viewport);
- }
- }
+void CanvasItemEditor::_draw_bones() {
+ RID ci = viewport->get_canvas_item();
if (skeleton_show_bones) {
int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width");
@@ -2269,6 +2576,125 @@ void CanvasItemEditor::_viewport_draw() {
}
}
+void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_xform) {
+ RID viewport_ci = viewport->get_canvas_item();
+
+ Transform2D transform_ci = p_xform;
+ CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
+ if (ci)
+ transform_ci = transform_ci * ci->get_transform();
+
+ for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
+ _draw_locks_and_groups(p_node->get_child(i), transform_ci);
+ }
+
+ if (ci) {
+ Ref<Texture> lock = get_icon("Lock", "EditorIcons");
+ if (p_node->has_meta("_edit_lock_")) {
+ lock->draw(viewport_ci, transform_ci.xform(Point2(0, 0)));
+ }
+
+ Ref<Texture> group = get_icon("Group", "EditorIcons");
+ if (ci->has_meta("_edit_group_")) {
+ Vector2 ofs = transform_ci.xform(Point2(0, 0));
+ if (ci->has_meta("_edit_lock_"))
+ ofs = Point2(ofs.x + lock->get_size().x, ofs.y);
+ group->draw(viewport_ci, ofs);
+ }
+ }
+}
+
+void CanvasItemEditor::_build_bones_list(Node *p_node) {
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _build_bones_list(p_node->get_child(i));
+ }
+
+ CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
+ if (c && c->is_visible_in_tree()) {
+ if (c->has_meta("_edit_bone_")) {
+
+ ObjectID id = c->get_instance_id();
+ if (!bone_list.has(id)) {
+ BoneList bone;
+ bone.bone = id;
+ bone_list[id] = bone;
+ }
+
+ bone_list[id].last_pass = bone_last_frame;
+ }
+ }
+}
+
+void CanvasItemEditor::_get_encompassing_rect(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform) {
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _get_encompassing_rect(p_node->get_child(i), r_rect, p_xform);
+ }
+
+ CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
+ if (c && c->is_visible_in_tree()) {
+ Rect2 rect = c->get_item_rect();
+ Transform2D xform = p_xform * c->get_transform();
+ r_rect.expand_to(xform.xform(rect.position));
+ r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
+ r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
+ r_rect.expand_to(xform.xform(rect.position + rect.size));
+ }
+}
+
+void CanvasItemEditor::_draw_viewport_base() {
+ if (show_rulers)
+ _draw_rulers();
+ _draw_focus();
+}
+
+void CanvasItemEditor::_draw_viewport() {
+
+ // hide/show buttons depending on the selection
+ bool all_locked = true;
+ bool all_group = true;
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+ if (selection.empty()) {
+ all_locked = false;
+ all_group = false;
+ } else {
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ if (Object::cast_to<Control>(E->get()) && !Object::cast_to<Control>(E->get())->has_meta("_edit_lock_")) {
+ all_locked = false;
+ break;
+ }
+ }
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ if (Object::cast_to<Control>(E->get()) && !Object::cast_to<Control>(E->get())->has_meta("_edit_group_")) {
+ all_group = false;
+ break;
+ }
+ }
+ }
+
+ lock_button->set_visible(!all_locked);
+ lock_button->set_disabled(selection.empty());
+ unlock_button->set_visible(all_locked);
+ group_button->set_visible(!all_group);
+ group_button->set_disabled(selection.empty());
+ ungroup_button->set_visible(all_group);
+
+ _update_scrollbars();
+
+ _draw_grid();
+ _draw_selection();
+ _draw_axis();
+ _draw_locks_and_groups(editor->get_edited_scene(), transform);
+
+ RID ci = viewport->get_canvas_item();
+ VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D());
+
+ EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
+ if (!over_plugin_list->empty()) {
+ over_plugin_list->forward_draw_over_canvas(transform, viewport);
+ }
+ _draw_focus();
+}
+
void CanvasItemEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_FIXED_PROCESS) {
@@ -2301,19 +2727,25 @@ void CanvasItemEditor::_notification(int p_what) {
Rect2 r = canvas_item->get_item_rect();
Transform2D xform = canvas_item->get_transform();
- float anchors[4];
- Vector2 pivot;
+ if (r != se->prev_rect || xform != se->prev_xform) {
+ viewport->update();
+ se->prev_rect = r;
+ se->prev_xform = xform;
+ }
+
if (Object::cast_to<Control>(canvas_item)) {
+ float anchors[4];
+ Vector2 pivot;
+
pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset();
anchors[MARGIN_LEFT] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_LEFT);
anchors[MARGIN_RIGHT] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_RIGHT);
anchors[MARGIN_TOP] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_TOP);
anchors[MARGIN_BOTTOM] = Object::cast_to<Control>(canvas_item)->get_anchor(MARGIN_BOTTOM);
- if (r != se->prev_rect || xform != se->prev_xform || pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) {
+ if (pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) {
viewport->update();
- se->prev_rect = r;
- se->prev_xform = xform;
+ viewport_base->update();
se->prev_pivot = pivot;
se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT];
se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT];
@@ -2362,6 +2794,9 @@ void CanvasItemEditor::_notification(int p_what) {
list_select_button->set_icon(get_icon("ListSelect", "EditorIcons"));
move_button->set_icon(get_icon("ToolMove", "EditorIcons"));
rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons"));
+ snap_button->set_icon(get_icon("Snap", "EditorIcons"));
+ snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
+ skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
select_handle = get_icon("EditorHandle", "EditorIcons");
@@ -2372,6 +2807,10 @@ void CanvasItemEditor::_notification(int p_what) {
ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons"));
key_insert_button->set_icon(get_icon("Key", "EditorIcons"));
+ zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons"));
+ zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
+ zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons"));
+
anchor_menu->set_icon(get_icon("Anchor", "EditorIcons"));
PopupMenu *p = anchor_menu->get_popup();
@@ -2406,6 +2845,9 @@ void CanvasItemEditor::_notification(int p_what) {
list_select_button->set_icon(get_icon("ListSelect", "EditorIcons"));
move_button->set_icon(get_icon("ToolMove", "EditorIcons"));
rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons"));
+ snap_button->set_icon(get_icon("Snap", "EditorIcons"));
+ snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
+ skeleton_menu->set_icon(get_icon("Bone", "EditorIcons"));
pan_button->set_icon(get_icon("ToolPan", "EditorIcons"));
pivot_button->set_icon(get_icon("EditPivot", "EditorIcons"));
select_handle = get_icon("EditorHandle", "EditorIcons");
@@ -2447,66 +2889,23 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
drag = DRAG_NONE;
+ // Clear the selection
editor_selection->clear(); //_clear_canvas_items();
editor_selection->add_node(p_canvas_item);
//_add_canvas_item(p_canvas_item);
viewport->update();
-}
-
-void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform) {
-
- if (!p_node)
- return;
-
- CanvasItem *c = Object::cast_to<CanvasItem>(p_node);
-
- for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
-
- //CanvasItem *r=NULL;
-
- if (c && !c->is_set_as_toplevel())
- _find_canvas_items_span(p_node->get_child(i), r_rect, p_xform * c->get_transform());
- else
- _find_canvas_items_span(p_node->get_child(i), r_rect, Transform2D());
- }
-
- if (c && c->is_visible_in_tree()) {
-
- Rect2 rect = c->get_item_rect();
- Transform2D xform = p_xform * c->get_transform();
-
- LockList lock;
- lock.lock = c->has_meta("_edit_lock_");
- lock.group = c->has_meta("_edit_group_");
-
- if (lock.group || lock.lock) {
- lock.pos = xform.xform(rect.position);
- lock_list.push_back(lock);
- }
-
- if (c->has_meta("_edit_bone_")) {
-
- ObjectID id = c->get_instance_id();
- if (!bone_list.has(id)) {
- BoneList bone;
- bone.bone = id;
- bone_list[id] = bone;
- }
-
- bone_list[id].last_pass = bone_last_frame;
- }
-
- r_rect.expand_to(xform.xform(rect.position));
- r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
- r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
- r_rect.expand_to(xform.xform(rect.position + rect.size));
- }
+ viewport_base->update();
}
void CanvasItemEditor::_update_scrollbars() {
updating_scroll = true;
+ if (show_rulers)
+ viewport_scrollable->set_begin(Point2(RULER_WIDTH, RULER_WIDTH));
+ else
+ viewport_scrollable->set_begin(Point2());
+
Size2 size = viewport->get_size();
Size2 hmin = h_scroll->get_minimum_size();
Size2 vmin = v_scroll->get_minimum_size();
@@ -2523,11 +2922,12 @@ void CanvasItemEditor::_update_scrollbars() {
Rect2 canvas_item_rect = Rect2(Point2(), screen_rect);
- lock_list.clear();
bone_last_frame++;
- if (editor->get_edited_scene())
- _find_canvas_items_span(editor->get_edited_scene(), canvas_item_rect, Transform2D());
+ if (editor->get_edited_scene()) {
+ _build_bones_list(editor->get_edited_scene());
+ _get_encompassing_rect(editor->get_edited_scene(), canvas_item_rect, Transform2D());
+ }
List<Map<ObjectID, BoneList>::Element *> bone_to_erase;
@@ -2550,7 +2950,6 @@ void CanvasItemEditor::_update_scrollbars() {
Point2 ofs;
if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) {
-
v_scroll->hide();
ofs.y = canvas_item_rect.position.y;
} else {
@@ -2611,6 +3010,7 @@ void CanvasItemEditor::_update_scroll(float) {
editor->get_scene_root()->set_global_canvas_transform(transform);
viewport->update();
+ viewport_base->update();
}
void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
@@ -2657,88 +3057,117 @@ void CanvasItemEditor::_set_full_rect() {
undo_redo->commit_action();
}
+void CanvasItemEditor::_zoom_minus() {
+ if (zoom < MIN_ZOOM)
+ return;
+ zoom /= 2.0;
+
+ _update_scroll(0);
+ viewport->update();
+ viewport_base->update();
+}
+
+void CanvasItemEditor::_zoom_reset() {
+ zoom = 1;
+ _update_scroll(0);
+ viewport->update();
+ viewport_base->update();
+}
+
+void CanvasItemEditor::_zoom_plus() {
+ if (zoom > MAX_ZOOM)
+ return;
+
+ zoom *= 2.0;
+ _update_scroll(0);
+ viewport->update();
+ viewport_base->update();
+}
+
+void CanvasItemEditor::_toggle_snap(bool p_status) {
+ snap_active = p_status;
+ viewport->update();
+ viewport_base->update();
+}
+
void CanvasItemEditor::_popup_callback(int p_op) {
last_option = MenuOption(p_op);
switch (p_op) {
- case SNAP_USE: {
- snap_grid = !snap_grid;
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE);
- edit_menu->get_popup()->set_item_checked(idx, snap_grid);
+ case SHOW_GRID: {
+ show_grid = !show_grid;
+ int idx = view_menu->get_popup()->get_item_index(SHOW_GRID);
+ view_menu->get_popup()->set_item_checked(idx, show_grid);
viewport->update();
+ viewport_base->update();
} break;
- case SNAP_SHOW_GRID: {
- snap_show_grid = !snap_show_grid;
- int idx = edit_menu->get_popup()->get_item_index(SNAP_SHOW_GRID);
- edit_menu->get_popup()->set_item_checked(idx, snap_show_grid);
- viewport->update();
+ case SNAP_USE_NODE_PARENT: {
+ snap_node_parent = !snap_node_parent;
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_parent);
+ } break;
+ case SNAP_USE_NODE_ANCHORS: {
+ snap_node_anchors = !snap_node_anchors;
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_ANCHORS);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_anchors);
+ } break;
+ case SNAP_USE_NODE_SIDES: {
+ snap_node_sides = !snap_node_sides;
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_SIDES);
+ smartsnap_config_popup->set_item_checked(idx, snap_node_sides);
+ } break;
+ case SNAP_USE_OTHER_NODES: {
+ snap_other_nodes = !snap_other_nodes;
+ int idx = smartsnap_config_popup->get_item_index(SNAP_USE_OTHER_NODES);
+ smartsnap_config_popup->set_item_checked(idx, snap_other_nodes);
+ } break;
+ case SNAP_USE_GRID: {
+ snap_grid = !snap_grid;
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_GRID);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_grid);
} break;
case SNAP_USE_ROTATION: {
snap_rotation = !snap_rotation;
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
- edit_menu->get_popup()->set_item_checked(idx, snap_rotation);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
} break;
case SNAP_RELATIVE: {
snap_relative = !snap_relative;
- int idx = edit_menu->get_popup()->get_item_index(SNAP_RELATIVE);
- edit_menu->get_popup()->set_item_checked(idx, snap_relative);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_relative);
viewport->update();
+ viewport_base->update();
} break;
case SNAP_USE_PIXEL: {
snap_pixel = !snap_pixel;
- int idx = edit_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
- edit_menu->get_popup()->set_item_checked(idx, snap_pixel);
+ int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_PIXEL);
+ snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
} break;
case SNAP_CONFIGURE: {
- ((SnapDialog *)snap_dialog)->set_fields(snap_offset, snap_step, snap_rotation_offset, snap_rotation_step);
+ ((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, snap_rotation_offset, snap_rotation_step);
snap_dialog->popup_centered(Size2(220, 160));
} break;
case SKELETON_SHOW_BONES: {
skeleton_show_bones = !skeleton_show_bones;
- int idx = skeleton_menu->get_item_index(SKELETON_SHOW_BONES);
- skeleton_menu->set_item_checked(idx, skeleton_show_bones);
+ int idx = skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES);
+ skeleton_menu->get_popup()->set_item_checked(idx, skeleton_show_bones);
viewport->update();
} break;
- case ZOOM_IN: {
- if (zoom > MAX_ZOOM)
- return;
- zoom = zoom * (1.0 / 0.5);
- _update_scroll(0);
+ case SHOW_HELPERS: {
+ show_helpers = !show_helpers;
+ int idx = view_menu->get_popup()->get_item_index(SHOW_HELPERS);
+ view_menu->get_popup()->set_item_checked(idx, show_helpers);
viewport->update();
- return;
} break;
- case ZOOM_OUT: {
- if (zoom < MIN_ZOOM)
- return;
-
- zoom = zoom * 0.5;
- _update_scroll(0);
+ case SHOW_RULERS: {
+ show_rulers = !show_rulers;
+ int idx = view_menu->get_popup()->get_item_index(SHOW_RULERS);
+ view_menu->get_popup()->set_item_checked(idx, show_rulers);
viewport->update();
- return;
-
+ viewport_base->update();
} break;
- case ZOOM_RESET: {
-
- zoom = 1;
- _update_scroll(0);
- viewport->update();
- return;
- } break;
- case ZOOM_SET: {
-
- updating_value_dialog = true;
-
- dialog_label->set_text(TTR("Zoom (%):"));
- dialog_val->set_min(0.1);
- dialog_val->set_step(0.1);
- dialog_val->set_max(800);
- dialog_val->set_value(zoom * 100);
- value_dialog->popup_centered(Size2(200, 85));
- updating_value_dialog = false;
-
- } break;
case LOCK_SELECTED: {
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -3085,7 +3514,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
n2d->set_meta("_edit_bone_", true);
if (!skeleton_show_bones)
- skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES));
+ skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
}
viewport->update();
@@ -3104,7 +3533,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
n2d->set_meta("_edit_bone_", Variant());
if (!skeleton_show_bones)
- skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES));
+ skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
}
viewport->update();
@@ -3124,7 +3553,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
canvas_item->set_meta("_edit_ik_", true);
if (!skeleton_show_bones)
- skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES));
+ skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
}
viewport->update();
@@ -3144,7 +3573,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
n2d->set_meta("_edit_ik_", Variant());
if (!skeleton_show_bones)
- skeleton_menu->activate_item(skeleton_menu->get_item_index(SKELETON_SHOW_BONES));
+ skeleton_menu->get_popup()->activate_item(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES));
}
viewport->update();
@@ -3207,15 +3636,19 @@ void CanvasItemEditor::_focus_selection(int p_op) {
void CanvasItemEditor::_bind_methods() {
+ ClassDB::bind_method("_zoom_minus", &CanvasItemEditor::_zoom_minus);
+ ClassDB::bind_method("_zoom_reset", &CanvasItemEditor::_zoom_reset);
+ ClassDB::bind_method("_zoom_plus", &CanvasItemEditor::_zoom_plus);
+ ClassDB::bind_method("_toggle_snap", &CanvasItemEditor::_toggle_snap);
ClassDB::bind_method("_update_scroll", &CanvasItemEditor::_update_scroll);
ClassDB::bind_method("_popup_callback", &CanvasItemEditor::_popup_callback);
- ClassDB::bind_method("_dialog_value_changed", &CanvasItemEditor::_dialog_value_changed);
ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
ClassDB::bind_method("_tool_select", &CanvasItemEditor::_tool_select);
ClassDB::bind_method("_keying_changed", &CanvasItemEditor::_keying_changed);
ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
- ClassDB::bind_method("_viewport_draw", &CanvasItemEditor::_viewport_draw);
- ClassDB::bind_method("_viewport_gui_input", &CanvasItemEditor::_viewport_gui_input);
+ ClassDB::bind_method("_draw_viewport", &CanvasItemEditor::_draw_viewport);
+ ClassDB::bind_method("_draw_viewport_base", &CanvasItemEditor::_draw_viewport_base);
+ ClassDB::bind_method("_viewport_base_gui_input", &CanvasItemEditor::_viewport_base_gui_input);
ClassDB::bind_method("_snap_changed", &CanvasItemEditor::_snap_changed);
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
@@ -3257,64 +3690,92 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->set_area_as_parent_rect();
bottom_split = memnew(VSplitContainer);
- bottom_split->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(bottom_split);
+ bottom_split->set_v_size_flags(SIZE_EXPAND_FILL);
palette_split = memnew(HSplitContainer);
- palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
bottom_split->add_child(palette_split);
+ palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
- Control *vp_base = memnew(Control);
- vp_base->set_v_size_flags(SIZE_EXPAND_FILL);
- palette_split->add_child(vp_base);
-
- ViewportContainer *vp = memnew(ViewportContainer);
- vp->set_stretch(true);
- vp_base->add_child(vp);
- vp->set_area_as_parent_rect();
- vp->add_child(p_editor->get_scene_root());
+ viewport_base = memnew(Control);
+ palette_split->add_child(viewport_base);
+ viewport_base->connect("draw", this, "_draw_viewport_base");
+ viewport_base->connect("gui_input", this, "_viewport_base_gui_input");
+ viewport_base->set_focus_mode(FOCUS_ALL);
+ viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
+ viewport_base->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ viewport_scrollable = memnew(Control);
+ viewport_base->add_child(viewport_scrollable);
+ viewport_scrollable->set_mouse_filter(MOUSE_FILTER_PASS);
+ viewport_scrollable->set_draw_behind_parent(true);
+ viewport_scrollable->set_area_as_parent_rect();
+ viewport_scrollable->set_begin(Point2(RULER_WIDTH, RULER_WIDTH));
+
+ ViewportContainer *scene_tree = memnew(ViewportContainer);
+ viewport_scrollable->add_child(scene_tree);
+ scene_tree->set_stretch(true);
+ scene_tree->set_area_as_parent_rect();
+ scene_tree->add_child(p_editor->get_scene_root());
viewport = memnew(CanvasItemEditorViewport(p_editor, this));
- vp_base->add_child(viewport);
+ viewport_scrollable->add_child(viewport);
+ viewport->set_mouse_filter(MOUSE_FILTER_PASS);
viewport->set_area_as_parent_rect();
viewport->set_clip_contents(true);
+ viewport->connect("draw", this, "_draw_viewport");
h_scroll = memnew(HScrollBar);
- v_scroll = memnew(VScrollBar);
-
viewport->add_child(h_scroll);
- viewport->add_child(v_scroll);
- viewport->connect("draw", this, "_viewport_draw");
- viewport->connect("gui_input", this, "_viewport_gui_input");
-
h_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED);
- v_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED);
-
h_scroll->hide();
+
+ v_scroll = memnew(VScrollBar);
+ viewport->add_child(v_scroll);
+ v_scroll->connect("value_changed", this, "_update_scroll", Vector<Variant>(), Object::CONNECT_DEFERRED);
v_scroll->hide();
+
+ HBoxContainer *zoom_hb = memnew(HBoxContainer);
+ viewport->add_child(zoom_hb);
+ zoom_hb->set_begin(Point2(5, 5));
+
+ zoom_minus = memnew(ToolButton);
+ zoom_hb->add_child(zoom_minus);
+ zoom_minus->connect("pressed", this, "_zoom_minus");
+ zoom_minus->set_focus_mode(FOCUS_NONE);
+
+ zoom_reset = memnew(ToolButton);
+ zoom_hb->add_child(zoom_reset);
+ zoom_reset->connect("pressed", this, "_zoom_reset");
+ zoom_reset->set_focus_mode(FOCUS_NONE);
+
+ zoom_plus = memnew(ToolButton);
+ zoom_hb->add_child(zoom_plus);
+ zoom_plus->connect("pressed", this, "_zoom_plus");
+ zoom_plus->set_focus_mode(FOCUS_NONE);
+
updating_scroll = false;
- viewport->set_focus_mode(FOCUS_ALL);
handle_len = 10;
first_update = true;
select_button = memnew(ToolButton);
- select_button->set_toggle_mode(true);
hb->add_child(select_button);
+ select_button->set_toggle_mode(true);
select_button->connect("pressed", this, "_tool_select", make_binds(TOOL_SELECT));
select_button->set_pressed(true);
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q));
select_button->set_tooltip(TTR("Select Mode") + " $sc\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection"));
move_button = memnew(ToolButton);
- move_button->set_toggle_mode(true);
hb->add_child(move_button);
+ move_button->set_toggle_mode(true);
move_button->connect("pressed", this, "_tool_select", make_binds(TOOL_MOVE));
move_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/move_mode", TTR("Move Mode"), KEY_W));
move_button->set_tooltip(TTR("Move Mode"));
rotate_button = memnew(ToolButton);
- rotate_button->set_toggle_mode(true);
hb->add_child(rotate_button);
+ rotate_button->set_toggle_mode(true);
rotate_button->connect("pressed", this, "_tool_select", make_binds(TOOL_ROTATE));
rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E));
rotate_button->set_tooltip(TTR("Rotate Mode"));
@@ -3322,25 +3783,60 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(memnew(VSeparator));
list_select_button = memnew(ToolButton);
- list_select_button->set_toggle_mode(true);
hb->add_child(list_select_button);
+ list_select_button->set_toggle_mode(true);
list_select_button->connect("pressed", this, "_tool_select", make_binds(TOOL_LIST_SELECT));
list_select_button->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode)."));
pivot_button = memnew(ToolButton);
- pivot_button->set_toggle_mode(true);
hb->add_child(pivot_button);
+ pivot_button->set_toggle_mode(true);
pivot_button->connect("pressed", this, "_tool_select", make_binds(TOOL_EDIT_PIVOT));
pivot_button->set_tooltip(TTR("Click to change object's rotation pivot."));
pan_button = memnew(ToolButton);
- pan_button->set_toggle_mode(true);
hb->add_child(pan_button);
+ pan_button->set_toggle_mode(true);
pan_button->connect("pressed", this, "_tool_select", make_binds(TOOL_PAN));
pan_button->set_tooltip(TTR("Pan Mode"));
hb->add_child(memnew(VSeparator));
+ snap_button = memnew(ToolButton);
+ hb->add_child(snap_button);
+ snap_button->set_toggle_mode(true);
+ snap_button->connect("toggled", this, "_toggle_snap");
+ snap_button->set_tooltip(TTR("Toggles snapping"));
+ snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_S));
+
+ snap_config_menu = memnew(MenuButton);
+ hb->add_child(snap_config_menu);
+ snap_config_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
+ snap_config_menu->set_h_size_flags(SIZE_SHRINK_END);
+ snap_config_menu->set_tooltip(TTR("Snapping options"));
+
+ PopupMenu *p = snap_config_menu->get_popup();
+ p->connect("id_pressed", this, "_popup_callback");
+ p->set_hide_on_checkable_item_selection(false);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to grid")), SNAP_USE_GRID);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
+ p->add_submenu_item(TTR("Smart snapping"), "SmartSnapping");
+
+ smartsnap_config_popup = memnew(PopupMenu);
+ p->add_child(smartsnap_config_popup);
+ smartsnap_config_popup->set_name("SmartSnapping");
+ smartsnap_config_popup->connect("id_pressed", this, "_popup_callback");
+ smartsnap_config_popup->set_hide_on_checkable_item_selection(false);
+ smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_parent", TTR("Snap to parent")), SNAP_USE_NODE_PARENT);
+ smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_anchors", TTR("Snap to node anchor")), SNAP_USE_NODE_ANCHORS);
+ smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_node_sides", TTR("Snap to node sides")), SNAP_USE_NODE_SIDES);
+ smartsnap_config_popup->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_other_nodes", TTR("Snap to other nodes")), SNAP_USE_OTHER_NODES);
+
+ hb->add_child(memnew(VSeparator));
+
lock_button = memnew(ToolButton);
hb->add_child(lock_button);
@@ -3364,35 +3860,23 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
hb->add_child(memnew(VSeparator));
- edit_menu = memnew(MenuButton);
- edit_menu->set_text(TTR("Edit"));
- hb->add_child(edit_menu);
- edit_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
+ skeleton_menu = memnew(MenuButton);
+ hb->add_child(skeleton_menu);
- PopupMenu *p;
- p = edit_menu->get_popup();
+ p = skeleton_menu->get_popup();
p->set_hide_on_checkable_item_selection(false);
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap")), SNAP_USE);
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid")), SNAP_SHOW_GRID);
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap..")), SNAP_CONFIGURE);
+ p->connect("id_pressed", this, "_popup_callback");
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES);
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES);
p->add_separator();
- p->add_submenu_item(TTR("Skeleton.."), "skeleton");
- skeleton_menu = memnew(PopupMenu);
- p->add_child(skeleton_menu);
- skeleton_menu->set_name("skeleton");
- skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES);
- skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES);
- skeleton_menu->add_separator();
- skeleton_menu->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES);
- skeleton_menu->add_separator();
- skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN);
- skeleton_menu->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN);
- skeleton_menu->set_hide_on_checkable_item_selection(false);
- skeleton_menu->connect("id_pressed", this, "_popup_callback");
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN);
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN);
+ p->set_hide_on_checkable_item_selection(false);
+ p->connect("id_pressed", this, "_popup_callback");
+
+ hb->add_child(memnew(VSeparator));
view_menu = memnew(MenuButton);
view_menu->set_text(TTR("View"));
@@ -3400,11 +3884,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
view_menu->get_popup()->connect("id_pressed", this, "_popup_callback");
p = view_menu->get_popup();
-
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_in", TTR("Zoom In")), ZOOM_IN);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_out", TTR("Zoom Out")), ZOOM_OUT);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset")), ZOOM_RESET);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_set", TTR("Zoom Set..")), ZOOM_SET);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_grid", TTR("Show Grid"), KEY_G), SHOW_GRID);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_helpers", TTR("Show helpers"), KEY_H), SHOW_HELPERS);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_rulers", TTR("Show rulers"), KEY_R), SHOW_RULERS);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION);
@@ -3475,23 +3957,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
snap_dialog->connect("confirmed", this, "_snap_changed");
add_child(snap_dialog);
- value_dialog = memnew(AcceptDialog);
- value_dialog->set_title(TTR("Set a Value"));
- value_dialog->get_ok()->set_text(TTR("Close"));
- add_child(value_dialog);
-
- Label *l = memnew(Label);
- l->set_text(TTR("Snap (Pixels):"));
- l->set_position(Point2(5, 5));
- value_dialog->add_child(l);
- dialog_label = l;
-
- dialog_val = memnew(SpinBox);
- dialog_val->set_anchor(MARGIN_RIGHT, ANCHOR_END);
- dialog_val->set_begin(Point2(15, 25));
- dialog_val->set_end(Point2(-10, 25));
- value_dialog->add_child(dialog_val);
- dialog_val->connect("value_changed", this, "_dialog_value_changed");
select_sb = Ref<StyleBoxTexture>(memnew(StyleBoxTexture));
selection_menu = memnew(PopupMenu);
@@ -3500,22 +3965,35 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
selection_menu->connect("id_pressed", this, "_selection_result_pressed");
selection_menu->connect("popup_hide", this, "_selection_menu_hide");
+ drag_pivot_shortcut = ED_SHORTCUT("canvas_item_editor/drag_pivot", TTR("Drag pivot from mouse position"), KEY_MASK_SHIFT | KEY_V);
+ set_pivot_shortcut = ED_SHORTCUT("canvas_item_editor/set_pivot", TTR("Set pivot at mouse position"), KEY_V);
+
+ multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);
+ divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);
+
key_pos = true;
key_rot = true;
key_scale = false;
+ show_grid = false;
+ show_helpers = false;
+ show_rulers = false;
zoom = 1;
- snap_offset = Vector2(0, 0);
- snap_step = Vector2(10, 10);
+ grid_offset = Point2();
+ grid_step = Point2(10, 10);
+ grid_step_multiplier = 0;
snap_rotation_offset = 0;
snap_rotation_step = 15 / (180 / Math_PI);
- snap_grid = false;
- snap_show_grid = false;
+ snap_active = false;
+ snap_node_parent = true;
+ snap_node_anchors = true;
+ snap_node_sides = true;
+ snap_other_nodes = true;
+ snap_grid = true;
snap_rotation = false;
snap_pixel = false;
skeleton_show_bones = true;
- skeleton_menu->set_item_checked(skeleton_menu->get_item_index(SKELETON_SHOW_BONES), true);
- updating_value_dialog = false;
+ skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);
box_selecting = false;
//zoom=0.5;
singleton = this;
@@ -3546,7 +4024,7 @@ void CanvasItemEditorPlugin::make_visible(bool p_visible) {
canvas_item_editor->show();
canvas_item_editor->set_fixed_process(true);
VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(), false);
- canvas_item_editor->viewport->grab_focus();
+ canvas_item_editor->viewport_base->grab_focus();
} else {
@@ -3715,7 +4193,7 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
target_pos -= texture_size / 2;
}
// there's nothing to be used as source position so snapping will work as absolute if enabled
- target_pos = canvas->snap_point(target_pos, Vector2());
+ target_pos = canvas->snap_point(target_pos);
editor_data->get_undo_redo().add_do_method(child, "set_position", target_pos);
}
@@ -3749,22 +4227,13 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name);
editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name));
- Point2 pos;
- Node2D *parent_node2d = Object::cast_to<Node2D>(parent);
- if (parent_node2d) {
- pos = parent_node2d->get_global_position();
- } else {
- Control *parent_control = Object::cast_to<Control>(parent);
- if (parent_control) {
- pos = parent_control->get_global_position();
- }
+ CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
+ if (parent_ci) {
+ Vector2 target_pos = canvas->get_canvas_transform().affine_inverse().xform(p_point);
+ target_pos = canvas->snap_point(target_pos);
+ target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
+ editor_data->get_undo_redo().add_do_method(instanced_scene, "set_position", target_pos);
}
- Transform2D trans = canvas->get_canvas_transform();
- Vector2 target_pos = (p_point - trans.get_origin()) / trans.get_scale().x - pos;
- // in relative snapping it may be useful for the user to take the original node position into account
- Vector2 start_pos = Object::cast_to<Node2D>(instanced_scene) ? Object::cast_to<Node2D>(instanced_scene)->get_position() : target_pos;
- target_pos = canvas->snap_point(target_pos, start_pos);
- editor_data->get_undo_redo().add_do_method(instanced_scene, "set_position", target_pos);
return true;
}
@@ -3843,6 +4312,20 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
continue;
}
memdelete(instanced_scene);
+ } else if (type == "Texture" ||
+ type == "ImageTexture" ||
+ type == "ViewportTexture" ||
+ type == "CurveTexture" ||
+ type == "GradientTexture" ||
+ type == "StreamTexture" ||
+ type == "AtlasTexture" ||
+ type == "LargeTexture") {
+ Ref<Texture> texture = ResourceLoader::load(files[i]);
+ if (texture.is_valid() == false) {
+ continue;
+ }
+ } else {
+ continue;
}
can_instance = true;
break;
@@ -3951,41 +4434,39 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
editor_data = editor->get_scene_tree_dock()->get_editor_data();
canvas = p_canvas;
preview_node = memnew(Node2D);
+
accept = memnew(AcceptDialog);
editor->get_gui_base()->add_child(accept);
selector = memnew(AcceptDialog);
+ editor->get_gui_base()->add_child(selector);
selector->set_title(TTR("Change default type"));
+ selector->connect("confirmed", this, "_on_change_type");
VBoxContainer *vbc = memnew(VBoxContainer);
+ selector->add_child(vbc);
vbc->set_h_size_flags(SIZE_EXPAND_FILL);
vbc->set_v_size_flags(SIZE_EXPAND_FILL);
vbc->set_custom_minimum_size(Size2(200, 260) * EDSCALE);
selector_label = memnew(Label);
+ vbc->add_child(selector_label);
selector_label->set_align(Label::ALIGN_CENTER);
selector_label->set_valign(Label::VALIGN_BOTTOM);
selector_label->set_custom_minimum_size(Size2(0, 30) * EDSCALE);
- vbc->add_child(selector_label);
-
- button_group.instance();
btn_group = memnew(VBoxContainer);
+ vbc->add_child(btn_group);
btn_group->set_h_size_flags(0);
+ button_group.instance();
for (int i = 0; i < types.size(); i++) {
CheckBox *check = memnew(CheckBox);
+ btn_group->add_child(check);
check->set_text(types[i]);
check->connect("button_down", this, "_on_select_type", varray(check));
- btn_group->add_child(check);
check->set_button_group(button_group);
}
- vbc->add_child(btn_group);
-
- selector->connect("confirmed", this, "_on_change_type");
-
- selector->add_child(vbc);
- editor->get_gui_base()->add_child(selector);
label = memnew(Label);
label->add_color_override("font_color_shadow", Color(0, 0, 0, 1));
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 2e1a2eac5f..af834507e0 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -58,6 +58,8 @@ public:
Vector2 prev_pivot;
float prev_anchors[4];
+ Transform2D pre_drag_xform;
+
CanvasItemEditorSelectedItem() { prev_rot = 0; }
};
@@ -68,7 +70,6 @@ class CanvasItemEditor : public VBoxContainer {
EditorNode *editor;
enum Tool {
-
TOOL_SELECT,
TOOL_LIST_SELECT,
TOOL_MOVE,
@@ -80,15 +81,18 @@ class CanvasItemEditor : public VBoxContainer {
enum MenuOption {
SNAP_USE,
- SNAP_SHOW_GRID,
+ SNAP_USE_NODE_PARENT,
+ SNAP_USE_NODE_ANCHORS,
+ SNAP_USE_NODE_SIDES,
+ SNAP_USE_OTHER_NODES,
+ SNAP_USE_GRID,
SNAP_USE_ROTATION,
SNAP_RELATIVE,
SNAP_CONFIGURE,
SNAP_USE_PIXEL,
- ZOOM_IN,
- ZOOM_OUT,
- ZOOM_RESET,
- ZOOM_SET,
+ SHOW_GRID,
+ SHOW_HELPERS,
+ SHOW_RULERS,
LOCK_SELECTED,
UNLOCK_SELECTED,
GROUP_SELECTED,
@@ -161,6 +165,8 @@ class CanvasItemEditor : public VBoxContainer {
Tool tool;
bool first_update;
Control *viewport;
+ Control *viewport_base;
+ Control *viewport_scrollable;
bool can_move_pivot;
@@ -168,14 +174,28 @@ class CanvasItemEditor : public VBoxContainer {
VScrollBar *v_scroll;
HBoxContainer *hb;
+ ToolButton *zoom_minus;
+ ToolButton *zoom_reset;
+ ToolButton *zoom_plus;
+
Transform2D transform;
+ bool show_grid;
+ bool show_rulers;
+ bool show_helpers;
float zoom;
- Vector2 snap_offset;
- Vector2 snap_step;
+
+ Point2 grid_offset;
+ Point2 grid_step;
+ int grid_step_multiplier;
+
float snap_rotation_step;
float snap_rotation_offset;
+ bool snap_active;
+ bool snap_node_parent;
+ bool snap_node_anchors;
+ bool snap_node_sides;
+ bool snap_other_nodes;
bool snap_grid;
- bool snap_show_grid;
bool snap_rotation;
bool snap_relative;
bool snap_pixel;
@@ -202,18 +222,6 @@ class CanvasItemEditor : public VBoxContainer {
Vector<_SelectResult> selection_results;
- struct LockList {
- Point2 pos;
- bool lock;
- bool group;
- LockList() {
- lock = false;
- group = false;
- }
- };
-
- List<LockList> lock_list;
-
struct BoneList {
Transform2D xform;
@@ -253,6 +261,10 @@ class CanvasItemEditor : public VBoxContainer {
ToolButton *move_button;
ToolButton *rotate_button;
+ ToolButton *snap_button;
+ MenuButton *snap_config_menu;
+ PopupMenu *smartsnap_config_popup;
+
ToolButton *pivot_button;
ToolButton *pan_button;
@@ -262,8 +274,7 @@ class CanvasItemEditor : public VBoxContainer {
ToolButton *group_button;
ToolButton *ungroup_button;
- MenuButton *edit_menu;
- PopupMenu *skeleton_menu;
+ MenuButton *skeleton_menu;
MenuButton *view_menu;
HBoxContainer *animation_hb;
MenuButton *animation_menu;
@@ -276,6 +287,9 @@ class CanvasItemEditor : public VBoxContainer {
PopupMenu *selection_menu;
+ Control *top_ruler;
+ Control *left_ruler;
+
//PopupMenu *popup;
DragType drag;
Point2 drag_from;
@@ -288,6 +302,11 @@ class CanvasItemEditor : public VBoxContainer {
Ref<Texture> select_handle;
Ref<Texture> anchor_handle;
+ Ref<ShortCut> drag_pivot_shortcut;
+ Ref<ShortCut> set_pivot_shortcut;
+ Ref<ShortCut> multiply_grid_step_shortcut;
+ Ref<ShortCut> divide_grid_step_shortcut;
+
int handle_len;
bool _is_part_of_subscene(CanvasItem *p_item);
void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, Vector<_SelectResult> &r_items, int limit = 0);
@@ -298,10 +317,6 @@ class CanvasItemEditor : public VBoxContainer {
ConfirmationDialog *snap_dialog;
- AcceptDialog *value_dialog;
- Label *dialog_label;
- SpinBox *dialog_val;
-
CanvasItem *ref_item;
void _edit_set_pivot(const Vector2 &mouse_pos);
@@ -315,9 +330,8 @@ class CanvasItemEditor : public VBoxContainer {
void _prepare_drag(const Point2 &p_click_pos);
DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point);
- float _anchor_snap(float anchor, bool *snapped = NULL, float p_opposite_anchor = -1);
- Vector2 _anchor_to_position(Control *p_control, Vector2 anchor);
- Vector2 _position_to_anchor(Control *p_control, Vector2 position);
+ Vector2 _anchor_to_position(const Control *p_control, Vector2 anchor);
+ Vector2 _position_to_anchor(const Control *p_control, Vector2 position);
void _popup_callback(int p_op);
bool updating_scroll;
@@ -328,7 +342,6 @@ class CanvasItemEditor : public VBoxContainer {
void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric);
void _append_canvas_item(CanvasItem *p_item);
- void _dialog_value_changed(double);
void _snap_changed();
void _selection_result_pressed(int);
void _selection_menu_hide();
@@ -337,26 +350,49 @@ class CanvasItemEditor : public VBoxContainer {
Point2 _find_topleftmost_point();
- void _find_canvas_items_span(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform);
+ void _build_bones_list(Node *p_node);
+
+ void _get_encompassing_rect(Node *p_node, Rect2 &r_rect, const Transform2D &p_xform);
Object *_get_editor_data(Object *p_what);
- CanvasItem *get_single_item();
+ CanvasItem *_get_single_item();
int get_item_count();
void _keying_changed();
void _unhandled_key_input(const Ref<InputEvent> &p_ev);
+ void _draw_text_at_position(Point2 p_position, String p_string, Margin p_side);
+ void _draw_margin_at_position(int p_value, Point2 p_position, Margin p_side);
void _draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side);
- void _viewport_gui_input(const Ref<InputEvent> &p_event);
- void _viewport_draw();
+ void _draw_rulers();
+ void _draw_focus();
+ void _draw_grid();
+ void _draw_selection();
+ void _draw_axis();
+ void _draw_bones();
+ void _draw_locks_and_groups(Node *p_node, const Transform2D &p_xform);
+
+ void _draw_viewport();
+
+ void _viewport_base_gui_input(const Ref<InputEvent> &p_event);
+ void _draw_viewport_base();
void _focus_selection(int p_op);
+ void _snap_if_closer(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation = 0.0, float p_radius = 10.0);
+ void _snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap);
+
void _set_anchors_preset(Control::LayoutPreset p_preset);
void _set_full_rect();
+ void _zoom_minus();
+ void _zoom_reset();
+ void _zoom_plus();
+
+ void _toggle_snap(bool p_status);
+
HSplitContainer *palette_split;
VSplitContainer *bottom_split;
@@ -400,7 +436,18 @@ protected:
static CanvasItemEditor *singleton;
public:
- Vector2 snap_point(Vector2 p_target, Vector2 p_start = Vector2(0, 0)) const;
+ enum SnapMode {
+ SNAP_GRID = 1 << 0,
+ SNAP_PIXEL = 1 << 1,
+ SNAP_NODE_PARENT = 1 << 2,
+ SNAP_NODE_ANCHORS = 1 << 3,
+ SNAP_NODE_SIDES = 1 << 4,
+ SNAP_OTHER_NODES = 1 << 5,
+
+ SNAP_DEFAULT = 0x03,
+ };
+
+ Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, const CanvasItem *p_canvas_item = NULL, unsigned int p_forced_modes = 0);
float snap_angle(float p_target, float p_start = 0) const;
Transform2D get_canvas_transform() const { return transform; }
diff --git a/editor/plugins/navigation_mesh_editor_plugin.cpp b/editor/plugins/navigation_mesh_editor_plugin.cpp
new file mode 100644
index 0000000000..f0f5a62494
--- /dev/null
+++ b/editor/plugins/navigation_mesh_editor_plugin.cpp
@@ -0,0 +1,165 @@
+/*************************************************************************/
+/* navigation_mesh_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "navigation_mesh_editor_plugin.h"
+#include "io/marshalls.h"
+#include "io/resource_saver.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/gui/box_container.h"
+
+#ifdef RECAST_ENABLED
+
+void NavigationMeshEditor::_node_removed(Node *p_node) {
+
+ if (p_node == node) {
+ node = NULL;
+
+ hide();
+ }
+}
+
+void NavigationMeshEditor::_notification(int p_option) {
+
+ if (p_option == NOTIFICATION_ENTER_TREE) {
+
+ button_bake->set_icon(get_icon("Bake", "EditorIcons"));
+ button_reset->set_icon(get_icon("Reload", "EditorIcons"));
+ }
+}
+
+void NavigationMeshEditor::_bake_pressed() {
+
+ ERR_FAIL_COND(!node);
+ const String conf_warning = node->get_configuration_warning();
+ if (!conf_warning.empty()) {
+ err_dialog->set_text(conf_warning);
+ err_dialog->popup_centered_minsize();
+ button_bake->set_pressed(false);
+ return;
+ }
+
+ NavigationMeshGenerator::clear(node->get_navigation_mesh());
+ NavigationMeshGenerator::bake(node->get_navigation_mesh(), node);
+
+ if (node) {
+ node->update_gizmo();
+ }
+}
+
+void NavigationMeshEditor::_clear_pressed() {
+
+ if (node)
+ NavigationMeshGenerator::clear(node->get_navigation_mesh());
+
+ button_bake->set_pressed(false);
+ bake_info->set_text("");
+
+ if (node) {
+ node->update_gizmo();
+ }
+}
+
+void NavigationMeshEditor::edit(NavigationMeshInstance *p_nav_mesh_instance) {
+
+ if (p_nav_mesh_instance == NULL || node == p_nav_mesh_instance) {
+ return;
+ }
+
+ node = p_nav_mesh_instance;
+}
+
+void NavigationMeshEditor::_bind_methods() {
+
+ ClassDB::bind_method("_bake_pressed", &NavigationMeshEditor::_bake_pressed);
+ ClassDB::bind_method("_clear_pressed", &NavigationMeshEditor::_clear_pressed);
+}
+
+NavigationMeshEditor::NavigationMeshEditor() {
+
+ bake_hbox = memnew(HBoxContainer);
+ button_bake = memnew(ToolButton);
+ button_bake->set_text(TTR("Bake!"));
+ button_bake->set_toggle_mode(true);
+ button_reset = memnew(Button);
+ button_bake->set_tooltip(TTR("Bake the navigation mesh.\n"));
+
+ bake_info = memnew(Label);
+ bake_hbox->add_child(button_bake);
+ bake_hbox->add_child(button_reset);
+ bake_hbox->add_child(bake_info);
+
+ err_dialog = memnew(AcceptDialog);
+ add_child(err_dialog);
+ node = NULL;
+
+ button_bake->connect("pressed", this, "_bake_pressed");
+ button_reset->connect("pressed", this, "_clear_pressed");
+ button_reset->set_tooltip(TTR("Clear the navigation mesh."));
+}
+
+NavigationMeshEditor::~NavigationMeshEditor() {
+}
+
+void NavigationMeshEditorPlugin::edit(Object *p_object) {
+
+ navigation_mesh_editor->edit(Object::cast_to<NavigationMeshInstance>(p_object));
+}
+
+bool NavigationMeshEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("NavigationMeshInstance");
+}
+
+void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
+
+ if (p_visible) {
+ navigation_mesh_editor->show();
+ navigation_mesh_editor->bake_hbox->show();
+ } else {
+
+ navigation_mesh_editor->hide();
+ navigation_mesh_editor->bake_hbox->hide();
+ navigation_mesh_editor->edit(NULL);
+ }
+}
+
+NavigationMeshEditorPlugin::NavigationMeshEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ navigation_mesh_editor = memnew(NavigationMeshEditor);
+ editor->get_viewport()->add_child(navigation_mesh_editor);
+ add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, navigation_mesh_editor->bake_hbox);
+ navigation_mesh_editor->hide();
+ navigation_mesh_editor->bake_hbox->hide();
+}
+
+NavigationMeshEditorPlugin::~NavigationMeshEditorPlugin() {
+}
+
+#endif // RECAST_ENABLED
diff --git a/editor/plugins/navigation_mesh_editor_plugin.h b/editor/plugins/navigation_mesh_editor_plugin.h
new file mode 100644
index 0000000000..bac7f608ab
--- /dev/null
+++ b/editor/plugins/navigation_mesh_editor_plugin.h
@@ -0,0 +1,86 @@
+/*************************************************************************/
+/* navigation_mesh_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef NAVIGATION_MESH_GENERATOR_PLUGIN_H
+#define NAVIGATION_MESH_GENERATOR_PLUGIN_H
+
+#ifdef RECAST_ENABLED
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "navigation_mesh_generator.h"
+
+class NavigationMeshEditor : public Control {
+ friend class NavigationMeshEditorPlugin;
+
+ GDCLASS(NavigationMeshEditor, Control);
+
+ AcceptDialog *err_dialog;
+
+ HBoxContainer *bake_hbox;
+ Button *button_bake;
+ Button *button_reset;
+ Label *bake_info;
+
+ NavigationMeshInstance *node;
+
+ void _bake_pressed();
+ void _clear_pressed();
+
+protected:
+ void _node_removed(Node *p_node);
+ static void _bind_methods();
+ void _notification(int p_option);
+
+public:
+ void edit(NavigationMeshInstance *p_nav_mesh_instance);
+ NavigationMeshEditor();
+ ~NavigationMeshEditor();
+};
+
+class NavigationMeshEditorPlugin : public EditorPlugin {
+
+ GDCLASS(NavigationMeshEditorPlugin, EditorPlugin);
+
+ NavigationMeshEditor *navigation_mesh_editor;
+ EditorNode *editor;
+
+public:
+ virtual String get_name() const { return "NavigationMesh"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual void make_visible(bool p_visible);
+
+ NavigationMeshEditorPlugin(EditorNode *p_node);
+ ~NavigationMeshEditorPlugin();
+};
+
+#endif // RECAST_ENABLED
+#endif // NAVIGATION_MESH_GENERATOR_PLUGIN_H
diff --git a/editor/plugins/navigation_mesh_generator.cpp b/editor/plugins/navigation_mesh_generator.cpp
new file mode 100644
index 0000000000..526db3a582
--- /dev/null
+++ b/editor/plugins/navigation_mesh_generator.cpp
@@ -0,0 +1,311 @@
+/*************************************************************************/
+/* navigation_mesh_generator.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "navigation_mesh_generator.h"
+
+#ifdef RECAST_ENABLED
+
+void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
+ p_verticies.push_back(p_vec3.x);
+ p_verticies.push_back(p_vec3.y);
+ p_verticies.push_back(p_vec3.z);
+}
+
+void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+ int current_vertex_count = p_verticies.size() / 3;
+
+ for (int i = 0; i < p_mesh->get_surface_count(); i++) {
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ continue;
+
+ int index_count = 0;
+ if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
+ index_count = p_mesh->surface_get_array_index_len(i);
+ } else {
+ index_count = p_mesh->surface_get_array_len(i);
+ }
+
+ ERR_CONTINUE((index_count == 0 || (index_count % 3) != 0));
+
+ int face_count = index_count / 3;
+
+ Array a = p_mesh->surface_get_arrays(i);
+
+ PoolVector<Vector3> mesh_vertices = a[Mesh::ARRAY_VERTEX];
+ PoolVector<Vector3>::Read vr = mesh_vertices.read();
+
+ if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
+
+ PoolVector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
+ PoolVector<int>::Read ir = mesh_indices.read();
+
+ for (int i = 0; i < mesh_vertices.size(); i++) {
+ _add_vertex(p_xform.xform(vr[i]), p_verticies);
+ }
+
+ for (int i = 0; i < face_count; i++) {
+ // CCW
+ p_indices.push_back(current_vertex_count + (ir[i * 3 + 0]));
+ p_indices.push_back(current_vertex_count + (ir[i * 3 + 2]));
+ p_indices.push_back(current_vertex_count + (ir[i * 3 + 1]));
+ }
+ } else {
+ face_count = mesh_vertices.size() / 3;
+ for (int i = 0; i < face_count; i++) {
+ _add_vertex(p_xform.xform(vr[i * 3 + 0]), p_verticies);
+ _add_vertex(p_xform.xform(vr[i * 3 + 2]), p_verticies);
+ _add_vertex(p_xform.xform(vr[i * 3 + 1]), p_verticies);
+
+ p_indices.push_back(current_vertex_count + (i * 3 + 0));
+ p_indices.push_back(current_vertex_count + (i * 3 + 1));
+ p_indices.push_back(current_vertex_count + (i * 3 + 2));
+ }
+ }
+ }
+}
+
+void NavigationMeshGenerator::_parse_geometry(const Transform &p_base_inverse, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices) {
+
+ if (Object::cast_to<MeshInstance>(p_node)) {
+
+ MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(p_node);
+ Ref<Mesh> mesh = mesh_instance->get_mesh();
+ if (mesh.is_valid()) {
+ _add_mesh(mesh, p_base_inverse * mesh_instance->get_global_transform(), p_verticies, p_indices);
+ }
+ }
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _parse_geometry(p_base_inverse, p_node->get_child(i), p_verticies, p_indices);
+ }
+}
+
+void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
+
+ PoolVector<Vector3> nav_vertices;
+
+ for (int i = 0; i < p_detail_mesh->nverts; i++) {
+ const float *v = &p_detail_mesh->verts[i * 3];
+ nav_vertices.append(Vector3(v[0], v[1], v[2]));
+ }
+ p_nav_mesh->set_vertices(nav_vertices);
+
+ for (int i = 0; i < p_detail_mesh->nmeshes; i++) {
+ const unsigned int *m = &p_detail_mesh->meshes[i * 4];
+ const unsigned int bverts = m[0];
+ const unsigned int btris = m[2];
+ const unsigned int ntris = m[3];
+ const unsigned char *tris = &p_detail_mesh->tris[btris * 4];
+ for (unsigned int j = 0; j < ntris; j++) {
+ Vector<int> nav_indices;
+ nav_indices.resize(3);
+ nav_indices[0] = ((int)(bverts + tris[j * 4 + 0]));
+ nav_indices[1] = ((int)(bverts + tris[j * 4 + 1]));
+ nav_indices[2] = ((int)(bverts + tris[j * 4 + 2]));
+ p_nav_mesh->add_polygon(nav_indices);
+ }
+ }
+}
+
+void NavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
+ rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh, rcPolyMeshDetail *detail_mesh,
+ Vector<float> &verticies, Vector<int> &indices) {
+ rcContext ctx;
+ ep->step(TTR("Setting up Configuration..."), 1);
+
+ const float *verts = verticies.ptr();
+ const int nverts = verticies.size() / 3;
+ const int *tris = indices.ptr();
+ const int ntris = indices.size() / 3;
+
+ float bmin[3], bmax[3];
+ rcCalcBounds(verts, nverts, bmin, bmax);
+
+ rcConfig cfg;
+ memset(&cfg, 0, sizeof(cfg));
+
+ cfg.cs = p_nav_mesh->get_cell_size();
+ cfg.ch = p_nav_mesh->get_cell_height();
+ cfg.walkableSlopeAngle = p_nav_mesh->get_agent_max_slope();
+ cfg.walkableHeight = (int)Math::ceil(p_nav_mesh->get_agent_height() / cfg.ch);
+ cfg.walkableClimb = (int)Math::floor(p_nav_mesh->get_agent_max_climb() / cfg.ch);
+ cfg.walkableRadius = (int)Math::ceil(p_nav_mesh->get_agent_radius() / cfg.cs);
+ cfg.maxEdgeLen = (int)(p_nav_mesh->get_edge_max_length() / p_nav_mesh->get_cell_size());
+ cfg.maxSimplificationError = p_nav_mesh->get_edge_max_error();
+ cfg.minRegionArea = (int)(p_nav_mesh->get_region_min_size() * p_nav_mesh->get_region_min_size());
+ cfg.mergeRegionArea = (int)(p_nav_mesh->get_region_merge_size() * p_nav_mesh->get_region_merge_size());
+ cfg.maxVertsPerPoly = (int)p_nav_mesh->get_verts_per_poly();
+ cfg.detailSampleDist = p_nav_mesh->get_detail_sample_distance() < 0.9f ? 0 : p_nav_mesh->get_cell_size() * p_nav_mesh->get_detail_sample_distance();
+ cfg.detailSampleMaxError = p_nav_mesh->get_cell_height() * p_nav_mesh->get_detail_sample_max_error();
+
+ cfg.bmin[0] = bmin[0];
+ cfg.bmin[1] = bmin[1];
+ cfg.bmin[2] = bmin[2];
+ cfg.bmax[0] = bmax[0];
+ cfg.bmax[1] = bmax[1];
+ cfg.bmax[2] = bmax[2];
+
+ ep->step(TTR("Calculating grid size..."), 2);
+ rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
+
+ ep->step(TTR("Creating heightfield..."), 3);
+ hf = rcAllocHeightfield();
+
+ ERR_FAIL_COND(!hf);
+ ERR_FAIL_COND(!rcCreateHeightfield(&ctx, *hf, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch));
+
+ ep->step(TTR("Marking walkable triangles..."), 4);
+ {
+ Vector<unsigned char> tri_areas;
+ tri_areas.resize(ntris);
+
+ ERR_FAIL_COND(tri_areas.size() == 0);
+
+ memset(tri_areas.ptr(), 0, ntris * sizeof(unsigned char));
+ rcMarkWalkableTriangles(&ctx, cfg.walkableSlopeAngle, verts, nverts, tris, ntris, tri_areas.ptr());
+
+ ERR_FAIL_COND(!rcRasterizeTriangles(&ctx, verts, nverts, tris, tri_areas.ptr(), ntris, *hf, cfg.walkableClimb));
+ }
+
+ if (p_nav_mesh->get_filter_low_hanging_obstacles())
+ rcFilterLowHangingWalkableObstacles(&ctx, cfg.walkableClimb, *hf);
+ if (p_nav_mesh->get_filter_ledge_spans())
+ rcFilterLedgeSpans(&ctx, cfg.walkableHeight, cfg.walkableClimb, *hf);
+ if (p_nav_mesh->get_filter_walkable_low_height_spans())
+ rcFilterWalkableLowHeightSpans(&ctx, cfg.walkableHeight, *hf);
+
+ ep->step(TTR("Constructing compact heightfield..."), 5);
+
+ chf = rcAllocCompactHeightfield();
+
+ ERR_FAIL_COND(!chf);
+ ERR_FAIL_COND(!rcBuildCompactHeightfield(&ctx, cfg.walkableHeight, cfg.walkableClimb, *hf, *chf));
+
+ rcFreeHeightField(hf);
+ hf = 0;
+
+ ep->step(TTR("Eroding walkable area..."), 6);
+ ERR_FAIL_COND(!rcErodeWalkableArea(&ctx, cfg.walkableRadius, *chf));
+
+ ep->step(TTR("Partioning..."), 7);
+ if (p_nav_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
+ ERR_FAIL_COND(!rcBuildDistanceField(&ctx, *chf));
+ ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
+ } else if (p_nav_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_MONOTONE) {
+ ERR_FAIL_COND(!rcBuildRegionsMonotone(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea));
+ } else {
+ ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, 0, cfg.minRegionArea));
+ }
+
+ ep->step(TTR("Creating contours..."), 8);
+
+ cset = rcAllocContourSet();
+
+ ERR_FAIL_COND(!cset);
+ ERR_FAIL_COND(!rcBuildContours(&ctx, *chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset));
+
+ ep->step(TTR("Creating polymesh..."), 9);
+
+ poly_mesh = rcAllocPolyMesh();
+ ERR_FAIL_COND(!poly_mesh);
+ ERR_FAIL_COND(!rcBuildPolyMesh(&ctx, *cset, cfg.maxVertsPerPoly, *poly_mesh));
+
+ detail_mesh = rcAllocPolyMeshDetail();
+ ERR_FAIL_COND(!detail_mesh);
+ ERR_FAIL_COND(!rcBuildPolyMeshDetail(&ctx, *poly_mesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *detail_mesh));
+
+ rcFreeCompactHeightfield(chf);
+ chf = 0;
+ rcFreeContourSet(cset);
+ cset = 0;
+
+ ep->step(TTR("Converting to native navigation mesh..."), 10);
+
+ _convert_detail_mesh_to_native_navigation_mesh(detail_mesh, p_nav_mesh);
+
+ rcFreePolyMesh(poly_mesh);
+ poly_mesh = 0;
+ rcFreePolyMeshDetail(detail_mesh);
+ detail_mesh = 0;
+}
+
+void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
+
+ ERR_FAIL_COND(!p_nav_mesh.is_valid());
+
+ EditorProgress ep("bake", TTR("Navigation Mesh Generator Setup:"), 11);
+ ep.step(TTR("Parsing Geometry..."), 0);
+
+ Vector<float> verticies;
+ Vector<int> indices;
+
+ _parse_geometry(Object::cast_to<Spatial>(p_node)->get_global_transform().affine_inverse(), p_node, verticies, indices);
+
+ if (verticies.size() > 0 && indices.size() > 0) {
+
+ rcHeightfield *hf = NULL;
+ rcCompactHeightfield *chf = NULL;
+ rcContourSet *cset = NULL;
+ rcPolyMesh *poly_mesh = NULL;
+ rcPolyMeshDetail *detail_mesh = NULL;
+
+ _build_recast_navigation_mesh(p_nav_mesh, &ep, hf, chf, cset, poly_mesh, detail_mesh, verticies, indices);
+
+ if (hf) {
+ rcFreeHeightField(hf);
+ hf = 0;
+ }
+ if (chf) {
+ rcFreeCompactHeightfield(chf);
+ chf = 0;
+ }
+ if (cset) {
+ rcFreeContourSet(cset);
+ cset = 0;
+ }
+ if (poly_mesh) {
+ rcFreePolyMesh(poly_mesh);
+ poly_mesh = 0;
+ }
+ if (detail_mesh) {
+ rcFreePolyMeshDetail(detail_mesh);
+ detail_mesh = 0;
+ }
+ }
+ ep.step(TTR("Done!"), 11);
+}
+
+void NavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) {
+ if (p_nav_mesh.is_valid()) {
+ p_nav_mesh->clear_polygons();
+ p_nav_mesh->set_vertices(PoolVector<Vector3>());
+ }
+}
+
+#endif //RECAST_ENABLED
diff --git a/editor/plugins/navigation_mesh_generator.h b/editor/plugins/navigation_mesh_generator.h
new file mode 100644
index 0000000000..0a1c497f8f
--- /dev/null
+++ b/editor/plugins/navigation_mesh_generator.h
@@ -0,0 +1,65 @@
+/*************************************************************************/
+/* navigation_mesh_generator.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef NAVIGATION_MESH_GENERATOR_H
+#define NAVIGATION_MESH_GENERATOR_H
+
+#ifdef RECAST_ENABLED
+
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
+
+#include "scene/3d/mesh_instance.h"
+
+#include "scene/3d/navigation_mesh.h"
+
+#include "os/thread.h"
+#include "scene/resources/shape.h"
+
+#include <Recast.h>
+
+class NavigationMeshGenerator {
+protected:
+ static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
+ static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
+ static void _parse_geometry(const Transform &p_base_inverse, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices);
+
+ static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
+ static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
+ rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh,
+ rcPolyMeshDetail *detail_mesh, Vector<float> &verticies, Vector<int> &indices);
+
+public:
+ static void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node);
+ static void clear(Ref<NavigationMesh> p_nav_mesh);
+};
+
+#endif // RECAST_ENABLED
+
+#endif // NAVIGATION_MESH_GENERATOR_H
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 3917c700f0..8c4e1b8f27 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -52,7 +52,7 @@ void Polygon2DEditor::_notification(int p_what) {
uv_button[UV_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
b_snap_grid->set_icon(get_icon("Grid", "EditorIcons"));
- b_snap_enable->set_icon(get_icon("Snap", "EditorIcons"));
+ b_snap_enable->set_icon(get_icon("SnapGrid", "EditorIcons"));
uv_icon_zoom->set_texture(get_icon("Zoom", "EditorIcons"));
get_tree()->connect("node_removed", this, "_node_removed");
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 6f03d086ca..9af5885a17 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -421,8 +421,10 @@ void ScriptEditor::_go_to_tab(int p_idx) {
_update_history_arrows();
_update_script_colors();
_update_members_overview();
+ _update_help_overview();
_update_selected_editor_menu();
_update_members_overview_visibility();
+ _update_help_overview_visibility();
}
void ScriptEditor::_add_recent_script(String p_path) {
@@ -555,6 +557,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save) {
_update_script_names();
_update_members_overview_visibility();
+ _update_help_overview_visibility();
_save_layout();
}
@@ -1110,6 +1113,7 @@ void ScriptEditor::_notification(int p_what) {
editor->connect("resource_saved", this, "_res_saved_callback");
script_list->connect("item_selected", this, "_script_selected");
members_overview->connect("item_selected", this, "_members_overview_selected");
+ help_overview->connect("item_selected", this, "_help_overview_selected");
script_split->connect("dragged", this, "_script_split_dragged");
autosave_timer->connect("timeout", this, "_autosave_scripts");
{
@@ -1278,6 +1282,15 @@ void ScriptEditor::_members_overview_selected(int p_idx) {
se->ensure_focus();
}
+void ScriptEditor::_help_overview_selected(int p_idx) {
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ EditorHelp *se = Object::cast_to<EditorHelp>(current);
+ if (!se) {
+ return;
+ }
+ se->scroll_to_section(help_overview->get_item_metadata(p_idx));
+}
+
void ScriptEditor::_script_selected(int p_idx) {
grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
@@ -1387,14 +1400,58 @@ void ScriptEditor::_update_members_overview() {
}
}
+void ScriptEditor::_update_help_overview_visibility() {
+
+ int selected = tab_container->get_current_tab();
+ if (selected < 0 || selected >= tab_container->get_child_count())
+ return;
+
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ EditorHelp *se = Object::cast_to<EditorHelp>(current);
+ if (!se) {
+ help_overview->set_visible(false);
+ return;
+ }
+
+ if (help_overview_enabled) {
+ help_overview->set_visible(true);
+ } else {
+ help_overview->set_visible(false);
+ }
+}
+
+void ScriptEditor::_update_help_overview() {
+
+ int selected = tab_container->get_current_tab();
+ if (selected < 0 || selected >= tab_container->get_child_count())
+ return;
+
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ EditorHelp *se = Object::cast_to<EditorHelp>(current);
+ if (!se) {
+ return;
+ }
+
+ help_overview->clear();
+
+ Vector<Pair<String, int> > sections = se->get_sections();
+ for (int i = 0; i < sections.size(); i++) {
+ help_overview->add_item(sections[i].first);
+ help_overview->set_item_metadata(i, sections[i].second);
+ }
+}
+
+void _help_overview_selected(int p_idx) {
+}
+
void ScriptEditor::_update_script_colors() {
bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled");
bool highlight_current = EditorSettings::get_singleton()->get("text_editor/open_scripts/highlight_current_script");
int hist_size = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_history_size");
- Color hot_color = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_hot_color");
- Color cold_color = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_cold_color");
+ Color hot_color = get_color("accent_color", "Editor");
+ Color cold_color = get_color("font_color", "Editor");
for (int i = 0; i < script_list->get_item_count(); i++) {
@@ -1531,6 +1588,7 @@ void ScriptEditor::_update_script_names() {
}
_update_members_overview();
+ _update_help_overview();
_update_script_colors();
}
@@ -1624,9 +1682,10 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool
break;
}
ERR_FAIL_COND_V(!se, false);
- tab_container->add_child(se);
+ // load script before adding as child else editor will crash at theme loading
se->set_edited_script(p_script);
+ tab_container->add_child(se);
se->set_tooltip_request_func("_get_debug_tooltip", this);
if (se->get_edit_menu()) {
se->get_edit_menu()->hide();
@@ -1785,7 +1844,9 @@ void ScriptEditor::_editor_settings_changed() {
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type");
members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
+ help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index");
_update_members_overview_visibility();
+ _update_help_overview_visibility();
float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs");
if (autosave_time > 0) {
@@ -2164,6 +2225,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_update_script_names", &ScriptEditor::_update_script_names);
ClassDB::bind_method("_tree_changed", &ScriptEditor::_tree_changed);
ClassDB::bind_method("_members_overview_selected", &ScriptEditor::_members_overview_selected);
+ ClassDB::bind_method("_help_overview_selected", &ScriptEditor::_help_overview_selected);
ClassDB::bind_method("_script_selected", &ScriptEditor::_script_selected);
ClassDB::bind_method("_script_created", &ScriptEditor::_script_created);
ClassDB::bind_method("_script_split_dragged", &ScriptEditor::_script_split_dragged);
@@ -2193,6 +2255,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
pending_auto_reload = false;
auto_reload_running_scripts = false;
members_overview_enabled = true;
+ help_overview_enabled = true;
editor = p_editor;
VBoxContainer *main_container = memnew(VBoxContainer);
@@ -2221,6 +2284,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
members_overview->set_custom_minimum_size(Size2(0, 100)); //need to give a bit of limit to avoid it from disappearing
members_overview->set_v_size_flags(SIZE_EXPAND_FILL);
+ help_overview = memnew(ItemList);
+ list_split->add_child(help_overview);
+ help_overview->set_custom_minimum_size(Size2(0, 100)); //need to give a bit of limit to avoid it from disappearing
+ help_overview->set_v_size_flags(SIZE_EXPAND_FILL);
+
tab_container = memnew(TabContainer);
tab_container->set_tabs_visible(false);
script_split->add_child(tab_container);
@@ -2520,8 +2588,6 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
- EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e"));
- EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3));
EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5));
EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path"));
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index d2677c6a4a..03fc4da7ce 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -187,6 +187,8 @@ class ScriptEditor : public PanelContainer {
HSplitContainer *script_split;
ItemList *members_overview;
bool members_overview_enabled;
+ ItemList *help_overview;
+ bool help_overview_enabled;
VSplitContainer *list_split;
TabContainer *tab_container;
EditorFileDialog *file_dialog;
@@ -294,6 +296,10 @@ class ScriptEditor : public PanelContainer {
void _members_overview_selected(int p_idx);
void _script_selected(int p_idx);
+ void _update_help_overview_visibility();
+ void _update_help_overview();
+ void _help_overview_selected(int p_idx);
+
void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used);
void _tree_changed();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 2192d3ac49..c875ee7011 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -75,35 +75,98 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->clear_colors();
- /* keyword color */
-
- text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)));
- text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0)));
- text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244")));
- text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf")));
- text_edit->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff")));
- text_edit->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa")));
- text_edit->add_color_override("font_color", EDITOR_DEF("text_editor/highlighting/text_color", Color(0, 0, 0)));
- text_edit->add_color_override("line_number_color", EDITOR_DEF("text_editor/highlighting/line_number_color", Color(0, 0, 0)));
- text_edit->add_color_override("caret_color", EDITOR_DEF("text_editor/highlighting/caret_color", Color(0, 0, 0)));
- text_edit->add_color_override("caret_background_color", EDITOR_DEF("text_editor/highlighting/caret_background_color", Color(0, 0, 0)));
- text_edit->add_color_override("font_selected_color", EDITOR_DEF("text_editor/highlighting/text_selected_color", Color(1, 1, 1)));
- text_edit->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
- text_edit->add_color_override("brace_mismatch_color", EDITOR_DEF("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2)));
- text_edit->add_color_override("current_line_color", EDITOR_DEF("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15)));
- text_edit->add_color_override("line_length_guideline_color", EDITOR_DEF("text_editor/highlighting/line_length_guideline_color", Color(0, 0, 0)));
- text_edit->add_color_override("word_highlighted_color", EDITOR_DEF("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15)));
- text_edit->add_color_override("number_color", EDITOR_DEF("text_editor/highlighting/number_color", Color(0.9, 0.6, 0.0, 2)));
- text_edit->add_color_override("function_color", EDITOR_DEF("text_editor/highlighting/function_color", Color(0.4, 0.6, 0.8)));
- text_edit->add_color_override("member_variable_color", EDITOR_DEF("text_editor/highlighting/member_variable_color", Color(0.9, 0.3, 0.3)));
- text_edit->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4)));
- text_edit->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2)));
- text_edit->add_color_override("search_result_color", EDITOR_DEF("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1)));
- text_edit->add_color_override("search_result_border_color", EDITOR_DEF("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1)));
- text_edit->add_color_override("symbol_color", EDITOR_DEF("text_editor/highlighting/symbol_color", Color::hex(0x005291ff)));
- text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+ Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
+ Color completion_background_color = EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0));
+ Color completion_selected_color = EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"));
+ Color completion_existing_color = EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"));
+ Color completion_scroll_color = EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"));
+ Color completion_font_color = EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"));
+ Color text_color = EDITOR_DEF("text_editor/highlighting/text_color", Color(0, 0, 0));
+ Color line_number_color = EDITOR_DEF("text_editor/highlighting/line_number_color", Color(0, 0, 0));
+ Color caret_color = EDITOR_DEF("text_editor/highlighting/caret_color", Color(0, 0, 0));
+ Color caret_background_color = EDITOR_DEF("text_editor/highlighting/caret_background_color", Color(0, 0, 0));
+ Color text_selected_color = EDITOR_DEF("text_editor/highlighting/text_selected_color", Color(1, 1, 1));
+ Color selection_color = EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1));
+ Color brace_mismatch_color = EDITOR_DEF("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2));
+ Color current_line_color = EDITOR_DEF("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15));
+ Color line_length_guideline_color = EDITOR_DEF("text_editor/highlighting/line_length_guideline_color", Color(0, 0, 0));
+ Color word_highlighted_color = EDITOR_DEF("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15));
+ Color number_color = EDITOR_DEF("text_editor/highlighting/number_color", Color(0.9, 0.6, 0.0, 2));
+ Color function_color = EDITOR_DEF("text_editor/highlighting/function_color", Color(0.4, 0.6, 0.8));
+ Color member_variable_color = EDITOR_DEF("text_editor/highlighting/member_variable_color", Color(0.9, 0.3, 0.3));
+ Color mark_color = EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4));
+ Color breakpoint_color = EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2));
+ Color search_result_color = EDITOR_DEF("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
+ Color search_result_border_color = EDITOR_DEF("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1));
+ Color symbol_color = EDITOR_DEF("text_editor/highlighting/symbol_color", Color::hex(0x005291ff));
Color keyword_color = EDITOR_DEF("text_editor/highlighting/keyword_color", Color(0.5, 0.0, 0.2));
+ Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0));
+ Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4));
+ Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color", Color::hex(0x797e7eff));
+ Color string_color = EDITOR_DEF("text_editor/highlighting/string_color", Color::hex(0x6b6f00ff));
+
+ // Adapt
+ if (EditorSettings::get_singleton()->get("text_editor/theme/color_theme") == "Adaptive") {
+ Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme();
+
+ symbol_color = tm->get_color("text_editor/theme/symbol_color", "Editor");
+ keyword_color = tm->get_color("text_editor/theme/keyword_color", "Editor");
+ basetype_color = tm->get_color("text_editor/theme/basetype_color", "Editor");
+ type_color = tm->get_color("text_editor/theme/type_color", "Editor");
+ comment_color = tm->get_color("text_editor/theme/comment_color", "Editor");
+ string_color = tm->get_color("text_editor/theme/string_color", "Editor");
+ background_color = tm->get_color("text_editor/theme/background_color", "Editor");
+ completion_background_color = tm->get_color("text_editor/theme/completion_background_color", "Editor");
+ completion_selected_color = tm->get_color("text_editor/theme/completion_selected_color", "Editor");
+ completion_existing_color = tm->get_color("text_editor/theme/completion_existing_color", "Editor");
+ completion_scroll_color = tm->get_color("text_editor/theme/completion_scroll_color", "Editor");
+ completion_font_color = tm->get_color("text_editor/theme/completion_font_color", "Editor");
+ text_color = tm->get_color("text_editor/theme/text_color", "Editor");
+ line_number_color = tm->get_color("text_editor/theme/line_number_color", "Editor");
+ caret_color = tm->get_color("text_editor/theme/caret_color", "Editor");
+ caret_background_color = tm->get_color("text_editor/theme/caret_background_color", "Editor");
+ text_selected_color = tm->get_color("text_editor/theme/text_selected_color", "Editor");
+ selection_color = tm->get_color("text_editor/theme/selection_color", "Editor");
+ brace_mismatch_color = tm->get_color("text_editor/theme/brace_mismatch_color", "Editor");
+ current_line_color = tm->get_color("text_editor/theme/current_line_color", "Editor");
+ line_length_guideline_color = tm->get_color("text_editor/theme/line_length_guideline_color", "Editor");
+ word_highlighted_color = tm->get_color("text_editor/theme/word_highlighted_color", "Editor");
+ number_color = tm->get_color("text_editor/theme/number_color", "Editor");
+ function_color = tm->get_color("text_editor/theme/function_color", "Editor");
+ member_variable_color = tm->get_color("text_editor/theme/member_variable_color", "Editor");
+ mark_color = tm->get_color("text_editor/theme/mark_color", "Editor");
+ breakpoint_color = tm->get_color("text_editor/theme/breakpoint_color", "Editor");
+ search_result_color = tm->get_color("text_editor/theme/search_result_color", "Editor");
+ search_result_border_color = tm->get_color("text_editor/theme/search_result_border_color", "Editor");
+ }
+
+ text_edit->add_color_override("background_color", background_color);
+ text_edit->add_color_override("completion_background_color", completion_background_color);
+ text_edit->add_color_override("completion_selected_color", completion_selected_color);
+ text_edit->add_color_override("completion_existing_color", completion_existing_color);
+ text_edit->add_color_override("completion_scroll_color", completion_scroll_color);
+ text_edit->add_color_override("completion_font_color", completion_font_color);
+ text_edit->add_color_override("font_color", text_color);
+ text_edit->add_color_override("line_number_color", line_number_color);
+ text_edit->add_color_override("caret_color", caret_color);
+ text_edit->add_color_override("caret_background_color", caret_background_color);
+ text_edit->add_color_override("font_selected_color", text_selected_color);
+ text_edit->add_color_override("selection_color", selection_color);
+ text_edit->add_color_override("brace_mismatch_color", brace_mismatch_color);
+ text_edit->add_color_override("current_line_color", current_line_color);
+ text_edit->add_color_override("line_length_guideline_color", line_length_guideline_color);
+ text_edit->add_color_override("word_highlighted_color", word_highlighted_color);
+ text_edit->add_color_override("number_color", number_color);
+ text_edit->add_color_override("function_color", function_color);
+ text_edit->add_color_override("member_variable_color", member_variable_color);
+ text_edit->add_color_override("mark_color", mark_color);
+ text_edit->add_color_override("breakpoint_color", breakpoint_color);
+ text_edit->add_color_override("search_result_color", search_result_color);
+ text_edit->add_color_override("search_result_border_color", search_result_border_color);
+ text_edit->add_color_override("symbol_color", symbol_color);
+
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
List<String> keywords;
script->get_language()->get_reserved_words(&keywords);
@@ -113,8 +176,6 @@ void ScriptTextEditor::_load_theme_settings() {
}
//colorize core types
- Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0));
-
text_edit->add_keyword_color("String", basetype_color);
text_edit->add_keyword_color("Vector2", basetype_color);
text_edit->add_keyword_color("Rect2", basetype_color);
@@ -140,8 +201,6 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_keyword_color("PoolColorArray", basetype_color);
//colorize engine types
- Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4));
-
List<StringName> types;
ClassDB::get_class_list(&types);
@@ -155,7 +214,6 @@ void ScriptTextEditor::_load_theme_settings() {
}
//colorize comments
- Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color", Color::hex(0x797e7eff));
List<String> comments;
script->get_language()->get_comment_delimiters(&comments);
@@ -169,7 +227,6 @@ void ScriptTextEditor::_load_theme_settings() {
}
//colorize strings
- Color string_color = EDITOR_DEF("text_editor/highlighting/string_color", Color::hex(0x6b6f00ff));
List<String> strings;
script->get_language()->get_string_delimiters(&strings);
@@ -209,6 +266,7 @@ void ScriptTextEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
//emit_signal("name_changed");
+ _load_theme_settings();
}
}
@@ -492,8 +550,6 @@ void ScriptTextEditor::set_edited_script(const Ref<Script> &p_script) {
script = p_script;
- _load_theme_settings();
-
code_editor->get_text_edit()->set_text(script->get_source_code());
code_editor->get_text_edit()->clear_undo_history();
code_editor->get_text_edit()->tag_saved_version();
@@ -948,13 +1004,26 @@ void ScriptTextEditor::_edit_option(int p_op) {
if (tx->get_selection_to_column() == 0)
end -= 1;
+ // Check if all lines in the selected block are commented
+ bool is_commented = true;
+ for (int i = begin; i <= end; i++) {
+ if (!tx->get_line(i).begins_with("#")) {
+ is_commented = false;
+ break;
+ }
+ }
for (int i = begin; i <= end; i++) {
String line_text = tx->get_line(i);
- if (line_text.begins_with("#"))
- line_text = line_text.substr(1, line_text.length());
- else
- line_text = "#" + line_text;
+ if (line_text.strip_edges().empty()) {
+ line_text = "#";
+ } else {
+ if (is_commented) {
+ line_text = line_text.substr(1, line_text.length());
+ } else {
+ line_text = "#" + line_text;
+ }
+ }
tx->set_line(i, line_text);
}
} else {
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 1b02f18d85..b0ee1a32ca 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -60,33 +60,96 @@ void ShaderTextEditor::_load_theme_settings() {
get_text_edit()->clear_colors();
- /* keyword color */
-
- get_text_edit()->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)));
- get_text_edit()->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0)));
- get_text_edit()->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244")));
- get_text_edit()->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf")));
- get_text_edit()->add_color_override("completion_scroll_color", EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff")));
- get_text_edit()->add_color_override("completion_font_color", EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa")));
- get_text_edit()->add_color_override("font_color", EDITOR_DEF("text_editor/highlighting/text_color", Color(0, 0, 0)));
- get_text_edit()->add_color_override("line_number_color", EDITOR_DEF("text_editor/highlighting/line_number_color", Color(0, 0, 0)));
- get_text_edit()->add_color_override("caret_color", EDITOR_DEF("text_editor/highlighting/caret_color", Color(0, 0, 0)));
- get_text_edit()->add_color_override("caret_background_color", EDITOR_DEF("text_editor/highlighting/caret_background_color", Color(0, 0, 0)));
- get_text_edit()->add_color_override("font_selected_color", EDITOR_DEF("text_editor/highlighting/text_selected_color", Color(1, 1, 1)));
- get_text_edit()->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
- get_text_edit()->add_color_override("brace_mismatch_color", EDITOR_DEF("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2)));
- get_text_edit()->add_color_override("current_line_color", EDITOR_DEF("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15)));
- get_text_edit()->add_color_override("word_highlighted_color", EDITOR_DEF("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15)));
- get_text_edit()->add_color_override("number_color", EDITOR_DEF("text_editor/highlighting/number_color", Color(0.9, 0.6, 0.0, 2)));
- get_text_edit()->add_color_override("function_color", EDITOR_DEF("text_editor/highlighting/function_color", Color(0.4, 0.6, 0.8)));
- get_text_edit()->add_color_override("member_variable_color", EDITOR_DEF("text_editor/highlighting/member_variable_color", Color(0.9, 0.3, 0.3)));
- get_text_edit()->add_color_override("mark_color", EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4)));
- get_text_edit()->add_color_override("breakpoint_color", EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2)));
- get_text_edit()->add_color_override("search_result_color", EDITOR_DEF("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1)));
- get_text_edit()->add_color_override("search_result_border_color", EDITOR_DEF("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1)));
- get_text_edit()->add_color_override("symbol_color", EDITOR_DEF("text_editor/highlighting/symbol_color", Color::hex(0x005291ff)));
+ Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0));
+ Color completion_background_color = EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0));
+ Color completion_selected_color = EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"));
+ Color completion_existing_color = EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"));
+ Color completion_scroll_color = EDITOR_DEF("text_editor/highlighting/completion_scroll_color", Color::html("ffffff"));
+ Color completion_font_color = EDITOR_DEF("text_editor/highlighting/completion_font_color", Color::html("aaaaaa"));
+ Color text_color = EDITOR_DEF("text_editor/highlighting/text_color", Color(0, 0, 0));
+ Color line_number_color = EDITOR_DEF("text_editor/highlighting/line_number_color", Color(0, 0, 0));
+ Color caret_color = EDITOR_DEF("text_editor/highlighting/caret_color", Color(0, 0, 0));
+ Color caret_background_color = EDITOR_DEF("text_editor/highlighting/caret_background_color", Color(0, 0, 0));
+ Color text_selected_color = EDITOR_DEF("text_editor/highlighting/text_selected_color", Color(1, 1, 1));
+ Color selection_color = EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1));
+ Color brace_mismatch_color = EDITOR_DEF("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2));
+ Color current_line_color = EDITOR_DEF("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15));
+ Color line_length_guideline_color = EDITOR_DEF("text_editor/highlighting/line_length_guideline_color", Color(0, 0, 0));
+ Color word_highlighted_color = EDITOR_DEF("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15));
+ Color number_color = EDITOR_DEF("text_editor/highlighting/number_color", Color(0.9, 0.6, 0.0, 2));
+ Color function_color = EDITOR_DEF("text_editor/highlighting/function_color", Color(0.4, 0.6, 0.8));
+ Color member_variable_color = EDITOR_DEF("text_editor/highlighting/member_variable_color", Color(0.9, 0.3, 0.3));
+ Color mark_color = EDITOR_DEF("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4));
+ Color breakpoint_color = EDITOR_DEF("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2));
+ Color search_result_color = EDITOR_DEF("text_editor/highlighting/search_result_color", Color(0.05, 0.25, 0.05, 1));
+ Color search_result_border_color = EDITOR_DEF("text_editor/highlighting/search_result_border_color", Color(0.1, 0.45, 0.1, 1));
+ Color symbol_color = EDITOR_DEF("text_editor/highlighting/symbol_color", Color::hex(0x005291ff));
Color keyword_color = EDITOR_DEF("text_editor/highlighting/keyword_color", Color(0.5, 0.0, 0.2));
+ Color basetype_color = EDITOR_DEF("text_editor/highlighting/base_type_color", Color(0.3, 0.3, 0.0));
+ Color type_color = EDITOR_DEF("text_editor/highlighting/engine_type_color", Color(0.0, 0.2, 0.4));
+ Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color", Color::hex(0x797e7eff));
+ Color string_color = EDITOR_DEF("text_editor/highlighting/string_color", Color::hex(0x6b6f00ff));
+
+ // Adapt
+ if (EditorSettings::get_singleton()->get("text_editor/theme/color_theme") == "Adaptive") {
+ Ref<Theme> tm = EditorNode::get_singleton()->get_theme_base()->get_theme();
+
+ symbol_color = tm->get_color("text_editor/theme/symbol_color", "Editor");
+ keyword_color = tm->get_color("text_editor/theme/keyword_color", "Editor");
+ basetype_color = tm->get_color("text_editor/theme/basetype_color", "Editor");
+ type_color = tm->get_color("text_editor/theme/type_color", "Editor");
+ comment_color = tm->get_color("text_editor/theme/comment_color", "Editor");
+ string_color = tm->get_color("text_editor/theme/string_color", "Editor");
+ background_color = tm->get_color("text_editor/theme/background_color", "Editor");
+ completion_background_color = tm->get_color("text_editor/theme/completion_background_color", "Editor");
+ completion_selected_color = tm->get_color("text_editor/theme/completion_selected_color", "Editor");
+ completion_existing_color = tm->get_color("text_editor/theme/completion_existing_color", "Editor");
+ completion_scroll_color = tm->get_color("text_editor/theme/completion_scroll_color", "Editor");
+ completion_font_color = tm->get_color("text_editor/theme/completion_font_color", "Editor");
+ text_color = tm->get_color("text_editor/theme/text_color", "Editor");
+ line_number_color = tm->get_color("text_editor/theme/line_number_color", "Editor");
+ caret_color = tm->get_color("text_editor/theme/caret_color", "Editor");
+ caret_background_color = tm->get_color("text_editor/theme/caret_background_color", "Editor");
+ text_selected_color = tm->get_color("text_editor/theme/text_selected_color", "Editor");
+ selection_color = tm->get_color("text_editor/theme/selection_color", "Editor");
+ brace_mismatch_color = tm->get_color("text_editor/theme/brace_mismatch_color", "Editor");
+ current_line_color = tm->get_color("text_editor/theme/current_line_color", "Editor");
+ line_length_guideline_color = tm->get_color("text_editor/theme/line_length_guideline_color", "Editor");
+ word_highlighted_color = tm->get_color("text_editor/theme/word_highlighted_color", "Editor");
+ number_color = tm->get_color("text_editor/theme/number_color", "Editor");
+ function_color = tm->get_color("text_editor/theme/function_color", "Editor");
+ member_variable_color = tm->get_color("text_editor/theme/member_variable_color", "Editor");
+ mark_color = tm->get_color("text_editor/theme/mark_color", "Editor");
+ breakpoint_color = tm->get_color("text_editor/theme/breakpoint_color", "Editor");
+ search_result_color = tm->get_color("text_editor/theme/search_result_color", "Editor");
+ search_result_border_color = tm->get_color("text_editor/theme/search_result_border_color", "Editor");
+ }
+
+ get_text_edit()->add_color_override("background_color", background_color);
+ get_text_edit()->add_color_override("completion_background_color", completion_background_color);
+ get_text_edit()->add_color_override("completion_selected_color", completion_selected_color);
+ get_text_edit()->add_color_override("completion_existing_color", completion_existing_color);
+ get_text_edit()->add_color_override("completion_scroll_color", completion_scroll_color);
+ get_text_edit()->add_color_override("completion_font_color", completion_font_color);
+ get_text_edit()->add_color_override("font_color", text_color);
+ get_text_edit()->add_color_override("line_number_color", line_number_color);
+ get_text_edit()->add_color_override("caret_color", caret_color);
+ get_text_edit()->add_color_override("caret_background_color", caret_background_color);
+ get_text_edit()->add_color_override("font_selected_color", text_selected_color);
+ get_text_edit()->add_color_override("selection_color", selection_color);
+ get_text_edit()->add_color_override("brace_mismatch_color", brace_mismatch_color);
+ get_text_edit()->add_color_override("current_line_color", current_line_color);
+ get_text_edit()->add_color_override("line_length_guideline_color", line_length_guideline_color);
+ get_text_edit()->add_color_override("word_highlighted_color", word_highlighted_color);
+ get_text_edit()->add_color_override("number_color", number_color);
+ get_text_edit()->add_color_override("function_color", function_color);
+ get_text_edit()->add_color_override("member_variable_color", member_variable_color);
+ get_text_edit()->add_color_override("mark_color", mark_color);
+ get_text_edit()->add_color_override("breakpoint_color", breakpoint_color);
+ get_text_edit()->add_color_override("search_result_color", search_result_color);
+ get_text_edit()->add_color_override("search_result_border_color", search_result_border_color);
+ get_text_edit()->add_color_override("symbol_color", symbol_color);
List<String> keywords;
ShaderLanguage::get_keyword_list(&keywords);
@@ -115,8 +178,6 @@ void ShaderTextEditor::_load_theme_settings() {
//Color basetype_color= EDITOR_DEF("text_editor/base_type_color",Color(0.3,0.3,0.0));
//colorize comments
- Color comment_color = EDITOR_DEF("text_editor/highlighting/comment_color", Color::hex(0x797e7eff));
-
get_text_edit()->add_color_region("/*", "*/", comment_color, false);
get_text_edit()->add_color_region("//", "", comment_color, false);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 93d12fd3d2..c1b0fdb5d6 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -76,18 +76,29 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
} else
camera->set_perspective(get_fov(), get_znear(), get_zfar());
- float inertia = EDITOR_DEF("editors/3d/orbit_inertia", 0.5);
- inertia = MAX(0, inertia);
+ //when not being manipulated, move softly
+ float free_orbit_inertia = EDITOR_DEF("editors/3d/free_orbit_inertia", 0.15);
+ float free_translation_inertia = EDITOR_DEF("editors/3d/free_translation_inertia", 0.15);
+ //when being manipulated, move more quickly
+ float manip_orbit_inertia = EDITOR_DEF("editors/3d/manipulation_orbit_inertia", 0.075);
+ float manip_translation_inertia = EDITOR_DEF("editors/3d/manipulation_translation_inertia", 0.075);
+
+ //determine if being manipulated
+ bool manipulated = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+
+ float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
+ float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
Cursor old_camera_cursor = camera_cursor;
camera_cursor = cursor;
- camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, p_interp_delta * (1 / inertia));
- camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, p_interp_delta * (1 / inertia));
+ camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
- bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
+ camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
- if (p_interp_delta == 0 || disable_interp || is_freelook_active()) {
+ if (p_interp_delta == 0 || is_freelook_active()) {
camera_cursor = cursor;
}
@@ -2555,11 +2566,18 @@ void SpatialEditorViewport::_create_preview(const Vector<String> &files) const {
String path = files[i];
RES res = ResourceLoader::load(path);
Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
- if (scene != NULL) {
- if (scene.is_valid()) {
- Node *instance = scene->instance();
- if (instance) {
- preview_node->add_child(instance);
+ Ref<Mesh> mesh = Ref<Mesh>(Object::cast_to<Mesh>(*res));
+ if (mesh != NULL || scene != NULL) {
+ if (mesh != NULL) {
+ MeshInstance *mesh_instance = memnew(MeshInstance);
+ mesh_instance->set_mesh(mesh);
+ preview_node->add_child(mesh_instance);
+ } else {
+ if (scene.is_valid()) {
+ Node *instance = scene->instance();
+ if (instance) {
+ preview_node->add_child(instance);
+ }
}
}
editor->get_scene_root()->add_child(preview_node);
@@ -2595,13 +2613,29 @@ bool SpatialEditorViewport::_cyclical_dependency_exists(const String &p_target_s
}
bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
- Ref<PackedScene> sdata = ResourceLoader::load(path);
- if (!sdata.is_valid()) { // invalid scene
- return false;
+ RES res = ResourceLoader::load(path);
+
+ Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
+ Ref<Mesh> mesh = Ref<Mesh>(Object::cast_to<Mesh>(*res));
+
+ Node *instanced_scene = NULL;
+
+ if (mesh != NULL || scene != NULL) {
+ if (mesh != NULL) {
+ MeshInstance *mesh_instance = memnew(MeshInstance);
+ mesh_instance->set_mesh(mesh);
+ mesh_instance->set_name(mesh->get_name());
+ instanced_scene = mesh_instance;
+ } else {
+ if (!scene.is_valid()) { // invalid scene
+ return false;
+ } else {
+ instanced_scene = scene->instance();
+ }
+ }
}
- Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
- if (!instanced_scene) { // error on instancing
+ if (instanced_scene == NULL) {
return false;
}
@@ -2650,7 +2684,8 @@ void SpatialEditorViewport::_perform_drop_data() {
continue;
}
Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res));
- if (scene != NULL) {
+ Ref<Mesh> mesh = Ref<Mesh>(Object::cast_to<Mesh>(*res));
+ if (mesh != NULL || scene != NULL) {
bool success = _create_instance(target_node, path, drop_pos);
if (!success) {
error_files.push_back(path);
@@ -2683,9 +2718,11 @@ bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Varian
List<String> scene_extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions);
+ List<String> mesh_extensions;
+ ResourceLoader::get_recognized_extensions_for_type("Mesh", &mesh_extensions);
for (int i = 0; i < files.size(); i++) {
- if (scene_extensions.find(files[i].get_extension())) {
+ if (mesh_extensions.find(files[i].get_extension()) || scene_extensions.find(files[i].get_extension())) {
RES res = ResourceLoader::load(files[i]);
if (res.is_null()) {
continue;
@@ -2699,6 +2736,13 @@ bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Varian
continue;
}
memdelete(instanced_scene);
+ } else if (type == "Mesh" || "ArrayMesh" || "PrimitiveMesh") {
+ Ref<Mesh> mesh = ResourceLoader::load(files[i]);
+ if (!mesh.is_valid()) {
+ continue;
+ }
+ } else {
+ continue;
}
can_instance = true;
break;
@@ -2843,8 +2887,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), KEY_D);
ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), KEY_W);
ED_SHORTCUT("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), KEY_S);
- ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_Q);
- ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_E);
+ ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_E);
+ ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_Q);
ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT);
preview_camera = memnew(Button);
@@ -3696,18 +3740,50 @@ void SpatialEditor::_init_indicators() {
origin_colors.push_back(Color(axis.x, axis.y, axis.z));
origin_points.push_back(axis * 4096);
origin_points.push_back(axis * -4096);
-#define ORIGIN_GRID_SIZE 25
+#define ORIGIN_GRID_SIZE 100
for (int j = -ORIGIN_GRID_SIZE; j <= ORIGIN_GRID_SIZE; j++) {
- grid_colors[i].push_back(grid_color);
- grid_colors[i].push_back(grid_color);
- grid_colors[i].push_back(grid_color);
- grid_colors[i].push_back(grid_color);
- grid_points[i].push_back(axis_n1 * ORIGIN_GRID_SIZE + axis_n2 * j);
- grid_points[i].push_back(-axis_n1 * ORIGIN_GRID_SIZE + axis_n2 * j);
- grid_points[i].push_back(axis_n2 * ORIGIN_GRID_SIZE + axis_n1 * j);
- grid_points[i].push_back(-axis_n2 * ORIGIN_GRID_SIZE + axis_n1 * j);
+ for (int k = -ORIGIN_GRID_SIZE; k <= ORIGIN_GRID_SIZE; k++) {
+
+ Vector3 p = axis_n1 * j + axis_n2 * k;
+ float trans = Math::pow(MAX(0, 1.0 - (Vector2(j, k).length() / ORIGIN_GRID_SIZE)), 2);
+
+ Vector3 pj = axis_n1 * (j + 1) + axis_n2 * k;
+ float transj = Math::pow(MAX(0, 1.0 - (Vector2(j + 1, k).length() / ORIGIN_GRID_SIZE)), 2);
+
+ Vector3 pk = axis_n1 * j + axis_n2 * (k + 1);
+ float transk = Math::pow(MAX(0, 1.0 - (Vector2(j, k + 1).length() / ORIGIN_GRID_SIZE)), 2);
+
+ Color trans_color = grid_color;
+ trans_color.a *= trans;
+
+ Color transk_color = grid_color;
+ transk_color.a *= transk;
+
+ Color transj_color = grid_color;
+ transj_color.a *= transj;
+
+ if (j % 10 == 0 || k % 10 == 0) {
+ trans_color.a *= 2;
+ }
+ if ((k + 1) % 10 == 0) {
+ transk_color.a *= 2;
+ }
+ if ((j + 1) % 10 == 0) {
+ transj_color.a *= 2;
+ }
+
+ grid_points[i].push_back(p);
+ grid_points[i].push_back(pk);
+ grid_colors[i].push_back(trans_color);
+ grid_colors[i].push_back(transk_color);
+
+ grid_points[i].push_back(p);
+ grid_points[i].push_back(pj);
+ grid_colors[i].push_back(trans_color);
+ grid_colors[i].push_back(transj_color);
+ }
}
grid[i] = VisualServer::get_singleton()->mesh_create();
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 43856116a6..b85ffd6c67 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -72,6 +72,14 @@ void TileMapEditor::_menu_option(int p_option) {
switch (p_option) {
+ case OPTION_PAINTING: {
+ // NOTE: We do not set tool = TOOL_PAINTING as this begins painting
+ // immediately without pressing the left mouse button first
+ tool = TOOL_NONE;
+
+ canvas_item_editor->update();
+
+ } break;
case OPTION_BUCKET: {
tool = TOOL_BUCKET;
@@ -703,7 +711,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
} else {
-
+ // Mousebutton was released
if (tool != TOOL_NONE) {
if (tool == TOOL_PAINTING) {
@@ -801,6 +809,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_undo_method(this, "_fill_points", points, pop);
undo_redo->commit_action();
+
+ // We want to keep the bucket-tool active
+ return true;
}
tool = TOOL_NONE;
@@ -1046,9 +1057,25 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
}
- if (tool != TOOL_NONE || !mouse_over)
+ if (!mouse_over) {
+ // Editor shortcuts should not fire if mouse not in viewport
return false;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/paint_tile", p_event)) {
+ // NOTE: We do not set tool = TOOL_PAINTING as this begins painting
+ // immediately without pressing the left mouse button first
+ tool = TOOL_NONE;
+ canvas_item_editor->update();
+
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/bucket_fill", p_event)) {
+ tool = TOOL_BUCKET;
+ canvas_item_editor->update();
+
+ return true;
+ }
if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) {
_menu_option(OPTION_ERASE_SELECTION);
@@ -1458,7 +1485,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase selection"), KEY_DELETE);
ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find tile"), KEY_MASK_CMD + KEY_F);
- ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"));
+ ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T);
ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A);
ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S);
@@ -1512,7 +1539,8 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
PopupMenu *p = options->get_popup();
- p->add_item(TTR("Bucket"), OPTION_BUCKET);
+ p->add_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P), OPTION_PAINTING);
+ p->add_shortcut(ED_SHORTCUT("tile_map_editor/bucket_fill", TTR("Bucket Fill"), KEY_G), OPTION_BUCKET);
p->add_separator();
p->add_item(TTR("Pick Tile"), OPTION_PICK_TILE, KEY_CONTROL);
p->add_separator();
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index e863c4bf3d..de9b9e8e0d 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -68,7 +68,8 @@ class TileMapEditor : public VBoxContainer {
OPTION_PICK_TILE,
OPTION_SELECT,
OPTION_DUPLICATE,
- OPTION_ERASE_SELECTION
+ OPTION_ERASE_SELECTION,
+ OPTION_PAINTING,
};
TileMap *node;
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 7e81513a8b..f4318a670c 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -48,7 +48,7 @@ void ProjectExportDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
- delete_preset->set_icon(get_icon("Del", "EditorIcons"));
+ delete_preset->set_icon(get_icon("Remove", "EditorIcons"));
connect("confirmed", this, "_export_pck_zip");
custom_feature_display->get_parent_control()->add_style_override("panel", get_stylebox("bg", "Tree"));
} break;
@@ -193,7 +193,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
patch->set_checked(0, true);
patch->set_tooltip(0, patchlist[i]);
patch->set_metadata(0, i);
- patch->add_button(0, get_icon("Del", "EditorIcons"), 0);
+ patch->add_button(0, get_icon("Remove", "EditorIcons"), 0);
patch->add_button(0, get_icon("folder", "FileDialog"), 1);
}
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index b36d4715c4..78d544fdcf 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -59,11 +59,13 @@ public:
enum Mode {
MODE_NEW,
MODE_IMPORT,
- MODE_INSTALL
+ MODE_INSTALL,
+ MODE_RENAME
};
private:
Mode mode;
+ Button *browse;
Label *pp, *pn;
Label *error;
LineEdit *project_path;
@@ -91,20 +93,20 @@ private:
return "";
}
- if (mode != MODE_IMPORT) {
+ if (mode == MODE_IMPORT || mode == MODE_RENAME) {
- if (d->file_exists("project.godot")) {
+ if (valid_path != "" && !d->file_exists("project.godot")) {
- error->set_text(TTR("Invalid project path, project.godot must not exist."));
+ error->set_text(TTR("Invalid project path, project.godot must exist."));
memdelete(d);
return "";
}
} else {
- if (valid_path != "" && !d->file_exists("project.godot")) {
+ if (d->file_exists("project.godot")) {
- error->set_text(TTR("Invalid project path, project.godot must exist."));
+ error->set_text(TTR("Invalid project path, project.godot must not exist."));
memdelete(d);
return "";
}
@@ -172,6 +174,17 @@ private:
void _text_changed(const String &p_text) {
_test_path();
+ error->set_text("");
+ if (p_text == "") {
+
+ error->set_text(TTR("Name cannot be empty"));
+ get_ok()->set_disabled(true);
+ return;
+ }
+ get_ok()->set_disabled(false);
+ }
+
+ void _name_changed(const String &p_text) {
}
void ok_pressed() {
@@ -182,138 +195,165 @@ private:
return;
}
- if (mode == MODE_IMPORT) {
- // nothing to do
+ if (mode == MODE_RENAME) {
+
+ String dir = _test_path();
+ if (dir == "") {
+ error->set_text(TTR("Invalid project path (changed anything?)."));
+ return;
+ }
+
+ ProjectSettings *current = memnew(ProjectSettings);
+ current->add_singleton(ProjectSettings::Singleton("Current"));
+
+ if (current->setup(dir, "")) {
+ error->set_text(TTR("Couldn't get project.godot in project path."));
+ } else {
+ ProjectSettings::CustomMap edited_settings;
+ edited_settings["application/config/name"] = project_name->get_text();
+
+ if (current->save_custom(dir.plus_file("/project.godot"), edited_settings, Vector<String>(), true)) {
+ error->set_text(TTR("Couldn't edit project.godot in project path."));
+ }
+ }
+
+ hide();
+ emit_signal("project_renamed");
} else {
- if (mode == MODE_NEW) {
- ProjectSettings::CustomMap initial_settings;
- initial_settings["application/config/name"] = project_name->get_text();
- initial_settings["application/config/icon"] = "res://icon.png";
- initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
+ if (mode == MODE_IMPORT) {
+ // nothing to do
+ } else {
+ if (mode == MODE_NEW) {
- if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
- error->set_text(TTR("Couldn't create project.godot in project path."));
- } else {
- ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+ ProjectSettings::CustomMap initial_settings;
+ initial_settings["application/config/name"] = project_name->get_text();
+ initial_settings["application/config/icon"] = "res://icon.png";
+ initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
- FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
- if (!f) {
+ if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
error->set_text(TTR("Couldn't create project.godot in project path."));
} else {
- f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
- f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
- f->store_line("[resource]");
- f->store_line("background_mode = 2");
- f->store_line("background_sky = SubResource( 1 )");
- memdelete(f);
+ ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+
+ FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
+ if (!f) {
+ error->set_text(TTR("Couldn't create project.godot in project path."));
+ } else {
+ f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
+ f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
+ f->store_line("[resource]");
+ f->store_line("background_mode = 2");
+ f->store_line("background_sky = SubResource( 1 )");
+ memdelete(f);
+ }
}
- }
- } else if (mode == MODE_INSTALL) {
+ } else if (mode == MODE_INSTALL) {
- FileAccess *src_f = NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
- unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
- if (!pkg) {
+ unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
+ if (!pkg) {
- dialog_error->set_text(TTR("Error opening package file, not in zip format."));
- return;
- }
+ dialog_error->set_text(TTR("Error opening package file, not in zip format."));
+ return;
+ }
- int ret = unzGoToFirstFile(pkg);
+ int ret = unzGoToFirstFile(pkg);
- Vector<String> failed_files;
+ Vector<String> failed_files;
- int idx = 0;
- while (ret == UNZ_OK) {
+ int idx = 0;
+ while (ret == UNZ_OK) {
- //get filename
- unz_file_info info;
- char fname[16384];
- ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
- String path = fname;
+ String path = fname;
- int depth = 1; //stuff from github comes with tag
- bool skip = false;
- while (depth > 0) {
- int pp = path.find("/");
- if (pp == -1) {
- skip = true;
- break;
+ int depth = 1; //stuff from github comes with tag
+ bool skip = false;
+ while (depth > 0) {
+ int pp = path.find("/");
+ if (pp == -1) {
+ skip = true;
+ break;
+ }
+ path = path.substr(pp + 1, path.length());
+ depth--;
}
- path = path.substr(pp + 1, path.length());
- depth--;
- }
- if (skip || path == String()) {
- //
- } else if (path.ends_with("/")) { // a dir
+ if (skip || path == String()) {
+ //
+ } else if (path.ends_with("/")) { // a dir
- path = path.substr(0, path.length() - 1);
+ path = path.substr(0, path.length() - 1);
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->make_dir(dir.plus_file(path));
- memdelete(da);
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ da->make_dir(dir.plus_file(path));
+ memdelete(da);
- } else {
+ } else {
- Vector<uint8_t> data;
- data.resize(info.uncompressed_size);
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
- //read
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptr(), data.size());
- unzCloseCurrentFile(pkg);
+ //read
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg, data.ptr(), data.size());
+ unzCloseCurrentFile(pkg);
- FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
+ FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
- if (f) {
- f->store_buffer(data.ptr(), data.size());
- memdelete(f);
- } else {
- failed_files.push_back(path);
+ if (f) {
+ f->store_buffer(data.ptr(), data.size());
+ memdelete(f);
+ } else {
+ failed_files.push_back(path);
+ }
}
- }
- idx++;
- ret = unzGoToNextFile(pkg);
- }
+ idx++;
+ ret = unzGoToNextFile(pkg);
+ }
- unzClose(pkg);
+ unzClose(pkg);
- if (failed_files.size()) {
- String msg = TTR("The following files failed extraction from package:") + "\n\n";
- for (int i = 0; i < failed_files.size(); i++) {
+ if (failed_files.size()) {
+ String msg = TTR("The following files failed extraction from package:") + "\n\n";
+ for (int i = 0; i < failed_files.size(); i++) {
- if (i > 15) {
- msg += "\nAnd " + itos(failed_files.size() - i) + " more files.";
- break;
+ if (i > 15) {
+ msg += "\nAnd " + itos(failed_files.size() - i) + " more files.";
+ break;
+ }
+ msg += failed_files[i] + "\n";
}
- msg += failed_files[i] + "\n";
- }
- dialog_error->set_text(msg);
- dialog_error->popup_centered_minsize();
+ dialog_error->set_text(msg);
+ dialog_error->popup_centered_minsize();
- } else {
- dialog_error->set_text(TTR("Package Installed Successfully!"));
- dialog_error->popup_centered_minsize();
+ } else {
+ dialog_error->set_text(TTR("Package Installed Successfully!"));
+ dialog_error->popup_centered_minsize();
+ }
}
}
- }
- dir = dir.replace("\\", "/");
- if (dir.ends_with("/"))
- dir = dir.substr(0, dir.length() - 1);
- String proj = dir.replace("/", "::");
- EditorSettings::get_singleton()->set("projects/" + proj, dir);
- EditorSettings::get_singleton()->save();
+ dir = dir.replace("\\", "/");
+ if (dir.ends_with("/"))
+ dir = dir.substr(0, dir.length() - 1);
+ String proj = dir.replace("/", "::");
+ EditorSettings::get_singleton()->set("projects/" + proj, dir);
+ EditorSettings::get_singleton()->save();
- hide();
- emit_signal("project_created", dir);
+ hide();
+ emit_signal("project_created", dir);
+ }
}
protected:
@@ -325,6 +365,7 @@ protected:
ClassDB::bind_method("_path_selected", &NewProjectDialog::_path_selected);
ClassDB::bind_method("_file_selected", &NewProjectDialog::_file_selected);
ADD_SIGNAL(MethodInfo("project_created"));
+ ADD_SIGNAL(MethodInfo("project_renamed"));
}
public:
@@ -340,44 +381,85 @@ public:
mode = p_mode;
}
- void show_dialog() {
-
- project_path->clear();
- project_name->clear();
+ void set_project_path(const String &p_path) {
+ project_path->set_text(p_path);
+ }
- if (mode == MODE_IMPORT) {
- set_title(TTR("Import Existing Project"));
- get_ok()->set_text(TTR("Import"));
- pp->set_text(TTR("Project Path (Must Exist):"));
- pn->set_text(TTR("Project Name:"));
- pn->hide();
- project_name->hide();
+ void show_dialog() {
- popup_centered(Size2(500, 125) * EDSCALE);
+ if (mode == MODE_RENAME) {
- } else if (mode == MODE_NEW) {
+ project_path->set_editable(false);
+ browse->set_disabled(true);
- set_title(TTR("Create New Project"));
- get_ok()->set_text(TTR("Create"));
+ set_title(TTR("Rename Project"));
+ get_ok()->set_text(TTR("Rename"));
pp->set_text(TTR("Project Path:"));
pn->set_text(TTR("Project Name:"));
pn->show();
project_name->show();
- popup_centered(Size2(500, 145) * EDSCALE);
- } else if (mode == MODE_INSTALL) {
+ String dir = _test_path();
+ if (dir == "") {
+ error->set_text(TTR("Invalid project path (changed anything?)."));
+ return;
+ }
+ ProjectSettings *current = memnew(ProjectSettings);
+ current->add_singleton(ProjectSettings::Singleton("Current"));
- set_title(TTR("Install Project:") + " " + zip_title);
- get_ok()->set_text(TTR("Install"));
- pp->set_text(TTR("Project Path:"));
- pn->hide();
- project_name->hide();
+ if (current->setup(dir, "")) {
+ error->set_text(TTR("Couldn't get project.godot in project path."));
+ } else {
+ if (current->has("application/config/name")) {
+ String appname = current->get("application/config/name");
+ project_name->set_text(appname);
+ }
+ }
popup_centered(Size2(500, 125) * EDSCALE);
- }
- project_path->grab_focus();
+ project_name->grab_focus();
- _test_path();
+ } else {
+
+ project_path->clear();
+ project_name->clear();
+ project_path->set_editable(true);
+ browse->set_disabled(false);
+
+ if (mode == MODE_IMPORT) {
+ set_title(TTR("Import Existing Project"));
+ get_ok()->set_text(TTR("Import"));
+ pp->set_text(TTR("Project Path (Must Exist):"));
+ pn->set_text(TTR("Project Name:"));
+ pn->hide();
+ project_name->hide();
+
+ popup_centered(Size2(500, 125) * EDSCALE);
+
+ } else if (mode == MODE_NEW) {
+
+ set_title(TTR("Create New Project"));
+ get_ok()->set_text(TTR("Create"));
+ pp->set_text(TTR("Project Path:"));
+ pn->set_text(TTR("Project Name:"));
+ pn->show();
+ project_name->show();
+
+ popup_centered(Size2(500, 145) * EDSCALE);
+ } else if (mode == MODE_INSTALL) {
+
+ set_title(TTR("Install Project:") + " " + zip_title);
+ get_ok()->set_text(TTR("Install"));
+ pp->set_text(TTR("Project Path:"));
+ pn->hide();
+ project_name->hide();
+
+ popup_centered(Size2(500, 125) * EDSCALE);
+ }
+ project_path->grab_focus();
+
+ _test_path();
+ }
}
NewProjectDialog() {
@@ -399,7 +481,7 @@ public:
pphb->add_child(project_path);
project_path->set_h_size_flags(SIZE_EXPAND_FILL);
- Button *browse = memnew(Button);
+ browse = memnew(Button);
pphb->add_child(browse);
browse->set_text(TTR("Browse"));
browse->connect("pressed", this, "_browse_path");
@@ -495,6 +577,7 @@ void ProjectManager::_update_project_buttons() {
erase_btn->set_disabled(selected_list.size() < 1);
open_btn->set_disabled(selected_list.size() < 1);
+ rename_btn->set_disabled(selected_list.size() < 1);
}
void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
@@ -889,6 +972,10 @@ void ProjectManager::_load_recent_projects() {
tabs->set_current_tab(0);
}
+void ProjectManager::_on_project_renamed() {
+ _load_recent_projects();
+}
+
void ProjectManager::_on_project_created(const String &dir) {
bool has_already = false;
for (int i = 0; i < scroll_childs->get_child_count(); i++) {
@@ -948,6 +1035,10 @@ void ProjectManager::_open_project_confirm() {
args.push_back("--editor");
+ if (OS::get_singleton()->is_disable_crash_handler()) {
+ args.push_back("--disable-crash-handler");
+ }
+
String exec = OS::get_singleton()->get_executable_path();
OS::ProcessID pid = 0;
@@ -999,6 +1090,10 @@ void ProjectManager::_run_project_confirm() {
args.push_back("--path");
args.push_back(path);
+ if (OS::get_singleton()->is_disable_crash_handler()) {
+ args.push_back("--disable-crash-handler");
+ }
+
String exec = OS::get_singleton()->get_executable_path();
OS::ProcessID pid = 0;
@@ -1083,6 +1178,21 @@ void ProjectManager::_import_project() {
npdialog->show_dialog();
}
+void ProjectManager::_rename_project() {
+
+ if (selected_list.size() == 0) {
+ return;
+ }
+
+ for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
+ const String &selected = E->key();
+ String path = EditorSettings::get_singleton()->get("projects/" + selected);
+ npdialog->set_project_path(path);
+ npdialog->set_mode(NewProjectDialog::MODE_RENAME);
+ npdialog->show_dialog();
+ }
+}
+
void ProjectManager::_erase_project_confirm() {
if (selected_list.size() == 0) {
@@ -1177,10 +1287,12 @@ void ProjectManager::_bind_methods() {
ClassDB::bind_method("_scan_begin", &ProjectManager::_scan_begin);
ClassDB::bind_method("_import_project", &ProjectManager::_import_project);
ClassDB::bind_method("_new_project", &ProjectManager::_new_project);
+ ClassDB::bind_method("_rename_project", &ProjectManager::_rename_project);
ClassDB::bind_method("_erase_project", &ProjectManager::_erase_project);
ClassDB::bind_method("_erase_project_confirm", &ProjectManager::_erase_project_confirm);
ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
ClassDB::bind_method("_load_recent_projects", &ProjectManager::_load_recent_projects);
+ ClassDB::bind_method("_on_project_renamed", &ProjectManager::_on_project_renamed);
ClassDB::bind_method("_on_project_created", &ProjectManager::_on_project_created);
ClassDB::bind_method("_update_scroll_pos", &ProjectManager::_update_scroll_pos);
ClassDB::bind_method("_panel_draw", &ProjectManager::_panel_draw);
@@ -1341,6 +1453,12 @@ ProjectManager::ProjectManager() {
tree_vb->add_child(import);
import->connect("pressed", this, "_import_project");
+ Button *rename = memnew(Button);
+ rename->set_text(TTR("Rename"));
+ tree_vb->add_child(rename);
+ rename->connect("pressed", this, "_rename_project");
+ rename_btn = rename;
+
Button *erase = memnew(Button);
erase->set_text(TTR("Remove"));
tree_vb->add_child(erase);
@@ -1396,6 +1514,7 @@ ProjectManager::ProjectManager() {
npdialog = memnew(NewProjectDialog);
gui_base->add_child(npdialog);
+ npdialog->connect("project_renamed", this, "_on_project_renamed");
npdialog->connect("project_created", this, "_on_project_created");
_load_recent_projects();
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 9fcf10a0d9..67fe0b503f 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -45,6 +45,7 @@ class ProjectManager : public Control {
Button *erase_btn;
Button *open_btn;
+ Button *rename_btn;
Button *run_btn;
FileDialog *scan_dir;
@@ -79,6 +80,7 @@ class ProjectManager : public Control {
void _open_project_confirm();
void _import_project();
void _new_project();
+ void _rename_project();
void _erase_project();
void _erase_project_confirm();
void _update_project_buttons();
@@ -87,6 +89,7 @@ class ProjectManager : public Control {
void _load_recent_projects();
void _on_project_created(const String &dir);
+ void _on_project_renamed();
void _update_scroll_pos(const String &dir);
void _scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index c7a4e1fc3b..b7300b9610 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -861,13 +861,13 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
menu->add_separator();
}
- menu->add_icon_item(get_icon("Load", "EditorIcons"), "Load", OBJ_MENU_LOAD);
+ menu->add_icon_item(get_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD);
if (!RES(v).is_null()) {
- menu->add_icon_item(get_icon("Edit", "EditorIcons"), "Edit", OBJ_MENU_EDIT);
- menu->add_icon_item(get_icon("Clear", "EditorIcons"), "Clear", OBJ_MENU_CLEAR);
- menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), "Make Unique", OBJ_MENU_MAKE_UNIQUE);
+ menu->add_icon_item(get_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT);
+ menu->add_icon_item(get_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR);
+ menu->add_icon_item(get_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
RES r = v;
if (r.is_valid() && r->get_path().is_resource_file()) {
menu->add_separator();
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index b92ebed167..4bcbe073ee 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -189,7 +189,7 @@ Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<Strin
Vector<Pair<String, Ref<Texture> > > sorted_list;
if (search_text == String() || list.size() == 0)
- return sorted_list;
+ return list;
Vector<float> scores;
scores.resize(list.size());
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 5b783493cb..2fcba7e3c0 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2016,6 +2016,5 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
clear_inherit_confirm->get_ok()->set_text(TTR("Clear!"));
add_child(clear_inherit_confirm);
- vbc->add_constant_override("separation", 4);
set_process_input(true);
}
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 284b25801c..76e75cff0a 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -1622,7 +1622,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles"));
tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
- tabs->set_v_size_flags(SIZE_EXPAND_FILL);
tabs->set_area_as_parent_rect();
add_child(tabs);
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 6cb5f0a70c..64ac2535a9 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -150,7 +150,7 @@ class ScriptEditorDebugger : public Control {
void _scene_tree_selected();
void _scene_tree_request();
void _parse_message(const String &p_msg, const Array &p_data);
- void _set_reason_text(const String &p_msg, MessageType p_type);
+ void _set_reason_text(const String &p_reason, MessageType p_type);
void _scene_tree_property_select_object(ObjectID p_object);
void _scene_tree_property_value_edited(const String &p_prop, const Variant &p_value);