Home | History | Annotate | Download | only in plat-irix5
      1 # Module 'panel'
      2 #
      3 # Support for the Panel library.
      4 # Uses built-in module 'pnl'.
      5 # Applications should use 'panel.function' instead of 'pnl.function';
      6 # most 'pnl' functions are transparently exported by 'panel',
      7 # but dopanel() is overridden and you have to use this version
      8 # if you want to use callbacks.
      9 from warnings import warnpy3k
     10 warnpy3k("the panel module has been removed in Python 3.0", stacklevel=2)
     11 del warnpy3k
     12 
     13 
     14 import pnl
     15 
     16 
     17 debug = 0
     18 
     19 
     20 # Test if an object is a list.
     21 #
     22 def is_list(x):
     23     return type(x) == type([])
     24 
     25 
     26 # Reverse a list.
     27 #
     28 def reverse(list):
     29     res = []
     30     for item in list:
     31         res.insert(0, item)
     32     return res
     33 
     34 
     35 # Get an attribute of a list, which may itself be another list.
     36 # Don't use 'prop' for name.
     37 #
     38 def getattrlist(list, name):
     39     for item in list:
     40         if item and is_list(item) and item[0] == name:
     41             return item[1:]
     42     return []
     43 
     44 
     45 # Get a property of a list, which may itself be another list.
     46 #
     47 def getproplist(list, name):
     48     for item in list:
     49         if item and is_list(item) and item[0] == 'prop':
     50             if len(item) > 1 and item[1] == name:
     51                 return item[2:]
     52     return []
     53 
     54 
     55 # Test if an actuator description contains the property 'end-of-group'
     56 #
     57 def is_endgroup(list):
     58     x = getproplist(list, 'end-of-group')
     59     return (x and x[0] == '#t')
     60 
     61 
     62 # Neatly display an actuator definition given as S-expression
     63 # the prefix string is printed before each line.
     64 #
     65 def show_actuator(prefix, a):
     66     for item in a:
     67         if not is_list(item):
     68             print prefix, item
     69         elif item and item[0] == 'al':
     70             print prefix, 'Subactuator list:'
     71             for a in item[1:]:
     72                 show_actuator(prefix + '    ', a)
     73         elif len(item) == 2:
     74             print prefix, item[0], '=>', item[1]
     75         elif len(item) == 3 and item[0] == 'prop':
     76             print prefix, 'Prop', item[1], '=>',
     77             print item[2]
     78         else:
     79             print prefix, '?', item
     80 
     81 
     82 # Neatly display a panel.
     83 #
     84 def show_panel(prefix, p):
     85     for item in p:
     86         if not is_list(item):
     87             print prefix, item
     88         elif item and item[0] == 'al':
     89             print prefix, 'Actuator list:'
     90             for a in item[1:]:
     91                 show_actuator(prefix + '    ', a)
     92         elif len(item) == 2:
     93             print prefix, item[0], '=>', item[1]
     94         elif len(item) == 3 and item[0] == 'prop':
     95             print prefix, 'Prop', item[1], '=>',
     96             print item[2]
     97         else:
     98             print prefix, '?', item
     99 
    100 
    101 # Exception raised by build_actuator or build_panel.
    102 #
    103 panel_error = 'panel error'
    104 
    105 
    106 # Dummy callback used to initialize the callbacks.
    107 #
    108 def dummy_callback(arg):
    109     pass
    110 
    111 
    112 # Assign attributes to members of the target.
    113 # Attribute names in exclist are ignored.
    114 # The member name is the attribute name prefixed with the prefix.
    115 #
    116 def assign_members(target, attrlist, exclist, prefix):
    117     for item in attrlist:
    118         if is_list(item) and len(item) == 2 and item[0] not in exclist:
    119             name, value = item[0], item[1]
    120             ok = 1
    121             if value[0] in '-0123456789':
    122                 value = eval(value)
    123             elif value[0] == '"':
    124                 value = value[1:-1]
    125             elif value == 'move-then-resize':
    126                 # Strange default set by Panel Editor...
    127                 ok = 0
    128             else:
    129                 print 'unknown value', value, 'for', name
    130                 ok = 0
    131             if ok:
    132                 lhs = 'target.' + prefix + name
    133                 stmt = lhs + '=' + repr(value)
    134                 if debug: print 'exec', stmt
    135                 try:
    136                     exec stmt + '\n'
    137                 except KeyboardInterrupt: # Don't catch this!
    138                     raise KeyboardInterrupt
    139                 except:
    140                     print 'assign failed:', stmt
    141 
    142 
    143 # Build a real actuator from an actuator description.
    144 # Return a pair (actuator, name).
    145 #
    146 def build_actuator(descr):
    147     namelist = getattrlist(descr, 'name')
    148     if namelist:
    149         # Assume it is a string
    150         actuatorname = namelist[0][1:-1]
    151     else:
    152         actuatorname = ''
    153     type = descr[0]
    154     if type[:4] == 'pnl_': type = type[4:]
    155     act = pnl.mkact(type)
    156     act.downfunc = act.activefunc = act.upfunc = dummy_callback
    157     #
    158     assign_members(act, descr[1:], ['al', 'data', 'name'], '')
    159     #
    160     # Treat actuator-specific data
    161     #
    162     datalist = getattrlist(descr, 'data')
    163     prefix = ''
    164     if type[-4:] == 'puck':
    165         prefix = 'puck_'
    166     elif type == 'mouse':
    167         prefix = 'mouse_'
    168     assign_members(act, datalist, [], prefix)
    169     #
    170     return act, actuatorname
    171 
    172 
    173 # Build all sub-actuators and add them to the super-actuator.
    174 # The super-actuator must already have been added to the panel.
    175 # Sub-actuators with defined names are added as members to the panel
    176 # so they can be referenced as p.name.
    177 #
    178 # Note: I have no idea how panel.endgroup() works when applied
    179 # to a sub-actuator.
    180 #
    181 def build_subactuators(panel, super_act, al):
    182     #
    183     # This is nearly the same loop as below in build_panel(),
    184     # except a call is made to addsubact() instead of addact().
    185     #
    186     for a in al:
    187         act, name = build_actuator(a)
    188         act.addsubact(super_act)
    189         if name:
    190             stmt = 'panel.' + name + ' = act'
    191             if debug: print 'exec', stmt
    192             exec stmt + '\n'
    193         if is_endgroup(a):
    194             panel.endgroup()
    195         sub_al = getattrlist(a, 'al')
    196         if sub_al:
    197             build_subactuators(panel, act, sub_al)
    198     #
    199     # Fix the actuator to which whe just added subactuators.
    200     # This can't hurt (I hope) and is needed for the scroll actuator.
    201     #
    202     super_act.fixact()
    203 
    204 
    205 # Build a real panel from a panel definition.
    206 # Return a panel object p, where for each named actuator a, p.name is a
    207 # reference to a.
    208 #
    209 def build_panel(descr):
    210     #
    211     # Sanity check
    212     #
    213     if (not descr) or descr[0] != 'panel':
    214         raise panel_error, 'panel description must start with "panel"'
    215     #
    216     if debug: show_panel('', descr)
    217     #
    218     # Create an empty panel
    219     #
    220     panel = pnl.mkpanel()
    221     #
    222     # Assign panel attributes
    223     #
    224     assign_members(panel, descr[1:], ['al'], '')
    225     #
    226     # Look for actuator list
    227     #
    228     al = getattrlist(descr, 'al')
    229     #
    230     # The order in which actuators are created is important
    231     # because of the endgroup() operator.
    232     # Unfortunately the Panel Editor outputs the actuator list
    233     # in reverse order, so we reverse it here.
    234     #
    235     al = reverse(al)
    236     #
    237     for a in al:
    238         act, name = build_actuator(a)
    239         act.addact(panel)
    240         if name:
    241             stmt = 'panel.' + name + ' = act'
    242             exec stmt + '\n'
    243         if is_endgroup(a):
    244             panel.endgroup()
    245         sub_al = getattrlist(a, 'al')
    246         if sub_al:
    247             build_subactuators(panel, act, sub_al)
    248     #
    249     return panel
    250 
    251 
    252 # Wrapper around pnl.dopanel() which calls call-back functions.
    253 #
    254 def my_dopanel():
    255     # Extract only the first 4 elements to allow for future expansion
    256     a, down, active, up = pnl.dopanel()[:4]
    257     if down:
    258         down.downfunc(down)
    259     if active:
    260         active.activefunc(active)
    261     if up:
    262         up.upfunc(up)
    263     return a
    264 
    265 
    266 # Create one or more panels from a description file (S-expressions)
    267 # generated by the Panel Editor.
    268 #
    269 def defpanellist(file):
    270     import panelparser
    271     descrlist = panelparser.parse_file(open(file, 'r'))
    272     panellist = []
    273     for descr in descrlist:
    274         panellist.append(build_panel(descr))
    275     return panellist
    276 
    277 
    278 # Import everything from built-in method pnl, so the user can always
    279 # use panel.foo() instead of pnl.foo().
    280 # This gives *no* performance penalty once this module is imported.
    281 #
    282 from pnl import *                       # for export
    283 
    284 dopanel = my_dopanel                    # override pnl.dopanel
    285