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()
Exemple #2
0
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()