Poco-extension. Hidden button is always clicked

Hello!
I have a button which enable only on some screens. But when I click on it via poco it is clicking as if it exists always. I tried to use exists() method, but it always returns true.
In my script I see that button enable programmatically
gui.set_enabled(back_icon_node, true)
How to validate this condition in test?

It was a long time since I used the interface, but if I recall correctly, the gui nodes should have properties.

Looking at the code it seems the “enabled” property was left out.

As a workaround, you should be able to call into Lua from your python script and check if the node in question is enabled.

Example 1 which runs in the context of the server. (go or gui)

Example 2 (same context as above)

Can this be fixed in the extension or do we need to add something to our C SDK?

The fix should be in the engine, as it’s the one providing the properties.

1 Like

Thanks for the answer, Mathias. I tried to run this:

cbk = poco.agent.rpc.call("Execute", "gui.is_enabled('back_icon_node')")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

But result is None.

1 Like

Ok, strange.
And you are running the poco server in the game form inside the gui script?

Sorry, I missed this moment. It’s needed to add additional poco server for gui script? I already have it in main script.

As mentioned, the call you make is made within the context of the server (in game).

So, if your server is started in your main.script (go), you cannot use “gui.*” functions.
And vice versa.

It’s seems to me it’s inconvenient. It’s possible to start server in multiple scripts?

I don’t know. I guess you can try, as long as you set different ports for each server?

1 Like

Ok. Perhaps not enough information I provided. I will try to collect all about my case.
In app I have gui script with such code:

local function update_top_bar(self, animate)
...
local back_icon_node = gui.get_node("back_icon")
...
gui.set_enabled(back_icon_node, false)

I have added poco-server in init and update functions of gui script.

function update(self, dt)
	poco:server_loop()
	poco:set_view_proj(get_view_proj()) 
	poco:set_gui_view_proj(get_gui_view_proj())
end
function init(self)
...
poco:init_server(15004)

Also added functions to get get projections:

local camera = require "render.camera"
local function get_view_proj()
	local view = camera.get_view(nil)
	local proj = camera.get_projection(nil)
	return proj * view
end
local function get_gui_view_proj()
	local x, y = camera.get_window_size()
	local mat = vmath.matrix4_orthographic(0, x, 0, y, -1, 1)
	return mat
end

Then I maked sure that everything is ok by test of clicking on any button. Now I try to get state of button ‘back_icon’ I have tried this:

cbk = poco.agent.rpc.call("Execute", "gui.is_enabled('back_icon_node')")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

and

cbk = poco.agent.rpc.call("Execute", "gui.is_enabled('back_icon')")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

Python test script (now I use windows app)

import sys
import unittest

from poco.drivers.std import StdPoco
from poco.utils.device import VirtualDevice

import util

options, args = util.parse_arguments(sys.argv)

options.address = "127.0.0.1"

device = VirtualDevice(options.address)

poco = StdPoco(addr=(options.address, options.port), device=device, use_airtest_input=False)

cbk = poco.agent.rpc.call("Execute", "gui.get_position(back_icon_node)")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

But result is always None. Would be glad any additional information.

I haven’t tried this myself, but maybe you actually need to return something?

poco.agent.rpc.call("Execute", "return gui.is_enabled('back_icon')")

Edit: Yes, looks like that’s the way: https://github.com/defold/extension-poco/blob/master/poco/lua/defold-poco.lua#L89-L96

1 Like

Thanks for advise. I tried this but it has no effect.

It’s because the code isn’t valid gui.* code.
The gui.is_enabled(node) takes a node, not an id.

cbk = poco.agent.rpc.call("Execute", "return gui.is_enabled(gui.get_node('back_icon'))")

I’ve also updated the master branch of the extension with another example.
Select the gui_server/main.collection as the main collection, and start the game.
Then run the python script examples/example_execute_gui.py and it should print out the enabled state of the two gui boxes:

users/mawe/extension-poco $ python examples/example_execute_gui.py                                                         [master] 11:14:35
[rpc]connected
Execute: result: 'False'
Execute: result: 'True'
Done

Yes! It works!
Now I add clicking on button ‘Merge Masters’ which enables ‘back_icon’ button

poco(text='Merge Masters').click()
cbk = poco.agent.rpc.call("Execute", "return gui.is_enabled(gui.get_node('back_icon'))")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

But in this case I get result ‘None’.

1 Like

You might need to wait for the click to be done?

I added time.sleep(5) before rpc call. Also I leaved only sleep without clicking. In this case result of rpc call is always ‘None’

time.sleep(5)
cbk = poco.agent.rpc.call("Execute", "return gui.is_enabled(gui.get_node('back_icon'))")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

Did you update the extension-poco to the latest version? (the master.zip)
I tried to add better error handling there (not sure if it helped though)

Also, you can try the example function I added in the main.gui_script:

	poco:set_dispatch_fn("GuiIsEnabled", function(id)
		print("INSIDE GuiIsEnabled FUNCTION!",id)
		return gui.is_enabled(gui.get_node(id))
	end)

Called from python:

cbk = poco.agent.rpc.call("GuiIsEnabled", "back_icon")
cbk.wait()
print("Execute: result: '%s'" % cbk.result)

For further info, I recommend you debug the defold-poco.lua file

Sorry missed this. Now updated. In last case with sleep I got error:
Execute: result: 'Failed to run 'return gui.is_enabled(gui.get_node('back_icon'))'. Error: [string "return gui.is_enabled(gui.get_node('back_icon'))"]:1: You can only access gui.* functions and values from a gui script instance (.gui_script file)'

This is what I meant earlier. "gui." functions can only be used in the context of gui scripts (and vice versa for go. functions)

It seems you’re sending the call to a .script ?
You previously had a server running on a separate port in the .gui_script, where did that go?