Notifications
Clear all

[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

6 Replies

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.

1 Reply
(@bobo)
Joined: 11 months ago

Posts: 0

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