Added snapping for scaling in 2D editor

This commit is contained in:
MCrafterzz 2019-10-30 15:18:57 +01:00
parent 9e1be8f8aa
commit 3a8a7fc31c
2 changed files with 57 additions and 4 deletions

View File

@ -70,11 +70,15 @@ class SnapDialog : public ConfirmationDialog {
SpinBox *primary_grid_steps;
SpinBox *rotation_offset;
SpinBox *rotation_step;
SpinBox *scale_step;
public:
SnapDialog() {
const int SPIN_BOX_GRID_RANGE = 16384;
const int SPIN_BOX_ROTATION_RANGE = 360;
const float SPIN_BOX_SCALE_MIN = 0.01f;
const float SPIN_BOX_SCALE_MAX = 100;
Label *label;
VBoxContainer *container;
GridContainer *child_container;
@ -180,9 +184,27 @@ public:
rotation_step->set_suffix("deg");
rotation_step->set_h_size_flags(SIZE_EXPAND_FILL);
child_container->add_child(rotation_step);
container->add_child(memnew(HSeparator));
child_container = memnew(GridContainer);
child_container->set_columns(2);
container->add_child(child_container);
label = memnew(Label);
label->set_text(TTR("Scale Step:"));
child_container->add_child(label);
label->set_h_size_flags(SIZE_EXPAND_FILL);
scale_step = memnew(SpinBox);
scale_step->set_min(SPIN_BOX_SCALE_MIN);
scale_step->set_max(SPIN_BOX_SCALE_MAX);
scale_step->set_allow_greater(true);
scale_step->set_h_size_flags(SIZE_EXPAND_FILL);
scale_step->set_step(0.01f);
child_container->add_child(scale_step);
}
void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step) {
void set_fields(const Point2 p_grid_offset, const Point2 p_grid_step, const int p_primary_grid_steps, const float p_rotation_offset, const float p_rotation_step, const float p_scale_step) {
grid_offset_x->set_value(p_grid_offset.x);
grid_offset_y->set_value(p_grid_offset.y);
grid_step_x->set_value(p_grid_step.x);
@ -190,14 +212,16 @@ public:
primary_grid_steps->set_value(p_primary_grid_steps);
rotation_offset->set_value(p_rotation_offset * (180 / Math_PI));
rotation_step->set_value(p_rotation_step * (180 / Math_PI));
scale_step->set_value(p_scale_step);
}
void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step) {
void get_fields(Point2 &p_grid_offset, Point2 &p_grid_step, int &p_primary_grid_steps, float &p_rotation_offset, float &p_rotation_step, float &p_scale_step) {
p_grid_offset = Point2(grid_offset_x->get_value(), grid_offset_y->get_value());
p_grid_step = Point2(grid_step_x->get_value(), grid_step_y->get_value());
p_primary_grid_steps = int(primary_grid_steps->get_value());
p_rotation_offset = rotation_offset->get_value() / (180 / Math_PI);
p_rotation_step = rotation_step->get_value() / (180 / Math_PI);
p_scale_step = scale_step->get_value();
}
};
@ -919,7 +943,7 @@ void CanvasItemEditor::_commit_canvas_item_state(List<CanvasItem *> p_canvas_ite
}
void CanvasItemEditor::_snap_changed() {
((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
((SnapDialog *)snap_dialog)->get_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
grid_step_multiplier = 0;
viewport->update();
}
@ -1850,6 +1874,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
bool uniform = m->get_shift();
bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
Point2 drag_from_local = simple_xform.xform(drag_from);
Point2 drag_to_local = simple_xform.xform(drag_to);
@ -1880,6 +1905,12 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
}
}
}
if (snap_scale && !is_ctrl) {
scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step;
scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step;
}
canvas_item->call("set_scale", scale);
return true;
}
@ -4349,6 +4380,11 @@ void CanvasItemEditor::_popup_callback(int p_op) {
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_ROTATION);
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
} break;
case SNAP_USE_SCALE: {
snap_scale = !snap_scale;
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
} break;
case SNAP_RELATIVE: {
snap_relative = !snap_relative;
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@ -4361,7 +4397,7 @@ void CanvasItemEditor::_popup_callback(int p_op) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_pixel);
} break;
case SNAP_CONFIGURE: {
((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step);
((SnapDialog *)snap_dialog)->set_fields(grid_offset, grid_step, primary_grid_steps, snap_rotation_offset, snap_rotation_step, snap_scale_step);
snap_dialog->popup_centered(Size2(220, 160) * EDSCALE);
} break;
case SKELETON_SHOW_BONES: {
@ -4912,6 +4948,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["primary_grid_steps"] = primary_grid_steps;
state["snap_rotation_offset"] = snap_rotation_offset;
state["snap_rotation_step"] = snap_rotation_step;
state["snap_scale_step"] = snap_scale_step;
state["smart_snap_active"] = smart_snap_active;
state["grid_snap_active"] = grid_snap_active;
state["snap_node_parent"] = snap_node_parent;
@ -4929,6 +4966,7 @@ Dictionary CanvasItemEditor::get_state() const {
state["show_zoom_control"] = zoom_hb->is_visible();
state["show_edit_locks"] = show_edit_locks;
state["snap_rotation"] = snap_rotation;
state["snap_scale"] = snap_scale;
state["snap_relative"] = snap_relative;
state["snap_pixel"] = snap_pixel;
state["skeleton_show_bones"] = skeleton_show_bones;
@ -4970,6 +5008,10 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_rotation_offset = state["snap_rotation_offset"];
}
if (state.has("snap_scale_step")) {
snap_scale_step = state["snap_scale_step"];
}
if (state.has("smart_snap_active")) {
smart_snap_active = state["smart_snap_active"];
smart_snap_button->set_pressed(smart_snap_active);
@ -5070,6 +5112,12 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) {
snap_config_menu->get_popup()->set_item_checked(idx, snap_rotation);
}
if (state.has("snap_scale")) {
snap_scale = state["snap_scale"];
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_USE_SCALE);
snap_config_menu->get_popup()->set_item_checked(idx, snap_scale);
}
if (state.has("snap_relative")) {
snap_relative = state["snap_relative"];
int idx = snap_config_menu->get_popup()->get_item_index(SNAP_RELATIVE);
@ -5155,6 +5203,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
grid_step_multiplier = 0;
snap_rotation_offset = 0;
snap_rotation_step = 15 / (180 / Math_PI);
snap_scale_step = 0.1f;
smart_snap_active = false;
grid_snap_active = false;
snap_node_parent = true;
@ -5377,6 +5426,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->connect("id_pressed", this, "_popup_callback");
p->set_hide_on_checkable_item_selection(false);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_rotation_snap", TTR("Use Rotation Snap")), SNAP_USE_ROTATION);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_scale_snap", TTR("Use Scale Snap")), SNAP_USE_SCALE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/snap_relative", TTR("Snap Relative")), SNAP_RELATIVE);
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_submenu_item(TTR("Smart Snapping"), "SmartSnapping");

View File

@ -108,6 +108,7 @@ private:
SNAP_USE_GRID,
SNAP_USE_GUIDES,
SNAP_USE_ROTATION,
SNAP_USE_SCALE,
SNAP_RELATIVE,
SNAP_CONFIGURE,
SNAP_USE_PIXEL,
@ -260,6 +261,7 @@ private:
float snap_rotation_step;
float snap_rotation_offset;
float snap_scale_step;
bool smart_snap_active;
bool grid_snap_active;
@ -270,6 +272,7 @@ private:
bool snap_other_nodes;
bool snap_guides;
bool snap_rotation;
bool snap_scale;
bool snap_relative;
bool snap_pixel;
bool skeleton_show_bones;