Notifications
Clear all

[Closed] how to use the same object in each button ?

Hello.

In the code below I create two buttons. I wanted to use the same object that I could update and use to setup data in each button. But I hit the wall. If I try to use object already created in my struct, inside button Event, I get:

Runtime error: Struct member access requires instance: _dataContainer <<

with this code:


struct MyContainer
(
	public
	lockView = true
)

struct TestUI
(
	private
	text = "hello",
	_dataContainer = MyContainer(),
	
	public
	fn Create = 
	(
		rollout MainWindow "Test"
		(

			button GI_btn @" GI " width:100 _height:30 pos:[20,40]
			button Farm_btn @" FARM " width:100 height:30 pos:[20, 70]
			
			/* EVENTS ---------------------------------------- */
			on GI_btn pressed do
			(
				_dataContainer.lockView = true
			)
				
			on Farm_btn pressed do
			(
				messagebox (_dataContainer.lockView as string)
			)
		)
		
		createDialog MainWindow 200 200
	)
)
_ui = TestUI()
_ui.Create()

Now if I modify the code:


struct MyContainer
(
	public
	lockView = true
)

struct TestUI
(
	private
	text = "hello",
	
	public
	fn Create _dataContainer= 
	(
		rollout MainWindow "Test"
		(

			button GI_btn @" GI " width:100 _height:30 pos:[20,40]
			button Farm_btn @" FARM " width:100 height:30 pos:[20, 70]
			
			/* EVENTS ---------------------------------------- */
			on GI_btn pressed do
			(
				_dataContainer.lockView = true
			)
				
			on Farm_btn pressed do
			(
				messagebox (_dataContainer.lockView as string)
			)
		)
		
		createDialog MainWindow 200 200
	)
)
_my = MyContainer()
_ui = TestUI()
_ui.Create _my

and try to pass data thru function and then use them in button events, i get:

Compile error: No outer local variable references permitted here: _dataContainer

So, how to correctly pass the same object into each button so I could work with the same data in each ?

3 Replies

I can modify code like this:


struct MyContainer
(
     public
     lockView = true
)

struct TestUI
(
     private
     text = "hello",
  
     public
     fn Create = 
     (
         rollout MainWindow "Test"
         (
             local _dataContainer = MyContainer()
             button GI_btn @" GI " width:100 _height:30 pos:[20,40]
             button Farm_btn @" FARM " width:100 height:30 pos:[20, 70]
  
             /* EVENTS ---------------------------------------- */
             on GI_btn pressed do
             (
                 _dataContainer.lockView = true
             )
  
             on Farm_btn pressed do
             (
                 messagebox (_dataContainer.lockView as string)
             )
         )

         createDialog MainWindow 200 200
     )
 )
_ui = TestUI()
_ui.Create()

and it will work perfectly.

Now lets create different setup:


struct MyContainer
(
    public
    lockView = true
)

struct TestUI
(
    private
    text = "hello",
    _data = MyContainer(),
    _buttonsRollout,
    _buttonsRolloutName = "Buttons",
    _optionsRollout,
    _optionsRolloutName = "Options",


    public
    fn Create = 
    (
        rollout _buttonsRollout _buttonsRolloutName
        (
            /* UI elements ---------------------------------------- */
            button GI_btn @" GI " width:60 height:30 pos:[20,10]
            button Farm_btn @" FARM " width:60 height:30 pos:[100, 10]
 
            /* EVENTS ---------------------------------------- */
            on GI_btn pressed do
            (
                messagebox (_data.lockView as string)
            )
 
            on Farm_btn pressed do
            (
                messagebox (_data.lockView as string)
            )
        )
        rollout _optionsRollout _optionsRolloutName
        (
            /* UI elements ---------------------------------------- */
            button GI_btn @" GI " width:60 height:30 pos:[20,10]
            button Farm_btn @" FARM " width:60 height:30 pos:[100, 10]
 
            /* EVENTS ---------------------------------------- */
            on GI_btn pressed do
            (
                messagebox (_data.lockView as string)
            )
 
            on Farm_btn pressed do
            (
                messagebox (_data.lockView as string)
            )
        )

        MainWindow = newRolloutFloater "Bake Utils" 200 200
        addRollout _buttonsRollout MainWindow
        addRollout _optionsRollout MainWindow
    )
)
_ui = TestUI()
_ui.Create()

Now I would like to acces the same data not only in buttons but also in both rollouts.
In this example adding “local _dataContainer = MyContainer()” to first rollout will not help. If I define MyContainer as global it will work , but I don’t want to do this. If rollout can use private variable from struct as its name, why it can’t use variable in button event ?

Probably because the scope is different when evaluating fn Create than from within the rollout event after creation.

Another way would be to make the structure member _dataContainer public and use an on open event to assign the structure to a local variable within each rollout:

struct MyContainer
(
    public
    lockView = true
)

struct TestUI
(
    private
    text = "hello",
    _buttonsRollout,
    _buttonsRolloutName = "Buttons",
    _optionsRollout,
    _optionsRolloutName = "Options",


    public
	_data = MyContainer(),
    fn Create = 
    (
        rollout _buttonsRollout _buttonsRolloutName
        (
			local parent
			
			on _buttonsRollout open do
			(
				parent = this
			)
			
            /* UI elements ---------------------------------------- */
            button GI_btn @" GI " width:60 height:30 pos:[20,10]
            button Farm_btn @" FARM " width:60 height:30 pos:[100, 10]
 
            /* EVENTS ---------------------------------------- */
            on GI_btn pressed do
            (
                messagebox (parent._data.lockView as string)
            )
 
            on Farm_btn pressed do
            (
                messagebox (parent._data.lockView as string)
            )
        )
        rollout _optionsRollout _optionsRolloutName
        (
			local parent
			
			on _optionsRollout open do
			(
				parent = this
			)
			
            /* UI elements ---------------------------------------- */
            button GI_btn @" GI " width:60 height:30 pos:[20,10]
            button Farm_btn @" FARM " width:60 height:30 pos:[100, 10]
 
            /* EVENTS ---------------------------------------- */
            on GI_btn pressed do
            (
                messagebox (parent._data.lockView as string)
            )
 
            on Farm_btn pressed do
            (
                messagebox (parent._data.lockView as string)
            )
        )

        MainWindow = newRolloutFloater "Bake Utils" 200 200
        addRollout _buttonsRollout MainWindow
        addRollout _optionsRollout MainWindow
    )
)
_ui = TestUI()
_ui.Create()

Or is this what you were trying to avoid?

1 Reply
(@mantragora)
Joined: 10 months ago

Posts: 0

In Python/C# there is no problem with something like this.

That’s what I wanted. I missed somewhere in documentation that you can use “this” keyword.

Thanks.