Notifications
Clear all

[Closed] Changing the Selection of a Listbox

Hello, I have tried researching this many times. I have it down to where my selection in the scene changes. The problem is I can’t seem to find a way to change what is highlighted or selected in a list box.

I need this to change because my tool requires both to be updated in a list as when you finish pressing the button on one object in the scene it goes to the next in both.

Here is the way it currently works:

function RenameAssetButtonAction x = (
for s in selection do s.name = uniquename x
)


button theBatchButton "Batch" width:80 align:#right offset:[45,25]
on theBatchButton pressed do
(
	RenameAssetButtonAction theRenamingBox.items[theRenamingBox.selection]
	
	theSceneNamesBox.items = #()
	theSceneNamesBox.items = for g in theobjs collect g.name
	
	ItemCount = theSceneNamesBox.items.count
	theNextSceneCount = ((theSceneNamesBox.selection) + 1)
	firstSceneIndex = theSceneNamesBox.items[1]
	nextSceneIndex = theSceneNamesBox.items[theSceneNamesBox.selection+1]
	
	if theNextSceneCount > ItemCount then (
		select (getNodeByName firstSceneIndex)
		
	)
	else (
		select (getNodeByName nextSceneIndex)
	)
)

Any help is greatly appreciated and thank you for your time.

6 Replies

is it what what you looking for:

try(destroydialog rol) catch()
rollout rol "Test" width:191
(
	listbox names_lb items:#(#one, #two, #tree) width:182 height:8 align:#left offset:[-8,0] 
	label info_lb width:182 align:#left offset:[-8,0]
	button action_bt "Action" width:182 align:#left offset:[-8,0]
	
	on action_bt pressed do
	(
		i = names_lb.selection
		
		ss = stringstream ""
		
		format "% >> %\n" i names_lb.items[i] to:ss
		info_lb.text = ss as string
		
		i += 1
		if i > names_lb.items.count do i = 1
			
		names_lb.selection = i
	)
)
createdialog rol

YES THANK YOU SO MUCH! I will take it from here and post my end code in the comments. If I find anyone else posting about this in the forums I will also try to help them with this issue.

Thank you very very much you are the best.

As promised: here is how it fits

	on theBatchButton pressed do
	(
		RenameAssetButtonAction theRenamingBox.items[theRenamingBox.selection]

		theSceneNamesBox.items = #()
		theSceneNamesBox.items = for g in theobjs collect g.name

		ItemCount = theSceneNamesBox.items.count
		theNextSceneCount = ((theSceneNamesBox.selection) + 1)
		firstSceneIndex = theSceneNamesBox.items[1]
		nextSceneIndex = theSceneNamesBox.items[theSceneNamesBox.selection+1]

		i = theSceneNamesBox.selection

		i += 1
		if i > theSceneNamesBox.items.count do i = 1
			
		theSceneNamesBox.selection = i

		if theNextSceneCount > ItemCount then (
			select (getNodeByName firstSceneIndex)

		)
		else (
			select (getNodeByName nextSceneIndex)
		)
	)
	on theBatchButton pressed do
	(
		RenameAssetButtonAction theRenamingBox.items[theRenamingBox.selection]
		-- first of all 
		-- theRenamingBox.items[theRenamingBox.selection]
		-- for listBox control is the same as:
		-- theRenamingBox.items.selected

		theSceneNamesBox.items = #()
		-- this line is not necessary because at the next line you all items again:
		theSceneNamesBox.items = for g in theobjs collect g.name
		-- line above is not necessary if theobjs were not changed. 
		-- It makes sense to update the list at the moment when theobjs list was changed, 
		-- or names of objects in the list were changed.  
		
		ItemCount = theSceneNamesBox.items.count
		theNextSceneCount = ((theSceneNamesBox.selection) + 1)
		-- not the right time to set this variable, because we don't know yet the next selection index
		firstSceneIndex = theSceneNamesBox.items[1]
		nextSceneIndex = theSceneNamesBox.items[theSceneNamesBox.selection+1]
		-- the line above is not safe. The selection index might be higher that number of items
		-- firstSceneIndex and nextSceneIndex are not good names for the variables. They are not indexes, but more like base name pattern

		i = theSceneNamesBox.selection

		i += 1
		if i > theSceneNamesBox.items.count do i = 1
			
		theSceneNamesBox.selection = i

		if theNextSceneCount > ItemCount then (
			select (getNodeByName firstSceneIndex)

		)
		else (
			select (getNodeByName nextSceneIndex)
		)
		-- the block above is not safe as well. It would be better just as:
		/*
		nodes = getNodeByName theSceneNamesBox.selected all:on
		if nodes.count > 0 then select nodes else clearselection()
		*/
	)	

the final version can be:

	on theBatchButton pressed do undo "Rename & Select" on
	(
		sel = theSceneNamesBox.selection
			
		RenameAssetButtonAction theRenamingBox.selected
		theSceneNamesBox.items = for g in theobjs collect g.name -- (???. i'm not sure we have to do it here)
		
		theSceneNamesBox.selection = if sel < theSceneNamesBox.items.count then (sel + 1) else 1 

		nodes = getNodeByName theSceneNamesBox.selected all:on
		if nodes.count > 0 then select nodes else clearSelection()
	)

another critics above your tool logic…
you have an action:

function RenameAssetButtonAction x = 
(
        for s in selection do s.name = uniquename x
)

which means that all selected objects will be uniquely renamed using specified base name.

but what if they all or some of them already match this rule?
they will be renamed anyway with incremental indexes.
try youself:

delete objects

objs = for k=1 to 10 collect box()
print "  before:\n"
print objs

for obj in objs do obj.name = uniquename #box
print "  after:\n"
print objs

for obj in objs do obj.name = uniquename #box
print "  after:\n"
print objs

as a ‘dirty’ solution you can do something:

objs.name = #__temp_name
for obj in objs do obj.name = uniquename #box

I was reading over this in depth over and over and over again because I was trying to understand it. This is exactly what I was trying to do with it, I’m glad you were in my head because from the very start when I concepted this out on a white board, I wrote it more like what you put:

Example:

nodes = getNodeByName theSceneNamesBox.selected all:on
if nodes.count > 0 then select nodes else clearSelection()

I felt this could be said with one or two statements, but as I found myself Frankensteining code it seemed lengthier and lengthier. I saw things online of other tools, and I would change words that I used from the MaxScript API in order to get it to work. I must of had nearly 100 tabs open at a time trying to figure this out. This being my first “real” (as in I’m actually using it for something physically) script I can’t appreciate enough the editing that you did because this made my script go from 114 lines to 92. and it is much more clear for me to make comments on. I believe this is called coding with purpose lol.

Anyway, thanks dude for the level up in maxscript