summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/animation_track_editor.cpp22
-rw-r--r--editor/editor_feature_profile.cpp2
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/editor_properties.cpp4
-rw-r--r--editor/editor_resource_picker.cpp41
-rw-r--r--editor/editor_resource_picker.h19
-rw-r--r--editor/editor_settings.cpp7
-rw-r--r--editor/export_template_manager.cpp4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp66
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h66
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp33
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp4
-rw-r--r--editor/plugins/path_3d_editor_plugin.h4
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1
-rw-r--r--editor/property_selector.cpp47
-rw-r--r--editor/scene_tree_dock.cpp59
-rw-r--r--editor/scene_tree_dock.h9
-rw-r--r--editor/shader_create_dialog.cpp633
-rw-r--r--editor/shader_create_dialog.h115
19 files changed, 1028 insertions, 118 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index c9d3df9ce2..f40dc3c64a 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3418,6 +3418,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
if (bool(EDITOR_DEF("editors/animation/confirm_insert_track", true))) {
//potential new key, does not exist
if (num_tracks == 1) {
+ // TRANSLATORS: %s will be replaced by a phrase describing the target of track.
insert_confirm_text->set_text(vformat(TTR("Create new track for %s and insert key?"), p_id.query));
} else {
insert_confirm_text->set_text(vformat(TTR("Create %d new tracks and insert keys?"), num_tracks));
@@ -3525,7 +3526,8 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
id.track_idx = track_idx;
id.value = p_xform;
id.type = Animation::TYPE_TRANSFORM3D;
- id.query = "node '" + p_node->get_name() + "'";
+ // TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
+ id.query = vformat(TTR("node '%s'"), p_node->get_name());
id.advance = false;
//dialog insert
@@ -3547,7 +3549,8 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
id.track_idx = i;
id.value = p_value;
id.type = Animation::TYPE_ANIMATION;
- id.query = "animation";
+ // TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
+ id.query = TTR("animation");
id.advance = false;
//dialog insert
_query_insert(id);
@@ -3560,7 +3563,7 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
id.track_idx = -1;
id.value = p_value;
id.type = Animation::TYPE_ANIMATION;
- id.query = "animation";
+ id.query = TTR("animation");
id.advance = false;
//dialog insert
_query_insert(id);
@@ -3609,7 +3612,8 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
id.track_idx = i;
id.value = p_value;
id.type = Animation::TYPE_VALUE;
- id.query = "property '" + p_property + "'";
+ // TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = false;
//dialog insert
_query_insert(id);
@@ -3639,7 +3643,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
id.track_idx = i;
id.value = value;
id.type = Animation::TYPE_BEZIER;
- id.query = "property '" + p_property + "'";
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = false;
//dialog insert
_query_insert(id);
@@ -3655,7 +3659,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
id.track_idx = -1;
id.value = p_value;
id.type = Animation::TYPE_VALUE;
- id.query = "property '" + p_property + "'";
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = false;
//dialog insert
_query_insert(id);
@@ -3708,7 +3712,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
id.track_idx = i;
id.value = p_value;
id.type = Animation::TYPE_VALUE;
- id.query = "property '" + p_property + "'";
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = p_advance;
//dialog insert
_query_insert(id);
@@ -3733,7 +3737,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
id.track_idx = i;
id.value = value;
id.type = Animation::TYPE_BEZIER;
- id.query = "property '" + p_property + "'";
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = p_advance;
//dialog insert
_query_insert(id);
@@ -3747,7 +3751,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
id.track_idx = -1;
id.value = p_value;
id.type = Animation::TYPE_VALUE;
- id.query = "property '" + p_property + "'";
+ id.query = vformat(TTR("property '%s'"), p_property);
id.advance = p_advance;
//dialog insert
_query_insert(id);
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index 72a0c353e8..84a9237a96 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -563,7 +563,7 @@ void EditorFeatureProfileManager::_class_list_item_selected() {
int feature_id = md;
String feature_description = EditorFeatureProfile::get_feature_description(EditorFeatureProfile::Feature(feature_id));
- description_bit->set_text(feature_description);
+ description_bit->set_text(TTRGET(feature_description));
return;
} else {
return;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 78500ab16c..2126a7b8be 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4944,6 +4944,16 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
scene_tabs_context_menu->set_position(mb->get_global_position());
scene_tabs_context_menu->popup();
}
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_UP && mb->is_pressed()) {
+ int previous_tab = editor_data.get_edited_scene() - 1;
+ previous_tab = previous_tab >= 0 ? previous_tab : editor_data.get_edited_scene_count() - 1;
+ _scene_tab_changed(previous_tab);
+ }
+ if (mb->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && mb->is_pressed()) {
+ int next_tab = editor_data.get_edited_scene() + 1;
+ next_tab %= editor_data.get_edited_scene_count();
+ _scene_tab_changed(next_tab);
+ }
}
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index fa03d281f2..789cabea9a 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2854,6 +2854,10 @@ void EditorPropertyResource::setup(Object *p_object, const String &p_path, const
EditorScriptPicker *script_picker = memnew(EditorScriptPicker);
script_picker->set_script_owner(Object::cast_to<Node>(p_object));
resource_picker = script_picker;
+ } else if (p_path == "shader" && p_base_type == "Shader" && Object::cast_to<ShaderMaterial>(p_object)) {
+ EditorShaderPicker *shader_picker = memnew(EditorShaderPicker);
+ shader_picker->set_edited_material(Object::cast_to<ShaderMaterial>(p_object));
+ resource_picker = shader_picker;
} else {
resource_picker = memnew(EditorResourcePicker);
}
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index f3965fe7de..a4ab749db4 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -847,6 +847,8 @@ EditorResourcePicker::EditorResourcePicker() {
edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input));
}
+// EditorScriptPicker
+
void EditorScriptPicker::set_create_options(Object *p_menu_node) {
PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node);
if (!menu_node) {
@@ -895,3 +897,42 @@ void EditorScriptPicker::_bind_methods() {
EditorScriptPicker::EditorScriptPicker() {
}
+
+// EditorShaderPicker
+
+void EditorShaderPicker::set_create_options(Object *p_menu_node) {
+ PopupMenu *menu_node = Object::cast_to<PopupMenu>(p_menu_node);
+ if (!menu_node) {
+ return;
+ }
+
+ menu_node->add_icon_item(get_theme_icon("Shader", "EditorIcons"), TTR("New Shader"), OBJ_MENU_NEW_SHADER);
+ menu_node->add_separator();
+}
+
+bool EditorShaderPicker::handle_menu_selected(int p_which) {
+ Ref<ShaderMaterial> material = Ref<ShaderMaterial>(get_edited_material());
+
+ switch (p_which) {
+ case OBJ_MENU_NEW_SHADER: {
+ if (material.is_valid()) {
+ EditorNode::get_singleton()->get_scene_tree_dock()->open_shader_dialog(material);
+ return true;
+ }
+ } break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void EditorShaderPicker::set_edited_material(ShaderMaterial *p_material) {
+ edited_material = p_material;
+}
+
+ShaderMaterial *EditorShaderPicker::get_edited_material() const {
+ return edited_material;
+}
+
+EditorShaderPicker::EditorShaderPicker() {
+}
diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h
index a4c3006c02..d77c31f831 100644
--- a/editor/editor_resource_picker.h
+++ b/editor/editor_resource_picker.h
@@ -144,4 +144,23 @@ public:
EditorScriptPicker();
};
+class EditorShaderPicker : public EditorResourcePicker {
+ GDCLASS(EditorShaderPicker, EditorResourcePicker);
+
+ enum ExtraMenuOption {
+ OBJ_MENU_NEW_SHADER = 10,
+ };
+
+ ShaderMaterial *edited_material = nullptr;
+
+public:
+ virtual void set_create_options(Object *p_menu_node) override;
+ virtual bool handle_menu_selected(int p_which) override;
+
+ void set_edited_material(ShaderMaterial *p_material);
+ ShaderMaterial *get_edited_material() const;
+
+ EditorShaderPicker();
+};
+
#endif // EDITOR_RESOURCE_PICKER_H
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 29ac836834..b1cd53092d 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -374,6 +374,11 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/display_scale", 0);
// Display what the Auto display scale setting effectively corresponds to.
float scale = get_auto_display_scale();
+
+ _initial_set("interface/editor/enable_debugging_pseudolocalization", false);
+ set_restart_if_changed("interface/editor/enable_debugging_pseudolocalization", true);
+ // Use pseudolocalization in editor.
+
hints["interface/editor/display_scale"] = PropertyInfo(Variant::INT, "interface/editor/display_scale", PROPERTY_HINT_ENUM, vformat("Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom", Math::round(scale * 100)), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
_initial_set("interface/editor/custom_display_scale", 1.0f);
hints["interface/editor/custom_display_scale"] = PropertyInfo(Variant::FLOAT, "interface/editor/custom_display_scale", PROPERTY_HINT_RANGE, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
@@ -953,11 +958,11 @@ fail:
}
void EditorSettings::setup_language() {
+ TranslationServer::get_singleton()->set_editor_pseudolocalization(get("interface/editor/enable_debugging_pseudolocalization"));
String lang = get("interface/editor/editor_language");
if (lang == "en") {
return; // Default, nothing to do.
}
-
// Load editor translation for configured/detected locale.
EditorTranslationList *etl = _editor_translations;
while (etl->data) {
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 699957897f..b646b3361d 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -889,8 +889,8 @@ ExportTemplateManager::ExportTemplateManager() {
request_mirrors->connect("request_completed", callable_mp(this, &ExportTemplateManager::_refresh_mirrors_completed));
mirror_options_button = memnew(MenuButton);
- mirror_options_button->get_popup()->add_item("Open in Web Browser", VISIT_WEB_MIRROR);
- mirror_options_button->get_popup()->add_item("Copy Mirror URL", COPY_MIRROR_URL);
+ mirror_options_button->get_popup()->add_item(TTR("Open in Web Browser"), VISIT_WEB_MIRROR);
+ mirror_options_button->get_popup()->add_item(TTR("Copy Mirror URL"), COPY_MIRROR_URL);
download_install_hb->add_child(mirror_options_button);
mirror_options_button->get_popup()->connect("id_pressed", callable_mp(this, &ExportTemplateManager::_mirror_options_button_cbk));
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 46e15d97bf..b8cbaaf7c1 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -145,7 +145,7 @@ Variant EditorNode3DGizmo::get_handle_value(int p_id) const {
return gizmo_plugin->get_handle_value(this, p_id);
}
-void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) {
if (get_script_instance() && get_script_instance()->has_method("_set_handle")) {
get_script_instance()->call("_set_handle", p_id, p_camera, p_point);
return;
@@ -155,7 +155,7 @@ void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p
gizmo_plugin->set_handle(this, p_id, p_camera, p_point);
}
-void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) const {
+void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) {
if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) {
get_script_instance()->call("_commit_handle", p_id, p_restore, p_cancel);
return;
@@ -196,7 +196,7 @@ Transform3D EditorNode3DGizmo::get_subgizmo_transform(int p_id) const {
return gizmo_plugin->get_subgizmo_transform(this, p_id);
}
-void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform) const {
+void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform) {
if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) {
get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform);
return;
@@ -206,7 +206,7 @@ void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform
gizmo_plugin->set_subgizmo_transform(this, p_id, p_transform);
}
-void EditorNode3DGizmo::commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) const {
+void EditorNode3DGizmo::commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) {
if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) {
Array ids;
for (int i = 0; i < p_ids.size(); i++) {
@@ -1145,13 +1145,13 @@ Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_giz
return Variant();
}
-void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
if (get_script_instance() && get_script_instance()->has_method("_set_handle")) {
get_script_instance()->call("_set_handle", p_gizmo, p_id, p_camera, p_point);
}
}
-void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) {
get_script_instance()->call("_commit_handle", p_gizmo, p_id, p_restore, p_cancel);
}
@@ -1184,13 +1184,13 @@ Transform3D EditorNode3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGi
return Transform3D();
}
-void EditorNode3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) const {
+void EditorNode3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) {
if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) {
get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform);
}
}
-void EditorNode3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) const {
+void EditorNode3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) {
if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) {
Array ids;
for (int i = 0; i < p_ids.size(); i++) {
@@ -1310,7 +1310,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec
return Math::rad2deg(a);
}
-void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
Transform3D gt = light->get_global_transform();
Transform3D gi = gt.affine_inverse();
@@ -1354,7 +1354,7 @@ void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
}
}
-void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore);
@@ -1538,7 +1538,7 @@ Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo
return player->get_emission_angle();
}
-void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
Transform3D gt = player->get_global_transform();
@@ -1575,7 +1575,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo
}
}
-void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -1684,7 +1684,7 @@ Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo,
}
}
-void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
Transform3D gt = camera->get_global_transform();
@@ -1713,7 +1713,7 @@ void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
}
}
-void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
@@ -2572,7 +2572,7 @@ Variant SoftBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo
return Variant(soft_body->is_point_pinned(p_id));
}
-void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node());
soft_body->pin_point_toggle(p_id);
}
@@ -2628,7 +2628,7 @@ Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3
return notifier->get_aabb();
}
-void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node());
Transform3D gt = notifier->get_global_transform();
@@ -2680,7 +2680,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p
}
}
-void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2820,7 +2820,7 @@ Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_g
return particles->get_visibility_aabb();
}
-void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
Transform3D gt = particles->get_global_transform();
@@ -2871,7 +2871,7 @@ void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int
}
}
-void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2985,7 +2985,7 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DG
return Variant();
}
-void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
Node3D *sn = p_gizmo->get_spatial_node();
Transform3D gt = sn->get_global_transform();
@@ -3031,7 +3031,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
}
}
-void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
Node3D *sn = p_gizmo->get_spatial_node();
if (Object::cast_to<GPUParticlesCollisionSphere>(sn) || Object::cast_to<GPUParticlesAttractorSphere>(sn)) {
@@ -3245,7 +3245,7 @@ Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_
return AABB(probe->get_extents(), probe->get_origin_offset());
}
-void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
Transform3D gt = probe->get_global_transform();
@@ -3302,7 +3302,7 @@ void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, in
}
}
-void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
AABB restore = p_restore;
@@ -3424,7 +3424,7 @@ Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int
return decal->get_extents();
}
-void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Transform3D gt = decal->get_global_transform();
@@ -3455,7 +3455,7 @@ void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Ca
decal->set_extents(extents);
}
-void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -3564,7 +3564,7 @@ Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, i
return probe->get_extents();
}
-void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node());
Transform3D gt = probe->get_global_transform();
@@ -3595,7 +3595,7 @@ void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
probe->set_extents(extents);
}
-void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -3723,10 +3723,10 @@ Variant LightmapGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo
return Variant();
}
-void LightmapGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void LightmapGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
}
-void LightmapGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void LightmapGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
}
bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -3905,10 +3905,10 @@ Variant LightmapProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gi
return Variant();
}
-void LightmapProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void LightmapProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
}
-void LightmapProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void LightmapProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
}
bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -4124,7 +4124,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
return Variant();
}
-void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
@@ -4241,7 +4241,7 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
}
}
-void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) const {
+void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index f303a61607..53f602460c 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -91,14 +91,14 @@ public:
virtual bool is_handle_highlighted(int p_id) const;
virtual String get_handle_name(int p_id) const;
virtual Variant get_handle_value(int p_id) const;
- virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const;
- virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const;
+ virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point);
+ virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false);
virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
virtual Transform3D get_subgizmo_transform(int p_id) const;
- virtual void set_subgizmo_transform(int p_id, Transform3D p_transform) const;
- virtual void commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const;
+ virtual void set_subgizmo_transform(int p_id, Transform3D p_transform);
+ virtual void commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false);
void set_selected(bool p_selected) { selected = p_selected; }
bool is_selected() const { return selected; }
@@ -161,14 +161,14 @@ public:
virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const;
virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const;
- virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const;
- virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const;
+ virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point);
+ virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false);
virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const;
- virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) const;
- virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) const;
+ virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform);
+ virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false);
Ref<EditorNode3DGizmo> get_gizmo(Node3D *p_spatial);
void set_state(int p_state);
@@ -189,8 +189,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Light3DGizmoPlugin();
@@ -206,8 +206,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
AudioStreamPlayer3DGizmoPlugin();
@@ -223,8 +223,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Camera3DGizmoPlugin();
@@ -355,7 +355,7 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
SoftBody3DGizmoPlugin();
@@ -372,8 +372,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
VisibleOnScreenNotifier3DGizmoPlugin();
};
@@ -402,8 +402,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
GPUParticles3DGizmoPlugin();
};
@@ -419,8 +419,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
GPUParticlesCollision3DGizmoPlugin();
};
@@ -436,8 +436,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
ReflectionProbeGizmoPlugin();
};
@@ -453,8 +453,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
DecalGizmoPlugin();
};
@@ -470,8 +470,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
VoxelGIGizmoPlugin();
};
@@ -487,8 +487,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
LightmapGIGizmoPlugin();
};
@@ -504,8 +504,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
LightmapProbeGizmoPlugin();
};
@@ -533,8 +533,8 @@ public:
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
CollisionShape3DGizmoPlugin();
};
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 5ed8205475..931c50fc44 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -122,31 +122,28 @@ void ViewportRotationControl::_draw() {
}
void ViewportRotationControl::_draw_axis(const Axis2D &p_axis) {
- bool focused = focused_axis == p_axis.axis;
- bool positive = p_axis.axis < 3;
- bool front = (Math::abs(p_axis.z_axis) <= 0.001 && positive) || p_axis.z_axis > 0.001;
- int direction = p_axis.axis % 3;
+ const bool focused = focused_axis == p_axis.axis;
+ const bool positive = p_axis.axis < 3;
+ const int direction = p_axis.axis % 3;
- Color axis_color = axis_colors[direction];
-
- if (!front) {
- axis_color = axis_color.darkened(0.4);
- }
- Color c = focused ? Color(0.9, 0.9, 0.9) : axis_color;
+ const Color axis_color = axis_colors[direction];
+ const double alpha = focused ? 1.0 : ((p_axis.z_axis + 1.0) / 2.0) * 0.5 + 0.5;
+ const Color c = focused ? Color(0.9, 0.9, 0.9) : Color(axis_color.r, axis_color.g, axis_color.b, alpha);
if (positive) {
- Vector2i center = get_size() / 2.0;
+ // Draw axis lines for the positive axes.
+ const Vector2i center = get_size() / 2.0;
draw_line(center, p_axis.screen_point, c, 1.5 * EDSCALE);
- }
- if (front) {
draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS, c);
- if (positive) {
- String axis_name = direction == 0 ? "X" : (direction == 1 ? "Y" : "Z");
- draw_char(get_theme_font(SNAME("rotation_control"), SNAME("EditorFonts")), p_axis.screen_point + Vector2i(-4, 5) * EDSCALE, axis_name, "", get_theme_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts")), Color(0.0, 0.0, 0.0));
- }
+
+ // Draw the axis letter for the positive axes.
+ const String axis_name = direction == 0 ? "X" : (direction == 1 ? "Y" : "Z");
+ draw_char(get_theme_font(SNAME("rotation_control"), SNAME("EditorFonts")), p_axis.screen_point + Vector2i(-4, 5) * EDSCALE, axis_name, "", get_theme_font_size(SNAME("rotation_control_size"), SNAME("EditorFonts")), Color(0.0, 0.0, 0.0, alpha));
} else {
- draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS * (0.55 + (0.2 * (1.0 + p_axis.z_axis))), c);
+ // Draw an outline around the negative axes.
+ draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS, c);
+ draw_circle(p_axis.screen_point, AXIS_CIRCLE_RADIUS * 0.8, c.darkened(0.4));
}
}
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index 63b89aea35..13f7908170 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -88,7 +88,7 @@ Variant Path3DGizmo::get_handle_value(int p_id) const {
return ofs;
}
-void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const {
+void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
@@ -157,7 +157,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point
}
}
-void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) const {
+void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index 5902500526..b74d7cc59e 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -47,8 +47,8 @@ class Path3DGizmo : public EditorNode3DGizmo {
public:
virtual String get_handle_name(int p_idx) const override;
virtual Variant get_handle_value(int p_id) const override;
- virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) const override;
- virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) const override;
+ virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) override;
+ virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) override;
virtual void redraw() override;
Path3DGizmo(Path3D *p_path = nullptr);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 452ad126b3..9a41a100bd 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -1007,6 +1007,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
const Dictionary vs_version = visual_shader->get_engine_version();
if (!vs_version.has_all(components)) {
visual_shader->update_engine_version(engine_version);
+ print_line(vformat(TTR("The shader (\"%s\") has been updated to correspond Godot %s.%s version."), visual_shader->get_path(), engine_version["major"], engine_version["minor"]));
} else {
for (int i = 0; i < components.size(); i++) {
if (vs_version[components[i]] != engine_version[components[i]]) {
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index a1deae92a4..96fcb4fe29 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -351,51 +351,64 @@ void PropertySelector::_item_selected() {
String class_type;
if (type != Variant::NIL) {
class_type = Variant::get_type_name(type);
-
- } else {
+ } else if (base_type != String()) {
class_type = base_type;
+ } else if (instance) {
+ class_type = instance->get_class();
}
DocTools *dd = EditorHelp::get_doc_data();
String text;
-
if (properties) {
- String at_class = class_type;
-
- while (at_class != String()) {
- Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
+ while (class_type != String()) {
+ Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(class_type);
if (E) {
for (int i = 0; i < E->get().properties.size(); i++) {
if (E->get().properties[i].name == name) {
text = DTR(E->get().properties[i].description);
+ break;
}
}
}
- at_class = ClassDB::get_parent_class(at_class);
+ if (text != String()) {
+ break;
+ }
+
+ // The property may be from a parent class, keep looking.
+ class_type = ClassDB::get_parent_class(class_type);
}
} else {
- String at_class = class_type;
-
- while (at_class != String()) {
- Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
+ while (class_type != String()) {
+ Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(class_type);
if (E) {
for (int i = 0; i < E->get().methods.size(); i++) {
if (E->get().methods[i].name == name) {
text = DTR(E->get().methods[i].description);
+ break;
}
}
}
- at_class = ClassDB::get_parent_class(at_class);
+ if (text != String()) {
+ break;
+ }
+
+ // The method may be from a parent class, keep looking.
+ class_type = ClassDB::get_parent_class(class_type);
}
}
- if (text == String()) {
- return;
+ if (text != String()) {
+ // Display both property name and description, since the help bit may be displayed
+ // far away from the location (especially if the dialog was resized to be taller).
+ help_bit->set_text(vformat("[b]%s[/b]: %s", name, text));
+ help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
+ } else {
+ // Use nested `vformat()` as translators shouldn't interfere with BBCode tags.
+ help_bit->set_text(vformat(TTR("No description available for %s."), vformat("[b]%s[/b]", name)));
+ help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
}
-
- help_bit->set_text(text);
}
void PropertySelector::_hide_requested() {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index c4d47c7594..8994adf112 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -45,6 +45,7 @@
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
+#include "editor/shader_create_dialog.h"
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
#include "servers/display_server.h"
@@ -1939,12 +1940,31 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
_update_script_button();
}
+void SceneTreeDock::_shader_created(Ref<Shader> p_shader) {
+ if (selected_shader_material.is_null()) {
+ return;
+ }
+
+ Ref<Shader> existing = selected_shader_material->get_shader();
+
+ editor_data->get_undo_redo().create_action(TTR("Set Shader"));
+ editor_data->get_undo_redo().add_do_method(selected_shader_material.ptr(), "set_shader", p_shader);
+ editor_data->get_undo_redo().add_undo_method(selected_shader_material.ptr(), "set_shader", existing);
+ editor_data->get_undo_redo().commit_action();
+}
+
void SceneTreeDock::_script_creation_closed() {
script_create_dialog->disconnect("script_created", callable_mp(this, &SceneTreeDock::_script_created));
script_create_dialog->disconnect("confirmed", callable_mp(this, &SceneTreeDock::_script_creation_closed));
script_create_dialog->disconnect("cancelled", callable_mp(this, &SceneTreeDock::_script_creation_closed));
}
+void SceneTreeDock::_shader_creation_closed() {
+ shader_create_dialog->disconnect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created));
+ shader_create_dialog->disconnect("confirmed", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
+ shader_create_dialog->disconnect("cancelled", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
+}
+
void SceneTreeDock::_toggle_editable_children_from_selection() {
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
@@ -2896,6 +2916,42 @@ void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) {
}
}
+void SceneTreeDock::attach_shader_to_selected() {
+ if (selected_shader_material.is_null()) {
+ return;
+ }
+
+ String path = selected_shader_material->get_path();
+ if (path == "") {
+ String root_path;
+ if (editor_data->get_edited_scene_root()) {
+ root_path = editor_data->get_edited_scene_root()->get_filename();
+ }
+ String shader_name;
+ if (selected_shader_material->get_name().is_empty()) {
+ shader_name = root_path.get_file();
+ } else {
+ shader_name = selected_shader_material->get_name();
+ }
+ if (root_path == "") {
+ path = String("res://").plus_file(shader_name);
+ } else {
+ path = root_path.get_base_dir().plus_file(shader_name);
+ }
+ }
+
+ shader_create_dialog->connect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created));
+ shader_create_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
+ shader_create_dialog->connect("cancelled", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
+ shader_create_dialog->config(path);
+ shader_create_dialog->popup_centered();
+}
+
+void SceneTreeDock::open_shader_dialog(Ref<ShaderMaterial> &p_for_material) {
+ selected_shader_material = p_for_material;
+ attach_shader_to_selected();
+}
+
void SceneTreeDock::open_add_child_dialog() {
create_dialog->set_base_type("CanvasItem");
_tool_selected(TOOL_NEW, true);
@@ -3267,6 +3323,9 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
script_create_dialog->set_inheritance_base_type("Node");
add_child(script_create_dialog);
+ shader_create_dialog = memnew(ShaderCreateDialog);
+ add_child(shader_create_dialog);
+
reparent_dialog = memnew(ReparentDialog);
add_child(reparent_dialog);
reparent_dialog->connect("reparent", callable_mp(this, &SceneTreeDock::_node_reparent));
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 4952122cb7..ccdc0a3786 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -49,6 +49,7 @@
#include "scene_tree_editor.h"
class EditorNode;
+class ShaderCreateDialog;
class SceneTreeDock : public VBoxContainer {
GDCLASS(SceneTreeDock, VBoxContainer);
@@ -138,6 +139,7 @@ class SceneTreeDock : public VBoxContainer {
HashMap<String, Map<RES, RES>> clipboard_resource_remap;
ScriptCreateDialog *script_create_dialog;
+ ShaderCreateDialog *shader_create_dialog;
AcceptDialog *accept;
ConfirmationDialog *delete_dialog;
ConfirmationDialog *editable_instance_remove_dialog;
@@ -166,6 +168,8 @@ class SceneTreeDock : public VBoxContainer {
VBoxContainer *create_root_dialog;
String selected_favorite_root;
+ Ref<ShaderMaterial> selected_shader_material;
+
void _add_children_to_popup(Object *p_obj, int p_depth);
void _node_reparent(NodePath p_path, bool p_keep_global_xform);
@@ -192,7 +196,9 @@ class SceneTreeDock : public VBoxContainer {
void _node_selected();
void _node_renamed();
void _script_created(Ref<Script> p_script);
+ void _shader_created(Ref<Shader> p_shader);
void _script_creation_closed();
+ void _shader_creation_closed();
void _delete_confirm(bool p_cut = false);
@@ -288,6 +294,9 @@ public:
void attach_script_to_selected(bool p_extend);
void open_script_dialog(Node *p_for_node, bool p_extend);
+ void attach_shader_to_selected();
+ void open_shader_dialog(Ref<ShaderMaterial> &p_for_material);
+
void open_add_child_dialog();
void open_instance_child_dialog();
diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp
new file mode 100644
index 0000000000..28d7dc43c0
--- /dev/null
+++ b/editor/shader_create_dialog.cpp
@@ -0,0 +1,633 @@
+/*************************************************************************/
+/* shader_create_dialog.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 "shader_create_dialog.h"
+#include "editor/editor_scale.h"
+#include "scene/resources/visual_shader.h"
+#include "servers/rendering/shader_types.h"
+
+void ShaderCreateDialog::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ _update_theme();
+
+ String last_lang = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_language", "");
+ if (!last_lang.is_empty()) {
+ for (int i = 0; i < language_menu->get_item_count(); i++) {
+ if (language_menu->get_item_text(i) == last_lang) {
+ language_menu->select(i);
+ current_language = i;
+ break;
+ }
+ }
+ } else {
+ language_menu->select(default_language);
+ }
+
+ current_mode = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_mode", 0);
+ mode_menu->select(current_mode);
+ } break;
+ case NOTIFICATION_THEME_CHANGED: {
+ _update_theme();
+ } break;
+ }
+}
+
+void ShaderCreateDialog::_update_theme() {
+ Ref<Texture2D> shader_icon = gc->get_theme_icon(SNAME("Shader"), SNAME("EditorIcons"));
+ if (shader_icon.is_valid()) {
+ language_menu->set_item_icon(0, shader_icon);
+ }
+
+ Ref<Texture2D> visual_shader_icon = gc->get_theme_icon(SNAME("VisualShader"), SNAME("EditorIcons"));
+ if (visual_shader_icon.is_valid()) {
+ language_menu->set_item_icon(1, visual_shader_icon);
+ }
+
+ path_button->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
+ status_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("bg"), SNAME("Tree")));
+}
+
+void ShaderCreateDialog::_update_language_info() {
+ language_data.clear();
+
+ List<StringName> classes;
+ classes.push_front(SNAME("Shader"));
+ classes.push_front(SNAME("VisualShader"));
+
+ for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
+ language_data.push_back(ShaderTypeData());
+ }
+
+ int idx = 0;
+ for (List<ShaderTypeData>::Element *E = language_data.front(); E; E = E->next()) {
+ if (idx == int(SHADER_TYPE_TEXT)) {
+ E->get().use_templates = true;
+ E->get().extensions.push_back("gdshader");
+ E->get().default_extension = "gdshader";
+ } else {
+ E->get().default_extension = "tres";
+ }
+ E->get().extensions.push_back("res");
+ E->get().extensions.push_back("tres");
+ idx++;
+ }
+}
+
+void ShaderCreateDialog::_path_hbox_sorted() {
+ if (is_visible()) {
+ int filename_start_pos = initial_base_path.rfind("/") + 1;
+ int filename_end_pos = initial_base_path.length();
+
+ if (!is_built_in) {
+ file_path->select(filename_start_pos, filename_end_pos);
+ }
+
+ file_path->set_caret_column(file_path->get_text().length());
+ file_path->set_caret_column(filename_start_pos);
+
+ file_path->grab_focus();
+ }
+}
+
+void ShaderCreateDialog::_mode_changed(int p_mode) {
+ current_mode = p_mode;
+ EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_mode", p_mode);
+}
+
+void ShaderCreateDialog::_template_changed(int p_template) {
+ current_template = p_template;
+ EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_template", p_template);
+}
+
+void ShaderCreateDialog::ok_pressed() {
+ if (is_new_shader_created) {
+ _create_new();
+ } else {
+ _load_exist();
+ }
+
+ is_new_shader_created = true;
+ _update_dialog();
+}
+
+void ShaderCreateDialog::_create_new() {
+ RES shader;
+
+ if (language_menu->get_selected() == int(SHADER_TYPE_TEXT)) {
+ Ref<Shader> text_shader;
+ text_shader.instantiate();
+ shader = text_shader;
+
+ StringBuilder code;
+ code += vformat("shader_type %s;\n", mode_menu->get_text().replace(" ", "").camelcase_to_underscore());
+
+ if (current_template == 0) { // Default template.
+ code += "\n";
+ switch (current_mode) {
+ case Shader::MODE_SPATIAL:
+ code += "void fragment() {\n";
+ code += "\t// Place fragment code here.\n";
+ code += "}\n";
+ break;
+ case Shader::MODE_CANVAS_ITEM:
+ code += "void fragment() {\n";
+ code += "\t// Place fragment code here.\n";
+ code += "}\n";
+ break;
+ case Shader::MODE_PARTICLES:
+ code += "void start() {\n";
+ code += "\t// Place start code here.\n";
+ code += "}\n";
+ code += "\n";
+ code += "void process() {\n";
+ code += "\t// Place process code here.\n";
+ code += "}\n";
+ break;
+ case Shader::MODE_SKY:
+ code += "void sky() {\n";
+ code += "\t// Place sky code here.\n";
+ code += "}\n";
+ break;
+ }
+ }
+ text_shader->set_code(code.as_string());
+ } else {
+ Ref<VisualShader> visual_shader;
+ visual_shader.instantiate();
+ shader = visual_shader;
+ visual_shader->set_engine_version(Engine::get_singleton()->get_version_info());
+ visual_shader->set_mode(Shader::Mode(current_mode));
+ }
+
+ if (!is_built_in) {
+ String lpath = ProjectSettings::get_singleton()->localize_path(file_path->get_text());
+ shader->set_path(lpath);
+ Error err = ResourceSaver::save(lpath, shader, ResourceSaver::FLAG_CHANGE_PATH);
+ if (err != OK) {
+ alert->set_text(TTR("Error - Could not create shader in filesystem."));
+ alert->popup_centered();
+ return;
+ }
+ }
+
+ emit_signal("shader_created", shader);
+ hide();
+}
+
+void ShaderCreateDialog::_load_exist() {
+ String path = file_path->get_text();
+ RES p_shader = ResourceLoader::load(path, "Shader");
+ if (p_shader.is_null()) {
+ alert->set_text(vformat(TTR("Error loading shader from %s"), path));
+ alert->popup_centered();
+ return;
+ }
+
+ emit_signal("shader_created", p_shader);
+ hide();
+}
+
+void ShaderCreateDialog::_language_changed(int p_language) {
+ ShaderTypeData data = language_data[p_language];
+
+ String selected_ext = "." + data.default_extension;
+ String path = file_path->get_text();
+ String extension = "";
+
+ if (path != "") {
+ if (path.find(".") != -1) {
+ extension = path.get_extension();
+ }
+ if (extension.length() == 0) {
+ path += selected_ext;
+ } else {
+ path = path.get_basename() + selected_ext;
+ }
+ } else {
+ path = "shader" + selected_ext;
+ }
+ _path_changed(path);
+ file_path->set_text(path);
+
+ template_menu->set_disabled(!data.use_templates);
+ template_menu->clear();
+
+ if (data.use_templates) {
+ int last_template = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_template", 0);
+
+ template_menu->add_item(TTR("Default"));
+ template_menu->add_item(TTR("Empty"));
+
+ template_menu->select(last_template);
+ current_template = last_template;
+ } else {
+ template_menu->add_item(TTR("N/A"));
+ }
+
+ EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_language", language_menu->get_item_text(language_menu->get_selected()));
+ _update_dialog();
+}
+
+void ShaderCreateDialog::_built_in_toggled(bool p_enabled) {
+ is_built_in = p_enabled;
+ if (p_enabled) {
+ is_new_shader_created = true;
+ } else {
+ _path_changed(file_path->get_text());
+ }
+ _update_dialog();
+}
+
+void ShaderCreateDialog::_browse_path() {
+ file_browse->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ file_browse->set_title(TTR("Open Shader / Choose Location"));
+ file_browse->get_ok_button()->set_text(TTR("Open"));
+
+ file_browse->set_disable_overwrite_warning(true);
+ file_browse->clear_filters();
+
+ List<String> extensions = language_data[language_menu->get_selected()].extensions;
+
+ for (const String &E : extensions) {
+ file_browse->add_filter("*." + E);
+ }
+
+ file_browse->set_current_path(file_path->get_text());
+ file_browse->popup_file_dialog();
+}
+
+void ShaderCreateDialog::_file_selected(const String &p_file) {
+ String p = ProjectSettings::get_singleton()->localize_path(p_file);
+ file_path->set_text(p);
+ _path_changed(p);
+
+ String filename = p.get_file().get_basename();
+ int select_start = p.rfind(filename);
+ file_path->select(select_start, select_start + filename.length());
+ file_path->set_caret_column(select_start + filename.length());
+ file_path->grab_focus();
+}
+
+void ShaderCreateDialog::_path_changed(const String &p_path) {
+ if (is_built_in) {
+ return;
+ }
+
+ is_path_valid = false;
+ is_new_shader_created = true;
+
+ String path_error = _validate_path(p_path, false);
+ if (path_error != "") {
+ _msg_path_valid(false, path_error);
+ _update_dialog();
+ return;
+ }
+
+ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ String p = ProjectSettings::get_singleton()->localize_path(p_path.strip_edges());
+ if (f->file_exists(p)) {
+ is_new_shader_created = false;
+ _msg_path_valid(true, TTR("File exists, it will be reused."));
+ }
+ memdelete(f);
+
+ is_path_valid = true;
+ _update_dialog();
+}
+
+void ShaderCreateDialog::_path_submitted(const String &p_path) {
+ ok_pressed();
+}
+
+void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled) {
+ if (p_base_path != "") {
+ initial_base_path = p_base_path.get_basename();
+ file_path->set_text(initial_base_path + "." + language_data[language_menu->get_selected()].default_extension);
+ current_language = language_menu->get_selected();
+ } else {
+ initial_base_path = "";
+ file_path->set_text("");
+ }
+ file_path->deselect();
+
+ built_in_enabled = p_built_in_enabled;
+ load_enabled = p_load_enabled;
+
+ _language_changed(current_language);
+ _path_changed(file_path->get_text());
+}
+
+String ShaderCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
+ String p = p_path.strip_edges();
+
+ if (p == "") {
+ return TTR("Path is empty.");
+ }
+ if (p.get_file().get_basename() == "") {
+ return TTR("Filename is empty.");
+ }
+
+ p = ProjectSettings::get_singleton()->localize_path(p);
+ if (!p.begins_with("res://")) {
+ return TTR("Path is not local.");
+ }
+
+ DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (d->change_dir(p.get_base_dir()) != OK) {
+ memdelete(d);
+ return TTR("Invalid base path.");
+ }
+ memdelete(d);
+
+ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (f->dir_exists(p)) {
+ memdelete(f);
+ return TTR("A directory with the same name exists.");
+ } else if (p_file_must_exist && !f->file_exists(p)) {
+ memdelete(f);
+ return TTR("File does not exist.");
+ }
+ memdelete(f);
+
+ String extension = p.get_extension();
+ Set<String> extensions;
+
+ for (int l = 0; l < SHADER_TYPE_MAX; l++) {
+ for (List<String>::Element *E = language_data[l].extensions.front(); E; E = E->next()) {
+ if (!extensions.has(E->get())) {
+ extensions.insert(E->get());
+ }
+ }
+ }
+
+ ShaderTypeData data = language_data[language_menu->get_selected()];
+
+ bool match = false;
+ int index = 0;
+ for (Set<String>::Element *E = extensions.front(); E; E = E->next()) {
+ if (E->get().nocasecmp_to(extension) == 0) {
+ match = true;
+ break;
+ }
+ index++;
+ }
+
+ if (!match) {
+ return TTR("Wrong extension chosen.");
+ }
+
+ return "";
+}
+
+void ShaderCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
+ error_label->set_text("- " + p_msg);
+ if (valid) {
+ error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
+ } else {
+ error_label->add_theme_color_override("font_color", gc->get_theme_color("error_color", "Editor"));
+ }
+}
+
+void ShaderCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
+ path_error_label->set_text("- " + p_msg);
+ if (valid) {
+ path_error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
+ } else {
+ path_error_label->add_theme_color_override("font_color", gc->get_theme_color("error_color", "Editor"));
+ }
+}
+
+void ShaderCreateDialog::_update_dialog() {
+ bool shader_ok = true;
+
+ if (!is_built_in && !is_path_valid) {
+ _msg_script_valid(false, TTR("Invalid path."));
+ shader_ok = false;
+ }
+ if (shader_ok) {
+ _msg_script_valid(true, TTR("Shader path/name is valid."));
+ }
+ if (!built_in_enabled) {
+ internal->set_pressed(false);
+ }
+
+ if (is_built_in) {
+ file_path->set_editable(false);
+ path_button->set_disabled(true);
+ re_check_path = true;
+ } else {
+ file_path->set_editable(true);
+ path_button->set_disabled(false);
+ if (re_check_path) {
+ re_check_path = false;
+ _path_changed(file_path->get_text());
+ }
+ }
+
+ internal->set_disabled(!built_in_enabled);
+
+ builtin_warning_label->set_visible(is_built_in);
+
+ if (is_built_in) {
+ get_ok_button()->set_text(TTR("Create"));
+ _msg_path_valid(true, TTR("Built-in shader (into scene file)."));
+ } else if (is_new_shader_created) {
+ get_ok_button()->set_text(TTR("Create"));
+ if (is_path_valid) {
+ _msg_path_valid(true, TTR("Will create a new shader file."));
+ }
+ } else if (load_enabled) {
+ get_ok_button()->set_text(TTR("Load"));
+ if (is_path_valid) {
+ _msg_path_valid(true, TTR("Will load an existing shader file."));
+ }
+ } else {
+ get_ok_button()->set_text(TTR("Create"));
+ _msg_path_valid(false, TTR("Shader file already exists."));
+
+ shader_ok = false;
+ }
+
+ get_ok_button()->set_disabled(!shader_ok);
+
+ Callable entered_call = callable_mp(this, &ShaderCreateDialog::_path_submitted);
+ if (shader_ok) {
+ if (!file_path->is_connected("text_submitted", entered_call)) {
+ file_path->connect("text_submitted", entered_call);
+ }
+ } else if (file_path->is_connected("text_submitted", entered_call)) {
+ file_path->disconnect("text_submitted", entered_call);
+ }
+}
+
+void ShaderCreateDialog::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("config", "path", "built_in_enabled", "load_enabled"), &ShaderCreateDialog::config, DEFVAL(true), DEFVAL(true));
+
+ ADD_SIGNAL(MethodInfo("shader_created", PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader")));
+}
+
+ShaderCreateDialog::ShaderCreateDialog() {
+ _update_language_info();
+
+ // Main Controls.
+
+ gc = memnew(GridContainer);
+ gc->set_columns(2);
+
+ // Error Fields.
+
+ VBoxContainer *vb = memnew(VBoxContainer);
+
+ error_label = memnew(Label);
+ vb->add_child(error_label);
+
+ path_error_label = memnew(Label);
+ vb->add_child(path_error_label);
+
+ builtin_warning_label = memnew(Label);
+ builtin_warning_label->set_text(
+ TTR("Note: Built-in shaders can't be edited using an external editor."));
+ vb->add_child(builtin_warning_label);
+ builtin_warning_label->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
+ builtin_warning_label->hide();
+
+ status_panel = memnew(PanelContainer);
+ status_panel->set_h_size_flags(Control::SIZE_FILL);
+ status_panel->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ status_panel->add_child(vb);
+
+ // Spacing.
+
+ Control *spacing = memnew(Control);
+ spacing->set_custom_minimum_size(Size2(0, 10 * EDSCALE));
+
+ vb = memnew(VBoxContainer);
+ vb->add_child(gc);
+ vb->add_child(spacing);
+ vb->add_child(status_panel);
+ add_child(vb);
+
+ // Language.
+
+ language_menu = memnew(OptionButton);
+ language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE);
+ language_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ gc->add_child(memnew(Label(TTR("Language:"))));
+ gc->add_child(language_menu);
+
+ for (int i = 0; i < SHADER_TYPE_MAX; i++) {
+ String language;
+ bool invalid = false;
+ switch (i) {
+ case SHADER_TYPE_TEXT:
+ language = "Shader";
+ default_language = i;
+ break;
+ case SHADER_TYPE_VISUAL:
+ language = "VisualShader";
+ break;
+ case SHADER_TYPE_MAX:
+ invalid = true;
+ break;
+ default:
+ invalid = true;
+ break;
+ }
+ if (invalid) {
+ continue;
+ }
+ language_menu->add_item(language);
+ }
+ if (default_language >= 0) {
+ language_menu->select(default_language);
+ }
+ current_language = default_language;
+ language_menu->connect("item_selected", callable_mp(this, &ShaderCreateDialog::_language_changed));
+
+ // Modes.
+
+ mode_menu = memnew(OptionButton);
+ for (const List<String>::Element *E = ShaderTypes::get_singleton()->get_types_list().front(); E; E = E->next()) {
+ mode_menu->add_item(E->get().capitalize());
+ }
+ gc->add_child(memnew(Label(TTR("Mode:"))));
+ gc->add_child(mode_menu);
+ mode_menu->connect("item_selected", callable_mp(this, &ShaderCreateDialog::_mode_changed));
+
+ // Templates.
+
+ template_menu = memnew(OptionButton);
+ gc->add_child(memnew(Label(TTR("Template:"))));
+ gc->add_child(template_menu);
+ template_menu->connect("item_selected", callable_mp(this, &ShaderCreateDialog::_template_changed));
+
+ // Built-in Shader.
+
+ internal = memnew(CheckBox);
+ internal->set_text(TTR("On"));
+ internal->connect("toggled", callable_mp(this, &ShaderCreateDialog::_built_in_toggled));
+ gc->add_child(memnew(Label(TTR("Built-in Shader:"))));
+ gc->add_child(internal);
+
+ // Path.
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hb->connect("sort_children", callable_mp(this, &ShaderCreateDialog::_path_hbox_sorted));
+ file_path = memnew(LineEdit);
+ file_path->connect("text_changed", callable_mp(this, &ShaderCreateDialog::_path_changed));
+ file_path->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hb->add_child(file_path);
+ path_button = memnew(Button);
+ path_button->connect("pressed", callable_mp(this, &ShaderCreateDialog::_browse_path));
+ hb->add_child(path_button);
+ gc->add_child(memnew(Label(TTR("Path:"))));
+ gc->add_child(hb);
+
+ // Dialog Setup.
+
+ file_browse = memnew(EditorFileDialog);
+ file_browse->connect("file_selected", callable_mp(this, &ShaderCreateDialog::_file_selected));
+ file_browse->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
+ add_child(file_browse);
+
+ alert = memnew(AcceptDialog);
+ alert->get_label()->set_autowrap_mode(Label::AUTOWRAP_WORD_SMART);
+ alert->get_label()->set_align(Label::ALIGN_CENTER);
+ alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
+ add_child(alert);
+
+ get_ok_button()->set_text(TTR("Create"));
+ set_hide_on_ok(false);
+
+ set_title(TTR("Create Shader"));
+}
diff --git a/editor/shader_create_dialog.h b/editor/shader_create_dialog.h
new file mode 100644
index 0000000000..cc338cd6b5
--- /dev/null
+++ b/editor/shader_create_dialog.h
@@ -0,0 +1,115 @@
+/*************************************************************************/
+/* shader_create_dialog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 SHADER_CREATE_DIALOG_H
+#define SHADER_CREATE_DIALOG_H
+
+#include "editor/editor_file_dialog.h"
+#include "editor/editor_settings.h"
+#include "scene/gui/check_box.h"
+#include "scene/gui/dialogs.h"
+#include "scene/gui/grid_container.h"
+#include "scene/gui/line_edit.h"
+#include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
+
+class ShaderCreateDialog : public ConfirmationDialog {
+ GDCLASS(ShaderCreateDialog, ConfirmationDialog);
+
+ enum ShaderType {
+ SHADER_TYPE_TEXT,
+ SHADER_TYPE_VISUAL,
+ SHADER_TYPE_MAX,
+ };
+
+ struct ShaderTypeData {
+ List<String> extensions;
+ String default_extension;
+ bool use_templates = false;
+ };
+
+ List<ShaderTypeData> language_data;
+
+ GridContainer *gc = nullptr;
+ Label *error_label = nullptr;
+ Label *path_error_label = nullptr;
+ Label *builtin_warning_label = nullptr;
+ PanelContainer *status_panel = nullptr;
+ OptionButton *language_menu = nullptr;
+ OptionButton *mode_menu = nullptr;
+ OptionButton *template_menu = nullptr;
+ CheckBox *internal = nullptr;
+ LineEdit *file_path = nullptr;
+ Button *path_button = nullptr;
+ EditorFileDialog *file_browse = nullptr;
+ AcceptDialog *alert = nullptr;
+
+ String initial_base_path;
+ bool is_new_shader_created = true;
+ bool is_path_valid = false;
+ bool is_built_in = false;
+ bool built_in_enabled = true;
+ bool load_enabled = false;
+ bool re_check_path = false;
+ int current_language = -1;
+ int default_language = -1;
+ int current_mode = 0;
+ int current_template = 0;
+
+ virtual void _update_language_info();
+
+ void _path_hbox_sorted();
+ void _path_changed(const String &p_path = String());
+ void _path_submitted(const String &p_path = String());
+ void _language_changed(int p_language = 0);
+ void _built_in_toggled(bool p_enabled);
+ void _template_changed(int p_template = 0);
+ void _mode_changed(int p_mode = 0);
+ void _browse_path();
+ void _file_selected(const String &p_file);
+ String _validate_path(const String &p_path, bool p_file_must_exist);
+ virtual void ok_pressed() override;
+ void _create_new();
+ void _load_exist();
+ void _msg_script_valid(bool valid, const String &p_msg = String());
+ void _msg_path_valid(bool valid, const String &p_msg = String());
+ void _update_dialog();
+
+protected:
+ void _update_theme();
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true);
+ ShaderCreateDialog();
+};
+
+#endif