# copyright (C) 1995-2004 Jean-Luc Fontaine (mailto:jfontain@free.fr) package require Tk 8.3 package require stooop ::stooop::class canvasReliefRectangle { proc canvasReliefRectangle {this canvas args} switched {$args} { set ($this,topLeft)\ [$canvas create line 0 0 0 0 0 0 -tags canvasReliefRectangle($this)] set ($this,bottomRight)\ [$canvas create line 0 0 0 0 0 0 -tags canvasReliefRectangle($this)] set ($this,canvas) $canvas switched::complete $this } proc ~canvasReliefRectangle {this} { $($this,canvas) delete canvasReliefRectangle($this) } proc options {this} { # force background initialization for color calculations return [list\ [list -background white]\ [list -coordinates {0 0 0 0} {0 0 0 0}]\ [list -relief flat flat]\ ] } proc set-background {this value} { ;# algorithm stolen from tkUnix3d.c set intensity 65535 ;# maximum intensity foreach {red green blue} [winfo rgb $($this,canvas) $value] {} if {\ (\ ($red * 0.5 * $red) + ($green * 1.0 * $green) +\ ($blue * 0.28 * $blue)\ ) < ($intensity * 0.05 * $intensity)\ } { set ($this,dark) [format {#%04X%04X%04X}\ [expr {($intensity + (3 * $red)) / 4}]\ [expr {($intensity + (3 * $green)) / 4}]\ [expr {($intensity + (3 * $blue)) / 4}]\ ] } else { set ($this,dark) [format {#%04X%04X%04X}\ [expr {(60 * $red) / 100}] [expr {(60 * $green) / 100}]\ [expr {(60 * $blue) / 100}]\ ] } if {$green > ($intensity * 0.95)} { set ($this,light) [format {#%04X%04X%04X}\ [expr {(90 * $red) / 100}] [expr {(90 * $green) / 100}]\ [expr {(90 * $blue) / 100}]\ ] } else { set tmp1 [expr {(14 * $red) / 10}] if {$tmp1 > $intensity} {set tmp1 $intensity} set tmp2 [expr {($intensity + $red) / 2}] set lightRed [expr {$tmp1 > $tmp2? $tmp1: $tmp2}] set tmp1 [expr {(14 * $green) / 10}] if {$tmp1 > $intensity} {set tmp1 $intensity} set tmp2 [expr {($intensity + $green) / 2}] set lightGreen [expr {$tmp1 > $tmp2? $tmp1: $tmp2}] set tmp1 [expr {(14 * $blue) / 10}] if {$tmp1 > $intensity} {set tmp1 $intensity} set tmp2 [expr {($intensity + $blue) / 2}] set lightBlue [expr {$tmp1 > $tmp2? $tmp1: $tmp2}] set ($this,light)\ [format {#%04X%04X%04X} $lightRed $lightGreen $lightBlue] } update $this } proc set-coordinates {this value} { foreach {left top right bottom} $value {} $($this,canvas) coords $($this,topLeft)\ $left $bottom $left $top $right $top $($this,canvas) coords $($this,bottomRight)\ $right $top $right $bottom $left $bottom } proc set-relief {this value} { if {![info exists ($this,dark)]} return ;# colors not yet calculated update $this } proc update {this} { switch $switched::($this,-relief) { flat { $($this,canvas) itemconfigure canvasReliefRectangle($this)\ -fill $switched::($this,-background) } raised { $($this,canvas) itemconfigure $($this,topLeft)\ -fill $($this,light) $($this,canvas) itemconfigure $($this,bottomRight)\ -fill $($this,dark) } sunken { $($this,canvas) itemconfigure $($this,topLeft)\ -fill $($this,dark) $($this,canvas) itemconfigure $($this,bottomRight)\ -fill $($this,light) } default { error "bad relief value \"$value\": must be flat, raised or sunken" } } } }