Node inspector add buttons?

Godot Version

4.2.1

Question

Hello, is there a way to add buttons or Vcontainers in the node inspector ?
something like the " @export var " does but instead using buttons ?
I seemed to rebember a video were this was being made, but have forgoten ever since…

so far the button shows has text, and has an assign box ?

@tool
extends Node2D

@export var btn1 = Button.new();


func _init():
	add_child(btn1); # doesnt change anything...
	pass;

1 Like

To add a Button in the inspector you will want to read about inspector plugins to know how to add your own controls in the inspector or modify the inspector controls for some properties.

Here’s more information about how to make plugins.

You can see a quick implementation here Quick and dirty Godot 4.x plugin to add buttons to the inspector · GitHub

1 Like

You can see a quick implementation here Quick and dirty Godot 4.x plugin to add buttons to the inspector · GitHub

that is the part i cant make it work ?
i already have an “extends EditorPlugin”, but it adds “add_control_to_container”

@tool
extends EditorPlugin

const menuScene = preload("res://menu/menu.tscn");
const tileDrawNode = preload("res://test3/tileDrawNode.gd");
const tileDrawIcon = preload("res://test3/icon.png");

var dockedScene;

func _enter_tree():
	add_custom_type("TileDraw", "Node2D", tileDrawNode, tileDrawIcon );
	dockedScene = menuScene.instantiate();
	add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, dockedScene );
	dockedScene.custom_minimum_size = Vector2(10,0);

func _handles(object: Object) -> bool:
	return object is tileDrawNode

in the costum node:

@tool
extends Node2D

@export var btn1 = Button.new();


How are you adding this buttons ? and putting them on the inspector node ?

func _add_inspector_buttons() -> Array:
	var buttons = []
	buttons.push_back({
		"name": "Test button",
		"icon": preload("res://icon.svg"),
		"pressed": _on_test_button_pressed
	})
	buttons.push_back({
		"name": "Another button",
		"pressed": _on_another_button_pressed
	})
	buttons.push_back({
		"name": "Other button with lambda",
		"pressed": func(): print('Lambda callback')
	})
	return buttons

My “extends EditorPlugin” cant find “tileDrawNode” has a var ?
Were can the buttons node be created ? Either way in my case the buttons would be a part of the “dockedScene”

To add custom controls or modify the controls in the inspector you need to use an EditorInspectorPlugin as the documentation linked above says. I’m doing that here where it accepts the nodes that have a method called _add_inspector_buttons() here and, then, when the inspector starts to parse the node before adding all the properties, it executes that method which returns an Array of Dictionaries with the information needed to create the buttons here.

thanks,
but i dont understand…
i already have a extends EditorPlugin, that adds a costum node called “tileDrawNode”…

ive made a script “tileDrawInspector.gd”

@tool
extends EditorPlugin
#---------//----------
var tlDrawInspector = preload("res://addons/tiledrawtest2/tileDrawInspector.gd");
#---------//----------

func _enter_tree():
	add_custom_type("TileDraw", "Node2D", tileDrawNode, tileDrawIcon );
	dockedScene = menuScene.instantiate();
	add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, dockedScene );
	dockedScene.custom_minimum_size = Vector2(10,0);
	
	tlDrawInspector = tlDrawInspector.new();
	add_inspector_plugin(tlDrawInspector);

in the script tileDrawInspector.gd how do i add the tileDrawNode ?

extends EditorInspectorPlugin

func _can_handle(object):

In your example you seemed to add “class EditorButtonPlugin extends EditorInspectorPlugin:” below the extends EditorPlugin ?
do i have to hack it this way ? wont these functions go in conflict with each other ?

BTW… the manual also doesnt work, how iam suposed to know what a “random_int_editor.gd” is ?

It’s an inner class

No, you can have it in different scripts.

It’s the script example here

You don’t? Read the documentation of the EditorInspectorPlugin class to understand what each virtual method does and what you need to implement.

You re the one who doesnt seemed to understand… Theres a comflict in “extends EditorPlugin”, i dont know what it is…
But you seemed to skip that part in your code by adding “class EditorButtonPlugin extends EditorInspectorPlugin:” in the same place were “extends EditorPlugin” is being made…

@tool
extends EditorPlugin


var editor_button_plugin:EditorButtonPlugin


func _enter_tree() -> void:
	editor_button_plugin = EditorButtonPlugin.new()
	add_inspector_plugin(editor_button_plugin)


func _exit_tree() -> void:
	if is_instance_valid(editor_button_plugin):
		remove_inspector_plugin(editor_button_plugin)
		editor_button_plugin = null

##--------------- this always shows up in a diferent script--------------------------
##--------------- this always shows up in a diferent script--------------------------
##--------------- this always shows up in a diferent script--------------------------
class EditorButtonPlugin extends EditorInspectorPlugin: ##---- this always shows up in a diferent script


	func _can_handle(object: Object) -> bool:
		return object.has_method('_add_inspector_buttons')

Why dont you try putting this in your script instead…

@tool
extends EditorPlugin && extends EditorInspectorPlugin

Why is it not a normal thing, to create a plugin and add a custom node to it, wich that plugin handles, and have some options in the custom node inspector, relative to what that node does…? All the nodes in godot 4 are made in this way…

Ive read the manual but for some reason its not working,
this doesnt do anything, nothing changes in the inspector…

@tool
extends EditorPlugin

const menuScene = preload("res://menu/menu.tscn");
const tileDrawNode = preload("res://test3/tileDrawNode.gd");
const tileDrawIcon = preload("res://test3/icon.png");

#---------//---inspector---//---------

var tlDrawInspector #------inspector plugin tileDrawInspector.gd


var dockedScene;
var whatIsvisible;



func _enter_tree():
	add_custom_type("TileDraw", "Node2D", tileDrawNode, tileDrawIcon );
	dockedScene = menuScene.instantiate();
	add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, dockedScene );
	dockedScene.custom_minimum_size = Vector2(10,0);
	
	dockedScene.get_child(2).plugINget = dockedScene; #---deleted
	
	
	tlDrawInspector  = preload("res://addons/tiledrawtest2/tileDrawInspector.gd").new();
	add_inspector_plugin(tlDrawInspector);

.
.

-----> tileDrawInspector.gd <------------

extends EditorInspectorPlugin



func _handles(object: Object) -> bool:
	#return object.has_method('_add_inspector_buttons');
	return object is Control;


func _parse_begin(object):
	var Blabel = Label.new();
	Blabel.set_text("ksjdhfjksdhfjksdhjkfhjksdf");

	add_custom_control(Blabel);

The normal control node inspector doesnt display any label or button or text

doing it the ( normal way )
EditorPlugin creates and handles a costum node:
“add_custom_type(“TileDraw”, “Node2D”, tileDrawNode, tileDrawIcon );”

EditorInspectorPlugin:
cant find this node,

func _handles(object: Object) -> bool:
	return object is tileDrawNode;

loading the script or adding this node again doesnt work

[ edit ]
Ive made a mistake… in handle object
in “extends EditorPlugin”
handle is called this way: " _handles"

in EditorInspectorPlugin
its called “_can_handle”

this should work

@tool
extends EditorPlugin

const menuScene = preload("res://menu/menu.tscn");
const tileDrawNode = preload("res://test3/tileDrawNode.gd");
const tileDrawIcon = preload("res://test3/icon.png");

var dockedScene;

#---------//---inspector-editor--//---------
var tlDrawInspector = preload("res://addons/tiledrawtest2/tileDrawInspector.gd");



func _enter_tree():
	add_custom_type("TileDraw", "Node2D", tileDrawNode, tileDrawIcon );
	dockedScene = menuScene.instantiate();
	add_control_to_container(CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, dockedScene );

	tlDrawInspector  = tlDrawInspector.new();
	add_inspector_plugin(tlDrawInspector);


func _handles(object: Object) -> bool:
	return object is tileDrawNode
@tool
extends Node2D
class_name tileDrawX1;
extends EditorInspectorPlugin

func _can_handle(object):
	if ( object is tileDrawX1 ):
		return true;

func _parse_begin(object):
	var Blabel = Label.new();
	Blabel.set_text("ksjdhfjksdhfjksdhjkfhjksdf");
	add_custom_control(Blabel);

Its the only way i know of calling that costum node on to extends EditorInspectorPlugin
he creates a costum type here of Node2D:
add_custom_type(“TileDraw”, “Node2D”, tileDrawNode, tileDrawIcon );
if “Node2D” is removed the node doesnt show up when adding a new node