Package VisionEgg :: Package PyroApps :: Module ScreenPositionGUI |
[frames] | no frames]

# Source Code for Module VisionEgg.PyroApps.ScreenPositionGUI

      1  #!/usr/bin/env python
      2  #
      3  # The Vision Egg: ScreenPositionGUI
      4  #
      5  # Copyright (C) 2001-2003 Andrew Straw.
      6  # Author: Andrew Straw <astraw@users.sourceforge.net>
      7  # URL: <http://www.visionegg.org/>
      8  #
      9  # Distributed under the terms of the GNU Lesser General Public License
     10  # (LGPL). See LICENSE.TXT that came with this file.
     11  #
     12  # $Id$
     13
     14  """Handle 3D perspective projection (client-side)"""
     15
     16  import sys, os, pickle, math, string
     17  import Tkinter, tkFileDialog
     18  import Pyro.core
     19  import VisionEgg.PyroClient
     20  import StringIO
     21
     22  __version__ = VisionEgg.release_name
     23  __cvs__ = string.split('$Revision$')[1]
     24  __date__ = string.join(string.split('$Date$')[1:3], ' ')
     25  __author__ = 'Andrew Straw <astraw@users.sourceforge.net>'
     26
     27 -class ScreenPositionParameters:
     28 -    def __init__(self):
     29
     30          # frustum (initial values - view portion of unit sphere)
     31          self.left = -0.2
     32          self.right = 0.2
     33          self.top = 0.2
     34          self.bottom = -0.2
     35          self.near = 0.2
     36          self.far = 20.0
     37
     38          # position/orientation
     39          self.eye = (0.0, 0.0, 0.0) # observer position
     40          self.center = (0.0, 0.0, -1.0) # center of gaze
     41          self.up = (0.0, 1.0, 0.0) # up vector
     42
     43 -class CallbackEntry(Tkinter.Entry):
     44 -    def __init__(self,master=None,callback=None,**kw):
     45          Tkinter.Entry.__init__(self,master, **kw)
     46          self.bind('<Return>',callback)
     47          self.bind('<Tab>',callback)
     48
     49 -class ScreenPositionControlFrame(Tkinter.Frame):
     50 -    def __init__(self, master=None, auto_connect=0, server_hostname='', server_port=7766, **kw):
     51          Tkinter.Frame.__init__(self,master,**kw)
     52          self.pyro_client = None
     53          self.entry_width = 10
     54          self.connected = 0
     55          self.meta_params = ScreenPositionParameters()
     56          self.loopable_variables = {}
     57
     58          row = 0
     59          Tkinter.Label(self,
     60                        text="3D Perspective Calibration",
     61                        font=("Helvetica",12,"bold")).grid(row=row,column=0,columnspan=2)
     62
     63          row += 1
     64          Tkinter.Label(self,
     65                        text="This dialog allows you to enter acheive "+\
     66                        "the proper perspective distortion for 3D scenes."
     67                        ).grid(row=row,column=0,columnspan=2)
     68
     69          if not auto_connect:
     70              row += 1
     71              # let columns expand
     72              connected_frame = Tkinter.Frame(self)
     73              connected_frame.grid(row=row,column=0,columnspan=2,sticky=Tkinter.W+Tkinter.E)
     74              connected_frame.columnconfigure(0,weight=1)
     75              connected_frame.columnconfigure(1,weight=1)
     76              connected_frame.columnconfigure(2,weight=1)
     77
     78              self.connected_label = Tkinter.Label(connected_frame,text="Server status: Not connected")
     79              self.connected_label.grid(row=0,column=0)
     80              Tkinter.Button(connected_frame,text="Connect",command=self.connect).grid(row=0,column=1)
     81              Tkinter.Button(connected_frame,text="Quit server",command=self.quit_server).grid(row=0,column=2)
     82
     83          row += 1
     84          param_frame = Tkinter.Frame(self)
     85          param_frame.grid(row=row,column=0,sticky=Tkinter.N)
     86          param_frame.columnconfigure(0,weight=1)
     87          param_frame.columnconfigure(1,weight=1)
     88
     89          pf_row = 0
     90          frustum_frame = Tkinter.Frame(param_frame)
     91          frustum_frame.grid(row=pf_row,column=0,columnspan=2,ipady=5)
     92
     93          ff_row = 0
     94          Tkinter.Label(frustum_frame,
     95                        text="Viewing volume size",
     96                        font=("Helvetica",12,"bold")).grid(row=ff_row,column=0,columnspan=3,ipady=5)
     97
     98          ff_row += 1
     99          Tkinter.Label(frustum_frame,text="Left:").grid(row=ff_row,column=0)
    100          self.left_tk_var = Tkinter.DoubleVar()
    101          self.left_tk_var.set(self.meta_params.left)
    102          CallbackEntry(frustum_frame,
    103                        self.send_values,
    104                        width=self.entry_width,
    105                        textvariable=self.left_tk_var).grid(row=ff_row,column=1)
    106
    107          ff_row += 1
    108          Tkinter.Label(frustum_frame,text="Right:").grid(row=ff_row,column=0)
    109          self.right_tk_var = Tkinter.DoubleVar()
    110          self.right_tk_var.set(self.meta_params.right)
    111          CallbackEntry(frustum_frame,
    112                        self.send_values,
    113                        width=self.entry_width,
    114                        textvariable=self.right_tk_var).grid(row=ff_row,column=1)
    115
    116          ff_row += 1
    117          Tkinter.Label(frustum_frame,text="Top:").grid(row=ff_row,column=0)
    118          self.top_tk_var = Tkinter.DoubleVar()
    119          self.top_tk_var.set(self.meta_params.top)
    120          CallbackEntry(frustum_frame,
    121                        self.send_values,
    122                        width=self.entry_width,
    123                        textvariable=self.top_tk_var).grid(row=ff_row,column=1)
    124
    125          ff_row += 1
    126          Tkinter.Label(frustum_frame,text="Bottom:").grid(row=ff_row,column=0)
    127          self.bottom_tk_var = Tkinter.DoubleVar()
    128          self.bottom_tk_var.set(self.meta_params.bottom)
    129          CallbackEntry(frustum_frame,
    130                        self.send_values,
    131                        width=self.entry_width,
    132                        textvariable=self.bottom_tk_var).grid(row=ff_row,column=1)
    133
    134          ff_row += 1
    135          Tkinter.Label(frustum_frame,text="Near:").grid(row=ff_row,column=0)
    136          self.near_tk_var = Tkinter.DoubleVar()
    137          self.near_tk_var.set(self.meta_params.near)
    138          CallbackEntry(frustum_frame,
    139                        self.send_values,
    140                        width=self.entry_width,
    141                        textvariable=self.near_tk_var).grid(row=ff_row,column=1)
    142
    143          ff_row += 1
    144          Tkinter.Label(frustum_frame,text="Far:").grid(row=ff_row,column=0)
    145          self.far_tk_var = Tkinter.DoubleVar()
    146          self.far_tk_var.set(self.meta_params.far)
    147          CallbackEntry(frustum_frame,
    148                        self.send_values,
    149                        width=self.entry_width,
    150                        textvariable=self.far_tk_var).grid(row=ff_row,column=1)
    151
    152          # quick frustum frame
    153          qf_frame = Tkinter.Frame(frustum_frame)
    154          qf_frame.grid(row=1,column=2,rowspan=ff_row)
    155
    156          qf_row = 0
    157          Tkinter.Button(qf_frame,text="Taller",command=self.frustum_taller).grid(row=qf_row,column=0,columnspan=2)
    158          qf_row += 1
    159          Tkinter.Button(qf_frame,text="Narrower",command=self.frustum_narrower).grid(row=qf_row,column=0)
    160          Tkinter.Button(qf_frame,text="Wider",command=self.frustum_wider).grid(row=qf_row,column=1)
    161          qf_row += 1
    162          Tkinter.Button(qf_frame,text="Shorter",command=self.frustum_shorter).grid(row=qf_row,column=0,columnspan=2)
    163
    164          qf_row = 0
    165          Tkinter.Button(qf_frame,text="Up",command=self.frustum_up).grid(row=qf_row,column=2,columnspan=2)
    166          qf_row += 1
    167          Tkinter.Button(qf_frame,text="Left",command=self.frustum_left).grid(row=qf_row,column=2)
    168          Tkinter.Button(qf_frame,text="Right",command=self.frustum_right).grid(row=qf_row,column=3)
    169          qf_row += 1
    170          Tkinter.Button(qf_frame,text="Down",command=self.frustum_down).grid(row=qf_row,column=2,columnspan=2)
    171
    172          pf_row += 1
    173          lookat_frame = Tkinter.Frame(param_frame)
    174          lookat_frame.grid(row=pf_row,column=0,columnspan=2,ipady=5)
    175
    176          la_row = 0
    177          Tkinter.Label(lookat_frame,
    178                        text="Viewing volume orientation",
    179                        font=("Helvetica",12,"bold")).grid(row=la_row,column=0,columnspan=3,ipady=5)
    180
    181          la_row += 1
    182          Tkinter.Label(lookat_frame,text="eye X:").grid(row=la_row,column=0)
    183          self.eye_x_tk_var = Tkinter.DoubleVar()
    184          self.eye_x_tk_var.set(self.meta_params.eye[0])
    185          CallbackEntry(lookat_frame,
    186                        self.send_values,
    187                        width=self.entry_width,
    188                        textvariable=self.eye_x_tk_var).grid(row=la_row,column=1)
    189
    190          la_row += 1
    191          Tkinter.Label(lookat_frame,text="eye Y:").grid(row=la_row,column=0)
    192          self.eye_y_tk_var = Tkinter.DoubleVar()
    193          self.eye_y_tk_var.set(self.meta_params.eye[1])
    194          CallbackEntry(lookat_frame,
    195                        self.send_values,
    196                        width=self.entry_width,
    197                        textvariable=self.eye_y_tk_var).grid(row=la_row,column=1)
    198
    199          la_row += 1
    200          Tkinter.Label(lookat_frame,text="eye Z:").grid(row=la_row,column=0)
    201          self.eye_z_tk_var = Tkinter.DoubleVar()
    202          self.eye_z_tk_var.set(self.meta_params.eye[2])
    203          CallbackEntry(lookat_frame,
    204                        self.send_values,
    205                        width=self.entry_width,
    206                        textvariable=self.eye_z_tk_var).grid(row=la_row,column=1)
    207
    208          la_row += 1
    209          Tkinter.Label(lookat_frame,text="look at X:").grid(row=la_row,column=0)
    210          self.center_x_tk_var = Tkinter.DoubleVar()
    211          self.center_x_tk_var.set(self.meta_params.center[0])
    212          CallbackEntry(lookat_frame,
    213                        self.send_values,
    214                        width=self.entry_width,
    215                        textvariable=self.center_x_tk_var).grid(row=la_row,column=1)
    216
    217          quick_la_frame = Tkinter.Frame(lookat_frame)
    218          quick_la_frame.grid(row=la_row,column=2,rowspan=3)
    219          qla_row = 0
    220          Tkinter.Button(quick_la_frame,text="Look at az -",command=self.az_decrease).grid(row=qla_row,column=0)
    221          Tkinter.Button(quick_la_frame,text="Look at az +",command=self.az_increase).grid(row=qla_row,column=1)
    222          self.look_at_az_str = Tkinter.StringVar()
    223          Tkinter.Label(quick_la_frame,textvariable=self.look_at_az_str).grid(row=qla_row,column=2)
    224
    225          qla_row += 1
    226          Tkinter.Button(quick_la_frame,text="Look at el -",command=self.el_decrease).grid(row=qla_row,column=0)
    227          Tkinter.Button(quick_la_frame,text="Look at el +",command=self.el_increase).grid(row=qla_row,column=1)
    228          self.look_at_el_str = Tkinter.StringVar()
    229          Tkinter.Label(quick_la_frame,textvariable=self.look_at_el_str).grid(row=qla_row,column=2)
    230
    231          az,el = self.get_az_el(self.meta_params.center)
    232          self.look_at_az_str.set("%.1f"%az)
    233          self.look_at_el_str.set("%.1f"%el)
    234
    235          la_row += 1
    236          Tkinter.Label(lookat_frame,text="look at Y:").grid(row=la_row,column=0)
    237          self.center_y_tk_var = Tkinter.DoubleVar()
    238          self.center_y_tk_var.set(self.meta_params.center[1])
    239          CallbackEntry(lookat_frame,
    240                        self.send_values,
    241                        width=self.entry_width,
    242                        textvariable=self.center_y_tk_var).grid(row=la_row,column=1)
    243
    244          la_row += 1
    245          Tkinter.Label(lookat_frame,text="look at Z:").grid(row=la_row,column=0)
    246          self.center_z_tk_var = Tkinter.DoubleVar()
    247          self.center_z_tk_var.set(self.meta_params.center[2])
    248          CallbackEntry(lookat_frame,
    249                        self.send_values,
    250                        width=self.entry_width,
    251                        textvariable=self.center_z_tk_var).grid(row=la_row,column=1)
    252
    253          la_row += 1
    254          Tkinter.Label(lookat_frame,text="up X:").grid(row=la_row,column=0)
    255          self.up_x_tk_var = Tkinter.DoubleVar()
    256          self.up_x_tk_var.set(self.meta_params.up[0])
    257          CallbackEntry(lookat_frame,
    258                        self.send_values,
    259                        width=self.entry_width,
    260                        textvariable=self.up_x_tk_var).grid(row=la_row,column=1)
    261
    262          quick_up_frame = Tkinter.Frame(lookat_frame)
    263          quick_up_frame.grid(row=la_row,column=2,rowspan=3)
    264          qup_row = 0
    265          Tkinter.Button(quick_up_frame,text="Up az -",command=self.up_az_decrease).grid(row=qup_row,column=0)
    266          Tkinter.Button(quick_up_frame,text="Up az +",command=self.up_az_increase).grid(row=qup_row,column=1)
    267          self.up_az_str = Tkinter.StringVar()
    268          Tkinter.Label(quick_up_frame,textvariable=self.up_az_str).grid(row=qup_row,column=2)
    269          qup_row += 1
    270          Tkinter.Button(quick_up_frame,text="Up el -",command=self.up_el_decrease).grid(row=qup_row,column=0)
    271          Tkinter.Button(quick_up_frame,text="Up el +",command=self.up_el_increase).grid(row=qup_row,column=1)
    272          self.up_el_str = Tkinter.StringVar()
    273          Tkinter.Label(quick_up_frame,textvariable=self.up_el_str).grid(row=qup_row,column=2)
    274
    275          az,el = self.get_az_el(self.meta_params.up)
    276          self.up_az_str.set("%.1f"%az)
    277          self.up_el_str.set("%.1f"%el)
    278
    279          la_row += 1
    280          Tkinter.Label(lookat_frame,text="up Y:").grid(row=la_row,column=0)
    281          self.up_y_tk_var = Tkinter.DoubleVar()
    282          self.up_y_tk_var.set(self.meta_params.up[1])
    283          CallbackEntry(lookat_frame,
    284                        self.send_values,
    285                        width=self.entry_width,
    286                        textvariable=self.up_y_tk_var).grid(row=la_row,column=1)
    287
    288          la_row += 1
    289          Tkinter.Label(lookat_frame,text="up Z:").grid(row=la_row,column=0)
    290          self.up_z_tk_var = Tkinter.DoubleVar()
    291          self.up_z_tk_var.set(self.meta_params.up[2])
    292          CallbackEntry(lookat_frame,
    293                        self.send_values,
    294                        width=self.entry_width,
    295                        textvariable=self.up_z_tk_var).grid(row=la_row,column=1)
    296
    297          row += 1
    298          button_row_frame = Tkinter.Frame(self)
    299          button_row_frame.grid(row=row,column=0,ipady=5)
    300          Tkinter.Label(button_row_frame,
    301                        text="File operations",
    302                        font=("Helvetica",12,"bold")).grid(row=0,column=0,columnspan=2,ipady=5)
    303          Tkinter.Button(button_row_frame,text="Save...",command=self.save).grid(row=1,column=0)
    304          Tkinter.Button(button_row_frame,text="Load...",command=self.load).grid(row=1,column=1)
    305
    306          if auto_connect:
    307              self.connect(server_hostname,server_port)
    308
    309 -    def frustum_narrower(self,dummy_arg=None): # callback
    310          self.left_tk_var.set(self.meta_params.left*(1.0/1.05))
    311          self.right_tk_var.set(self.meta_params.right*(1.0/1.05))
    312          self.send_values()
    313
    314 -    def frustum_wider(self,dummy_arg=None): # callback
    315          self.left_tk_var.set(self.meta_params.left*1.05)
    316          self.right_tk_var.set(self.meta_params.right*1.05)
    317          self.send_values()
    318
    319 -    def frustum_shorter(self,dummy_arg=None): # callback
    320          self.bottom_tk_var.set(self.meta_params.bottom*(1.0/1.05))
    321          self.top_tk_var.set(self.meta_params.top*(1.0/1.05))
    322          self.send_values()
    323
    324 -    def frustum_taller(self,dummy_arg=None): # callback
    325          self.bottom_tk_var.set(self.meta_params.bottom*1.05)
    326          self.top_tk_var.set(self.meta_params.top*1.05)
    327          self.send_values()
    328
    329 -    def frustum_left(self,dummy_arg=None): # callback
    330          self.left_tk_var.set(self.meta_params.left*1.025)
    331          self.right_tk_var.set(self.meta_params.right*(1.0/1.025))
    332          self.send_values()
    333
    334 -    def frustum_right(self,dummy_arg=None): # callback
    335          self.left_tk_var.set(self.meta_params.left*(1.0/1.025))
    336          self.right_tk_var.set(self.meta_params.right*1.025)
    337          self.send_values()
    338
    339 -    def frustum_down(self,dummy_arg=None): # callback
    340          self.bottom_tk_var.set(self.meta_params.bottom*1.025)
    341          self.top_tk_var.set(self.meta_params.top*(1.0/1.025))
    342          self.send_values()
    343
    344 -    def frustum_up(self,dummy_arg=None): # callback
    345          self.bottom_tk_var.set(self.meta_params.bottom*(1.0/1.025))
    346          self.top_tk_var.set(self.meta_params.top*1.025)
    347          self.send_values()
    348
    349 -    def get_az_el(self,xyz_tuple):
    350          x,y,z = xyz_tuple
    351          r = math.sqrt(x*x + y*y + z*z)
    352          theta = math.acos(-y/r)
    353          rh = r * math.sin(theta)
    354          phi = math.atan2(-z,x)
    355          az = -(phi * 180.0/math.pi - 90.0)
    356          el = theta * 180.0/math.pi - 90.0
    357          return az,el
    358
    359 -    def get_xyz(self,az_el):
    360          az,el = az_el
    361          theta = (el + 90.0) / 180.0 * math.pi
    362          phi = (az + 90.0) / 180.0 * math.pi
    363          y = -math.cos(theta)
    364          rh = math.sin(theta)
    365          x = -rh * math.cos(phi)
    366          z = -rh * math.sin(phi)
    367          return x,y,z
    368
    369 -    def az_increase(self,dummy_arg=None): # callback
    370          az,el = self.get_az_el(self.meta_params.center)
    371          az = az + 5.0
    372          self.look_at_az_str.set("%.1f"%az)
    373          x,y,z = self.get_xyz((az,el))
    374          self.center_x_tk_var.set("%.4f"%x)
    375          self.center_y_tk_var.set("%.4f"%y)
    376          self.center_z_tk_var.set("%.4f"%z)
    377          self.send_values()
    378
    379 -    def az_decrease(self,dummy_arg=None): # callback
    380          az,el = self.get_az_el(self.meta_params.center)
    381          az = az - 5.0
    382          self.look_at_az_str.set("%.1f"%az)
    383          x,y,z = self.get_xyz((az,el))
    384          self.center_x_tk_var.set("%.4f"%x)
    385          self.center_y_tk_var.set("%.4f"%y)
    386          self.center_z_tk_var.set("%.4f"%z)
    387          self.send_values()
    388
    389 -    def el_increase(self,dummy_arg=None): # callback
    390          az,el = self.get_az_el(self.meta_params.center)
    391          el = el + 5.0
    392          el = min(el,90.0)
    393          self.look_at_el_str.set("%.1f"%el)
    394          x,y,z = self.get_xyz((az,el))
    395          self.center_x_tk_var.set("%.4f"%x)
    396          self.center_y_tk_var.set("%.4f"%y)
    397          self.center_z_tk_var.set("%.4f"%z)
    398          self.send_values()
    399
    400 -    def el_decrease(self,dummy_arg=None): # callback
    401          az,el = self.get_az_el(self.meta_params.center)
    402          el = el - 5.0
    403          el = max(el,-90.0)
    404          self.look_at_el_str.set("%.1f"%el)
    405          x,y,z = self.get_xyz((az,el))
    406          self.center_x_tk_var.set("%.4f"%x)
    407          self.center_y_tk_var.set("%.4f"%y)
    408          self.center_z_tk_var.set("%.4f"%z)
    409          self.send_values()
    410
    411 -    def up_az_increase(self,dummy_arg=None): # callback
    412          az,el = self.get_az_el(self.meta_params.up)
    413          az = az + 5.0
    414          self.up_az_str.set("%.1f"%az)
    415          x,y,z = self.get_xyz((az,el))
    416          self.up_x_tk_var.set("%.4f"%x)
    417          self.up_y_tk_var.set("%.4f"%y)
    418          self.up_z_tk_var.set("%.4f"%z)
    419          self.send_values()
    420
    421 -    def up_az_decrease(self,dummy_arg=None): # callback
    422          az,el = self.get_az_el(self.meta_params.up)
    423          az = az - 5.0
    424          self.up_az_str.set("%.1f"%az)
    425          x,y,z = self.get_xyz((az,el))
    426          self.up_x_tk_var.set("%.4f"%x)
    427          self.up_y_tk_var.set("%.4f"%y)
    428          self.up_z_tk_var.set("%.4f"%z)
    429          self.send_values()
    430
    431 -    def up_el_increase(self,dummy_arg=None): # callback
    432          az,el = self.get_az_el(self.meta_params.up)
    433          el = el + 5.0
    434          el = min(el,90.0)
    435          self.up_el_str.set("%.1f"%el)
    436          x,y,z = self.get_xyz((az,el))
    437          self.up_x_tk_var.set("%.4f"%x)
    438          self.up_y_tk_var.set("%.4f"%y)
    439          self.up_z_tk_var.set("%.4f"%z)
    440          self.send_values()
    441
    442 -    def up_el_decrease(self,dummy_arg=None): # callback
    443          az,el = self.get_az_el(self.meta_params.up)
    444          el = el - 5.0
    445          el = max(el,-90.0)
    446          self.up_el_str.set("%.1f"%el)
    447          x,y,z = self.get_xyz((az,el))
    448          self.up_x_tk_var.set("%.4f"%x)
    449          self.up_y_tk_var.set("%.4f"%y)
    450          self.up_z_tk_var.set("%.4f"%z)
    451          self.send_values()
    452
    453 -    def save(self):
    454          filename = tkFileDialog.asksaveasfilename(defaultextension=".ve_3dproj",filetypes=[('Projection file','*.ve_3dproj')])
    455          fd = open(filename,"wb")
    456          save_dict = self.get_param_dict()
    457          pickle.dump( save_dict, fd )
    458
    459 -    def load(self):
    460          filename = tkFileDialog.askopenfilename(defaultextension=".ve_3dproj",filetypes=[('Projection file','*.ve_3dproj')])
    461          if not filename:
    462              return
    463          fd = open(filename,"rb")
    464          file_contents = fd.read()
    465          file_contents = file_contents.replace('\r\n','\n') # deal with Windows newlines
    466          memory_file = StringIO.StringIO(file_contents)
    467          load_dict = pickle.load(memory_file)
    468          self.set_param_dict( load_dict )
    469          self.send_values()
    470
    471 -    def get_shortname(self):
    472          """Used as basename for saving parameter files"""
    473          return "screen_position"
    474
    475 -    def get_param_dict(self):
    476          result = {}
    477          for param_name in dir(self.meta_params):
    478              if param_name[:2] != '__' and param_name[-2:] != '__':
    479                  result[param_name] = getattr(self.meta_params,param_name)
    480          return result
    481
    482 -    def get_type(self):
    483          return "screenPositionGUI"
    484
    485 -    def set_param_dict(self,new_param_dict):
    486          orig_params = dir(self.meta_params)
    487          for new_param_name in new_param_dict.keys():
    488              if new_param_name[:2] != '__' and new_param_name[-2:] != '__':
    489                  if new_param_name not in orig_params:
    490                      raise ValueError('Gave parameter "%s", which I do not know about.'%(new_param_name,))
    491                  setattr(self.meta_params,new_param_name,new_param_dict[new_param_name])
    492          self.left_tk_var.set( self.meta_params.left )
    493          self.right_tk_var.set( self.meta_params.right )
    494          self.top_tk_var.set( self.meta_params.top )
    495          self.bottom_tk_var.set( self.meta_params.bottom )
    496          self.near_tk_var.set( self.meta_params.near )
    497          self.far_tk_var.set( self.meta_params.far )
    498          self.eye_x_tk_var.set( self.meta_params.eye[0] )
    499          self.eye_y_tk_var.set( self.meta_params.eye[1] )
    500          self.eye_z_tk_var.set( self.meta_params.eye[2] )
    501          self.center_x_tk_var.set( self.meta_params.center[0] )
    502          self.center_y_tk_var.set( self.meta_params.center[1] )
    503          self.center_z_tk_var.set( self.meta_params.center[2] )
    504          self.up_x_tk_var.set( self.meta_params.up[0] )
    505          self.up_y_tk_var.set( self.meta_params.up[1] )
    506          self.up_z_tk_var.set( self.meta_params.up[2] )
    507
    508 -    def get_parameters_as_strings(self):
    509          result = []
    510          for param_name in dir(self.meta_params):
    511              if param_name[:2] != '__' and param_name[-2:] != '__':
    512                  value = getattr(self.meta_params,param_name)
    513                  value_string = str(value)
    514                  result.append((param_name,value_string))
    515          return result
    516
    517 -    def get_loopable_variable_names(self):
    518          return self.loopable_variables.keys()
    519
    520 -    def set_loopable_variable(self,easy_name,value):
    521          meta_param_var_name,tk_var = self.loopable_variables[easy_name]
    522          setattr(self.meta_params,meta_param_var_name,value)
    523          tk_var.set(value)
    524          self.update() # update screen with new tk_var value
    525
    526 -    def send_values(self,dummy_arg=None):
    527          self.meta_params.left = self.left_tk_var.get()
    528          self.meta_params.right = self.right_tk_var.get()
    529          self.meta_params.top = self.top_tk_var.get()
    530          self.meta_params.bottom = self.bottom_tk_var.get()
    531          self.meta_params.near = self.near_tk_var.get()
    532          self.meta_params.far = self.far_tk_var.get()
    533          self.meta_params.eye = (self.eye_x_tk_var.get(),
    534                                  self.eye_y_tk_var.get(),
    535                                  self.eye_z_tk_var.get())
    536          self.meta_params.center = (self.center_x_tk_var.get(),
    537                                  self.center_y_tk_var.get(),
    538                                  self.center_z_tk_var.get())
    539          self.meta_params.up = (self.up_x_tk_var.get(),
    540                                  self.up_y_tk_var.get(),
    541                                  self.up_z_tk_var.get())
    542
    543          if self.connected:
    544              self.projection_controller.set_parameters( self.meta_params )
    545
    546 -    def connect(self,server_hostname='',server_port=7766):
    547          self.pyro_client = VisionEgg.PyroClient.PyroClient(server_hostname,server_port)
    548
    549          self.projection_controller = self.pyro_client.get("projection_controller")
    550
    551          self.connected = 1
    552          if hasattr(self, 'connected_label'):
    553              self.connected_label.config(text="Server status: Connected")
    554              self.send_values() # send values only when running this way, otherwise get values
    555          else:
    556              self.meta_params = self.projection_controller.get_parameters()
    557              self.set_param_dict( {} ) # updates screen values to self.meta_params
    558
    559 -    def quit_server(self,dummy=None):
    560          self.projection_controller.quit_server()
    561          self.connected = 0
    562          self.connected_label.config(text="Server status: Not connected")
    563
    564  if __name__=='__main__':
    565      frame = ScreenPositionControlFrame()
    566      frame.pack(expand=1,fill=Tkinter.BOTH)
    567      frame.winfo_toplevel().title("%s"%(os.path.basename(os.path.splitext(sys.argv[0])[0]),))
    568      frame.mainloop()
    569