-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathepicsEnumeratedControl.tcl
147 lines (121 loc) · 4.08 KB
/
epicsEnumeratedControl.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#
# This software is Copyright by the Board of Trustees of Michigan
# State University (c) Copyright 2005.
#
# You may use this software under the terms of the GNU public license
# (GPL) ir the Tcl BSD derived license The terms of these licenses
# are described at:
#
# GPL: http://www.gnu.org/licenses/gpl.txt
# Tcl: http://www.tcl.tk/softare/tcltk/license.html
# Start with the second paragraph under the Tcl/Tk License terms
# as ownership is solely by Board of Trustees at Michigan State University.
#
# Author:
# Ron Fox
# NSCL
# Michigan State University
# East Lansing, MI 48824-1321
# This software provides a megawidget for controlling EPICS
# enumerated devices. An enumerated devie in EPICS currently
# consists only of things that have distinct values.
# Unfortuntately, epics enumerated channels are underpowered with
# respect to self description. What I'd really like to be able to do
# is ask them questions like:
# 1. How many distinct states do you have.
# 2. What is the list of names that correspond to those states.
#
# Since I can't do this now, I must get this information at widget
# construction time from the application.
# These will be used to configure the underlying radioMatrix.
#
# OPTIONS:
# -orient - passed to radioMatrix
# -columns - passed to radioMatrix
# -rows - passed to radioMatrix.
# -values - passed to radioMatrix.
# -channel - Epics channel to connect to this control.
# The label will reflect the channel value and the
# radio buttons will modify the SETV field for the channel
# in the database.
# METHODS:
# Get - Gets the current requested value.
# Set - Sets a new requested value.
#
# NOTES:
# 1. The Gui is implemented in terms of a radioMatrix
# 2. The widget creates variables in the ::controlwidget:: namespace
# this allows multiple widgets that track the same item to co-exist
# and do the right thing.
# 3. rows/columns/values constraints hold as for the radioMatrix widget.
#
package provide epicsEnumeratedControl 1.0
package require Tk
package require epics
package require radioMatrix
package require bindDown
namespace eval controlwidget {
namespace export epicsEnumeratedControl
}
snit::widget ::controlwidget::epicsEnumeratedControl {
option -channel
option -orient
option -columns
option -rows
option -values
constructor args {
$self configurelist $args
# Set up access to the epics channel.
set channel $options(-channel)
if {$channel eq "" } {
error "epicsEnumeratedControl needs a -channel"
}
epicschannel $channel
$channel link ::controlwidget::$channel
# build up the command to create the radioMatrix:
set rmOptions "-variable $channel"; # Track the channel in the label.
append rmOptions { -command [mymethod onChange]}
foreach opt [list -orient -columns -rows -values] {
if {$options($opt) ne ""} {
append rmOptions " $opt [list $options($opt)]"
}
}
# Create and set the widget>
eval controlwidget::radioMatrix $win.rm $rmOptions \
-variable ::controlwidget::$channel
pack $win.rm -fill both -expand 1
# If possible, attempt to load the radios from the
# SETV .. can't do for modicons..
if {[string range $channel 0 1] ne "P#"} {
epicschannel $channel.SETV
after 100 [mymethod updateRadio]
}
bindDown $win $win
}
# Processes radio button hits.. just turns these around
# into settings.
#
method onChange {} {
set newValue [$win.rm Get]
if {$newValue ne ""} {
set channel $options(-channel)
$channel set $newValue
}
}
# Called, hopefully when the channel is connected to set the
# initial radio button (if we can).
#
method updateRadio {} {
set channel $options(-channel)
# If not connected reschedule every 100ms
if {[catch {$channel.SETV get} value] || ($value eq "")} {
after 100 [mymethod updateRadio]
return
}
$self Set $value
}
# Delegate the set method to the radio matrix.
method Set value {
$win.rm Set $value
}
}