On a image create photo, a triangle of various dimensions may be painted on demand. The aim is to replace the BWidget ArrowButton by a ttk::button and a dynamically generated image.
The triangle is painted with the given foreground color on transparent background.
image create photo i -width 30 -height 30 arrowimage i up pack [ttk::button .l -image i -style Toolbutton]
arrowimage
photoCmd | The command name of an image, as given to the image create photo command |
dir | Direction of the arrow. One of top,right, bottom or left |
ipadx | Empty pixels around the image on the left and right of the image |
ipady | Empty pixels around the image on the top and bottom of the image |
clean | Same as BWidget Arrowbutton clean parameter |
foreground | The foreground color of the arrow |
proc arrowimage { photoCmd dir {ipadx 0} {ipady 0} {clean 0} {foreground black} } { set width [$photoCmd cget -width] set height [$photoCmd cget -height] # w and h are max width and max height of arrow set w [expr {$width - 2*$ipadx}] set h [expr {$height - 2*$ipady}] if { $w < 2 } {set w 2} if { $h < 2 } {set h 2} if { $clean > 0 } { # arrange for base to be odd if { [string equal $dir "top"] || [string equal $dir "bottom"] } { if { !($w % 2) } { incr w -1 } if { $clean == 2 } { # arrange for h = (w+1)/2 set h2 [expr {($w+1)/2}] if { $h2 > $h } { set w [expr {2*$h-1}] } else { set h $h2 } } } else { if { !($h % 2) } { incr h -1 } if { $clean == 2 } { # arrange for w = (h+1)/2 set w2 [expr {($h+1)/2}] if { $w2 > $w } { set h [expr {2*$w-1}] } else { set w $w2 } } } } set x0 [expr {($width-$w)/2}] set y0 [expr {($height-$h)/2}] set x1 [expr {$x0+$w-1}] set y1 [expr {$y0+$h-1}] # > Make the frame transparent and the inside with a square for {set y 0} {$y < $y0} {incr y} { for {set x 0} {$x < $height} {incr x} { $photoCmd transparency set $x $y 1 } } for {set y [expr {$y1+1}]} {$y < $height} {incr y} { for {set x 0} {$x < $height} {incr x} { $photoCmd transparency set $x $y 1 } } for {set y $y0} {$y <= $y1} {incr y} { for {set x 0} {$x < $x0} {incr x} { $photoCmd transparency set $x $y 1 } } for {set y $y0} {$y <= $y1} {incr y} { for {set x [expr {$x1+1}]} {$x < $width} {incr x} { $photoCmd transparency set $x $y 1 } } $photoCmd put $foreground -to $x0 $y0 [expr {$x1+1}] [expr {$y1+1}] # > Paint triangles as transparency switch $dir { top - bottom { set h0 $x0 set h1 $x1 set v0 $y0 set v1 $y1 # > On even size move right limit one to right set e1 [expr {($w % 2 == 0)?1:0}] set fHorX 1 } default { set h0 $y0 set h1 $y1 set v0 $x0 set v1 $x1 # > On even size move right limit one to right set e1 [expr {($h % 2 == 0)?1:0}] set fHorX 0 } } switch $dir { top - left { set corVert $v0 set DCorVert 1 } default { set corVert $v1 set DCorVert -1 } } set m [expr {($h0+$h1)/2}] set DHor [expr {$h1 - $m}] set DVert [expr {$v1 - $v0}] set d 0 set r 0 for {set vertLoop 0} {$vertLoop < $DVert} {incr vertLoop} { set limitHor [expr {$m - $d}] for {set horLoop 0} {$horLoop < $limitHor} {incr horLoop} { $photoCmd transparency set\ [expr {$fHorX?$horLoop:$corVert}]\ [expr {$fHorX?$corVert:$horLoop}] 1 } set limitHor [expr {$m + $d + 1 + $e1}] for {set horLoop $limitHor} {$horLoop <= $h1} {incr horLoop} { $photoCmd transparency set\ [expr {$fHorX?$horLoop:$corVert}]\ [expr {$fHorX?$corVert:$horLoop}] 1 } incr corVert $DCorVert incr r $DHor incr d [expr { $r / $DVert } ] set r [expr { $r % $DVert}] } }