summaryrefslogtreecommitdiffstats
path: root/editor/plugins/canvas_item_editor_plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins/canvas_item_editor_plugin.cpp')
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp81
1 files changed, 66 insertions, 15 deletions
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 8a9118a03e..5ac5dd6ee6 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1344,22 +1344,33 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
// Drag the pivot (in pivot mode / with V key)
if (drag_type == DRAG_NONE) {
+ bool move_temp_pivot = ((b.is_valid() && b->is_shift_pressed()) || (k.is_valid() && k->is_shift_pressed()));
+
if ((b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::LEFT && tool == TOOL_EDIT_PIVOT) ||
- (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::V && tool == TOOL_SELECT && k->get_modifiers_mask().is_empty())) {
+ (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == Key::V && tool == TOOL_SELECT && (k->get_modifiers_mask().is_empty() || move_temp_pivot))) {
List<CanvasItem *> selection = _get_edited_canvas_items();
// Filters the selection with nodes that allow setting the pivot
drag_selection = List<CanvasItem *>();
for (CanvasItem *ci : selection) {
- if (ci->_edit_use_pivot()) {
+ if (ci->_edit_use_pivot() || move_temp_pivot) {
drag_selection.push_back(ci);
}
}
// Start dragging if we still have nodes
if (drag_selection.size() > 0) {
+ Vector2 event_pos = (b.is_valid()) ? b->get_position() : viewport->get_local_mouse_position();
+
+ if (move_temp_pivot) {
+ drag_type = DRAG_TEMP_PIVOT;
+ temp_pivot = transform.affine_inverse().xform(event_pos);
+ viewport->queue_redraw();
+ return true;
+ }
+
_save_canvas_item_state(drag_selection);
- drag_from = transform.affine_inverse().xform((b.is_valid()) ? b->get_position() : viewport->get_local_mouse_position());
+ drag_from = transform.affine_inverse().xform(event_pos);
Vector2 new_pos;
if (drag_selection.size() == 1) {
new_pos = snap_point(drag_from, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]);
@@ -1416,6 +1427,20 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
return true;
}
}
+
+ if (drag_type == DRAG_TEMP_PIVOT) {
+ if (m.is_valid()) {
+ temp_pivot = transform.affine_inverse().xform(m->get_position());
+ viewport->queue_redraw();
+ return true;
+ }
+
+ if ((b.is_valid() && !b->is_pressed() && b->get_button_index() == MouseButton::LEFT && tool == TOOL_EDIT_PIVOT) ||
+ (k.is_valid() && !k->is_pressed() && k->get_keycode() == Key::V)) {
+ drag_type = DRAG_NONE;
+ return true;
+ }
+ }
return false;
}
@@ -1441,7 +1466,9 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
drag_type = DRAG_ROTATE;
drag_from = transform.affine_inverse().xform(b->get_position());
CanvasItem *ci = drag_selection[0];
- if (ci->_edit_use_pivot()) {
+ if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) {
+ drag_rotation_center = temp_pivot;
+ } else if (ci->_edit_use_pivot()) {
drag_rotation_center = ci->get_global_transform_with_canvas().xform(ci->_edit_get_pivot());
} else {
drag_rotation_center = ci->get_global_transform_with_canvas().get_origin();
@@ -1461,7 +1488,16 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
drag_to = transform.affine_inverse().xform(m->get_position());
//Rotate the opposite way if the canvas item's compounded scale has an uneven number of negative elements
bool opposite = (ci->get_global_transform().get_scale().sign().dot(ci->get_transform().get_scale().sign()) == 0);
- ci->_edit_set_rotation(snap_angle(ci->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), ci->_edit_get_rotation()));
+ real_t prev_rotation = ci->_edit_get_rotation();
+ real_t new_rotation = snap_angle(ci->_edit_get_rotation() + (opposite ? -1 : 1) * (drag_from - drag_rotation_center).angle_to(drag_to - drag_rotation_center), prev_rotation);
+
+ ci->_edit_set_rotation(new_rotation);
+ if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) {
+ Transform2D xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse();
+ Vector2 radius = xform.xform(ci->_edit_get_position()) - temp_pivot;
+ radius = radius.rotated(new_rotation - prev_rotation);
+ ci->_edit_set_position(xform.affine_inverse().xform(temp_pivot + radius));
+ }
viewport->queue_redraw();
}
return true;
@@ -3161,7 +3197,7 @@ void CanvasItemEditor::_draw_ruler_tool() {
} else {
if (grid_snap_active) {
Ref<Texture2D> position_icon = get_editor_theme_icon(SNAME("EditorPosition"));
- viewport->draw_texture(get_editor_theme_icon(SNAME("EditorPosition")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
+ viewport->draw_texture(position_icon, (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
}
}
}
@@ -3583,6 +3619,10 @@ void CanvasItemEditor::_draw_selection() {
get_theme_color(SNAME("accent_color"), EditorStringName(Editor)) * Color(1, 1, 1, 0.6),
Math::round(2 * EDSCALE));
}
+
+ if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) {
+ viewport->draw_texture(pivot_icon, (temp_pivot - view_offset) * zoom - (pivot_icon->get_size() / 2).floor(), get_theme_color(SNAME("accent_color"), SNAME("Editor")));
+ }
}
void CanvasItemEditor::_draw_straight_line(Point2 p_from, Point2 p_to, Color p_color) {
@@ -3931,8 +3971,6 @@ void CanvasItemEditor::_notification(int p_what) {
} break;
case NOTIFICATION_PROCESS: {
- int nb_having_pivot = 0;
-
// Update the viewport if the canvas_item changes
List<CanvasItem *> selection = _get_edited_canvas_items(true);
for (CanvasItem *ci : selection) {
@@ -3972,14 +4010,10 @@ void CanvasItemEditor::_notification(int p_what) {
viewport->queue_redraw();
}
}
-
- if (ci->_edit_use_pivot()) {
- nb_having_pivot++;
- }
}
- // Activate / Deactivate the pivot tool
- pivot_button->set_disabled(nb_having_pivot == 0);
+ // Activate / Deactivate the pivot tool.
+ pivot_button->set_disabled(selection.is_empty());
// Update the viewport if bones changes
for (KeyValue<BoneKey, BoneList> &E : bone_list) {
@@ -4048,6 +4082,11 @@ void CanvasItemEditor::_selection_changed() {
_reset_drag();
}
selected_from_canvas = false;
+
+ if (temp_pivot != Vector2(INFINITY, INFINITY)) {
+ temp_pivot = Vector2(INFINITY, INFINITY);
+ viewport->queue_redraw();
+ }
}
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
@@ -4202,6 +4241,18 @@ void CanvasItemEditor::_button_tool_select(int p_index) {
tool = (Tool)p_index;
+ if (p_index == TOOL_EDIT_PIVOT && Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
+ // Special action that places temporary rotation pivot in the middle of the selection.
+ List<CanvasItem *> selection = _get_edited_canvas_items();
+ if (!selection.is_empty()) {
+ Vector2 center;
+ for (const CanvasItem *ci : selection) {
+ center += ci->_edit_get_position();
+ }
+ temp_pivot = center / selection.size();
+ }
+ }
+
viewport->queue_redraw();
_update_cursor();
}
@@ -5279,7 +5330,7 @@ CanvasItemEditor::CanvasItemEditor() {
main_menu_hbox->add_child(pivot_button);
pivot_button->set_toggle_mode(true);
pivot_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_EDIT_PIVOT));
- pivot_button->set_tooltip_text(TTR("Click to change object's rotation pivot."));
+ pivot_button->set_tooltip_text(TTR("Click to change object's rotation pivot.") + "\n" + TTR("Shift: Set temporary rotation pivot.") + "\n" + TTR("Click this button while holding Shift to put the rotation pivot in the center of the selected nodes."));
pan_button = memnew(Button);
pan_button->set_theme_type_variation("FlatButton");