summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp141
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h64
-rw-r--r--editor/plugins/editor_debugger_plugin.cpp2
-rw-r--r--editor/plugins/editor_debugger_plugin.h2
-rw-r--r--editor/plugins/editor_preview_plugins.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp136
-rw-r--r--editor/plugins/node_3d_editor_plugin.h27
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp30
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h12
-rw-r--r--editor/plugins/script_text_editor.cpp29
-rw-r--r--editor/plugins/shader_editor_plugin.cpp6
-rw-r--r--editor/plugins/theme_editor_plugin.cpp57
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp5
-rw-r--r--editor/plugins/tiles/tile_data_editors.h2
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp689
-rw-r--r--editor/plugins/tiles/tile_map_editor.h35
-rw-r--r--editor/plugins/tiles/tile_proxies_manager_dialog.h2
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp26
-rw-r--r--editor/plugins/version_control_editor_plugin.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp86
23 files changed, 885 insertions, 475 deletions
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index cf9e94bd3b..16e224b105 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -81,8 +81,8 @@ public:
SnapDialog() {
const int SPIN_BOX_GRID_RANGE = 16384;
const int SPIN_BOX_ROTATION_RANGE = 360;
- const float SPIN_BOX_SCALE_MIN = 0.01f;
- const float SPIN_BOX_SCALE_MAX = 100;
+ const real_t SPIN_BOX_SCALE_MIN = 0.01;
+ const real_t SPIN_BOX_SCALE_MAX = 100;
Label *label;
VBoxContainer *container;
@@ -210,7 +210,7 @@ public:
child_container->add_child(scale_step);
}
- void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step, const float p_scale_step) {
+ void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const real_t p_rotation_offset, const real_t p_rotation_step, const real_t p_scale_step) {
grid_offset_x->set_value(p_grid_offset.x);
grid_offset_y->set_value(p_grid_offset.y);
grid_step_x->set_value(p_grid_step.x);
@@ -221,7 +221,7 @@ public:
scale_step->set_value(p_scale_step);
}
- void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step, float &p_scale_step) {
+ void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, real_t &p_rotation_offset, real_t &p_rotation_step, real_t &p_scale_step) {
p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_primary_grid_steps = int(primary_grid_steps->get_value());
@@ -249,12 +249,12 @@ bool CanvasItemEditor::_is_node_movable(const Node *p_node, bool p_popup_warning
}
void CanvasItemEditor::_snap_if_closer_float(
- float p_value,
- float &r_current_snap, SnapTarget &r_current_snap_target,
- float p_target_value, SnapTarget p_snap_target,
- float p_radius) {
- float radius = p_radius / zoom;
- float dist = Math::abs(p_value - p_target_value);
+ const real_t p_value,
+ real_t &r_current_snap, SnapTarget &r_current_snap_target,
+ const real_t p_target_value, const SnapTarget p_snap_target,
+ const real_t p_radius) {
+ const real_t radius = p_radius / zoom;
+ const real_t dist = Math::abs(p_value - p_target_value);
if ((p_radius < 0 || dist < radius) && (r_current_snap_target == SNAP_TARGET_NONE || dist < Math::abs(r_current_snap - p_value))) {
r_current_snap = p_target_value;
r_current_snap_target = p_snap_target;
@@ -264,9 +264,9 @@ void CanvasItemEditor::_snap_if_closer_float(
void CanvasItemEditor::_snap_if_closer_point(
Point2 p_value,
Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
- Point2 p_target_value, SnapTarget p_snap_target,
- real_t rotation,
- float p_radius) {
+ Point2 p_target_value, const SnapTarget p_snap_target,
+ const real_t rotation,
+ const real_t p_radius) {
Transform2D rot_trans = Transform2D(rotation, Point2());
p_value = rot_trans.inverse().xform(p_value);
p_target_value = rot_trans.inverse().xform(p_target_value);
@@ -459,7 +459,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
return output;
}
-float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
+real_t CanvasItemEditor::snap_angle(real_t p_target, real_t p_start) const {
if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CTRL)) && snap_rotation_step != 0) {
if (snap_relative) {
return Math::snapped(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
@@ -923,7 +923,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
}
// Hover over guides
- float minimum = 1e20;
+ real_t minimum = 1e20;
is_hovering_h_guide = false;
is_hovering_v_guide = false;
@@ -1264,7 +1264,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
if (pan_gesture.is_valid() && !p_already_accepted) {
// If ctrl key pressed, then zoom instead of pan.
if (pan_gesture->is_ctrl_pressed()) {
- const float factor = pan_gesture->get_delta().y;
+ const real_t factor = pan_gesture->get_delta().y;
zoom_widget->set_zoom_by_increments(1);
if (factor != 1.f) {
@@ -1490,9 +1490,9 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
anchor_pos[i] = (transform * control->get_global_transform_with_canvas()).xform(_anchor_to_position(control, anchor_pos[i]));
anchor_rects[i] = Rect2(anchor_pos[i], anchor_handle->get_size());
if (control->is_layout_rtl()) {
- anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 1 || i == 2), float(i <= 1));
+ anchor_rects[i].position -= anchor_handle->get_size() * Vector2(real_t(i == 1 || i == 2), real_t(i <= 1));
} else {
- anchor_rects[i].position -= anchor_handle->get_size() * Vector2(float(i == 0 || i == 3), float(i <= 1));
+ anchor_rects[i].position -= anchor_handle->get_size() * Vector2(real_t(i == 0 || i == 3), real_t(i <= 1));
}
}
@@ -1646,7 +1646,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
};
DragType resize_drag = DRAG_NONE;
- float radius = (select_handle->get_size().width / 2) * 1.5;
+ real_t radius = (select_handle->get_size().width / 2) * 1.5;
for (int i = 0; i < 4; i++) {
int prev = (i + 3) % 4;
@@ -1692,7 +1692,7 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
bool symmetric = m->is_alt_pressed();
Rect2 local_rect = canvas_item->_edit_get_rect();
- float aspect = local_rect.get_size().y / local_rect.get_size().x;
+ real_t aspect = local_rect.get_size().y / local_rect.get_size().x;
Point2 current_begin = local_rect.get_position();
Point2 current_end = local_rect.get_position() + local_rect.get_size();
Point2 max_begin = (symmetric) ? (current_begin + current_end - canvas_item->_edit_get_minimum_size()) / 2.0 : current_end - canvas_item->_edit_get_minimum_size();
@@ -1883,7 +1883,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Size2 scale = canvas_item->call("get_scale");
Size2 original_scale = scale;
- float ratio = scale.y / scale.x;
+ real_t ratio = scale.y / scale.x;
if (drag_type == DRAG_SCALE_BOTH) {
Size2 scale_factor = drag_to_local / drag_from_local;
if (uniform) {
@@ -2541,7 +2541,7 @@ void CanvasItemEditor::_update_cursor() {
List<CanvasItem *> selection = _get_edited_canvas_items();
if (selection.size() == 1) {
- float angle = Math::fposmod((double)selection[0]->get_global_transform_with_canvas().get_rotation(), Math_PI);
+ const double angle = Math::fposmod((double)selection[0]->get_global_transform_with_canvas().get_rotation(), Math_PI);
if (angle > Math_PI * 7.0 / 8.0) {
rotation_array_index = 0;
} else if (angle > Math_PI * 5.0 / 8.0) {
@@ -2647,7 +2647,7 @@ void CanvasItemEditor::_draw_margin_at_position(int p_value, Point2 p_position,
}
}
-void CanvasItemEditor::_draw_percentage_at_position(float p_value, Point2 p_position, Side p_side) {
+void CanvasItemEditor::_draw_percentage_at_position(real_t p_value, Point2 p_position, Side p_side) {
String str = TS->format_number(vformat("%.1f ", p_value * 100.0)) + TS->percent_sign();
if (p_value != 0) {
_draw_text_at_position(p_position, str, p_side);
@@ -2672,7 +2672,7 @@ void CanvasItemEditor::_draw_guides() {
if (drag_type == DRAG_V_GUIDE && i == dragged_guide_index) {
continue;
}
- float x = xform.xform(Point2(vguides[i], 0)).x;
+ real_t x = xform.xform(Point2(vguides[i], 0)).x;
viewport->draw_line(Point2(x, 0), Point2(x, viewport->get_size().y), guide_color, Math::round(EDSCALE));
}
}
@@ -2683,7 +2683,7 @@ void CanvasItemEditor::_draw_guides() {
if (drag_type == DRAG_H_GUIDE && i == dragged_guide_index) {
continue;
}
- float y = xform.xform(Point2(0, hguides[i])).y;
+ real_t y = xform.xform(Point2(0, hguides[i])).y;
viewport->draw_line(Point2(0, y), Point2(viewport->get_size().x, y), guide_color, Math::round(EDSCALE));
}
}
@@ -2747,7 +2747,7 @@ void CanvasItemEditor::_draw_rulers() {
ruler_transform.scale_basis(Point2(2, 2));
}
} else {
- float basic_rule = 100;
+ real_t basic_rule = 100;
for (int i = 0; basic_rule * zoom > 100; i++) {
basic_rule /= (i % 2) ? 5.0 : 2.0;
}
@@ -2776,7 +2776,7 @@ void CanvasItemEditor::_draw_rulers() {
Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).round();
if (i % (major_subdivision * minor_subdivision) == 0) {
viewport->draw_line(Point2(position.x, 0), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE));
- float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x;
+ real_t val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x;
viewport->draw_string(font, Point2(position.x + 2, font->get_height(font_size)), TS->format_number(vformat(((int)val == val) ? "%d" : "%.1f", val)), HALIGN_LEFT, -1, font_size, font_color);
} else {
if (i % minor_subdivision == 0) {
@@ -2793,7 +2793,7 @@ void CanvasItemEditor::_draw_rulers() {
Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).round();
if (i % (major_subdivision * minor_subdivision) == 0) {
viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color, Math::round(EDSCALE));
- float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y;
+ real_t val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y;
Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(font_size), position.y - 2));
viewport->draw_set_transform_matrix(viewport->get_transform() * text_xform);
@@ -2926,8 +2926,8 @@ void CanvasItemEditor::_draw_ruler_tool() {
viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
if (draw_secondary_lines) {
- const float horizontal_angle_rad = atan2(length_vector.y, length_vector.x);
- const float vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad;
+ const real_t horizontal_angle_rad = atan2(length_vector.y, length_vector.x);
+ const real_t vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad;
const int horizontal_angle = round(180 * horizontal_angle_rad / Math_PI);
const int vertical_angle = round(180 * vertical_angle_rad / Math_PI);
@@ -2963,28 +2963,28 @@ void CanvasItemEditor::_draw_ruler_tool() {
// Angle arcs
int arc_point_count = 8;
- float arc_radius_max_length_percent = 0.1;
- float ruler_length = length_vector.length() * zoom;
- float arc_max_radius = 50.0;
- float arc_line_width = 2.0;
+ real_t arc_radius_max_length_percent = 0.1;
+ real_t ruler_length = length_vector.length() * zoom;
+ real_t arc_max_radius = 50.0;
+ real_t arc_line_width = 2.0;
const Vector2 end_to_begin = (end - begin);
- float arc_1_start_angle =
+ real_t arc_1_start_angle =
end_to_begin.x < 0 ?
(end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 - vertical_angle_rad : Math_PI / 2.0) :
(end_to_begin.y < 0 ? 3.0 * Math_PI / 2.0 : Math_PI / 2.0 - vertical_angle_rad);
- float arc_1_end_angle = arc_1_start_angle + vertical_angle_rad;
+ real_t arc_1_end_angle = arc_1_start_angle + vertical_angle_rad;
// Constrain arc to triangle height & max size
- float arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius);
+ real_t arc_1_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.y)), arc_max_radius);
- float arc_2_start_angle =
+ real_t arc_2_start_angle =
end_to_begin.x < 0 ?
(end_to_begin.y < 0 ? 0.0 : -horizontal_angle_rad) :
(end_to_begin.y < 0 ? Math_PI - horizontal_angle_rad : Math_PI);
- float arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad;
+ real_t arc_2_end_angle = arc_2_start_angle + horizontal_angle_rad;
// Constrain arc to triangle width & max size
- float arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius);
+ real_t arc_2_radius = MIN(MIN(arc_radius_max_length_percent * ruler_length, ABS(end_to_begin.x)), arc_max_radius);
viewport->draw_arc(begin, arc_1_radius, arc_1_start_angle, arc_1_end_angle, arc_point_count, ruler_primary_color, Math::round(EDSCALE * arc_line_width));
viewport->draw_arc(end, arc_2_radius, arc_2_start_angle, arc_2_end_angle, arc_point_count, ruler_primary_color, Math::round(EDSCALE * arc_line_width));
@@ -3022,7 +3022,7 @@ void CanvasItemEditor::_draw_control_anchors(Control *control) {
RID ci = viewport->get_canvas_item();
if (tool == TOOL_SELECT && !Object::cast_to<Container>(control->get_parent())) {
// Compute the anchors
- float anchors_values[4];
+ real_t anchors_values[4];
anchors_values[0] = control->get_anchor(SIDE_LEFT);
anchors_values[1] = control->get_anchor(SIDE_TOP);
anchors_values[2] = control->get_anchor(SIDE_RIGHT);
@@ -3061,7 +3061,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
Color color_base = Color(0.8, 0.8, 0.8, 0.5);
// Compute the anchors
- float anchors_values[4];
+ real_t anchors_values[4];
anchors_values[0] = control->get_anchor(SIDE_LEFT);
anchors_values[1] = control->get_anchor(SIDE_TOP);
anchors_values[2] = control->get_anchor(SIDE_RIGHT);
@@ -3107,7 +3107,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
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];
+ real_t anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
line_starts[i] = corners_pos[i].lerp(corners_pos[(i + 1) % 4], anchor_val);
line_ends[i] = corners_pos[(i + 3) % 4].lerp(corners_pos[(i + 2) % 4], anchor_val);
anchor_snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
@@ -3115,7 +3115,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
}
// Display the percentages next to the lines
- float percent_val;
+ real_t 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, (Side)((dragged_anchor + 1) % 4));
@@ -3134,9 +3134,9 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
}
// Draw the margin values and the node width/height when dragging control side
- float ratio = 0.33;
+ const real_t ratio = 0.33;
Transform2D parent_transform = xform * control->get_transform().affine_inverse();
- float node_pos_in_parent[4];
+ real_t node_pos_in_parent[4];
Rect2 parent_rect = control->get_parent_anchorable_rect();
@@ -3453,10 +3453,10 @@ void CanvasItemEditor::_draw_straight_line(Point2 p_from, Point2 p_to, Color p_c
points.push_back(Point2(0, to.y));
points.push_back(Point2(viewport_size.x, to.y));
} else {
- float y_for_zero_x = (to.y * from.x - from.y * to.x) / (from.x - to.x);
- float x_for_zero_y = (to.x * from.y - from.x * to.y) / (from.y - to.y);
- float y_for_viewport_x = ((to.y - from.y) * (viewport_size.x - from.x)) / (to.x - from.x) + from.y;
- float x_for_viewport_y = ((to.x - from.x) * (viewport_size.y - from.y)) / (to.y - from.y) + from.x; // faux
+ real_t y_for_zero_x = (to.y * from.x - from.y * to.x) / (from.x - to.x);
+ real_t x_for_zero_y = (to.x * from.y - from.x * to.y) / (from.y - to.y);
+ real_t y_for_viewport_x = ((to.y - from.y) * (viewport_size.x - from.x)) / (to.x - from.x) + from.y;
+ real_t x_for_viewport_y = ((to.x - from.x) * (viewport_size.y - from.y)) / (to.y - from.y) + from.x; // faux
//bool start_set = false;
if (y_for_zero_x >= 0 && y_for_zero_x <= viewport_size.y) {
@@ -3602,7 +3602,7 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
RID viewport_canvas_item = viewport->get_canvas_item();
if (canvas_item) {
- float offset = 0;
+ real_t offset = 0;
Ref<Texture2D> lock = get_theme_icon(SNAME("LockViewport"), SNAME("EditorIcons"));
if (p_node->has_meta("_edit_lock_") && show_edit_locks) {
@@ -3726,7 +3726,7 @@ void CanvasItemEditor::_notification(int p_what) {
Control *control = Object::cast_to<Control>(canvas_item);
if (control) {
- float anchors[4];
+ real_t anchors[4];
Vector2 pivot;
pivot = control->get_pivot_offset();
@@ -4003,7 +4003,7 @@ void CanvasItemEditor::_update_scrollbars() {
bool constrain_editor_view = bool(EditorSettings::get_singleton()->get("editors/2d/constrain_editor_view"));
if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) {
- float centered = -(size.y / 2) / zoom + screen_rect.y / 2;
+ real_t centered = -(size.y / 2) / zoom + screen_rect.y / 2;
if (constrain_editor_view && ABS(centered - previous_update_view_offset.y) < ABS(centered - view_offset.y)) {
view_offset.y = previous_update_view_offset.y;
}
@@ -4024,7 +4024,7 @@ void CanvasItemEditor::_update_scrollbars() {
}
if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) {
- float centered = -(size.x / 2) / zoom + screen_rect.x / 2;
+ real_t centered = -(size.x / 2) / zoom + screen_rect.x / 2;
if (constrain_editor_view && ABS(centered - previous_update_view_offset.x) < ABS(centered - view_offset.x)) {
view_offset.x = previous_update_view_offset.x;
}
@@ -4091,7 +4091,7 @@ void CanvasItemEditor::_popup_warning_temporarily(Control *p_control, const floa
info_overlay->set_offset(SIDE_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
}
-void CanvasItemEditor::_update_scroll(float) {
+void CanvasItemEditor::_update_scroll(real_t) {
if (updating_scroll) {
return;
}
@@ -4185,14 +4185,14 @@ void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
undo_redo->commit_action();
}
-void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
+void CanvasItemEditor::_zoom_on_position(real_t p_zoom, Point2 p_position) {
p_zoom = CLAMP(p_zoom, MIN_ZOOM, MAX_ZOOM);
if (p_zoom == zoom) {
return;
}
- float prev_zoom = zoom;
+ real_t prev_zoom = zoom;
zoom = p_zoom;
view_offset += p_position / prev_zoom - p_position / zoom;
@@ -4201,7 +4201,7 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
// in small details (texts, lines).
// This correction adds a jitter movement when zooming, so we correct only when the
// zoom factor is an integer. (in the other cases, all pixels won't be aligned anyway)
- float closest_zoom_factor = Math::round(zoom);
+ const real_t closest_zoom_factor = Math::round(zoom);
if (Math::is_zero_approx(zoom - closest_zoom_factor)) {
// make sure scene pixel at view_offset is aligned on a screen pixel
Vector2 view_offset_int = view_offset.floor();
@@ -4213,7 +4213,7 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
update_viewport();
}
-void CanvasItemEditor::_update_zoom(float p_zoom) {
+void CanvasItemEditor::_update_zoom(real_t p_zoom) {
_zoom_on_position(p_zoom, viewport_scrollable->get_size() / 2.0);
}
@@ -4898,8 +4898,8 @@ void CanvasItemEditor::_focus_selection(int p_op) {
} else { // VIEW_FRAME_TO_SELECTION
if (rect.size.x > CMP_EPSILON && rect.size.y > CMP_EPSILON) {
- float scale_x = viewport->get_size().x / rect.size.x;
- float scale_y = viewport->get_size().y / rect.size.y;
+ real_t scale_x = viewport->get_size().x / rect.size.x;
+ real_t scale_y = viewport->get_size().y / rect.size.y;
zoom = scale_x < scale_y ? scale_x : scale_y;
zoom *= 0.90;
viewport->update();
@@ -4964,7 +4964,7 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
if (state.has("zoom")) {
// Compensate the editor scale, so that the editor scale can be changed
// and the zoom level will still be the same (relative to the editor scale).
- zoom = float(p_state["zoom"]) * MAX(1, EDSCALE);
+ zoom = real_t(p_state["zoom"]) * MAX(1, EDSCALE);
zoom_widget->set_zoom(zoom);
}
@@ -5815,7 +5815,22 @@ bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String &p_targe
}
void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &path, const Point2 &p_point) {
- child->set_name(path.get_file().get_basename());
+ // Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
+ String name = path.get_file().get_basename();
+ switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) {
+ case NAME_CASING_PASCAL_CASE:
+ name = name.capitalize().replace(" ", "");
+ break;
+ case NAME_CASING_CAMEL_CASE:
+ name = name.capitalize().replace(" ", "");
+ name[0] = name.to_lower()[0];
+ break;
+ case NAME_CASING_SNAKE_CASE:
+ name = name.capitalize().replace(" ", "_").to_lower();
+ break;
+ }
+ child->set_name(name);
+
Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(ResourceCache::get(path)));
Size2 texture_size = texture->get_size();
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index d466032588..1f59dfbc49 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -48,10 +48,10 @@ class CanvasItemEditorSelectedItem : public Object {
public:
Transform2D prev_xform;
- float prev_rot = 0;
+ real_t prev_rot = 0;
Rect2 prev_rect;
Vector2 prev_pivot;
- float prev_anchors[4] = { 0.0f };
+ real_t prev_anchors[4] = { (real_t)0.0 };
Transform2D pre_drag_xform;
Rect2 pre_drag_rect;
@@ -250,7 +250,7 @@ private:
bool show_edit_locks;
bool show_transformation_gizmos;
- float zoom;
+ real_t zoom;
Point2 view_offset;
Point2 previous_update_view_offset;
@@ -262,9 +262,9 @@ private:
int primary_grid_steps;
int grid_step_multiplier;
- float snap_rotation_step;
- float snap_rotation_offset;
- float snap_scale_step;
+ real_t snap_rotation_step;
+ real_t snap_rotation_offset;
+ real_t snap_scale_step;
bool smart_snap_active;
bool grid_snap_active;
@@ -292,7 +292,7 @@ private:
struct _SelectResult {
CanvasItem *item = nullptr;
- float z_index = 0;
+ real_t z_index = 0;
bool has_z = true;
_FORCE_INLINE_ bool operator<(const _SelectResult &p_rr) const {
return has_z && p_rr.has_z ? p_rr.z_index < z_index : p_rr.has_z;
@@ -309,7 +309,7 @@ private:
struct BoneList {
Transform2D xform;
- float length = 0.f;
+ real_t length = 0;
uint64_t last_pass = 0;
};
@@ -332,7 +332,7 @@ private:
struct PoseClipboard {
Vector2 pos;
Vector2 scale;
- float rot = 0;
+ real_t rot = 0;
ObjectID id;
};
List<PoseClipboard> pose_clipboard;
@@ -432,7 +432,7 @@ private:
void _popup_callback(int p_op);
bool updating_scroll;
- void _update_scroll(float);
+ void _update_scroll(real_t);
void _update_scrollbars();
void _append_canvas_item(CanvasItem *p_item);
void _snap_changed();
@@ -459,7 +459,7 @@ private:
void _draw_text_at_position(Point2 p_position, String p_string, Side p_side);
void _draw_margin_at_position(int p_value, Point2 p_position, Side p_side);
- void _draw_percentage_at_position(float p_value, Point2 p_position, Side p_side);
+ void _draw_percentage_at_position(real_t p_value, Point2 p_position, Side p_side);
void _draw_straight_line(Point2 p_from, Point2 p_to, Color p_color);
void _draw_smart_snapping();
@@ -501,16 +501,16 @@ private:
SnapTarget snap_target[2];
Transform2D snap_transform;
void _snap_if_closer_float(
- float p_value,
- float &r_current_snap, SnapTarget &r_current_snap_target,
- float p_target_value, SnapTarget p_snap_target,
- float p_radius = 10.0);
+ const real_t p_value,
+ real_t &r_current_snap, SnapTarget &r_current_snap_target,
+ const real_t p_target_value, const SnapTarget p_snap_target,
+ const real_t p_radius = 10.0);
void _snap_if_closer_point(
Point2 p_value,
Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2],
- Point2 p_target_value, SnapTarget p_snap_target,
- real_t rotation = 0.0,
- float p_radius = 10.0);
+ Point2 p_target_value, const SnapTarget p_snap_target,
+ const real_t rotation = 0.0,
+ const real_t p_radius = 10.0);
void _snap_other_nodes(
const Point2 p_value,
const Transform2D p_transform_to_snap,
@@ -527,8 +527,8 @@ private:
VBoxContainer *controls_vb;
EditorZoomWidget *zoom_widget;
- void _update_zoom(float p_zoom);
- void _zoom_on_position(float p_zoom, Point2 p_position = Point2());
+ void _update_zoom(real_t p_zoom);
+ void _zoom_on_position(real_t p_zoom, Point2 p_position = Point2());
void _button_toggle_smart_snap(bool p_status);
void _button_toggle_grid_snap(bool p_status);
void _button_override_camera(bool p_pressed);
@@ -557,28 +557,6 @@ protected:
HBoxContainer *get_panel_hb() { return hb; }
- struct compare_items_x {
- bool operator()(const CanvasItem *a, const CanvasItem *b) const {
- return a->get_global_transform().elements[2].x < b->get_global_transform().elements[2].x;
- }
- };
-
- struct compare_items_y {
- bool operator()(const CanvasItem *a, const CanvasItem *b) const {
- return a->get_global_transform().elements[2].y < b->get_global_transform().elements[2].y;
- }
- };
-
- struct proj_vector2_x {
- float get(const Vector2 &v) { return v.x; }
- void set(Vector2 &v, float f) { v.x = f; }
- };
-
- struct proj_vector2_y {
- float get(const Vector2 &v) { return v.y; }
- void set(Vector2 &v, float f) { v.y = f; }
- };
-
template <class P, class C>
void space_selected_items();
@@ -599,7 +577,7 @@ public:
};
Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, unsigned int p_forced_modes = 0, const CanvasItem *p_self_canvas_item = nullptr, List<CanvasItem *> p_other_nodes_exceptions = List<CanvasItem *>());
- float snap_angle(float p_target, float p_start = 0) const;
+ real_t snap_angle(real_t p_target, real_t p_start = 0) const;
Transform2D get_canvas_transform() const { return transform; }
diff --git a/editor/plugins/editor_debugger_plugin.cpp b/editor/plugins/editor_debugger_plugin.cpp
index 89073b7189..5f3b11ac42 100644
--- a/editor/plugins/editor_debugger_plugin.cpp
+++ b/editor/plugins/editor_debugger_plugin.cpp
@@ -32,7 +32,7 @@
#include "editor/debugger/script_editor_debugger.h"
-void EditorDebuggerPlugin::_breaked(bool p_really_did, bool p_can_debug) {
+void EditorDebuggerPlugin::_breaked(bool p_really_did, bool p_can_debug, String p_message, bool p_has_stackdump) {
if (p_really_did) {
emit_signal(SNAME("breaked"), p_can_debug);
} else {
diff --git a/editor/plugins/editor_debugger_plugin.h b/editor/plugins/editor_debugger_plugin.h
index b33a8ed925..5995d790c5 100644
--- a/editor/plugins/editor_debugger_plugin.h
+++ b/editor/plugins/editor_debugger_plugin.h
@@ -41,7 +41,7 @@ class EditorDebuggerPlugin : public Control {
private:
ScriptEditorDebugger *debugger = nullptr;
- void _breaked(bool p_really_did, bool p_can_debug);
+ void _breaked(bool p_really_did, bool p_can_debug, String p_message, bool p_has_stackdump);
void _started();
void _stopped();
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index 81c340e9a4..d7618b973e 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -724,7 +724,7 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.125);
xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.125) * xform.basis;
AABB rot_aabb = xform.xform(aabb);
- float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
+ real_t m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
if (m == 0) {
return Ref<Texture2D>();
}
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 2138f943da..46e15d97bf 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -320,7 +320,7 @@ void EditorNode3DGizmo::add_vertices(const Vector<Vector3> &p_vertices, const Re
instances.push_back(ins);
}
-void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material, float p_scale, const Color &p_modulate) {
+void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale, const Color &p_modulate) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index 61ee3a95a9..f303a61607 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -84,7 +84,7 @@ public:
void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
- void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
+ void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false);
void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D());
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0d3298c4a4..3b64224b27 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -107,8 +107,8 @@ void ViewportRotationControl::_notification(int p_what) {
}
void ViewportRotationControl::_draw() {
- Vector2i center = get_size() / 2.0;
- float radius = get_size().x / 2.0;
+ const Vector2i center = get_size() / 2.0;
+ const real_t radius = get_size().x / 2.0;
if (focused_axis > -2 || orbiting) {
draw_circle(center, radius, Color(0.5, 0.5, 0.5, 0.25));
@@ -151,15 +151,13 @@ void ViewportRotationControl::_draw_axis(const Axis2D &p_axis) {
}
void ViewportRotationControl::_get_sorted_axis(Vector<Axis2D> &r_axis) {
- Vector2i center = get_size() / 2.0;
- float radius = get_size().x / 2.0;
-
- float axis_radius = radius - AXIS_CIRCLE_RADIUS - 2.0 * EDSCALE;
- Basis camera_basis = viewport->to_camera_transform(viewport->cursor).get_basis().inverse();
+ const Vector2i center = get_size() / 2.0;
+ const real_t radius = get_size().x / 2.0 - AXIS_CIRCLE_RADIUS - 2.0 * EDSCALE;
+ const Basis camera_basis = viewport->to_camera_transform(viewport->cursor).get_basis().inverse();
for (int i = 0; i < 3; ++i) {
Vector3 axis_3d = camera_basis.get_axis(i);
- Vector2i axis_vector = Vector2(axis_3d.x, -axis_3d.y) * axis_radius;
+ Vector2i axis_vector = Vector2(axis_3d.x, -axis_3d.y) * radius;
if (Math::abs(axis_3d.z) < 1.0) {
Axis2D pos_axis;
@@ -261,7 +259,7 @@ void ViewportRotationControl::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ViewportRotationControl::_gui_input);
}
-void Node3DEditorViewport::_update_camera(float p_interp_delta) {
+void Node3DEditorViewport::_update_camera(real_t p_interp_delta) {
bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
Cursor old_camera_cursor = camera_cursor;
@@ -281,7 +279,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
// We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
camera_cursor.eye_pos = old_camera_cursor.eye_pos.lerp(cursor.eye_pos, CLAMP(factor, 0, 1));
- float orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ real_t orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
orbit_inertia = MAX(0.0001, orbit_inertia);
camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
@@ -299,13 +297,13 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
} else {
//when not being manipulated, move softly
- float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
- float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
+ real_t free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ real_t free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
//when being manipulated, move more quickly
- float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
- float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
+ real_t manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
+ real_t manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
- float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
+ real_t zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
//determine if being manipulated
bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
@@ -313,8 +311,8 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
manipulated |= Input::get_singleton()->is_key_pressed(KEY_CTRL);
- float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
- float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
+ real_t orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
+ real_t translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
zoom_inertia = MAX(0.0001, zoom_inertia);
camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
@@ -329,7 +327,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
}
camera_cursor.pos = old_camera_cursor.pos.lerp(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
- camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia)));
+ camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN((real_t)1.0, p_interp_delta * (1 / zoom_inertia)));
}
}
@@ -539,7 +537,7 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) {
continue;
}
- float dist = pos.distance_to(point);
+ const real_t dist = pos.distance_to(point);
if (dist < 0) {
continue;
@@ -603,7 +601,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe
continue;
}
- float dist = pos.distance_to(point);
+ const real_t dist = pos.distance_to(point);
if (dist < 0) {
continue;
@@ -648,7 +646,7 @@ void Node3DEditorViewport::_select_region() {
return; //nothing really
}
- float z_offset = MAX(0.0, 5.0 - get_znear());
+ const real_t z_offset = MAX(0.0, 5.0 - get_znear());
Vector3 box[4] = {
Vector3(
@@ -914,20 +912,19 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
Vector3 ray = _get_ray(Vector2(p_screenpos.x, p_screenpos.y));
Transform3D gt = spatial_editor->get_gizmo_transform();
- float gs = gizmo_scale;
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
int col_axis = -1;
- float col_d = 1e20;
+ real_t col_d = 1e20;
for (int i = 0; i < 3; i++) {
- Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
- float grabber_radius = gs * GIZMO_ARROW_SIZE;
+ const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gizmo_scale * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
+ const real_t grabber_radius = gizmo_scale * GIZMO_ARROW_SIZE;
Vector3 r;
if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
- float d = r.distance_to(ray_pos);
+ const real_t d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
col_axis = i;
@@ -946,17 +943,17 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
- const Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
+ const Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gizmo_scale * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
Vector3 r;
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
- float dist = r.distance_to(grabber_pos);
+ const real_t dist = r.distance_to(grabber_pos);
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
- if (dist < (gs * GIZMO_PLANE_SIZE * 1.5)) {
- float d = ray_pos.distance_to(r);
+ if (dist < (gizmo_scale * GIZMO_PLANE_SIZE * 1.5)) {
+ const real_t d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
col_axis = i;
@@ -993,12 +990,12 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
continue;
}
- float dist = r.distance_to(gt.origin);
- Vector3 r_dir = (r - gt.origin).normalized();
+ const real_t dist = r.distance_to(gt.origin);
+ const Vector3 r_dir = (r - gt.origin).normalized();
if (_get_camera_normal().dot(r_dir) <= 0.005) {
- if (dist > gs * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gs * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
- float d = ray_pos.distance_to(r);
+ if (dist > gizmo_scale * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gizmo_scale * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
+ const real_t d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
col_axis = i;
@@ -1025,13 +1022,13 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
float col_d = 1e20;
for (int i = 0; i < 3; i++) {
- Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * GIZMO_SCALE_OFFSET;
- float grabber_radius = gs * GIZMO_ARROW_SIZE;
+ const Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gizmo_scale * GIZMO_SCALE_OFFSET;
+ const real_t grabber_radius = gizmo_scale * GIZMO_ARROW_SIZE;
Vector3 r;
if (Geometry3D::segment_intersects_sphere(ray_pos, ray_pos + ray * MAX_Z, grabber_pos, grabber_radius, &r)) {
- float d = r.distance_to(ray_pos);
+ const real_t d = r.distance_to(ray_pos);
if (d < col_d) {
col_d = d;
col_axis = i;
@@ -1045,22 +1042,22 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b
col_d = 1e20;
for (int i = 0; i < 3; i++) {
- Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
- Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
+ const Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
+ const Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
- Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
+ const Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gizmo_scale * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
Vector3 r;
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
- float dist = r.distance_to(grabber_pos);
+ const real_t dist = r.distance_to(grabber_pos);
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
- if (dist < (gs * GIZMO_PLANE_SIZE * 1.5)) {
- float d = ray_pos.distance_to(r);
+ if (dist < (gizmo_scale * GIZMO_PLANE_SIZE * 1.5)) {
+ const real_t d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
col_axis = i;
@@ -1295,7 +1292,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b.is_valid()) {
emit_signal(SNAME("clicked"), this);
- float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor();
+ const real_t zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
case MOUSE_BUTTON_WHEEL_UP: {
if (is_freelook_active()) {
@@ -1782,13 +1779,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else {
- float center_click_dist = click.distance_to(_edit.center);
- float center_inters_dist = intersection.distance_to(_edit.center);
+ const real_t center_click_dist = click.distance_to(_edit.center);
+ const real_t center_inters_dist = intersection.distance_to(_edit.center);
if (center_click_dist == 0) {
break;
}
- float scale = center_inters_dist - center_click_dist;
+ const real_t scale = center_inters_dist - center_click_dist;
motion = Vector3(scale, scale, scale);
}
@@ -3529,18 +3526,15 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
return;
}
- Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized();
- Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized();
- Plane p(camera_xform.origin, camz);
- float gizmo_d = MAX(Math::abs(p.distance_to(xform.origin)), CMP_EPSILON);
- float d0 = camera->unproject_position(camera_xform.origin + camz * gizmo_d).y;
- float d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y;
- float dd = Math::abs(d0 - d1);
- if (dd == 0) {
- dd = 0.0001;
- }
+ const Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized();
+ const Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized();
+ const Plane p(camera_xform.origin, camz);
+ const real_t gizmo_d = MAX(Math::abs(p.distance_to(xform.origin)), CMP_EPSILON);
+ const real_t d0 = camera->unproject_position(camera_xform.origin + camz * gizmo_d).y;
+ const real_t d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y;
+ const real_t dd = MAX(Math::abs(d0 - d1), CMP_EPSILON);
- float gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
+ const real_t gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
// At low viewport heights, multiply the gizmo scale based on the viewport height.
// This prevents the gizmo from growing very large and going outside the viewport.
const int viewport_base_height = 400 * MAX(1, EDSCALE);
@@ -3796,7 +3790,7 @@ void Node3DEditorViewport::focus_selection() {
}
if (count != 0) {
- center /= float(count);
+ center /= count;
}
cursor.pos = center;
@@ -4460,14 +4454,14 @@ void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
}
if (dragging_h) {
- float new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width;
+ real_t new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width;
new_ratio = CLAMP(new_ratio, 40 / get_size().width, (get_size().width - 40) / get_size().width);
ratio_h = new_ratio;
queue_sort();
update();
}
if (dragging_v) {
- float new_ratio = drag_begin_ratio.y + (mm->get_position().y - drag_begin_pos.y) / get_size().height;
+ real_t new_ratio = drag_begin_ratio.y + (mm->get_position().y - drag_begin_pos.y) / get_size().height;
new_ratio = CLAMP(new_ratio, 40 / get_size().height, (get_size().height - 40) / get_size().height);
ratio_v = new_ratio;
queue_sort();
@@ -5018,13 +5012,13 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
}
if (d.has("zfar")) {
- settings_zfar->set_value(float(d["zfar"]));
+ settings_zfar->set_value(double(d["zfar"]));
}
if (d.has("znear")) {
- settings_znear->set_value(float(d["znear"]));
+ settings_znear->set_value(double(d["znear"]));
}
if (d.has("fov")) {
- settings_fov->set_value(float(d["fov"]));
+ settings_fov->set_value(double(d["fov"]));
}
if (d.has("show_grid")) {
bool use = d["show_grid"];
@@ -7206,7 +7200,9 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
hbc_menu->add_child(context_menu_container);
_update_context_menu_stylebox();
+ // Get the view menu popup and have it stay open when a checkable item is selected
p = view_menu->get_popup();
+ p->set_hide_on_checkable_item_selection(false);
accept = memnew(AcceptDialog);
editor->get_gui_base()->add_child(accept);
@@ -7625,8 +7621,8 @@ Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
return p_target;
}
-float Node3DEditor::get_translate_snap() const {
- float snap_value;
+double Node3DEditor::get_translate_snap() const {
+ double snap_value;
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_translate->get_text().to_float() / 10.0;
} else {
@@ -7636,8 +7632,8 @@ float Node3DEditor::get_translate_snap() const {
return snap_value;
}
-float Node3DEditor::get_rotate_snap() const {
- float snap_value;
+double Node3DEditor::get_rotate_snap() const {
+ double snap_value;
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_rotate->get_text().to_float() / 3.0;
} else {
@@ -7647,8 +7643,8 @@ float Node3DEditor::get_rotate_snap() const {
return snap_value;
}
-float Node3DEditor::get_scale_snap() const {
- float snap_value;
+double Node3DEditor::get_scale_snap() const {
+ double snap_value;
if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_scale->get_text().to_float() / 2.0;
} else {
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 6ac3345daf..cb2edbcbc1 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -201,7 +201,7 @@ private:
bool orthogonal;
bool auto_orthogonal;
bool lock_rotation;
- float gizmo_scale;
+ real_t gizmo_scale;
bool freelook_active;
real_t freelook_speed;
@@ -221,7 +221,7 @@ private:
struct _RayResult {
Node3D *item = nullptr;
- float depth = 0;
+ real_t depth = 0;
_FORCE_INLINE_ bool operator<(const _RayResult &p_rr) const { return depth < p_rr.depth; }
};
@@ -306,7 +306,7 @@ private:
struct Cursor {
Vector3 pos;
- float x_rot, y_rot, distance;
+ real_t x_rot, y_rot, distance;
Vector3 eye_pos; // Used in freelook mode
bool region_select;
Point2 region_begin, region_end;
@@ -340,8 +340,7 @@ private:
void set_message(String p_message, float p_time = 5);
- //
- void _update_camera(float p_interp_delta);
+ void _update_camera(real_t p_interp_delta);
Transform3D to_camera_transform(const Cursor &p_cursor) const;
void _draw();
@@ -450,8 +449,8 @@ public:
private:
View view;
bool mouseover;
- float ratio_h;
- float ratio_v;
+ real_t ratio_h;
+ real_t ratio_v;
bool hovering_v;
bool hovering_h;
@@ -534,9 +533,9 @@ private:
Ref<Node3DGizmo> current_hover_gizmo;
int current_hover_gizmo_handle;
- float snap_translate_value;
- float snap_rotate_value;
- float snap_scale_value;
+ real_t snap_translate_value;
+ real_t snap_rotate_value;
+ real_t snap_scale_value;
Ref<ArrayMesh> selection_box_xray;
Ref<ArrayMesh> selection_box;
@@ -554,7 +553,7 @@ private:
struct Gizmo {
bool visible = false;
- float scale = 0;
+ real_t scale = 0;
Transform3D transform;
} gizmo;
@@ -752,9 +751,9 @@ public:
ToolMode get_tool_mode() const { return tool_mode; }
bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); }
bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; }
- float get_translate_snap() const;
- float get_rotate_snap() const;
- float get_scale_snap() const;
+ double get_translate_snap() const;
+ double get_rotate_snap() const;
+ double get_scale_snap() const;
Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; }
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index b420372eff..9377395418 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -400,25 +400,25 @@ void Polygon2DEditor::_set_show_grid(bool p_show) {
uv_edit_draw->update();
}
-void Polygon2DEditor::_set_snap_off_x(float p_val) {
+void Polygon2DEditor::_set_snap_off_x(real_t p_val) {
snap_offset.x = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
uv_edit_draw->update();
}
-void Polygon2DEditor::_set_snap_off_y(float p_val) {
+void Polygon2DEditor::_set_snap_off_y(real_t p_val) {
snap_offset.y = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_offset", snap_offset);
uv_edit_draw->update();
}
-void Polygon2DEditor::_set_snap_step_x(float p_val) {
+void Polygon2DEditor::_set_snap_step_x(real_t p_val) {
snap_step.x = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
uv_edit_draw->update();
}
-void Polygon2DEditor::_set_snap_step_y(float p_val) {
+void Polygon2DEditor::_set_snap_step_y(real_t p_val) {
snap_step.y = p_val;
EditorSettings::get_singleton()->set_project_metadata("polygon_2d_uv_editor", "snap_step", snap_step);
uv_edit_draw->update();
@@ -569,11 +569,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
int closest = -1;
- float closest_dist = 1e20;
+ real_t closest_dist = 1e20;
for (int i = points_prev.size() - internal_vertices; i < points_prev.size(); i++) {
Vector2 tuv = mtx.xform(uv_create_poly_prev[i]);
- float dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
+ real_t dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
if (dist < 8 && dist < closest_dist) {
closest = i;
closest_dist = dist;
@@ -639,11 +639,11 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
if (uv_move_current == UV_MODE_ADD_POLYGON) {
int closest = -1;
- float closest_dist = 1e20;
+ real_t closest_dist = 1e20;
for (int i = 0; i < points_prev.size(); i++) {
Vector2 tuv = mtx.xform(points_prev[i]);
- float dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
+ real_t dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
if (dist < 8 && dist < closest_dist) {
closest = i;
closest_dist = dist;
@@ -825,7 +825,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
center /= uv_new.size();
- float angle = (uv_drag_from - mtx.xform(center)).normalized().angle_to((uv_drag_to - mtx.xform(center)).normalized());
+ real_t angle = (uv_drag_from - mtx.xform(center)).normalized().angle_to((uv_drag_to - mtx.xform(center)).normalized());
for (int i = 0; i < uv_new.size(); i++) {
Vector2 rel = points_prev[i] - center;
@@ -848,13 +848,13 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
center /= uv_new.size();
- float from_dist = uv_drag_from.distance_to(mtx.xform(center));
- float to_dist = uv_drag_to.distance_to(mtx.xform(center));
+ real_t from_dist = uv_drag_from.distance_to(mtx.xform(center));
+ real_t to_dist = uv_drag_to.distance_to(mtx.xform(center));
if (from_dist < 2) {
break;
}
- float scale = to_dist / from_dist;
+ real_t scale = to_dist / from_dist;
for (int i = 0; i < uv_new.size(); i++) {
Vector2 rel = points_prev[i] - center;
@@ -881,8 +881,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
{
int pc = painted_weights.size();
- float amount = bone_paint_strength->get_value();
- float radius = bone_paint_radius->get_value() * EDSCALE;
+ real_t amount = bone_paint_strength->get_value();
+ real_t radius = bone_paint_radius->get_value() * EDSCALE;
if (uv_mode == UV_MODE_CLEAR_WEIGHT) {
amount = -amount;
@@ -925,7 +925,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
}
-void Polygon2DEditor::_uv_scroll_changed(float) {
+void Polygon2DEditor::_uv_scroll_changed(real_t) {
if (updating_uv_scroll) {
return;
}
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index af3b2f5aef..cbe7ecf360 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -95,7 +95,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
void _update_bone_list();
Vector2 uv_draw_ofs;
- float uv_draw_zoom;
+ real_t uv_draw_zoom;
Vector<Vector2> points_prev;
Vector<Vector2> uv_create_uv_prev;
Vector<Vector2> uv_create_poly_prev;
@@ -127,17 +127,17 @@ class Polygon2DEditor : public AbstractPolygon2DEditor {
void _cancel_editing();
void _update_polygon_editing_state();
- void _uv_scroll_changed(float);
+ void _uv_scroll_changed(real_t);
void _uv_input(const Ref<InputEvent> &p_input);
void _uv_draw();
void _uv_mode(int p_mode);
void _set_use_snap(bool p_use);
void _set_show_grid(bool p_show);
- void _set_snap_off_x(float p_val);
- void _set_snap_off_y(float p_val);
- void _set_snap_step_x(float p_val);
- void _set_snap_step_y(float p_val);
+ void _set_snap_off_x(real_t p_val);
+ void _set_snap_off_y(real_t p_val);
+ void _set_snap_step_x(real_t p_val);
+ void _set_snap_step_y(real_t p_val);
void _uv_edit_mode_select(int p_mode);
void _uv_edit_popup_hide();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 65459d159d..5bbe56a800 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -204,7 +204,13 @@ void ScriptTextEditor::_set_theme_for_script() {
for (const String &string : strings) {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
- text_edit->add_string_delimiter(beg, end, end == "");
+ if (!text_edit->has_string_delimiter(beg)) {
+ text_edit->add_string_delimiter(beg, end, end == "");
+ }
+
+ if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) {
+ text_edit->add_auto_brace_completion_pair(beg, end);
+ }
}
List<String> comments;
@@ -214,6 +220,10 @@ void ScriptTextEditor::_set_theme_for_script() {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
text_edit->add_comment_delimiter(beg, end, end == "");
+
+ if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) {
+ text_edit->add_auto_brace_completion_pair(beg, end);
+ }
}
}
@@ -742,7 +752,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
EditorNode::get_singleton()->load_resource(p_symbol);
}
- } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) {
+ } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), p_symbol, script->get_path(), base, result) == OK) {
_goto_line(p_row);
result.class_name = result.class_name.trim_prefix("_");
@@ -845,18 +855,17 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
}
ScriptLanguage::LookupResult result;
- if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) {
- text_edit->set_highlighted_word(p_symbol);
+ if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) {
+ text_edit->set_symbol_lookup_word_as_valid(true);
} else if (p_symbol.is_rel_path()) {
String path = _get_absolute_path(p_symbol);
if (FileAccess::exists(path)) {
- text_edit->set_highlighted_word(p_symbol);
+ text_edit->set_symbol_lookup_word_as_valid(true);
} else {
- text_edit->set_highlighted_word(String());
+ text_edit->set_symbol_lookup_word_as_valid(false);
}
-
} else {
- text_edit->set_highlighted_word(String());
+ text_edit->set_symbol_lookup_word_as_valid(false);
}
}
@@ -1544,7 +1553,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
base = _find_node_for_script(base, base, script);
}
ScriptLanguage::LookupResult result;
- if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), word_at_pos, script->get_path(), base, result) == OK) {
+ if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) {
open_docs = true;
}
}
@@ -1829,7 +1838,7 @@ ScriptTextEditor::ScriptTextEditor() {
code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"));
- code_editor->get_text_editor()->set_select_identifiers_on_hover(true);
+ code_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true);
code_editor->get_text_editor()->set_context_menu_enabled(false);
context_menu = memnew(PopupMenu);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 2c45b96106..95973f9dfd 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -158,6 +158,10 @@ void ShaderTextEditor::_load_theme_settings() {
text_editor->add_comment_delimiter("/*", "*/", false);
text_editor->add_comment_delimiter("//", "", true);
+ if (!text_editor->has_auto_brace_completion_open_key("/*")) {
+ text_editor->add_auto_brace_completion_pair("/*", "*/");
+ }
+
if (warnings_panel) {
// Warnings panel
warnings_panel->add_theme_font_override("normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts")));
@@ -659,7 +663,7 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
shader_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"));
- shader_editor->get_text_editor()->set_select_identifiers_on_hover(true);
+ shader_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true);
shader_editor->get_text_editor()->set_context_menu_enabled(false);
shader_editor->get_text_editor()->connect("gui_input", callable_mp(this, &ShaderEditor::_text_edit_gui_input));
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index 0929a629f8..7ea3deedb9 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -1278,6 +1278,9 @@ void ThemeItemEditorDialog::_update_edit_types() {
edit_items_remove_class->set_disabled(false);
edit_items_remove_custom->set_disabled(false);
edit_items_remove_all->set_disabled(false);
+
+ edit_items_message->set_text("");
+ edit_items_message->hide();
} else {
edit_items_add_color->set_disabled(true);
edit_items_add_constant->set_disabled(true);
@@ -1289,6 +1292,9 @@ void ThemeItemEditorDialog::_update_edit_types() {
edit_items_remove_class->set_disabled(true);
edit_items_remove_custom->set_disabled(true);
edit_items_remove_all->set_disabled(true);
+
+ edit_items_message->set_text(TTR("Select a theme type from the list to edit its items.\nYou can add a custom type or import a type with its items from another theme."));
+ edit_items_message->show();
}
_update_edit_item_tree(selected_type);
}
@@ -1305,6 +1311,7 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
TreeItem *root = edit_items_tree->create_item();
List<StringName> names;
+ bool has_any_items = false;
{ // Colors.
names.clear();
@@ -1324,6 +1331,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
}
}
@@ -1345,6 +1354,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
}
}
@@ -1366,6 +1377,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
}
}
@@ -1387,6 +1400,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
}
}
@@ -1408,6 +1423,8 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
}
}
@@ -1429,6 +1446,20 @@ void ThemeItemEditorDialog::_update_edit_item_tree(String p_item_type) {
item->add_button(0, get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")), ITEMS_TREE_RENAME_ITEM, false, TTR("Rename Item"));
item->add_button(0, get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), ITEMS_TREE_REMOVE_ITEM, false, TTR("Remove Item"));
}
+
+ has_any_items = true;
+ }
+ }
+
+ // If some type is selected, but it doesn't seem to have any items, show a guiding message.
+ Vector<int> selected_ids = edit_type_list->get_selected_items();
+ if (selected_ids.size() > 0) {
+ if (!has_any_items) {
+ edit_items_message->set_text(TTR("This theme type is empty.\nAdd more items to it manually or by importing from another theme."));
+ edit_items_message->show();
+ } else {
+ edit_items_message->set_text("");
+ edit_items_message->hide();
}
}
}
@@ -1873,6 +1904,14 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() {
edit_items_vb->add_child(edit_items_tree);
edit_items_tree->connect("button_pressed", callable_mp(this, &ThemeItemEditorDialog::_item_tree_button_pressed));
+ edit_items_message = memnew(Label);
+ edit_items_message->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
+ edit_items_message->set_mouse_filter(Control::MOUSE_FILTER_STOP);
+ edit_items_message->set_align(Label::ALIGN_CENTER);
+ edit_items_message->set_valign(Label::VALIGN_CENTER);
+ edit_items_message->set_autowrap_mode(Label::AUTOWRAP_WORD);
+ edit_items_tree->add_child(edit_items_message);
+
edit_theme_item_dialog = memnew(ConfirmationDialog);
edit_theme_item_dialog->set_title(TTR("Add Theme Item"));
add_child(edit_theme_item_dialog);
@@ -2542,15 +2581,15 @@ void ThemeTypeEditor::_update_type_items() {
// Various type settings.
if (ClassDB::class_exists(edited_type)) {
type_variation_edit->set_editable(false);
- type_variation_edit->set_tooltip(TTR("A type associated with a built-in class cannot be marked as a variation of another type."));
type_variation_edit->set_text("");
type_variation_button->hide();
+ type_variation_locked->show();
} else {
type_variation_edit->set_editable(true);
- type_variation_edit->set_tooltip("");
type_variation_edit->set_text(edited_theme->get_type_variation_base(edited_type));
_add_focusable(type_variation_edit);
type_variation_button->show();
+ type_variation_locked->hide();
}
}
@@ -3067,8 +3106,11 @@ ThemeTypeEditor::ThemeTypeEditor() {
type_settings_list->set_h_size_flags(SIZE_EXPAND_FILL);
type_settings_sc->add_child(type_settings_list);
+ VBoxContainer *type_variation_vb = memnew(VBoxContainer);
+ type_settings_list->add_child(type_variation_vb);
+
HBoxContainer *type_variation_hb = memnew(HBoxContainer);
- type_settings_list->add_child(type_variation_hb);
+ type_variation_vb->add_child(type_variation_hb);
Label *type_variation_label = memnew(Label);
type_variation_hb->add_child(type_variation_label);
type_variation_label->set_text(TTR("Base Type"));
@@ -3083,6 +3125,13 @@ ThemeTypeEditor::ThemeTypeEditor() {
type_variation_button->set_tooltip(TTR("Select the variation base type from a list of available types."));
type_variation_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_variation_cbk));
+ type_variation_locked = memnew(Label);
+ type_variation_vb->add_child(type_variation_locked);
+ type_variation_locked->set_align(Label::ALIGN_CENTER);
+ type_variation_locked->set_autowrap_mode(Label::AUTOWRAP_WORD);
+ type_variation_locked->set_text(TTR("A type associated with a built-in class cannot be marked as a variation of another type."));
+ type_variation_locked->hide();
+
add_type_dialog = memnew(ThemeTypeDialog);
add_child(add_type_dialog);
add_type_dialog->connect("type_selected", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_selected));
@@ -3130,7 +3179,7 @@ void ThemeEditor::_theme_save_button_cbk(bool p_save_as) {
}
void ThemeEditor::_theme_edit_button_cbk() {
- theme_edit_dialog->popup_centered(Size2(850, 760) * EDSCALE);
+ theme_edit_dialog->popup_centered(Size2(850, 700) * EDSCALE);
}
void ThemeEditor::_add_preview_button_cbk() {
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index e78b244a42..5b0357e3f8 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -197,6 +197,7 @@ class ThemeItemEditorDialog : public AcceptDialog {
Button *edit_items_remove_custom;
Button *edit_items_remove_all;
Tree *edit_items_tree;
+ Label *edit_items_message;
enum ItemsTreeAction {
ITEMS_TREE_RENAME_ITEM,
@@ -324,6 +325,7 @@ class ThemeTypeEditor : public MarginContainer {
LineEdit *type_variation_edit;
Button *type_variation_button;
+ Label *type_variation_locked;
enum TypeDialogMode {
ADD_THEME_TYPE,
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 84e40e2ffa..13f04cb804 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -32,6 +32,7 @@
#include "core/input/input.h"
#include "core/os/keyboard.h"
+#include "scene/2d/tile_map.h"
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
@@ -259,7 +260,7 @@ void TileAtlasView::_draw_base_tiles() {
Vector2i offset_pos = (margins + (atlas_coords * texture_region_size) + tile_set_atlas_source->get_tile_texture_region(atlas_coords).size / 2 + tile_set_atlas_source->get_tile_effective_texture_offset(atlas_coords, 0));
// Draw the tile.
- TileSetPluginAtlasRendering::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0);
+ TileMap::draw_tile(base_tiles_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, 0);
}
}
}
@@ -375,7 +376,7 @@ void TileAtlasView::_draw_alternatives() {
}
// Draw the tile.
- TileSetPluginAtlasRendering::draw_tile(alternatives_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, alternative_id);
+ TileMap::draw_tile(alternatives_draw->get_canvas_item(), offset_pos, tile_set, source_id, atlas_coords, alternative_id);
// Increment the x position.
current_pos.x += transposed ? texture_region.size.y : texture_region.size.x;
diff --git a/editor/plugins/tiles/tile_data_editors.h b/editor/plugins/tiles/tile_data_editors.h
index 781f26cc02..99998dc779 100644
--- a/editor/plugins/tiles/tile_data_editors.h
+++ b/editor/plugins/tiles/tile_data_editors.h
@@ -36,10 +36,10 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
+#include "scene/2d/tile_map.h"
#include "scene/gui/box_container.h"
#include "scene/gui/control.h"
#include "scene/gui/label.h"
-#include "scene/resources/tile_set.h"
class TileDataEditor : public VBoxContainer {
GDCLASS(TileDataEditor, VBoxContainer);
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index e70aed8ed6..77084f551a 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -377,6 +377,11 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
return false;
}
+ if (tile_map_layer < 0) {
+ return false;
+ }
+ ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), false);
+
Ref<TileSet> tile_set = tile_map->get_tileset();
if (!tile_set.is_valid()) {
return false;
@@ -391,7 +396,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
coords_array.push_back(E->get());
}
- tile_map_clipboard = tile_map->get_pattern(coords_array);
+ tile_map_clipboard = tile_map->get_pattern(tile_map_layer, coords_array);
}
if (ED_IS_SHORTCUT("tiles_editor/cut", p_event)) {
@@ -399,8 +404,8 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!tile_map_selection.is_empty()) {
undo_redo->create_action(TTR("Delete tiles"));
for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
- undo_redo->add_undo_method(tile_map, "set_cell", E->get(), tile_map->get_cell_source_id(E->get()), tile_map->get_cell_atlas_coords(E->get()), tile_map->get_cell_alternative_tile(E->get()));
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->get(), tile_map->get_cell_source_id(tile_map_layer, E->get()), tile_map->get_cell_atlas_coords(tile_map_layer, E->get()), tile_map->get_cell_alternative_tile(tile_map_layer, E->get()));
}
undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
tile_map_selection.clear();
@@ -430,8 +435,8 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!tile_map_selection.is_empty()) {
undo_redo->create_action(TTR("Delete tiles"));
for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
- undo_redo->add_undo_method(tile_map, "set_cell", E->get(), tile_map->get_cell_source_id(E->get()), tile_map->get_cell_atlas_coords(E->get()), tile_map->get_cell_alternative_tile(E->get()));
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->get(), tile_map->get_cell_source_id(tile_map_layer, E->get()), tile_map->get_cell_atlas_coords(tile_map_layer, E->get()), tile_map->get_cell_alternative_tile(tile_map_layer, E->get()));
}
undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
tile_map_selection.clear();
@@ -456,9 +461,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
Vector2i coords = E->key();
if (!drag_modified.has(coords)) {
- drag_modified.insert(coords, tile_map->get_cell(coords));
+ drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
}
- tile_map->set_cell(coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
} break;
case DRAG_TYPE_BUCKET: {
@@ -472,9 +477,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
Vector2i coords = E->key();
if (!drag_modified.has(coords)) {
- drag_modified.insert(coords, tile_map->get_cell(coords));
+ drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
}
- tile_map->set_cell(coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
}
}
@@ -497,7 +502,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
if (mb->is_pressed()) {
// Pressed
- if (tool_buttons_group->get_pressed_button() == select_tool_button) {
+ if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
+ // Do nothing.
+ } else if (tool_buttons_group->get_pressed_button() == select_tool_button) {
drag_start_mouse_pos = mpos;
if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) {
// Move the selection
@@ -505,8 +512,8 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
drag_modified.clear();
for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
Vector2i coords = E->get();
- drag_modified.insert(coords, tile_map->get_cell(coords));
- tile_map->set_cell(coords, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
+ drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
+ tile_map->set_cell(tile_map_layer, coords, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
}
} else {
// Select tiles
@@ -530,9 +537,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
Vector2i coords = E->key();
if (!drag_modified.has(coords)) {
- drag_modified.insert(coords, tile_map->get_cell(coords));
+ drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
}
- tile_map->set_cell(coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
} else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
drag_type = DRAG_TYPE_LINE;
@@ -556,9 +563,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
Vector2i coords = E->key();
if (!drag_modified.has(coords)) {
- drag_modified.insert(coords, tile_map->get_cell(coords));
+ drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
}
- tile_map->set_cell(coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ tile_map->set_cell(tile_map_layer, coords, E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
}
}
@@ -587,6 +594,11 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
return;
}
+ if (tile_map_layer < 0) {
+ return;
+ }
+ ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
+
Ref<TileSet> tile_set = tile_map->get_tileset();
if (!tile_set.is_valid()) {
return;
@@ -623,7 +635,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
for (int x = rect.position.x; x < rect.get_end().x; x++) {
for (int y = rect.position.y; y < rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y);
- if (tile_map->get_cell_source_id(coords) != TileSet::INVALID_SOURCE) {
+ if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(coords) - tile_shape_size / 2, tile_shape_size));
tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0), false);
}
@@ -637,7 +649,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
for (int x = rect.position.x; x < rect.get_end().x; x++) {
for (int y = rect.position.y; y < rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y);
- if (tile_map->get_cell_source_id(coords) != TileSet::INVALID_SOURCE) {
+ if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
to_draw.insert(coords);
}
}
@@ -914,6 +926,8 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start
TileMapPattern erase_pattern;
erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
+ Map<Vector2i, TileMapCell> err_output;
+ ERR_FAIL_COND_V(pattern->is_empty(), err_output);
// Compute the offset to align things to the bottom or right.
bool aligned_right = p_end_cell.x < p_start_cell.x;
@@ -956,6 +970,12 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
return Map<Vector2i, TileMapCell>();
}
+ if (tile_map_layer < 0) {
+ return Map<Vector2i, TileMapCell>();
+ }
+ Map<Vector2i, TileMapCell> output;
+ ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), output);
+
Ref<TileSet> tile_set = tile_map->get_tileset();
if (!tile_set.is_valid()) {
return Map<Vector2i, TileMapCell>();
@@ -966,9 +986,8 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
- Map<Vector2i, TileMapCell> output;
if (!pattern->is_empty()) {
- TileMapCell source = tile_map->get_cell(p_coords);
+ TileMapCell source = tile_map->get_cell(tile_map_layer, p_coords);
// If we are filling empty tiles, compute the tilemap boundaries.
Rect2i boundaries;
@@ -985,9 +1004,9 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
Vector2i coords = to_check.back()->get();
to_check.pop_back();
if (!already_checked.has(coords)) {
- if (source.source_id == tile_map->get_cell_source_id(coords) &&
- source.get_atlas_coords() == tile_map->get_cell_atlas_coords(coords) &&
- source.alternative_tile == tile_map->get_cell_alternative_tile(coords) &&
+ if (source.source_id == tile_map->get_cell_source_id(tile_map_layer, coords) &&
+ source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
+ source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
(source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
@@ -1027,13 +1046,13 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
}
}
} else {
- to_check = tile_map->get_used_cells();
+ to_check = tile_map->get_used_cells(tile_map_layer);
}
for (int i = 0; i < to_check.size(); i++) {
Vector2i coords = to_check[i];
- if (source.source_id == tile_map->get_cell_source_id(coords) &&
- source.get_atlas_coords() == tile_map->get_cell_atlas_coords(coords) &&
- source.alternative_tile == tile_map->get_cell_alternative_tile(coords) &&
+ if (source.source_id == tile_map->get_cell_source_id(tile_map_layer, coords) &&
+ source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
+ source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
(source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
@@ -1066,6 +1085,11 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
return;
}
+ if (tile_map_layer < 0) {
+ return;
+ }
+ ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
+
Ref<TileSet> tile_set = tile_map->get_tileset();
if (!tile_set.is_valid()) {
return;
@@ -1091,7 +1115,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
tile_map_selection.erase(coords);
}
} else {
- if (tile_map->get_cell_source_id(coords) != TileSet::INVALID_SOURCE) {
+ if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
tile_map_selection.insert(coords);
}
}
@@ -1123,7 +1147,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
coords = tile_map->map_pattern(top_left, selection_used_cells[i], selection_pattern);
cells_undo[coords] = TileMapCell(drag_modified[coords].source_id, drag_modified[coords].get_atlas_coords(), drag_modified[coords].alternative_tile);
coords = tile_map->map_pattern(top_left + offset, selection_used_cells[i], selection_pattern);
- cells_undo[coords] = TileMapCell(tile_map->get_cell_source_id(coords), tile_map->get_cell_atlas_coords(coords), tile_map->get_cell_alternative_tile(coords));
+ cells_undo[coords] = TileMapCell(tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
}
Map<Vector2i, TileMapCell> cells_do;
@@ -1138,10 +1162,10 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
undo_redo->create_action(TTR("Move tiles"));
// Move the tiles.
for (Map<Vector2i, TileMapCell>::Element *E = cells_do.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
for (Map<Vector2i, TileMapCell>::Element *E = cells_undo.front(); E; E = E->next()) {
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
// Update the selection.
@@ -1162,12 +1186,12 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
for (int x = rect.position.x; x < rect.get_end().x; x++) {
for (int y = rect.position.y; y < rect.get_end().y; y++) {
Vector2i coords = Vector2i(x, y);
- if (tile_map->get_cell_source_id(coords) != TileSet::INVALID_SOURCE) {
+ if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
coords_array.push_back(coords);
}
}
}
- selection_pattern = tile_map->get_pattern(coords_array);
+ selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
if (!selection_pattern->is_empty()) {
_update_tileset_selection_from_selection_pattern();
} else {
@@ -1178,8 +1202,8 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
case DRAG_TYPE_PAINT: {
undo_redo->create_action(TTR("Paint tiles"));
for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key()));
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key()));
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
undo_redo->commit_action(false);
} break;
@@ -1190,8 +1214,8 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) {
continue;
}
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key()));
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key()));
}
undo_redo->commit_action();
} break;
@@ -1202,16 +1226,16 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
if (!erase_button->is_pressed() && E->get().source_id == TileSet::INVALID_SOURCE) {
continue;
}
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key()));
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key()));
}
undo_redo->commit_action();
} break;
case DRAG_TYPE_BUCKET: {
undo_redo->create_action(TTR("Paint tiles"));
for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key()));
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key()));
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
undo_redo->commit_action(false);
} break;
@@ -1221,8 +1245,8 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
TypedArray<Vector2i> used_cells = tile_map_clipboard->get_used_cells();
for (int i = 0; i < used_cells.size(); i++) {
Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(mpos - mouse_offset), used_cells[i], tile_map_clipboard);
- undo_redo->add_do_method(tile_map, "set_cell", coords, tile_map_clipboard->get_cell_source_id(used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(used_cells[i]));
- undo_redo->add_undo_method(tile_map, "set_cell", coords, tile_map->get_cell_source_id(coords), tile_map->get_cell_atlas_coords(coords), tile_map->get_cell_alternative_tile(coords));
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, coords, tile_map_clipboard->get_cell_source_id(used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(used_cells[i]));
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, coords, tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
}
undo_redo->commit_action();
} break;
@@ -1301,13 +1325,15 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tilemap_selection(
return;
}
+ ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
+
memdelete(selection_pattern);
TypedArray<Vector2i> coords_array;
for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
coords_array.push_back(E->get());
}
- selection_pattern = tile_map->get_pattern(coords_array);
+ selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
}
void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection() {
@@ -1344,8 +1370,7 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection(
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
// Organize using coordinates.
- for (List<const TileMapCell *>::Element *E_cell = E_source->get().front(); E_cell; E_cell = E_cell->next()) {
- const TileMapCell *current = E_cell->get();
+ for (const TileMapCell *current : E_source->get()) {
if (current->alternative_tile == 0) {
organized_pattern[current->get_atlas_coords()] = current;
} else {
@@ -1364,8 +1389,8 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection(
}
} else {
// Add everything unorganized.
- for (List<const TileMapCell *>::Element *E_cell = E_source->get().front(); E_cell; E_cell = E_cell->next()) {
- unorganized.push_back(E_cell->get());
+ for (const TileMapCell *cell : E_source->get()) {
+ unorganized.push_back(cell);
}
}
@@ -1375,8 +1400,8 @@ void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection(
}
Vector2i organized_size = selection_pattern->get_size();
int unorganized_index = 0;
- for (List<const TileMapCell *>::Element *E_cell = unorganized.front(); E_cell; E_cell = E_cell->next()) {
- selection_pattern->set_cell(Vector2(organized_size.x + unorganized_index, vertical_offset), E_cell->get()->source_id, E_cell->get()->get_atlas_coords(), E_cell->get()->alternative_tile);
+ for (const TileMapCell *cell : unorganized) {
+ selection_pattern->set_cell(Vector2(organized_size.x + unorganized_index, vertical_offset), cell->source_id, cell->get_atlas_coords(), cell->alternative_tile);
unorganized_index++;
}
vertical_offset += MAX(organized_size.y, 1);
@@ -1711,13 +1736,19 @@ TypedArray<Vector2i> TileMapEditorTilesPlugin::_get_tile_map_selection() const {
return output;
}
-void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id) {
- tile_map_id = p_tile_map_id;
+void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer) {
+ _stop_dragging(); // Avoids staying in a wrong drag state.
- // Clear the selection.
- tile_set_selection.clear();
- tile_map_selection.clear();
- selection_pattern->clear();
+ if (tile_map_id != p_tile_map_id) {
+ tile_map_id = p_tile_map_id;
+
+ // Clear the selection.
+ tile_set_selection.clear();
+ tile_map_selection.clear();
+ selection_pattern->clear();
+ }
+
+ tile_map_layer = p_tile_map_layer;
}
void TileMapEditorTilesPlugin::_bind_methods() {
@@ -2299,6 +2330,7 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c
}
ERR_FAIL_INDEX_V(p_terrain_set, tile_set->get_terrain_sets_count(), Set<Constraint>());
+ ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), Set<Constraint>());
// Build a set of dummy constraints get the constrained points.
Set<Constraint> dummy_constraints;
@@ -2322,7 +2354,7 @@ Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_c
Map<Vector2i, TileSet::CellNeighbor> overlapping_terrain_bits = c.get_overlapping_coords_and_peering_bits();
for (Map<Vector2i, TileSet::CellNeighbor>::Element *E_overlapping = overlapping_terrain_bits.front(); E_overlapping; E_overlapping = E_overlapping->next()) {
if (!p_to_replace.has(E_overlapping->key())) {
- TileMapCell neighbor_cell = tile_map->get_cell(E_overlapping->key());
+ TileMapCell neighbor_cell = tile_map->get_cell(tile_map_layer, E_overlapping->key());
TileData *neighbor_tile_data = nullptr;
if (terrain_tiles.has(neighbor_cell) && terrain_tiles[neighbor_cell]->get_terrain_set() == p_terrain_set) {
neighbor_tile_data = terrain_tiles[neighbor_cell];
@@ -2629,6 +2661,90 @@ Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map
return output;
}
+void TileMapEditorTerrainsPlugin::_stop_dragging() {
+ TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
+ if (!tile_map) {
+ return;
+ }
+
+ Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
+ Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position());
+
+ switch (drag_type) {
+ case DRAG_TYPE_PICK: {
+ Vector2i coords = tile_map->world_to_map(mpos);
+ TileMapCell tile = tile_map->get_cell(tile_map_layer, coords);
+
+ if (terrain_tiles.has(tile)) {
+ Array terrains_tile_pattern = _build_terrains_tile_pattern(terrain_tiles[tile]);
+
+ // Find the tree item for the right terrain set.
+ bool need_tree_item_switch = true;
+ TreeItem *tree_item = terrains_tree->get_selected();
+ if (tree_item) {
+ Dictionary metadata_dict = tree_item->get_metadata(0);
+ if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
+ int terrain_set = metadata_dict["terrain_set"];
+ int terrain_id = metadata_dict["terrain_id"];
+ if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
+ need_tree_item_switch = false;
+ }
+ }
+ }
+
+ if (need_tree_item_switch) {
+ for (tree_item = terrains_tree->get_root()->get_first_child(); tree_item; tree_item = tree_item->get_next_visible()) {
+ Dictionary metadata_dict = tree_item->get_metadata(0);
+ if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
+ int terrain_set = metadata_dict["terrain_set"];
+ int terrain_id = metadata_dict["terrain_id"];
+ if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
+ // Found
+ tree_item->select(0);
+ _update_tiles_list();
+ break;
+ }
+ }
+ }
+ }
+
+ // Find the list item for the given tile.
+ if (tree_item) {
+ for (int i = 0; i < terrains_tile_list->get_item_count(); i++) {
+ Dictionary metadata_dict = terrains_tile_list->get_item_metadata(i);
+ TerrainsTilePattern in_meta_terrains_tile_pattern = metadata_dict["terrains_tile_pattern"];
+ bool equals = true;
+ for (int j = 0; j < terrains_tile_pattern.size(); j++) {
+ if (terrains_tile_pattern[j] != in_meta_terrains_tile_pattern[j]) {
+ equals = false;
+ break;
+ }
+ }
+ if (equals) {
+ terrains_tile_list->select(i);
+ break;
+ }
+ }
+ } else {
+ ERR_PRINT("Terrain tile not found.");
+ }
+ }
+ picker_button->set_pressed(false);
+ } break;
+ case DRAG_TYPE_PAINT: {
+ undo_redo->create_action(TTR("Paint terrain"));
+ for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) {
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->key(), tile_map->get_cell_source_id(tile_map_layer, E->key()), tile_map->get_cell_atlas_coords(tile_map_layer, E->key()), tile_map->get_cell_alternative_tile(tile_map_layer, E->key()));
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ }
+ undo_redo->commit_action(false);
+ } break;
+ default:
+ break;
+ }
+ drag_type = DRAG_TYPE_NONE;
+}
+
bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
if (!is_visible_in_tree()) {
// If the bottom editor is not visible, we ignore inputs.
@@ -2649,6 +2765,11 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
return false;
}
+ if (tile_map_layer < 0) {
+ return false;
+ }
+ ERR_FAIL_COND_V(tile_map_layer >= tile_map->get_layers_count(), false);
+
// Get the selected terrain.
TerrainsTilePattern selected_terrains_tile_pattern;
int selected_terrain_set = -1;
@@ -2690,9 +2811,9 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
Map<Vector2i, TileMapCell> modified = _draw_terrains(to_draw, selected_terrain_set);
for (Map<Vector2i, TileMapCell>::Element *E = modified.front(); E; E = E->next()) {
if (!drag_modified.has(E->key())) {
- drag_modified[E->key()] = tile_map->get_cell(E->key());
+ drag_modified[E->key()] = tile_map->get_cell(tile_map_layer, E->key());
}
- tile_map->set_cell(E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ tile_map->set_cell(tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
}
} break;
@@ -2728,86 +2849,14 @@ bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent>
Map<Vector2i, TileMapCell> to_draw = _draw_terrains(terrains_to_draw, selected_terrain_set);
for (Map<Vector2i, TileMapCell>::Element *E = to_draw.front(); E; E = E->next()) {
- drag_modified[E->key()] = tile_map->get_cell(E->key());
- tile_map->set_cell(E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
+ drag_modified[E->key()] = tile_map->get_cell(tile_map_layer, E->key());
+ tile_map->set_cell(tile_map_layer, E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
}
}
}
} else {
// Released
- switch (drag_type) {
- case DRAG_TYPE_PICK: {
- Vector2i coords = tile_map->world_to_map(mpos);
- TileMapCell tile = tile_map->get_cell(coords);
-
- if (terrain_tiles.has(tile)) {
- Array terrains_tile_pattern = _build_terrains_tile_pattern(terrain_tiles[tile]);
-
- // Find the tree item for the right terrain set.
- bool need_tree_item_switch = true;
- TreeItem *tree_item = terrains_tree->get_selected();
- if (tree_item) {
- Dictionary metadata_dict = tree_item->get_metadata(0);
- if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
- int terrain_set = metadata_dict["terrain_set"];
- int terrain_id = metadata_dict["terrain_id"];
- if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
- need_tree_item_switch = false;
- }
- }
- }
-
- if (need_tree_item_switch) {
- for (tree_item = terrains_tree->get_root()->get_first_child(); tree_item; tree_item = tree_item->get_next_visible()) {
- Dictionary metadata_dict = tree_item->get_metadata(0);
- if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
- int terrain_set = metadata_dict["terrain_set"];
- int terrain_id = metadata_dict["terrain_id"];
- if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
- // Found
- tree_item->select(0);
- _update_tiles_list();
- break;
- }
- }
- }
- }
-
- // Find the list item for the given tile.
- if (tree_item) {
- for (int i = 0; i < terrains_tile_list->get_item_count(); i++) {
- Dictionary metadata_dict = terrains_tile_list->get_item_metadata(i);
- TerrainsTilePattern in_meta_terrains_tile_pattern = metadata_dict["terrains_tile_pattern"];
- bool equals = true;
- for (int j = 0; j < terrains_tile_pattern.size(); j++) {
- if (terrains_tile_pattern[j] != in_meta_terrains_tile_pattern[j]) {
- equals = false;
- break;
- }
- }
- if (equals) {
- terrains_tile_list->select(i);
- break;
- }
- }
- } else {
- ERR_PRINT("Terrain tile not found.");
- }
- }
- picker_button->set_pressed(false);
- } break;
- case DRAG_TYPE_PAINT: {
- undo_redo->create_action(TTR("Paint terrain"));
- for (Map<Vector2i, TileMapCell>::Element *E = drag_modified.front(); E; E = E->next()) {
- undo_redo->add_do_method(tile_map, "set_cell", E->key(), tile_map->get_cell_source_id(E->key()), tile_map->get_cell_atlas_coords(E->key()), tile_map->get_cell_alternative_tile(E->key()));
- undo_redo->add_undo_method(tile_map, "set_cell", E->key(), E->get().source_id, E->get().get_atlas_coords(), E->get().alternative_tile);
- }
- undo_redo->commit_action(false);
- } break;
- default:
- break;
- }
- drag_type = DRAG_TYPE_NONE;
+ _stop_dragging();
}
CanvasItemEditor::get_singleton()->update_viewport();
@@ -3080,8 +3129,12 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() {
}
}
-void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id) {
+void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer) {
+ _stop_dragging(); // Avoids staying in a wrong drag state.
+
tile_map_id = p_tile_map_id;
+ tile_map_layer = p_tile_map_layer;
+
_update_terrains_cache();
_update_terrains_tree();
_update_tiles_list();
@@ -3166,10 +3219,12 @@ void TileMapEditor::_notification(int p_what) {
advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons")));
toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
+ toogle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons")));
break;
case NOTIFICATION_INTERNAL_PROCESS:
if (is_visible_in_tree() && tileset_changed_needs_update) {
_update_bottom_panel();
+ _update_layers_selection();
tile_map_editor_plugins[tabs->get_current_tab()]->tile_set_changed();
CanvasItemEditor::get_singleton()->update_viewport();
tileset_changed_needs_update = false;
@@ -3178,6 +3233,16 @@ void TileMapEditor::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
break;
+ case NOTIFICATION_VISIBILITY_CHANGED:
+ TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
+ if (tile_map) {
+ if (is_visible_in_tree()) {
+ tile_map->set_selected_layer(tile_map_layer);
+ } else {
+ tile_map->set_selected_layer(-1);
+ }
+ }
+ break;
}
}
@@ -3185,6 +3250,63 @@ void TileMapEditor::_on_grid_toggled(bool p_pressed) {
EditorSettings::get_singleton()->set("editors/tiles_editor/display_grid", p_pressed);
}
+void TileMapEditor::_layers_selection_button_draw() {
+ if (!has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) {
+ return;
+ }
+
+ RID ci = layers_selection_button->get_canvas_item();
+ Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton"));
+
+ Color clr = Color(1, 1, 1);
+ if (get_theme_constant(SNAME("modulate_arrow"))) {
+ switch (layers_selection_button->get_draw_mode()) {
+ case BaseButton::DRAW_PRESSED:
+ clr = get_theme_color(SNAME("font_pressed_color"));
+ break;
+ case BaseButton::DRAW_HOVER:
+ clr = get_theme_color(SNAME("font_hover_color"));
+ break;
+ case BaseButton::DRAW_DISABLED:
+ clr = get_theme_color(SNAME("font_disabled_color"));
+ break;
+ default:
+ clr = get_theme_color(SNAME("font_color"));
+ }
+ }
+
+ Size2 size = layers_selection_button->get_size();
+
+ Point2 ofs;
+ if (is_layout_rtl()) {
+ ofs = Point2(get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2)));
+ } else {
+ ofs = Point2(size.width - arrow->get_width() - get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2)));
+ }
+ Rect2 dst_rect = Rect2(ofs, arrow->get_size());
+ if (!layers_selection_button->is_pressed()) {
+ dst_rect.size = -dst_rect.size;
+ }
+ arrow->draw_rect(ci, dst_rect, false, clr);
+}
+
+void TileMapEditor::_layers_selection_button_pressed() {
+ if (!layers_selection_popup->is_visible()) {
+ Size2 size = layers_selection_popup->get_contents_minimum_size();
+ size.x = MAX(size.x, layers_selection_button->get_size().x);
+ layers_selection_popup->set_position(layers_selection_button->get_screen_position() - Size2(0, size.y * get_global_transform().get_scale().y));
+ layers_selection_popup->set_size(size);
+ layers_selection_popup->popup();
+ } else {
+ layers_selection_popup->hide();
+ }
+}
+
+void TileMapEditor::_layers_selection_id_pressed(int p_id) {
+ tile_map_layer = p_id;
+ _update_layers_selection();
+}
+
void TileMapEditor::_advanced_menu_button_id_pressed(int p_id) {
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (!tile_map) {
@@ -3198,18 +3320,20 @@ void TileMapEditor::_advanced_menu_button_id_pressed(int p_id) {
if (p_id == 0) { // Replace Tile Proxies
undo_redo->create_action(TTR("Replace Tiles with Proxies"));
- TypedArray<Vector2i> used_cells = tile_map->get_used_cells();
- for (int i = 0; i < used_cells.size(); i++) {
- Vector2i cell_coords = used_cells[i];
- TileMapCell from = tile_map->get_cell(cell_coords);
- Array to_array = tile_set->map_tile_proxy(from.source_id, from.get_atlas_coords(), from.alternative_tile);
- TileMapCell to;
- to.source_id = to_array[0];
- to.set_atlas_coords(to_array[1]);
- to.alternative_tile = to_array[2];
- if (from != to) {
- undo_redo->add_do_method(tile_map, "set_cell", cell_coords, to.source_id, to.get_atlas_coords(), to.alternative_tile);
- undo_redo->add_undo_method(tile_map, "set_cell", cell_coords, from.source_id, from.get_atlas_coords(), from.alternative_tile);
+ for (int layer_index = 0; layer_index < tile_map->get_layers_count(); layer_index++) {
+ TypedArray<Vector2i> used_cells = tile_map->get_used_cells(layer_index);
+ for (int i = 0; i < used_cells.size(); i++) {
+ Vector2i cell_coords = used_cells[i];
+ TileMapCell from = tile_map->get_cell(layer_index, cell_coords);
+ Array to_array = tile_set->map_tile_proxy(from.source_id, from.get_atlas_coords(), from.alternative_tile);
+ TileMapCell to;
+ to.source_id = to_array[0];
+ to.set_atlas_coords(to_array[1]);
+ to.alternative_tile = to_array[2];
+ if (from != to) {
+ undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, cell_coords, to.source_id, to.get_atlas_coords(), to.alternative_tile);
+ undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, cell_coords, from.source_id, from.get_atlas_coords(), from.alternative_tile);
+ }
}
}
undo_redo->commit_action();
@@ -3315,7 +3439,7 @@ void TileMapEditor::_tile_map_changed() {
void TileMapEditor::_tab_changed(int p_tab_id) {
// Make the plugin edit the correct tilemap.
- tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id);
+ tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
// Update toolbar.
for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
@@ -3339,7 +3463,129 @@ void TileMapEditor::_tab_changed(int p_tab_id) {
CanvasItemEditor::get_singleton()->update_viewport();
}
+void TileMapEditor::_layers_select_next_or_previous(bool p_next) {
+ TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
+ if (!tile_map) {
+ return;
+ }
+
+ if (tile_map->get_layers_count() < 1) {
+ return;
+ }
+
+ if (tile_map_layer < 0) {
+ tile_map_layer = 0;
+ }
+
+ int inc = p_next ? 1 : -1;
+ int origin_layer = tile_map_layer;
+ tile_map_layer = Math::posmod((tile_map_layer + inc), tile_map->get_layers_count());
+ while (tile_map_layer != origin_layer) {
+ if (tile_map->is_layer_enabled(tile_map_layer)) {
+ break;
+ }
+ tile_map_layer = Math::posmod((tile_map_layer + inc), tile_map->get_layers_count());
+ }
+
+ _update_layers_selection();
+}
+
+void TileMapEditor::_update_layers_selection() {
+ layers_selection_popup->clear();
+
+ TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
+ if (!tile_map) {
+ return;
+ }
+
+ // Update the selected layer.
+ if (is_visible_in_tree() && tile_map->get_layers_count() >= 1) {
+ tile_map_layer = CLAMP(tile_map_layer, 0, tile_map->get_layers_count() - 1);
+
+ // Search for an enabled layer if the current one is not.
+ int origin_layer = tile_map_layer;
+ while (tile_map_layer >= 0 && !tile_map->is_layer_enabled(tile_map_layer)) {
+ tile_map_layer--;
+ }
+ if (tile_map_layer < 0) {
+ tile_map_layer = origin_layer;
+ while (tile_map_layer < tile_map->get_layers_count() && !tile_map->is_layer_enabled(tile_map_layer)) {
+ tile_map_layer++;
+ }
+ }
+ if (tile_map_layer >= tile_map->get_layers_count()) {
+ tile_map_layer = -1;
+ }
+ } else {
+ tile_map_layer = -1;
+ }
+ tile_map->set_selected_layer(toogle_highlight_selected_layer_button->is_pressed() ? tile_map_layer : -1);
+
+ // Build the list of layers.
+ for (int i = 0; i < tile_map->get_layers_count(); i++) {
+ String name = tile_map->get_layer_name(i);
+ layers_selection_popup->add_item(name.is_empty() ? vformat(TTR("Layer #%d"), i) : name, i);
+ layers_selection_popup->set_item_as_radio_checkable(i, true);
+ layers_selection_popup->set_item_disabled(i, !tile_map->is_layer_enabled(i));
+ layers_selection_popup->set_item_checked(i, i == tile_map_layer);
+ }
+
+ // Update the button label.
+ if (tile_map_layer >= 0) {
+ layers_selection_button->set_text(layers_selection_popup->get_item_text(tile_map_layer));
+ } else {
+ layers_selection_button->set_text(TTR("Select a layer"));
+ }
+
+ // Set button minimum width.
+ Size2 min_button_size = Size2(layers_selection_popup->get_contents_minimum_size().x, 0);
+ if (has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) {
+ Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton"));
+ min_button_size.x += arrow->get_size().x;
+ }
+ layers_selection_button->set_custom_minimum_size(min_button_size);
+ layers_selection_button->update();
+
+ tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
+}
+
+void TileMapEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value) {
+ UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
+ ERR_FAIL_COND(!undo_redo);
+
+ TileMap *tile_map = Object::cast_to<TileMap>(p_edited);
+ if (tile_map) {
+ if (p_property == "layers_count") {
+ int new_layers_count = (int)p_new_value;
+ if (new_layers_count < tile_map->get_layers_count()) {
+ List<PropertyInfo> property_list;
+ tile_map->get_property_list(&property_list);
+
+ for (PropertyInfo property_info : property_list) {
+ Vector<String> components = String(property_info.name).split("/", true, 2);
+ if (components.size() == 2 && components[0].begins_with("layer_") && components[0].trim_prefix("layer_").is_valid_int()) {
+ int index = components[0].trim_prefix("layer_").to_int();
+ if (index >= new_layers_count) {
+ undo_redo->add_undo_property(tile_map, property_info.name, tile_map->get(property_info.name));
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
bool TileMapEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
+ if (ED_IS_SHORTCUT("tiles_editor/select_next_layer", p_event) && p_event->is_pressed()) {
+ _layers_select_next_or_previous(true);
+ return true;
+ }
+
+ if (ED_IS_SHORTCUT("tiles_editor/select_previous_layer", p_event) && p_event->is_pressed()) {
+ _layers_select_next_or_previous(false);
+ return true;
+ }
+
return tile_map_editor_plugins[tabs->get_current_tab()]->forward_canvas_gui_input(p_event);
}
@@ -3363,49 +3609,52 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Vector2i tile_shape_size = tile_set->get_tile_size();
// Draw tiles with invalid IDs in the grid.
- TypedArray<Vector2i> used_cells = tile_map->get_used_cells();
- for (int i = 0; i < used_cells.size(); i++) {
- Vector2i coords = used_cells[i];
- int tile_source_id = tile_map->get_cell_source_id(coords);
- if (tile_source_id >= 0) {
- Vector2i tile_atlas_coords = tile_map->get_cell_atlas_coords(coords);
- int tile_alternative_tile = tile_map->get_cell_alternative_tile(coords);
-
- TileSetSource *source = nullptr;
- if (tile_set->has_source(tile_source_id)) {
- source = *tile_set->get_source(tile_source_id);
- }
-
- if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
- // Generate a random color from the hashed values of the tiles.
- Array a = tile_set->map_tile_proxy(tile_source_id, tile_atlas_coords, tile_alternative_tile);
- if (int(a[0]) == tile_source_id && Vector2i(a[1]) == tile_atlas_coords && int(a[2]) == tile_alternative_tile) {
- // Only display the pattern if we have no proxy tile.
- Array to_hash;
- to_hash.push_back(tile_source_id);
- to_hash.push_back(tile_atlas_coords);
- to_hash.push_back(tile_alternative_tile);
- uint32_t hash = RandomPCG(to_hash.hash()).rand();
-
- Color color;
- color = color.from_hsv(
- (float)((hash >> 24) & 0xFF) / 256.0,
- Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
- Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
- 0.8);
-
- // Draw the scaled tile.
- Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(coords) - Vector2(tile_shape_size) / 2, Vector2(tile_shape_size)));
- tile_set->draw_tile_shape(p_overlay, cell_region, color, true, warning_pattern_texture);
+ if (tile_map_layer >= 0) {
+ ERR_FAIL_COND(tile_map_layer >= tile_map->get_layers_count());
+ TypedArray<Vector2i> used_cells = tile_map->get_used_cells(tile_map_layer);
+ for (int i = 0; i < used_cells.size(); i++) {
+ Vector2i coords = used_cells[i];
+ int tile_source_id = tile_map->get_cell_source_id(tile_map_layer, coords);
+ if (tile_source_id >= 0) {
+ Vector2i tile_atlas_coords = tile_map->get_cell_atlas_coords(tile_map_layer, coords);
+ int tile_alternative_tile = tile_map->get_cell_alternative_tile(tile_map_layer, coords);
+
+ TileSetSource *source = nullptr;
+ if (tile_set->has_source(tile_source_id)) {
+ source = *tile_set->get_source(tile_source_id);
}
- // Draw the warning icon.
- int min_axis = missing_tile_texture->get_size().min_axis();
- Vector2 icon_size;
- icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
- icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
- Rect2 rect = Rect2(xform.xform(tile_map->map_to_world(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
- p_overlay->draw_texture_rect(missing_tile_texture, rect);
+ if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
+ // Generate a random color from the hashed values of the tiles.
+ Array a = tile_set->map_tile_proxy(tile_source_id, tile_atlas_coords, tile_alternative_tile);
+ if (int(a[0]) == tile_source_id && Vector2i(a[1]) == tile_atlas_coords && int(a[2]) == tile_alternative_tile) {
+ // Only display the pattern if we have no proxy tile.
+ Array to_hash;
+ to_hash.push_back(tile_source_id);
+ to_hash.push_back(tile_atlas_coords);
+ to_hash.push_back(tile_alternative_tile);
+ uint32_t hash = RandomPCG(to_hash.hash()).rand();
+
+ Color color;
+ color = color.from_hsv(
+ (float)((hash >> 24) & 0xFF) / 256.0,
+ Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
+ Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
+ 0.8);
+
+ // Draw the scaled tile.
+ Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(coords) - Vector2(tile_shape_size) / 2, Vector2(tile_shape_size)));
+ tile_set->draw_tile_shape(p_overlay, cell_region, color, true, warning_pattern_texture);
+ }
+
+ // Draw the warning icon.
+ int min_axis = missing_tile_texture->get_size().min_axis();
+ Vector2 icon_size;
+ icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
+ icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
+ Rect2 rect = Rect2(xform.xform(tile_map->map_to_world(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
+ p_overlay->draw_texture_rect(missing_tile_texture, rect);
+ }
}
}
}
@@ -3476,14 +3725,19 @@ void TileMapEditor::edit(TileMap *p_tile_map) {
return;
}
- // Disconnect to changes.
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (tile_map) {
+ // Unselect layer if we are changing tile_map.
+ if (tile_map != p_tile_map) {
+ tile_map->set_selected_layer(-1);
+ }
+
+ // Disconnect to changes.
tile_map->disconnect("changed", callable_mp(this, &TileMapEditor::_tile_map_changed));
}
- // Change the edited object.
if (p_tile_map) {
+ // Change the edited object.
tile_map_id = p_tile_map->get_instance_id();
tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
// Connect to changes.
@@ -3494,8 +3748,10 @@ void TileMapEditor::edit(TileMap *p_tile_map) {
tile_map_id = ObjectID();
}
+ _update_layers_selection();
+
// Call the plugins.
- tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id);
+ tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
_tile_map_changed();
}
@@ -3503,6 +3759,10 @@ void TileMapEditor::edit(TileMap *p_tile_map) {
TileMapEditor::TileMapEditor() {
set_process_internal(true);
+ // Shortcuts.
+ ED_SHORTCUT("tiles_editor/select_next_layer", TTR("Select Next Tile Map Layer"), KEY_PAGEUP);
+ ED_SHORTCUT("tiles_editor/select_previous_layer", TTR("Select Previous Tile Map Layer"), KEY_PAGEDOWN);
+
// TileMap editor plugins
tile_map_editor_plugins.push_back(memnew(TileMapEditorTilesPlugin));
tile_map_editor_plugins.push_back(memnew(TileMapEditorTerrainsPlugin));
@@ -3516,18 +3776,46 @@ TileMapEditor::TileMapEditor() {
tabs->connect("tab_changed", callable_mp(this, &TileMapEditor::_tab_changed));
// --- TileMap toolbar ---
- tilemap_toolbar = memnew(HBoxContainer);
- tilemap_toolbar->set_h_size_flags(SIZE_EXPAND_FILL);
- tilemap_toolbar->add_child(tabs);
+ tile_map_toolbar = memnew(HBoxContainer);
+ tile_map_toolbar->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ // Tabs.
+ tile_map_toolbar->add_child(tabs);
+
+ // Tabs toolbars.
for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
tile_map_editor_plugins[i]->get_toolbar()->hide();
- tilemap_toolbar->add_child(tile_map_editor_plugins[i]->get_toolbar());
+ tile_map_toolbar->add_child(tile_map_editor_plugins[i]->get_toolbar());
}
// Wide empty separation control.
Control *h_empty_space = memnew(Control);
h_empty_space->set_h_size_flags(SIZE_EXPAND_FILL);
- tilemap_toolbar->add_child(h_empty_space);
+ tile_map_toolbar->add_child(h_empty_space);
+
+ // Layer selector.
+ layers_selection_popup = memnew(PopupMenu);
+ layers_selection_popup->connect("id_pressed", callable_mp(this, &TileMapEditor::_layers_selection_id_pressed));
+ layers_selection_popup->set_close_on_parent_focus(false);
+
+ layers_selection_button = memnew(Button);
+ layers_selection_button->set_toggle_mode(true);
+ layers_selection_button->connect("draw", callable_mp(this, &TileMapEditor::_layers_selection_button_draw));
+ layers_selection_button->connect("pressed", callable_mp(this, &TileMapEditor::_layers_selection_button_pressed));
+ layers_selection_button->connect("hidden", callable_mp((Window *)layers_selection_popup, &Popup::hide));
+ layers_selection_button->set_tooltip(TTR("Tile Map Layer"));
+ layers_selection_button->add_child(layers_selection_popup);
+ tile_map_toolbar->add_child(layers_selection_button);
+
+ toogle_highlight_selected_layer_button = memnew(Button);
+ toogle_highlight_selected_layer_button->set_flat(true);
+ toogle_highlight_selected_layer_button->set_toggle_mode(true);
+ toogle_highlight_selected_layer_button->set_pressed(true);
+ toogle_highlight_selected_layer_button->connect("pressed", callable_mp(this, &TileMapEditor::_update_layers_selection));
+ toogle_highlight_selected_layer_button->set_tooltip(TTR("Highlight Selected TileMap Layer"));
+ tile_map_toolbar->add_child(toogle_highlight_selected_layer_button);
+
+ tile_map_toolbar->add_child(memnew(VSeparator));
// Grid toggle.
toggle_grid_button = memnew(Button);
@@ -3535,14 +3823,14 @@ TileMapEditor::TileMapEditor() {
toggle_grid_button->set_toggle_mode(true);
toggle_grid_button->set_tooltip(TTR("Toggle grid visibility."));
toggle_grid_button->connect("toggled", callable_mp(this, &TileMapEditor::_on_grid_toggled));
- tilemap_toolbar->add_child(toggle_grid_button);
+ tile_map_toolbar->add_child(toggle_grid_button);
// Advanced settings menu button.
advanced_menu_button = memnew(MenuButton);
advanced_menu_button->set_flat(true);
advanced_menu_button->get_popup()->add_item(TTR("Automatically Replace Tiles with Proxies"));
advanced_menu_button->get_popup()->connect("id_pressed", callable_mp(this, &TileMapEditor::_advanced_menu_button_id_pressed));
- tilemap_toolbar->add_child(advanced_menu_button);
+ tile_map_toolbar->add_child(advanced_menu_button);
missing_tileset_label = memnew(Label);
missing_tileset_label->set_text(TTR("The edited TileMap node has no TileSet resource."));
@@ -3561,6 +3849,9 @@ TileMapEditor::TileMapEditor() {
}
_tab_changed(0);
+
+ // Registers UndoRedo inspector callback.
+ EditorNode::get_singleton()->get_editor_data().add_undo_redo_inspector_hook_callback(callable_mp(this, &TileMapEditor::_undo_redo_inspector_callback));
}
TileMapEditor::~TileMapEditor() {
diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h
index 236774a06b..6e2f2ce2ba 100644
--- a/editor/plugins/tiles/tile_map_editor.h
+++ b/editor/plugins/tiles/tile_map_editor.h
@@ -47,7 +47,7 @@ public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return false; };
virtual void forward_canvas_draw_over_viewport(Control *p_overlay){};
virtual void tile_set_changed(){};
- virtual void edit(ObjectID p_tile_map_id){};
+ virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer){};
};
class TileMapEditorTilesPlugin : public TileMapEditorPlugin {
@@ -56,7 +56,8 @@ class TileMapEditorTilesPlugin : public TileMapEditorPlugin {
private:
UndoRedo *undo_redo = EditorNode::get_undo_redo();
ObjectID tile_map_id;
- virtual void edit(ObjectID p_tile_map_id) override;
+ int tile_map_layer = -1;
+ virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
///// Toolbar /////
HBoxContainer *toolbar;
@@ -185,7 +186,8 @@ class TileMapEditorTerrainsPlugin : public TileMapEditorPlugin {
private:
UndoRedo *undo_redo = EditorNode::get_undo_redo();
ObjectID tile_map_id;
- virtual void edit(ObjectID p_tile_map_id) override;
+ int tile_map_layer = -1;
+ virtual void edit(ObjectID p_tile_map_id, int p_tile_map_layer) override;
// Toolbar.
HBoxContainer *toolbar;
@@ -258,9 +260,9 @@ private:
Map<Vector2i, TerrainsTilePattern> _wave_function_collapse(const Set<Vector2i> &p_to_replace, int p_terrain_set, const Set<TileMapEditorTerrainsPlugin::Constraint> p_constraints) const;
TileMapCell _get_random_tile_from_pattern(int p_terrain_set, TerrainsTilePattern p_terrain_tile_pattern) const;
Map<Vector2i, TileMapCell> _draw_terrains(const Map<Vector2i, TerrainsTilePattern> &p_to_paint, int p_terrain_set) const;
+ void _stop_dragging();
// Cached data.
-
TerrainsTilePattern _build_terrains_tile_pattern(TileData *p_tile_data);
LocalVector<Map<TerrainsTilePattern, Set<TileMapCell>>> per_terrain_terrains_tile_patterns_tiles;
LocalVector<LocalVector<Set<TerrainsTilePattern>>> per_terrain_terrains_tile_patterns;
@@ -300,12 +302,20 @@ private:
UndoRedo *undo_redo = EditorNode::get_undo_redo();
bool tileset_changed_needs_update = false;
ObjectID tile_map_id;
+ int tile_map_layer = -1;
// Vector to keep plugins.
Vector<TileMapEditorPlugin *> tile_map_editor_plugins;
// Toolbar.
- HBoxContainer *tilemap_toolbar;
+ HBoxContainer *tile_map_toolbar;
+
+ PopupMenu *layers_selection_popup;
+ Button *layers_selection_button;
+ Button *toogle_highlight_selected_layer_button;
+ void _layers_selection_button_draw();
+ void _layers_selection_button_pressed();
+ void _layers_selection_id_pressed(int p_id);
Button *toggle_grid_button;
void _on_grid_toggled(bool p_pressed);
@@ -313,19 +323,26 @@ private:
MenuButton *advanced_menu_button;
void _advanced_menu_button_id_pressed(int p_id);
- // Bottom panel
+ // Bottom panel.
Label *missing_tileset_label;
Tabs *tabs;
void _update_bottom_panel();
- // TileMap
+ // TileMap.
Ref<Texture2D> missing_tile_texture;
Ref<Texture2D> warning_pattern_texture;
- // CallBack
+ // CallBack.
void _tile_map_changed();
void _tab_changed(int p_tab_changed);
+ // Updates.
+ void _layers_select_next_or_previous(bool p_next);
+ void _update_layers_selection();
+
+ // Inspector undo/redo callback.
+ void _undo_redo_inspector_callback(Object *p_undo_redo, Object *p_edited, String p_property, Variant p_new_value);
+
protected:
void _notification(int p_what);
void _draw_shape(Control *p_control, Rect2 p_region, TileSet::TileShape p_shape, TileSet::TileOffsetAxis p_offset_axis, Color p_color);
@@ -335,7 +352,7 @@ public:
void forward_canvas_draw_over_viewport(Control *p_overlay);
void edit(TileMap *p_tile_map);
- Control *get_toolbar() { return tilemap_toolbar; };
+ Control *get_toolbar() { return tile_map_toolbar; };
TileMapEditor();
~TileMapEditor();
diff --git a/editor/plugins/tiles/tile_proxies_manager_dialog.h b/editor/plugins/tiles/tile_proxies_manager_dialog.h
index f6898e960b..6849be2cd6 100644
--- a/editor/plugins/tiles/tile_proxies_manager_dialog.h
+++ b/editor/plugins/tiles/tile_proxies_manager_dialog.h
@@ -34,9 +34,9 @@
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
+#include "scene/2d/tile_map.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
-#include "scene/resources/tile_set.h"
class TileProxiesManagerDialog : public ConfirmationDialog {
GDCLASS(TileProxiesManagerDialog, ConfirmationDialog);
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 5804f54649..a9a36427db 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -31,6 +31,7 @@
#include "version_control_editor_plugin.h"
#include "core/object/script_language.h"
+#include "core/os/keyboard.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
@@ -292,6 +293,29 @@ void VersionControlEditorPlugin::_update_commit_button() {
commit_button->set_disabled(commit_message->get_text().strip_edges() == "");
}
+void VersionControlEditorPlugin::_commit_message_gui_input(const Ref<InputEvent> &p_event) {
+ if (!commit_message->has_focus()) {
+ return;
+ }
+ if (commit_message->get_text().strip_edges().is_empty()) {
+ // Do not allow empty commit messages.
+ return;
+ }
+ const Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid() && k->is_pressed()) {
+ if (ED_IS_SHORTCUT("version_control/commit", p_event)) {
+ if (staged_files_count == 0) {
+ // Stage all files only when no files were previously staged.
+ _stage_all();
+ }
+ _send_commit_msg();
+ commit_message->accept_event();
+ return;
+ }
+ }
+}
+
void VersionControlEditorPlugin::register_editor() {
if (!EditorVCSInterface::get_singleton()) {
EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock);
@@ -462,7 +486,9 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
commit_message->set_custom_minimum_size(Size2(200, 100));
commit_message->set_wrap_enabled(true);
commit_message->connect("text_changed", callable_mp(this, &VersionControlEditorPlugin::_update_commit_button));
+ commit_message->connect("gui_input", callable_mp(this, &VersionControlEditorPlugin::_commit_message_gui_input));
commit_box_vbc->add_child(commit_message);
+ ED_SHORTCUT("version_control/commit", TTR("Commit"), KEY_MASK_CMD | KEY_ENTER);
commit_button = memnew(Button);
commit_button->set_text(TTR("Commit Changes"));
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
index 7d7c66a7ee..d2ba63c86c 100644
--- a/editor/plugins/version_control_editor_plugin.h
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -111,6 +111,7 @@ private:
void _update_stage_status();
void _update_commit_status();
void _update_commit_button();
+ void _commit_message_gui_input(const Ref<InputEvent> &p_event);
friend class EditorVCSInterface;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index add75d47fd..452ad126b3 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -35,7 +35,6 @@
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
#include "core/os/keyboard.h"
-#include "core/version.h"
#include "editor/editor_log.h"
#include "editor/editor_properties.h"
#include "editor/editor_scale.h"
@@ -921,6 +920,10 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
expression_box->add_comment_delimiter("/*", "*/", false);
expression_box->add_comment_delimiter("//", "", true);
+ if (!expression_box->has_auto_brace_completion_open_key("/*")) {
+ expression_box->add_auto_brace_completion_pair("/*", "*/");
+ }
+
expression_box->set_text(expression);
expression_box->set_context_menu_enabled(false);
expression_box->set_draw_line_numbers(true);
@@ -995,9 +998,23 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
visual_shader->connect("changed", callable_mp(this, &VisualShaderEditor::_update_preview));
}
#ifndef DISABLE_DEPRECATED
- String version = VERSION_BRANCH;
- if (visual_shader->get_version() != version) {
- visual_shader->update_version(version);
+ Dictionary engine_version = Engine::get_singleton()->get_version_info();
+ static Array components;
+ if (components.is_empty()) {
+ components.push_back("major");
+ components.push_back("minor");
+ }
+ const Dictionary vs_version = visual_shader->get_engine_version();
+ if (!vs_version.has_all(components)) {
+ visual_shader->update_engine_version(engine_version);
+ } else {
+ for (int i = 0; i < components.size(); i++) {
+ if (vs_version[components[i]] != engine_version[components[i]]) {
+ visual_shader->update_engine_version(engine_version);
+ print_line(vformat(TTR("The shader (\"%s\") has been updated to correspond Godot %s.%s version."), visual_shader->get_path(), engine_version["major"], engine_version["minor"]));
+ break;
+ }
+ }
}
#endif
visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE);
@@ -4143,6 +4160,8 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), "output_is_srgb", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV2", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
@@ -4175,8 +4194,6 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Input", "Input", "Common", "VisualShaderNodeInput", TTR("Input parameter.")));
- // SPATIAL INPUTS
-
const String input_param_for_vertex_and_fragment_shader_modes = TTR("'%s' input parameter for vertex and fragment shader modes.");
const String input_param_for_fragment_and_light_shader_modes = TTR("'%s' input parameter for fragment and light shader modes.");
const String input_param_for_fragment_shader_mode = TTR("'%s' input parameter for fragment shader mode.");
@@ -4190,6 +4207,19 @@ VisualShaderEditor::VisualShaderEditor() {
const String input_param_for_process_and_collide_shader_mode = TTR("'%s' input parameter for process and collide shader modes.");
const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader modes.");
+ // NODE3D INPUTS
+
+ add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), "instance_id", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), "instance_custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), "instance_custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+
add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
@@ -4199,15 +4229,13 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Side", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "side"), "side", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV2", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), "backlight", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
@@ -4215,21 +4243,19 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Metallic", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "metallic"), "metallic", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), "backlight", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV2", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
-
// CANVASITEM INPUTS
+ add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), "at_light_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), "canvas", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), "instance_custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), "instance_custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), "screen", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+
add_options.push_back(AddOption("AtLightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), "at_light_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), "normal_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
@@ -4241,6 +4267,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), "specular_shininess_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininessTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "specular_shininess_texture"), "specular_shininess_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
@@ -4248,23 +4275,16 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightColorAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color_alpha"), "light_color_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), "light_position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_vertex"), "light_vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), "light_vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), "shadow", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), "shadow_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), "specular_shininess", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), "specular_shininess_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), "at_light_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), "canvas", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), "screen", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
-
// SKY INPUTS
add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
@@ -4297,12 +4317,14 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- // PARTICLES
+ // PARTICLES INPUTS
add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), "collision_depth", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), "collision_normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, -1, Shader::MODE_PARTICLES));
+ // PARTICLES
+
+ add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", "A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters.", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
@@ -4320,7 +4342,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("FloatOp", "Scalar", "Common", "VisualShaderNodeFloatOp", TTR("Float operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("IntOp", "Scalar", "Common", "VisualShaderNodeIntOp", TTR("Integer operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- //CONSTANTS
+ // CONSTANTS
for (int i = 0; i < MAX_FLOAT_CONST_DEFS; i++) {
add_options.push_back(AddOption(float_constant_defs[i].name, "Scalar", "Constants", "VisualShaderNodeFloatConstant", float_constant_defs[i].desc, -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, float_constant_defs[i].value));