@@ -43,36 +43,196 @@ void Camera2DEditor::edit(Camera2D *p_camera) {
4343 if (p_camera == selected_camera) {
4444 return ;
4545 }
46+ const Callable update_overlays = callable_mp (plugin, &EditorPlugin::update_overlays);
47+
48+ if (selected_camera) {
49+ selected_camera->disconnect (SceneStringName (draw), update_overlays);
50+ if (drag_type != Drag::NONE) {
51+ selected_camera->set_limit_rect (drag_revert);
52+ }
53+ drag_type = Drag::NONE;
54+ hover_type = Drag::NONE;
55+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override (CURSOR_ARROW);
56+ }
4657 selected_camera = p_camera;
58+
59+ if (selected_camera) {
60+ selected_camera->connect (SceneStringName (draw), update_overlays);
61+ }
62+ plugin->update_overlays ();
63+ }
64+
65+ bool Camera2DEditor::forward_canvas_gui_input (const Ref<InputEvent> &p_event) {
66+ if (!selected_camera || !selected_camera->is_limit_enabled ()) {
67+ return false ;
68+ }
69+
70+ Ref<InputEventMouseButton> mb = p_event;
71+ if (mb.is_valid ()) {
72+ if (mb->get_button_index () == MouseButton::LEFT) {
73+ if (mb->is_pressed ()) {
74+ if (hover_type != Drag::NONE) {
75+ Vector2 pos = CanvasItemEditor::get_singleton ()->get_canvas_transform ().affine_inverse ().xform (mb->get_position ());
76+ const Rect2 limit_rect = selected_camera->get_limit_rect ();
77+
78+ drag_type = hover_type;
79+ drag_revert = selected_camera->get_limit_rect ();
80+ center_drag_point = pos - limit_rect.position ;
81+ return true ;
82+ }
83+ } else if (drag_type != Drag::NONE) {
84+ EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
85+ ur->create_action (TTR (" Edit Camera2D Limits" ));
86+ ur->add_do_method (selected_camera, " _set_limit_rect" , selected_camera->get_limit_rect ());
87+ ur->add_do_method (this , " _update_overlays_if_needed" , selected_camera);
88+ ur->add_undo_method (selected_camera, " _set_limit_rect" , drag_revert);
89+ ur->add_undo_method (this , " _update_overlays_if_needed" , selected_camera);
90+ ur->commit_action (false );
91+
92+ drag_type = Drag::NONE;
93+ return true ;
94+ }
95+ } else if (drag_type != Drag::NONE && mb->get_button_index () == MouseButton::RIGHT && mb->is_pressed ()) {
96+ selected_camera->set_limit_rect (drag_revert);
97+ drag_type = Drag::NONE;
98+ plugin->update_overlays ();
99+ _update_hover (mb->get_position ());
100+ return true ;
101+ }
102+ return false ;
103+ }
104+
105+ Ref<InputEventMouseMotion> mm = p_event;
106+ if (mm.is_valid ()) {
107+ Vector2 pos = mm->get_position ();
108+ if (drag_type == Drag::NONE) {
109+ _update_hover (pos);
110+ return false ;
111+ }
112+
113+ pos = CanvasItemEditor::get_singleton ()->get_canvas_transform ().affine_inverse ().xform (pos);
114+ pos = CanvasItemEditor::get_singleton ()->snap_point (pos);
115+
116+ switch (drag_type) {
117+ case Drag::LEFT: {
118+ selected_camera->set_limit (SIDE_LEFT, MIN (selected_camera->get_limit (SIDE_RIGHT), pos.x ));
119+ plugin->update_overlays ();
120+ } break ;
121+
122+ case Drag::RIGHT: {
123+ selected_camera->set_limit (SIDE_RIGHT, MAX (selected_camera->get_limit (SIDE_LEFT), pos.x ));
124+ plugin->update_overlays ();
125+ } break ;
126+
127+ case Drag::TOP: {
128+ selected_camera->set_limit (SIDE_TOP, MIN (selected_camera->get_limit (SIDE_BOTTOM), pos.y ));
129+ plugin->update_overlays ();
130+ } break ;
131+
132+ case Drag::BOTTOM: {
133+ selected_camera->set_limit (SIDE_BOTTOM, MAX (selected_camera->get_limit (SIDE_TOP), pos.y ));
134+ plugin->update_overlays ();
135+ } break ;
136+
137+ case Drag::CENTER: {
138+ Rect2 target_rect = selected_camera->get_limit_rect ();
139+ target_rect.position = pos - center_drag_point;
140+ selected_camera->set_limit_rect (target_rect);
141+ plugin->update_overlays ();
142+ } break ;
143+
144+ case Drag::NONE: {
145+ } break ;
146+ }
147+ return true ;
148+ }
149+
150+ return false ;
151+ }
152+
153+ void Camera2DEditor::forward_canvas_draw_over_viewport (Control *p_overlay) {
154+ if (!selected_camera || !selected_camera->is_limit_enabled ()) {
155+ return ;
156+ }
157+ Rect2 limit_rect = selected_camera->get_limit_rect ();
158+ limit_rect = CanvasItemEditor::get_singleton ()->get_canvas_transform ().xform (limit_rect);
159+ p_overlay->draw_rect (limit_rect, Color (1 , 1 , 0.25 , 0.63 ), false , 3 );
47160}
48161
49162void Camera2DEditor::_menu_option (int p_option) {
50163 switch (p_option) {
51164 case MENU_SNAP_LIMITS_TO_VIEWPORT: {
52165 EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
53- Rect2 prev_rect = selected_camera->get_limit_rect ();
54- ur->create_action (TTR (" Snap the Limits to the Viewport" ), UndoRedo::MERGE_DISABLE, selected_camera);
55- ur->add_do_method (this , " _snap_limits_to_viewport" );
56- ur->add_do_reference (selected_camera);
57- ur->add_undo_method (this , " _undo_snap_limits_to_viewport" , prev_rect);
166+ ur->create_action (TTR (" Snap Camera2D Limits to the Viewport" ), UndoRedo::MERGE_DISABLE, selected_camera);
167+ ur->add_do_method (this , " _snap_limits_to_viewport" , selected_camera);
168+ ur->add_undo_method (selected_camera, " _set_limit_rect" , selected_camera->get_limit_rect ());
169+ ur->add_undo_method (this , " _update_overlays_if_needed" , selected_camera);
58170 ur->commit_action ();
59171 } break ;
60172 }
61173}
62174
63- void Camera2DEditor::_snap_limits_to_viewport () {
64- selected_camera->set_limit (SIDE_LEFT, 0 );
65- selected_camera->set_limit (SIDE_TOP, 0 );
66- selected_camera->set_limit (SIDE_RIGHT, GLOBAL_GET (" display/window/size/viewport_width" ));
67- selected_camera->set_limit (SIDE_BOTTOM, GLOBAL_GET (" display/window/size/viewport_height" ));
175+ void Camera2DEditor::_snap_limits_to_viewport (Camera2D *p_camera) {
176+ p_camera->set_limit (SIDE_LEFT, 0 );
177+ p_camera->set_limit (SIDE_TOP, 0 );
178+ p_camera->set_limit (SIDE_RIGHT, GLOBAL_GET (" display/window/size/viewport_width" ));
179+ p_camera->set_limit (SIDE_BOTTOM, GLOBAL_GET (" display/window/size/viewport_height" ));
180+ _update_overlays_if_needed (p_camera);
181+ }
182+
183+ void Camera2DEditor::_update_overlays_if_needed (Camera2D *p_camera) {
184+ if (p_camera == selected_camera) {
185+ plugin->update_overlays ();
186+ }
68187}
69188
70- void Camera2DEditor::_undo_snap_limits_to_viewport (const Rect2 &p_prev_rect) {
71- Point2 end = p_prev_rect.get_end ();
72- selected_camera->set_limit (SIDE_LEFT, p_prev_rect.position .x );
73- selected_camera->set_limit (SIDE_TOP, p_prev_rect.position .y );
74- selected_camera->set_limit (SIDE_RIGHT, end.x );
75- selected_camera->set_limit (SIDE_BOTTOM, end.y );
189+ void Camera2DEditor::_update_hover (const Vector2 &p_mouse_pos) {
190+ if (CanvasItemEditor::get_singleton ()->get_current_tool () != CanvasItemEditor::TOOL_SELECT) {
191+ hover_type = Drag::NONE;
192+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override ();
193+ return ;
194+ }
195+
196+ const Rect2 limit_rect = CanvasItemEditor::get_singleton ()->get_canvas_transform ().xform (selected_camera->get_limit_rect ());
197+ const float drag_tolerance = 8.0 ;
198+
199+ hover_type = Drag::NONE;
200+ if (p_mouse_pos.y > limit_rect.position .y && p_mouse_pos.y < limit_rect.get_end ().y ) {
201+ if (Math::abs (p_mouse_pos.x - limit_rect.position .x ) < drag_tolerance) {
202+ hover_type = Drag::LEFT;
203+ } else if (Math::abs (p_mouse_pos.x - limit_rect.get_end ().x ) < drag_tolerance) {
204+ hover_type = Drag::RIGHT;
205+ }
206+ } else if (p_mouse_pos.x > limit_rect.position .x && p_mouse_pos.x < limit_rect.get_end ().x ) {
207+ if (Math::abs (p_mouse_pos.y - limit_rect.position .y ) < drag_tolerance) {
208+ hover_type = Drag::TOP;
209+ } else if (Math::abs (p_mouse_pos.y - limit_rect.get_end ().y ) < drag_tolerance) {
210+ hover_type = Drag::BOTTOM;
211+ }
212+ }
213+
214+ /* Temporarily disabled, because it needs more changes.
215+ if (hover_type == Drag::NONE && limit_rect.has_point(p_mouse_pos)) {
216+ hover_type = Drag::CENTER;
217+ }
218+ */
219+
220+ switch (hover_type) {
221+ case Drag::NONE: {
222+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override ();
223+ } break ;
224+ case Drag::LEFT:
225+ case Drag::RIGHT: {
226+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override (CURSOR_HSIZE);
227+ } break ;
228+ case Drag::TOP:
229+ case Drag::BOTTOM: {
230+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override (CURSOR_VSIZE);
231+ } break ;
232+ case Drag::CENTER: {
233+ CanvasItemEditor::get_singleton ()->set_cursor_shape_override (CURSOR_MOVE);
234+ } break ;
235+ }
76236}
77237
78238void Camera2DEditor::_notification (int p_what) {
@@ -84,56 +244,24 @@ void Camera2DEditor::_notification(int p_what) {
84244}
85245
86246void Camera2DEditor::_bind_methods () {
87- ClassDB::bind_method (D_METHOD (" _snap_limits_to_viewport" ), &Camera2DEditor::_snap_limits_to_viewport);
88- ClassDB::bind_method (D_METHOD (" _undo_snap_limits_to_viewport " , " prev_rect " ), &Camera2DEditor::_undo_snap_limits_to_viewport );
247+ ClassDB::bind_method (D_METHOD (" _snap_limits_to_viewport" , " camera " ), &Camera2DEditor::_snap_limits_to_viewport);
248+ ClassDB::bind_method (D_METHOD (" _update_overlays_if_needed " , " camera " ), &Camera2DEditor::_update_overlays_if_needed );
89249}
90250
91- Camera2DEditor::Camera2DEditor () {
92- options = memnew (MenuButton);
93-
94- CanvasItemEditor::get_singleton ()->add_control_to_menu_panel (options);
251+ Camera2DEditor::Camera2DEditor (EditorPlugin *p_plugin) {
252+ plugin = p_plugin;
95253
254+ options = memnew (MenuButton);
96255 options->set_text (TTRC (" Camera2D" ));
97-
98256 options->get_popup ()->add_item (TTRC (" Snap the Limits to the Viewport" ), MENU_SNAP_LIMITS_TO_VIEWPORT);
99257 options->set_switch_on_hover (true );
100-
258+ options->hide ();
259+ CanvasItemEditor::get_singleton ()->add_control_to_menu_panel (options);
101260 options->get_popup ()->connect (SceneStringName (id_pressed), callable_mp (this , &Camera2DEditor::_menu_option));
102-
103- add_user_signal (MethodInfo (" _editor_theme_changed" ));
104- }
105-
106- void Camera2DEditorPlugin::_update_approach_text_visibility () {
107- if (camera_2d_editor->selected_camera == nullptr ) {
108- return ;
109- }
110- approach_to_move_rect->set_visible (camera_2d_editor->selected_camera ->is_limit_enabled ());
111- }
112-
113- void Camera2DEditorPlugin::_editor_theme_changed () {
114- approach_to_move_rect->remove_theme_color_override (SceneStringName (font_color));
115- approach_to_move_rect->add_theme_color_override (SceneStringName (font_color), Color (0 .6f , 0 .6f , 0 .6f , 1 ));
116- approach_to_move_rect->add_theme_color_override (" font_shadow_color" , Color (0 .2f , 0 .2f , 0 .2f , 1 ));
117- approach_to_move_rect->add_theme_constant_override (" shadow_outline_size" , 1 * EDSCALE);
118- approach_to_move_rect->add_theme_constant_override (" line_spacing" , 0 );
119261}
120262
121263void Camera2DEditorPlugin::edit (Object *p_object) {
122- Callable update_text = callable_mp (this , &Camera2DEditorPlugin::_update_approach_text_visibility);
123- StringName update_signal = SNAME (" _camera_limit_enabled_updated" );
124-
125- Camera2D *prev_cam = camera_2d_editor->selected_camera ;
126- if (prev_cam != nullptr && prev_cam->is_connected (update_signal, update_text)) {
127- prev_cam->disconnect (update_signal, update_text);
128- }
129- Camera2D *cam = Object::cast_to<Camera2D>(p_object);
130- if (cam != nullptr ) {
131- camera_2d_editor->edit (cam);
132- _update_approach_text_visibility ();
133- if (!cam->is_connected (update_signal, update_text)) {
134- cam->connect (update_signal, update_text);
135- }
136- }
264+ camera_2d_editor->edit (Object::cast_to<Camera2D>(p_object));
137265}
138266
139267bool Camera2DEditorPlugin::handles (Object *p_object) const {
@@ -143,24 +271,12 @@ bool Camera2DEditorPlugin::handles(Object *p_object) const {
143271void Camera2DEditorPlugin::make_visible (bool p_visible) {
144272 if (p_visible) {
145273 camera_2d_editor->options ->show ();
146- approach_to_move_rect->show ();
147274 } else {
148275 camera_2d_editor->options ->hide ();
149- approach_to_move_rect->hide ();
150276 }
151277}
152278
153279Camera2DEditorPlugin::Camera2DEditorPlugin () {
154- camera_2d_editor = memnew (Camera2DEditor);
280+ camera_2d_editor = memnew (Camera2DEditor ( this ) );
155281 EditorNode::get_singleton ()->get_gui_base ()->add_child (camera_2d_editor);
156- camera_2d_editor->connect (SNAME (" _editor_theme_changed" ), callable_mp (this , &Camera2DEditorPlugin::_editor_theme_changed));
157-
158- approach_to_move_rect = memnew (Label);
159- approach_to_move_rect->set_focus_mode (Control::FOCUS_ACCESSIBILITY);
160- approach_to_move_rect->set_text (TTRC (" In Move Mode: \n Hold Ctrl + left mouse button to move the limit rectangle.\n Hold left mouse button to move the camera only." ));
161- approach_to_move_rect->hide ();
162- _editor_theme_changed ();
163- CanvasItemEditor::get_singleton ()->get_controls_container ()->add_child (approach_to_move_rect);
164-
165- make_visible (false );
166282}
0 commit comments