Jump to content
Sign in to follow this  
Guest mantragora

how to use the same object in each button ?

Recommended Posts

Guest mantragora

Hello.

3dsmax question.

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 ?

Share this post


Link to post
Share on other sites
Guest mantragora

I can modify code like this:

struct MyContainer
(
     public
     lockView = true
)

struct TestUI
(
     private
     text = "hello",

     public
     fn Create = 
     (
         rollout MainWindow "Test"
         (
             /* LOCAL data ---------------------------------------- */
             local _dataContainer = MyContainer()

             /* UI elements ---------------------------------------- */
             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 _data = 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 ?

Edited by mantragora

Share this post


Link to post
Share on other sites

have you tried accessing MyContainer directly, instead of making it a variable inside another struct?

EG: instead of

_dataContainer.lockView = true

try

MyContainer.lockView = true

Share this post


Link to post
Share on other sites

[dupe post thx singtel]

Edited by cpb

Share this post


Link to post
Share on other sites
Guest mantragora

have you tried accessing MyContainer directly, instead of making it a variable inside another struct?

EG: instead of

_dataContainer.lockView = true

try

MyContainer.lockView = true

yeah, I get

Unknown property: "lockView" in #Struct:MyContainer(

lockView:<data>; Public) <<

when I do this

on GI_btn pressed do
(
    messagebox (MyContainer.lockView as string)
)

Any other ideas ? :)

Edited by mantragora

Share this post


Link to post
Share on other sites

Are you using Max? :)

What are you trying to do? Trying to reduce code duplication for similar rollouts? You can do stuff like:

rollout myrollout ""
(
    filein "rollout controls.ms"
)

Share this post


Link to post
Share on other sites
Guest mantragora

Are you using Max? :)

Nope 1. I'm trying to convince myself that I made mistake by assuming that Max is really sh*ty application. There must be a reason all those flies out there use this sh*t.

What are you trying to do? Trying to reduce code duplication for similar rollouts?

Nope 2. I want to use/have access to the same data in each rollout. That's why I need to pass the same instance to each. Button one sets some data, saves file. Button two can use the same data, modify it and save file with different name. It has to be this way since this object will be passed into 10 other objects before going into buttons. Some will modify it, others will use to it to set own dat etc.

Edited by mantragora

Share this post


Link to post
Share on other sites

lol in that case why not use a global struct? There is nothing wrong in using a global struct.

I like having nested structs like:

Framework.Math.Sqrt etc.

Share this post


Link to post
Share on other sites
Guest mantragora

lol in that case why not use a global struct? There is nothing wrong in using a global struct.

Well, yeah, but I don't need to use this anywhere beside those rollouts so I would like to avoid putting anything in global scope. I'm really curious why variable that is perfectly visible in scope below can't be used in events. That's something really obvious to do. Is there really no other way to pass the same data into two rollouts that are placed in one RolloutFloater ?

Share this post


Link to post
Share on other sites

I think that has to do with the rollout being local and not able to correctly reference the function's argument to the rollout.

There are lots of corner cases like this in maxscript, that's why the compiler is made to catch them because they know about them :)

Share this post


Link to post
Share on other sites
Guest mantragora
... because they know about them :)

F**K

Legend:

** = UC

Edited by mantragora

Share this post


Link to post
Share on other sites

lol I reported many issues before but they don't care. They only added public/private inside structs recently but it's useless :)

Share this post


Link to post
Share on other sites
Guest mantragora

lol I reported many issues before but they don't care. They only added public/private inside structs recently but it's useless :)

So I suppose this would be better solution for situation like this ?

dotNetObject "System.Windows.Forms.Form"
dotNetObject "MaxCustomControls.MaxForm"

Or are there similar problems with passing into .Net too ?

Share this post


Link to post
Share on other sites

Oh yes, MaxForm is good. I actually made a Form that inherits from MaxForm for internal Max hooks, and used it exclusively for all my tools.

It has different issues, but ones I would prefer over mxs dialogs.

The key is to implement most things on the .NET side. You can use the Max .NET SDK with it. That's what I did :)

Share this post


Link to post
Share on other sites

lol in that case why not use a global struct? There is nothing wrong in using a global struct.

I like having nested structs like:

Framework.Math.Sqrt etc.

yep the struct should be global. Nothing wrong with that.

Share this post


Link to post
Share on other sites
Guest mantragora

yep the struct should be global. Nothing wrong with that.

Only Max user can say that.

There are a lot things wrong with that ! If data is not needed anywhere beside some piece of code, it shouldn't be accessible everywhere. We are not in 70's anymore.

Pick any program and language out there and what I wanted to make here it will work without any problems.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×