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

Code before:
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/scene_tree_dock.h"
#include "scene/gui/menu_button.h"

void CPUParticles3DEditor::_node_removed(Node *p_node) {
	if (p_node == node) {
		node = nullptr;
		hide();
	}
}

void CPUParticles3DEditor::_notification(int p_notification) {
	switch (p_notification) {
		case NOTIFICATION_ENTER_TREE: {
			options->set_icon(get_editor_theme_icon(SNAME("CPUParticles3D")));
		} break;
	}
}

void CPUParticles3DEditor::_menu_option(int p_option) {
	switch (p_option) {
		case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
			emission_tree_dialog->popup_scenetree_dialog();

		} break;

		case MENU_OPTION_RESTART: {
			node->restart();
		} break;

		case MENU_OPTION_CONVERT_TO_GPU_PARTICLES: {
			GPUParticles3D *gpu_particles = memnew(GPUParticles3D);
			gpu_particles->convert_from_particles(node);
			gpu_particles->set_name(node->get_name());
			gpu_particles->set_transform(node->get_transform());
			gpu_particles->set_visible(node->is_visible());
			gpu_particles->set_process_mode(node->get_process_mode());

			EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
			ur->create_action(TTR("Convert to GPUParticles3D"), UndoRedo::MERGE_DISABLE, node);
			SceneTreeDock::get_singleton()->replace_node(node, gpu_particles);
			ur->commit_action(false);

		} break;
		case MENU_OPTION_GENERATE_AABB: {
			// Add one second to the default generation lifetime, since the progress is updated every second.
			generate_seconds->set_value(MAX(1.0, trunc(node->get_lifetime()) + 1.0));


Review comment (suggestion):
With these three methods all being required for the desired behavior in the PR, I wonder if it's worth clumping them up into a single function.

Perhaps by passing what they need as parameters in `popup_scenetree_dialog()`? If getting the `get_scene_tree()` is even possible from there.

Code after:
#include "editor/editor_node.h"
#include "editor/editor_undo_redo_manager.h"
#include "editor/gui/scene_tree_editor.h"
#include "editor/plugins/node_3d_editor_plugin.h"
#include "editor/scene_tree_dock.h"
#include "scene/gui/menu_button.h"

void CPUParticles3DEditor::_node_removed(Node *p_node) {
	if (p_node == node) {
		node = nullptr;
		hide();
	}
}

void CPUParticles3DEditor::_notification(int p_notification) {
	switch (p_notification) {
		case NOTIFICATION_ENTER_TREE: {
			options->set_icon(get_editor_theme_icon(SNAME("CPUParticles3D")));
		} break;
	}
}

void CPUParticles3DEditor::_menu_option(int p_option) {
	switch (p_option) {
		case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
			emission_tree_dialog->popup_scenetree_dialog();
		} break;

		case MENU_OPTION_RESTART: {
			node->restart();
		} break;

		case MENU_OPTION_CONVERT_TO_GPU_PARTICLES: {
			GPUParticles3D *gpu_particles = memnew(GPUParticles3D);
			gpu_particles->convert_from_particles(node);
			gpu_particles->set_name(node->get_name());
			gpu_particles->set_transform(node->get_transform());
			gpu_particles->set_visible(node->is_visible());
			gpu_particles->set_process_mode(node->get_process_mode());

			EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
			ur->create_action(TTR("Convert to GPUParticles3D"), UndoRedo::MERGE_DISABLE, node);
			SceneTreeDock::get_singleton()->replace_node(node, gpu_particles);
			ur->commit_action(false);

		} break;
		case MENU_OPTION_GENERATE_AABB: {
			// Add one second to the default generation lifetime, since the progress is updated every second.
			generate_seconds->set_value(MAX(1.0, trunc(node->get_lifetime()) + 1.0));

			if (generate_seconds->get_value() >= 11.0 + CMP_EPSILON) {