"""mems.instrument.client.tk.settings_frame

Contains the SettingsFrame class, which provides the UI for changing
the microscope's aperture, coordinates, lighting, and various other settings.

"""

# created 2002/01/23, AMK

__revision__ = "$Id: settings_frame.py,v 1.2 2002/02/19 22:31:34 akuchlin Exp $"

import Tkinter, Pmw

# Flag to enable dummy layout display code
LAYOUT = 0

def PmwOptionMenuSet (self, index = Pmw.SELECT):
    """Set a Pmw OptionMenu to a given value, without running the
    associated command"""
    index = self.index(index)
    text = self._itemList[index]

    var = self._menubutton.cget('textvariable')
    if var == '':
        self._menubutton.configure(text = text)
    else:
        self._menu.tk.globalsetvar(var, text)


class SettingsFrame(Tkinter.Frame):
    magnifications = ['5X', '10X', '20X', '50X', '100X']
    modes = ['Brightfield', 'Darkfield', 'ICR']
    apertures = ['1', '2', '3', '4', '5']
    
    def __init__ (self,client,*args):
        self.client = client
        
        apply(Tkinter.Frame.__init__,(self,) + args)

        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="X:")
        label.pack(side=Tkinter.LEFT)
        field = self.x_field = Tkinter.Entry(f, width=10)
        field.bind('<Return>', self.adjust_x)
        field.pack(side=Tkinter.RIGHT)
        f.pack(side=Tkinter.TOP)
        
        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="Y:")
        label.pack(side=Tkinter.LEFT)
        field = self.y_field = Tkinter.Entry(f, width=10)
        field.bind('<Return>', self.adjust_y)
        field.pack(side=Tkinter.RIGHT)
        f.pack(side=Tkinter.TOP)
        
        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="Magnification:")
        label.pack(side=Tkinter.LEFT)
        self.magnification = Tkinter.StringVar()
        self.magnification.set(self.magnifications[0])
        magf = Pmw.OptionMenu(f,
                              items = self.magnifications,
                              initialitem = 0,
                              command = self.adjust_mag)
        
        magf.pack(side=Tkinter.RIGHT)
        self.magnification_menu = magf
        f.pack(side=Tkinter.TOP)
        
        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="Mode:")
        label.pack(side=Tkinter.LEFT)
        modef = Pmw.OptionMenu(f,
                               items = self.modes,
                               initialitem = 0,
                               command = self.adjust_mode)
        
        modef.pack(side=Tkinter.RIGHT)
        self.mode_menu = modef
        f.pack(side=Tkinter.TOP)
        
        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="Aperture:")
        label.pack(side=Tkinter.LEFT)
        aperturef = Pmw.OptionMenu(f,
                                   items = self.apertures,
                                   initialitem = 0,
                                   command = self.adjust_aperture)
        
        aperturef.pack(side=Tkinter.RIGHT)
        self.aperture_menu = aperturef
        f.pack(side=Tkinter.TOP)
        
        f = Tkinter.Frame(self)
        label = Tkinter.Label(f, text="Light:")
        label.pack(side=Tkinter.LEFT)
        self.light_scale = Tkinter.Scale(f,
                                         orient = Tkinter.HORIZONTAL,
                                         from_ = 0, to=100,
#                                         command = self.adjust_light
                                        )
#        self.light_scale.bind('<Enter>', self.client.warn_about_leave)
        self.light_scale.bind('<ButtonRelease-1>', self.adjust_light)
        self.light_scale.pack(side = Tkinter.RIGHT)
        f.pack(side=Tkinter.TOP)
        
##        f = Tkinter.Frame(self)
##        label = Tkinter.Label(f, text="Angle:")
##        label.pack(side=Tkinter.LEFT)
##        self.angle_scale = Tkinter.Scale(f,
##                                         orient = Tkinter.HORIZONTAL,
##                                         from_ = -180, to=180,
##                                         command=self.adjust_angle
##                                        )
##        self.angle_scale.bind('<ButtonRelease-1>', self.adjust_angle)
##        self.angle_scale.pack(side = Tkinter.RIGHT)
##        f.pack(side=Tkinter.TOP)

    #
    # Callbacks that send commands to the microscope, called from the GUI
    #
    
    def adjust_x (self, event):
        if not self.client.state.in_control: return

        try:
            x = int(self.x_field.get())
        except ValueError:
            self.x_field.delete('0', 'end')
            self.x_field.insert('0', str(self.client.state.x))
        else:
            self.client.move(x=x)


    def adjust_y (self, event):
        if not self.client.state.in_control: return

        try:
            y = int(self.y_field.get())
        except ValueError:
            self.y_field.delete('0', 'end')
            self.y_field.insert('0', str(self.client.state.y))
        else:
            self.client.move(y=y)


    def adjust_mag (self, value):
        if not self.client.state.in_control: return

        # Convert '10X' to the integer 10
        value = int(value[:-1])
        self.client.move(magnification = value)

        
    def adjust_mode (self, value):
        if not self.client.state.in_control: return
        self.client.move(mode = value)


    def adjust_aperture (self, value):
        if not self.client.state.in_control: return
        self.client.move(aperture = int(value))


    def adjust_light (self, event):
        if not self.client.state.in_control: return
        value = self.light_scale.get()
        value = int(value)
        self.client.move(light = value)

 
    def adjust_angle (self, event):
        if not self.client.state.in_control: return
        self.client.move(angle = self.angle_scale.get())
        
    #
    # Callback used when the microscope's state has been changed
    #
    
    def update (self, state):
##        print 'Microscope physically now at:', state.x, state.y
        
        self.x_field.delete('0', 'end')
        self.x_field.insert('0', str(state.x))
        self.y_field.delete('0', 'end')
        self.y_field.insert('0', str(state.y))

        if LAYOUT:
            context = self.client.image_display.layout_context
            if context is not None:
                context.set_translate(self.client.state.x,
                                      self.client.state.y)

                # redisplay() is only called if the x/y scaling
                # changes; otherwise, the rendering context will
                # translate the elements as required.

                if (self.client.state.x_scale != context.x_scale or
                    self.client.state.y_scale != context.y_scale):
                    self.client.image_display.layout_context.set_scale(
                        x_scale = self.client.state.x_scale,
                        y_scale = self.client.state.y_scale)
                    self.client.image_display.redisplay_layout()

        PmwOptionMenuSet(self.magnification_menu, '%iX' % state.magnification)
        PmwOptionMenuSet(self.mode_menu, state.mode)
        if 1<= state.aperture < 6:
            PmwOptionMenuSet(self.aperture_menu, str(state.aperture))

        self.light_scale.set(state.light)

        if self.client.state.in_control:
            return

#        self.angle_scale.set(state.angle)

