Jump to content

how to use the same object in each button ?


Guest mantragora

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 ?

Link to comment
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
Link to comment
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
Link to comment
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
Link to comment
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 ?

Link to comment
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 :)

Link to comment
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 ?

Link to comment
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 :)

Link to comment
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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...