def CreatePanel(self): " build (but do not fill in) panel components" wdesc, wrbv, winfo, wdrv = 200, 105, 90, 120 if self._size == 'medium': wdesc, wrbv, winfo, wdrv = 140, 85, 80, 100 elif self._size == 'small': wdesc, wrbv, winfo, wdrv = 50, 60, 25, 80 self.desc = PVText(self, size=(wdesc, 25), style=LTEXT) self.desc.SetForegroundColour("Blue") font = self.desc.GetFont() font.PointSize -= 1 self.desc.SetFont(font) self.rbv = PVText(self, size=(wrbv, 25), fg='Blue', style=RCEN) self.info = wx.StaticText(self, label='', size=(winfo, 25), style=RCEN) self.info.SetForegroundColour("Red") self.drive = PVFloatCtrl(self, size=(wdrv, -1), style=wx.TE_RIGHT) try: self.FillPanelComponents() except PyDeadObjectError: return spacer = wx.StaticText(self, label=' ', size=(5, 5), style=RIGHT) if self._size != 'small': self.__sizer.AddMany([(spacer, 0, CEN)]) self.__sizer.AddMany([(self.desc, 1, LCEN), (self.info, 0, CEN), (self.rbv, 0, CEN), (self.drive, 0, CEN)]) if self._size == 'full': self.twk_list = ['', ''] self.__twkbox = wx.ComboBox(self, value='', size=(100, -1), choices=self.twk_list, style=wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER) self.__twkbox.Bind(wx.EVT_COMBOBOX, self.OnTweakBoxComboEvent) self.__twkbox.Bind(wx.EVT_TEXT_ENTER, self.OnTweakBoxEnterEvent) self.twr = PVButton(self, label='<', size=(30, 30)) self.twf = PVButton(self, label='>', size=(30, 30)) self.stopbtn = add_button(self, label=' Stop ', action=self.OnStopButton) self.morebtn = add_button(self, label=' More ', action=self.OnMoreButton) self.__sizer.AddMany([(self.twr, 0, CEN), (self.__twkbox, 0, CEN), (self.twf, 0, CEN), (self.stopbtn, 0, CEN), (self.morebtn, 0, CEN)]) self.SetAutoLayout(1) print("create ", self.motor) pack(self, self.__sizer)
def MotorCtrl(self, panel, attr, size=(80, -1)): "PVFloatCtrl for a Motor attribute" return PVFloatCtrl(panel, size=size, precision=self.motor.PREC, pv=self.motor.PV(attr), style=wx.TE_RIGHT)
class MotorPanel(wx.Panel): """ MotorPanel a simple wx windows panel for controlling an Epics Motor use psize='full' (defaiult) for full capabilities, or 'medium' or 'small' for minimal version """ __motor_fields = ('SET', 'disabled', 'LLM', 'HLM', 'LVIO', 'TWV', 'HLS', 'LLS', 'SPMG', 'DESC') def __init__(self, parent, motor=None, psize='full', messenger=None, prec=None, **kw): wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) self.parent = parent if hasattr(messenger, '__call__'): self.__messenger = messenger self.format = None if prec is not None: self.format = "%%.%if" % prec self.motor = None self._size = 'full' if psize in ('medium', 'small'): self._size = psize self.__sizer = wx.BoxSizer(wx.HORIZONTAL) self.CreatePanel() if motor is not None: try: self.SelectMotor(motor) except PyDeadObjectError: pass @EpicsFunction def SelectMotor(self, motor): " set motor to a named motor PV" if motor is None: return epics.poll() try: if self.motor is not None: for i in self.__motor_fields: self.motor.clear_callback(attr=i) except PyDeadObjectError: return if isinstance(motor, (str, unicode)): self.motor = epics.Motor(motor) elif isinstance(motor, epics.Motor): self.motor = motor self.motor.get_info() if self.format is None: self.format = "%%.%if" % self.motor.PREC self.FillPanel() for attr in self.__motor_fields: self.motor.get_pv(attr).add_callback(self.OnMotorEvent, wid=self.GetId(), field=attr) if self._size == 'full': self.SetTweak(self.format % self.motor.TWV) @EpicsFunction def FillPanelComponents(self): epics.poll() try: if self.motor is None: return except PyDeadObjectError: return self.drive.SetPV(self.motor.PV('VAL')) self.rbv.SetPV(self.motor.PV('RBV')) self.desc.SetPV(self.motor.PV('DESC')) descpv = self.motor.PV('DESC').get() self.desc.Wrap(45) if self._size == 'full': self.twf.SetPV(self.motor.PV('TWF')) self.twr.SetPV(self.motor.PV('TWR')) elif len(descpv) > 20: font = self.desc.GetFont() font.PointSize -= 1 self.desc.SetFont(font) self.info.SetLabel('') for f in ('SET', 'LVIO', 'SPMG', 'LLS', 'HLS', 'disabled'): uname = self.motor.PV(f).pvname wx.CallAfter(self.OnMotorEvent, pvname=uname, field=f) def CreatePanel(self): " build (but do not fill in) panel components" wdesc, wrbv, winfo, wdrv = 200, 105, 90, 120 if self._size == 'medium': wdesc, wrbv, winfo, wdrv = 140, 85, 80, 100 elif self._size == 'small': wdesc, wrbv, winfo, wdrv = 45, 70, 40, 80 self.desc = PVText(self, size=(wdesc, 25), style=LTEXT) self.desc.SetForegroundColour("Blue") self.rbv = PVText(self, size=(wrbv, 25), fg='Blue', style=RCEN) self.info = wx.StaticText(self, label='', size=(winfo, 25), style=RCEN) self.info.SetForegroundColour("Red") self.drive = PVFloatCtrl(self, size=(wdrv, -1), style=wx.TE_RIGHT) try: self.FillPanelComponents() except PyDeadObjectError: return spacer = wx.StaticText(self, label=' ', size=(5, 5), style=RIGHT) self.__sizer.AddMany([(spacer, 0, CEN), (self.desc, 1, LCEN), (self.info, 1, CEN), (self.rbv, 0, CEN), (self.drive, 0, CEN)]) if self._size == 'full': self.twk_list = ['', ''] self.__twkbox = wx.ComboBox(self, value='', size=(100, -1), choices=self.twk_list, style=wx.CB_DROPDOWN | wx.TE_PROCESS_ENTER) self.__twkbox.Bind(wx.EVT_COMBOBOX, self.OnTweakBoxComboEvent) self.__twkbox.Bind(wx.EVT_TEXT_ENTER, self.OnTweakBoxEnterEvent) self.twr = PVButton(self, label='<', size=(30, 30)) self.twf = PVButton(self, label='>', size=(30, 30)) self.stopbtn = add_button(self, label=' Stop ', action=self.OnStopButton) self.morebtn = add_button(self, label=' More ', action=self.OnMoreButton) self.__sizer.AddMany([(self.twr, 0, CEN), (self.__twkbox, 0, CEN), (self.twf, 0, CEN), (self.stopbtn, 0, CEN), (self.morebtn, 0, CEN)]) self.SetAutoLayout(1) pack(self, self.__sizer) @EpicsFunction def FillPanel(self): " fill in panel components for motor " try: if self.motor is None: return self.FillPanelComponents() self.drive.Update() self.desc.Update() self.rbv.Update() if self._size == 'full': self.twk_list = self.make_step_list() self.UpdateStepList() except PyDeadObjectError: pass @EpicsFunction def OnStopButton(self, event=None): "stop button" if self.motor is None: return curstate = str(self.stopbtn.GetLabel()).lower().strip() self.motor.StopNow() epics.poll() val = 3 if curstate == 'stop': val = 0 self.motor.put('SPMG', val) @EpicsFunction def OnMoreButton(self, event=None): "more button" if self.motor is not None: MotorDetailFrame(parent=self, motor=self.motor) @DelayedEpicsCallback def OnTweakBoxEnterEvent(self, event=None): val = float(self.__twkbox.GetValue()) wx.CallAfter(self.motor.PV('TWV').put, val) @DelayedEpicsCallback def OnTweakBoxComboEvent(self, event=None): val = float(self.__twkbox.GetValue()) wx.CallAfter(self.motor.PV('TWV').put, val) @DelayedEpicsCallback def OnMotorEvent(self, pvname=None, field=None, event=None, **kws): if pvname is None: return None field_val = self.motor.get(field) field_str = self.motor.get(field, as_string=True) if field == 'LLM': self.drive.SetMin(self.motor.LLM) elif field == 'HLM': self.drive.SetMax(self.motor.HLM) elif field in ('LVIO', 'HLS', 'LLS'): s = 'Limit!' if field_val == 0: s = '' self.info.SetLabel(s) elif field == 'SET': label, color = 'Set:', 'Yellow' if field_val == 0: label, color = '', 'White' self.info.SetLabel(label) self.drive.bgcol_valid = color self.drive.SetBackgroundColour(color) self.drive.Refresh() elif field == 'disabled': label = ('', 'Disabled')[field_val] self.info.SetLabel(label) elif field == 'DESC': font = self.rbv.GetFont() if len(field_str) > 20: font.PointSize -= 1 self.desc.SetFont(font) elif field == 'TWV' and self._size == 'full': self.SetTweak(field_str) elif field == 'SPMG' and self._size == 'full': label, info, color = 'Stop', '', 'White' if field_val == 0: label, info, color = ' Go ', 'Stopped', 'Yellow' elif field_val == 1: label, info, color = ' Resume ', 'Paused', 'Yellow' elif field_val == 2: label, info, color = ' Go ', 'Move Once', 'Yellow' self.stopbtn.SetLabel(label) self.info.SetLabel(info) self.stopbtn.SetBackgroundColour(color) self.stopbtn.Refresh() else: pass @EpicsFunction def SetTweak(self, val): if not isinstance(val, str): val = self.format % val try: if val not in self.twk_list: self.UpdateStepList(value=val) self.__twkbox.SetValue(val) except PyDeadObjectError: pass def make_step_list(self): """ create initial list of motor steps, based on motor range and precision""" if self.motor is None: return [] return [self.format % i for i in self.motor.make_step_list()] def UpdateStepList(self, value=None): "add a value and re-sort the list of Step values" if value is not None: self.twk_list.append(value) x = [float(i) for i in self.twk_list] x.sort() self.twk_list = [self.format % i for i in x] # remake list in TweakBox self.__twkbox.Clear() self.__twkbox.AppendItems(self.twk_list)
def __init__(self, parent=None, motor=None): ScrolledPanel.__init__(self, parent, size=MAINSIZE, name='', style=wx.EXPAND | wx.GROW | wx.TAB_TRAVERSAL) self.Freeze() self.motor = motor prec = motor.PREC sizer = wx.BoxSizer(wx.VERTICAL) ds = wx.GridBagSizer(1, 6) dp = wx.Panel(self) ds.Add(xLabel(dp, 'Label'), (0, 0), (1, 1), LCEN, 5) ds.Add(self.MotorTextCtrl(dp, 'DESC', size=(180, -1)), (0, 1), (1, 1), LCEN, 5) ds.Add(xLabel(dp, 'units'), (0, 2), (1, 1), LCEN, 5) ds.Add(self.MotorTextCtrl(dp, 'EGU', size=(90, -1)), (0, 3), (1, 1), LCEN, 5) ds.Add(xLabel(dp, "Precision"), (0, 4), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'PREC', size=(30, -1)), (0, 5), (1, 1), CEN) set_sizer(dp, ds) sizer.Add(dp, 0) sizer.Add((3, 3), 0) sizer.Add(wx.StaticLine(self, size=(100, 2)), 0, wx.EXPAND) sizer.Add((3, 3), 0) ds = wx.GridBagSizer(6, 4) dp = wx.Panel(self) nrow = 0 ds.Add(xTitle(dp, "Drive"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(xLabel(dp, "User"), (nrow, 1), (1, 1), CEN, 5) ds.Add(xLabel(dp, "Dial"), (nrow, 2), (1, 1), CEN, 5) ds.Add(xLabel(dp, "Raw"), (nrow, 3), (1, 1), CEN, 5) #### nrow += 1 self.info = wx.StaticText(dp, label='', size=(55, 20), style=CEN) self.info.SetForegroundColour("Red") ds.Add(xLabel(dp, "High Limit"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'HLM'), (nrow, 1), (1, 1), CEN, 5) ds.Add(self.MotorCtrl(dp, 'DHLM'), (nrow, 2), (1, 1), CEN, 5) ds.Add(self.info, (nrow, 3), (1, 1), CEN, 5) #### nrow += 1 ostyle = RCEN | wx.EXPAND ds.Add(xLabel(dp, "Readback"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorText(dp, 'RBV'), (nrow, 1), (1, 1), ostyle, 5) ds.Add(self.MotorText(dp, 'DRBV'), (nrow, 2), (1, 1), ostyle, 5) ds.Add(self.MotorText(dp, 'RRBV'), (nrow, 3), (1, 1), ostyle, 5) #### nrow += 1 self.drives = [ self.MotorCtrl(dp, 'VAL'), self.MotorCtrl(dp, 'DVAL'), self.MotorCtrl(dp, 'RVAL') ] ds.Add(xLabel(dp, "Move"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.drives[0], (nrow, 1), (1, 1), CEN, 5) ds.Add(self.drives[1], (nrow, 2), (1, 1), CEN, 5) ds.Add(self.drives[2], (nrow, 3), (1, 1), CEN, 5) nrow += 1 ds.Add(xLabel(dp, "Low Limit"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'LLM'), (nrow, 1), (1, 1), CEN, 5) ds.Add(self.MotorCtrl(dp, 'DLLM'), (nrow, 2), (1, 1), CEN, 5) #### twk_sizer = wx.BoxSizer(wx.HORIZONTAL) twk_panel = wx.Panel(dp) twk_val = PVFloatCtrl(twk_panel, size=(110, -1), precision=prec) twk_val.SetPV(self.motor.PV('TWV')) twk_left = wx.Button(twk_panel, label='<', size=(30, 30)) twk_right = wx.Button(twk_panel, label='>', size=(30, 30)) twk_left.Bind(wx.EVT_BUTTON, self.OnLeftButton) twk_right.Bind(wx.EVT_BUTTON, self.OnRightButton) twk_sizer.AddMany([(twk_left, 0, CEN), (twk_val, 0, CEN), (twk_right, 0, CEN)]) set_sizer(twk_panel, twk_sizer) nrow += 1 ds.Add(xLabel(dp, "Tweak"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(twk_panel, (nrow, 1), (1, 2), wx.ALIGN_LEFT, 5) epv = self.motor.PV('disabled') able_btns = PVEnumButtons(dp, pv=epv, orientation=wx.VERTICAL, size=(80, 60)) ds.Add(able_btns, (nrow - 1, 3), (2, 1), CEN, 5) stop_btns = PVEnumButtons(dp, pv=self.motor.PV('SPMG'), orientation=wx.VERTICAL, size=(100, 125)) ds.Add(stop_btns, (2, 4), (4, 1), wx.ALIGN_RIGHT, 5) for attr in ('LLM', 'HLM', 'DLLM', 'DHLM'): pv = self.motor.PV(attr) pv.add_callback(self.OnLimitChange, wid=self.GetId(), attr=attr) # set_sizer(dp, ds) # ,fit=True) sizer.Add(dp, 0) #### sizer.Add((3, 3), 0) sizer.Add(wx.StaticLine(self, size=(100, 2)), 0, wx.EXPAND) sizer.Add((3, 3), 0) sizer.Add(xTitle(self, 'Calibration'), 0, LCEN, 25) ds = wx.GridBagSizer(6, 5) dp = wx.Panel(self) ds.Add(xLabel(dp, 'Mode: '), (0, 0), (1, 1), LCEN, 5) ds.Add( PVEnumButtons(dp, pv=self.motor.PV('SET'), orientation=wx.HORIZONTAL, size=(175, 25)), (0, 1), (1, 2), wx.ALIGN_LEFT) ds.Add(xLabel(dp, 'Direction: '), (1, 0), (1, 1), LCEN, 5) ds.Add( PVEnumButtons(dp, pv=self.motor.PV('DIR'), orientation=wx.HORIZONTAL, size=(175, 25)), (1, 1), (1, 2), wx.ALIGN_LEFT) ds.Add(xLabel(dp, 'Freeze Offset: '), (0, 4), (1, 1), LCEN, 5) ds.Add(PVEnumChoice(dp, pv=self.motor.PV('FOFF'), size=(110, -1)), (0, 5), (1, 1), CEN) ds.Add(xLabel(dp, 'Offset Value: '), (1, 4), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'OFF'), (1, 5), (1, 1), CEN) set_sizer(dp, ds) sizer.Add(dp, 0) ##### sizer.Add((3, 3), 0) sizer.Add(wx.StaticLine(self, size=(100, 2)), 0, wx.EXPAND) sizer.Add((3, 3), 0) # ds = wx.GridBagSizer(6, 3) dp = wx.Panel(self) nrow = 0 ds.Add(xTitle(dp, "Dynamics"), (nrow, 0), (1, 1), LCEN, 55) ds.Add(xLabel(dp, "Normal"), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Backlash"), (nrow, 2), (1, 1), CEN) #### nrow += 1 ds.Add(xLabel(dp, "Max Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'VMAX'), (nrow, 1), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'VELO'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp, 'BVEL'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Base Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'VBAS'), (nrow, 1), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Accel (s)"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'ACCL'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp, 'BACC'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Backslash Distance"), (nrow, 0), (1, 2), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'BDST'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Move Fraction"), (nrow, 0), (1, 2), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'FRAC'), (nrow, 2), (1, 1), CEN) set_sizer(dp, ds) # ,fit=True) sizer.Add(dp, 0) sizer.Add((3, 3), 0) sizer.Add(wx.StaticLine(self, size=(100, 2)), 0, wx.EXPAND) sizer.Add((3, 3), 0) sizer.Add(xTitle(self, 'Resolution, Readback, and Retries'), 0, LCEN, 5) ds = wx.GridBagSizer(4, 4) dp = wx.Panel(self) nrow = 0 ds.Add(xLabel(dp, "Motor Res"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'MRES'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Encoder Res"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'ERES'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Steps / Rev"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'SREV'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Units / Rev"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'UREV'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Readback Res"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'RRES'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Readback Delay (s)"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'DLY'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Retry Deadband"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'RDBD'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Max Retries"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'RTRY'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Use Encoder"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(PVEnumChoice(dp, pv=self.motor.PV('UEIP'), size=(110, -1)), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Use Readback"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(PVEnumChoice(dp, pv=self.motor.PV('URIP'), size=(110, -1)), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Use NTM"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(PVEnumChoice(dp, pv=self.motor.PV('NTM'), size=(110, -1)), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "NTM Factor"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'NTMF'), (nrow, 3), (1, 1), CEN) set_sizer(dp, ds) sizer.Add(dp, 0) sizer.Add(wx.StaticLine(self, size=(100, 2)), 0, wx.EXPAND) for attr in self.__motor_fields: self.motor.PV(attr).add_callback(self.OnMotorEvent, wid=self.GetId(), field=attr) self.info.SetLabel('') for f in ('HLS', 'LLS', 'LVIO', 'SET'): if self.motor.get(f): wx.CallAfter(self.OnMotorEvent, pvname=self.motor.PV(f).pvname, field=f) set_sizer(self, sizer, fit=True) self.SetupScrolling() self.Thaw()
def __init__(self, parent=None, motor=None): wx.Frame.__init__(self, parent, wx.ID_ANY, size=(525, 650), style=wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) self.motor = motor prec = motor.PREC motor_pvname = self.motor._prefix devtype = motor.get('DTYP', as_string=True) if motor_pvname.endswith('.'): motor_pvname = motor_pvname[:-1] self.SetTitle("Motor Details: %s | %s | (%s)" % (motor_pvname, self.motor.DESC, devtype)) panel = ScrolledPanel(self, size=(500, 650), name='mpanel', style=wx.GROW|wx.TAB_TRAVERSAL) sizer = wx.BoxSizer(wx.VERTICAL) spanel = wx.Panel(panel, -1, size=(500, 50)) ssizer = wx.BoxSizer(wx.HORIZONTAL) ssizer.AddMany([(wx.StaticText(spanel, label=' Label ', size=(65, -1)), 0, RCEN), (self.MotorTextCtrl(spanel, 'DESC', size=(210, -1)), 1, LCEN), (wx.StaticText(spanel, label=' units ', size=(75, -1)), 0, RCEN), (self.MotorTextCtrl(spanel, 'EGU', size=(95, -1)), 0, LCEN) ]) set_sizer(spanel, ssizer) sizer.Add(spanel, 0, wx.EXPAND) sizer.Add(wx.StaticLine(panel, size=(100, 2)), 0, wx.EXPAND) ds = wx.GridBagSizer(6, 4) dp = wx.Panel(panel) nrow = 0 nrow += 1 ds.Add(xTitle(dp,"Drive"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(xLabel(dp,"User" ), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp,"Dial" ), (nrow, 2), (1, 1), CEN) ds.Add(xLabel(dp,"Raw" ), (nrow, 3), (1, 1), CEN) #### nrow += 1 self.info = wx.StaticText(dp, label='', size=(55, 20), style=CEN) self.info.SetForegroundColour("Red") ds.Add(xLabel(dp,"High Limit"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp,'HLM'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp,'DHLM'), (nrow, 2), (1, 1), CEN) ds.Add(self.info, (nrow, 3), (1, 1), CEN) #### nrow += 1 ostyle = RCEN|wx.EXPAND ds.Add(xLabel(dp,"Readback"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorText(dp, 'RBV'), (nrow, 1), (1, 1), ostyle, 5) ds.Add(self.MotorText(dp, 'DRBV'), (nrow, 2), (1, 1), ostyle, 5) ds.Add(self.MotorText(dp, 'RRBV'), (nrow, 3), (1, 1), ostyle, 5) #### nrow += 1 self.drives = [self.MotorCtrl(dp, 'VAL'), self.MotorCtrl(dp, 'DVAL'), self.MotorCtrl(dp, 'RVAL')] ds.Add(xLabel(dp,"Move"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.drives[0], (nrow, 1), (1, 1), CEN) ds.Add(self.drives[1], (nrow, 2), (1, 1), CEN) ds.Add(self.drives[2], (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp,"Low Limit"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'LLM'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp, 'DLLM'), (nrow, 2), (1, 1), CEN) #### twk_sizer = wx.BoxSizer(wx.HORIZONTAL) twk_panel = wx.Panel(dp) twk_val = PVFloatCtrl(twk_panel, size=(110, -1), precision=prec) twk_val.SetPV(self.motor.PV('TWV')) twk_left = wx.Button(twk_panel, label='<', size=(30, 30)) twk_right = wx.Button(twk_panel, label='>', size=(30, 30)) twk_left.Bind(wx.EVT_BUTTON, self.OnLeftButton) twk_right.Bind(wx.EVT_BUTTON, self.OnRightButton) twk_sizer.AddMany([(twk_left, 0, CEN), (twk_val, 0, CEN), (twk_right, 0, CEN)]) set_sizer(twk_panel, twk_sizer) nrow += 1 ds.Add(xLabel(dp,"Tweak"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(twk_panel, (nrow, 1), (1, 2), wx.ALIGN_LEFT) epv = self.motor.PV('disabled') able_btns = PVEnumButtons(dp, pv=epv, orientation = wx.VERTICAL, size=(110, -1)) ds.Add(able_btns, (nrow-1, 3), (2, 1), CEN) stop_btns = PVEnumButtons(dp, pv=self.motor.PV('SPMG'), orientation = wx.VERTICAL, size=(110,-1)) ds.Add(stop_btns, (2, 4), (4, 1), wx.ALIGN_RIGHT) for attr in ('LLM', 'HLM', 'DLLM', 'DHLM'): pv = self.motor.PV(attr) pv.add_callback(self.OnLimitChange, wid=self.GetId(), attr=attr) # set_sizer(dp, ds) # ,fit=True) sizer.Add(dp, 0) #### sizer.Add(wx.StaticLine(panel, size=(100, 2)), 0, wx.EXPAND) sizer.Add((5, 5), 0) sizer.Add(xTitle(panel, 'Calibration'), 0, LCEN, 5) ds = wx.GridBagSizer(6, 5) dp = wx.Panel(panel) ds.Add(xLabel(dp, 'Mode: '), (0, 0), (1, 1), LCEN, 5) ds.Add(PVEnumButtons(dp, pv=self.motor.PV('SET'), orientation = wx.HORIZONTAL, size=(-1, -1)), (0, 1), (1, 2), wx.ALIGN_LEFT) ds.Add(xLabel(dp, 'Direction: '), (1, 0), (1, 1), LCEN, 5) ds.Add(PVEnumButtons(dp, pv=self.motor.PV('DIR'), orientation=wx.HORIZONTAL, size=(-1, -1)), (1, 1), (1, 2), wx.ALIGN_LEFT) ds.Add(xLabel(dp, 'Freeze Offset: '), (0, 4), (1, 1), LCEN, 5) ds.Add(PVEnumChoice(dp, pv=self.motor.PV('FOFF'), size=(110, -1)), (0, 5), (1, 1), CEN) ds.Add(xLabel(dp, 'Offset Value: '), (1, 4), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp,'OFF'), (1, 5), (1, 1), CEN) set_sizer(dp, ds) sizer.Add(dp, 0) ##### sizer.Add((5, 5), 0) sizer.Add(wx.StaticLine(panel, size=(100, 2)), 0, wx.EXPAND) sizer.Add((5, 5), 0) # ds = wx.GridBagSizer(6, 3) dp = wx.Panel(panel) nrow = 0 ds.Add(xTitle(dp, "Dynamics"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(xLabel(dp, "Normal" ), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Backlash" ), (nrow, 2), (1, 1), CEN) #### nrow += 1 ds.Add(xLabel(dp, "Max Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'SMAX'), (nrow, 1), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'VELO'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp, 'BVEL'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Base Speed"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'VBAS'), (nrow, 1), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Accel (s)"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'ACCL'), (nrow, 1), (1, 1), CEN) ds.Add(self.MotorCtrl(dp, 'BACC'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Backslash Distance"), (nrow, 0), (1, 2), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'BDST'), (nrow, 2), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Move Fraction"), (nrow, 0), (1, 2), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'FRAC'), (nrow, 2), (1, 1), CEN) set_sizer(dp, ds) # ,fit=True) sizer.Add(dp, 0) sizer.Add(wx.StaticLine(panel, size=(100, 2)), 0, wx.EXPAND) sizer.Add((5, 5), 0) sizer.Add(xTitle(panel, 'Resolution'), 0, LCEN, 5) ds = wx.GridBagSizer(4, 4) dp = wx.Panel(panel) nrow = 0 ds.Add(xLabel(dp, "Motor Res"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'MRES'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Encoder Res"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'ERES'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Steps / Rev"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'SREV'), (nrow, 1), (1, 1), CEN) ds.Add(xLabel(dp, "Units / Rev"), (nrow, 2), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'UREV'), (nrow, 3), (1, 1), CEN) nrow += 1 ds.Add(xLabel(dp, "Precision"), (nrow, 0), (1, 1), LCEN, 5) ds.Add(self.MotorCtrl(dp, 'PREC'), (nrow, 1), (1, 1), CEN) set_sizer(dp, ds) sizer.Add(dp, 0) sizer.Add(wx.StaticLine(panel, size=(100, 2)), 0, wx.EXPAND) for attr in self.__motor_fields: self.motor.PV(attr).add_callback(self.OnMotorEvent, wid=self.GetId(), field=attr) self.info.SetLabel('') for f in ('HLS', 'LLS', 'LVIO', 'SET'): if self.motor.get(f): wx.CallAfter(self.OnMotorEvent, pvname=self.motor.PV(f).pvname, field=f) set_sizer(panel, sizer, fit=True) panel.SetupScrolling() self.Show() self.Raise()