/Lib/plat-irix5/panel.py

http://unladen-swallow.googlecode.com/ · Python · 284 lines · 154 code · 37 blank · 93 comment · 63 complexity · 00760fe06d83947b0b17107bd37252d8 MD5 · raw file

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