home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyth_os2.zip / python-1.0.2 / Lib / stdwin / tablewin.py < prev    next >
Text File  |  1992-01-01  |  6KB  |  237 lines

  1. # Module 'tablewin'
  2.  
  3. # Display a table, with per-item actions:
  4.  
  5. #       A1   |   A2   |   A3   |  ....  |   AN
  6. #       B1   |   B2   |   B3   |  ....  |   BN
  7. #       C1   |   C2   |   C3   |  ....  |   CN
  8. #       ..   |   ..   |   ..   |  ....  |   ..
  9. #       Z1   |   Z2   |   Z3   |  ....  |   ZN
  10.  
  11. # Not all columns need to have the same length.
  12. # The data structure is a list of columns;
  13. # each column is a list of items.
  14. # Each item is a pair of a string and an action procedure.
  15. # The first item may be a column title.
  16.  
  17. import stdwin
  18. import gwin
  19. from stdwinevents import *
  20.  
  21. def open(title, data): # Public function to open a table window
  22.     #
  23.     # Set geometry parameters (one day, these may be changeable)
  24.     #
  25.     margin = stdwin.textwidth('  ')
  26.     lineheight = stdwin.lineheight()
  27.     #
  28.     # Geometry calculations
  29.     #
  30.     colstarts = [0]
  31.     totwidth = 0
  32.     maxrows = 0
  33.     for coldata in data:
  34.         # Height calculations
  35.         rows = len(coldata)
  36.         if rows > maxrows: maxrows = rows
  37.         # Width calculations
  38.         width = colwidth(coldata) + margin
  39.         totwidth = totwidth + width
  40.         colstarts.append(totwidth)
  41.     #
  42.     # Calculate document and window height
  43.     #
  44.     docwidth, docheight = totwidth, maxrows*lineheight
  45.     winwidth, winheight = docwidth, docheight
  46.     if winwidth > stdwin.textwidth('n')*100: winwidth = 0
  47.     if winheight > stdwin.lineheight()*30: winheight = 0
  48.     #
  49.     # Create the window
  50.     #
  51.     stdwin.setdefwinsize(winwidth, winheight)
  52.     w = gwin.open(title)
  53.     #
  54.     # Set properties and override methods
  55.     #
  56.     w.data = data
  57.     w.margin = margin
  58.     w.lineheight = lineheight
  59.     w.colstarts = colstarts
  60.     w.totwidth = totwidth
  61.     w.maxrows = maxrows
  62.     w.selection = (-1, -1)
  63.     w.lastselection = (-1, -1)
  64.     w.selshown = 0
  65.     w.setdocsize(docwidth, docheight)
  66.     w.draw = draw
  67.     w.mup = mup
  68.     w.arrow = arrow
  69.     #
  70.     # Return
  71.     #
  72.     return w
  73.  
  74. def update(w, data): # Change the data
  75.     #
  76.     # Hide selection
  77.     #
  78.     hidesel(w, w.begindrawing())
  79.     #
  80.     # Get old geometry parameters
  81.     #
  82.     margin = w.margin
  83.     lineheight = w.lineheight
  84.     #
  85.     # Geometry calculations
  86.     #
  87.     colstarts = [0]
  88.     totwidth = 0
  89.     maxrows = 0
  90.     for coldata in data:
  91.         # Height calculations
  92.         rows = len(coldata)
  93.         if rows > maxrows: maxrows = rows
  94.         # Width calculations
  95.         width = colwidth(coldata) + margin
  96.         totwidth = totwidth + width
  97.         colstarts.append(totwidth)
  98.     #
  99.     # Calculate document and window height
  100.     #
  101.     docwidth, docheight = totwidth, maxrows*lineheight
  102.     #
  103.     # Set changed properties and change window size
  104.     #
  105.     w.data = data
  106.     w.colstarts = colstarts
  107.     w.totwidth = totwidth
  108.     w.maxrows = maxrows
  109.     w.change((0, 0), (10000, 10000))
  110.     w.setdocsize(docwidth, docheight)
  111.     w.change((0, 0), (docwidth, docheight))
  112.     #
  113.     # Show selection, or forget it if out of range
  114.     #
  115.     showsel(w, w.begindrawing())
  116.     if not w.selshown: w.selection = (-1, -1)
  117.  
  118. def colwidth(coldata): # Subroutine to calculate column width
  119.     maxwidth = 0
  120.     for string, action in coldata:
  121.         width = stdwin.textwidth(string)
  122.         if width > maxwidth: maxwidth = width
  123.     return maxwidth
  124.  
  125. def draw(w, ((left, top), (right, bottom))): # Draw method
  126.     ileft = whichcol(w, left)
  127.     iright = whichcol(w, right-1) + 1
  128.     if iright > len(w.data): iright = len(w.data)
  129.     itop = divmod(top, w.lineheight)[0]
  130.     if itop < 0: itop = 0
  131.     ibottom, remainder = divmod(bottom, w.lineheight)
  132.     if remainder: ibottom = ibottom + 1
  133.     d = w.begindrawing()
  134.     if ileft <= w.selection[0] < iright:
  135.         if itop <= w.selection[1] < ibottom:
  136.             hidesel(w, d)
  137.     d.erase((left, top), (right, bottom))
  138.     for i in range(ileft, iright):
  139.         col = w.data[i]
  140.         jbottom = len(col)
  141.         if ibottom < jbottom: jbottom = ibottom
  142.         h = w.colstarts[i]
  143.         v = itop * w.lineheight
  144.         for j in range(itop, jbottom):
  145.             string, action = col[j]
  146.             d.text((h, v), string)
  147.             v = v + w.lineheight
  148.     showsel(w, d)
  149.  
  150. def mup(w, detail): # Mouse up method
  151.     (h, v), nclicks, button, mask = detail
  152.     icol = whichcol(w, h)
  153.     if 0 <= icol < len(w.data):
  154.         irow = divmod(v, w.lineheight)[0]
  155.         col = w.data[icol]
  156.         if 0 <= irow < len(col):
  157.             string, action = col[irow]
  158.             action(w, string, (icol, irow), detail)
  159.  
  160. def whichcol(w, h): # Return column number (may be >= len(w.data))
  161.     for icol in range(0, len(w.data)):
  162.         if h < w.colstarts[icol+1]:
  163.             return icol
  164.     return len(w.data)
  165.  
  166. def arrow(w, type):
  167.     if type == WC_LEFT:
  168.         incr = -1, 0
  169.     elif type == WC_UP:
  170.         incr = 0, -1
  171.     elif type == WC_RIGHT:
  172.         incr = 1, 0
  173.     elif type == WC_DOWN:
  174.         incr = 0, 1
  175.     else:
  176.         return
  177.     icol, irow = w.lastselection
  178.     icol = icol + incr[0]
  179.     if icol < 0: icol = len(w.data)-1
  180.     if icol >= len(w.data): icol = 0
  181.     if 0 <= icol < len(w.data):
  182.         irow = irow + incr[1]
  183.         if irow < 0: irow = len(w.data[icol]) - 1
  184.         if irow >= len(w.data[icol]): irow = 0
  185.     else:
  186.         irow = 0
  187.     if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
  188.         w.lastselection = icol, irow
  189.         string, action = w.data[icol][irow]
  190.         detail = (0, 0), 1, 1, 1
  191.         action(w, string, (icol, irow), detail)
  192.  
  193.  
  194. # Selection management
  195. # TO DO: allow multiple selected entries
  196.  
  197. def select(w, selection): # Public function to set the item selection
  198.     d = w.begindrawing()
  199.     hidesel(w, d)
  200.     w.selection = selection
  201.     showsel(w, d)
  202.     if w.selshown: lastselection = selection
  203.  
  204. def hidesel(w, d): # Hide the selection, if shown
  205.     if w.selshown: invertsel(w, d)
  206.  
  207. def showsel(w, d): # Show the selection, if hidden
  208.     if not w.selshown: invertsel(w, d)
  209.  
  210. def invertsel(w, d): # Invert the selection, if valid
  211.     icol, irow = w.selection
  212.     if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
  213.         left = w.colstarts[icol]
  214.         right = w.colstarts[icol+1]
  215.         top = irow * w.lineheight
  216.         bottom = (irow+1) * w.lineheight
  217.         d.invert((left, top), (right, bottom))
  218.         w.selshown = (not w.selshown)
  219.  
  220.  
  221. # Demonstration
  222.  
  223. def demo_action(w, string, (icol, irow), detail): # Action function for demo
  224.     select(w, (irow, icol))
  225.  
  226. def demo(): # Demonstration
  227.     da = demo_action # shorthand
  228.     col0 = [('a1', da), ('bbb1', da), ('c1', da)]
  229.     col1 = [('a2', da), ('bbb2', da)]
  230.     col2 = [('a3', da), ('b3', da), ('c3', da), ('d4', da), ('d5', da)]
  231.     col3 = []
  232.     for i in range(1, 31): col3.append('xxx' + `i`, da)
  233.     data = [col0, col1, col2, col3]
  234.     w = open('tablewin.demo', data)
  235.     gwin.mainloop()
  236.     return w
  237.