srcwin.py 3.06 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2 3 4 5 6 7 8 9
# srcwin.py -- a source listing window

import stdwin
from stdwinevents import *
import basewin

WIDTH = 40
MAXHEIGHT = 24

10 11

class TextWindow(basewin.BaseWindow):
Guido van Rossum's avatar
Guido van Rossum committed
12
	
13
	def __init__(self, title, contents):
14 15
		self.contents = contents
		self.linecount = countlines(self.contents)
Guido van Rossum's avatar
Guido van Rossum committed
16 17
		#
		self.lineheight = lh = stdwin.lineheight()
18 19
		self.leftmargin = self.getmargin()
		self.top = 0
Guido van Rossum's avatar
Guido van Rossum committed
20 21 22 23 24 25
		self.rightmargin = 30000 # Infinity
		self.bottom = lh * self.linecount
		#
		width = WIDTH*stdwin.textwidth('0')
		height = lh*min(MAXHEIGHT, self.linecount)
		stdwin.setdefwinsize(width, height)
26
		basewin.BaseWindow.__init__(self, title)
Guido van Rossum's avatar
Guido van Rossum committed
27
		#
28
		self.win.setdocsize(0, self.bottom)
Guido van Rossum's avatar
Guido van Rossum committed
29 30 31
		self.initeditor()
	
	def initeditor(self):
32
		r = (self.leftmargin, self.top), (self.rightmargin, self.bottom)
Guido van Rossum's avatar
Guido van Rossum committed
33 34 35 36 37 38
		self.editor = self.win.textcreate(r)
		self.editor.settext(self.contents)
	
	def closeeditor(self):
		self.editor.close()
	
39 40 41 42
#	def reopen(self):
#		self.closeeditor()
#		basewin.BaseWindow.reopen(self)
#		self.initeditor()
Guido van Rossum's avatar
Guido van Rossum committed
43
	
44
	# Override the following two methods to format line numbers differently
Guido van Rossum's avatar
Guido van Rossum committed
45 46 47 48
	
	def getmark(self, lineno):
		return `lineno`
	
49 50 51 52 53
	def getmargin(self):
		return stdwin.textwidth(`self.linecount + 1` + ' ')
	
	# Event dispatcher, called from mainloop.mainloop()
	
Guido van Rossum's avatar
Guido van Rossum committed
54 55 56 57 58
	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)
	
59 60 61 62 63 64
	# Event handlers
	
	def close(self):
		self.closeeditor()
		basewin.BaseWindow.close(self)
	
Guido van Rossum's avatar
Guido van Rossum committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
	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()
	
81 82 83
	# Calls from outside
	
	def changemark(self, lineno): # redraw the mark for a line
Guido van Rossum's avatar
Guido van Rossum committed
84 85 86 87 88 89 90 91 92 93 94
		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()

95
	def showline(self, lineno): # scroll to make a line visible
Guido van Rossum's avatar
Guido van Rossum committed
96 97 98 99 100 101 102
		left = 0
		top = (lineno-1) * self.lineheight
		right = self.leftmargin
		bottom = lineno * self.lineheight
		self.win.show((left, top), (right, bottom))


103 104 105 106 107 108 109 110 111 112 113 114
# Subroutine to count the number of lines in a string

def countlines(text):
	n = 0
	for c in text:
		if c == '\n': n = n+1
	if text and text[-1] != '\n': n = n+1 # Partial last line
	return n


class SourceWindow(TextWindow):

115
	def __init__(self, filename):
116 117 118 119
		self.filename = filename
		f = open(self.filename, 'r')
		contents = f.read()
		f.close()
120
		TextWindow.__init__(self, self.filename, contents)
121 122 123

# ------------------------------ testing ------------------------------

Guido van Rossum's avatar
Guido van Rossum committed
124 125 126 127
TESTFILE = 'srcwin.py'

def test():
	import mainloop
128
	sw = SourceWindow(TESTFILE)
Guido van Rossum's avatar
Guido van Rossum committed
129
	mainloop.mainloop()