[Closed] Populating dropdown list
I need to populate a dropdown list with all the scene cameras. Which that part is simple.
But the problem I’m coming across is if someone creates a camera after the dialog has been opened. What do you guys thing would be the best way to re-populate the dialog?
My first thought is a selection callback function.
Here is the base of the script so far.
(
camArray = for i in cameras where superclassof i == Camera collect i.name
rollout drop_roll "Drop Down List"
(
dropdownlist obj_dd "Objects :" offset:[0,-20] items:camArray
)
createDialog drop_roll
)
I wrote and posted a script here for adding materials to SME. I used a dotnet combobox and created a function to collect items as an array, clear the combobox list, and populate it with the current state of the array. I then ran that function on dialog open and combobox DropDown. That ensured any time it is expanded it will have the current list of items.
-Eric
This is a sample of what I was going for using callbacks but for some odd reason it wont work…
(
global drop_roll
camArray = for i in cameras where superclassof i == Camera collect i.name
rollout drop_roll "Drop Down List"
(
dropdownlist obj_dd "Objects :" offset:[0,-20] items:camArray
fn fnUpdateCamList =
(
print "cool"
camArray = for i in cameras where superclassof i == Camera collect i.name
drop_roll.obj_dd.items = camArray
)
on drop_roll close do (callbacks.RemoveScripts #nodeCreated id:#camUpdate)
on drop_roll open do
(
callbacks.addScript #nodeCreated "drop_roll.fnUpdateCamList()" id:#camUpdate
)
)
createDialog drop_roll
)
#nodeCreated is not right callback in your case… the better one is #sceneNodeAdded. it fires on Undo/Redo as well as on Create.
i modified your code a little to support #delete:
global drop_roll
try (destroydialog drop_roll) catch()
rollout drop_roll "Drop Down List"
(
dropdownlist obj_dd "Objects :" offset:[0,-20] items:#()
fn updateCamList action: = if (action == #collect) or iskindof (node = callbacks.notificationParam()) Camera do
(
format "action:%
" action
drop_roll.obj_dd.items = for c in cameras where (action != #delete or c != node) and (iskindof c Camera) collect c.name
)
on drop_roll close do (callbacks.RemoveScripts id:#camUpdate)
on drop_roll open do
(
callbacks.addScript #sceneNodeAdded "drop_roll.updateCamList action:#add" id:#camUpdate
callbacks.addScript #nodePreDelete "drop_roll.updateCamList action:#delete" id:#camUpdate
updateCamList action:#collect
)
)
createDialog drop_roll
You will need to add callbacks for nameChanged and deleted, or it won’t properly update the list. Here is a sample of what I used using dotnet combobox:
(
try (destroyDialog drop_roll) catch()
rollout drop_roll "Drop Down List"
(
dotNetControl obj_dd "System.Windows.Forms.ComboBox" height:22
-- When the ComboBox selection is changed change do something
fn dd_fill =
(
-- Collect the Cameras into an array
camArray = for i in cameras where superclassof i == Camera collect i.name
-- Clear the ComboBox list
obj_dd.items.clear()
-- Build a new ComboBox list using the view array
obj_dd.items.addrange camArray
)
on drop_roll open do
(
--Fill on open
dd_fill()
)
on obj_dd DropDown do
(
--Fill on expanding the list
dd_fill()
)
on obj_dd SelectedIndexChanged do
(
--Command to execute on selecting the entry
select (getNodeByName obj_dd.text)
)
)
createDialog drop_roll height:30
)
You should be able to set the Combobox to a dropdown only item, but can’t get the DropDownStyle to continue showing the list when trying to change it.
-Eric
unknown property: “fnUpdateCamList” in Rollout:drop_roll
Anubis:
Goin in that way (using the General Event Callback Mechanism)
you should add more callbacks:
#nodeCloned – to catch cloned objects too
#sceneNodeAdded – to catch merged objectsIn the new NodeEventCallback (added in Max 2009)
you can do this with 1 callback,
and its more precise – catch even undo/redo operations.
Just as mention Anubis has recently just mentioned the nodeCallback function which was implemented into 3ds max 2009.
i don’t like callbacks… slow pc… so when i have more callbacks it’s even slower
camthing = #("------Select Camera------")
sceneCam = for o in cameras where classof o != TargetObject collect o
sceneCamNames = camthing + (for o in sceneCam collect o.name)
rollout ""
(
dropdownList ddl_cam "" pos:[105,1] width:18 height:21 items:sceneCamNames toolTip:"Select Scene Cams."
on ddl_cam selected i do
(
if ( i > 0 ) then try(select sceneCam[i-1])catch(
sceneCam = for o in cameras where classof o != TargetObject collect o
sceneCamNames = camthing + (for o in sceneCam collect o.name)
RappaToolsUI.ddl_cam.items = sceneCamNames
)
if ( i == 1 ) then
(
sceneCam = for o in cameras where classof o != TargetObject collect o
sceneCamNames = camthing + (for o in sceneCam collect o.name)
RappaToolsUI.ddl_cam.items = sceneCamNames
)
)
)