| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  path_2d_editor_plugin.cpp                                             */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the        */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including    */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
					
						
							|  |  |  | /* the following conditions:                                              */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "path_2d_editor_plugin.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "canvas_item_editor_plugin.h"
 | 
					
						
							| 
									
										
										
										
											2021-06-11 14:51:48 +02:00
										 |  |  | #include "core/io/file_access.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/keyboard.h"
 | 
					
						
							| 
									
										
										
										
											2022-02-12 02:46:22 +01:00
										 |  |  | #include "editor/editor_node.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 14:21:25 +01:00
										 |  |  | #include "editor/editor_settings.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-25 18:06:46 +01:00
										 |  |  | #include "editor/editor_undo_redo_manager.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-15 13:14:55 +01:00
										 |  |  | #include "editor/themes/editor_scale.h"
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | #include "scene/gui/dialogs.h"
 | 
					
						
							| 
									
										
										
										
											2022-11-19 12:45:49 +01:00
										 |  |  | #include "scene/gui/menu_button.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-27 21:07:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void Path2DEditor::_notification(int p_what) { | 
					
						
							|  |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2022-08-29 11:04:31 +02:00
										 |  |  | 		case NOTIFICATION_ENTER_TREE: | 
					
						
							| 
									
										
										
										
											2022-01-28 20:21:50 +03:00
										 |  |  | 		case NOTIFICATION_THEME_CHANGED: { | 
					
						
							| 
									
										
										
										
											2023-08-13 02:33:39 +02:00
										 |  |  | 			curve_edit->set_icon(get_editor_theme_icon(SNAME("CurveEdit"))); | 
					
						
							|  |  |  | 			curve_edit_curve->set_icon(get_editor_theme_icon(SNAME("CurveCurve"))); | 
					
						
							|  |  |  | 			curve_create->set_icon(get_editor_theme_icon(SNAME("CurveCreate"))); | 
					
						
							|  |  |  | 			curve_del->set_icon(get_editor_theme_icon(SNAME("CurveDelete"))); | 
					
						
							|  |  |  | 			curve_close->set_icon(get_editor_theme_icon(SNAME("CurveClose"))); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 			curve_clear_points->set_icon(get_editor_theme_icon(SNAME("Clear"))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void Path2DEditor::_node_removed(Node *p_node) { | 
					
						
							|  |  |  | 	if (p_node == node) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		node = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		hide(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!node) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!node->is_visible_in_tree()) { | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	if (node->get_curve().is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 17:59:19 +02:00
										 |  |  | 	real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 	Ref<InputEventMouseButton> mb = p_event; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	if (mb.is_valid()) { | 
					
						
							|  |  |  | 		Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 10:54:24 +02:00
										 |  |  | 		Vector2 gpoint = mb->get_position(); | 
					
						
							| 
									
										
										
										
											2021-08-14 14:01:57 +05:45
										 |  |  | 		Vector2 cpoint = node->to_local(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position()))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		if (mb->is_pressed() && action == ACTION_NONE) { | 
					
						
							|  |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-13 22:49:20 -05:00
										 |  |  | 			original_mouse_pos = gpoint; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			for (int i = 0; i < curve->get_point_count(); i++) { | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 				real_t dist_to_p = gpoint.distance_to(xform.xform(curve->get_point_position(i))); | 
					
						
							|  |  |  | 				real_t dist_to_p_out = gpoint.distance_to(xform.xform(curve->get_point_position(i) + curve->get_point_out(i))); | 
					
						
							|  |  |  | 				real_t dist_to_p_in = gpoint.distance_to(xform.xform(curve->get_point_position(i) + curve->get_point_in(i))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				// Check for point movement start (for point + in/out controls).
 | 
					
						
							| 
									
										
										
										
											2021-08-13 16:31:57 -05:00
										 |  |  | 				if (mb->get_button_index() == MouseButton::LEFT) { | 
					
						
							| 
									
										
										
										
											2021-04-24 14:33:50 -06:00
										 |  |  | 					if (mode == MODE_EDIT && !mb->is_shift_pressed() && dist_to_p < grab_threshold) { | 
					
						
							| 
									
										
										
										
											2017-05-27 17:56:20 -07:00
										 |  |  | 						// Points can only be moved in edit mode.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						action = ACTION_MOVING_POINT; | 
					
						
							|  |  |  | 						action_point = i; | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 						moving_from = curve->get_point_position(i); | 
					
						
							| 
									
										
										
										
											2017-05-27 17:56:20 -07:00
										 |  |  | 						moving_screen_from = gpoint; | 
					
						
							|  |  |  | 						return true; | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 					} else if (mode == MODE_EDIT || mode == MODE_EDIT_CURVE) { | 
					
						
							|  |  |  | 						// In/out controls can be moved in multiple modes.
 | 
					
						
							|  |  |  | 						if (dist_to_p_out < grab_threshold && i < (curve->get_point_count() - 1)) { | 
					
						
							|  |  |  | 							action = ACTION_MOVING_OUT; | 
					
						
							|  |  |  | 							action_point = i; | 
					
						
							|  |  |  | 							moving_from = curve->get_point_out(i); | 
					
						
							|  |  |  | 							moving_screen_from = gpoint; | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 							orig_in_length = curve->get_point_in(action_point).length(); | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 							return true; | 
					
						
							|  |  |  | 						} else if (dist_to_p_in < grab_threshold && i > 0) { | 
					
						
							|  |  |  | 							action = ACTION_MOVING_IN; | 
					
						
							|  |  |  | 							action_point = i; | 
					
						
							|  |  |  | 							moving_from = curve->get_point_in(i); | 
					
						
							|  |  |  | 							moving_screen_from = gpoint; | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 							orig_out_length = curve->get_point_out(action_point).length(); | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 							return true; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2016-10-26 23:18:18 -07:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				// Check for point deletion.
 | 
					
						
							| 
									
										
										
										
											2022-12-23 23:53:16 +01:00
										 |  |  | 				EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 				if ((mb->get_button_index() == MouseButton::RIGHT && (mode == MODE_EDIT || mode == MODE_CREATE)) || (mb->get_button_index() == MouseButton::LEFT && mode == MODE_DELETE)) { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 					if (dist_to_p < grab_threshold) { | 
					
						
							|  |  |  | 						undo_redo->create_action(TTR("Remove Point from Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(curve.ptr(), "remove_point", i); | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 						undo_redo->add_undo_method(curve.ptr(), "add_point", curve->get_point_position(i), curve->get_point_in(i), curve->get_point_out(i), i); | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 						undo_redo->commit_action(); | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} else if (dist_to_p_out < grab_threshold) { | 
					
						
							|  |  |  | 						undo_redo->create_action(TTR("Remove Out-Control from Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(curve.ptr(), "set_point_out", i, Vector2()); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(curve.ptr(), "set_point_out", i, curve->get_point_out(i)); | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 						undo_redo->commit_action(); | 
					
						
							|  |  |  | 						return true; | 
					
						
							|  |  |  | 					} else if (dist_to_p_in < grab_threshold) { | 
					
						
							|  |  |  | 						undo_redo->create_action(TTR("Remove In-Control from Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(curve.ptr(), "set_point_in", i, Vector2()); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(curve.ptr(), "set_point_in", i, curve->get_point_in(i)); | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 						undo_redo->commit_action(); | 
					
						
							|  |  |  | 						return true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 		if (action != ACTION_NONE && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { | 
					
						
							|  |  |  | 			_cancel_current_action(); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 		// Check for point creation.
 | 
					
						
							| 
									
										
										
										
											2022-09-02 12:37:48 +03:00
										 |  |  | 		if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_or_control_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 			curve->add_point(cpoint); | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 			moving_from = cpoint; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 			action = ACTION_MOVING_NEW_POINT; | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			action_point = curve->get_point_count() - 1; | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 			moving_from = curve->get_point_position(action_point); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			moving_screen_from = gpoint; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 			canvas_item_editor->update_viewport(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 		// Check for segment split.
 | 
					
						
							| 
									
										
										
										
											2021-08-13 16:31:57 -05:00
										 |  |  | 		if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && mode == MODE_EDIT && on_edge) { | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			Vector2 gpoint2 = mb->get_position(); | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int insertion_point = -1; | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			float mbLength = curve->get_closest_offset(xform.affine_inverse().xform(gpoint2)); | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 			int len = curve->get_point_count(); | 
					
						
							|  |  |  | 			for (int i = 0; i < len - 1; i++) { | 
					
						
							|  |  |  | 				float compareLength = curve->get_closest_offset(curve->get_point_position(i + 1)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (mbLength >= curve->get_closest_offset(curve->get_point_position(i)) && mbLength <= compareLength) { | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 					insertion_point = i; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (insertion_point == -1) { | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 				insertion_point = curve->get_point_count() - 2; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 			const Vector2 new_point = xform.affine_inverse().xform(gpoint2); | 
					
						
							|  |  |  | 			curve->add_point(new_point, Vector2(0, 0), Vector2(0, 0), insertion_point + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 19:29:23 +02:00
										 |  |  | 			action = ACTION_MOVING_NEW_POINT_FROM_SPLIT; | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 			action_point = insertion_point + 1; | 
					
						
							|  |  |  | 			moving_from = curve->get_point_position(action_point); | 
					
						
							| 
									
										
										
										
											2019-02-12 21:10:08 +01:00
										 |  |  | 			moving_screen_from = gpoint2; | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			canvas_item_editor->update_viewport(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			on_edge = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 		// Check for point movement completion.
 | 
					
						
							| 
									
										
										
										
											2021-08-13 16:31:57 -05:00
										 |  |  | 		if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && action != ACTION_NONE) { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-23 23:53:16 +01:00
										 |  |  | 			EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); | 
					
						
							|  |  |  | 			switch (action) { | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				case ACTION_NONE: | 
					
						
							|  |  |  | 					// N/A, handled in above condition.
 | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 				case ACTION_MOVING_POINT: | 
					
						
							| 
									
										
										
										
											2024-01-13 22:49:20 -05:00
										 |  |  | 					if (original_mouse_pos != gpoint) { | 
					
						
							| 
									
										
										
										
											2024-03-25 15:28:24 +08:00
										 |  |  | 						undo_redo->create_action(TTR("Move Point in Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(curve.ptr(), "set_point_position", action_point, moving_from); | 
					
						
							| 
									
										
										
										
											2024-01-13 22:49:20 -05:00
										 |  |  | 						undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->commit_action(false); | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2024-03-25 15:28:24 +08:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case ACTION_MOVING_NEW_POINT: { | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 					undo_redo->create_action(TTR("Add Point to Curve")); | 
					
						
							|  |  |  | 					undo_redo->add_do_method(curve.ptr(), "add_point", cpoint); | 
					
						
							| 
									
										
										
										
											2024-03-25 15:28:24 +08:00
										 |  |  | 					undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint); | 
					
						
							|  |  |  | 					undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 					undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count() - 1); | 
					
						
							|  |  |  | 					undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2024-03-25 15:28:24 +08:00
										 |  |  | 					undo_redo->commit_action(false); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 19:29:23 +02:00
										 |  |  | 				case ACTION_MOVING_NEW_POINT_FROM_SPLIT: { | 
					
						
							|  |  |  | 					undo_redo->create_action(TTR("Split Curve")); | 
					
						
							|  |  |  | 					undo_redo->add_do_method(curve.ptr(), "add_point", Vector2(), Vector2(), Vector2(), action_point); | 
					
						
							|  |  |  | 					undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint); | 
					
						
							|  |  |  | 					undo_redo->add_undo_method(curve.ptr(), "remove_point", action_point); | 
					
						
							|  |  |  | 					undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 					undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 					undo_redo->commit_action(false); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				case ACTION_MOVING_IN: { | 
					
						
							| 
									
										
										
										
											2024-01-13 22:49:20 -05:00
										 |  |  | 					if (original_mouse_pos != gpoint) { | 
					
						
							|  |  |  | 						undo_redo->create_action(TTR("Move In-Control in Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, new_pos); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, moving_from); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (mirror_handle_angle) { | 
					
						
							|  |  |  | 							undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length)); | 
					
						
							|  |  |  | 							undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length)); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				case ACTION_MOVING_OUT: { | 
					
						
							| 
									
										
										
										
											2024-01-13 22:49:20 -05:00
										 |  |  | 					if (original_mouse_pos != gpoint) { | 
					
						
							|  |  |  | 						undo_redo->create_action(TTR("Move Out-Control in Curve")); | 
					
						
							|  |  |  | 						undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, new_pos); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, moving_from); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (mirror_handle_angle) { | 
					
						
							|  |  |  | 							undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length)); | 
					
						
							|  |  |  | 							undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_in_length)); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 						undo_redo->commit_action(); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			action = ACTION_NONE; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	Ref<InputEventMouseMotion> mm = p_event; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 	if (mm.is_valid()) { | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 		if (action == ACTION_NONE && mode == MODE_EDIT) { | 
					
						
							|  |  |  | 			// Handle Edge Follow
 | 
					
						
							|  |  |  | 			bool old_edge = on_edge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); | 
					
						
							|  |  |  | 			Vector2 gpoint = mm->get_position(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							| 
									
										
										
										
											2024-07-26 11:52:26 +02:00
										 |  |  | 			if (curve.is_null()) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (curve->get_point_count() < 2) { | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// Find edge
 | 
					
						
							|  |  |  | 			edge_point = xform.xform(curve->get_closest_point(xform.affine_inverse().xform(mm->get_position()))); | 
					
						
							|  |  |  | 			on_edge = false; | 
					
						
							|  |  |  | 			if (edge_point.distance_to(gpoint) <= grab_threshold) { | 
					
						
							|  |  |  | 				on_edge = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// However, if near a control point or its in-out handles then not on edge
 | 
					
						
							|  |  |  | 			int len = curve->get_point_count(); | 
					
						
							|  |  |  | 			for (int i = 0; i < len; i++) { | 
					
						
							|  |  |  | 				Vector2 pp = curve->get_point_position(i); | 
					
						
							|  |  |  | 				Vector2 p = xform.xform(pp); | 
					
						
							|  |  |  | 				if (p.distance_to(gpoint) <= grab_threshold) { | 
					
						
							|  |  |  | 					on_edge = false; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				p = xform.xform(pp + curve->get_point_in(i)); | 
					
						
							|  |  |  | 				if (p.distance_to(gpoint) <= grab_threshold) { | 
					
						
							|  |  |  | 					on_edge = false; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				p = xform.xform(pp + curve->get_point_out(i)); | 
					
						
							|  |  |  | 				if (p.distance_to(gpoint) <= grab_threshold) { | 
					
						
							|  |  |  | 					on_edge = false; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (on_edge || old_edge != on_edge) { | 
					
						
							|  |  |  | 				canvas_item_editor->update_viewport(); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 		if (action != ACTION_NONE) { | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 			// Handle point/control movement.
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); | 
					
						
							| 
									
										
										
										
											2017-06-03 10:54:24 +02:00
										 |  |  | 			Vector2 gpoint = mm->get_position(); | 
					
						
							| 
									
										
										
										
											2017-10-15 22:33:25 +02:00
										 |  |  | 			Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position()))); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Ref<Curve2D> curve = node->get_curve(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			switch (action) { | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				case ACTION_NONE: | 
					
						
							|  |  |  | 					// N/A, handled in above condition.
 | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-26 22:56:14 +01:00
										 |  |  | 				case ACTION_MOVING_POINT: | 
					
						
							| 
									
										
										
										
											2024-08-28 19:29:23 +02:00
										 |  |  | 				case ACTION_MOVING_NEW_POINT: | 
					
						
							|  |  |  | 				case ACTION_MOVING_NEW_POINT_FROM_SPLIT: { | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 					curve->set_point_position(action_point, cpoint); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				case ACTION_MOVING_IN: { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 					curve->set_point_in(action_point, new_pos); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (mirror_handle_angle) { | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 						curve->set_point_out(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-21 14:10:10 -07:00
										 |  |  | 				case ACTION_MOVING_OUT: { | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 					curve->set_point_out(action_point, new_pos); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					if (mirror_handle_angle) { | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 						curve->set_point_in(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 			canvas_item_editor->update_viewport(); | 
					
						
							| 
									
										
										
										
											2017-05-20 12:38:03 -03:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-10-15 22:33:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-18 20:00:07 +02:00
										 |  |  | void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	if (!node || !node->is_visible_in_tree() || node->get_curve().is_null()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 	Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-13 02:33:39 +02:00
										 |  |  | 	const Ref<Texture2D> path_sharp_handle = get_editor_theme_icon(SNAME("EditorPathSharpHandle")); | 
					
						
							|  |  |  | 	const Ref<Texture2D> path_smooth_handle = get_editor_theme_icon(SNAME("EditorPathSmoothHandle")); | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 	// Both handle icons must be of the same size
 | 
					
						
							|  |  |  | 	const Size2 handle_size = path_sharp_handle->get_size(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-13 02:33:39 +02:00
										 |  |  | 	const Ref<Texture2D> curve_handle = get_editor_theme_icon(SNAME("EditorCurveHandle")); | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 	const Size2 curve_handle_size = curve_handle->get_size(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Ref<Curve2D> curve = node->get_curve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int len = curve->get_point_count(); | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 	Control *vpc = canvas_item_editor->get_viewport_control(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	for (int i = 0; i < len; i++) { | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 		Vector2 point = xform.xform(curve->get_point_position(i)); | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 		// Determines the point icon to be used
 | 
					
						
							|  |  |  | 		bool smooth = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (i < len - 1) { | 
					
						
							| 
									
										
										
										
											2024-05-07 10:05:42 +02:00
										 |  |  | 			Vector2 point_out = xform.xform(curve->get_point_position(i) + curve->get_point_out(i)); | 
					
						
							|  |  |  | 			if (point != point_out) { | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 				smooth = true; | 
					
						
							|  |  |  | 				// Draw the line with a dark and light color to be visible on all backgrounds
 | 
					
						
							| 
									
										
										
										
											2024-05-07 10:05:42 +02:00
										 |  |  | 				vpc->draw_line(point, point_out, Color(0, 0, 0, 0.5), Math::round(EDSCALE)); | 
					
						
							|  |  |  | 				vpc->draw_line(point, point_out, Color(1, 1, 1, 0.5), Math::round(EDSCALE)); | 
					
						
							|  |  |  | 				vpc->draw_texture_rect(curve_handle, Rect2(point_out - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75)); | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (i > 0) { | 
					
						
							| 
									
										
										
										
											2024-05-07 10:05:42 +02:00
										 |  |  | 			Vector2 point_in = xform.xform(curve->get_point_position(i) + curve->get_point_in(i)); | 
					
						
							|  |  |  | 			if (point != point_in) { | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 				smooth = true; | 
					
						
							|  |  |  | 				// Draw the line with a dark and light color to be visible on all backgrounds
 | 
					
						
							| 
									
										
										
										
											2024-05-07 10:05:42 +02:00
										 |  |  | 				vpc->draw_line(point, point_in, Color(0, 0, 0, 0.5), Math::round(EDSCALE)); | 
					
						
							|  |  |  | 				vpc->draw_line(point, point_in, Color(1, 1, 1, 0.5), Math::round(EDSCALE)); | 
					
						
							|  |  |  | 				vpc->draw_texture_rect(curve_handle, Rect2(point_in - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75)); | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-08-18 22:18:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		vpc->draw_texture_rect( | 
					
						
							|  |  |  | 				smooth ? path_smooth_handle : path_sharp_handle, | 
					
						
							|  |  |  | 				Rect2(point - handle_size * 0.5, handle_size), | 
					
						
							|  |  |  | 				false); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (on_edge) { | 
					
						
							| 
									
										
										
										
											2023-08-13 02:33:39 +02:00
										 |  |  | 		Ref<Texture2D> add_handle = get_editor_theme_icon(SNAME("EditorHandleAdd")); | 
					
						
							| 
									
										
										
										
											2018-12-01 14:45:54 -06:00
										 |  |  | 		p_overlay->draw_texture(add_handle, edge_point - add_handle->get_size() * 0.5); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | void Path2DEditor::_node_visibility_changed() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!node) { | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 	canvas_item_editor->update_viewport(); | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | void Path2DEditor::edit(Node *p_path2d) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (!canvas_item_editor) { | 
					
						
							|  |  |  | 		canvas_item_editor = CanvasItemEditor::get_singleton(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 	if (action != ACTION_NONE) { | 
					
						
							|  |  |  | 		_cancel_current_action(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 	if (p_path2d) { | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 		node = Object::cast_to<Path2D>(p_path2d); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 16:56:03 +02:00
										 |  |  | 		if (!node->is_connected(SceneStringName(visibility_changed), callable_mp(this, &Path2DEditor::_node_visibility_changed))) { | 
					
						
							|  |  |  | 			node->connect(SceneStringName(visibility_changed), callable_mp(this, &Path2DEditor::_node_visibility_changed)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 		// The node may have been deleted at this point.
 | 
					
						
							| 
									
										
										
										
											2024-05-13 16:56:03 +02:00
										 |  |  | 		if (node && node->is_connected(SceneStringName(visibility_changed), callable_mp(this, &Path2DEditor::_node_visibility_changed))) { | 
					
						
							|  |  |  | 			node->disconnect(SceneStringName(visibility_changed), callable_mp(this, &Path2DEditor::_node_visibility_changed)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		node = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditor::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-02-13 12:47:24 +01:00
										 |  |  | 	//ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option);
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("_clear_curve_points"), &Path2DEditor::_clear_curve_points); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_restore_curve_points"), &Path2DEditor::_restore_curve_points); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditor::_mode_selected(int p_mode) { | 
					
						
							|  |  |  | 	if (p_mode == MODE_CREATE) { | 
					
						
							|  |  |  | 		curve_create->set_pressed(true); | 
					
						
							|  |  |  | 		curve_edit->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit_curve->set_pressed(false); | 
					
						
							|  |  |  | 		curve_del->set_pressed(false); | 
					
						
							|  |  |  | 	} else if (p_mode == MODE_EDIT) { | 
					
						
							|  |  |  | 		curve_create->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit->set_pressed(true); | 
					
						
							|  |  |  | 		curve_edit_curve->set_pressed(false); | 
					
						
							|  |  |  | 		curve_del->set_pressed(false); | 
					
						
							|  |  |  | 	} else if (p_mode == MODE_EDIT_CURVE) { | 
					
						
							|  |  |  | 		curve_create->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit_curve->set_pressed(true); | 
					
						
							|  |  |  | 		curve_del->set_pressed(false); | 
					
						
							|  |  |  | 	} else if (p_mode == MODE_DELETE) { | 
					
						
							|  |  |  | 		curve_create->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit->set_pressed(false); | 
					
						
							|  |  |  | 		curve_edit_curve->set_pressed(false); | 
					
						
							|  |  |  | 		curve_del->set_pressed(true); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	} else if (p_mode == MODE_CLOSE) { | 
					
						
							|  |  |  | 		if (node->get_curve().is_null()) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (node->get_curve()->get_point_count() < 3) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 		Vector2 begin = node->get_curve()->get_point_position(0); | 
					
						
							|  |  |  | 		Vector2 end = node->get_curve()->get_point_position(node->get_curve()->get_point_count() - 1); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-16 13:19:55 -04:00
										 |  |  | 		if (begin.is_equal_approx(end)) { | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-12-23 23:53:16 +01:00
										 |  |  | 		EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		undo_redo->create_action(TTR("Close the Curve")); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		undo_redo->add_do_method(node->get_curve().ptr(), "add_point", begin); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(node->get_curve().ptr(), "remove_point", node->get_curve()->get_point_count()); | 
					
						
							| 
									
										
										
										
											2018-10-18 14:06:57 +02:00
										 |  |  | 		undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	} else if (p_mode == MODE_CLEAR_POINTS) { | 
					
						
							|  |  |  | 		if (node->get_curve().is_null()) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (node->get_curve()->get_point_count() == 0) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); | 
					
						
							|  |  |  | 		PackedVector2Array points = node->get_curve()->get_points().duplicate(); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 		undo_redo->create_action(TTR("Clear Curve Points"), UndoRedo::MERGE_DISABLE, node); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(this, "_clear_curve_points", node); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(this, "_restore_curve_points", node, points); | 
					
						
							|  |  |  | 		undo_redo->add_do_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 		undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); | 
					
						
							|  |  |  | 		undo_redo->commit_action(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	mode = Mode(p_mode); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | void Path2DEditor::_handle_option_pressed(int p_option) { | 
					
						
							|  |  |  | 	PopupMenu *pm; | 
					
						
							|  |  |  | 	pm = handle_menu->get_popup(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (p_option) { | 
					
						
							|  |  |  | 		case HANDLE_OPTION_ANGLE: { | 
					
						
							|  |  |  | 			bool is_checked = pm->is_item_checked(HANDLE_OPTION_ANGLE); | 
					
						
							|  |  |  | 			mirror_handle_angle = !is_checked; | 
					
						
							|  |  |  | 			pm->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle); | 
					
						
							|  |  |  | 			pm->set_item_disabled(HANDLE_OPTION_LENGTH, !mirror_handle_angle); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case HANDLE_OPTION_LENGTH: { | 
					
						
							|  |  |  | 			bool is_checked = pm->is_item_checked(HANDLE_OPTION_LENGTH); | 
					
						
							|  |  |  | 			mirror_handle_length = !is_checked; | 
					
						
							|  |  |  | 			pm->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | void Path2DEditor::_cancel_current_action() { | 
					
						
							|  |  |  | 	ERR_FAIL_NULL(node); | 
					
						
							|  |  |  | 	Ref<Curve2D> curve = node->get_curve(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(curve.is_null()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (action) { | 
					
						
							|  |  |  | 		case ACTION_MOVING_POINT: { | 
					
						
							|  |  |  | 			curve->set_point_position(action_point, moving_from); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case ACTION_MOVING_NEW_POINT: { | 
					
						
							|  |  |  | 			curve->remove_point(curve->get_point_count() - 1); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 19:29:23 +02:00
										 |  |  | 		case ACTION_MOVING_NEW_POINT_FROM_SPLIT: { | 
					
						
							|  |  |  | 			curve->remove_point(action_point); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-12 15:22:50 +02:00
										 |  |  | 		case ACTION_MOVING_IN: { | 
					
						
							|  |  |  | 			curve->set_point_in(action_point, moving_from); | 
					
						
							|  |  |  | 			curve->set_point_out(action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length)); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case ACTION_MOVING_OUT: { | 
					
						
							|  |  |  | 			curve->set_point_out(action_point, moving_from); | 
					
						
							|  |  |  | 			curve->set_point_in(action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_in_length)); | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: { | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	canvas_item_editor->update_viewport(); | 
					
						
							|  |  |  | 	action = ACTION_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | void Path2DEditor::_confirm_clear_points() { | 
					
						
							|  |  |  | 	if (!node || node->get_curve().is_null()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (node->get_curve()->get_point_count() == 0) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	clear_points_dialog->reset_size(); | 
					
						
							|  |  |  | 	clear_points_dialog->popup_centered(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditor::_clear_curve_points(Path2D *p_path2d) { | 
					
						
							|  |  |  | 	if (!p_path2d || p_path2d->get_curve().is_null()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Ref<Curve2D> curve = p_path2d->get_curve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (curve->get_point_count() == 0) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	curve->clear_points(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (node == p_path2d) { | 
					
						
							|  |  |  | 		_mode_selected(MODE_CREATE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditor::_restore_curve_points(Path2D *p_path2d, const PackedVector2Array &p_points) { | 
					
						
							|  |  |  | 	if (!p_path2d || p_path2d->get_curve().is_null()) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	Ref<Curve2D> curve = p_path2d->get_curve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (curve->get_point_count() > 0) { | 
					
						
							|  |  |  | 		curve->clear_points(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (int i = 0; i < p_points.size(); i += 3) { | 
					
						
							|  |  |  | 		curve->add_point(p_points[i + 2], p_points[i], p_points[i + 1]); // The Curve2D::points pattern is [point_in, point_out, point_position].
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (node == p_path2d) { | 
					
						
							|  |  |  | 		_mode_selected(MODE_EDIT); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 10:36:51 +01:00
										 |  |  | Path2DEditor::Path2DEditor() { | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  | 	curve_edit = memnew(Button); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	curve_edit->set_theme_type_variation("FlatButton"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_edit->set_toggle_mode(true); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	curve_edit->set_pressed(true); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_edit->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2022-09-02 12:37:48 +03:00
										 |  |  | 	curve_edit->set_tooltip_text(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD_OR_CTRL) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_edit->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT)); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(curve_edit); | 
					
						
							| 
									
										
										
										
											2022-01-28 20:21:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  | 	curve_edit_curve = memnew(Button); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	curve_edit_curve->set_theme_type_variation("FlatButton"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_edit_curve->set_toggle_mode(true); | 
					
						
							|  |  |  | 	curve_edit_curve->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2022-08-25 12:42:17 +02:00
										 |  |  | 	curve_edit_curve->set_tooltip_text(TTR("Select Control Points (Shift+Drag)")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_edit_curve->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_EDIT_CURVE)); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(curve_edit_curve); | 
					
						
							| 
									
										
										
										
											2022-01-28 20:21:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  | 	curve_create = memnew(Button); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	curve_create->set_theme_type_variation("FlatButton"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_create->set_toggle_mode(true); | 
					
						
							|  |  |  | 	curve_create->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	curve_create->set_tooltip_text(TTR("Add Point (in empty space)") + "\n" + TTR("Right Click: Delete Point")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_create->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_CREATE)); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(curve_create); | 
					
						
							| 
									
										
										
										
											2022-01-28 20:21:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  | 	curve_del = memnew(Button); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	curve_del->set_theme_type_variation("FlatButton"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_del->set_toggle_mode(true); | 
					
						
							|  |  |  | 	curve_del->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2022-08-25 12:42:17 +02:00
										 |  |  | 	curve_del->set_tooltip_text(TTR("Delete Point")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_del->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_DELETE)); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(curve_del); | 
					
						
							| 
									
										
										
										
											2022-01-28 20:21:50 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-19 20:49:04 +02:00
										 |  |  | 	curve_close = memnew(Button); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	curve_close->set_theme_type_variation("FlatButton"); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 	curve_close->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							| 
									
										
										
										
											2022-08-25 12:42:17 +02:00
										 |  |  | 	curve_close->set_tooltip_text(TTR("Close Curve")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_close->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_CLOSE)); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(curve_close); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	curve_clear_points = memnew(Button); | 
					
						
							|  |  |  | 	curve_clear_points->set_theme_type_variation("FlatButton"); | 
					
						
							|  |  |  | 	curve_clear_points->set_focus_mode(Control::FOCUS_NONE); | 
					
						
							|  |  |  | 	curve_clear_points->set_tooltip_text(TTR("Clear Points")); | 
					
						
							| 
									
										
										
										
											2024-05-14 09:40:21 +02:00
										 |  |  | 	curve_clear_points->connect(SceneStringName(pressed), callable_mp(this, &Path2DEditor::_confirm_clear_points)); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	add_child(curve_clear_points); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clear_points_dialog = memnew(ConfirmationDialog); | 
					
						
							|  |  |  | 	clear_points_dialog->set_title(TTR("Please Confirm...")); | 
					
						
							|  |  |  | 	clear_points_dialog->set_text(TTR("Remove all curve points?")); | 
					
						
							| 
									
										
										
										
											2024-05-14 14:28:18 +02:00
										 |  |  | 	clear_points_dialog->connect(SceneStringName(confirmed), callable_mp(this, &Path2DEditor::_mode_selected).bind(MODE_CLEAR_POINTS)); | 
					
						
							| 
									
										
										
										
											2023-09-05 01:22:01 -03:00
										 |  |  | 	add_child(clear_points_dialog); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 	PopupMenu *menu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	handle_menu = memnew(MenuButton); | 
					
						
							| 
									
										
										
										
											2023-09-19 18:03:10 +02:00
										 |  |  | 	handle_menu->set_flat(false); | 
					
						
							|  |  |  | 	handle_menu->set_theme_type_variation("FlatMenuButton"); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 	handle_menu->set_text(TTR("Options")); | 
					
						
							| 
									
										
										
										
											2023-09-11 23:50:10 +02:00
										 |  |  | 	add_child(handle_menu); | 
					
						
							| 
									
										
										
										
											2018-05-01 11:13:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	menu = handle_menu->get_popup(); | 
					
						
							|  |  |  | 	menu->add_check_item(TTR("Mirror Handle Angles")); | 
					
						
							|  |  |  | 	menu->set_item_checked(HANDLE_OPTION_ANGLE, mirror_handle_angle); | 
					
						
							|  |  |  | 	menu->add_check_item(TTR("Mirror Handle Lengths")); | 
					
						
							|  |  |  | 	menu->set_item_checked(HANDLE_OPTION_LENGTH, mirror_handle_length); | 
					
						
							| 
									
										
										
										
											2024-05-14 14:13:31 +02:00
										 |  |  | 	menu->connect(SceneStringName(id_pressed), callable_mp(this, &Path2DEditor::_handle_option_pressed)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditorPlugin::edit(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 	path2d_editor->edit(Object::cast_to<Node>(p_object)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Path2DEditorPlugin::handles(Object *p_object) const { | 
					
						
							| 
									
										
										
										
											2017-01-02 23:03:46 -03:00
										 |  |  | 	return p_object->is_class("Path2D"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Path2DEditorPlugin::make_visible(bool p_visible) { | 
					
						
							|  |  |  | 	if (p_visible) { | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 		path2d_editor->show(); | 
					
						
							| 
									
										
										
										
											2014-07-06 11:49:27 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 		path2d_editor->hide(); | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		path2d_editor->edit(nullptr); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 10:36:51 +01:00
										 |  |  | Path2DEditorPlugin::Path2DEditorPlugin() { | 
					
						
							|  |  |  | 	path2d_editor = memnew(Path2DEditor); | 
					
						
							| 
									
										
										
										
											2014-04-03 16:19:06 +08:00
										 |  |  | 	CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor); | 
					
						
							| 
									
										
										
										
											2014-04-02 23:00:53 +08:00
										 |  |  | 	path2d_editor->hide(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Path2DEditorPlugin::~Path2DEditorPlugin() { | 
					
						
							|  |  |  | } |