Notifications
Clear all

[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
)

9 Replies

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

denisT – Your errored out when I tried to delete and object?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

what does it say?

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 objects

In 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.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

it’s not an error of my script. it’s an error of your old one.

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
			)
	)
)

from remusjuncu.com/rappatools/