source: trunk/gui/scripts/dropdown.tcl @ 738

Last change on this file since 738 was 676, checked in by mmc, 17 years ago

Fixed all fonts to set pixelsize instead of pointsize, so that fonts in
the latest X distribution look right.

Added initial Rappture::bugreport::submit command for submitting bug
reports to nanoHUB.org. This isn't tied in yet, but it's a start.

File size: 6.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: dropdown - base class for drop-down panels
3#
4#  This is the base class for a family of drop-down widget panels.
5#  They might be used, for example, to build the drop-down list for
6#  a combobox.
7#
8# ======================================================================
9#  AUTHOR:  Michael McLennan, Purdue University
10#  Copyright (c) 2004-2005  Purdue Research Foundation
11#
12#  See the file "license.terms" for information on usage and
13#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14# ======================================================================
15package require Itk
16
17option add *Dropdown.textBackground white widgetDefault
18option add *Dropdown.outline black widgetDefault
19option add *Dropdown.borderwidth 1 widgetDefault
20option add *Dropdown.font -*-helvetica-medium-r-normal-*-12-* widgetDefault
21
22itcl::class Rappture::Dropdown {
23    inherit itk::Toplevel
24
25    itk_option define -outline outline Outline ""
26    itk_option define -postcommand postCommand PostCommand ""
27    itk_option define -unpostcommand unpostCommand UnpostCommand ""
28
29    constructor {args} { # defined below }
30
31    public method post {where args}
32    public method unpost {}
33
34    protected method _adjust {{widget ""}}
35
36    public proc outside {w x y}
37
38    bind RapptureDropdown <ButtonPress> \
39        {if {[Rappture::Dropdown::outside %W %X %Y]} {%W unpost}}
40}
41
42itk::usual Dropdown {
43    keep -background -outline -cursor -font
44}
45
46# ----------------------------------------------------------------------
47# CONSTRUCTOR
48# ----------------------------------------------------------------------
49itcl::body Rappture::Dropdown::constructor {args} {
50    wm overrideredirect $itk_component(hull) yes
51    wm withdraw $itk_component(hull)
52
53    component hull configure -borderwidth 1 -background black
54    itk_option remove hull.background hull.borderwidth
55
56    # add bindings to release the grab
57    set btags [bindtags $itk_component(hull)]
58    bindtags $itk_component(hull) [linsert $btags 1 RapptureDropdown]
59
60    eval itk_initialize $args
61}
62
63# ----------------------------------------------------------------------
64# USAGE: post @<x>,<y>
65# USAGE: post <widget> <justify>
66#
67# Clients use this to pop up the dropdown on the screen.  The position
68# should be either a specific location "@x,y", or a <widget> and its
69# justification.
70# ----------------------------------------------------------------------
71itcl::body Rappture::Dropdown::post {where args} {
72    set owner [expr {([winfo exists $where]) ? $where : ""}]
73    _adjust $owner    ;# make sure contents are up-to-date
74    update idletasks  ;# fix size info
75
76    if {[string length $itk_option(-postcommand)] > 0} {
77        set cmd [list uplevel #0 $itk_option(-postcommand)]
78        if {[catch $cmd result]} {
79            bgerror $result
80        }
81    }
82
83    set w [winfo width $itk_component(hull)]
84    set h [winfo height $itk_component(hull)]
85    set sw [winfo screenwidth $itk_component(hull)]
86    set sh [winfo screenwidth $itk_component(hull)]
87
88    if {[regexp {^@([0-9]+),([0-9]+)$} $where match x y]} {
89        set xpos $x
90        set ypos $y
91    } elseif {[winfo exists $where]} {
92        set x0 [winfo rootx $where]
93        switch -- $args {
94            left { set xpos $x0 }
95            right { set xpos [expr {$x0 + [winfo width $where] - $sw}] }
96            default {
97                error "bad option \"$args\": should be left, right"
98            }
99        }
100        set ypos [expr {[winfo rooty $where]+[winfo height $where]}]
101    } else {
102        error "bad position \"$where\": should be widget name or @x,y"
103    }
104
105    # make sure the dropdown doesn't go off screen
106    if {$xpos > 0} {
107        # left-justified positions
108        if {$xpos + $w > $sw} {
109            set xpos [expr {$sw-$w}]
110            if {$xpos < 0} { set xpos 0 }
111        }
112        set xpos "+$xpos"
113    } else {
114        # right-justified positions
115        if {$xpos - $w < -$sw} {
116            set xpos [expr {-$sw+$w}]
117            if {$xpos > 0} { set xpos -1 }
118        }
119    }
120    if {$ypos + $h > $sh} {
121        set ypos [expr {$sh-$h}]
122        if {$ypos < 0} { set ypos 0 }
123    }
124
125    # post the dropdown on the screen
126    wm geometry $itk_component(hull) "$xpos+$ypos"
127    update
128
129    wm deiconify $itk_component(hull)
130    raise $itk_component(hull)
131
132    # grab the mouse pointer
133    update
134    while {[catch {grab set -global $itk_component(hull)}]} {
135        after 100
136    }
137}
138
139# ----------------------------------------------------------------------
140# USAGE: unpost
141#
142# Takes down the dropdown, if it is showing on the screen.
143# ----------------------------------------------------------------------
144itcl::body Rappture::Dropdown::unpost {} {
145    grab release $itk_component(hull)
146    wm withdraw $itk_component(hull)
147
148    if {[string length $itk_option(-unpostcommand)] > 0} {
149        set cmd [list uplevel #0 $itk_option(-unpostcommand)]
150        if {[catch $cmd result]} {
151            bgerror $result
152        }
153    }
154}
155
156# ----------------------------------------------------------------------
157# USAGE: _adjust
158#
159# This method is invoked each time the dropdown is posted to adjust
160# its size and contents.
161# ----------------------------------------------------------------------
162itcl::body Rappture::Dropdown::_adjust {{widget ""}} {
163    # derived classes redefine this to do something useful
164}
165
166# ----------------------------------------------------------------------
167# USAGE: outside <widget> <x> <y>
168#
169# Checks to see if the root coordinate <x>,<y> is outside of the
170# area for the <widget>.  Returns 1 if so, and 0 otherwise.
171# ----------------------------------------------------------------------
172itcl::body Rappture::Dropdown::outside {widget x y} {
173    return [expr {$x < [winfo rootx $widget]
174             || $x > [winfo rootx $widget]+[winfo width $widget]
175             || $y < [winfo rooty $widget]
176             || $y > [winfo rooty $widget]+[winfo height $widget]}]
177}
178
179# ----------------------------------------------------------------------
180# CONFIGURATION OPTION: -outline
181# ----------------------------------------------------------------------
182itcl::configbody Rappture::Dropdown::outline {
183    component hull configure -background $itk_option(-outline)
184}
Note: See TracBrowser for help on using the repository browser.