summaryrefslogtreecommitdiffstats
path: root/Lib/stdwin/tablewin.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1990-10-13 19:23:40 (GMT)
committerGuido van Rossum <guido@python.org>1990-10-13 19:23:40 (GMT)
commitc636014c430620325f8d213e9ba10d925991b8d7 (patch)
tree058a21f7da3d8c6e7da0756ef7b1402fe7169a1a /Lib/stdwin/tablewin.py
parentdf79a1ee192231a75a381798bb35cefaf6c31a2a (diff)
downloadcpython-c636014c430620325f8d213e9ba10d925991b8d7.zip
cpython-c636014c430620325f8d213e9ba10d925991b8d7.tar.gz
cpython-c636014c430620325f8d213e9ba10d925991b8d7.tar.bz2
Initial revision
Diffstat (limited to 'Lib/stdwin/tablewin.py')
-rwxr-xr-xLib/stdwin/tablewin.py237
1 files changed, 237 insertions, 0 deletions
diff --git a/Lib/stdwin/tablewin.py b/Lib/stdwin/tablewin.py
new file mode 100755
index 0000000..05a954e
--- /dev/null
+++ b/Lib/stdwin/tablewin.py
@@ -0,0 +1,237 @@
+# Module 'tablewin'
+
+# Display a table, with per-item actions:
+
+# A1 | A2 | A3 | .... | AN
+# B1 | B2 | B3 | .... | BN
+# C1 | C2 | C3 | .... | CN
+# .. | .. | .. | .... | ..
+# Z1 | Z2 | Z3 | .... | ZN
+
+# Not all columns need to have the same length.
+# The data structure is a list of columns;
+# each column is a list of items.
+# Each item is a pair of a string and an action procedure.
+# The first item may be a column title.
+
+import stdwin
+import gwin
+
+def open(title, data): # Public function to open a table window
+ #
+ # Set geometry parameters (one day, these may be changeable)
+ #
+ margin = stdwin.textwidth(' ')
+ lineheight = stdwin.lineheight()
+ #
+ # Geometry calculations
+ #
+ colstarts = [0]
+ totwidth = 0
+ maxrows = 0
+ for coldata in data:
+ # Height calculations
+ rows = len(coldata)
+ if rows > maxrows: maxrows = rows
+ # Width calculations
+ width = colwidth(coldata) + margin
+ totwidth = totwidth + width
+ colstarts.append(totwidth)
+ #
+ # Calculate document and window height
+ #
+ docwidth, docheight = totwidth, maxrows*lineheight
+ winwidth, winheight = docwidth, docheight
+ if winwidth > stdwin.textwidth('n')*100: winwidth = 0
+ if winheight > stdwin.lineheight()*30: winheight = 0
+ #
+ # Create the window
+ #
+ stdwin.setdefwinsize(winwidth, winheight)
+ w = gwin.open(title)
+ #
+ # Set properties and override methods
+ #
+ w.data = data
+ w.margin = margin
+ w.lineheight = lineheight
+ w.colstarts = colstarts
+ w.totwidth = totwidth
+ w.maxrows = maxrows
+ w.selection = (-1, -1)
+ w.lastselection = (-1, -1)
+ w.selshown = 0
+ w.setdocsize(docwidth, docheight)
+ w.draw = draw
+ w.mup = mup
+ w.arrow = arrow
+ #
+ # Return
+ #
+ return w
+
+def update(w, data): # Change the data
+ #
+ # Hide selection
+ #
+ hidesel(w, w.begindrawing())
+ #
+ # Get old geometry parameters
+ #
+ margin = w.margin
+ lineheight = w.lineheight
+ #
+ # Geometry calculations
+ #
+ colstarts = [0]
+ totwidth = 0
+ maxrows = 0
+ for coldata in data:
+ # Height calculations
+ rows = len(coldata)
+ if rows > maxrows: maxrows = rows
+ # Width calculations
+ width = colwidth(coldata) + margin
+ totwidth = totwidth + width
+ colstarts.append(totwidth)
+ #
+ # Calculate document and window height
+ #
+ docwidth, docheight = totwidth, maxrows*lineheight
+ #
+ # Set changed properties and change window size
+ #
+ w.data = data
+ w.colstarts = colstarts
+ w.totwidth = totwidth
+ w.maxrows = maxrows
+ w.change((0, 0), (10000, 10000))
+ w.setdocsize(docwidth, docheight)
+ w.change((0, 0), (docwidth, docheight))
+ #
+ # Show selection, or forget it if out of range
+ #
+ showsel(w, w.begindrawing())
+ if not w.selshown: w.selection = (-1, -1)
+
+def colwidth(coldata): # Subroutine to calculate column width
+ maxwidth = 0
+ for string, action in coldata:
+ width = stdwin.textwidth(string)
+ if width > maxwidth: maxwidth = width
+ return maxwidth
+
+def draw(w, ((left, top), (right, bottom))): # Draw method
+ ileft = whichcol(w, left)
+ iright = whichcol(w, right-1) + 1
+ if iright > len(w.data): iright = len(w.data)
+ itop = divmod(top, w.lineheight)[0]
+ if itop < 0: itop = 0
+ ibottom, remainder = divmod(bottom, w.lineheight)
+ if remainder: ibottom = ibottom + 1
+ d = w.begindrawing()
+ if ileft <= w.selection[0] < iright:
+ if itop <= w.selection[1] < ibottom:
+ hidesel(w, d)
+ d.erase((left, top), (right, bottom))
+ for i in range(ileft, iright):
+ col = w.data[i]
+ jbottom = len(col)
+ if ibottom < jbottom: jbottom = ibottom
+ h = w.colstarts[i]
+ v = itop * w.lineheight
+ for j in range(itop, jbottom):
+ string, action = col[j]
+ d.text((h, v), string)
+ v = v + w.lineheight
+ showsel(w, d)
+
+def mup(w, detail): # Mouse up method
+ (h, v), nclicks, button, mask = detail
+ icol = whichcol(w, h)
+ if 0 <= icol < len(w.data):
+ irow = divmod(v, w.lineheight)[0]
+ col = w.data[icol]
+ if 0 <= irow < len(col):
+ string, action = col[irow]
+ action(w, string, (icol, irow), detail)
+
+def whichcol(w, h): # Return column number (may be >= len(w.data))
+ for icol in range(0, len(w.data)):
+ if h < w.colstarts[icol+1]:
+ return icol
+ return len(w.data)
+
+def arrow(w, type):
+ import stdwinsupport
+ S = stdwinsupport
+ if type = S.wc_left:
+ incr = -1, 0
+ elif type = S.wc_up:
+ incr = 0, -1
+ elif type = S.wc_right:
+ incr = 1, 0
+ elif type = S.wc_down:
+ incr = 0, 1
+ else:
+ return
+ icol, irow = w.lastselection
+ icol = icol + incr[0]
+ if icol < 0: icol = len(w.data)-1
+ if icol >= len(w.data): icol = 0
+ if 0 <= icol < len(w.data):
+ irow = irow + incr[1]
+ if irow < 0: irow = len(w.data[icol]) - 1
+ if irow >= len(w.data[icol]): irow = 0
+ else:
+ irow = 0
+ if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
+ w.lastselection = icol, irow
+ string, action = w.data[icol][irow]
+ detail = (0, 0), 1, 1, 1
+ action(w, string, (icol, irow), detail)
+
+
+# Selection management
+# TO DO: allow multiple selected entries
+
+def select(w, selection): # Public function to set the item selection
+ d = w.begindrawing()
+ hidesel(w, d)
+ w.selection = selection
+ showsel(w, d)
+ if w.selshown: lastselection = selection
+
+def hidesel(w, d): # Hide the selection, if shown
+ if w.selshown: invertsel(w, d)
+
+def showsel(w, d): # Show the selection, if hidden
+ if not w.selshown: invertsel(w, d)
+
+def invertsel(w, d): # Invert the selection, if valid
+ icol, irow = w.selection
+ if 0 <= icol < len(w.data) and 0 <= irow < len(w.data[icol]):
+ left = w.colstarts[icol]
+ right = w.colstarts[icol+1]
+ top = irow * w.lineheight
+ bottom = (irow+1) * w.lineheight
+ d.invert((left, top), (right, bottom))
+ w.selshown = (not w.selshown)
+
+
+# Demonstration
+
+def demo_action(w, string, (icol, irow), detail): # Action function for demo
+ select(w, (irow, icol))
+
+def demo(): # Demonstration
+ da = demo_action # shorthand
+ col0 = [('a1', da), ('bbb1', da), ('c1', da)]
+ col1 = [('a2', da), ('bbb2', da)]
+ col2 = [('a3', da), ('b3', da), ('c3', da), ('d4', da), ('d5', da)]
+ col3 = []
+ for i in range(1, 31): col3.append('xxx' + `i`, da)
+ data = [col0, col1, col2, col3]
+ w = open('tablewin.demo', data)
+ gwin.mainloop()
+ return w