Hack to make a "modal dialog"

Frank Leahy frank at backtalk.com
Mon May 24 09:15:53 EDT 2004


I wrote last week asking if anyone had a way to make a dialog "modal" 
without actually using the modal keyword (as doing so stops whatever 
process is currently running).

After a day of playing around with different solutions here's what I 
came up with.  I hope someone else finds it useful as well.

1. I added a transparent button (I called it "Trap Mouse Events") to 
all of the stacks that might be open when the progress dialog appears.  
The button is the top-most control, and is set to invisible (the size 
and location doesn't matter as that gets set when it's shown, see 
below).

In each transparent button was the following script:

on mouseDown
   BottleneckTasks "trapMouseDown"
end mouseDown

on mouseDoubleDown
   BottleneckTasks "trapMouseDown"
end mouseDoubleDown

on mouseUp
   -- do nothing
end mouseUp

on mouseDoubleUp
   -- do nothing
end mouseDoubleUp

2. I wrote a function called BottleneckTasks(tasks) that takes a single 
parameter "task".  I've appended its script to the bottom of this 
message.

3.  I found all of the places that BottleneckTasks() needed to be 
called in my code, which turned out to be in the following handlers:

	preOpenStack -- if a stack opens (it shouldn't) show the button
	closeStack -- when a stack closes, hide the button
	resumeStack -- if a stack comes to front bring the dialog back to the 
front
	menuPick -- I didn't want any menuPicks to occur while the dialog was 
up

4. When the progress dialog opens I have it call 
BottleneckTasks("openThumbnailProgress"), which loops through all of 
the open windows, resizing the "Trap Mouse Events button and setting it 
to visible.

5. While the progress dialog is open, if the user clicks in any stack 
the mouseDown handler in the transparent button gets called, which 
forces the progress dialog back to the front.

6. Finally, when the progress dialog disappears, the transparent 
buttons are all hidden by calling 
BottleneckTasks("closeThumbnailProgress")

That's it in a nutshell.

The only problem is that the resumeStack message doesn't always get 
called if you bring a window to the front by clicking in the title bar 
(a bug perhaps?), but that just means it's hidden until you click 
somewhere in one of the open windows.

Best,
-- Frank

on BottleneckTasks task
   put StackIsOpen("Thumbnail Progress") into progressIsOpen

   switch (task)

   case "openThumbnailProgress"
     -- show and resize trap button on all open stacks
     put the openStacks into theStacks
     put the number of lines of theStacks into numStacks
     repeat with i = 1 to numStacks
       put line i of theStacks into nextStack
       if there is a button "Trap Mouse Events" of stack nextStack then
         SizeAndShowMouseTrapButton nextStack
       end if
     end repeat
     break

   case "closeThumbnailProgress"
     -- hide on all open stacks
     put the openStacks into theStacks
     put the number of lines of theStacks into numStacks
     repeat with i = 1 to numStacks
       put line i of theStacks into nextStack
       if there is a button "Trap Mouse Events" of stack nextStack then
         hide button "Trap Mouse Events" of stack nextStack
       end if
     end repeat
     break

   case "preOpenStack"
     -- Shouldn't happen, but if it does show and resize trap button
     if there is a button "Trap Mouse Events" then
       if progressIsOpen then
         put the short name of this stack into stackName
         SizeAndShowMouseTrapButton stackName
       else
         hide button "Trap Mouse Events"
       end if
     end if
     break

   case "closeStack"
     if there is a button "Trap Mouse Events" then
       hide button "Trap Mouse Events"
     end if
     break

   case "resumeStack"
     if progressIsOpen then
       go to stack "Thumbnail Progress"
     end if
     break

   case "menuPick"
     if progressIsOpen then
       go to stack "Thumbnail Progress"
       -- need to exit to top so menuPick doesn't happen
       exit to top
     end if
     break

   case "trapMouseDown"
     if progressIsOpen then
       go to stack "Thumbnail Progress"
     else
       -- it shouldn't be visible, but it appears to be
       hide button "Trap Mouse Events"
     end if
     break

   default
     if task <> empty then breakpoint
     go to stack "Thumbnail Progress"
     break

   end switch
end BottleneckTasks

on SizeAndShowMouseTrapButton stackName
   put the height of stack stackName into theHeight
   add 100 to theHeight
   put the width of stack stackName into theWidth
   add 100 to theWidth
   put trunc(theHeight/2) into y
   put trunc(theWidth/2) into x
   set the height of button "Trap Mouse Events" of stack stackName to 
theHeight
   set the width of button "Trap Mouse Events" of stack stackName to 
theWidth
   set the location of button "Trap Mouse Events" of stack stackName to 
(x & "," & y)
   show button "Trap Mouse Events" of stack stackName
end SizeAndShowMouseTrapButton



More information about the use-livecode mailing list