Browse Source

Expose GridMapEditorPlugin to scripts and add methods to manipulate the selection and selected palette item

Bad Sector 8 months ago
parent
commit
baf03e4fb6

+ 1 - 3
modules/gridmap/config.py

@@ -7,9 +7,7 @@ def configure(env):
 
 
 
 
 def get_doc_classes():
 def get_doc_classes():
-    return [
-        "GridMap",
-    ]
+    return ["GridMap", "GridMapEditorPlugin"]
 
 
 
 
 def get_doc_path():
 def get_doc_path():

+ 66 - 0
modules/gridmap/doc_classes/GridMapEditorPlugin.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GridMapEditorPlugin" inherits="EditorPlugin" keywords="tilemap" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
+	<brief_description>
+		Editor for [GridMap] nodes.
+	</brief_description>
+	<description>
+		GridMapEditorPlugin provides access to the [GridMap] editor functionality.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+		<method name="clear_selection">
+			<return type="void" />
+			<description>
+				Deselects any currently selected cells.
+			</description>
+		</method>
+		<method name="get_current_grid_map" qualifiers="const">
+			<return type="GridMap" />
+			<description>
+				Returns the [GridMap] node currently edited by the grid map editor.
+			</description>
+		</method>
+		<method name="get_selected_cells" qualifiers="const">
+			<return type="Array" />
+			<description>
+				Returns an array of [Vector3i]s with the selected cells' coordinates.
+			</description>
+		</method>
+		<method name="get_selected_palette_item" qualifiers="const">
+			<return type="int" />
+			<description>
+				Returns the index of the selected [MeshLibrary] item in the grid map editor's palette or [code]-1[/code] if no item is selected.
+				[b]Note:[/b] The indices might not be in the same order as they appear in the editor's interface.
+			</description>
+		</method>
+		<method name="get_selection" qualifiers="const">
+			<return type="AABB" />
+			<description>
+				Returns the cell coordinate bounds of the current selection. Use [method has_selection] to check if there is an active selection.
+			</description>
+		</method>
+		<method name="has_selection" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if there are selected cells.
+			</description>
+		</method>
+		<method name="set_selected_palette_item" qualifiers="const">
+			<return type="void" />
+			<param index="0" name="item" type="int" />
+			<description>
+				Selects the [MeshLibrary] item with the given index in the grid map editor's palette. If a negative index is given, no item will be selected. If a value greater than the last index is given, the last item will be selected.
+				[b]Note:[/b] The indices might not be in the same order as they appear in the editor's interface.
+			</description>
+		</method>
+		<method name="set_selection">
+			<return type="void" />
+			<param index="0" name="begin" type="Vector3i" />
+			<param index="1" name="end" type="Vector3i" />
+			<description>
+				Selects the cells inside the given bounds from [param begin] to [param end].
+			</description>
+		</method>
+	</methods>
+</class>

+ 123 - 8
modules/gridmap/editor/grid_map_editor_plugin.cpp

@@ -343,6 +343,41 @@ void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const
 	}
 	}
 }
 }
 
 
+AABB GridMapEditor::_get_selection() const {
+	AABB ret;
+	if (selection.active) {
+		ret.position = selection.begin;
+		ret.size = selection.end - selection.begin;
+	} else {
+		ret.position.zero();
+		ret.size.zero();
+	}
+	return ret;
+}
+
+bool GridMapEditor::_has_selection() const {
+	return node != nullptr && selection.active;
+}
+
+Array GridMapEditor::_get_selected_cells() const {
+	Array ret;
+	if (node != nullptr && selection.active) {
+		for (int i = selection.begin.x; i <= selection.end.x; i++) {
+			for (int j = selection.begin.y; j <= selection.end.y; j++) {
+				for (int k = selection.begin.z; k <= selection.end.z; k++) {
+					Vector3i selected = Vector3i(i, j, k);
+					int itm = node->get_cell_item(selected);
+					if (itm == GridMap::INVALID_CELL_ITEM) {
+						continue;
+					}
+					ret.append(selected);
+				}
+			}
+		}
+	}
+	return ret;
+}
+
 bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click) {
 bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click) {
 	if (!spatial_editor) {
 	if (!spatial_editor) {
 		return false;
 		return false;
@@ -1717,7 +1752,40 @@ GridMapEditor::~GridMapEditor() {
 	}
 	}
 }
 }
 
 
+void GridMapEditorPlugin::_notification(int p_what) {
+	switch (p_what) {
+		case NOTIFICATION_ENTER_TREE: {
+			grid_map_editor = memnew(GridMapEditor);
+			grid_map_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+			grid_map_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+			grid_map_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
+			grid_map_editor->hide();
+
+			panel_button = EditorNode::get_bottom_panel()->add_item(TTR("GridMap"), grid_map_editor, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_grid_map_bottom_panel", TTR("Toggle GridMap Bottom Panel")));
+			panel_button->hide();
+		} break;
+		case NOTIFICATION_EXIT_TREE: {
+			EditorNode::get_bottom_panel()->remove_item(grid_map_editor);
+			memdelete_notnull(grid_map_editor);
+			grid_map_editor = nullptr;
+			panel_button = nullptr;
+		} break;
+	}
+}
+
+void GridMapEditorPlugin::_bind_methods() {
+	ClassDB::bind_method(D_METHOD("get_current_grid_map"), &GridMapEditorPlugin::get_current_grid_map);
+	ClassDB::bind_method(D_METHOD("set_selection", "begin", "end"), &GridMapEditorPlugin::set_selection);
+	ClassDB::bind_method(D_METHOD("clear_selection"), &GridMapEditorPlugin::clear_selection);
+	ClassDB::bind_method(D_METHOD("get_selection"), &GridMapEditorPlugin::get_selection);
+	ClassDB::bind_method(D_METHOD("has_selection"), &GridMapEditorPlugin::has_selection);
+	ClassDB::bind_method(D_METHOD("get_selected_cells"), &GridMapEditorPlugin::get_selected_cells);
+	ClassDB::bind_method(D_METHOD("set_selected_palette_item", "item"), &GridMapEditorPlugin::set_selected_palette_item);
+	ClassDB::bind_method(D_METHOD("get_selected_palette_item"), &GridMapEditorPlugin::get_selected_palette_item);
+}
+
 void GridMapEditorPlugin::edit(Object *p_object) {
 void GridMapEditorPlugin::edit(Object *p_object) {
+	ERR_FAIL_NULL(grid_map_editor);
 	grid_map_editor->edit(Object::cast_to<GridMap>(p_object));
 	grid_map_editor->edit(Object::cast_to<GridMap>(p_object));
 }
 }
 
 
@@ -1726,6 +1794,7 @@ bool GridMapEditorPlugin::handles(Object *p_object) const {
 }
 }
 
 
 void GridMapEditorPlugin::make_visible(bool p_visible) {
 void GridMapEditorPlugin::make_visible(bool p_visible) {
+	ERR_FAIL_NULL(grid_map_editor);
 	if (p_visible) {
 	if (p_visible) {
 		BaseButton *button = grid_map_editor->mode_buttons_group->get_pressed_button();
 		BaseButton *button = grid_map_editor->mode_buttons_group->get_pressed_button();
 		if (button == nullptr) {
 		if (button == nullptr) {
@@ -1745,15 +1814,61 @@ void GridMapEditorPlugin::make_visible(bool p_visible) {
 	}
 	}
 }
 }
 
 
+GridMap *GridMapEditorPlugin::get_current_grid_map() const {
+	ERR_FAIL_NULL_V(grid_map_editor, nullptr);
+	return grid_map_editor->node;
+}
+
+void GridMapEditorPlugin::set_selection(const Vector3i &p_begin, const Vector3i &p_end) {
+	ERR_FAIL_NULL(grid_map_editor);
+	grid_map_editor->_set_selection(true, p_begin, p_end);
+}
+
+void GridMapEditorPlugin::clear_selection() {
+	ERR_FAIL_NULL(grid_map_editor);
+	grid_map_editor->_set_selection(false);
+}
+
+AABB GridMapEditorPlugin::get_selection() const {
+	ERR_FAIL_NULL_V(grid_map_editor, AABB());
+	return grid_map_editor->_get_selection();
+}
+
+bool GridMapEditorPlugin::has_selection() const {
+	ERR_FAIL_NULL_V(grid_map_editor, false);
+	return grid_map_editor->_has_selection();
+}
+
+Array GridMapEditorPlugin::get_selected_cells() const {
+	ERR_FAIL_NULL_V(grid_map_editor, Array());
+	return grid_map_editor->_get_selected_cells();
+}
+
+void GridMapEditorPlugin::set_selected_palette_item(int p_item) const {
+	ERR_FAIL_NULL(grid_map_editor);
+	if (grid_map_editor->node && grid_map_editor->node->get_mesh_library().is_valid()) {
+		if (p_item < -1) {
+			p_item = -1;
+		} else if (p_item >= grid_map_editor->node->get_mesh_library()->get_item_list().size()) {
+			p_item = grid_map_editor->node->get_mesh_library()->get_item_list().size() - 1;
+		}
+		if (p_item != grid_map_editor->selected_palette) {
+			grid_map_editor->selected_palette = p_item;
+			grid_map_editor->update_palette();
+		}
+	}
+}
+
+int GridMapEditorPlugin::get_selected_palette_item() const {
+	ERR_FAIL_NULL_V(grid_map_editor, 0);
+	if (grid_map_editor->selected_palette >= 0 && grid_map_editor->node && grid_map_editor->node->get_mesh_library().is_valid()) {
+		return grid_map_editor->selected_palette;
+	} else {
+		return -1;
+	}
+}
+
 GridMapEditorPlugin::GridMapEditorPlugin() {
 GridMapEditorPlugin::GridMapEditorPlugin() {
-	grid_map_editor = memnew(GridMapEditor);
-	grid_map_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
-	grid_map_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-	grid_map_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
-	grid_map_editor->hide();
-
-	panel_button = EditorNode::get_bottom_panel()->add_item(TTR("GridMap"), grid_map_editor, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_grid_map_bottom_panel", TTR("Toggle GridMap Bottom Panel")));
-	panel_button->hide();
 }
 }
 
 
 GridMapEditorPlugin::~GridMapEditorPlugin() {
 GridMapEditorPlugin::~GridMapEditorPlugin() {

+ 16 - 0
modules/gridmap/editor/grid_map_editor_plugin.h

@@ -243,6 +243,9 @@ class GridMapEditor : public VBoxContainer {
 	void _update_selection_transform();
 	void _update_selection_transform();
 	void _validate_selection();
 	void _validate_selection();
 	void _set_selection(bool p_active, const Vector3 &p_begin = Vector3(), const Vector3 &p_end = Vector3());
 	void _set_selection(bool p_active, const Vector3 &p_begin = Vector3(), const Vector3 &p_end = Vector3());
+	AABB _get_selection() const;
+	bool _has_selection() const;
+	Array _get_selected_cells() const;
 
 
 	void _floor_changed(float p_value);
 	void _floor_changed(float p_value);
 	void _floor_mouse_exited();
 	void _floor_mouse_exited();
@@ -272,6 +275,10 @@ class GridMapEditorPlugin : public EditorPlugin {
 	GridMapEditor *grid_map_editor = nullptr;
 	GridMapEditor *grid_map_editor = nullptr;
 	Button *panel_button = nullptr;
 	Button *panel_button = nullptr;
 
 
+protected:
+	void _notification(int p_what);
+	static void _bind_methods();
+
 public:
 public:
 	virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
 	virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); }
 	virtual String get_plugin_name() const override { return "GridMap"; }
 	virtual String get_plugin_name() const override { return "GridMap"; }
@@ -280,6 +287,15 @@ public:
 	virtual bool handles(Object *p_object) const override;
 	virtual bool handles(Object *p_object) const override;
 	virtual void make_visible(bool p_visible) override;
 	virtual void make_visible(bool p_visible) override;
 
 
+	GridMap *get_current_grid_map() const;
+	void set_selection(const Vector3i &p_begin, const Vector3i &p_end);
+	void clear_selection();
+	AABB get_selection() const;
+	bool has_selection() const;
+	Array get_selected_cells() const;
+	void set_selected_palette_item(int p_item) const;
+	int get_selected_palette_item() const;
+
 	GridMapEditorPlugin();
 	GridMapEditorPlugin();
 	~GridMapEditorPlugin();
 	~GridMapEditorPlugin();
 };
 };

+ 1 - 0
modules/gridmap/register_types.cpp

@@ -46,6 +46,7 @@ void initialize_gridmap_module(ModuleInitializationLevel p_level) {
 	}
 	}
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 	if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
 	if (p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
+		GDREGISTER_CLASS(GridMapEditorPlugin);
 		EditorPlugins::add_by_type<GridMapEditorPlugin>();
 		EditorPlugins::add_by_type<GridMapEditorPlugin>();
 	}
 	}
 #endif
 #endif