diff options
Diffstat (limited to 'editor/plugins')
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)); |