Registering clicks in the 3D viewport

Godot Version

4.2.1

Question

So I have the following code in my editor plugin script:

@tool
extends EditorPlugin
func _enter_tree():
         main_screen_changed.connect(screen_changed)

func _input(event):
	#mouse click
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
                      print( "mouse clicked -> " + str(EditorInterface.get_editor_main_screen( ))  )
				
                        var object = 	EditorInterface.get_edited_scene_root().find_child('object', false, false)
                         object.position = object.position + vector3(0,10,0)

func screen_changed(screen):
        print(screen)

here is my issue: when I click on the inspector dock or the scene dock or the “scripts” section of the main dock I get this message registering my click:
"mouse clicked → MainScreen:<VBoxContainer#81252059715> "
but I do not want to register a click on inspector or anywhere other than the 3D view, since I am modifiying objects that are clicked on. (in this example I move object up 10 on y-axis). How can I limit the registering of inputs ONLY in the main screen and only if we are looking at the 3D viewport.

TO NOTE:
interestingly, adding screen_changed function as I did DOES register when I switch the view from 2D, 3D, Script, AssetLib
which is weird because EditorInterface.get_editor_main_screen( ) gets just the main panel, whereas main_screen_changed.connect(screen_changed) gets the main panel’s current view (which is what I want!)

how do I do this? how to I get if we clicked in the MAIN SCREEN and only if we are n 3D VIEW???

for those who want to know, the solution is this custom fonction “get_main_screen()” which gets the editor interface and finds the buttons ( 2D, 3D, Script, AssetLib) and checks which one is pressed

#mouse click
func _input(event):
	#make sure we are in3D view
	if get_main_screen() != "3D":
		return

         if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
                         #do click stuff here
                         return

func get_main_screen()->String:
	var screen="null"
	var base:Panel = get_editor_interface().get_base_control()
	var editor_head:BoxContainer = base.get_child(0).get_child(0)
	if editor_head.get_child_count()<3:
		return screen
		
	var main_screen_buttons:Array = editor_head.get_child(2).get_children()
	for button in main_screen_buttons:
		if button.button_pressed:
			screen = button.text
			break
	return screen
2 Likes

Ive been trying to do the same thing…
Can you get the one on the manual working ?

signals

the editor main screen should have a name in this case i cant find it anywere

yes! in my original post I posted:

func screen_changed(screen):
        print(screen)

this will print “2D, 3D, Script or AssetLib” when you click on one of those buttons to change the view.
What I wanted however is which of these buttons are ALREADY pressed and not only when it is changed.
the solution I posted does this. Whenever “get_main"screen()” function is called, it will give you which “2D, 3D, Script or AssetLib” that is already pushed.

i couldnt get it working that way… cant rebember for sure but it was erroring some were.
in this case child(0) for 2D button… i wanted to check if the editor was on 2D mode
Also dont know if anyone can get the signal on the manual working ?

@tool
extends EditorPlugin


var mouseDEL = 0;


func _process(delta):
	
	if ( Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) && mouseDEL == 0 ):
		
		var top_2D = get_editor_interface().get_base_control().get_child(0).get_child(0).get_child(2).get_child(0) # child(1) for 3D

		if ( top_2D.button_pressed == true ):
			print( "\n2D button_on_TOP_of_that_Thing: " + str (  top_2D ) )


		mouseDEL = 1;

	if ( ! Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT)  && mouseDEL != 0 ):

		mouseDEL = 0;

btw "button_pressed " doesnt show on autocomplete

this worked fine for me:

@tool
extends EditorPlugin

func _input(event):
	
	if event is InputEventMouseButton:
		var top2d = get_editor_interface().get_base_control().get_child(0).get_child(0).get_child(2).get_child(0)
		
		if top2d.button_pressed == true:
			print( "we are in 2d screen")
'''
                #optional debugging: print when we are NOT in 2D screen
                else:
			print( "we are NOT in 2d screen")
'''

to note, I removed the var mouseDEL = 0; but you can put it back if you want to save variables when mouse is pressed.
more importantly, your code uses func _process(delta) and Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) whereas I am using func _input(event): and if event is InputEventMouseButton: to get mouse inputs. i think this might be your issue actually…
the code as is works fine for me.
I am in godot 4.2.1