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