[Closed] Scripting Rollouts for tabs
I’m in the process of working on scripts for public release.
I was curious to get some opinions of ways people would see as the best route to go when making this particular UI with rollouts.
I need to have multiple tabs/rollouts and in needing that I’ve decided to go in the direction similar to fumeFX. When the button is pressed it adds a rollout and removes any previous ones.
My two concerns are
- What is the best way to store the settings/values of each rollout item control and reload them when that tab/rollout is reopened
- Best way to streamline the ability to remove/add rollouts.
My thoughts for the settings/values would be to just make them all local variables to the main rollout, otherwise worst case scenierio is to make them save to an ini file when the rollout is closed or any parameter is changed and then load it on AddSubRollout.
I’ve created a rough example here and posted in for users to build on and possibly better streamline. In a way that if others would like to use this as a starting point they could.
It may include building a function that would remove all rollouts except that one associated with that button. Right now mine is a bit redundant.
Lastly, I had a last second idea of making it so instead of removing any rollouts just making a function that would hide the rollout.visible state?!!!
I look forward to hearing back from you guys.
Thanks
JokerMartini
try(destroyDialog ::rltest)catch()
rollout rltest "test"
(
subrollout srWin "test1" pos:[8,36] width:154 height:60
label lb style_sunkenedge:true width:48 height:20 pos:[8,8]
checkbutton cbA "A" width:46 height:18 pos:[9,9]
label lb0 style_sunkenedge:true width:48 height:20 pos:[59,8]
checkbutton cbB "B" width:46 height:18 pos:[60,9]
label lb3 style_sunkenedge:true width:48 height:20 pos:[110,8]
checkbutton cbC "C" width:46 height:18 pos:[111,9]
on cbA changed state do (
if state then (
rltest.height = 106
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
AddSubRollout rltest.srWin rlAa
) else (
rltest.height = 36
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
)
)
on cbB changed state do (
if state then (
rltest.height = 106
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
AddSubRollout rltest.srWin rlB
) else (
rltest.height = 36
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
)
)
on cbC changed state do (
if state then (
rltest.height = 106
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
AddSubRollout rltest.srWin rlC
) else (
rltest.height = 36
for rl in srWin.rollouts do removeSubRollout rltest.srWin rl
)
)
)
rollout rlAa "A"
(
spinner test1as "test1as" width:100
)
rollout rlB "B"
(
spinner test1as "test1as" width:100
)
rollout rlC "C"
(
spinner test1as "test1as" width:100
)
createdialog rltest 170 36
About the issue of rollout items loosing their state after adding/removing them when building a dialog similar the the render dialog, with tabs.
What I’m doing is storing all rollout item values into a struct, everytime a value is entered. And I restore the values when the rollout is created.
This may be inconvenient, but I need the data anyway, to be able to keep settings when the dialog is closed/reopened. And to be able to store/restore settings into a preset file.
here are some fragments of a dialog where i’m doing that:
struct struct_settings (dialog_width,dialog_height,subdivs_x,subdivs_y,size_x,size_y,percent_x,percent_y,square,subdiv_mode,bordermode,splinemode)
global mlpopgridSettings
if (mlpopgridSettings==undefined) do mlpopgridSettings = struct_settings dialog_width:348 dialog_height:383 subdivs_x:10 subdivs_y:10 size_x:10 size_y:10 percent_x:10 percent_y:10 square:false subdiv_mode:1 bordermode:1 splinemode:1
...
...
fn updateSettings overwrite:false autoUpdate:false =
(
if overwrite then
(
mlpopgridSettings.subdiv_mode=rdo_subdivs_type.state
mlpopgridSettings.subdivs_x=spn_subdivs_X.value
mlpopgridSettings.subdivs_y=spn_subdivs_Y.value
mlpopgridSettings.size_x=spn_size_X.value
mlpopgridSettings.size_y=spn_size_Y.value
mlpopgridSettings.percent_x=spn_percent_X.value
mlpopgridSettings.percent_y=spn_percent_Y.value
mlpopgridSettings.bordermode=rdo_border.state
mlpopgridSettings.splinemode=rdo_splineMode.state
mlpopgridSettings.square=chk_square.state
)
else
(
rdo_subdivs_type.state=mlpopgridSettings.subdiv_mode
spn_subdivs_X.value=mlpopgridSettings.subdivs_x
spn_subdivs_Y.value=mlpopgridSettings.subdivs_y
spn_size_X.value=mlpopgridSettings.size_x
spn_size_Y.value=mlpopgridSettings.size_y
spn_percent_X.value=mlpopgridSettings.percent_x
spn_percent_Y.value=mlpopgridSettings.percent_y
rdo_border.state=mlpopgridSettings.bordermode
rdo_splineMode.state=mlpopgridSettings.splinemode
chk_square.state=mlpopgridSettings.square
)
on rdo_subdivs_type changed a do updateSettings overwrite:true
on spn_subdivs_X changed a do updateSettings overwrite:true
on spn_subdivs_X entered inSpin_arg inCancel_arg do updateSettings overwrite:true autoUpdate:true
on spn_subdivs_Y changed a do updateSettings overwrite:true
on spn_subdivs_Y entered inSpin_arg inCancel_arg do updateSettings overwrite:true autoUpdate:true
on spn_size_X changed a do updateSettings overwrite:true
Do you have an examples you would want to share so we could build onto it.
I edited the previous post with some example code from a dialog of mine, not sure if it is useful…
I think we could build on examples people post on here and build a solid rollout ui that people could use if they want.
For example in your script you could shorten the code quite a bit really.
You can access all the controls in a ui by the <rollout>.controls propertie
So maybe we could write a function that would just run through the targeted rollout on open and close which would store the settings for each item in a bitArray.
Example Idea: (does not work, just a basic idea of a potential concept)
fn fnSaveRolloutSettings trgRollout = (--//Saves active rollout ui controls to bitArray
for item = trgRollout.controls do (
save settings from item to array
)
)
fn fnLoadRolloutSettings trgRollout = (--//Loads active rollout ui controls from bitArray
for item = trgRollout.controls do (
load settings from array to item
)
)
I used to be obsessed about optimizing/shortening code, until I realized that in many cases there is no point.
In situations where performance doesn’t matter I tend to use code that can easily modified/expanded with copy&paste, instead of building “elegant” functions, when there is no benefit.
I found that “stupid”, linear code can me more flexible and readable, at least for me.
But I’m looking forward to a more elegant solution. I just don’t want to spend a lot of time building it
here is how i do it in some simple cases:
try(closeRolloutFloater dialog) catch()
struct rolloutData (this, title, open = off, border = on, controls = #())
struct controlData (this, data, enabled, visible)
global main, dialog, secA, secB
rollout main "main"
(
-- local classes = #(SpinnerControl, CheckBoxControl, RadioControl, ...)
fn getControlData control =
(
data = case (classof control) of
(
SpinnerControl:
#(
#(#value, control.value),
#(#range, control.range)
)
CheckBoxControl:
#(
#(#tristate, control.tristate),
#(#controller, control.controller)
)
RadioControl:
#(
#(#state, control.state)
)
)
controlData this:control data:data enabled:control.enabled visible:control.enabled
)
fn getRolloutData rol =
(
controls = for c in rol.controls where (data = getControlData c) != undefined collect data
rolloutData this:rol title:rol.title open:rol.open controls:controls
)
fn setRolloutData data = if data != undefined and iskindof (rol = data.this) RolloutClass do
(
rol.title = data.title
for c in data.controls where (finditem rol.controls c.this) != 0 do
(
if c.data != undefined do for d in c.data do setproperty c.this d[1] d[2]
c.this.enabled = c.enabled
c.this.visible = c.visible
)
rol.open = data.open
)
checkbutton bt1 "A" width:78 across:2
checkbutton bt2 "B" width:78
fn stateRollout rol dialog:dialog state:on =
(
(if state then addrollout else removerollout) rol dialog
)
on bt1 changed state do stateRollout secA dialog:dialog state:state
on bt2 changed state do stateRollout secB dialog:dialog state:state
fn updateRolloutStates =
(
bt1.state = (finditem dialog.rollouts secA) != 0
bt2.state = (finditem dialog.rollouts secB) != 0
)
)
rollout secA "A"
(
local data = if data != undefined do data
radiobuttons rb labels:#("High", "Low") across:2
spinner sp "A: " range:[0,1e9,1] type:#integer fieldwidth:40
on secA close do
(
data = main.getRolloutData secA
format "closeA: %
" data
)
on secA open do
(
if data != undefined do
(
format "openA:%
" data
main.setRolloutData data
)
)
)
rollout secB "B"
(
local data = if data != undefined do data
checkbox cb "Enabled" checked:on across:2
spinner sp "B: " range:[0,1e9,2] type:#integer fieldwidth:40
on secB close do
(
data = main.getRolloutData secB
format "closeB: %
" data
)
on secB open do
(
if data != undefined do
(
format "openB:%
" data
main.setRolloutData data
)
)
)
dialog = newrolloutfloater "Dynamic" 202 200
addrollout main dialog
addrollout secA dialog
addrollout secB dialog
main.updateRolloutStates()
/*
removeRollout main dialog
removeRollout secA dialog
removeRollout secB dialog
*/
I’m not a fan of them really either. Do you have any other suggestions on ways I could build a ui that would be without using rollouts?
How would you do it?
i said that i hate SUBROLLOUTS.
rollouts are fine, i use them a lot.
sometimes rollouts is the only way of the building UI (utilities, scripted materials, plug-ins, etc.)
I misread it the first time around.
I understand what your saying. Thanks for the example.
I’m trying to narrow down on what would work best for a script I’m working on which inolves it having some sorta tab system or rollout system to simplify the ui otherwise the dialog would be way to long.
The sub rollout stuff just makes it a pain to mess with properties and whatnot.