Repository: godotengine/godot
File: editor/plugins/camera_2d_editor_plugin.cpp (C++)

Code before:
		if (!cam->is_connected(update_signal, update_text)) {
			cam->connect(update_signal, update_text);
		}
	}
}

bool Camera2DEditorPlugin::handles(Object *p_object) const {
	return p_object->is_class("Camera2D");
}

void Camera2DEditorPlugin::make_visible(bool p_visible) {
	if (p_visible) {
		camera_2d_editor->options->show();
		approach_to_move_rect->show();
	} else {
		camera_2d_editor->options->hide();
		camera_2d_editor->edit(nullptr);
		approach_to_move_rect->hide();
	}
}

Camera2DEditorPlugin::Camera2DEditorPlugin() {
	camera_2d_editor = memnew(Camera2DEditor);
	EditorNode::get_singleton()->get_gui_base()->add_child(camera_2d_editor);

	approach_to_move_rect = memnew(Label);
	approach_to_move_rect->set_text(TTR("In moving mode: \nHold Ctrl + left mouse button to move the limit rectangle.\nHold left mouse button to move the camera only."));
	approach_to_move_rect->add_theme_color_override(SceneStringName(font_color), Color(0.6f, 0.6f, 0.6f, 1));
	approach_to_move_rect->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1));
	approach_to_move_rect->add_theme_constant_override("shadow_outline_size", 1 * EDSCALE);
	approach_to_move_rect->add_theme_constant_override("line_spacing", 0);
	approach_to_move_rect->hide();
	CanvasItemEditor::get_singleton()->get_controls_container()->add_child(approach_to_move_rect);

	make_visible(false);
}

Camera2DEditorPlugin::~Camera2DEditorPlugin() {
}


Review comment (suggestion):
This logic is flawed. You should first check for `selected_camera` and disconnect the signal from it, then connect to `cam`. You are disconnecting and connecting the same camera.

Usually the editor has its own `edit()` method that handles this, the plugin only forwards it.

Code after:

void Camera2DEditorPlugin::_update_approach_text_visibility() {
	if (camera_2d_editor->selected_camera == nullptr) {
		return;
	}
	approach_to_move_rect->set_visible(camera_2d_editor->selected_camera->is_limit_enabled());
}

void Camera2DEditorPlugin::_editor_theme_changed() {
	approach_to_move_rect->remove_theme_color_override(SceneStringName(font_color));
	approach_to_move_rect->add_theme_color_override(SceneStringName(font_color), Color(0.6f, 0.6f, 0.6f, 1));
	approach_to_move_rect->add_theme_color_override("font_shadow_color", Color(0.2f, 0.2f, 0.2f, 1));
	approach_to_move_rect->add_theme_constant_override("shadow_outline_size", 1 * EDSCALE);
	approach_to_move_rect->add_theme_constant_override("line_spacing", 0);
}

void Camera2DEditorPlugin::edit(Object *p_object) {
	Callable update_text = callable_mp(this, &Camera2DEditorPlugin::_update_approach_text_visibility);
	StringName update_signal = SNAME("_camera_limit_enabled_updated");

	Camera2D *prev_cam = camera_2d_editor->selected_camera;
	if (prev_cam != nullptr && prev_cam->is_connected(update_signal, update_text)) {
		prev_cam->disconnect(update_signal, update_text);
	}
	Camera2D *cam = Object::cast_to<Camera2D>(p_object);
	if (cam != nullptr) {
		camera_2d_editor->edit(cam);
		_update_approach_text_visibility();
		if (!cam->is_connected(update_signal, update_text)) {
			cam->connect(update_signal, update_text);
		}
	}
}

bool Camera2DEditorPlugin::handles(Object *p_object) const {
	return p_object->is_class("Camera2D");
}

void Camera2DEditorPlugin::make_visible(bool p_visible) {
	if (p_visible) {
		camera_2d_editor->options->show();
		approach_to_move_rect->show();
	} else {
		camera_2d_editor->options->hide();
		approach_to_move_rect->hide();
	}
}

Camera2DEditorPlugin::Camera2DEditorPlugin() {
	camera_2d_editor = memnew(Camera2DEditor);
	EditorNode::get_singleton()->get_gui_base()->add_child(camera_2d_editor);