blob: a71c568ace9031b4030fa8e912fd7921ef095eb4 [file] [log] [blame]
Guido van Rossumbabe2bf1992-01-22 22:21:31 +00001# srcwin.py -- a source listing window
2
3import stdwin
4from stdwinevents import *
5import basewin
6
7WIDTH = 40
8MAXHEIGHT = 24
9
Guido van Rossum6fd42b81992-01-27 16:58:03 +000010
11class TextWindow(basewin.BaseWindow):
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000012
Guido van Rossum6fd42b81992-01-27 16:58:03 +000013 def init(self, title, contents):
14 self.contents = contents
15 self.linecount = countlines(self.contents)
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000016 #
17 self.lineheight = lh = stdwin.lineheight()
Guido van Rossum6fd42b81992-01-27 16:58:03 +000018 self.leftmargin = self.getmargin()
19 self.top = 0
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000020 self.rightmargin = 30000 # Infinity
21 self.bottom = lh * self.linecount
22 #
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000023 width = WIDTH*stdwin.textwidth('0')
24 height = lh*min(MAXHEIGHT, self.linecount)
25 stdwin.setdefwinsize(width, height)
Guido van Rossum6fd42b81992-01-27 16:58:03 +000026 self = basewin.BaseWindow.init(self, title)
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000027 #
Guido van Rossum6fd42b81992-01-27 16:58:03 +000028 self.win.setdocsize(0, self.bottom)
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000029 self.initeditor()
30 return self
31
32 def initeditor(self):
Guido van Rossum6fd42b81992-01-27 16:58:03 +000033 r = (self.leftmargin, self.top), (self.rightmargin, self.bottom)
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000034 self.editor = self.win.textcreate(r)
35 self.editor.settext(self.contents)
36
37 def closeeditor(self):
38 self.editor.close()
39
Guido van Rossum6fd42b81992-01-27 16:58:03 +000040# def reopen(self):
41# self.closeeditor()
42# basewin.BaseWindow.reopen(self)
43# self.initeditor()
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000044
Guido van Rossum6fd42b81992-01-27 16:58:03 +000045 # Override the following two methods to format line numbers differently
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000046
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000047 def getmark(self, lineno):
48 return `lineno`
49
Guido van Rossum6fd42b81992-01-27 16:58:03 +000050 def getmargin(self):
51 return stdwin.textwidth(`self.linecount + 1` + ' ')
52
53 # Event dispatcher, called from mainloop.mainloop()
54
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000055 def dispatch(self, event):
56 if event[0] == WE_NULL: return # Dummy tested by mainloop
57 if event[0] == WE_DRAW or not self.editor.event(event):
58 basewin.BaseWindow.dispatch(self, event)
59
Guido van Rossum6fd42b81992-01-27 16:58:03 +000060 # Event handlers
61
62 def close(self):
63 self.closeeditor()
64 basewin.BaseWindow.close(self)
65
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000066 def draw(self, detail):
67 dummy = self.editor.draw(detail)
68 # Draw line numbers
69 (left, top), (right, bottom) = detail
70 topline = top/self.lineheight
71 botline = bottom/self.lineheight + 1
72 botline = min(self.linecount, botline)
73 d = self.win.begindrawing()
74 try:
75 h, v = 0, self.lineheight * topline
76 for lineno in range(topline+1, botline+1):
77 d.text((h, v), self.getmark(lineno))
78 v = v + self.lineheight
79 finally:
80 d.close()
81
Guido van Rossum6fd42b81992-01-27 16:58:03 +000082 # Calls from outside
83
84 def changemark(self, lineno): # redraw the mark for a line
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000085 left = 0
86 top = (lineno-1) * self.lineheight
87 right = self.leftmargin
88 bottom = lineno * self.lineheight
89 d = self.win.begindrawing()
90 try:
91 d.erase((left, top), (right, bottom))
92 d.text((left, top), self.getmark(lineno))
93 finally:
94 d.close()
95
Guido van Rossum6fd42b81992-01-27 16:58:03 +000096 def showline(self, lineno): # scroll to make a line visible
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000097 left = 0
98 top = (lineno-1) * self.lineheight
99 right = self.leftmargin
100 bottom = lineno * self.lineheight
101 self.win.show((left, top), (right, bottom))
102
103
Guido van Rossum6fd42b81992-01-27 16:58:03 +0000104# Subroutine to count the number of lines in a string
105
106def countlines(text):
107 n = 0
108 for c in text:
109 if c == '\n': n = n+1
110 if text and text[-1] != '\n': n = n+1 # Partial last line
111 return n
112
113
114class SourceWindow(TextWindow):
115
116 def init(self, filename):
117 self.filename = filename
118 f = open(self.filename, 'r')
119 contents = f.read()
120 f.close()
121 return TextWindow.init(self, self.filename, contents)
122
123# ------------------------------ testing ------------------------------
124
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000125TESTFILE = 'srcwin.py'
126
127def test():
128 import mainloop
129 sw = SourceWindow().init(TESTFILE)
130 mainloop.mainloop()