Update tcl to version 8.5.5
[msysgit.git] / mingw / lib / tk8.4 / palette.tcl
blobc53fad5992c21e680f49738cc5422b6e35a3db10
1 # palette.tcl --
3 # This file contains procedures that change the color palette used
4 # by Tk.
6 # RCS: @(#) $Id: palette.tcl,v 1.8.2.2 2006/03/17 10:50:11 patthoyts Exp $
8 # Copyright (c) 1995-1997 Sun Microsystems, Inc.
10 # See the file "license.terms" for information on usage and redistribution
11 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 # ::tk_setPalette --
15 # Changes the default color scheme for a Tk application by setting
16 # default colors in the option database and by modifying all of the
17 # color options for existing widgets that have the default value.
19 # Arguments:
20 # The arguments consist of either a single color name, which
21 # will be used as the new background color (all other colors will
22 # be computed from this) or an even number of values consisting of
23 # option names and values. The name for an option is the one used
24 # for the option database, such as activeForeground, not -activeforeground.
26 proc ::tk_setPalette {args} {
27 if {[winfo depth .] == 1} {
28 # Just return on monochrome displays, otherwise errors will occur
29 return
32 # Create an array that has the complete new palette. If some colors
33 # aren't specified, compute them from other colors that are specified.
35 if {[llength $args] == 1} {
36 set new(background) [lindex $args 0]
37 } else {
38 array set new $args
40 if {![info exists new(background)]} {
41 error "must specify a background color"
43 set bg [winfo rgb . $new(background)]
44 if {![info exists new(foreground)]} {
45 # Note that the range of each value in the triple returned by
46 # [winfo rgb] is 0-65535, and your eyes are more sensitive to
47 # green than to red, and more to red than to blue.
48 foreach {r g b} $bg {break}
49 if {$r+1.5*$g+0.5*$b > 100000} {
50 set new(foreground) black
51 } else {
52 set new(foreground) white
56 # To avoir too many lindex...
57 foreach {fg_r fg_g fg_b} [winfo rgb . $new(foreground)] {break}
58 foreach {bg_r bg_g bg_b} $bg {break}
60 set darkerBg [format #%02x%02x%02x [expr {(9*$bg_r)/2560}] \
61 [expr {(9*$bg_g)/2560}] [expr {(9*$bg_b)/2560}]]
62 foreach i {activeForeground insertBackground selectForeground \
63 highlightColor} {
64 if {![info exists new($i)]} {
65 set new($i) $new(foreground)
68 if {![info exists new(disabledForeground)]} {
69 set new(disabledForeground) [format #%02x%02x%02x \
70 [expr {(3*$bg_r + $fg_r)/1024}] \
71 [expr {(3*$bg_g + $fg_g)/1024}] \
72 [expr {(3*$bg_b + $fg_b)/1024}]]
74 if {![info exists new(highlightBackground)]} {
75 set new(highlightBackground) $new(background)
77 if {![info exists new(activeBackground)]} {
78 # Pick a default active background that islighter than the
79 # normal background. To do this, round each color component
80 # up by 15% or 1/3 of the way to full white, whichever is
81 # greater.
83 foreach i {0 1 2} color "$bg_r $bg_g $bg_b" {
84 set light($i) [expr {$color/256}]
85 set inc1 [expr {($light($i)*15)/100}]
86 set inc2 [expr {(255-$light($i))/3}]
87 if {$inc1 > $inc2} {
88 incr light($i) $inc1
89 } else {
90 incr light($i) $inc2
92 if {$light($i) > 255} {
93 set light($i) 255
96 set new(activeBackground) [format #%02x%02x%02x $light(0) \
97 $light(1) $light(2)]
99 if {![info exists new(selectBackground)]} {
100 set new(selectBackground) $darkerBg
102 if {![info exists new(troughColor)]} {
103 set new(troughColor) $darkerBg
105 if {![info exists new(selectColor)]} {
106 set new(selectColor) #b03060
109 # let's make one of each of the widgets so we know what the
110 # defaults are currently for this platform.
111 toplevel .___tk_set_palette
112 wm withdraw .___tk_set_palette
113 foreach q {
114 button canvas checkbutton entry frame label labelframe
115 listbox menubutton menu message radiobutton scale scrollbar
116 spinbox text
118 $q .___tk_set_palette.$q
121 # Walk the widget hierarchy, recoloring all existing windows.
122 # The option database must be set according to what we do here,
123 # but it breaks things if we set things in the database while
124 # we are changing colors...so, ::tk::RecolorTree now returns the
125 # option database changes that need to be made, and they
126 # need to be evalled here to take effect.
127 # We have to walk the whole widget tree instead of just
128 # relying on the widgets we've created above to do the work
129 # because different extensions may provide other kinds
130 # of widgets that we don't currently know about, so we'll
131 # walk the whole hierarchy just in case.
133 eval [tk::RecolorTree . new]
135 destroy .___tk_set_palette
137 # Change the option database so that future windows will get the
138 # same colors.
140 foreach option [array names new] {
141 option add *$option $new($option) widgetDefault
144 # Save the options in the variable ::tk::Palette, for use the
145 # next time we change the options.
147 array set ::tk::Palette [array get new]
150 # ::tk::RecolorTree --
151 # This procedure changes the colors in a window and all of its
152 # descendants, according to information provided by the colors
153 # argument. This looks at the defaults provided by the option
154 # database, if it exists, and if not, then it looks at the default
155 # value of the widget itself.
157 # Arguments:
158 # w - The name of a window. This window and all its
159 # descendants are recolored.
160 # colors - The name of an array variable in the caller,
161 # which contains color information. Each element
162 # is named after a widget configuration option, and
163 # each value is the value for that option.
165 proc ::tk::RecolorTree {w colors} {
166 upvar $colors c
167 set result {}
168 set prototype .___tk_set_palette.[string tolower [winfo class $w]]
169 if {![winfo exists $prototype]} {
170 unset prototype
172 foreach dbOption [array names c] {
173 set option -[string tolower $dbOption]
174 set class [string replace $dbOption 0 0 [string toupper \
175 [string index $dbOption 0]]]
176 if {![catch {$w configure $option} value]} {
177 # if the option database has a preference for this
178 # dbOption, then use it, otherwise use the defaults
179 # for the widget.
180 set defaultcolor [option get $w $dbOption $class]
181 if {[string match {} $defaultcolor] || \
182 ([info exists prototype] && \
183 [$prototype cget $option] ne "$defaultcolor")} {
184 set defaultcolor [winfo rgb . [lindex $value 3]]
185 } else {
186 set defaultcolor [winfo rgb . $defaultcolor]
188 set chosencolor [winfo rgb . [lindex $value 4]]
189 if {[string match $defaultcolor $chosencolor]} {
190 # Change the option database so that future windows will get
191 # the same colors.
192 append result ";\noption add [list \
193 *[winfo class $w].$dbOption $c($dbOption) 60]"
194 $w configure $option $c($dbOption)
198 foreach child [winfo children $w] {
199 append result ";\n[::tk::RecolorTree $child c]"
201 return $result
204 # ::tk::Darken --
205 # Given a color name, computes a new color value that darkens (or
206 # brightens) the given color by a given percent.
208 # Arguments:
209 # color - Name of starting color.
210 # perecent - Integer telling how much to brighten or darken as a
211 # percent: 50 means darken by 50%, 110 means brighten
212 # by 10%.
214 proc ::tk::Darken {color percent} {
215 foreach {red green blue} [winfo rgb . $color] {
216 set red [expr {($red/256)*$percent/100}]
217 set green [expr {($green/256)*$percent/100}]
218 set blue [expr {($blue/256)*$percent/100}]
219 break
221 if {$red > 255} {
222 set red 255
224 if {$green > 255} {
225 set green 255
227 if {$blue > 255} {
228 set blue 255
230 return [format "#%02x%02x%02x" $red $green $blue]
233 # ::tk_bisque --
234 # Reset the Tk color palette to the old "bisque" colors.
236 # Arguments:
237 # None.
239 proc ::tk_bisque {} {
240 tk_setPalette activeBackground #e6ceb1 activeForeground black \
241 background #ffe4c4 disabledForeground #b0b0b0 foreground black \
242 highlightBackground #ffe4c4 highlightColor black \
243 insertBackground black selectColor #b03060 \
244 selectBackground #e6ceb1 selectForeground black \
245 troughColor #cdb79e