[Closed] MAXscript interface continuity
I am working with MAXscript interfaces for several purposes and often come across the problem that if I make a plug-in object by inheriting from a standard object, or if I make a scripted utility, then the interface will not remain the same when I switch tab and go back or when I re-open a file. To make clear what I mean, I have two often occuring examples of this.
The first is a pickbutton in a plug-in node that first shows the text “select object”, but after selection shows the name of the object. Changing the caption of the pickbutton is done with an event, but if I switch from the modifier tab to the create tab and then back, then the caption has been resetted to “select object”. Interface elements whose state is linked to an object parameter work fine, but things like this caption do not.
The second example is a scripted utility that has some checkboxes. If I save my scene, close 3dsmax and then open the scene again in a new instance of 3dsmax, then the checkboxes will automatically reset to their default instead of to the state when I saved them.
How can I solve such interface consistency problems?
Thanks in advance for looking at my question!
I didn’t work with scripted utilities and plugin-objects for a long time.
But in customAttributes I keep some parameters to store the interface state.
I use the open handler of the rollout to restore the last state of the rollout with its buttons, checkboxes etc.
maybe this can be done with your tools, too.
Georg
rdg is right, you will need to store the string for the pick button in a #string parameter and on the opening of the rollout you will have to set that parameter. Maybe something like this.
on theRollout open do
(
if theString!="" then thePickButton.text=theString
)
I am using something like the methods PEN and rdg describe already, but it is quite cumbersome to do so, as I need to write extra code for each interface element. Is there no way to do this automatically?
Something like a $_SESSION for rollouts?
Never heard of.
But maybe this could be implemented by collecting all rollout elements “on close”.
<rollout>.controls
might help.
Georg
This doesn’t need to be done for all interface ellements. In the case of a checkBox for instance…
parameters params rollout:theRollout
(
theCheckBoxState type:#boolean ui:theCheckBox animatable:false
)
rollout theRollout "TheRollout"
(
checkBox theCheckBox "The CheckBox"
)
The state of the check box will be stored in the parameter block and is connected directly to the UI item. There is no need in cases like this to do anything extra when the rollout opens.
A pickButton can be linked to a node param, but you’ll need to use autoDisplay for the node’s name to show up.
parameters params rollout:theRollout
(
theNode type:#node ui:theNodePicker
)
rollout theRollout “TheRollout”
(
pickButton theNodePicker autoDisplay:true
)
Ah, that nicely solves the problem for this specific situation.
Is there a similar solution for updating lists of objects?
AFAIK, the only way to automatically link multiple nodes to ui controls is to use multiple pickButtons, like so: (and this probably only works for fixed array sizes)
parameters params rollout:theRollout
(
theNodeList type:#nodeTab tabSize:2 tabSizeVariable:false ui:(theNodePicker1, theNodePicker2)
)
rollout theRollout "TheRollout"
(
pickButton theNodePicker1 autoDisplay:true
pickButton theNodePicker2 autoDisplay:true
)
If you want to use a listbox instead of multiple pickButtons, you’d need something like this:
parameters params rollout:theRollout
(
theNodeList type:#nodeTab tabSize:0 tabSizeVariable:true
-- update the multiListBox when the nodeTab has changed
on theNodeList tabChanged change tabIndex tabCount do this.theRollout.updateNodeList()
)
rollout theRollout "TheRollout"
(
-- filter used by pickButton. Prevents duplicate entries
fn filterUnique obj = findItem this.theNodeList obj == 0
multiListBox lstNodeList
pickButton btnAdd "Add" across:2 filter:filterUnique
button btnRemove "Remove"
-- function to update the multiListBox
fn updateNodeList = lstNodeList.items = for obj in theNodeList collect obj.name
-- add/remove nodes
on btnAdd picked obj do append theNodeList obj
on btnRemove pressed do
(
-- collect all nodes that aren't selected
theNodeList = for i = 1 to theNodeList.count where not lstNodeList.selection[i] collect theNodeList[i]
)
-- update the multiListBox when the rollout is opened
on theRollout open do updateNodeList()
)