godot_voxel/editor/graph/voxel_graph_editor_plugin.cpp
Marc Gilleron 61f17ce96d Formatting
2020-10-25 20:38:23 +00:00

106 lines
4.1 KiB
C++

#include "voxel_graph_editor_plugin.h"
#include "../../generators/graph/voxel_generator_graph.h"
#include "voxel_graph_editor.h"
#include "voxel_graph_node_inspector_wrapper.h"
#include <editor/editor_scale.h>
VoxelGraphEditorPlugin::VoxelGraphEditorPlugin(EditorNode *p_node) {
//EditorInterface *ed = get_editor_interface();
_graph_editor = memnew(VoxelGraphEditor);
_graph_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
_graph_editor->connect(VoxelGraphEditor::SIGNAL_NODE_SELECTED, this, "_on_graph_editor_node_selected");
_graph_editor->connect(VoxelGraphEditor::SIGNAL_NOTHING_SELECTED, this, "_on_graph_editor_nothing_selected");
_bottom_panel_button = add_control_to_bottom_panel(_graph_editor, TTR("Voxel Graph"));
_bottom_panel_button->hide();
}
bool VoxelGraphEditorPlugin::handles(Object *p_object) const {
if (p_object == nullptr) {
return false;
}
VoxelGeneratorGraph *graph_ptr = Object::cast_to<VoxelGeneratorGraph>(p_object);
if (graph_ptr != nullptr) {
return true;
}
VoxelGraphNodeInspectorWrapper *wrapper = Object::cast_to<VoxelGraphNodeInspectorWrapper>(p_object);
if (wrapper != nullptr) {
return true;
}
return false;
}
void VoxelGraphEditorPlugin::edit(Object *p_object) {
VoxelGeneratorGraph *graph_ptr = Object::cast_to<VoxelGeneratorGraph>(p_object);
if (graph_ptr == nullptr) {
VoxelGraphNodeInspectorWrapper *wrapper = Object::cast_to<VoxelGraphNodeInspectorWrapper>(p_object);
if (wrapper != nullptr) {
graph_ptr = *wrapper->get_graph();
}
}
Ref<VoxelGeneratorGraph> graph(graph_ptr);
_graph_editor->set_undo_redo(&get_undo_redo()); // UndoRedo isn't available in constructor
_graph_editor->set_graph(graph);
}
void VoxelGraphEditorPlugin::make_visible(bool visible) {
if (visible) {
_bottom_panel_button->show();
make_bottom_panel_item_visible(_graph_editor);
} else {
_bottom_panel_button->hide();
// TODO Awful hack to handle the nonsense happening in `_on_graph_editor_node_selected`
if (!_deferred_visibility_scheduled) {
_deferred_visibility_scheduled = true;
call_deferred("_hide_deferred");
}
}
}
void VoxelGraphEditorPlugin::_hide_deferred() {
_deferred_visibility_scheduled = false;
if (_bottom_panel_button->is_visible()) {
// Still visible actually? Don't hide then
return;
}
// The point is when the plugin's UI closed (for real, not closed and re-opened simultaneously!),
// it should cleanup its UI to not waste RAM (as it references stuff).
edit(nullptr);
if (_graph_editor->is_visible_in_tree()) {
hide_bottom_panel();
}
}
void VoxelGraphEditorPlugin::_on_graph_editor_node_selected(uint32_t node_id) {
Ref<VoxelGraphNodeInspectorWrapper> wrapper;
wrapper.instance();
wrapper->setup(_graph_editor->get_graph(), node_id);
// Note: it's neither explicit nor documented, but the reference will stay alive due to EditorHistory::_add_object
get_editor_interface()->inspect_object(*wrapper);
// TODO Absurd situation here...
// `inspect_object()` gets to a point where Godot hides ALL plugins for some reason...
// And all this, to have the graph editor rebuilt and shown again, because it DOES also handle that resource type -_-
// https://github.com/godotengine/godot/issues/40166
}
void VoxelGraphEditorPlugin::_on_graph_editor_nothing_selected() {
// The inspector is a glorious singleton, so when we select nodes to edit their properties, it prevents
// from accessing the graph resource itself, to save it for example.
// I'd like to embed properties inside the nodes themselves, but it's a bit more work,
// so for now I make it so deselecting all nodes in the graph (like clicking in the background) selects the graph.
Ref<VoxelGeneratorGraph> graph = _graph_editor->get_graph();
if (graph.is_valid()) {
get_editor_interface()->inspect_object(*graph);
}
}
void VoxelGraphEditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("_on_graph_editor_node_selected", "node_id"),
&VoxelGraphEditorPlugin::_on_graph_editor_node_selected);
ClassDB::bind_method(D_METHOD("_on_graph_editor_nothing_selected"),
&VoxelGraphEditorPlugin::_on_graph_editor_nothing_selected);
ClassDB::bind_method(D_METHOD("_hide_deferred"), &VoxelGraphEditorPlugin::_hide_deferred);
}