summaryrefslogtreecommitdiffstats
path: root/Lib/lib-stdwin/srcwin.py
blob: 3f323bad53a427b181648405dd8bf6e29e00ce0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# srcwin.py -- a source listing window

import stdwin
from stdwinevents import *
import basewin

WIDTH = 40
MAXHEIGHT = 24

class SourceWindow(basewin.BaseWindow):
	
	def init(self, filename):
		self.filename = filename
		#
		f = open(self.filename, 'r') # raise exception if not found
		self.contents = f.read()
		f.seek(0)
		self.linecount = len(f.readlines())
		f.close()
		#
		self.lineheight = lh = stdwin.lineheight()
		self.leftmargin = stdwin.textwidth('00000000')
		self.rightmargin = 30000 # Infinity
		self.bottom = lh * self.linecount
		#
		stdwin.setdefwinpos(0, 0)
		width = WIDTH*stdwin.textwidth('0')
		height = lh*min(MAXHEIGHT, self.linecount)
		stdwin.setdefwinsize(width, height)
		self = basewin.BaseWindow.init(self, filename)
		#
		self.win.setdocsize(0, self.bottom + lh)
		self.initeditor()
		return self
	
	def initeditor(self):
		r = (self.leftmargin, 0), (self.rightmargin, self.bottom)
		self.editor = self.win.textcreate(r)
		self.editor.settext(self.contents)
	
	def closeeditor(self):
		self.editor.close()
	
	def reopen(self):
		self.closeeditor()
		basewin.BaseWindow.reopen(self)
		self.initeditor()
	
	def close(self):
		self.closeeditor()
		basewin.BaseWindow.close(self)
	
	# Override this method to format line numbers differently
	def getmark(self, lineno):
		return `lineno`
	
	def dispatch(self, event):
		if event[0] == WE_NULL: return # Dummy tested by mainloop
		if event[0] == WE_DRAW or not self.editor.event(event):
			basewin.BaseWindow.dispatch(self, event)
	
	def draw(self, detail):
		dummy = self.editor.draw(detail)
		# Draw line numbers
		(left, top), (right, bottom) = detail
		topline = top/self.lineheight
		botline = bottom/self.lineheight + 1
		botline = min(self.linecount, botline)
		d = self.win.begindrawing()
		try:
			h, v = 0, self.lineheight * topline
			for lineno in range(topline+1, botline+1):
				d.text((h, v), self.getmark(lineno))
				v = v + self.lineheight
		finally:
			d.close()
	
	def changemark(self, lineno):
		left = 0
		top = (lineno-1) * self.lineheight
		right = self.leftmargin
		bottom = lineno * self.lineheight
		d = self.win.begindrawing()
		try:
			d.erase((left, top), (right, bottom))
			d.text((left, top), self.getmark(lineno))
		finally:
			d.close()

	def showline(self, lineno):
		left = 0
		top = (lineno-1) * self.lineheight
		right = self.leftmargin
		bottom = lineno * self.lineheight
		self.win.show((left, top), (right, bottom))


TESTFILE = 'srcwin.py'

def test():
	import mainloop
	sw = SourceWindow().init(TESTFILE)
	mainloop.mainloop()