# needlemeter.tcl
#
# Part of: The TCL'ers Wiki
# Contents: a needlemeter widget
# Date: Fri Jun 13, 2003
#
# Abstract
#
#
#
# Copyright (c) 2003 Marco Maggi
#
# The author hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose,
# provided that existing copyright notices are retained in all copies
# and that this notice is included verbatim in any distributions. No
# written agreement, license, or royalty fee is required for any of the
# authorized uses. Modifications to this software may be copyrighted by
# their authors and need not follow the licensing terms described here,
# provided that the new terms are clearly indicated on the first page of
# each file where they apply.
#
# IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY
# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
# DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAVE BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
# NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# AND THE AUTHOR AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
# MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
# $Id: 9177,v 1.2 2005-07-01 06:00:18 jcw Exp $
#
package require Tcl 8
package require Tk 8
option add *borderWidth 1
option add *Scale.from 0.0
option add *Scale.to 10.0
option add *Scale.resolution 0.1
option add *Scale.orient vertical
option add *Scale.label value
option add *Scale.showValue 1
proc main { argc argv } {
global forever
wm withdraw .
wm title . "A needlemeter widget"
wm geometry . +10+10
needlemeter::constructor .t1 ::value1
scale .s1 -command "set ::value1"
needlemeter::constructor .t2 ::value2
after 100 "periodic ::value2 0.0"
needlemeter::constructor .t3 ::value3
after 100 "sinusoid ::value3 0.0 0.45 0.05"
needlemeter::constructor .t4 ::value4
after 100 "sinusoid ::value4 0.0 0.2 0.05"
button .b -text Quit -command "set ::forever 1"
grid .t1 .s1 .t2 .t3 .t4 .b -padx 2 -pady 2
wm deiconify .
vwait forever
needlemeter::destructor .t1
needlemeter::destructor .t2
needlemeter::destructor .t3
needlemeter::destructor .t4
exit 0
}
proc periodic { varname value } {
upvar $varname name
set name $value
after 50 "periodic $varname [expr {$value+0.01}]"
}
proc sinusoid { varname value ampli delta } {
upvar $varname name
set name [expr {$ampli*sin($value)}]
after 50 "sinusoid $varname [expr {$value+$delta}] $ampli $delta"
}
namespace eval needlemeter {
option add *Needlemeter.indexid {}
option add *Needlemeter.relief flat
option add *Needlemeter.borderWidth 0
option add *Needlemeter.Canvas.background gray
option add *Needlemeter.Canvas.width 15m
option add *Needlemeter.Canvas.height 15m
option add *Needlemeter.Canvas.foreground black
option add *Needlemeter.Canvas.highlightThickness 0
option add *Needlemeter.Canvas.borderWidth 1
option add *Needlemeter.Canvas.relief raised
variable pi 3.14159265359
}
proc needlemeter::constructor { widget varname } {
variable pi
upvar $varname value
frame $widget -class Needlemeter
canvas [set c $widget.canvas]
grid $c -sticky news
option add ${widget}.varname $varname
set width [$c cget -width]
# display
set x1 [expr {$width/50.0*4.0}]
set y1 [expr {$width/50.0*4.0}]
set x2 [expr {$width/50.0*46.0}]
set y2 [expr {$width/50.0*46.0}]
$c create oval $x1 $y1 $x2 $y2 -fill white -width 1 -outline lightgray
set xc [expr {($x2-$x1)/2.0}]
shadowcircle $c $x1 $y1 $x2 $y2 40 0.7m 135.0
set value 0
drawline $widget $value
trace add variable $varname write \
[namespace code "tracer $widget $varname"]
return $widget
}
proc needlemeter::destructor { widget } {
set varname [option get $widget varname {}]
trace remove variable $varname write \
[namespace code "tracer $widget $varname"]
return
}
proc needlemeter::tracer { widget varname args } {
upvar $varname value
drawline $widget $value
return
}
proc needlemeter::drawline { widget value } {
variable pi
set id [option get $widget indexid {}]
set min [option get $widget min {}]
set max [option get $widget max {}]
set c $widget.canvas
set angle [expr {($value+0.5)*2*$pi}]
set width [$c cget -width]
set half [expr {$width/2.0}]
set length [expr {$half*0.6}]
set xl [expr {$half-$length*sin($angle)}]
set yl [expr {$half+$length*cos($angle)}]
set xs [expr {$half+0.3*$length*sin($angle)}]
set ys [expr {$half-0.3*$length*cos($angle)}]
catch {$c delete $id}
set id [$c create line $xs $ys $xl $yl -fill red -width 1m]
option add *[string trimleft $widget .].indexid $id
return
}
proc shadowcircle { canvas x1 y1 x2 y2 ticks width orient } {
set radius [expr {($x2-$x1)/2.0}]
set angle $orient
set delta [expr {180.0/$ticks}]
for {set i 0} {$i <= $ticks} {incr i} {
set a [expr {($angle+$i*$delta)}]
set b [expr {($angle-$i*$delta)}]
set color [expr {40+$i*(200/$ticks)}]
set color [format "#%x%x%x" $color $color $color]
$canvas create arc $x1 $y1 $x2 $y2 -start $a -extent $delta \
-style arc -outline $color -width $width
$canvas create arc $x1 $y1 $x2 $y2 -start $b -extent $delta \
-style arc -outline $color -width $width
}
}
main $argc $argv
### end of file
# Local Variables:
# mode: tcl
# page-delimiter: "^#PAGE"
# End:
uniquename 2013jul28
This code has been here 10 years without a screenshot that shows what this 'needlemeter' looks like. Here is an image.

Marco Maggi posted a couple of fancier meters at
A voltmeter-like widget: type 1 and
A tachometer-like widget: type 1.