diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-04-13 10:21:44 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-13 10:21:44 -0300 |
commit | 1d15c5d726600047805ab10d53ff2a7efdc41d8e (patch) | |
tree | b2e2cbe054e4d12c5ffa1172d504a0188e09274f | |
parent | 3a5b25d5b489ad88c2861c9c37b56469580fbf03 (diff) | |
parent | a724f34ef30bdf362b9059634e4ef21e21101ddd (diff) |
Merge pull request #17502 from groud/2Deditor_rect
Remove the rect surrounding 2D nodes in 2D editor when it's not pertinent
37 files changed, 788 insertions, 274 deletions
diff --git a/editor/icons/icon_editor_position.svg b/editor/icons/icon_editor_position.svg new file mode 100644 index 0000000000..7cbce07fab --- /dev/null +++ b/editor/icons/icon_editor_position.svg @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg919" + sodipodi:docname="icon_editor_position.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06"> + <metadata + id="metadata925"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs923" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2550" + inkscape:window-height="1414" + id="namedview921" + showgrid="false" + inkscape:zoom="64" + inkscape:cx="13.492036" + inkscape:cy="5.8518769" + inkscape:window-x="1370" + inkscape:window-y="20" + inkscape:window-maximized="0" + inkscape:current-layer="svg919" + inkscape:snap-page="true" /> + <g + id="g6479"> + <path + id="path913" + d="M 6 0 L 6 4.4199219 A 4.2661548 4.0576186 0 0 0 4.2910156 6 L 0 6 L 0 10 L 4.2949219 10 A 4.2661548 4.0576186 0 0 0 6 11.582031 L 6 16 L 10 16 L 10 11.580078 A 4.2661548 4.0576186 0 0 0 11.708984 10 L 16 10 L 16 6 L 11.705078 6 A 4.2661548 4.0576186 0 0 0 10 4.4179688 L 10 0 L 6 0 z " + style="fill:#ffffff;fill-opacity:0.70588237" /> + <path + id="path915" + d="M 7 1 L 7 4.0605469 A 4.2661548 4.0576186 0 0 1 8 3.9414062 A 4.2661548 4.0576186 0 0 1 9 4.0605469 L 9 1 L 7 1 z M 1 7 L 1 9 L 3.8691406 9 A 4.2661548 4.0576186 0 0 1 3.734375 8 A 4.2661548 4.0576186 0 0 1 3.8710938 7 L 1 7 z M 12.130859 7 A 4.2661548 4.0576186 0 0 1 12.265625 8 A 4.2661548 4.0576186 0 0 1 12.128906 9 L 15 9 L 15 7 L 12.130859 7 z M 7 11.939453 L 7 15 L 9 15 L 9 11.939453 A 4.2661548 4.0576186 0 0 1 8 12.058594 A 4.2661548 4.0576186 0 0 1 7 11.939453 z " + style="fill:#ff8484;stroke:none;fill-opacity:1" /> + <circle + id="circle1517" + r="2.9201488" + cy="8" + cx="8" + style="fill:#ff8484;fill-opacity:1;stroke-width:0.97338283" /> + </g> +</svg> diff --git a/editor/icons/icon_editor_position_previous.svg b/editor/icons/icon_editor_position_previous.svg new file mode 100644 index 0000000000..d9eb7d7ce2 --- /dev/null +++ b/editor/icons/icon_editor_position_previous.svg @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg919" + sodipodi:docname="icon_editor_position_previous.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06"> + <metadata + id="metadata925"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs923" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1356" + inkscape:window-height="742" + id="namedview921" + showgrid="false" + inkscape:zoom="11.313709" + inkscape:cx="14.523034" + inkscape:cy="-5.7323703" + inkscape:window-x="4" + inkscape:window-y="20" + inkscape:window-maximized="0" + inkscape:current-layer="svg919" + inkscape:snap-page="true" /> + <path + style="fill:#6699ff;stroke:none;fill-opacity:0.69803923" + d="M 7 1 L 7 4.0605469 A 4.2661548 4.0576186 0 0 1 8 3.9414062 A 4.2661548 4.0576186 0 0 1 9 4.0605469 L 9 1 L 7 1 z M 1 7 L 1 9 L 3.8691406 9 A 4.2661548 4.0576186 0 0 1 3.734375 8 A 4.2661548 4.0576186 0 0 1 3.8710938 7 L 1 7 z M 12.130859 7 A 4.2661548 4.0576186 0 0 1 12.265625 8 A 4.2661548 4.0576186 0 0 1 12.128906 9 L 15 9 L 15 7 L 12.130859 7 z M 7 11.939453 L 7 15 L 9 15 L 9 11.939453 A 4.2661548 4.0576186 0 0 1 8 12.058594 A 4.2661548 4.0576186 0 0 1 7 11.939453 z " + id="path915" /> + <circle + style="fill:#6699ff;fill-opacity:0.69803923;stroke-width:0.97338283" + cx="8" + cy="8" + r="2.9201488" + id="circle1517" /> +</svg> diff --git a/editor/icons/icon_editor_position_unselected.svg b/editor/icons/icon_editor_position_unselected.svg new file mode 100644 index 0000000000..8f32c89f16 --- /dev/null +++ b/editor/icons/icon_editor_position_unselected.svg @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg919" + sodipodi:docname="icon_editor_position_unselected.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06"> + <metadata + id="metadata925"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs923" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2550" + inkscape:window-height="1414" + id="namedview921" + showgrid="false" + inkscape:zoom="64" + inkscape:cx="13.492036" + inkscape:cy="8.3518769" + inkscape:window-x="1370" + inkscape:window-y="20" + inkscape:window-maximized="0" + inkscape:current-layer="svg919" + inkscape:snap-page="true" /> + <path + style="fill:#000000;fill-opacity:0.41077441" + d="M 6 0 L 6 4.4199219 A 4.2661548 4.0576186 0 0 0 4.2910156 6 L 0 6 L 0 10 L 4.2949219 10 A 4.2661548 4.0576186 0 0 0 6 11.582031 L 6 16 L 10 16 L 10 11.580078 A 4.2661548 4.0576186 0 0 0 11.708984 10 L 16 10 L 16 6 L 11.705078 6 A 4.2661548 4.0576186 0 0 0 10 4.4179688 L 10 0 L 6 0 z " + id="path913" /> + <path + style="fill:#d9d9d9;stroke:none;fill-opacity:1" + d="M 7 1 L 7 4.0605469 A 4.2661548 4.0576186 0 0 1 8 3.9414062 A 4.2661548 4.0576186 0 0 1 9 4.0605469 L 9 1 L 7 1 z M 1 7 L 1 9 L 3.8691406 9 A 4.2661548 4.0576186 0 0 1 3.734375 8 A 4.2661548 4.0576186 0 0 1 3.8710938 7 L 1 7 z M 12.130859 7 A 4.2661548 4.0576186 0 0 1 12.265625 8 A 4.2661548 4.0576186 0 0 1 12.128906 9 L 15 9 L 15 7 L 12.130859 7 z M 7 11.939453 L 7 15 L 9 15 L 9 11.939453 A 4.2661548 4.0576186 0 0 1 8 12.058594 A 4.2661548 4.0576186 0 0 1 7 11.939453 z " + id="path915" /> + <circle + style="fill:#d9d9d9;fill-opacity:1;stroke-width:0.97338283" + cx="8" + cy="8" + r="2.9201488" + id="circle1517" /> +</svg> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index b8d0958c99..bb94aee462 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -196,11 +196,15 @@ void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, Transform2D ci_transform = canvas_item->get_global_transform_with_canvas(); Transform2D to_snap_transform = p_to_snap ? p_to_snap->get_global_transform_with_canvas() : Transform2D(); if (fmod(ci_transform.get_rotation() - to_snap_transform.get_rotation(), (real_t)360.0) == 0.0) { - Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position()); - Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size()); - - _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation()); - _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation()); + if (canvas_item->_edit_use_rect()) { + Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position()); + Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size()); + _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation()); + _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation()); + } else { + Point2 position = ci_transform.xform(Point2()); + _snap_if_closer_point(p_value, position, r_current_snap, r_snapped, ci_transform.get_rotation()); + } } } for (int i = 0; i < p_current->get_child_count(); i++) { @@ -221,23 +225,23 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const // Parent sides and center if ((is_snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) { - Point2 begin; - Point2 end; - bool can_snap = false; if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { - begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0))); - end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1))); - can_snap = true; - } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) { - begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position()); - end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size()); - can_snap = true; - } - - if (can_snap) { + Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0))); + Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1))); _snap_if_closer_point(p_target, begin, output, snapped, rotation); _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation); _snap_if_closer_point(p_target, end, output, snapped, rotation); + } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) { + if (parent_ci->_edit_use_rect()) { + Point2 begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position()); + Point2 end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size()); + _snap_if_closer_point(p_target, begin, output, snapped, rotation); + _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation); + _snap_if_closer_point(p_target, end, output, snapped, rotation); + } else { + Point2 position = p_canvas_item->get_transform().affine_inverse().xform(Point2()); + _snap_if_closer_point(p_target, position, output, snapped, rotation); + } } } @@ -253,16 +257,23 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const // Self sides if ((is_snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { - Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position()); - Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size()); - _snap_if_closer_point(p_target, begin, output, snapped, rotation); - _snap_if_closer_point(p_target, end, output, snapped, rotation); + if (p_canvas_item->_edit_use_rect()) { + Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position()); + Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size()); + _snap_if_closer_point(p_target, begin, output, snapped, rotation); + _snap_if_closer_point(p_target, end, output, snapped, rotation); + } } // Self center if ((is_snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) { - Point2 center = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size() / 2.0); - _snap_if_closer_point(p_target, center, output, snapped, rotation); + if (p_canvas_item->_edit_use_rect()) { + Point2 center = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size() / 2.0); + _snap_if_closer_point(p_target, center, output, snapped, rotation); + } else { + Point2 position = p_canvas_item->get_global_transform_with_canvas().xform(Point2()); + _snap_if_closer_point(p_target, position, output, snapped, rotation); + } } } @@ -364,63 +375,85 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_li // Handles the first element CanvasItem *canvas_item = p_list.front()->get(); - Rect2 rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2()); + Rect2 rect; + if (canvas_item->_edit_use_rect()) { + rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(canvas_item->_edit_get_rect().position + canvas_item->_edit_get_rect().size / 2), Size2()); + } else { + rect = Rect2(canvas_item->get_global_transform_with_canvas().xform(Point2()), Size2()); + } - // Handles the other ones + // Expand with the other ones for (List<CanvasItem *>::Element *E = p_list.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); - Rect2 current_rect = canvas_item->_edit_get_rect(); Transform2D xform = canvas_item->get_global_transform_with_canvas(); - rect.expand_to(xform.xform(current_rect.position)); - rect.expand_to(xform.xform(current_rect.position + Vector2(current_rect.size.x, 0))); - rect.expand_to(xform.xform(current_rect.position + current_rect.size)); - rect.expand_to(xform.xform(current_rect.position + Vector2(0, current_rect.size.y))); + if (canvas_item->_edit_use_rect()) { + Rect2 current_rect = canvas_item->_edit_get_rect(); + + rect.expand_to(xform.xform(current_rect.position)); + rect.expand_to(xform.xform(current_rect.position + Vector2(current_rect.size.x, 0))); + rect.expand_to(xform.xform(current_rect.position + current_rect.size)); + rect.expand_to(xform.xform(current_rect.position + Vector2(0, current_rect.size.y))); + } else { + rect.expand_to(xform.xform(Point2())); + } } return rect; } -void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, Node *p_node, bool &r_first, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { +void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { if (!p_node) return; if (Object::cast_to<Viewport>(p_node)) return; - CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - bool inherited = p_node != get_tree()->get_edited_scene_root() && p_node->get_filename() != ""; - bool editable = inherited && EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); + /*bool inherited = p_node != get_tree()->get_edited_scene_root() && p_node->get_filename() != ""; + bool editable = !inherited || EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); - if (!lock_children && (!inherited || editable)) { - for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_toplevel()) { - _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); - } else { - CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); - _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); - } + if (!lock_children && editable) {}*/ + + for (int i = p_node->get_child_count() - 1; i >= 0; i--) { + if (canvas_item && !canvas_item->is_set_as_toplevel()) { + _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + } else { + const CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); + _expand_encompassing_rect_using_children(r_rect, p_node->get_child(i), r_first, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); } } if (canvas_item && canvas_item->is_visible_in_tree() && !canvas_item->has_meta("_edit_lock_")) { - Rect2 rect = canvas_item->_edit_get_rect(); Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform(); - if (r_first) { - r_rect = Rect2(xform.xform(rect.position + rect.size / 2), Size2()); - r_first = false; + if (canvas_item->_edit_use_rect()) { + Rect2 rect = canvas_item->_edit_get_rect(); + if (r_first) { + r_rect = Rect2(xform.xform(rect.position + rect.size / 2), Size2()); + r_first = false; + } + if (r_rect.size != Size2()) { + r_rect.expand_to(xform.xform(rect.position)); + r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0))); + r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y))); + r_rect.expand_to(xform.xform(rect.position + rect.size)); + } + } else { + if (r_first) { + r_rect = Rect2(xform.xform(Point2()), Size2()); + r_first = false; + } else { + r_rect.expand_to(xform.xform(Point2())); + } } - r_rect.expand_to(xform.xform(rect.position)); - r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0))); - r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y))); - r_rect.expand_to(xform.xform(rect.position + rect.size)); } } -Rect2 CanvasItemEditor::_get_scene_encompassing_rect() { +Rect2 CanvasItemEditor::_get_encompassing_rect(const Node *p_node) { Rect2 rect; bool first = true; - _expand_encompassing_rect_using_children(rect, editor->get_edited_scene(), first); + _expand_encompassing_rect_using_children(rect, p_node, first); + return rect; } @@ -433,22 +466,23 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no const real_t grab_distance = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); - for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - if (canvas_item && !canvas_item->is_set_as_toplevel()) - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, 0, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); - else { - CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); - _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, 0, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); //use base transform + Node *scene = editor->get_edited_scene(); + if (!(p_node != scene && p_node->get_owner() != scene && (!scene->is_editable_instance(p_node) || p_node->has_meta("_edit_lock_")))) { + for (int i = p_node->get_child_count() - 1; i >= 0; i--) { + if (canvas_item && !canvas_item->is_set_as_toplevel()) { + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, limit, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); + _find_canvas_items_at_pos(p_pos, p_node->get_child(i), r_items, limit, Transform2D(), cl ? cl->get_transform() : p_canvas_xform); + } + if (limit != 0 && r_items.size() >= limit) + return; } - if (limit != 0 && r_items.size() >= limit) - return; } - if (canvas_item && canvas_item->is_visible_in_tree() && !canvas_item->has_meta("_edit_lock_")) { - + if (canvas_item && canvas_item->is_visible_in_tree() && (canvas_item->get_owner() != editor->get_edited_scene() || !canvas_item->has_meta("_edit_lock_"))) { Transform2D xform = (p_parent_xform * p_canvas_xform * canvas_item->get_transform()).affine_inverse(); const real_t local_grab_distance = xform.basis_xform(Vector2(grab_distance, 0)).length(); - if (canvas_item->_edit_is_selected_on_click(xform.xform(p_pos), local_grab_distance)) { Node2D *node = Object::cast_to<Node2D>(canvas_item); @@ -463,7 +497,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no return; } -void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { +void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { if (!p_node) return; if (Object::cast_to<Viewport>(p_node)) @@ -472,31 +506,37 @@ void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_n CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); bool inherited = p_node != get_tree()->get_edited_scene_root() && p_node->get_filename() != ""; - bool editable = inherited && EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); + bool editable = !inherited || EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node); bool lock_children = p_node->has_meta("_edit_group_") && p_node->get_meta("_edit_group_"); + bool locked = p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_"); - if (!lock_children && (!inherited || editable)) { + if (!lock_children && !locked && editable) { for (int i = p_node->get_child_count() - 1; i >= 0; i--) { if (canvas_item && !canvas_item->is_set_as_toplevel()) { - _find_canvas_items_at_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, p_parent_xform * canvas_item->get_transform(), p_canvas_xform); } else { CanvasLayer *canvas_layer = Object::cast_to<CanvasLayer>(p_node); - _find_canvas_items_at_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); + _find_canvas_items_in_rect(p_rect, p_node->get_child(i), r_items, Transform2D(), canvas_layer ? canvas_layer->get_transform() : p_canvas_xform); } } } if (canvas_item && canvas_item->is_visible_in_tree() && !canvas_item->has_meta("_edit_lock_")) { - - Rect2 rect = canvas_item->_edit_get_rect(); Transform2D xform = p_parent_xform * p_canvas_xform * canvas_item->get_transform(); - if (p_rect.has_point(xform.xform(rect.position)) && - p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) && - p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) && - p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) { + if (canvas_item->_edit_use_rect()) { + Rect2 rect = canvas_item->_edit_get_rect(); + if (p_rect.has_point(xform.xform(rect.position)) && + p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) && + p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) && + p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) { - r_items->push_back(canvas_item); + r_items->push_back(canvas_item); + } + } else { + if (p_rect.has_point(xform.xform(Point2()))) { + r_items->push_back(canvas_item); + } } } } @@ -575,8 +615,11 @@ void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items if (se) { se->undo_state = canvas_item->_edit_get_state(); se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - se->pre_drag_rect = canvas_item->_edit_get_rect(); - + if (canvas_item->_edit_use_rect()) { + se->pre_drag_rect = canvas_item->_edit_get_rect(); + } else { + se->pre_drag_rect = Rect2(); + } se->pre_drag_bones_length = List<float>(); se->pre_drag_bones_undo_state = List<Dictionary>(); @@ -1290,54 +1333,55 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { List<CanvasItem *> selection = _get_edited_canvas_items(); if (selection.size() == 1) { CanvasItem *canvas_item = selection[0]; + if (canvas_item->_edit_use_rect()) { + Rect2 rect = canvas_item->_edit_get_rect(); + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + + Vector2 endpoints[4] = { + xform.xform(rect.position), + xform.xform(rect.position + Vector2(rect.size.x, 0)), + xform.xform(rect.position + rect.size), + xform.xform(rect.position + Vector2(0, rect.size.y)) + }; - Rect2 rect = canvas_item->_edit_get_rect(); - Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); - - Vector2 endpoints[4] = { - xform.xform(rect.position), - xform.xform(rect.position + Vector2(rect.size.x, 0)), - xform.xform(rect.position + rect.size), - xform.xform(rect.position + Vector2(0, rect.size.y)) - }; - - DragType dragger[] = { - DRAG_TOP_LEFT, - DRAG_TOP, - DRAG_TOP_RIGHT, - DRAG_RIGHT, - DRAG_BOTTOM_RIGHT, - DRAG_BOTTOM, - DRAG_BOTTOM_LEFT, - DRAG_LEFT - }; - - DragType resize_drag = DRAG_NONE; - float radius = (select_handle->get_size().width / 2) * 1.5; - - for (int i = 0; i < 4; i++) { - int prev = (i + 3) % 4; - int next = (i + 1) % 4; + DragType dragger[] = { + DRAG_TOP_LEFT, + DRAG_TOP, + DRAG_TOP_RIGHT, + DRAG_RIGHT, + DRAG_BOTTOM_RIGHT, + DRAG_BOTTOM, + DRAG_BOTTOM_LEFT, + DRAG_LEFT + }; - Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); - ofs *= (select_handle->get_size().width / 2); - ofs += endpoints[i]; - if (ofs.distance_to(b->get_position()) < radius) - resize_drag = dragger[i * 2]; + DragType resize_drag = DRAG_NONE; + float radius = (select_handle->get_size().width / 2) * 1.5; - ofs = (endpoints[i] + endpoints[next]) / 2; - ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2); - if (ofs.distance_to(b->get_position()) < radius) - resize_drag = dragger[i * 2 + 1]; - } + for (int i = 0; i < 4; i++) { + int prev = (i + 3) % 4; + int next = (i + 1) % 4; + + Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); + ofs *= (select_handle->get_size().width / 2); + ofs += endpoints[i]; + if (ofs.distance_to(b->get_position()) < radius) + resize_drag = dragger[i * 2]; + + ofs = (endpoints[i] + endpoints[next]) / 2; + ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2); + if (ofs.distance_to(b->get_position()) < radius) + resize_drag = dragger[i * 2 + 1]; + } - if (resize_drag != DRAG_NONE) { - drag_type = resize_drag; - drag_from = transform.affine_inverse().xform(b->get_position()); - drag_selection = List<CanvasItem *>(); - drag_selection.push_back(canvas_item); - _save_canvas_item_state(drag_selection); - return true; + if (resize_drag != DRAG_NONE) { + drag_type = resize_drag; + drag_from = transform.affine_inverse().xform(b->get_position()); + drag_selection = List<CanvasItem *>(); + drag_selection.push_back(canvas_item); + _save_canvas_item_state(drag_selection); + return true; + } } } } @@ -1535,61 +1579,64 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { _save_canvas_item_state(drag_selection, true); } - _restore_canvas_item_state(drag_selection, true); - - bool move_local_base = k->get_alt(); - bool move_local_base_rotated = k->get_control() || k->get_metakey(); - - Vector2 dir; - if (k->get_scancode() == KEY_UP) - dir += Vector2(0, -1); - else if (k->get_scancode() == KEY_DOWN) - dir += Vector2(0, 1); - else if (k->get_scancode() == KEY_LEFT) - dir += Vector2(-1, 0); - else if (k->get_scancode() == KEY_RIGHT) - dir += Vector2(1, 0); - if (k->get_shift()) - dir *= grid_step * Math::pow(2.0, grid_step_multiplier); - - drag_to += dir; - if (k->get_shift()) - drag_to = drag_to.snapped(grid_step * Math::pow(2.0, grid_step_multiplier)); - - Point2 previous_pos; - if (drag_selection.size() == 1) { - Transform2D xform = drag_selection[0]->get_global_transform_with_canvas() * drag_selection[0]->get_transform().affine_inverse(); - previous_pos = xform.xform(drag_selection[0]->_edit_get_position()); - } else { - previous_pos = _get_encompassing_rect_from_list(drag_selection).position; - } + if (drag_selection.size() > 0) { - Point2 new_pos; - if (drag_selection.size() == 1) { - Node2D *node_2d = Object::cast_to<Node2D>(drag_selection[0]); - if (node_2d && move_local_base_rotated) { - Transform2D m; - m.rotate(node_2d->get_rotation()); - new_pos += m.xform(drag_to); - } else if (move_local_base) { - new_pos += drag_to; + _restore_canvas_item_state(drag_selection, true); + + bool move_local_base = k->get_alt(); + bool move_local_base_rotated = k->get_control() || k->get_metakey(); + + Vector2 dir; + if (k->get_scancode() == KEY_UP) + dir += Vector2(0, -1); + else if (k->get_scancode() == KEY_DOWN) + dir += Vector2(0, 1); + else if (k->get_scancode() == KEY_LEFT) + dir += Vector2(-1, 0); + else if (k->get_scancode() == KEY_RIGHT) + dir += Vector2(1, 0); + if (k->get_shift()) + dir *= grid_step * Math::pow(2.0, grid_step_multiplier); + + drag_to += dir; + if (k->get_shift()) + drag_to = drag_to.snapped(grid_step * Math::pow(2.0, grid_step_multiplier)); + + Point2 previous_pos; + if (drag_selection.size() == 1) { + Transform2D xform = drag_selection[0]->get_global_transform_with_canvas() * drag_selection[0]->get_transform().affine_inverse(); + previous_pos = xform.xform(drag_selection[0]->_edit_get_position()); + } else { + previous_pos = _get_encompassing_rect_from_list(drag_selection).position; + } + + Point2 new_pos; + if (drag_selection.size() == 1) { + Node2D *node_2d = Object::cast_to<Node2D>(drag_selection[0]); + if (node_2d && move_local_base_rotated) { + Transform2D m; + m.rotate(node_2d->get_rotation()); + new_pos += m.xform(drag_to); + } else if (move_local_base) { + new_pos += drag_to; + } else { + new_pos = previous_pos + (drag_to - drag_from); + } } else { new_pos = previous_pos + (drag_to - drag_from); } - } else { - new_pos = previous_pos + (drag_to - drag_from); - } - for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { - CanvasItem *canvas_item = E->get(); - CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); + for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { + CanvasItem *canvas_item = E->get(); + CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); + Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse() * canvas_item->get_transform(); - Node2D *node2d = Object::cast_to<Node2D>(canvas_item); - if (node2d && se->pre_drag_bones_undo_state.size() > 0) { - _solve_IK(node2d, new_pos); - } else { - canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + Node2D *node2d = Object::cast_to<Node2D>(canvas_item); + if (node2d && se->pre_drag_bones_undo_state.size() > 0) { + _solve_IK(node2d, new_pos); + } else { + canvas_item->_edit_set_position(canvas_item->_edit_get_position() + xform.xform(new_pos) - xform.xform(previous_pos)); + } } } return true; @@ -1648,6 +1695,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { return true; } else if (!selection_results.empty()) { + // Sorts items according the their z-index selection_results.sort(); NodePath root_path = get_tree()->get_edited_scene_root()->get_path(); @@ -1707,16 +1755,17 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { canvas_item = selection[0].item; // Check if the canvas item is in a group, and select the group instead if it is the case - CanvasItem *canvas_item_tmp = canvas_item; - while (canvas_item_tmp) { - if (canvas_item->has_meta("_edit_group_")) { + Node *node = canvas_item; + while (node && node != scene) { + CanvasItem *canvas_item_tmp = Object::cast_to<CanvasItem>(node); + if (canvas_item_tmp && node->has_meta("_edit_group_")) { canvas_item = canvas_item_tmp; } - canvas_item_tmp = canvas_item_tmp->get_parent_item(); + node = node->get_parent(); } // Make sure the selected node is in the current scene - Node *node = canvas_item; + node = canvas_item; while (node && ((node != scene && node->get_owner() != scene) || !node->is_class("CanvasItem"))) { node = node->get_parent(); }; @@ -1766,7 +1815,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { if (bsfrom.y > bsto.y) SWAP(bsfrom.y, bsto.y); - _find_canvas_items_at_rect(Rect2(bsfrom, bsto - bsfrom), scene, &selitems); + _find_canvas_items_in_rect(Rect2(bsfrom, bsto - bsfrom), scene, &selitems); for (List<CanvasItem *>::Element *E = selitems.front(); E; E = E->next()) { editor_selection->add_node(E->get()); } @@ -1800,6 +1849,42 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) { return false; } +bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) { + + Ref<InputEventMouseMotion> m = p_event; + if (m.is_valid()) { + if (drag_type == DRAG_NONE && tool == TOOL_SELECT) { + Point2 click = transform.affine_inverse().xform(m->get_position()); + Node *scene = editor->get_edited_scene(); + + //Checks if the hovered items changed, update the viewport if so + Vector<_SelectResult> hovering_results_tmp; + _find_canvas_items_at_pos(click, scene, hovering_results_tmp); + hovering_results_tmp.sort(); + bool changed = false; + if (hovering_results.size() == hovering_results_tmp.size()) { + for (int i = 0; i < hovering_results.size(); i++) { + if (hovering_results[i].item != hovering_results_tmp[i].item) { + changed = true; + break; + } + } + } else { + changed = true; + } + + if (changed) { + hovering_results = hovering_results_tmp; + viewport->update(); + } + + return true; + } + } + + return false; +} + void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { bool accepted = false; if ((accepted = _gui_input_rulers_and_guides(p_event))) { @@ -1827,6 +1912,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { if (accepted) accept_event(); + // Handles the mouse hovering + _gui_input_hover(p_event); + // Change the cursor CursorShape c = CURSOR_ARROW; switch (drag_type) { @@ -2093,6 +2181,9 @@ void CanvasItemEditor::_draw_grid() { void CanvasItemEditor::_draw_selection() { Ref<Texture> pivot_icon = get_icon("EditorPivot", "EditorIcons"); + Ref<Texture> position_icon = get_icon("EditorPosition", "EditorIcons"); + Ref<Texture> previous_position_icon = get_icon("EditorPositionPrevious", "EditorIcons"); + RID ci = viewport->get_canvas_item(); List<CanvasItem *> selection = _get_edited_canvas_items(false, false); @@ -2102,8 +2193,6 @@ void CanvasItemEditor::_draw_selection() { CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get()); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - Rect2 rect = canvas_item->_edit_get_rect(); - // Draw the previous position if we are dragging the node if (show_helpers && (drag_type == DRAG_ALL || drag_type == DRAG_ROTATE || @@ -2112,42 +2201,52 @@ void CanvasItemEditor::_draw_selection() { const Transform2D pre_drag_xform = transform * se->pre_drag_xform; const Color pre_drag_color = Color(0.4, 0.6, 1, 0.7); - Vector2 pre_drag_endpoints[4] = { + if (canvas_item->_edit_use_rect()) { + Vector2 pre_drag_endpoints[4] = { - pre_drag_xform.xform(se->pre_drag_rect.position), - pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(se->pre_drag_rect.size.x, 0)), - pre_drag_xform.xform(se->pre_drag_rect.position + se->pre_drag_rect.size), - pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(0, se->pre_drag_rect.size.y)) - }; + pre_drag_xform.xform(se->pre_drag_rect.position), + pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(se->pre_drag_rect.size.x, 0)), + pre_drag_xform.xform(se->pre_drag_rect.position + se->pre_drag_rect.size), + pre_drag_xform.xform(se->pre_drag_rect.position + Vector2(0, se->pre_drag_rect.size.y)) + }; - for (int i = 0; i < 4; i++) { - viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2); + for (int i = 0; i < 4; i++) { + viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2); + } + } else { + viewport->draw_texture(previous_position_icon, (pre_drag_xform.xform(Point2()) - (previous_position_icon->get_size() / 2)).floor()); } } Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); - VisualServer::get_singleton()->canvas_item_add_set_transform(ci, xform); - - // Draw the selected items surrounding boxes - Vector2 endpoints[4] = { - xform.xform(rect.position), - xform.xform(rect.position + Vector2(rect.size.x, 0)), - xform.xform(rect.position + rect.size), - xform.xform(rect.position + Vector2(0, rect.size.y)) - }; - Color c = Color(1, 0.6, 0.4, 0.7); + // Draw the selected items position / surrounding boxes + if (canvas_item->_edit_use_rect()) { + Rect2 rect = canvas_item->_edit_get_rect(); + Vector2 endpoints[4] = { + xform.xform(rect.position), + xform.xform(rect.position + Vector2(rect.size.x, 0)), + xform.xform(rect.position + rect.size), + xform.xform(rect.position + Vector2(0, rect.size.y)) + }; + + Color c = Color(1, 0.6, 0.4, 0.7); - VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D()); + for (int i = 0; i < 4; i++) { + viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, 2); + } + } else { - for (int i = 0; i < 4; i++) { - viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, 2); + Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin()); + viewport->draw_set_transform_matrix(transform); + viewport->draw_texture(position_icon, -(position_icon->get_size() / 2)); + viewport->draw_set_transform_matrix(Transform2D()); } if (single && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks // Draw the pivot if (canvas_item->_edit_get_pivot() != Vector2() || drag_type == DRAG_PIVOT || tool == TOOL_EDIT_PIVOT) { // This is not really clean :/ - viewport->draw_texture(pivot_icon, xform.xform(canvas_item->_edit_get_pivot()) + (-pivot_icon->get_size() / 2).floor()); + viewport->draw_texture(pivot_icon, (xform.xform(canvas_item->_edit_get_pivot()) - (pivot_icon->get_size() / 2)).floor()); } Control *control = Object::cast_to<Control>(canvas_item); @@ -2329,7 +2428,14 @@ void CanvasItemEditor::_draw_selection() { } } - if (tool == TOOL_SELECT) { + if (tool == TOOL_SELECT && canvas_item->_edit_use_rect()) { + Rect2 rect = canvas_item->_edit_get_rect(); + Vector2 endpoints[4] = { + xform.xform(rect.position), + xform.xform(rect.position + Vector2(rect.size.x, 0)), + xform.xform(rect.position + rect.size), + xform.xform(rect.position + Vector2(0, rect.size.y)) + }; for (int i = 0; i < 4; i++) { // Draw the resize handles int prev = (i + 3) % 4; @@ -2506,32 +2612,121 @@ void CanvasItemEditor::_draw_bones() { } } -void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_xform) { +void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { + ERR_FAIL_COND(!p_node); + + Node *scene = editor->get_edited_scene(); + if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node)) + return; + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + if (canvas_item && !canvas_item->is_visible()) + return; + + Transform2D parent_xform = p_parent_xform; + Transform2D canvas_xform = p_canvas_xform; + + if (canvas_item && !canvas_item->is_set_as_toplevel()) { + parent_xform = parent_xform * canvas_item->get_transform(); + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); + parent_xform = Transform2D(); + canvas_xform = cl ? cl->get_transform() : p_canvas_xform; + } + + for (int i = p_node->get_child_count() - 1; i >= 0; i--) { + _draw_invisible_nodes_positions(p_node->get_child(i), parent_xform, canvas_xform); + } + + if (canvas_item && !canvas_item->_edit_use_rect() && !editor_selection->is_selected(canvas_item)) { + Transform2D xform = transform * canvas_xform * parent_xform; + + // Draw the node's position + Ref<Texture> position_icon = get_icon("EditorPositionUnselected", "EditorIcons"); + Transform2D transform = Transform2D(xform.get_rotation(), xform.get_origin()); + viewport->draw_set_transform_matrix(transform); + viewport->draw_texture(position_icon, -position_icon->get_size() / 2, Color(1.0, 1.0, 1.0, 0.5)); + viewport->draw_set_transform_matrix(Transform2D()); + } +} + +void CanvasItemEditor::_draw_hover() { + List<Rect2> previous_rects; + + for (int i = 0; i < hovering_results.size(); i++) { + // Draw the node's name and icon + CanvasItem *canvas_item = hovering_results[i].item; + + if (canvas_item->_edit_use_rect()) + continue; + + Transform2D xform = transform * canvas_item->get_global_transform_with_canvas(); + + // Get the resources + Ref<Texture> node_icon; + if (has_icon(canvas_item->get_class(), "EditorIcons")) + node_icon = get_icon(canvas_item->get_class(), "EditorIcons"); + else + node_icon = get_icon("Object", "EditorIcons"); + Ref<Font> font = get_font("font", "Label"); + String node_name = canvas_item->get_name(); + Size2 node_name_size = font->get_string_size(node_name); + Size2 item_size = Size2(node_icon->get_size().x + 4 + node_name_size.x, MAX(node_icon->get_size().y, node_name_size.y - 3)); + + Point2 pos = xform.get_origin() - Point2(0, item_size.y) + (Point2(node_icon->get_size().x, -node_icon->get_size().y) / 4); + // Rectify the position to avoid overlaping items + for (List<Rect2>::Element *E = previous_rects.front(); E; E = E->next()) { + if (E->get().intersects(Rect2(pos, item_size))) { + pos.y = E->get().get_position().y - item_size.y; + } + } + + previous_rects.push_back(Rect2(pos, item_size)); + + // Draw the node icon and name + viewport->draw_texture(node_icon, pos, Color(1.0, 1.0, 1.0, 0.5)); + viewport->draw_string(font, pos + Point2(node_icon->get_size().x + 4, item_size.y - 3), node_name, Color(1.0, 1.0, 1.0, 0.5)); + } +} + +void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) { ERR_FAIL_COND(!p_node); - RID viewport_ci = viewport->get_canvas_item(); + Node *scene = editor->get_edited_scene(); + if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) + return; + CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node); + if (canvas_item && !canvas_item->is_visible()) + return; + + Transform2D parent_xform = p_parent_xform; + Transform2D canvas_xform = p_canvas_xform; - Transform2D transform_ci = p_xform; - CanvasItem *ci = Object::cast_to<CanvasItem>(p_node); - if (ci) - transform_ci = transform_ci * ci->get_transform(); + if (canvas_item && !canvas_item->is_set_as_toplevel()) { + parent_xform = parent_xform * canvas_item->get_transform(); + } else { + CanvasLayer *cl = Object::cast_to<CanvasLayer>(p_node); + parent_xform = Transform2D(); + canvas_xform = cl ? cl->get_transform() : p_canvas_xform; + } for (int i = p_node->get_child_count() - 1; i >= 0; i--) { - _draw_locks_and_groups(p_node->get_child(i), transform_ci); + _draw_locks_and_groups(p_node->get_child(i), parent_xform, canvas_xform); } - if (ci) { + RID viewport_canvas_item = viewport->get_canvas_item(); + if (canvas_item) { + float offset = 0; + Ref<Texture> lock = get_icon("LockViewport", "EditorIcons"); if (p_node->has_meta("_edit_lock_")) { - lock->draw(viewport_ci, transform_ci.xform(Point2(0, 0))); + lock->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); + offset += lock->get_size().x; } Ref<Texture> group = get_icon("GroupViewport", "EditorIcons"); - if (ci->has_meta("_edit_group_")) { - Vector2 ofs = transform_ci.xform(Point2(0, 0)); - if (ci->has_meta("_edit_lock_")) - ofs = Point2(ofs.x + lock->get_size().x, ofs.y); - group->draw(viewport_ci, ofs); + if (canvas_item->has_meta("_edit_group_")) { + group->draw(viewport_canvas_item, (transform * canvas_xform * parent_xform).xform(Point2(0, 0)) + Point2(offset, 0)); + //offset += group->get_size().x; } } } @@ -2597,8 +2792,10 @@ void CanvasItemEditor::_draw_viewport() { _draw_grid(); _draw_selection(); _draw_axis(); - if (editor->get_edited_scene()) - _draw_locks_and_groups(editor->get_edited_scene(), transform); + if (editor->get_edited_scene()) { + _draw_locks_and_groups(editor->get_edited_scene()); + _draw_invisible_nodes_positions(editor->get_edited_scene()); + } RID ci = viewport->get_canvas_item(); VisualServer::get_singleton()->canvas_item_add_set_transform(ci, Transform2D()); @@ -2618,6 +2815,7 @@ void CanvasItemEditor::_draw_viewport() { if (show_guides) _draw_guides(); _draw_focus(); + _draw_hover(); } void CanvasItemEditor::_notification(int p_what) { @@ -2633,12 +2831,17 @@ void CanvasItemEditor::_notification(int p_what) { CanvasItem *canvas_item = E->get(); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item); - Rect2 r = canvas_item->_edit_get_rect(); + Rect2 rect; + if (canvas_item->_edit_use_rect()) { + rect = canvas_item->_edit_get_rect(); + } else { + rect = Rect2(); + } Transform2D xform = canvas_item->get_transform(); - if (r != se->prev_rect || xform != se->prev_xform) { + if (rect != se->prev_rect || xform != se->prev_xform) { viewport->update(); - se->prev_rect = r; + se->prev_rect = rect; se->prev_xform = xform; } @@ -2840,7 +3043,7 @@ void CanvasItemEditor::_update_scrollbars() { // Calculate scrollable area Rect2 canvas_item_rect = Rect2(Point2(), screen_rect); if (editor->get_edited_scene()) { - Rect2 content_rect = _get_scene_encompassing_rect(); + Rect2 content_rect = _get_encompassing_rect(editor->get_edited_scene()); canvas_item_rect.expand_to(content_rect.position); canvas_item_rect.expand_to(content_rect.position + content_rect.size); } @@ -3539,7 +3742,12 @@ void CanvasItemEditor::_focus_selection(int p_op) { //if (!canvas_item->is_visible_in_tree()) continue; ++count; - Rect2 item_rect = canvas_item->_edit_get_rect(); + Rect2 item_rect; + if (canvas_item->_edit_use_rect()) { + item_rect = canvas_item->_edit_get_rect(); + } else { + item_rect = Rect2(); + } Vector2 pos = canvas_item->get_global_transform().get_origin(); Vector2 scale = canvas_item->get_global_transform().get_scale(); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index da7ce9172a..5ca8a37610 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -258,6 +258,7 @@ class CanvasItemEditor : public VBoxContainer { }; Vector<_SelectResult> selection_results; + Vector<_SelectResult> hovering_results; struct BoneList { @@ -336,7 +337,7 @@ class CanvasItemEditor : public VBoxContainer { Ref<ShortCut> divide_grid_step_shortcut; void _find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, int limit = 0, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); - void _find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); + void _find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); bool _select_click_on_item(CanvasItem *item, Point2 p_click_pos, bool p_append); ConfirmationDialog *snap_dialog; @@ -366,8 +367,8 @@ class CanvasItemEditor : public VBoxContainer { List<CanvasItem *> _get_edited_canvas_items(bool retreive_locked = false, bool remove_canvas_item_if_parent_in_selection = true); Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list); - void _expand_encompassing_rect_using_children(Rect2 &p_rect, Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); - Rect2 _get_scene_encompassing_rect(); + void _expand_encompassing_rect_using_children(Rect2 &p_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); + Rect2 _get_encompassing_rect(const Node *p_node); Object *_get_editor_data(Object *p_what); @@ -387,7 +388,9 @@ class CanvasItemEditor : public VBoxContainer { void _draw_selection(); void _draw_axis(); void _draw_bones(); - void _draw_locks_and_groups(Node *p_node, const Transform2D &p_xform); + void _draw_invisible_nodes_positions(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); + void _draw_locks_and_groups(Node *p_node, const Transform2D &p_parent_xform = Transform2D(), const Transform2D &p_canvas_xform = Transform2D()); + void _draw_hover(); void _draw_viewport(); @@ -400,6 +403,7 @@ class CanvasItemEditor : public VBoxContainer { bool _gui_input_select(const Ref<InputEvent> &p_event); bool _gui_input_zoom_or_pan(const Ref<InputEvent> &p_event); bool _gui_input_rulers_and_guides(const Ref<InputEvent> &p_event); + bool _gui_input_hover(const Ref<InputEvent> &p_event); void _gui_input_viewport(const Ref<InputEvent> &p_event); diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 824f50495b..447bd9a090 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -80,6 +80,10 @@ Rect2 AnimatedSprite::_edit_get_rect() const { return Rect2(ofs, s); } +bool AnimatedSprite::_edit_use_rect() const { + return true; +} + void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos) { Map<StringName, Anim>::Element *E = animations.find(p_anim); diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index a38adf792c..c7606d88aa 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -157,6 +157,7 @@ public: virtual Point2 _edit_get_pivot() const; virtual bool _edit_use_pivot() const; virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void set_sprite_frames(const Ref<SpriteFrames> &p_frames); Ref<SpriteFrames> get_sprite_frames() const; diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 446b367be0..caa1adebdb 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -55,6 +55,10 @@ Rect2 BackBufferCopy::_edit_get_rect() const { return rect; } +bool BackBufferCopy::_edit_use_rect() const { + return true; +} + void BackBufferCopy::set_rect(const Rect2 &p_rect) { rect = p_rect; diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index b786c2b828..752d56de2b 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -54,6 +54,7 @@ protected: public: Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 2b89062181..60368816a9 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -245,6 +245,14 @@ CanvasItemMaterial::~CanvasItemMaterial() { /////////////////////////////////////////////////////////////////// +bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { + if (_edit_use_rect()) { + return _edit_get_rect().has_point(p_point); + } else { + return p_point.length() < p_tolerance; + } +} + bool CanvasItem::is_visible_in_tree() const { if (!is_inside_tree()) @@ -980,7 +988,8 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position); ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position); - ClassDB::bind_method(D_METHOD("_edit_use_position"), &CanvasItem::_edit_use_position); + ClassDB::bind_method(D_METHOD("_edit_set_scale", "scale"), &CanvasItem::_edit_set_scale); + ClassDB::bind_method(D_METHOD("_edit_get_scale"), &CanvasItem::_edit_get_scale); ClassDB::bind_method(D_METHOD("_edit_set_rect", "rect"), &CanvasItem::_edit_set_rect); ClassDB::bind_method(D_METHOD("_edit_get_rect"), &CanvasItem::_edit_get_rect); ClassDB::bind_method(D_METHOD("_edit_use_rect"), &CanvasItem::_edit_use_rect); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 980fcb4109..85de0d2796 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -220,30 +220,46 @@ public: /* EDITOR */ + // Save and restore a CanvasItem state virtual void _edit_set_state(const Dictionary &p_state){}; virtual Dictionary _edit_get_state() const { return Dictionary(); }; - // Used to move/select the node - virtual void _edit_set_position(const Point2 &p_position){}; - virtual Point2 _edit_get_position() const { return Point2(); }; - virtual bool _edit_use_position() const { return false; }; + // Used to move the node + virtual void _edit_set_position(const Point2 &p_position) = 0; + virtual Point2 _edit_get_position() const = 0; - // Used to resize/move/select the node + // Used to scale the node + virtual void _edit_set_scale(const Size2 &p_scale) = 0; + virtual Size2 _edit_get_scale() const = 0; + + // Used to resize/move the node virtual void _edit_set_rect(const Rect2 &p_rect){}; - virtual Rect2 _edit_get_rect() const { return Rect2(-32, -32, 64, 64); }; - virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return _edit_get_rect().has_point(p_point); } - Rect2 _edit_get_item_and_children_rect() const; + virtual Rect2 _edit_get_rect() const { return Rect2(0, 0, 0, 0); }; virtual bool _edit_use_rect() const { return false; }; + Rect2 _edit_get_item_and_children_rect() const; + + // used to select the node + virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; + // Used to rotate the node - virtual void _edit_set_rotation(float p_rotation){}; - virtual float _edit_get_rotation() const { return 0.0; }; - virtual bool _edit_use_rotation() const { return false; }; + virtual void + _edit_set_rotation(float p_rotation){}; + virtual float _edit_get_rotation() const { + return 0.0; + }; + virtual bool _edit_use_rotation() const { + return false; + }; // Used to set a pivot virtual void _edit_set_pivot(const Point2 &p_pivot){}; - virtual Point2 _edit_get_pivot() const { return Point2(); }; - virtual bool _edit_use_pivot() const { return false; }; + virtual Point2 _edit_get_pivot() const { + return Point2(); + }; + virtual bool _edit_use_pivot() const { + return false; + }; virtual Size2 _edit_get_minimum_size() const; @@ -308,7 +324,9 @@ public: virtual Transform2D get_global_transform_with_canvas() const; CanvasItem *get_toplevel() const; - _FORCE_INLINE_ RID get_canvas_item() const { return canvas_item; } + _FORCE_INLINE_ RID get_canvas_item() const { + return canvas_item; + } void set_block_transform_notify(bool p_enable); bool is_block_transform_notify_enabled() const; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 7e2026d225..9d2a83fda7 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -264,6 +264,10 @@ Rect2 CollisionPolygon2D::_edit_get_rect() const { return aabb; } +bool CollisionPolygon2D::_edit_use_rect() const { + return true; +} + bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return Geometry::is_point_in_polygon(p_point, Variant(polygon)); diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index 4dafe7d1da..412a923292 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -73,6 +73,7 @@ public: Vector<Point2> get_polygon() const; virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; virtual String get_configuration_warning() const; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 0eeb6dafe5..83ef4df8f4 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -173,11 +173,6 @@ Ref<Shape2D> CollisionShape2D::get_shape() const { return shape; } -Rect2 CollisionShape2D::_edit_get_rect() const { - - return rect; -} - bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { if (!shape.is_valid()) diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index cdff595828..ed2c09d53d 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -54,7 +54,6 @@ protected: static void _bind_methods(); public: - virtual Rect2 _edit_get_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; void set_shape(const Ref<Shape2D> &p_shape); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 1220ff299c..9a44eb31bb 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -65,6 +65,10 @@ Rect2 Light2D::_edit_get_rect() const { return Rect2(texture_offset - s / 2.0, s); } +bool Light2D::_edit_use_rect() const { + return true; +} + void Light2D::_update_light_visibility() { if (!is_inside_tree()) diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index 16d8c485d4..543805e329 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -92,6 +92,7 @@ public: virtual Point2 _edit_get_pivot() const; virtual bool _edit_use_pivot() const; virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void set_enabled(bool p_enabled); bool is_enabled() const; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index ba4a5c5571..229c2c6fe8 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -62,6 +62,10 @@ Rect2 Line2D::_edit_get_rect() const { return aabb; } +bool Line2D::_edit_use_rect() const { + return true; +} + bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { const real_t d = _width / 2 + p_tolerance; diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h index 0eba024555..24c48982cd 100644 --- a/scene/2d/line_2d.h +++ b/scene/2d/line_2d.h @@ -59,6 +59,7 @@ public: Line2D(); virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; void set_points(const PoolVector<Vector2> &p_points); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 95e24505be..2a52ade01d 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -58,16 +58,39 @@ void Node2D::_edit_set_state(const Dictionary &p_state) { } void Node2D::_edit_set_position(const Point2 &p_position) { - pos = p_position; - _update_transform(); - _change_notify("position"); + set_position(p_position); } Point2 Node2D::_edit_get_position() const { return pos; } +void Node2D::_edit_set_scale(const Size2 &p_scale) { + set_scale(p_scale); +} + +Size2 Node2D::_edit_get_scale() const { + return _scale; +} + +void Node2D::_edit_set_rotation(float p_rotation) { + angle = p_rotation; + _update_transform(); + _change_notify("rotation"); + _change_notify("rotation_degrees"); +} + +float Node2D::_edit_get_rotation() const { + return angle; +} + +bool Node2D::_edit_use_rotation() const { + return true; +} + void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { + ERR_FAIL_COND(!_edit_use_rect()); + Rect2 r = _edit_get_rect(); Vector2 zero_offset; @@ -83,7 +106,7 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { if (r.size.y != 0) new_scale.y = p_edit_rect.size.y / r.size.y; - Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset; //p_edit_rect.pos - r.pos; + Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset; Transform2D postxf; postxf.set_rotation_and_scale(angle, _scale); @@ -97,25 +120,6 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { _change_notify("position"); } -bool Node2D::_edit_use_rect() const { - return true; -} - -void Node2D::_edit_set_rotation(float p_rotation) { - angle = p_rotation; - _update_transform(); - _change_notify("rotation"); - _change_notify("rotation_degrees"); -} - -float Node2D::_edit_get_rotation() const { - return angle; -} - -bool Node2D::_edit_use_rotation() const { - return true; -} - void Node2D::_update_xform_values() { pos = _mat.elements[2]; diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index f817b214f8..725686cdf8 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -62,12 +62,16 @@ public: virtual void _edit_set_position(const Point2 &p_position); virtual Point2 _edit_get_position() const; - virtual void _edit_set_rect(const Rect2 &p_edit_rect); - virtual bool _edit_use_rect() const; + + virtual void _edit_set_scale(const Size2 &p_scale); + virtual Size2 _edit_get_scale() const; + virtual void _edit_set_rotation(float p_rotation); virtual float _edit_get_rotation() const; virtual bool _edit_use_rotation() const; + virtual void _edit_set_rect(const Rect2 &p_edit_rect); + void set_position(const Point2 &p_pos); void set_rotation(float p_radians); void set_rotation_degrees(float p_degrees); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 052a0ac026..7b77b34b26 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -57,6 +57,10 @@ Rect2 Path2D::_edit_get_rect() const { return aabb; } +bool Path2D::_edit_use_rect() const { + return true; +} + bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { for (int i = 0; i < curve->get_point_count(); i++) { diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 735d289d74..64696442c3 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -48,6 +48,7 @@ protected: public: virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; void set_curve(const Ref<Curve2D> &p_curve); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 2cb1e86f51..bf5bf29b2e 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -73,6 +73,10 @@ Rect2 Polygon2D::_edit_get_rect() const { return item_rect; } +bool Polygon2D::_edit_use_rect() const { + return true; +} + bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return Geometry::is_point_in_polygon(p_point - get_offset(), Variant(polygon)); diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 3a24177548..262208f2f1 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -68,6 +68,7 @@ public: virtual Point2 _edit_get_pivot() const; virtual bool _edit_use_pivot() const; virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index 37f6aaa2d6..64d23719e7 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -44,6 +44,10 @@ Rect2 Position2D::_edit_get_rect() const { return Rect2(Point2(-10, -10), Size2(20, 20)); } +bool Position2D::_edit_use_rect() const { + return false; +} + void Position2D::_notification(int p_what) { switch (p_what) { diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index 6f6a34c452..bff474cccd 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -44,6 +44,7 @@ protected: public: virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; Position2D(); }; diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index b6cb734cee..9480f18176 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -335,6 +335,10 @@ Rect2 TouchScreenButton::_edit_get_rect() const { return Rect2(Size2(), texture->get_size()); } +bool TouchScreenButton::_edit_use_rect() const { + return true; +} + void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) { visibility = p_mode; update(); diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h index e6f2a2f3cd..b2fafcc93d 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/screen_button.h @@ -104,6 +104,7 @@ public: bool is_pressed() const; Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; TouchScreenButton(); }; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 67f016ae79..ca1ac2cd7f 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -58,6 +58,14 @@ bool Sprite::_edit_use_pivot() const { return true; } +Rect2 Sprite::_edit_get_rect() const { + return get_rect(); +} + +bool Sprite::_edit_use_rect() const { + return true; +} + void Sprite::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const { Size2 s; diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index abd04515ec..609ad8bb34 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -74,7 +74,9 @@ public: virtual Point2 _edit_get_pivot() const; virtual bool _edit_use_pivot() const; virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const; - virtual Rect2 _edit_get_rect() const { return get_rect(); } + + virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index c126dd8f6b..14eb26b1ec 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -1119,6 +1119,10 @@ Rect2 TileMap::_edit_get_rect() const { return rect_cache; } +bool TileMap::_edit_use_rect() const { + return true; +} + void TileMap::set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 587bd3b684..07947004b3 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -245,6 +245,7 @@ public: int get_cellv(const Vector2 &p_pos) const; Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void make_bitmask_area_dirty(const Vector2 &p_pos); void update_bitmask_area(const Vector2 &p_pos); diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 4b38534d97..ddca97e60a 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -89,6 +89,10 @@ Rect2 VisibilityNotifier2D::_edit_get_rect() const { return rect; } +bool VisibilityNotifier2D::_edit_use_rect() const { + return true; +} + Rect2 VisibilityNotifier2D::get_rect() const { return rect; diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index 93a35a709e..c4e12dfa22 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -56,6 +56,7 @@ protected: public: virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 6ca6d82807..b7c1d35fd7 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -94,6 +94,14 @@ Point2 Control::_edit_get_position() const { return get_position(); }; +void Control::_edit_set_scale(const Size2 &p_scale) { + set_scale(p_scale); +} + +Size2 Control::_edit_get_scale() const { + return data.scale; +} + void Control::_edit_set_rect(const Rect2 &p_edit_rect) { set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snapped(Vector2(1, 1))); set_size(p_edit_rect.size.snapped(Vector2(1, 1))); diff --git a/scene/gui/control.h b/scene/gui/control.h index a215490295..b5453e60f5 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -283,6 +283,9 @@ public: virtual void _edit_set_position(const Point2 &p_position); virtual Point2 _edit_get_position() const; + virtual void _edit_set_scale(const Size2 &p_scale); + virtual Size2 _edit_get_scale() const; + virtual void _edit_set_rect(const Rect2 &p_edit_rect); virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const; |