Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Rollout, Functions and scope

Rollout, Functions and scope

alexandre_bisewski
Enthusiast Enthusiast
2,172 Views
12 Replies
Message 1 of 13

Rollout, Functions and scope

alexandre_bisewski
Enthusiast
Enthusiast

Hey guys!

 

I am missing something simple here. 

I have one rollout with a textbox _name inside and a button. So on click in this button  we call a function like fn EditName= that need to insert some text in this textbox _name...

 

So if I put the function before the rollout I will not receive the error about an undefined function but I will receive the error undefined button!!! Even I put the function after the rollout I will not receive the error undefined button but now I will receive the error undefined function. 

 

One way that I can solve it is putting the code of this function inside the rollout button on pressed. But I will need to call this same functions in other parts of the code so doesn't make sense to do it.

 

What I am missing here?

 

Thank you

0 Likes
Accepted solutions (4)
2,173 Views
12 Replies
Replies (12)
Message 2 of 13

alexandre_bisewski
Enthusiast
Enthusiast

oww...I think that Denis was answered before it here:

https://forums.autodesk.com/t5/3ds-max-programming/how-to-declare-a-function-in-maxscript/td-p/10990...

 

I need to declare a Global before everything.

0 Likes
Message 3 of 13

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

For starters, just consider that any control handler is the same as a function.
Max Script only allows direct definition, so each function can only use previously defined elements (controls, locals, functions, etc.).
(this is not exactly true, but follow this rule to get started).

So, the rollout with your functionality can look as:

try(destroydialog rol) catch ()
rollout rol "RO:1F5D40FA" width:191
(
	button set_text_bt "Set Text" width:60
	edittext edit_tx width:100 align:#center
	
	fn setEditText text = 
	(
		edit_tx.text = text
	)
	on set_text_bt pressed do setEditText (if keyboard.controlPressed then "CONTROL" else "DEFAULT")
	on set_text_bt rightclick do setEditText "RIGHTCLICK"
	

	on rol open do
	(
	)
)
createdialog rol

 

0 Likes
Message 4 of 13

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

There may be a situation when it is impossible to arrange elements in specific order (for example when some controls are dynamically created). In this case you can pass a control to the function which defined before:

try(destroydialog rol) catch ()
rollout rol "RO:1F5D40FB" width:191
(
	fn setEditText text control: = 
	(
		control.text = text
	)

	button set_text_bt "Set Text" width:60
	edittext edit1_tx width:100 align:#center
	edittext edit2_tx width:100 align:#center
	
	on set_text_bt pressed do setEditText (if keyboard.controlPressed then "CONTROL" else "DEFAULT") control:edit1_tx
	on set_text_bt rightclick do setEditText "RIGHTCLICK" control:edit2_tx
	

	on rol open do
	(
	)
)
createdialog rol
Message 5 of 13

alexandre_bisewski
Enthusiast
Enthusiast

Hi Denis...Thank you again for your attention.

 

I am creating all the function out of the rollout braces.

 

I am only put inside the rollout the on events click a clicked button.

 

So looking for your sample I can see that I am wrong. I need to put all functions relationed with that rollout inside? 

 

Thank you

 

0 Likes
Message 6 of 13

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

Another option I try to avoid (due to its hard-to-understand nature) is to use the full path to the rollout elements, including the rollout itself as the root of the path:

try(destroydialog rol) catch ()
rollout rol "RO:1F5D40FC" width:191
(
	button set_text_bt "Set Text" width:60
	
	on set_text_bt pressed do 
	(
		rol.setEditText1 (if keyboard.controlPressed then "CONTROL" else "DEFAULT")
	)
	on set_text_bt rightclick do rol.setEditText2 "RIGHTCLICK"
	
	fn setEditText1 text = 
	(
		rol.edit1_tx.text = text
	)
	fn setEditText2 text = 
	(
		rol.edit2_tx.text = text
	)
	edittext edit1_tx width:100 align:#center
	edittext edit2_tx width:100 align:#center

	on rol open do
	(
	)
)
createdialog rol
Message 7 of 13

denisT.MaxDoctor
Advisor
Advisor

whatever the case may be, always remember to stick to the golden rule of coding - 'the simpler, the better' 😉

0 Likes
Message 8 of 13

alexandre_bisewski
Enthusiast
Enthusiast

All my code is like it:

 

--variables declarations

 

--Functions  --functions that need to be declarated before the rollout because will be used by some control in these rollouts

 

--Rollouts

(

    on btn pressed=()

)

--CreateDialog...

--addsubrollout...

 

--Functions that need to be declarated after because will use some control from these rollouts. 

 

This scope is wrong?

 

 

 

 

 

Message 9 of 13

denisT.MaxDoctor
Advisor
Advisor

If methods (functions) are related to the dialog functionality and work with its items, it is better to place all these methods in the dialog body. 
If the methods are general purpose and not directly related to the rollout, it is better to take them out of the body of the rollout.
In any case, you should aim for the tool to generate a minimum of new global elements (functions, variables, etc.).

0 Likes
Message 10 of 13

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

@alexandre_bisewski wrote:

...

This scope is wrong?

 


not wrong, but amateurish.

 

It would be more professional to consolidate everything into a single structure. I've demonstrated various approaches on different forums, but to sum it up in a few lines, it could be something like:

 

global MyTool_Name
(
	struct MyTool_Name_Struct
	(
	/*
	private
		-- private methods and variables
	*/
	public
		-- public methods and variables
		
		dialog = 
		(
			rollout dialog "My Dialog"
			(
			)
		),
		fn destroy = 
		(
			-- store settings, destroy dialog and delete data
		),
		fn create = 
		(
			-- initialize data, load settings, ...
			createdialog dialog
		),
		on create do
		(
		)
	)
	
	MyTool_Name = MyTool_Name_Struct()
	ok
)
/*
MyTool_Name.create()
*/

 

Message 11 of 13

alexandre_bisewski
Enthusiast
Enthusiast

holly molly...What is this code? 

 

Man, I really need to study more...

 

Basically if I understand you are creating everything inside a class.  This is your class: global MyTool_Name

After you are creating the structure of this class and in the end you are starting it:MyTool_Name.create()

 

I will study it more...

 

Thank you Denis!

0 Likes
Message 12 of 13

denisT.MaxDoctor
Advisor
Advisor

@alexandre_bisewski wrote:

Basically if I understand you are creating everything inside a class.  This is your class: global MyTool_Name

After you are creating the structure of this class and in the end you are starting it:MyTool_Name.create()

 


MyTool_Name is an instance of the MyTool_Name_Struct structure. Since there's usually no need to create more than one instance of the tool, we only create it once. Everything is contained within MyTool_Name_Struct, but it's defined in a local scope, and the definition itself remains local. Thus, only the MyTool_Name variable is global, enclosing everything needed for the tool to function.

Message 13 of 13

alexandre_bisewski
Enthusiast
Enthusiast
0 Likes