[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 ?
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?
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.