home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / sgi / gl / glstdwin / glstdwin.py < prev    next >
Text File  |  1992-03-30  |  9KB  |  401 lines

  1. # GL STDWIN
  2. #
  3. # See stdwingl for a convenient hack to use this instead of built-in stdwin
  4. # without modifying your application, except for one line in the main file.
  5. #
  6. # Intrinsic differences with built-in stdwin (hard or impossible to fix):
  7. # - Need to call w.close() to close a window !!!
  8. # - Need to call m.close() to remove a menu !!!
  9. # - Doesn't enforce the existence of at most one drawing object
  10. # - No textedit package
  11. # - No X11 selections
  12. #
  13. # Not yet implemented:
  14. # - shade drawing
  15. # - elliptical arc drawing (need to play with transformation)
  16. # - more than one mouse button
  17. # - scroll bars (need to redo viewport handling to get this)
  18. # - partial redraws
  19. # - dialog boxes
  20. # - timer events
  21. # - cursors
  22. #
  23. # Extra features:
  24. # - color (for now, you need to know the colormap index)
  25.  
  26.  
  27. import gl
  28. import fm
  29. from GL import *
  30. from DEVICE import *
  31. from stdwinevents import *
  32.  
  33.  
  34. # Customizable constants
  35. #
  36. DEF_FONT = 'Times-Roman'        # Default font
  37. DEF_SIZE = 12                # Default font size (points)
  38. MASK = 20                # Viewport minus scrmask
  39.  
  40.  
  41. # A structure to hold global variables
  42. #
  43. class Struct: pass
  44. G = Struct()
  45. #
  46. G.queue = []                # Pending STDWIN events
  47. G.drawqueue = []            # Windows that need WE_REDRAW
  48. G.windowmap = {}            # Map window id to window object
  49. G.windowmap['0'] = None            # For convenience
  50. G.focus = None                # Input focus
  51. G.fg = BLACK                # Foreground color
  52. G.bg = WHITE                # Background color
  53. G.def_size = 0, 0            # Default window size
  54. G.def_pos = 0, 0            # Default window position
  55. #
  56. G.size = DEF_SIZE
  57. G.font = fm.findfont(DEF_FONT).scalefont(G.size)
  58.  
  59.  
  60. # Initialize GL
  61. #
  62. gl.foreground()
  63. gl.noport()
  64. dummygid = gl.winopen('')
  65.  
  66. # Ask for all sorts of events
  67. #
  68. # Both REDRAW (= resize and/or redraw!) and INPUTCHANGE are implicitly queued
  69. #qdevice(REDRAW)
  70. #qdevice(INPUTCHANGE)
  71. #
  72. # Keyboard
  73. gl.qdevice(KEYBD)
  74. gl.qdevice(LEFTARROWKEY)
  75. gl.qdevice(RIGHTARROWKEY)
  76. gl.qdevice(UPARROWKEY)
  77. gl.qdevice(DOWNARROWKEY)
  78. gl.qdevice(LEFTALTKEY)
  79. gl.qdevice(RIGHTALTKEY)
  80. #
  81. # Mouse
  82. gl.qdevice(LEFTMOUSE)
  83. #gl.qdevice(MIDDLEMOUSE)
  84. gl.qdevice(RIGHTMOUSE)            # Menu button
  85. # NB MOUSEX, MOUSEY events are queued on button down
  86. #
  87. # Window close requests
  88. gl.qdevice(WINQUIT)
  89. gl.qdevice(WINSHUT)
  90. #
  91. # These aren't needed
  92. #gl.qdevice(TIMER0)
  93. #gl.qdevice(WINFREEZE)
  94. #gl.qdevice(WINTHAW)
  95. #gl.qdevice(REDRAWICONIC)
  96.  
  97.  
  98. # STDWIN: create a new window
  99. #
  100. def open(title):
  101.     h, v = G.def_pos
  102.     width, height = G.def_size
  103.     if h > 0 or v > 0:
  104.         # Choose arbitrary defaults
  105.         if h < 0: h = 10
  106.         if v < 0: v = 30
  107.         if width <= 0: width = 400
  108.         if height <= 0: height = 300
  109.         gl.prefposition(h, h+width, 1024-v, 1024-v-height)
  110.     elif width > 0 or height > 0:
  111.         if width <= 0: width = 400
  112.         if height <= 0: height = 300
  113.         gl.prefsize(width, height)
  114.     from glstdwwin import WindowObject
  115.     win = WindowObject()._init(title)
  116.     G.windowmap[`win._gid`] = win
  117.     return win
  118.  
  119.  
  120. # STDWIN: set default initial window position (0 means use default)
  121. #
  122. def setdefwinpos(h, v):
  123.     G.def_pos = h, v
  124.  
  125.  
  126. # STDWIN: set default window size (0 means use default)
  127. #
  128. def setdefwinsize(width, height):
  129.     G.def_size = width, height
  130.  
  131.  
  132. # STDWIN: beep or ring the bell
  133. #
  134. def fleep():
  135.     gl.ringbell()
  136.  
  137.  
  138. # STDWIN: set default foreground color
  139. #
  140. def setfgcolor(color):
  141.     G.fg = color
  142.  
  143.  
  144. # STDWIN: set default background color
  145. #
  146. def setbgcolor(color):
  147.     G.bg = color
  148.  
  149.  
  150. # STDWIN: get default foreground color
  151. #
  152. def getfgcolor():
  153.     return G.fgcolor
  154.  
  155.  
  156. # STDWIN: get default background color
  157. #
  158. def getbgcolor():
  159.     return G.bgcolor
  160.  
  161.  
  162. # Table mapping characters to key codes
  163. #
  164. key2code = key = {}
  165. key['A'] = AKEY
  166. key['B'] = BKEY
  167. key['C'] = CKEY
  168. key['D'] = DKEY
  169. key['E'] = EKEY
  170. key['F'] = FKEY
  171. key['G'] = GKEY
  172. key['H'] = HKEY
  173. key['I'] = IKEY
  174. key['J'] = JKEY
  175. key['K'] = KKEY
  176. key['L'] = LKEY
  177. key['M'] = MKEY
  178. key['N'] = NKEY
  179. key['O'] = OKEY
  180. key['P'] = PKEY
  181. key['Q'] = QKEY
  182. key['R'] = RKEY
  183. key['S'] = SKEY
  184. key['T'] = TKEY
  185. key['U'] = UKEY
  186. key['V'] = VKEY
  187. key['W'] = WKEY
  188. key['X'] = XKEY
  189. key['Y'] = YKEY
  190. key['Z'] = ZKEY
  191. key['0'] = ZEROKEY
  192. key['1'] = ONEKEY
  193. key['2'] = TWOKEY
  194. key['3'] = THREEKEY
  195. key['4'] = FOURKEY
  196. key['5'] = FIVEKEY
  197. key['6'] = SIXKEY
  198. key['7'] = SEVENKEY
  199. key['8'] = EIGHTKEY
  200. key['9'] = NINEKEY
  201. del key
  202. #
  203. code2key = {}
  204. codelist = []
  205. for key in key2code.keys():
  206.     code = key2code[key]
  207.     code2key[`code`] = key
  208.     codelist.append(code)
  209. del key
  210.  
  211.  
  212. # STDWIN: wait for the next event
  213. #
  214. commands = {}
  215. commands['\r'] = WC_RETURN
  216. commands['\b'] = WC_BACKSPACE
  217. commands['\t'] = WC_TAB
  218. #
  219. def getevent():
  220.   while 1:
  221.     #
  222.     # Get next event from the processed queue, if any
  223.     #
  224.     if G.queue:
  225.         event = G.queue[0]
  226.         del G.queue[0]
  227.         #print 'getevent from queue -->', event
  228.         return event
  229.     #
  230.     # Get next event from the draw queue, if any,
  231.     # but only if there is nothing in the system queue.
  232.     #
  233.     if G.drawqueue and not gl.qtest():
  234.         win = G.drawqueue[0]
  235.         del G.drawqueue[0]
  236.         gl.winset(win._gid)
  237.         gl.color(win._bg)
  238.         gl.clear()
  239.         event = WE_DRAW, win, win._area
  240.         #print 'getevent from drawqueue -->', event
  241.         return event
  242.     #
  243.     # Get next event from system queue, blocking if necessary
  244.     # until one is available.
  245.     # Some cases immediately return the event, others do nothing
  246.     # or append one or more events to the processed queue.
  247.     #
  248.     dev, val = gl.qread()
  249.     #
  250.     if dev == REDRAW:
  251.         win = G.windowmap[`val`]
  252.         old_area = win._area
  253.         win._fixviewport()
  254.         win._needredraw()
  255.         if old_area <> win._area:
  256.             #print 'getevent --> WE_SIZE'
  257.             return WE_SIZE, win, None
  258.     elif dev == KEYBD:
  259.         if val == 3:
  260.             raise KeyboardInterrupt # Control-C in window
  261.         character = chr(val)
  262.         if commands.has_key(character):
  263.             return WE_COMMAND, G.focus, commands[character]
  264.         return WE_CHAR, G.focus, character
  265.     elif dev == LEFTARROWKEY:
  266.         if val:
  267.             return WE_COMMAND, G.focus, WC_LEFT
  268.     elif dev == RIGHTARROWKEY:
  269.         if val:
  270.             return WE_COMMAND, G.focus, WC_RIGHT
  271.     elif dev == UPARROWKEY:
  272.         if val:
  273.             return WE_COMMAND, G.focus, WC_UP
  274.     elif dev == DOWNARROWKEY:
  275.         if val:
  276.             return WE_COMMAND, G.focus, WC_DOWN
  277.     elif dev in (LEFTALTKEY, RIGHTALTKEY):
  278.         if val:
  279.             for code in codelist:
  280.                 gl.qdevice(code)
  281.         else:
  282.             for code in codelist:
  283.                 gl.unqdevice(code)
  284.     elif dev in codelist:
  285.         if val:
  286.             event = G.focus._doshortcut(code2key[`dev`])
  287.             if event:
  288.                 return event
  289.     elif dev == LEFTMOUSE:
  290.         G.mousex = gl.getvaluator(MOUSEX)
  291.         G.mousey = gl.getvaluator(MOUSEY)
  292.         if val:
  293.             type = WE_MOUSE_DOWN
  294.             gl.qdevice(MOUSEX)
  295.             gl.qdevice(MOUSEY)
  296.         else:
  297.             type = WE_MOUSE_UP
  298.             gl.unqdevice(MOUSEX)
  299.             gl.unqdevice(MOUSEY)
  300.         return _mouseevent(type)
  301.     elif dev == MOUSEX:
  302.         G.mousex = val
  303.         return _mouseevent(WE_MOUSE_MOVE)
  304.     elif dev == MOUSEY:
  305.         G.mousey = val
  306.         return _mouseevent(WE_MOUSE_MOVE)
  307.     elif dev == RIGHTMOUSE:        # Menu button press/release
  308.         if val:            # Press
  309.             event = G.focus._domenu()
  310.             if event:
  311.                 return event
  312.     elif dev == INPUTCHANGE:
  313.         if G.focus:
  314.             G.queue.append(WE_DEACTIVATE, G.focus, None)
  315.         G.focus = G.windowmap[`val`]
  316.         if G.focus:
  317.             G.queue.append(WE_ACTIVATE, G.focus, None)
  318.     elif dev in (WINSHUT, WINQUIT):
  319.         return WE_CLOSE, G.windowmap[`val`], None
  320.     else:
  321.         print '*** qread() --> dev:', dev, 'val:', val
  322.  
  323. # Helper routine to construct a mouse (up, move or down) event
  324. #
  325. def _mouseevent(type):
  326.     gl.winset(G.focus._gid)
  327.     orgx, orgy = gl.getorigin()
  328.     sizex, sizey = gl.getsize()
  329.     x = G.mousex - orgx
  330.     y = G.mousey - orgy
  331.     return type, G.focus, ((x, sizey-y), 1, 0, 0)
  332.  
  333.  
  334.  
  335.  
  336. # STDWIN: text measuring functions
  337.  
  338. def baseline():
  339.     (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
  340.         height, nglyphs) = G.font.getfontinfo()
  341.     return height - yorig
  342.  
  343. def lineheight():
  344.     (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
  345.             height, nglyphs) = G.font.getfontinfo()
  346.     return height
  347.  
  348. def textbreak(string, width):
  349.     # XXX Slooooow!
  350.     n = len(string)
  351.     nwidth = textwidth(string[:n])
  352.     while nwidth > width:
  353.         n = n-1
  354.         nwidth = textwidth(string[:n])
  355.     return n
  356.  
  357. def textwidth(string):
  358.     return G.font.getstrwidth(string)
  359.  
  360.  
  361. # STDWIN: set default font and size
  362.  
  363. def setfont(fontname):
  364.     G.font = fm.findfont(fontname).scalefont(G.size)
  365.  
  366. def setsize(size):
  367.     ratio = float(size) / float(G.size)
  368.     G.size = size
  369.     G.font = G.font.scalefont(ratio)
  370.  
  371.  
  372. # Utility functions
  373.  
  374. # Exclusive-or of two BYTES
  375. #
  376. def xor(x, y):
  377.     a = bits(x)
  378.     b = bits(y)
  379.     c = [0, 0, 0, 0, 0, 0, 0, 0]
  380.     for i in range(8):
  381.         c[i] = (a[i] + b[i]) % 2
  382.     return stib(c)
  383.  
  384. # Return the bits of a byte as a list of 8 integers
  385. #
  386. def bits(x):
  387.     b = [0, 0, 0, 0, 0, 0, 0, 0]
  388.     for i in range(8):
  389.         x, b[i] = divmod(x, 2)
  390.     return b
  391.  
  392. # Convert a list of 8 integers (0|1) to a byte
  393. #
  394. def stib(b):
  395.     x = 0
  396.     shift = 1
  397.     for i in range(8):
  398.         x = x + b[i]*shift
  399.         shift = shift*2
  400.     return x
  401.