summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/SCsub2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp60
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h5
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp32
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h30
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp40
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h30
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp63
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h32
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp12
-rw-r--r--editor/plugins/animation_player_editor_plugin.h4
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp38
-rw-r--r--editor/plugins/animation_state_machine_editor.h30
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp36
-rw-r--r--editor/plugins/animation_tree_editor_plugin.h30
-rw-r--r--editor/plugins/animation_tree_player_editor_plugin.cpp4
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp3
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp4
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.cpp3
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.h2
-rw-r--r--editor/plugins/camera_editor_plugin.cpp12
-rw-r--r--editor/plugins/camera_editor_plugin.h1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp1226
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h62
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp6
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp57
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h4
-rw-r--r--editor/plugins/cpu_particles_editor_plugin.cpp31
-rw-r--r--editor/plugins/cpu_particles_editor_plugin.h30
-rw-r--r--editor/plugins/curve_editor_plugin.cpp13
-rw-r--r--editor/plugins/curve_editor_plugin.h6
-rw-r--r--editor/plugins/editor_preview_plugins.cpp157
-rw-r--r--editor/plugins/editor_preview_plugins.h26
-rw-r--r--editor/plugins/gi_probe_editor_plugin.cpp2
-rw-r--r--editor/plugins/gi_probe_editor_plugin.h2
-rw-r--r--editor/plugins/item_list_editor_plugin.cpp33
-rw-r--r--editor/plugins/item_list_editor_plugin.h4
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp40
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h4
-rw-r--r--editor/plugins/material_editor_plugin.cpp390
-rw-r--r--editor/plugins/material_editor_plugin.h71
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp8
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp26
-rw-r--r--editor/plugins/particles_2d_editor_plugin.h4
-rw-r--r--editor/plugins/particles_editor_plugin.cpp6
-rw-r--r--editor/plugins/particles_editor_plugin.h1
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp44
-rw-r--r--editor/plugins/path_2d_editor_plugin.h4
-rw-r--r--editor/plugins/path_editor_plugin.cpp28
-rw-r--r--editor/plugins/path_editor_plugin.h2
-rw-r--r--editor/plugins/physical_bone_plugin.cpp28
-rw-r--r--editor/plugins/physical_bone_plugin.h6
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp7
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp76
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h8
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp49
-rw-r--r--editor/plugins/root_motion_editor_plugin.h30
-rw-r--r--editor/plugins/script_editor_plugin.cpp134
-rw-r--r--editor/plugins/script_editor_plugin.h4
-rw-r--r--editor/plugins/script_text_editor.cpp80
-rw-r--r--editor/plugins/shader_editor_plugin.cpp29
-rw-r--r--editor/plugins/skeleton_editor_plugin.cpp8
-rw-r--r--editor/plugins/skeleton_editor_plugin.h4
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.cpp4
-rw-r--r--editor/plugins/skeleton_ik_editor_plugin.h6
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp474
-rw-r--r--editor/plugins/spatial_editor_plugin.h23
-rw-r--r--editor/plugins/sprite_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp26
-rw-r--r--editor/plugins/text_editor.cpp16
-rw-r--r--editor/plugins/texture_editor_plugin.cpp4
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp7
-rw-r--r--editor/plugins/theme_editor_plugin.cpp4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp367
-rw-r--r--editor/plugins/tile_map_editor_plugin.h30
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp90
-rw-r--r--editor/plugins/tile_set_editor_plugin.h8
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp56
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h30
79 files changed, 2448 insertions, 1922 deletions
diff --git a/editor/plugins/SCsub b/editor/plugins/SCsub
index f1fa50148f..2b1e889fb0 100644
--- a/editor/plugins/SCsub
+++ b/editor/plugins/SCsub
@@ -1,5 +1,5 @@
#!/usr/bin/env python
Import('env')
-Export('env')
+
env.add_source_files(env.editor_sources, "*.cpp")
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 2d341cdd93..16423decc4 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -132,8 +132,8 @@ Vector2 AbstractPolygon2DEditor::_get_offset(int p_idx) const {
void AbstractPolygon2DEditor::_commit_action() {
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
}
@@ -218,7 +218,7 @@ void AbstractPolygon2DEditor::_node_removed(Node *p_node) {
edit(NULL);
hide();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
}
@@ -229,6 +229,18 @@ void AbstractPolygon2DEditor::_wip_changed() {
}
}
+void AbstractPolygon2DEditor::_wip_cancel() {
+
+ wip.clear();
+ wip_active = false;
+
+ edited_point = PosVertex();
+ hover_point = Vertex();
+ selected_point = Vertex();
+
+ canvas_item_editor->update_viewport();
+}
+
void AbstractPolygon2DEditor::_wip_close() {
if (!wip_active)
return;
@@ -275,6 +287,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return (mb.is_valid() && mb->get_button_index() == 1);
}
+ CanvasItemEditor::Tool tool = CanvasItemEditor::get_singleton()->get_current_tool();
+ if (tool != CanvasItemEditor::TOOL_SELECT)
+ return false;
+
if (mb.is_valid()) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
@@ -283,10 +299,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) {
-
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
+ if (mb->get_control() || mb->get_shift() || mb->get_alt())
+ return false;
const PosVertex insert = closest_edge_point(gpoint);
@@ -330,7 +346,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
edited_point = PosVertex(closest, xform.affine_inverse().xform(closest.pos));
selected_point = closest;
edge_point = PosVertex();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
} else {
@@ -399,7 +415,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
wip_active = true;
_wip_changed();
edited_point = PosVertex(-1, 1, cpoint);
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
hover_point = Vertex();
selected_point = Vertex(0);
edge_point = PosVertex();
@@ -420,12 +436,12 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
_wip_changed();
edited_point = PosVertex(-1, wip.size(), cpoint);
selected_point = Vertex(wip.size() - 1);
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
}
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
- _wip_close();
+ _wip_cancel();
}
}
}
@@ -449,7 +465,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
_set_polygon(edited_point.polygon, vertices);
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} else if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) {
const PosVertex onEdgeVertex = closest_edge_point(gpoint);
@@ -458,20 +474,20 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
hover_point = Vertex();
edge_point = onEdgeVertex;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} else {
if (edge_point.valid()) {
edge_point = PosVertex();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
const PosVertex new_hover_point = closest_point(gpoint);
if (hover_point != new_hover_point) {
hover_point = new_hover_point;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
}
}
@@ -490,7 +506,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
wip.remove(selected_point.vertex);
_wip_changed();
selected_point = wip.size() - 1;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
} else {
@@ -506,18 +522,18 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
} else if (wip_active && k->get_scancode() == KEY_ENTER) {
_wip_close();
+ } else if (wip_active && k->get_scancode() == KEY_ESCAPE) {
+ _wip_cancel();
}
}
return false;
}
-void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) {
+void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!_get_node())
return;
- Control *vpc = canvas_item_editor->get_viewport_control();
-
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons");
@@ -558,7 +574,7 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) {
Vector2 point = xform.xform(p);
Vector2 next_point = xform.xform(p2);
- vpc->draw_line(point, next_point, col, 2 * EDSCALE);
+ p_overlay->draw_line(point, next_point, col, 2 * EDSCALE);
}
}
@@ -582,7 +598,7 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) {
p2 = points[(i + 1) % n_points] + offset;
const Vector2 next_point = xform.xform(p2);
- vpc->draw_line(point, next_point, col, 2 * EDSCALE);
+ p_overlay->draw_line(point, next_point, col, 2 * EDSCALE);
}
}
@@ -594,14 +610,14 @@ void AbstractPolygon2DEditor::forward_draw_over_viewport(Control *p_overlay) {
const Vector2 point = xform.xform(p);
const Color modulate = vertex == active_point ? Color(0.5, 1, 2) : Color(1, 1, 1);
- vpc->draw_texture(handle, point - handle->get_size() * 0.5, modulate);
+ p_overlay->draw_texture(handle, point - handle->get_size() * 0.5, modulate);
}
}
if (edge_point.valid()) {
Ref<Texture> add_handle = get_icon("EditorHandleAdd", "EditorIcons");
- vpc->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5);
+ p_overlay->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5);
}
}
@@ -625,7 +641,7 @@ void AbstractPolygon2DEditor::edit(Node *p_polygon) {
hover_point = Vertex();
selected_point = Vertex();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} else {
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 9ba03bcdf6..c03670f254 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -103,6 +103,7 @@ protected:
virtual void _menu_option(int p_option);
void _wip_changed();
void _wip_close();
+ void _wip_cancel();
bool _delete_point(const Vector2 &p_gpoint);
void _notification(int p_what);
@@ -137,7 +138,7 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
- void forward_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_polygon);
AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive = true);
@@ -153,7 +154,7 @@ class AbstractPolygon2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return polygon_editor->forward_gui_input(p_event); }
- virtual void forward_draw_over_viewport(Control *p_overlay) { polygon_editor->forward_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { polygon_editor->forward_canvas_draw_over_viewport(p_overlay); }
bool has_main_screen() const { return false; }
virtual String get_name() const { return klass; }
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index 5373015654..4b1e710705 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -1,6 +1,36 @@
+/*************************************************************************/
+/* animation_blend_space_1d_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "animation_blend_space_1d_editor.h"
-#include "os/keyboard.h"
+#include "core/os/keyboard.h"
#include "scene/animation/animation_blend_tree.h"
StringName AnimationNodeBlendSpace1DEditor::get_blend_position_path() const {
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 278357b9c7..ca6135406c 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_blend_space_1d_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ANIMATION_BLEND_SPACE_1D_EDITOR_H
#define ANIMATION_BLEND_SPACE_1D_EDITOR_H
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 2d240b5a5c..394b888d0e 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -1,10 +1,40 @@
+/*************************************************************************/
+/* animation_blend_space_2d_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "animation_blend_space_2d_editor.h"
#include "core/io/resource_loader.h"
+#include "core/math/delaunay.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
-#include "math/delaunay.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
@@ -404,7 +434,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (blend_space->get_snap().x > 0) {
- int prev_idx;
+ int prev_idx = 0;
for (int i = 0; i < s.x; i++) {
float v = blend_space->get_min_space().x + i * (blend_space->get_max_space().x - blend_space->get_min_space().x) / s.x;
@@ -420,7 +450,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
if (blend_space->get_snap().y > 0) {
- int prev_idx;
+ int prev_idx = 0;
for (int i = 0; i < s.y; i++) {
float v = blend_space->get_max_space().y - i * (blend_space->get_max_space().y - blend_space->get_min_space().y) / s.y;
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 0bf1e25d7a..613289e4d8 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_blend_space_2d_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ANIMATION_BLEND_SPACE_2D_EDITOR_H
#define ANIMATION_BLEND_SPACE_2D_EDITOR_H
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index dbb5fa578b..eb3c432ee7 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -1,10 +1,40 @@
+/*************************************************************************/
+/* animation_blend_tree_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "animation_blend_tree_editor_plugin.h"
#include "core/io/resource_loader.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/editor_inspector.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
@@ -101,10 +131,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
Ref<AnimationNode> agnode = blend_tree->get_node(E->get());
- if (!agnode->is_connected("changed", this, "_node_changed")) {
- agnode->connect("changed", this, "_node_changed", varray(agnode->get_instance_id()), CONNECT_DEFERRED);
- }
-
node->set_offset(blend_tree->get_node_position(E->get()) * EDSCALE);
node->set_title(agnode->get_caption());
@@ -211,7 +237,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
mb->get_popup()->connect("index_pressed", this, "_anim_selected", varray(options, E->get()), CONNECT_DEFERRED);
}
- /* should be no longer necesary, as the boolean works
+ /* should be no longer necessary, as the boolean works
Ref<AnimationNodeOneShot> oneshot = agnode;
if (oneshot.is_valid()) {
@@ -512,11 +538,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
if (base->has_node(accum)) {
Node *node = base->get_node(accum);
- if (has_icon(node->get_class(), "EditorIcons")) {
- ti->set_icon(0, get_icon(node->get_class(), "EditorIcons"));
- } else {
- ti->set_icon(0, get_icon("Node", "EditorIcons"));
- }
+ ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node"));
}
} else {
@@ -529,7 +551,7 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
node = base->get_node(accum);
}
if (!node)
- continue; //no node, cant edit
+ continue; //no node, can't edit
if (path.get_subname_count()) {
@@ -670,7 +692,9 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
Ref<Animation> anim = player->get_animation(an->get_animation());
if (anim.is_valid()) {
E->get()->set_max(anim->get_length());
- E->get()->set_value(an->get_playback_time());
+ //StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E->get().input_node;
+ StringName time_path = AnimationTreeEditor::get_singleton()->get_base_path() + String(E->key()) + "/time";
+ E->get()->set_value(AnimationTreeEditor::get_singleton()->get_tree()->get(time_path));
}
}
}
@@ -695,14 +719,6 @@ void AnimationNodeBlendTreeEditor::_scroll_changed(const Vector2 &p_scroll) {
updating = false;
}
-void AnimationNodeBlendTreeEditor::_node_changed(ObjectID p_node) {
-
- AnimationNode *an = Object::cast_to<AnimationNode>(ObjectDB::get_instance(p_node));
- //if (an && an->get_parent() == blend_tree) {
- _update_graph();
- //}
-}
-
void AnimationNodeBlendTreeEditor::_bind_methods() {
ClassDB::bind_method("_update_graph", &AnimationNodeBlendTreeEditor::_update_graph);
@@ -720,7 +736,6 @@ void AnimationNodeBlendTreeEditor::_bind_methods() {
ClassDB::bind_method("_update_filters", &AnimationNodeBlendTreeEditor::_update_filters);
ClassDB::bind_method("_filter_edited", &AnimationNodeBlendTreeEditor::_filter_edited);
ClassDB::bind_method("_filter_toggled", &AnimationNodeBlendTreeEditor::_filter_toggled);
- ClassDB::bind_method("_node_changed", &AnimationNodeBlendTreeEditor::_node_changed);
ClassDB::bind_method("_removed_from_graph", &AnimationNodeBlendTreeEditor::_removed_from_graph);
ClassDB::bind_method("_property_changed", &AnimationNodeBlendTreeEditor::_property_changed);
ClassDB::bind_method("_file_opened", &AnimationNodeBlendTreeEditor::_file_opened);
@@ -820,8 +835,6 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
if (p_node.is_valid()) {
blend_tree = p_node;
- } else {
- blend_tree.unref();
}
if (blend_tree.is_null()) {
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 35ecc32979..e2daefdec6 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_blend_tree_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
#define ANIMATION_BLEND_TREE_EDITOR_PLUGIN_H
@@ -74,8 +104,6 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
void _filter_toggled();
Ref<AnimationNode> _filter_edit;
- void _node_changed(ObjectID p_node);
-
void _property_changed(const StringName &p_property, const Variant &p_value);
void _removed_from_graph();
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 9ab5436de8..445664f8dd 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -30,12 +30,12 @@
#include "animation_player_editor_plugin.h"
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/keyboard.h"
+#include "core/project_settings.h"
#include "editor/animation_track_editor.h"
#include "editor/editor_settings.h"
-#include "io/resource_loader.h"
-#include "io/resource_saver.h"
-#include "os/keyboard.h"
-#include "project_settings.h"
// For onion skinning
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -908,7 +908,7 @@ void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
}
}
-void AnimationPlayerEditor::forward_force_draw_over_viewport(Control *p_overlay) {
+void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
if (!onion.can_overlay)
return;
@@ -1515,7 +1515,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
void AnimationPlayerEditor::_start_onion_skinning() {
- // FIXME: Using "idle_frame" makes onion layers update one frame behing the current
+ // FIXME: Using "idle_frame" makes onion layers update one frame behind the current
if (!get_tree()->is_connected("idle_frame", this, "call_deferred")) {
get_tree()->connect("idle_frame", this, "call_deferred", varray("_prepare_onion_layers_1"));
}
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 5ac7b99903..55f082aadb 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -246,7 +246,7 @@ public:
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void edit(AnimationPlayer *p_player);
- void forward_force_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_force_draw_over_viewport(Control *p_overlay);
AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin);
};
@@ -271,7 +271,7 @@ public:
virtual bool handles(Object *p_object) const;
virtual void make_visible(bool p_visible);
- virtual void forward_force_draw_over_viewport(Control *p_overlay) { anim_editor->forward_force_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) { anim_editor->forward_canvas_force_draw_over_viewport(p_overlay); }
AnimationPlayerEditorPlugin(EditorNode *p_node);
~AnimationPlayerEditorPlugin();
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 3a65cb9b38..e83773257b 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -1,10 +1,40 @@
+/*************************************************************************/
+/* animation_state_machine_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "animation_state_machine_editor.h"
#include "core/io/resource_loader.h"
+#include "core/math/delaunay.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
-#include "math/delaunay.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
@@ -633,7 +663,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
transition_lines.clear();
- //draw conecting line for potential new transition
+ //draw connecting line for potential new transition
if (connecting) {
Vector2 from = (state_machine->get_node_position(connecting_from) * EDSCALE) - state_machine->get_graph_offset() * EDSCALE;
Vector2 to;
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 49d08607cf..7b8a4a0e94 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_state_machine_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ANIMATION_STATE_MACHINE_EDITOR_H
#define ANIMATION_STATE_MACHINE_EDITOR_H
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index 19921ef54f..24787a78e9 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_tree_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "animation_tree_editor_plugin.h"
#include "animation_blend_space_1d_editor.h"
@@ -5,10 +35,10 @@
#include "animation_blend_tree_editor_plugin.h"
#include "animation_state_machine_editor.h"
#include "core/io/resource_loader.h"
+#include "core/math/delaunay.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
-#include "math/delaunay.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/animation/animation_blend_tree.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h
index b12054bb62..be8848d600 100644
--- a/editor/plugins/animation_tree_editor_plugin.h
+++ b/editor/plugins/animation_tree_editor_plugin.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* animation_tree_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ANIMATION_TREE_EDITOR_PLUGIN_H
#define ANIMATION_TREE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/animation_tree_player_editor_plugin.cpp b/editor/plugins/animation_tree_player_editor_plugin.cpp
index 36d10ab99e..c79e3a436d 100644
--- a/editor/plugins/animation_tree_player_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -31,9 +31,9 @@
#include "animation_tree_player_editor_plugin.h"
#include "core/io/resource_loader.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
#include "scene/main/viewport.h"
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 66770d98e5..138b8a491c 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -962,6 +962,9 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
HBoxContainer *hbc = memnew(HBoxContainer);
+ if (p_page_count < 2)
+ return hbc;
+
//do the mario
int from = p_page - 5;
if (from < 0)
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index 454a5d72f2..06ca5833e2 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -30,9 +30,9 @@
#include "audio_stream_editor_plugin.h"
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
#include "editor/editor_settings.h"
-#include "io/resource_loader.h"
-#include "project_settings.h"
void AudioStreamEditor::_notification(int p_what) {
diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp
index 59b79bd070..40e3bb5be2 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.cpp
+++ b/editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -50,6 +50,7 @@ void BakedLightmapEditorPlugin::_bake() {
case BakedLightmap::BAKE_ERROR_CANT_CREATE_IMAGE:
EditorNode::get_singleton()->show_warning(TTR("Failed creating lightmap images, make sure path is writable."));
break;
+ default: {}
}
}
}
@@ -107,7 +108,7 @@ void BakedLightmapEditorPlugin::_bind_methods() {
BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) {
editor = p_node;
- bake = memnew(Button);
+ bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h
index a32b573851..8d3b5b1dd6 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.h
+++ b/editor/plugins/baked_lightmap_editor_plugin.h
@@ -42,7 +42,7 @@ class BakedLightmapEditorPlugin : public EditorPlugin {
BakedLightmap *lightmap;
- Button *bake;
+ ToolButton *bake;
EditorNode *editor;
static EditorProgress *tmp_progress;
diff --git a/editor/plugins/camera_editor_plugin.cpp b/editor/plugins/camera_editor_plugin.cpp
index 37fbb54c30..3d8b24ccc7 100644
--- a/editor/plugins/camera_editor_plugin.cpp
+++ b/editor/plugins/camera_editor_plugin.cpp
@@ -32,18 +32,6 @@
#include "spatial_editor_plugin.h"
-void CameraEditor::_notification(int p_what) {
-
- switch (p_what) {
-
- /* case NOTIFICATION_PROCESS: {
-
- if (preview->is_pressed() && node)
- node->call("make_current");
-
- } break;*/
- }
-}
void CameraEditor::_node_removed(Node *p_node) {
if (p_node == node) {
diff --git a/editor/plugins/camera_editor_plugin.h b/editor/plugins/camera_editor_plugin.h
index 275624beeb..0340808c9a 100644
--- a/editor/plugins/camera_editor_plugin.h
+++ b/editor/plugins/camera_editor_plugin.h
@@ -50,7 +50,6 @@ class CameraEditor : public Control {
void _pressed();
protected:
- void _notification(int p_what);
void _node_removed(Node *p_node);
static void _bind_methods();
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 72248b62a3..ee2283a035 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -30,15 +30,15 @@
#include "canvas_item_editor_plugin.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
+#include "core/print_string.h"
+#include "core/project_settings.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/script_editor_debugger.h"
-#include "os/input.h"
-#include "os/keyboard.h"
-#include "print_string.h"
-#include "project_settings.h"
#include "scene/2d/light_2d.h"
#include "scene/2d/particles_2d.h"
#include "scene/2d/polygon_2d.h"
@@ -55,6 +55,7 @@
#define MAX_ZOOM 100
#define RULER_WIDTH 15 * EDSCALE
+#define SCALE_HANDLE_DISTANCE 25
class SnapDialog : public ConfirmationDialog {
@@ -178,6 +179,23 @@ void CanvasItemEditor::_snap_if_closer_float(float p_value, float p_target_snap,
}
}
+bool CanvasItemEditor::_is_node_locked(const Node *p_node) {
+ return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
+}
+
+bool CanvasItemEditor::_is_node_movable(const Node *p_node, bool p_popup_warning) {
+ if (_is_node_locked(p_node)) {
+ return false;
+ }
+ if (Object::cast_to<Control>(p_node) && Object::cast_to<Container>(p_node->get_parent())) {
+ if (p_popup_warning) {
+ _popup_warning_temporarily(warning_child_of_container, 3.0);
+ }
+ return false;
+ }
+ return true;
+}
+
void CanvasItemEditor::_snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) {
Transform2D rot_trans = Transform2D(rotation, Point2());
p_value = rot_trans.inverse().xform(p_value);
@@ -335,10 +353,11 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
return;
- if (k->get_control())
- return;
+ if (k->get_scancode() == KEY_CONTROL || k->get_scancode() == KEY_ALT || k->get_scancode() == KEY_SHIFT) {
+ viewport->update();
+ }
- if (k->is_pressed() && !k->is_echo()) {
+ if (k->is_pressed() && !k->get_control() && !k->is_echo()) {
if ((snap_grid || show_grid) && multiply_grid_step_shortcut.is_valid() && multiply_grid_step_shortcut->is_shortcut(p_ev)) {
// Multiply the grid size
grid_step_multiplier = MIN(grid_step_multiplier + 1, 12);
@@ -409,7 +428,7 @@ void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, c
}
}
- if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !canvas_item->has_meta("_edit_lock_"))) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && (include_locked_nodes || !_is_node_locked(canvas_item))) {
Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform();
Rect2 rect = canvas_item->_edit_get_rect();
if (r_first) {
@@ -431,7 +450,7 @@ Rect2 CanvasItemEditor::_get_encompassing_rect(const Node *p_node) {
return rect;
}
-void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, int p_limit, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
+void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
if (!p_node)
return;
if (Object::cast_to<Viewport>(p_node))
@@ -441,14 +460,16 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
- if (canvas_item && !canvas_item->is_set_as_toplevel()) {
- _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, p_parent_xform * canvas_item->get_transform(), p_canvas_xform);
+ if (canvas_item) {
+ if (!canvas_item->is_set_as_toplevel()) {
+ _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform);
+ } else {
+ _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform);
+ }
} else {
CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node);
- _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, p_limit, Transform2D(), cl ? cl->get_transform() : p_canvas_xform);
+ _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, Transform2D(), cl ? cl->get_transform() : p_canvas_xform);
}
- if (p_limit != 0 && r_items.size() >= p_limit)
- return;
}
if (canvas_item && canvas_item->is_visible_in_tree()) {
@@ -468,11 +489,11 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
return;
}
-void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, int p_limit) {
+void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items) {
Node *scene = editor->get_edited_scene();
- _find_canvas_items_at_pos(p_pos, scene, r_items, p_limit);
+ _find_canvas_items_at_pos(p_pos, scene, r_items);
//Remove invalid results
for (int i = 0; i < r_items.size(); i++) {
@@ -503,7 +524,7 @@ void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_Sel
}
//Remove the item if invalid
- if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || (canvas_item->has_meta("_edit_lock_") && canvas_item->get_meta("_edit_lock_"))) {
+ if (!canvas_item || duplicate || (canvas_item != scene && canvas_item->get_owner() != scene && !scene->is_editable_instance(canvas_item->get_owner())) || _is_node_locked(canvas_item)) {
r_items.remove(i);
i--;
} else {
@@ -604,12 +625,16 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
bool editable = p_node == scene || p_node->get_owner() == scene || scene->is_editable_instance(p_node->get_owner());
bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_");
- bool locked = p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
+ bool locked = _is_node_locked(p_node);
if (!lock_children || !editable) {
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
- if (canvas_item && !canvas_item->is_set_as_toplevel()) {
- _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform);
+ if (canvas_item) {
+ if (!canvas_item->is_set_as_toplevel()) {
+ _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform);
+ } else {
+ _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, canvas_item->get_transform(), p_canvas_xform);
+ }
} else {
CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node);
_find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform);
@@ -667,7 +692,7 @@ List<CanvasItem *> CanvasItemEditor::_get_edited_canvas_items(bool retreive_lock
List<CanvasItem *> selection;
for (Map<Node *, Object *>::Element *E = editor_selection->get_selection().front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (!retreive_locked || !canvas_item->has_meta("_edit_lock_"))) {
+ if (canvas_item && canvas_item->is_visible_in_tree() && canvas_item->get_viewport() == EditorNode::get_singleton()->get_scene_root() && (retreive_locked || !_is_node_locked(canvas_item))) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
if (se) {
selection.push_back(canvas_item);
@@ -705,6 +730,46 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2
return (p_control->get_transform().xform(position) - parent_rect.position) / parent_rect.size;
}
+void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state) {
+ if (p_bones_length)
+ *p_bones_length = List<float>();
+ if (p_bones_state)
+ *p_bones_state = List<Dictionary>();
+
+ const Node2D *bone = Object::cast_to<Node2D>(p_canvas_item);
+ if (bone && bone->has_meta("_edit_bone_")) {
+ // Check if we have an IK chain
+ List<const Node2D *> bone_ik_list;
+ bool ik_found = false;
+ bone = Object::cast_to<Node2D>(bone->get_parent());
+ while (bone) {
+ bone_ik_list.push_back(bone);
+ if (bone->has_meta("_edit_ik_")) {
+ ik_found = true;
+ break;
+ } else if (!bone->has_meta("_edit_bone_")) {
+ break;
+ }
+ bone = Object::cast_to<Node2D>(bone->get_parent());
+ }
+
+ //Save the bone state and length if we have an IK chain
+ if (ik_found) {
+ bone = Object::cast_to<Node2D>(p_canvas_item);
+ Transform2D bone_xform = bone->get_global_transform();
+ for (List<const Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) {
+ bone_xform = bone_xform * bone->get_transform().affine_inverse();
+ const Node2D *parent_bone = bone_E->get();
+ if (p_bones_length)
+ p_bones_length->push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position()));
+ if (p_bones_state)
+ p_bones_state->push_back(parent_bone->_edit_get_state());
+ bone = parent_bone;
+ }
+ }
+ }
+}
+
void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) {
for (List<CanvasItem *>::Element *E = p_canvas_items.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
@@ -717,54 +782,28 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items
} else {
se->pre_drag_rect = Rect2();
}
- se->pre_drag_bones_length = List<float>();
- se->pre_drag_bones_undo_state = List<Dictionary>();
// If we have a bone, save the state of all nodes in the IK chain
- Node2D *bone = Object::cast_to<Node2D>(canvas_item);
- if (bone && bone->has_meta("_edit_bone_")) {
- // Check if we have an IK chain
- List<Node2D *> bone_ik_list;
- bool ik_found = false;
- bone = Object::cast_to<Node2D>(bone->get_parent());
- while (bone) {
- bone_ik_list.push_back(bone);
- if (bone->has_meta("_edit_ik_")) {
- ik_found = true;
- break;
- } else if (!bone->has_meta("_edit_bone_")) {
- break;
- }
- bone = Object::cast_to<Node2D>(bone->get_parent());
- }
-
- //Save the bone state and length if we have an IK chain
- if (ik_found) {
- bone = Object::cast_to<Node2D>(canvas_item);
- Transform2D bone_xform = bone->get_global_transform();
- for (List<Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) {
- bone_xform = bone_xform * bone->get_transform().affine_inverse();
- Node2D *parent_bone = bone_E->get();
- se->pre_drag_bones_length.push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position()));
- se->pre_drag_bones_undo_state.push_back(parent_bone->_edit_get_state());
- bone = parent_bone;
- }
- }
- }
+ _save_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_length), &(se->pre_drag_bones_undo_state));
}
}
}
+void CanvasItemEditor::_restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state) {
+ CanvasItem *canvas_item = p_canvas_item;
+ for (const List<Dictionary>::Element *E = p_bones_state->front(); E; E = E->next()) {
+ canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
+ canvas_item->_edit_set_state(E->get());
+ }
+}
+
void CanvasItemEditor::_restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones) {
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
canvas_item->_edit_set_state(se->undo_state);
if (restore_bones) {
- for (List<Dictionary>::Element *E = se->pre_drag_bones_undo_state.front(); E; E = E->next()) {
- canvas_item = Object::cast_to<CanvasItem>(canvas_item->get_parent());
- canvas_item->_edit_set_state(E->get());
- }
+ _restore_canvas_item_ik_chain(canvas_item, &(se->pre_drag_bones_undo_state));
}
}
}
@@ -997,8 +1036,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
// Scroll or pan down
if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
view_offset.y += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
- _update_scrollbars();
- viewport->update();
+ update_viewport();
} else {
_zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), b->get_position());
}
@@ -1009,8 +1047,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
// Scroll or pan up
if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
view_offset.y -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
- _update_scrollbars();
- viewport->update();
+ update_viewport();
} else {
_zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), b->get_position());
}
@@ -1021,8 +1058,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
// Pan left
if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
view_offset.x -= int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
- _update_scrollbars();
- viewport->update();
+ update_viewport();
return true;
}
}
@@ -1031,8 +1067,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
// Pan right
if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
view_offset.x += int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor();
- _update_scrollbars();
- viewport->update();
+ update_viewport();
return true;
}
}
@@ -1084,8 +1119,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
}
view_offset.x -= relative.x / zoom;
view_offset.y -= relative.y / zoom;
- _update_scrollbars();
- viewport->update();
+ update_viewport();
return true;
}
}
@@ -1103,8 +1137,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event) {
const Vector2 delta = (int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom) * pan_gesture->get_delta();
view_offset.x += delta.x;
view_offset.y += delta.y;
- _update_scrollbars();
- viewport->update();
+ update_viewport();
return true;
}
@@ -1189,73 +1222,72 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(leaf_node);
- if (se && !se->pre_drag_bones_undo_state.empty()) {
-
- // Build the node list
- Point2 leaf_pos = target_position;
-
- List<Node2D *> joints_list;
- List<Point2> joints_pos;
- Node2D *joint = leaf_node;
- Transform2D joint_transform = leaf_node->get_global_transform_with_canvas();
- for (int i = 0; i < se->pre_drag_bones_undo_state.size() + 1; i++) {
- joints_list.push_back(joint);
- joints_pos.push_back(joint_transform.get_origin());
- joint_transform = joint_transform * joint->get_transform().affine_inverse();
- joint = Object::cast_to<Node2D>(joint->get_parent());
- }
- Point2 root_pos = joints_list.back()->get()->get_global_transform_with_canvas().get_origin();
-
- // Restraints the node to a maximum distance is necessary
- float total_len = 0;
- for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) {
- total_len += E->get();
- }
- if ((root_pos.distance_to(leaf_pos)) > total_len) {
- Vector2 rel = leaf_pos - root_pos;
- rel = rel.normalized() * total_len;
- leaf_pos = root_pos + rel;
- }
- joints_pos[0] = leaf_pos;
-
- // Run the solver
- int solver_iterations = 64;
- float solver_k = 0.3;
-
- // Build the position list
- for (int i = 0; i < solver_iterations; i++) {
- // Handle the leaf joint
- int node_id = 0;
+ if (se) {
+ int nb_bones = se->pre_drag_bones_undo_state.size();
+ if (nb_bones > 0) {
+
+ // Build the node list
+ Point2 leaf_pos = target_position;
+
+ List<Node2D *> joints_list;
+ List<Point2> joints_pos;
+ Node2D *joint = leaf_node;
+ Transform2D joint_transform = leaf_node->get_global_transform_with_canvas();
+ for (int i = 0; i < nb_bones + 1; i++) {
+ joints_list.push_back(joint);
+ joints_pos.push_back(joint_transform.get_origin());
+ joint_transform = joint_transform * joint->get_transform().affine_inverse();
+ joint = Object::cast_to<Node2D>(joint->get_parent());
+ }
+ Point2 root_pos = joints_list.back()->get()->get_global_transform_with_canvas().get_origin();
+
+ // Restraints the node to a maximum distance is necessary
+ float total_len = 0;
for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) {
- Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized();
- int len = E->get();
- if (E == se->pre_drag_bones_length.front()) {
- joints_pos[1] = joints_pos[1].linear_interpolate(joints_pos[0] + len * direction, solver_k);
- } else if (E == se->pre_drag_bones_length.back()) {
- joints_pos[node_id] = joints_pos[node_id].linear_interpolate(joints_pos[node_id + 1] - len * direction, solver_k);
- } else {
- Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0;
- joints_pos[node_id] = joints_pos[node_id].linear_interpolate(center - (direction * len) / 2.0, solver_k);
- joints_pos[node_id + 1] = joints_pos[node_id + 1].linear_interpolate(center + (direction * len) / 2.0, solver_k);
+ total_len += E->get();
+ }
+ if ((root_pos.distance_to(leaf_pos)) > total_len) {
+ Vector2 rel = leaf_pos - root_pos;
+ rel = rel.normalized() * total_len;
+ leaf_pos = root_pos + rel;
+ }
+ joints_pos[0] = leaf_pos;
+
+ // Run the solver
+ int solver_iterations = 64;
+ float solver_k = 0.3;
+
+ // Build the position list
+ for (int i = 0; i < solver_iterations; i++) {
+ // Handle the leaf joint
+ int node_id = 0;
+ for (List<float>::Element *E = se->pre_drag_bones_length.front(); E; E = E->next()) {
+ Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized();
+ int len = E->get();
+ if (E == se->pre_drag_bones_length.front()) {
+ joints_pos[1] = joints_pos[1].linear_interpolate(joints_pos[0] + len * direction, solver_k);
+ } else if (E == se->pre_drag_bones_length.back()) {
+ joints_pos[node_id] = joints_pos[node_id].linear_interpolate(joints_pos[node_id + 1] - len * direction, solver_k);
+ } else {
+ Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0;
+ joints_pos[node_id] = joints_pos[node_id].linear_interpolate(center - (direction * len) / 2.0, solver_k);
+ joints_pos[node_id + 1] = joints_pos[node_id + 1].linear_interpolate(center + (direction * len) / 2.0, solver_k);
+ }
+ node_id++;
}
- node_id++;
}
- }
- // Set the position
- float total_rot = 0.0f;
- for (int node_id = joints_list.size() - 1; node_id > 0; node_id--) {
- Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized();
- Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized();
- float rot = current.angle_to(target);
- if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) {
- rot = -rot;
+ // Set the position
+ for (int node_id = joints_list.size() - 1; node_id > 0; node_id--) {
+ Point2 current = (joints_list[node_id - 1]->get_global_position() - joints_list[node_id]->get_global_position()).normalized();
+ Point2 target = (joints_pos[node_id - 1] - joints_list[node_id]->get_global_position()).normalized();
+ float rot = current.angle_to(target);
+ if (joints_list[node_id]->get_global_transform().basis_determinant() < 0) {
+ rot = -rot;
+ }
+ joints_list[node_id]->rotate(rot);
}
- joints_list[node_id]->rotate(rot);
- total_rot += rot;
}
-
- joints_list[0]->rotate(-total_rot);
}
}
@@ -1266,18 +1298,28 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
// Start rotation
if (drag_type == DRAG_NONE) {
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
- drag_selection = _get_edited_canvas_items();
- if (drag_selection.size() > 0 && ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE)) {
- drag_type = DRAG_ROTATE;
- drag_from = transform.affine_inverse().xform(b->get_position());
- CanvasItem *canvas_item = drag_selection[0];
- if (canvas_item->_edit_use_pivot()) {
- drag_rotation_center = canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_pivot());
- } else {
- drag_rotation_center = canvas_item->get_global_transform_with_canvas().get_origin();
+ if ((b->get_control() && !b->get_alt() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
+ List<CanvasItem *> selection = _get_edited_canvas_items();
+
+ // Remove not movable nodes
+ for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
+ if (!_is_node_movable(E->get(), true))
+ selection.erase(E);
+ }
+
+ drag_selection = selection;
+ if (drag_selection.size() > 0) {
+ drag_type = DRAG_ROTATE;
+ drag_from = transform.affine_inverse().xform(b->get_position());
+ CanvasItem *canvas_item = drag_selection[0];
+ if (canvas_item->_edit_use_pivot()) {
+ drag_rotation_center = canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_pivot());
+ } else {
+ drag_rotation_center = canvas_item->get_global_transform_with_canvas().get_origin();
+ }
+ _save_canvas_item_state(drag_selection);
+ return true;
}
- _save_canvas_item_state(drag_selection);
- return true;
}
}
}
@@ -1340,7 +1382,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
Control *control = Object::cast_to<Control>(selection[0]);
- if (control && !Object::cast_to<Container>(control->get_parent())) {
+ if (control && _is_node_movable(control)) {
Vector2 anchor_pos[4];
anchor_pos[0] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP));
anchor_pos[1] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP));
@@ -1459,7 +1501,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
CanvasItem *canvas_item = selection[0];
- if (canvas_item->_edit_use_rect()) {
+ if (canvas_item->_edit_use_rect() && _is_node_movable(canvas_item)) {
Rect2 rect = canvas_item->_edit_get_rect();
Transform2D xform = transform * canvas_item->get_global_transform_with_canvas();
@@ -1615,6 +1657,112 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
return false;
}
+bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventMouseButton> b = p_event;
+ Ref<InputEventMouseMotion> m = p_event;
+
+ // Drag resize handles
+ if (drag_type == DRAG_NONE) {
+ if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed() && ((b->get_alt() && b->get_control()) || tool == TOOL_SCALE)) {
+ List<CanvasItem *> selection = _get_edited_canvas_items();
+ if (selection.size() == 1) {
+ CanvasItem *canvas_item = selection[0];
+
+ if (_is_node_movable(canvas_item)) {
+
+ Transform2D xform = transform * canvas_item->get_global_transform_with_canvas();
+ Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+
+ drag_type = DRAG_SCALE_BOTH;
+
+ Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
+ Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
+ drag_type = DRAG_SCALE_X;
+ }
+ Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) {
+ drag_type = DRAG_SCALE_Y;
+ }
+
+ drag_from = transform.affine_inverse().xform(b->get_position());
+ drag_selection = List<CanvasItem *>();
+ drag_selection.push_back(canvas_item);
+ _save_canvas_item_state(drag_selection);
+ return true;
+ }
+ }
+ }
+ }
+
+ if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) {
+ // Resize the node
+ if (m.is_valid()) {
+ _restore_canvas_item_state(drag_selection);
+ CanvasItem *canvas_item = drag_selection[0];
+
+ drag_to = transform.affine_inverse().xform(m->get_position());
+
+ Transform2D parent_xform = canvas_item->get_global_transform_with_canvas() * canvas_item->get_transform().affine_inverse();
+ Transform2D unscaled_transform = (transform * parent_xform * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized();
+ Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
+
+ bool uniform = m->get_shift();
+
+ Point2 drag_from_local = simple_xform.xform(drag_from);
+ Point2 drag_to_local = simple_xform.xform(drag_to);
+ Point2 offset = drag_to_local - drag_from_local;
+
+ Size2 scale = canvas_item->call("get_scale");
+ float ratio = scale.y / scale.x;
+ if (drag_type == DRAG_SCALE_BOTH) {
+ Size2 scale_factor = drag_to_local / drag_from_local;
+ if (uniform) {
+ scale *= (scale_factor.x + scale_factor.y) / 2.0;
+ } else {
+ scale *= scale_factor;
+ }
+ } else {
+ Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE;
+ Size2 parent_scale = parent_xform.get_scale();
+ scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y);
+ if (drag_type == DRAG_SCALE_X) {
+ scale.x += scale_factor.x;
+ if (uniform) {
+ scale.y = scale.x * ratio;
+ }
+ } else if (drag_type == DRAG_SCALE_Y) {
+ scale.y += scale_factor.y;
+ if (uniform) {
+ scale.x = scale.y / ratio;
+ }
+ }
+ }
+ canvas_item->call("set_scale", scale);
+ return true;
+ }
+
+ // Confirm resize
+ if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) {
+ _commit_canvas_item_state(drag_selection, TTR("Scale CanvasItem"));
+ drag_type = DRAG_NONE;
+ viewport->update();
+ return true;
+ }
+
+ // Cancel a drag
+ if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) {
+ _restore_canvas_item_state(drag_selection);
+ drag_type = DRAG_NONE;
+ viewport->update();
+ return true;
+ }
+ }
+ return false;
+}
+
bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
Ref<InputEventMouseMotion> m = p_event;
@@ -1623,20 +1771,39 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
if (drag_type == DRAG_NONE) {
//Start moving the nodes
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
- List<CanvasItem *> selection = _get_edited_canvas_items();
- if ((b->get_alt() || tool == TOOL_MOVE) && selection.size() > 0) {
- drag_type = DRAG_ALL;
- drag_from = transform.affine_inverse().xform(b->get_position());
- drag_selection = selection;
- _save_canvas_item_state(drag_selection);
+ if ((b->get_alt() && !b->get_control()) || tool == TOOL_MOVE) {
+ List<CanvasItem *> selection = _get_edited_canvas_items();
+
+ // Remove not movable nodes
+ for (int i = 0; i < selection.size(); i++) {
+ if (!_is_node_movable(selection[i], true)) {
+ selection.erase(selection[i]);
+ }
+ }
+
+ if (selection.size() > 0) {
+ drag_type = DRAG_MOVE;
+ drag_from = transform.affine_inverse().xform(b->get_position());
+ drag_selection = selection;
+ _save_canvas_item_state(drag_selection);
+ }
return true;
}
}
}
- if (drag_type == DRAG_ALL) {
+ if (drag_type == DRAG_MOVE) {
// Move the nodes
if (m.is_valid()) {
+
+ // Save the ik chain for reapplying before IK solve
+ Vector<List<Dictionary> > all_bones_ik_states;
+ for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
+ List<Dictionary> bones_ik_states;
+ _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states);
+ all_bones_ik_states.push_back(bones_ik_states);
+ }
+
_restore_canvas_item_state(drag_selection, true);
drag_to = transform.affine_inverse().xform(m->get_position());
@@ -1658,6 +1825,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
}
bool force_no_IK = m->get_alt();
+ int index = 0;
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
@@ -1665,16 +1833,21 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
if (node2d && se->pre_drag_bones_undo_state.size() > 0 && !force_no_IK) {
+ real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
+ real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
_solve_IK(node2d, new_pos);
} else {
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
}
+ index++;
}
return true;
}
// Confirm the move (only if it was moved)
- if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && (drag_type == DRAG_ALL)) {
+ if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && (drag_type == DRAG_MOVE)) {
if (transform.affine_inverse().xform(b->get_position()) != drag_from) {
_commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true);
}
@@ -1707,6 +1880,14 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
if (drag_selection.size() > 0) {
+ // Save the ik chain for reapplying before IK solve
+ Vector<List<Dictionary> > all_bones_ik_states;
+ for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
+ List<Dictionary> bones_ik_states;
+ _save_canvas_item_ik_chain(E->get(), NULL, &bones_ik_states);
+ all_bones_ik_states.push_back(bones_ik_states);
+ }
+
_restore_canvas_item_state(drag_selection, true);
bool move_local_base = k->get_alt();
@@ -1752,6 +1933,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
new_pos = previous_pos + (drag_to - drag_from);
}
+ int index = 0;
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
@@ -1759,10 +1941,15 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
Node2D *node2d = Object::cast_to<Node2D>(canvas_item);
if (node2d && se->pre_drag_bones_undo_state.size() > 0) {
+ real_t initial_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ _restore_canvas_item_ik_chain(node2d, &(all_bones_ik_states[index]));
+ real_t final_leaf_node_rotation = node2d->get_global_transform_with_canvas().get_rotation();
+ node2d->rotate(initial_leaf_node_rotation - final_leaf_node_rotation);
_solve_IK(node2d, new_pos);
} else {
canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos));
}
+ index++;
}
}
return true;
@@ -1820,11 +2007,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
for (int i = 0; i < selection_results.size(); i++) {
CanvasItem *item = selection_results[i].item;
- Ref<Texture> icon;
- if (item->has_meta("_editor_icon"))
- icon = item->get_meta("_editor_icon");
- else
- icon = get_icon(has_icon(item->get_class(), "EditorIcons") ? item->get_class() : String("Object"), "EditorIcons");
+ Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(item, "Node");
String node_path = "/" + root_name + "/" + root_path.rel_path_to(item->get_path());
selection_menu->add_item(item->get_name());
@@ -1853,27 +2036,14 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
Vector<_SelectResult> selection;
// Retrieve the items
- _get_canvas_items_at_pos(click, selection, editor_selection->get_selection().empty() ? 1 : 0);
+ _get_canvas_items_at_pos(click, selection);
// Retrieve the bones
_get_bones_at_pos(click, selection);
- for (int i = 0; i < selection.size(); i++) {
- if (editor_selection->is_selected(selection[i].item)) {
- // Drag the node(s) if requested
- List<CanvasItem *> selection = _get_edited_canvas_items();
-
- drag_type = DRAG_ALL;
- drag_selection = selection;
- drag_from = click;
- _save_canvas_item_state(drag_selection);
-
- return true;
- }
- }
-
- if (!selection.empty())
+ if (!selection.empty()) {
canvas_item = selection[0].item;
+ }
if (!canvas_item) {
// Start a box selection
@@ -1894,10 +2064,19 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
// Drag the node(s) if requested
List<CanvasItem *> selection = _get_edited_canvas_items();
- drag_type = DRAG_ALL;
- drag_selection = selection;
- drag_from = click;
- _save_canvas_item_state(drag_selection);
+ // Remove not movable nodes
+ for (int i = 0; i < selection.size(); i++) {
+ if (!_is_node_movable(selection[i], true)) {
+ selection.erase(selection[i]);
+ }
+ }
+
+ if (selection.size() > 0) {
+ drag_type = DRAG_MOVE;
+ drag_selection = selection;
+ drag_from = click;
+ _save_canvas_item_state(drag_selection);
+ }
}
// Select the item
return true;
@@ -1974,10 +2153,7 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) {
_HoverResult hover_result;
hover_result.position = canvas_item->get_global_transform_with_canvas().get_origin();
- if (has_icon(canvas_item->get_class(), "EditorIcons"))
- hover_result.icon = get_icon(canvas_item->get_class(), "EditorIcons");
- else
- hover_result.icon = get_icon("Object", "EditorIcons");
+ hover_result.icon = EditorNode::get_singleton()->get_object_icon(canvas_item);
hover_result.name = canvas_item->get_name();
hovering_results_tmp.push_back(hover_result);
@@ -2019,6 +2195,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
//printf("Open scene on double click\n");
} else if ((accepted = _gui_input_anchors(p_event))) {
//printf("Anchors\n");
+ } else if ((accepted = _gui_input_scale(p_event))) {
+ //printf("Set scale\n");
} else if ((accepted = _gui_input_pivot(p_event))) {
//printf("Set pivot\n");
} else if ((accepted = _gui_input_resize(p_event))) {
@@ -2031,6 +2209,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
//printf("Zoom or pan\n");
} else if ((accepted = _gui_input_select(p_event))) {
//printf("Selection\n");
+ } else {
+ //printf("Not accepted\n");
}
if (accepted)
@@ -2073,7 +2253,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
case DRAG_BOTTOM_LEFT:
c = CURSOR_BDIAGSIZE;
break;
- case DRAG_ALL:
+ case DRAG_MOVE:
c = CURSOR_MOVE;
break;
case DRAG_PAN:
@@ -2235,7 +2415,7 @@ void CanvasItemEditor::_draw_rulers() {
if (i % minor_subdivision == 0) {
viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color);
} else {
- viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.66), Point2(position.x, RULER_WIDTH), graduation_color);
+ viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.75), Point2(position.x, RULER_WIDTH), graduation_color);
}
}
}
@@ -2247,12 +2427,17 @@ void CanvasItemEditor::_draw_rulers() {
if (i % (major_subdivision * minor_subdivision) == 0) {
viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color);
float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y;
- viewport->draw_string(font, Point2(2, position.y + 2 + font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
+
+ Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(), position.y - 2));
+ viewport->draw_set_transform_matrix(viewport->get_transform() * text_xform);
+ viewport->draw_string(font, Point2(), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color);
+ viewport->draw_set_transform_matrix(viewport->get_transform());
+
} else {
if (i % minor_subdivision == 0) {
viewport->draw_line(Point2(RULER_WIDTH * 0.33, position.y), Point2(RULER_WIDTH, position.y), graduation_color);
} else {
- viewport->draw_line(Point2(RULER_WIDTH * 0.66, position.y), Point2(RULER_WIDTH, position.y), graduation_color);
+ viewport->draw_line(Point2(RULER_WIDTH * 0.75, position.y), Point2(RULER_WIDTH, position.y), graduation_color);
}
}
}
@@ -2301,6 +2486,188 @@ void CanvasItemEditor::_draw_grid() {
}
}
+void CanvasItemEditor::_draw_control_helpers(Control *control) {
+ Transform2D xform = transform * control->get_global_transform_with_canvas();
+ RID ci = viewport->get_canvas_item();
+ if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
+ // Draw the helpers
+ Color color_base = Color(0.8, 0.8, 0.8, 0.5);
+
+ float anchors_values[4];
+ anchors_values[0] = control->get_anchor(MARGIN_LEFT);
+ anchors_values[1] = control->get_anchor(MARGIN_TOP);
+ anchors_values[2] = control->get_anchor(MARGIN_RIGHT);
+ anchors_values[3] = control->get_anchor(MARGIN_BOTTOM);
+
+ // Draw the anchors
+ Vector2 anchors[4];
+ Vector2 anchors_pos[4];
+ for (int i = 0; i < 4; i++) {
+ anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]);
+ anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i]));
+ }
+
+ // Get which anchor is dragged
+ int dragged_anchor = -1;
+ switch (drag_type) {
+ case DRAG_ANCHOR_ALL:
+ case DRAG_ANCHOR_TOP_LEFT:
+ dragged_anchor = 0;
+ break;
+ case DRAG_ANCHOR_TOP_RIGHT:
+ dragged_anchor = 1;
+ break;
+ case DRAG_ANCHOR_BOTTOM_RIGHT:
+ dragged_anchor = 2;
+ break;
+ case DRAG_ANCHOR_BOTTOM_LEFT:
+ dragged_anchor = 3;
+ break;
+ default:
+ break;
+ }
+
+ if (dragged_anchor >= 0) {
+ // Draw the 4 lines when dragged
+ bool snapped;
+ Color color_snapped = Color(0.64, 0.93, 0.67, 0.5);
+
+ Vector2 corners_pos[4];
+ for (int i = 0; i < 4; i++) {
+ corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END)));
+ }
+
+ Vector2 line_starts[4];
+ Vector2 line_ends[4];
+ for (int i = 0; i < 4; i++) {
+ float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
+ line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val);
+ line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val);
+ snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
+ viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
+ }
+
+ // Display the percentages next to the lines
+ float percent_val;
+ percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor];
+ percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val;
+ _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4));
+
+ percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4];
+ percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val;
+ _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor));
+
+ percent_val = anchors_values[(dragged_anchor + 1) % 4];
+ percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val;
+ _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor));
+
+ percent_val = anchors_values[dragged_anchor];
+ percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val;
+ _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4));
+ }
+
+ Rect2 anchor_rects[4];
+ anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size());
+ anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y));
+ anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size());
+ anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y));
+
+ for (int i = 0; i < 4; i++) {
+ anchor_handle->draw_rect(ci, anchor_rects[i]);
+ }
+
+ // Draw the margin values and the node width/height when dragging control side
+ float ratio = 0.33;
+ Transform2D parent_transform = xform * control->get_transform().affine_inverse();
+ float node_pos_in_parent[4];
+
+ Rect2 parent_rect = control->get_parent_anchorable_rect();
+
+ node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * parent_rect.size.width + control->get_margin(MARGIN_LEFT) + parent_rect.position.x;
+ node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * parent_rect.size.height + control->get_margin(MARGIN_TOP) + parent_rect.position.y;
+ node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * parent_rect.size.width + control->get_margin(MARGIN_RIGHT) + parent_rect.position.x;
+ node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * parent_rect.size.height + control->get_margin(MARGIN_BOTTOM) + parent_rect.position.y;
+
+ Point2 start, end;
+ switch (drag_type) {
+ case DRAG_LEFT:
+ case DRAG_TOP_LEFT:
+ case DRAG_BOTTOM_LEFT:
+ _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
+ case DRAG_MOVE:
+ start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio));
+ end = start - Vector2(control->get_margin(MARGIN_LEFT), 0);
+ _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ default:
+ break;
+ }
+ switch (drag_type) {
+ case DRAG_RIGHT:
+ case DRAG_TOP_RIGHT:
+ case DRAG_BOTTOM_RIGHT:
+ _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
+ case DRAG_MOVE:
+ start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio));
+ end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0);
+ _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ default:
+ break;
+ }
+ switch (drag_type) {
+ case DRAG_TOP:
+ case DRAG_TOP_LEFT:
+ case DRAG_TOP_RIGHT:
+ _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT);
+ case DRAG_MOVE:
+ start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]);
+ end = start - Vector2(0, control->get_margin(MARGIN_TOP));
+ _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ default:
+ break;
+ }
+ switch (drag_type) {
+ case DRAG_BOTTOM:
+ case DRAG_BOTTOM_LEFT:
+ case DRAG_BOTTOM_RIGHT:
+ _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT);
+ case DRAG_MOVE:
+ start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]);
+ end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM));
+ _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT);
+ viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
+ break;
+ default:
+ break;
+ }
+
+ switch (drag_type) {
+ //Draw the ghost rect if the node if rotated/scaled
+ case DRAG_LEFT:
+ case DRAG_TOP_LEFT:
+ case DRAG_TOP:
+ case DRAG_TOP_RIGHT:
+ case DRAG_RIGHT:
+ case DRAG_BOTTOM_RIGHT:
+ case DRAG_BOTTOM:
+ case DRAG_BOTTOM_LEFT:
+ case DRAG_MOVE:
+ if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) {
+ Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size());
+ viewport->draw_rect(parent_transform.xform(rect), color_base, false);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void CanvasItemEditor::_draw_selection() {
Ref<Texture> pivot_icon = get_icon("EditorPivot", "EditorIcons");
Ref<Texture> position_icon = get_icon("EditorPosition", "EditorIcons");
@@ -2317,7 +2684,7 @@ void CanvasItemEditor::_draw_selection() {
// Draw the previous position if we are dragging the node
if (show_helpers &&
- (drag_type == DRAG_ALL || drag_type == DRAG_ROTATE ||
+ (drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE ||
drag_type == DRAG_LEFT || drag_type == DRAG_RIGHT || drag_type == DRAG_TOP || drag_type == DRAG_BOTTOM ||
drag_type == DRAG_TOP_LEFT || drag_type == DRAG_TOP_RIGHT || drag_type == DRAG_BOTTOM_LEFT || drag_type == DRAG_BOTTOM_RIGHT)) {
const Transform2D pre_drag_xform = transform * se->pre_drag_xform;
@@ -2359,200 +2726,27 @@ void CanvasItemEditor::_draw_selection() {
}
} else {
- Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin());
- viewport->draw_set_transform_matrix(transform);
+ Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+ viewport->draw_set_transform_matrix(simple_xform);
viewport->draw_texture(position_icon, -(position_icon->get_size() / 2));
- viewport->draw_set_transform_matrix(Transform2D());
+ viewport->draw_set_transform_matrix(viewport->get_transform());
}
- if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
+ if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
// Draw the pivot
if (canvas_item->_edit_get_pivot() != Vector2() || drag_type == DRAG_PIVOT || tool == TOOL_EDIT_PIVOT) { // This is not really clean :/
viewport->draw_texture(pivot_icon, (xform.xform(canvas_item->_edit_get_pivot()) - (pivot_icon->get_size() / 2)).floor());
}
+ // Draw control-related helpers
Control *control = Object::cast_to<Control>(canvas_item);
- if (control) {
- if (tool == TOOL_SELECT && show_helpers && !Object::cast_to<Container>(control->get_parent())) {
- // Draw the helpers
- Color color_base = Color(0.8, 0.8, 0.8, 0.5);
-
- float anchors_values[4];
- anchors_values[0] = control->get_anchor(MARGIN_LEFT);
- anchors_values[1] = control->get_anchor(MARGIN_TOP);
- anchors_values[2] = control->get_anchor(MARGIN_RIGHT);
- anchors_values[3] = control->get_anchor(MARGIN_BOTTOM);
-
- // Draw the anchors
- Vector2 anchors[4];
- Vector2 anchors_pos[4];
- for (int i = 0; i < 4; i++) {
- anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]);
- anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i]));
- }
-
- // Get which anchor is dragged
- int dragged_anchor = -1;
- switch (drag_type) {
- case DRAG_ANCHOR_ALL:
- case DRAG_ANCHOR_TOP_LEFT:
- dragged_anchor = 0;
- break;
- case DRAG_ANCHOR_TOP_RIGHT:
- dragged_anchor = 1;
- break;
- case DRAG_ANCHOR_BOTTOM_RIGHT:
- dragged_anchor = 2;
- break;
- case DRAG_ANCHOR_BOTTOM_LEFT:
- dragged_anchor = 3;
- break;
- default:
- break;
- }
-
- if (dragged_anchor >= 0) {
- // Draw the 4 lines when dragged
- bool snapped;
- Color color_snapped = Color(0.64, 0.93, 0.67, 0.5);
-
- Vector2 corners_pos[4];
- for (int i = 0; i < 4; i++) {
- corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END)));
- }
-
- Vector2 line_starts[4];
- Vector2 line_ends[4];
- for (int i = 0; i < 4; i++) {
- float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
- line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val);
- line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val);
- snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
- viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
- }
-
- // Display the percentages next to the lines
- float percent_val;
- percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor];
- percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val;
- _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4));
-
- percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4];
- percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val;
- _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor));
-
- percent_val = anchors_values[(dragged_anchor + 1) % 4];
- percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val;
- _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor));
-
- percent_val = anchors_values[dragged_anchor];
- percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val;
- _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4));
- }
-
- Rect2 anchor_rects[4];
- anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size());
- anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y));
- anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size());
- anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y));
-
- for (int i = 0; i < 4; i++) {
- anchor_handle->draw_rect(ci, anchor_rects[i]);
- }
-
- // Draw the margin values and the node width/height when dragging control side
- float ratio = 0.33;
- Transform2D parent_transform = xform * control->get_transform().affine_inverse();
- float node_pos_in_parent[4];
-
- Rect2 parent_rect = control->get_parent_anchorable_rect();
-
- node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * parent_rect.size.width + control->get_margin(MARGIN_LEFT) + parent_rect.position.x;
- node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * parent_rect.size.height + control->get_margin(MARGIN_TOP) + parent_rect.position.y;
- node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * parent_rect.size.width + control->get_margin(MARGIN_RIGHT) + parent_rect.position.x;
- node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * parent_rect.size.height + control->get_margin(MARGIN_BOTTOM) + parent_rect.position.y;
-
- Point2 start, end;
- switch (drag_type) {
- case DRAG_LEFT:
- case DRAG_TOP_LEFT:
- case DRAG_BOTTOM_LEFT:
- _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
- case DRAG_ALL:
- start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio));
- end = start - Vector2(control->get_margin(MARGIN_LEFT), 0);
- _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP);
- viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
- break;
- default:
- break;
- }
- switch (drag_type) {
- case DRAG_RIGHT:
- case DRAG_TOP_RIGHT:
- case DRAG_BOTTOM_RIGHT:
- _draw_margin_at_position(control->get_size().width, parent_transform.xform(Vector2((node_pos_in_parent[0] + node_pos_in_parent[2]) / 2, node_pos_in_parent[3])) + Vector2(0, 5), MARGIN_BOTTOM);
- case DRAG_ALL:
- start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio));
- end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0);
- _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM);
- viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
- break;
- default:
- break;
- }
- switch (drag_type) {
- case DRAG_TOP:
- case DRAG_TOP_LEFT:
- case DRAG_TOP_RIGHT:
- _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2)) + Vector2(5, 0), MARGIN_RIGHT);
- case DRAG_ALL:
- start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]);
- end = start - Vector2(0, control->get_margin(MARGIN_TOP));
- _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT);
- viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
- break;
- default:
- break;
- }
- switch (drag_type) {
- case DRAG_BOTTOM:
- case DRAG_BOTTOM_LEFT:
- case DRAG_BOTTOM_RIGHT:
- _draw_margin_at_position(control->get_size().height, parent_transform.xform(Vector2(node_pos_in_parent[2], (node_pos_in_parent[1] + node_pos_in_parent[3]) / 2) + Vector2(5, 0)), MARGIN_RIGHT);
- case DRAG_ALL:
- start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]);
- end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM));
- _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT);
- viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1);
- break;
- default:
- break;
- }
-
- switch (drag_type) {
- //Draw the ghost rect if the node if rotated/scaled
- case DRAG_LEFT:
- case DRAG_TOP_LEFT:
- case DRAG_TOP:
- case DRAG_TOP_RIGHT:
- case DRAG_RIGHT:
- case DRAG_BOTTOM_RIGHT:
- case DRAG_BOTTOM:
- case DRAG_BOTTOM_LEFT:
- case DRAG_ALL:
- if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) {
- Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size());
- viewport->draw_rect(parent_transform.xform(rect), color_base, false);
- }
- break;
- default:
- break;
- }
- }
+ if (control && _is_node_movable(control)) {
+ _draw_control_helpers(control);
}
- if (tool == TOOL_SELECT && canvas_item->_edit_use_rect()) {
+ // Draw the resize handles
+ if (tool == TOOL_SELECT && canvas_item->_edit_use_rect() && _is_node_movable(canvas_item)) {
Rect2 rect = canvas_item->_edit_get_rect();
Vector2 endpoints[4] = {
xform.xform(rect.position),
@@ -2561,7 +2755,6 @@ void CanvasItemEditor::_draw_selection() {
xform.xform(rect.position + Vector2(0, rect.size.y))
};
for (int i = 0; i < 4; i++) {
- // Draw the resize handles
int prev = (i + 3) % 4;
int next = (i + 1) % 4;
@@ -2576,6 +2769,47 @@ void CanvasItemEditor::_draw_selection() {
select_handle->draw(ci, (ofs - (select_handle->get_size() / 2)).floor());
}
}
+
+ // Draw the rescale handles
+ bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
+ if ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) {
+ if (_is_node_movable(canvas_item)) {
+ Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+
+ Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
+ bool uniform = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+ Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
+
+ if (drag_type == DRAG_SCALE_X) {
+ scale_factor.x += offset.x;
+ if (uniform) {
+ scale_factor.y += offset.x;
+ }
+ } else if (drag_type == DRAG_SCALE_Y) {
+ scale_factor.y -= offset.y;
+ if (uniform) {
+ scale_factor.x -= offset.y;
+ }
+ }
+
+ //scale_factor *= zoom;
+
+ viewport->draw_set_transform_matrix(simple_xform);
+ Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ Color x_axis_color(1.0, 0.4, 0.4, 0.6);
+ viewport->draw_rect(x_handle_rect, x_axis_color);
+ viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), x_axis_color);
+
+ Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE);
+ Color y_axis_color(0.4, 1.0, 0.4, 0.6);
+ viewport->draw_rect(y_handle_rect, y_axis_color);
+ viewport->draw_line(Point2(), Point2(0, -scale_factor.y * EDSCALE), y_axis_color);
+
+ viewport->draw_set_transform_matrix(viewport->get_transform());
+ }
+ }
}
}
@@ -2650,7 +2884,7 @@ void CanvasItemEditor::_draw_axis() {
RID ci = viewport->get_canvas_item();
- Color area_axis_color(0.4, 0.4, 1.0, 0.4);
+ Color area_axis_color = EditorSettings::get_singleton()->get("editors/2d/viewport_border_color");
Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
@@ -2750,15 +2984,16 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
_draw_invisible_nodes_positions(p_node->get_child(i), parent_xform, canvas_xform);
}
- if (canvas_item && !canvas_item->_edit_use_rect() && !editor_selection->is_selected(canvas_item)) {
+ if (canvas_item && !canvas_item->_edit_use_rect() && (!editor_selection->is_selected(canvas_item) || _is_node_locked(canvas_item))) {
Transform2D xform = transform * canvas_xform * parent_xform;
// Draw the node's position
Ref<Texture> position_icon = get_icon("EditorPositionUnselected", "EditorIcons");
- Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin());
- viewport->draw_set_transform_matrix(transform);
+ Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * Transform2D(canvas_item->_edit_get_rotation(), canvas_item->_edit_get_position())).orthonormalized();
+ Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
+ viewport->draw_set_transform_matrix(simple_xform);
viewport->draw_texture(position_icon, -position_icon->get_size() / 2, Color(1.0, 1.0, 1.0, 0.5));
- viewport->draw_set_transform_matrix(Transform2D());
+ viewport->draw_set_transform_matrix(viewport->get_transform());
}
}
@@ -2775,7 +3010,7 @@ void CanvasItemEditor::_draw_hover() {
Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3));
Point2 pos = transform.xform(hovering_results[i].position) - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4);
- // Rectify the position to avoid overlaping items
+ // Rectify the position to avoid overlapping items
for (List<Rect2>::Element *E = previous_rects.front(); E; E = E->next()) {
if (E->get().intersects(Rect2(pos, item_size))) {
pos.y = E->get().get_position().y - item_size.y;
@@ -2822,13 +3057,13 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
float offset = 0;
Ref<Texture> lock = get_icon("LockViewport", "EditorIcons");
- if (p_node->has_meta("_edit_lock_")) {
+ if (p_node->has_meta("_edit_lock_") && show_edit_locks) {
lock->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0));
offset += lock->get_size().x;
}
Ref<Texture> group = get_icon("GroupViewport", "EditorIcons");
- if (canvas_item->has_meta("_edit_group_")) {
+ if (canvas_item->has_meta("_edit_group_") && show_edit_locks) {
group->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0));
//offset += group->get_size().x;
}
@@ -2902,6 +3137,7 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {
}
void CanvasItemEditor::_draw_viewport() {
+
// Update the transform
transform = Transform2D();
transform.scale_basis(Size2(zoom, zoom));
@@ -2937,6 +3173,8 @@ void CanvasItemEditor::_draw_viewport() {
group_button->set_disabled(selection.empty());
ungroup_button->set_visible(all_group);
+ info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
+
_draw_grid();
_draw_selection();
_draw_axis();
@@ -2950,11 +3188,11 @@ void CanvasItemEditor::_draw_viewport() {
EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
- over_plugin_list->forward_draw_over_viewport(viewport);
+ over_plugin_list->forward_canvas_draw_over_viewport(viewport);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
if (!force_over_plugin_list->empty()) {
- force_over_plugin_list->forward_force_draw_over_viewport(viewport);
+ force_over_plugin_list->forward_canvas_force_draw_over_viewport(viewport);
}
_draw_bones();
@@ -2966,6 +3204,11 @@ void CanvasItemEditor::_draw_viewport() {
_draw_hover();
}
+void CanvasItemEditor::update_viewport() {
+ _update_scrollbars();
+ viewport->update();
+}
+
void CanvasItemEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
@@ -3086,6 +3329,7 @@ void CanvasItemEditor::_notification(int p_what) {
select_button->set_icon(get_icon("ToolSelect", "EditorIcons"));
list_select_button->set_icon(get_icon("ListSelect", "EditorIcons"));
move_button->set_icon(get_icon("ToolMove", "EditorIcons"));
+ scale_button->set_icon(get_icon("ToolScale", "EditorIcons"));
rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons"));
snap_button->set_icon(get_icon("Snap", "EditorIcons"));
snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
@@ -3159,11 +3403,14 @@ void CanvasItemEditor::_notification(int p_what) {
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
- drag_type = DRAG_NONE;
+ Array selection = editor_selection->get_selected_nodes();
+ if (selection.size() != 1 || (Node *)selection[0] != p_canvas_item) {
+ drag_type = DRAG_NONE;
- // Clear the selection
- editor_selection->clear(); //_clear_canvas_items();
- editor_selection->add_node(p_canvas_item);
+ // Clear the selection
+ editor_selection->clear(); //_clear_canvas_items();
+ editor_selection->add_node(p_canvas_item);
+ }
}
void CanvasItemEditor::_queue_update_bone_list() {
@@ -3295,6 +3542,35 @@ void CanvasItemEditor::_update_scrollbars() {
updating_scroll = false;
}
+void CanvasItemEditor::_popup_warning_depop(Control *p_control) {
+ ERR_FAIL_COND(!popup_temporarily_timers.has(p_control));
+
+ Timer *timer = popup_temporarily_timers[p_control];
+ p_control->hide();
+ remove_child(timer);
+ popup_temporarily_timers.erase(p_control);
+ memdelete(timer);
+ info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
+}
+
+void CanvasItemEditor::_popup_warning_temporarily(Control *p_control, const float p_duration) {
+ Timer *timer;
+ if (!popup_temporarily_timers.has(p_control)) {
+ timer = memnew(Timer);
+ timer->connect("timeout", this, "_popup_warning_depop", varray(p_control));
+ timer->set_one_shot(true);
+ add_child(timer);
+
+ popup_temporarily_timers[p_control] = timer;
+ } else {
+ timer = popup_temporarily_timers[p_control];
+ }
+
+ timer->start(p_duration);
+ p_control->show();
+ info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
+}
+
void CanvasItemEditor::_update_scroll(float) {
if (updating_scroll)
@@ -3371,8 +3647,7 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
view_offset.x = Math::round(view_offset.x + ofs.x);
view_offset.y = Math::round(view_offset.y + ofs.y);
- _update_scrollbars();
- viewport->update();
+ update_viewport();
}
void CanvasItemEditor::_button_zoom_minus() {
@@ -3394,7 +3669,7 @@ void CanvasItemEditor::_button_toggle_snap(bool p_status) {
void CanvasItemEditor::_button_tool_select(int p_index) {
- ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, rotate_button, pivot_button, pan_button };
+ ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button };
for (int i = 0; i < TOOL_MAX; i++) {
tb[i]->set_pressed(i == p_index);
}
@@ -3426,6 +3701,12 @@ void CanvasItemEditor::_popup_callback(int p_op) {
view_menu->get_popup()->set_item_checked(idx, show_viewport);
viewport->update();
} break;
+ case SHOW_EDIT_LOCKS: {
+ show_edit_locks = !show_edit_locks;
+ int idx = view_menu->get_popup()->get_item_index(SHOW_EDIT_LOCKS);
+ view_menu->get_popup()->set_item_checked(idx, show_edit_locks);
+ viewport->update();
+ } break;
case SNAP_USE_NODE_PARENT: {
snap_node_parent = !snap_node_parent;
int idx = smartsnap_config_popup->get_item_index(SNAP_USE_NODE_PARENT);
@@ -3963,8 +4244,7 @@ void CanvasItemEditor::_focus_selection(int p_op) {
Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
view_offset.x -= offset.x / zoom;
view_offset.y -= offset.y / zoom;
- _update_scrollbars();
- viewport->update();
+ update_viewport();
} else { // VIEW_FRAME_TO_SELECTION
@@ -3997,10 +4277,11 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_snap_changed", &CanvasItemEditor::_snap_changed);
ClassDB::bind_method("_update_bone_list", &CanvasItemEditor::_update_bone_list);
ClassDB::bind_method("_tree_changed", &CanvasItemEditor::_tree_changed);
-
+ ClassDB::bind_method("_popup_warning_depop", &CanvasItemEditor::_popup_warning_depop);
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);
+ ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport);
ADD_SIGNAL(MethodInfo("item_lock_status_changed"));
ADD_SIGNAL(MethodInfo("item_group_status_changed"));
@@ -4029,6 +4310,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["show_rulers"] = show_rulers;
state["show_guides"] = show_guides;
state["show_helpers"] = show_helpers;
+ state["show_edit_locks"] = show_edit_locks;
state["snap_rotation"] = snap_rotation;
state["snap_relative"] = snap_relative;
state["snap_pixel"] = snap_pixel;
@@ -4148,6 +4430,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
view_menu->get_popup()->set_item_checked(idx, show_helpers);
}
+ if (state.has("show_edit_locks")) {
+ show_edit_locks = state["show_edit_locks"];
+ int idx = view_menu->get_popup()->get_item_index(SHOW_EDIT_LOCKS);
+ view_menu->get_popup()->set_item_checked(idx, show_edit_locks);
+ }
+
if (state.has("snap_rotation")) {
snap_rotation = state["snap_rotation"];
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
@@ -4175,7 +4463,22 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
viewport->update();
}
+void CanvasItemEditor::add_control_to_info_overlay(Control *p_control) {
+ ERR_FAIL_COND(!p_control);
+
+ p_control->set_h_size_flags(p_control->get_h_size_flags() & ~Control::SIZE_EXPAND_FILL);
+ info_overlay->add_child(p_control);
+ info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
+}
+
+void CanvasItemEditor::remove_control_from_info_overlay(Control *p_control) {
+
+ info_overlay->remove_child(p_control);
+ info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
+}
+
void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
+ ERR_FAIL_COND(!p_control);
hb->add_child(p_control);
}
@@ -4201,6 +4504,46 @@ void CanvasItemEditor::focus_selection() {
CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
+ key_pos = true;
+ key_rot = true;
+ key_scale = false;
+
+ show_grid = false;
+ show_origin = true;
+ show_viewport = true;
+ show_helpers = false;
+ show_rulers = true;
+ show_guides = true;
+ show_edit_locks = true;
+ zoom = 1;
+ view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH);
+ previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen
+ grid_offset = Point2();
+ grid_step = Point2(10, 10);
+ grid_step_multiplier = 0;
+ snap_rotation_offset = 0;
+ snap_rotation_step = 15 / (180 / Math_PI);
+ snap_active = false;
+ snap_node_parent = true;
+ snap_node_anchors = true;
+ snap_node_sides = true;
+ snap_node_center = true;
+ snap_other_nodes = true;
+ snap_grid = true;
+ snap_guides = true;
+ snap_rotation = false;
+ snap_pixel = false;
+
+ skeleton_show_bones = true;
+
+ drag_type = DRAG_NONE;
+ drag_from = Vector2();
+ drag_to = Vector2();
+ dragged_guide_pos = Point2();
+ dragged_guide_index = -1;
+
+ bone_last_frame = 0;
+
bone_list_dirty = false;
tool = TOOL_SELECT;
undo_redo = p_editor->get_undo_redo();
@@ -4244,6 +4587,28 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
viewport->connect("draw", this, "_draw_viewport");
viewport->connect("gui_input", this, "_gui_input_viewport");
+ info_overlay = memnew(VBoxContainer);
+ info_overlay->set_anchors_and_margins_preset(Control::PRESET_BOTTOM_LEFT);
+ info_overlay->set_margin(MARGIN_LEFT, 10);
+ info_overlay->set_margin(MARGIN_BOTTOM, -15);
+ info_overlay->set_v_grow_direction(Control::GROW_DIRECTION_BEGIN);
+ info_overlay->add_constant_override("separation", 10);
+ viewport_scrollable->add_child(info_overlay);
+
+ Theme *info_overlay_theme = memnew(Theme);
+ info_overlay_theme->copy_default_theme();
+ info_overlay->set_theme(info_overlay_theme);
+
+ StyleBoxFlat *info_overlay_label_stylebox = memnew(StyleBoxFlat);
+ info_overlay_label_stylebox->set_bg_color(Color(0.0, 0.0, 0.0, 0.2));
+ info_overlay_label_stylebox->set_expand_margin_size_all(4);
+ info_overlay_theme->set_stylebox("normal", "Label", info_overlay_label_stylebox);
+
+ warning_child_of_container = memnew(Label);
+ warning_child_of_container->hide();
+ warning_child_of_container->set_text("Warning: Children of a container get their position and size determined only by their parent");
+ add_control_to_info_overlay(warning_child_of_container);
+
h_scroll = memnew(HScrollBar);
viewport->add_child(h_scroll);
h_scroll->connect("value_changed", this, "_update_scroll");
@@ -4273,7 +4638,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
zoom_plus = memnew(ToolButton);
zoom_hb->add_child(zoom_plus);
zoom_plus->connect("pressed", this, "_button_zoom_plus");
- zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_PLUS));
+ zoom_plus->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", TTR("Zoom in"), KEY_MASK_CMD | KEY_EQUAL)); // Usually direct access key for PLUS
zoom_plus->set_focus_mode(FOCUS_NONE);
updating_scroll = false;
@@ -4286,6 +4651,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q));
select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection"));
+ hb->add_child(memnew(VSeparator));
+
move_button = memnew(ToolButton);
hb->add_child(move_button);
move_button->set_toggle_mode(true);
@@ -4300,6 +4667,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
rotate_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/rotate_mode", TTR("Rotate Mode"), KEY_E));
rotate_button->set_tooltip(TTR("Rotate Mode"));
+ scale_button = memnew(ToolButton);
+ hb->add_child(scale_button);
+ scale_button->set_toggle_mode(true);
+ scale_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SCALE));
+ scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), KEY_S));
+ scale_button->set_tooltip(TTR("Scale Mode"));
+
hb->add_child(memnew(VSeparator));
list_select_button = memnew(ToolButton);
@@ -4383,6 +4757,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
skeleton_menu = memnew(MenuButton);
hb->add_child(skeleton_menu);
+ skeleton_menu->set_tooltip(TTR("Skeleton Options"));
p = skeleton_menu->get_popup();
p->set_hide_on_checkable_item_selection(false);
@@ -4409,6 +4784,8 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_guides", TTR("Show Guides"), KEY_Y), SHOW_GUIDES);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_origin", TTR("Show Origin")), SHOW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_viewport", TTR("Show Viewport")), SHOW_VIEWPORT);
+ p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/show_edit_locks", TTR("Show Group And Lock Icons")), SHOW_EDIT_LOCKS);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/center_selection", TTR("Center Selection"), KEY_F), VIEW_CENTER_TO_SELECTION);
p->add_shortcut(ED_SHORTCUT("canvas_item_editor/frame_selection", TTR("Frame Selection"), KEY_MASK_SHIFT | KEY_F), VIEW_FRAME_TO_SELECTION);
@@ -4489,48 +4866,11 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), KEY_KP_MULTIPLY);
divide_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/divide_grid_step", TTR("Divide grid step by 2"), KEY_KP_DIVIDE);
- key_pos = true;
- key_rot = true;
- key_scale = false;
-
- show_grid = false;
- show_origin = true;
- show_viewport = true;
- show_helpers = false;
- show_rulers = true;
- show_guides = true;
- zoom = 1;
- view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH);
- previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen
- grid_offset = Point2();
- grid_step = Point2(10, 10);
- grid_step_multiplier = 0;
- snap_rotation_offset = 0;
- snap_rotation_step = 15 / (180 / Math_PI);
- snap_active = false;
- snap_node_parent = true;
- snap_node_anchors = true;
- snap_node_sides = true;
- snap_node_center = true;
- snap_other_nodes = true;
- snap_grid = true;
- snap_guides = true;
- snap_rotation = false;
- snap_pixel = false;
- skeleton_show_bones = true;
skeleton_menu->get_popup()->set_item_checked(skeleton_menu->get_popup()->get_item_index(SKELETON_SHOW_BONES), true);
singleton = this;
set_process_unhandled_key_input(true);
- drag_type = DRAG_NONE;
- drag_from = Vector2();
- drag_to = Vector2();
- dragged_guide_pos = Point2();
- dragged_guide_index = -1;
-
- bone_last_frame = 0;
-
// Update the menus' checkboxes
call_deferred("set_state", get_state());
}
@@ -4730,19 +5070,13 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
editor_data->get_undo_redo().add_do_property(child, "polygon", list);
}
- // locate at preview position
- Point2 pos = Point2(0, 0);
- if (parent && parent->has_method("get_global_position")) {
- pos = parent->call("get_global_position");
- }
- Transform2D trans = canvas->get_canvas_transform();
- Point2 target_position = (p_point - trans.get_origin()) / trans.get_scale().x - pos;
- if (default_type == "Polygon2D" || default_type == "TouchScreenButton" || default_type == "TextureRect" || default_type == "NinePatchRect") {
- target_position -= texture_size / 2;
- }
+ // Compute the global position
+ Transform2D xform = canvas_item_editor->get_canvas_transform();
+ Point2 target_position = xform.affine_inverse().xform(p_point);
+
// there's nothing to be used as source position so snapping will work as absolute if enabled
- target_position = canvas->snap_point(target_position);
- editor_data->get_undo_redo().add_do_method(child, "set_position", target_position);
+ target_position = canvas_item_editor->snap_point(target_position);
+ editor_data->get_undo_redo().add_do_method(child, "set_global_position", target_position);
}
bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) {
@@ -4777,8 +5111,8 @@ bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, cons
CanvasItem *parent_ci = Object::cast_to<CanvasItem>(parent);
if (parent_ci) {
- Vector2 target_pos = canvas->get_canvas_transform().affine_inverse().xform(p_point);
- target_pos = canvas->snap_point(target_pos);
+ Vector2 target_pos = canvas_item_editor->get_canvas_transform().affine_inverse().xform(p_point);
+ target_pos = canvas_item_editor->snap_point(target_pos);
target_pos = parent_ci->get_global_transform_with_canvas().affine_inverse().xform(target_pos);
editor_data->get_undo_redo().add_do_method(instanced_scene, "set_position", target_pos);
}
@@ -4791,7 +5125,6 @@ void CanvasItemEditorViewport::_perform_drop_data() {
// Without root dropping multiple files is not allowed
if (!target_node && selected_files.size() > 1) {
- accept->get_ok()->set_text(TTR("Ok"));
accept->set_text(TTR("Cannot instantiate multiple nodes without root."));
accept->popup_centered_minsize();
return;
@@ -4853,7 +5186,6 @@ void CanvasItemEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
@@ -4887,7 +5219,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
type == "AtlasTexture" ||
type == "LargeTexture") {
Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(*res));
- if (texture.is_valid() == false) {
+ if (!texture.is_valid()) {
continue;
}
} else {
@@ -4900,7 +5232,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
if (!preview_node->get_parent()) { // create preview only once
_create_preview(files);
}
- Transform2D trans = canvas->get_canvas_transform();
+ Transform2D trans = canvas_item_editor->get_canvas_transform();
preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x);
label->set_text(vformat(TTR("Adding %s..."), default_type));
}
@@ -4995,7 +5327,7 @@ void CanvasItemEditorViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("_on_mouse_exit"), &CanvasItemEditorViewport::_on_mouse_exit);
}
-CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas) {
+CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas_item_editor) {
default_type = "Sprite";
// Node2D
types.push_back("Sprite");
@@ -5010,7 +5342,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
target_node = NULL;
editor = p_node;
editor_data = editor->get_scene_tree_dock()->get_editor_data();
- canvas = p_canvas;
+ canvas_item_editor = p_canvas_item_editor;
preview_node = memnew(Node2D);
accept = memnew(AcceptDialog);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 2c943385ad..207e57dbe2 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -64,25 +64,31 @@ public:
Dictionary undo_state;
- CanvasItemEditorSelectedItem() { prev_rot = 0; }
+ CanvasItemEditorSelectedItem() :
+ prev_anchors() {
+ prev_rot = 0;
+ }
};
class CanvasItemEditor : public VBoxContainer {
GDCLASS(CanvasItemEditor, VBoxContainer);
- EditorNode *editor;
-
+public:
enum Tool {
TOOL_SELECT,
TOOL_LIST_SELECT,
TOOL_MOVE,
+ TOOL_SCALE,
TOOL_ROTATE,
TOOL_EDIT_PIVOT,
TOOL_PAN,
TOOL_MAX
};
+private:
+ EditorNode *editor;
+
enum MenuOption {
SNAP_USE,
SNAP_USE_NODE_PARENT,
@@ -102,6 +108,7 @@ class CanvasItemEditor : public VBoxContainer {
SHOW_GUIDES,
SHOW_ORIGIN,
SHOW_VIEWPORT,
+ SHOW_EDIT_LOCKS,
LOCK_SELECTED,
UNLOCK_SELECTED,
GROUP_SELECTED,
@@ -188,7 +195,10 @@ class CanvasItemEditor : public VBoxContainer {
DRAG_ANCHOR_BOTTOM_RIGHT,
DRAG_ANCHOR_BOTTOM_LEFT,
DRAG_ANCHOR_ALL,
- DRAG_ALL,
+ DRAG_MOVE,
+ DRAG_SCALE_X,
+ DRAG_SCALE_Y,
+ DRAG_SCALE_BOTH,
DRAG_ROTATE,
DRAG_PIVOT,
DRAG_V_GUIDE,
@@ -213,6 +223,11 @@ class CanvasItemEditor : public VBoxContainer {
ToolButton *zoom_reset;
ToolButton *zoom_plus;
+ Map<Control *, Timer *> popup_temporarily_timers;
+
+ Label *warning_child_of_container;
+ VBoxContainer *info_overlay;
+
Transform2D transform;
bool show_grid;
bool show_rulers;
@@ -220,6 +235,7 @@ class CanvasItemEditor : public VBoxContainer {
bool show_origin;
bool show_viewport;
bool show_helpers;
+ bool show_edit_locks;
float zoom;
Point2 view_offset;
Point2 previous_update_view_offset;
@@ -272,6 +288,10 @@ class CanvasItemEditor : public VBoxContainer {
Transform2D xform;
float length;
uint64_t last_pass;
+
+ BoneList() :
+ length(0.f),
+ last_pass(0) {}
};
uint64_t bone_last_frame;
@@ -298,17 +318,19 @@ class CanvasItemEditor : public VBoxContainer {
List<PoseClipboard> pose_clipboard;
ToolButton *select_button;
- ToolButton *list_select_button;
+
ToolButton *move_button;
+ ToolButton *scale_button;
ToolButton *rotate_button;
+ ToolButton *list_select_button;
+ ToolButton *pivot_button;
+ ToolButton *pan_button;
+
ToolButton *snap_button;
MenuButton *snap_config_menu;
PopupMenu *smartsnap_config_popup;
- ToolButton *pivot_button;
- ToolButton *pan_button;
-
ToolButton *lock_button;
ToolButton *unlock_button;
@@ -355,8 +377,10 @@ class CanvasItemEditor : public VBoxContainer {
Ref<ShortCut> multiply_grid_step_shortcut;
Ref<ShortCut> divide_grid_step_shortcut;
- void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, int p_limit = 0, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
- void _get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, int p_limit = 0);
+ bool _is_node_locked(const Node *p_node);
+ bool _is_node_movable(const Node *p_node, bool p_popup_warning = false);
+ void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
+ void _get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items);
void _get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items);
void _find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D());
@@ -368,7 +392,9 @@ class CanvasItemEditor : public VBoxContainer {
void _add_canvas_item(CanvasItem *p_canvas_item);
+ void _save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state);
void _save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones = false);
+ void _restore_canvas_item_ik_chain(CanvasItem *p_canvas_item, const List<Dictionary> *p_bones_state);
void _restore_canvas_item_state(List<CanvasItem *> p_canvas_items, bool restore_bones = false);
void _commit_canvas_item_state(List<CanvasItem *> p_canvas_items, String action_name, bool commit_bones = false);
@@ -408,6 +434,7 @@ class CanvasItemEditor : public VBoxContainer {
void _draw_guides();
void _draw_focus();
void _draw_grid();
+ void _draw_control_helpers(Control *control);
void _draw_selection();
void _draw_axis();
void _draw_bones();
@@ -420,6 +447,7 @@ class CanvasItemEditor : public VBoxContainer {
bool _gui_input_anchors(const Ref<InputEvent> &p_event);
bool _gui_input_move(const Ref<InputEvent> &p_event);
bool _gui_input_open_scene_on_double_click(const Ref<InputEvent> &p_event);
+ bool _gui_input_scale(const Ref<InputEvent> &p_event);
bool _gui_input_pivot(const Ref<InputEvent> &p_event);
bool _gui_input_resize(const Ref<InputEvent> &p_event);
bool _gui_input_rotate(const Ref<InputEvent> &p_event);
@@ -458,6 +486,9 @@ class CanvasItemEditor : public VBoxContainer {
void _update_bone_list();
void _tree_changed(Node *);
+ void _popup_warning_temporarily(Control *p_control, const float p_duration);
+ void _popup_warning_depop(Control *p_control);
+
friend class CanvasItemEditorPlugin;
protected:
@@ -523,11 +554,18 @@ public:
void add_control_to_menu_panel(Control *p_control);
void remove_control_from_menu_panel(Control *p_control);
+ void add_control_to_info_overlay(Control *p_control);
+ void remove_control_from_info_overlay(Control *p_control);
+
HSplitContainer *get_palette_split();
VSplitContainer *get_bottom_split();
Control *get_viewport_control() { return viewport; }
+ void update_viewport();
+
+ Tool get_current_tool() { return tool; }
+
void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; }
void edit(CanvasItem *p_canvas_item);
@@ -570,7 +608,7 @@ class CanvasItemEditorViewport : public Control {
EditorNode *editor;
EditorData *editor_data;
- CanvasItemEditor *canvas;
+ CanvasItemEditor *canvas_item_editor;
Node2D *preview_node;
AcceptDialog *accept;
WindowDialog *selector;
@@ -604,7 +642,7 @@ public:
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const;
virtual void drop_data(const Point2 &p_point, const Variant &p_data);
- CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas);
+ CanvasItemEditorViewport(EditorNode *p_node, CanvasItemEditor *p_canvas_item_editor);
~CanvasItemEditorViewport();
};
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index 5109379add..805a7d3835 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -31,10 +31,10 @@
#include "collision_polygon_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/os/file_access.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "editor/editor_settings.h"
-#include "os/file_access.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/3d/camera.h"
#include "spatial_editor_plugin.h"
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 9e052bb027..313ba1ee6b 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -129,7 +129,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
capsule->set_height(parameter * 2 - capsule->get_radius() * 2);
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
} break;
@@ -138,7 +138,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
Ref<CircleShape2D> circle = node->get_shape();
circle->set_radius(p_point.length());
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} break;
@@ -160,7 +160,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
line->set_normal(p_point.normalized());
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
} break;
@@ -170,7 +170,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
ray->set_length(Math::abs(p_point.y));
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} break;
@@ -183,7 +183,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
rect->set_extents(extents.abs());
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
} break;
@@ -198,16 +198,16 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
seg->set_b(p_point);
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
} break;
}
+ node->get_shape()->_change_notify();
}
void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
- Control *c = canvas_item_editor->get_viewport_control();
undo_redo->create_action(TTR("Set Handle"));
switch (shape_type) {
@@ -216,14 +216,14 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
if (idx == 0) {
undo_redo->add_do_method(capsule.ptr(), "set_radius", capsule->get_radius());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(capsule.ptr(), "set_radius", p_org);
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
} else if (idx == 1) {
undo_redo->add_do_method(capsule.ptr(), "set_height", capsule->get_height());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(capsule.ptr(), "set_height", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
}
} break;
@@ -232,9 +232,9 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
Ref<CircleShape2D> circle = node->get_shape();
undo_redo->add_do_method(circle.ptr(), "set_radius", circle->get_radius());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(circle.ptr(), "set_radius", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} break;
@@ -251,14 +251,14 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
if (idx == 0) {
undo_redo->add_do_method(line.ptr(), "set_d", line->get_d());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(line.ptr(), "set_d", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} else {
undo_redo->add_do_method(line.ptr(), "set_normal", line->get_normal());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(line.ptr(), "set_normal", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
}
} break;
@@ -267,9 +267,9 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
Ref<RayShape2D> ray = node->get_shape();
undo_redo->add_do_method(ray.ptr(), "set_length", ray->get_length());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(ray.ptr(), "set_length", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} break;
@@ -277,9 +277,9 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
Ref<RectangleShape2D> rect = node->get_shape();
undo_redo->add_do_method(rect.ptr(), "set_extents", rect->get_extents());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(rect.ptr(), "set_extents", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} break;
@@ -287,14 +287,14 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
Ref<SegmentShape2D> seg = node->get_shape();
if (idx == 0) {
undo_redo->add_do_method(seg.ptr(), "set_a", seg->get_a());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(seg.ptr(), "set_a", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} else if (idx == 1) {
undo_redo->add_do_method(seg.ptr(), "set_b", seg->get_b());
- undo_redo->add_do_method(c, "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(seg.ptr(), "set_b", p_org);
- undo_redo->add_undo_method(c, "update");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
}
} break;
@@ -323,7 +323,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
if (mb.is_valid()) {
Vector2 gpoint = mb->get_position();
- Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
@@ -412,10 +411,10 @@ void CollisionShape2DEditor::_get_current_shape_type() {
shape_type = -1;
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
-void CollisionShape2DEditor::forward_draw_over_viewport(Control *p_overlay) {
+void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!node) {
return;
@@ -539,7 +538,7 @@ void CollisionShape2DEditor::edit(Node *p_node) {
node = NULL;
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
void CollisionShape2DEditor::_bind_methods() {
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index 10784f1129..fb7b2acb0f 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -75,7 +75,7 @@ protected:
public:
bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
- void forward_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_node);
CollisionShape2DEditor(EditorNode *p_editor);
@@ -89,7 +89,7 @@ class CollisionShape2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); }
- virtual void forward_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/cpu_particles_editor_plugin.cpp b/editor/plugins/cpu_particles_editor_plugin.cpp
index b32f927249..8d3ebc5052 100644
--- a/editor/plugins/cpu_particles_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_editor_plugin.cpp
@@ -1,4 +1,35 @@
+/*************************************************************************/
+/* cpu_particles_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "cpu_particles_editor_plugin.h"
+
#include "editor/plugins/spatial_editor_plugin.h"
void CPUParticlesEditor::_node_removed(Node *p_node) {
diff --git a/editor/plugins/cpu_particles_editor_plugin.h b/editor/plugins/cpu_particles_editor_plugin.h
index f47d17104d..16fb0bab0c 100644
--- a/editor/plugins/cpu_particles_editor_plugin.h
+++ b/editor/plugins/cpu_particles_editor_plugin.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* cpu_particles_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef CPU_PARTICLES_EDITOR_PLUGIN_H
#define CPU_PARTICLES_EDITOR_PLUGIN_H
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index f5bdf77973..ace3012c10 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -31,9 +31,9 @@
#include "curve_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
-#include "core_string_names.h"
-#include "os/input.h"
-#include "os/keyboard.h"
+#include "core/core_string_names.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
CurveEditor::CurveEditor() {
_selected_point = -1;
@@ -205,13 +205,13 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
curve.set_point_left_tangent(_selected_point, tangent);
// Note: if a tangent is set to linear, it shouldn't be linked to the other
- if (link && _selected_point != curve.get_point_count() - 1 && !curve.get_point_right_mode(_selected_point) != Curve::TANGENT_FREE)
+ if (link && _selected_point != (curve.get_point_count() - 1) && curve.get_point_right_mode(_selected_point) != Curve::TANGENT_LINEAR)
curve.set_point_right_tangent(_selected_point, tangent);
} else {
curve.set_point_right_tangent(_selected_point, tangent);
- if (link && _selected_point != 0 && !curve.get_point_left_mode(_selected_point) != Curve::TANGENT_FREE)
+ if (link && _selected_point != 0 && curve.get_point_left_mode(_selected_point) != Curve::TANGENT_LINEAR)
curve.set_point_left_tangent(_selected_point, tangent);
}
}
@@ -782,12 +782,13 @@ bool CurvePreviewGenerator::handles(const String &p_type) const {
return p_type == "Curve";
}
-Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from) {
+Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 p_size) const {
Ref<Curve> curve_ref = p_from;
ERR_FAIL_COND_V(curve_ref.is_null(), Ref<Texture>());
Curve &curve = **curve_ref;
+ // FIXME: Should be ported to use p_size as done in b2633a97
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
thumbnail_size *= EDSCALE;
Ref<Image> img_ref;
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index 255f359ed2..fa0b92e353 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -131,14 +131,14 @@ class CurveEditorPlugin : public EditorPlugin {
public:
CurveEditorPlugin(EditorNode *p_node);
- String get_name() const { return "Curve"; }
+ virtual String get_name() const { return "Curve"; }
};
class CurvePreviewGenerator : public EditorResourcePreviewGenerator {
GDCLASS(CurvePreviewGenerator, EditorResourcePreviewGenerator)
public:
- bool handles(const String &p_type) const;
- Ref<Texture> generate(const Ref<Resource> &p_from);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const Ref<Resource> &p_from, const Size2 p_size) const;
};
#endif // CURVE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 9acbceec92..7f83865777 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -30,12 +30,12 @@
#include "editor_preview_plugins.h"
+#include "core/io/file_access_memory.h"
+#include "core/io/resource_loader.h"
+#include "core/os/os.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-#include "io/file_access_memory.h"
-#include "io/resource_loader.h"
-#include "os/os.h"
#include "scene/resources/bit_mask.h"
#include "scene/resources/dynamic_font.h"
#include "scene/resources/material.h"
@@ -78,7 +78,11 @@ bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Texture");
}
-Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
+bool EditorTexturePreviewPlugin::should_generate_small_preview() const {
+ return true;
+}
+
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<Image> img;
Ref<AtlasTexture> atex = p_from;
@@ -100,8 +104,6 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
img = img->duplicate();
img->clear_mipmaps();
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
if (img->is_compressed()) {
if (img->decompress() != OK)
return Ref<Texture>();
@@ -109,22 +111,15 @@ Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) const {
img->convert(Image::FORMAT_RGBA8);
}
- int width, height;
- if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
- width = thumbnail_size;
- height = img->get_height() * thumbnail_size / img->get_width();
- } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
- height = thumbnail_size;
- width = img->get_width() * thumbnail_size / img->get_height();
- } else {
-
- width = img->get_width();
- height = img->get_height();
+ Vector2 new_size = img->get_size();
+ if (new_size.x > p_size.x) {
+ new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
}
+ if (new_size.y > p_size.y) {
+ new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+ }
+ img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
- img->resize(width, height);
post_process_preview(img);
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -143,7 +138,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const {
return p_type == "Image";
}
-Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<Image> img = p_from;
@@ -153,8 +148,6 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
img = img->duplicate();
img->clear_mipmaps();
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
if (img->is_compressed()) {
if (img->decompress() != OK)
return Ref<Image>();
@@ -162,22 +155,15 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
img->convert(Image::FORMAT_RGBA8);
}
- int width, height;
- if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
- width = thumbnail_size;
- height = img->get_height() * thumbnail_size / img->get_width();
- } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
- height = thumbnail_size;
- width = img->get_width() * thumbnail_size / img->get_height();
- } else {
-
- width = img->get_width();
- height = img->get_height();
+ Vector2 new_size = img->get_size();
+ if (new_size.x > p_size.x) {
+ new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+ }
+ if (new_size.y > p_size.y) {
+ new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
+ img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
- img->resize(width, height);
post_process_preview(img);
Ref<ImageTexture> ptex;
@@ -190,6 +176,9 @@ Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from) const {
EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
}
+bool EditorImagePreviewPlugin::should_generate_small_preview() const {
+ return true;
+}
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////
bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
@@ -197,7 +186,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "BitMap");
}
-Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<BitMap> bm = p_from;
@@ -227,8 +216,6 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
img.instance();
img->create(bm->get_size().width, bm->get_size().height, 0, Image::FORMAT_L8, data);
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
if (img->is_compressed()) {
if (img->decompress() != OK)
return Ref<Texture>();
@@ -236,22 +223,15 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
img->convert(Image::FORMAT_RGBA8);
}
- int width, height;
- if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
-
- width = thumbnail_size;
- height = img->get_height() * thumbnail_size / img->get_width();
- } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
-
- height = thumbnail_size;
- width = img->get_width() * thumbnail_size / img->get_height();
- } else {
-
- width = img->get_width();
- height = img->get_height();
+ Vector2 new_size = img->get_size();
+ if (new_size.x > p_size.x) {
+ new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+ }
+ if (new_size.y > p_size.y) {
+ new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
}
+ img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
- img->resize(width, height);
post_process_preview(img);
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -260,6 +240,10 @@ Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) const {
return ptex;
}
+bool EditorBitmapPreviewPlugin::should_generate_small_preview() const {
+ return true;
+}
+
EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() {
}
@@ -269,12 +253,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "PackedScene");
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
- return generate_from_path(p_from->get_path());
+ return generate_from_path(p_from->get_path(), p_size);
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) const {
+Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const {
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
@@ -323,7 +307,11 @@ bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Material"); //any material
}
-Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
+bool EditorMaterialPreviewPlugin::should_generate_small_preview() const {
+ return true;
+}
+
+Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<Material> material = p_from;
ERR_FAIL_COND_V(material.is_null(), Ref<Texture>());
@@ -346,10 +334,9 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) const {
ERR_FAIL_COND_V(!img.is_valid(), Ref<ImageTexture>());
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
img->convert(Image::FORMAT_RGBA8);
- img->resize(thumbnail_size, thumbnail_size);
+ int thumbnail_size = MAX(p_size.x, p_size.y);
+ img->resize(thumbnail_size, thumbnail_size, Image::INTERPOLATE_CUBIC);
post_process_preview(img);
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
ptex->create_from_image(img, 0);
@@ -490,7 +477,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Script");
}
-Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<Script> scr = p_from;
if (scr.is_null())
@@ -512,10 +499,9 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) const {
int line = 0;
int col = 0;
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
Ref<Image> img;
img.instance();
+ int thumbnail_size = MAX(p_size.x, p_size.y);
img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8);
Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color");
@@ -613,16 +599,15 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "AudioStream");
}
-Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<AudioStream> stream = p_from;
ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>());
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
PoolVector<uint8_t> img;
- int w = thumbnail_size;
- int h = thumbnail_size;
+
+ int w = p_size.x;
+ int h = p_size.y;
img.resize(w * h * 3);
PoolVector<uint8_t>::Write imgdata = img.write();
@@ -711,7 +696,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
}
-Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
Ref<Mesh> mesh = p_from;
ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>());
@@ -749,10 +734,17 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) const {
VS::get_singleton()->instance_set_base(mesh_instance, RID());
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
img->convert(Image::FORMAT_RGBA8);
- img->resize(thumbnail_size, thumbnail_size);
+
+ Vector2 new_size = img->get_size();
+ if (new_size.x > p_size.x) {
+ new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+ }
+ if (new_size.y > p_size.y) {
+ new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+ }
+ img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
+
post_process_preview(img);
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
@@ -825,15 +817,12 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "DynamicFontData");
}
-Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) const {
+Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const {
Ref<DynamicFontData> SampledFont;
SampledFont.instance();
SampledFont->set_font_path(p_path);
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size *= EDSCALE;
-
Ref<DynamicFont> sampled_font;
sampled_font.instance();
sampled_font->set_size(50);
@@ -864,7 +853,15 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c
ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>());
img->convert(Image::FORMAT_RGBA8);
- img->resize(thumbnail_size, thumbnail_size);
+
+ Vector2 new_size = img->get_size();
+ if (new_size.x > p_size.x) {
+ new_size = Vector2(p_size.x, new_size.y * p_size.x / new_size.x);
+ }
+ if (new_size.y > p_size.y) {
+ new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
+ }
+ img->resize(new_size.x, new_size.y, Image::INTERPOLATE_CUBIC);
post_process_preview(img);
@@ -874,9 +871,9 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path) c
return ptex;
}
-Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from) const {
+Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const {
- return generate_from_path(p_from->get_path());
+ return generate_from_path(p_from->get_path(), p_size);
}
EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 8bd7943383..ed5d2a3ecd 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -39,7 +39,8 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual bool should_generate_small_preview() const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorTexturePreviewPlugin();
};
@@ -48,7 +49,8 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorImagePreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual bool should_generate_small_preview() const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorImagePreviewPlugin();
};
@@ -57,7 +59,8 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator {
GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator)
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual bool should_generate_small_preview() const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorBitmapPreviewPlugin();
};
@@ -66,8 +69,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
- virtual Ref<Texture> generate_from_path(const String &p_path) const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const;
EditorPackedScenePreviewPlugin();
};
@@ -95,7 +98,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual bool should_generate_small_preview() const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorMaterialPreviewPlugin();
~EditorMaterialPreviewPlugin();
@@ -104,7 +108,7 @@ public:
class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorScriptPreviewPlugin();
};
@@ -112,7 +116,7 @@ public:
class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorAudioStreamPreviewPlugin();
};
@@ -139,7 +143,7 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
EditorMeshPreviewPlugin();
~EditorMeshPreviewPlugin();
@@ -162,8 +166,8 @@ protected:
public:
virtual bool handles(const String &p_type) const;
- virtual Ref<Texture> generate(const RES &p_from) const;
- virtual Ref<Texture> generate_from_path(const String &p_path) const;
+ virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const;
+ virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const;
EditorFontPreviewPlugin();
~EditorFontPreviewPlugin();
diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp
index 06da64b181..5fc5cad1ef 100644
--- a/editor/plugins/gi_probe_editor_plugin.cpp
+++ b/editor/plugins/gi_probe_editor_plugin.cpp
@@ -90,7 +90,7 @@ void GIProbeEditorPlugin::_bind_methods() {
GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
editor = p_node;
- bake = memnew(Button);
+ bake = memnew(ToolButton);
bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake GI Probe"));
bake->hide();
diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h
index 017e9bd743..1b3b63f227 100644
--- a/editor/plugins/gi_probe_editor_plugin.h
+++ b/editor/plugins/gi_probe_editor_plugin.h
@@ -42,7 +42,7 @@ class GIProbeEditorPlugin : public EditorPlugin {
GIProbe *gi_probe;
- Button *bake;
+ ToolButton *bake;
EditorNode *editor;
static EditorProgress *tmp_progress;
diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp
index f75fb0d109..8df40232b0 100644
--- a/editor/plugins/item_list_editor_plugin.cpp
+++ b/editor/plugins/item_list_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "item_list_editor_plugin.h"
-#include "io/resource_loader.h"
+#include "core/io/resource_loader.h"
bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) {
@@ -278,25 +278,27 @@ void ItemListEditor::_add_pressed() {
void ItemListEditor::_delete_pressed() {
- TreeItem *ti = tree->get_selected();
-
- if (!ti)
+ if (selected_idx == -1)
return;
- if (ti->get_parent() != tree->get_root())
+ String current_selected = (String)property_editor->get_selected_path();
+
+ if (current_selected == "")
return;
- int idx = ti->get_text(0).to_int();
+ // FIXME: Currently relying on selecting a *property* to derive what item to delete
+ // e.g. you select "1/enabled" to delete item 1.
+ // This should be fixed so that you can delete by selecting the item section header,
+ // or a delete button on that header.
- if (selected_idx == -1)
- return;
+ int idx = current_selected.get_slice("/", 0).to_int();
item_plugins[selected_idx]->erase(idx);
}
void ItemListEditor::_edit_items() {
- dialog->popup_centered(Vector2(300, 400));
+ dialog->popup_centered(Vector2(300, 400) * EDSCALE);
}
void ItemListEditor::edit(Node *p_item_list) {
@@ -315,10 +317,7 @@ void ItemListEditor::edit(Node *p_item_list) {
item_plugins[i]->set_object(p_item_list);
property_editor->edit(item_plugins[i]);
- if (has_icon(item_list->get_class(), "EditorIcons"))
- toolbar_button->set_icon(get_icon(item_list->get_class(), "EditorIcons"));
- else
- toolbar_button->set_icon(Ref<Texture>());
+ toolbar_button->set_icon(EditorNode::get_singleton()->get_object_icon(item_list, ""));
selected_idx = i;
return;
@@ -351,8 +350,6 @@ ItemListEditor::ItemListEditor() {
selected_idx = -1;
- add_child(memnew(VSeparator));
-
toolbar_button = memnew(ToolButton);
toolbar_button->set_text(TTR("Items"));
add_child(toolbar_button);
@@ -382,13 +379,9 @@ ItemListEditor::ItemListEditor() {
hbc->add_child(del_button);
del_button->connect("pressed", this, "_delete_button");
- property_editor = memnew(PropertyEditor);
- property_editor->hide_top_label();
- property_editor->set_subsection_selectable(true);
+ property_editor = memnew(EditorInspector);
vbc->add_child(property_editor);
property_editor->set_v_size_flags(SIZE_EXPAND_FILL);
-
- tree = property_editor->get_property_tree();
}
ItemListEditor::~ItemListEditor() {
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index d6a071b9b9..3dc3775f83 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -32,9 +32,9 @@
#define ITEM_LIST_EDITOR_PLUGIN_H
#include "canvas_item_editor_plugin.h"
+#include "editor/editor_inspector.h"
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-
#include "scene/gui/menu_button.h"
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
@@ -210,7 +210,7 @@ class ItemListEditor : public HBoxContainer {
ToolButton *toolbar_button;
AcceptDialog *dialog;
- PropertyEditor *property_editor;
+ EditorInspector *property_editor;
Tree *tree;
Button *add_button;
Button *del_button;
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index 3351e5918f..6a16cf0989 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -31,8 +31,8 @@
#include "light_occluder_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/os/file_access.h"
#include "editor/editor_settings.h"
-#include "os/file_access.h"
void LightOccluder2DEditor::_notification(int p_what) {
@@ -57,7 +57,7 @@ void LightOccluder2DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = NULL;
hide();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
}
@@ -88,8 +88,8 @@ void LightOccluder2DEditor::_wip_close(bool p_closed) {
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_closed", node->get_occluder_polygon()->is_closed());
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_closed", p_closed);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
wip.clear();
wip_active = false;
@@ -139,7 +139,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
wip.push_back(cpoint);
wip_active = true;
edited_point_pos = cpoint;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
edited_point = 1;
return true;
} else {
@@ -158,7 +158,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
wip.push_back(cpoint);
edited_point = wip.size();
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
//add wip point
@@ -183,8 +183,8 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
poly.push_back(cpoint);
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return true;
}
@@ -217,7 +217,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
edited_point = closest_idx + 1;
edited_point_pos = xform.affine_inverse().xform(closest_pos);
node->get_occluder_polygon()->set_polygon(Variant(poly));
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
} else {
@@ -244,7 +244,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
pre_move_edit = poly;
edited_point = closest_idx;
edited_point_pos = xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
}
@@ -259,8 +259,8 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
edited_point = -1;
@@ -290,8 +290,8 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
poly.remove(closest_idx);
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return true;
}
@@ -312,20 +312,18 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
cpoint = canvas_item_editor->snap_point(cpoint);
edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
}
return false;
}
-void LightOccluder2DEditor::forward_draw_over_viewport(Control *p_overlay) {
+void LightOccluder2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!node || !node->get_occluder_polygon().is_valid())
return;
- Control *vpc = canvas_item_editor->get_viewport_control();
-
Vector<Vector2> poly;
if (wip_active)
@@ -353,9 +351,9 @@ void LightOccluder2DEditor::forward_draw_over_viewport(Control *p_overlay) {
if (i == poly.size() - 1 && (!node->get_occluder_polygon()->is_closed() || wip_active)) {
} else {
- vpc->draw_line(point, next_point, col, 2);
+ p_overlay->draw_line(point, next_point, col, 2);
}
- vpc->draw_texture(handle, point - handle->get_size() * 0.5);
+ p_overlay->draw_texture(handle, point - handle->get_size() * 0.5);
}
}
@@ -371,7 +369,7 @@ void LightOccluder2DEditor::edit(Node *p_collision_polygon) {
wip.clear();
wip_active = false;
edited_point = -1;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
} else {
node = NULL;
}
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 39de8b1020..a1962892ee 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -83,7 +83,7 @@ protected:
public:
Vector2 snap_point(const Vector2 &p_point) const;
- void forward_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_draw_over_viewport(Control *p_overlay);
bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
LightOccluder2DEditor(EditorNode *p_editor);
@@ -98,7 +98,7 @@ class LightOccluder2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return light_occluder_editor->forward_gui_input(p_event); }
- virtual void forward_draw_over_viewport(Control *p_overlay) { return light_occluder_editor->forward_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return light_occluder_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "LightOccluder2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index f282d391ff..5e59a73061 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -28,397 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
-// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored.
-
#include "material_editor_plugin.h"
-#include "scene/3d/particles.h"
-
-#if 0
-
-#include "scene/main/viewport.h"
-
-void MaterialEditor::_gui_input(InputEvent p_event) {
-
-
-}
-
-void MaterialEditor::_notification(int p_what) {
-
- if (p_what==NOTIFICATION_PHYSICS_PROCESS) {
-
- }
-
-
- if (p_what==NOTIFICATION_READY) {
-
- //get_scene()->connect("node_removed",this,"_node_removed");
-
- if (first_enter) {
- //it's in propertyeditor so.. could be moved around
-
- light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons"));
- light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons"));
- light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons"));
- light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons"));
-
- sphere_switch->set_normal_texture(get_icon("MaterialPreviewSphereOff","EditorIcons"));
- sphere_switch->set_pressed_texture(get_icon("MaterialPreviewSphere","EditorIcons"));
- box_switch->set_normal_texture(get_icon("MaterialPreviewCubeOff","EditorIcons"));
- box_switch->set_pressed_texture(get_icon("MaterialPreviewCube","EditorIcons"));
-
- first_enter=false;
- }
-
- }
-
- if (p_what==NOTIFICATION_DRAW) {
-
-
- Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
- Size2 size = get_size();
-
- draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
-
- }
-}
-
-
-
-void MaterialEditor::edit(Ref<Material> p_material) {
-
- material=p_material;
-
- if (!material.is_null()) {
- sphere_mesh->surface_set_material(0,material);
- box_mesh->surface_set_material(0,material);
- } else {
-
- hide();
- }
-
-}
-
-
-void MaterialEditor::_button_pressed(Node* p_button) {
-
- if (p_button==light_1_switch) {
- light1->set_enabled(!light_1_switch->is_pressed());
- }
-
- if (p_button==light_2_switch) {
- light2->set_enabled(!light_2_switch->is_pressed());
- }
-
- if (p_button==box_switch) {
- box_instance->show();
- sphere_instance->hide();
- box_switch->set_pressed(true);
- sphere_switch->set_pressed(false);
- }
-
- if (p_button==sphere_switch) {
- box_instance->hide();
- sphere_instance->show();
- box_switch->set_pressed(false);
- sphere_switch->set_pressed(true);
- }
-
-}
-
-void MaterialEditor::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_gui_input"),&MaterialEditor::_gui_input);
- ClassDB::bind_method(D_METHOD("_button_pressed"),&MaterialEditor::_button_pressed);
-
-}
-
-MaterialEditor::MaterialEditor() {
-
- viewport = memnew( Viewport );
- Ref<World> world;
- world.instance();
- viewport->set_world(world); //use own world
- add_child(viewport);
- viewport->set_disable_input(true);
-
- camera = memnew( Camera );
- camera->set_transform(Transform(Matrix3(),Vector3(0,0,3)));
- camera->set_perspective(45,0.1,10);
- viewport->add_child(camera);
-
- light1 = memnew( DirectionalLight );
- light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
- viewport->add_child(light1);
-
- light2 = memnew( DirectionalLight );
- light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
- light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7));
- light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7));
- viewport->add_child(light2);
-
- sphere_instance = memnew( MeshInstance );
- viewport->add_child(sphere_instance);
-
- box_instance = memnew( MeshInstance );
- viewport->add_child(box_instance);
-
- Transform box_xform;
- box_xform.basis.rotate(Vector3(1,0,0),Math::deg2rad(25));
- box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0,1,0),Math::deg2rad(25));
- box_xform.basis.scale(Vector3(0.8,0.8,0.8));
- box_instance->set_transform(box_xform);
-
- {
-
- sphere_mesh.instance();
-
-
- int lats=32;
- int lons=32;
- float radius=1.0;
-
- PoolVector<Vector3> vertices;
- PoolVector<Vector3> normals;
- PoolVector<Vector2> uvs;
- PoolVector<float> tangents;
- Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5);
-
- for(int i = 1; i <= lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
-
- double lat1 = Math_PI * (-0.5 + (double) i / lats);
- double z1 = Math::sin(lat1);
- double zr1 = Math::cos(lat1);
-
- for(int j = lons; j >= 1; j--) {
-
- double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
- double x0 = Math::cos(lng0);
- double y0 = Math::sin(lng0);
-
- double lng1 = 2 * Math_PI * (double) (j) / lons;
- double x1 = Math::cos(lng1);
- double y1 = Math::sin(lng1);
-
-
- Vector3 v[4]={
- Vector3(x1 * zr0, z0, y1 *zr0),
- Vector3(x1 * zr1, z1, y1 *zr1),
- Vector3(x0 * zr1, z1, y0 *zr1),
- Vector3(x0 * zr0, z0, y0 *zr0)
- };
-
-#define ADD_POINT(m_idx) \
- normals.push_back(v[m_idx]); \
- vertices.push_back(v[m_idx] * radius); \
- { \
- Vector2 uv(Math::atan2(v[m_idx].x, v[m_idx].z), Math::atan2(-v[m_idx].y, v[m_idx].z)); \
- uv /= Math_PI; \
- uv *= 4.0; \
- uv = uv * 0.5 + Vector2(0.5, 0.5); \
- uvs.push_back(uv); \
- } \
- { \
- Vector3 t = tt.xform(v[m_idx]); \
- tangents.push_back(t.x); \
- tangents.push_back(t.y); \
- tangents.push_back(t.z); \
- tangents.push_back(1.0); \
- }
-
-
-
- ADD_POINT(0);
- ADD_POINT(1);
- ADD_POINT(2);
-
- ADD_POINT(2);
- ADD_POINT(3);
- ADD_POINT(0);
- }
- }
-
- Array arr;
- arr.resize(VS::ARRAY_MAX);
- arr[VS::ARRAY_VERTEX]=vertices;
- arr[VS::ARRAY_NORMAL]=normals;
- arr[VS::ARRAY_TANGENT]=tangents;
- arr[VS::ARRAY_TEX_UV]=uvs;
-
- sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr);
-
- sphere_instance->set_mesh(sphere_mesh);
-
- }
- {
-
-
- box_mesh.instance();
-
- PoolVector<Vector3> vertices;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector3> uvs;
-
- int vtx_idx=0;
-#define ADD_VTX(m_idx) \
- ; \
- vertices.push_back(face_points[m_idx]); \
- normals.push_back(normal_points[m_idx]); \
- tangents.push_back(normal_points[m_idx][1]); \
- tangents.push_back(normal_points[m_idx][2]); \
- tangents.push_back(normal_points[m_idx][0]); \
- tangents.push_back(1.0); \
- uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0)); \
- vtx_idx++;\
-
- for (int i=0;i<6;i++) {
-
-
- Vector3 face_points[4];
- Vector3 normal_points[4];
- float uv_points[8]={0,0,0,1,1,1,1,0};
-
- for (int j=0;j<4;j++) {
-
- float v[3];
- v[0]=1.0;
- v[1]=1-2*((j>>1)&1);
- v[2]=v[1]*(1-2*(j&1));
-
- for (int k=0;k<3;k++) {
-
- if (i<3)
- face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
- else
- face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
- }
- normal_points[j]=Vector3();
- normal_points[j][i%3]=(i>=3?-1:1);
- }
-
- //tri 1
- ADD_VTX(0);
- ADD_VTX(1);
- ADD_VTX(2);
- //tri 2
- ADD_VTX(2);
- ADD_VTX(3);
- ADD_VTX(0);
-
- }
-
-
-
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[VisualServer::ARRAY_NORMAL]= normals ;
- d[VisualServer::ARRAY_TANGENT]= tangents ;
- d[VisualServer::ARRAY_TEX_UV]= uvs ;
- d[VisualServer::ARRAY_VERTEX]= vertices ;
-
- PoolVector<int> indices;
- indices.resize(vertices.size());
- for(int i=0;i<vertices.size();i++)
- indices.set(i,i);
- d[VisualServer::ARRAY_INDEX]=indices;
-
- box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d);
- box_instance->set_mesh(box_mesh);
- box_instance->hide();
-
-
-
- }
-
- set_custom_minimum_size(Size2(1,150)*EDSCALE);
-
- HBoxContainer *hb = memnew( HBoxContainer );
- add_child(hb);
- hb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 2);
-
- VBoxContainer *vb_shape = memnew( VBoxContainer );
- hb->add_child(vb_shape);
-
- sphere_switch = memnew( TextureButton );
- sphere_switch->set_toggle_mode(true);
- sphere_switch->set_pressed(true);
- vb_shape->add_child(sphere_switch);
- sphere_switch->connect("pressed",this,"_button_pressed",varray(sphere_switch));
-
- box_switch = memnew( TextureButton );
- box_switch->set_toggle_mode(true);
- box_switch->set_pressed(false);
- vb_shape->add_child(box_switch);
- box_switch->connect("pressed",this,"_button_pressed",varray(box_switch));
-
- hb->add_spacer();
-
- VBoxContainer *vb_light = memnew( VBoxContainer );
- hb->add_child(vb_light);
-
- light_1_switch = memnew( TextureButton );
- light_1_switch->set_toggle_mode(true);
- vb_light->add_child(light_1_switch);
- light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch));
-
- light_2_switch = memnew( TextureButton );
- light_2_switch->set_toggle_mode(true);
- vb_light->add_child(light_2_switch);
- light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch));
-
- first_enter=true;
-
-}
-
-
-void MaterialEditorPlugin::edit(Object *p_object) {
-
- Material * s = Object::cast_to<Material>(p_object);
- if (!s)
- return;
-
- material_editor->edit(Ref<Material>(s));
-}
-
-bool MaterialEditorPlugin::handles(Object *p_object) const {
-
- return p_object->is_type("Material");
-}
-
-void MaterialEditorPlugin::make_visible(bool p_visible) {
-
- if (p_visible) {
- material_editor->show();
- //material_editor->set_process(true);
- } else {
-
- material_editor->hide();
- //material_editor->set_process(false);
- }
-
-}
-
-MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
-
- editor=p_node;
- material_editor = memnew( MaterialEditor );
- add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,material_editor);
- material_editor->hide();
-
-
-
-}
-
-
-MaterialEditorPlugin::~MaterialEditorPlugin()
-{
-}
-#endif
+#include "scene/resources/particles_material.h"
String SpatialMaterialConversionPlugin::converts_to() const {
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 31a927d83f..c06d95e700 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -32,77 +32,6 @@
#define MATERIAL_EDITOR_PLUGIN_H
#include "editor/property_editor.h"
-// FIXME: Disabled as (according to reduz) users were complaining that it gets in the way
-// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored.
-#if 0
-
-#include "editor/editor_node.h"
-#include "editor/editor_plugin.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/light.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/resources/material.h"
-
-class MaterialEditor : public Control {
-
- GDCLASS(MaterialEditor, Control);
-
-
- Viewport *viewport;
- MeshInstance *sphere_instance;
- MeshInstance *box_instance;
- DirectionalLight *light1;
- DirectionalLight *light2;
- Camera *camera;
-
- Ref<Mesh> sphere_mesh;
- Ref<Mesh> box_mesh;
-
- TextureButton *sphere_switch;
- TextureButton *box_switch;
-
- TextureButton *light_1_switch;
- TextureButton *light_2_switch;
-
-
- Ref<Material> material;
-
-
- void _button_pressed(Node* p_button);
- bool first_enter;
-
-protected:
- void _notification(int p_what);
- void _gui_input(InputEvent p_event);
- static void _bind_methods();
-public:
-
- void edit(Ref<Material> p_material);
- MaterialEditor();
-};
-
-
-class MaterialEditorPlugin : public EditorPlugin {
-
- GDCLASS( MaterialEditorPlugin, EditorPlugin );
-
- MaterialEditor *material_editor;
- EditorNode *editor;
-
-public:
-
- virtual String get_name() const { return "Material"; }
- bool has_main_screen() const { return false; }
- virtual void edit(Object *p_node);
- virtual bool handles(Object *p_node) const;
- virtual void make_visible(bool p_visible);
-
- MaterialEditorPlugin(EditorNode *p_node);
- ~MaterialEditorPlugin();
-
-};
-
-#endif
class SpatialMaterialConversionPlugin : public EditorResourceConversionPlugin {
GDCLASS(SpatialMaterialConversionPlugin, EditorResourceConversionPlugin)
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 7b7e23531a..73a216e96f 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -65,14 +65,6 @@ void MeshEditor::_notification(int p_what) {
first_enter = false;
}
}
-
- if (p_what == NOTIFICATION_DRAW) {
-
- Ref<Texture> checkerboard = get_icon("Checkerboard", "EditorIcons");
- Size2 size = get_size();
-
- //draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
- }
}
void MeshEditor::_update_rotation() {
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index ae5d510502..ab94258c44 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -31,9 +31,10 @@
#include "particles_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
-#include "io/image_loader.h"
-#include "scene/3d/particles.h"
+#include "core/io/image_loader.h"
+#include "scene/2d/cpu_particles_2d.h"
#include "scene/gui/separator.h"
+#include "scene/resources/particles_material.h"
void Particles2DEditorPlugin::edit(Object *p_object) {
@@ -82,6 +83,25 @@ void Particles2DEditorPlugin::_menu_callback(int p_idx) {
emission_mask->popup_centered_minsize();
} break;
+ case MENU_OPTION_CONVERT_TO_CPU_PARTICLES: {
+
+ UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
+
+ CPUParticles2D *cpu_particles = memnew(CPUParticles2D);
+ cpu_particles->convert_from_particles(particles);
+ cpu_particles->set_name(particles->get_name());
+ cpu_particles->set_transform(particles->get_transform());
+ cpu_particles->set_visible(particles->is_visible());
+ cpu_particles->set_pause_mode(particles->get_pause_mode());
+
+ undo_redo->create_action("Replace Particles by CPUParticles");
+ undo_redo->add_do_method(particles, "replace_by", cpu_particles);
+ undo_redo->add_undo_method(cpu_particles, "replace_by", particles);
+ undo_redo->add_do_reference(cpu_particles);
+ undo_redo->add_undo_reference(particles);
+ undo_redo->commit_action();
+
+ } break;
}
}
@@ -355,6 +375,8 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) {
menu->get_popup()->add_separator();
menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
// menu->get_popup()->add_item(TTR("Clear Emission Mask"), MENU_CLEAR_EMISSION_MASK);
+ menu->get_popup()->add_separator();
+ menu->get_popup()->add_item(TTR("Convert to CPUParticles"), MENU_OPTION_CONVERT_TO_CPU_PARTICLES);
menu->set_text(TTR("Particles"));
toolbar->add_child(menu);
diff --git a/editor/plugins/particles_2d_editor_plugin.h b/editor/plugins/particles_2d_editor_plugin.h
index 2b6123141b..eaa96d84e9 100644
--- a/editor/plugins/particles_2d_editor_plugin.h
+++ b/editor/plugins/particles_2d_editor_plugin.h
@@ -34,7 +34,6 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/collision_polygon_2d.h"
-
#include "scene/2d/particles_2d.h"
#include "scene/gui/box_container.h"
#include "scene/gui/file_dialog.h"
@@ -47,7 +46,8 @@ class Particles2DEditorPlugin : public EditorPlugin {
MENU_GENERATE_VISIBILITY_RECT,
MENU_LOAD_EMISSION_MASK,
- MENU_CLEAR_EMISSION_MASK
+ MENU_CLEAR_EMISSION_MASK,
+ MENU_OPTION_CONVERT_TO_CPU_PARTICLES
};
enum EmissionMode {
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index 3c381158a4..f2dfae7a9f 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -29,9 +29,12 @@
/*************************************************************************/
#include "particles_editor_plugin.h"
+
+#include "core/io/resource_loader.h"
#include "editor/plugins/spatial_editor_plugin.h"
-#include "io/resource_loader.h"
#include "scene/3d/cpu_particles.h"
+#include "scene/resources/particles_material.h"
+
bool ParticlesEditorBase::_generate(PoolVector<Vector3> &points, PoolVector<Vector3> &normals) {
bool use_normals = emission_fill->get_selected() == 1;
@@ -450,6 +453,7 @@ void ParticlesEditor::_bind_methods() {
ParticlesEditor::ParticlesEditor() {
+ node = NULL;
particles_editor_hb = memnew(HBoxContainer);
SpatialEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
options = memnew(MenuButton);
diff --git a/editor/plugins/particles_editor_plugin.h b/editor/plugins/particles_editor_plugin.h
index 622ce6e8a9..830d30d98f 100644
--- a/editor/plugins/particles_editor_plugin.h
+++ b/editor/plugins/particles_editor_plugin.h
@@ -43,6 +43,7 @@
class ParticlesEditorBase : public Control {
GDCLASS(ParticlesEditorBase, Control)
+
protected:
Spatial *base_node;
Panel *panel;
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 33e182faef..c67c96798a 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -31,9 +31,9 @@
#include "path_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/os/file_access.h"
+#include "core/os/keyboard.h"
#include "editor/editor_settings.h"
-#include "os/file_access.h"
-#include "os/keyboard.h"
void Path2DEditor::_notification(int p_what) {
@@ -130,8 +130,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Remove Point from Curve"));
undo_redo->add_do_method(curve.ptr(), "remove_point", i);
undo_redo->add_undo_method(curve.ptr(), "add_point", curve->get_point_position(i), curve->get_point_in(i), curve->get_point_out(i), i);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return true;
} else if (dist_to_p_out < grab_threshold) {
@@ -139,8 +139,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Remove Out-Control from Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_out", i, Vector2());
undo_redo->add_undo_method(curve.ptr(), "set_point_out", i, curve->get_point_out(i));
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return true;
} else if (dist_to_p_in < grab_threshold) {
@@ -148,8 +148,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Remove In-Control from Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_in", i, Vector2());
undo_redo->add_undo_method(curve.ptr(), "set_point_in", i, curve->get_point_in(i));
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return true;
}
@@ -165,8 +165,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Add Point to Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", cpoint);
undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count());
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
action = ACTION_MOVING_POINT;
@@ -174,7 +174,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
moving_from = curve->get_point_position(action_point);
moving_screen_from = gpoint;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
@@ -196,8 +196,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Move Point in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint);
undo_redo->add_undo_method(curve.ptr(), "set_point_position", action_point, moving_from);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
} break;
@@ -212,8 +212,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length));
undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length));
}
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
} break;
@@ -228,8 +228,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length));
undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_in_length));
}
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
} break;
@@ -280,7 +280,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} break;
}
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
return true;
}
}
@@ -288,7 +288,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void Path2DEditor::forward_draw_over_viewport(Control *p_overlay) {
+void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!node)
return;
@@ -331,7 +331,7 @@ void Path2DEditor::_node_visibility_changed() {
if (!node)
return;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->update_viewport();
}
void Path2DEditor::edit(Node *p_path2d) {
@@ -406,8 +406,8 @@ void Path2DEditor::_mode_selected(int p_mode) {
undo_redo->create_action(TTR("Remove Point from Curve"));
undo_redo->add_do_method(node->get_curve().ptr(), "add_point", begin);
undo_redo->add_undo_method(node->get_curve().ptr(), "remove_point", node->get_curve()->get_point_count());
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_do_method(canvas_item_editor, "update_viewport");
+ undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
return;
}
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 1e3955f84f..3a78657746 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -107,7 +107,7 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
- void forward_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_path2d);
Path2DEditor(EditorNode *p_editor);
};
@@ -121,7 +121,7 @@ class Path2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
- virtual void forward_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "Path2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 618c70d1a1..df6c40ed02 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "path_editor_plugin.h"
-#include "os/keyboard.h"
+#include "core/os/keyboard.h"
#include "scene/resources/curve.h"
#include "spatial_editor_plugin.h"
@@ -57,7 +57,7 @@ String PathSpatialGizmo::get_handle_name(int p_idx) const {
return n;
}
-Variant PathSpatialGizmo::get_handle_value(int p_idx) const {
+Variant PathSpatialGizmo::get_handle_value(int p_idx) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
@@ -215,8 +215,8 @@ void PathSpatialGizmo::redraw() {
clear();
- Ref<SpatialMaterial> path_material = gizmo_plugin->get_material("path_material");
- Ref<SpatialMaterial> path_thin_material = gizmo_plugin->get_material("path_thin_material");
+ Ref<SpatialMaterial> path_material = gizmo_plugin->get_material("path_material", this);
+ Ref<SpatialMaterial> path_thin_material = gizmo_plugin->get_material("path_thin_material", this);
Ref<SpatialMaterial> handles_material = gizmo_plugin->get_material("handles");
Ref<Curve3D> c = path->get_curve();
@@ -641,24 +641,8 @@ String PathSpatialGizmoPlugin::get_name() const {
PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() {
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
-
- Ref<SpatialMaterial> path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
- path_color.a = 0.8;
- path_material->set_albedo(path_color);
- path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- path_material->set_line_width(3);
- path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-
- Ref<SpatialMaterial> path_thin_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ create_material("path_material", path_color);
path_color.a = 0.4;
- path_thin_material->set_albedo(path_color);
- path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
- path_thin_material->set_line_width(1);
- path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
- path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-
- add_material("path_material", path_material);
- add_material("path_thin_material", path_thin_material);
+ create_material("path_thin_material", path_color);
create_handle_material("handles");
}
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 61f309e794..c77b2a41cc 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -45,7 +45,7 @@ class PathSpatialGizmo : public EditorSpatialGizmo {
public:
virtual String get_handle_name(int p_idx) const;
- virtual Variant get_handle_value(int p_idx) const;
+ virtual Variant get_handle_value(int p_idx);
virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
diff --git a/editor/plugins/physical_bone_plugin.cpp b/editor/plugins/physical_bone_plugin.cpp
index 42f1adcadf..6341d7f2ef 100644
--- a/editor/plugins/physical_bone_plugin.cpp
+++ b/editor/plugins/physical_bone_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -69,15 +69,7 @@ PhysicalBoneEditor::PhysicalBoneEditor(EditorNode *p_editor) :
hide();
}
-PhysicalBoneEditor::~PhysicalBoneEditor() {
- // TODO the spatial_editor_hb should be removed from SpatialEditor, but in this moment it's not possible
- for (int i = spatial_editor_hb->get_child_count() - 1; 0 <= i; --i) {
- Node *n = spatial_editor_hb->get_child(i);
- spatial_editor_hb->remove_child(n);
- memdelete(n);
- }
- memdelete(spatial_editor_hb);
-}
+PhysicalBoneEditor::~PhysicalBoneEditor() {}
void PhysicalBoneEditor::set_selected(PhysicalBone *p_pb) {
@@ -98,19 +90,17 @@ void PhysicalBoneEditor::show() {
PhysicalBonePlugin::PhysicalBonePlugin(EditorNode *p_editor) :
editor(p_editor),
- selected(NULL) {
-
- physical_bone_editor = memnew(PhysicalBoneEditor(editor));
-}
+ selected(NULL),
+ physical_bone_editor(editor) {}
void PhysicalBonePlugin::make_visible(bool p_visible) {
if (p_visible) {
- physical_bone_editor->show();
+ physical_bone_editor.show();
} else {
- physical_bone_editor->hide();
- physical_bone_editor->set_selected(NULL);
+ physical_bone_editor.hide();
+ physical_bone_editor.set_selected(NULL);
selected = NULL;
}
}
@@ -119,5 +109,5 @@ void PhysicalBonePlugin::edit(Object *p_node) {
selected = static_cast<PhysicalBone *>(p_node); // Trust it
ERR_FAIL_COND(!selected);
- physical_bone_editor->set_selected(selected);
+ physical_bone_editor.set_selected(selected);
}
diff --git a/editor/plugins/physical_bone_plugin.h b/editor/plugins/physical_bone_plugin.h
index 9e7a50307a..e1f8c9ec47 100644
--- a/editor/plugins/physical_bone_plugin.h
+++ b/editor/plugins/physical_bone_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,7 +64,7 @@ class PhysicalBonePlugin : public EditorPlugin {
EditorNode *editor;
PhysicalBone *selected;
- PhysicalBoneEditor *physical_bone_editor;
+ PhysicalBoneEditor physical_bone_editor;
public:
virtual String get_name() const { return "PhysicalBone"; }
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index a437cd5362..f937744d45 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -31,10 +31,10 @@
#include "polygon_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/os/file_access.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "editor/editor_settings.h"
-#include "os/file_access.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/2d/skeleton_2d.h"
Node2D *Polygon2DEditor::_get_node() const {
@@ -767,6 +767,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
node->set_polygon(uv_new);
}
} break;
+ default: {}
}
if (bone_painting) {
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index c6e8ec1a2b..bd4a35c9d8 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -30,9 +30,9 @@
#include "resource_preloader_editor_plugin.h"
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
#include "editor/editor_settings.h"
-#include "io/resource_loader.h"
-#include "project_settings.h"
void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
}
@@ -44,7 +44,6 @@ void ResourcePreloaderEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
load->set_icon(get_icon("Folder", "EditorIcons"));
- _delete->set_icon(get_icon("Remove", "EditorIcons"));
}
if (p_what == NOTIFICATION_READY) {
@@ -138,15 +137,11 @@ void ResourcePreloaderEditor::_item_edited() {
}
}
-void ResourcePreloaderEditor::_delete_confirm_pressed() {
+void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) {
- if (!tree->get_selected())
- return;
-
- String to_remove = tree->get_selected()->get_text(0);
undo_redo->create_action(TTR("Delete Resource"));
- undo_redo->add_do_method(preloader, "remove_resource", to_remove);
- undo_redo->add_undo_method(preloader, "add_resource", to_remove, preloader->get_resource(to_remove));
+ undo_redo->add_do_method(preloader, "remove_resource", p_to_remove);
+ undo_redo->add_undo_method(preloader, "add_resource", p_to_remove, preloader->get_resource(p_to_remove));
undo_redo->add_do_method(this, "_update_library");
undo_redo->add_undo_method(this, "_update_library");
undo_redo->commit_action();
@@ -184,21 +179,6 @@ void ResourcePreloaderEditor::_paste_pressed() {
undo_redo->commit_action();
}
-void ResourcePreloaderEditor::_delete_pressed() {
-
- if (!tree->get_selected())
- return;
-
- _delete_confirm_pressed(); //it has undo.. why bother with a dialog..
- /*
- dialog->set_title("Confirm...");
- dialog->set_text("Remove Resource '"+tree->get_selected()->get_text(0)+"' ?");
- //dialog->get_cancel()->set_text("Cancel");
- //dialog->get_ok()->show();
- dialog->get_ok()->set_text("Remove");
- dialog->popup_centered(Size2(300,60));*/
-}
-
void ResourcePreloaderEditor::_update_library() {
tree->clear();
@@ -228,18 +208,20 @@ void ResourcePreloaderEditor::_update_library() {
ERR_CONTINUE(r.is_null());
- ti->set_tooltip(0, r->get_path());
+ String type = r->get_class();
+ ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(type, "Object"));
+ ti->set_tooltip(0, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + type);
+
ti->set_text(1, r->get_path());
- ti->add_button(1, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
- ti->set_tooltip(1, TTR("Instance:") + " " + r->get_path() + "\n" + TTR("Type:") + " " + r->get_class());
ti->set_editable(1, false);
ti->set_selectable(1, false);
- String type = r->get_class();
- ti->set_text(2, type);
- ti->set_selectable(2, false);
- if (has_icon(type, "EditorIcons"))
- ti->set_icon(2, get_icon(type, "EditorIcons"));
+ if (type == "PackedScene") {
+ ti->add_button(1, get_icon("InstanceOptions", "EditorIcons"), BUTTON_OPEN_SCENE, false, TTR("Open in Editor"));
+ } else {
+ ti->add_button(1, get_icon("Load", "EditorIcons"), BUTTON_EDIT_RESOURCE, false, TTR("Open in Editor"));
+ }
+ ti->add_button(1, get_icon("Remove", "EditorIcons"), BUTTON_REMOVE, false, TTR("Remove"));
}
//player->add_resource("default",resource);
@@ -250,10 +232,16 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column,
TreeItem *item = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!item);
- String rpath = item->get_text(p_column);
-
- if (p_id == BUTTON_SUBSCENE) {
+ if (p_id == BUTTON_OPEN_SCENE) {
+ String rpath = item->get_text(p_column);
EditorInterface::get_singleton()->open_scene_from_path(rpath);
+
+ } else if (p_id == BUTTON_EDIT_RESOURCE) {
+ RES r = preloader->get_resource(item->get_text(0));
+ EditorInterface::get_singleton()->edit_resource(r);
+
+ } else if (p_id == BUTTON_REMOVE) {
+ _remove_resource(item->get_text(0));
}
}
@@ -366,12 +354,11 @@ void ResourcePreloaderEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ResourcePreloaderEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_load_pressed"), &ResourcePreloaderEditor::_load_pressed);
ClassDB::bind_method(D_METHOD("_item_edited"), &ResourcePreloaderEditor::_item_edited);
- ClassDB::bind_method(D_METHOD("_delete_pressed"), &ResourcePreloaderEditor::_delete_pressed);
ClassDB::bind_method(D_METHOD("_paste_pressed"), &ResourcePreloaderEditor::_paste_pressed);
- ClassDB::bind_method(D_METHOD("_delete_confirm_pressed"), &ResourcePreloaderEditor::_delete_confirm_pressed);
ClassDB::bind_method(D_METHOD("_files_load_request"), &ResourcePreloaderEditor::_files_load_request);
ClassDB::bind_method(D_METHOD("_update_library"), &ResourcePreloaderEditor::_update_library);
ClassDB::bind_method(D_METHOD("_cell_button_pressed"), &ResourcePreloaderEditor::_cell_button_pressed);
+ ClassDB::bind_method(D_METHOD("_remove_resource", "to_remove"), &ResourcePreloaderEditor::_remove_resource);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &ResourcePreloaderEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &ResourcePreloaderEditor::can_drop_data_fw);
@@ -392,9 +379,6 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
load->set_tooltip(TTR("Load Resource"));
hbc->add_child(load);
- _delete = memnew(Button);
- hbc->add_child(_delete);
-
paste = memnew(Button);
paste->set_text(TTR("Paste"));
hbc->add_child(paste);
@@ -404,13 +388,11 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
tree = memnew(Tree);
tree->connect("button_pressed", this, "_cell_button_pressed");
- tree->set_columns(3);
- tree->set_column_min_width(0, 3);
- tree->set_column_min_width(1, 1);
- tree->set_column_min_width(2, 1);
+ tree->set_columns(2);
+ tree->set_column_min_width(0, 2);
+ tree->set_column_min_width(1, 3);
tree->set_column_expand(0, true);
tree->set_column_expand(1, true);
- tree->set_column_expand(2, true);
tree->set_v_size_flags(SIZE_EXPAND_FILL);
tree->set_drag_forwarding(this);
@@ -420,10 +402,8 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
add_child(dialog);
load->connect("pressed", this, "_load_pressed");
- _delete->connect("pressed", this, "_delete_pressed");
paste->connect("pressed", this, "_paste_pressed");
file->connect("files_selected", this, "_files_load_request");
- //dialog->connect("confirmed", this,"_delete_confirm_pressed");
tree->connect("item_edited", this, "_item_edited");
loading_scene = false;
}
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index e737157785..0a8238ce18 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -43,11 +43,12 @@ class ResourcePreloaderEditor : public PanelContainer {
GDCLASS(ResourcePreloaderEditor, PanelContainer);
enum {
- BUTTON_SUBSCENE = 0,
+ BUTTON_OPEN_SCENE,
+ BUTTON_EDIT_RESOURCE,
+ BUTTON_REMOVE
};
Button *load;
- Button *_delete;
Button *paste;
Tree *tree;
bool loading_scene;
@@ -62,8 +63,7 @@ class ResourcePreloaderEditor : public PanelContainer {
void _load_scene_pressed();
void _files_load_request(const Vector<String> &p_paths);
void _paste_pressed();
- void _delete_pressed();
- void _delete_confirm_pressed();
+ void _remove_resource(const String &p_to_remove);
void _update_library();
void _cell_button_pressed(Object *p_item, int p_column, int p_id);
void _item_edited();
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index af3c09afc5..b3adf19a64 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* root_motion_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "root_motion_editor_plugin.h"
#include "editor/editor_node.h"
#include "scene/main/viewport.h"
@@ -79,11 +109,7 @@ void EditorPropertyRootMotion::_node_assign() {
if (base->has_node(accum)) {
Node *node = base->get_node(accum);
- if (has_icon(node->get_class(), "EditorIcons")) {
- ti->set_icon(0, get_icon(node->get_class(), "EditorIcons"));
- } else {
- ti->set_icon(0, get_icon("Node", "EditorIcons"));
- }
+ ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node"));
}
} else {
@@ -96,7 +122,7 @@ void EditorPropertyRootMotion::_node_assign() {
node = base->get_node(accum);
}
if (!node)
- continue; //no node, cant edit
+ continue; //no node, can't edit
if (path.get_subname_count()) {
@@ -205,14 +231,7 @@ void EditorPropertyRootMotion::update_property() {
ERR_FAIL_COND(!target_node);
assign->set_text(target_node->get_name());
-
- Ref<Texture> icon;
- if (has_icon(target_node->get_class(), "EditorIcons"))
- icon = get_icon(target_node->get_class(), "EditorIcons");
- else
- icon = get_icon("Node", "EditorIcons");
-
- assign->set_icon(icon);
+ assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node"));
}
void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) {
@@ -284,7 +303,7 @@ bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::
return true;
}
- return false; //can be overriden, although it will most likely be last anyway
+ return false; //can be overridden, although it will most likely be last anyway
}
void EditorInspectorRootMotionPlugin::parse_end() {
diff --git a/editor/plugins/root_motion_editor_plugin.h b/editor/plugins/root_motion_editor_plugin.h
index 84af47872f..2b5492350b 100644
--- a/editor/plugins/root_motion_editor_plugin.h
+++ b/editor/plugins/root_motion_editor_plugin.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* root_motion_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef ROOT_MOTION_EDITOR_PLUGIN_H
#define ROOT_MOTION_EDITOR_PLUGIN_H
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index fa034c97c0..085660b79e 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -59,25 +59,10 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
}
-static bool _can_open_in_editor(Script *p_script) {
-
+static bool _is_built_in_script(Script *p_script) {
String path = p_script->get_path();
- if (path.find("::") != -1) {
- //refuse handling this if it can't be edited
-
- bool valid = false;
- for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_edited_scene_count(); i++) {
- if (path.begins_with(EditorNode::get_singleton()->get_editor_data().get_scene_path(i))) {
- valid = true;
- break;
- }
- }
-
- return valid;
- }
-
- return true;
+ return path.find("::") != -1;
}
class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache {
@@ -111,7 +96,7 @@ public:
}
}
- RES get_cached_resource(const String &p_path) {
+ virtual RES get_cached_resource(const String &p_path) {
Map<String, Cache>::Element *E = cached.find(p_path);
if (!E) {
@@ -149,9 +134,11 @@ public:
max_cache_size = 128;
max_time_cache = 5 * 60 * 1000; //minutes, five
}
+
+ virtual ~EditorScriptCodeCompletionCache() {}
};
-void ScriptEditorQuickOpen::popup(const Vector<String> &p_functions, bool p_dontclear) {
+void ScriptEditorQuickOpen::popup_dialog(const Vector<String> &p_functions, bool p_dontclear) {
popup_centered_ratio(0.6);
if (p_dontclear)
@@ -223,6 +210,9 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
search_box->set_right_icon(get_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
} break;
+ case NOTIFICATION_EXIT_TREE: {
+ disconnect("confirmed", this, "_confirmed");
+ } break;
}
}
@@ -503,7 +493,14 @@ void ScriptEditor::_open_recent_script(int p_idx) {
edit(text_file, true);
return;
}
- // if it's a path then its most likely a deleted file not help
+ // if it's a path then it's most likely a deleted file not help
+ } else if (path.find("::") != -1) {
+ // built-in script
+ Ref<Script> script = ResourceLoader::load(path);
+ if (script.is_valid()) {
+ edit(script, true);
+ return;
+ }
} else if (!path.is_resource_file()) {
_help_class_open(path);
return;
@@ -805,7 +802,7 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
if (se) {
RES edited_res = se->get_edited_resource();
- if (edited_res.is_valid() && p_for_script != edited_res)
+ if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res)
continue;
if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1)
@@ -862,7 +859,7 @@ void ScriptEditor::_file_dialog_action(String p_file) {
if (extensions.find(p_file.get_extension())) {
Ref<Script> scr = ResourceLoader::load(p_file);
if (!scr.is_valid()) {
- editor->show_warning(TTR("Error could not load file."), TTR("Error!"));
+ editor->show_warning(TTR("Error: could not load file."), TTR("Error!"));
file_dialog_option = -1;
return;
}
@@ -939,7 +936,7 @@ void ScriptEditor::_menu_option(int p_option) {
switch (p_option) {
case FILE_NEW: {
- script_create_dialog->config("Node", ".gd");
+ script_create_dialog->config("Node", "new_script");
script_create_dialog->popup_centered(Size2(300, 300) * EDSCALE);
} break;
case FILE_NEW_TEXTFILE: {
@@ -976,15 +973,15 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case SEARCH_HELP: {
- help_search_dialog->popup();
+ help_search_dialog->popup_dialog();
} break;
case SEARCH_CLASSES: {
- help_index->popup();
+ help_index->popup_dialog();
} break;
case SEARCH_WEBSITE: {
- OS::get_singleton()->shell_open("http://docs.godotengine.org/");
+ OS::get_singleton()->shell_open("https://docs.godotengine.org/");
} break;
case WINDOW_NEXT: {
@@ -1212,7 +1209,7 @@ void ScriptEditor::_menu_option(int p_option) {
case SEARCH_CLASSES: {
- help_index->popup();
+ help_index->popup_dialog();
help_index->call_deferred("select_class", help->get_class());
} break;
case HELP_SEARCH_FIND: {
@@ -1369,7 +1366,9 @@ void ScriptEditor::_notification(int p_what) {
if (is_visible()) {
find_in_files_button->show();
} else {
- find_in_files->hide();
+ if (find_in_files->is_visible_in_tree()) {
+ editor->hide_bottom_panel();
+ }
find_in_files_button->hide();
}
@@ -1422,21 +1421,6 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) {
emit_signal("editor_script_changed", p_script);
}
-static const Node *_find_node_with_script(const Node *p_node, const RefPtr &p_script) {
-
- if (p_node->get_script() == p_script)
- return p_node;
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- const Node *result = _find_node_with_script(p_node->get_child(i), p_script);
- if (result)
- return result;
- }
-
- return NULL;
-}
-
void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
for (int i = 0; i < tab_container->get_child_count(); i++) {
@@ -1742,7 +1726,7 @@ void ScriptEditor::_update_script_names() {
} break;
case DISPLAY_DIR_AND_NAME: {
if (!path.get_base_dir().get_file().empty()) {
- sd.name = path.get_base_dir().get_file() + "/" + name;
+ sd.name = path.get_base_dir().get_file().plus_file(name);
} else {
sd.name = name;
}
@@ -1793,8 +1777,8 @@ void ScriptEditor::_update_script_names() {
new_cur_tab = i;
}
}
- tab_container->call_deferred("set_current_tab", new_prev_tab);
- tab_container->call_deferred("set_current_tab", new_cur_tab);
+ tab_container->set_current_tab(new_prev_tab);
+ tab_container->set_current_tab(new_cur_tab);
_sort_list_on_update = false;
}
@@ -1981,7 +1965,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
// doesn't have it, make a new one
- ScriptEditorBase *se;
+ ScriptEditorBase *se = NULL;
for (int i = script_editor_func_count - 1; i >= 0; i--) {
se = script_editor_funcs[i](p_resource);
@@ -2017,6 +2001,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
_go_to_tab(tab_container->get_tab_count() - 1);
}
+ _sort_list_on_update = true;
_update_script_names();
_save_layout();
se->connect("name_changed", this, "_update_script_names");
@@ -2106,8 +2091,6 @@ void ScriptEditor::_editor_play() {
debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_STEP), true);
debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_BREAK), false);
debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true);
-
- //debugger_gui->start_listening(Globals::get_singleton()->get("debug/debug_port"));
}
void ScriptEditor::_editor_pause() {
@@ -2591,6 +2574,7 @@ void ScriptEditor::_help_class_open(const String &p_class) {
eh->go_to_class(p_class, 0);
eh->connect("go_to_help", this, "_help_class_goto");
_add_recent_script(p_class);
+ _sort_list_on_update = true;
_update_script_names();
_save_layout();
}
@@ -2620,6 +2604,7 @@ void ScriptEditor::_help_class_goto(const String &p_desc) {
eh->go_to_help(p_desc);
eh->connect("go_to_help", this, "_help_class_goto");
_add_recent_script(eh->get_class());
+ _sort_list_on_update = true;
_update_script_names();
_save_layout();
}
@@ -2728,7 +2713,7 @@ void ScriptEditor::set_scene_root_script(Ref<Script> p_script) {
if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")))
return;
- if (open_dominant && p_script.is_valid() && _can_open_in_editor(p_script.ptr())) {
+ if (open_dominant && p_script.is_valid()) {
edit(p_script);
}
}
@@ -2749,11 +2734,11 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) {
}
void ScriptEditor::_help_index(String p_text) {
- help_index->popup();
+ help_index->popup_dialog();
}
void ScriptEditor::_help_search(String p_text) {
- help_search_dialog->popup(p_text);
+ help_search_dialog->popup_dialog(p_text);
}
void ScriptEditor::_open_script_request(const String &p_path) {
@@ -2826,8 +2811,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
find_in_files->set_with_replace(with_replace);
find_in_files->start_search();
- find_in_files_button->set_pressed(true);
- find_in_files->show();
+ editor->make_bottom_panel_item_visible(find_in_files);
}
void ScriptEditor::_on_find_in_files_modified_files(PoolStringArray paths) {
@@ -2911,7 +2895,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
restoring_layout = false;
waiting_update_names = false;
pending_auto_reload = false;
- auto_reload_running_scripts = false;
+ auto_reload_running_scripts = true;
members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
help_overview_enabled = EditorSettings::get_singleton()->get("text_editor/help/show_help_index");
editor = p_editor;
@@ -2932,7 +2916,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
script_list = memnew(ItemList);
list_split->add_child(script_list);
- script_list->set_custom_minimum_size(Size2(150 * EDSCALE, 90)); //need to give a bit of limit to avoid it from disappearing
+ script_list->set_custom_minimum_size(Size2(150, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing
script_list->set_v_size_flags(SIZE_EXPAND_FILL);
script_split->set_split_offset(140);
_sort_list_on_update = true;
@@ -2971,7 +2955,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
overview_vbox->add_child(members_overview);
members_overview->set_allow_reselect(true);
- members_overview->set_custom_minimum_size(Size2(0, 90)); //need to give a bit of limit to avoid it from disappearing
+ members_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing
members_overview->set_v_size_flags(SIZE_EXPAND_FILL);
members_overview->set_allow_rmb_select(true);
members_overview->set_drag_forwarding(this);
@@ -2979,12 +2963,12 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
help_overview = memnew(ItemList);
overview_vbox->add_child(help_overview);
help_overview->set_allow_reselect(true);
- help_overview->set_custom_minimum_size(Size2(0, 90)); //need to give a bit of limit to avoid it from disappearing
+ help_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing
help_overview->set_v_size_flags(SIZE_EXPAND_FILL);
tab_container = memnew(TabContainer);
tab_container->set_tabs_visible(false);
- tab_container->set_custom_minimum_size(Size2(200 * EDSCALE, 0));
+ tab_container->set_custom_minimum_size(Size2(200, 0) * EDSCALE);
script_split->add_child(tab_container);
tab_container->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -3017,10 +3001,10 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show In File System")), SHOW_IN_FILE_SYSTEM);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show in FileSystem")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Prev"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_previous", TTR("History Previous"), KEY_MASK_ALT | KEY_LEFT), WINDOW_PREV);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/history_next", TTR("History Next"), KEY_MASK_ALT | KEY_RIGHT), WINDOW_NEXT);
file_menu->get_popup()->add_separator();
@@ -3067,7 +3051,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
debug_menu->get_popup()->add_separator();
//debug_menu->get_popup()->add_check_item("Show Debugger",DEBUG_SHOW);
debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/keep_debugger_open", TTR("Keep Debugger Open")), DEBUG_SHOW_KEEP_OPEN);
- debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/debug_with_exteral_editor", TTR("Debug with external editor")), DEBUG_WITH_EXTERNAL_EDITOR);
+ debug_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("debugger/debug_with_external_editor", TTR("Debug with External Editor")), DEBUG_WITH_EXTERNAL_EDITOR);
debug_menu->get_popup()->connect("id_pressed", this, "_menu_option");
debug_menu->get_popup()->set_item_disabled(debug_menu->get_popup()->get_item_index(DEBUG_NEXT), true);
@@ -3140,7 +3124,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
error_dialog = memnew(AcceptDialog);
add_child(error_dialog);
- error_dialog->get_ok()->set_text(TTR("OK"));
debugger = memnew(ScriptEditorDebugger(editor));
debugger->connect("goto_script_line", this, "_goto_script_line");
@@ -3194,9 +3177,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, this, "_start_find_in_files", varray(true));
add_child(find_in_files_dialog);
find_in_files = memnew(FindInFilesPanel);
- find_in_files_button = editor->add_bottom_panel_item(TTR("Search results"), find_in_files);
- find_in_files_button->set_tooltip(TTR("Search in files"));
- find_in_files->set_custom_minimum_size(Size2(0, 200));
+ find_in_files_button = editor->add_bottom_panel_item(TTR("Search Results"), find_in_files);
+ find_in_files->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
find_in_files->connect(FindInFilesPanel::SIGNAL_RESULT_SELECTED, this, "_on_find_in_files_result_selected");
find_in_files->connect(FindInFilesPanel::SIGNAL_FILES_MODIFIED, this, "_on_find_in_files_modified_files");
find_in_files->hide();
@@ -3224,7 +3206,17 @@ ScriptEditor::~ScriptEditor() {
void ScriptEditorPlugin::edit(Object *p_object) {
if (Object::cast_to<Script>(p_object)) {
- script_editor->edit(Object::cast_to<Script>(p_object));
+
+ Script *p_script = Object::cast_to<Script>(p_object);
+ String scene_path = p_script->get_path().get_slice("::", 0);
+
+ if (_is_built_in_script(p_script) && !EditorNode::get_singleton()->is_scene_open(scene_path)) {
+ EditorNode::get_singleton()->load_scene(scene_path);
+
+ script_editor->call_deferred("edit", p_script);
+ } else {
+ script_editor->edit(p_script);
+ }
}
if (Object::cast_to<TextFile>(p_object)) {
@@ -3239,13 +3231,7 @@ bool ScriptEditorPlugin::handles(Object *p_object) const {
}
if (Object::cast_to<Script>(p_object)) {
-
- bool valid = _can_open_in_editor(Object::cast_to<Script>(p_object));
-
- if (!valid) { //user tried to open it by clicking
- EditorNode::get_singleton()->show_warning(TTR("Built-in scripts can only be edited when the scene they belong to is loaded"));
- }
- return valid;
+ return true;
}
return p_object->is_class("Script");
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 737f17358b..28c07393f7 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -31,6 +31,7 @@
#ifndef SCRIPT_EDITOR_PLUGIN_H
#define SCRIPT_EDITOR_PLUGIN_H
+#include "core/script_language.h"
#include "editor/code_editor.h"
#include "editor/editor_help.h"
#include "editor/editor_plugin.h"
@@ -44,7 +45,6 @@
#include "scene/gui/tree.h"
#include "scene/main/timer.h"
#include "scene/resources/text_file.h"
-#include "script_language.h"
class ScriptEditorQuickOpen : public ConfirmationDialog {
@@ -67,7 +67,7 @@ protected:
static void _bind_methods();
public:
- void popup(const Vector<String> &p_functions, bool p_dontclear = false);
+ void popup_dialog(const Vector<String> &p_functions, bool p_dontclear = false);
ScriptEditorQuickOpen();
};
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4e7047ee38..c3e2aa86f0 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -30,10 +30,10 @@
#include "script_text_editor.h"
+#include "core/os/keyboard.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/script_editor_debugger.h"
-#include "os/keyboard.h"
Vector<String> ScriptTextEditor::get_functions() {
@@ -179,7 +179,7 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_color_override("search_result_border_color", search_result_border_color);
text_edit->add_color_override("symbol_color", symbol_color);
- text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6));
colors_cache.symbol_color = symbol_color;
colors_cache.keyword_color = keyword_color;
@@ -317,6 +317,7 @@ void ScriptTextEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY:
_load_theme_settings();
+ _change_syntax_highlighter(EditorSettings::get_singleton()->get_project_metadata("script_text_editor", "syntax_highlighter", 0));
break;
}
}
@@ -772,7 +773,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case EDIT_CLONE_DOWN: {
- code_editor->code_lines_down();
+ code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
@@ -816,6 +817,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
if (tx->get_selection_to_column() == 0)
end -= 1;
+ int col_to = tx->get_selection_to_column();
+ int cursor_pos = tx->cursor_get_column();
+
// Check if all lines in the selected block are commented
bool is_commented = true;
for (int i = begin; i <= end; i++) {
@@ -838,19 +842,42 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
tx->set_line(i, line_text);
}
+
+ // Adjust selection & cursor position.
+ int offset = is_commented ? -1 : 1;
+ int col_from = tx->get_selection_from_column() > 0 ? tx->get_selection_from_column() + offset : 0;
+
+ if (is_commented && tx->cursor_get_column() == tx->get_line(tx->cursor_get_line()).length() + 1)
+ cursor_pos += 1;
+
+ if (tx->get_selection_to_column() != 0 && col_to != tx->get_line(tx->get_selection_to_line()).length() + 1)
+ col_to += offset;
+
+ if (tx->cursor_get_column() != 0)
+ cursor_pos += offset;
+
+ tx->select(begin, col_from, tx->get_selection_to_line(), col_to);
+ tx->cursor_set_column(cursor_pos);
+
} else {
int begin = tx->cursor_get_line();
String line_text = tx->get_line(begin);
- if (line_text.begins_with(delimiter))
+ int col = tx->cursor_get_column();
+ if (line_text.begins_with(delimiter)) {
line_text = line_text.substr(delimiter.length(), line_text.length());
- else
+ col -= 1;
+ } else {
line_text = delimiter + line_text;
+ col += 1;
+ }
+
tx->set_line(begin, line_text);
+ tx->cursor_set_column(col);
}
tx->end_complex_operation();
tx->update();
- //tx->deselect();
+
} break;
case EDIT_COMPLETE: {
@@ -939,7 +966,8 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case SEARCH_LOCATE_FUNCTION: {
- quick_open->popup(get_functions());
+ quick_open->popup_dialog(get_functions());
+ quick_open->set_title(TTR("Go to Function"));
} break;
case SEARCH_GOTO_LINE: {
@@ -1058,6 +1086,7 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
}
// highlighter_menu->set_item_checked(p_idx, true);
set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
+ EditorSettings::get_singleton()->set_project_metadata("script_text_editor", "syntax_highlighter", p_idx);
}
void ScriptTextEditor::_bind_methods() {
@@ -1256,7 +1285,7 @@ void ScriptTextEditor::_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 seleted text
+ // Right click is outside the selected text
tx->deselect();
}
}
@@ -1273,7 +1302,6 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
word_at_mouse = tx->get_selection_text();
bool has_color = (word_at_mouse == "Color");
- int fold_state = 0;
bool foldable = tx->can_fold(row) || tx->is_folded(row);
bool open_docs = false;
bool goto_definition = false;
@@ -1475,9 +1503,9 @@ ScriptTextEditor::ScriptTextEditor() {
convert_case->set_name("convert_case");
edit_menu->get_popup()->add_child(convert_case);
edit_menu->get_popup()->add_submenu_item(TTR("Convert Case"), "convert_case");
- convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase")), EDIT_TO_UPPERCASE);
- convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase")), EDIT_TO_LOWERCASE);
- convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize")), EDIT_CAPITALIZE);
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Uppercase"), KEY_MASK_SHIFT | KEY_F4), EDIT_TO_UPPERCASE);
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Lowercase"), KEY_MASK_SHIFT | KEY_F5), EDIT_TO_LOWERCASE);
+ convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KEY_MASK_SHIFT | KEY_F6), EDIT_CAPITALIZE);
convert_case->connect("id_pressed", this, "_edit_option");
highlighters["Standard"] = NULL;
@@ -1549,13 +1577,14 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C);
+ ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
#else
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B);
-#endif
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE);
+#endif
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_X);
+ 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);
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I);
#ifdef OSX_ENABLED
@@ -1564,27 +1593,28 @@ void ScriptTextEditor::register_editor() {
ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9);
#endif
ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9);
- ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Goto Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
- ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Goto Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
-
- ED_SHORTCUT("script_text_editor/convert_to_uppercase", TTR("Convert To Uppercase"), KEY_MASK_SHIFT | KEY_F4);
- ED_SHORTCUT("script_text_editor/convert_to_lowercase", TTR("Convert To Lowercase"), KEY_MASK_SHIFT | KEY_F3);
- ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize"), KEY_MASK_SHIFT | KEY_F2);
+ ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD);
+ ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA);
ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G);
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G);
+ ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
#else
ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3);
ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3);
-#endif
ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R);
+#endif
- ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
+ ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
- ED_SHORTCUT("script_text_editor/goto_function", TTR("Goto Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
- ED_SHORTCUT("script_text_editor/goto_line", TTR("Goto Line..."), KEY_MASK_CMD | KEY_L);
+#ifdef OSX_ENABLED
+ ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J);
+#else
+ ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F);
+#endif
+ ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KEY_MASK_CMD | KEY_L);
#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 5ee40dc90a..638de1b213 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -86,10 +86,7 @@ void ShaderTextEditor::_load_theme_settings() {
Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color");
Color symbol_color = EDITOR_GET("text_editor/highlighting/symbol_color");
Color keyword_color = EDITOR_GET("text_editor/highlighting/keyword_color");
- Color basetype_color = EDITOR_GET("text_editor/highlighting/base_type_color");
- Color type_color = EDITOR_GET("text_editor/highlighting/engine_type_color");
Color comment_color = EDITOR_GET("text_editor/highlighting/comment_color");
- Color string_color = EDITOR_GET("text_editor/highlighting/string_color");
get_text_edit()->add_color_override("background_color", background_color);
get_text_edit()->add_color_override("completion_background_color", completion_background_color);
@@ -140,26 +137,9 @@ void ShaderTextEditor::_load_theme_settings() {
get_text_edit()->add_keyword_color(E->get(), keyword_color);
}
- //colorize core types
- //Color basetype_color= EDITOR_DEF("text_editor/base_type_color",Color(0.3,0.3,0.0));
-
//colorize comments
get_text_edit()->add_color_region("/*", "*/", comment_color, false);
get_text_edit()->add_color_region("//", "", comment_color, false);
-
- /*//colorize strings
- Color string_color = EDITOR_DEF("text_editor/string_color",Color::hex(0x6b6f00ff));
-
- List<String> strings;
- shader->get_shader_mode()->get_string_delimiters(&strings);
-
- for (List<String>::Element *E=strings.front();E;E=E->next()) {
-
- String string = E->get();
- String beg = string.get_slice(" ",0);
- String end = string.get_slice_count(" ")>1?string.get_slice(" ",1):String();
- get_text_edit()->add_color_region(beg,end,string_color,end=="");
- }*/
}
void ShaderTextEditor::_check_shader_mode() {
@@ -283,7 +263,7 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->delete_lines();
} break;
case EDIT_CLONE_DOWN: {
- shader_editor->code_lines_down();
+ shader_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_COMMENT: {
@@ -426,7 +406,7 @@ void ShaderEditor::ensure_select_current() {
void ShaderEditor::edit(const Ref<Shader> &p_shader) {
- if (p_shader.is_null())
+ if (p_shader.is_null() || !p_shader->is_text_shader())
return;
shader = p_shader;
@@ -468,7 +448,6 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
int col, row;
TextEdit *tx = shader_editor->get_text_edit();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
- Vector2 mpos = mb->get_global_position() - tx->get_global_position();
tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret"));
if (tx->is_right_click_moving_caret()) {
@@ -480,7 +459,7 @@ void ShaderEditor::_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 seleted text
+ // Right click is outside the selected text
tx->deselect();
}
}
@@ -606,7 +585,7 @@ void ShaderEditorPlugin::edit(Object *p_object) {
bool ShaderEditorPlugin::handles(Object *p_object) const {
Shader *shader = Object::cast_to<Shader>(p_object);
- return shader != NULL;
+ return shader != NULL && shader->is_text_shader();
}
void ShaderEditorPlugin::make_visible(bool p_visible) {
diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp
index 314db4198d..8b0beefb3e 100644
--- a/editor/plugins/skeleton_editor_plugin.cpp
+++ b/editor/plugins/skeleton_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "skeleton_editor_plugin.h"
+
#include "scene/3d/collision_shape.h"
#include "scene/3d/physics_body.h"
-#include "scene/3d/physics_joint.h";
+#include "scene/3d/physics_joint.h"
#include "scene/resources/capsule_shape.h"
#include "scene/resources/sphere_shape.h"
#include "spatial_editor_plugin.h"
@@ -150,6 +151,7 @@ void SkeletonEditor::_bind_methods() {
}
SkeletonEditor::SkeletonEditor() {
+ skeleton = NULL;
options = memnew(MenuButton);
SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
diff --git a/editor/plugins/skeleton_editor_plugin.h b/editor/plugins/skeleton_editor_plugin.h
index 0ab94c15b5..aac3e06063 100644
--- a/editor/plugins/skeleton_editor_plugin.h
+++ b/editor/plugins/skeleton_editor_plugin.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp
index 2d343d3edd..c605548a6b 100644
--- a/editor/plugins/skeleton_ik_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_editor_plugin.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h
index e645bea39a..3e412305c9 100644
--- a/editor/plugins/skeleton_ik_editor_plugin.h
+++ b/editor/plugins/skeleton_ik_editor_plugin.h
@@ -1,12 +1,12 @@
/*************************************************************************/
-/* skeleton_ik_editor_plugin.h */
+/* skeleton_ik_editor_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 906c51b9f6..a5563c0497 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -30,23 +30,25 @@
#include "spatial_editor_plugin.h"
-#include "camera_matrix.h"
+#include "core/math/camera_matrix.h"
#include "core/os/input.h"
-
+#include "core/os/keyboard.h"
+#include "core/print_string.h"
+#include "core/project_settings.h"
+#include "core/sort.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor/script_editor_debugger.h"
#include "editor/spatial_editor_gizmos.h"
-#include "os/keyboard.h"
-#include "print_string.h"
-#include "project_settings.h"
#include "scene/3d/camera.h"
+#include "scene/3d/collision_shape.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/physics_body.h"
#include "scene/3d/visual_instance.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
-#include "sort.h"
#define DISTANCE_DEFAULT 4
@@ -274,7 +276,7 @@ void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single) {
_select(sp, clicked_wants_append, true);
}
-void SpatialEditorViewport::_select(Spatial *p_node, bool p_append, bool p_single) {
+void SpatialEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
if (!p_append) {
editor_selection->clear();
@@ -307,7 +309,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
Node *edited_scene = get_tree()->get_edited_scene_root();
ObjectID closest = 0;
- Spatial *item = NULL;
+ Node *item = NULL;
float closest_dist = 1e20;
int selected_handle = -1;
@@ -340,20 +342,15 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
continue;
if (dist < closest_dist) {
- //make sure that whathever is selected is editable
- while (spat && spat != edited_scene && spat->get_owner() != edited_scene && !edited_scene->is_editable_instance(spat->get_owner())) {
- spat = Object::cast_to<Spatial>(spat->get_owner());
+ item = Object::cast_to<Node>(spat);
+ while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
+ item = item->get_owner();
}
- if (spat) {
- item = spat;
- closest = spat->get_instance_id();
- closest_dist = dist;
- selected_handle = handle;
- } else {
- ERR_PRINT("Bug?");
- }
+ closest = item->get_instance_id();
+ closest_dist = dist;
+ selected_handle = handle;
}
}
@@ -499,7 +496,7 @@ void SpatialEditorViewport::_select_region() {
}
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario());
- Vector<Spatial *> selected;
+ Vector<Node *> selected;
Node *edited_scene = get_tree()->get_edited_scene_root();
@@ -509,12 +506,12 @@ void SpatialEditorViewport::_select_region() {
if (!sp)
continue;
- Spatial *root_sp = sp;
- while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) {
- root_sp = Object::cast_to<Spatial>(root_sp->get_owner());
+ Node *item = Object::cast_to<Node>(sp);
+ while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
+ item = item->get_owner();
}
- if (selected.find(root_sp) != -1) continue;
+ if (selected.find(item) != -1) continue;
Ref<EditorSpatialGizmo> seg = sp->get_gizmo();
@@ -522,7 +519,7 @@ void SpatialEditorViewport::_select_region() {
continue;
if (seg->intersect_frustum(camera, frustum)) {
- selected.push_back(root_sp);
+ selected.push_back(item);
}
}
@@ -534,12 +531,12 @@ void SpatialEditorViewport::_select_region() {
void SpatialEditorViewport::_update_name() {
- String ortho = orthogonal ? TTR("Orthogonal") : TTR("Perspective");
+ String view_mode = orthogonal ? TTR("Orthogonal") : TTR("Perspective");
if (name != "")
- view_menu->set_text("[ " + name + " " + ortho + " ]");
+ view_menu->set_text(name + " " + view_mode);
else
- view_menu->set_text("[ " + ortho + " ]");
+ view_menu->set_text(view_mode);
view_menu->set_size(Vector2(0, 0)); // resets the button size
}
@@ -850,11 +847,7 @@ void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
Spatial *spat = selection_results[i].item;
- Ref<Texture> icon;
- if (spat->has_meta("_editor_icon"))
- icon = spat->get_meta("_editor_icon");
- else
- icon = get_icon(has_icon(spat->get_class(), "EditorIcons") ? spat->get_class() : String("Object"), "EditorIcons");
+ Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(spat, "Node");
String node_path = "/" + root_name + "/" + root_path.rel_path_to(spat->get_path());
@@ -959,8 +952,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed()) {
int mod = _get_key_modifier(b);
- if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
- set_freelook_active(true);
+ if (!orthogonal) {
+ if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
+ set_freelook_active(true);
+ }
}
} else {
set_freelook_active(false);
@@ -1004,6 +999,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
set_message(TTR("View Plane Transform."), 2);
} break;
+ case TRANSFORM_YZ:
+ case TRANSFORM_XZ:
+ case TRANSFORM_XY: {
+ } break;
}
}
} break;
@@ -1137,7 +1136,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (clicked) {
_select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
+ // Processing was deferred.
clicked = 0;
}
@@ -1244,7 +1243,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!clicked_includes_current) {
_select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
+ // Processing was deferred.
}
_compute_edit(_edit.mouse_pos);
@@ -1342,7 +1341,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
@@ -1471,7 +1471,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
+ // Disable local transformation for TRANSFORM_VIEW
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW);
float snap = 0;
if (_edit.snap || spatial_editor->is_snap_enabled()) {
@@ -1552,6 +1553,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2));
axis = Vector3(0, 0, 1);
break;
+ case TRANSFORM_YZ:
+ case TRANSFORM_XZ:
+ case TRANSFORM_XY:
+ break;
}
Vector3 intersection;
@@ -1642,6 +1647,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_ZOOM;
} else if (freelook_active) {
nav_mode = NAVIGATION_LOOK;
+ } else if (orthogonal) {
+ nav_mode = NAVIGATION_PAN;
}
} else if (m->get_button_mask() & BUTTON_MASK_MIDDLE) {
@@ -1792,7 +1799,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("spatial_editor/focus_selection", p_event)) {
_menu_option(VIEW_CENTER_TO_SELECTION);
}
- if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
+ // Orthgonal mode doesn't work in freelook.
+ if (!freelook_active && ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
_menu_option(orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL);
_update_name();
}
@@ -1822,7 +1830,8 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
set_message(TTR("Animation Key Inserted."));
}
- if (ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
+ // Freelook doesn't work in orthogonal mode.
+ if (!orthogonal && ED_IS_SHORTCUT("spatial_editor/freelook_toggle", p_event)) {
set_freelook_active(!is_freelook_active());
} else if (k->get_scancode() == KEY_ESCAPE) {
@@ -1892,7 +1901,7 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
- bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
+ bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis");
if (invert_y_axis) {
cursor.x_rot -= p_relative.y * radians_per_pixel;
@@ -1910,37 +1919,38 @@ void SpatialEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, con
void SpatialEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
- // Freelook only works properly in perspective.
- // It technically works too in ortho, but it's awful for a user due to fov being near zero
- if (!orthogonal) {
- real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
- real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
- bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y-axis");
-
- // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
- Transform prev_camera_transform = to_camera_transform(cursor);
+ if (orthogonal) {
+ _nav_pan(p_event, p_relative);
+ return;
+ }
- if (invert_y_axis) {
- cursor.x_rot -= p_relative.y * radians_per_pixel;
- } else {
- cursor.x_rot += p_relative.y * radians_per_pixel;
- }
- cursor.y_rot += p_relative.x * radians_per_pixel;
- if (cursor.x_rot > Math_PI / 2.0)
- cursor.x_rot = Math_PI / 2.0;
- if (cursor.x_rot < -Math_PI / 2.0)
- cursor.x_rot = -Math_PI / 2.0;
+ real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
+ real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis");
- // Look is like the opposite of Orbit: the focus point rotates around the camera
- Transform camera_transform = to_camera_transform(cursor);
- Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
- Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
- Vector3 diff = prev_pos - pos;
- cursor.pos += diff;
+ // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
+ Transform prev_camera_transform = to_camera_transform(cursor);
- name = "";
- _update_name();
+ if (invert_y_axis) {
+ cursor.x_rot -= p_relative.y * radians_per_pixel;
+ } else {
+ cursor.x_rot += p_relative.y * radians_per_pixel;
}
+ cursor.y_rot += p_relative.x * radians_per_pixel;
+ if (cursor.x_rot > Math_PI / 2.0)
+ cursor.x_rot = Math_PI / 2.0;
+ if (cursor.x_rot < -Math_PI / 2.0)
+ cursor.x_rot = -Math_PI / 2.0;
+
+ // Look is like the opposite of Orbit: the focus point rotates around the camera
+ Transform camera_transform = to_camera_transform(cursor);
+ Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = prev_pos - pos;
+ cursor.pos += diff;
+
+ name = "";
+ _update_name();
}
void SpatialEditorViewport::set_freelook_active(bool active_now) {
@@ -2082,7 +2092,7 @@ void SpatialEditorViewport::set_message(String p_message, float p_time) {
}
void SpatialEditorPlugin::edited_scene_changed() {
- for (int i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) {
+ for (uint32_t i = 0; i < SpatialEditor::VIEWPORTS_COUNT; i++) {
SpatialEditorViewport *viewport = SpatialEditor::get_singleton()->get_editor_viewport(i);
if (viewport->is_visible()) {
viewport->notification(Control::NOTIFICATION_VISIBILITY_CHANGED);
@@ -2123,7 +2133,7 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
Node *scene_root = editor->get_scene_tree_dock()->get_editor_data()->get_edited_scene_root();
- if (previewing_cinema == true && scene_root != NULL) {
+ if (previewing_cinema && scene_root != NULL) {
Camera *cam = scene_root->get_viewport()->get_camera();
if (cam != NULL && cam != previewing) {
//then switch the viewport's camera to the scene's viewport camera
@@ -2206,7 +2216,7 @@ void SpatialEditorViewport::_notification(int p_what) {
bool shrink = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION));
- if (shrink != viewport_container->get_stretch_shrink() > 1) {
+ if (shrink != (viewport_container->get_stretch_shrink() > 1)) {
viewport_container->set_stretch_shrink(shrink ? 2 : 1);
}
@@ -2221,8 +2231,21 @@ void SpatialEditorViewport::_notification(int p_what) {
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
info_label->set_visible(show_info);
+ Camera *current_camera;
+
+ if (previewing) {
+ current_camera = previewing;
+ } else {
+ current_camera = camera;
+ }
+
if (show_info) {
String text;
+ text += "X: " + rtos(current_camera->get_translation().x).pad_decimals(1) + "\n";
+ text += "Y: " + rtos(current_camera->get_translation().y).pad_decimals(1) + "\n";
+ text += "Z: " + rtos(current_camera->get_translation().z).pad_decimals(1) + "\n";
+ text += TTR("Pitch") + ": " + itos(Math::round(current_camera->get_rotation_degrees().x)) + "\n";
+ text += TTR("Yaw") + ": " + itos(Math::round(current_camera->get_rotation_degrees().y)) + "\n\n";
text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n";
text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n";
text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n";
@@ -2249,6 +2272,11 @@ void SpatialEditorViewport::_notification(int p_what) {
float cinema_half_width = cinema_label->get_size().width / 2.0f;
cinema_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -cinema_half_width);
}
+
+ if (lock_rotation) {
+ float locked_half_width = locked_label->get_size().width / 2.0f;
+ locked_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -locked_half_width);
+ }
}
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -2259,21 +2287,36 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->connect("mouse_exited", this, "_surface_mouse_exit");
surface->connect("focus_entered", this, "_surface_focus_enter");
surface->connect("focus_exited", this, "_surface_focus_exit");
- info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
- fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
- cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
- preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
+
_init_gizmo_instance(index);
}
+
if (p_what == NOTIFICATION_EXIT_TREE) {
_finish_gizmo_instances();
}
- if (p_what == NOTIFICATION_MOUSE_ENTER) {
- }
+ if (p_what == NOTIFICATION_THEME_CHANGED) {
- if (p_what == NOTIFICATION_DRAW) {
+ view_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons"));
+ preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
+
+ view_menu->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ view_menu->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+
+ preview_camera->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ preview_camera->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ preview_camera->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ preview_camera->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ preview_camera->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+
+ info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
+ locked_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles"));
}
}
@@ -2319,12 +2362,12 @@ void SpatialEditorViewport::_draw() {
EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
- over_plugin_list->forward_draw_over_viewport(surface);
+ over_plugin_list->forward_spatial_draw_over_viewport(surface);
}
EditorPluginList *force_over_plugin_list = editor->get_editor_plugins_force_over();
if (!force_over_plugin_list->empty()) {
- force_over_plugin_list->forward_force_draw_over_viewport(surface);
+ force_over_plugin_list->forward_spatial_force_draw_over_viewport(surface);
}
if (surface->has_focus()) {
@@ -2353,7 +2396,6 @@ void SpatialEditorViewport::_draw() {
Point2 center = _point_to_screen(_edit.center);
VisualServer::get_singleton()->canvas_item_add_line(ci, _edit.mouse_pos, center, Color(0.4, 0.7, 1.0, 0.8));
}
-
if (previewing) {
Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
@@ -2515,8 +2557,14 @@ void SpatialEditorViewport::_menu_option(int p_option) {
if (!se)
continue;
- Transform xform = camera_transform;
- xform.scale_basis(sp->get_scale());
+ Transform xform;
+ if (orthogonal) {
+ xform = sp->get_global_transform();
+ xform.basis.set_euler(camera_transform.basis.get_euler());
+ } else {
+ xform = camera_transform;
+ xform.scale_basis(sp->get_scale());
+ }
undo_redo->add_do_method(sp, "set_global_transform", xform);
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
@@ -2564,9 +2612,9 @@ void SpatialEditorViewport::_menu_option(int p_option) {
lock_rotation = !current;
view_menu->get_popup()->set_item_checked(idx, !current);
if (lock_rotation) {
- view_menu->set_icon(get_icon("Lock", "EditorIcons"));
+ locked_label->show();
} else {
- view_menu->set_icon(Ref<Texture>());
+ locked_label->hide();
}
} break;
@@ -2636,11 +2684,6 @@ void SpatialEditorViewport::_menu_option(int p_option) {
bool current = view_menu->get_popup()->is_item_checked(idx);
view_menu->get_popup()->set_item_checked(idx, !current);
- if (current)
- preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
- else
- preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 15 * EDSCALE + fps_label->get_size().height);
-
} break;
case VIEW_DISPLAY_NORMAL: {
@@ -2754,7 +2797,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore
if (!preview)
preview_camera->hide();
- view_menu->show();
+ view_menu->set_disabled(false);
surface->update();
} else {
@@ -2762,7 +2805,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
previewing = preview;
previewing->connect("tree_exiting", this, "_preview_exited_scene");
VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace
- view_menu->hide();
+ view_menu->set_disabled(true);
surface->update();
}
}
@@ -3274,7 +3317,6 @@ void SpatialEditorViewport::_perform_drop_data() {
files_str += error_files[i].get_file().get_basename() + ",";
}
files_str = files_str.substr(0, files_str.length() - 1);
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str()));
accept->popup_centered_minsize();
}
@@ -3355,7 +3397,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
if (root_node) {
list.push_back(root_node);
} else {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered_minsize();
_remove_preview();
@@ -3363,7 +3404,6 @@ void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p
}
}
if (list.size() != 1) {
- accept->get_ok()->set_text(TTR("OK"));
accept->set_text(TTR("This operation requires a single selected node."));
accept->popup_centered_minsize();
_remove_preview();
@@ -3422,9 +3462,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface->set_focus_mode(FOCUS_ALL);
view_menu = memnew(MenuButton);
+ view_menu->set_flat(false);
surface->add_child(view_menu);
- view_menu->set_position(Point2(4, 4) * EDSCALE);
- view_menu->set_self_modulate(Color(1, 1, 1, 0.5));
+ view_menu->set_position(Point2(10, 10) * EDSCALE);
+
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/bottom_view"), VIEW_BOTTOM);
view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/left_view"), VIEW_LEFT);
@@ -3475,12 +3516,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_Q);
ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT);
- preview_camera = memnew(Button);
- preview_camera->set_toggle_mode(true);
- preview_camera->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE);
- preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
- preview_camera->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE);
- preview_camera->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ preview_camera = memnew(CheckBox);
+ preview_camera->set_position(Point2(10, 38) * EDSCALE); // Below the 'view_menu' MenuButton.
preview_camera->set_text(TTR("Preview"));
surface->add_child(preview_camera);
preview_camera->hide();
@@ -3500,7 +3537,6 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface->add_child(info_label);
info_label->hide();
- // FPS Counter.
fps_label = memnew(Label);
fps_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE);
fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
@@ -3518,6 +3554,16 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
cinema_label->hide();
previewing_cinema = false;
+ locked_label = memnew(Label);
+ locked_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -20 * EDSCALE);
+ locked_label->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -10 * EDSCALE);
+ locked_label->set_h_grow_direction(GROW_DIRECTION_END);
+ locked_label->set_v_grow_direction(GROW_DIRECTION_BEGIN);
+ locked_label->set_align(Label::ALIGN_CENTER);
+ surface->add_child(locked_label);
+ locked_label->set_text(TTR("View Rotation Locked"));
+ locked_label->hide();
+
accept = NULL;
freelook_active = false;
@@ -3546,69 +3592,77 @@ void SpatialEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event)
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
- Vector2 size = get_size();
+ if (mb->is_pressed()) {
+ Vector2 size = get_size();
- int h_sep = get_constant("separation", "HSplitContainer");
- int v_sep = get_constant("separation", "VSplitContainer");
+ int h_sep = get_constant("separation", "HSplitContainer");
+ int v_sep = get_constant("separation", "VSplitContainer");
- int mid_w = size.width * ratio_h;
- int mid_h = size.height * ratio_v;
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
- dragging_h = mb->get_position().x > (mid_w - h_sep / 2) && mb->get_position().x < (mid_w + h_sep / 2);
- dragging_v = mb->get_position().y > (mid_h - v_sep / 2) && mb->get_position().y < (mid_h + v_sep / 2);
+ dragging_h = mb->get_position().x > (mid_w - h_sep / 2) && mb->get_position().x < (mid_w + h_sep / 2);
+ dragging_v = mb->get_position().y > (mid_h - v_sep / 2) && mb->get_position().y < (mid_h + v_sep / 2);
- drag_begin_pos = mb->get_position();
- drag_begin_ratio.x = ratio_h;
- drag_begin_ratio.y = ratio_v;
+ drag_begin_pos = mb->get_position();
+ drag_begin_ratio.x = ratio_h;
+ drag_begin_ratio.y = ratio_v;
- switch (view) {
- case VIEW_USE_1_VIEWPORT: {
-
- dragging_h = false;
- dragging_v = false;
-
- } break;
- case VIEW_USE_2_VIEWPORTS: {
+ switch (view) {
+ case VIEW_USE_1_VIEWPORT: {
- dragging_h = false;
+ dragging_h = false;
+ dragging_v = false;
- } break;
- case VIEW_USE_2_VIEWPORTS_ALT: {
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
- dragging_v = false;
+ dragging_h = false;
- } break;
- case VIEW_USE_3_VIEWPORTS: {
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
- if (dragging_v)
- dragging_h = false;
- else
dragging_v = false;
- } break;
- case VIEW_USE_3_VIEWPORTS_ALT: {
+ } break;
+ case VIEW_USE_3_VIEWPORTS:
+ case VIEW_USE_3_VIEWPORTS_ALT:
+ case VIEW_USE_4_VIEWPORTS: {
- if (dragging_h)
- dragging_v = false;
- else
- dragging_h = false;
- } break;
- case VIEW_USE_4_VIEWPORTS: {
+ // Do nothing.
- } break;
+ } break;
+ }
+ } else {
+ dragging_h = false;
+ dragging_v = false;
}
}
- if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- dragging_h = false;
- dragging_v = false;
- }
-
Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid() && (dragging_h || dragging_v)) {
+ if (mm.is_valid()) {
+
+ if (view == VIEW_USE_3_VIEWPORTS || view == VIEW_USE_3_VIEWPORTS_ALT || view == VIEW_USE_4_VIEWPORTS) {
+ Vector2 size = get_size();
+
+ int h_sep = get_constant("separation", "HSplitContainer");
+ int v_sep = get_constant("separation", "VSplitContainer");
+
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
+
+ bool was_hovering_h = hovering_h;
+ bool was_hovering_v = hovering_v;
+ hovering_h = mm->get_position().x > (mid_w - h_sep / 2) && mm->get_position().x < (mid_w + h_sep / 2);
+ hovering_v = mm->get_position().y > (mid_h - v_sep / 2) && mm->get_position().y < (mid_h + v_sep / 2);
+
+ if (was_hovering_h != hovering_h || was_hovering_v != hovering_v) {
+ update();
+ }
+ }
if (dragging_h) {
float new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width;
@@ -3638,9 +3692,12 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW && mouseover) {
Ref<Texture> h_grabber = get_icon("grabber", "HSplitContainer");
-
Ref<Texture> v_grabber = get_icon("grabber", "VSplitContainer");
+ Ref<Texture> hdiag_grabber = get_icon("GuiViewportHdiagsplitter", "EditorIcons");
+ Ref<Texture> vdiag_grabber = get_icon("GuiViewportVdiagsplitter", "EditorIcons");
+ Ref<Texture> vh_grabber = get_icon("GuiViewportVhsplitter", "EditorIcons");
+
Vector2 size = get_size();
int h_sep = get_constant("separation", "HSplitContainer");
@@ -3657,35 +3714,62 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
case VIEW_USE_1_VIEWPORT: {
- //nothing to show
+ // Nothing to show.
} break;
case VIEW_USE_2_VIEWPORTS: {
draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
} break;
case VIEW_USE_2_VIEWPORTS_ALT: {
draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
} break;
case VIEW_USE_3_VIEWPORTS: {
- draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
} break;
case VIEW_USE_3_VIEWPORTS_ALT: {
- draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
- draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
+
} break;
case VIEW_USE_4_VIEWPORTS: {
Vector2 half(mid_w, mid_h);
- draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
- draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
+ if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
+ draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_DRAG);
+ } else if ((hovering_v && !dragging_h) || dragging_v) {
+ draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_VSPLIT);
+ } else if (hovering_h || dragging_h) {
+ draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
+ set_default_cursor_shape(CURSOR_HSPLIT);
+ }
} break;
}
@@ -3729,6 +3813,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
case VIEW_USE_1_VIEWPORT: {
+ viewports[0]->show();
for (int i = 1; i < 4; i++) {
viewports[i]->hide();
@@ -3739,7 +3824,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_2_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
if (i == 1 || i == 3)
viewports[i]->hide();
@@ -3753,7 +3838,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_2_VIEWPORTS_ALT: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
if (i == 1 || i == 3)
viewports[i]->hide();
@@ -3766,7 +3851,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_3_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
if (i == 1)
viewports[i]->hide();
@@ -3781,7 +3866,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_3_VIEWPORTS_ALT: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
if (i == 1)
viewports[i]->hide();
@@ -3796,7 +3881,7 @@ void SpatialEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_4_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
+ for (int i = 0; i < 4; i++) {
viewports[i]->show();
}
@@ -3829,10 +3914,13 @@ void SpatialEditorViewportContainer::_bind_methods() {
SpatialEditorViewportContainer::SpatialEditorViewportContainer() {
+ set_clip_contents(true);
view = VIEW_USE_1_VIEWPORT;
mouseover = false;
ratio_h = 0.5;
ratio_v = 0.5;
+ hovering_v = false;
+ hovering_h = false;
dragging_v = false;
dragging_h = false;
}
@@ -3914,8 +4002,9 @@ void _update_all_gizmos(Node *p_node) {
}
}
-void SpatialEditor::update_all_gizmos() {
- _update_all_gizmos(SceneTree::get_singleton()->get_root());
+void SpatialEditor::update_all_gizmos(Node *p_node) {
+ if (!p_node) p_node = SceneTree::get_singleton()->get_root();
+ _update_all_gizmos(p_node);
}
Object *SpatialEditor::_get_editor_data(Object *p_what) {
@@ -4103,7 +4192,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
for (int j = 0; j < gizmo_plugins.size(); ++j) {
if (!gizmo_plugins[j]->can_be_hidden()) continue;
int state = EditorSpatialGizmoPlugin::ON_TOP;
- for (uint32_t i = 0; i < keys.size(); i++) {
+ for (int i = 0; i < keys.size(); i++) {
if (gizmo_plugins.write[j]->get_name() == keys[i]) {
state = gizmos_status[keys[i]];
}
@@ -4115,10 +4204,10 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
gizmo_plugins.write[j]->set_state(state);
switch (state) {
- case EditorSpatialGizmoPlugin::ON_TOP:
+ case EditorSpatialGizmoPlugin::VISIBLE:
gizmos_menu->set_item_icon(idx, gizmos_menu->get_icon("visibility_visible"));
break;
- case EditorSpatialGizmoPlugin::VISIBLE:
+ case EditorSpatialGizmoPlugin::ON_TOP:
gizmos_menu->set_item_icon(idx, gizmos_menu->get_icon("visibility_xray"));
break;
case EditorSpatialGizmoPlugin::HIDDEN:
@@ -4228,10 +4317,10 @@ void SpatialEditor::_menu_gizmo_toggled(int p_option) {
// Change icon
const int state = gizmos_menu->get_item_state(idx);
switch (state) {
- case EditorSpatialGizmoPlugin::ON_TOP:
+ case EditorSpatialGizmoPlugin::VISIBLE:
gizmos_menu->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_visible"));
break;
- case EditorSpatialGizmoPlugin::VISIBLE:
+ case EditorSpatialGizmoPlugin::ON_TOP:
gizmos_menu->set_item_icon(idx, view_menu->get_popup()->get_icon("visibility_xray"));
break;
case EditorSpatialGizmoPlugin::HIDDEN:
@@ -4427,6 +4516,8 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
void SpatialEditor::_init_indicators() {
{
+ origin_enabled = true;
+ grid_enabled = true;
indicator_mat.instance();
indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
@@ -4467,9 +4558,6 @@ void SpatialEditor::_init_indicators() {
VS::get_singleton()->instance_set_layer_mask(origin_instance, 1 << SpatialEditorViewport::GIZMO_GRID_LAYER);
VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, VS::SHADOW_CASTING_SETTING_OFF);
-
- grid_enabled = true;
- last_grid_snap = 1;
}
{
@@ -4751,7 +4839,7 @@ void SpatialEditor::_init_gizmos_menu() {
for (int i = 0; i < gizmo_plugins.size(); ++i) {
if (!gizmo_plugins[i]->can_be_hidden()) continue;
String plugin_name = gizmo_plugins[i]->get_name();
- gizmos_menu->add_multistate_item(TTR(plugin_name), 3, EditorSpatialGizmoPlugin::ON_TOP, i);
+ gizmos_menu->add_multistate_item(TTR(plugin_name), 3, EditorSpatialGizmoPlugin::VISIBLE, i);
gizmos_menu->set_item_icon(gizmos_menu->get_item_index(i), gizmos_menu->get_icon("visibility_visible"));
}
}
@@ -4990,32 +5078,29 @@ void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
if (!k->is_pressed())
return;
- if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event))
+ 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))
+ } 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))
+ } 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))
+ } 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))
+ } 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))
+ } 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))
+ } 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);
}
+ }
}
}
}
@@ -5291,6 +5376,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
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"));
+ hbc_menu->add_child(memnew(VSeparator));
+
tool_button[TOOL_MODE_MOVE] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_MOVE]);
tool_button[TOOL_MODE_MOVE]->set_toggle_mode(true);
@@ -5315,6 +5402,8 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
+ hbc_menu->add_child(memnew(VSeparator));
+
tool_button[TOOL_MODE_LIST_SELECT] = memnew(ToolButton);
hbc_menu->add_child(tool_button[TOOL_MODE_LIST_SELECT]);
tool_button[TOOL_MODE_LIST_SELECT]->set_toggle_mode(true);
@@ -5335,8 +5424,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved)."));
- VSeparator *vs = memnew(VSeparator);
- hbc_menu->add_child(vs);
+ hbc_menu->add_child(memnew(VSeparator));
tool_option_button[TOOL_OPT_LOCAL_COORDS] = memnew(ToolButton);
hbc_menu->add_child(tool_option_button[TOOL_OPT_LOCAL_COORDS]);
@@ -5358,8 +5446,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
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));
- vs = memnew(VSeparator);
- hbc_menu->add_child(vs);
+ hbc_menu->add_child(memnew(VSeparator));
// Drag and drop support;
preview_node = memnew(Spatial);
@@ -5381,7 +5468,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
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/snap_to_floor", TTR("Snap To Floor"), KEY_PAGEDOWN);
ED_SHORTCUT("spatial_editor/freelook_toggle", TTR("Toggle Freelook"), KEY_MASK_SHIFT + KEY_F);
@@ -5392,7 +5478,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
hbc_menu->add_child(transform_menu);
p = transform_menu->get_popup();
- p->add_shortcut(ED_SHORTCUT("spatial_editor/snap_to_floor", TTR("Snap object to floor")), MENU_SNAP_TO_FLOOR);
+ 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);
@@ -5401,7 +5487,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
view_menu = memnew(MenuButton);
view_menu->set_text(TTR("View"));
- view_menu->set_position(Point2(212, 0));
hbc_menu->add_child(view_menu);
p = view_menu->get_popup();
@@ -5593,7 +5678,6 @@ void SpatialEditorPlugin::make_visible(bool p_visible) {
spatial_editor->show();
spatial_editor->set_process(true);
- spatial_editor->grab_focus();
} else {
@@ -5664,7 +5748,7 @@ SpatialEditorPlugin::~SpatialEditorPlugin() {
void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
- Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5));
+ Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6));
Vector<Ref<SpatialMaterial> > mats;
@@ -5706,7 +5790,7 @@ void EditorSpatialGizmoPlugin::create_material(const String &p_name, const Color
void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture> &p_texture, bool p_on_top, const Color &p_albedo) {
- Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.5));
+ Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6));
Vector<Ref<SpatialMaterial> > icons;
@@ -5719,7 +5803,7 @@ void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const
Color color = instanced ? instanced_color : p_albedo;
if (!selected) {
- color.a *= 0.3;
+ color.a *= 0.85;
}
icon->set_albedo(color);
@@ -5835,7 +5919,7 @@ void EditorSpatialGizmoPlugin::unregister_gizmo(EditorSpatialGizmo *p_gizmo) {
}
EditorSpatialGizmoPlugin::EditorSpatialGizmoPlugin() {
- current_state = ON_TOP;
+ current_state = VISIBLE;
}
EditorSpatialGizmoPlugin::~EditorSpatialGizmoPlugin() {
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 5850c0dbf1..c515a4aaf9 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -86,7 +86,7 @@ public:
Vector<Vector3> handles;
Vector<Vector3> secondary_handles;
- float selectable_icon_size = -1.0f;
+ float selectable_icon_size;
bool billboard_handle;
bool valid;
@@ -127,9 +127,7 @@ public:
virtual void redraw();
virtual void free();
- //TODO remove (?)
virtual bool is_editable() const;
- virtual bool can_draw() const;
void set_hidden(bool p_hidden);
void set_plugin(EditorSpatialGizmoPlugin *p_gizmo);
@@ -194,7 +192,7 @@ private:
EditorSelection *editor_selection;
UndoRedo *undo_redo;
- Button *preview_camera;
+ CheckBox *preview_camera;
ViewportContainer *viewport_container;
MenuButton *view_menu;
@@ -213,6 +211,7 @@ private:
Label *info_label;
Label *fps_label;
Label *cinema_label;
+ Label *locked_label;
struct _RayResult {
@@ -226,7 +225,7 @@ private:
void _compute_edit(const Point2 &p_point);
void _clear_selected();
void _select_clicked(bool p_append, bool p_single);
- void _select(Spatial *p_node, bool p_append, bool p_single);
+ void _select(Node *p_node, bool p_append, bool p_single);
ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false);
void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false);
Vector3 _get_ray_pos(const Vector2 &p_pos) const;
@@ -406,6 +405,7 @@ public:
AcceptDialog *p_accept);
Viewport *get_viewport_node() { return viewport; }
+ Camera *get_camera() { return camera; } // return the default camera object.
SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index);
};
@@ -445,6 +445,9 @@ private:
float ratio_h;
float ratio_v;
+ bool hovering_v;
+ bool hovering_h;
+
bool dragging_v;
bool dragging_h;
Vector2 drag_begin_pos;
@@ -512,7 +515,6 @@ private:
RID grid[3];
RID grid_instance[3];
bool grid_visible[3]; //currently visible
- float last_grid_snap;
bool grid_enable[3]; //should be always visible if true
bool grid_enabled;
@@ -677,7 +679,7 @@ public:
Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; }
void update_transform_gizmo();
- void update_all_gizmos();
+ void update_all_gizmos(Node *p_node = NULL);
void snap_selected_nodes_to_floor();
void select_gizmo_highlight_axis(int p_axis);
void set_custom_camera(Node *p_camera) { custom_camera = p_camera; }
@@ -710,7 +712,6 @@ public:
void register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref);
- Camera *get_camera() { return NULL; }
void edit(Spatial *p_spatial);
void clear();
@@ -753,9 +754,9 @@ class EditorSpatialGizmoPlugin : public Resource {
GDCLASS(EditorSpatialGizmoPlugin, Resource);
public:
- static const int ON_TOP = 0;
- static const int VISIBLE = 1;
- static const int HIDDEN = 2;
+ static const int VISIBLE = 0;
+ static const int HIDDEN = 1;
+ static const int ON_TOP = 2;
private:
int current_state;
diff --git a/editor/plugins/sprite_editor_plugin.cpp b/editor/plugins/sprite_editor_plugin.cpp
index 58a1835e68..c574b5e8ba 100644
--- a/editor/plugins/sprite_editor_plugin.cpp
+++ b/editor/plugins/sprite_editor_plugin.cpp
@@ -97,7 +97,7 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float
int lasti = p2->Contour.size() - 1;
Vector2 prev = Vector2(p2->Contour[lasti].X / PRECISION, p2->Contour[lasti].Y / PRECISION);
- for (int i = 0; i < p2->Contour.size(); i++) {
+ for (unsigned int i = 0; i < p2->Contour.size(); i++) {
Vector2 cur = Vector2(p2->Contour[i].X / PRECISION, p2->Contour[i].Y / PRECISION);
if (cur.distance_to(prev) > 0.5) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index fcbbee2b9c..40781908fd 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -30,9 +30,9 @@
#include "sprite_frames_editor_plugin.h"
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
#include "editor/editor_settings.h"
-#include "io/resource_loader.h"
-#include "project_settings.h"
#include "scene/3d/sprite_3d.h"
void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
@@ -548,7 +548,6 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
} else {
hide();
- //set_physics_process(false);
}
}
@@ -816,16 +815,26 @@ SpriteFramesEditor::SpriteFramesEditor() {
void SpriteFramesEditorPlugin::edit(Object *p_object) {
frames_editor->set_undo_redo(&get_undo_redo());
- SpriteFrames *s = Object::cast_to<SpriteFrames>(p_object);
- if (!s)
- return;
+
+ SpriteFrames *s;
+ AnimatedSprite *animated_sprite = Object::cast_to<AnimatedSprite>(p_object);
+ if (animated_sprite) {
+ s = *animated_sprite->get_sprite_frames();
+ } else {
+ s = Object::cast_to<SpriteFrames>(p_object);
+ }
frames_editor->edit(s);
}
bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("SpriteFrames");
+ AnimatedSprite *animated_sprite = Object::cast_to<AnimatedSprite>(p_object);
+ if (animated_sprite && *animated_sprite->get_sprite_frames()) {
+ return true;
+ } else {
+ return p_object->is_class("SpriteFrames");
+ }
}
void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
@@ -833,14 +842,11 @@ void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
button->show();
editor->make_bottom_panel_item_visible(frames_editor);
- //frames_editor->set_process(true);
} else {
button->hide();
if (frames_editor->is_visible_in_tree())
editor->hide_bottom_panel();
-
- //frames_editor->set_process(false);
}
}
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 16c25f3074..4a8eae1ba4 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -30,6 +30,8 @@
#include "text_editor.h"
+#include "editor_node.h"
+
void TextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
highlighters[p_highlighter->get_name()] = p_highlighter;
highlighter_menu->add_radio_check_item(p_highlighter->get_name());
@@ -64,6 +66,7 @@ void TextEditor::_change_syntax_highlighter(int p_idx) {
el = el->next();
}
set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
+ EditorSettings::get_singleton()->set_project_metadata("text_editor", "syntax_highlighter", p_idx);
}
void TextEditor::_load_theme_settings() {
@@ -128,7 +131,7 @@ void TextEditor::_load_theme_settings() {
text_edit->add_color_override("search_result_border_color", search_result_border_color);
text_edit->add_color_override("symbol_color", symbol_color);
- text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 4));
+ text_edit->add_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6));
colors_cache.font_color = text_color;
colors_cache.symbol_color = symbol_color;
@@ -158,10 +161,7 @@ String TextEditor::get_name() {
Ref<Texture> TextEditor::get_icon() {
- if (get_parent_control() && get_parent_control()->has_icon(text_file->get_class(), "EditorIcons")) {
- return get_parent_control()->get_icon(text_file->get_class(), "EditorIcons");
- }
- return Ref<Texture>();
+ return EditorNode::get_singleton()->get_object_icon(text_file.operator->(), "");
}
RES TextEditor::get_edited_resource() const {
@@ -299,7 +299,7 @@ void TextEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY:
_load_theme_settings();
- set_syntax_highlighter(NULL);
+ _change_syntax_highlighter(EditorSettings::get_singleton()->get_project_metadata("text_editor", "syntax_highlighter", 0));
break;
}
}
@@ -360,7 +360,7 @@ void TextEditor::_edit_option(int p_op) {
} break;
case EDIT_CLONE_DOWN: {
- code_editor->code_lines_down();
+ code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
@@ -475,7 +475,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 seleted text
+ // Right click is outside the selected text
tx->deselect();
}
}
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index e891850870..140d37fdb5 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -30,9 +30,9 @@
#include "texture_editor_plugin.h"
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
#include "editor/editor_settings.h"
-#include "io/resource_loader.h"
-#include "project_settings.h"
void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
}
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 4390b94ece..7c3e524d89 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -31,8 +31,8 @@
#include "texture_region_editor_plugin.h"
#include "core/core_string_names.h"
-#include "os/input.h"
-#include "os/keyboard.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "scene/gui/check_box.h"
/**
@@ -846,7 +846,8 @@ TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) {
p->set_item_checked(0, true);
p->connect("id_pressed", this, "_set_snap_mode");
hb_grid = memnew(HBoxContainer);
- hb_tools->add_child(hb_grid);
+ //hb_tools->add_child(hb_grid);
+ main_vb->add_child(hb_grid);
hb_grid->add_child(memnew(VSeparator));
hb_grid->add_child(memnew(Label(TTR("Offset:"))));
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 92b95963f9..acee1a6942 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -30,8 +30,8 @@
#include "theme_editor_plugin.h"
-#include "os/file_access.h"
-#include "version.h"
+#include "core/os/file_access.h"
+#include "core/version.h"
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 598f7034d8..213cd2ce1a 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -31,10 +31,11 @@
#include "tile_map_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
+#include "core/math/math_funcs.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/gui/split_container.h"
void TileMapEditor::_notification(int p_what) {
@@ -43,8 +44,8 @@ void TileMapEditor::_notification(int p_what) {
case NOTIFICATION_PROCESS: {
- if (bucket_queue.size() && canvas_item_editor) {
- canvas_item_editor->update();
+ if (bucket_queue.size()) {
+ CanvasItemEditor::get_singleton()->update_viewport();
}
} break;
@@ -65,13 +66,11 @@ void TileMapEditor::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- transp->set_icon(get_icon("Transpose", "EditorIcons"));
- mirror_x->set_icon(get_icon("MirrorX", "EditorIcons"));
- mirror_y->set_icon(get_icon("MirrorY", "EditorIcons"));
- rotate_0->set_icon(get_icon("Rotate0", "EditorIcons"));
- rotate_90->set_icon(get_icon("Rotate90", "EditorIcons"));
- rotate_180->set_icon(get_icon("Rotate180", "EditorIcons"));
- rotate_270->set_icon(get_icon("Rotate270", "EditorIcons"));
+ rotate_left_button->set_icon(get_icon("Rotate270", "EditorIcons"));
+ rotate_right_button->set_icon(get_icon("Rotate90", "EditorIcons"));
+ flip_horizontal_button->set_icon(get_icon("MirrorX", "EditorIcons"));
+ flip_vertical_button->set_icon(get_icon("MirrorY", "EditorIcons"));
+ clear_transform_button->set_icon(get_icon("Clear", "EditorIcons"));
search_box->set_right_icon(get_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
@@ -97,27 +96,27 @@ void TileMapEditor::_menu_option(int p_option) {
// immediately without pressing the left mouse button first
tool = TOOL_NONE;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_BUCKET: {
tool = TOOL_BUCKET;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_PICK_TILE: {
tool = TOOL_PICKING;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_SELECT: {
tool = TOOL_SELECTING;
selection_active = false;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_COPY: {
@@ -126,7 +125,7 @@ void TileMapEditor::_menu_option(int p_option) {
if (selection_active) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
} break;
case OPTION_ERASE_SELECTION: {
@@ -141,7 +140,7 @@ void TileMapEditor::_menu_option(int p_option) {
selection_active = false;
copydata.clear();
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_FIX_INVALID: {
@@ -165,7 +164,7 @@ void TileMapEditor::_menu_option(int p_option) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
} break;
}
@@ -182,13 +181,13 @@ void TileMapEditor::_palette_multi_selected(int index, bool selected) {
void TileMapEditor::_canvas_mouse_enter() {
mouse_over = true;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
void TileMapEditor::_canvas_mouse_exit() {
mouse_over = false;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
Vector<int> TileMapEditor::get_selected_tiles() const {
@@ -238,8 +237,8 @@ void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_
cell_new["transpose"] = p_cell_new.tr;
cell_new["auto_coord"] = p_cell_new.ac;
- undo_redo->add_undo_method(node, "set_celld", p_vec, cell_old);
- undo_redo->add_do_method(node, "set_celld", p_vec, cell_new);
+ undo_redo->add_undo_method(node, "_set_celld", p_vec, cell_old);
+ undo_redo->add_do_method(node, "_set_celld", p_vec, cell_new);
}
void TileMapEditor::_start_undo(const String &p_action) {
@@ -301,7 +300,7 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p
}
node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
- if (manual_autotile || node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE) {
+ if (manual_autotile || (p_value != -1 && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE)) {
if (current != -1) {
node->set_cell_autotile_coord(p_pos.x, p_pos.y, position);
}
@@ -318,7 +317,7 @@ void TileMapEditor::_manual_toggled(bool p_enabled) {
void TileMapEditor::_text_entered(const String &p_text) {
- canvas_item_editor->grab_focus();
+ canvas_item_editor_viewport->grab_focus();
}
void TileMapEditor::_text_changed(const String &p_text) {
@@ -357,6 +356,10 @@ void TileMapEditor::_update_palette() {
if (!node)
return;
+ // Update the clear button
+ clear_transform_button->set_disabled(!flip_h && !flip_v && !transpose);
+
+ // Update the palette
Vector<int> selected = get_selected_tiles();
palette->clear();
manual_palette->clear();
@@ -429,9 +432,6 @@ void TileMapEditor::_update_palette() {
Ref<Texture> tex = tileset->tile_get_texture(entries[i].id);
if (tex.is_valid()) {
- Color color = tileset->tile_get_modulate(entries[i].id);
- palette->set_item_icon_modulate(palette->get_item_count() - 1, color);
-
Rect2 region = tileset->tile_get_region(entries[i].id);
if (tileset->tile_get_tile_mode(entries[i].id) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(entries[i].id) == TileSet::ATLAS_TILE) {
@@ -440,10 +440,25 @@ void TileMapEditor::_update_palette() {
region.position += (region.size + Vector2(spacing, spacing)) * tileset->autotile_get_icon_coordinate(entries[i].id);
}
- if (!region.has_no_area())
+ // Transpose and flip
+ palette->set_item_icon_transposed(palette->get_item_count() - 1, transpose);
+ if (flip_h) {
+ region.size.x = -region.size.x;
+ }
+ if (flip_v) {
+ region.size.y = -region.size.y;
+ }
+
+ // Set region
+ if (region.size != Size2())
palette->set_item_icon_region(palette->get_item_count() - 1, region);
+ // Set icon
palette->set_item_icon(palette->get_item_count() - 1, tex);
+
+ // Modulation
+ Color color = tileset->tile_get_modulate(entries[i].id);
+ palette->set_item_icon_modulate(palette->get_item_count() - 1, color);
}
palette->set_item_metadata(palette->get_item_count() - 1, entries[i].id);
@@ -519,12 +534,12 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) {
selected.push_back(id);
set_selected_tiles(selected);
- mirror_x->set_pressed(node->is_cell_x_flipped(p_pos.x, p_pos.y));
- mirror_y->set_pressed(node->is_cell_y_flipped(p_pos.x, p_pos.y));
- transp->set_pressed(node->is_cell_transposed(p_pos.x, p_pos.y));
+ flip_h = node->is_cell_x_flipped(p_pos.x, p_pos.y);
+ flip_v = node->is_cell_y_flipped(p_pos.x, p_pos.y);
+ transpose = node->is_cell_transposed(p_pos.x, p_pos.y);
- _update_transform_buttons();
- canvas_item_editor->update();
+ _update_palette();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, bool preview) {
@@ -671,7 +686,7 @@ void TileMapEditor::_select(const Point2i &p_from, const Point2i &p_to) {
rectangle.position = begin;
rectangle.size = end - begin;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
void TileMapEditor::_erase_selection() {
@@ -686,7 +701,7 @@ void TileMapEditor::_erase_selection() {
}
}
-void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) {
+void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) {
Ref<Texture> t = node->get_tileset()->tile_get_texture(p_cell);
@@ -783,19 +798,19 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h
modulate.a = 0.5;
if (r.has_no_area())
- canvas_item_editor->draw_texture_rect(t, rect, false, modulate, p_transpose);
+ p_viewport->draw_texture_rect(t, rect, false, modulate, p_transpose);
else
- canvas_item_editor->draw_texture_rect_region(t, rect, r, modulate, p_transpose);
+ p_viewport->draw_texture_rect_region(t, rect, r, modulate, p_transpose);
}
-void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) {
+void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform) {
PoolVector<Vector2> points = _bucket_fill(p_point, false, true);
PoolVector<Vector2>::Read pr = points.read();
int len = points.size();
for (int i = 0; i < len; ++i) {
- _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform);
+ _draw_cell(p_viewport, p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform);
}
}
@@ -978,7 +993,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
paint_undo.clear();
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
@@ -995,7 +1010,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
_finish_undo();
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
} else if (tool == TOOL_PASTING) {
@@ -1011,12 +1026,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
_finish_undo();
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true; // We want to keep the Pasting tool
} else if (tool == TOOL_SELECTING) {
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
} else if (tool == TOOL_BUCKET) {
@@ -1055,7 +1070,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
selection_active = false;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1065,7 +1080,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
copydata.clear();
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1106,7 +1121,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_finish_undo();
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
tool = TOOL_NONE;
@@ -1149,7 +1164,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (new_over_tile != over_tile) {
over_tile = new_over_tile;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
if (show_tile_info) {
@@ -1235,7 +1250,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_set_cell(points[i], invalid_cell);
}
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
return true;
@@ -1294,7 +1309,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_NONE;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1308,13 +1323,13 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// NOTE: We do not set tool = TOOL_PAINTING as this begins painting
// immediately without pressing the left mouse button first
tool = TOOL_NONE;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/bucket_fill", p_event)) {
tool = TOOL_BUCKET;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1327,7 +1342,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_SELECTING;
selection_active = false;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1337,7 +1352,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (selection_active) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
@@ -1354,7 +1369,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_PASTING;
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
}
@@ -1366,23 +1381,20 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) {
flip_h = !flip_h;
- mirror_x->set_pressed(flip_h);
- _update_transform_buttons();
- canvas_item_editor->update();
+ _update_palette();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) {
flip_v = !flip_v;
- mirror_y->set_pressed(flip_v);
- _update_transform_buttons();
- canvas_item_editor->update();
+ _update_palette();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) {
transpose = !transpose;
- transp->set_pressed(transpose);
- _update_transform_buttons();
- canvas_item_editor->update();
+ _update_palette();
+ CanvasItemEditor::get_singleton()->update_viewport();
return true;
}
}
@@ -1390,17 +1402,16 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
+void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
if (!node)
return;
Transform2D cell_xf = node->get_cell_transform();
-
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Transform2D xform_inv = xform.affine_inverse();
- Size2 screen_size = canvas_item_editor->get_size();
+ Size2 screen_size = p_overlay->get_size();
{
Rect2 aabb;
aabb.position = node->world_to_map(xform_inv.xform(Vector2()));
@@ -1419,7 +1430,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
Vector2 to = xform.xform(node->map_to_world(Vector2(i, si.position.y + si.size.y + 1)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
- canvas_item_editor->draw_line(from, to, col, 1);
+ p_overlay->draw_line(from, to, col, 1);
if (max_lines-- == 0)
break;
}
@@ -1439,7 +1450,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
Vector2 from = xform.xform(node->map_to_world(Vector2(i, j), true) + ofs);
Vector2 to = xform.xform(node->map_to_world(Vector2(i, j + 1), true) + ofs);
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
- canvas_item_editor->draw_line(from, to, col, 1);
+ p_overlay->draw_line(from, to, col, 1);
if (max_lines-- == 0)
break;
@@ -1457,7 +1468,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
Vector2 to = xform.xform(node->map_to_world(Vector2(si.position.x + si.size.x + 1, i)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
- canvas_item_editor->draw_line(from, to, col, 1);
+ p_overlay->draw_line(from, to, col, 1);
if (max_lines-- == 0)
break;
@@ -1476,7 +1487,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
Vector2 from = xform.xform(node->map_to_world(Vector2(j, i), true) + ofs);
Vector2 to = xform.xform(node->map_to_world(Vector2(j + 1, i), true) + ofs);
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
- canvas_item_editor->draw_line(from, to, col, 1);
+ p_overlay->draw_line(from, to, col, 1);
if (max_lines-- == 0)
break;
@@ -1493,7 +1504,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(rectangle.size.x + 1, rectangle.size.y + 1)))));
points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(0, rectangle.size.y + 1)))));
- canvas_item_editor->draw_colored_polygon(points, Color(0.2, 0.8, 1, 0.4));
+ p_overlay->draw_colored_polygon(points, Color(0.2, 0.8, 1, 0.4));
}
if (mouse_over) {
@@ -1519,7 +1530,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
col = Color(1.0, 0.4, 0.2, 0.8);
for (int i = 0; i < 4; i++)
- canvas_item_editor->draw_line(endpoints[i], endpoints[(i + 1) % 4], col, 2);
+ p_overlay->draw_line(endpoints[i], endpoints[(i + 1) % 4], col, 2);
bool bucket_preview = EditorSettings::get_singleton()->get("editors/tile_map/bucket_fill_preview");
if (tool == TOOL_SELECTING || tool == TOOL_PICKING || !bucket_preview) {
@@ -1538,7 +1549,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- _draw_cell(ids[0], E->key(), flip_h, flip_v, transpose, xform);
+ _draw_cell(p_overlay, ids[0], E->key(), flip_h, flip_v, transpose, xform);
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
@@ -1551,7 +1562,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
- _draw_cell(ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform);
+ _draw_cell(p_overlay, ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform);
}
}
} else if (tool == TOOL_PASTING) {
@@ -1573,7 +1584,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
TileData tcd = E->get();
- _draw_cell(tcd.cell, tcd.pos + ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform);
+ _draw_cell(p_overlay, tcd.cell, tcd.pos + ofs, tcd.flip_h, tcd.flip_v, tcd.transpose, xform);
}
Rect2i duplicate = rectangle;
@@ -1585,12 +1596,12 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(duplicate.size.x + 1, duplicate.size.y + 1)))));
points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(0, duplicate.size.y + 1)))));
- canvas_item_editor->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2));
+ p_overlay->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2));
} else if (tool == TOOL_BUCKET) {
Vector<int> tiles = get_selected_tiles();
- _draw_fill_preview(tiles[0], over_tile, flip_h, flip_v, transpose, xform);
+ _draw_fill_preview(p_overlay, tiles[0], over_tile, flip_h, flip_v, transpose, xform);
} else {
@@ -1599,7 +1610,7 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
if (st.size() == 1 && st[0] == TileMap::INVALID_CELL)
return;
- _draw_cell(st[0], over_tile, flip_h, flip_v, transpose, xform);
+ _draw_cell(p_overlay, st[0], over_tile, flip_h, flip_v, transpose, xform);
}
}
}
@@ -1608,8 +1619,8 @@ void TileMapEditor::edit(Node *p_tile_map) {
search_box->set_text("");
- if (!canvas_item_editor) {
- canvas_item_editor = CanvasItemEditor::get_singleton()->get_viewport_control();
+ if (!canvas_item_editor_viewport) {
+ canvas_item_editor_viewport = CanvasItemEditor::get_singleton()->get_viewport_control();
}
if (node)
@@ -1617,20 +1628,20 @@ void TileMapEditor::edit(Node *p_tile_map) {
if (p_tile_map) {
node = Object::cast_to<TileMap>(p_tile_map);
- if (!canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
- canvas_item_editor->connect("mouse_entered", this, "_canvas_mouse_enter");
- if (!canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
- canvas_item_editor->connect("mouse_exited", this, "_canvas_mouse_exit");
+ if (!canvas_item_editor_viewport->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
+ canvas_item_editor_viewport->connect("mouse_entered", this, "_canvas_mouse_enter");
+ if (!canvas_item_editor_viewport->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
+ canvas_item_editor_viewport->connect("mouse_exited", this, "_canvas_mouse_exit");
_update_palette();
} else {
node = NULL;
- if (canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
- canvas_item_editor->disconnect("mouse_entered", this, "_canvas_mouse_enter");
- if (canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
- canvas_item_editor->disconnect("mouse_exited", this, "_canvas_mouse_exit");
+ if (canvas_item_editor_viewport->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
+ canvas_item_editor_viewport->disconnect("mouse_entered", this, "_canvas_mouse_enter");
+ if (canvas_item_editor_viewport->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
+ canvas_item_editor_viewport->disconnect("mouse_exited", this, "_canvas_mouse_exit");
_update_palette();
}
@@ -1644,9 +1655,7 @@ void TileMapEditor::edit(Node *p_tile_map) {
void TileMapEditor::_tileset_settings_changed() {
_update_palette();
-
- if (canvas_item_editor)
- canvas_item_editor->update();
+ CanvasItemEditor::get_singleton()->update_viewport();
}
void TileMapEditor::_icon_size_changed(float p_value) {
@@ -1667,7 +1676,10 @@ void TileMapEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_canvas_mouse_enter"), &TileMapEditor::_canvas_mouse_enter);
ClassDB::bind_method(D_METHOD("_canvas_mouse_exit"), &TileMapEditor::_canvas_mouse_exit);
ClassDB::bind_method(D_METHOD("_tileset_settings_changed"), &TileMapEditor::_tileset_settings_changed);
- ClassDB::bind_method(D_METHOD("_update_transform_buttons"), &TileMapEditor::_update_transform_buttons);
+ ClassDB::bind_method(D_METHOD("_rotate"), &TileMapEditor::_rotate);
+ ClassDB::bind_method(D_METHOD("_flip_horizontal"), &TileMapEditor::_flip_horizontal);
+ ClassDB::bind_method(D_METHOD("_flip_vertical"), &TileMapEditor::_flip_vertical);
+ ClassDB::bind_method(D_METHOD("_clear_transform"), &TileMapEditor::_clear_transform);
ClassDB::bind_method(D_METHOD("_palette_selected"), &TileMapEditor::_palette_selected);
ClassDB::bind_method(D_METHOD("_palette_multi_selected"), &TileMapEditor::_palette_multi_selected);
@@ -1692,37 +1704,67 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i &p_pos) {
return op;
}
-void TileMapEditor::_update_transform_buttons(Object *p_button) {
- //ERR_FAIL_NULL(p_button);
- ToolButton *b = Object::cast_to<ToolButton>(p_button);
- //ERR_FAIL_COND(!b);
-
- if (b == rotate_0) {
- mirror_x->set_pressed(false);
- mirror_y->set_pressed(false);
- transp->set_pressed(false);
- } else if (b == rotate_90) {
- mirror_x->set_pressed(true);
- mirror_y->set_pressed(false);
- transp->set_pressed(true);
- } else if (b == rotate_180) {
- mirror_x->set_pressed(true);
- mirror_y->set_pressed(true);
- transp->set_pressed(false);
- } else if (b == rotate_270) {
- mirror_x->set_pressed(false);
- mirror_y->set_pressed(true);
- transp->set_pressed(true);
+void TileMapEditor::_rotate(int steps) {
+ const bool normal_rotation_matrix[][3] = {
+ { false, false, false },
+ { true, true, false },
+ { false, true, true },
+ { true, false, true }
+ };
+
+ const bool mirrored_rotation_matrix[][3] = {
+ { false, true, false },
+ { true, true, true },
+ { false, false, true },
+ { true, false, false }
+ };
+
+ if (transpose ^ flip_h ^ flip_v) {
+ // Odd number of flags activated = mirrored rotation
+ for (int i = 0; i < 4; i++) {
+ if (transpose == mirrored_rotation_matrix[i][0] &&
+ flip_h == mirrored_rotation_matrix[i][1] &&
+ flip_v == mirrored_rotation_matrix[i][2]) {
+ int new_id = Math::wrapi(i + steps, 0, 4);
+ transpose = mirrored_rotation_matrix[new_id][0];
+ flip_h = mirrored_rotation_matrix[new_id][1];
+ flip_v = mirrored_rotation_matrix[new_id][2];
+ break;
+ }
+ }
+ } else {
+ // Even number of flags activated = normal rotation
+ for (int i = 0; i < 4; i++) {
+ if (transpose == normal_rotation_matrix[i][0] &&
+ flip_h == normal_rotation_matrix[i][1] &&
+ flip_v == normal_rotation_matrix[i][2]) {
+ int new_id = Math::wrapi(i + steps, 0, 4);
+ transpose = normal_rotation_matrix[new_id][0];
+ flip_h = normal_rotation_matrix[new_id][1];
+ flip_v = normal_rotation_matrix[new_id][2];
+ break;
+ }
+ }
}
- flip_h = mirror_x->is_pressed();
- flip_v = mirror_y->is_pressed();
- transpose = transp->is_pressed();
+ _update_palette();
+}
+
+void TileMapEditor::_flip_horizontal() {
+ flip_h = !flip_h;
+ _update_palette();
+}
+
+void TileMapEditor::_flip_vertical() {
+ flip_v = !flip_v;
+ _update_palette();
+}
- rotate_0->set_pressed(!flip_h && !flip_v && !transpose);
- rotate_90->set_pressed(flip_h && !flip_v && transpose);
- rotate_180->set_pressed(flip_h && flip_v && !transpose);
- rotate_270->set_pressed(!flip_h && flip_v && transpose);
+void TileMapEditor::_clear_transform() {
+ transpose = false;
+ flip_h = false;
+ flip_v = false;
+ _update_palette();
}
TileMapEditor::TileMapEditor(EditorNode *p_editor) {
@@ -1730,7 +1772,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
node = NULL;
manual_autotile = false;
manual_position = Vector2(0, 0);
- canvas_item_editor = NULL;
+ canvas_item_editor_viewport = NULL;
editor = p_editor;
undo_redo = editor->get_undo_redo();
@@ -1755,10 +1797,8 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A);
ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S);
- HBoxContainer *tool_hb1 = memnew(HBoxContainer);
- add_child(tool_hb1);
- HBoxContainer *tool_hb2 = memnew(HBoxContainer);
- add_child(tool_hb2);
+ HBoxContainer *tool_hb = memnew(HBoxContainer);
+ add_child(tool_hb);
manual_button = memnew(CheckBox);
manual_button->set_text("Disable Autotile");
@@ -1843,52 +1883,37 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
p->connect("id_pressed", this, "_menu_option");
toolbar->add_child(options);
-
- transp = memnew(ToolButton);
- transp->set_toggle_mode(true);
- transp->set_tooltip(TTR("Transpose") + " (" + ED_GET_SHORTCUT("tile_map_editor/transpose")->get_as_text() + ")");
- transp->set_focus_mode(FOCUS_NONE);
- transp->connect("pressed", this, "_update_transform_buttons", make_binds(transp));
- tool_hb1->add_child(transp);
- mirror_x = memnew(ToolButton);
- mirror_x->set_toggle_mode(true);
- mirror_x->set_tooltip(TTR("Mirror X") + " (" + ED_GET_SHORTCUT("tile_map_editor/mirror_x")->get_as_text() + ")");
- mirror_x->set_focus_mode(FOCUS_NONE);
- mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x));
- tool_hb1->add_child(mirror_x);
- mirror_y = memnew(ToolButton);
- mirror_y->set_toggle_mode(true);
- mirror_y->set_tooltip(TTR("Mirror Y") + " (" + ED_GET_SHORTCUT("tile_map_editor/mirror_y")->get_as_text() + ")");
- mirror_y->set_focus_mode(FOCUS_NONE);
- mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y));
- tool_hb1->add_child(mirror_y);
-
- rotate_0 = memnew(ToolButton);
- rotate_0->set_toggle_mode(true);
- rotate_0->set_tooltip(TTR("Rotate 0 degrees"));
- rotate_0->set_focus_mode(FOCUS_NONE);
- rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0));
- tool_hb2->add_child(rotate_0);
- rotate_90 = memnew(ToolButton);
- rotate_90->set_toggle_mode(true);
- rotate_90->set_tooltip(TTR("Rotate 90 degrees"));
- rotate_90->set_focus_mode(FOCUS_NONE);
- rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90));
- tool_hb2->add_child(rotate_90);
- rotate_180 = memnew(ToolButton);
- rotate_180->set_toggle_mode(true);
- rotate_180->set_tooltip(TTR("Rotate 180 degrees"));
- rotate_180->set_focus_mode(FOCUS_NONE);
- rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180));
- tool_hb2->add_child(rotate_180);
- rotate_270 = memnew(ToolButton);
- rotate_270->set_toggle_mode(true);
- rotate_270->set_tooltip(TTR("Rotate 270 degrees"));
- rotate_270->set_focus_mode(FOCUS_NONE);
- rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270));
- tool_hb2->add_child(rotate_270);
-
- rotate_0->set_pressed(true);
+ rotate_left_button = memnew(ToolButton);
+ rotate_left_button->set_tooltip(TTR("Rotate left"));
+ rotate_left_button->set_focus_mode(FOCUS_NONE);
+ rotate_left_button->connect("pressed", this, "_rotate", varray(-1));
+ tool_hb->add_child(rotate_left_button);
+
+ rotate_right_button = memnew(ToolButton);
+ rotate_right_button->set_tooltip(TTR("Rotate right"));
+ rotate_right_button->set_focus_mode(FOCUS_NONE);
+ rotate_right_button->connect("pressed", this, "_rotate", varray(1));
+ tool_hb->add_child(rotate_right_button);
+
+ flip_horizontal_button = memnew(ToolButton);
+ flip_horizontal_button->set_tooltip(TTR("Flip horizontally"));
+ flip_horizontal_button->set_focus_mode(FOCUS_NONE);
+ flip_horizontal_button->connect("pressed", this, "_flip_horizontal");
+ tool_hb->add_child(flip_horizontal_button);
+
+ flip_vertical_button = memnew(ToolButton);
+ flip_vertical_button->set_tooltip(TTR("Flip vertically"));
+ flip_vertical_button->set_focus_mode(FOCUS_NONE);
+ flip_vertical_button->connect("pressed", this, "_flip_vertical");
+ tool_hb->add_child(flip_vertical_button);
+
+ clear_transform_button = memnew(ToolButton);
+ clear_transform_button->set_tooltip(TTR("Clear transform"));
+ clear_transform_button->set_focus_mode(FOCUS_NONE);
+ clear_transform_button->connect("pressed", this, "_clear_transform");
+ tool_hb->add_child(clear_transform_button);
+
+ clear_transform_button->set_disabled(true);
}
TileMapEditor::~TileMapEditor() {
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index c824824d56..68e5806ee5 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -82,7 +82,7 @@ class TileMapEditor : public VBoxContainer {
EditorNode *editor;
UndoRedo *undo_redo;
- Control *canvas_item_editor;
+ Control *canvas_item_editor_viewport;
LineEdit *search_box;
HSlider *size_slider;
@@ -93,13 +93,13 @@ class TileMapEditor : public VBoxContainer {
Label *tile_info;
MenuButton *options;
- ToolButton *transp;
- ToolButton *mirror_x;
- ToolButton *mirror_y;
- ToolButton *rotate_0;
- ToolButton *rotate_90;
- ToolButton *rotate_180;
- ToolButton *rotate_270;
+
+ ToolButton *flip_horizontal_button;
+ ToolButton *flip_vertical_button;
+ ToolButton *rotate_left_button;
+ ToolButton *rotate_right_button;
+ ToolButton *clear_transform_button;
+
CheckBox *manual_button;
Tool tool;
@@ -168,8 +168,8 @@ class TileMapEditor : public VBoxContainer {
void _select(const Point2i &p_from, const Point2i &p_to);
void _erase_selection();
- void _draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform);
- void _draw_fill_preview(int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform);
+ void _draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform);
+ void _draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Transform2D &p_xform);
void _clear_bucket_cache();
void _update_copydata();
@@ -196,17 +196,21 @@ class TileMapEditor : public VBoxContainer {
void _tileset_settings_changed();
void _icon_size_changed(float p_value);
+ void _clear_transform();
+ void _flip_horizontal();
+ void _flip_vertical();
+ void _rotate(int steps);
+
protected:
void _notification(int p_what);
static void _bind_methods();
CellOp _get_op_from_cell(const Point2i &p_pos);
- void _update_transform_buttons(Object *p_button = NULL);
public:
HBoxContainer *get_toolbar() const { return toolbar; }
bool forward_gui_input(const Ref<InputEvent> &p_event);
- void forward_draw_over_viewport(Control *p_overlay);
+ void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(Node *p_tile_map);
@@ -225,7 +229,7 @@ protected:
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); }
- virtual void forward_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { tile_map_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "TileMap"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index f981ead7eb..d0e0b3e006 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -483,6 +483,11 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
//---------------
helper = memnew(TilesetEditorContext(this));
tile_names_opacity = 0;
+
+ // config scale
+ max_scale = 10.0f;
+ min_scale = 0.1f;
+ scale_ratio = 1.2f;
}
TileSetEditor::~TileSetEditor() {
@@ -569,6 +574,10 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
int invalid_count = 0;
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());
+
if (texture_map.has(t->get_rid())) {
invalid_count++;
} else {
@@ -577,11 +586,15 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
texture_list->set_item_metadata(texture_list->get_item_count() - 1, t->get_rid());
}
}
- update_texture_list_icon();
- texture_list->select(texture_list->get_item_count() - 1);
- _on_texture_list_selected(texture_list->get_item_count() - 1);
+
+ if (texture_list->get_item_count() > 0) {
+ update_texture_list_icon();
+ texture_list->select(texture_list->get_item_count() - 1);
+ _on_texture_list_selected(texture_list->get_item_count() - 1);
+ }
+
if (invalid_count > 0) {
- err_dialog->set_text(String::num(invalid_count, 0) + TTR(" file(s) was not added because was already on the list."));
+ err_dialog->set_text(vformat(TTR("%s file(s) were not added because was already on the list."), String::num(invalid_count, 0)));
err_dialog->popup_centered(Size2(300, 60));
}
}
@@ -795,6 +808,7 @@ void TileSetEditor::_on_workspace_draw() {
spin_priority->set_suffix(" / " + String::num(total, 0));
draw_highlight_subtile(edited_shape_coord, queue_others);
} break;
+ default: {}
}
draw_tile_subdivision(get_current_tile(), Color(0.347214, 0.722656, 0.617063));
@@ -944,7 +958,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
Ref<InputEventMouseMotion> mm = p_ie;
if (mb.is_valid()) {
- if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && !creating_shape) {
if (!current_tile_region.has_point(mb->get_position())) {
List<int> *tiles = new List<int>();
tileset->get_tile_list(tiles);
@@ -963,6 +977,15 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
+
+ // Mouse Wheel Event
+ const int _mouse_button_index = mb->get_button_index();
+ if (_mouse_button_index == BUTTON_WHEEL_UP && mb->get_control()) {
+ _zoom_in();
+
+ } else if (_mouse_button_index == BUTTON_WHEEL_DOWN && mb->get_control()) {
+ _zoom_out();
+ }
}
// Drag Middle Mouse
if (mm.is_valid()) {
@@ -1365,6 +1388,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
} break;
+ default: {}
}
}
}
@@ -1434,26 +1458,15 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
workspace->update();
}
} break;
+ default: {}
}
}
} else if (p_tool == ZOOM_OUT) {
- float scale = workspace->get_scale().x;
- if (scale > 0.1) {
- scale /= 2;
- workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
- }
+ _zoom_out();
} else if (p_tool == ZOOM_1) {
- workspace->set_scale(Vector2(1, 1));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size);
+ _reset_zoom();
} else if (p_tool == ZOOM_IN) {
- float scale = workspace->get_scale().x;
- scale *= 2;
- workspace->set_scale(Vector2(scale, scale));
- workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
- workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ _zoom_in();
} else if (p_tool == TOOL_SELECT) {
if (creating_shape) {
// Cancel Creation
@@ -1492,6 +1505,31 @@ void TileSetEditor::_set_snap_sep(Vector2 p_val) {
workspace->update();
}
+void TileSetEditor::_zoom_in() {
+ float scale = workspace->get_scale().x;
+ if (scale < max_scale) {
+ scale *= scale_ratio;
+ workspace->set_scale(Vector2(scale, scale));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ }
+}
+void TileSetEditor::_zoom_out() {
+
+ float scale = workspace->get_scale().x;
+ if (scale > min_scale) {
+ scale /= scale_ratio;
+ workspace->set_scale(Vector2(scale, scale));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size * scale);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
+ }
+}
+void TileSetEditor::_reset_zoom() {
+ workspace->set_scale(Vector2(1, 1));
+ workspace_container->set_custom_minimum_size(workspace->get_rect().size);
+ workspace_overlay->set_custom_minimum_size(workspace->get_rect().size);
+}
+
void TileSetEditor::draw_highlight_current_tile() {
if (get_current_tile() >= 0) {
@@ -1862,6 +1900,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
}
} break;
+ default: {}
}
if (creating_shape) {
for (int j = 0; j < current_shape.size() - 1; j++) {
@@ -2072,13 +2111,24 @@ void TileSetEditor::update_texture_list() {
List<int> ids;
tileset->get_tile_list(&ids);
+ Vector<int> ids_to_remove;
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ // Clear tiles referencing gone textures (user has been already given the chance to fix broken deps)
+ if (!tileset->tile_get_texture(E->get()).is_valid()) {
+ ids_to_remove.push_back(E->get());
+ ERR_CONTINUE(!tileset->tile_get_texture(E->get()).is_valid());
+ }
+
if (!texture_map.has(tileset->tile_get_texture(E->get())->get_rid())) {
texture_list->add_item(tileset->tile_get_texture(E->get())->get_path().get_file());
texture_map.insert(tileset->tile_get_texture(E->get())->get_rid(), tileset->tile_get_texture(E->get()));
texture_list->set_item_metadata(texture_list->get_item_count() - 1, tileset->tile_get_texture(E->get())->get_rid());
}
}
+ for (int i = 0; i < ids_to_remove.size(); i++) {
+ tileset->remove_tile(ids_to_remove[i]);
+ }
+
if (texture_list->get_item_count() > 0 && selected_texture.is_valid()) {
texture_list->select(texture_list->find_metadata(selected_texture->get_rid()));
if (texture_list->get_selected_items().size() > 0)
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 23bf68b90f..bd8a2ddb98 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -141,6 +141,10 @@ class TileSetEditor : public Control {
EditMode edit_mode;
int current_tile;
+ float max_scale;
+ float min_scale;
+ float scale_ratio;
+
void update_texture_list();
void update_texture_list_icon();
@@ -178,6 +182,10 @@ private:
void _set_snap_off(Vector2 p_val);
void _set_snap_sep(Vector2 p_val);
+ void _zoom_in();
+ void _zoom_out();
+ void _reset_zoom();
+
void draw_highlight_current_tile();
void draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted = Vector<Vector2>());
void draw_tile_subdivision(int p_id, Color p_color) const;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 63e89b78ea..39e50ec7f8 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -1,10 +1,40 @@
+/*************************************************************************/
+/* visual_shader_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "visual_shader_editor_plugin.h"
#include "core/io/resource_loader.h"
+#include "core/os/input.h"
+#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/editor_properties.h"
-#include "os/input.h"
-#include "os/keyboard.h"
#include "scene/animation/animation_player.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
@@ -480,6 +510,17 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
}
undo_redo->create_action("Nodes Connected");
+
+ List<VisualShader::Connection> conns;
+ visual_shader->get_node_connections(type, &conns);
+
+ for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
+ if (E->get().to_node == to && E->get().to_port == p_to_index) {
+ undo_redo->add_do_method(visual_shader.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
+ }
+ }
+
undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from, p_from_index, to, p_to_index);
undo_redo->add_do_method(this, "_update_graph");
@@ -599,7 +640,7 @@ void VisualShaderEditor::_duplicate_nodes() {
int id = String(graph->get_child(i)->get_name()).to_int();
Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
Ref<VisualShaderNodeOutput> output = node;
- if (output.is_valid()) //cant duplicate output
+ if (output.is_valid()) //can't duplicate output
continue;
if (node.is_valid()) {
nodes.push_back(id);
@@ -902,7 +943,10 @@ public:
class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
GDCLASS(VisualShaderNodePluginDefaultEditor, VBoxContainer)
public:
- void _property_changed(const String &prop, const Variant &p_value) {
+ void _property_changed(const String &prop, const Variant &p_value, bool p_changing = false) {
+
+ if (p_changing)
+ return;
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
@@ -949,7 +993,7 @@ public:
}
static void _bind_methods() {
- ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed);
+ ClassDB::bind_method("_property_changed", &VisualShaderNodePluginDefaultEditor::_property_changed, DEFVAL(false));
ClassDB::bind_method("_node_changed", &VisualShaderNodePluginDefaultEditor::_node_changed);
ClassDB::bind_method("_refresh_request", &VisualShaderNodePluginDefaultEditor::_refresh_request);
}
@@ -1128,7 +1172,7 @@ bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::
return true;
}
- return false; //can be overriden, although it will most likely be last anyway
+ return false; //can be overridden, although it will most likely be last anyway
}
void EditorInspectorShaderModePlugin::parse_end() {
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index f86374ff6b..49a51ede8f 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* visual_shader_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef VISUAL_SHADER_EDITOR_PLUGIN_H
#define VISUAL_SHADER_EDITOR_PLUGIN_H