4
__version__ = "$Revision: 1.5 $"
5
__date__ = "$Date: 2004/08/12 19:18:54 $"
8
from PythonCard import clipboard, dialog, graphic, model
9
from PythonCard.turtle import AbstractTurtle, BitmapTurtle
14
class LSystem(model.Background):
16
def on_initialize(self, event):
18
self.on_iterations_select(None)
19
self.on_angle_select(None)
21
def on_iterations_select(self, event):
22
self.components.iterationDisplay.text = \
23
str(self.components.iterations.value)
25
def on_angle_select(self, event):
26
self.components.angleDisplay.text = \
27
str(self.components.angle.value)
29
def on_angleDisplay_textUpdate(self, event):
30
self.components.angle.value = \
31
int(self.components.angleDisplay.text)
33
def on_Render_command(self, event):
34
self.statusBar.text = "Drawing, please wait..."
35
starttime = time.time()
37
fractalString = self.expand(
38
self.components.scriptField.text,
39
self.components.iterations.value)
41
angle = self.components.angle.value
42
self.components.bufOff.autoRefresh = False
43
bounds = drawAbstractFractal(
48
width, height = self.components.bufOff.size
50
(width - 2 * borderWidth) / (bounds[2]-bounds[0]),
51
(height - 2 * borderWidth) / (bounds[3]-bounds[1]))
52
startPos = (bounds[0] * -scale + borderWidth,
53
bounds[1] * -scale + borderWidth)
54
self.components.bufOff.autoRefresh = True
62
stoptime = time.time()
63
self.statusBar.text = "Draw time: %.2f seconds" % (stoptime - starttime)
65
def drawFractal(self, aFractalString, color, legLength, angle, startPos):
66
self.components.bufOff.clear()
67
t = BitmapTurtle(self.components.bufOff)
70
t.moveTo(startPos[0], startPos[1])
71
for char in aFractalString:
85
def expand(self, fractalRules, iterations):
86
lines = fractalRules.upper().split('\n')
89
name, value = rule.split('=')
90
assert(name=='AXIOM' or len(name)==1)
93
for i in range(iterations):
95
for pos, char in enumerate(l):
96
repl = rules.get(char, None)
102
def initSizers(self):
103
sizer1 = wx.BoxSizer(wx.VERTICAL)
104
comp = self.components
105
flags = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_BOTTOM
106
# Mac wxButton needs 7 pixels on bottom and right
108
sizer1.Add(comp.btnColor, 0, flags, macPadding)
109
sizer1.Add(comp.bufOff, 1, wx.EXPAND)
112
sizer1.SetSizeHints(self)
113
self.panel.SetSizer(sizer1)
114
self.panel.SetAutoLayout(1)
117
def on_btnColor_mouseClick(self, event):
118
result = dialog.colorDialog(self)
120
self.components.bufOff.foregroundColor = result.color
121
event.target.backgroundColor = result.color
124
result = dialog.openFileDialog(None, "Import which file?")
126
path = result.paths[0]
127
os.chdir(os.path.dirname(path))
129
bmp = graphic.Bitmap(self.filename)
130
self.components.bufOff.drawBitmap(bmp, (0, 0))
132
def on_menuFileOpen_select(self, event):
135
def on_menuFileSaveAs_select(self, event):
136
if self.filename is None:
140
path, filename = os.path.split(self.filename)
141
result = dialog.saveFileDialog(None, "Save As", path, filename)
143
path = result.paths[0]
144
fileType = graphic.bitmapType(path)
147
bmp = self.components.bufOff.getBitmap()
148
bmp.SaveFile(path, fileType)
155
def on_menuEditCopy_select(self, event):
156
widget = self.findFocus()
157
if hasattr(widget, 'editable') and widget.canCopy():
160
clipboard.setClipboard(self.components.bufOff.getBitmap())
162
def on_menuEditPaste_select(self, event):
163
widget = self.findFocus()
164
if hasattr(widget, 'editable') and widget.canPaste():
167
bmp = clipboard.getClipboard()
168
if isinstance(bmp, wx.Bitmap):
169
self.components.bufOff.drawBitmap(bmp)
171
def on_editClear_command(self, event):
172
self.components.bufOff.clear()
174
def drawAbstractFractal(aFractalString, legLength, angle, startPos):
175
def recalcBounds(bounds, turtle):
176
x, y = turtle.getXY()
177
bounds[0] = min(bounds[0], x)
178
bounds[1] = min(bounds[1], y)
179
bounds[2] = max(bounds[2], x)
180
bounds[3] = max(bounds[3], y)
182
t = AbstractTurtle((1,1))
184
t.moveTo(startPos[0], startPos[1])
185
bounds = list(startPos + startPos)
186
for char in aFractalString:
189
recalcBounds(bounds, t)
192
recalcBounds(bounds, t)
203
from PythonCard.tests import pyunit
205
class LSystemTests(pyunit.TestCase):
212
def testBoundsCheckBackwardMoves(self):
213
bounds = drawAbstractFractal('BB+B', 1, 90, (10.0,20.0))
214
# remember that down is positive in this coordinate system
215
self.assertEqual([9.0, 20.0, 10.0, 22.0], bounds)
217
def testBoundsCheckForwardMoves(self):
218
bounds = drawAbstractFractal('FF-F', 1, 90, (10.0,20.0))
219
# remember that down is positive in this coordinate system
220
self.assertEqual([9.0, 18.0, 10.0, 20.0], bounds)
222
if __name__ == '__main__':
223
app = model.Application(LSystem)