4040#include " scene/gui/menu_button.h"
4141
4242void Camera2DEditor::edit (Camera2D *p_camera) {
43- if (p_camera == selected_camera) {
43+ 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+ }
4651 selected_camera = p_camera;
52+
53+ if (selected_camera) {
54+ selected_camera->connect (SceneStringName (draw), update_overlays);
55+ }
56+ plugin->update_overlays ();
57+ }
58+
59+ bool Camera2DEditor::forward_canvas_gui_input (const Ref<InputEvent> &p_event) {
60+ if (!selected_camera || !selected_camera->is_limit_enabled ()) {
61+ return false ;
62+ }
63+
64+ Ref<InputEventMouseButton> mb = p_event;
65+ if (mb.is_valid ()) {
66+ if (mb->get_button_index () == MouseButton::LEFT) {
67+ if (mb->is_pressed ()) {
68+ const Rect2 limit_rect = selected_camera->get_limit_rect ();
69+ const Vector2 pos = CanvasItemEditor::get_singleton ()->get_canvas_transform ().affine_inverse ().xform (mb->get_position ());
70+ drag_revert = limit_rect;
71+
72+ if (pos.y > limit_rect.position .y && pos.y < limit_rect.get_end ().y ) {
73+ if (Math::abs (pos.x - limit_rect.position .x ) < 8 ) {
74+ drag_type = Drag::LEFT;
75+ return true ;
76+ } else if (Math::abs (pos.x - limit_rect.get_end ().x ) < 8 ) {
77+ drag_type = Drag::RIGHT;
78+ return true ;
79+ }
80+ } else if (pos.x > limit_rect.position .x && pos.x < limit_rect.get_end ().x ) {
81+ if (Math::abs (pos.y - limit_rect.position .y ) < 8 ) {
82+ drag_type = Drag::TOP;
83+ return true ;
84+ } else if (Math::abs (pos.y - limit_rect.get_end ().y ) < 8 ) {
85+ drag_type = Drag::BOTTOM;
86+ return true ;
87+ }
88+ }
89+
90+ if (limit_rect.has_point (pos)) {
91+ drag_type = Drag::CENTER;
92+ center_drag_point = pos - limit_rect.position ;
93+ plugin->update_overlays ();
94+ return true ;
95+ }
96+ } else if (drag_type != Drag::NONE) {
97+ EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
98+ ur->create_action (TTR (" Edit Camera2D Limits" ));
99+ ur->add_do_method (selected_camera, " _set_limit_rect" , selected_camera->get_limit_rect ());
100+ ur->add_do_method (this , " _update_overlays_if_needed" , selected_camera);
101+ ur->add_undo_method (selected_camera, " _set_limit_rect" , drag_revert);
102+ ur->add_undo_method (this , " _update_overlays_if_needed" , selected_camera);
103+ ur->commit_action (false );
104+
105+ drag_type = Drag::NONE;
106+ return true ;
107+ }
108+ } else if (drag_type != Drag::NONE && mb->get_button_index () == MouseButton::RIGHT && mb->is_pressed ()) {
109+ selected_camera->set_limit_rect (drag_revert);
110+ drag_type = Drag::NONE;
111+ plugin->update_overlays ();
112+ return true ;
113+ }
114+ return false ;
115+ }
116+
117+ if (drag_type == Drag::NONE) {
118+ return false ;
119+ }
120+
121+ Ref<InputEventMouseMotion> mm = p_event;
122+ if (mm.is_valid ()) {
123+ Vector2 pos = CanvasItemEditor::get_singleton ()->get_canvas_transform ().affine_inverse ().xform (mm->get_position ());
124+ pos = CanvasItemEditor::get_singleton ()->snap_point (pos);
125+
126+ switch (drag_type) {
127+ case Drag::LEFT: {
128+ selected_camera->set_limit (SIDE_LEFT, MIN (selected_camera->get_limit (SIDE_RIGHT), pos.x ));
129+ plugin->update_overlays ();
130+ } break ;
131+
132+ case Drag::RIGHT: {
133+ selected_camera->set_limit (SIDE_RIGHT, MAX (selected_camera->get_limit (SIDE_LEFT), pos.x ));
134+ plugin->update_overlays ();
135+ } break ;
136+
137+ case Drag::TOP: {
138+ selected_camera->set_limit (SIDE_TOP, MIN (selected_camera->get_limit (SIDE_BOTTOM), pos.y ));
139+ plugin->update_overlays ();
140+ } break ;
141+
142+ case Drag::BOTTOM: {
143+ selected_camera->set_limit (SIDE_BOTTOM, MAX (selected_camera->get_limit (SIDE_TOP), pos.y ));
144+ plugin->update_overlays ();
145+ } break ;
146+
147+ case Drag::CENTER: {
148+ Rect2 target_rect = selected_camera->get_limit_rect ();
149+ target_rect.position = pos - center_drag_point;
150+ selected_camera->set_limit_rect (target_rect);
151+ plugin->update_overlays ();
152+ } break ;
153+ }
154+ return true ;
155+ }
156+
157+ return false ;
158+ }
159+
160+ void Camera2DEditor::forward_canvas_draw_over_viewport (Control *p_overlay) {
161+ if (!selected_camera || !selected_camera->is_limit_enabled ()) {
162+ return ;
163+ }
164+ Rect2 limit_rect = selected_camera->get_limit_rect ();
165+ limit_rect = CanvasItemEditor::get_singleton ()->get_canvas_transform ().xform (limit_rect);
166+ p_overlay->draw_rect (limit_rect, Color (1 , 1 , 0.25 , 0.63 ), false , 3 );
47167}
48168
49169void Camera2DEditor::_menu_option (int p_option) {
50170 switch (p_option) {
51171 case MENU_SNAP_LIMITS_TO_VIEWPORT: {
52172 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);
173+ ur->create_action (TTR (" Snap Camera2D Limits to the Viewport" ), UndoRedo::MERGE_DISABLE, selected_camera);
174+ ur->add_do_method (this , " _snap_limits_to_viewport" , selected_camera);
175+ ur->add_undo_method (selected_camera, " _set_limit_rect" , selected_camera->get_limit_rect ());
176+ ur->add_undo_method (this , " _update_overlays_if_needed" , selected_camera);
58177 ur->commit_action ();
59178 } break ;
60179 }
61180}
62181
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" ));
182+ void Camera2DEditor::_snap_limits_to_viewport (Camera2D *p_camera) {
183+ p_camera->set_limit (SIDE_LEFT, 0 );
184+ p_camera->set_limit (SIDE_TOP, 0 );
185+ p_camera->set_limit (SIDE_RIGHT, GLOBAL_GET (" display/window/size/viewport_width" ));
186+ p_camera->set_limit (SIDE_BOTTOM, GLOBAL_GET (" display/window/size/viewport_height" ));
187+ _update_overlays_if_needed (p_camera);
68188}
69189
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 );
190+ void Camera2DEditor::_update_overlays_if_needed (Camera2D *p_camera) {
191+ if (p_camera == selected_camera) {
192+ plugin->update_overlays ();
193+ }
76194}
77195
78196void Camera2DEditor::_notification (int p_what) {
@@ -84,56 +202,24 @@ void Camera2DEditor::_notification(int p_what) {
84202}
85203
86204void 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 );
205+ ClassDB::bind_method (D_METHOD (" _snap_limits_to_viewport" , " camera " ), &Camera2DEditor::_snap_limits_to_viewport);
206+ ClassDB::bind_method (D_METHOD (" _update_overlays_if_needed " , " camera " ), &Camera2DEditor::_update_overlays_if_needed );
89207}
90208
91- Camera2DEditor::Camera2DEditor () {
92- options = memnew (MenuButton);
93-
94- CanvasItemEditor::get_singleton ()->add_control_to_menu_panel (options);
209+ Camera2DEditor::Camera2DEditor (EditorPlugin *p_plugin) {
210+ plugin = p_plugin;
95211
212+ options = memnew (MenuButton);
96213 options->set_text (TTRC (" Camera2D" ));
97-
98214 options->get_popup ()->add_item (TTRC (" Snap the Limits to the Viewport" ), MENU_SNAP_LIMITS_TO_VIEWPORT);
99215 options->set_switch_on_hover (true );
100-
216+ options->hide ();
217+ CanvasItemEditor::get_singleton ()->add_control_to_menu_panel (options);
101218 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 );
119219}
120220
121221void 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- }
222+ camera_2d_editor->edit (Object::cast_to<Camera2D>(p_object));
137223}
138224
139225bool Camera2DEditorPlugin::handles (Object *p_object) const {
@@ -143,24 +229,12 @@ bool Camera2DEditorPlugin::handles(Object *p_object) const {
143229void Camera2DEditorPlugin::make_visible (bool p_visible) {
144230 if (p_visible) {
145231 camera_2d_editor->options ->show ();
146- approach_to_move_rect->show ();
147232 } else {
148233 camera_2d_editor->options ->hide ();
149- approach_to_move_rect->hide ();
150234 }
151235}
152236
153237Camera2DEditorPlugin::Camera2DEditorPlugin () {
154- camera_2d_editor = memnew (Camera2DEditor);
238+ camera_2d_editor = memnew (Camera2DEditor ( this ) );
155239 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 );
166240}
0 commit comments