summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/connections_dialog.cpp16
-rw-r--r--editor/editor_export.cpp5
-rw-r--r--editor/editor_inspector.cpp135
-rw-r--r--editor/editor_inspector.h15
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/editor_node.h1
-rw-r--r--editor/editor_properties.cpp242
-rw-r--r--editor/editor_properties.h28
-rw-r--r--editor/editor_spin_slider.cpp73
-rw-r--r--editor/editor_spin_slider.h9
-rw-r--r--editor/editor_themes.cpp9
-rw-r--r--editor/export_template_manager.cpp13
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/icons/icon_GUI_tree_arrow_up.svg60
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp284
-rw-r--r--editor/plugins/audio_stream_editor_plugin.h93
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp55
-rw-r--r--editor/plugins/path_2d_editor_plugin.h12
-rw-r--r--editor/plugins/path_editor_plugin.cpp65
-rw-r--r--editor/plugins/path_editor_plugin.h19
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--editor/project_export.cpp7
-rw-r--r--editor/project_settings_editor.cpp11
-rw-r--r--editor/spatial_editor_gizmos.cpp8
24 files changed, 1046 insertions, 136 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 7f93917744..8933fd7fe8 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -428,6 +428,13 @@ void ConnectionsDock::_make_or_edit_connection() {
bool oshot = connect_dialog->get_oneshot();
cToMake.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
+ bool add_script_function = connect_dialog->get_make_callback();
+ PoolStringArray script_function_args;
+ if (add_script_function) {
+ // pick up args here before "it" is deleted by update_tree
+ script_function_args = it->get_metadata(0).operator Dictionary()["args"];
+ }
+
if (connect_dialog->is_editing()) {
_disconnect(*it);
_connect(cToMake);
@@ -435,9 +442,12 @@ void ConnectionsDock::_make_or_edit_connection() {
_connect(cToMake);
}
- if (connect_dialog->get_make_callback()) {
- PoolStringArray args = it->get_metadata(0).operator Dictionary()["args"];
- editor->emit_signal("script_add_function_request", target, cToMake.method, args);
+ // IMPORTANT NOTE: _disconnect and _connect cause an update_tree,
+ // which will delete the object "it" is pointing to
+ it = NULL;
+
+ if (add_script_function) {
+ editor->emit_signal("script_add_function_request", target, cToMake.method, script_function_args);
hide();
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 7739b08eff..317fffad64 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -409,6 +409,7 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
String cur_dir = da->get_current_dir().replace("\\", "/");
if (!cur_dir.ends_with("/"))
cur_dir += "/";
+ String cur_dir_no_prefix = cur_dir.replace("res://", "");
Vector<String> dirs;
String f;
@@ -417,8 +418,10 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
dirs.push_back(f);
else {
String fullpath = cur_dir + f;
+ // Test also against path without res:// so that filters like `file.txt` can work.
+ String fullpath_no_prefix = cur_dir_no_prefix + f;
for (int i = 0; i < p_filters.size(); ++i) {
- if (fullpath.matchn(p_filters[i])) {
+ if (fullpath.matchn(p_filters[i]) || fullpath_no_prefix.matchn(p_filters[i])) {
if (!exclude) {
r_list.insert(fullpath);
} else {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 17f383c8ae..482b0dec35 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -91,6 +91,9 @@ void EditorProperty::_notification(int p_what) {
Rect2 rect;
Rect2 bottom_rect;
+ right_child_rect = Rect2();
+ bottom_child_rect = Rect2();
+
{
int child_room = size.width * (1.0 - split_ratio);
Ref<Font> font = get_font("font", "Tree");
@@ -118,7 +121,8 @@ void EditorProperty::_notification(int p_what) {
if (bottom_editor) {
- int m = get_constant("item_margin", "Tree");
+ int m = 0; //get_constant("item_margin", "Tree");
+
bottom_rect = Rect2(m, rect.size.height + get_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height);
}
}
@@ -147,10 +151,12 @@ void EditorProperty::_notification(int p_what) {
continue;
fit_child_in_rect(c, rect);
+ right_child_rect = rect;
}
if (bottom_editor) {
fit_child_in_rect(bottom_editor, bottom_rect);
+ bottom_child_rect = bottom_rect;
}
update(); //need to redraw text
@@ -158,6 +164,7 @@ void EditorProperty::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
Ref<Font> font = get_font("font", "Tree");
+ Color dark_color = get_color("dark_color_2", "Editor");
Size2 size = get_size();
if (bottom_editor) {
@@ -171,6 +178,13 @@ void EditorProperty::_notification(int p_what) {
draw_style_box(sb, Rect2(Vector2(), size));
}
+ if (right_child_rect != Rect2()) {
+ draw_rect(right_child_rect, dark_color);
+ }
+ if (bottom_child_rect != Rect2()) {
+ draw_rect(bottom_child_rect, dark_color);
+ }
+
Color color;
if (draw_red) {
color = get_color("error_color", "Editor");
@@ -251,7 +265,7 @@ void EditorProperty::_notification(int p_what) {
//int vs = get_constant("vseparation", "Tree");
Color guide_color = get_color("guide_color", "Tree");
int vs_height = get_size().height; // vs / 2;
- draw_line(Point2(0, vs_height), Point2(get_size().width, vs_height), guide_color);
+ // draw_line(Point2(0, vs_height), Point2(get_size().width, vs_height), guide_color);
}
}
@@ -926,6 +940,14 @@ EditorInspectorCategory::EditorInspectorCategory() {
////////////////////////////////////////////////
////////////////////////////////////////////////
+void EditorInspectorSection::_test_unfold() {
+
+ if (!vbox_added) {
+ add_child(vbox);
+ vbox_added = true;
+ }
+}
+
void EditorInspectorSection::_notification(int p_what) {
if (p_what == NOTIFICATION_SORT_CHILDREN) {
@@ -936,9 +958,9 @@ void EditorInspectorSection::_notification(int p_what) {
#ifdef TOOLS_ENABLED
if (foldable) {
if (object->editor_is_section_unfolded(section)) {
- arrow = get_icon("arrow", "Tree");
+ arrow = get_icon("arrow_up", "Tree");
} else {
- arrow = get_icon("arrow_collapsed", "Tree");
+ arrow = get_icon("arrow", "Tree");
}
}
#endif
@@ -951,7 +973,7 @@ void EditorInspectorSection::_notification(int p_what) {
}
offset.y += get_constant("vseparation", "Tree");
- offset.x += get_constant("item_margin", "Tree");
+ offset.x += get_constant("inspector_margin", "Editor");
Rect2 rect(offset, size - offset);
@@ -979,9 +1001,9 @@ void EditorInspectorSection::_notification(int p_what) {
#ifdef TOOLS_ENABLED
if (foldable) {
if (object->editor_is_section_unfolded(section)) {
- arrow = get_icon("arrow", "Tree");
+ arrow = get_icon("arrow_up", "Tree");
} else {
- arrow = get_icon("arrow_collapsed", "Tree");
+ arrow = get_icon("arrow", "Tree");
}
}
#endif
@@ -998,14 +1020,14 @@ void EditorInspectorSection::_notification(int p_what) {
int hs = get_constant("hseparation", "Tree");
+ Color color = get_color("font_color", "Tree");
+ draw_string(font, Point2(hs, font->get_ascent() + (h - font->get_height()) / 2).floor(), label, color, get_size().width);
+
int ofs = 0;
if (arrow.is_valid()) {
- draw_texture(arrow, Point2(ofs, (h - arrow->get_height()) / 2).floor());
+ draw_texture(arrow, Point2(get_size().width - arrow->get_width(), (h - arrow->get_height()) / 2).floor());
ofs += hs + arrow->get_width();
}
-
- Color color = get_color("font_color", "Tree");
- draw_string(font, Point2(ofs, font->get_ascent() + (h - font->get_height()) / 2).floor(), label, color, get_size().width);
}
}
@@ -1027,8 +1049,8 @@ Size2 EditorInspectorSection::get_minimum_size() const {
}
Ref<Font> font = get_font("font", "Tree");
- ms.height += font->get_ascent() + get_constant("vseparation", "Tree");
- ms.width += get_constant("item_margin", "Tree");
+ ms.height += font->get_height() + get_constant("vseparation", "Tree");
+ ms.width += get_constant("inspector_margin", "Editor");
return ms;
}
@@ -1041,16 +1063,20 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
bg_color = p_bg_color;
foldable = p_foldable;
+ if (!foldable && !vbox_added) {
+ add_child(vbox);
+ vbox_added = true;
+ }
+
#ifdef TOOLS_ENABLED
if (foldable) {
+ _test_unfold();
if (object->editor_is_section_unfolded(section)) {
vbox->show();
} else {
vbox->hide();
}
}
- // void editor_set_section_unfold(const String &p_section, bool p_unfolded);
-
#endif
}
@@ -1063,6 +1089,9 @@ void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+
+ _test_unfold();
+
bool unfold = !object->editor_is_section_unfolded(section);
object->editor_set_section_unfold(section, unfold);
if (unfold) {
@@ -1082,6 +1111,9 @@ void EditorInspectorSection::unfold() {
if (!foldable)
return;
+
+ _test_unfold();
+
#ifdef TOOLS_ENABLED
object->editor_set_section_unfold(section, true);
@@ -1094,6 +1126,8 @@ void EditorInspectorSection::fold() {
if (!foldable)
return;
+ if (!vbox_added)
+ return; //kinda pointless
#ifdef TOOLS_ENABLED
object->editor_set_section_unfold(section, false);
@@ -1115,7 +1149,14 @@ EditorInspectorSection::EditorInspectorSection() {
object = NULL;
foldable = false;
vbox = memnew(VBoxContainer);
- add_child(vbox);
+ vbox_added = false;
+ //add_child(vbox);
+}
+
+EditorInspectorSection::~EditorInspectorSection() {
+ if (!vbox_added) {
+ memdelete(vbox);
+ }
}
////////////////////////////////////////////////
@@ -1276,8 +1317,10 @@ void EditorInspector::update_tree() {
String filter = search_box ? search_box->get_text() : "";
String group;
String group_base;
+ VBoxContainer *category_vbox = NULL;
- List<PropertyInfo> plist;
+ List<PropertyInfo>
+ plist;
object->get_property_list(&plist, true);
HashMap<String, VBoxContainer *> item_path;
@@ -1329,6 +1372,7 @@ void EditorInspector::update_tree() {
EditorInspectorCategory *category = memnew(EditorInspectorCategory);
main_vbox->add_child(category);
+ category_vbox = NULL; //reset
String type = p.name;
if (has_icon(type, "EditorIcons"))
@@ -1414,6 +1458,11 @@ void EditorInspector::update_tree() {
continue;
}
+ if (category_vbox == NULL) {
+ category_vbox = memnew(VBoxContainer);
+ main_vbox->add_child(category_vbox);
+ }
+
VBoxContainer *current_vbox = main_vbox;
{
@@ -1441,6 +1490,14 @@ void EditorInspector::update_tree() {
current_vbox = item_path[acc_path];
level = (MIN(level + 1, 4));
}
+
+ if (current_vbox == main_vbox) {
+ //do not add directly to the main vbox, given it has no spacing
+ if (category_vbox == NULL) {
+ category_vbox = memnew(VBoxContainer);
+ }
+ current_vbox = category_vbox;
+ }
}
bool checkable = false;
@@ -1627,6 +1684,10 @@ void EditorInspector::edit(Object *p_object) {
object = p_object;
if (object) {
+ update_scroll_request = 0; //reset
+ if (scroll_cache.has(object->get_instance_id())) { //if exists, set something else
+ update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accomodated
+ }
object->add_change_receptor(this);
update_tree();
}
@@ -1732,6 +1793,19 @@ int EditorInspector::get_scroll_offset() const {
return get_v_scroll();
}
+void EditorInspector::set_use_sub_inspector_bg(bool p_enable) {
+
+ use_sub_inspector_bg = p_enable;
+ if (!is_inside_tree())
+ return;
+
+ if (use_sub_inspector_bg) {
+ add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
+ } else {
+ add_style_override("bg", get_stylebox("bg", "Tree"));
+ }
+}
+
void EditorInspector::_edit_request_change(Object *p_object, const String &p_property) {
if (object != p_object) //may be undoing/redoing for a non edited object, so ignore
@@ -1942,7 +2016,11 @@ void EditorInspector::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
get_tree()->connect("node_removed", this, "_node_removed");
- add_style_override("bg", get_stylebox("bg", "Tree"));
+ if (use_sub_inspector_bg) {
+ add_style_override("bg", get_stylebox("sub_inspector_bg", "Editor"));
+ } else if (is_inside_tree()) {
+ add_style_override("bg", get_stylebox("bg", "Tree"));
+ }
}
if (p_what == NOTIFICATION_EXIT_TREE) {
@@ -1952,6 +2030,10 @@ void EditorInspector::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
+ if (update_scroll_request >= 0) {
+ get_v_scrollbar()->call_deferred("set_value", update_scroll_request);
+ update_scroll_request = -1;
+ }
if (refresh_countdown > 0) {
refresh_countdown -= get_process_delta_time();
if (refresh_countdown <= 0) {
@@ -1999,6 +2081,16 @@ void EditorInspector::_changed_callback(Object *p_changed, const char *p_prop) {
_edit_request_change(p_changed, p_prop);
}
+void EditorInspector::_vscroll_changed(double p_offset) {
+
+ if (update_scroll_request >= 0) //waiting, do nothing
+ return;
+
+ if (object) {
+ scroll_cache[object->get_instance_id()] = p_offset;
+ }
+}
+
void EditorInspector::_bind_methods() {
ClassDB::bind_method("_property_changed", &EditorInspector::_property_changed, DEFVAL(false));
@@ -2014,6 +2106,8 @@ void EditorInspector::_bind_methods() {
ClassDB::bind_method("_property_selected", &EditorInspector::_property_selected);
ClassDB::bind_method("_resource_selected", &EditorInspector::_resource_selected);
ClassDB::bind_method("_object_id_selected", &EditorInspector::_object_id_selected);
+ ClassDB::bind_method("_vscroll_changed", &EditorInspector::_vscroll_changed);
+
ClassDB::bind_method("refresh", &EditorInspector::refresh);
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property")));
@@ -2026,6 +2120,7 @@ EditorInspector::EditorInspector() {
undo_redo = NULL;
main_vbox = memnew(VBoxContainer);
main_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_vbox->add_constant_override("separation", 0);
add_child(main_vbox);
set_enable_h_scroll(false);
set_enable_v_scroll(true);
@@ -2047,4 +2142,8 @@ EditorInspector::EditorInspector() {
_prop_edited = "property_edited";
set_process(true);
property_focusable = -1;
+ use_sub_inspector_bg = false;
+
+ get_v_scrollbar()->connect("value_changed", this, "_vscroll_changed");
+ update_scroll_request = -1;
}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index b7a492f114..320641c693 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -55,6 +55,9 @@ private:
bool draw_red;
bool keying;
+ Rect2 right_child_rect;
+ Rect2 bottom_child_rect;
+
Rect2 keying_rect;
bool keying_hover;
Rect2 revert_rect;
@@ -194,9 +197,12 @@ class EditorInspectorSection : public Container {
String section;
Object *object;
VBoxContainer *vbox;
+ bool vbox_added; //optimization
Color bg_color;
bool foldable;
+ void _test_unfold();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -213,6 +219,7 @@ public:
Object *get_edited_object();
EditorInspectorSection();
+ ~EditorInspectorSection();
};
class EditorInspector : public ScrollContainer {
@@ -249,16 +256,20 @@ class EditorInspector : public ScrollContainer {
bool update_all_pending;
bool read_only;
bool keying;
+ bool use_sub_inspector_bg;
float refresh_countdown;
bool update_tree_pending;
StringName _prop_edited;
StringName property_selected;
int property_focusable;
+ int update_scroll_request;
Map<StringName, Map<StringName, String> > descr_cache;
Map<StringName, String> class_descr_cache;
+ Map<ObjectID, int> scroll_cache;
+
void _edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field);
void _property_changed(const String &p_path, const Variant &p_value, bool changing = false);
@@ -281,6 +292,8 @@ class EditorInspector : public ScrollContainer {
void _filter_changed(const String &p_text);
void _parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped);
+ void _vscroll_changed(double);
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -330,6 +343,8 @@ public:
void set_scroll_offset(int p_offset);
int get_scroll_offset() const;
+ void set_use_sub_inspector_bg(bool p_enable);
+
EditorInspector();
};
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 70bc090bc4..52f6f1ed0e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -73,6 +73,7 @@
#include "editor/plugins/animation_state_machine_editor.h"
#include "editor/plugins/animation_tree_editor_plugin.h"
#include "editor/plugins/asset_library_editor_plugin.h"
+#include "editor/plugins/audio_stream_editor_plugin.h"
#include "editor/plugins/baked_lightmap_editor_plugin.h"
#include "editor/plugins/camera_editor_plugin.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -1855,10 +1856,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
- case SETTINGS_EXPORT_PREFERENCES: {
-
- //project_export_settings->popup_centered_ratio();
- } break;
case FILE_IMPORT_SUBSCENE: {
if (!editor_data.get_edited_scene_root()) {
@@ -4189,7 +4186,7 @@ void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
for (int i = 0; i < p_files.size(); i++) {
String from = p_files[i];
- if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) != -1)) {
+ if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) == -1)) {
continue;
}
String to = to_path.plus_file(from.get_file());
@@ -4673,7 +4670,7 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/capitalize_properties", true);
EDITOR_DEF("interface/inspector/disable_folding", false);
EDITOR_DEF("interface/inspector/open_resources_in_current_inspector", true);
- EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "Material,Mesh");
+ EDITOR_DEF("interface/inspector/resources_types_to_open_in_new_inspector", "SpatialMaterial");
EDITOR_DEF("run/auto_save/save_before_running", true);
theme_base = memnew(Control);
@@ -5445,6 +5442,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this)));
add_editor_plugin(memnew(CurveEditorPlugin(this)));
add_editor_plugin(memnew(TextureEditorPlugin(this)));
+ add_editor_plugin(memnew(AudioStreamEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(SkeletonEditorPlugin(this)));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 7aa060fe14..88fe008b34 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -164,7 +164,6 @@ private:
SETTINGS_UPDATE_ALWAYS,
SETTINGS_UPDATE_CHANGES,
SETTINGS_UPDATE_SPINNER_HIDE,
- SETTINGS_EXPORT_PREFERENCES,
SETTINGS_PREFERENCES,
SETTINGS_LAYOUT_SAVE,
SETTINGS_LAYOUT_DELETE,
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index cd0bba4c9c..0b49b5a801 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -178,6 +178,8 @@ void EditorPropertyTextEnum::_bind_methods() {
EditorPropertyTextEnum::EditorPropertyTextEnum() {
options = memnew(OptionButton);
options->set_clip_text(true);
+ options->set_flat(true);
+
add_child(options);
add_focusable(options);
options->connect("item_selected", this, "_option_selected");
@@ -441,6 +443,7 @@ void EditorPropertyEnum::_bind_methods() {
EditorPropertyEnum::EditorPropertyEnum() {
options = memnew(OptionButton);
options->set_clip_text(true);
+ options->set_flat(true);
add_child(options);
add_focusable(options);
options->connect("item_selected", this, "_option_selected");
@@ -641,9 +644,11 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
}
if (name == "") {
- name = "Layer " + itos(i + 1);
+ name = TTR("Layer") + " " + itos(i + 1);
}
+ name += "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i);
+
names.push_back(name);
}
@@ -733,6 +738,7 @@ void EditorPropertyInteger::setup(int p_min, int p_max, bool p_allow_greater, bo
EditorPropertyInteger::EditorPropertyInteger() {
spin = memnew(EditorSpinSlider);
+ spin->set_flat(true);
add_child(spin);
add_focusable(spin);
spin->connect("value_changed", this, "_value_changed");
@@ -819,6 +825,7 @@ void EditorPropertyFloat::setup(double p_min, double p_max, double p_step, bool
EditorPropertyFloat::EditorPropertyFloat() {
spin = memnew(EditorSpinSlider);
+ spin->set_flat(true);
add_child(spin);
add_focusable(spin);
spin->connect("value_changed", this, "_value_changed");
@@ -829,6 +836,12 @@ EditorPropertyFloat::EditorPropertyFloat() {
void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
+ Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
+ preset->set_global_position(easing_draw->get_global_transform().xform(mb->get_position()));
+ preset->popup();
+ }
+
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
@@ -866,7 +879,7 @@ void EditorPropertyEasing::_draw_easing() {
Size2 s = easing_draw->get_size();
Rect2 r(Point2(), s);
r = r.grow(3);
- get_stylebox("normal", "LineEdit")->draw(ci, r);
+ //get_stylebox("normal", "LineEdit")->draw(ci, r);
int points = 48;
@@ -876,6 +889,7 @@ void EditorPropertyEasing::_draw_easing() {
Ref<Font> f = get_font("font", "Label");
Color color = get_color("font_color", "Label");
+ Vector<Point2> lines;
for (int i = 1; i <= points; i++) {
float ifl = i / float(points);
@@ -888,10 +902,12 @@ void EditorPropertyEasing::_draw_easing() {
iflp = 1.0 - iflp;
}
- VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(iflp * s.width, prev * s.height), Point2(ifl * s.width, h * s.height), color);
+ lines.push_back(Point2(ifl * s.width, h * s.height));
+ lines.push_back(Point2(iflp * s.width, prev * s.height));
prev = h;
}
+ easing_draw->draw_multiline(lines, color, 1.0, true);
f->draw(ci, Point2(10, 10 + f->get_ascent()), String::num(exp, 2), color);
}
@@ -899,29 +915,17 @@ void EditorPropertyEasing::update_property() {
easing_draw->update();
}
-void EditorPropertyEasing::_set_preset(float p_val) {
- emit_signal("property_changed", get_edited_property(), p_val);
+void EditorPropertyEasing::_set_preset(int p_preset) {
+ static const float preset_value[EASING_MAX] = { 0.0, 1.0, 2.0, 0.5, -2.0, -0.5 };
+
+ emit_signal("property_changed", get_edited_property(), preset_value[p_preset]);
easing_draw->update();
}
void EditorPropertyEasing::setup(bool p_full, bool p_flip) {
flip = p_flip;
- if (p_full) {
- HBoxContainer *hb2 = memnew(HBoxContainer);
- vb->add_child(hb2);
- button_out_in = memnew(ToolButton);
- button_out_in->set_tooltip(TTR("Out-In"));
- button_out_in->set_h_size_flags(SIZE_EXPAND_FILL);
- button_out_in->connect("pressed", this, "_set_preset", varray(-0.5));
- hb2->add_child(button_out_in);
-
- button_in_out = memnew(ToolButton);
- button_in_out->set_tooltip(TTR("In"));
- button_in_out->set_h_size_flags(SIZE_EXPAND_FILL);
- button_in_out->connect("pressed", this, "_set_preset", varray(-2));
- hb2->add_child(button_in_out);
- }
+ full = p_full;
}
void EditorPropertyEasing::_notification(int p_what) {
@@ -929,15 +933,19 @@ void EditorPropertyEasing::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
+ preset->clear();
+ preset->add_icon_item(get_icon("CurveConstant", "EditorIcons"), "Zero", EASING_ZERO);
+ preset->add_icon_item(get_icon("CurveLinear", "EditorIcons"), "Linear", EASING_LINEAR);
+ preset->add_icon_item(get_icon("CurveIn", "EditorIcons"), "In", EASING_IN);
+ preset->add_icon_item(get_icon("CurveOut", "EditorIcons"), "Out", EASING_OUT);
+ if (full) {
+ preset->add_icon_item(get_icon("CurveInOut", "EditorIcons"), "In-Out", EASING_IN_OUT);
+ preset->add_icon_item(get_icon("CurveOutIn", "EditorIcons"), "Out-In", EASING_OUT_IN);
+ }
easing_draw->set_custom_minimum_size(Size2(0, get_font("font", "Label")->get_height() * 2));
- button_linear->set_icon(get_icon("CurveLinear", "EditorIcons"));
- button_out->set_icon(get_icon("CurveOut", "EditorIcons"));
- button_in->set_icon(get_icon("CurveIn", "EditorIcons"));
- button_constant->set_icon(get_icon("CurveConstant", "EditorIcons"));
- if (button_out_in)
- button_out_in->set_icon(get_icon("CurveOutIn", "EditorIcons"));
- if (button_in_out)
- button_in_out->set_icon(get_icon("CurveInOut", "EditorIcons"));
+ } break;
+ case NOTIFICATION_RESIZED: {
+
} break;
}
}
@@ -951,47 +959,18 @@ void EditorPropertyEasing::_bind_methods() {
EditorPropertyEasing::EditorPropertyEasing() {
- vb = memnew(VBoxContainer);
- add_child(vb);
- HBoxContainer *hb = memnew(HBoxContainer);
- set_label_reference(hb);
-
- vb->add_child(hb);
-
- button_linear = memnew(ToolButton);
- button_linear->set_tooltip(TTR("Linear"));
- button_linear->set_h_size_flags(SIZE_EXPAND_FILL);
- button_linear->connect("pressed", this, "_set_preset", varray(1));
- hb->add_child(button_linear);
-
- button_constant = memnew(ToolButton);
- button_constant->set_tooltip(TTR("Linear"));
- button_constant->set_h_size_flags(SIZE_EXPAND_FILL);
- button_constant->connect("pressed", this, "_set_preset", varray(0));
- hb->add_child(button_constant);
-
- button_out = memnew(ToolButton);
- button_out->set_tooltip(TTR("Out"));
- button_out->set_h_size_flags(SIZE_EXPAND_FILL);
- button_out->connect("pressed", this, "_set_preset", varray(0.5));
- hb->add_child(button_out);
-
- button_in = memnew(ToolButton);
- button_in->set_tooltip(TTR("In"));
- button_in->set_h_size_flags(SIZE_EXPAND_FILL);
- button_in->connect("pressed", this, "_set_preset", varray(2));
- hb->add_child(button_in);
-
- button_in_out = NULL;
- button_out_in = NULL;
-
easing_draw = memnew(Control);
easing_draw->connect("draw", this, "_draw_easing");
easing_draw->connect("gui_input", this, "_drag_easing");
easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE);
- vb->add_child(easing_draw);
+ add_child(easing_draw);
+
+ preset = memnew(PopupMenu);
+ add_child(preset);
+ preset->connect("id_pressed", this, "_set_preset");
flip = false;
+ full = false;
}
///////////////////// VECTOR2 /////////////////////////
@@ -1014,6 +993,18 @@ void EditorPropertyVector2::update_property() {
setting = false;
}
+void EditorPropertyVector2::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 2; i++) {
+
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
+
void EditorPropertyVector2::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector2::_value_changed);
@@ -1034,6 +1025,7 @@ EditorPropertyVector2::EditorPropertyVector2() {
static const char *desc[2] = { "x", "y" };
for (int i = 0; i < 2; i++) {
spin[i] = memnew(EditorSpinSlider);
+ spin[i]->set_flat(true);
spin[i]->set_label(desc[i]);
vb->add_child(spin[i]);
add_focusable(spin[i]);
@@ -1066,7 +1058,17 @@ void EditorPropertyRect2::update_property() {
spin[3]->set_value(val.size.y);
setting = false;
}
+void EditorPropertyRect2::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 4; i++) {
+ Color c = base;
+ c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyRect2::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyRect2::_value_changed);
@@ -1088,6 +1090,8 @@ EditorPropertyRect2::EditorPropertyRect2() {
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
+
vb->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
@@ -1116,7 +1120,17 @@ void EditorPropertyVector3::update_property() {
spin[2]->set_value(val.z);
setting = false;
}
+void EditorPropertyVector3::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 3; i++) {
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyVector3::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector3::_value_changed);
@@ -1138,6 +1152,8 @@ EditorPropertyVector3::EditorPropertyVector3() {
for (int i = 0; i < 3; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
+
vb->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
@@ -1168,7 +1184,17 @@ void EditorPropertyPlane::update_property() {
spin[3]->set_value(val.d);
setting = false;
}
+void EditorPropertyPlane::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 3; i++) {
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyPlane::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyPlane::_value_changed);
@@ -1190,6 +1216,7 @@ EditorPropertyPlane::EditorPropertyPlane() {
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
vb->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
@@ -1221,7 +1248,17 @@ void EditorPropertyQuat::update_property() {
spin[3]->set_value(val.w);
setting = false;
}
+void EditorPropertyQuat::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 3; i++) {
+ Color c = base;
+ c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyQuat::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyQuat::_value_changed);
@@ -1243,6 +1280,8 @@ EditorPropertyQuat::EditorPropertyQuat() {
for (int i = 0; i < 4; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
+
vb->add_child(spin[i]);
add_focusable(spin[i]);
spin[i]->connect("value_changed", this, "_value_changed");
@@ -1280,7 +1319,17 @@ void EditorPropertyAABB::update_property() {
setting = false;
}
+void EditorPropertyAABB::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 6; i++) {
+ Color c = base;
+ c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyAABB::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyAABB::_value_changed);
@@ -1304,6 +1353,8 @@ EditorPropertyAABB::EditorPropertyAABB() {
for (int i = 0; i < 6; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
+
g->add_child(spin[i]);
spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
add_focusable(spin[i]);
@@ -1342,7 +1393,17 @@ void EditorPropertyTransform2D::update_property() {
setting = false;
}
+void EditorPropertyTransform2D::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 6; i++) {
+ Color c = base;
+ c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyTransform2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyTransform2D::_value_changed);
@@ -1362,10 +1423,11 @@ EditorPropertyTransform2D::EditorPropertyTransform2D() {
g->set_columns(2);
add_child(g);
- static const char *desc[6] = { "xx", "xy", "yx", "yy", "ox", "oy" };
+ static const char *desc[6] = { "x", "y", "x", "y", "x", "y" };
for (int i = 0; i < 6; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
g->add_child(spin[i]);
spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
add_focusable(spin[i]);
@@ -1410,7 +1472,17 @@ void EditorPropertyBasis::update_property() {
setting = false;
}
+void EditorPropertyBasis::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 9; i++) {
+ Color c = base;
+ c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyBasis::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyBasis::_value_changed);
@@ -1430,10 +1502,11 @@ EditorPropertyBasis::EditorPropertyBasis() {
g->set_columns(3);
add_child(g);
- static const char *desc[9] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz" };
+ static const char *desc[9] = { "x", "y", "z", "x", "y", "z", "x", "y", "z" };
for (int i = 0; i < 9; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
g->add_child(spin[i]);
spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
add_focusable(spin[i]);
@@ -1484,7 +1557,17 @@ void EditorPropertyTransform::update_property() {
setting = false;
}
+void EditorPropertyTransform::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ Color base = get_color("accent_color", "Editor");
+ for (int i = 0; i < 12; i++) {
+ Color c = base;
+ c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
+ spin[i]->set_custom_label_color(true, c);
+ }
+ }
+}
void EditorPropertyTransform::_bind_methods() {
ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyTransform::_value_changed);
@@ -1504,10 +1587,11 @@ EditorPropertyTransform::EditorPropertyTransform() {
g->set_columns(3);
add_child(g);
- static const char *desc[12] = { "xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz", "ox", "oy", "oz" };
+ static const char *desc[12] = { "x", "y", "z", "x", "y", "z", "x", "y", "z", "x", "y", "z" };
for (int i = 0; i < 12; i++) {
spin[i] = memnew(EditorSpinSlider);
spin[i]->set_label(desc[i]);
+ spin[i]->set_flat(true);
g->add_child(spin[i]);
spin[i]->set_h_size_flags(SIZE_EXPAND_FILL);
add_focusable(spin[i]);
@@ -1854,7 +1938,19 @@ void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<T
RES p = get_edited_object()->get(get_edited_property());
if (p.is_valid() && p->get_instance_id() == p_obj) {
if (p_preview.is_valid()) {
- assign->set_icon(p_preview);
+ String type = p->get_class_name();
+ preview->set_margin(MARGIN_LEFT, assign->get_icon()->get_width() + assign->get_stylebox("normal")->get_default_margin(MARGIN_LEFT) + get_constant("hseparation", "Button"));
+ if (type == "GradientTexture") {
+ preview->set_stretch_mode(TextureRect::STRETCH_SCALE);
+ assign->set_custom_minimum_size(Size2(1, 1));
+ } else {
+ preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+ thumbnail_size *= EDSCALE;
+ assign->set_custom_minimum_size(Size2(1, thumbnail_size));
+ }
+ preview->set_texture(p_preview);
+ assign->set_text("");
}
}
}
@@ -2048,6 +2144,9 @@ void EditorPropertyResource::update_property() {
sub_inspector = memnew(EditorInspector);
sub_inspector->set_enable_v_scroll(false);
+ sub_inspector->set_use_sub_inspector_bg(true);
+ sub_inspector->set_enable_capitalize_paths(true);
+
sub_inspector->connect("property_keyed", this, "_sub_inspector_property_keyed");
sub_inspector->connect("resource_selected", this, "_sub_inspector_resource_selected");
sub_inspector->connect("object_id_selected", this, "_sub_inspector_object_id_selected");
@@ -2095,6 +2194,7 @@ void EditorPropertyResource::update_property() {
#endif
}
+ preview->set_texture(Ref<Texture>());
if (res == RES()) {
assign->set_icon(Ref<Texture>());
assign->set_text(TTR("[empty]"));
@@ -2333,6 +2433,14 @@ EditorPropertyResource::EditorPropertyResource() {
assign->connect("draw", this, "_button_draw");
hbc->add_child(assign);
+ preview = memnew(TextureRect);
+ preview->set_expand(true);
+ preview->set_anchors_and_margins_preset(PRESET_WIDE);
+ preview->set_margin(MARGIN_TOP, 1);
+ preview->set_margin(MARGIN_BOTTOM, -1);
+ preview->set_margin(MARGIN_RIGHT, -1);
+ assign->add_child(preview);
+
menu = memnew(PopupMenu);
add_child(menu);
edit = memnew(Button);
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index ecccd7274d..0afb1bf955 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -278,16 +278,26 @@ public:
class EditorPropertyEasing : public EditorProperty {
GDCLASS(EditorPropertyEasing, EditorProperty)
Control *easing_draw;
- ToolButton *button_out, *button_in, *button_linear, *button_constant;
- ToolButton *button_in_out, *button_out_in;
- VBoxContainer *vb;
+ PopupMenu *preset;
+ bool full;
+
+ enum {
+ EASING_ZERO,
+ EASING_LINEAR,
+ EASING_IN,
+ EASING_OUT,
+ EASING_IN_OUT,
+ EASING_OUT_IN,
+ EASING_MAX
+
+ };
bool flip;
void _drag_easing(const Ref<InputEvent> &p_ev);
void _draw_easing();
void _notification(int p_what);
- void _set_preset(float p_val);
+ void _set_preset(int);
protected:
static void _bind_methods();
@@ -305,6 +315,7 @@ class EditorPropertyVector2 : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -320,6 +331,7 @@ class EditorPropertyRect2 : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -335,6 +347,7 @@ class EditorPropertyVector3 : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -350,6 +363,7 @@ class EditorPropertyPlane : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -365,6 +379,7 @@ class EditorPropertyQuat : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -380,6 +395,7 @@ class EditorPropertyAABB : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -395,6 +411,7 @@ class EditorPropertyTransform2D : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -410,6 +427,7 @@ class EditorPropertyBasis : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -425,6 +443,7 @@ class EditorPropertyTransform : public EditorProperty {
void _value_changed(double p_val);
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
@@ -488,6 +507,7 @@ class EditorPropertyResource : public EditorProperty {
};
Button *assign;
+ TextureRect *preview;
Button *edit;
PopupMenu *menu;
EditorFileDialog *file;
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index c7a33de3f1..79023a1f28 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -90,10 +90,12 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
}
grabbing_spinner_dist_cache += diff_x;
- if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4) {
+ if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * EDSCALE) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
grabbing_spinner = true;
- } else {
+ }
+
+ if (grabbing_spinner) {
if (mm->get_control() || updown_offset != -1) {
set_value(Math::round(get_value()));
if (ABS(grabbing_spinner_dist_cache) > 6) {
@@ -159,20 +161,20 @@ void EditorSpinSlider::_notification(int p_what) {
updown_offset = -1;
Ref<StyleBox> sb = get_stylebox("normal", "LineEdit");
- draw_style_box(sb, Rect2(Vector2(), get_size()));
+ if (!flat) {
+ draw_style_box(sb, Rect2(Vector2(), get_size()));
+ }
Ref<Font> font = get_font("font", "LineEdit");
+ int sep_base = 4 * EDSCALE;
+ int sep = sep_base + sb->get_offset().x; //make it have the same margin on both sides, looks better
+
+ int string_width = font->get_string_size(label).width;
+ int number_width = get_size().width - sb->get_minimum_size().width - string_width - sep;
- int avail_width = get_size().width - sb->get_minimum_size().width;
- avail_width -= font->get_string_size(label).width;
Ref<Texture> updown = get_icon("updown", "SpinBox");
if (get_step() == 1) {
- avail_width -= updown->get_width();
- }
-
- if (has_focus()) {
- Ref<StyleBox> focus = get_stylebox("focus", "LineEdit");
- draw_style_box(focus, Rect2(Vector2(), get_size()));
+ number_width -= updown->get_width();
}
String numstr = get_text_value();
@@ -180,10 +182,26 @@ void EditorSpinSlider::_notification(int p_what) {
int vofs = (get_size().height - font->get_height()) / 2 + font->get_ascent();
Color fc = get_color("font_color", "LineEdit");
+ Color lc;
+ if (use_custom_label_color) {
+ lc = custom_label_color;
+ } else {
+ lc = fc;
+ }
- int label_ofs = sb->get_offset().x + avail_width;
- draw_string(font, Vector2(label_ofs, vofs), label, fc * Color(1, 1, 1, 0.5));
- draw_string(font, Vector2(sb->get_offset().x, vofs), numstr, fc, avail_width);
+ if (flat && label != String()) {
+ Color label_bg_color = get_color("dark_color_3", "Editor");
+ draw_rect(Rect2(Vector2(), Vector2(sb->get_offset().x * 2 + string_width, get_size().height)), label_bg_color);
+ }
+
+ if (has_focus()) {
+ Ref<StyleBox> focus = get_stylebox("focus", "LineEdit");
+ draw_style_box(focus, Rect2(Vector2(), get_size()));
+ }
+
+ draw_string(font, Vector2(sb->get_offset().x, vofs), label, lc * Color(1, 1, 1, 0.5));
+
+ draw_string(font, Vector2(sb->get_offset().x + string_width + sep, vofs), numstr, fc, number_width);
if (get_step() == 1) {
Ref<Texture> updown = get_icon("updown", "SpinBox");
@@ -250,9 +268,11 @@ void EditorSpinSlider::_notification(int p_what) {
update();
}
if (p_what == NOTIFICATION_FOCUS_ENTER) {
- if (!Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) {
+ /* Sorry, I dont like this, it makes navigating the different fields with arrows more difficult
+ * if (!Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && !value_input_just_closed) {
_focus_entered();
- }
+ }*/
+
value_input_just_closed = false;
}
}
@@ -334,6 +354,21 @@ bool EditorSpinSlider::is_read_only() const {
return read_only;
}
+void EditorSpinSlider::set_flat(bool p_enable) {
+
+ flat = p_enable;
+ update();
+}
+
+bool EditorSpinSlider::is_flat() const {
+ return flat;
+}
+
+void EditorSpinSlider::set_custom_label_color(bool p_use_custom_label_color, Color p_custom_label_color) {
+ use_custom_label_color = p_use_custom_label_color;
+ custom_label_color = p_custom_label_color;
+}
+
void EditorSpinSlider::_focus_entered() {
Rect2 gr = get_global_rect();
value_input->set_text(get_text_value());
@@ -353,6 +388,9 @@ void EditorSpinSlider::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_read_only", "read_only"), &EditorSpinSlider::set_read_only);
ClassDB::bind_method(D_METHOD("is_read_only"), &EditorSpinSlider::is_read_only);
+ ClassDB::bind_method(D_METHOD("set_flat", "flat"), &EditorSpinSlider::set_flat);
+ ClassDB::bind_method(D_METHOD("is_flat"), &EditorSpinSlider::is_flat);
+
ClassDB::bind_method(D_METHOD("_gui_input"), &EditorSpinSlider::_gui_input);
ClassDB::bind_method(D_METHOD("_grabber_mouse_entered"), &EditorSpinSlider::_grabber_mouse_entered);
ClassDB::bind_method(D_METHOD("_grabber_mouse_exited"), &EditorSpinSlider::_grabber_mouse_exited);
@@ -363,10 +401,12 @@ void EditorSpinSlider::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "label"), "set_label", "get_label");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
}
EditorSpinSlider::EditorSpinSlider() {
+ flat = false;
grabbing_spinner_attempt = false;
grabbing_spinner = false;
grabbing_spinner_dist_cache = 0;
@@ -395,4 +435,5 @@ EditorSpinSlider::EditorSpinSlider() {
value_input_just_closed = false;
hide_slider = false;
read_only = false;
+ use_custom_label_color = false;
}
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index 5316c0264a..fb32534ef4 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -68,6 +68,10 @@ class EditorSpinSlider : public Range {
void _value_input_entered(const String &);
void _value_focus_exited();
bool hide_slider;
+ bool flat;
+
+ bool use_custom_label_color;
+ Color custom_label_color;
protected:
void _notification(int p_what);
@@ -88,6 +92,11 @@ public:
void set_read_only(bool p_enable);
bool is_read_only() const;
+ void set_flat(bool p_enable);
+ bool is_flat() const;
+
+ void set_custom_label_color(bool p_use_custom_label_color, Color p_custom_label_color);
+
virtual Size2 get_minimum_size() const;
EditorSpinSlider();
};
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 0534a398f4..084caff083 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -656,6 +656,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));
theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size) * EDSCALE);
+ Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1, 2, 0, 0, 0);
+ sub_inspector_bg->set_border_width(MARGIN_LEFT, 2);
+ sub_inspector_bg->set_border_color(MARGIN_LEFT, accent_color * Color(1, 1, 1, 0.3));
+ sub_inspector_bg->set_draw_center(true);
+
+ theme->set_stylebox("sub_inspector_bg", "Editor", sub_inspector_bg);
+ theme->set_constant("inspector_margin", "Editor", 8 * EDSCALE);
+
// Tree & ItemList background
Ref<StyleBoxFlat> style_tree_bg = style_default->duplicate();
style_tree_bg->set_bg_color(dark_color_1);
@@ -666,6 +674,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Tree
theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_icon("arrow_up", "Tree", theme->get_icon("GuiTreeArrowUp", "EditorIcons"));
theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
theme->set_icon("updown", "Tree", theme->get_icon("GuiTreeUpdown", "EditorIcons"));
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 541c848ca3..931785333f 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -123,7 +123,6 @@ void ExportTemplateManager::_update_template_list() {
void ExportTemplateManager::_download_template(const String &p_version) {
- print_line("download " + p_version);
while (template_list->get_child_count()) {
memdelete(template_list->get_child(0));
}
@@ -228,7 +227,10 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
version = data_str;
}
- fc++;
+ if (file.get_file().size() != 0) {
+ fc++;
+ }
+
ret = unzGoToNextFile(pkg);
}
@@ -268,6 +270,11 @@ void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
String file = String(fname).get_file();
+ if (file.size() == 0) {
+ ret = unzGoToNextFile(pkg);
+ continue;
+ }
+
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -344,7 +351,6 @@ void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_
bool mirrors_found = false;
Dictionary d = r;
- print_line(r);
if (d.has("mirrors")) {
Array mirrors = d["mirrors"];
for (int i = 0; i < mirrors.size(); i++) {
@@ -499,7 +505,6 @@ void ExportTemplateManager::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (!is_visible_in_tree()) {
- print_line("closed");
set_process(false);
}
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index eebf1b6ab8..f65fb5365b 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1862,7 +1862,7 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option);
ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option);
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);
- ClassDB::bind_method(D_METHOD("_move_operation_confirm"), &FileSystemDock::_move_operation_confirm);
+ ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false));
ClassDB::bind_method(D_METHOD("_move_with_overwrite"), &FileSystemDock::_move_with_overwrite);
ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm);
ClassDB::bind_method(D_METHOD("_duplicate_operation_confirm"), &FileSystemDock::_duplicate_operation_confirm);
diff --git a/editor/icons/icon_GUI_tree_arrow_up.svg b/editor/icons/icon_GUI_tree_arrow_up.svg
new file mode 100644
index 0000000000..4e6e8e9e29
--- /dev/null
+++ b/editor/icons/icon_GUI_tree_arrow_up.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ version="1.1"
+ viewBox="0 0 12 12"
+ id="svg6"
+ sodipodi:docname="icon_GUI_tree_arrow_up.svg"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)">
+ <metadata
+ id="metadata12">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs10" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1673"
+ inkscape:window-height="594"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="19.666667"
+ inkscape:cx="-4.3220338"
+ inkscape:cy="6.0000001"
+ inkscape:window-x="67"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg6" />
+ <g
+ transform="rotate(180,6,526.08476)"
+ id="g4">
+ <path
+ d="m 3,1045.4 3,3 3,-3"
+ id="path2"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.39216003" />
+ </g>
+</svg>
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
new file mode 100644
index 0000000000..ddb03d0250
--- /dev/null
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -0,0 +1,284 @@
+/*************************************************************************/
+/* audio_stream_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 "audio_stream_editor_plugin.h"
+
+#include "editor/editor_settings.h"
+#include "io/resource_loader.h"
+#include "project_settings.h"
+
+void AudioStreamEditor::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_READY) {
+ AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", this, "_preview_changed");
+ }
+
+ if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
+ _play_button->set_icon(get_icon("MainPlay", "EditorIcons"));
+ _stop_button->set_icon(get_icon("Stop", "EditorIcons"));
+ _preview->set_frame_color(get_color("dark_color_2", "Editor"));
+ set_frame_color(get_color("dark_color_1", "Editor"));
+
+ _indicator->update();
+ _preview->update();
+ }
+
+ if (p_what == NOTIFICATION_PROCESS) {
+ _current = _player->get_playback_position();
+ _indicator->update();
+ _preview->update();
+ }
+
+ if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
+ if (!is_visible_in_tree()) {
+ _stop();
+ }
+ }
+}
+
+void AudioStreamEditor::_draw_preview() {
+ Rect2 rect = _preview->get_rect();
+ Size2 size = get_size();
+
+ Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream);
+ float preview_len = preview->get_length();
+
+ Vector<Vector2> lines;
+ lines.resize(size.width * 2);
+
+ for (int i = 0; i < size.width; i++) {
+
+ float ofs = i * preview_len / size.width;
+ float ofs_n = (i + 1) * preview_len / size.width;
+ float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5;
+ float min = preview->get_min(ofs, ofs_n) * 0.5 + 0.5;
+
+ int idx = i;
+ lines[idx * 2 + 0] = Vector2(i + 1, rect.position.y + min * rect.size.y);
+ lines[idx * 2 + 1] = Vector2(i + 1, rect.position.y + max * rect.size.y);
+ }
+
+ Vector<Color> color;
+ color.push_back(get_color("contrast_color_2", "Editor"));
+
+ VS::get_singleton()->canvas_item_add_multiline(_preview->get_canvas_item(), lines, color);
+}
+
+void AudioStreamEditor::_preview_changed(ObjectID p_which) {
+
+ if (stream.is_valid() && stream->get_instance_id() == p_which) {
+ _preview->update();
+ }
+}
+
+void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+
+ if (!is_visible())
+ return;
+ update();
+}
+
+void AudioStreamEditor::_play() {
+
+ if (_player->is_playing()) {
+ _player->stop();
+ _play_button->set_icon(get_icon("MainPlay", "EditorIcons"));
+ set_process(false);
+ } else {
+ _player->play(_current);
+ _play_button->set_icon(get_icon("Pause", "EditorIcons"));
+ set_process(true);
+ }
+}
+
+void AudioStreamEditor::_stop() {
+
+ _player->stop();
+ _on_finished();
+}
+
+void AudioStreamEditor::_on_finished() {
+
+ _play_button->set_icon(get_icon("MainPlay", "EditorIcons"));
+ _current = 0;
+ _indicator->update();
+ set_process(false);
+}
+
+void AudioStreamEditor::_draw_indicator() {
+
+ if (!stream.is_valid()) {
+ return;
+ }
+
+ Rect2 rect = _preview->get_rect();
+ float len = stream->get_length();
+ float ofs_x = _current / len * rect.size.width;
+ _indicator->draw_line(Point2(ofs_x, 0), Point2(ofs_x, rect.size.height), get_color("accent_color", "Editor"), 1);
+
+ _current_label->set_text(String::num(_current, 2).pad_decimals(2) + " /");
+}
+
+void AudioStreamEditor::_on_input_indicator(Ref<InputEvent> p_event) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid()) {
+ if (mb->is_pressed()) {
+ _seek_to(mb->get_position().x);
+ }
+ _dragging = mb->is_pressed();
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+ if (_dragging) {
+ _seek_to(mm->get_position().x);
+ }
+ }
+}
+
+void AudioStreamEditor::_seek_to(real_t p_x) {
+ _current = p_x / _preview->get_rect().size.x * stream->get_length();
+ _current = CLAMP(_current, 0, stream->get_length());
+ _player->seek(_current);
+ _indicator->update();
+}
+
+void AudioStreamEditor::edit(Ref<AudioStream> p_stream) {
+
+ if (!stream.is_null())
+ stream->remove_change_receptor(this);
+
+ stream = p_stream;
+ _player->set_stream(stream);
+ _current = 0;
+ String text = String::num(stream->get_length(), 2).pad_decimals(2) + "s";
+ _duration_label->set_text(text);
+
+ if (!stream.is_null()) {
+ stream->add_change_receptor(this);
+ update();
+ } else {
+ hide();
+ }
+}
+
+void AudioStreamEditor::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_preview_changed"), &AudioStreamEditor::_preview_changed);
+ ClassDB::bind_method(D_METHOD("_play"), &AudioStreamEditor::_play);
+ ClassDB::bind_method(D_METHOD("_stop"), &AudioStreamEditor::_stop);
+ ClassDB::bind_method(D_METHOD("_on_finished"), &AudioStreamEditor::_on_finished);
+ ClassDB::bind_method(D_METHOD("_draw_preview"), &AudioStreamEditor::_draw_preview);
+ ClassDB::bind_method(D_METHOD("_draw_indicator"), &AudioStreamEditor::_draw_indicator);
+ ClassDB::bind_method(D_METHOD("_on_input_indicator"), &AudioStreamEditor::_on_input_indicator);
+}
+
+AudioStreamEditor::AudioStreamEditor() {
+
+ set_custom_minimum_size(Size2(1, 100));
+ _current = 0;
+ _dragging = false;
+
+ _player = memnew(AudioStreamPlayer);
+ _player->connect("finished", this, "_on_finished");
+ add_child(_player);
+
+ VBoxContainer *vbox = memnew(VBoxContainer);
+ vbox->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_MINSIZE, 0);
+ add_child(vbox);
+
+ _preview = memnew(ColorRect);
+ _preview->set_v_size_flags(SIZE_EXPAND_FILL);
+ _preview->connect("draw", this, "_draw_preview");
+ vbox->add_child(_preview);
+
+ _indicator = memnew(Control);
+ _indicator->set_anchors_and_margins_preset(PRESET_WIDE);
+ _indicator->connect("draw", this, "_draw_indicator");
+ _indicator->connect("gui_input", this, "_on_input_indicator");
+ _preview->add_child(_indicator);
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ hbox->add_constant_override("separation", 0);
+ vbox->add_child(hbox);
+
+ _play_button = memnew(ToolButton);
+ hbox->add_child(_play_button);
+ _play_button->set_focus_mode(Control::FOCUS_NONE);
+ _play_button->connect("pressed", this, "_play");
+
+ _stop_button = memnew(ToolButton);
+ hbox->add_child(_stop_button);
+ _stop_button->set_focus_mode(Control::FOCUS_NONE);
+ _stop_button->connect("pressed", this, "_stop");
+
+ _current_label = memnew(Label);
+ _current_label->set_align(Label::ALIGN_RIGHT);
+ _current_label->set_h_size_flags(SIZE_EXPAND_FILL);
+ _current_label->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
+ _current_label->set_modulate(Color(1, 1, 1, 0.5));
+ hbox->add_child(_current_label);
+
+ _duration_label = memnew(Label);
+ _duration_label->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
+ hbox->add_child(_duration_label);
+}
+
+void AudioStreamEditorPlugin::edit(Object *p_object) {
+
+ AudioStream *s = Object::cast_to<AudioStream>(p_object);
+ if (!s)
+ return;
+
+ audio_editor->edit(Ref<AudioStream>(s));
+}
+
+bool AudioStreamEditorPlugin::handles(Object *p_object) const {
+
+ return p_object->is_class("AudioStream");
+}
+
+void AudioStreamEditorPlugin::make_visible(bool p_visible) {
+
+ audio_editor->set_visible(p_visible);
+}
+
+AudioStreamEditorPlugin::AudioStreamEditorPlugin(EditorNode *p_node) {
+
+ editor = p_node;
+ audio_editor = memnew(AudioStreamEditor);
+ add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, audio_editor);
+ audio_editor->hide();
+}
+
+AudioStreamEditorPlugin::~AudioStreamEditorPlugin() {
+}
diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h
new file mode 100644
index 0000000000..1887874b74
--- /dev/null
+++ b/editor/plugins/audio_stream_editor_plugin.h
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* audio_stream_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 AUDIO_STREAM_EDITOR_PLUGIN_H
+#define AUDIO_STREAM_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/audio/audio_player.h"
+#include "scene/gui/color_rect.h"
+#include "scene/resources/texture.h"
+
+class AudioStreamEditor : public ColorRect {
+
+ GDCLASS(AudioStreamEditor, ColorRect);
+
+ Ref<AudioStream> stream;
+ AudioStreamPlayer *_player;
+ ColorRect *_preview;
+ Control *_indicator;
+ Label *_current_label;
+ Label *_duration_label;
+
+ ToolButton *_play_button;
+ ToolButton *_stop_button;
+
+ float _current;
+ bool _dragging;
+
+protected:
+ void _notification(int p_what);
+ void _preview_changed(ObjectID p_which);
+ void _play();
+ void _stop();
+ void _on_finished();
+ void _draw_preview();
+ void _draw_indicator();
+ void _on_input_indicator(Ref<InputEvent> p_event);
+ void _seek_to(real_t p_x);
+ void _changed_callback(Object *p_changed, const char *p_prop);
+ static void _bind_methods();
+
+public:
+ void edit(Ref<AudioStream> p_stream);
+ AudioStreamEditor();
+};
+
+class AudioStreamEditorPlugin : public EditorPlugin {
+
+ GDCLASS(AudioStreamEditorPlugin, EditorPlugin);
+
+ AudioStreamEditor *audio_editor;
+ EditorNode *editor;
+
+public:
+ virtual String get_name() const { return "Audio"; }
+ 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);
+
+ AudioStreamEditorPlugin(EditorNode *p_node);
+ ~AudioStreamEditorPlugin();
+};
+
+#endif // AUDIO_STREAM_EDITOR_PLUGIN_H
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 5ec42b07aa..33e182faef 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -109,6 +109,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
action_point = i;
moving_from = curve->get_point_out(i);
moving_screen_from = gpoint;
+ orig_in_length = curve->get_point_in(action_point).length();
return true;
} else if (dist_to_p_in < grab_threshold && i > 0) {
@@ -116,6 +117,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
action_point = i;
moving_from = curve->get_point_in(i);
moving_screen_from = gpoint;
+ orig_out_length = curve->get_point_out(action_point).length();
return true;
}
}
@@ -205,6 +207,11 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Move In-Control in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, new_pos);
undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, moving_from);
+
+ if (mirror_handle_angle) {
+ undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length));
+ undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length));
+ }
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->commit_action();
@@ -216,6 +223,11 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Move Out-Control in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, new_pos);
undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, moving_from);
+
+ if (mirror_handle_angle) {
+ undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length));
+ undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_in_length));
+ }
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->commit_action();
@@ -255,10 +267,16 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
case ACTION_MOVING_IN: {
curve->set_point_in(action_point, new_pos);
+
+ if (mirror_handle_angle)
+ curve->set_point_out(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length));
} break;
case ACTION_MOVING_OUT: {
curve->set_point_out(action_point, new_pos);
+
+ if (mirror_handle_angle)
+ curve->set_point_in(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length));
} break;
}
@@ -342,6 +360,7 @@ void Path2DEditor::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option);
ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Path2DEditor::_node_visibility_changed);
ClassDB::bind_method(D_METHOD("_mode_selected"), &Path2DEditor::_mode_selected);
+ ClassDB::bind_method(D_METHOD("_handle_option_pressed"), &Path2DEditor::_handle_option_pressed);
}
void Path2DEditor::_mode_selected(int p_mode) {
@@ -396,11 +415,33 @@ void Path2DEditor::_mode_selected(int p_mode) {
mode = Mode(p_mode);
}
+void Path2DEditor::_handle_option_pressed(int p_option) {
+
+ PopupMenu *pm;
+ pm = handle_menu->get_popup();
+
+ switch (p_option) {
+ case HANDLE_OPTION_ANGLE: {
+ bool is_checked = pm->is_item_checked(HANDLE_OPTION_ANGLE);
+ mirror_handle_angle = !is_checked;
+ pm->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle);
+ pm->set_item_disabled(HANDLE_OPTION_LENGTH, !mirror_handle_angle);
+ } break;
+ case HANDLE_OPTION_LENGTH: {
+ bool is_checked = pm->is_item_checked(HANDLE_OPTION_LENGTH);
+ mirror_handle_length = !is_checked;
+ pm->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length);
+ } break;
+ }
+}
+
Path2DEditor::Path2DEditor(EditorNode *p_editor) {
canvas_item_editor = NULL;
editor = p_editor;
undo_redo = editor->get_undo_redo();
+ mirror_handle_angle = true;
+ mirror_handle_length = true;
mode = MODE_EDIT;
action = ACTION_NONE;
@@ -444,6 +485,20 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
curve_close->set_tooltip(TTR("Close Curve"));
curve_close->connect("pressed", this, "_mode_selected", varray(ACTION_CLOSE));
base_hb->add_child(curve_close);
+
+ PopupMenu *menu;
+
+ handle_menu = memnew(MenuButton);
+ handle_menu->set_text(TTR("Options"));
+ base_hb->add_child(handle_menu);
+
+ menu = handle_menu->get_popup();
+ menu->add_check_item(TTR("Mirror Handle Angles"));
+ menu->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle);
+ menu->add_check_item(TTR("Mirror Handle Lengths"));
+ menu->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length);
+ menu->connect("id_pressed", this, "_handle_option_pressed");
+
base_hb->hide();
curve_edit->set_pressed(true);
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index c92a696967..1e3955f84f 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -69,6 +69,15 @@ class Path2DEditor : public HBoxContainer {
ToolButton *curve_edit_curve;
ToolButton *curve_del;
ToolButton *curve_close;
+ MenuButton *handle_menu;
+
+ bool mirror_handle_angle;
+ bool mirror_handle_length;
+
+ enum HandleOption {
+ HANDLE_OPTION_ANGLE,
+ HANDLE_OPTION_LENGTH
+ };
enum Action {
@@ -82,8 +91,11 @@ class Path2DEditor : public HBoxContainer {
int action_point;
Point2 moving_from;
Point2 moving_screen_from;
+ float orig_in_length;
+ float orig_out_length;
void _mode_selected(int p_mode);
+ void _handle_option_pressed(int p_option);
void _node_visibility_changed();
friend class Path2DEditorPlugin;
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 6dde639c54..72a8b55a52 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -128,11 +128,22 @@ void PathSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_p
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
+ if (!PathEditorPlugin::singleton->is_handle_clicked()) {
+ orig_in_length = c->get_point_in(idx).length();
+ orig_out_length = c->get_point_out(idx).length();
+ PathEditorPlugin::singleton->set_handle_clicked(true);
+ }
+
Vector3 local = gi.xform(inters) - base;
if (t == 0) {
c->set_point_in(idx, local);
+
+ if (PathEditorPlugin::singleton->mirror_angle_enabled())
+ c->set_point_out(idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length));
} else {
c->set_point_out(idx, local);
+ if (PathEditorPlugin::singleton->mirror_angle_enabled())
+ c->set_point_in(idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_in_length));
}
}
}
@@ -165,8 +176,6 @@ void PathSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p
int idx = p_idx / 2;
int t = p_idx % 2;
- Vector3 ofs;
-
if (t == 0) {
if (p_cancel) {
c->set_point_in(p_idx, p_restore);
@@ -176,6 +185,11 @@ void PathSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p
ur->create_action(TTR("Set Curve In Position"));
ur->add_do_method(c.ptr(), "set_point_in", idx, c->get_point_in(idx));
ur->add_undo_method(c.ptr(), "set_point_in", idx, p_restore);
+
+ if (PathEditorPlugin::singleton->mirror_angle_enabled()) {
+ ur->add_do_method(c.ptr(), "set_point_out", idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -c->get_point_in(idx) : (-c->get_point_in(idx).normalized() * orig_out_length));
+ ur->add_undo_method(c.ptr(), "set_point_out", idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -static_cast<Vector3>(p_restore) : (-static_cast<Vector3>(p_restore).normalized() * orig_out_length));
+ }
ur->commit_action();
} else {
@@ -188,6 +202,11 @@ void PathSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p
ur->create_action(TTR("Set Curve Out Position"));
ur->add_do_method(c.ptr(), "set_point_out", idx, c->get_point_out(idx));
ur->add_undo_method(c.ptr(), "set_point_out", idx, p_restore);
+
+ if (PathEditorPlugin::singleton->mirror_angle_enabled()) {
+ ur->add_do_method(c.ptr(), "set_point_in", idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -c->get_point_out(idx) : (-c->get_point_out(idx).normalized() * orig_in_length));
+ ur->add_undo_method(c.ptr(), "set_point_in", idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -static_cast<Vector3>(p_restore) : (-static_cast<Vector3>(p_restore).normalized() * orig_in_length));
+ }
ur->commit_action();
}
}
@@ -291,6 +310,9 @@ bool PathEditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<Inp
Point2 mbpos(mb->get_position().x, mb->get_position().y);
+ if (!mb->is_pressed())
+ set_handle_clicked(false);
+
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) {
//click into curve, break it down
PoolVector<Vector3> v3a = c->tessellate();
@@ -459,6 +481,7 @@ void PathEditorPlugin::make_visible(bool p_visible) {
curve_edit->show();
curve_del->show();
curve_close->show();
+ handle_menu->show();
sep->show();
} else {
@@ -466,6 +489,7 @@ void PathEditorPlugin::make_visible(bool p_visible) {
curve_edit->hide();
curve_del->hide();
curve_close->hide();
+ handle_menu->hide();
sep->hide();
{
@@ -495,6 +519,26 @@ void PathEditorPlugin::_close_curve() {
c->add_point(c->get_point_position(0), c->get_point_in(0), c->get_point_out(0));
}
+void PathEditorPlugin::_handle_option_pressed(int p_option) {
+
+ PopupMenu *pm;
+ pm = handle_menu->get_popup();
+
+ switch (p_option) {
+ case HANDLE_OPTION_ANGLE: {
+ bool is_checked = pm->is_item_checked(HANDLE_OPTION_ANGLE);
+ mirror_handle_angle = !is_checked;
+ pm->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle);
+ pm->set_item_disabled(HANDLE_OPTION_LENGTH, !mirror_handle_angle);
+ } break;
+ case HANDLE_OPTION_LENGTH: {
+ bool is_checked = pm->is_item_checked(HANDLE_OPTION_LENGTH);
+ mirror_handle_length = !is_checked;
+ pm->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length);
+ } break;
+ }
+}
+
void PathEditorPlugin::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -510,6 +554,7 @@ void PathEditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("_mode_changed"), &PathEditorPlugin::_mode_changed);
ClassDB::bind_method(D_METHOD("_close_curve"), &PathEditorPlugin::_close_curve);
+ ClassDB::bind_method(D_METHOD("_handle_option_pressed"), &PathEditorPlugin::_handle_option_pressed);
}
PathEditorPlugin *PathEditorPlugin::singleton = NULL;
@@ -519,6 +564,8 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
path = NULL;
editor = p_node;
singleton = this;
+ mirror_handle_angle = true;
+ mirror_handle_length = true;
path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
path_material->set_albedo(Color(0.5, 0.5, 1.0, 0.8));
@@ -567,6 +614,20 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
curve_close->set_tooltip(TTR("Close Curve"));
SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_close);
+ PopupMenu *menu;
+
+ handle_menu = memnew(MenuButton);
+ handle_menu->set_text(TTR("Options"));
+ handle_menu->hide();
+ SpatialEditor::get_singleton()->add_control_to_menu_panel(handle_menu);
+
+ menu = handle_menu->get_popup();
+ menu->add_check_item(TTR("Mirror Handle Angles"));
+ menu->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle);
+ menu->add_check_item(TTR("Mirror Handle Lengths"));
+ menu->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length);
+ menu->connect("id_pressed", this, "_handle_option_pressed");
+
curve_edit->set_pressed(true);
/*
collision_polygon_editor = memnew( PathEditor(p_node) );
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 6d5f07f729..52dfb78b61 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -1,4 +1,4 @@
-/*************************************************************************/
+/*************************************************************************/
/* path_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
@@ -40,6 +40,8 @@ class PathSpatialGizmo : public EditorSpatialGizmo {
Path *path;
mutable Vector3 original;
+ mutable float orig_in_length;
+ mutable float orig_out_length;
public:
virtual String get_handle_name(int p_idx) const;
@@ -60,6 +62,7 @@ class PathEditorPlugin : public EditorPlugin {
ToolButton *curve_edit;
ToolButton *curve_del;
ToolButton *curve_close;
+ MenuButton *handle_menu;
EditorNode *editor;
@@ -67,6 +70,15 @@ class PathEditorPlugin : public EditorPlugin {
void _mode_changed(int p_idx);
void _close_curve();
+ void _handle_option_pressed(int p_option);
+ bool handle_clicked;
+ bool mirror_handle_angle;
+ bool mirror_handle_length;
+
+ enum HandleOption {
+ HANDLE_OPTION_ANGLE,
+ HANDLE_OPTION_LENGTH
+ };
protected:
void _notification(int p_what);
@@ -88,6 +100,11 @@ public:
virtual bool handles(Object *p_object) const;
virtual void make_visible(bool p_visible);
+ bool mirror_angle_enabled() { return mirror_handle_angle; }
+ bool mirror_length_enabled() { return mirror_handle_length; }
+ bool is_handle_clicked() { return handle_clicked; }
+ void set_handle_clicked(bool clicked) { handle_clicked = clicked; }
+
PathEditorPlugin(EditorNode *p_node);
~PathEditorPlugin();
};
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 9a351c26fa..682ca744ff 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -768,17 +768,17 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("VectorOp", "Operators", "VisualShaderNodeVectorOp"));
add_options.push_back(AddOption("ColorOp", "Operators", "VisualShaderNodeColorOp"));
add_options.push_back(AddOption("TransformMult", "Operators", "VisualShaderNodeTransformMult"));
- add_options.push_back(AddOption("TransformVecMult", "Operators", "VisualShaderNodeTransformVecMult"));
+ add_options.push_back(AddOption("TransformVectorMult", "Operators", "VisualShaderNodeTransformVecMult"));
add_options.push_back(AddOption("ScalarFunc", "Functions", "VisualShaderNodeScalarFunc"));
add_options.push_back(AddOption("VectorFunc", "Functions", "VisualShaderNodeVectorFunc"));
add_options.push_back(AddOption("DotProduct", "Functions", "VisualShaderNodeDotProduct"));
add_options.push_back(AddOption("VectorLen", "Functions", "VisualShaderNodeVectorLen"));
add_options.push_back(AddOption("ScalarInterp", "Interpolation", "VisualShaderNodeScalarInterp"));
add_options.push_back(AddOption("VectorInterp", "Interpolation", "VisualShaderNodeVectorInterp"));
- add_options.push_back(AddOption("VectorConstruct", "Construct", "VisualShaderNodeVectorConstruct"));
- add_options.push_back(AddOption("TransformConstruct", "Construct", "VisualShaderNodeTransformConstruct"));
- add_options.push_back(AddOption("VectorDestruct", "Destruct", "VisualShaderNodeVectorDestruct"));
- add_options.push_back(AddOption("TransformDestruct", "Destruct", "VisualShaderNodeTransformDestruct"));
+ add_options.push_back(AddOption("VectorCompose", "Compose", "VisualShaderNodeVectorCompose"));
+ add_options.push_back(AddOption("TransformCompose", "Compose", "VisualShaderNodeTransformCompose"));
+ add_options.push_back(AddOption("VectorDecompose", "Decompose", "VisualShaderNodeVectorDecompose"));
+ add_options.push_back(AddOption("TransformDecompose", "Decompose", "VisualShaderNodeTransformDecompose"));
add_options.push_back(AddOption("Scalar", "Uniforms", "VisualShaderNodeScalarUniform"));
add_options.push_back(AddOption("Vector", "Uniforms", "VisualShaderNodeVec3Uniform"));
add_options.push_back(AddOption("Color", "Uniforms", "VisualShaderNodeColorUniform"));
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 9f87fc82b5..170546f14c 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -76,6 +76,9 @@ void ProjectExportDialog::popup_export() {
}
_update_presets();
+ if (presets->get_current() >= 0) {
+ _edit_preset(presets->get_current()); // triggers rescan for templates if newly installed
+ }
// Restore valid window bounds or pop up at default size.
if (EditorSettings::get_singleton()->has_setting("interface/dialogs/export_bounds")) {
@@ -154,7 +157,6 @@ void ProjectExportDialog::_update_presets() {
if (current_idx != -1) {
presets->select(current_idx);
- //_edit_preset(current_idx);
}
updating = false;
@@ -167,6 +169,7 @@ void ProjectExportDialog::_edit_preset(int p_index) {
name->set_editable(false);
runnable->set_disabled(true);
parameters->edit(NULL);
+ presets->unselect_all();
delete_preset->set_disabled(true);
sections->hide();
patches->clear();
@@ -438,11 +441,9 @@ void ProjectExportDialog::_delete_preset() {
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(presets->get_current());
}
Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 8c7565a441..7e4e589bb4 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -394,6 +394,7 @@ void ProjectSettingsEditor::_show_last_added(const Ref<InputEvent> &p_event, con
while (child) {
Variant input = child->get_meta("__input");
if (p_event == input) {
+ r->set_collapsed(false);
child->select(0);
found = true;
break;
@@ -654,6 +655,14 @@ void ProjectSettingsEditor::_update_actions() {
if (setting)
return;
+ Map<String, bool> collapsed;
+
+ if (input_editor->get_root() && input_editor->get_root()->get_children()) {
+ for (TreeItem *item = input_editor->get_root()->get_children(); item; item = item->get_next()) {
+ collapsed[item->get_text(0)] = item->is_collapsed();
+ }
+ }
+
input_editor->clear();
TreeItem *root = input_editor->create_item();
input_editor->set_hide_root(true);
@@ -677,6 +686,8 @@ void ProjectSettingsEditor::_update_actions() {
TreeItem *item = input_editor->create_item(root);
item->set_text(0, name);
item->set_custom_bg_color(0, get_color("prop_subsection", "Editor"));
+ if (collapsed.has(name))
+ item->set_collapsed(collapsed[name]);
item->set_editable(1, true);
item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 3b0ac8864a..c45dea0df7 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -3272,10 +3272,10 @@ NavigationMeshSpatialGizmo::NavigationMeshSpatialGizmo(NavigationMeshInstance *p
navmesh = p_navmesh;
}
- //////
- ///
- ///
- ///
+//////
+///
+///
+///
#define BODY_A_RADIUS 0.25
#define BODY_B_RADIUS 0.27