#########################################################
## Copyright (c) 2005
## University of Washington
## Licensed under the terms set forth by University of
## Washington. If you did not sign such a license, you
## are using this software/code illegally and you do not
## have permission to use, modify, or redistribute
## this or any files in this software package.
##
## modal.r
## Functions for showing modal (dialog) and non-modal
## (normal) Tcl/Tk windows.
#########################################################

#########################################################
## Function: modal.window
##
## Shows a window as if it were a dialog box. In other words,
## the window must be destroyed (eg the user must click OK)
## before interacting with the rest of the application.
##
## This function is kind of goofy, because
## you have to create the window and pack it first.
## In Tcl/Tk it is always visible, but only becomes modal
## when you call this function.
##
## control is released to the parent window when
## window is destroyed.
#########################################################
modal.window <- function(window, parentwindow, hideParent=FALSE) {
  if(class(window) != "tkwin")
  {
    stop("window Argument's class must be 'tkwin', created by tktoplevel()")
  }

  if(class(parentwindow) != "tkwin")
  {
    stop("parentwindow Argument's class must be 'tkwin', created by tktoplevel()")
  }

  tkgrab(window)
  if (hideParent)
  {
    tkwm.withdraw(parentwindow)
  }
  else
  {
    tkwm.transient(window, parentwindow)
  }
  tkwm.protocol(window, 
    "WM_DELETE_WINDOW",
    function() { tkgrab.release(window); tkdestroy(window) } 
    )
  ## We can stop user interaction with the parent window...
  ## except that we can't stop them from closing it!
  ## So go away if parent window is destroyed
  tkwm.protocol(parentwindow, 
    "WM_DELETE_WINDOW",
    function() { tkgrab.release(window); tkdestroy(window); tkdestroy(parentwindow) } 
    )
  tkraise(window)
  tkwait.window(window)
  if(hideParent)
  {
    tkwm.deiconify(parentwindow)
  }
}

## Function: nonmodal.window
##
## Shows a window non-modally. i.e. the user can
## navigate between this window and others in the same
## application.
##
## This function is kind of goofy, because
## you have to create the window and pack it first.
## In Tcl/Tk it is always visible, but only becomes modal
## when you call this function.
##
## control is released to the parent window when
## window is destroyed.
nonmodal.window <- function(window, parentwindow, hideParent=FALSE) {
  if(class(window) != "tkwin")
  {
    stop("window Argument's class must be 'tkwin', created by tktoplevel()")
  }

  if(class(parentwindow) != "tkwin")
  {
    stop("parentwindow Argument's class must be 'tkwin', created by tktoplevel()")
  }

  if (hideParent)
  {
    tkwm.withdraw(parentwindow)
  }

  tkbind(window, "<Destroy>", function() { tkwm.deiconify(parentwindow) } )

  tkraise(window)
}
