[Closed] destroydialog delay
I’m writing a silly little script for fun and practice. The idea of the script is to make a progressbar that will last for a predetermined length of time. When you run the script it comes up with a dialog where you enter some text and a length of time in minutes, then you press go and a progresbar pops up and increments every second til the predetermined length of time is reached. The problem I’m having is that even though the script trys to destroy the original input dialog before opening the progressbar, it doesn’t seem to actually dissapear til the progressbar has finished it’s thing.
Anyone got any ideas as to why the input dialog doesn’t close when I think it should?
Thanks,
Cg
prog = 0.0
ph = 30
rollout ProgressDisplay "Progress"
( label Plabel "" align:#left
Progressbar Progress "" height:ph
)
rollout input "Input"
( edittext excuse "Enter excuse"
spinner time "Time in minutes" range:[.166,100.0,0.166]
button go "go"
on go pressed do
( destroydialog input
timedelay = (time.value)*60
interval = 100/timedelay
createdialog ProgressDisplay width:800
ProgressDisplay.Plabel.text = excuse.text
starttime = timestamp()
testTime = timestamp()
gap = (testtime - starttime)/1000
while Prog < 100 do
(
if oldgap != gap then
(
prog+= interval
ProgressDisplay.Progress.value = prog
)
oldgap = gap
testTime = timestamp()
gap = (testtime - starttime)/1000
print gap
)
destroydialog ProgressDisplay
)
)
createdialog input
Chris,
While the handler of the button is evaulating (for the whole update time), the main Max thread is frozen and does nothing. In other words, as long as you are not doing anything to the scene, viewports etc, Max will not refresh its UI until the script has exited the handler.
The way I would do it (but it does NOT block the Main thread so one could still work while the progress dialog is ticking) would be to use a timer which works PARALLEL to the Max UI.
Here is an example:
(--create LOCAL scope! ALWAYS!
local timedelay = 0 --predeclare the variables
local starttime = 0 --so both can be seen by the two rollouts
rollout ProgressDisplay "Progress"
( label Plabel "" align:#left
Progressbar Progress "" height:30
timer tmr_clock interval:1000 active:false --timer control, tick once per second
on tmr_clock tick do --on each tick
(
local timeSoFar = timestamp() - starttime --calculate the milliseconds since the start
ProgressDisplay.Progress.value = 100.0* timeSoFar/timedelay --update the progress
if timeSoFar > timedelay do --if the time has passed.
(
tmr_clock.active = false --stop the timer
destroydialog ProgressDisplay --and destroy the dialog
)
)
)
rollout input "Input"
( edittext excuse "Enter excuse"
spinner time "Time in minutes" range:[.166,100.0,0.166]
button go "go"
on go pressed do
(
starttime = timestamp() --stop the initial time
destroydialog input --destroy the old dialog
timedelay = time.value*60000 --calculate the wait time in milliseconds
createdialog ProgressDisplay width:800 --create the progressbar
ProgressDisplay.tmr_clock.active = true --enable the timer
ProgressDisplay.Plabel.text = excuse.text --set the excuse text
)
)
createdialog input --create the main dialog
)--end script
If you DO want the Main thread to be blocked to prevent the user from working in Max, you would have to live with your current code.
Testing out the script it seems the dialog does actually close when you’re expecting it to, its just a display issue. I added in a [b]completeRedraw/b in the line right after where you call the dialog to be destroyed and it disappears as it should. Not too sure why this is happening in the first place though.
But if the dialog happens to be over the command panel, for example, it would not go away (I tried the same hack ;)). It only fixes the cases where the dialog has its default position over the viewports…
Here’s another approach which does block max’s main thread. In the go button handler, the input dialog is moved off screen and a timer is activated. The original code block is moved to the startProgress event. This delay enables the main thread to run for a short period of time, just enough for max to redraw its window.
( -- as Bobo pointed out, always place your code in a scope
-- unless you have a good reason not to.
prog = 0.0
ph = 30
rollout ProgressDisplay "Progress"
(
label Plabel "" align:#left
Progressbar Progress "" height:ph
)
rollout input "Input"
(
edittext excuse "Enter excuse"
spinner time "Time in minutes" range:[.166,100.0,0.166]
button go "go"
timer startProgress interval:50 active:false
on start tick do
(
-- deactivate the timer
startProgress.active = false
timedelay = (time.value)*60
interval = 100/timedelay
createdialog ProgressDisplay width:800
ProgressDisplay.Plabel.text = excuse.text
starttime = timestamp()
testTime = timestamp()
gap = (testtime - starttime)/1000
while Prog < 100 do
(
if oldgap != gap then
(
prog+= interval
ProgressDisplay.Progress.value = prog
)
oldgap = gap
testTime = timestamp()
gap = (testtime - starttime)/1000
print gap
)
-- destroy both dialogs
destroydialog ProgressDisplay
destroydialog input
)
on go pressed do
(
-- move the dialog off screen
setDialogPos input [10000, 0]
-- give max 50 milliseconds to redraw
startProgress.active = true
)
)
createdialog input
) -- end local scope
[edit]FWIW, on start tick do should read on startProgress tick do …[/edit]
Martijn
Be honest, this is a script to allow you to run to appear like you’re working when you aren’t :). Like the program “CoffeeBreak”, genius. Public release please.
-Colin
Well, yeah it is a fake “the computer is working” thing. Mostly it’s a practice in opening one dialog from another, but it’s grown a bit since the original idea. The way I had it the other day it was nearly working, but when Bobo rewrote some of it, he really helped me undersatand how to structure things so that variables can be shared between dialogs but still be local. And a nicer way to time things. Thanks again Bobo.
Here’s the script as it stands now.
macroScript Progress
category:"CgRay"
(
local timedelay = 0 --predeclare the variables
local starttime = 0 --so both can be seen by the two rollouts
local progCol = color 30 10 190
local divisions = 100
rollout ProgressDisplay "Progress"
( label Plabel "" align:#left
Progressbar Progress "" height:20 color:progCol
label lbl_p1 "%" align:#left
Progressbar Progress2 "" height:20 color:progCol
label lbl_p2 "%" align:#left
timer tmr_clock interval:1 active:false --timer control, tick once per second
on tmr_clock tick do --on each tick
(
local timeSoFar = timestamp() - starttime --calculate the milliseconds since the start
ProgressDisplay.Progress.value = 100.0* timeSoFar/timedelay --update the progress
Prog2 = divisions * 100.0 * timeSoFar/timedelay
while Prog2 > 100 do
(
prog2 -= 100
)
ProgressDisplay.Progress2.value = prog2
ProgressDisplay.lbl_p1.text = (ProgressDisplay.Progress.value as integer) as string + "%"
ProgressDisplay.lbl_p2.text = (prog2 as integer) as string + "%"
if timeSoFar > timedelay do --if the time has passed.
(
tmr_clock.active = false --stop the timer
destroydialog ProgressDisplay --and destroy the dialog
messagebox ("Finished "+ ProgressDisplay.Plabel.text as string) title:"Complete"
)
)
)
rollout input "Input"
( edittext excuse "Enter excuse" text:"Timewasting"
spinner time "Time (minutes)" range:[0.0,1000.0,0.166]
label lbl_colour "Pick colour" align:#left across:2
dropdownlist ddl_Colour items:#("Red","Green","Blue","Purple","Yellow","Orange") selection:3
spinner spn_divisions "Divisions" type:#integer range:[5,100,10]
button go "Go"
on go pressed do
( case input.ddl_colour.selection of
(
1: (progCol = color 255 0 0)
2: (progCol = color 0 255 0)
3: (progCol = color 30 10 190)
4: (progCol = color 150 0 150)
5: (progCol = color 255 255 0)
6: (progCol = color 255 128 0)
)
divisions = spn_divisions.value
starttime = timestamp() --stop the initial time
destroydialog input --destroy the old dialog
timedelay = time.value*60000 --calculate the wait time in milliseconds
createdialog ProgressDisplay width:600 --create the progressbar
ProgressDisplay.tmr_clock.active = true --enable the timer
ProgressDisplay.Plabel.text = excuse.text --set the excuse text
)
)
createdialog input --create the main dialog
)--end script