[Closed] Dynamic Dropdownlist
What would be the best way to dynamically load a dropdownlist.
I have a dropdownlist which has all my maxscript in it. When i create a new one or place a new one within the folder on my desktop Id like when I open the dropdown list that it be updated with all the new scripts.
Any thoughts on this?
My initial thought would be to do a timer which updates ever so often which I would assume to be taxing.
i would use .net ComboBox and its DropDown event. All things with timer are slowing down the system.
try(destroydialog ::drop_roll)catch()
rollout drop_roll “Drop Down List”
(
local obj_arrayA = #(“1”,“2”,“3”,“4”,“5”)
local obj_arrayB = #(“6”,“7”,“8”,“9”,“10”)
dropdownlist obj_dd "Objects :" offset:[0,-20] items:obj_arrayA
fn fnUpdateList = obj_dd.items = (join obj_arrayA obj_arrayB)
on obj_dd rightClick do fnUpdateList()
)
createDialog drop_roll
You could look into a dotnet FileSystemWatcher object if realtime update is so crucial.
See my post in your other dropdownlist thread, here, for a .net combobox example.
denisT, do you know how to get the DropDownStyle to work? My tests don’t disable the combobox text entry and break the dropdown function. Or do you need to use the MaxCustomControls.MaxToolStripComboBox to get the DropDownStyles to work?
-Eric
Strange, using DropDownStyle.DropDownList works fine for me without MaxCustomControls…
I found a nice method that I converted from VB to use with a combobox – it calculates the maximum width of the text strings in the dropdown and adjusts the width accordingly. You use the dropdown event to fire this function and pass the combobox as the argument (depending of the scope of the function of course)
-- function calculates the max width of an item string in the dropdownlist and adjusts the comboboxdropdown accordingly. Is called by the dropdown event
fn FindWidthForDropDown ComboBox =
(
local g = ComboBox.CreateGraphics()
local WidestWidth = ComboBox.DropDownWidth
local ValueToMeasure
local CurrentWidth
local vertScrollBarWidth = if ComboBox.Items.Count > ComboBox.MaxDropDownItems then ((dotnetclass "systeminformation").VerticalScrollBarWidth)*2 else 0
For i = 0 To ComboBox.Items.Count - 1 do
(
ValueToMeasure = ComboBox.Items.item[i]
CurrentWidth = (g.measurestring ComboBox.items.item[i] ComboBox.font).width +vertScrollBarWidth
If CurrentWidth > WidestWidth Then WidestWidth = CurrentWidth
)
ComboBox.DropDownWidth = WidestWidth
g.Dispose()
)
so you can set this up as so –
on cmbcontrol dropdown sender args do FindWidthForDropDown sender
p.s eric- DropDownStyle.DropDownList works for me also
It sounds like dotNet is the way to go for this type of thing. I’ll look into it and see what I can get. I’m not to familiar with the dotNet controls at all. But I’m more than up for a new challenge.
I’ll be sure to post what I end up with to see what you guys think.
Thanks
JokerMartini
This is what I have so far for the maxscript side of things.
(
local directory = "Q:\ASSETS\John-Martini\Scripts\JokerMartini\_MyTools" -- Targeted scripts folder
local sFiles = getFiles (directory + "\\*.ms*")
local ScriptsArray = #()
local thisScript = 1
local ScriptName = 1
sort sFiles
ScriptsArray = for file in sFiles collect
(
local fIndex = findItem sFiles file
local fbName = "b" + (fIndex as string)
(getFIleNameFile file)
)
rollout rlScriptList "Scripts"
(
dropdownlist ScriptsList "" width:170 pos:[2,2] items:ScriptsArray height:23
button btnOpenScript "Run Script" width:87 height:26 pos:[0,24]
button btnEditScript "Edit Script" width:87 height:26 pos:[87,24]
on ScriptsList selected i do
(
thisScript = i
ScriptName = ScriptsList.items[i]
)
on btnOpenScript pressed do
(
execute (openfile (sFiles[thisScript] as string))
print ScriptName
try(destroyDialog rlScriptList)catch()
)
on btnEditScript pressed do
(
if thisScript != undefined do (edit (sFiles[thisScript] as string))
print ScriptName
try(destroyDialog rlScriptList)catch()
)
)
createDialog rlScriptList 174 50 500 200
)
This is what I have so far for the dotNet version.
This is great by the way. Thank you everyone!
However I’m not sure how to get the count property for the combobox to use to execute the script.
I’m open to different methods of calling up the script, whether its using its “string name” or by the order its placed in the array. Whichever is most efficient and fool proof.
--Change the local variable "Directory" to a folder filled with just .ms scripts for max
--After that the scripts list will be ordered alphabetically with all the scripts found in the targeted folder
--Select a script in the dropdownlist and then evaluate the script and the rest is self explanatory
try(destroyDialog ::rlScriptList)catch()
(
local directory = "Q:\ASSETS\John-Martini\Scripts\JokerMartini\_MyTools" -- Targeted scripts folder
local sFiles = getFiles (directory + "\\*.ms*")
local ScriptsArray = #()
local thisScript = 1
local ScriptName = ""
sort sFiles
rollout rlScriptList "Scripts"
(
dotNetControl dlScriptsList "System.Windows.Forms.ComboBox" height:20 width:160 pos:[10,10]
button btnOpenScript "Run Script" width:80 height:28 pos:[10,40]
button btnEditScript "Edit Script" width:80 height:28 pos:[90,40]
fn fnUpdateList = -- collects scripts and sorts them
(
-- Collect the scripts into an array
ScriptsArray = for file in sFiles collect
(
local fIndex = findItem sFiles file
local fbName = "b" + (fIndex as string)
(getFIleNameFile file)
)
-- Clear the ComboBox list
dlScriptsList.items.clear()
-- Build a new ComboBox list using the view array
dlScriptsList.items.addrange ScriptsArray
)
on dlScriptsList open do (fnUpdateList()) --Fill on open
on dlScriptsList DropDown do (fnUpdateList()) --Fill on expanding the list
on dlScriptsList SelectedIndexChanged do
(
--Command to execute on selecting the entry
ScriptName = dlScriptsList.text
)
on btnOpenScript pressed do
(
execute (openfile (sFiles[thisScript] as string))
print ScriptName
try(destroyDialog rlScriptList)catch()
)
on btnEditScript pressed do
(
if thisScript != undefined do (edit (sFiles[thisScript] as string))
print ScriptName
try(destroyDialog rlScriptList)catch()
)
)
createDialog rlScriptList 180 80
)
Hey John,
if i see correct the final goal then
maybe this script will be interesting to you.
utility scriptBrowser "MXS Browser"
(
local rootDir = GetDir #scripts
local sdLength = rootDir.count + 1
local templist = #()
local subDirs = for d in GetDirectories (rootDir + "\\*") collect d
local visDirs = for s in subDirs collect (replace s 1 sdLength "")
local files = getFiles (subDirs[1] + "[\\*.ms](file://*.ms)")
DropDownList currDir "" items:visDirs
ListBox filelist
radiobuttons action labels:#("Edit", "Run")
function UpdateFiles = (
if files.count != 0 then (
for f = 1 to files.count do templist[f] = FilenameFromPath files[f]
filelist.items = templist
) else filelist.items = #()
)
on scriptBrowser open do ( UpdateFiles() )
on filelist doubleClicked itm do if filelist.selection != 0 do
(
local itmFile = (rootDir + "\\" + currDir.selected + templist[itm])
case action.state of (
1: edit itmFile
2: FileIn itmFile
default: edit itmFile
)
)
on currDir selected i do
(
templist = #()
files = getFiles (rootDir + "\\" + currDir.items[i] + "[\\*.ms](file://*.ms)")
UpdateFiles()
)
)
It may need update only if you create new folder
Its a bit old, one of my first scripts ever
but you know, i like the simple staffs
and i use it as it is all the time
I’ve hit a snag.
In this script the dropdown list label/text is “Scripts List:”
I want that word to remain in the list the entire time.
I’ve pasted the code here below on what I figured would work based on the things I know but for some reason the dropdownlist.text = “Scripts List:” will not overwrite it for some reason.
Is there a count property like the max dropdownlist has as well?
try(destroyDialog ::rlScriptList)catch()
(
local directory = “$scripts/Startup/” – Targeted scripts folder
local sFiles = getFiles (directory + “\.ms”)
local ScriptsArray = #()
local thisScript = 1
local ScriptName = “”
sort sFiles
rollout rlScriptList "Scripts"
(
dotNetControl dlScriptsList "System.Windows.Forms.ComboBox" text:"Scripts List:" height:20 width:160 pos:[10,10]
fn fnUpdateList = -- collects scripts and sorts them
(
-- Collect the scripts into an array
ScriptsArray = for file in sFiles collect
(
local fIndex = findItem sFiles file
local fbName = "b" + (fIndex as string)
(getFIleNameFile file)
)
-- Clear the ComboBox list
dlScriptsList.items.clear()
-- Build a new ComboBox list using the view array
dlScriptsList.items.addrange ScriptsArray
)
on dlScriptsList open do (fnUpdateList()) --Fill on open
on dlScriptsList DropDown do (fnUpdateList()) --Fill on expanding the list
on dlScriptsList SelectedIndexChanged do
(
--Command to execute on selecting the entry
ScriptName = dlScriptsList.text
print ScriptName
dlScriptsList.text = "Scripts List:"
)
)
createDialog rlScriptList 180 40
)