Skip to content

Commit ffac4e3

Browse files
committed
v211215.1
1 parent c1fb4de commit ffac4e3

File tree

7 files changed

+205
-106
lines changed

7 files changed

+205
-106
lines changed

dist/easycoder-241212.1.tar.gz

-42.9 KB
Binary file not shown.

easycoder/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
from .ec_value import *
1111
from .ec_graphics import *
1212

13-
__version__ = "241212.1"
13+
__version__ = "241215.1"

easycoder/ec_graphics.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from easycoder import FatalError, RuntimeError, Handler
1+
from .ec_classes import FatalError, RuntimeError
2+
from .ec_handler import Handler
23
from .ec_renderer import *
34

45
class Graphics(Handler):
@@ -29,6 +30,8 @@ def r_attach(self, command):
2930
if element == None:
3031
FatalError(self.program.compiler, f'There is no screen element with id \'{id}\'')
3132
return -1
33+
if element['type'] != target['keyword']:
34+
FatalError(self.program.compiler, f'Mismatched element type ({element['type']} and {target['keyword']})')
3235
self.putSymbolValue(target, {'type': 'text', 'content': id})
3336
return self.nextPC()
3437

@@ -79,6 +82,31 @@ def k_image(self, command):
7982
def r_image(self, command):
8083
return self.nextPC()
8184

85+
def k_move(self, command):
86+
if self.nextIsSymbol():
87+
record = self.getSymbolRecord()
88+
if record['keyword'] in ['rectangle', 'ellipse', 'text', 'image']:
89+
command['name'] = record['name']
90+
if self.nextToken() in ['by', 'to']:
91+
command['type'] = self.getToken()
92+
command['x'] = self.nextValue()
93+
command['y'] = self.nextValue()
94+
self.add(command)
95+
return True
96+
return False
97+
98+
def r_move(self, command):
99+
target = self.getVariable(command['name'])
100+
id = self.getSymbolValue(target)['content']
101+
type = command['type']
102+
x = self.getRuntimeValue(command['x'])
103+
y = self.getRuntimeValue(command['y'])
104+
if type == 'by':
105+
moveElement(id, x, y)
106+
elif type == 'to':
107+
moveElementTo(id, x, y)
108+
return self.nextPC()
109+
82110
def k_on(self, command):
83111
token = self.nextToken()
84112
command['type'] = token
@@ -186,9 +214,7 @@ def k_render(self, command):
186214
def r_render(self, command):
187215
parent = command['parent']
188216
value = self.getRuntimeValue(command['value'])
189-
result = render(value, parent)
190-
if result != None:
191-
RuntimeError(command['program'], f'Rendering error: {result}')
217+
render(value, parent)
192218
return self.nextPC()
193219

194220
def k_set(self, command):
@@ -290,13 +316,22 @@ def compileValue(self):
290316
if self.tokenIs('the'):
291317
self.nextToken()
292318
token = self.getToken()
319+
320+
value['type'] = token
321+
293322
if token == 'color':
294323
name = self.nextToken()
295324
value = {}
296325
value['type'] = 'string'
297326
value['content'] = name
298327
return value
299-
328+
329+
elif token == 'attribute':
330+
value['attribute'] = self.nextValue()
331+
if (self.nextIs('of')):
332+
if (self.nextIsSymbol()):
333+
value['name'] = self.getToken()
334+
return value
300335
return None
301336

302337
#############################################################################
@@ -321,6 +356,15 @@ def v_symbol(self, symbolRecord):
321356
return result
322357
else:
323358
return ''
359+
360+
def v_attribute(self, v):
361+
target = self.getVariable(v['name'])
362+
attribute = self.getRuntimeValue(v['attribute'])
363+
name = target['value'][target['index']]['content']
364+
value = {}
365+
value['type'] = 'int'
366+
value['content'] = getAttribute(name, attribute)
367+
return value
324368

325369
#############################################################################
326370
# Compile a condition

easycoder/ec_renderer.py

Lines changed: 82 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -126,40 +126,41 @@ def renderIntoRectangle(widgetType, values, offset, args):
126126
outlineWidth = getValue(args, values['outlineWidth']) if 'outlineWidth' in values else 1
127127
else:
128128
outlineWidth = 0
129-
if widgetType == 'rect':
129+
if widgetType == 'rectangle':
130130
widgetId = getCanvas().create_rectangle(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
131131
elif widgetType == 'ellipse':
132132
widgetId = getCanvas().create_oval(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
133133
else:
134134
return f'Unknown widget type \'{widgetType}\''
135-
if 'id' in values:
136-
id = getValue(args, values['id'])
137-
widgetSpec = {
138-
"id": widgetId,
139-
"left": left,
140-
"top": top,
141-
"width": width,
142-
"height": height
143-
}
144-
elements[id] = widgetSpec
145-
zlist.append({id: widgetSpec})
135+
if 'name' in values:
136+
widgetName = getValue(args, values['name'])
137+
else:
138+
widgetName = None
139+
widgetSpec = {
140+
"type": widgetType,
141+
"name": widgetName,
142+
"id": widgetId,
143+
"left": left,
144+
"top": top,
145+
"width": width,
146+
"height": height,
147+
"children": []
148+
}
149+
elements[widgetName] = widgetSpec
150+
zlist.append({widgetName: widgetSpec})
146151
if '#' in values:
147152
children = values['#']
148153
if type(children) == list:
149154
for item in children:
150155
if item in values:
151156
child = values[item]
152-
result = renderWidget(child, {'dx': left, 'dy': top}, args)
153-
if result != None:
154-
return result
155-
else:
156-
return f'Unable to render \'{item}\''
157+
childSpec = renderWidget(child, {'dx': left, 'dy': top}, args)
158+
widgetSpec['children'].append(childSpec['name'])
157159
else:
158160
child = values[children]
159-
result = renderWidget(child, offset)
160-
if result != None:
161-
return result
162-
return None
161+
childSpec = renderWidget(child, {'dx': left, 'dy': top}, args)
162+
widgetSpec['children'].append(childSpec['name'])
163+
return widgetSpec
163164

164165
def renderText(values, offset, args):
165166
left = getValue(args, values['left']) if 'left' in values else 10
@@ -201,20 +202,24 @@ def renderText(values, offset, args):
201202
else:
202203
containerId = getCanvas().create_rectangle(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
203204
textId = canvas.create_text(left + xoff, fontTop + adjust, fill=color, font=f'"{fontFace}" {fontSize} {fontWeight}', text=text, anchor=anchor)
204-
if 'id' in values:
205-
id = getValue(args, values['id'])
206-
widgetSpec = {
207-
"id": textId,
208-
"containerId": containerId,
209-
"left": left,
210-
"top": top,
211-
"width": width,
212-
"height": height
213-
}
214-
elements[id] = widgetSpec
215-
zlist.append({id: widgetSpec})
216-
return None
217-
205+
if 'name' in values:
206+
widgetName = getValue(args, values['name'])
207+
else:
208+
widgetName = None
209+
widgetSpec = {
210+
"type": "text",
211+
"name": widgetName,
212+
"id": textId,
213+
"containerId": containerId,
214+
"left": left,
215+
"top": top,
216+
"width": width,
217+
"height": height
218+
}
219+
elements[widgetName] = widgetSpec
220+
zlist.append({widgetName: widgetSpec})
221+
return widgetSpec
222+
218223
def renderImage(values, offset, args):
219224
global images
220225
left = getValue(args, values['left']) if 'left' in values else 10
@@ -227,30 +232,34 @@ def renderImage(values, offset, args):
227232
bottom = top + height
228233
src = getValue(args, values['src']) if 'src' in values else None
229234
containerId = getCanvas().create_rectangle(left, top, right, bottom, width=0)
230-
if 'id' in values:
231-
id = values['id']
232-
widgetSpec = {
233-
"id": containerId,
234-
"left": left,
235-
"top": top,
236-
"width": width,
237-
"height": height
238-
}
239-
elements[id] = widgetSpec
240-
zlist.append({id: widgetSpec})
241-
if src == None:
242-
return f'No image source given for \'{id}\''
235+
if 'name' in values:
236+
widgetName = values['name']
237+
else:
238+
widgetName = None
239+
widgetSpec = {
240+
"type": "image",
241+
"nme": widgetName,
242+
"id": containerId,
243+
"left": left,
244+
"top": top,
245+
"width": width,
246+
"height": height
247+
}
248+
elements[widgetName] = widgetSpec
249+
zlist.append({widgetName: widgetSpec})
250+
if src == None:
251+
raise(Exception(f'No image source given for \'{id}\''))
243252
img = (Image.open(src))
244253
resized_image= img.resize((width, height), Image.ANTIALIAS)
245254
new_image= ImageTk.PhotoImage(resized_image)
246255
imageid = getCanvas().create_image(left, top, anchor='nw', image=new_image)
247256
images[containerId] = {'id': imageid, "image": new_image}
248-
return None
257+
return widgetSpec
249258

250259
# Create a canvas or render a widget
251260
def renderWidget(widget, offset, args):
252261
widgetType = widget['type']
253-
if widgetType in ['rect', 'ellipse']:
262+
if widgetType in ['rectangle', 'ellipse']:
254263
return renderIntoRectangle(widgetType, widget, offset, args)
255264
elif widgetType == 'text':
256265
return renderText(widget, offset, args)
@@ -263,12 +272,10 @@ def renderSpec(spec, offset, args):
263272
# If a list, iterate it
264273
if type(widgets) is list:
265274
for widget in widgets:
266-
result = renderWidget(spec[widget], offset, args)
267-
if result != None:
268-
return result
275+
renderWidget(spec[widget], offset, args)
269276
# Otherwise, process the single widget
270277
else:
271-
return renderWidget(spec[widgets], offset, args)
278+
renderWidget(spec[widgets], offset, args)
272279

273280
# Main entry point
274281
offset = {'dx': 0, 'dy': 0}
@@ -277,13 +284,13 @@ def renderSpec(spec, offset, args):
277284

278285
# If it'a string, process it
279286
if type(spec) is str:
280-
return renderSpec(json.loads(spec), offset, {})
287+
renderSpec(json.loads(spec), offset, {})
281288

282289
# If it's a 'dict', extract the spec and the args
283290
if type(spec) is dict:
284291
args = spec['args']
285292
spec = json.loads(spec['spec'])
286-
return renderSpec(spec, offset, args)
293+
renderSpec(spec, offset, args)
287294

288295
# Get the widget whose name is given
289296
def getElement(name):
@@ -302,3 +309,22 @@ def setBackground(name, value):
302309
id = getElement(name)['id']
303310
getCanvas().itemconfig(getElement(name)['id'], fill=value)
304311

312+
# Move an element by an amount
313+
def moveElement(name, dx, dy):
314+
element = getElement(name)
315+
getCanvas().move(element['id'], dx, dy)
316+
element['left'] += dx
317+
element['top'] += dy
318+
for childName in element['children']:
319+
element = getElement(childName)
320+
getCanvas().move(element['id'], dx, dy)
321+
322+
# Move an element to a new location
323+
def moveElementTo(name, left, top):
324+
element = getElement(name)
325+
moveElement(name, left - element['left'], top - element['top'])
326+
327+
# Get an attribute of an element
328+
def getAttribute(name, attribute):
329+
element = getElement(name)
330+
return element[attribute]

0 commit comments

Comments
 (0)