[Closed] Modular, semi-dynamic toolbar UI for tools?
I’ve done a fair amount of searching and wasn’t able to come up with anything specific, though there are discussions and references to the topic.
What I’d like is a system to populate a master tools dialog based on scripts in a folder. The main tool would be run, and it would scan a specified folder such as \tools, and add each .ms file as a rollout in the main tool. It wouldn’t have to know about any predefined list of tools or .ms files.
The individual files would also be able to run independently of the main tool. If the tool was not run from the master tools dialog, it would create a local dialog and add the rollout to it. If the tool was called from the master tools dialog, it would skip dialog creation and only add the rollout to the existing master tools dialog. Perhaps using a global variable.
The end goal is to be able to develop, modify, and test complicated tools on their own, but also be able to quickly have them incorporated into a tools collection. Also, to keep the various tools to a manageable size, rather than incorporated into one humongous maxscript file.
Is this possible without becoming overly complex?
Blockquote
I chose my words poorly when I said toolbar. What I meant was a tool(a dialog) which is actually just another script that acts like a container for other scripts/tools. Those scripts would be rollouts of a consistent width.
Something like this:
In that example, the user would install one script, which is the container dialog ‘Tools v1.0.’ When it runs, it scans a directory for scripts and loads them into the tool. However many maxscripts are found in a specified search folder, they get added to the dialog. In this example, there are 4 scripts: RigCharacter.ms, Export.ms, ApplyUVs.ms, and CenterPivot.ms.
In that way, an artist only has to install one script, one time. Then, the search folder could be a source control directory. Each time the artist got latest from source control and restarted Max, the artist would have the latest version of any tool and also any new scripts/tools. For example: Tool 5, 6, 7…etc. The functionality of the tools could be added to or removed from just by altering what’s in the directory with no intervention or maintenance required by the artist.
Blockquote
The problem with macroscripts is that they require setup work by the user every single time they want to add a new script. And, the tools can’t be organized into one dialog. Also, they need to be copied to the users scripts startup folder which is not conducive to source control and frequent updates.
That’s impossible
what needed to add a subrollout is the name of the rollout and it is impossible
I had wrote a script beside scripts , like a toolbar , any scripts can be added to the toolbar , any time to use just click the button on it ,also to add with a path , saved the data with any changed
but to add rollout to another script , unless all scripts was wrote by youself and with the same rule
Some scripts may not have any UI at all. I don’t get your goal, Are you looking for a UI solution or source control?
I know exactly what you want, and I have struggled for years.
As @cgt139746852 said, That’s impossible unless all scripts were written by yourself and with the same rule.
I remember @denisT said that floating tools are better.
Another thing I can’t stand is Big ass toolbar UI! give me back my viewport.
I have written so many toolbar UI just like that(Modular, Compact) for myself.
With the help of many friendly guys in this forum, I had written a brand new tool shelf for personal use last year(2018).
About this simple stuff:
It’s a pure tool shelf with only the start buttons.
Scripts are categorized by custom tab page.
What can be added include: ms/mse file, macroScripts, maxscript/python.
It can be shrunk to a small icon by double click if I don’t want to see it. I can move it to any position.
What I mean is, pop up tool is better than the placeholder toolbar.
That’s pretty cool.
For my purposes, the UI will be controlled by me. Every script will have the same width so that they will fit into the main Rollout UI. That’s no problem. I just want a way to dynamically load rollouts from a folder. Whatever scripts are in a specified folder, get loaded into the tool as rollouts.
The main goal is to be able to get to the point where people can setup and install one script one time, and then new or updated tools will be automatically loaded with zero further setup or input from the users. Whatever scripts are copied and pasted into a folder, or downloaded from a source control app, or placed in a network location, will be loaded by the tool next time Max is run and the toolbar/framework script is run/opened.
This is for my benefit as the developer as well as the users. I don’t have to maintain some giant tool with dozens of different tools in it. Individual tools are easier to test, debug, update and maintain. The users don’t have to continually install new versions and new tools, or tools they don’t need for their job. It would also be handy for external outsource developers.
Here’s the method I finally came up with:
-- Modular script toolbox
-- Adds all the rollouts found in a directory to the floater
clearlistener()
try(destroydialog Toolbox) catch()
theIniFile = getDir #plugcfg + "/Toolbox.ini"
-- get position from ini file for new dialog
if (hasINISetting theIniFile "Toolbox" "Position") then thePos = execute (getIniSetting theIniFile "Toolbox" "Position")
else thePos = [100,100]
-- get size from ini file for new dialog
if (hasINISetting theIniFile "Toolbox" "Size") then theSize = execute (getIniSetting theIniFile "Toolbox" "Size")
else theSize = [250,300]
-- search a directory for max scripts with a rollout and load them into the Toolbox
function load_scripts directory =(
loadpath = directory + "\\"
files = getFiles (loadpath + "*.ms")
for f in files do (
-- search this maxscript for the name of the rollout in it
readfileopen = openfile f
found = false
rolloutname = undefined
while not eof readfileopen and found == false do(
if(skiptostring readfileopen "rollout " != undefined) then(
rolloutname = readDelimitedString readfileopen " "
found = true
)
)
close readfileopen
if found == true and rolloutname != undefined do(
filein f
stringcommand = "addsubrollout " + "Toolbox.RolloutsContainer " + rolloutname
execute stringcommand
)
)
)
rollout Toolbox "Toolbox"(
button p1 "Persitent 1" pos:[5,5]
button setpath "Set Path" pos:[95,5]
button reloadbutton "Reload Scripts" pos:[160,5]
subrollout RolloutsContainer "Rollouts" width:225 height:theSize.y
on reloadbutton pressed do(
-- remove all the rollouts except for the main toolbox
rollouts = Toolbox.RolloutsContainer.rollouts
for r in rollouts do if r.name != "Toolbox" do removesubrollout Toolbox.RolloutsContainer r
-- load all the scritps
if (hasINISetting theIniFile "Toolbox" "Toolsdirectory") then toolspath = getIniSetting theIniFile "Toolbox" "Toolsdirectory"
else toolspath = getDir #userscripts
load_scripts toolspath
)
on Toolbox moved pos do(
setIniSetting theIniFile "Toolbox" "Position" (pos as string)
)
on Toolbox resized size do(
RolloutsContainer.height = size.y
RolloutsContainer.width = 225
Toolbox.width = 250
setIniSetting theIniFile "Toolbox" "Size" (size as string)
)
on setpath pressed do(
-- load current directory to feed into getsavepath
if (hasINISetting theIniFile "Toolbox" "Toolsdirectory") then currentpath = getIniSetting theIniFile "Toolbox" "Toolsdirectory"
else currentpath = getDir #userscripts
-- get new directory
toolspath = getSavePath caption:"Select Maxscript Tools directory" initialDir:currentpath
if toolspath != undefined do setIniSetting theIniFile "Toolbox" "Toolsdirectory" (toolspath as string)
-- reload the scripts from the new path
reloadbutton.pressed()
)
)
-- create dialog
createDialog Toolbox pos:thePos width:250 height:theSize.y style:#(#style_resizing,#style_titlebar, #style_border, #style_sysmenu)
-- read tools directory
if (hasINISetting theIniFile "Toolbox" "Toolsdirectory") then toolspath = getIniSetting theIniFile "Toolbox" "Toolsdirectory"
else toolspath = getDir #userscripts
-- load the scripts
load_scripts toolspath
Sample Tool File:
-- Sample tool script file "Tool_D.ms"
rollout tool_d "Tool D"(
button d1 "d1"
on d1 pressed do messagebox "D1"
)
-- if the Toolbox isn't open, the script can run standalone
if Toolbox == undefined or Toolbox.open == false do(
try(destroydialog Toolbox)catch()
rof=newrolloutfloater "Test" 250 200
addrollout tool_d rof
)