Notifications
Clear all

[Closed] Rollout from Struct – Access buttons/fields

Hello All!

I am reworking a script for my company, and i was looking into ways of restructuring a very long, linear script (over 4k lines) into something more manageable, using Struct’s and “includes”.

so far, most of the script had been restructured using the workflow mentioned above, and works as expected, using hard-coded approach, where i call/set things directly. Now, this is time to try and hook it all up with my UI, that had also been separated into its own Struct.

I can create and show my Rollout, but i seem to struggle with understanding of how to get to my buttons, drop-down menus, etc… from my main script… Unfortunately, i cannot show majority of my code here, due to company’s policy, (sorry :bowdown: ), but here is a pseudo code i wrote to help and illustrate my confusion.

include @"struct\ViewUtils.ms"
myUi = Sview()
buttonsFromUi = myUi.getRollout()
buttonsFromUi.saveSpline
on buttonsFromUi.saveButton pressed do (
	print "save was pressed"
	)
	-- cannot access the state of the button, get an error :
	-- Type error: Call needs function or class
	
-- When i run buttonsFromUi = myUi.getRollout() i get
	--"Rollout:jtMakeModularRig"" - name of my rollout
-- when i run	buttonsFromUi.saveButton return is: 
	-- "ButtonControl:saveButton"

	
myUi.show() -- function that shows the UI (works fine)

The getRollout() function is called via myUi.show() func, and INIT’s my UI,

anyone has a suggestion on what approach i should take? thanks for view this guys, appreciate any feedback.

9 Replies

first of all is to forget about ‘include’ option(technique)… it was a blind idea in the mxs.

structures… i have an examples on this forum how to make a tool by using just only one struct. no extra globals. only one struct

your company policy is absolutely right but it will be much helpful for you to show a mxs snippet than a ‘pseudo’ code

@denisT: Thanks for reply Denis. here is a stripped version of my UI, i got rid of everything, except for a button, and left everything wrapped in a struct. COPY/PASTE should be fine to make this work.

struct rigUi
(
	fn getRollout =
	(
		rollout rigRollout ("Rigger") width:200 height:575
		(
			edittext charName "Character name:" labelOnTop:false pos:[10,25] visible:true
			dropdownlist module "Add module: " items:#("Core","Spine","Head") pos:[10,60]
			label parent "Parent: " width:40 pos:[10,105]
			button pressMe "Press me" width:140 pos:[50,105]
		)
	return rigRollout
	),
	fn show =
	(
		try(destroyDialog rigRollout) 
		catch()
		newRollout = getRollout()
		createDialog newRollout	
	)
)

this file was saved in the same folder as my other scripts as “ViewUtils.ms”

If you could explain to me in a few words or point to your thread where you talk about proper ways to “include”, that would be great, i was reading the MAX-Doc and there are few suggestions to use “include” or “fileIn”.

Here is the code that i wrote to test and try to get something out of my button. In reality, i would getting some data from the user/scene, but in this test, i would like to atleast get this button to print something for me.

include @"ViewUtils.ms"
myUi = rigUi()
myRollout = myUi.getRollout()
myButton = myRollout.pressMe

on myButton pressed do (
	print "Press Me - Ok"
)

myUi.show()

I am coming from python, and therefore i understand that my button inside the ViewUtils should trigger/send some sort of callback to get INITed in once the UI-object was created, but not sure what should i do here, in maxscript.

Thanks again, for a quick reply.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

that’s another reason to show your code. i’m doing pretty well in python. it’s much easier to answer when i know the question.
you’ve asked about a wide wrapping scruct sample:
http://forums.cgsociety.org/showthread.php?f=98&t=1091058&highlight=world

To access roll-out controls within a struct, it is not sufficient to simply spawn the roll-out: you need a variable name assigned to the roll-out, so the controls can be accessed as children of the variable.

struct rigUi
(
	
	myRolloutHoldingVariable,
	
	fn getRollout =
	(
		this.myRolloutHoldingVariable=rollout rigRollout ("Rigger") width:200 height:575
		(
			edittext charName "Character name:" labelOnTop:false pos:[10,25] visible:true
			dropdownlist module "Add module: " items:#("Core","Spine","Head") pos:[10,60]
			label parent "Parent: " width:40 pos:[10,105]
			button pressMe "Press me" width:140 pos:[50,105]
		)
	return rigRollout
	),
	fn show =
	(
		try(destroyDialog rigRollout) 
		catch()
		newRollout = getRollout()
		createDialog newRollout	
	)
)

myUi=rigUi()--declare the struct
mUi.myRolloutHoldingVariable
<undefined>--variable is undefined
myUi.getRollout()--getrollut
myUi.show()
mUi.myRolloutHoldingVariable
<Rollout:rigRollout>--variable is a rollout
mUi.myRolloutHoldingVariable.module.selected--retruns selected item of dropdownlist control

at least, that is how I accomplish it.
There may be more robust solutions.

@Mambo4: Thank you, i think this is what i had been looking for. i will try to implement it in my current workflow and see how this handles. In my attempts, i sort of started to think that way, however, instead of making a rollout via VAR, instead, i was INITing a var, but passing my functions from outside, (were plenty of errors). i will try your solution.

@DenisT: Thank you for the link, this is great stuff. now with the Mambo’s solution and your explanation and code breakdown it should be a little easier for me to tackle this task.

i will post back what i have been able to accomplish.

thanks again guys!

here is how i do it (you also can find some other sample on this forum).

struct dialogUI
(
	title = "Dialog",
	label = "i see you!",
	width = 200,
	pos = [800,200],
	dialog =
	(
		rollout dialog title 
		(
			local owner = if owner != undefined do owner
			label lb owner.label
		)
	),
	fn show = (createdialog dialog widht:width pos:pos),
	fn close = try(destroydialog dialog) catch(),
	on create do dialog.owner = this
)
(dialogUI()).show()

the scruct sees its dialog, and the dialog sees its owner struct

@DenisT – yes, i saw this OWNER in the post you linked me to. I got a little confused with communication between buttons, i got the idea of the RadioButtons, checkboxes, and dropdowns(list items), but how do you handle buttons that are being pressed?
in max-doc, i found a page that introduces the “myButton.pressed()” approach, however, once i define the class and call this method the result is undefined.
In the sample, however, the code is presented where “on MyButton pressed do” is defined. and then “.pressed()” method is available. But is there a way to have the button perform an action (the ON button PRESSED) called and passed to the rollout struct?

EDIT: here is the link from the Docs that i am referring to: Accessing Locals and Other Items

i don’t have max around so i will try to write blindfold…

struct dialogUI
 (
 	title = "Dialog",
 	label = "i see you!",
 	width = 200,
 	pos = [800,200],
	fn onButtonPressed = 
	(
		print "the button pressed!"
	),
 	dialog =
 	(
 		rollout dialog title 
 		(
 			local owner = if owner != undefined do owner
			button press_bt "Press" widht:100
 			label lb owner.label

			on press_bt pressed do owner.onButtonPressed()
 		)
 	),
 	fn show = (createdialog dialog widht:width pos:pos),
 	fn close = try(destroydialog dialog) catch(),
 	on create do dialog.owner = this
 )
 (dialogUI()).show()

so we are using the same pointer to the owner structure
[left][left] [/left]
[/left]

I always listen to Denis. He’s a God amongst us mortals

I do want to drop a minor word on the topic. I can’t remember what versions of Max did this for me… but if you have to support older versions you may run into a problem passing “this”. I haven’t had the issue in quite some time, but I think as recently as Max 2009 or 2008 it wasn’t passing as expected in some tools I was working on at the time. I don’t have those versions anymore so can’t really test anymore… and if your company is only using the latest versions it simply doesn’t matter.