Browse Source

Added snapping for scaling in 2D editor

MCrafterzz 5 years ago
parent
commit
3a8a7fc31c

+ 54 - 4
editor/plugins/canvas_item_editor_plugin.cpp

@@ -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");

+ 3 - 0
editor/plugins/canvas_item_editor_plugin.h

@@ -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;