1 | #!/usr/bin/env python |
---|
2 | #Boa:Dialog:PvDialog |
---|
3 | |
---|
4 | #************************************************************************* |
---|
5 | # Copyright (c) 2009-2010 The University of Chicago, as Operator of Argonne |
---|
6 | # National Laboratory. |
---|
7 | # Copyright (c) 2009-2010 The Regents of the University of California, as |
---|
8 | # Operator of Los Alamos National Laboratory. |
---|
9 | # This file is distributed subject to a Software License Agreement found |
---|
10 | # in the file LICENSE that is included with this distribution. |
---|
11 | #************************************************************************* |
---|
12 | |
---|
13 | ''' |
---|
14 | Provides Python Class: PvDialog |
---|
15 | Dialog to configure the EPICS PVs for an X,Y pair |
---|
16 | |
---|
17 | @version: |
---|
18 | ########### SVN repository information ################### |
---|
19 | # $Date: 2011-09-09 17:12:01 +0000 (Fri, 09 Sep 2011) $ |
---|
20 | # $Author: jemian $ |
---|
21 | # $Revision: 631 $ |
---|
22 | # $URL: wxmtxy/trunk/src/moxy/pvsetup.py $ |
---|
23 | # $Id: pvsetup.py 631 2011-09-09 17:12:01Z jemian $ |
---|
24 | ########### SVN repository information ################### |
---|
25 | ''' |
---|
26 | |
---|
27 | |
---|
28 | import wx |
---|
29 | import pvConnect |
---|
30 | import pprint |
---|
31 | import wxmtxy_axis |
---|
32 | import inspect |
---|
33 | import os |
---|
34 | |
---|
35 | |
---|
36 | COLOR_PV_OK = wx.Colour(235, 254, 231) # pale green |
---|
37 | COLOR_PV_NOT_OK = wx.Colour(254, 232, 255) # pale pink |
---|
38 | COLOR_PV_AUTOFILL = wx.Colour(200, 200, 200) # pale grey |
---|
39 | |
---|
40 | [wxID_PVDIALOG, wxID_PVDIALOGBUTTON_CANCEL, wxID_PVDIALOGBUTTON_CLEAR_X, |
---|
41 | wxID_PVDIALOGBUTTON_CLEAR_Y, wxID_PVDIALOGBUTTON_OK, |
---|
42 | wxID_PVDIALOGBUTTON_REVERT, wxID_PVDIALOGCB_IS_MOTOR_X, |
---|
43 | wxID_PVDIALOGCB_IS_MOTOR_Y, wxID_PVDIALOGEPICS_LOGO, wxID_PVDIALOGLBL_DESC, |
---|
44 | wxID_PVDIALOGLBL_DONE, wxID_PVDIALOGLBL_EGU, wxID_PVDIALOGLBL_RBV, |
---|
45 | wxID_PVDIALOGLBL_STOP, wxID_PVDIALOGLBL_VAL, wxID_PVDIALOGPV_X_DESC, |
---|
46 | wxID_PVDIALOGPV_X_DMOV, wxID_PVDIALOGPV_X_EGU, wxID_PVDIALOGPV_X_RBV, |
---|
47 | wxID_PVDIALOGPV_X_STOP, wxID_PVDIALOGPV_X_VAL, wxID_PVDIALOGPV_Y_DESC, |
---|
48 | wxID_PVDIALOGPV_Y_DMOV, wxID_PVDIALOGPV_Y_EGU, wxID_PVDIALOGPV_Y_RBV, |
---|
49 | wxID_PVDIALOGPV_Y_STOP, wxID_PVDIALOGPV_Y_VAL, wxID_PVDIALOGTITLE, |
---|
50 | ] = [wx.NewId() for _init_ctrls in range(28)] |
---|
51 | |
---|
52 | |
---|
53 | class PvDialog(wx.Dialog): |
---|
54 | '''Dialog to configure the EPICS PVs for an X,Y pair |
---|
55 | |
---|
56 | This code also checks to see if the PV names entered are valid. |
---|
57 | User is expected to press the [enter] key to submit a PV name |
---|
58 | for validation. Background of text entry box will turn green |
---|
59 | to signify that the chosen PV name is valid (has been found). |
---|
60 | The background will be pink for invalid PV strings. |
---|
61 | The background will be grey for PV standard fields in motor records. |
---|
62 | ''' |
---|
63 | |
---|
64 | def _init_ctrls(self, prnt): |
---|
65 | # generated method, don't edit |
---|
66 | wx.Dialog.__init__(self, id=wxID_PVDIALOG, name='EPICS configuration', parent=prnt, |
---|
67 | pos=wx.Point(191, 166), size=wx.Size(638, 434), |
---|
68 | style=wx.DIALOG_MODAL | wx.DEFAULT_DIALOG_STYLE, |
---|
69 | title='PvDialog') |
---|
70 | self.SetClientSize(wx.Size(630, 400)) |
---|
71 | self.SetToolTipString('Configure EPICS PVs') |
---|
72 | |
---|
73 | self.cb_is_motor_x = wx.CheckBox(id=wxID_PVDIALOGCB_IS_MOTOR_X, |
---|
74 | label='X axis is motor', name='cb_is_motor_x', parent=self, |
---|
75 | pos=wx.Point(72, 80), size=wx.Size(256, 16), style=0) |
---|
76 | self.cb_is_motor_x.SetValue(True) |
---|
77 | self.cb_is_motor_x.SetToolTipString('Autofill the fields for a motor record for the X axis') |
---|
78 | |
---|
79 | self.pv_x_desc = wx.TextCtrl(id=wxID_PVDIALOGPV_X_DESC, |
---|
80 | name='pv_x_desc', parent=self, pos=wx.Point(72, 108), |
---|
81 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
82 | self.pv_x_desc.SetToolTipString('PV for X axis description') |
---|
83 | self.pv_x_desc.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_descTextEnter, |
---|
84 | id=wxID_PVDIALOGPV_X_DESC) |
---|
85 | |
---|
86 | self.pv_x_rbv = wx.TextCtrl(id=wxID_PVDIALOGPV_X_RBV, name='pv_x_rbv', |
---|
87 | parent=self, pos=wx.Point(72, 148), size=wx.Size(256, 21), |
---|
88 | style=wx.TE_PROCESS_ENTER, value='') |
---|
89 | self.pv_x_rbv.SetToolTipString('PV for X axis readback value') |
---|
90 | self.pv_x_rbv.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_rbvTextEnter, |
---|
91 | id=wxID_PVDIALOGPV_X_RBV) |
---|
92 | |
---|
93 | self.pv_x_val = wx.TextCtrl(id=wxID_PVDIALOGPV_X_VAL, name='pv_x_val', |
---|
94 | parent=self, pos=wx.Point(72, 188), size=wx.Size(256, 21), |
---|
95 | style=wx.TE_PROCESS_ENTER, value='') |
---|
96 | self.pv_x_val.SetToolTipString('PV for X axis target (commanded) value') |
---|
97 | self.pv_x_val.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_valTextEnter, |
---|
98 | id=wxID_PVDIALOGPV_X_VAL) |
---|
99 | |
---|
100 | self.pv_x_dmov = wx.TextCtrl(id=wxID_PVDIALOGPV_X_DMOV, |
---|
101 | name='pv_x_dmov', parent=self, pos=wx.Point(72, 228), |
---|
102 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
103 | self.pv_x_dmov.SetToolTipString('PV for X axis NOT MOVING bit (1=not moving)') |
---|
104 | self.pv_x_dmov.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_dmovTextEnter, |
---|
105 | id=wxID_PVDIALOGPV_X_DMOV) |
---|
106 | |
---|
107 | self.pv_x_egu = wx.TextCtrl(id=wxID_PVDIALOGPV_X_EGU, name='pv_x_egu', |
---|
108 | parent=self, pos=wx.Point(72, 268), size=wx.Size(256, 21), |
---|
109 | style=wx.TE_PROCESS_ENTER, value='') |
---|
110 | self.pv_x_egu.SetToolTipString('PV for X axis engineering units)') |
---|
111 | self.pv_x_egu.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_eguTextEnter, |
---|
112 | id=wxID_PVDIALOGPV_X_EGU) |
---|
113 | |
---|
114 | self.pv_x_stop = wx.TextCtrl(id=wxID_PVDIALOGPV_X_STOP, |
---|
115 | name='pv_x_stop', parent=self, pos=wx.Point(72, 308), |
---|
116 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
117 | self.pv_x_stop.SetToolTipString('PV to STOP X axis') |
---|
118 | self.pv_x_stop.Bind(wx.EVT_TEXT_ENTER, self.OnPv_x_stopTextEnter, |
---|
119 | id=wxID_PVDIALOGPV_X_STOP) |
---|
120 | |
---|
121 | self.cb_is_motor_y = wx.CheckBox(id=wxID_PVDIALOGCB_IS_MOTOR_Y, |
---|
122 | label='Y axis is motor', name='cb_is_motor_y', parent=self, |
---|
123 | pos=wx.Point(352, 88), size=wx.Size(256, 16), style=0) |
---|
124 | self.cb_is_motor_y.SetValue(True) |
---|
125 | self.cb_is_motor_y.SetToolTipString('Autofill the fields for a motor record for the Y axis') |
---|
126 | |
---|
127 | self.pv_y_desc = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_DESC, |
---|
128 | name='pv_y_desc', parent=self, pos=wx.Point(352, 108), |
---|
129 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
130 | self.pv_y_desc.SetToolTipString('PV for Y axis description') |
---|
131 | self.pv_y_desc.SetBackgroundColour(wx.Colour(254, 232, 255)) |
---|
132 | self.pv_y_desc.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_descTextEnter, |
---|
133 | id=wxID_PVDIALOGPV_Y_DESC) |
---|
134 | |
---|
135 | self.pv_y_rbv = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_RBV, name='pv_y_rbv', |
---|
136 | parent=self, pos=wx.Point(352, 148), size=wx.Size(256, 21), |
---|
137 | style=wx.TE_PROCESS_ENTER, value='') |
---|
138 | self.pv_y_rbv.SetToolTipString('PV for Y axis readback value') |
---|
139 | self.pv_y_rbv.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_rbvTextEnter, |
---|
140 | id=wxID_PVDIALOGPV_Y_RBV) |
---|
141 | |
---|
142 | self.pv_y_val = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_VAL, name='pv_y_val', |
---|
143 | parent=self, pos=wx.Point(352, 188), size=wx.Size(256, 21), |
---|
144 | style=wx.TE_PROCESS_ENTER, value='') |
---|
145 | self.pv_y_val.SetToolTipString('PV for Y axis target (commanded) value') |
---|
146 | self.pv_y_val.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_valTextEnter, |
---|
147 | id=wxID_PVDIALOGPV_Y_VAL) |
---|
148 | |
---|
149 | self.pv_y_dmov = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_DMOV, |
---|
150 | name='pv_y_dmov', parent=self, pos=wx.Point(352, 228), |
---|
151 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
152 | self.pv_y_dmov.SetToolTipString('PV for Y axis NOT MOVING bit (1=not moving)') |
---|
153 | self.pv_y_dmov.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_dmovTextEnter, |
---|
154 | id=wxID_PVDIALOGPV_Y_DMOV) |
---|
155 | |
---|
156 | self.pv_y_egu = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_EGU, name='pv_y_egu', |
---|
157 | parent=self, pos=wx.Point(352, 268), size=wx.Size(256, 21), |
---|
158 | style=wx.TE_PROCESS_ENTER, value='') |
---|
159 | self.pv_y_egu.SetToolTipString('PV for Y axis engineering units') |
---|
160 | self.pv_y_egu.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_eguTextEnter, |
---|
161 | id=wxID_PVDIALOGPV_Y_EGU) |
---|
162 | |
---|
163 | self.pv_y_stop = wx.TextCtrl(id=wxID_PVDIALOGPV_Y_STOP, |
---|
164 | name='pv_y_stop', parent=self, pos=wx.Point(352, 308), |
---|
165 | size=wx.Size(256, 21), style=wx.TE_PROCESS_ENTER, value='') |
---|
166 | self.pv_y_stop.SetToolTipString('PV to STOP Y axis') |
---|
167 | self.pv_y_stop.Bind(wx.EVT_TEXT_ENTER, self.OnPv_y_stopTextEnter, |
---|
168 | id=wxID_PVDIALOGPV_Y_STOP) |
---|
169 | |
---|
170 | self.title = wx.StaticText(id=wxID_PVDIALOGTITLE, |
---|
171 | label='Configure EPICS PVs', name='title', parent=self, |
---|
172 | pos=wx.Point(136, 16), size=wx.Size(233, 27), |
---|
173 | style=wx.ALIGN_CENTRE) |
---|
174 | self.title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL, False, |
---|
175 | 'Arial')) |
---|
176 | |
---|
177 | self.lbl_done = wx.StaticText(id=wxID_PVDIALOGLBL_DONE, label='DMOV', |
---|
178 | name='lbl_done', parent=self, pos=wx.Point(24, 232), |
---|
179 | size=wx.Size(40, 13), style=0) |
---|
180 | |
---|
181 | self.lbl_val = wx.StaticText(id=wxID_PVDIALOGLBL_VAL, label='VAL', |
---|
182 | name='lbl_val', parent=self, pos=wx.Point(24, 192), |
---|
183 | size=wx.Size(40, 13), style=0) |
---|
184 | |
---|
185 | self.lbl_rbv = wx.StaticText(id=wxID_PVDIALOGLBL_RBV, label='RBV', |
---|
186 | name='lbl_rbv', parent=self, pos=wx.Point(24, 152), |
---|
187 | size=wx.Size(40, 13), style=0) |
---|
188 | |
---|
189 | self.lbl_desc = wx.StaticText(id=wxID_PVDIALOGLBL_DESC, label='DESC', |
---|
190 | name='lbl_desc', parent=self, pos=wx.Point(24, 112), |
---|
191 | size=wx.Size(40, 13), style=0) |
---|
192 | |
---|
193 | self.lbl_egu = wx.StaticText(id=wxID_PVDIALOGLBL_EGU, label='EGU', |
---|
194 | name='lbl_egu', parent=self, pos=wx.Point(24, 272), |
---|
195 | size=wx.Size(40, 13), style=0) |
---|
196 | |
---|
197 | self.lbl_stop = wx.StaticText(id=wxID_PVDIALOGLBL_STOP, label='STOP', |
---|
198 | name='lbl_stop', parent=self, pos=wx.Point(24, 312), |
---|
199 | size=wx.Size(40, 13), style=0) |
---|
200 | |
---|
201 | self.button_ok = wx.Button(id=wx.ID_OK, label='Ok', name='button_ok', |
---|
202 | parent=self, pos=wx.Point(40, 352), size=wx.Size(100, 30), |
---|
203 | style=0) |
---|
204 | self.button_ok.SetToolTipString('accept all changes') |
---|
205 | self.button_ok.Bind(wx.EVT_BUTTON, self.OnButton_okButton, |
---|
206 | id=wxID_PVDIALOGBUTTON_OK) |
---|
207 | |
---|
208 | self.button_cancel = wx.Button(id=wx.ID_CANCEL, label='Cancel', |
---|
209 | name='button_cancel', parent=self, pos=wx.Point(150, 352), |
---|
210 | size=wx.Size(100, 30), style=0) |
---|
211 | self.button_cancel.SetToolTipString('cancel all changes') |
---|
212 | self.button_cancel.Bind(wx.EVT_BUTTON, self.OnButton_cancelButton, |
---|
213 | id=wxID_PVDIALOGBUTTON_CANCEL) |
---|
214 | |
---|
215 | self.button_clear_x = wx.Button(id=wxID_PVDIALOGBUTTON_CLEAR_X, |
---|
216 | label='Clear X', name='button_clear_x', parent=self, |
---|
217 | pos=wx.Point(260, 352), size=wx.Size(100, 30), style=0) |
---|
218 | self.button_clear_x.SetToolTipString('clear all fields for X axis') |
---|
219 | self.button_clear_x.Bind(wx.EVT_BUTTON, self.OnButton_clear_x_Button, |
---|
220 | id=wxID_PVDIALOGBUTTON_CLEAR_X) |
---|
221 | |
---|
222 | self.button_clear_y = wx.Button(id=wxID_PVDIALOGBUTTON_CLEAR_Y, |
---|
223 | label='Clear Y', name='button_clear_y', parent=self, |
---|
224 | pos=wx.Point(370, 352), size=wx.Size(100, 30), style=0) |
---|
225 | self.button_clear_y.SetToolTipString('clear all fields for X axis') |
---|
226 | self.button_clear_y.Bind(wx.EVT_BUTTON, self.OnButton_clear_y_Button, |
---|
227 | id=wxID_PVDIALOGBUTTON_CLEAR_Y) |
---|
228 | |
---|
229 | self.button_revert = wx.Button(id=wxID_PVDIALOGBUTTON_REVERT, |
---|
230 | label='Revert', name='button_revert', parent=self, |
---|
231 | pos=wx.Point(480, 352), size=wx.Size(100, 30), style=0) |
---|
232 | self.button_revert.SetToolTipString('Change all fields back to original values as dialog was started') |
---|
233 | self.button_revert.Bind(wx.EVT_BUTTON, self.OnButton_revertButton, |
---|
234 | id=wxID_PVDIALOGBUTTON_REVERT) |
---|
235 | |
---|
236 | self.epics_logo = wx.StaticBitmap( |
---|
237 | id=wxID_PVDIALOGEPICS_LOGO, |
---|
238 | name='epics_logo', parent=self, pos=wx.Point(16, 8), |
---|
239 | size=wx.Size(50, 51), style=0) |
---|
240 | self.epics_logo.SetToolTipString('EPICS logo') |
---|
241 | self.epics_logo.SetLabel('EPICS logo') |
---|
242 | self.epics_logo.SetHelpText('EPICS logo') |
---|
243 | |
---|
244 | def __init_names__(self): |
---|
245 | '''conversion table of widget names |
---|
246 | |
---|
247 | Create a dictionary of names for the widgets by axis. |
---|
248 | This should simplify addressing these widgets internally.''' |
---|
249 | self.widget = {'x': {}, 'y': {}} |
---|
250 | self.widget['x']['isMotorRec'] = self.cb_is_motor_x |
---|
251 | self.widget['x']['DESC'] = self.pv_x_desc |
---|
252 | self.widget['x']['RBV'] = self.pv_x_rbv |
---|
253 | self.widget['x']['VAL'] = self.pv_x_val |
---|
254 | self.widget['x']['DMOV'] = self.pv_x_dmov |
---|
255 | self.widget['x']['STOP'] = self.pv_x_stop |
---|
256 | self.widget['x']['EGU'] = self.pv_x_egu |
---|
257 | self.widget['y']['isMotorRec'] = self.cb_is_motor_y |
---|
258 | self.widget['y']['DESC'] = self.pv_y_desc |
---|
259 | self.widget['y']['RBV'] = self.pv_y_rbv |
---|
260 | self.widget['y']['VAL'] = self.pv_y_val |
---|
261 | self.widget['y']['DMOV'] = self.pv_y_dmov |
---|
262 | self.widget['y']['STOP'] = self.pv_y_stop |
---|
263 | self.widget['y']['EGU'] = self.pv_y_egu |
---|
264 | |
---|
265 | def __init__(self, parent, original_config): |
---|
266 | '''establish the dialog box |
---|
267 | @param parent: widget that owns this class |
---|
268 | @param original_config: Python dictionary with axes configurations''' |
---|
269 | # first, find the directory where this code is installed |
---|
270 | # so the bitmaps can be found |
---|
271 | # Note that this breaks edit ability of BoaConstructor |
---|
272 | root_dir = os.path.split(inspect.getsourcefile(PvDialog))[0] |
---|
273 | self.bmp = {} |
---|
274 | for item in ['epicslogo101']: |
---|
275 | file = os.path.join(root_dir, 'graphics', item + '.bmp') |
---|
276 | self.bmp[item] = wx.Bitmap(file, wx.BITMAP_TYPE_BMP) |
---|
277 | self._init_ctrls(parent) # create the controls |
---|
278 | self.epics_logo.SetBitmap(self.bmp['epicslogo101']) |
---|
279 | self.__init_names__() # widget conversion table |
---|
280 | self.SetConfiguration(original_config) # initial values |
---|
281 | self.original_config = self.GetConfiguration() # for "Revert" |
---|
282 | |
---|
283 | # ################################ |
---|
284 | # ## added methods ### |
---|
285 | # ################################ |
---|
286 | |
---|
287 | def _applyConfiguration_(self, xref, config): |
---|
288 | '''load/configure the widgets with the configuration of one axis |
---|
289 | |
---|
290 | @param xref: self.widget[axis] where axis is either "x" or "y" |
---|
291 | @param config: dictionary of values for this axis |
---|
292 | ''' |
---|
293 | field = 'isMotorRec' |
---|
294 | isMotorRec = False |
---|
295 | if config.has_key(field): |
---|
296 | xref[field].SetValue(config[field]) |
---|
297 | isMotorRec = config[field] |
---|
298 | for field in wxmtxy_axis.field_list: |
---|
299 | if config.has_key(field): |
---|
300 | #pprint.pprint(config) |
---|
301 | #print field, repr(config[field]), str(config[field]) |
---|
302 | xref[field].SetValue(config[field]) |
---|
303 | state = False |
---|
304 | pv = xref[field].GetValue() |
---|
305 | if len(pv) > 0: |
---|
306 | state = pvConnect.testConnect(pv) |
---|
307 | #print pv, state |
---|
308 | self._SetPvColor(xref[field], state, isMotorRec) |
---|
309 | |
---|
310 | def _SetPvColor(self, widget, state, ismotor): |
---|
311 | '''Change the background color on the PV string widgets. |
---|
312 | Also base color choice on whether the PV is part |
---|
313 | of a motor record or not. |
---|
314 | @param widget: used as widget.SetBackgroundColour(map[state]) |
---|
315 | @param state: [Boolean] Moving = True |
---|
316 | @param ismotor: [Boolean] Is it an EPICS "motor" record? |
---|
317 | ''' |
---|
318 | map = { |
---|
319 | True: COLOR_PV_OK, |
---|
320 | False: COLOR_PV_NOT_OK |
---|
321 | } |
---|
322 | if ismotor: # remap if maybe part of motor record |
---|
323 | map["False"] = COLOR_PV_AUTOFILL |
---|
324 | widget.SetBackgroundColour(map[state]) |
---|
325 | |
---|
326 | def SetColor(self, axis, field): |
---|
327 | '''change the background color on the given widgets |
---|
328 | @param axis: [string] "x" or "y" |
---|
329 | @param field: [string] member of wxmtxy_axis.field_list''' |
---|
330 | pv = self.widget[axis][field].GetValue() |
---|
331 | isMotorRec = self.widget[axis]['isMotorRec'].GetValue() |
---|
332 | state = False |
---|
333 | if len(pv) > 0: |
---|
334 | state = pvConnect.testConnect(pv) |
---|
335 | self._SetPvColor(self.widget[axis][field], state, isMotorRec) |
---|
336 | |
---|
337 | def _pv_base_name(self, pv): |
---|
338 | '''given an EPICS PV name, return the base name |
---|
339 | @param pv: [string] EPICS Process Variable name |
---|
340 | @return: base part of PV name |
---|
341 | |
---|
342 | @note: _pv_base_name("the:pv:name.VAL") = "the:pv:name" |
---|
343 | @note: _pv_base_name("another:name") = "another:name" |
---|
344 | ''' |
---|
345 | return pv.split('.')[0] |
---|
346 | |
---|
347 | def GetConfiguration(self): |
---|
348 | '''@return Python dictionary containing the PV info for X & Y axes''' |
---|
349 | config = {'x': {}, 'y': {}} |
---|
350 | for axis in ['x', 'y']: |
---|
351 | field = 'isMotorRec' |
---|
352 | config[axis][field]=self.widget[axis][field].GetValue() |
---|
353 | for field in wxmtxy_axis.field_list: |
---|
354 | config[axis][field]=self.widget[axis][field].GetValue() |
---|
355 | return config |
---|
356 | |
---|
357 | def SetConfiguration(self, config): |
---|
358 | '''Set the configuration of the widgets. |
---|
359 | @param config: Python dictionary containing the PV info for X & Y axes''' |
---|
360 | for axis in ['x', 'y']: |
---|
361 | if config.has_key(axis): |
---|
362 | self._applyConfiguration_(self.widget[axis], config[axis]) |
---|
363 | |
---|
364 | def _SetIsMotorCheckbox_(self, axis): |
---|
365 | '''Set/clear the "isMotorRec" checkbox if the VAL PV is/not from a motor record. |
---|
366 | @param axis: [string] "x" or "y" |
---|
367 | ''' |
---|
368 | base = self._pv_base_name(self.widget[axis]['VAL'].GetValue()) |
---|
369 | isMotorRec = self._isMotorRec_(base) |
---|
370 | self.widget[axis]['isMotorRec'].SetValue(isMotorRec) |
---|
371 | |
---|
372 | def _isMotorRec_(self, pv): |
---|
373 | '''test if the given PV is a motor record |
---|
374 | @param pv: [string] EPICS Process Variable name''' |
---|
375 | return pvConnect.GetRTYP(pv) == 'motor' |
---|
376 | |
---|
377 | def _clear_axis(self, axis): |
---|
378 | '''clear all the fields on the named axis |
---|
379 | @param axis: [string] "x" or "y"''' |
---|
380 | config = {'isMotorRec': False} |
---|
381 | for field in wxmtxy_axis.field_list: |
---|
382 | config[field] = '' |
---|
383 | self._applyConfiguration_(self.widget[axis], config) |
---|
384 | |
---|
385 | # ################################ |
---|
386 | # ## event handling routines ### |
---|
387 | # ################################ |
---|
388 | |
---|
389 | def OnPv_x_dmovTextEnter(self, event): |
---|
390 | '''set background color |
---|
391 | @param event: wxPython event object''' |
---|
392 | self.SetColor('x', 'DMOV') |
---|
393 | |
---|
394 | def OnPv_y_dmovTextEnter(self, event): |
---|
395 | '''set background color |
---|
396 | @param event: wxPython event object''' |
---|
397 | self.SetColor('y', 'DMOV') |
---|
398 | |
---|
399 | def OnPv_x_valTextEnter(self, event): |
---|
400 | '''set background color and 'isMotorRec' checkbox for X axis |
---|
401 | @param event: wxPython event object''' |
---|
402 | self.SetColor('x', 'VAL') |
---|
403 | self._SetIsMotorCheckbox_('x') |
---|
404 | |
---|
405 | def OnPv_y_valTextEnter(self, event): |
---|
406 | '''set background color and 'isMotorRec' checkbox for Y axis |
---|
407 | @param event: wxPython event object''' |
---|
408 | self.SetColor('y', 'VAL') |
---|
409 | self._SetIsMotorCheckbox_('y') |
---|
410 | |
---|
411 | def OnPv_x_rbvTextEnter(self, event): |
---|
412 | '''set background color |
---|
413 | @param event: wxPython event object''' |
---|
414 | self.SetColor('x', 'RBV') |
---|
415 | |
---|
416 | def OnPv_y_rbvTextEnter(self, event): |
---|
417 | '''set background color |
---|
418 | @param event: wxPython event object''' |
---|
419 | self.SetColor('y', 'RBV') |
---|
420 | |
---|
421 | def OnPv_x_descTextEnter(self, event): |
---|
422 | '''set background color |
---|
423 | @param event: wxPython event object''' |
---|
424 | self.SetColor('x', 'DESC') |
---|
425 | |
---|
426 | def OnPv_y_descTextEnter(self, event): |
---|
427 | '''set background color |
---|
428 | @param event: wxPython event object''' |
---|
429 | self.SetColor('y', 'DESC') |
---|
430 | |
---|
431 | def OnPv_x_eguTextEnter(self, event): |
---|
432 | '''set background color |
---|
433 | @param event: wxPython event object''' |
---|
434 | self.SetColor('x', 'EGU') |
---|
435 | |
---|
436 | def OnPv_y_eguTextEnter(self, event): |
---|
437 | '''set background color |
---|
438 | @param event: wxPython event object''' |
---|
439 | self.SetColor('y', 'EGU') |
---|
440 | |
---|
441 | def OnPv_x_stopTextEnter(self, event): |
---|
442 | '''set background color |
---|
443 | @param event: wxPython event object''' |
---|
444 | self.SetColor('x', 'STOP') |
---|
445 | |
---|
446 | def OnPv_y_stopTextEnter(self, event): |
---|
447 | '''set background color |
---|
448 | @param event: wxPython event object''' |
---|
449 | self.SetColor('y', 'STOP') |
---|
450 | |
---|
451 | def OnButton_okButton(self, event): |
---|
452 | '''Handler for the cancel button. |
---|
453 | The default behavior will handle all that is needed here. |
---|
454 | |
---|
455 | @param event: wxPython event object |
---|
456 | ''' |
---|
457 | event.Skip() |
---|
458 | |
---|
459 | def OnButton_cancelButton(self, event): |
---|
460 | '''Handler for the cancel button. |
---|
461 | The default behavior will handle all that is needed here. |
---|
462 | |
---|
463 | There is no chance to restore the original |
---|
464 | configuration before the dialog returns. The calling |
---|
465 | routine must determine if the result was wx.ID_OK |
---|
466 | before calling dlg.GetConfiguration(). |
---|
467 | |
---|
468 | @param event: wxPython event object |
---|
469 | ''' |
---|
470 | event.Skip() |
---|
471 | |
---|
472 | def OnButton_clear_x_Button(self, event): |
---|
473 | '''clear all the fields on the X axis |
---|
474 | @param event: wxPython event object''' |
---|
475 | self._clear_axis('x') |
---|
476 | |
---|
477 | def OnButton_clear_y_Button(self, event): |
---|
478 | '''clear all the fields on the Y axis |
---|
479 | @param event: wxPython event object''' |
---|
480 | self._clear_axis('y') |
---|
481 | |
---|
482 | def OnButton_revertButton(self, event): |
---|
483 | '''reset all the fields on both axes to original values |
---|
484 | @param event: wxPython event object''' |
---|
485 | self.SetConfiguration(self.original_config) |
---|
486 | |
---|
487 | |
---|
488 | if __name__ == '__main__': |
---|
489 | '''example of how to set up the caller for this dialog''' |
---|
490 | config = { |
---|
491 | 'x': { |
---|
492 | # USAXS a1y: 32idbLAX:m58:c1:m1 |
---|
493 | 'isMotorRec': True, |
---|
494 | 'VAL': '32idbLAX:m58:c1:m1.VAL' |
---|
495 | }, |
---|
496 | 'y': { |
---|
497 | # USAXS a2y: 32idbLAX:m58:c1:m2 |
---|
498 | 'isMotorRec': False, |
---|
499 | 'VAL': '32idbLAX:m58:c1:m2.VAL', |
---|
500 | 'RBV': '32idbLAX:m58:c1:m2.RBV', |
---|
501 | 'EGU': '32idbLAX:m58:c1:m2.EGU', |
---|
502 | 'DESC': '32idbLAX:m58:c1:m2.DESC', |
---|
503 | 'DMOV': '32idbLAX:m58:c1:m2.DMOV', |
---|
504 | 'STOP': '32idbLAX:m58:c1:m2.STOP' |
---|
505 | } |
---|
506 | } |
---|
507 | app = wx.PySimpleApp() |
---|
508 | dlg = PvDialog(None, config) |
---|
509 | try: |
---|
510 | result = dlg.ShowModal() |
---|
511 | finally: |
---|
512 | print "OK button pressed:", result == wx.ID_OK |
---|
513 | if result == wx.ID_OK: |
---|
514 | # get the new configuration |
---|
515 | config = dlg.GetConfiguration() |
---|
516 | pprint.pprint(config) |
---|
517 | dlg.Destroy() |
---|
518 | app.MainLoop() |
---|
519 | pvConnect.on_exit() |
---|