summaryrefslogtreecommitdiffstats
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp3
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h3
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h3
-rw-r--r--editor/plugins/animation_player_editor_plugin.h3
-rw-r--r--editor/plugins/animation_tree_player_editor_plugin.h3
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp17
-rw-r--r--editor/plugins/camera_editor_plugin.h4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp15
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/item_list_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h3
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp9
-rw-r--r--editor/plugins/multimesh_editor_plugin.h4
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h3
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/particles_editor_plugin.cpp21
-rw-r--r--editor/plugins/particles_editor_plugin.h6
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp42
-rw-r--r--editor/plugins/path_2d_editor_plugin.h3
-rw-r--r--editor/plugins/path_editor_plugin.cpp3
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp7
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/script_editor_plugin.cpp21
-rw-r--r--editor/plugins/script_text_editor.cpp46
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp141
-rw-r--r--editor/plugins/spatial_editor_plugin.h3
-rw-r--r--editor/plugins/text_editor.cpp59
-rw-r--r--editor/plugins/text_editor.h3
-rw-r--r--editor/plugins/theme_editor_plugin.cpp85
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp2
-rw-r--r--editor/plugins/tile_map_editor_plugin.h4
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp3
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp227
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h17
40 files changed, 467 insertions, 332 deletions
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 574b47d770..7f023af848 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -571,7 +571,8 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
return;
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
- const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
+ // All polygon points are sharp, so use the sharp handle icon
+ const Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
const Vertex active_point = get_active_point();
const int n_polygons = _get_polygon_count();
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 97244fa4e9..a00cdd0cf6 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -36,9 +36,6 @@
#include "scene/2d/polygon_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class AbstractPolygon2DEditor : public HBoxContainer {
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 74186791e1..850a6201bb 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index cb40159a40..77b57a50d0 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -40,9 +40,6 @@
#include "scene/gui/graph_edit.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 22152fa8f4..2ab2df68e6 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTrackEditor;
class AnimationPlayerEditorPlugin;
diff --git a/editor/plugins/animation_tree_player_editor_plugin.h b/editor/plugins/animation_tree_player_editor_plugin.h
index f4bfe58909..03bc559b86 100644
--- a/editor/plugins/animation_tree_player_editor_plugin.h
+++ b/editor/plugins/animation_tree_player_editor_plugin.h
@@ -38,9 +38,6 @@
#include "scene/gui/button.h"
#include "scene/gui/popup.h"
#include "scene/gui/tree.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class AnimationTreePlayerEditor : public Control {
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 4a2295fab2..132bf3973e 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -270,10 +270,10 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
if (!p_video) {
preview.image = get_icon("ThumbnailWait", "EditorIcons");
}
- if (preview_images.size() == 0 && !p_video) {
+ preview_images.push_back(preview);
+ if (preview_images.size() == 1 && !p_video) {
_preview_click(p_id);
}
- preview_images.push_back(preview);
}
EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
@@ -354,16 +354,16 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
} break;
case HTTPRequest::RESULT_REQUEST_FAILED: {
error_text = TTR("Request failed, return code:") + " " + itos(p_code);
- status->set_text(TTR("Request Failed."));
+ status->set_text(TTR("Request failed."));
} break;
case HTTPRequest::RESULT_DOWNLOAD_FILE_CANT_OPEN:
case HTTPRequest::RESULT_DOWNLOAD_FILE_WRITE_ERROR: {
- error_text = TTR("Cannot save response to") + " " + download->get_download_file();
+ error_text = TTR("Cannot save response to:") + " " + download->get_download_file();
status->set_text(TTR("Write error."));
} break;
case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
error_text = TTR("Request failed, too many redirects");
- status->set_text(TTR("Redirect Loop."));
+ status->set_text(TTR("Redirect loop."));
} break;
case HTTPRequest::RESULT_TIMEOUT: {
error_text = TTR("Request failed, timeout");
@@ -472,9 +472,8 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
}
void EditorAssetLibraryItemDownload::_close() {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->remove(download->get_download_file()); //clean up removed file
- memdelete(da);
+ // Clean up downloaded file.
+ DirAccess::remove_file_or_error(download->get_download_file());
queue_delete();
}
@@ -759,7 +758,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
switch (image_queue[p_queue_id].image_type) {
case IMAGE_QUEUE_ICON:
- image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_CUBIC);
+ image->resize(64 * EDSCALE, 64 * EDSCALE, Image::INTERPOLATE_LANCZOS);
break;
case IMAGE_QUEUE_THUMBNAIL: {
diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h
index eac9acab93..400aee132d 100644
--- a/editor/plugins/camera_editor_plugin.h
+++ b/editor/plugins/camera_editor_plugin.h
@@ -35,10 +35,6 @@
#include "editor/editor_plugin.h"
#include "scene/3d/camera.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CameraEditor : public Control {
GDCLASS(CameraEditor, Control);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index ff134ff2d1..cc707dbf44 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2918,10 +2918,15 @@ void CanvasItemEditor::_draw_selection() {
Point2 bsfrom = transform.xform(drag_from);
Point2 bsto = transform.xform(box_selecting_to);
- VisualServer::get_singleton()->canvas_item_add_rect(
- ci,
+ viewport->draw_rect(
Rect2(bsfrom, bsto - bsfrom),
- get_color("accent_color", "Editor") * Color(1, 1, 1, 0.375));
+ get_color("box_selection_fill_color", "Editor"));
+
+ viewport->draw_rect(
+ Rect2(bsfrom, bsto - bsfrom),
+ get_color("box_selection_stroke_color", "Editor"),
+ false,
+ Math::round(EDSCALE));
}
if (drag_type == DRAG_ROTATE) {
@@ -4998,11 +5003,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_grid", TTR("Snap to Grid")), SNAP_USE_GRID);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("canvas_item_editor/configure_snap", TTR("Configure Snap...")), SNAP_CONFIGURE);
+
smartsnap_config_popup = memnew(PopupMenu);
p->add_child(smartsnap_config_popup);
smartsnap_config_popup->set_name("SmartSnapping");
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 553ded6b14..e6eab57810 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -39,9 +39,6 @@
#include "scene/gui/label.h"
#include "scene/gui/panel_container.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditorViewport;
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index e15360d4e5..3f0734fb19 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/collision_polygon_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CollisionPolygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(CollisionPolygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index a699641aba..2a904a53ba 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -38,10 +38,6 @@
#include "scene/3d/mesh_instance.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class CanvasItemEditor;
class Polygon3DEditor : public HBoxContainer {
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index 7c2116f06b..9d625af959 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -87,8 +87,7 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
Ref<Image> img;
img.instance();
Error err = ImageLoader::load_image(source_emission_file, img);
- ERR_EXPLAIN(TTR("Error loading image:") + " " + source_emission_file);
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Error loading image: " + source_emission_file + ".");
if (img->is_compressed()) {
img->decompress();
@@ -196,8 +195,7 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
valid_normals.resize(vpc);
}
- ERR_EXPLAIN(TTR("No pixels with transparency > 128 in image..."));
- ERR_FAIL_COND(valid_positions.size() == 0);
+ ERR_FAIL_COND_MSG(valid_positions.size() == 0, "No pixels with transparency > 128 in image...");
if (capture_colors) {
PoolColorArray pca;
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index 701632e576..78b176620e 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -39,10 +39,6 @@
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ItemListPlugin : public Object {
GDCLASS(ItemListPlugin, Object);
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 633fda7091..95fa0df2c1 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/light_occluder_2d.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class LightOccluder2DEditor : public AbstractPolygon2DEditor {
GDCLASS(LightOccluder2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index d59efe49e7..3ea014a38d 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -147,9 +147,8 @@ void MultiMeshEditor::_populate() {
w.release();
PoolVector<Face3> faces = geometry;
- ERR_EXPLAIN(TTR("Parent has no solid faces to populate."));
int facecount = faces.size();
- ERR_FAIL_COND(!facecount);
+ ERR_FAIL_COND_MSG(!facecount, "Parent has no solid faces to populate.");
PoolVector<Face3>::Read r = faces.read();
@@ -164,10 +163,8 @@ void MultiMeshEditor::_populate() {
area_accum += area;
}
- ERR_EXPLAIN(TTR("Couldn't map area."));
- ERR_FAIL_COND(triangle_area_map.size() == 0);
- ERR_EXPLAIN(TTR("Couldn't map area."));
- ERR_FAIL_COND(area_accum == 0);
+ ERR_FAIL_COND_MSG(triangle_area_map.size() == 0, "Couldn't map area.");
+ ERR_FAIL_COND_MSG(area_accum == 0, "Couldn't map area.");
Ref<MultiMesh> multimesh = memnew(MultiMesh);
multimesh->set_mesh(mesh);
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index fe87a2b9cb..5323441bd8 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/multimesh_instance.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class MultiMeshEditor : public Control {
GDCLASS(MultiMeshEditor, Control);
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 336c28d642..2a387a8b1e 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -34,9 +34,6 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/2d/navigation_polygon.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class NavigationPolygonEditor : public AbstractPolygon2DEditor {
GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index e68bca55cb..8025e12885 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -160,8 +160,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
Ref<Image> img;
img.instance();
Error err = ImageLoader::load_image(source_emission_file, img);
- ERR_EXPLAIN(TTR("Error loading image:") + " " + source_emission_file);
- ERR_FAIL_COND(err != OK);
+ ERR_FAIL_COND_MSG(err != OK, "Error loading image: " + source_emission_file + ".");
if (img->is_compressed()) {
img->decompress();
@@ -269,8 +268,7 @@ void Particles2DEditorPlugin::_generate_emission_mask() {
valid_normals.resize(vpc);
}
- ERR_EXPLAIN(TTR("No pixels with transparency > 128 in image..."));
- ERR_FAIL_COND(valid_positions.size() == 0);
+ ERR_FAIL_COND_MSG(valid_positions.size() == 0, "No pixels with transparency > 128 in image...");
PoolVector<uint8_t> texdata;
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index 75d31459e8..31b0539bfe 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -55,8 +55,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (!triangle_area_map.size() || area_accum == 0) {
- err_dialog->set_text(TTR("Faces contain no area!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry's faces don't contain any area."));
return false;
}
@@ -90,8 +89,7 @@ bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vect
if (gcount == 0) {
- err_dialog->set_text(TTR("No faces!"));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(TTR("The geometry doesn't contain any faces."));
return false;
}
@@ -169,11 +167,16 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (!sel)
return;
+ if (!sel->is_class("Spatial")) {
+
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't inherit from Spatial."), sel->get_name()));
+ return;
+ }
+
VisualInstance *vi = Object::cast_to<VisualInstance>(sel);
if (!vi) {
- err_dialog->set_text(TTR("Node does not contain geometry."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain geometry."), sel->get_name()));
return;
}
@@ -181,8 +184,7 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) {
if (geometry.size() == 0) {
- err_dialog->set_text(TTR("Node does not contain geometry (faces)."));
- err_dialog->popup_centered_minsize();
+ EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain face geometry."), sel->get_name()));
return;
}
@@ -231,9 +233,6 @@ ParticlesEditorBase::ParticlesEditorBase() {
emission_dialog->get_ok()->set_text(TTR("Create"));
emission_dialog->connect("confirmed", this, "_generate_emission_points");
- err_dialog = memnew(ConfirmationDialog);
- add_child(err_dialog);
-
emission_file_dialog = memnew(EditorFileDialog);
add_child(emission_file_dialog);
emission_file_dialog->connect("file_selected", this, "_resource_seleted");
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 5d05fbd4ac..1b3a1877a4 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -36,10 +36,6 @@
#include "scene/3d/particles.h"
#include "scene/gui/spin_box.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ParticlesEditorBase : public Control {
GDCLASS(ParticlesEditorBase, Control);
@@ -53,8 +49,6 @@ protected:
EditorFileDialog *emission_file_dialog;
SceneTreeDialog *emission_tree_dialog;
- ConfirmationDialog *err_dialog;
-
ConfirmationDialog *emission_dialog;
SpinBox *emission_amount;
OptionButton *emission_fill;
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index b87bd29cbd..f02dc0bd6d 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -367,18 +367,18 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
- if (!node)
+ if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid())
return;
- if (!node->is_visible_in_tree())
- return;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- if (!node->get_curve().is_valid())
- return;
+ const Ref<Texture> path_sharp_handle = get_icon("EditorPathSharpHandle", "EditorIcons");
+ const Ref<Texture> path_smooth_handle = get_icon("EditorPathSmoothHandle", "EditorIcons");
+ // Both handle icons must be of the same size
+ const Size2 handle_size = path_sharp_handle->get_size();
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Size2 handle_size = handle->get_size();
+ const Ref<Texture> curve_handle = get_icon("EditorCurveHandle", "EditorIcons");
+ const Size2 curve_handle_size = curve_handle->get_size();
Ref<Curve2D> curve = node->get_curve();
@@ -387,19 +387,35 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
for (int i = 0; i < len; i++) {
Vector2 point = xform.xform(curve->get_point_position(i));
- vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false, Color(1, 1, 1, 1));
+ // Determines the point icon to be used
+ bool smooth = false;
if (i < len - 1) {
Vector2 pointout = xform.xform(curve->get_point_position(i) + curve->get_point_out(i));
- vpc->draw_line(point, pointout, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointout - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointout) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointout, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointout, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointout - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
if (i > 0) {
Vector2 pointin = xform.xform(curve->get_point_position(i) + curve->get_point_in(i));
- vpc->draw_line(point, pointin, Color(0.5, 0.5, 1.0, 0.8), 1.0);
- vpc->draw_texture_rect(handle, Rect2(pointin - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3));
+ if (point != pointin) {
+ smooth = true;
+ // Draw the line with a dark and light color to be visible on all backgrounds
+ vpc->draw_line(point, pointin, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_line(point, pointin, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true);
+ vpc->draw_texture_rect(curve_handle, Rect2(pointin - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75));
+ }
}
+
+ vpc->draw_texture_rect(
+ smooth ? path_smooth_handle : path_sharp_handle,
+ Rect2(point - handle_size * 0.5, handle_size),
+ false);
}
if (on_edge) {
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 44472f7a81..ecec5f5253 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -36,9 +36,6 @@
#include "scene/2d/path_2d.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class CanvasItemEditor;
class Path2DEditor : public HBoxContainer {
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 1ae5acc5ff..2493380585 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -652,7 +652,6 @@ PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
- path_color.a = 0.4;
- create_material("path_thin_material", path_color);
+ create_material("path_thin_material", Color(0.5, 0.5, 0.5));
create_handle_material("handles");
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 59004a08c0..bd532a6418 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -1045,8 +1045,8 @@ void Polygon2DEditor::_uv_draw() {
}
}
- Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
- Ref<Texture> internal_handle = get_icon("EditorInternalHandle", "EditorIcons");
+ // All UV points are sharp, so use the sharp handle icon
+ Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons");
Color poly_line_color = Color(0.9, 0.5, 0.5);
if (polygons.size() || polygon_create.size()) {
@@ -1120,7 +1120,8 @@ void Polygon2DEditor::_uv_draw() {
if (i < uv_draw_max) {
uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5);
} else {
- uv_edit_draw->draw_texture(internal_handle, mtx.xform(uvs[i]) - internal_handle->get_size() * 0.5);
+ // Internal vertex
+ uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1));
}
}
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 24ca2ea3f4..009501a70c 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -33,9 +33,7 @@
#include "editor/plugins/abstract_polygon_2d_editor.h"
#include "scene/gui/scroll_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
+
class Polygon2DEditor : public AbstractPolygon2DEditor {
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index ec391186c3..76c7545874 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -490,9 +490,6 @@ void ScriptEditor::_update_recent_scripts() {
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
recent_scripts->clear();
- recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent")));
- recent_scripts->add_separator();
-
String path;
for (int i = 0; i < rc.size(); i++) {
@@ -515,11 +512,6 @@ void ScriptEditor::_open_recent_script(int p_idx) {
return;
}
- // take two for the open recent button
- if (p_idx > 0) {
- p_idx -= 2;
- }
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
ERR_FAIL_INDEX(p_idx, rc.size());
@@ -1000,7 +992,7 @@ void ScriptEditor::_menu_option(int p_option) {
file_dialog->clear_filters();
file_dialog->popup_centered_ratio();
- file_dialog->set_title(TTR("New TextFile..."));
+ file_dialog->set_title(TTR("New Text File..."));
} break;
case FILE_OPEN: {
file_dialog->set_mode(EditorFileDialog::MODE_OPEN_FILE);
@@ -1072,6 +1064,7 @@ void ScriptEditor::_menu_option(int p_option) {
save_all_scripts();
} break;
case SEARCH_IN_FILES: {
+
_on_find_in_files_requested("");
} break;
case SEARCH_HELP: {
@@ -3240,7 +3233,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->set_switch_on_hover(true);
file_menu->get_popup()->set_hide_on_window_lose_focus(true);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new", TTR("New Script...")), FILE_NEW);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New TextFile...")), FILE_NEW_TEXTFILE);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/new_textfile", TTR("New Text File...")), FILE_NEW_TEXTFILE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/open", TTR("Open...")), FILE_OPEN);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T), FILE_REOPEN_CLOSED);
file_menu->get_popup()->add_submenu_item(TTR("Open Recent"), "RecentScripts", FILE_OPEN_RECENT);
@@ -3273,17 +3266,20 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
theme_submenu->connect("id_pressed", this, "_theme_option");
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/import_theme", TTR("Import Theme...")), THEME_IMPORT);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/reload_theme", TTR("Reload Theme")), THEME_RELOAD);
+
theme_submenu->add_separator();
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme", TTR("Save Theme")), THEME_SAVE);
theme_submenu->add_shortcut(ED_SHORTCUT("script_editor/save_theme_as", TTR("Save Theme As...")), THEME_SAVE_AS);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_other_tabs", TTR("Close Other Tabs")), CLOSE_OTHER_TABS);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X), FILE_RUN);
+
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/toggle_scripts_panel", TTR("Toggle Scripts Panel"), KEY_MASK_CMD | KEY_BACKSLASH), TOGGLE_SCRIPTS_PANEL);
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -3572,8 +3568,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "text_editor/external/exec_flags", PROPERTY_HINT_PLACEHOLDER_TEXT, "Call flags with placeholders: {project}, {file}, {col}, {line}."));
ED_SHORTCUT("script_editor/reopen_closed_script", TTR("Reopen Closed Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_T);
- ED_SHORTCUT("script_editor/open_recent", TTR("Open Recent"));
- ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files"));
+ ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Scripts"));
}
ScriptEditorPlugin::~ScriptEditorPlugin() {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 284e0b3d97..bded590351 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,6 +30,7 @@
#include "script_text_editor.h"
+#include "core/math/expression.h"
#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
@@ -1147,6 +1148,32 @@ void ScriptTextEditor::_edit_option(int p_op) {
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
+ case EDIT_EVALUATE: {
+
+ Expression expression;
+ Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
+ PoolStringArray results;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String line = lines[i];
+ String whitespace = line.substr(0, line.size() - line.strip_edges(true, false).size()); //extract the whitespace at the beginning
+
+ if (expression.parse(line) == OK) {
+ Variant result = expression.execute(Array(), Variant(), false);
+ if (expression.get_error_text() == "") {
+ results.append(whitespace + (String)result);
+ } else {
+ results.append(line);
+ }
+ } else {
+ results.append(line);
+ }
+ }
+
+ code_editor->get_text_edit()->begin_complex_operation(); //prevents creating a two-step undo
+ code_editor->get_text_edit()->insert_text_at_cursor(results.join("\n"));
+ code_editor->get_text_edit()->end_complex_operation();
+ } break;
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
@@ -1170,7 +1197,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
// Yep, because it doesn't make sense to instance this dialog for every single script open...
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
-
} break;
case SEARCH_LOCATE_FUNCTION: {
@@ -1621,23 +1647,26 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
line_with_replaced_args = line_with_replaced_args.insert(color_args_pos, new_args);
color_args = new_args;
+ code_editor->get_text_edit()->begin_complex_operation();
code_editor->get_text_edit()->set_line(color_position.x, line_with_replaced_args);
+ code_editor->get_text_edit()->end_complex_operation();
code_editor->get_text_edit()->update();
}
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition) {
context_menu->clear();
- if (p_selection) {
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
- }
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+ context_menu->add_separator();
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
- context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
+
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
@@ -1648,6 +1677,7 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
}
if (p_foldable)
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
@@ -1748,6 +1778,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
+ edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
@@ -1873,6 +1904,7 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D);
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
#endif
+ ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E);
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T);
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y);
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 4b2307555b..38c6da5c33 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -120,6 +120,7 @@ class ScriptTextEditor : public ScriptEditorBase {
EDIT_TO_UPPERCASE,
EDIT_TO_LOWERCASE,
EDIT_CAPITALIZE,
+ EDIT_EVALUATE,
EDIT_TOGGLE_FOLD_LINE,
EDIT_FOLD_ALL_LINES,
EDIT_UNFOLD_ALL_LINES,
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 58234ba954..2eb3ce1ec3 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -2373,16 +2373,22 @@ void SpatialEditorViewport::_draw() {
get_stylebox("Focus", "EditorStyles")->draw(surface->get_canvas_item(), r);
}
- RID ci = surface->get_canvas_item();
-
if (cursor.region_select) {
+ const Rect2 selection_rect = Rect2(cursor.region_begin, cursor.region_end - cursor.region_begin);
- VisualServer::get_singleton()->canvas_item_add_rect(
- ci,
- Rect2(cursor.region_begin, cursor.region_end - cursor.region_begin),
- get_color("accent_color", "Editor") * Color(1, 1, 1, 0.375));
+ surface->draw_rect(
+ selection_rect,
+ get_color("box_selection_fill_color", "Editor"));
+
+ surface->draw_rect(
+ selection_rect,
+ get_color("box_selection_stroke_color", "Editor"),
+ false,
+ Math::round(EDSCALE));
}
+ RID ci = surface->get_canvas_item();
+
if (message_time > 0) {
Ref<Font> font = get_font("font", "Label");
Point2 msgpos = Point2(5, get_size().y - 20);
@@ -3551,7 +3557,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Doppler Enable")), VIEW_AUDIO_DOPPLER);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Enable Doppler")), VIEW_AUDIO_DOPPLER);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
@@ -5170,7 +5176,7 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
// We add a bit of margin to the from position to avoid it from snapping
// when the spatial is already on a floor and there's another floor under
// it
- from = from + Vector3(0.0, 0.1, 0.0);
+ from = from + Vector3(0.0, 0.2, 0.0);
Dictionary d;
@@ -5185,31 +5191,56 @@ void SpatialEditor::snap_selected_nodes_to_floor() {
Array keys = snap_data.keys();
- if (keys.size()) {
- undo_redo->create_action(TTR("Snap Nodes To Floor"));
+ // The maximum height an object can travel to be snapped
+ const float max_snap_height = 20.0;
+
+ // Will be set to `true` if at least one node from the selection was sucessfully snapped
+ bool snapped_to_floor = false;
+ if (keys.size()) {
+ // For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
+ // We need to check this before snapping to register the undo/redo action only if needed.
for (int i = 0; i < keys.size(); i++) {
Node *node = keys[i];
Spatial *sp = Object::cast_to<Spatial>(node);
-
Dictionary d = snap_data[node];
Vector3 from = d["from"];
- Vector3 position_offset = d["position_offset"];
-
- Vector3 to = from - Vector3(0.0, 10.0, 0.0);
+ Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
Set<RID> excluded = _get_physics_bodies_rid(sp);
if (ss->intersect_ray(from, to, result, excluded)) {
- Transform new_transform = sp->get_global_transform();
- new_transform.origin.y = result.position.y;
- new_transform.origin = new_transform.origin - position_offset;
-
- undo_redo->add_do_method(sp, "set_global_transform", new_transform);
- undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ snapped_to_floor = true;
}
}
- undo_redo->commit_action();
+ if (snapped_to_floor) {
+ undo_redo->create_action(TTR("Snap Nodes To Floor"));
+
+ // Perform snapping if at least one node can be snapped
+ for (int i = 0; i < keys.size(); i++) {
+ Node *node = keys[i];
+ Spatial *sp = Object::cast_to<Spatial>(node);
+ Dictionary d = snap_data[node];
+ Vector3 from = d["from"];
+ Vector3 to = from - Vector3(0.0, max_snap_height, 0.0);
+ Set<RID> excluded = _get_physics_bodies_rid(sp);
+
+ if (ss->intersect_ray(from, to, result, excluded)) {
+ Vector3 position_offset = d["position_offset"];
+ Transform new_transform = sp->get_global_transform();
+
+ new_transform.origin.y = result.position.y;
+ new_transform.origin = new_transform.origin - position_offset;
+
+ undo_redo->add_do_method(sp, "set_global_transform", new_transform);
+ undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform());
+ }
+ }
+
+ undo_redo->commit_action();
+ } else {
+ EditorNode::get_singleton()->show_warning(TTR("Couldn't find a solid floor to snap the selection to."));
+ }
}
}
@@ -5219,42 +5250,6 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
return;
snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
-
- Ref<InputEventKey> k = p_event;
-
- if (k.is_valid()) {
-
- // Note: need to check is_echo because first person movement keys might still be held
- if (!is_any_freelook_active() && !p_event->is_echo()) {
-
- if (!k->is_pressed())
- return;
-
- if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event)) {
- _menu_item_pressed(MENU_TOOL_SELECT);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event)) {
- _menu_item_pressed(MENU_TOOL_MOVE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event)) {
- _menu_item_pressed(MENU_TOOL_ROTATE);
- } else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event)) {
- _menu_item_pressed(MENU_TOOL_SCALE);
- } else if (ED_IS_SHORTCUT("spatial_editor/snap_to_floor", p_event)) {
- snap_selected_nodes_to_floor();
- } else if (ED_IS_SHORTCUT("spatial_editor/local_coords", p_event)) {
- if (are_local_coords_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_LOCAL_COORDS);
- } else {
- _menu_item_toggled(true, MENU_TOOL_LOCAL_COORDS);
- }
- } else if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
- if (is_snap_enabled()) {
- _menu_item_toggled(false, MENU_TOOL_USE_SNAP);
- } else {
- _menu_item_toggled(true, MENU_TOOL_USE_SNAP);
- }
- }
- }
- }
}
void SpatialEditor::_notification(int p_what) {
@@ -5528,7 +5523,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SELECT]->set_pressed(true);
button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SELECT]->set_tooltip(TTR("Select Mode (Q)") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
+ tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q));
+ tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
hbc_menu->add_child(memnew(VSeparator));
@@ -5538,7 +5534,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_MOVE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_MOVE;
tool_button[TOOL_MODE_MOVE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_MOVE]->set_tooltip(TTR("Move Mode (W)"));
+ tool_button[TOOL_MODE_MOVE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_move", TTR("Move Mode"), KEY_W));
tool_button[TOOL_MODE_ROTATE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_ROTATE]);
@@ -5546,7 +5542,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_ROTATE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_ROTATE;
tool_button[TOOL_MODE_ROTATE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_ROTATE]->set_tooltip(TTR("Rotate Mode (E)"));
+ tool_button[TOOL_MODE_ROTATE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Rotate Mode"), KEY_E));
tool_button[TOOL_MODE_SCALE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_SCALE]);
@@ -5554,7 +5550,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->set_flat(true);
button_binds.write[0] = MENU_TOOL_SCALE;
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
- tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
+ tool_button[TOOL_MODE_SCALE]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_scale", TTR("Scale Mode"), KEY_R));
hbc_menu->add_child(memnew(VSeparator));
@@ -5598,9 +5594,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_flat(true);
button_binds.write[0] = MENU_TOOL_LOCAL_COORDS;
tool_option_button[TOOL_OPT_LOCAL_COORDS]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/local_coords", TTR("Local Coords"), KEY_T);
- sct = ED_GET_SHORTCUT("spatial_editor/local_coords").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_tooltip(vformat(TTR("Local Space Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_shortcut(ED_SHORTCUT("spatial_editor/local_coords", TTR("Use Local Space"), KEY_T));
tool_option_button[TOOL_OPT_USE_SNAP] = memnew(ToolButton);
hbc_menu->add_child(tool_option_button[TOOL_OPT_USE_SNAP]);
@@ -5608,9 +5602,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_flat(true);
button_binds.write[0] = MENU_TOOL_USE_SNAP;
tool_option_button[TOOL_OPT_USE_SNAP]->connect("toggled", this, "_menu_item_toggled", button_binds);
- ED_SHORTCUT("spatial_editor/snap", TTR("Snap"), KEY_Y);
- sct = ED_GET_SHORTCUT("spatial_editor/snap").ptr()->get_as_text();
- tool_option_button[TOOL_OPT_USE_SNAP]->set_tooltip(vformat(TTR("Snap Mode (%s)"), sct));
+ tool_option_button[TOOL_OPT_USE_SNAP]->set_shortcut(ED_SHORTCUT("spatial_editor/snap", TTR("Use Snap"), KEY_Y));
hbc_menu->add_child(memnew(VSeparator));
@@ -5630,12 +5622,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F);
ED_SHORTCUT("spatial_editor/align_transform_with_view", TTR("Align Transform with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_M);
ED_SHORTCUT("spatial_editor/align_rotation_with_view", TTR("Align Rotation with View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
-
- ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q);
- ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
- ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
- ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
-
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
PopupMenu *p;
@@ -5647,10 +5633,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p = transform_menu->get_popup();
p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap Object to Floor"), KEY_PAGEDOWN), MENU_SNAP_TO_FLOOR);
- p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
- p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/transform_dialog", TTR("Transform Dialog...")), MENU_TRANSFORM_DIALOG);
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/configure_snap", TTR("Configure Snap...")), MENU_TRANSFORM_CONFIGURE_SNAP);
+
p->connect("id_pressed", this, "_menu_item_pressed");
view_menu = memnew(MenuButton);
@@ -5674,11 +5661,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_submenu_item(TTR("Gizmos"), "GizmosMenu");
p->add_separator();
-
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
+
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
+ p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS);
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 523573333b..728b67f6fa 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -37,9 +37,6 @@
#include "scene/3d/light.h"
#include "scene/3d/visual_instance.h"
#include "scene/gui/panel_container.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
class Camera;
class SpatialEditor;
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index a8fbadb773..89e419ede8 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -221,19 +221,19 @@ void TextEditor::_validate_script() {
void TextEditor::_update_bookmark_list() {
- bookmarks_menu->get_popup()->clear();
+ bookmarks_menu->clear();
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
Array bookmark_list = code_editor->get_text_edit()->get_bookmarks_array();
if (bookmark_list.size() == 0) {
return;
}
- bookmarks_menu->get_popup()->add_separator();
+ bookmarks_menu->add_separator();
for (int i = 0; i < bookmark_list.size(); i++) {
String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
@@ -242,17 +242,17 @@ void TextEditor::_update_bookmark_list() {
line = line.substr(0, 50);
}
- bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
- bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]);
}
}
void TextEditor::_bookmark_item_pressed(int p_idx) {
if (p_idx < 4) { // Any item before the separator.
- _edit_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ _edit_option(bookmarks_menu->get_item_id(p_idx));
} else {
- code_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx));
}
}
@@ -482,6 +482,14 @@ void TextEditor::_edit_option(int p_op) {
code_editor->get_find_replace_bar()->popup_replace();
} break;
+ case SEARCH_IN_FILES: {
+
+ String selected_text = code_editor->get_text_edit()->get_selection_text();
+
+ // Yep, because it doesn't make sense to instance this dialog for every single script open...
+ // So this will be delegated to the ScriptEditor.
+ emit_signal("search_in_files_requested", selected_text);
+ } break;
case SEARCH_GOTO_LINE: {
goto_line_dialog->popup_find_line(tx);
@@ -558,7 +566,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
int to_column = tx->get_selection_to_column();
if (row < from_line || row > to_line || (row == from_line && col < from_column) || (row == to_line && col > to_column)) {
- // Right click is outside the selected text
+ // Right click is outside the selected text.
tx->deselect();
}
}
@@ -637,17 +645,14 @@ TextEditor::TextEditor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_previous"), SEARCH_FIND_PREV);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
search_menu->get_popup()->add_separator();
- search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
-
- goto_line_dialog = memnew(GotoLineDialog);
- add_child(goto_line_dialog);
+ search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
edit_menu = memnew(MenuButton);
+ edit_hb->add_child(edit_menu);
edit_menu->set_text(TTR("Edit"));
edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
- edit_hb->add_child(edit_menu);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
edit_menu->get_popup()->add_separator();
@@ -689,13 +694,25 @@ TextEditor::TextEditor() {
highlighter_menu->add_radio_check_item(TTR("Standard"));
highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
- bookmarks_menu = memnew(MenuButton);
- edit_hb->add_child(bookmarks_menu);
- bookmarks_menu->set_text(TTR("Bookmarks"));
- bookmarks_menu->set_switch_on_hover(true);
+ MenuButton *goto_menu = memnew(MenuButton);
+ edit_hb->add_child(goto_menu);
+ goto_menu->set_text(TTR("Go To"));
+ goto_menu->set_switch_on_hover(true);
+ goto_menu->get_popup()->connect("id_pressed", this, "_edit_option");
+
+ goto_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
+ goto_menu->get_popup()->add_separator();
+
+ bookmarks_menu = memnew(PopupMenu);
+ bookmarks_menu->set_name(TTR("Bookmarks"));
+ goto_menu->get_popup()->add_child(bookmarks_menu);
+ goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks");
_update_bookmark_list();
bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
- bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
+ bookmarks_menu->connect("index_pressed", this, "_bookmark_item_pressed");
+
+ goto_line_dialog = memnew(GotoLineDialog);
+ add_child(goto_line_dialog);
code_editor->get_text_edit()->set_drag_forwarding(this);
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index c0d4052646..c8b49a61e0 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -46,7 +46,7 @@ private:
MenuButton *edit_menu;
PopupMenu *highlighter_menu;
MenuButton *search_menu;
- MenuButton *bookmarks_menu;
+ PopupMenu *bookmarks_menu;
PopupMenu *context_menu;
GotoLineDialog *goto_line_dialog;
@@ -87,6 +87,7 @@ private:
SEARCH_FIND_NEXT,
SEARCH_FIND_PREV,
SEARCH_REPLACE,
+ SEARCH_IN_FILES,
SEARCH_GOTO_LINE,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 5b67d259ba..3055a9382c 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -36,6 +36,7 @@
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
theme = p_theme;
+ main_panel->set_theme(p_theme);
main_container->set_theme(p_theme);
}
@@ -53,6 +54,7 @@ void ThemeEditor::_propagate_redraw(Control *p_at) {
void ThemeEditor::_refresh_interval() {
+ _propagate_redraw(main_panel);
_propagate_redraw(main_container);
}
@@ -130,14 +132,14 @@ void ThemeEditor::_save_template_cbk(String fname) {
Map<String, _TECategory> categories;
- //fill types
+ // Fill types.
List<StringName> type_list;
Theme::get_default()->get_type_list(&type_list);
for (List<StringName>::Element *E = type_list.front(); E; E = E->next()) {
categories.insert(E->get(), _TECategory());
}
- //fill default theme
+ // Fill default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -189,11 +191,9 @@ void ThemeEditor::_save_template_cbk(String fname) {
}
FileAccess *file = FileAccess::open(filename, FileAccess::WRITE);
- if (!file) {
- ERR_EXPLAIN(TTR("Can't save theme to file:") + " " + filename);
- return;
- }
+ ERR_FAIL_COND_MSG(!file, "Can't save theme to file: " + filename + ".");
+
file->store_line("; ******************* ");
file->store_line("; Template Theme File ");
file->store_line("; ******************* ");
@@ -256,7 +256,7 @@ void ThemeEditor::_save_template_cbk(String fname) {
file->store_line("");
file->store_line("");
- //write default theme
+ // Write default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
_TECategory &tc = E->get();
@@ -501,7 +501,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_select_label->show();
type_select->show();
- if (p_option == POPUP_ADD) { //add
+ if (p_option == POPUP_ADD) { // Add.
add_del_dialog->set_title(TTR("Add Item"));
add_del_dialog->get_ok()->set_text(TTR("Add"));
@@ -509,7 +509,7 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
base_theme = Theme::get_default();
- } else if (p_option == POPUP_CLASS_ADD) { //add
+ } else if (p_option == POPUP_CLASS_ADD) { // Add.
add_del_dialog->set_title(TTR("Add All Items"));
add_del_dialog->get_ok()->set_text(TTR("Add All"));
@@ -552,12 +552,10 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_menu->get_popup()->clear();
- if (p_option == 0 || p_option == 1) { //add
+ if (p_option == 0 || p_option == 1) { // Add.
List<StringName> new_types;
theme->get_type_list(&new_types);
-
- //uh kind of sucks
for (List<StringName>::Element *F = new_types.front(); F; F = F->next()) {
bool found = false;
@@ -583,15 +581,17 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
void ThemeEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_PROCESS) {
-
- time_left -= get_process_delta_time();
- if (time_left < 0) {
- time_left = 1.5;
- _refresh_interval();
- }
- } else if (p_what == NOTIFICATION_THEME_CHANGED) {
- theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ switch (p_what) {
+ case NOTIFICATION_PROCESS: {
+ time_left -= get_process_delta_time();
+ if (time_left < 0) {
+ time_left = 1.5;
+ _refresh_interval();
+ }
+ } break;
+ case NOTIFICATION_THEME_CHANGED: {
+ theme_menu->set_icon(get_icon("Theme", "EditorIcons"));
+ } break;
}
}
@@ -629,35 +629,34 @@ ThemeEditor::ThemeEditor() {
top_menu->add_child(theme_menu);
theme_menu->get_popup()->connect("id_pressed", this, "_theme_menu_cbk");
- scroll = memnew(ScrollContainer);
+ ScrollContainer *scroll = memnew(ScrollContainer);
add_child(scroll);
- scroll->set_theme(Theme::get_default());
scroll->set_enable_v_scroll(true);
scroll->set_enable_h_scroll(false);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container = memnew(MarginContainer);
- scroll->add_child(main_container);
- main_container->set_theme(Theme::get_default());
- main_container->set_clip_contents(true);
- main_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
- main_container->set_v_size_flags(SIZE_EXPAND_FILL);
- main_container->set_h_size_flags(SIZE_EXPAND_FILL);
+ MarginContainer *root_container = memnew(MarginContainer);
+ scroll->add_child(root_container);
+ root_container->set_theme(Theme::get_default());
+ root_container->set_clip_contents(true);
+ root_container->set_custom_minimum_size(Size2(700, 0) * EDSCALE);
+ root_container->set_v_size_flags(SIZE_EXPAND_FILL);
+ root_container->set_h_size_flags(SIZE_EXPAND_FILL);
//// Preview Controls ////
- Panel *panel = memnew(Panel);
- main_container->add_child(panel);
+ main_panel = memnew(Panel);
+ root_container->add_child(main_panel);
- MarginContainer *mc = memnew(MarginContainer);
- main_container->add_child(mc);
- mc->add_constant_override("margin_right", 4 * EDSCALE);
- mc->add_constant_override("margin_top", 4 * EDSCALE);
- mc->add_constant_override("margin_left", 4 * EDSCALE);
- mc->add_constant_override("margin_bottom", 4 * EDSCALE);
+ main_container = memnew(MarginContainer);
+ root_container->add_child(main_container);
+ main_container->add_constant_override("margin_right", 4 * EDSCALE);
+ main_container->add_constant_override("margin_top", 4 * EDSCALE);
+ main_container->add_constant_override("margin_left", 4 * EDSCALE);
+ main_container->add_constant_override("margin_bottom", 4 * EDSCALE);
HBoxContainer *main_hb = memnew(HBoxContainer);
- mc->add_child(main_hb);
+ main_container->add_child(main_hb);
VBoxContainer *first_vb = memnew(VBoxContainer);
main_hb->add_child(first_vb);
@@ -695,19 +694,19 @@ ThemeEditor::ThemeEditor() {
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_check_item(TTR("Check Item"));
test_menu_button->get_popup()->add_check_item(TTR("Checked Item"));
- test_menu_button->get_popup()->set_item_checked(3, true);
+ test_menu_button->get_popup()->set_item_checked(4, true);
test_menu_button->get_popup()->add_separator();
test_menu_button->get_popup()->add_radio_check_item(TTR("Radio Item"));
test_menu_button->get_popup()->add_radio_check_item(TTR("Checked Radio Item"));
- test_menu_button->get_popup()->set_item_checked(6, true);
+ test_menu_button->get_popup()->set_item_checked(7, true);
test_menu_button->get_popup()->add_separator(TTR("Named Sep."));
PopupMenu *test_submenu = memnew(PopupMenu);
test_menu_button->get_popup()->add_child(test_submenu);
test_submenu->set_name("submenu");
test_menu_button->get_popup()->add_submenu_item(TTR("Submenu"), "submenu");
- test_submenu->add_item(TTR("Item 1"));
- test_submenu->add_item(TTR("Item 2"));
+ test_submenu->add_item(TTR("Subitem 1"));
+ test_submenu->add_item(TTR("Subitem 2"));
first_vb->add_child(test_menu_button);
OptionButton *test_option_button = memnew(OptionButton);
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index cc236907a9..6ffee46569 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -45,7 +45,7 @@ class ThemeEditor : public VBoxContainer {
GDCLASS(ThemeEditor, VBoxContainer);
- ScrollContainer *scroll;
+ Panel *main_panel;
MarginContainer *main_container;
Ref<Theme> theme;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index b2f06ca41f..b4cce9745e 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -2006,7 +2006,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
// Tools
paint_button = memnew(ToolButton);
paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P));
- paint_button->set_tooltip(TTR("Shift+RMB: Line Draw\nShift+Ctrl+RMB: Rectangle Paint"));
+ paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint"));
paint_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_NONE));
paint_button->set_toggle_mode(true);
toolbar->add_child(paint_button);
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 3331fb971f..c841eb1f98 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -41,10 +41,6 @@
#include "scene/gui/menu_button.h"
#include "scene/gui/tool_button.h"
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class TileMapEditor : public VBoxContainer {
GDCLASS(TileMapEditor, VBoxContainer);
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 1a27e749e2..c1e85788f8 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -646,8 +646,7 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
for (int i = 0; i < p_paths.size(); i++) {
Ref<Texture> t = Ref<Texture>(ResourceLoader::load(p_paths[i]));
- ERR_EXPLAIN("'" + p_paths[i] + "' is not a valid texture.");
- ERR_CONTINUE(!t.is_valid());
+ ERR_CONTINUE_MSG(!t.is_valid(), "'" + p_paths[i] + "' is not a valid texture.");
if (texture_map.has(t->get_rid())) {
invalid_count++;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 863cf75a93..589964f620 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -69,8 +69,16 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
}
visual_shader = Ref<VisualShader>(p_visual_shader);
+ if (!visual_shader->is_connected("changed", this, "_update_preview")) {
+ visual_shader->connect("changed", this, "_update_preview");
+ }
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
} else {
+ if (visual_shader.is_valid()) {
+ if (visual_shader->is_connected("changed", this, "")) {
+ visual_shader->disconnect("changed", this, "_update_preview");
+ }
+ }
visual_shader.unref();
}
@@ -79,7 +87,9 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
} else {
if (changed) { // to avoid tree collapse
_clear_buffer();
+ _update_custom_nodes();
_update_options_menu();
+ _update_preview();
}
_update_graph();
}
@@ -95,31 +105,36 @@ void VisualShaderEditor::remove_plugin(const Ref<VisualShaderNodePlugin> &p_plug
plugins.erase(p_plugin);
}
-void VisualShaderEditor::add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
-
+void VisualShaderEditor::clear_custom_types() {
for (int i = 0; i < add_options.size(); i++) {
- ERR_FAIL_COND(add_options[i].script == p_script);
+ if (add_options[i].is_custom) {
+ add_options.remove(i);
+ }
}
-
- AddOption ao;
- ao.name = p_name;
- ao.script = p_script;
- ao.category = p_category;
- add_options.push_back(ao);
-
- _update_options_menu();
}
-void VisualShaderEditor::remove_custom_type(const Ref<Script> &p_script) {
+void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category) {
+
+ ERR_FAIL_COND(!p_name.is_valid_identifier());
+ ERR_FAIL_COND(!p_script.is_valid());
for (int i = 0; i < add_options.size(); i++) {
- if (add_options[i].script == p_script) {
- add_options.remove(i);
- return;
+ if (add_options[i].is_custom) {
+ if (add_options[i].script == p_script)
+ return;
}
}
- _update_options_menu();
+ AddOption ao;
+ ao.name = p_name;
+ ao.script = p_script;
+ ao.return_type = p_return_icon_type;
+ ao.description = p_description;
+ ao.category = p_category;
+ ao.sub_category = p_sub_category;
+ ao.is_custom = true;
+
+ add_options.push_back(ao);
}
bool VisualShaderEditor::_is_available(int p_mode) {
@@ -162,6 +177,58 @@ bool VisualShaderEditor::_is_available(int p_mode) {
return (p_mode == -1 || (p_mode & current_mode) != 0);
}
+void VisualShaderEditor::_update_custom_nodes() {
+ clear_custom_types();
+ List<StringName> class_list;
+ ScriptServer::get_global_class_list(&class_list);
+ for (int i = 0; i < class_list.size(); i++) {
+ if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
+
+ String script_path = ScriptServer::get_global_class_path(class_list[i]);
+ Ref<Resource> res = ResourceLoader::load(script_path);
+ ERR_FAIL_COND(res.is_null());
+ ERR_FAIL_COND(!res->is_class("Script"));
+ Ref<Script> script = Ref<Script>(res);
+
+ Ref<VisualShaderNodeCustom> ref;
+ ref.instance();
+ ref->set_script(script.get_ref_ptr());
+
+ String name;
+ if (ref->has_method("_get_name")) {
+ name = (String)ref->call("_get_name");
+ } else {
+ name = "Unnamed";
+ }
+
+ String description = "";
+ if (ref->has_method("_get_description")) {
+ description = (String)ref->call("_get_description");
+ }
+
+ int return_icon_type = -1;
+ if (ref->has_method("_get_return_icon_type")) {
+ return_icon_type = (int)ref->call("_get_return_icon_type");
+ }
+
+ String category = "";
+ if (ref->has_method("_get_category")) {
+ category = (String)ref->call("_get_category");
+ }
+ if (category == "") {
+ category = "Custom";
+ }
+
+ String sub_category = "";
+ if (ref->has_method("_get_subcategory")) {
+ sub_category = (String)ref->call("_get_subcategory");
+ }
+
+ add_custom_type(name, script, description, return_icon_type, category, sub_category);
+ }
+ }
+}
+
void VisualShaderEditor::_update_options_menu() {
node_desc->set_text("");
@@ -284,7 +351,7 @@ void VisualShaderEditor::_update_options_menu() {
case VisualShaderNode::PORT_TYPE_TRANSFORM:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"));
break;
- case VisualShaderNode::PORT_TYPE_COLOR:
+ case VisualShaderNode::PORT_TYPE_ICON_COLOR:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Color", "EditorIcons"));
break;
default:
@@ -466,21 +533,23 @@ void VisualShaderEditor::_update_graph() {
offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
node->add_child(offset);
- HBoxContainer *hb2 = memnew(HBoxContainer);
+ if (group_node->is_editable()) {
+ HBoxContainer *hb2 = memnew(HBoxContainer);
- Button *add_input_btn = memnew(Button);
- add_input_btn->set_text(TTR("Add input +"));
- add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_input_btn);
+ Button *add_input_btn = memnew(Button);
+ add_input_btn->set_text(TTR("Add input +"));
+ add_input_btn->connect("pressed", this, "_add_input_port", varray(nodes[n_i], group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_input_btn);
- hb2->add_spacer();
+ hb2->add_spacer();
- Button *add_output_btn = memnew(Button);
- add_output_btn->set_text(TTR("Add output +"));
- add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
- hb2->add_child(add_output_btn);
+ Button *add_output_btn = memnew(Button);
+ add_output_btn->set_text(TTR("Add output +"));
+ add_output_btn->connect("pressed", this, "_add_output_port", varray(nodes[n_i], group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED);
+ hb2->add_child(add_output_btn);
- node->add_child(hb2);
+ node->add_child(hb2);
+ }
}
for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) {
@@ -942,8 +1011,10 @@ void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
}
void VisualShaderEditor::_rebuild() {
- EditorNode::get_singleton()->get_log()->clear();
- visual_shader->rebuild();
+ if (visual_shader != NULL) {
+ EditorNode::get_singleton()->get_log()->clear();
+ visual_shader->rebuild();
+ }
}
void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) {
@@ -1139,7 +1210,9 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
Ref<VisualShaderNode> vsnode;
- if (add_options[p_idx].type != String()) {
+ bool is_custom = add_options[p_idx].is_custom;
+
+ if (!is_custom && add_options[p_idx].type != String()) {
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type));
ERR_FAIL_COND(!vsn);
@@ -1504,6 +1577,29 @@ void VisualShaderEditor::_notification(int p_what) {
node_filter->set_right_icon(Control::get_icon("Search", "EditorIcons"));
+ preview_shader->set_icon(Control::get_icon("Shader", "EditorIcons"));
+
+ {
+ Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
+ Color text_color = EDITOR_GET("text_editor/highlighting/text_color");
+ Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
+ Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
+ Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
+
+ preview_text->add_color_override("background_color", background_color);
+
+ for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
+
+ preview_text->add_keyword_color(E->get(), keyword_color);
+ }
+
+ preview_text->add_font_override("font", get_font("expression", "EditorFonts"));
+ preview_text->add_color_override("font_color", text_color);
+ preview_text->add_color_override("symbol_color", symbol_color);
+ preview_text->add_color_region("/*", "*/", comment_color, false);
+ preview_text->add_color_region("//", "", comment_color, false);
+ }
+
tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Tools", "EditorIcons"));
if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())
@@ -1954,6 +2050,15 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
}
+void VisualShaderEditor::_show_preview_text() {
+ preview_showed = !preview_showed;
+ preview_text->set_visible(preview_showed);
+}
+
+void VisualShaderEditor::_update_preview() {
+ preview_text->set_text(visual_shader->get_code());
+}
+
void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_rebuild", &VisualShaderEditor::_rebuild);
ClassDB::bind_method("_update_graph", &VisualShaderEditor::_update_graph);
@@ -1993,6 +2098,8 @@ void VisualShaderEditor::_bind_methods() {
ClassDB::bind_method("_node_resized", &VisualShaderEditor::_node_resized);
ClassDB::bind_method("_set_node_size", &VisualShaderEditor::_set_node_size);
ClassDB::bind_method("_clear_buffer", &VisualShaderEditor::_clear_buffer);
+ ClassDB::bind_method("_show_preview_text", &VisualShaderEditor::_show_preview_text);
+ ClassDB::bind_method("_update_preview", &VisualShaderEditor::_update_preview);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &VisualShaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &VisualShaderEditor::can_drop_data_fw);
@@ -2019,13 +2126,23 @@ VisualShaderEditor::VisualShaderEditor() {
saved_node_pos = Point2(0, 0);
ShaderLanguage::get_keyword_list(&keyword_list);
+ preview_showed = false;
+
to_node = -1;
to_slot = -1;
from_node = -1;
from_slot = -1;
+ main_box = memnew(HSplitContainer);
+ main_box->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ add_child(main_box);
+
graph = memnew(GraphEdit);
- add_child(graph);
+ graph->get_zoom_hbox()->set_h_size_flags(SIZE_EXPAND_FILL);
+ graph->set_v_size_flags(SIZE_EXPAND_FILL);
+ graph->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_box->add_child(graph);
graph->set_drag_forwarding(this);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
@@ -2074,6 +2191,25 @@ VisualShaderEditor::VisualShaderEditor() {
graph->get_zoom_hbox()->move_child(add_node, 0);
add_node->connect("pressed", this, "_show_members_dialog", varray(false));
+ preview_shader = memnew(ToolButton);
+ preview_shader->set_toggle_mode(true);
+ preview_shader->set_tooltip(TTR("Show resulted shader code."));
+ graph->get_zoom_hbox()->add_child(preview_shader);
+ preview_shader->connect("pressed", this, "_show_preview_text");
+
+ ///////////////////////////////////////
+ // PREVIEW PANEL
+ ///////////////////////////////////////
+
+ preview_text = memnew(TextEdit);
+ main_box->add_child(preview_text);
+ preview_text->set_h_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_v_size_flags(SIZE_EXPAND_FILL);
+ preview_text->set_visible(preview_showed);
+ preview_text->set_custom_minimum_size(Size2(400 * EDSCALE, 0));
+ preview_text->set_syntax_coloring(true);
+ preview_text->set_readonly(true);
+
///////////////////////////////////////
// SHADER NODES TREE
///////////////////////////////////////
@@ -2164,8 +2300,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), VisualShaderNodeColorOp::OP_SCREEN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), VisualShaderNodeColorOp::OP_SOFT_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR));
+ add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
// CONDITIONAL
@@ -2351,8 +2487,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
@@ -2368,12 +2504,12 @@ VisualShaderEditor::VisualShaderEditor() {
// TEXTURES
- add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
+ add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
- add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR));
- add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_COLOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR));
+ add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_ICON_COLOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL));
// TRANSFORM
@@ -2445,10 +2581,10 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR));
add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
@@ -2466,6 +2602,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside.")));
add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true));
add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true));
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index d2b1e8bc45..1556c7cd43 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -60,14 +60,18 @@ class VisualShaderEditor : public VBoxContainer {
int editing_port;
Ref<VisualShader> visual_shader;
+ HSplitContainer *main_box;
GraphEdit *graph;
ToolButton *add_node;
+ ToolButton *preview_shader;
OptionButton *edit_type;
PanelContainer *error_panel;
Label *error_label;
+ TextEdit *preview_text;
+
UndoRedo *undo_redo;
Point2 saved_node_pos;
bool saved_node_pos_dirty;
@@ -75,6 +79,8 @@ class VisualShaderEditor : public VBoxContainer {
ConfirmationDialog *members_dialog;
MenuButton *tools;
+ bool preview_showed;
+
enum ToolsMenuOptions {
EXPAND_ALL,
COLLAPSE_ALL
@@ -104,6 +110,7 @@ class VisualShaderEditor : public VBoxContainer {
int func;
float value;
bool highend;
+ bool is_custom;
AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
name = p_name;
@@ -117,6 +124,7 @@ class VisualShaderEditor : public VBoxContainer {
func = p_func;
value = p_value;
highend = p_highend;
+ is_custom = false;
}
AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
@@ -131,6 +139,7 @@ class VisualShaderEditor : public VBoxContainer {
func = p_func;
value = p_value;
highend = p_highend;
+ is_custom = false;
}
};
@@ -140,8 +149,12 @@ class VisualShaderEditor : public VBoxContainer {
void _draw_color_over_button(Object *obj, Color p_color);
void _add_node(int p_idx, int p_op_idx = -1);
+ void _update_custom_nodes();
void _update_options_menu();
+ void _show_preview_text();
+ void _update_preview();
+
static VisualShaderEditor *singleton;
void _node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node);
@@ -240,8 +253,8 @@ public:
static VisualShaderEditor *get_singleton() { return singleton; }
- void add_custom_type(const String &p_name, const String &p_category, const Ref<Script> &p_script);
- void remove_custom_type(const Ref<Script> &p_script);
+ void clear_custom_types();
+ void add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, const String &p_sub_category);
virtual Size2 get_minimum_size() const;
void edit(VisualShader *p_visual_shader);