From 0d35d4d53b12197bea3650293bbc342fc0b57139 Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Thu, 6 Jul 2017 09:16:27 +0200 Subject: Replace GUI anchor type by a float between 0 and 1 --- editor/plugins/canvas_item_editor_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index a35d7a9a5..92acd966d 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2338,7 +2338,7 @@ void CanvasItemEditor::_update_scroll(float) { viewport->update(); } -void CanvasItemEditor::_set_anchor(Control::AnchorType p_left, Control::AnchorType p_top, Control::AnchorType p_right, Control::AnchorType p_bottom) { +void CanvasItemEditor::_set_anchor(float p_left, float p_top, float p_right, float p_bottom) { List &selection = editor_selection->get_selected_node_list(); undo_redo->create_action(TTR("Change Anchors")); @@ -3372,7 +3372,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { dialog_val = memnew(SpinBox); dialog_val->set_anchor(MARGIN_RIGHT, ANCHOR_END); dialog_val->set_begin(Point2(15, 25)); - dialog_val->set_end(Point2(10, 25)); + dialog_val->set_end(Point2(-10, 25)); value_dialog->add_child(dialog_val); dialog_val->connect("value_changed", this, "_dialog_value_changed"); select_sb = Ref(memnew(StyleBoxTexture)); -- cgit v1.2.3-70-g09d2 From bd0384a9e93e3e8d792cef678dd9f3467a6a088d Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Tue, 11 Jul 2017 00:14:22 +0200 Subject: Add anchor visualization --- editor/icons/2x/icon_editor_control_anchor.png | Bin 0 -> 855 bytes editor/icons/icon_editor_control_anchor.png | Bin 0 -> 472 bytes editor/icons/source/icon_editor_control_anchor.svg | 98 ++++++++++++++++++ editor/plugins/canvas_item_editor_plugin.cpp | 110 ++++++++++++++------- editor/plugins/canvas_item_editor_plugin.h | 4 + scene/gui/control.cpp | 1 + 6 files changed, 175 insertions(+), 38 deletions(-) create mode 100644 editor/icons/2x/icon_editor_control_anchor.png create mode 100644 editor/icons/icon_editor_control_anchor.png create mode 100644 editor/icons/source/icon_editor_control_anchor.svg (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/icons/2x/icon_editor_control_anchor.png b/editor/icons/2x/icon_editor_control_anchor.png new file mode 100644 index 000000000..838f85b76 Binary files /dev/null and b/editor/icons/2x/icon_editor_control_anchor.png differ diff --git a/editor/icons/icon_editor_control_anchor.png b/editor/icons/icon_editor_control_anchor.png new file mode 100644 index 000000000..158dd62a7 Binary files /dev/null and b/editor/icons/icon_editor_control_anchor.png differ diff --git a/editor/icons/source/icon_editor_control_anchor.svg b/editor/icons/source/icon_editor_control_anchor.svg new file mode 100644 index 000000000..473b69d06 --- /dev/null +++ b/editor/icons/source/icon_editor_control_anchor.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 92acd966d..6516776ed 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -775,6 +775,15 @@ CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Point2 &p_cli return DRAG_NONE; } +Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) { + ERR_FAIL_COND_V(!p_control, Vector2()); + + Transform2D parent_transform = p_control->get_transform().affine_inverse(); + Size2 parent_size = p_control->get_parent_area_size(); + + return parent_transform.xform(Vector2(parent_size.x * anchor.x, parent_size.y * anchor.y)); +} + void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) { List &selection = editor_selection->get_selected_node_list(); @@ -1528,76 +1537,75 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { // Keep the height/width ratio of the item float aspect = local_rect.size.aspect(); switch (drag) { - case DRAG_LEFT: { + case DRAG_LEFT: drag_vector.y = -drag_vector.x / aspect; - } break; - case DRAG_RIGHT: { + break; + case DRAG_RIGHT: drag_vector.y = drag_vector.x / aspect; - } break; - case DRAG_TOP: { + break; + case DRAG_TOP: drag_vector.x = -drag_vector.y * aspect; - } break; - case DRAG_BOTTOM: { + break; + case DRAG_BOTTOM: drag_vector.x = drag_vector.y * aspect; - } break; + break; case DRAG_BOTTOM_LEFT: - case DRAG_TOP_RIGHT: { + case DRAG_TOP_RIGHT: if (aspect > 1.0) { // width > height, take x as reference drag_vector.y = -drag_vector.x / aspect; } else { // height > width, take y as reference drag_vector.x = -drag_vector.y * aspect; } - } break; + break; case DRAG_BOTTOM_RIGHT: - case DRAG_TOP_LEFT: { + case DRAG_TOP_LEFT: if (aspect > 1.0) { // width > height, take x as reference drag_vector.y = drag_vector.x / aspect; } else { // height > width, take y as reference drag_vector.x = drag_vector.y * aspect; } - } break; + break; } } else { switch (drag) { case DRAG_RIGHT: - case DRAG_LEFT: { + case DRAG_LEFT: drag_vector.y = 0; - } break; + break; case DRAG_TOP: - case DRAG_BOTTOM: { + case DRAG_BOTTOM: drag_vector.x = 0; - } break; + break; } } switch (drag) { - case DRAG_ALL: { + case DRAG_ALL: begin += drag_vector; end += drag_vector; - } break; + break; case DRAG_RIGHT: case DRAG_BOTTOM: - case DRAG_BOTTOM_RIGHT: { + case DRAG_BOTTOM_RIGHT: incend(begin.x, end.x, drag_vector.x, minsize.x, symmetric); incend(begin.y, end.y, drag_vector.y, minsize.y, symmetric); - } break; - - case DRAG_TOP_LEFT: { + break; + case DRAG_TOP_LEFT: incbeg(begin.x, end.x, drag_vector.x, minsize.x, symmetric); incbeg(begin.y, end.y, drag_vector.y, minsize.y, symmetric); - } break; - + break; case DRAG_TOP: - case DRAG_TOP_RIGHT: { + case DRAG_TOP_RIGHT: incbeg(begin.y, end.y, drag_vector.y, minsize.y, symmetric); incend(begin.x, end.x, drag_vector.x, minsize.x, symmetric); - } break; + break; case DRAG_LEFT: - case DRAG_BOTTOM_LEFT: { + case DRAG_BOTTOM_LEFT: incbeg(begin.x, end.x, drag_vector.x, minsize.x, symmetric); incend(begin.y, end.y, drag_vector.y, minsize.y, symmetric); - } break; - case DRAG_PIVOT: { + break; + + case DRAG_PIVOT: if (canvas_item->cast_to()) { Node2D *n2d = canvas_item->cast_to(); @@ -1607,15 +1615,13 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { canvas_item->cast_to()->set_pivot_offset(se->undo_pivot + drag_vector); } continue; - } break; - case DRAG_NODE_2D: { + break; + case DRAG_NODE_2D: ERR_FAIL_COND(!canvas_item->cast_to()); canvas_item->cast_to()->set_global_position(dto); continue; - } break; - - default: {} + break; } if (!dragging_bone) { @@ -1870,13 +1876,32 @@ void CanvasItemEditor::_viewport_draw() { pivot_found = true; } } - if (canvas_item->cast_to()) { - Vector2 pivot_ofs = canvas_item->cast_to()->get_pivot_offset(); + + Control *control = canvas_item->cast_to(); + if (control) { + Vector2 pivot_ofs = control->get_pivot_offset(); if (pivot_ofs != Vector2()) { viewport->draw_texture(pivot, xform.xform(pivot_ofs) + (-pivot->get_size() / 2).floor()); } can_move_pivot = true; pivot_found = true; + + if (tool == TOOL_SELECT) { + // Draw the anchors + Rect2 anchor_rects[4]; + anchor_rects[0] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP)))), anchor_handle->get_size()); + anchor_rects[1] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP)))), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); + anchor_rects[2] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM)))), -anchor_handle->get_size()); + anchor_rects[3] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM)))), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); + + anchor_rects[0].position -= anchor_handle->get_size(); + anchor_rects[1].position -= Vector2(0.0, anchor_handle->get_size().y); + anchor_rects[3].position -= Vector2(anchor_handle->get_size().x, 0.0); + + for (int i = 0; i < 4; i++) { + anchor_handle->draw_rect(ci, anchor_rects[i]); + } + } } if (tool == TOOL_SELECT) { @@ -2063,19 +2088,27 @@ void CanvasItemEditor::_notification(int p_what) { continue; Rect2 r = canvas_item->get_item_rect(); - Transform2D xform = canvas_item->get_transform(); + float anchors[4]; Vector2 pivot; if (canvas_item->cast_to()) { pivot = canvas_item->cast_to()->get_pivot_offset(); + anchors[MARGIN_LEFT] = canvas_item->cast_to()->get_anchor(MARGIN_LEFT); + anchors[MARGIN_RIGHT] = canvas_item->cast_to()->get_anchor(MARGIN_RIGHT); + anchors[MARGIN_TOP] = canvas_item->cast_to()->get_anchor(MARGIN_TOP); + anchors[MARGIN_BOTTOM] = canvas_item->cast_to()->get_anchor(MARGIN_BOTTOM); } - if (r != se->prev_rect || xform != se->prev_xform || pivot != se->prev_pivot) { + if (r != se->prev_rect || xform != se->prev_xform || pivot != se->prev_pivot || anchors[MARGIN_LEFT] != se->prev_anchors[MARGIN_LEFT] || anchors[MARGIN_RIGHT] != se->prev_anchors[MARGIN_RIGHT] || anchors[MARGIN_TOP] != se->prev_anchors[MARGIN_TOP] || anchors[MARGIN_BOTTOM] != se->prev_anchors[MARGIN_BOTTOM]) { viewport->update(); se->prev_rect = r; se->prev_xform = xform; se->prev_pivot = pivot; + se->prev_anchors[MARGIN_LEFT] = anchors[MARGIN_LEFT]; + se->prev_anchors[MARGIN_RIGHT] = anchors[MARGIN_RIGHT]; + se->prev_anchors[MARGIN_TOP] = anchors[MARGIN_TOP]; + se->prev_anchors[MARGIN_BOTTOM] = anchors[MARGIN_BOTTOM]; } } @@ -2124,6 +2157,7 @@ void CanvasItemEditor::_notification(int p_what) { pan_button->set_icon(get_icon("ToolPan", "EditorIcons")); pivot_button->set_icon(get_icon("EditPivot", "EditorIcons")); select_handle = get_icon("EditorHandle", "EditorIcons"); + anchor_handle = get_icon("EditorControlAnchor", "EditorIcons"); lock_button->set_icon(get_icon("Lock", "EditorIcons")); unlock_button->set_icon(get_icon("Unlock", "EditorIcons")); group_button->set_icon(get_icon("Group", "EditorIcons")); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 53cfb8885..bd6591011 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -57,6 +57,7 @@ public: float prev_rot; Rect2 prev_rect; Vector2 prev_pivot; + float prev_anchors[4]; CanvasItemEditorSelectedItem() { prev_rot = 0; } }; @@ -300,6 +301,7 @@ class CanvasItemEditor : public VBoxContainer { #endif Ref select_sb; Ref select_handle; + Ref anchor_handle; int handle_len; bool _is_part_of_subscene(CanvasItem *p_item); @@ -328,6 +330,8 @@ class CanvasItemEditor : public VBoxContainer { DragType _find_drag_type(const Point2 &p_click, Vector2 &r_point); void _prepare_drag(const Point2 &p_click_pos); + Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); + void _popup_callback(int p_op); bool updating_scroll; void _update_scroll(float); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 4d0678db7..f7058989a 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1304,6 +1304,7 @@ void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin) { _size_changed(); } } + update(); _change_notify(); } -- cgit v1.2.3-70-g09d2 From fcff42dcb717478d963ce6ad197c5ed7bdfb080c Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Sat, 29 Jul 2017 16:57:32 +0200 Subject: Make anchors draggable --- editor/plugins/canvas_item_editor_plugin.cpp | 101 ++++++++++++++++++++++++--- editor/plugins/canvas_item_editor_plugin.h | 9 ++- 2 files changed, 99 insertions(+), 11 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 6516776ed..cbb983172 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -709,8 +709,8 @@ CanvasItem *CanvasItemEditor::get_single_item() { return single_item; } -CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Point2 &p_click, Vector2 &r_point) { - +CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const Point2 &p_click, Vector2 &r_point) { + // Returns a drag type if a resize handle is clicked CanvasItem *canvas_item = get_single_item(); ERR_FAIL_COND_V(!canvas_item, DRAG_NONE); @@ -784,6 +784,51 @@ Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor return parent_transform.xform(Vector2(parent_size.x * anchor.x, parent_size.y * anchor.y)); } +Vector2 CanvasItemEditor::_position_to_anchor(Control *p_control, Vector2 position) { + ERR_FAIL_COND_V(!p_control, Vector2()); + Size2 parent_size = p_control->get_parent_area_size(); + + return p_control->get_transform().xform(position) / parent_size; +} + +CanvasItemEditor::DragType CanvasItemEditor::_get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point) { + // Returns a drag type if an anchor handle is clicked + CanvasItem *canvas_item = get_single_item(); + ERR_FAIL_COND_V(!canvas_item, DRAG_NONE); + + Control *control = canvas_item->cast_to(); + ERR_FAIL_COND_V(!control, DRAG_NONE); + + Vector2 anchor_pos[4]; + anchor_pos[0] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP)); + anchor_pos[1] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP)); + anchor_pos[2] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM)); + anchor_pos[3] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM)); + + Rect2 anchor_rects[4]; + for (int i = 0; i < 4; i++) { + 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()); + anchor_rects[i].position -= anchor_handle->get_size() * Vector2(i == 0 || i == 3, i <= 1); + } + + DragType dragger[] = { + DRAG_ANCHOR_TOP_LEFT, + DRAG_ANCHOR_TOP_RIGHT, + DRAG_ANCHOR_BOTTOM_RIGHT, + DRAG_ANCHOR_BOTTOM_LEFT, + }; + + for (int i = 0; i < 4; i++) { + if (anchor_rects[i].has_point(p_click)) { + r_point = transform.affine_inverse().xform(anchor_pos[i]); + return dragger[i]; + } + } + + return DRAG_NONE; +} + void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) { List &selection = editor_selection->get_selected_node_list(); @@ -1345,8 +1390,8 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { } } - // Drag - drag = _find_drag_type(click, drag_point_from); + // Drag resize handles + drag = _get_resize_handle_drag_type(click, drag_point_from); if (drag != DRAG_NONE) { drag_from = transform.affine_inverse().xform(click); se->undo_state = canvas_item->edit_get_state(); @@ -1356,6 +1401,16 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { se->undo_pivot = canvas_item->cast_to()->get_pivot_offset(); return; } + + // Drag anchor handles + if (canvas_item->cast_to()) { + drag = _get_anchor_handle_drag_type(click, drag_point_from); + if (drag != DRAG_NONE) { + drag_from = transform.affine_inverse().xform(click); + se->undo_state = canvas_item->edit_get_state(); + return; + } + } } } @@ -1432,9 +1487,8 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { } if (drag == DRAG_NONE) { - if ((m->get_button_mask() & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m->get_button_mask() & BUTTON_MASK_MIDDLE || (m->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { - + // Pan the viewport Point2i relative; if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect()); @@ -1450,7 +1504,6 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { } List &selection = editor_selection->get_selected_node_list(); - for (List::Element *E = selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get()->cast_to(); @@ -1479,7 +1532,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { continue; if (drag == DRAG_ROTATE) { - + // Rotate the node Vector2 center = canvas_item->get_global_transform_with_canvas().get_origin(); { Node2D *node = canvas_item->cast_to(); @@ -1508,10 +1561,40 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { continue; } + Control *control = canvas_item->cast_to(); + if (control) { + Vector2 anchor = _position_to_anchor(control, canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto - drag_from + drag_point_from)); + + switch (drag) { + // Handles anchor dragging + case DRAG_ANCHOR_TOP_LEFT: + control->set_anchor(MARGIN_LEFT, anchor.x); + control->set_anchor(MARGIN_TOP, anchor.y); + continue; + break; + case DRAG_ANCHOR_TOP_RIGHT: + control->set_anchor(MARGIN_RIGHT, anchor.x); + control->set_anchor(MARGIN_TOP, anchor.y); + continue; + break; + case DRAG_ANCHOR_BOTTOM_RIGHT: + control->set_anchor(MARGIN_RIGHT, anchor.x); + control->set_anchor(MARGIN_BOTTOM, anchor.y); + continue; + break; + case DRAG_ANCHOR_BOTTOM_LEFT: + control->set_anchor(MARGIN_LEFT, anchor.x); + control->set_anchor(MARGIN_BOTTOM, anchor.y); + continue; + break; + } + } + bool uniform = m->get_shift(); bool symmetric = m->get_alt(); - dto = dto - (drag == DRAG_ALL || drag == DRAG_NODE_2D ? drag_from - drag_point_from : Vector2(0, 0)); + if (drag == DRAG_ALL || drag == DRAG_NODE_2D) + dto -= drag_from - drag_point_from; if (uniform && (drag == DRAG_ALL || drag == DRAG_NODE_2D)) { if (ABS(dto.x - drag_point_from.x) > ABS(dto.y - drag_point_from.y)) { diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index bd6591011..fd89a451e 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -144,11 +144,14 @@ class CanvasItemEditor : public VBoxContainer { DRAG_BOTTOM_RIGHT, DRAG_BOTTOM, DRAG_BOTTOM_LEFT, + DRAG_ANCHOR_TOP_LEFT, + DRAG_ANCHOR_TOP_RIGHT, + DRAG_ANCHOR_BOTTOM_RIGHT, + DRAG_ANCHOR_BOTTOM_LEFT, DRAG_ALL, DRAG_ROTATE, DRAG_PIVOT, DRAG_NODE_2D, - }; enum KeyMoveMODE { @@ -327,10 +330,12 @@ class CanvasItemEditor : public VBoxContainer { void _key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE p_move_mode); void _list_select(const Ref &b); - DragType _find_drag_type(const Point2 &p_click, Vector2 &r_point); + DragType _get_resize_handle_drag_type(const Point2 &p_click, Vector2 &r_point); void _prepare_drag(const Point2 &p_click_pos); + DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); + Vector2 _position_to_anchor(Control *p_control, Vector2 position); void _popup_callback(int p_op); bool updating_scroll; -- cgit v1.2.3-70-g09d2 From b329cb9c71ff43d013bd29574db251ddebf9f245 Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Sun, 30 Jul 2017 15:32:22 +0200 Subject: Snap anchors when dragged, depending on the zoom level --- editor/plugins/canvas_item_editor_plugin.cpp | 22 +++++++++++++++++++++- editor/plugins/canvas_item_editor_plugin.h | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index cbb983172..1fd343c4b 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -775,6 +775,24 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const return DRAG_NONE; } +Vector2 CanvasItemEditor::_anchor_snap(Vector2 anchor) { + float radius = 0.05 / zoom; + if (fabs(anchor.x - ANCHOR_BEGIN) < radius) { + anchor.x = ANCHOR_BEGIN; + } else if (fabs(anchor.x - ANCHOR_CENTER) < radius) { + anchor.x = ANCHOR_CENTER; + } else if (fabs(anchor.x - ANCHOR_END) < radius) { + anchor.x = ANCHOR_END; + } + if (fabs(anchor.y - ANCHOR_BEGIN) < radius) { + anchor.y = ANCHOR_BEGIN; + } else if (fabs(anchor.y - ANCHOR_CENTER) < radius) { + anchor.y = ANCHOR_CENTER; + } else if (fabs(anchor.y - ANCHOR_END) < radius) { + anchor.y = ANCHOR_END; + } + return anchor; +} Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) { ERR_FAIL_COND_V(!p_control, Vector2()); @@ -1319,6 +1337,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { if (b) { bool ik_found = false; + bool first = true; while (b) { @@ -1563,10 +1582,11 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { Control *control = canvas_item->cast_to(); if (control) { + // Drag and snap the anchor Vector2 anchor = _position_to_anchor(control, canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto - drag_from + drag_point_from)); + anchor = _anchor_snap(anchor); switch (drag) { - // Handles anchor dragging case DRAG_ANCHOR_TOP_LEFT: control->set_anchor(MARGIN_LEFT, anchor.x); control->set_anchor(MARGIN_TOP, anchor.y); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index fd89a451e..0263bc108 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -334,6 +334,7 @@ class CanvasItemEditor : public VBoxContainer { void _prepare_drag(const Point2 &p_click_pos); DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); + Vector2 _anchor_snap(Vector2 anchor); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(Control *p_control, Vector2 position); -- cgit v1.2.3-70-g09d2 From 3264cea7ae65ca05b03460cfddefc30a2fa93e3c Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Sun, 30 Jul 2017 17:59:57 +0200 Subject: Add lines to make understandable when anchors are snapped --- editor/plugins/canvas_item_editor_plugin.cpp | 111 +++++++++++++++++++++------ editor/plugins/canvas_item_editor_plugin.h | 2 +- 2 files changed, 88 insertions(+), 25 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 1fd343c4b..043cdb24a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -775,23 +775,40 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const return DRAG_NONE; } -Vector2 CanvasItemEditor::_anchor_snap(Vector2 anchor) { +Vector2 CanvasItemEditor::_anchor_snap(const Vector2 anchor, bool *snapped_x, bool *snapped_y) { + Vector2 result = anchor; + if (snapped_x) + *snapped_x = false; + if (snapped_y) + *snapped_y = false; float radius = 0.05 / zoom; - if (fabs(anchor.x - ANCHOR_BEGIN) < radius) { - anchor.x = ANCHOR_BEGIN; - } else if (fabs(anchor.x - ANCHOR_CENTER) < radius) { - anchor.x = ANCHOR_CENTER; - } else if (fabs(anchor.x - ANCHOR_END) < radius) { - anchor.x = ANCHOR_END; - } - if (fabs(anchor.y - ANCHOR_BEGIN) < radius) { - anchor.y = ANCHOR_BEGIN; - } else if (fabs(anchor.y - ANCHOR_CENTER) < radius) { - anchor.y = ANCHOR_CENTER; - } else if (fabs(anchor.y - ANCHOR_END) < radius) { - anchor.y = ANCHOR_END; - } - return anchor; + if (fabs(result.x - ANCHOR_BEGIN) < radius) { + result.x = ANCHOR_BEGIN; + if (snapped_x) + *snapped_x = true; + } else if (fabs(result.x - ANCHOR_CENTER) < radius) { + result.x = ANCHOR_CENTER; + if (snapped_x) + *snapped_x = true; + } else if (fabs(result.x - ANCHOR_END) < radius) { + result.x = ANCHOR_END; + if (snapped_x) + *snapped_x = true; + } + if (fabs(result.y - ANCHOR_BEGIN) < radius) { + result.y = ANCHOR_BEGIN; + if (snapped_y) + *snapped_y = true; + } else if (fabs(result.y - ANCHOR_CENTER) < radius) { + result.y = ANCHOR_CENTER; + if (snapped_y) + *snapped_y = true; + } else if (fabs(result.y - ANCHOR_END) < radius) { + result.y = ANCHOR_END; + if (snapped_y) + *snapped_y = true; + } + return result; } Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) { ERR_FAIL_COND_V(!p_control, Vector2()); @@ -1991,15 +2008,61 @@ void CanvasItemEditor::_viewport_draw() { if (tool == TOOL_SELECT) { // Draw the anchors + Vector2 anchors[4]; + anchors[0] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP)); + anchors[1] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP)); + anchors[2] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM)); + anchors[3] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM)); + + Vector2 anchors_pos[4]; + for (int i = 0; i < 4; i++) { + anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i])); + } + + // Get which anchor is dragged + int dragged_anchor = -1; + switch (drag) { + case DRAG_ANCHOR_TOP_LEFT: + dragged_anchor = 0; + break; + case DRAG_ANCHOR_TOP_RIGHT: + dragged_anchor = 1; + break; + case DRAG_ANCHOR_BOTTOM_RIGHT: + dragged_anchor = 2; + break; + case DRAG_ANCHOR_BOTTOM_LEFT: + dragged_anchor = 3; + break; + } + + if (dragged_anchor >= 0) { + // Draw the 4 lines when dragged + bool snapped_x, snapped_y; + Color color_snapped = Color(0.64, 0.93, 0.67, 0.5); + Color color_base = Color(0.8, 0.8, 0.8, 0.5); + + Vector2 corners_pos[4]; + for (int i = 0; i < 4; i++) { + corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END))); + } + + for (int i = 0; i < 4; i++) { + float anchor_val = (i % 2 == 0) ? anchors[i].x : anchors[i].y; + anchor_val = (i >= 2) ? ANCHOR_END - anchor_val : anchor_val; + Vector2 line_start = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); + Vector2 line_end = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); + _anchor_snap(anchors[i], &snapped_x, &snapped_y); + viewport->draw_line(line_start, line_end, ((i % 2 == 0 && snapped_x) || (i % 2 == 1 && snapped_y)) ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); + } + + } + Rect2 anchor_rects[4]; - anchor_rects[0] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP)))), anchor_handle->get_size()); - anchor_rects[1] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP)))), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); - anchor_rects[2] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM)))), -anchor_handle->get_size()); - anchor_rects[3] = Rect2(xform.xform(_anchor_to_position(control, Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM)))), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); - - anchor_rects[0].position -= anchor_handle->get_size(); - anchor_rects[1].position -= Vector2(0.0, anchor_handle->get_size().y); - anchor_rects[3].position -= Vector2(anchor_handle->get_size().x, 0.0); + anchor_rects[0] = Rect2(anchors_pos[0] - anchor_handle->get_size(), anchor_handle->get_size()); + anchor_rects[1] = Rect2(anchors_pos[1] - Vector2(0.0, anchor_handle->get_size().y), Point2(-anchor_handle->get_size().x, anchor_handle->get_size().y)); + anchor_rects[2] = Rect2(anchors_pos[2], -anchor_handle->get_size()); + anchor_rects[3] = Rect2(anchors_pos[3] - Vector2(anchor_handle->get_size().x, 0.0), Point2(anchor_handle->get_size().x, -anchor_handle->get_size().y)); for (int i = 0; i < 4; i++) { anchor_handle->draw_rect(ci, anchor_rects[i]); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 0263bc108..dbae632b0 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -334,7 +334,7 @@ class CanvasItemEditor : public VBoxContainer { void _prepare_drag(const Point2 &p_click_pos); DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); - Vector2 _anchor_snap(Vector2 anchor); + Vector2 _anchor_snap(const Vector2 anchor, bool *snapped_x = NULL, bool *snapped_y = NULL); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(Control *p_control, Vector2 position); -- cgit v1.2.3-70-g09d2 From 2032cb25221bb4388b9875a49fd4c882ee400af8 Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Mon, 31 Jul 2017 18:49:46 +0200 Subject: Simplifies the canvas editor code --- editor/plugins/canvas_item_editor_plugin.cpp | 86 ++++++++++++---------------- editor/plugins/canvas_item_editor_plugin.h | 2 +- 2 files changed, 37 insertions(+), 51 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 043cdb24a..9acb9fbbf 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -775,41 +775,27 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const return DRAG_NONE; } -Vector2 CanvasItemEditor::_anchor_snap(const Vector2 anchor, bool *snapped_x, bool *snapped_y) { - Vector2 result = anchor; - if (snapped_x) - *snapped_x = false; - if (snapped_y) - *snapped_y = false; +float CanvasItemEditor::_anchor_snap(const float anchor, bool *snapped) { + float result = anchor; + if (snapped) + *snapped = false; float radius = 0.05 / zoom; - if (fabs(result.x - ANCHOR_BEGIN) < radius) { - result.x = ANCHOR_BEGIN; - if (snapped_x) - *snapped_x = true; - } else if (fabs(result.x - ANCHOR_CENTER) < radius) { - result.x = ANCHOR_CENTER; - if (snapped_x) - *snapped_x = true; - } else if (fabs(result.x - ANCHOR_END) < radius) { - result.x = ANCHOR_END; - if (snapped_x) - *snapped_x = true; - } - if (fabs(result.y - ANCHOR_BEGIN) < radius) { - result.y = ANCHOR_BEGIN; - if (snapped_y) - *snapped_y = true; - } else if (fabs(result.y - ANCHOR_CENTER) < radius) { - result.y = ANCHOR_CENTER; - if (snapped_y) - *snapped_y = true; - } else if (fabs(result.y - ANCHOR_END) < radius) { - result.y = ANCHOR_END; - if (snapped_y) - *snapped_y = true; + if (fabs(result - ANCHOR_BEGIN) < radius) { + result = ANCHOR_BEGIN; + if (snapped) + *snapped = true; + } else if (fabs(result - ANCHOR_CENTER) < radius) { + result = ANCHOR_CENTER; + if (snapped) + *snapped = true; + } else if (fabs(result - ANCHOR_END) < radius) { + result = ANCHOR_END; + if (snapped) + *snapped = true; } return result; } + Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) { ERR_FAIL_COND_V(!p_control, Vector2()); @@ -1601,27 +1587,26 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { if (control) { // Drag and snap the anchor Vector2 anchor = _position_to_anchor(control, canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto - drag_from + drag_point_from)); - anchor = _anchor_snap(anchor); switch (drag) { case DRAG_ANCHOR_TOP_LEFT: - control->set_anchor(MARGIN_LEFT, anchor.x); - control->set_anchor(MARGIN_TOP, anchor.y); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y)); continue; break; case DRAG_ANCHOR_TOP_RIGHT: - control->set_anchor(MARGIN_RIGHT, anchor.x); - control->set_anchor(MARGIN_TOP, anchor.y); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y)); continue; break; case DRAG_ANCHOR_BOTTOM_RIGHT: - control->set_anchor(MARGIN_RIGHT, anchor.x); - control->set_anchor(MARGIN_BOTTOM, anchor.y); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y)); continue; break; case DRAG_ANCHOR_BOTTOM_LEFT: - control->set_anchor(MARGIN_LEFT, anchor.x); - control->set_anchor(MARGIN_BOTTOM, anchor.y); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y)); continue; break; } @@ -2007,15 +1992,17 @@ void CanvasItemEditor::_viewport_draw() { pivot_found = true; if (tool == TOOL_SELECT) { + float anchors_values[4]; + anchors_values[0] = control->get_anchor(MARGIN_LEFT); + anchors_values[1] = control->get_anchor(MARGIN_TOP); + anchors_values[2] = control->get_anchor(MARGIN_RIGHT); + anchors_values[3] = control->get_anchor(MARGIN_BOTTOM); + // Draw the anchors Vector2 anchors[4]; - anchors[0] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_TOP)); - anchors[1] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_TOP)); - anchors[2] = Vector2(control->get_anchor(MARGIN_RIGHT), control->get_anchor(MARGIN_BOTTOM)); - anchors[3] = Vector2(control->get_anchor(MARGIN_LEFT), control->get_anchor(MARGIN_BOTTOM)); - Vector2 anchors_pos[4]; for (int i = 0; i < 4; i++) { + anchors[i] = Vector2((i % 2 == 0) ? anchors_values[i] : anchors_values[(i + 1) % 4], (i % 2 == 1) ? anchors_values[i] : anchors_values[(i + 1) % 4]); anchors_pos[i] = xform.xform(_anchor_to_position(control, anchors[i])); } @@ -2038,7 +2025,7 @@ void CanvasItemEditor::_viewport_draw() { if (dragged_anchor >= 0) { // Draw the 4 lines when dragged - bool snapped_x, snapped_y; + bool snapped; Color color_snapped = Color(0.64, 0.93, 0.67, 0.5); Color color_base = Color(0.8, 0.8, 0.8, 0.5); @@ -2048,12 +2035,11 @@ void CanvasItemEditor::_viewport_draw() { } for (int i = 0; i < 4; i++) { - float anchor_val = (i % 2 == 0) ? anchors[i].x : anchors[i].y; - anchor_val = (i >= 2) ? ANCHOR_END - anchor_val : anchor_val; + float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; Vector2 line_start = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); Vector2 line_end = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); - _anchor_snap(anchors[i], &snapped_x, &snapped_y); - viewport->draw_line(line_start, line_end, ((i % 2 == 0 && snapped_x) || (i % 2 == 1 && snapped_y)) ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); + _anchor_snap(anchors_values[i], &snapped); + viewport->draw_line(line_start, line_end, snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); } } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index dbae632b0..e6901b232 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -334,7 +334,7 @@ class CanvasItemEditor : public VBoxContainer { void _prepare_drag(const Point2 &p_click_pos); DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); - Vector2 _anchor_snap(const Vector2 anchor, bool *snapped_x = NULL, bool *snapped_y = NULL); + float _anchor_snap(const float anchor, bool *snapped = NULL); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(Control *p_control, Vector2 position); -- cgit v1.2.3-70-g09d2 From b73613e1eb66bf1807a4e106c87ebfaf6914813f Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Wed, 2 Aug 2017 18:33:06 +0200 Subject: Displays percentages when dragging anchors --- editor/plugins/canvas_item_editor_plugin.cpp | 49 ++++++++++++++++++++++++++-- editor/plugins/canvas_item_editor_plugin.h | 2 ++ 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 9acb9fbbf..353149828 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1879,6 +1879,30 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { } } +void CanvasItemEditor::_draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side) { + if (p_value != 0) { + Color color = Color(0.8, 0.8, 0.8, 0.5); + Ref font = get_font("font", "Label"); + String str = vformat("%.1f %%", p_value * 100.0); + Size2 text_size = font->get_string_size(str); + switch (p_side) { + case MARGIN_LEFT: + p_position += Vector2(-text_size.x - 5, text_size.y / 2); + break; + case MARGIN_TOP: + p_position += Vector2(-text_size.x / 2, -5); + break; + case MARGIN_RIGHT: + p_position += Vector2(5, text_size.y / 2); + break; + case MARGIN_BOTTOM: + p_position += Vector2(-text_size.x / 2, text_size.y + 5); + break; + } + viewport->draw_string(font, p_position, str, color); + } +} + void CanvasItemEditor::_viewport_draw() { // TODO fetch the viewport? @@ -2034,14 +2058,33 @@ void CanvasItemEditor::_viewport_draw() { corners_pos[i] = xform.xform(_anchor_to_position(control, Vector2((i == 0 || i == 3) ? ANCHOR_BEGIN : ANCHOR_END, (i <= 1) ? ANCHOR_BEGIN : ANCHOR_END))); } + Vector2 line_starts[4]; + Vector2 line_ends[4]; for (int i = 0; i < 4; i++) { float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; - Vector2 line_start = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); - Vector2 line_end = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); + line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); + line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); _anchor_snap(anchors_values[i], &snapped); - viewport->draw_line(line_start, line_end, snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); + viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); } + // Display the percentages next to the lines + float percent_val; + percent_val = anchors_values[(dragged_anchor + 2) % 4] - anchors_values[dragged_anchor]; + percent_val = (dragged_anchor >= 2) ? -percent_val : percent_val; + _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 1) % 4]) / 2, (Margin)((dragged_anchor + 1) % 4)); + + percent_val = anchors_values[(dragged_anchor + 3) % 4] - anchors_values[(dragged_anchor + 1) % 4]; + percent_val = ((dragged_anchor + 1) % 4 >= 2) ? -percent_val : percent_val; + _draw_percentage_at_position(percent_val, (anchors_pos[dragged_anchor] + anchors_pos[(dragged_anchor + 3) % 4]) / 2, (Margin)(dragged_anchor)); + + percent_val = anchors_values[(dragged_anchor + 1) % 4]; + percent_val = ((dragged_anchor + 1) % 4 >= 2) ? ANCHOR_END - percent_val : percent_val; + _draw_percentage_at_position(percent_val, (line_starts[dragged_anchor] + anchors_pos[dragged_anchor]) / 2, (Margin)(dragged_anchor)); + + percent_val = anchors_values[dragged_anchor]; + percent_val = (dragged_anchor >= 2) ? ANCHOR_END - percent_val : percent_val; + _draw_percentage_at_position(percent_val, (line_ends[(dragged_anchor + 1) % 4] + anchors_pos[dragged_anchor]) / 2, (Margin)((dragged_anchor + 1) % 4)); } Rect2 anchor_rects[4]; diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index e6901b232..009329c27 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -365,6 +365,8 @@ class CanvasItemEditor : public VBoxContainer { void _unhandled_key_input(const Ref &p_ev); + void _draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side); + void _viewport_gui_input(const Ref &p_event); void _viewport_draw(); -- cgit v1.2.3-70-g09d2 From f5ff7e9fa039e54de2e48bfb46239bbda497287a Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Wed, 2 Aug 2017 19:24:05 +0200 Subject: Make anchors snap to each other --- editor/plugins/canvas_item_editor_plugin.cpp | 55 +++++++++++++++------------- editor/plugins/canvas_item_editor_plugin.h | 2 +- 2 files changed, 31 insertions(+), 26 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 353149828..fc3cee033 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -775,25 +775,30 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const return DRAG_NONE; } -float CanvasItemEditor::_anchor_snap(const float anchor, bool *snapped) { - float result = anchor; - if (snapped) - *snapped = false; +float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_opposite_anchor) { + bool snapped = false; + float dist, dist_min = 0.0; float radius = 0.05 / zoom; - if (fabs(result - ANCHOR_BEGIN) < radius) { - result = ANCHOR_BEGIN; - if (snapped) - *snapped = true; - } else if (fabs(result - ANCHOR_CENTER) < radius) { - result = ANCHOR_CENTER; - if (snapped) - *snapped = true; - } else if (fabs(result - ANCHOR_END) < radius) { - result = ANCHOR_END; - if (snapped) - *snapped = true; + float basic_anchors[3] = { ANCHOR_BEGIN, ANCHOR_CENTER, ANCHOR_END }; + for (int i = 0; i < 3; i++) { + if ((dist = fabs(p_anchor - basic_anchors[i])) < radius) { + if (!snapped || dist <= dist_min) { + p_anchor = basic_anchors[i]; + dist_min = dist; + snapped = true; + } + } + } + if (p_opposite_anchor >= 0 && (dist = fabs(p_anchor - p_opposite_anchor)) < radius) { + if (!snapped || dist <= dist_min) { + p_anchor = p_opposite_anchor; + dist_min = dist; + snapped = true; + } } - return result; + if (p_snapped) + *p_snapped = snapped; + return p_anchor; } Vector2 CanvasItemEditor::_anchor_to_position(Control *p_control, Vector2 anchor) { @@ -1590,23 +1595,23 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { switch (drag) { case DRAG_ANCHOR_TOP_LEFT: - control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x)); - control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y)); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT))); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM))); continue; break; case DRAG_ANCHOR_TOP_RIGHT: - control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x)); - control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y)); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT))); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM))); continue; break; case DRAG_ANCHOR_BOTTOM_RIGHT: - control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x)); - control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y)); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT))); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP))); continue; break; case DRAG_ANCHOR_BOTTOM_LEFT: - control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x)); - control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y)); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT))); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP))); continue; break; } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 009329c27..c6b428996 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -334,7 +334,7 @@ class CanvasItemEditor : public VBoxContainer { void _prepare_drag(const Point2 &p_click_pos); DragType _get_anchor_handle_drag_type(const Point2 &p_click, Vector2 &r_point); - float _anchor_snap(const float anchor, bool *snapped = NULL); + float _anchor_snap(float anchor, bool *snapped = NULL, float p_opposite_anchor = -1); Vector2 _anchor_to_position(Control *p_control, Vector2 anchor); Vector2 _position_to_anchor(Control *p_control, Vector2 position); -- cgit v1.2.3-70-g09d2 From e8c83b31bddd1767a828aaed2f34c1a442bd6919 Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Fri, 4 Aug 2017 19:27:30 +0200 Subject: Added the possibility to move all anchors at once when they are clustered --- editor/plugins/canvas_item_editor_plugin.cpp | 14 +++++++++++++- editor/plugins/canvas_item_editor_plugin.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index fc3cee033..d9550f979 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -848,7 +848,11 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_anchor_handle_drag_type(const for (int i = 0; i < 4; i++) { if (anchor_rects[i].has_point(p_click)) { r_point = transform.affine_inverse().xform(anchor_pos[i]); - return dragger[i]; + if ((anchor_pos[0] == anchor_pos[2]) && (anchor_pos[0].distance_to(p_click) < anchor_handle->get_size().length() / 3.0)) { + return DRAG_ANCHOR_ALL; + } else { + return dragger[i]; + } } } @@ -1614,6 +1618,13 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP))); continue; break; + case DRAG_ANCHOR_ALL: + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x)); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y)); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y)); + continue; + break; } } @@ -2038,6 +2049,7 @@ void CanvasItemEditor::_viewport_draw() { // Get which anchor is dragged int dragged_anchor = -1; switch (drag) { + case DRAG_ANCHOR_ALL: case DRAG_ANCHOR_TOP_LEFT: dragged_anchor = 0; break; diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index c6b428996..49c9cd9dc 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -148,6 +148,7 @@ class CanvasItemEditor : public VBoxContainer { DRAG_ANCHOR_TOP_RIGHT, DRAG_ANCHOR_BOTTOM_RIGHT, DRAG_ANCHOR_BOTTOM_LEFT, + DRAG_ANCHOR_ALL, DRAG_ALL, DRAG_ROTATE, DRAG_PIVOT, -- cgit v1.2.3-70-g09d2 From c26af6f2b7c5dde7530a773d19a999c1805b91fb Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Fri, 11 Aug 2017 18:16:28 +0200 Subject: Adds a function to set Anchors with a layout preset --- editor/plugins/canvas_item_editor_plugin.cpp | 45 ++++----- editor/plugins/canvas_item_editor_plugin.h | 2 +- scene/gui/control.cpp | 132 +++++++++++++++++++++++++++ scene/gui/control.h | 21 +++++ 4 files changed, 173 insertions(+), 27 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index d9550f979..3a933690a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2584,7 +2584,7 @@ void CanvasItemEditor::_update_scroll(float) { viewport->update(); } -void CanvasItemEditor::_set_anchor(float p_left, float p_top, float p_right, float p_bottom) { +void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) { List &selection = editor_selection->get_selected_node_list(); undo_redo->create_action(TTR("Change Anchors")); @@ -2592,10 +2592,7 @@ void CanvasItemEditor::_set_anchor(float p_left, float p_top, float p_right, flo Control *c = E->get()->cast_to(); - undo_redo->add_do_method(c, "set_anchor", MARGIN_LEFT, p_left); - undo_redo->add_do_method(c, "set_anchor", MARGIN_TOP, p_top); - undo_redo->add_do_method(c, "set_anchor", MARGIN_RIGHT, p_right); - undo_redo->add_do_method(c, "set_anchor", MARGIN_BOTTOM, p_bottom); + undo_redo->add_do_method(c, "set_anchors_preset", p_preset); undo_redo->add_undo_method(c, "set_anchor", MARGIN_LEFT, c->get_anchor(MARGIN_LEFT)); undo_redo->add_undo_method(c, "set_anchor", MARGIN_TOP, c->get_anchor(MARGIN_TOP)); undo_redo->add_undo_method(c, "set_anchor", MARGIN_RIGHT, c->get_anchor(MARGIN_RIGHT)); @@ -2613,10 +2610,7 @@ void CanvasItemEditor::_set_full_rect() { Control *c = E->get()->cast_to(); - undo_redo->add_do_method(c, "set_anchor", MARGIN_LEFT, ANCHOR_BEGIN); - undo_redo->add_do_method(c, "set_anchor", MARGIN_TOP, ANCHOR_BEGIN); - undo_redo->add_do_method(c, "set_anchor", MARGIN_RIGHT, ANCHOR_END); - undo_redo->add_do_method(c, "set_anchor", MARGIN_BOTTOM, ANCHOR_END); + undo_redo->add_do_method(c, "set_anchors_preset", PRESET_WIDE); undo_redo->add_do_method(c, "set_margin", MARGIN_LEFT, 0); undo_redo->add_do_method(c, "set_margin", MARGIN_TOP, 0); undo_redo->add_do_method(c, "set_margin", MARGIN_RIGHT, 0); @@ -2837,53 +2831,52 @@ void CanvasItemEditor::_popup_callback(int p_op) { //space_selected_items< proj_vector2_y, compare_items_y >(); } break; case ANCHOR_ALIGN_TOP_LEFT: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN); + _set_anchors_preset(PRESET_TOP_LEFT); } break; case ANCHOR_ALIGN_TOP_RIGHT: { - _set_anchor(ANCHOR_END, ANCHOR_BEGIN, ANCHOR_END, ANCHOR_BEGIN); + _set_anchors_preset(PRESET_TOP_RIGHT); } break; case ANCHOR_ALIGN_BOTTOM_LEFT: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_END, ANCHOR_BEGIN, ANCHOR_END); + _set_anchors_preset(PRESET_BOTTOM_LEFT); } break; case ANCHOR_ALIGN_BOTTOM_RIGHT: { - _set_anchor(ANCHOR_END, ANCHOR_END, ANCHOR_END, ANCHOR_END); + _set_anchors_preset(PRESET_BOTTOM_RIGHT); } break; case ANCHOR_ALIGN_CENTER_LEFT: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_CENTER, ANCHOR_BEGIN, ANCHOR_CENTER); + _set_anchors_preset(PRESET_CENTER_LEFT); } break; case ANCHOR_ALIGN_CENTER_RIGHT: { - - _set_anchor(ANCHOR_END, ANCHOR_CENTER, ANCHOR_END, ANCHOR_CENTER); + _set_anchors_preset(PRESET_CENTER_RIGHT); } break; case ANCHOR_ALIGN_CENTER_TOP: { - _set_anchor(ANCHOR_CENTER, ANCHOR_BEGIN, ANCHOR_CENTER, ANCHOR_BEGIN); + _set_anchors_preset(PRESET_CENTER_TOP); } break; case ANCHOR_ALIGN_CENTER_BOTTOM: { - _set_anchor(ANCHOR_CENTER, ANCHOR_END, ANCHOR_CENTER, ANCHOR_END); + _set_anchors_preset(PRESET_CENTER_BOTTOM); } break; case ANCHOR_ALIGN_CENTER: { - _set_anchor(ANCHOR_CENTER, ANCHOR_CENTER, ANCHOR_CENTER, ANCHOR_CENTER); + _set_anchors_preset(PRESET_CENTER); } break; case ANCHOR_ALIGN_TOP_WIDE: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_END, ANCHOR_BEGIN); + _set_anchors_preset(PRESET_TOP_WIDE); } break; case ANCHOR_ALIGN_LEFT_WIDE: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_END); + _set_anchors_preset(PRESET_LEFT_WIDE); } break; case ANCHOR_ALIGN_RIGHT_WIDE: { - _set_anchor(ANCHOR_END, ANCHOR_BEGIN, ANCHOR_END, ANCHOR_END); + _set_anchors_preset(PRESET_RIGHT_WIDE); } break; case ANCHOR_ALIGN_BOTTOM_WIDE: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_END, ANCHOR_END, ANCHOR_END); + _set_anchors_preset(PRESET_BOTTOM_WIDE); } break; case ANCHOR_ALIGN_VCENTER_WIDE: { - _set_anchor(ANCHOR_CENTER, ANCHOR_BEGIN, ANCHOR_CENTER, ANCHOR_END); + _set_anchors_preset(PRESET_VCENTER_WIDE); } break; case ANCHOR_ALIGN_HCENTER_WIDE: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_CENTER, ANCHOR_END, ANCHOR_CENTER); + _set_anchors_preset(PRESET_HCENTER_WIDE); } break; case ANCHOR_ALIGN_WIDE: { - _set_anchor(ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_END, ANCHOR_END); + _set_anchors_preset(PRESET_WIDE); } break; case ANCHOR_ALIGN_WIDE_FIT: { _set_full_rect(); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 49c9cd9dc..9b027fda6 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -373,7 +373,7 @@ class CanvasItemEditor : public VBoxContainer { void _focus_selection(int p_op); - void _set_anchor(float p_left, float p_top, float p_right, float p_bottom); + void _set_anchors_preset(Control::LayoutPreset p_preset); void _set_full_rect(); HSplitContainer *palette_split; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 30ee51fd1..9e5f22cfa 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1337,6 +1337,120 @@ void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos set_margin(p_margin, p_pos); } +void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin) { + //Left + switch (p_preset) { + case PRESET_TOP_LEFT: + case PRESET_BOTTOM_LEFT: + case PRESET_CENTER_LEFT: + case PRESET_TOP_WIDE: + case PRESET_BOTTOM_WIDE: + case PRESET_LEFT_WIDE: + case PRESET_HCENTER_WIDE: + case PRESET_WIDE: + set_anchor(MARGIN_LEFT, ANCHOR_BEGIN, p_keep_margin); + break; + + case PRESET_CENTER_TOP: + case PRESET_CENTER_BOTTOM: + case PRESET_CENTER: + case PRESET_VCENTER_WIDE: + set_anchor(MARGIN_LEFT, ANCHOR_CENTER, p_keep_margin); + break; + + case PRESET_TOP_RIGHT: + case PRESET_BOTTOM_RIGHT: + case PRESET_CENTER_RIGHT: + case PRESET_RIGHT_WIDE: + set_anchor(MARGIN_LEFT, ANCHOR_END, p_keep_margin); + break; + } + + // Top + switch (p_preset) { + case PRESET_TOP_LEFT: + case PRESET_TOP_RIGHT: + case PRESET_CENTER_TOP: + case PRESET_LEFT_WIDE: + case PRESET_RIGHT_WIDE: + case PRESET_TOP_WIDE: + case PRESET_VCENTER_WIDE: + case PRESET_WIDE: + set_anchor(MARGIN_TOP, ANCHOR_BEGIN, p_keep_margin); + break; + + case PRESET_CENTER_LEFT: + case PRESET_CENTER_RIGHT: + case PRESET_CENTER: + case PRESET_HCENTER_WIDE: + set_anchor(MARGIN_TOP, ANCHOR_CENTER, p_keep_margin); + break; + + case PRESET_BOTTOM_LEFT: + case PRESET_BOTTOM_RIGHT: + case PRESET_CENTER_BOTTOM: + case PRESET_BOTTOM_WIDE: + set_anchor(MARGIN_TOP, ANCHOR_END, p_keep_margin); + break; + } + + // Right + switch (p_preset) { + case PRESET_TOP_LEFT: + case PRESET_BOTTOM_LEFT: + case PRESET_CENTER_LEFT: + case PRESET_LEFT_WIDE: + set_anchor(MARGIN_RIGHT, ANCHOR_BEGIN, p_keep_margin); + break; + + case PRESET_CENTER_TOP: + case PRESET_CENTER_BOTTOM: + case PRESET_CENTER: + case PRESET_VCENTER_WIDE: + set_anchor(MARGIN_RIGHT, ANCHOR_CENTER, p_keep_margin); + break; + + case PRESET_TOP_RIGHT: + case PRESET_BOTTOM_RIGHT: + case PRESET_CENTER_RIGHT: + case PRESET_TOP_WIDE: + case PRESET_RIGHT_WIDE: + case PRESET_BOTTOM_WIDE: + case PRESET_HCENTER_WIDE: + case PRESET_WIDE: + set_anchor(MARGIN_RIGHT, ANCHOR_END, p_keep_margin); + break; + } + + // Bottom + switch (p_preset) { + case PRESET_TOP_LEFT: + case PRESET_TOP_RIGHT: + case PRESET_CENTER_TOP: + case PRESET_TOP_WIDE: + set_anchor(MARGIN_BOTTOM, ANCHOR_BEGIN, p_keep_margin); + break; + + case PRESET_CENTER_LEFT: + case PRESET_CENTER_RIGHT: + case PRESET_CENTER: + case PRESET_HCENTER_WIDE: + set_anchor(MARGIN_BOTTOM, ANCHOR_CENTER, p_keep_margin); + break; + + case PRESET_BOTTOM_LEFT: + case PRESET_BOTTOM_RIGHT: + case PRESET_CENTER_BOTTOM: + case PRESET_LEFT_WIDE: + case PRESET_RIGHT_WIDE: + case PRESET_BOTTOM_WIDE: + case PRESET_VCENTER_WIDE: + case PRESET_WIDE: + set_anchor(MARGIN_BOTTOM, ANCHOR_END, p_keep_margin); + break; + } +} + float Control::get_anchor(Margin p_margin) const { return data.anchor[p_margin]; @@ -2343,6 +2457,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_combined_minimum_size"), &Control::get_combined_minimum_size); ClassDB::bind_method(D_METHOD("set_anchor", "margin", "anchor", "keep_margin"), &Control::set_anchor, DEFVAL(false)); ClassDB::bind_method(D_METHOD("_set_anchor", "margin", "anchor"), &Control::_set_anchor); + ClassDB::bind_method(D_METHOD("set_anchors_preset", "preset", "keep_margin"), &Control::set_anchors_preset, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_anchor", "margin"), &Control::get_anchor); ClassDB::bind_method(D_METHOD("set_margin", "margin", "offset"), &Control::set_margin); ClassDB::bind_method(D_METHOD("set_anchor_and_margin", "margin", "anchor", "offset"), &Control::set_anchor_and_margin); @@ -2541,6 +2656,23 @@ void Control::_bind_methods() { BIND_CONSTANT(CURSOR_HSPLIT); BIND_CONSTANT(CURSOR_HELP); + BIND_CONSTANT(PRESET_TOP_LEFT); + BIND_CONSTANT(PRESET_TOP_RIGHT); + BIND_CONSTANT(PRESET_BOTTOM_LEFT); + BIND_CONSTANT(PRESET_BOTTOM_RIGHT); + BIND_CONSTANT(PRESET_CENTER_LEFT); + BIND_CONSTANT(PRESET_CENTER_TOP); + BIND_CONSTANT(PRESET_CENTER_RIGHT); + BIND_CONSTANT(PRESET_CENTER_BOTTOM); + BIND_CONSTANT(PRESET_CENTER); + BIND_CONSTANT(PRESET_LEFT_WIDE); + BIND_CONSTANT(PRESET_TOP_WIDE); + BIND_CONSTANT(PRESET_RIGHT_WIDE); + BIND_CONSTANT(PRESET_BOTTOM_WIDE); + BIND_CONSTANT(PRESET_VCENTER_WIDE); + BIND_CONSTANT(PRESET_HCENTER_WIDE); + BIND_CONSTANT(PRESET_WIDE); + BIND_CONSTANT(SIZE_EXPAND); BIND_CONSTANT(SIZE_FILL); BIND_CONSTANT(SIZE_EXPAND_FILL); diff --git a/scene/gui/control.h b/scene/gui/control.h index 9c78932cf..8c7f70068 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -103,6 +103,25 @@ public: CURSOR_MAX }; + enum LayoutPreset { + PRESET_TOP_LEFT, + PRESET_TOP_RIGHT, + PRESET_BOTTOM_LEFT, + PRESET_BOTTOM_RIGHT, + PRESET_CENTER_LEFT, + PRESET_CENTER_TOP, + PRESET_CENTER_RIGHT, + PRESET_CENTER_BOTTOM, + PRESET_CENTER, + PRESET_LEFT_WIDE, + PRESET_TOP_WIDE, + PRESET_RIGHT_WIDE, + PRESET_BOTTOM_WIDE, + PRESET_VCENTER_WIDE, + PRESET_HCENTER_WIDE, + PRESET_WIDE + }; + private: struct CComparator { @@ -275,6 +294,7 @@ public: void set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin = false); void set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos); + void set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin = false); float get_anchor(Margin p_margin) const; @@ -426,6 +446,7 @@ public: VARIANT_ENUM_CAST(Control::FocusMode); VARIANT_ENUM_CAST(Control::SizeFlags); VARIANT_ENUM_CAST(Control::CursorShape); +VARIANT_ENUM_CAST(Control::LayoutPreset); VARIANT_ENUM_CAST(Control::MouseFilter); VARIANT_ENUM_CAST(Control::GrowDirection); -- cgit v1.2.3-70-g09d2 From 0041e08f747f5d29ca7fbc65eb86175983aa84af Mon Sep 17 00:00:00 2001 From: Gilles Roudiere Date: Fri, 11 Aug 2017 19:25:26 +0200 Subject: Avoids inverted anchors Add a push_opposite_anchor argument pushing the opposite anchor if needed --- editor/plugins/canvas_item_editor_plugin.cpp | 16 ++++++++-------- scene/gui/control.cpp | 28 ++++++++++++++++++---------- scene/gui/control.h | 4 ++-- 3 files changed, 28 insertions(+), 20 deletions(-) (limited to 'editor/plugins/canvas_item_editor_plugin.cpp') diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3a933690a..64428e950 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1599,23 +1599,23 @@ void CanvasItemEditor::_viewport_gui_input(const Ref &p_event) { switch (drag) { case DRAG_ANCHOR_TOP_LEFT: - control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT))); - control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM))); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT)), false, false); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM)), false, false); continue; break; case DRAG_ANCHOR_TOP_RIGHT: - control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT))); - control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM))); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT)), false, false); + control->set_anchor(MARGIN_TOP, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_BOTTOM)), false, false); continue; break; case DRAG_ANCHOR_BOTTOM_RIGHT: - control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT))); - control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP))); + control->set_anchor(MARGIN_RIGHT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_LEFT)), false, false); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP)), false, false); continue; break; case DRAG_ANCHOR_BOTTOM_LEFT: - control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT))); - control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP))); + control->set_anchor(MARGIN_LEFT, _anchor_snap(anchor.x, NULL, control->get_anchor(MARGIN_RIGHT)), false, false); + control->set_anchor(MARGIN_BOTTOM, _anchor_snap(anchor.y, NULL, control->get_anchor(MARGIN_TOP)), false, false); continue; break; case DRAG_ANCHOR_ALL: diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9e5f22cfa..f68132f4f 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1304,14 +1304,22 @@ float Control::_a2s(float p_val, float p_anchor, float p_range) const { return Math::floor(p_val + (p_anchor * p_range)); } -void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin) { +void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bool p_push_opposite_anchor) { + bool pushed = false; data.anchor[p_margin] = CLAMP(p_anchor, 0.0, 1.0); - if (is_inside_tree()) { - if (!p_keep_margin) { - float pr = _get_parent_range(p_margin); - float s = _a2s(data.margin[p_margin], data.anchor[p_margin], pr); - data.margin[p_margin] = _s2a(s, p_anchor, pr); + + if (((p_margin == MARGIN_LEFT || p_margin == MARGIN_TOP) && data.anchor[p_margin] > data.anchor[(p_margin + 2) % 4]) || + ((p_margin == MARGIN_RIGHT || p_margin == MARGIN_BOTTOM) && data.anchor[p_margin] < data.anchor[(p_margin + 2) % 4])) { + if (p_push_opposite_anchor) { + data.anchor[(p_margin + 2) % 4] = data.anchor[p_margin]; + pushed = true; } else { + data.anchor[p_margin] = data.anchor[(p_margin + 2) % 4]; + } + } + + if (is_inside_tree()) { + if (p_keep_margin) { _size_changed(); } } @@ -1331,9 +1339,9 @@ void Control::_set_anchor(Margin p_margin, float p_anchor) { #endif } -void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos) { +void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos, bool p_push_opposite_anchor) { - set_anchor(p_margin, p_anchor); + set_anchor(p_margin, p_anchor, false, p_push_opposite_anchor); set_margin(p_margin, p_pos); } @@ -2455,12 +2463,12 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("accept_event"), &Control::accept_event); ClassDB::bind_method(D_METHOD("get_minimum_size"), &Control::get_minimum_size); ClassDB::bind_method(D_METHOD("get_combined_minimum_size"), &Control::get_combined_minimum_size); - ClassDB::bind_method(D_METHOD("set_anchor", "margin", "anchor", "keep_margin"), &Control::set_anchor, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("set_anchor", "margin", "anchor", "keep_margin", "push_opposite_anchor"), &Control::set_anchor, DEFVAL(false), DEFVAL(true)); ClassDB::bind_method(D_METHOD("_set_anchor", "margin", "anchor"), &Control::_set_anchor); ClassDB::bind_method(D_METHOD("set_anchors_preset", "preset", "keep_margin"), &Control::set_anchors_preset, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_anchor", "margin"), &Control::get_anchor); ClassDB::bind_method(D_METHOD("set_margin", "margin", "offset"), &Control::set_margin); - ClassDB::bind_method(D_METHOD("set_anchor_and_margin", "margin", "anchor", "offset"), &Control::set_anchor_and_margin); + ClassDB::bind_method(D_METHOD("set_anchor_and_margin", "margin", "anchor", "offset", "push_opposite_anchor"), &Control::set_anchor_and_margin, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_begin", "pos"), &Control::set_begin); ClassDB::bind_method(D_METHOD("set_end", "pos"), &Control::set_end); ClassDB::bind_method(D_METHOD("set_position", "pos"), &Control::set_position); diff --git a/scene/gui/control.h b/scene/gui/control.h index 8c7f70068..60d835044 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -292,8 +292,8 @@ public: /* POSITIONING */ - void set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin = false); - void set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos); + void set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin = false, bool p_push_opposite_anchor = true); + void set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos, bool p_push_opposite_anchor = true); void set_anchors_preset(LayoutPreset p_preset, bool p_keep_margin = false); float get_anchor(Margin p_margin) const; -- cgit v1.2.3-70-g09d2