PDA

View Full Version : the best way to open a rollout floater windows


prettyPixel
03-13-2005, 02:43 PM
Here are 3 script which make apparement the same thing: open a new rollout floater window.
I found these various versions in the documentation and the examples.
What are the differences between these three programs?

Is it beter to use try and catch instead of "if myScriptFloater != undefined" ?

In many case the line "try(destroyDialog myScript)catch()" don't exist in example scripts.
Why ? This operation is made by default when we close the script ?


rollout myScript "myScript"
(
-- code
)
try (closerolloutfloater myScriptFloater)catch()
myScriptFloater = newRolloutFloater "myScript" 162 128
addRollout myScript myScriptFloater rolledUp:false

rollout myScript "myScript"
(
-- code
)
if myScriptFloater != undefined do ( closerolloutfloater myScriptFloater )
myScriptFloater = newRolloutFloater "myScript" 162 128
addRollout myScript myScriptFloater rolledUp:false

rollout myScript "myScript"
(
-- code
)
try(destroyDialog myScript)catch()
createDialog myScript 162 128

Can anyone enlighten me on this?
I would appreciate all answers.

Bobo
03-13-2005, 07:09 PM
Here are 3 script which make apparement the same thing: open a new rollout floater window.
I found these various versions in the documentation and the examples.
What are the differences between these three programs?



Sample scripts are not fully functional scripts. They are intended to give you an IDEA how to use something, not work in production.

If you try to create a new Floater or Dialog before closing an existing one, you might get two. This is not something you want, so usually you are responsible for closing before opening.

Now there is a slight difference in the real-world. The question is - where does the variable LIVE - is it a local variable in a MacroScript, is it a global variable?

Here are some ideas:

If you are testing stuff (like in the examples you posted), the rollout variable AND the floater variable are obviously implicitly global (as there are no outer scopes above their definition).
This means that you cannot have two scripts that try to open a dialog in a variable called myScriptFloater. You would have to give these variables (both the rollout and the floater) reasonably descriptive names related to the things the script does.

If you are creating a MacroScript, this is a different story.
A MacroScript defines a local scope known (and documented) as Private Global. This means that the scope is local relatively to MAXScript, but once created, it persists until MAX is closed. So local variables created in the root of a MacroScript live until you shut down MAX, just like global variables do. Because of that, you could declare the vatiable to hold the rollout or floater inside that scope and it would always be there, so you could access it and close the floater or dialog if necessary.

I personally prefer to declare the floater or dialog's rollout as global, giving it a long descriptive name. This gives me a way to directly access anything inside the utility from the Listener or from other scripts if necessary.

There is also the question WHEN to destroy the dialog or floater.
I think that the best order would be

MacroScript Test category:"Test"
(
global LongDescriptiveName_Rollout
try(destroyDialog LongDescriptiveName_Rollout)catch()
rollout LongDescriptiveName_Rollout "Test Rollout"
(
label do_nothing "Just a placeholder"
)--end rollout
createDialog LongDescriptiveName_Rollout
)--end macro

*Evaluate this and place on a toolbar.
*If you would press the button multiple times, the dialog will close correctly.
*While the dialog is open, evaluate the script source again.
*Press the button.
RESULT: The old dialog closes, a new one replaces it.


Now, while the previous dialog is still open, evaluate this:

MacroScript Test category:"Test"
(
global LongDescriptiveName_Rollout
rollout LongDescriptiveName_Rollout "Test Rollout"
(
label do_nothing "Just a placeholder"
)--end rollout
try(destroyDialog LongDescriptiveName_Rollout)catch()
createDialog LongDescriptiveName_Rollout
)--end macro

The only difference is that the closing of the dialog happens AFTER the definition of the rollout. Unfortunately, in this case the rollout is re-declared (and creates a new unique rollout instance, different from the previous one), so the destroyDialog call is applies to the new instance of the rollout, and leaves a copy of the old one open!
If you would press the button multiple times, the NEW dialog will close and open correctly, but if you are bug-hunting during a script development, you might end up with multiple orphaned dialog copies after each new Cltr+E of the source code!
Interestingly, since in this case the destroyDialog ALWAYS sees a valid defined rollout, you don't need the try()catch() at all! But the above drawback during debugging is a good reason to close dialogs before defining their rollouts...

The same happens when the rollout variable is declared as local (Private Global) on top of the MacroScript definition:

MacroScript Test category:"Test"
(
local LongDescriptiveName_Rollout2
rollout LongDescriptiveName_Rollout2 "Test Rollout"
(
label do_nothing "Just a placeholder"
)--end rollout
try(destroyDialog LongDescriptiveName_Rollout2)catch()
createDialog LongDescriptiveName_Rollout2
)--end macro

Opening and closing the dialog after the first evaluation (or after restarting max) works great, but if you would reevaluate the code (because you had to fix an error for example), a previously opened dialog by this script would be left orphaned and will not be closed before opening a new one.

So I suggest, at least in the case of destroyDialog, to place the closing code right after the variable declaration, and use a long descriptibe GLOBAL variable to store the dialog's rollout.

In the case of CloseRolloutFloater, both a try()catch() and if ... == undefined do() are valid choices. I find typing try()catch() faster, and since I am usually developing under time pressure, simpler typing is what I prefer ;)

Note that the main difference between newRolloutFloater and createDialog is that the newRolloutFloater creates a new instance of a Rollout Floater class, while createDialog takes an EXISTING instance of a rollout class and TURNS it into a dialog. So the location of the closing code relatively to the rollout definitions in the case of a Floater has no role. It just has to be done BEFORE creating the new floater...

Hope this helps a bit.

prettyPixel
03-14-2005, 02:32 AM
Fantastic ! Many thanks for this answer very useful. Really excellent. :thumbsup:

I followed the examples and now I understand importance of the order to remove or to add an rollout.

I have also tried to apply it for multiple rollout in a floating rollout windows.
Note the inverse order during removing the additional rollout.
I hope this code correct:

MacroScript Test category:"Test"
(
global LongDescriptiveNameFloater
global LongDescriptiveName1_Rollout
global LongDescriptiveName2_Rollout

try(removeRollout LongDescriptiveName2_Rollout)catch()
try(removeRollout LongDescriptiveName1_Rollout)catch()
try(closerolloutfloater LongDescriptiveNameFloater)catch()

rollout LongDescriptiveName1_Rollout "Test Rollout 1"
(
label do_nothing "Just a placeholder"
)--end rollout

rollout LongDescriptiveName2_Rollout "Test Rollout 2"
(
label do_nothing2 "Just a placeholder2"
)--end rollout

LongDescriptiveNameFloater = newRolloutFloater "LongDescriptiveName" 162 128
addRollout LongDescriptiveName1_Rollout LongDescriptiveNameFloater rolledUp:false
addRollout LongDescriptiveName2_Rollout LongDescriptiveNameFloater rolledUp:false
)--end macro


So you have answered to my question... and about the macroscipts at the same time.
This answer could be really useful for others maxscript beginners like me.
Do you have anything against me posting a link to this thread in "Post Your best Max Programing tuts. here!" ?
That seems to me a good place

have a good day,
PrettyPixel

CGTalk Moderation
03-14-2005, 02:32 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.