Mercurial > cpython-lru_cache-weakref
annotate Lib/lib-stdwin/tablewin.py @ 4566:6403c94de50d legacy-trunk
Added safeguard against failure in __del__.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Wed, 27 Nov 1996 19:39:58 +0000 |
| parents | 913fc9ff43ac |
| children |
| rev | line source |
|---|---|
| 5 | 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 | |
| 533 | 19 from stdwinevents import * |
| 5 | 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): | |
| 559 | 167 if type == WC_LEFT: |
| 5 | 168 incr = -1, 0 |
| 559 | 169 elif type == WC_UP: |
| 5 | 170 incr = 0, -1 |
| 559 | 171 elif type == WC_RIGHT: |
| 5 | 172 incr = 1, 0 |
| 559 | 173 elif type == WC_DOWN: |
| 5 | 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 = [] | |
|
4365
913fc9ff43ac
Change to always call list.append with a single argument.
Guido van Rossum <guido@python.org>
parents:
559
diff
changeset
|
232 for i in range(1, 31): col3.append(('xxx' + `i`, da)) |
| 5 | 233 data = [col0, col1, col2, col3] |
| 234 w = open('tablewin.demo', data) | |
| 235 gwin.mainloop() | |
| 236 return w |
