summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/SCsub35
-rw-r--r--editor/animation_editor.cpp88
-rw-r--r--editor/create_dialog.cpp38
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/dependency_editor.cpp1
-rw-r--r--editor/doc/doc_data.cpp132
-rw-r--r--editor/doc/doc_data.h8
-rw-r--r--editor/editor_audio_buses.cpp134
-rw-r--r--editor/editor_audio_buses.h20
-rw-r--r--editor/editor_dir_dialog.cpp4
-rw-r--r--editor/editor_export.cpp161
-rw-r--r--editor/editor_export.h49
-rw-r--r--editor/editor_file_dialog.cpp33
-rw-r--r--editor/editor_fonts.cpp20
-rw-r--r--editor/editor_help.cpp319
-rw-r--r--editor/editor_help.h5
-rw-r--r--editor/editor_log.cpp25
-rw-r--r--editor/editor_log.h3
-rw-r--r--editor/editor_node.cpp129
-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_run.cpp4
-rw-r--r--editor/editor_settings.cpp34
-rw-r--r--editor/editor_themes.cpp565
-rw-r--r--editor/fileserver/editor_file_server.cpp2
-rw-r--r--editor/filesystem_dock.cpp68
-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_class_list.svg10
-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_big_thumb.svg (renamed from editor/icons/icon_file_big_broken.svg)0
-rw-r--r--editor/icons/icon_file_dead.svg7
-rw-r--r--editor/icons/icon_file_dead_big_thumb.svg (renamed from editor/icons/icon_file_big_dead.svg)0
-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_filesystem.svg5
-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_key_call.svg5
-rw-r--r--editor/icons/icon_logo.svg7
-rw-r--r--editor/icons/icon_mini_checkerboard.svg4
-rw-r--r--editor/icons/icon_shader_material.svg11
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp6
-rw-r--r--editor/import/resource_importer_scene.cpp51
-rw-r--r--editor/import/resource_importer_scene.h9
-rw-r--r--editor/import/resource_importer_texture.cpp7
-rw-r--r--editor/import/resource_importer_wav.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp130
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp57
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h4
-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.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp79
-rw-r--r--editor/plugins/script_editor_plugin.h6
-rw-r--r--editor/plugins/script_text_editor.cpp149
-rw-r--r--editor/plugins/shader_editor_plugin.cpp123
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp150
-rw-r--r--editor/plugins/spatial_editor_plugin.h4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp37
-rw-r--r--editor/plugins/tile_map_editor_plugin.h3
-rw-r--r--editor/project_export.cpp9
-rw-r--r--editor/project_manager.cpp417
-rw-r--r--editor/project_manager.h4
-rw-r--r--editor/project_settings_editor.cpp8
-rw-r--r--editor/property_editor.cpp21
-rw-r--r--editor/property_selector.cpp33
-rw-r--r--editor/property_selector.h3
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/scene_tree_dock.cpp56
-rw-r--r--editor/script_editor_debugger.cpp1
-rw-r--r--editor/script_editor_debugger.h2
83 files changed, 2922 insertions, 1146 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 702adf0c68..40493c1de3 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"));
}
}
@@ -1092,12 +1092,16 @@ void AnimationKeyEditor::_track_editor_draw() {
int sep = get_constant("vseparation", "Tree");
int hsep = get_constant("hseparation", "Tree");
Color color = get_color("font_color", "Tree");
- Color sepcolor = Color(1, 1, 1, 0.2);
- Color timecolor = Color(1, 1, 1, 0.2);
- Color hover_color = Color(1, 1, 1, 0.05);
- Color select_color = Color(1, 1, 1, 0.1);
+ Color sepcolor = color;
+ sepcolor.a = 0.2;
+ Color timecolor = color;
+ timecolor.a = 0.2;
+ Color hover_color = color;
+ hover_color.a = 0.05;
+ 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");
@@ -1157,7 +1161,8 @@ void AnimationKeyEditor::_track_editor_draw() {
int settings_limit = size.width - right_separator_ofs;
int name_limit = settings_limit * name_column_ratio;
- Color linecolor = Color(1, 1, 1, 0.2);
+ Color linecolor = color;
+ linecolor.a = 0.2;
te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), linecolor);
te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), linecolor);
te->draw_texture(hsize_icon, ofs + Point2(name_limit - hsize_icon->get_width() - hsep, (h - hsize_icon->get_height()) / 2));
@@ -1482,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);
@@ -2890,15 +2895,9 @@ void AnimationKeyEditor::_notification(int p_what) {
key_editor->edit(key_edit);
- zoomicon->set_texture(get_icon("Zoom", "EditorIcons"));
zoomicon->set_custom_minimum_size(Size2(24 * EDSCALE, 0));
zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
- menu_add_track->set_icon(get_icon("Add", "EditorIcons"));
- 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);
@@ -2921,18 +2920,10 @@ void AnimationKeyEditor::_notification(int p_what) {
optimize_dialog->connect("confirmed", this, "_animation_optimize");
menu_track->get_popup()->add_child(tpp);
- //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions");
- //menu_track->get_popup()->add_separator();
+
menu_track->get_popup()->add_item(TTR("Optimize Animation"), TRACK_MENU_OPTIMIZE);
menu_track->get_popup()->add_item(TTR("Clean-Up Animation"), TRACK_MENU_CLEAN_UP);
- curve_linear->set_icon(get_icon("CurveLinear", "EditorIcons"));
- curve_in->set_icon(get_icon("CurveIn", "EditorIcons"));
- curve_out->set_icon(get_icon("CurveOut", "EditorIcons"));
- curve_inout->set_icon(get_icon("CurveInOut", "EditorIcons"));
- curve_outin->set_icon(get_icon("CurveOutIn", "EditorIcons"));
- curve_constant->set_icon(get_icon("CurveConstant", "EditorIcons"));
-
curve_linear->connect("pressed", this, "_menu_track", varray(CURVE_SET_LINEAR));
curve_in->connect("pressed", this, "_menu_track", varray(CURVE_SET_IN));
curve_out->connect("pressed", this, "_menu_track", varray(CURVE_SET_OUT));
@@ -2940,17 +2931,39 @@ void AnimationKeyEditor::_notification(int p_what) {
curve_outin->connect("pressed", this, "_menu_track", varray(CURVE_SET_OUTIN));
curve_constant->connect("pressed", this, "_menu_track", varray(CURVE_SET_CONSTANT));
+ edit_button->connect("pressed", this, "_toggle_edit_curves");
+
+ curve_edit->connect("transition_changed", this, "_curve_transition_changed");
+ call_select->connect("selected", this, "_add_call_track");
+
+ _update_menu();
+
+ } break;
+
+ case NOTIFICATION_THEME_CHANGED: {
+ zoomicon->set_texture(get_icon("Zoom", "EditorIcons"));
+
+ menu_add_track->set_icon(get_icon("Add", "EditorIcons"));
+
+ menu_track->set_icon(get_icon("Tools", "EditorIcons"));
+
+ menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_VALUE_TRACK, get_icon("KeyValue", "EditorIcons"));
+ menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_TRANSFORM_TRACK, get_icon("KeyXform", "EditorIcons"));
+ menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_CALL_TRACK, get_icon("KeyCall", "EditorIcons"));
+
+ curve_linear->set_icon(get_icon("CurveLinear", "EditorIcons"));
+ curve_in->set_icon(get_icon("CurveIn", "EditorIcons"));
+ curve_out->set_icon(get_icon("CurveOut", "EditorIcons"));
+ curve_inout->set_icon(get_icon("CurveInOut", "EditorIcons"));
+ curve_outin->set_icon(get_icon("CurveOutIn", "EditorIcons"));
+ curve_constant->set_icon(get_icon("CurveConstant", "EditorIcons"));
+
move_up_button->set_icon(get_icon("MoveUp", "EditorIcons"));
move_down_button->set_icon(get_icon("MoveDown", "EditorIcons"));
remove_button->set_icon(get_icon("Remove", "EditorIcons"));
edit_button->set_icon(get_icon("EditKey", "EditorIcons"));
- edit_button->connect("pressed", this, "_toggle_edit_curves");
loop->set_icon(get_icon("Loop", "EditorIcons"));
- curve_edit->connect("transition_changed", this, "_curve_transition_changed");
-
- //edit_button->add_color_override("font_color",get_color("font_color","Tree"));
- //edit_button->add_color_override("font_color_hover",get_color("font_color","Tree"));
{
@@ -2976,24 +2989,8 @@ void AnimationKeyEditor::_notification(int p_what) {
get_icon("InterpWrapClamp", "EditorIcons"),
get_icon("InterpWrapLoop", "EditorIcons"),
};
-
- //right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11;
right_data_size_cache = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep * 8;
}
- call_select->connect("selected", this, "_add_call_track");
- //rename_anim->set_icon( get_icon("Rename","EditorIcons") );
- /*
- edit_anim->set_icon( get_icon("Edit","EditorIcons") );
- blend_anim->set_icon( get_icon("Blend","EditorIcons") );
- play->set_icon( get_icon("Play","EditorIcons") );
- stop->set_icon( get_icon("Stop","EditorIcons") );
- pause->set_icon( get_icon("Pause","EditorIcons") );
-*/
- //menu->set_icon(get_icon("Animation","EditorIcons"));
- //play->set_icon(get_icon("AnimationPlay","EditorIcons"));
- //menu->set_icon(get_icon("Animation","EditorIcons"));
- _update_menu();
-
} break;
}
}
@@ -3816,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);
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 344cb87aa6..9797a2e9f5 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));
}
}
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/dependency_editor.cpp b/editor/dependency_editor.cpp
index 890c3d8091..54bf31cd62 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -489,6 +489,7 @@ DependencyErrorDialog::DependencyErrorDialog() {
vb->add_margin_child(TTR("Scene failed to load due to missing dependencies:"), files, true);
files->set_v_size_flags(SIZE_EXPAND_FILL);
get_ok()->set_text(TTR("Open Anyway"));
+ get_cancel()->set_text(TTR("Done"));
text = memnew(Label);
vb->add_child(text);
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 6937f74316..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());
}
@@ -414,7 +408,10 @@ void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
void EditorAudioBus::_bus_popup_pressed(int p_option) {
- if (p_option == 1) {
+ if (p_option == 2) {
+ // Reset volume
+ emit_signal("vol_reset_request");
+ } else if (p_option == 1) {
emit_signal("delete_request");
} else if (p_option == 0) {
//duplicate
@@ -617,6 +614,7 @@ void EditorAudioBus::_bind_methods() {
ADD_SIGNAL(MethodInfo("duplicate_request"));
ADD_SIGNAL(MethodInfo("delete_request"));
+ ADD_SIGNAL(MethodInfo("vol_reset_request"));
ADD_SIGNAL(MethodInfo("drop_end_request"));
ADD_SIGNAL(MethodInfo("dropped"));
}
@@ -679,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);
@@ -742,6 +745,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses) {
bus_popup = bus_options->get_popup();
bus_popup->add_item(TTR("Duplicate"));
bus_popup->add_item(TTR("Delete"));
+ bus_popup->add_item(TTR("Reset Volume"));
bus_popup->connect("index_pressed", this, "_bus_popup_pressed");
delete_effect_popup = memnew(PopupMenu);
@@ -790,6 +794,7 @@ void EditorAudioBuses::_update_buses() {
bus_hb->add_child(audio_bus);
audio_bus->connect("delete_request", this, "_delete_bus", varray(audio_bus), CONNECT_DEFERRED);
audio_bus->connect("duplicate_request", this, "_duplicate_bus", varray(), CONNECT_DEFERRED);
+ audio_bus->connect("vol_reset_request", this, "_reset_bus_volume", varray(audio_bus), CONNECT_DEFERRED);
audio_bus->connect("drop_end_request", this, "_request_drop_end");
audio_bus->connect("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED);
}
@@ -919,6 +924,20 @@ void EditorAudioBuses::_duplicate_bus(int p_which) {
ur->commit_action();
}
+void EditorAudioBuses::_reset_bus_volume(Object *p_which) {
+
+ EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which);
+ int index = bus->get_index();
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Reset Bus Volume"));
+ ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", index, 0.f);
+ ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", index, AudioServer::get_singleton()->get_bus_volume_db(index));
+ ur->add_do_method(this, "_update_buses");
+ ur->add_undo_method(this, "_update_buses");
+ ur->commit_action();
+}
+
void EditorAudioBuses::_request_drop_end() {
if (!drop_end && bus_hb->get_child_count()) {
@@ -1063,6 +1082,7 @@ void EditorAudioBuses::_bind_methods() {
ClassDB::bind_method("_load_default_layout", &EditorAudioBuses::_load_default_layout);
ClassDB::bind_method("_new_layout", &EditorAudioBuses::_new_layout);
ClassDB::bind_method("_duplicate_bus", &EditorAudioBuses::_duplicate_bus);
+ ClassDB::bind_method("_reset_bus_volume", &EditorAudioBuses::_reset_bus_volume);
ClassDB::bind_method("_file_dialog_callback", &EditorAudioBuses::_file_dialog_callback);
}
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index e04ba7b89d..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;
@@ -158,6 +165,7 @@ class EditorAudioBuses : public VBoxContainer {
void _delete_bus(Object *p_which);
void _duplicate_bus(int p_which);
+ void _reset_bus_volume(Object *p_which);
void _request_drop_end();
void _drop_at_index(int p_bus, int p_index);
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 915fb7e5db..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);
@@ -697,6 +813,8 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
zd.zip = zip;
Error err = export_project_files(p_preset, _save_zip_file, &zd);
+ if (err != OK)
+ ERR_PRINT("Failed to export project files");
zipClose(zip, NULL);
@@ -865,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) {
@@ -1111,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);
@@ -1167,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..288b923e87 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) {
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 3ab3f05906..d806b825ba 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);
@@ -147,7 +147,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..035819f503 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) {
@@ -129,7 +126,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 +147,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 +173,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 91d2ddcd19..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) {
@@ -412,7 +414,6 @@ void EditorNode::_fs_changed() {
}
if (changed.size()) {
- int idx = 0;
for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) {
E->get()->reload_from_file();
}
@@ -1387,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();
@@ -1398,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);
@@ -1425,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);
@@ -1440,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);
@@ -1997,6 +2034,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
int cur_idx = editor_data.get_edited_scene();
_remove_edited_scene();
Error err = load_scene(filename);
+ if (err != OK)
+ ERR_PRINT("Failed to load scene");
editor_data.move_edited_scene_to_index(cur_idx);
get_undo_redo()->clear_history();
scene_tabs->set_current_tab(cur_idx);
@@ -2741,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;
}
@@ -2759,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);
}
}
}
@@ -3212,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>();
}
@@ -3304,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;
@@ -3607,13 +3641,6 @@ void EditorNode::_update_dock_slots_visibility() {
right_r_vsplit,
};
- HSplitContainer *h_splits[4] = {
- left_l_hsplit,
- left_r_hsplit,
- main_hsplit,
- right_hsplit,
- };
-
if (!docks_visible) {
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
@@ -4034,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);
@@ -4042,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);
}
@@ -4134,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
@@ -4476,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);
@@ -4821,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);
@@ -4878,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));
@@ -5035,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);
@@ -5236,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);
@@ -5248,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());
@@ -5445,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_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 db76a27f5f..d4ee6b2d17 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -574,10 +574,10 @@ 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);
@@ -599,8 +599,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);
@@ -676,9 +676,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/3d/warped_mouse_panning", true);
set("editors/3d/orbit_sensitivity", 0.4);
- set("editors/3d/freelook_inertia", 3);
- set("editors/3d/freelook_base_speed", 1);
+ set("editors/3d/orbit_inertia", 0.2);
+ hints["editors/3d/orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
+
+ set("editors/3d/freelook_inertia", 0.2);
+ hints["editors/3d/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
+
+ set("editors/3d/freelook_base_speed", 0.5);
+ hints["editors/3d/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.1");
set("editors/3d/freelook_activation_modifier", 0);
hints["editors/3d/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl");
@@ -723,6 +729,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);
@@ -730,6 +739,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);
@@ -914,13 +924,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();
@@ -932,7 +942,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;
}
@@ -989,7 +999,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";
@@ -1001,7 +1011,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 19356aad3a..3482261c19 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,10 +108,9 @@ 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
@@ -161,15 +160,41 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = tr
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_theme ? NULL : &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, !dark_theme && !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 +204,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 +211,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);
@@ -202,27 +224,27 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
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 +255,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);
- theme->set_color("highlight_color", "Editor", highlight_color);
+ 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("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 +285,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,36 +308,110 @@ 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);
+ // Script Editor
+ theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(4, 0, 4, 4));
+ 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);
@@ -325,72 +432,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);
+ // 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);
- 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);
-
- 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"));
@@ -398,21 +486,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"));
@@ -420,8 +506,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);
@@ -431,121 +517,147 @@ 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);
+ style_content_panel->set_default_margin(MARGIN_RIGHT, margin_size_extra);
+ style_content_panel->set_default_margin(MARGIN_BOTTOM, margin_size_extra);
+ style_content_panel->set_default_margin(MARGIN_LEFT, margin_size_extra);
+
+ // 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);
+ 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_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));
@@ -554,13 +666,12 @@ 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);
// 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);
@@ -571,6 +682,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);
@@ -598,21 +717,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));
@@ -621,18 +752,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"));
@@ -643,21 +771,24 @@ 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);
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);
graphsbselected->set_border_width_all(border_width);
- graphsbselected->set_border_color_all(Color(1, 1, 1, 0.9));
+ 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);
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);
graphsbcomment->set_border_width_all(border_width);
@@ -673,9 +804,81 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected);
// 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/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index ba90beee22..fccf7c323c 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -34,7 +34,7 @@
#include "io/marshalls.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
-#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n", m_what, OS::get_singleton()->get_ticks_usec());
+#define DEBUG_TIME(m_what) printf("MS: %s - %lu\n", m_what, OS::get_singleton()->get_ticks_usec());
//#define DEBUG_TIME(m_what)
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index a66d1724a1..f0ace864e4 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);
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_class_list.svg b/editor/icons/icon_class_list.svg
index 1f2b37bd25..87a20743c7 100644
--- a/editor/icons/icon_class_list.svg
+++ b/editor/icons/icon_class_list.svg
@@ -1,11 +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="#e0e0e0">
-<rect x="1" y="1038.4" width="5" height=".99998"/>
-<rect x="6" y="1037.4" width="6" height="3"/>
-<rect x="3" y="1038.4" width="1" height="11"/>
-<rect x="4" y="1043.4" width="5" height="1"/>
-<rect x="9" y="1042.4" width="6" height="3"/>
-<rect x="4" y="1048.4" width="5" height="1"/>
-<rect x="9" y="1047.4" width="6" height="3"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m6 1v1h-5v1h2v10h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-4h2v1h6v-3h-6z" fill="#e0e0e0"/>
</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_big_broken.svg b/editor/icons/icon_file_broken_big_thumb.svg
index 167bb1bb5f..167bb1bb5f 100644
--- a/editor/icons/icon_file_big_broken.svg
+++ b/editor/icons/icon_file_broken_big_thumb.svg
diff --git a/editor/icons/icon_file_dead.svg b/editor/icons/icon_file_dead.svg
new file mode 100644
index 0000000000..e0aee6fd90
--- /dev/null
+++ b/editor/icons/icon_file_dead.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 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"/>
+</g>
+</g>
+</svg>
diff --git a/editor/icons/icon_file_big_dead.svg b/editor/icons/icon_file_dead_big_thumb.svg
index c8aab912f1..c8aab912f1 100644
--- a/editor/icons/icon_file_big_dead.svg
+++ b/editor/icons/icon_file_dead_big_thumb.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..60a456a600
--- /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="#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-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_filesystem.svg b/editor/icons/icon_filesystem.svg
new file mode 100644
index 0000000000..41e0348d68
--- /dev/null
+++ b/editor/icons/icon_filesystem.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="m1 1v5h2v8h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-2h3v-4h-2l-1-1h-3z" fill="#e0e0e0"/>
+</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_key_call.svg b/editor/icons/icon_key_call.svg
new file mode 100644
index 0000000000..7fcc65801a
--- /dev/null
+++ b/editor/icons/icon_key_call.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)">
+<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#adf18f"/>
+</g>
+</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_mini_checkerboard.svg b/editor/icons/icon_mini_checkerboard.svg
new file mode 100644
index 0000000000..e740113b2d
--- /dev/null
+++ b/editor/icons/icon_mini_checkerboard.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m0 0v8h8v-8h-8zm8 8v8h8v-8h-8z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9994"/>
+<path d="m8 0v8h8v-8h-8zm0 8h-8v8h8v-8z" fill="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9994"/>
+</svg>
diff --git a/editor/icons/icon_shader_material.svg b/editor/icons/icon_shader_material.svg
new file mode 100644
index 0000000000..f77aa837c5
--- /dev/null
+++ b/editor/icons/icon_shader_material.svg
@@ -0,0 +1,11 @@
+<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 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h2 6 3l-2-2h-8z" fill="#ff7070"/>
+<path transform="translate(0 1036.4)" d="m1 3v2h2v-2h-2zm8 0v2h5l-2-2h-3z" fill="#ffeb70"/>
+<path transform="translate(0 1036.4)" d="m1 5v2h2v-2h-2zm8 0v1c0 0.554 0.44599 1 1 1h3 2v-1l-1-1h-5z" fill="#9dff70"/>
+<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#70ffb9"/>
+<path transform="translate(0 1036.4)" d="m1 9v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#70deff"/>
+<path transform="translate(0 1036.4)" d="m1 13v1c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-1h-2-10-2z" fill="#ff70ac"/>
+<path transform="translate(0 1036.4)" d="m1 11v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#9f70ff"/>
+</g>
+</svg>
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 21cf08f524..831eb74b66 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -55,8 +55,8 @@ Error EditorSceneImporterGLTF::_parse_glb(const String &p_path, GLTFState &state
uint32_t magic = f->get_32();
ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF
- uint32_t version = f->get_32();
- uint32_t length = f->get_32();
+ f->get_32(); // version
+ f->get_32(); // length
uint32_t chunk_length = f->get_32();
uint32_t chunk_type = f->get_32();
@@ -1945,7 +1945,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
bool last = false;
while (true) {
- float value = _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
+ _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation);
if (last) {
break;
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 594728d2e0..cc519c1c4b 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -40,6 +40,8 @@
#include "scene/3d/portal.h"
#include "scene/3d/room_instance.h"
#include "scene/3d/vehicle_body.h"
+#include "scene/animation/animation_player.h"
+#include "scene/resources/animation.h"
#include "scene/resources/box_shape.h"
#include "scene/resources/plane_shape.h"
#include "scene/resources/ray_shape.h"
@@ -118,9 +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_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_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes");
case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials");
}
@@ -230,8 +236,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Array
if (isroot)
return p_node;
-
- if (MeshInstance *mi = Object::cast_to<MeshInstance>(p_node)) {
+ MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ if (mi) {
Node *col = mi->create_trimesh_collision_node();
ERR_FAIL_COND_V(!col, NULL);
@@ -810,12 +816,33 @@ static String _make_extname(const String &p_str) {
return ext_name;
}
-void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
+void ResourceImporterScene::_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) {
List<PropertyInfo> pi;
print_line("node: " + String(p_node->get_name()));
+ if (p_make_animations) {
+ if (Object::cast_to<AnimationPlayer>(p_node)) {
+ AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
+
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
+
+ Ref<Animation> anim = ap->get_animation(E->get());
+ ERR_CONTINUE(anim.is_null());
+
+ if (!p_animations.has(anim)) {
+
+ String ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim");
+ ResourceSaver::save(ext_name, anim, ResourceSaver::FLAG_CHANGE_PATH);
+ p_animations[anim] = anim;
+ }
+ }
+ }
+ }
+
p_node->get_property_list(&pi);
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
@@ -907,7 +934,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
for (int i = 0; i < p_node->get_child_count(); i++) {
- _make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes);
+ _make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes);
}
}
@@ -927,9 +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;
- bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS;
+ 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 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;
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));
@@ -943,6 +971,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), animations_out ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_angular_error"), 0.01));
@@ -1024,7 +1053,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
String root_type = p_options["nodes/root_type"];
if (scene->get_class() != root_type) {
- Node *base_node = base_node = Object::cast_to<Node>(ClassDB::instance(root_type));
+ Node *base_node = Object::cast_to<Node>(ClassDB::instance(root_type));
if (base_node) {
@@ -1078,13 +1107,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
_filter_tracks(scene, animation_filter);
}
+ bool external_animations = int(p_options["animation/storage"]) == 1;
bool external_materials = p_options["materials/storage"];
bool external_meshes = p_options["meshes/storage"];
bool external_scenes = int(p_options["nodes/storage"]) == 1;
String base_path = p_source_file.get_base_dir();
- if (external_materials || external_meshes || external_scenes) {
+ if (external_animations || external_materials || external_meshes || external_scenes) {
if (bool(p_options["external_files/store_in_subdir"])) {
String subdir_name = p_source_file.get_file().get_basename();
@@ -1097,13 +1127,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
}
}
- if (external_materials || external_meshes) {
+ if (external_animations || external_materials || external_meshes) {
+ Map<Ref<Animation>, Ref<Animation> > anim_map;
Map<Ref<Material>, Ref<Material> > mat_map;
Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map;
bool keep_materials = bool(p_options["materials/keep_on_reimport"]);
- _make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map);
+ _make_external_resources(scene, base_path, external_animations, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map);
}
progress.step(TTR("Running Custom Script.."), 2);
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 9c3d5e7876..652977b98a 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -85,8 +85,15 @@ class ResourceImporterScene : public ResourceImporter {
enum Presets {
PRESET_SEPARATE_MATERIALS,
PRESET_SEPARATE_MESHES,
+ PRESET_SEPERATE_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_MULTIPLE_SCENES,
PRESET_MULTIPLE_SCENES_AND_MATERIALS,
};
@@ -112,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_materials, bool p_keep_materials, bool p_make_meshes, 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/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index e2bacd70e4..025dbbaacf 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -103,7 +103,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
}
/* GET FILESIZE */
- uint32_t filesize = file->get_32();
+ file->get_32(); // filesize
/* CHECK WAVE */
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index cc7fc57cde..d7762a66df 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -55,79 +55,87 @@ void AnimationPlayerEditor::_gui_input(Ref<InputEvent> p_event) {
}
void AnimationPlayerEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
- if (p_what == NOTIFICATION_PROCESS) {
-
- if (!player)
- return;
+ if (!player)
+ return;
- updating = true;
+ updating = true;
- if (player->is_playing()) {
+ if (player->is_playing()) {
- {
- String animname = player->get_current_animation();
+ {
+ String animname = player->get_current_animation();
- if (player->has_animation(animname)) {
- Ref<Animation> anim = player->get_animation(animname);
- if (!anim.is_null()) {
+ if (player->has_animation(animname)) {
+ Ref<Animation> anim = player->get_animation(animname);
+ if (!anim.is_null()) {
- frame->set_max(anim->get_length());
+ frame->set_max(anim->get_length());
+ }
}
}
+ frame->set_value(player->get_current_animation_pos());
+ key_editor->set_anim_pos(player->get_current_animation_pos());
+ EditorNode::get_singleton()->get_property_editor()->refresh();
+
+ } else if (last_active) {
+ //need the last frame after it stopped
+
+ frame->set_value(player->get_current_animation_pos());
}
- frame->set_value(player->get_current_animation_pos());
- key_editor->set_anim_pos(player->get_current_animation_pos());
- EditorNode::get_singleton()->get_property_editor()->refresh();
- } else if (last_active) {
- //need the last frame after it stopped
+ last_active = player->is_playing();
+ //seek->set_val(player->get_position());
+ updating = false;
- frame->set_value(player->get_current_animation_pos());
- }
+ } break;
- last_active = player->is_playing();
- //seek->set_val(player->get_position());
- updating = false;
- }
+ case NOTIFICATION_ENTER_TREE: {
+
+ save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu");
+
+ tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu");
+
+ blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed");
- if (p_what == NOTIFICATION_ENTER_TREE) {
-
- //editor->connect("hide_animation_player_editors",this,"_hide_anim_editors");
- add_anim->set_icon(get_icon("New", "EditorIcons"));
- rename_anim->set_icon(get_icon("Rename", "EditorIcons"));
- duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons"));
- autoplay->set_icon(get_icon("AutoPlay", "EditorIcons"));
- load_anim->set_icon(get_icon("Folder", "EditorIcons"));
- save_anim->set_icon(get_icon("Save", "EditorIcons"));
- save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu");
- remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
-
- blend_anim->set_icon(get_icon("Blend", "EditorIcons"));
- play->set_icon(get_icon("PlayStart", "EditorIcons"));
- play_from->set_icon(get_icon("Play", "EditorIcons"));
- play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons"));
- play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons"));
-
- autoplay_icon = get_icon("AutoPlay", "EditorIcons");
- stop->set_icon(get_icon("Stop", "EditorIcons"));
- resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons"));
- pin->set_icon(get_icon("Pin", "EditorIcons"));
- tool_anim->set_icon(get_icon("Tools", "EditorIcons"));
- tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu");
-
- blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed");
-
- /*
- anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons"));
- anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons"));
- anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons"));
- anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons"));
- anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons"));
- anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons"));
-*/
-
- get_tree()->connect("node_removed", this, "_node_removed");
+ 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: {
+
+ add_anim->set_icon(get_icon("New", "EditorIcons"));
+ rename_anim->set_icon(get_icon("Rename", "EditorIcons"));
+ duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons"));
+ autoplay->set_icon(get_icon("AutoPlay", "EditorIcons"));
+ load_anim->set_icon(get_icon("Folder", "EditorIcons"));
+ save_anim->set_icon(get_icon("Save", "EditorIcons"));
+
+ remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
+
+ blend_anim->set_icon(get_icon("Blend", "EditorIcons"));
+ play->set_icon(get_icon("PlayStart", "EditorIcons"));
+ play_from->set_icon(get_icon("Play", "EditorIcons"));
+ play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons"));
+ play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons"));
+
+ autoplay_icon = get_icon("AutoPlay", "EditorIcons");
+ stop->set_icon(get_icon("Stop", "EditorIcons"));
+ resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons"));
+ pin->set_icon(get_icon("Pin", "EditorIcons"));
+ tool_anim->set_icon(get_icon("Tools", "EditorIcons"));
+
+ } break;
}
}
@@ -1176,7 +1184,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
set_focus_mode(FOCUS_ALL);
player = NULL;
- add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel"));
Label *l;
@@ -1376,7 +1383,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
key_editor = memnew(AnimationKeyEditor);
add_child(key_editor);
- add_constant_override("separation", get_constant("separation", "VBoxContainer"));
key_editor->set_v_size_flags(SIZE_EXPAND_FILL);
key_editor->connect("timeline_changed", this, "_animation_key_editor_seek");
key_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_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 df4598793c..b28da54c6d 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -580,7 +580,8 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE
} else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT
- if (Node2D *node_2d = Object::cast_to<Node2D>(canvas_item)) {
+ Node2D *node_2d = Object::cast_to<Node2D>(canvas_item);
+ if (node_2d) {
if (p_move_mode == MOVE_LOCAL_WITH_ROT) {
Transform2D m;
@@ -589,9 +590,10 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE
}
node_2d->set_position(node_2d->get_position() + drag);
- } else if (Control *control = Object::cast_to<Control>(canvas_item)) {
-
- control->set_position(control->get_position() + drag);
+ } else {
+ Control *control = Object::cast_to<Control>(canvas_item);
+ if (control)
+ control->set_position(control->get_position() + drag);
}
}
}
@@ -742,7 +744,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op
float radius = 0.05 / zoom;
float basic_anchors[3] = { 0.0, 0.5, 1.0 };
for (int i = 0; i < 3; i++) {
- if ((dist = fabs(p_anchor - basic_anchors[i])) < radius) {
+ dist = fabs(p_anchor - basic_anchors[i]);
+ if (dist < radius) {
if (!snapped || dist <= dist_min) {
p_anchor = basic_anchors[i];
dist_min = dist;
@@ -750,7 +753,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op
}
}
}
- if (p_opposite_anchor >= 0 && (dist = fabs(p_anchor - p_opposite_anchor)) < radius) {
+ 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;
@@ -841,6 +845,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])) {
@@ -1407,6 +1413,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;
}
@@ -1428,6 +1435,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;
}
@@ -1437,6 +1445,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
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;
}
}
@@ -1515,7 +1524,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
}
if (drag == DRAG_NONE) {
- if ((m->get_button_mask() & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m->get_button_mask() & BUTTON_MASK_MIDDLE || (m->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
+ if (((m->get_button_mask() & BUTTON_MASK_LEFT) && tool == TOOL_PAN) || (m->get_button_mask() & BUTTON_MASK_MIDDLE) || ((m->get_button_mask() & BUTTON_MASK_LEFT) && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
// Pan the viewport
Point2i relative;
if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
@@ -1989,6 +1998,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);
@@ -2269,6 +2295,8 @@ void CanvasItemEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_FIXED_PROCESS) {
+ EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
+
List<Node *> &selection = editor_selection->get_selected_node_list();
bool all_control = true;
@@ -2295,19 +2323,24 @@ 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;
se->prev_pivot = pivot;
se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT];
se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT];
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 2e1a2eac5f..f61bfc9ebb 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; }
};
@@ -315,7 +317,7 @@ 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);
+ float _anchor_snap(float p_anchor, bool *p_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);
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 f7008298f0..3917c700f0 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -395,7 +395,7 @@ bool Polygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid()) {
- if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
+ if (edited_point != -1 && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) {
Vector2 gpoint = mm->get_position();
Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
@@ -554,7 +554,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
if (mm.is_valid()) {
- if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+ if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
Vector2 drag(mm->get_relative().x, mm->get_relative().y);
uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 04be1ba4ab..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);
@@ -2416,6 +2484,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
use_space_indentation = false;
ScriptServer::edit_request_func = _open_script_request;
+
+ add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
+ tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditor", "EditorStyles"));
}
ScriptEditor::~ScriptEditor() {
@@ -2517,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 fae57eb5d2..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();
@@ -624,7 +680,7 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<String>
}
String hint;
Error err = script->get_language()->complete_code(p_code, script->get_path().get_base_dir(), base, r_options, r_force, hint);
- if (hint != "") {
+ if (err == OK && hint != "") {
code_editor->get_text_edit()->set_code_hint(hint);
}
}
@@ -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 b02016c273..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);
@@ -164,6 +225,8 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<String>
String calltip;
Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip);
+ if (err != OK)
+ ERR_PRINT("Shaderlang complete failed");
if (calltip != "") {
get_text_edit()->set_code_hint(calltip);
@@ -403,13 +466,7 @@ void ShaderEditorPlugin::edit(Object *p_object) {
bool ShaderEditorPlugin::handles(Object *p_object) const {
- bool handles = true;
Shader *shader = Object::cast_to<Shader>(p_object);
- /*
- if (Object::cast_to<ShaderGraph>(shader)) // Don't handle ShaderGraph's
- handles = false;
- */
-
return shader != NULL;
}
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index a5f55835f0..a6ab36ed27 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -76,40 +76,46 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
} else
camera->set_perspective(get_fov(), get_znear(), get_zfar());
- Transform new_transform = to_camera_transform(cursor);
- Transform old_transform = camera->get_global_transform();
- Transform transform;
+ //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);
- 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);
+ //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);
- if (p_interp_delta && !disable_interp) {
- //interpolate
- float interp_speed = 14; //maybe should be made configuration
- transform = old_transform.interpolate_with(new_transform, MIN(1.0, p_interp_delta * interp_speed));
- } else {
- transform = new_transform;
+ 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, 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)));
+
+ 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 || is_freelook_active()) {
+ camera_cursor = cursor;
}
float tolerance = 0.0001;
bool equal = true;
- for (int i = 0; i < 3; i++) {
- if (transform.basis[i].distance_to(old_transform.basis[i]) > tolerance) {
- equal = false;
- break;
- }
- }
+ if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance)
+ equal = false;
- if (equal && transform.origin.distance_to(old_transform.origin) > tolerance) {
+ if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance)
equal = false;
- }
- if (equal) {
- transform = new_transform;
- }
+ if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance)
+ equal = false;
- if (!equal || p_interp_delta == 0) {
- //print_line(transform);
- camera->set_global_transform(transform);
+ if (!equal || p_interp_delta == 0 || is_freelook_active()) {
+
+ camera->set_global_transform(to_camera_transform(camera_cursor));
update_transform_gizmo_view();
}
}
@@ -1540,6 +1546,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
Vector3 diff = camera->get_translation() - pos;
cursor.pos += diff;
+ freelook_target_position += diff;
name = "";
_update_name();
@@ -1661,7 +1668,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
Point2i relative;
- if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) {
+ if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) {
relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
} else {
relative = p_ev_mouse_motion->get_relative();
@@ -1672,7 +1679,7 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous
void SpatialEditorViewport::_update_freelook(real_t delta) {
if (!is_freelook_active()) {
- freelook_velocity = Vector3();
+ freelook_target_position = cursor.pos;
return;
}
@@ -1689,60 +1696,47 @@ void SpatialEditorViewport::_update_freelook(real_t delta) {
int key_speed_modifier = Object::cast_to<InputEventKey>(ED_GET_SHORTCUT("spatial_editor/freelook_speed_modifier")->get_shortcut().ptr())->get_scancode();
Vector3 direction;
- bool pressed = false;
bool speed_modifier = false;
const Input &input = *Input::get_singleton();
if (input.is_key_pressed(key_left)) {
direction -= right;
- pressed = true;
}
if (input.is_key_pressed(key_right)) {
direction += right;
- pressed = true;
}
if (input.is_key_pressed(key_forward)) {
direction += forward;
- pressed = true;
}
if (input.is_key_pressed(key_backwards)) {
direction -= forward;
- pressed = true;
}
if (input.is_key_pressed(key_up)) {
direction += up;
- pressed = true;
}
if (input.is_key_pressed(key_down)) {
direction -= up;
- pressed = true;
}
if (input.is_key_pressed(key_speed_modifier)) {
speed_modifier = true;
}
- const EditorSettings &s = *EditorSettings::get_singleton();
- real_t inertia = s.get("editors/3d/freelook_inertia");
- if (inertia < 0)
- inertia = 0;
-
- const real_t base_speed = s.get("editors/3d/freelook_base_speed");
- const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor");
+ real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2);
+ inertia = MAX(0, inertia);
+ const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5);
+ const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5);
real_t speed = base_speed * cursor.distance;
if (speed_modifier)
speed *= modifier_speed_factor;
- Vector3 instant_velocity = direction * speed;
-
// Higher inertia should increase "lag" (lerp with factor between 0 and 1)
- // Inertia of zero should produce instant movement (lerp with factor of 1)
- // Takes reference of 60fps for units, so that inertia of 1 gives approximate lerp factor of 0.5
- real_t factor = 1.0 / (1.0 + inertia * delta * 60.f);
- freelook_velocity = freelook_velocity.linear_interpolate(instant_velocity, CLAMP(factor, 0, 1));
+ // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
- cursor.pos += freelook_velocity * delta;
+ freelook_target_position += direction * speed;
+ real_t factor = (1.0 / (inertia + 0.001)) * delta;
+ cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1));
}
void SpatialEditorViewport::set_message(String p_message, float p_time) {
@@ -2528,7 +2522,6 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
found_gizmos.insert(seg);
- int handle = -1;
Vector3 hit_point;
Vector3 hit_normal;
bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false);
@@ -2861,8 +2854,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);
@@ -3423,13 +3416,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
settings_znear->set_value(float(d["znear"]));
if (d.has("fov"))
settings_fov->set_value(float(d["fov"]));
-
- if (d.has("default_srgb")) {
- bool use = d["default_srgb"];
-
- //viewport_environment->set_enable_fx(Environment::FX_SRGB,use);
- //view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use );
- }
if (d.has("show_grid")) {
bool use = d["show_grid"];
@@ -3721,18 +3707,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/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index db5abe2b53..5f3ef2dbee 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -131,7 +131,7 @@ private:
float gizmo_scale;
bool freelook_active;
- Vector3 freelook_velocity;
+ Vector3 freelook_target_position;
PanelContainer *info;
Label *info_label;
@@ -239,7 +239,7 @@ private:
distance = 4;
region_select = false;
}
- } cursor;
+ } cursor, camera_cursor;
void scale_cursor_distance(real_t scale);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index f943ee5f6d..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;
@@ -550,7 +558,6 @@ void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i &p_point, bool
PoolVector<Vector2> points = _bucket_fill(p_point, false, true);
PoolVector<Vector2>::Read pr = points.read();
int len = points.size();
- int time_after = OS::get_singleton()->get_ticks_msec();
for (int i = 0; i < len; ++i) {
_draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform);
@@ -704,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) {
@@ -802,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;
@@ -1047,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);
@@ -1459,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);
@@ -1513,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 d649afc594..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);
}
@@ -425,9 +425,10 @@ void ProjectExportDialog::_delete_preset_confirm() {
int idx = presets->get_current();
parameters->edit(NULL); //to avoid crash
+ _edit_preset(-1);
EditorExport::get_singleton()->remove_export_preset(idx);
_update_presets();
- _edit_preset(-1);
+ _edit_preset(presets->get_current());
}
Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
@@ -732,6 +733,8 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
ERR_FAIL_COND(platform.is_null());
Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0);
+ if (err != OK)
+ ERR_PRINT("Failed to export project");
}
void ProjectExportDialog::_bind_methods() {
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 323a36154e..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");
@@ -449,13 +531,15 @@ struct ProjectItem {
String conf;
uint64_t last_modified;
bool favorite;
+ bool grayed;
ProjectItem() {}
- ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false) {
+ ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false) {
project = p_project;
path = p_path;
conf = p_conf;
last_modified = p_last_modified;
favorite = p_favorite;
+ grayed = p_grayed;
}
_FORCE_INLINE_ bool operator<(const ProjectItem &l) const { return last_modified > l.last_modified; }
_FORCE_INLINE_ bool operator==(const ProjectItem &l) const { return project == l.project; }
@@ -465,7 +549,7 @@ void ProjectManager::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- Engine::get_singleton()->set_editor_hint(true);
+ Engine::get_singleton()->set_editor_hint(false);
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
@@ -493,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) {
@@ -737,6 +822,7 @@ void ProjectManager::_load_recent_projects() {
String project = _name.get_slice("/", 1);
String conf = path.plus_file("project.godot");
bool favorite = (_name.begins_with("favorite_projects/")) ? true : false;
+ bool grayed = false;
uint64_t last_modified = 0;
if (FileAccess::exists(conf)) {
@@ -748,16 +834,15 @@ void ProjectManager::_load_recent_projects() {
if (cache_modified > last_modified)
last_modified = cache_modified;
}
-
- ProjectItem item(project, path, conf, last_modified, favorite);
- if (favorite)
- favorite_projects.push_back(item);
- else
- projects.push_back(item);
} else {
- //project doesn't exist on disk but it's in the XML settings file
- EditorSettings::get_singleton()->erase(_name); //remove it
+ grayed = true;
}
+
+ ProjectItem item(project, path, conf, last_modified, favorite, grayed);
+ if (favorite)
+ favorite_projects.push_back(item);
+ else
+ projects.push_back(item);
}
projects.sort();
@@ -782,14 +867,14 @@ void ProjectManager::_load_recent_projects() {
String path = item.path;
String conf = item.conf;
bool is_favorite = item.favorite;
+ bool is_grayed = item.grayed;
Ref<ConfigFile> cf = memnew(ConfigFile);
- Error err = cf->load(conf);
- ERR_CONTINUE(err != OK);
+ Error cf_err = cf->load(conf);
String project_name = TTR("Unnamed Project");
- if (cf->has_section_key("application", "config/name")) {
+ if (cf_err == OK && cf->has_section_key("application", "config/name")) {
project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape();
}
@@ -797,7 +882,7 @@ void ProjectManager::_load_recent_projects() {
continue;
Ref<Texture> icon;
- if (cf->has_section_key("application", "config/icon")) {
+ if (cf_err == OK && cf->has_section_key("application", "config/icon")) {
String appicon = cf->get_value("application", "config/icon");
if (appicon != "") {
Ref<Image> img;
@@ -819,8 +904,10 @@ void ProjectManager::_load_recent_projects() {
}
String main_scene;
- if (cf->has_section_key("application", "run/main_scene")) {
+ if (cf_err == OK && cf->has_section_key("application", "run/main_scene")) {
main_scene = cf->get_value("application", "run/main_scene");
+ } else {
+ main_scene = "";
}
selected_list_copy.erase(project);
@@ -848,6 +935,8 @@ void ProjectManager::_load_recent_projects() {
hb->add_child(tf);
VBoxContainer *vb = memnew(VBoxContainer);
+ if (is_grayed)
+ vb->set_modulate(Color(0.5, 0.5, 0.5));
vb->set_name("project");
vb->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_child(vb);
@@ -883,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++) {
@@ -926,6 +1019,13 @@ void ProjectManager::_open_project_confirm() {
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);
+ String conf = path + "/project.godot";
+ if (!FileAccess::exists(conf)) {
+ dialog_error->set_text(TTR("Can't open project"));
+ dialog_error->popup_centered_minsize();
+ return;
+ }
+
print_line("OPENING: " + path + " (" + selected + ")");
List<String> args;
@@ -935,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;
@@ -986,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;
@@ -1070,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) {
@@ -1164,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);
@@ -1328,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);
@@ -1383,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();
@@ -1397,6 +1529,9 @@ ProjectManager::ProjectManager() {
run_error_diag = memnew(AcceptDialog);
gui_base->add_child(run_error_diag);
run_error_diag->set_title(TTR("Can't run project"));
+
+ dialog_error = memnew(AcceptDialog);
+ gui_base->add_child(dialog_error);
}
ProjectManager::~ProjectManager() {
diff --git a/editor/project_manager.h b/editor/project_manager.h
index ecc01955ba..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;
@@ -58,6 +59,7 @@ class ProjectManager : public Control {
ConfirmationDialog *multi_run_ask;
ConfirmationDialog *multi_scan_ask;
AcceptDialog *run_error_diag;
+ AcceptDialog *dialog_error;
NewProjectDialog *npdialog;
ScrollContainer *scroll;
VBoxContainer *scroll_childs;
@@ -78,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();
@@ -86,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/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 49687a504f..1f65589643 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -182,8 +182,8 @@ void ProjectSettingsEditor::_device_input_add() {
Ref<InputEvent> ie;
String name = add_at;
int idx = edit_idx;
- Variant old_val = ProjectSettings::get_singleton()->get(name);
- Array arr = old_val;
+ Array old_val = ProjectSettings::get_singleton()->get(name);
+ Array arr = old_val.duplicate();
switch (add_type) {
@@ -285,8 +285,8 @@ void ProjectSettingsEditor::_press_a_key_confirm() {
String name = add_at;
int idx = edit_idx;
- Variant old_val = ProjectSettings::get_singleton()->get(name);
- Array arr = old_val;
+ Array old_val = ProjectSettings::get_singleton()->get(name);
+ Array arr = old_val.duplicate();
for (int i = 0; i < arr.size(); i++) {
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index a42fb41ee2..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();
@@ -2275,19 +2275,6 @@ void PropertyEditor::_check_reload_status(const String &p_name, TreeItem *item)
}
}
- if (_might_be_in_instance()) {
-
- Variant vorig;
- Dictionary d = item->get_metadata(0);
- int usage = d.has("usage") ? int(int(d["usage"]) & (PROPERTY_USAGE_STORE_IF_NONONE | PROPERTY_USAGE_STORE_IF_NONZERO)) : 0;
-
- if (_get_instanced_node_original_property(p_name, vorig) || usage) {
- Variant v = obj->get(p_name);
-
- bool has_reload = _is_property_different(v, vorig, usage);
- }
- }
-
if (obj->call("property_can_revert", p_name).operator bool()) {
has_reload = true;
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 6bbb35ceab..86de7c56e1 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -75,6 +75,8 @@ void PropertySelector::_update_search() {
if (properties)
set_title(TTR("Select Property"));
+ else if (virtuals_only)
+ set_title(TTR("Select Virtual Method"));
else
set_title(TTR("Select Method"));
@@ -209,7 +211,7 @@ void PropertySelector::_update_search() {
StringName base = base_type;
while (base) {
methods.push_back(MethodInfo("*" + String(base)));
- ClassDB::get_method_list(base, &methods, true);
+ ClassDB::get_method_list(base, &methods, true, true);
base = ClassDB::get_parent_class(base);
}
}
@@ -230,11 +232,13 @@ void PropertySelector::_update_search() {
Ref<Texture> icon;
script_methods = false;
+ print_line("name: " + E->get().name);
+ String rep = E->get().name.replace("*", "");
if (E->get().name == "*Script Methods") {
icon = get_icon("Script", "EditorIcons");
script_methods = true;
- } else if (has_icon(E->get().name, "EditorIcons")) {
- icon = get_icon(E->get().name, "EditorIcons");
+ } else if (has_icon(rep, "EditorIcons")) {
+ icon = get_icon(rep, "EditorIcons");
} else {
icon = get_icon("Object", "EditorIcons");
}
@@ -247,6 +251,12 @@ void PropertySelector::_update_search() {
if (!script_methods && name.begins_with("_") && !(E->get().flags & METHOD_FLAG_VIRTUAL))
continue;
+ if (virtuals_only && !(E->get().flags & METHOD_FLAG_VIRTUAL))
+ continue;
+
+ if (!virtuals_only && (E->get().flags & METHOD_FLAG_VIRTUAL))
+ continue;
+
if (search_box->get_text() != String() && name.find(search_box->get_text()) == -1)
continue;
@@ -283,6 +293,12 @@ void PropertySelector::_update_search() {
desc += " )";
+ if (E->get().flags & METHOD_FLAG_CONST)
+ desc += " const";
+
+ if (E->get().flags & METHOD_FLAG_VIRTUAL)
+ desc += " virtual";
+
item->set_text(0, desc);
item->set_metadata(0, name);
item->set_selectable(0, true);
@@ -397,7 +413,7 @@ void PropertySelector::_notification(int p_what) {
}
}
-void PropertySelector::select_method_from_base_type(const String &p_base, const String &p_current) {
+void PropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only) {
base_type = p_base;
selected = p_current;
@@ -405,6 +421,7 @@ void PropertySelector::select_method_from_base_type(const String &p_base, const
script = 0;
properties = false;
instance = NULL;
+ virtuals_only = p_virtuals_only;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -421,6 +438,7 @@ void PropertySelector::select_method_from_script(const Ref<Script> &p_script, co
script = p_script->get_instance_id();
properties = false;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -436,6 +454,7 @@ void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const
script = 0;
properties = false;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -456,6 +475,7 @@ void PropertySelector::select_method_from_instance(Object *p_instance, const Str
}
properties = false;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -471,6 +491,7 @@ void PropertySelector::select_property_from_base_type(const String &p_base, cons
script = 0;
properties = true;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -488,6 +509,7 @@ void PropertySelector::select_property_from_script(const Ref<Script> &p_script,
script = p_script->get_instance_id();
properties = true;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -503,6 +525,7 @@ void PropertySelector::select_property_from_basic_type(Variant::Type p_type, con
script = 0;
properties = true;
instance = NULL;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -518,6 +541,7 @@ void PropertySelector::select_property_from_instance(Object *p_instance, const S
script = 0;
properties = true;
instance = p_instance;
+ virtuals_only = false;
popup_centered_ratio(0.6);
search_box->set_text("");
@@ -554,6 +578,7 @@ PropertySelector::PropertySelector() {
search_options->connect("cell_selected", this, "_item_selected");
search_options->set_hide_root(true);
search_options->set_hide_folding(true);
+ virtuals_only = false;
help_bit = memnew(EditorHelpBit);
vbc->add_margin_child(TTR("Description:"), help_bit);
diff --git a/editor/property_selector.h b/editor/property_selector.h
index 3fa60771d7..eb745d776f 100644
--- a/editor/property_selector.h
+++ b/editor/property_selector.h
@@ -55,6 +55,7 @@ class PropertySelector : public ConfirmationDialog {
String base_type;
ObjectID script;
Object *instance;
+ bool virtuals_only;
void _item_selected();
@@ -63,7 +64,7 @@ protected:
static void _bind_methods();
public:
- void select_method_from_base_type(const String &p_base, const String &p_current = "");
+ void select_method_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false);
void select_method_from_script(const Ref<Script> &p_script, const String &p_current = "");
void select_method_from_basic_type(Variant::Type p_type, const String &p_current = "");
void select_method_from_instance(Object *p_instance, const String &p_current = "");
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 afdf48b314..5b783493cb 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -433,7 +433,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
dup->set_name(parent->validate_child_name(dup));
- editor_data->get_undo_redo().add_do_method(parent, "_add_child_below_node", node, dup);
+ editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", node, dup);
for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
if (!duplimap.has(F->get())) {
@@ -582,13 +582,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
new_scene_from_dialog->popup_centered_ratio();
new_scene_from_dialog->set_title(TTR("Save New Scene As.."));
-
} break;
case TOOL_COPY_NODE_PATH: {
List<Node *> selection = editor_selection->get_selected_node_list();
-
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
Node *root = EditorNode::get_singleton()->get_edited_scene();
NodePath path = root->get_path().rel_path_to(node->get_path());
OS::get_singleton()->set_clipboard(path);
@@ -597,8 +597,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_EDITABLE_CHILDREN: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children"));
int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder"));
@@ -617,8 +619,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_USE_PLACEHOLDER: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
bool placeholder = node->get_scene_instance_load_placeholder();
placeholder = !placeholder;
int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children"));
@@ -635,15 +639,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_CLEAR_INSTANCING: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
Node *root = EditorNode::get_singleton()->get_edited_scene();
UndoRedo *undo_redo = &editor_data->get_undo_redo();
if (!root)
break;
ERR_FAIL_COND(node->get_filename() == String());
-
undo_redo->create_action(TTR("Discard Instancing"));
undo_redo->add_do_method(node, "set_filename", "");
undo_redo->add_undo_method(node, "set_filename", node->get_filename());
@@ -656,8 +661,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_OPEN: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
scene_tree->emit_signal("open", node->get_filename());
}
}
@@ -667,8 +674,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
node->set_scene_inherited_state(Ref<SceneState>());
scene_tree->update_tree();
EditorNode::get_singleton()->get_property_editor()->update_tree();
@@ -677,8 +686,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_SCENE_OPEN_INHERITED: {
List<Node *> selection = editor_selection->get_selected_node_list();
- if (List<Node *>::Element *e = selection.front()) {
- if (Node *node = e->get()) {
+ List<Node *>::Element *e = selection.front();
+ if (e) {
+ Node *node = e->get();
+ if (node) {
if (node && node->get_scene_inherited_state().is_valid()) {
scene_tree->emit_signal("open", node->get_scene_inherited_state()->get_path());
}
@@ -823,7 +834,14 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node *, Node *> &duplimap) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
continue;
String name = E->get().name;
- node->set(name, p_node->get(name));
+ Variant value = p_node->get(name);
+ // Duplicate dictionaries and arrays, mainly needed for __meta__
+ if (value.get_type() == Variant::DICTIONARY) {
+ value = Dictionary(value).copy();
+ } else if (value.get_type() == Variant::ARRAY) {
+ value = Array(value).duplicate();
+ }
+ node->set(name, value);
}
List<Node::GroupInfo> group_info;
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);