[Closed] Combobox: edit text when "ENTER" pressed
Problem is explained better in this post !
Hey,
I was just fooling around in maxscript and wanted an easy and visual way to edit items in an array.
So I used a combobox but I can’t seem to get how you can change an item.
I think it should be as simple as you select your item in the list, the focus automatically jumps to the edit field and there you type the new name and when pressed “enter” the item (string) value would be changed.
But whenever I press enter the list item doesn’t change and if I reselect the same item the edit text box just resets to the orriginal name.
For the second question, and bare with me because I don’t know the official terms.
Is there a way to create a variable name (the thing you use to adress it) from the content of another variable string.
An example:
temp = "OBJ_selection"
-- code that changes "OBJ_selection" to a variable
OBJ_selection = selection -- where OBJ_selection would now be a variable
I fear the second thing will not be possible but maybe it is ^^
A third question is about creating custom attributes (spinner + slider ) that I add through maxscript with the following code:
ctrl1 type:#float ui:(ctrl1SPINNER,ctrl1SLIDER)
local range=[-30,30,0]
spinner ctrl1SPINNER "" range:range align:#right width:40
slider ctrl1SLIDER "variable1" range:range width:100 offset:[0,-25]
but now I wonder if it would be possible to change the range of the sliders with the parameter editor after it has been created ?
Or if that wouldn’t be possible, if they could be accessed through maxscript and to recreate the parameter editor!
Thanks in advance people!
(and sorry if it isn’t clear, just say and I will try to explain it clearer )
Hi Tom,
in response to your third question, I think it’s not going to be possible to use the Parameter Editor directly, but I guess you could use an Object in combination with the Parameter Editor as a ControlObject if thats what you wanted In that case just grab the info off of the Object and put it on the spinner.range.
The other way I see is to put it into the Maxscript Rollout itself:
rollout spinnerTestRollout "spinnerTestRollout"
(
local range=[-30,30,0]
edittext etRange "ChangeRange:" text:(range[1] as string+","+range[2] as String+","+range[3] as String)
spinner ctrl1SPINNER "" range:range align:#right width:40
slider ctrl1SLIDER "variable1" range:range width:100 offset:[0,-25]
on etRange changed cString do
(
-- filter the string so you get an array with all 3 "Numbers", note they are still string
cStringFiltered = filterstring cString ", "
-- check the amount of numbers in the array, since the range only works with 3
if cStringFiltered.count == 3 do
(
-- check if all values are convertable to a valid int to avoid errors
if cStringFiltered[1] as Integer != undefined AND cStringFiltered[2] as Integer != undefined AND cStringFiltered[3] as Integer != undefined do
(
-- put the strings into a point3 and convert them to integer
newRange = [cStringFiltered[1] as Integer,cStringFiltered[2] as Integer,cStringFiltered[3] as Integer]
-- give the new range to the spinner and slider
ctrl1SLIDER.range = newRange
ctrl1SPINNER.range = newRange
)
)
)
)
Createdialog spinnerTestRollout
I guess for the second question you could do something like taking the “Obj_selection” String and use a FileStream to write it into a .ms file and then filein the .ms file later on. To me this method feels a bit dirty tho.
I’ll take a look on your other question when I get some time later today.
Hope that helped you a little.
~Markus
On Number 2 (variable from string): you can do it, but would need to dynamically build the code as a string and the execute the string. See this thread for more information on the topic.
-Eric
this is what I’ve gotten from BoBo replies in the thread Eric has posted:
abc = 123
execute "abc"
theVal = 42 --new variable with the value you want in abc
-->42
execute("abc" + "=" + theVal as string) --assing as part of the execute
-->42
abc --check abc, it is 42 now
-->42
but is is the same as simply using:
abc = 123
theVal = 42
abc = theVal
The precise reason I’m willing to create a variable from a string is that I want to create a spinner through maxscript. But I want the user to have control about how the slider would be named, for when they want to acces it via wire parameters. And these names would be stored in a string array.
test_stringName = "SliderSpinner_A"
ca=attributes SpinnerSliderControl
(
parameters params1 rollout:params
(
-- ctrl1 must be 'test_stringname as string'
ctrl1 type:#float ui:(ctrl1SPINNER,ctrl1SLIDER)
)
rollout params rolloutName
(
local range=[-30,30,0]
spinner ctrl1SPINNER "" range:range align:#right width:40
slider ctrl1SLIDER "" range:range width:100 offset:[0,-30]
)
)
I found a solution to the first problem, which is that I used a .NET list and when double clicked a new edit dialog box opens up.
On the variable name problem I’m still a bit stuck,
j = 1
execute (("myBox" + j as string) + " = Box()")
myBox1.position = [50,0,0]
-- this works and the box is on [50,0,0]
-- however this doesn't:
execute (stringName + " = type:#float ui:(ctrl1SPINNER,ctrl1SLIDER)")
and this is the code that works and adds a slider + spinner who are linked to the selection.
ca=attributes SpinnerSliderControl
(
parameters params1 rollout:params
(
ctrl1 type:#float ui:(ctrl1SPINNER,ctrl1SLIDER)
)
rollout params "Controls"
(
local range=[-90,90,0]
spinner ctrl1SPINNER "" range:range align:#right width:40
slider ctrl1SLIDER "" range:range width:100 offset:[0,-25] )
)
custAttributes.add $.modifiers[1] ca
But in this code when I try to wire to this slider it will be adressed as “ctrl1” and I want the name to be chosen up front which is then stored in a string Variable!
as i understand you want to have multiple similar by functionality and type parameters controlled by one set of UI controls. Which parameter has to be controlled is by users choice.
i already told on this forum that there is no way to change scripted plug-in or cust attributes parameter block on the fly. the only way is to rebuild whole parameter block with new definition of plug-in or cust attribute.
so the solution for you is to make all alternative parameters in advance. and make a method to bind a parameter with ui control(s).
here is a sample how to do it (at least in some cases i use this solution):
global test_attrib = attributes "Test Data" attribID:#(0x1cabed9b, 0x5551de47)
(
local vals = #(#val_1,#val_2,#val_3,#val_4)
parameters main rollout:params
(
control_id type:#index default:1 ui:ui_control_id animatable:off
val_1 type:#float default:0 ui:ui_val_1 animatable:on
val_2 type:#float default:0 ui:ui_val_2 animatable:on
val_3 type:#float default:0 ui:ui_val_3 animatable:on
val_4 type:#float default:0 ui:ui_val_4 animatable:on
on control_id set id do
(
local c = getpropertycontroller this vals[id]
if this.params.ui_val_sl.controller != c do this.params.ui_val_sl.controller = c
if this.params.ui_val_sp.controller != c do this.params.ui_val_sp.controller = c
)
)
rollout params "Parameters"
(
label lb_val_1 "Value 1:" across:2 align:#right offset:[10,0]
spinner ui_val_1 fieldwidth:50 align:#right offset:[6,0] enabled:off
label lb_val_2 "Value 2:" across:2 align:#right offset:[10,0]
spinner ui_val_2 fieldwidth:50 align:#right offset:[6,0] enabled:off
label lb_val_3 "Value 3:" across:2 align:#right offset:[10,0]
spinner ui_val_3 fieldwidth:50 align:#right offset:[6,0] enabled:off
label lb_val_4 "Value 4:" across:2 align:#right offset:[10,0]
spinner ui_val_4 fieldwidth:50 align:#right offset:[6,0] enabled:off
dropdownlist ui_control_id "Current: " items:#("Value 1","Value 2","Value 3","Value 4") width:59 align:#right offset:[6,0]
slider ui_val_sl "" width:96 ticks:0 align:#left offset:[-8,0] across:2
spinner ui_val_sp "" fieldwidth:50 align:#right offset:[6,2]
on params open do
(
local c = getpropertycontroller this vals[control_id]
ui_val_sl.controller = c
ui_val_sp.controller = c
)
)
on create do
(
for p in vals do setpropertycontroller this p (createinstance linear_float)
)
)
(
delete objects
b = box isselected:on
emp = emptymodifier name:"Data 1"
addmodifier b emp
custattributes.add emp test_attrib
)
i added disabled spinners to UI just to show that the binding works correct. in the real solution we don’t need them.
you can see that i do the assigning of controllers on CREATE (or postcreate) event, and binding on Rollout OPEN event and control_id SET event. so it makes the binding undoable and changeable from outside.
Did you read through the thread I linked to? You will need to have the tool build the code as a string and then execute it. Or you will need to have the code modify/rebuild the CA definition.
At least those are the only ways I can think of doing it,
-Eric
I also read over the execute() thread, very nice info. But came to the same conclusion. Execute works fine for most cases. But as soon as you use it to create a spinner etc. inside the parameters or rollout it does not seem to work.
So I wrote out what I meant yesterday with the filestream. Its pretty much the same thing that PiXeL_MoNKeY just mentioned I guess :).
-- spinner and ctrl names
spinnerVarName = "imASpinner"
spinnerCtrlName = "mySpinner"
-- Defining the folder and scriptname for the rollout
cScriptDir = "c:\\scriptTest\\"
cScriptName = "testRollout.ms"
-- create directory
makeDir cScriptDir all:true
-- filepath
cScriptFilePath = (cScriptDir + cScriptName)
-- create the .ms file
cScriptFileStream = createFile cScriptFilePath
format "ca=attributes SpinnerSliderControl
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "parameters params1 rollout:params
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "% type:#float ui:(%,ctrl1SLIDER)
" spinnerCtrlName spinnerVarName to:cScriptFileStream
format ")
" to:cScriptFileStream
format "
" to:cScriptFileStream
format "rollout params \"Controls\"
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "local range=[-90,90,0]
" to:cScriptFileStream
format "spinner % \"\" range:range align:#right width:40
" spinnerVarName to:cScriptFileStream
format "slider ctrl1SLIDER \"\" range:range width:100 offset:[0,-25]
" to:cScriptFileStream
format ")
" to:cScriptFileStream
format ")
" to:cScriptFileStream
close cScriptFileStream
include cScriptFilePath
-- just for the purpose of testing
cObj = $testObj
custAttributes.add cObj.modifiers[1] ca
Even though I don’t like this solution too much, its working
I hope this is helpful in a way.
It would be nice to see another “cleaner” solution to the problem.
~Markus
@starsybil: vbmenu_register(“postmenu_7073225”, true); Thank you but I tried to get your code working but somehow it crashes on line 40 : “custAttributes.add cObj.modifiers[1] ca” and the error: Unknown property: “modifiers” in undefined
I have a simple box with the name testObj and an Attribute holder added selected.
@denisT: Thank you, I’ve gotten a new way to look at things which will be a cool learning experience. But the problem isn’t solved that way, when I run your script the names that are accessed are still the ones you define here:
val_1 type:#float default:0 ui:ui_val_1 animatable:on
val_2 type:#float default:0 ui:ui_val_2 animatable:on
val_3 type:#float default:0 ui:ui_val_3 animatable:on
val_4 type:#float default:0 ui:ui_val_4 animatable:on
see attachement.
Thank you for everybody’s help, the things I’m learning are way past what I expected to learn from this project! It is freaking awesome ! :buttrock:
Woo sry for that, my mistake, actually you just have to use filein instead of include, I should have restarted my max, then I would have noticed it ^^
So like this:
-- spinner and ctrl names
spinnerVarName = "imASpinner"
spinnerCtrlName = "mySpinner"
-- Defining the folder and scriptname for the rollout
cScriptDir = "c:\\scriptTest\\"
cScriptName = "testRollout.ms"
-- create directory
makeDir cScriptDir all:true
-- filepath
cScriptFilePath = (cScriptDir + cScriptName)
-- create the .ms file
cScriptFileStream = createFile cScriptFilePath
format "ca=attributes SpinnerSliderControl
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "parameters params1 rollout:params
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "% type:#float ui:(%,ctrl1SLIDER)
" spinnerCtrlName spinnerVarName to:cScriptFileStream
format ")
" to:cScriptFileStream
format "
" to:cScriptFileStream
format "rollout params \"Controls\"
" to:cScriptFileStream
format "(
" to:cScriptFileStream
format "local range=[-90,90,0]
" to:cScriptFileStream
format "spinner % \"\" range:range align:#right width:40
" spinnerVarName to:cScriptFileStream
format "slider ctrl1SLIDER \"\" range:range width:100 offset:[0,-25]
" to:cScriptFileStream
format ")
" to:cScriptFileStream
format ")
" to:cScriptFileStream
close cScriptFileStream
filein cScriptFilePath
-- just for the purpose of testing
cObj = $testObj
custAttributes.add cObj.modifiers[1] ca
I just tried it, it should really work now if you still want to have a look
~Markus
I think that what I’m looking for is as simple to be found as it was simple in the help file:
Remapping Parameters when Redefining Custom Attributes
[left]The optional remap:keyword allows parameter names in the definitions to be changed when updating existing definitions. It is also available in Scripted Plug-ins.[/left]
[left]The keyword takes as an argument a 2 element array, where each element contains an array of string literal or name values. The size of the 2 arrays must be the same. [/left]
[left]The names in the first array are the existing parameter names, the names in the second array are the new parameter names. As parameter names are read in while migrating existing plugin instances, the parameter names are searched for in the first array. If the name is found, the data associated with that parameter is moved to the parameter name in the corresponding location in the second array. If a parameter name is not found in the first array, the parameter name is not remapped. If the parameter name in the second array does not match a parameter name in the new definition, the parameter data is not moved to the new definition.[/left]
[left]
CAT_DEF = attributes Custom_Attributes[/left]
[left]Redefine:CAT_CurrentDef[/left]
[left]remap:#(#("Param1"),#("Param9"))[/left]
[left]([/left]
[left]Parameters main rollout:params[/left]
[left]([/left]
[left]'Param9' Type:#float UI:'Param9' Default:0.0[/left]
[left]'Param2' Type:#float UI:'Param2' Default:0.0[/left]
[left])[/left]
[left]Rollout Params "Custom Attributes"[/left]
[left]([/left]
[left]spinner 'Param9' "Param9" Width:160 Height:16 Align:#Center Type:#float Range:[0,100,0][/left]
[left]spinner 'Param2' "Param2" Width:160 Height:16 Align:#Center Type:#float Range:[0,100,0][/left]
[left])[/left]
[left])[/left]
[left]CustAttributes.add CAT_TargetObject CAT_DEF #Unique BaseObject:false[/left]
[left]
[/left]
[left]This will move the data associated with parameter Param1 to parameter Param9 in existing instances.[/left]
[left]I guess this I simply should create an array with the default names and an array with the new names given by the user. The only problem is I don’t get how this works actually. [/left]
[left]Even when I try to use the example given, it keeps giving errors… [/left]
[left]Another problem I stumbled upon is that I can’t seem to access anything when I’m in the[/left]
[left]attributes area brackets (where the attributes get defined) I can’t access an array or even print ! I’m pretty sure this is programming 101 and is very simple to solve but I can’t seem to find a solution.[/left]
[left]
[/left]
[left]-- print 1 -- this would NOT crash[/left]
[left]ca=attributes SpinnerSliderControl[/left]
(
-- print 2 -- this would crash
local range=[-90,90,0] -- !!! inserting array items in here would crash / or defining the "range" before print1 and using it would crash as well.
parameters params1 rollout: params
(
-- print 3 -- this would crash
ctrl1 type:#float ui:(ctrl1SPINNER,ctrl1SLIDER)
)
rollout params "Controls" --textbox voor rollout naam ?
(
-- print 4 -- this would crash
spinner ctrl1SPINNER "" range:range align:#right width:40
slider ctrl1SLIDER "" range:range width:100 offset:[0,-25]
)
)