1 | #!/usr/bin/env python |
---|
2 | #Boa:FramePanel:XYpair |
---|
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 | Define the GUI elements and interface for one X,Y pair |
---|
15 | |
---|
16 | @version: |
---|
17 | ########### SVN repository information ################### |
---|
18 | # $Date: 2011-09-09 17:12:01 +0000 (Fri, 09 Sep 2011) $ |
---|
19 | # $Author: jemian $ |
---|
20 | # $Revision: 631 $ |
---|
21 | # $URL: wxmtxy/trunk/src/moxy/pair.py $ |
---|
22 | # $Id: pair.py 631 2011-09-09 17:12:01Z jemian $ |
---|
23 | ########### SVN repository information ################### |
---|
24 | ''' |
---|
25 | |
---|
26 | import wx |
---|
27 | import wx.lib.stattext |
---|
28 | import wxmtxy_tab |
---|
29 | import wxmtxy_row |
---|
30 | import wxmtxy_axis |
---|
31 | import wx.lib.scrolledpanel |
---|
32 | #import pvConnect |
---|
33 | import copy |
---|
34 | import pprint |
---|
35 | |
---|
36 | |
---|
37 | [wxID_XYPAIR, wxID_XYPAIRLBLMOTOR, wxID_XYPAIRLBLREADBACK, |
---|
38 | wxID_XYPAIRLBLTARGET, wxID_XYPAIRLBL_X_TITLE, wxID_XYPAIRLBL_Y_TITLE, |
---|
39 | wxID_XYPAIRSTOP, wxID_XYPAIRTABLE, wxID_XYPAIRTITLE, wxID_XYPAIRX_RBV, |
---|
40 | wxID_XYPAIRX_VAL, wxID_XYPAIRY_RBV, wxID_XYPAIRY_VAL, |
---|
41 | ] = [wx.NewId() for _init_ctrls in range(13)] |
---|
42 | |
---|
43 | |
---|
44 | class XYpair(wx.Panel): |
---|
45 | '''Table of settings for a specified X,Y pair of EPICS motors''' |
---|
46 | |
---|
47 | # see: http://wiki.wxpython.org/BoaFAQ |
---|
48 | _custom_classes = { |
---|
49 | 'wx.lib.scrolledpanel.ScrolledPanel': ['Tab'], |
---|
50 | 'wx.Dialog': ['PvDialog'] |
---|
51 | } |
---|
52 | |
---|
53 | COLOR_MOVING = wx.Colour(179, 250, 142) # pale green |
---|
54 | COLOR_NOT_MOVING = wx.Colour(200, 191, 140) # default below |
---|
55 | COLOR_NOT_MOVING = wx.Colour(237, 233, 227) # Boa shows this one, which? |
---|
56 | |
---|
57 | def _init_coll_fgsEpics_Items(self, parent): |
---|
58 | # generated method, don't edit |
---|
59 | |
---|
60 | parent.AddWindow(self.lblMotor, 0, border=2, |
---|
61 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.GROW) |
---|
62 | parent.AddWindow(self.lbl_x_title, 1, border=2, |
---|
63 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.GROW) |
---|
64 | parent.AddWindow(self.lbl_y_title, 1, border=2, |
---|
65 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.GROW) |
---|
66 | parent.AddWindow(self.lblReadback, 0, border=2, |
---|
67 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.GROW) |
---|
68 | parent.AddWindow(self.x_rbv, 1, border=2, flag=wx.ALL | wx.GROW) |
---|
69 | parent.AddWindow(self.y_rbv, 1, border=2, flag=wx.ALL | wx.GROW) |
---|
70 | parent.AddWindow(self.lblTarget, 0, border=2, |
---|
71 | flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.GROW) |
---|
72 | parent.AddWindow(self.x_val, 1, border=2, flag=wx.ALL | wx.GROW) |
---|
73 | parent.AddWindow(self.y_val, 1, border=2, flag=wx.ALL | wx.GROW) |
---|
74 | |
---|
75 | def _init_coll_sizer_Items(self, parent): |
---|
76 | # generated method, don't edit |
---|
77 | |
---|
78 | parent.AddWindow(self.title, 0, border=0, flag=wx.GROW) |
---|
79 | parent.AddSizer(self.fgsEpics, 0, border=4, flag=wx.ALL | wx.GROW) |
---|
80 | parent.AddWindow(self.stop, 0, border=0, flag=wx.ALIGN_CENTER) |
---|
81 | parent.AddWindow(self.table, 1, border=0, flag=wx.GROW) |
---|
82 | |
---|
83 | def _init_coll_fgsEpics_Growables(self, parent): |
---|
84 | # generated method, don't edit |
---|
85 | |
---|
86 | parent.AddGrowableCol(1) |
---|
87 | parent.AddGrowableCol(2) |
---|
88 | |
---|
89 | def _init_sizers(self): |
---|
90 | # generated method, don't edit |
---|
91 | self.sizer = wx.BoxSizer(orient=wx.VERTICAL) |
---|
92 | |
---|
93 | self.fgsEpics = wx.FlexGridSizer(cols=3, hgap=4, rows=3, vgap=4) |
---|
94 | |
---|
95 | self._init_coll_sizer_Items(self.sizer) |
---|
96 | self._init_coll_fgsEpics_Items(self.fgsEpics) |
---|
97 | self._init_coll_fgsEpics_Growables(self.fgsEpics) |
---|
98 | |
---|
99 | self.SetSizer(self.sizer) |
---|
100 | |
---|
101 | def _init_ctrls(self, prnt): |
---|
102 | # generated method, don't edit |
---|
103 | wx.Panel.__init__(self, id=wxID_XYPAIR, name='XYpair', parent=prnt, |
---|
104 | pos=wx.Point(532, 345), size=wx.Size(408, 274), |
---|
105 | style=wx.TRANSPARENT_WINDOW | wx.TAB_TRAVERSAL) |
---|
106 | self.SetClientSize(wx.Size(400, 240)) |
---|
107 | self.SetMinSize(wx.Size(240, 240)) |
---|
108 | |
---|
109 | self.title = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRTITLE, |
---|
110 | label='Window Title', name='title', parent=self, pos=wx.Point(0, |
---|
111 | 0), size=wx.Size(400, 23), style=wx.ALIGN_CENTRE) |
---|
112 | self.title.SetFont(wx.Font(15, wx.SWISS, wx.NORMAL, wx.NORMAL, False, |
---|
113 | u'Arial')) |
---|
114 | self.title.Center(wx.BOTH) |
---|
115 | self.title.SetToolTipString('description of this X,Y set') |
---|
116 | |
---|
117 | self.lblMotor = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRLBLMOTOR, |
---|
118 | label='motor', name='lblMotor', parent=self, pos=wx.Point(6, 29), |
---|
119 | size=wx.Size(80, 20), style=wx.ALIGN_CENTRE) |
---|
120 | self.lblMotor.SetToolTipString(u'values obtained from EPICS') |
---|
121 | self.lblMotor.Center(wx.BOTH) |
---|
122 | self.lblMotor.SetBackgroundColour(wx.Colour(200, 191, 140)) |
---|
123 | self.lblMotor.SetMinSize(wx.Size(80, 20)) |
---|
124 | |
---|
125 | self.lbl_x_title = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRLBL_X_TITLE, |
---|
126 | label='title_x', name='lbl_x_title', parent=self, pos=wx.Point(94, |
---|
127 | 29), size=wx.Size(146, 20), style=wx.ALIGN_CENTRE) |
---|
128 | self.lbl_x_title.SetToolTipString('name and units of X axis') |
---|
129 | self.lbl_x_title.Center(wx.BOTH) |
---|
130 | self.lbl_x_title.SetBackgroundColour(wx.Colour(200, 191, 140)) |
---|
131 | self.lbl_x_title.SetMinSize(wx.Size(80, 20)) |
---|
132 | |
---|
133 | self.lbl_y_title = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRLBL_Y_TITLE, |
---|
134 | label='title_y', name='lbl_y_title', parent=self, |
---|
135 | pos=wx.Point(248, 29), size=wx.Size(146, 20), |
---|
136 | style=wx.ALIGN_CENTRE) |
---|
137 | self.lbl_y_title.SetToolTipString(u'name and units of Y axis') |
---|
138 | self.lbl_y_title.Center(wx.BOTH) |
---|
139 | self.lbl_y_title.SetBackgroundColour(wx.Colour(200, 191, 140)) |
---|
140 | self.lbl_y_title.SetMinSize(wx.Size(80, 20)) |
---|
141 | |
---|
142 | self.lblReadback = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRLBLREADBACK, |
---|
143 | label='readback', name='lblReadback', parent=self, pos=wx.Point(6, |
---|
144 | 57), size=wx.Size(80, 20), style=wx.ALIGN_CENTRE) |
---|
145 | self.lblReadback.SetToolTipString(u'indicates current position') |
---|
146 | self.lblReadback.Center(wx.BOTH) |
---|
147 | self.lblReadback.SetBackgroundColour(wx.Colour(200, 191, 140)) |
---|
148 | self.lblReadback.SetMinSize(wx.Size(80, 20)) |
---|
149 | |
---|
150 | self.x_rbv = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRX_RBV, |
---|
151 | label='x_rbv', name='x_rbv', parent=self, pos=wx.Point(94, 57), |
---|
152 | size=wx.Size(146, 20), style=wx.ALIGN_CENTRE) |
---|
153 | self.x_rbv.SetToolTipString(u'X axis readback value') |
---|
154 | self.x_rbv.Center(wx.BOTH) |
---|
155 | self.x_rbv.SetMinSize(wx.Size(80, 20)) |
---|
156 | |
---|
157 | self.y_rbv = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRY_RBV, |
---|
158 | label='y_rbv', name='y_rbv', parent=self, pos=wx.Point(248, 57), |
---|
159 | size=wx.Size(146, 20), style=wx.ALIGN_CENTRE) |
---|
160 | self.y_rbv.SetToolTipString(u'Y axis readback value') |
---|
161 | self.y_rbv.Center(wx.BOTH) |
---|
162 | self.y_rbv.SetMinSize(wx.Size(80, 20)) |
---|
163 | |
---|
164 | self.lblTarget = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRLBLTARGET, |
---|
165 | label='target', name='lblTarget', parent=self, pos=wx.Point(6, |
---|
166 | 85), size=wx.Size(80, 20), style=wx.ALIGN_CENTRE) |
---|
167 | self.lblTarget.SetToolTipString(u'also known as "commanded value"') |
---|
168 | self.lblTarget.Center(wx.BOTH) |
---|
169 | self.lblTarget.SetBackgroundColour(wx.Colour(200, 191, 140)) |
---|
170 | self.lblTarget.SetMinSize(wx.Size(80, 20)) |
---|
171 | |
---|
172 | self.x_val = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRX_VAL, |
---|
173 | label='x_val', name='x_val', parent=self, pos=wx.Point(94, 85), |
---|
174 | size=wx.Size(146, 20), style=wx.ALIGN_CENTRE) |
---|
175 | self.x_val.SetToolTipString(u'X axis target value') |
---|
176 | self.x_val.Center(wx.BOTH) |
---|
177 | self.x_val.SetMinSize(wx.Size(80, 20)) |
---|
178 | |
---|
179 | self.y_val = wx.lib.stattext.GenStaticText(ID=wxID_XYPAIRY_VAL, |
---|
180 | label='y_val', name='y_val', parent=self, pos=wx.Point(248, 85), |
---|
181 | size=wx.Size(146, 20), style=wx.ALIGN_CENTRE) |
---|
182 | self.y_val.SetToolTipString(u'Y axis target value') |
---|
183 | self.y_val.Center(wx.BOTH) |
---|
184 | self.y_val.SetMinSize(wx.Size(80, 20)) |
---|
185 | |
---|
186 | self.stop = wx.Button(id=wxID_XYPAIRSTOP, label='Stop', name='stop', |
---|
187 | parent=self, pos=wx.Point(140, 111), size=wx.Size(120, 32), |
---|
188 | style=0) |
---|
189 | self.stop.SetBackgroundColour(wx.Colour(223, 0, 0)) |
---|
190 | self.stop.SetForegroundColour(wx.Colour(255, 255, 255)) |
---|
191 | self.stop.SetToolTipString(u'command EPICS to stop these two motors') |
---|
192 | self.stop.SetHelpText(u'command EPICS to stop these two motors') |
---|
193 | self.stop.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, |
---|
194 | 'Arial')) |
---|
195 | self.stop.Bind(wx.EVT_BUTTON, self.OnStopButton, id=wxID_XYPAIRSTOP) |
---|
196 | |
---|
197 | self.table = wx.Notebook(id=wxID_XYPAIRTABLE, name='table', parent=self, |
---|
198 | pos=wx.Point(0, 143), size=wx.Size(400, 97), style=0) |
---|
199 | self.table.SetMinSize(wx.Size(240, 50)) |
---|
200 | self.table.SetToolTipString(u'table of various settings for X,Y motors"') |
---|
201 | |
---|
202 | self._init_sizers() |
---|
203 | |
---|
204 | def __init_names__(self): |
---|
205 | '''cross-reference the widgets to a dictionary''' |
---|
206 | self.widget = {"x": {}, "y": {}} |
---|
207 | self.widget["x"]["VAL"] = self.x_val |
---|
208 | self.widget["y"]["VAL"] = self.y_val |
---|
209 | self.widget["x"]["RBV"] = self.x_rbv |
---|
210 | self.widget["y"]["RBV"] = self.y_rbv |
---|
211 | self.widget["x"]["title"] = self.lbl_x_title |
---|
212 | self.widget["y"]["title"] = self.lbl_y_title |
---|
213 | |
---|
214 | def __init__(self, parent, name, root, rootCallback, newtab=False): |
---|
215 | '''initialize an instance of this class |
---|
216 | @param parent: object that owns this class |
---|
217 | @param name: display test that describes this XYpair |
---|
218 | @param root: root object |
---|
219 | @param rootCallback: routine in the parent to handle Button events from the Tab |
---|
220 | @param newtab: [Boolean] create a default Tab group?''' |
---|
221 | self.tab_count = 0 |
---|
222 | self.epics = {} |
---|
223 | self.titles = {} |
---|
224 | for axis in ['x', 'y']: |
---|
225 | self.epics[axis] = wxmtxy_axis.Axis() |
---|
226 | self.titles[axis] = {} |
---|
227 | for field in ['DESC', 'EGU']: |
---|
228 | self.titles[axis][field] = "" |
---|
229 | self._init_ctrls(parent) |
---|
230 | self.__init_names__() # build a cross-reference |
---|
231 | self.parent = parent |
---|
232 | self.SetName(name) |
---|
233 | self.root = root |
---|
234 | self.rootCallback = rootCallback |
---|
235 | self.SetAxisTitles('X axis, egu', 'Y axis, egu') |
---|
236 | if newtab == True: |
---|
237 | self.NewTab() |
---|
238 | self.Layout() |
---|
239 | #self.SetMotorColor("x", True) |
---|
240 | #self.SetMotorColor("y", False) |
---|
241 | self.SetEpicsConfig({'x': {}, 'y': {}}) |
---|
242 | |
---|
243 | # ################################ |
---|
244 | # ## added methods ### |
---|
245 | # ################################ |
---|
246 | |
---|
247 | def NewTab(self, newrow=True): |
---|
248 | '''make a new tab |
---|
249 | @param newrow: [Boolean] option to create a first row''' |
---|
250 | panel = wxmtxy_tab.Tab(parent=self.table, pair=self, |
---|
251 | pairCallback=self.TabHandler, newrow=newrow) |
---|
252 | self.tab_count += 1 |
---|
253 | self.table.AddPage(imageId=-1, page=panel, select=True, |
---|
254 | text='tab ' + repr(self.tab_count)) |
---|
255 | return panel |
---|
256 | |
---|
257 | def DeleteTab(self): |
---|
258 | '''Delete the given tab''' |
---|
259 | tabnum = self.GetSelection() |
---|
260 | if tabnum < 0: |
---|
261 | return 'No tab to delete.' |
---|
262 | else: |
---|
263 | text = self.GetTabText(tabnum) |
---|
264 | self.table.DeletePage(tabnum) |
---|
265 | return 'Deleted tab named: ' + text |
---|
266 | |
---|
267 | def TabHandler(self, theTab, theRow, command): |
---|
268 | '''Callback function to handle a command from a tab |
---|
269 | @param theTab: wxmtxy_tab.Tab object |
---|
270 | @param theRow: wxmtxy_row.Row object |
---|
271 | @param command: [string] Row button action to pass upward for handling''' |
---|
272 | self.rootCallback(self, theTab, theRow, command) |
---|
273 | |
---|
274 | def GetSelection(self): |
---|
275 | '''@return index number of the selected tab object''' |
---|
276 | return self.table.GetSelection() |
---|
277 | |
---|
278 | def GetTabSelection(self): |
---|
279 | '''@return selected tab object''' |
---|
280 | tabnum = self.GetSelection() |
---|
281 | if tabnum < 0: |
---|
282 | return None |
---|
283 | return self.table.GetPage(tabnum) |
---|
284 | |
---|
285 | def GetPageTitle(self): |
---|
286 | '''@return page title''' |
---|
287 | return self.title.GetLabel() |
---|
288 | |
---|
289 | def SetPageTitle(self, title): |
---|
290 | '''define the page title |
---|
291 | @param title: [string] new page title''' |
---|
292 | self.title.SetLabel(title) |
---|
293 | self.Layout() |
---|
294 | |
---|
295 | def GetTabText(self, tabnum): |
---|
296 | '''return the text of the tab numbered tabnum |
---|
297 | @param tabnum: [int] index of selected tab''' |
---|
298 | return self.table.GetPageText(tabnum) |
---|
299 | |
---|
300 | def SetTabText(self, tabnum, text): |
---|
301 | '''set the text of the tab numbered tabnum |
---|
302 | @param tabnum: [int] index of selected tab |
---|
303 | @param text: [string] new text''' |
---|
304 | self.table.SetPageText(tabnum, text) |
---|
305 | |
---|
306 | def GetAxisTitleX(self): |
---|
307 | '''@return X axis title''' |
---|
308 | return self.lbl_x_title.GetLabel() |
---|
309 | |
---|
310 | def GetAxisTitleY(self): |
---|
311 | '''@return Y axis title''' |
---|
312 | return self.lbl_y_title.GetLabel() |
---|
313 | |
---|
314 | def SetMotorColor(self, axis, state): |
---|
315 | '''change the background color of the RBV and VAL widgets |
---|
316 | |
---|
317 | @param axis: [string] either "x" or "y" |
---|
318 | @param state: [Boolean], color is green if state == False, neutral if True |
---|
319 | ''' |
---|
320 | colormap = {False: self.COLOR_MOVING, True: self.COLOR_NOT_MOVING} |
---|
321 | rbv = {"x": self.x_rbv, "y": self.y_rbv} |
---|
322 | val = {"x": self.x_val, "y": self.y_val} |
---|
323 | rbv[axis].SetBackgroundColour(colormap[state]) |
---|
324 | val[axis].SetBackgroundColour(colormap[state]) |
---|
325 | self.Refresh() |
---|
326 | self.Layout() |
---|
327 | |
---|
328 | def GetRbvXY(self): |
---|
329 | '''@return readback values for X and Y as a tuple''' |
---|
330 | x = self.x_rbv.GetLabel() |
---|
331 | y = self.y_rbv.GetLabel() |
---|
332 | return x, y |
---|
333 | |
---|
334 | def SetAxisTitles(self, x_title, y_title): |
---|
335 | '''define the axis titles |
---|
336 | @param x_title: [string] X axis title |
---|
337 | @param y_title: [string] Y axis title''' |
---|
338 | self.lbl_x_title.SetLabel(x_title) |
---|
339 | self.lbl_y_title.SetLabel(y_title) |
---|
340 | self.Layout() |
---|
341 | |
---|
342 | def GetEpicsConfig(self): |
---|
343 | '''@return deep copy of EPICS PV configuration''' |
---|
344 | config = {} |
---|
345 | for axis in ['x', 'y']: |
---|
346 | config[axis] = copy.deepcopy(self.epics[axis].GetConfigure()) |
---|
347 | return config |
---|
348 | |
---|
349 | def SetEpicsConfig(self, config): |
---|
350 | '''define the EPICS PVs from a configuration |
---|
351 | @param config: Python dictionary with axes configurations''' |
---|
352 | for axis in ['x', 'y']: |
---|
353 | self.epics[axis].SetConfigure(copy.deepcopy(config[axis])) |
---|
354 | |
---|
355 | def CallbackPositions(self, epics_args, user_args): |
---|
356 | '''receive a callback on the VAL and RBV fields''' |
---|
357 | axis = user_args[0][0] |
---|
358 | field = user_args[0][1] |
---|
359 | value = epics_args['pv_value'] |
---|
360 | if epics_args.has_key('pv_precision'): |
---|
361 | # what about display precision? |
---|
362 | fmt = '%.' + str(epics_args['pv_precision']) |
---|
363 | abs_value = abs(value) |
---|
364 | if abs_value >= 1e5 or (abs_value < 1e-5 and abs_value > 0): |
---|
365 | fmt += 'E' |
---|
366 | else: |
---|
367 | fmt += 'f' |
---|
368 | str_value = fmt % value |
---|
369 | else: |
---|
370 | str_value = str(value) |
---|
371 | self.widget[axis][field] .SetLabel(str_value) |
---|
372 | self.Layout() |
---|
373 | |
---|
374 | def CallbackTitle(self, epics_args, user_args): |
---|
375 | '''receive a callback on the DESC and EGU fields''' |
---|
376 | axis = user_args[0][0] |
---|
377 | field = user_args[0][1] |
---|
378 | value = epics_args['pv_value'] |
---|
379 | self.titles[axis][field] = value |
---|
380 | title = "%s, %s" % (self.titles[axis]['DESC'], self.titles[axis]['EGU']) |
---|
381 | self.widget[axis]['title'] .SetLabel(title) |
---|
382 | |
---|
383 | def CallbackDMOV(self, epics_args, user_args): |
---|
384 | '''receive a callback on the DMOV field''' |
---|
385 | axis = user_args[0][0] |
---|
386 | value = epics_args['pv_value'] |
---|
387 | self.SetMotorColor(axis, value == 1) |
---|
388 | |
---|
389 | def ConnectEpics(self): |
---|
390 | '''try to connect the XY_pair PV names with EPICS''' |
---|
391 | #+++++++++++++++++++++++++++++++ |
---|
392 | # need to replace this starting from the example in wxmtxy_axis.main() |
---|
393 | #+++++++++++++++++++++++++++++++ |
---|
394 | for axis in ['x', 'y']: |
---|
395 | cfg = self.epics[axis].GetConfigure() |
---|
396 | for field in ['VAL', 'RBV']: |
---|
397 | item = self.epics[axis].db[field] |
---|
398 | item.connection.SetUserCallback(self.CallbackPositions) |
---|
399 | item.connection.SetUserArgs((axis, field)) |
---|
400 | item.SetWidget(self.widget[axis][field] .SetLabel) |
---|
401 | |
---|
402 | # advanced handling |
---|
403 | desc = self.epics[axis].db['DESC'] |
---|
404 | desc.connection.SetUserCallback(self.CallbackTitle) |
---|
405 | desc.connection.SetUserArgs((axis, 'DESC')) |
---|
406 | |
---|
407 | egu = self.epics[axis].db['EGU'] |
---|
408 | egu.connection.SetUserCallback(self.CallbackTitle) |
---|
409 | egu.connection.SetUserArgs((axis, 'EGU')) |
---|
410 | |
---|
411 | dmov = self.epics[axis].db['DMOV'] |
---|
412 | dmov.connection.SetUserCallback(self.CallbackDMOV) |
---|
413 | dmov.connection.SetUserArgs((axis, 'DMOV')) |
---|
414 | |
---|
415 | # do not need to setup the STOP button |
---|
416 | |
---|
417 | cfg['AXIS'] = axis |
---|
418 | #pprint.pprint(cfg) |
---|
419 | self.epics[axis].Connect() |
---|
420 | |
---|
421 | def ReleaseEpics(self): |
---|
422 | '''release connections with the XY_pair EPICS PVs |
---|
423 | @note: When will this be called?''' |
---|
424 | for axis in ['x', 'y']: |
---|
425 | self.epics[axis].Disconnect() |
---|
426 | |
---|
427 | def StopAxes(self): |
---|
428 | '''Send a stop to both axes''' |
---|
429 | for axis in ['x', 'y']: |
---|
430 | #print __name__, 'Stop axis', axis |
---|
431 | self.epics[axis].Stop() |
---|
432 | |
---|
433 | def MoveAxes(self, x, y): |
---|
434 | '''Command both axes to move to new position |
---|
435 | @param x: [float] new X position |
---|
436 | @param y: [float] new Y position''' |
---|
437 | #print __name__, 'MoveAxes:', x, y |
---|
438 | self.epics['x'].Move(x) |
---|
439 | self.epics['y'].Move(y) |
---|
440 | |
---|
441 | # ################################ |
---|
442 | # ## event handling routines ### |
---|
443 | # ################################ |
---|
444 | |
---|
445 | def OnStopButton(self, event): |
---|
446 | '''user requested to stop the X and Y motors |
---|
447 | @param event: wxPython event object''' |
---|
448 | self.TabHandler(self, None, 'stop') |
---|