ScriptSpot

Forum topic · General Scripting

How permanently save a text written in an EditText and added in a ListBox?

By Michele71 · 2010-09-20

Description

As written in the title, how permanently save a text written in an EditText and added in a ListBox? (when I reopen the rollout, the text written before is present in the listbox)

Below is my example:

-----------------------------------------------------------------



rollout t "test"
(
	listbox l1 "" items:#()
	edittext ed1 "" 
	button b "Insert Name in ListBox"
	button s "Save Text in Listbox"
	
	
	on b pressed do
	(
		if txt != "" do 

(
l1.items = append l1.items (ed1.text as string)
l1.selection = l1.items.count
ed1.text = ""
)

)
	
on s pressed do
(
-- How save the text???	
)
	

)
createdialog t

------------------------------------------------------------

Waiting for help, a greeting from
Michele

Question off topic:
how to write script code in discussions?

Comments (15)

Michele71 · 2010-09-21

For Anubis@:
You have another solution to resolve this problem??? it's nice to know if there is another way.... :) :)

Graph · 2010-09-21

printAllElements is nessecary to print out arrays with more than n (15 or so) items.
you might have noticed before that when you print an array to the listener the ..) at the end, thats what has been written to the reg too so it crashed. with printAllElements every single element is written; you can either en/disable it globally or like i did use it to "encase" an expression

furthermore in the first codeblock you again forgot the lineBreak ( ; )
..execute val ; if classOf..

happy it works

Michele71 · 2010-09-21

I am happy for your great help you gave me Insanto!!!

I completed the script part with the ability to delete the text from listbox...



if l1.items.count > 0 and l1.selection > 0 do
l1.items = deleteItem l1.items l1.selection	

Michele71 · 2010-09-21

Thanks Insanto!!! This update works fine:) :)

Today during my tests I've written:


ListBoxControl :(local val = functions.gIs RO.name i.name if val != undefined AND classOf val == String do val = execute val if classOf val == array do i.items = val

but I did not understand that this was necessary also:


ListBoxControl : (with printAllElements true functions.sIs RO.name i.name i.items)

while I was writing:


ListBoxControl : (functions.sIs RO.name i.name i.items)

In fact the script was not working...

Thank you again Insanto! :)

P.S: I can explain the part that I skip to write?

( /* automated loading and

Graph · 2010-09-21


(
	/*
		automated loading and saving of UISettings for a complete Rollout
		make sure to not rename your rollout and/or UIItems between dev versions or the settings wont transfer
		simply include the struct and its local var in the header of your index scriptFile
		
		use the functions as demonstrated in the rolllout-example
	*/
	
	local functions
	struct temp 
	(
		val = 0 --dont change
		,
		gIs = fn gIs Category Key File:"Settings" =  
		(
			
			local type, val, key1
			
			registry.createKey HKEY_CURRENT_USER ("Software\\ROSettings\\"+File as string + "\\" + Category as string) accessRights:#all newKeyCreated:&newKeyCreated key:&key1
			
			registry.queryValue key1 (Key as string) type:&type value:&val
			
			val
		)--END gIs FN
		,
		sIs = fn sIs Category Key Val File:"Settings" del:false = 
		(
			try
			(
				local newKeyCreated , key1
				
				registry.createKey HKEY_CURRENT_USER ("Software\\ROSettings\\"+File as string + "\\" + Category as string) accessRights:#all newKeyCreated:&newKeyCreated key:&key1
				
				if not del then
				(
					registry.setvalue key1 (Key as string) #REG_SZ (Val as string)
				)
				else
				(
					registry.deleteKey key1
				)
			)
			catch
			(	
				print (registry.getLastError())	
			)
		)--END sIs FN
		,
		saveROSettings = fn saveROSettings RO =
		(
			local items = RO.controls
			
			for i in items do
			(
				print (classOf i)  --uncommend to find out the classes of the UI items
				
				case classOf i of
				(
					SpinnerControl : (functions.sIs RO.name i.name i.value)
					
					ColorPickerControl : (functions.sIs RO.name i.name i.color)
					
					CheckBoxControl : (functions.sIs RO.name i.name i.checked)
					
					CheckButtonControl : (functions.sIs RO.name i.name i.checked)
					
					RadioControl : (functions.sIs RO.name i.name i.state)
					
					ListBoxControl : (with printAllElements true functions.sIs RO.name i.name i.items)
					
				)--END classes cases
			)--END items loop
		)--END saveROSettings FN
		,
		getROSettings = fn getROSettings RO =
		(
			local items = RO.controls
			
			for i in items do
			(
				case classOf i of
				(
					SpinnerControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == float OR classOf val == integer do i.value = val
					)
					
					ColorPickerControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == color do i.color = val
					)
					
					CheckBoxControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == BooleanClass do i.checked = val
					)
					
					CheckButtonControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == BooleanClass do i.checked = val
					)					
					
					RadioControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == float OR classOf val == integer  do i.state = val
					)					
					
					ListBoxControl :
					(
						local val = functions.gIs RO.name i.name 
						if val != undefined AND classOf val == String do val = execute val 
						if classOf val == array do i.items = val
					)
					
				)--END classes cases
			)--END items loop
		)--END getROSettings FN
	)
	functions = temp val:1
	
	rollout testRO ""
	(
--  		spinner spinner1
--  		
--  		colorPicker colorpck1
-- 		
-- 		checkBox checkbox1 "what?"
-- 		
-- 		checkbutton checkbutton1 "check this"
-- 		
-- 		radiobuttons radioButtons1 "choices" labels:#("btn1", "btn2")
-- 		
		listbox lb1 "dynamic LB"
		
		button lb1Fill "Fill LB with mat names"
		
		on lb1Fill pressed do
		(
			lb1.items = for mat in meditMaterials collect mat.name
		)
		
		on testRO open do
		(
			functions.getROSettings testRO
		)
		
		on testRO close do
		(
			functions.saveROSettings testRO
		)
		
	)--END RO
	
	createdialog testRO
	
)

this one now includes a working example of how to store/restore items in a listbox between sessions.
it only deals with that part tho
obviously you also want a description going with the ior value so i'd suggest some seperator you can later take the strings appart by with the filterstring function, a semicolon comes to mind as people most probably wont include that in the name.
thing with storing and restoring strings is the interpretation. i made a little function to help with that (converts an array to a string containing verbatim signed array items)


		fn modArr arr =
		(
			local res = "#("
			for i = 1 to arr.count do
			(
				item = arr[i]
				res +=  "@\"" + item + "\""
				if i < arr.count do res += ", "
			)
			res += ")"
			res
		)--END modArr FN

using that you can store/restore any stringArray savely to ini or reg without having to worry about string literals

Michele71 · 2010-09-21

Hello Anubis and Insanto.
Now explain better what I want;

I am creating a script where there is a text list (listbox) with names and values relate to the IOR (index of Reflection). Now the list is very long and I am dividing into categories (metal, liquid, fabric etc.). While I was writing the list (to see in the listbox) I thought: Is possible update the list? If I want to add a new material IOR how to do? It 'like to create presets: I select the category "Metal" and I add a new name text in this category...
Now, with the example shown at start post, I could write the text and add it in ListBox. But when I closed (and reopen) rollut, the text disappeared. I decided to create a save button to this function...But how to save the text permanently?
Example Insanto is good, but I find it difficult to arrange the array in the script, while Anubis, I must find the text the next opening script... I hope that I explained :) :)

I have ListBox whit IOR value
I have the spinner to adjust IOR in the material (or something like)
I'll update the listbox with new IOR text

....

Hi and thanks again from Michele :)

Anubis · 2010-09-21

Hi Insanto,
do not understand me wrong. Access to registry from Max is a good feature, but personally I see sense to use it only if I need to interact with Windows environment, so I prefer ini files ;-)

P.S. - Here I add a simple example for Michele to get started with ini files.

rollout roExample "Example INI sets"
(
	-- set INI location to the script location
	local iniFile = getFilenamePath (getSourceFileName()) + "example.ini"
	
	listbox theList "" items:#()
	
	on roExample open do -- read INI on open
	(
		if doesFileExist iniFile do (
			data = GetINISetting iniFile "Settings" "ListItems"
			-- convert the string to array of strings:
			data = filterString data ","
			theList.items = data
		)
	)
	on roExample close do -- save to INI on close
	(
		str = ""
		for i in theList.items do append str (i + ",")
		setINISetting iniFile "Settings" "ListItems" str
	)
)
createDialog roExample

-- to see how it works, you can run next tests (line by line):
roExample.theList.items = #("hello","abc","xyz","102")
DestroyDialog roExample
edit (getFilenamePath (getSourceFileName()) + "example.ini")
createDialog roExample

Cheers

Graph · 2010-09-21

because the registry is independent of the max version and user config and i dont mess with anything i always create new ones. ini files are all good n fine but for my taste to mediocre :P

Anubis · 2010-09-21

I really wonder why the peoples mess with registry keys for that purpose... Never mind...

Hi Michele,
I'm not sure what exactly you ask. If you need to store the items in memory (for the active session only), then you need only a variable. Example:

-- just create a global variable (array) where to store the strings
if savedData == undefined do global savedData = #()

if classOf roExample == RolloutClass do DestroyDialog roExample

rollout roExample "Example"
(
	listbox theList "" items:#()
	edittext theInput ""
	button btnAdd "Add" width:60 align:#left across:2
	button btnRem "Remove" width:60 align:#right
	
	-- get saved data on start up
	on roExample open do (theList.items = savedData)
	
	on btnAdd pressed do -- add NEW item
	(
		str = theInput.text
		if str.count > 0 do (
			append savedData str
			theList.items = savedData
			theList.selection = savedData.count
		)
	)
	
	on btnRem pressed do -- delete SELECTED item
	(
		itm = theList.selection
		if itm > 0 do (
			deleteItem savedData itm
			theList.items = savedData
		)
	)
)
createDialog roExample

And if you need to keep this data for the next sessions, just spend a little time to study read/write INI files ;-)

Michele71 · 2010-09-21

Thanks Again. Today try with your advice :)

And yes, "The night produce advice"

Graph · 2010-09-21

the classOf val you want is array not integer or items

..  do val = execute val ;  ..

--sleep helps ;)

Michele71 · 2010-09-20

Thanks Insanto. The link works and I have already done tests. I have added:


ListBoxControl : (functions.sIs RO.name i.name i.items) -- and

ListBoxControl :(local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val if classOf val == items OR classOf val == integer do i.items = val)

But dont work. I've been careful to the initial instructions. The problem is append word written EditText as array in items listbox...I can not understand where I am wrong...

Graph · 2010-09-20

? I checked the link and it leads to the "Save/Load UIItem's values" article.

you just have to add the editText UI control to the cases (the Items's class) to make it work for your purpose
it prints the classes (of all UIItems of the supplied RO) when the RO is closed; to the listener

in case the link doesnt work for you heres the code:


(
	/*
		automated loading and saving of UISettings for a complete Rollout
		make sure to not rename your rollout and/or UIItems between dev versions or the settings wont transfer
		simply include the struct and its local var in the header of your index scriptFile
		
		use the functions as demonstrated in the rolllout-example
	*/
	
	local functions
	struct temp 
	(
		val = 0 --dont change
		,
		gIs = fn gIs Category Key File:"Settings" =  
		(
			
			local type, val, key1
			
			registry.createKey HKEY_CURRENT_USER ("Software\\ROSettings\\"+File as string + "\\" + Category as string) accessRights:#all newKeyCreated:&newKeyCreated key:&key1
			
			registry.queryValue key1 (Key as string) type:&type value:&val
			
			val
		)--END gIs FN
		,
		sIs = fn sIs Category Key Val File:"Settings" del:false = 
		(
			try
			(
				local newKeyCreated , key1
				
				registry.createKey HKEY_CURRENT_USER ("Software\\ROSettings\\"+File as string + "\\" + Category as string) accessRights:#all newKeyCreated:&newKeyCreated key:&key1
				
				if not del then
				(
					registry.setvalue key1 (Key as string) #REG_SZ (Val as string)
				)
				else
				(
					registry.deleteKey key1
				)
			)
			catch
			(	
				print (registry.getLastError())	
			)
		)--END sIs FN
		,
		saveROSettings = fn saveROSettings RO =
		(
			local items = RO.controls
			
			for i in items do
			(
				print (classOf i)  --uncommend to find out the classes of the UI items
				
				case classOf i of
				(
					SpinnerControl : (functions.sIs RO.name i.name i.value)
					
					ColorPickerControl : (functions.sIs RO.name i.name i.color)
					
					CheckBoxControl : (functions.sIs RO.name i.name i.checked)
					
					CheckButtonControl : (functions.sIs RO.name i.name i.checked)
					
					RadioControl : (functions.sIs RO.name i.name i.state)
					
				)--END classes cases
			)--END items loop
		)--END saveROSettings FN
		,
		getROSettings = fn getROSettings RO =
		(
			local items = RO.controls
			
			for i in items do
			(
				case classOf i of
				(
					SpinnerControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == float OR classOf val == integer do i.value = val
					)
					
					ColorPickerControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == color do i.color = val
					)
					
					CheckBoxControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == BooleanClass do i.checked = val
					)
					
					CheckButtonControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == BooleanClass do i.checked = val
					)					
					
					RadioControl : 
					(
						local val = functions.gIs RO.name i.name ; if val != undefined AND classOf val == String do val = execute val
						if classOf val == float OR classOf val == integer  do i.state = val
					)					
					
				)--END classes cases
			)--END items loop
		)--END getROSettings FN
	)
	functions = temp val:1
	
	rollout testRO ""
	(
 		spinner spinner1
 		
 		colorPicker colorpck1
		
		checkBox checkbox1 "what?"
		
		checkbutton checkbutton1 "check this"
		
		radiobuttons radioButtons1 "choices" labels:#("btn1", "btn2")
		
		
		on testRO open do
		(
			functions.getROSettings testRO
		)
		
		on testRO close do
		(
			functions.saveROSettings testRO
		)
		
	)--END RO
	
	createdialog testRO
	
)

Michele71 · 2010-09-20

Be a coincidence, but today I was looking at your great site congratulations ;)
And thank you for the answers that you gave me. Now check your link!

Very thanks Insanto!!! :) :)