[Closed] handling IRollupWindow
Someone asked if it’s possible to have some rollups opened by default and others closed. That’s my attempt to tackle the issue.
While it seems to work overall, sometimes I get undefined trying to get IRollupPanel using IRollupWindow.GetPanel method (line:19). Any thoughts on what could be the cause of it?
And the main question is: How these IRollupWindow and IRollupPanel instances should be handled after work is done? Should I dispose them or what?
fn rollupDoorman forceOpenRollups: = (
if forceOpenRollups == unsupplied do forceOpenRollups = #("Selection","Edit Vertices","Edit Edges","Edit Geometry","Edit Borders","Edit Polygons","Polygon: Smoothing Groups","Polygon: Material IDs")
modPanelHWND = undefined
for c in UIAccessor.GetChildWindows (windows.getMAXHWND()) while modPanelHWND == undefined where (d = windows.getHWNDData c)[4] == "ModifyTask" do modPanelHWND = d[1]
rollupWindows = for w in windows.getChildrenHWND modPanelHWND where w[4] == "RollupWindow" collect w[1]
for rollupWindowHWND in rollupWindows do (
IRollupWindow = (dotnetclass "Autodesk.Max.GlobalInterface").Instance.getIRollup (dotnetobject "system.intptr" rollupWindowHWND)
-- format "
IRollupWindow.numpanels: %
" IRollupWindow.numpanels
for i=0 to IRollupWindow.numpanels-1 do (
IRollupPanel = IRollupWindow.GetPanel (IRollupWindow.GetPanelDlg i asdotnetobject:true)
if IRollupPanel == undefined do (format "Failed at %
" i; continue)
rollupName = UIAccessor.GetWindowText IRollupPanel.TitleWnd
-- format "%: %
" i rollupName
if findItem forceOpenRollups rollupName > 0 then (
if not IRollupWindow.IsPanelOpen i do IRollupWindow.SetPanelOpen i true false
) else (
if IRollupWindow.IsPanelOpen i do IRollupWindow.SetPanelOpen i false false
)
)
)
)
fn weAreOpenHandler = (
local base = modPanel.getCurrentObject()
case classof base of (
Editable_Poly: rollupDoorman()
Edit_Poly: rollupDoorman()
Editable_Mesh: rollupDoorman()
Edit_Mesh: rollupDoorman()
default:()
)
)
callbacks.removeScripts #modPanelSelChanged id:#weAreOpen
callbacks.removeScripts #ModPanelSubObjectLevelChanged id:#weAreOpen
callbacks.addScript #modPanelSelChanged "weAreOpenHandler()" id:#weAreOpen
callbacks.addScript #ModPanelSubObjectLevelChanged "weAreOpenHandler()" id:#weAreOpen
cool… but all these will not work in 2017+
i’m waiting for a complete UI solution in MAX. hopefully it will be 2018
and IRollupWindow related question
I’ve looked in SDK… you are definitely can reorder rollups from SDK. IRollupWindow and IRollupPanel give access to that.
Reordering rollouts on the command panel
I’d like to add custom attributes rollout and make it first rollup.
Can somebody explain how to move/reorder rollouts using IRollupWindow and IRollupPanel methods correctly?
I’ve managed to move my rollup where I want it to be, but when I switch to create mode and then back to modify mode it stays where it was initially (if I manually place it second, third etc it will always keep this place when I change back to modify mode).
Should I save it’s state somehow?
I tried to, but SaveState fails… sdk sources lacks info about RollupState
Here’s my code
fn ReorderModpanelRollups titles indexes =
(
local g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
local modPanelHWND = undefined
for c in windows.getChildrenHWND #max while modPanelHWND == undefined where c[4] == "ModifyTask" do modPanelHWND = c[1]
local rollupWindows = for w in windows.getChildrenHWND modPanelHWND where w[4] == "RollupWindow" collect w[1]
for rollupWindowHWND in rollupWindows do
(
local IRollupWindow = g.getIRollup (dotnetobject "system.intptr" rollupWindowHWND)
format "\nIRollupWindow.numpanels: %\n" IRollupWindow.numpanels
local reordered = false
for i=0 to IRollupWindow.numpanels-1 do
(
local IRollupPanel = IRollupWindow.GetPanel (IRollupWindow.GetPanelDlg i asdotnetobject:true)
if IRollupPanel != undefined do
(
local rollupName = UIAccessor.GetWindowText IRollupPanel.TitleWnd
format "%: % cat:%\n" i rollupName IRollupPanel.category
local index = findItem titles rollupName
if index > 0 and IRollupPanel.category != indexes[index] do
(
-- show IRollupPanel
IRollupPanel.category = indexes[index]
reordered = true
)
)
)
if reordered do
(
IRollupWindow.updateLayout()
-- try to save rollup states
for i=0 to IRollupWindow.numpanels-1 do
(
local IRollupPanel = IRollupWindow.GetPanel (IRollupWindow.GetPanelDlg i asdotnetobject:true)
if IRollupPanel != undefined do
(
try ( IRollupWindow.SaveState (dotNetObject "System.IntPtr" IRollupPanel.HInst) ) catch (format "save failed at %\n" i)
)
)
)
g.ReleaseIRollup IRollupWindow
)
)
t = Teapot()
addModifier t (Edit_Poly())
max modify mode
ReorderModpanelRollups #( "Paint Deformation", "Selection" ) #( 1, 2 )
ok… looks like it must be saved like this
local current_mod = modPanel.getCurrentObject()
local cid = g.Class_ID.create current_mod.classid[1] current_mod.classid[2]
local sid = (dotnetclass "Autodesk.Max.SClass_ID").Osm
local rollupName = UIAccessor.GetWindowText IRollupPanel.TitleWnd
g.IRollupSettings.CatReg.UpdateCat sid cid rollupName IRollupPanel.Category
Good catch! Thanks!
… probably you have to save it for next sessions of MAX if you want:
g.IRollupSettings.CatReg.Save()