source: trunk/gui/scripts/periodictable.tcl @ 1627

Last change on this file since 1627 was 1627, checked in by gah, 15 years ago

added periodic element table control

File size: 19.9 KB
Line 
1
2# ----------------------------------------------------------------------
3#  COMPONENT: periodictable - drop-down list of items
4#
5#  This is a drop-down listbox, which might be used in conjunction
6#  with 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 *PeriodicTable.textBackground white widgetDefault
18option add *PeriodicTable.outline black widgetDefault
19option add *PeriodicTable.borderwidth 1 widgetDefault
20option add *PeriodicTable.relief flat widgetDefault
21option add *PeriodicTable.font "Arial 8"
22
23itcl::class Rappture::PeriodicTable {
24    inherit Rappture::Dropdown
25
26    constructor {args} { # defined below }
27
28    public method enable {args}
29    public method disable {args}
30    public method get {args}
31    public method select {name}
32    public method value { {name ""} }
33
34    private variable _table
35    private variable _dispatcher ""
36    private variable _current ""
37    private variable _state
38
39    protected method _adjust {{widget ""}}
40
41    protected method _react {}
42    protected method Redraw {}
43    protected method Activate { widget id x y }
44    protected method Deactivate { widget id }
45    protected method FindElement { string }
46    private common _colors
47    array set _colors {
48        actinoid-activebackground                       \#cd679a
49        actinoid-activeforeground                       white
50        actinoid-disabledbackground                     \#ff99cc 
51        actinoid-disabledforeground                     \#D97DAB
52        actinoid-background                             \#ff99cc
53        actinoid-foreground                             black
54        alkali_metal-activebackground                   \#cd3434
55        alkali_metal-activeforeground                   white
56        alkali_metal-disabledbackground                 \#ff6666
57        alkali_metal-disabledforeground                 \#D04747
58        alkali_metal-background                         \#ff6666
59        alkali_metal-foreground                         black
60        alkaline_earth_metal-activebackground           \#cdac7b
61        alkaline_earth_metal-activeforeground           white
62        alkaline_earth_metal-disabledbackground         \#ffdead
63        alkaline_earth_metal-disabledforeground         \#C19A64
64        alkaline_earth_metal-background                 \#ffdead
65        alkaline_earth_metal-foreground                 black
66        halogen-activebackground                        \#cdcd67
67        halogen-activeforeground                        white
68        halogen-disabledbackground                      \#ffff99
69        halogen-disabledforeground                      \#D5D562
70        halogen-background                              \#ffff99
71        halogen-foreground                              black
72        lanthanoid-activebackground                     \#cd8dcd
73        lanthanoid-activeforeground                     white
74        lanthanoid-disabledbackground                   \#ffbfff
75        lanthanoid-disabledforeground                   \#D884D8
76        lanthanoid-background                           \#ffbfff
77        lanthanoid-foreground                           black
78        metalloid-activebackground                      \#9a9a67
79        metalloid-activeforeground                      white
80        metalloid-disabledbackground                    \#cccc99
81        metalloid-disabledforeground                    \#92922C
82        metalloid-background                            \#cccc99
83        metalloid-foreground                            black
84        noble_gas-activebackground                      \#8ecdcd
85        noble_gas-activeforeground                      white
86        noble_gas-disabledbackground                    \#c0ffff
87        noble_gas-disabledforeground                    \#7FC1C1
88        noble_gas-background                            \#c0ffff
89        noble_gas-foreground                            black
90        other_non_metal-activebackground                \#6ecd6e
91        other_non_metal-activeforeground                white
92        other_non_metal-disabledbackground              \#a0ffa0
93        other_non_metal-disabledforeground              \#6ACD6A
94        other_non_metal-background                      \#a0ffa0
95        other_non_metal-foreground                      black
96        post_transition_metal-activebackground          \#9a9a9a       
97        post_transition_metal-activeforeground          white
98        post_transition_metal-disabledbackground        \#cccccc
99        post_transition_metal-disabledforeground        \#999999
100        post_transition_metal-background                \#cccccc
101        post_transition_metal-foreground                black
102        transition_metal-activebackground               \#cd8e8e
103        transition_metal-activeforeground               white
104        transition_metal-disabledbackground             \#ffc0c0
105        transition_metal-disabledforeground             \#C77E7E
106        transition_metal-background                     \#ffc0c0
107        transition_metal-foreground                     black
108        unknown-activebackground                        \#cdcdcd
109        unknown-activeforeground                        white
110        unknown-disabledbackground                      \#ffffff
111        unknown-disabledforeground                      \#B9B9B9
112        unknown-background                              \#ffffff
113        unknown-foreground                              black
114    }
115    private common _tableData {
116        Hydrogen        1  H  1.0079    1 1     other_non_metal
117        Helium          2  He 4.0026    1 18    noble_gas
118        Lithium         3  Li 6.941(2)  2 1     alkali_metal
119        Beryllium       4  Be 9.0122    2 2     alkaline_earth_metal
120        Boron           5  B  10.811(7) 2 13    metalloid
121        Carbon          6  C  12.011    2 14    other_non_metal
122        Nitrogen        7  N  14.007    2 15    other_non_metal
123        Oxygen          8  O  15.999    2 16    other_non_metal
124        Fluorine        9  F  18.998    2 17    halogen
125        Neon            10 Ne 20.180    2 18    noble_gas
126       
127        Sodium          11 Na 22.990    3 1     alkali_metal
128        Magnesium       12 Mg 24.305    3 2     alkaline_earth_metal
129        Aluminium       13 Al 26.982    3 13    post_transition_metal
130        Silicon         14 Si 28.086    3 14    metalloid
131        Phosphorus      15 P  30.974    3 15    other_non_metal
132        Sulfur          16 S  32.066(6) 3 16    other_non_metal
133        Chlorine        17 Cl 35.453    3 17    halogen
134        Argon           18 Ar 39.948(1) 3 18    noble_gas
135       
136        Potassium       19 K  39.098    4 1     alkali_metal
137        Calcium         20 Ca 40.078(4) 4 2     alkaline_earth_metal
138        Scandium        21 Sc 44.956    4 3     transition_metal
139        Titanium        22 Ti 47.867(1) 4 4     transition_metal
140        Vanadium        23 V  50.942(1) 4 5     transition_metal
141        Chromium        24 Cr 51.996    4 6     transition_metal
142        Manganese       25 Mn 54.938    4 7     transition_metal
143        Iron            26 Fe 55.845(2) 4 8     transition_metal
144        Cobalt          27 Co 58.933    4 9     transition_metal
145        Nickel          28 Ni 58.693    4 10    transition_metal
146        Copper          29 Cu 63.546(3) 4 11    transition_metal
147        Zinc            30 Zn 65.39(2)  4 12    transition_metal
148        Gallium         31 Ga 69.723(1) 4 13    post_transition_metal
149        Germanium       32 Ge 72.61(2)  4 14    metalloid
150        Arsenic         33 As 74.922    4 15    metalloid
151        Selenium        34 Se 78.96(3)  4 16    other_non_metal
152        Bromine         35 Br 79.904(1) 4 17    halogen
153        Krypton         36 Kr 83.80(1)  4 18    noble_gas
154       
155        Rubidium        37 Rb 85.468    5 1     alkali_metal
156        Strontium       38 Sr 87.62(1)  5 2     alkaline_earth_metal
157        Yttrium         39 Y  88.906    5 3     transition_metal
158        Zirconium       40 Zr 91.224(2) 5 4     transition_metal
159        Niobium         41 Nb 92.906    5 5     transition_metal
160        Molybdenum      42 Mo 95.94(1)  5 6     transition_metal
161        Technetium      43 Tc [97.907]  5 7     transition_metal
162        Ruthenium       44 Ru 101.07(2) 5 8     transition_metal
163        Rhodium         45 Rh 102.906   5 9     transition_metal
164        Palladium       46 Pd 106.42(1) 5 10    transition_metal
165        Silver          47 Ag 107.868   5 11    transition_metal
166        Cadmium         48 Cd 112.411(8) 5 12   transition_metal
167        Indium          49 In 114.818(3) 5 13   post_transition_metal
168        Tin             50 Sn 118.710(7) 5 14   post_transition_metal
169        Antimony        51 Sb 121.760(1) 5 15   metalloid
170        Tellurium       52 Te 127.60(3) 5 16    metalloid
171        Iodine          53 I  126.904   5 17    halogen
172        Xenon           54 Xe 131.29(2) 5 18    noble_gas
173       
174        Cesium          55 Cs 132.905   6 1     alkali_metal
175        Barium          56 Ba 137.327(7) 6 2    alkaline_earth_metal
176        Lanthanides     57-71 * *       6 3     lanthanoid
177        Hafnium         72 Hf 178.49(2) 6 4     transition_metal
178        Tantalum        73 Ta 180.948   6 5     transition_metal
179        Tungsten        74 W  183.84(1) 6 6     transition_metal
180        Rhenium         75 Re 186.207(1) 6 7    transition_metal
181        Osmium          76 Os 190.23(3) 6 8     transition_metal
182        Iridium         77 Ir 192.217(3) 6 9    transition_metal
183        Platinum        78 Pt 195.084(9) 6 10   transition_metal
184        Gold            79 Au 196.967 6 11      transition_metal
185        Mercury         80 Hg 200.59(2) 6 12    transition_metal
186        Thallium        81 Tl 204.383   6 13    post_transition_metal
187        Lead            82 Pb 207.2(1) 6 14     post_transition_metal
188        Bismuth         83 Bi 208.980   6 15    post_transition_metal
189        Polonium        84 Po [208.982] 6 16    metalloid
190        Astatine        85 At [209.987] 6 17    halogen
191        Radon           86 Rn [222.018] 6 18    noble_gas
192       
193        Francium        87 Fr [223.020] 7 1     alkali_metal
194        Radium          88 Ra [226.0254] 7 2    alkaline_earth_metal
195        Actinides       89-103 * * 7 3          actinoid
196        Rutherfordium   104 Rf [263.113] 7 4    transition_metal
197        Dubnium         105 Db [262.114] 7 5    transition_metal
198        Seaborgium      106 Sg [266.122] 7 6    transition_metal
199        Bohrium         107 Bh [264.1247] 7 7   transition_metal
200        Hassium         108 Hs [269.134] 7 8    transition_metal
201        Meitnerium      109 Mt [268.139] 7 9    transition_metal
202        Darmstadtium    110 Ds [272.146] 7 10   transition_metal
203        Roentgenium     111 Rg [272.154] 7 11   transition_metal
204        Ununbium        112 Uub [277]   7 12    transition_metal
205        Ununtrium       113 Uut [284] 7 13      post_transition_metal
206        Ununquadium     114 Uuq [289] 7 14      post_transition_metal
207        Ununpentium     115 Uup [288] 7 15      post_transition_metal
208        Ununhexium      116 Uuh [292]  7 16     post_transition_metal
209        Ununseptium     117 Uus ? 7 17          unknown
210        Ununoctium      118 Uuo [294] 7 18      unknown
211       
212        Lanthanum       57 La 138.905 8 3       lanthanoid
213        Cerium          58 Ce 140.116(1) 8 4    lanthanoid
214        Praseodymium    59 Pr 140.908 8 5       lanthanoid
215        Neodymium       60 Nd 144.242(3) 8 6    lanthanoid
216        Promethium      61 Pm [144.913] 8 7     lanthanoid
217        Samarium        62 Sm 150.36(2) 8 8     lanthanoid
218        Europium        63 Eu 151.964(1) 8 9    lanthanoid
219        Gadolinium      64 Gd 157.25(3) 8 10    lanthanoid
220        Terbium         65 Tb 158.925   8 11    lanthanoid
221        Dysprosium      66 Dy 162.500(1) 8 12   lanthanoid
222        Holmium         67 Ho 164.930 8 13      lanthanoid
223        Erbium          68 Er 167.259(3) 8 14   lanthanoid
224        Thulium         69 Tm 168.934   8 15    lanthanoid
225        Ytterbium       70 Yb 173.04(3) 8 16    lanthanoid
226        Lutetium        71 Lu 174.967(1) 8 17   lanthanoid
227       
228        Actinium        89 Ac [227.027] 9 3     actinoid
229        Thorium         90 Th 232.038   9 4     actinoid
230        Protactinium    91 Pa 231.036 9 5       actinoid
231        Uranium         92 U 238.029 9 6        actinoid
232        Neptunium       93 Np [237.048] 9 7     actinoid
233        Plutonium       94 Pu [244.064] 9 8     actinoid
234        Americium       95 Am [243.061] 9 9     actinoid
235        Curium          96 Cm [247.070] 9 10    actinoid
236        Berkelium       97 Bk [247.070] 9 11    actinoid
237        Californium     98 Cf [251.080] 9 12    actinoid
238        Einsteinium     99 Es [252.083] 9 13    actinoid
239        Fermium         100 Fm [257.095] 9 14   actinoid
240        Mendelevium     101 Md [258.098] 9 15   actinoid
241        Nobelium        102 No [259.101] 9 16   actinoid
242        Lawrencium      103 Lr [262.110] 9 17   actinoid
243    }
244}
245   
246itk::usual PeriodicTable {
247    keep -background -outline -cursor
248}
249
250# ----------------------------------------------------------------------
251# CONSTRUCTOR
252# ----------------------------------------------------------------------
253itcl::body Rappture::PeriodicTable::constructor {args} {
254    Rappture::dispatcher _dispatcher
255    $_dispatcher register !rebuild
256    $_dispatcher dispatch $this !rebuild "[itcl::code $this Redraw]; list"
257    foreach { name number symbol weight row column type } $_tableData {
258        set _table($name) [list name $name number $number symbol $symbol \
259                weight $weight row $row column $column type $type]
260        set _state($name) "normal"
261    }
262    itk_component add scroller {
263        Rappture::Scroller $itk_interior.sc \
264            -xscrollmode off -yscrollmode auto
265    }
266    pack $itk_component(scroller) -expand yes -fill both
267
268    itk_component add table {
269        canvas $itk_component(scroller).table \
270            -highlightthickness 0
271    } {
272        usual
273        rename -background -textbackground textBackground Background
274        ignore -highlightthickness -highlightbackground -highlightcolor
275        keep -relief
276    }
277    $itk_component(scroller) contents $itk_component(table)
278
279    # add bindings so the table can react to selections
280    bind RappturePeriodicTable-$this <ButtonRelease-1> [itcl::code $this _react]
281    bind RappturePeriodicTable-$this <KeyPress-Return> [itcl::code $this _react]
282    bind RappturePeriodicTable-$this <KeyPress-space> [itcl::code $this _react]
283    bind RappturePeriodicTable-$this <KeyPress-Escape> [itcl::code $this unpost]
284
285    set btags [bindtags $itk_component(table)]
286    set i [lsearch $btags [winfo class $itk_component(table)]]
287    if {$i < 0} {
288        set i end
289    }
290    set btags [linsert $btags [expr {$i+1}] RappturePeriodicTable-$this]
291    bindtags $itk_component(table) $btags
292   
293    eval itk_initialize $args
294    Redraw
295}
296
297# ----------------------------------------------------------------------
298# USAGE: enable <list of elements>
299#
300# Inserts one or more values into this drop-down list.  Each value
301# has a keyword (computer-friendly value) and a label (human-friendly
302# value).  The labels appear in the listbox.  If the label is "--",
303# then the value is used as the label.
304# ----------------------------------------------------------------------
305itcl::body Rappture::PeriodicTable::enable {args} {
306    set c $itk_component(table)
307    foreach elem [array names _table] {
308        set _state($elem) "disabled"
309        $c bind $elem <Enter> {}
310        $c bind $elem <Leave> {}
311        $c bind $elem <ButtonRelease-1> {}
312    }
313    foreach arg $args {
314        set elem [FindElement $arg]
315        if { $elem == "" } {
316            puts stderr "unknown element \"$arg\""
317        } else {
318            set _state($elem) "normal"
319            $c bind $elem <Enter> \
320                [itcl::code $this Activate %W $elem %X %Y]
321            $c bind $elem <Leave> [itcl::code $this Deactivate %W $elem]
322            $c bind $elem <ButtonRelease-1> [itcl::code $this value $elem]
323        }
324    }
325    Redraw
326    $_dispatcher event -idle !rebuild
327}
328
329# ----------------------------------------------------------------------
330# USAGE: exclude <list of elements>
331#
332# Inserts one or more values into this drop-down list.  Each value
333# has a keyword (computer-friendly value) and a label (human-friendly
334# value).  The labels appear in the listbox.  If the label is "--",
335# then the value is used as the label.
336# ----------------------------------------------------------------------
337itcl::body Rappture::PeriodicTable::disable {args} {
338    set c $itk_component(table)
339    foreach name [array names _table] {
340        set _state($name) "normal"
341        $c bind $elem <Enter> \
342            [itcl::code $this Activate %W $elem %X %Y]
343        $c bind $elem <Leave> [itcl::code $this Deactivate %W $elem]
344        $c bind $elem <ButtonRelease-1> [itcl::code $this value $elem]
345    }
346    foreach arg $args {
347        set elem [FindElement $arg]
348        if { $elem == "" } {
349            puts stderr "unknown element \"$arg\""
350        } else {
351            set _state($elem) "disabled"
352            $c bind $elem <Enter> {}
353            $c bind $elem <Leave> {}
354            $c bind $elem <ButtonRelease-1> {}
355        }
356    }
357    Redraw
358    $_dispatcher event -idle !rebuild
359}
360
361# ----------------------------------------------------------------------
362# USAGE: get ?-symbol|-name|-all? ?name?
363#
364# Queries one or more values from the drop-down list.  With no args,
365# it returns a list of all values and labels in the list.  If the
366# index is specified, then it returns the value or label (or both)
367# for the specified index.
368# ----------------------------------------------------------------------
369itcl::body Rappture::PeriodicTable::get { args } {
370    set first [lindex $args 0]
371    set choices {-symbol -weight -number -name -all}
372    set format "-name"
373    if {[string index $first 0] == "-"} {
374        if {[lsearch $choices $first] < 0} {
375            error "bad option \"$first\": should be [join [lsort $choices] {, }]"
376        }
377        set format $first
378        set args [lrange $args 1 end]
379    }
380    # return the whole list or just a single value
381    if {[llength $args] > 1} {
382        error "wrong # args: should be [join [lsort $choices] {, }]"
383    }
384    if {[llength $args] == 0} {
385        set name $_current
386    } else {
387        set name [lindex $args 0]
388    }
389    set elem [FindElement $name]
390    if { $elem == "" || $_state($elem) == "disabled" } {
391        return ""
392    }
393    array set info $_table($elem)
394    # scan through and build up the return list
395    switch -- $format {
396        -name   { set value $info(name)   }
397        -symbol { set value $info(symbol) }
398        -weight { set value $info(weight) }
399        -number { set value $info(number) }
400        -all {
401            foreach key { name weight number name } {
402                lappend value name $info($key)
403            }
404        }
405    }
406    return $value
407}
408
409# ----------------------------------------------------------------------
410# USAGE: select <name>
411#
412# Used to manipulate the selection in the table.
413#
414# ----------------------------------------------------------------------
415itcl::body Rappture::PeriodicTable::select { what } {
416    set elem [FindElement $what]
417    if { $elem == "" } {
418        set elem "Hydrogen"
419    }
420    set _current $elem
421    $_dispatcher event -idle !rebuild
422}
423
424# ----------------------------------------------------------------------
425# USAGE: _adjust ?<widget>?
426#
427# This method is invoked each time the dropdown is posted to adjust
428# its size and contents.  If the <widget> is specified, it is the
429# controlling widget.
430# ----------------------------------------------------------------------
431itcl::body Rappture::PeriodicTable::_adjust {{widget ""}} {
432    chain $widget
433
434    focus $itk_component(table)
435}
436
437# ----------------------------------------------------------------------
438# USAGE: _react
439#
440# Invoked automatically when the user has selected something from
441# the listbox.  Unposts the drop-down and generates an event letting
442# the client know that the selection has changed.
443# ----------------------------------------------------------------------
444itcl::body Rappture::PeriodicTable::_react {} {
445    unpost
446    event generate $itk_component(hull) <<PeriodicTableSelect>>
447}
448
449itcl::body Rappture::PeriodicTable::Activate { canvas id x y } {
450    set c $itk_component(table)
451    array set info $_table($id)
452    set type $info(type)
453    set fg $_colors($type-activeforeground)
454    set bg $_colors($type-activebackground)
455    $c itemconfigure $id-rect -outline black -width 1 -fill $bg
456    $c itemconfigure $id-number -fill white
457    $c itemconfigure $id-symbol -fill white
458    ::Rappture::Tooltip::text $c \
459        "$info(name) ($info(symbol))\nNumber: $info(number)\nWeight: $info(weight)"
460    ::Rappture::Tooltip::tooltip pending $c @$x,$y
461}
462
463itcl::body Rappture::PeriodicTable::Deactivate { canvas id } {
464    set c $itk_component(table)
465    array set info $_table($id)
466    set type $info(type)
467    set fg $_colors($type-foreground)
468    set bg $_colors($type-background)
469    $c itemconfigure $id-rect -outline $fg -width 1 -fill $bg
470    $c itemconfigure $id-number -fill $fg
471    $c itemconfigure $id-symbol -fill $fg
472    ::Rappture::Tooltip::tooltip cancel
473}
474
475itcl::body Rappture::PeriodicTable::value {{value "" }} {
476    if { $value != "" } {
477        set _current $value
478    }
479}
480
481# ----------------------------------------------------------------------
482# USAGE: Redraw
483#
484# Invoked automatically when the user has selected something from
485# the canvas.  Unposts the drop-down and generates an event letting
486# the client know that the selection has changed.
487# ----------------------------------------------------------------------
488itcl::body Rappture::PeriodicTable::Redraw {} {
489set sqwidth 24
490set sqheight 24
491set xoffset 4
492set yoffset 4
493set last ""
494    set c $itk_component(table)
495    $c delete all
496    foreach name [array names _table] {
497        array set info $_table($name)
498        set x1 [expr ($info(column)-1)*$sqwidth+$xoffset]
499        set y1 [expr ($info(row)-1)*$sqheight+$yoffset]
500        set x2 [expr ($info(column)*$sqwidth)-2+$xoffset]
501        set y2 [expr ($info(row)*$sqheight)-2+$yoffset]
502        #puts stderr symbol=$info(symbol)
503        set type $info(type)
504        if { $_state($name) == "disabled" } {
505            set fg $_colors($type-disabledforeground)
506            set bg $_colors($type-disabledbackground)
507        } else {
508            set fg $_colors($type-foreground)
509            set bg $_colors($type-background)
510        }
511        $c create rectangle $x1 $y1 $x2 $y2 -outline $fg -fill $bg \
512            -tags $info(name)-rect
513        if { $info(symbol) != "*" } {
514            $c create text [expr ($x2+$x1)/2+1] [expr ($y2+$y1)/2+4] \
515                -anchor c -fill $fg \
516                -text [string range $info(symbol) 0 4] \
517                -font "Arial 8 bold" -tags $info(name)-symbol
518            $c create text [expr $x2-2] [expr $y1+2] -anchor ne \
519                -text $info(number) -fill $fg \
520                -font "math1 6" -tags $info(name)-number
521        }
522        $c create rectangle $x1 $y1 $x2 $y2 -outline "" -fill "" \
523            -tags $info(name)
524        if { $_state($name) == "normal" } {
525        $c bind $info(name) <Enter> \
526            [itcl::code $this Activate %W $info(name) %X %Y]
527        $c bind $info(name) <Leave> [itcl::code $this Deactivate %W $info(name)]
528        $c bind $info(name) <ButtonRelease-1> [itcl::code $this value $info(name)]
529        }
530    }
531    update
532    foreach { x1 y1 x2 y2 } [$c bbox all] break
533    set width [expr $x2-$x1+$xoffset*2]
534    set height [expr $y2-$y1+$yoffset*2]
535    $c configure -height $height -width $width -background white
536}
537
538# ----------------------------------------------------------------------
539# USAGE: select <name>
540#
541# Used to manipulate the selection in the table.
542#
543# ----------------------------------------------------------------------
544itcl::body Rappture::PeriodicTable::FindElement { what } {
545    foreach name [array names _table] {
546        array set info $_table($name)
547        if { $what == $info(name) || $what == $info(number) ||
548             $what == $info(symbol) } {
549            break
550        }
551        array unset info
552    }
553    if { [info exists info] } {
554        return $info(name)
555    }
556    return ""
557}
558
Note: See TracBrowser for help on using the repository browser.