Пример #1
0
    def __init__(self, parent, n):
        self.n = n
        wx.Frame.__init__(self, parent=parent, title="Setup")
        self.panel = wx.Panel(self)

        # Controls
        style = wx.TE_PROCESS_ENTER
        self.myLabel = ComboBox(self.panel, size=(320, -1), style=style)
        self.Value = ComboBox(self.panel, size=(320, -1), style=style)
        self.Format = ComboBox(self.panel, size=(320, -1), style=style)
        self.Test = ComboBox(self.panel, size=(320, -1), style=style)

        # Callbacks
        self.Bind(wx.EVT_COMBOBOX, self.OnLabel, self.myLabel)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnLabel, self.myLabel)
        self.Bind(wx.EVT_COMBOBOX, self.OnValue, self.Value)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnValue, self.Value)
        self.Bind(wx.EVT_COMBOBOX, self.OnFormat, self.Format)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnFormat, self.Format)
        self.Bind(wx.EVT_COMBOBOX, self.OnTest, self.Test)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnTest, self.Test)
        self.Bind(wx.EVT_SIZE, self.OnResize)

        # Layout
        self.layout = wx.BoxSizer()
        grid = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
        flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND

        label = "Label:"
        grid.Add(wx.StaticText(self.panel, label=label), flag=flag)
        grid.Add(self.myLabel, flag=flag, proportion=1)
        label = "Value:"
        grid.Add(wx.StaticText(self.panel, label=label), flag=flag)
        grid.Add(self.Value, flag=flag, proportion=1)
        label = "Format:"
        grid.Add(wx.StaticText(self.panel, label=label), flag=flag)
        grid.Add(self.Format, flag=flag, proportion=1)
        label = "Test:"
        grid.Add(wx.StaticText(self.panel, label=label), flag=flag)
        grid.Add(self.Test, flag=flag, proportion=1)
        # Leave a 10-pixel wide space around the panel.
        self.layout.Add(grid, flag=wx.EXPAND | wx.ALL, proportion=1, border=10)

        self.panel.SetSizer(self.layout)
        self.panel.Fit()
        self.Fit()

        # Intialization
        labels, values, formats, tests = [], [], [], []
        for label in checklist.defaults:
            labels += [label]
            values += [checklist.defaults[label]["value"]]
            formats += [checklist.defaults[label]["format"]]
            tests += [checklist.defaults[label]["test"]]
        self.myLabel.Items = labels
        self.Value.Items = values
        self.Format.Items = formats
        self.Test.Items = tests

        self.refresh()
    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()
Пример #3
0
    def __init__(self,parent=None):
        wx.Frame.__init__(self,parent=parent,title="Configuration")
        panel = wx.Panel(self)

        # Controls
        style = wx.TE_PROCESS_ENTER
        self.UserValue = TextCtrl(self,size=(90,-1),style=style)
        self.DialValue = TextCtrl(self,size=(90,-1),style=style)
        self.HighLimit = TextCtrl(self,size=(90,-1),style=style)
        self.LowLimit  = TextCtrl(self,size=(90,-1),style=style)
        self.Sign = ComboBox(self,size=(90,-1),style=style,
            choices=["+1","-1"])
        self.Offset = TextCtrl(self,size=(90,-1),style=style)
        self.Speed = ComboBox (self,size=(90,-1),style=style,
            choices=["1.8","15","90"])

        self.Bind (wx.EVT_TEXT_ENTER,self.OnEnter)
        self.Bind (wx.EVT_COMBOBOX,self.OnEnter)
        self.Bind (wx.EVT_TEXT_ENTER,self.OnEnterUserValue,self.UserValue)

        # Layout
        layout = wx.BoxSizer()
        grid = wx.FlexGridSizer (cols=2,hgap=5,vgap=5)
        flag = wx.ALIGN_CENTER_VERTICAL
        
        label = "User value:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.UserValue,flag=flag)
        label = "Dial value:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.DialValue,flag=flag)
        label = "High Limit:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.HighLimit,flag=flag)
        label = "Low Limit:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.LowLimit,flag=flag)
        label = "Sign:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.Sign,flag=flag)
        label = "Offset:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.Offset,flag=flag)
        label = "Speed:"
        grid.Add (wx.StaticText(self,label=label),flag=flag)
        grid.Add (self.Speed,flag=flag)
        # Leave a 10-pixel wide space around the panel.
        layout.Add (grid,flag=wx.EXPAND|wx.ALL,border=10)

        self.SetSizer(layout)
        self.Fit()

        self.update()
Пример #4
0
    def __init__(self, parent=None, name="TimingPanel"):
        wx.Frame.__init__(self, parent=parent, title=self.title)
        self.name = name
        panel = wx.Panel(self)

        from Icon import SetIcon
        SetIcon(self, self.icon)

        # Controls
        from EditableControls import ComboBox
        style = wx.TE_PROCESS_ENTER
        width = 160

        self.Prefix = ComboBox(panel, style=style, size=(width, -1))

        self.Address = wx.TextCtrl(panel,
                                   style=wx.TE_READONLY,
                                   size=(width, -1))
        self.Address.Enabled = False

        # Callbacks
        self.Bind(wx.EVT_TEXT_ENTER, self.OnEnterPrefix, self.Prefix)
        self.Bind(wx.EVT_COMBOBOX, self.OnEnterPrefix, self.Prefix)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        # Layout
        layout = wx.GridBagSizer(1, 1)
        a = wx.ALIGN_CENTRE_VERTICAL
        e = wx.EXPAND

        row = 0
        label = wx.StaticText(panel, label="EPICS Record:")
        layout.Add(label, (row, 0), flag=a)
        layout.Add(self.Prefix, (row, 1), flag=a | e)

        row += 1
        label = wx.StaticText(panel, label="IP Address (auto detect):")
        layout.Add(label, (row, 0), flag=a)
        layout.Add(self.Address, (row, 1), flag=a | e)

        # Leave a 5-pixel wide border.
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(layout, flag=wx.ALL, border=5)
        panel.SetSizer(box)
        panel.Fit()
        self.Fit()

        self.Show()
        self.refresh()
Пример #5
0
    def __init__(self,parent,n):
        self.n = n
        wx.Frame.__init__(self,parent=parent,title="Log",size=(640,240))
        from Icon import SetIcon
        SetIcon(self,"Server")
        self.panel = wx.Panel(self)

        # Controls
        from EditableControls import TextCtrl,ComboBox
        style = wx.TE_PROCESS_ENTER|wx.TE_MULTILINE|wx.TE_DONTWRAP
        self.Log = TextCtrl(self.panel,size=(-1,-1),style=style)
        self.Log.Font = wx.Font(pointSize=10,family=wx.TELETYPE,style=wx.NORMAL,
            weight=wx.NORMAL)
        self.Clear = wx.Button(self.panel,size=(-1,-1),label="Clear Log")
        self.Level = ComboBox(self.panel,size=(-1,-1),choices=self.levels)

        # Callbacks
        self.Bind(wx.EVT_TEXT_ENTER,self.OnLog,self.Log)
        self.Bind(wx.EVT_BUTTON,self.OnClear,self.Clear)
        self.Bind(wx.EVT_COMBOBOX,self.OnLevel,self.Level)
        self.Bind(wx.EVT_TEXT_ENTER,self.OnLevel,self.Level)

        # Layout
        self.layout = wx.BoxSizer(wx.VERTICAL)
        self.layout.Add(self.Log,flag=wx.ALL|wx.EXPAND,proportion=1,border=2)
        self.controls = wx.BoxSizer(wx.HORIZONTAL)
        self.layout.Add(self.controls,flag=wx.ALL|wx.EXPAND,proportion=0,border=2)
        self.controls.Add(self.Clear,flag=wx.ALL|wx.EXPAND,proportion=0,border=2)
        self.controls.Add(self.Level,flag=wx.ALL|wx.EXPAND,proportion=0,border=2)
        self.panel.SetSizer(self.layout)
        self.Layout()

        # Periodically refresh the displayed settings.
        self.values = {}
        self.Bind(wx.EVT_TIMER,self.OnUpdate)
        from threading import Thread
        self.thread = Thread(target=self.keep_updated,name=self.name)
        self.thread.daemon = True
        self.thread.start()
Пример #6
0
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Editable Controls Test")

        panel = wx.Panel(self)
        # Controls
        choices = ["Hydrogen", "Helium", "Lithium", "Beryllium"]
        self.ComboBox = ComboBox(panel,
                                 choices=choices,
                                 style=wx.TE_PROCESS_ENTER,
                                 name="Sample ComboBox")
        self.TextCtrl = TextCtrl(panel,
                                 style=wx.TE_PROCESS_ENTER,
                                 name="Sample TextCtrl")
        # Callbacks
        self.Bind(wx.EVT_TEXT_ENTER, self.OnComboBox, self.ComboBox)
        self.Bind(wx.EVT_COMBOBOX, self.OnComboBox, self.ComboBox)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnTextCtrl, self.TextCtrl)
        # Layout
        layout = wx.GridBagSizer(1, 1)
        a = wx.ALIGN_CENTRE_VERTICAL
        e = wx.EXPAND
        layout.Add(wx.StaticText(panel, label="ComboBox:"), (0, 0), flag=a)
        layout.Add(self.ComboBox, (0, 1), flag=a | e)
        layout.Add(wx.StaticText(panel, label="TextCtrl:"), (1, 0), flag=a)
        layout.Add(self.TextCtrl, (1, 1), flag=a | e)
        # Leave a 5 pixel wide border.
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(layout, flag=wx.ALL, border=5)
        panel.SetSizer(box)
        panel.Fit()
        self.Fit()
        self.Show()
        # Initialization
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.refresh, self.timer)
        self.timer.Start(1000, oneShot=True)
Пример #7
0
    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()
Пример #8
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()
Пример #9
0
    def __init__(self):
        wx.Frame.__init__(self,parent=None)
        self.Title = "Lightwave Temperature Controller DL"

        # Icon
        from Icon import SetIcon
        SetIcon(self,"Temperature Controller")

        # Controls
        panel = wx.Panel(self)
        style = wx.TE_PROCESS_ENTER
        self.SetPoint = ComboBox(panel,style=style)

        style = wx.TE_READONLY
        self.ActualTemperature = wx.TextCtrl(panel,style=style)
        self.CurrentPower = wx.TextCtrl(panel,style=style)

        self.Status = ComboBox(panel,style=style,choices=["On","Off",""])

        self.LiveCheckBox = wx.CheckBox (panel,label="Live")
        self.RefreshButton = wx.Button (panel,label="Refresh",size=(65,-1))
        self.MoreButton = wx.Button (panel,label="More...",size=(60,-1))
        self.RampButton = wx.Button (panel,label="Ramp...",size=(60,-1))
        w,h = self.MoreButton.Size
        self.AboutButton = wx.Button (panel,label="?",size=(h*1.25,h*0.75))

        # Callbacks
        self.Bind (wx.EVT_TEXT_ENTER,self.OnEnterSetPoint,self.SetPoint)
        self.Bind (wx.EVT_COMBOBOX,self.OnEnterSetPoint,self.SetPoint)

        self.Bind (wx.EVT_TEXT_ENTER,self.OnChangeStatus,self.Status)
        self.Bind (wx.EVT_COMBOBOX,self.OnChangeStatus,self.Status)

        self.Bind (wx.EVT_CHECKBOX,self.OnLive,self.LiveCheckBox)
        self.Bind (wx.EVT_BUTTON,self.OnRefresh,self.RefreshButton)
        self.Bind (wx.EVT_BUTTON,self.OnMore,self.MoreButton)
        self.Bind (wx.EVT_BUTTON,self.OnAbout,self.AboutButton)
        self.Bind (wx.EVT_BUTTON,self.OnTemperatureRamp,self.RampButton)

        # Layout
        layout = wx.GridBagSizer(1,1)
        a = wx.ALIGN_CENTRE_VERTICAL
        e = wx.EXPAND

        # Under Linux, if the version of wxWidget is 2.6 or older,
        # the label size needs to be specified to prevent line wrapping.
        # (This bug has been corrected in version 2.8).
        layout.Add (wx.StaticText(panel,label="Set Point:"),(0,0),flag=a)
        layout.Add (self.SetPoint,(0,1),flag=a|e)

        t = wx.StaticText(panel,label="Actual Temperature:")
        layout.Add (t,(1,0),flag=a)
        layout.Add (self.ActualTemperature,(1,1),flag=a|e)

        t = wx.StaticText(panel,label="Current / Power:")
        layout.Add (t,(2,0),flag=a)
        layout.Add (self.CurrentPower,(2,1),flag=a|e)

        t = wx.StaticText(panel,label="Status:")
        layout.Add (t,(3,0),flag=a)
        layout.Add (self.Status,(3,1),flag=a|e)

        buttons = wx.BoxSizer(wx.HORIZONTAL)
        buttons.Add (self.LiveCheckBox,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.RefreshButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.MoreButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.RampButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.AboutButton,flag=wx.ALIGN_CENTER_VERTICAL)

        # Leave a 5 pixel wide border.
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add (layout,flag=wx.ALL,border=5)
        box.Add (buttons,flag=wx.ALL|wx.ALIGN_CENTER_HORIZONTAL,border=5)
        panel.SetSizer(box)
        panel.Fit()
        self.Fit()

        self.Show()

        # Restore saved history.
        config_dir = wx.StandardPaths.Get().GetUserDataDir()
        config_file = config_dir+"/TemperatureController.py"
        self.config = wx.FileConfig (localFilename=config_file)
        value = self.config.Read('History')
        if value: self.history = eval(value)
        else: self.history = []
        self.update_history()
        # Initialization
        self.timer = wx.Timer(self)
        self.Bind (wx.EVT_TIMER,self.refresh,self.timer)
        self.timer.Start(1000,oneShot=True)
Пример #10
0
class Lightwave_Temperature_Controller_Panel (wx.Frame):
    """Control panel for ILX Lighwave Precision Temperature Controller"""

    def __init__(self):
        wx.Frame.__init__(self,parent=None)
        self.Title = "Lightwave Temperature Controller DL"

        # Icon
        from Icon import SetIcon
        SetIcon(self,"Temperature Controller")

        # Controls
        panel = wx.Panel(self)
        style = wx.TE_PROCESS_ENTER
        self.SetPoint = ComboBox(panel,style=style)

        style = wx.TE_READONLY
        self.ActualTemperature = wx.TextCtrl(panel,style=style)
        self.CurrentPower = wx.TextCtrl(panel,style=style)

        self.Status = ComboBox(panel,style=style,choices=["On","Off",""])

        self.LiveCheckBox = wx.CheckBox (panel,label="Live")
        self.RefreshButton = wx.Button (panel,label="Refresh",size=(65,-1))
        self.MoreButton = wx.Button (panel,label="More...",size=(60,-1))
        self.RampButton = wx.Button (panel,label="Ramp...",size=(60,-1))
        w,h = self.MoreButton.Size
        self.AboutButton = wx.Button (panel,label="?",size=(h*1.25,h*0.75))

        # Callbacks
        self.Bind (wx.EVT_TEXT_ENTER,self.OnEnterSetPoint,self.SetPoint)
        self.Bind (wx.EVT_COMBOBOX,self.OnEnterSetPoint,self.SetPoint)

        self.Bind (wx.EVT_TEXT_ENTER,self.OnChangeStatus,self.Status)
        self.Bind (wx.EVT_COMBOBOX,self.OnChangeStatus,self.Status)

        self.Bind (wx.EVT_CHECKBOX,self.OnLive,self.LiveCheckBox)
        self.Bind (wx.EVT_BUTTON,self.OnRefresh,self.RefreshButton)
        self.Bind (wx.EVT_BUTTON,self.OnMore,self.MoreButton)
        self.Bind (wx.EVT_BUTTON,self.OnAbout,self.AboutButton)
        self.Bind (wx.EVT_BUTTON,self.OnTemperatureRamp,self.RampButton)

        # Layout
        layout = wx.GridBagSizer(1,1)
        a = wx.ALIGN_CENTRE_VERTICAL
        e = wx.EXPAND

        # Under Linux, if the version of wxWidget is 2.6 or older,
        # the label size needs to be specified to prevent line wrapping.
        # (This bug has been corrected in version 2.8).
        layout.Add (wx.StaticText(panel,label="Set Point:"),(0,0),flag=a)
        layout.Add (self.SetPoint,(0,1),flag=a|e)

        t = wx.StaticText(panel,label="Actual Temperature:")
        layout.Add (t,(1,0),flag=a)
        layout.Add (self.ActualTemperature,(1,1),flag=a|e)

        t = wx.StaticText(panel,label="Current / Power:")
        layout.Add (t,(2,0),flag=a)
        layout.Add (self.CurrentPower,(2,1),flag=a|e)

        t = wx.StaticText(panel,label="Status:")
        layout.Add (t,(3,0),flag=a)
        layout.Add (self.Status,(3,1),flag=a|e)

        buttons = wx.BoxSizer(wx.HORIZONTAL)
        buttons.Add (self.LiveCheckBox,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.RefreshButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.MoreButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.RampButton,flag=wx.ALIGN_CENTER_VERTICAL)
        buttons.AddSpacer(5)
        buttons.Add (self.AboutButton,flag=wx.ALIGN_CENTER_VERTICAL)

        # Leave a 5 pixel wide border.
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add (layout,flag=wx.ALL,border=5)
        box.Add (buttons,flag=wx.ALL|wx.ALIGN_CENTER_HORIZONTAL,border=5)
        panel.SetSizer(box)
        panel.Fit()
        self.Fit()

        self.Show()

        # Restore saved history.
        config_dir = wx.StandardPaths.Get().GetUserDataDir()
        config_file = config_dir+"/TemperatureController.py"
        self.config = wx.FileConfig (localFilename=config_file)
        value = self.config.Read('History')
        if value: self.history = eval(value)
        else: self.history = []
        self.update_history()
        # Initialization
        self.timer = wx.Timer(self)
        self.Bind (wx.EVT_TIMER,self.refresh,self.timer)
        self.timer.Start(1000,oneShot=True)

    def update_history(self):
        """Update the pull down menu for the set point."""
        self.SetPoint.Clear() # clears menu
        choices = []
        for T in sorted(set(self.history)): choices += [str(T)]
        self.SetPoint.AppendItems(choices)

    def OnEnterSetPoint(self,event):
        """Called when typing Enter in the position field.
        or selecting a choice from the combo box drop down menu"""
        text = self.SetPoint.Value
        try: T = float(eval(text.replace("C","")))
        except: self.refresh(); return
        lightwave_temperature_controller.command_value = T

        self.history = self.history[-20:]+[T]
        self.update_history()

        self.refresh()

        # Make sure the history gets saved.
        config_dir = wx.StandardPaths.Get().GetUserDataDir()
        from os.path import exists
        from os import makedirs
        if not exists(config_dir): makedirs(config_dir)
        self.config.Write ('history',repr(self.history))
        self.config.Flush()

    def OnChangeStatus(self,event):
        """Called when typing Enter in the position field.
        or selecting a choice from the combo box drop down menu"""
        text = self.Status.Value
        if text == "On": lightwave_temperature_controller.enabled = True
        if text == "Off": lightwave_temperature_controller.enabled = False
        self.refresh()

    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(250,oneShot=True)

    def OnRefresh(self,event):
        """Called when refrsh button is pressed"""
        self.refresh()

    def refresh(self,event=None):
        """Update displayed values"""
        value = tofloat(lightwave_temperature_controller.command_value)
        self.SetPoint.Value = "%.3f C" % value if not isnan(value) else ""

        value = lightwave_temperature_controller.value
        self.ActualTemperature.Value = "%.3f C"%value if not isnan(value) else ""
        moving = lightwave_temperature_controller.moving
        self.ActualTemperature.ForegroundColour = (255,0,0) if moving else (0,0,0)
        ##self.ActualTemperature.BackgroundColour = (255,235,235) if moving else (255,255,255)

        current = lightwave_temperature_controller.I
        current = "%.3f A" % current if not isnan(current) else ""
        power = lightwave_temperature_controller.P
        power = "%.3f W" % power if not isnan(power) else ""
        self.CurrentPower.Value = "%s / %s" % (current,power)

        value = toint(lightwave_temperature_controller.enabled)
        if value == 0: text = "Off"
        elif value == 1: text = "On"
        else: text = ""
        self.Status.Value = text

    def OnMore(self,event):
        """Display panel with additional parameters."""
        self.parameter_panel = ParameterPanel(self)

    def OnTemperatureRamp(self,event):
        """Show panel with temperature ramp parameters"""
        self.temperature_ramp_panel = TemperatureRamp(self)

    def OnAbout(self,event):
        "Called from the Help/About"
        from os.path import basename
        from inspect import getfile
        filename = getfile(lambda x: None)
        info = basename(filename)+" "+__version__+"\n"+__doc__
        dlg = wx.MessageDialog(self,info,"About",wx.OK|wx.ICON_INFORMATION)
        dlg.CenterOnParent()
        dlg.ShowModal()
        dlg.Destroy()
    def __init__(self,
                 parent,
                 register,
                 title,
                 update=[lambda: None],
                 pre_update=None,
                 post_update=None,
                 keep_value=False,
                 attribute="offset",
                 *args,
                 **kwargs):
        """
        update: list of procedures to be called after tweeking the offset
        pre_update: procedure to be called before tweeking the offset
        """
        wx.Panel.__init__(self, parent)
        self.title = title
        self.register = register
        if update is not None: self.update = update
        if pre_update is not None: self.pre_update = pre_update
        if post_update is not None: self.post_update = post_update
        self.keep_value = keep_value
        self.attribute = attribute

        self.name = "TimingPanel.Calibration." + str(register)
        from Icon import SetIcon
        SetIcon(self, self.icon)

        # Controls
        style = wx.TE_PROCESS_ENTER
        from EditableControls import TextCtrl
        self.Current = TextCtrl(self, size=(155, -1), style=style)
        self.Decr = wx.Button(self, label="<", size=(30, -1))
        self.Incr = wx.Button(self, label=">", size=(30, -1))
        self.Set = wx.Button(self, label="Set...", size=(50, -1))

        from numpy import arange, unique
        from timing_system import round_next
        choices = 10**arange(-11.0, -2.01, 1)
        dt = self.register.stepsize
        choices = [round_next(t, dt) for t in choices]
        choices = unique(choices)
        choices = choices[choices > 0]
        from time_string import time_string
        choices = [time_string(t) for t in choices]

        from EditableControls import ComboBox
        self.Step = ComboBox(self,
                             size=(80, -1),
                             choices=choices,
                             style=style,
                             value=time_string(self.next_step(self.step)))
        # Callbacks
        self.Bind(wx.EVT_TEXT_ENTER, self.OnChange, self.Current)
        self.Bind(wx.EVT_COMBOBOX, self.OnChange, self.Current)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnStep, self.Step)
        self.Bind(wx.EVT_COMBOBOX, self.OnStep, self.Step)
        self.Bind(wx.EVT_BUTTON, self.OnDecr, self.Decr)
        self.Bind(wx.EVT_BUTTON, self.OnIncr, self.Incr)
        self.Bind(wx.EVT_BUTTON, self.OnSet, self.Set)
        # Layout
        layout = wx.GridBagSizer(1, 1)
        layout.SetEmptyCellSize((0, 0))
        av = wx.ALIGN_CENTRE_VERTICAL
        ah = wx.ALIGN_CENTRE_HORIZONTAL
        e = wx.EXPAND
        t = wx.StaticText(self, label=self.title, size=(110, -1))
        t.Wrap(110)
        layout.Add(t, (0, 0), span=(2, 1), flag=av)
        layout.Add(self.Decr, (0, 2), flag=av)
        layout.Add(self.Current, (0, 3), flag=av | e)
        layout.Add(self.Incr, (0, 4), flag=av)
        group = wx.BoxSizer(wx.HORIZONTAL)
        t = wx.StaticText(self, label="Step")
        group.Add(t, flag=av)
        group.AddSpacer((5, 5))
        group.Add(self.Step, flag=av)
        group.AddSpacer((5, 5))
        group.Add(self.Set, flag=av)
        layout.Add(group, (1, 2), span=(1, 3), flag=ah)
        self.SetSizer(layout)
        self.Fit()

        self.keep_alive()
Пример #12
0
    def __init__(self,parent,motor,refresh_period=1.0):
        wx.Panel.__init__(self,parent)
        self.motor = motor
        self.refresh_period = refresh_period
        
        # Controls
        self.MotorName = wx.StaticText(self,size=(100,-1),style=wx.ALIGN_CENTRE)
        self.background = self.MotorName.BackgroundColour
        self.Unit = wx.StaticText(self,size=(100,-1),style=wx.ALIGN_CENTRE)
        self.Value = wx.StaticText(self,size=(100,-1),style=wx.ALIGN_CENTRE)
        self.CommandValue = TextCtrl(self,size=(100,-1),style=wx.TE_PROCESS_ENTER)
        self.TweakValue = ComboBox(self,size=(50,-1),style=wx.TE_PROCESS_ENTER)

        left = wx.ArtProvider.GetBitmap(wx.ART_GO_BACK)
        right = wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD)

        self.TweakDownButton = wx.BitmapButton(self,bitmap=left)
        self.TweakUpButton = wx.BitmapButton(self,bitmap=right)

        self.EnableButton = wx.ToggleButton(self,label="Enabled",size=(70,-1))
        w,h = self.EnableButton.Size
        self.HomeButton = wx.ToggleButton(self,label="Homed",size=(w,h))

        self.Bind(wx.EVT_CONTEXT_MENU,self.OnConfigureMenu,self.MotorName)
        self.Bind(wx.EVT_CONTEXT_MENU,self.OnConfigureMenu,self.Unit)
        self.Bind(wx.EVT_CONTEXT_MENU,self.OnSetValueMenu,self.Value)
        self.Bind(wx.EVT_TEXT_ENTER,self.OnEnterCommandValue,self.CommandValue)
        self.Bind(wx.EVT_CONTEXT_MENU,self.OnSetValueMenu,self.CommandValue)
        self.Bind(wx.EVT_COMBOBOX,self.OnEnterTweakValue,self.TweakValue)
        self.Bind(wx.EVT_TEXT_ENTER,self.OnEnterTweakValue,self.TweakValue)
        self.Bind(wx.EVT_CONTEXT_MENU,self.OnTweakMenu,self.TweakValue)
        self.Bind(wx.EVT_BUTTON,self.OnTweakDown,self.TweakDownButton)
        self.Bind(wx.EVT_BUTTON,self.OnTweakUp,self.TweakUpButton)
        self.Bind(wx.EVT_TOGGLEBUTTON,self.OnEnable,self.EnableButton)
        self.Bind(wx.EVT_TOGGLEBUTTON,self.OnHome,self.HomeButton)

        # Layout
        controls = wx.GridBagSizer(1,1)
        a = wx.ALIGN_CENTRE_HORIZONTAL|wx.ALIGN_CENTRE_VERTICAL
        e = wx.EXPAND

        controls.Add(self.MotorName,(0,0),span=(1,3),flag=a|e)
        controls.Add(self.Unit,(1,0),span=(1,3),flag=a|e)
        controls.Add(self.Value,(2,0),span=(1,3),flag=a|e)
        controls.Add(self.CommandValue,(3,0),span=(1,3),flag=a|e)
        controls.Add(self.TweakDownButton,(4,0),flag=a|e)
        controls.Add(self.TweakValue,(4,1),flag=a|e)
        controls.Add(self.TweakUpButton,(4,2),flag=a|e)
        controls.Add(self.EnableButton,(5,1),flag=a)
        controls.Add(self.HomeButton,(6,1),flag=a)

        # Leave a 10 pixel wide border.
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(controls,flag=wx.ALL,border=5)
        self.SetSizer(box)
        self.Fit()

        # Initialization
        self.CommandValue.Enabled = False
        self.TweakDownButton.Enabled = False
        self.TweakUpButton.Enabled = False
        self.EnableButton.Enabled = False
        self.HomeButton.Enabled = False

        # Refresh
        self.attributes = ["name","unit","value","command_value",
            "moving","enabled","homed","homing"]
        from numpy import nan
        self.values = dict([(n,nan) for n in self.attributes])
        self.values["name"] = ""
        self.values["unit"] = ""
        self.old_values = {}
        
        from threading import Thread
        self.refresh_thread = Thread(target=self.refresh_background,
            name=self.name+".refresh")
        self.refreshing = False

        from wx.lib.newevent import NewEvent
        self.EVT_THREAD = NewEvent()[1]
        self.Bind(self.EVT_THREAD,self.OnUpdate)
        self.thread = Thread(target=self.keep_updated,name=self.name)
        self.thread.start()
    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()
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 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()