summaryrefslogtreecommitdiff
path: root/iwidgets/generic/shell.itk
diff options
context:
space:
mode:
Diffstat (limited to 'iwidgets/generic/shell.itk')
-rw-r--r--iwidgets/generic/shell.itk375
1 files changed, 375 insertions, 0 deletions
diff --git a/iwidgets/generic/shell.itk b/iwidgets/generic/shell.itk
new file mode 100644
index 00000000000..85ebfbc7cb9
--- /dev/null
+++ b/iwidgets/generic/shell.itk
@@ -0,0 +1,375 @@
+# Shell
+# ----------------------------------------------------------------------
+# This class is implements a shell which is a top level widget
+# giving a childsite and providing activate, deactivate, and center
+# methods.
+#
+# ----------------------------------------------------------------------
+# AUTHOR: Mark L. Ulferts EMAIL: mulferts@austin.dsccc.com
+# Kris Raney EMAIL: kraney@spd.dsccc.com
+#
+# @(#) $Id$
+# ----------------------------------------------------------------------
+# Copyright (c) 1996 DSC Technologies Corporation
+# ======================================================================
+# Permission to use, copy, modify, distribute and license this software
+# and its documentation for any purpose, and without fee or written
+# agreement with DSC, is hereby granted, provided that the above copyright
+# notice appears in all copies and that both the copyright notice and
+# warranty disclaimer below appear in supporting documentation, and that
+# the names of DSC Technologies Corporation or DSC Communications
+# Corporation not be used in advertising or publicity pertaining to the
+# software without specific, written prior permission.
+#
+# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
+# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
+# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
+# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
+# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+# SOFTWARE.
+# ======================================================================
+
+#
+# Usual options.
+#
+itk::usual Shell {
+ keep -background -cursor -modality
+}
+
+# ------------------------------------------------------------------
+# SHELL
+# ------------------------------------------------------------------
+itcl::class iwidgets::Shell {
+ inherit itk::Toplevel
+
+ constructor {args} {}
+
+ itk_option define -master master Window ""
+ itk_option define -modality modality Modality none
+ itk_option define -padx padX Pad 0
+ itk_option define -pady padY Pad 0
+ itk_option define -width width Width 0
+ itk_option define -height height Height 0
+
+ public method childsite {}
+ public method activate {}
+ public method deactivate {args}
+ public method center {{widget {}}}
+
+ private variable _result {} ;# Resultant value for modal activation.
+ private variable _busied {} ;# List of busied top level widgets.
+
+ common grabstack {}
+ common _wait
+}
+
+#
+# Provide a lowercased access method for the Shell class.
+#
+proc ::iwidgets::shell {pathName args} {
+ uplevel ::iwidgets::Shell $pathName $args
+}
+
+# ------------------------------------------------------------------
+# CONSTRUCTOR
+# ------------------------------------------------------------------
+itcl::body iwidgets::Shell::constructor {args} {
+ itk_option add hull.width hull.height
+
+ #
+ # Maintain a withdrawn state until activated.
+ #
+ wm withdraw $itk_component(hull)
+
+ #
+ # Create the user child site
+ #
+ itk_component add -protected shellchildsite {
+ frame $itk_interior.shellchildsite
+ }
+ pack $itk_component(shellchildsite) -fill both -expand yes
+
+ #
+ # Set the itk_interior variable to be the childsite for derived
+ # classes.
+ #
+ set itk_interior $itk_component(shellchildsite)
+
+ #
+ # Bind the window manager delete protocol to deactivation of the
+ # widget. This can be overridden by the user via the execution
+ # of a similar command outside the class.
+ #
+ wm protocol $itk_component(hull) WM_DELETE_WINDOW [itcl::code $this deactivate]
+
+ #
+ # Initialize the widget based on the command line options.
+ #
+ eval itk_initialize $args
+}
+
+# ------------------------------------------------------------------
+# OPTIONS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# OPTION: -master
+#
+# Specifies the master window for the shell. The window manager is
+# informed that the shell is a transient window whose master is
+# -masterwindow.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::master {}
+
+# ------------------------------------------------------------------
+# OPTION: -modality
+#
+# Specify the modality of the dialog.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::modality {
+ switch $itk_option(-modality) {
+ none -
+ application -
+ global {
+ }
+
+ default {
+ error "bad modality option \"$itk_option(-modality)\":\
+ should be none, application, or global"
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -padx
+#
+# Specifies a padding distance for the childsite in the X-direction.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::padx {
+ pack config $itk_component(shellchildsite) -padx $itk_option(-padx)
+}
+
+# ------------------------------------------------------------------
+# OPTION: -pady
+#
+# Specifies a padding distance for the childsite in the Y-direction.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::pady {
+ pack config $itk_component(shellchildsite) -pady $itk_option(-pady)
+}
+
+# ------------------------------------------------------------------
+# OPTION: -width
+#
+# Specifies the width of the shell. The value may be specified in
+# any of the forms acceptable to Tk_GetPixels. A value of zero
+# causes the width to be adjusted to the required value based on
+# the size requests of the components placed in the childsite.
+# Otherwise, the width is fixed.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::width {
+ #
+ # The width option was added to the hull in the constructor.
+ # So, any width value given is passed automatically to the
+ # hull. All we have to do is play with the propagation.
+ #
+ if {$itk_option(-width) != 0} {
+ pack propagate $itk_component(hull) no
+ } else {
+ pack propagate $itk_component(hull) yes
+ }
+}
+
+# ------------------------------------------------------------------
+# OPTION: -height
+#
+# Specifies the height of the shell. The value may be specified in
+# any of the forms acceptable to Tk_GetPixels. A value of zero
+# causes the height to be adjusted to the required value based on
+# the size requests of the components placed in the childsite.
+# Otherwise, the height is fixed.
+# ------------------------------------------------------------------
+itcl::configbody iwidgets::Shell::height {
+ #
+ # The height option was added to the hull in the constructor.
+ # So, any height value given is passed automatically to the
+ # hull. All we have to do is play with the propagation.
+ #
+ if {$itk_option(-height) != 0} {
+ pack propagate $itk_component(hull) no
+ } else {
+ pack propagate $itk_component(hull) yes
+ }
+}
+
+# ------------------------------------------------------------------
+# METHODS
+# ------------------------------------------------------------------
+
+# ------------------------------------------------------------------
+# METHOD: childsite
+#
+# Return the pathname of the user accessible area.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Shell::childsite {} {
+ return $itk_component(shellchildsite)
+}
+
+# ------------------------------------------------------------------
+# METHOD: activate
+#
+# Display the dialog and wait based on the modality. For application
+# and global modal activations, perform a grab operation, and wait
+# for the result. The result may be returned via an argument to the
+# "deactivate" method.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Shell::activate {} {
+
+ if {[winfo ismapped $itk_component(hull)]} {
+ raise $itk_component(hull)
+ return
+ }
+
+ if {($itk_option(-master) != {}) && \
+ [winfo exists $itk_option(-master)]} {
+ wm transient $itk_component(hull) $itk_option(-master)
+ }
+
+ set _wait($this) 0
+ raise $itk_component(hull)
+ wm deiconify $itk_component(hull)
+ tkwait visibility $itk_component(hull)
+
+ # Need to flush the event loop. This line added as a result of
+ # SF ticket #227885.
+ update idletasks
+
+ if {$itk_option(-modality) == "application"} {
+ if {$grabstack != {}} {
+ grab release [lindex $grabstack end]
+ }
+
+ set err 1
+ while {$err == 1} {
+ set err [catch [list grab $itk_component(hull)]]
+ if {$err == 1} {
+ after 1000
+ }
+ }
+
+ lappend grabstack [list grab $itk_component(hull)]
+
+ tkwait variable [itcl::scope _wait($this)]
+ return $_result
+
+ } elseif {$itk_option(-modality) == "global" } {
+ if {$grabstack != {}} {
+ grab release [lindex $grabstack end]
+ }
+
+ set err 1
+ while {$err == 1} {
+ set err [catch [list grab -global $itk_component(hull)]]
+ if {$err == 1} {
+ after 1000
+ }
+ }
+
+ lappend grabstack [list grab -global $itk_component(hull)]
+
+ tkwait variable [itcl::scope _wait($this)]
+ return $_result
+ }
+}
+
+# ------------------------------------------------------------------
+# METHOD: deactivate
+#
+# Deactivate the display of the dialog. The method takes an optional
+# argument to passed to the "activate" method which returns the value.
+# This is only effective for application and global modal dialogs.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Shell::deactivate {args} {
+
+ if {! [winfo ismapped $itk_component(hull)]} {
+ return
+ }
+
+ if {$itk_option(-modality) == "none"} {
+ wm withdraw $itk_component(hull)
+ } elseif {$itk_option(-modality) == "application"} {
+ grab release $itk_component(hull)
+ if {$grabstack != {}} {
+ if {[set grabstack [lreplace $grabstack end end]] != {}} {
+ eval [lindex $grabstack end]
+ }
+ }
+
+ wm withdraw $itk_component(hull)
+
+ } elseif {$itk_option(-modality) == "global"} {
+ grab release $itk_component(hull)
+ if {$grabstack != {}} {
+ if {[set grabstack [lreplace $grabstack end end]] != {}} {
+ eval [lindex $grabstack end]
+ }
+ }
+
+ wm withdraw $itk_component(hull)
+ }
+
+ if {[llength $args]} {
+ set _result $args
+ } else {
+ set _result {}
+ }
+
+ set _wait($this) 1
+ return
+}
+
+# ------------------------------------------------------------------
+# METHOD: center
+#
+# Centers the dialog with respect to another widget or the screen
+# as a whole.
+# ------------------------------------------------------------------
+itcl::body iwidgets::Shell::center {{widget {}}} {
+ update idletasks
+
+ set hull $itk_component(hull)
+ set w [winfo width $hull]
+ set h [winfo height $hull]
+ set sh [winfo screenheight $hull] ;# display screen's height/width
+ set sw [winfo screenwidth $hull]
+
+ #
+ # User can request it centered with respect to root by passing in '{}'
+ #
+ if { $widget == "" } {
+ set reqX [expr {($sw-$w)/2}]
+ set reqY [expr {($sh-$h)/2}]
+ } else {
+ set wfudge 5 ;# wm width fudge factor
+ set hfudge 20 ;# wm height fudge factor
+ set widgetW [winfo width $widget]
+ set widgetH [winfo height $widget]
+ set reqX [expr {[winfo rootx $widget]+($widgetW-($widgetW/2))-($w/2)}]
+ set reqY [expr {[winfo rooty $widget]+($widgetH-($widgetH/2))-($h/2)}]
+
+ #
+ # Adjust for errors - if too long or too tall
+ #
+ if { ($reqX+$w+$wfudge) > $sw } { set reqX [expr {$sw-$w-$wfudge}] }
+ if { $reqX < $wfudge } { set reqX $wfudge }
+ if { ($reqY+$h+$hfudge) > $sh } { set reqY [expr {$sh-$h-$hfudge}] }
+ if { $reqY < $hfudge } { set reqY $hfudge }
+ }
+
+ wm geometry $hull +$reqX+$reqY
+}
+