class LaserAttenuatorPanel(wx.Frame): """variable laser attenuator control panel""" def __init__(self, trans, title="Laser Attenuator"): """trans: attenautor objects""" self.trans = trans wx.Frame.__init__(self, parent=None, title=title) # Highlight an Edit control if its contents have been modified # but not applied yet by hitting the Enter key. self.edited = wx.Colour(255, 255, 220) panel = wx.Panel(self) # Controls style = wx.TE_PROCESS_ENTER size = (100, -1) choices = ["0"] self.Angle = ComboBox(panel, choices=choices, size=size, style=style) choices = ["1", "0.5", "0.2", "0.1", "0.05", "0.02", "0.01"] self.Transmission = ComboBox(panel, choices=choices, size=size, style=style) self.LiveCheckBox = wx.CheckBox(panel, label="Live") self.RefreshButton = wx.Button(panel, label="Refresh") # Callbacks self.Angle.Bind(wx.EVT_CHAR, self.OnEditAngle) self.Bind(wx.EVT_TEXT_ENTER, self.OnEnterAngle, self.Angle) self.Bind(wx.EVT_COMBOBOX, self.OnEnterAngle, self.Angle) self.Transmission.Bind(wx.EVT_CHAR, self.OnEditTransmission) self.Bind(wx.EVT_TEXT_ENTER, self.OnEnterTransmission, self.Transmission) self.Bind(wx.EVT_COMBOBOX, self.OnEnterTransmission, self.Transmission) self.Bind(wx.EVT_CHECKBOX, self.OnLive, self.LiveCheckBox) self.Bind(wx.EVT_BUTTON, self.OnRefresh, self.RefreshButton) # Layout layout = wx.GridBagSizer(1, 1) a = wx.ALIGN_CENTRE_VERTICAL e = wx.EXPAND # Specified a label length to prevent line wrapping. # This is a bug in the Linux version of wxPython 2.6, fixed in 2.8. size = (160, -1) t = wx.StaticText(panel, label="Angle [deg]:", size=size) layout.Add(t, (0, 0), flag=a) layout.Add(self.Angle, (0, 1), flag=a | e) t = wx.StaticText(panel, label="Transmission:", size=size) layout.Add(t, (1, 0), flag=a) layout.Add(self.Transmission, (1, 1), flag=a | e) # Leave a 10 pixel wide border. box = wx.BoxSizer(wx.VERTICAL) box.Add(layout, flag=wx.ALL, border=5) buttons = wx.BoxSizer(wx.HORIZONTAL) buttons.Add(self.LiveCheckBox, flag=wx.ALIGN_CENTER_VERTICAL) buttons.AddSpacer((5, 5)) buttons.Add(self.RefreshButton, flag=wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, border=5) box.Add(buttons, flag=wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, border=5) panel.SetSizer(box) panel.Fit() self.Fit() self.Show() # Initialization self.refresh() def refresh(self): """Updates the controls with current values""" self.Angle.SetValue("%.1f" % self.trans.angle) self.Transmission.SetValue("%.3g" % self.trans.value) def OnLive(self, event): """Called when the 'Live' checkbox is either checked or unchecked.""" self.RefreshButton.Enabled = not self.LiveCheckBox.Value if self.LiveCheckBox.Value == True: self.keep_alive() def keep_alive(self, event=None): """Periodically refresh te displayed settings (every second).""" if self.LiveCheckBox.Value == False: return self.refresh() self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.keep_alive, self.timer) self.timer.Start(1000, oneShot=True) def OnEditAngle(self, event): "Called when typing in the position field." self.Angle.SetBackgroundColour(self.edited) # Pass this event on to further event handlers bound to this event. # Otherwise, the typed text does not appear in the window. event.Skip() def OnEnterAngle(self, event): "Called when typing Enter in the position field." self.Angle.SetBackgroundColour(wx.WHITE) text = self.Angle.GetValue() try: value = float(eval(text)) except: self.refresh() return self.trans.angle = value self.refresh() def OnEditTransmission(self, event): "Called when typing in the position field." self.Transmission.SetBackgroundColour(self.edited) # Pass this event on to further event handlers bound to this event. # Otherwise, the typed text does not appear in the window. event.Skip() def OnEnterTransmission(self, event): "Called when typing Enter in the position field." self.Transmission.SetBackgroundColour(wx.WHITE) text = self.Transmission.GetValue() try: value = float(eval(text)) except: self.refresh() return self.trans.value = value self.refresh() def OnRefresh(self, event=None): "Check whether the network connection is OK." # Reset pending status of entered new position self.Angle.SetBackgroundColour(wx.WHITE) self.Transmission.SetBackgroundColour(wx.WHITE) self.refresh()
class DiffractometerSetup (wx.Dialog): """Configures Diffractometer""" def __init__ (self,parent=None): wx.Dialog.__init__(self,parent,-1,"Diffractometer Setup") # Controls style = wx.TE_PROCESS_ENTER self.Configuration = ComboBox (self,size=(175,-1),style=style, choices=["BioCARS Diffractometer","NIH Diffractometer","LCLS Diffractometer"]) self.Apply = wx.Button(self,label="Apply",size=(75,-1)) self.Save = wx.Button(self,label="Save",size=(75,-1)) self.X = ComboBox (self,size=(160,-1),style=style, choices=["GonX","SampleX"]) self.Y = ComboBox (self,size=(160,-1),style=style, choices=["GonY","SampleY"]) self.Z = ComboBox (self,size=(160,-1),style=style, choices=["GonZ","SampleZ"]) self.Phi = ComboBox (self,size=(160,-1),style=style, choices=["Phi","SamplePhi"]) self.XYType = ComboBox (self,size=(160,-1),style=style, choices=["rotating","stationary"]) self.RotationCenterX = TextCtrl (self,size=(160,-1),style=style) self.RotationCenterY = TextCtrl (self,size=(160,-1),style=style) self.XScale = TextCtrl (self,size=(160,-1),style=style) self.YScale = TextCtrl (self,size=(160,-1),style=style) self.ZScale = TextCtrl (self,size=(160,-1),style=style) self.PhiScale = TextCtrl (self,size=(160,-1),style=style) self.Bind (wx.EVT_TEXT_ENTER,self.OnEnter) self.Bind (wx.EVT_COMBOBOX,self.OnEnter) self.Configuration.Bind (wx.EVT_COMBOBOX,self.OnSelectConfiguration) self.Save.Bind (wx.EVT_BUTTON,self.OnSave) self.Apply.Bind (wx.EVT_BUTTON,self.OnApply) # Layout layout = wx.BoxSizer() vbox = wx.BoxSizer(wx.VERTICAL) config = wx.BoxSizer(wx.HORIZONTAL) flag = wx.ALIGN_CENTER config.Add (self.Configuration,flag=flag) config.Add (self.Apply,flag=flag) config.Add (self.Save,flag=flag) vbox.Add (config,flag=wx.EXPAND|wx.ALL) grid = wx.FlexGridSizer(cols=2,hgap=5,vgap=5) flag = wx.ALIGN_CENTER_VERTICAL label = "X Translation:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.X,flag=flag) label = "Y Translation:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.Y,flag=flag) label = "Z Translation:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.Z,flag=flag) label = "Phi Rotation:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.Phi,flag=flag) label = "XY Translation Type:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.XYType,flag=flag) label = "Rotation Center X:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.RotationCenterX,flag=flag) label = "Rotation Center Y:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.RotationCenterY,flag=flag) label = "X Scale Factor:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.XScale,flag=flag) label = "Y Scale Factor:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.YScale,flag=flag) label = "Z Scale Factor:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.ZScale,flag=flag) label = "Phi Scale Factor:" grid.Add (wx.StaticText(self,label=label),flag=flag) grid.Add (self.PhiScale,flag=flag) # Leave a 10-pixel wide space around the panel. vbox.Add (grid,flag=wx.EXPAND|wx.ALL) layout.Add (vbox,flag=wx.EXPAND|wx.ALL,border=10) self.SetSizer(layout) self.Fit() self.Show() self.update() def update(self,Event=0): self.X.Value = diffractometer.x_motor_name self.Y.Value = diffractometer.y_motor_name self.Z.Value = diffractometer.z_motor_name self.Phi.Value = diffractometer.phi_motor_name self.XYType.Value = \ "rotating" if diffractometer.xy_rotating else "stationary" self.RotationCenterX.Value = "%.4f mm" % \ diffractometer.rotation_center_x self.RotationCenterY.Value = "%.4f mm" % \ diffractometer.rotation_center_y self.XScale.Value = str(diffractometer.x_scale) self.YScale.Value = str(diffractometer.y_scale) self.ZScale.Value = str(diffractometer.z_scale) self.PhiScale.Value = str(diffractometer.phi_scale) self.Configuration.Value = self.current_configuration # Reschedule "update". self.update_timer = wx.Timer(self) self.Bind (wx.EVT_TIMER,self.update,self.update_timer) self.update_timer.Start(2000,oneShot=True) def get_current_configuration(self): from DB import dbget return dbget("diffractometer.current_configuration") def set_current_configuration(self,value): from DB import dbput dbput("diffractometer.current_configuration",value) current_configuration = property(get_current_configuration, set_current_configuration) def OnEnter(self,event): diffractometer.x_motor_name = str(self.X.Value) diffractometer.y_motor_name = str(self.Y.Value) diffractometer.z_motor_name = str(self.Z.Value) diffractometer.phi_motor_name = str(self.Phi.Value) diffractometer.xy_rotating = True if self.XYType.Value == "rotating" else False value = self.RotationCenterX.Value.replace("mm","") try: diffractometer.rotation_center_x = float(eval(value)) except: pass value = self.RotationCenterY.Value.replace("mm","") try: diffractometer.rotation_center_y = float(eval(value)) except: pass try: diffractometer.x_scale = float(eval(self.XScale.Value)) except: pass try: diffractometer.y_scale = float(eval(self.YScale.Value)) except: pass try: diffractometer.z_scale = float(eval(self.ZScale.Value)) except: pass try: diffractometer.phi_scale = float(eval(self.PhiScale.Value)) except: pass self.update() def OnSelectConfiguration(self,event): self.current_configuration = str(self.Configuration.Value) ##print "current configuration: % r" % self.current_configuration def OnEnterConfiguration(self,event): self.current_configuration = str(self.Configuration.Value) ##print "current configuration: % r" % self.current_configuration def OnSave(self,event): ##print "save_configuration %r" % self.current_configuration save_configuration(self.current_configuration) def OnApply(self,event): ##print "load_configuration %r" % self.current_configuration load_configuration(self.current_configuration) self.update()
class ConfigurationPanel(wx.Frame): """Manage settings for different locations / instruments""" from setting import setting size = setting("size",(600,800)) def __init__ (self,parent=None): wx.Frame.__init__(self,parent,title="Configurations",size=self.size) from Icon import SetIcon SetIcon(self,"Tool") # Controls self.panel = wx.lib.scrolledpanel.ScrolledPanel(self) style = wx.TE_PROCESS_ENTER self.Configuration = ComboBox(self.panel,size=(240,-1),style=style) self.SavedToCurrent = wx.Button(self.panel,label=" Saved ->",size=(160,-1)) self.CurrentToSaved = wx.Button(self.panel,label="<- Current ",size=(160,-1)) N = len(configurations.parameters.descriptions) self.Descriptions = [TextCtrl(self.panel,size=(240,-1),style=style) for i in range(0,N)] self.CurrentValues = [ComboBox(self.panel,size=(160,-1),style=style) for i in range(0,N)] self.SavedValues = [ComboBox(self.panel,size=(160,-1),style=style) for i in range(0,N)] # Callbacks self.Configuration.Bind(wx.EVT_TEXT_ENTER,self.OnConfiguration) self.Configuration.Bind(wx.EVT_COMBOBOX,self.OnConfiguration) self.SavedToCurrent.Bind(wx.EVT_BUTTON,self.OnSavedToCurrent) self.CurrentToSaved.Bind(wx.EVT_BUTTON,self.OnCurrentToSaved) self.Bind(wx.EVT_TEXT_ENTER,self.OnEnter) self.Bind(wx.EVT_COMBOBOX,self.OnEnter) self.Bind(wx.EVT_SIZE,self.OnResize) ##self.Bind(wx.EVT_CLOSE,self.OnClose) # Layout layout = wx.BoxSizer() grid = wx.FlexGridSizer(cols=3,hgap=2,vgap=2) flag = wx.ALIGN_LEFT grid.Add (self.Configuration,flag=flag) grid.Add (self.SavedToCurrent,flag=flag) grid.Add (self.CurrentToSaved,flag=flag) for i in range(0,N): grid.Add (self.Descriptions[i],flag=flag) grid.Add (self.SavedValues[i],flag=flag) grid.Add (self.CurrentValues[i],flag=flag) # Leave a 10-pixel wide space around the panel. border_box = wx.BoxSizer(wx.VERTICAL) border_box.Add (grid,flag=wx.EXPAND|wx.ALL) layout.Add (border_box,flag=wx.EXPAND|wx.ALL,border=10) self.panel.SetSizer(layout) ##self.panel.SetAutoLayout(True) self.panel.SetupScrolling() ##self.panel.Fit() ##self.Fit() self.Show() self.keep_alive() def keep_alive(self,event=None): """Periodically refresh the displayed settings (every second).""" self.refresh() self.timer = wx.Timer(self) self.Bind (wx.EVT_TIMER,self.keep_alive,self.timer) self.timer.Start(1000,oneShot=True) def refresh(self,Event=None): """Update all controls""" configuration_names = configurations.configuration_names if not self.Configuration.Value in configuration_names: self.Configuration.Value = configurations.current_configuration self.Configuration.Items = configuration_names configuration_name = self.Configuration.Value ##self.SavedLabel.Label = configuration_name descriptions = configurations.parameters.descriptions values = [str(v) for v in configurations[""]] saved_values = [str(v) for v in configurations[configuration_name]] choices = [[str(c) for c in l] for l in configurations.choices] agree = [v1 == v2 for v1,v2 in zip(values,saved_values)] N = len(descriptions) for i in range(0,N): self.Descriptions[i].Value = descriptions[i] self.SavedValues[i].Value = saved_values[i] self.SavedValues[i].Items = choices[i] self.SavedValues[i].BackgroundColour = (255,255,255) if agree[i] else (255,190,190) self.SavedValues[i].ForegroundColour = (100,100,100) self.CurrentValues[i].Value = values[i] self.CurrentValues[i].Items = choices[i] self.Configuration. BackgroundColour = (255,255,255) if all(agree) else (255,190,190) self.SavedToCurrent.BackgroundColour = (255,255,255) if all(agree) else (255,190,190) self.SavedToCurrent.Enabled = not all(agree) self.CurrentToSaved.Enabled = not all(agree) def OnConfiguration(self,event): """Called if the configration is switched""" self.refresh() def OnSavedToCurrent(self,event): """Make the named saved configuration active""" name = self.Configuration.Value configurations[""] = configurations[name] self.refresh() def OnCurrentToSaved(self,event): """Save the active configuration under the selected name""" name = self.Configuration.Value configurations[name] = configurations[""] self.refresh() def OnEnter(self,event): """Called it a entry is modified""" N = len(configurations.parameters.descriptions) name = self.Configuration.Value configurations[name] = [eval(self.SavedValues [i].Value) for i in range(0,N)] configurations[""] = [eval(self.CurrentValues[i].Value) for i in range(0,N)] self.refresh() def OnResize(self,event): event.Skip() self.size = tuple(self.Size) def OnClose(self,event): """Handle Window closed event""" self.Destroy()