easycoder 241215.1__py2.py3-none-any.whl → 241218.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of easycoder might be problematic. Click here for more details.
- easycoder/__init__.py +1 -1
- easycoder/ec_renderer.py +65 -60
- {easycoder-241215.1.dist-info → easycoder-241218.1.dist-info}/METADATA +3 -3
- {easycoder-241215.1.dist-info → easycoder-241218.1.dist-info}/RECORD +7 -7
- {easycoder-241215.1.dist-info → easycoder-241218.1.dist-info}/LICENSE +0 -0
- {easycoder-241215.1.dist-info → easycoder-241218.1.dist-info}/WHEEL +0 -0
- {easycoder-241215.1.dist-info → easycoder-241218.1.dist-info}/entry_points.txt +0 -0
easycoder/__init__.py
CHANGED
easycoder/ec_renderer.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import sys, json
|
|
4
4
|
import tkinter as tk
|
|
5
|
-
from PIL import
|
|
5
|
+
from PIL import Image, ImageTk
|
|
6
6
|
|
|
7
7
|
elements = {}
|
|
8
8
|
zlist = []
|
|
@@ -50,8 +50,8 @@ def createScreen(values):
|
|
|
50
50
|
id = list(element)[0]
|
|
51
51
|
values = element[id]
|
|
52
52
|
x1 = values['left']
|
|
53
|
-
x2 = x1 + values['width']
|
|
54
|
-
y1 = values['top']
|
|
53
|
+
x2 = x1 + values['width'] + getScreenLeft(values['parent'])
|
|
54
|
+
y1 = values['top'] + getScreenTop(values['parent'])
|
|
55
55
|
y2 = y1 + values['height']
|
|
56
56
|
if x >= x1 and x < x2 and y >= y1 and y < y2:
|
|
57
57
|
if id in elements:
|
|
@@ -110,16 +110,16 @@ def render(spec, parent):
|
|
|
110
110
|
return args[item]
|
|
111
111
|
return item
|
|
112
112
|
|
|
113
|
-
def renderIntoRectangle(widgetType, values,
|
|
113
|
+
def renderIntoRectangle(widgetType, values, parent, args):
|
|
114
114
|
global zlist
|
|
115
115
|
left = getValue(args, values['left']) if 'left' in values else 10
|
|
116
|
+
screenLeft = left + getScreenLeft(parent)
|
|
116
117
|
top = getValue(args, values['top']) if 'top' in values else 10
|
|
117
|
-
|
|
118
|
-
top = offset['dy'] + top
|
|
118
|
+
screenTop = top + getScreenTop(parent)
|
|
119
119
|
width = getValue(args, values['width']) if 'width' in values else 100
|
|
120
120
|
height = getValue(args, values['height']) if 'height' in values else 100
|
|
121
|
-
right =
|
|
122
|
-
bottom =
|
|
121
|
+
right = screenLeft + width
|
|
122
|
+
bottom = screenTop + height
|
|
123
123
|
fill = values['fill'] if 'fill' in values else None
|
|
124
124
|
outline = values['outline'] if 'outline' in values else None
|
|
125
125
|
if outline != None:
|
|
@@ -127,9 +127,9 @@ def render(spec, parent):
|
|
|
127
127
|
else:
|
|
128
128
|
outlineWidth = 0
|
|
129
129
|
if widgetType == 'rectangle':
|
|
130
|
-
widgetId = getCanvas().create_rectangle(
|
|
130
|
+
widgetId = getCanvas().create_rectangle(screenLeft, screenTop, right, bottom, fill=fill, outline=outline, width=outlineWidth)
|
|
131
131
|
elif widgetType == 'ellipse':
|
|
132
|
-
widgetId = getCanvas().create_oval(
|
|
132
|
+
widgetId = getCanvas().create_oval(screenLeft, screenTop, right, bottom, fill=fill, outline=outline, width=outlineWidth)
|
|
133
133
|
else:
|
|
134
134
|
return f'Unknown widget type \'{widgetType}\''
|
|
135
135
|
if 'name' in values:
|
|
@@ -144,6 +144,7 @@ def render(spec, parent):
|
|
|
144
144
|
"top": top,
|
|
145
145
|
"width": width,
|
|
146
146
|
"height": height,
|
|
147
|
+
"parent": parent,
|
|
147
148
|
"children": []
|
|
148
149
|
}
|
|
149
150
|
elements[widgetName] = widgetSpec
|
|
@@ -154,54 +155,49 @@ def render(spec, parent):
|
|
|
154
155
|
for item in children:
|
|
155
156
|
if item in values:
|
|
156
157
|
child = values[item]
|
|
157
|
-
childSpec = renderWidget(child,
|
|
158
|
+
childSpec = renderWidget(child, widgetSpec, args)
|
|
158
159
|
widgetSpec['children'].append(childSpec['name'])
|
|
159
160
|
else:
|
|
160
161
|
child = values[children]
|
|
161
|
-
childSpec = renderWidget(child,
|
|
162
|
+
childSpec = renderWidget(child, widgetSpec, args)
|
|
162
163
|
widgetSpec['children'].append(childSpec['name'])
|
|
163
164
|
return widgetSpec
|
|
164
165
|
|
|
165
|
-
def renderText(values,
|
|
166
|
+
def renderText(values, parent, args):
|
|
166
167
|
left = getValue(args, values['left']) if 'left' in values else 10
|
|
168
|
+
screenLeft = left + getScreenLeft(parent)
|
|
167
169
|
top = getValue(args, values['top']) if 'top' in values else 10
|
|
168
|
-
|
|
169
|
-
top = offset['dy'] + top
|
|
170
|
+
screenTop = top + getScreenTop(parent)
|
|
170
171
|
width = getValue(args, values['width']) if 'width' in values else 100
|
|
171
172
|
height = getValue(args, values['height']) if 'height' in values else 100
|
|
172
|
-
right = left + width
|
|
173
|
-
bottom = top + height
|
|
174
173
|
shape = getValue(args, values['shape']) if 'shape' in values else 'rectangle'
|
|
175
|
-
fill = getValue(args, values['fill']) if 'fill' in values else None
|
|
176
174
|
outline = getValue(args, values['outline']) if 'outline' in values else None
|
|
177
|
-
outlineWidth = getValue(args, values['outlineWidth']) if 'outlineWidth' in values else 0 if outline == None else 1
|
|
178
175
|
color = getValue(args, values['color']) if 'color' in values else None
|
|
179
176
|
text = getValue(args, values['text']) if 'text' in values else ''
|
|
180
177
|
fontFace = getValue(args, values['fontFace']) if 'fontFace' in values else 'Helvetica'
|
|
181
178
|
fontWeight = getValue(args, values['fontWeight']) if 'fontWeight' in values else 'normal'
|
|
182
|
-
|
|
183
|
-
fontTop = top + height/2
|
|
179
|
+
fontTop = int(round(screenTop + height/2))
|
|
184
180
|
if 'fontSize' in values:
|
|
185
181
|
fontSize = getValue(args, values['fontSize'])
|
|
186
|
-
fontTop =
|
|
187
|
-
|
|
182
|
+
fontTop = int(round(screenTop + height/2 - fontSize/4))
|
|
183
|
+
else:
|
|
184
|
+
fontSize = int(round(height*2/5) if shape == 'ellipse' else round(height*3/5))
|
|
185
|
+
fontTop -= int(round(screenTop + height/2 - fontSize/5))
|
|
186
|
+
adjust = int(round(fontSize/5)) if shape == 'ellipse' else 0
|
|
188
187
|
align = getValue(args, values['align']) if 'align' in values else 'center'
|
|
189
188
|
if align == 'left':
|
|
190
|
-
xoff = round(fontSize/5)
|
|
189
|
+
xoff = int(round(fontSize/5))
|
|
191
190
|
anchor = 'w'
|
|
192
191
|
elif align == 'right':
|
|
193
|
-
xoff = width - round(fontSize/5)
|
|
192
|
+
xoff = width - int(round(fontSize/5))
|
|
194
193
|
anchor = 'e'
|
|
195
194
|
else:
|
|
196
|
-
xoff = width/2
|
|
195
|
+
xoff = int(round(width/2))
|
|
197
196
|
anchor = 'center'
|
|
198
197
|
if xoff < 3:
|
|
199
198
|
xoff = 3
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
else:
|
|
203
|
-
containerId = getCanvas().create_rectangle(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
|
|
204
|
-
textId = canvas.create_text(left + xoff, fontTop + adjust, fill=color, font=f'"{fontFace}" {fontSize} {fontWeight}', text=text, anchor=anchor)
|
|
199
|
+
xoff -= int(round(fontSize/4))
|
|
200
|
+
textId = canvas.create_text(screenLeft + xoff, fontTop + adjust, fill=color, font=f'"{fontFace}" {fontSize} {fontWeight}', text=text, anchor=anchor)
|
|
205
201
|
if 'name' in values:
|
|
206
202
|
widgetName = getValue(args, values['name'])
|
|
207
203
|
else:
|
|
@@ -210,87 +206,84 @@ def render(spec, parent):
|
|
|
210
206
|
"type": "text",
|
|
211
207
|
"name": widgetName,
|
|
212
208
|
"id": textId,
|
|
213
|
-
"containerId": containerId,
|
|
214
209
|
"left": left,
|
|
215
210
|
"top": top,
|
|
216
211
|
"width": width,
|
|
217
|
-
"height": height
|
|
212
|
+
"height": height,
|
|
213
|
+
"parent": parent
|
|
218
214
|
}
|
|
219
215
|
elements[widgetName] = widgetSpec
|
|
220
216
|
zlist.append({widgetName: widgetSpec})
|
|
221
217
|
return widgetSpec
|
|
222
218
|
|
|
223
|
-
def renderImage(values,
|
|
219
|
+
def renderImage(values, parent, args):
|
|
224
220
|
global images
|
|
225
221
|
left = getValue(args, values['left']) if 'left' in values else 10
|
|
222
|
+
screenLeft = left + getScreenLeft(parent)
|
|
226
223
|
top = getValue(args, values['top']) if 'top' in values else 10
|
|
227
|
-
|
|
228
|
-
top = offset['dy'] + top
|
|
224
|
+
screenTop = top + getScreenTop(parent)
|
|
229
225
|
width = getValue(args, values['width']) if 'width' in values else 100
|
|
230
|
-
|
|
231
|
-
right = left + width
|
|
232
|
-
bottom = top + height
|
|
233
|
-
src = getValue(args, values['src']) if 'src' in values else None
|
|
234
|
-
containerId = getCanvas().create_rectangle(left, top, right, bottom, width=0)
|
|
226
|
+
source = getValue(args, values['source']) if 'source' in values else None
|
|
235
227
|
if 'name' in values:
|
|
236
228
|
widgetName = values['name']
|
|
237
229
|
else:
|
|
238
230
|
widgetName = None
|
|
231
|
+
if source == None:
|
|
232
|
+
raise(Exception(f'No image source given for \'{id}\''))
|
|
233
|
+
img = (Image.open(source))
|
|
234
|
+
height = int(round(img.height * width / img.width))
|
|
235
|
+
resized_image= img.resize((width, height), Image.LANCZOS)
|
|
236
|
+
new_image= ImageTk.PhotoImage(resized_image)
|
|
237
|
+
imageid = getCanvas().create_image(screenLeft, screenTop, anchor='nw', image=new_image)
|
|
238
|
+
images[widgetName] = {'id': imageid, "image": new_image}
|
|
239
239
|
widgetSpec = {
|
|
240
240
|
"type": "image",
|
|
241
241
|
"nme": widgetName,
|
|
242
|
-
"id": containerId,
|
|
243
242
|
"left": left,
|
|
244
243
|
"top": top,
|
|
245
244
|
"width": width,
|
|
246
|
-
"height": height
|
|
245
|
+
"height": height,
|
|
246
|
+
"source": source,
|
|
247
|
+
"parent": parent
|
|
247
248
|
}
|
|
248
249
|
elements[widgetName] = widgetSpec
|
|
249
250
|
zlist.append({widgetName: widgetSpec})
|
|
250
|
-
if src == None:
|
|
251
|
-
raise(Exception(f'No image source given for \'{id}\''))
|
|
252
|
-
img = (Image.open(src))
|
|
253
|
-
resized_image= img.resize((width, height), Image.ANTIALIAS)
|
|
254
|
-
new_image= ImageTk.PhotoImage(resized_image)
|
|
255
|
-
imageid = getCanvas().create_image(left, top, anchor='nw', image=new_image)
|
|
256
|
-
images[containerId] = {'id': imageid, "image": new_image}
|
|
257
251
|
return widgetSpec
|
|
258
252
|
|
|
259
253
|
# Create a canvas or render a widget
|
|
260
|
-
def renderWidget(widget,
|
|
254
|
+
def renderWidget(widget, parent, args):
|
|
261
255
|
widgetType = widget['type']
|
|
262
256
|
if widgetType in ['rectangle', 'ellipse']:
|
|
263
|
-
return renderIntoRectangle(widgetType, widget,
|
|
257
|
+
return renderIntoRectangle(widgetType, widget, parent, args)
|
|
264
258
|
elif widgetType == 'text':
|
|
265
|
-
return renderText(widget,
|
|
259
|
+
return renderText(widget, parent, args)
|
|
266
260
|
elif widgetType == 'image':
|
|
267
|
-
return renderImage(widget,
|
|
261
|
+
return renderImage(widget, parent, args)
|
|
268
262
|
|
|
269
263
|
# Render a complete specification
|
|
270
|
-
def renderSpec(spec,
|
|
264
|
+
def renderSpec(spec, parent, args):
|
|
271
265
|
widgets = spec['#']
|
|
272
266
|
# If a list, iterate it
|
|
273
267
|
if type(widgets) is list:
|
|
274
268
|
for widget in widgets:
|
|
275
|
-
renderWidget(spec[widget],
|
|
269
|
+
renderWidget(spec[widget], parent, args)
|
|
276
270
|
# Otherwise, process the single widget
|
|
277
271
|
else:
|
|
278
|
-
renderWidget(spec[widgets],
|
|
272
|
+
renderWidget(spec[widgets], parent, args)
|
|
279
273
|
|
|
280
274
|
# Main entry point
|
|
281
|
-
offset = {'dx': 0, 'dy': 0}
|
|
282
275
|
if parent != screen:
|
|
283
276
|
RuntimeError(None, 'Can\'t yet render into parent widget')
|
|
284
277
|
|
|
285
278
|
# If it'a string, process it
|
|
286
279
|
if type(spec) is str:
|
|
287
|
-
renderSpec(json.loads(spec),
|
|
280
|
+
renderSpec(json.loads(spec), None, {})
|
|
288
281
|
|
|
289
282
|
# If it's a 'dict', extract the spec and the args
|
|
290
283
|
if type(spec) is dict:
|
|
291
284
|
args = spec['args']
|
|
292
285
|
spec = json.loads(spec['spec'])
|
|
293
|
-
renderSpec(spec,
|
|
286
|
+
renderSpec(spec, None, args)
|
|
294
287
|
|
|
295
288
|
# Get the widget whose name is given
|
|
296
289
|
def getElement(name):
|
|
@@ -328,3 +321,15 @@ def moveElementTo(name, left, top):
|
|
|
328
321
|
def getAttribute(name, attribute):
|
|
329
322
|
element = getElement(name)
|
|
330
323
|
return element[attribute]
|
|
324
|
+
|
|
325
|
+
# Get the screen left position of an element
|
|
326
|
+
def getScreenLeft(element):
|
|
327
|
+
if element == None:
|
|
328
|
+
return 0
|
|
329
|
+
return element['left'] + getScreenLeft(element['parent'])
|
|
330
|
+
|
|
331
|
+
# Get the screen top position of an element
|
|
332
|
+
def getScreenTop(element):
|
|
333
|
+
if element == None:
|
|
334
|
+
return 0
|
|
335
|
+
return element['top'] + getScreenTop(element['parent'])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 241218.1
|
|
4
4
|
Summary: Rapid scripting in English
|
|
5
5
|
Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
|
|
6
6
|
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
@@ -62,7 +62,7 @@ Here in the repository is a folder called `scripts` containing some sample scrip
|
|
|
62
62
|
## Graphical programmming
|
|
63
63
|
**_EasyCoder_** is currently being extended to include a graphical programming environment. A single demo script `graphics-demo.ecs` is included in the `scripts` directory. To run it, first install the Python graphics library if it's not already present on your system. On Linux this is done with `sudo apt install python3-tk`. On Windows it's `pip install tk`. Then give the command `easycoder -g scripts/graphics-demo.ecs`.
|
|
64
64
|
|
|
65
|
-
As development progresses this demo script will be extended to include new features as they are added. **_EasyCoder_** graphics are handled by a library module, `ec_renderer` that can be used outside of the **
|
|
65
|
+
As development progresses this demo script will be extended to include new features as they are added. **_EasyCoder_** graphics are handled by a library module, `ec_renderer` that can be used outside of the **_EasyCoder_** environment, in other Python programs.
|
|
66
66
|
|
|
67
67
|
## EasyCoder programming reference
|
|
68
68
|
|
|
@@ -74,5 +74,5 @@ The language comprises a general-purpose core package, which can be enhanced by
|
|
|
74
74
|
|
|
75
75
|
**_EasyCoder_** can be extended to add new functionality with the use of 'plugins'. These contain compiler and runtime modules for the added language features. **_EasyCoder_** can use the added keywords, values and conditions freely; the effect is completely seamless. There is an outline example in the `plugins` directory called `example.py`, which comprises a module called `Points` with new language syntax to deal with two-valued items such as coordinates. In the `scripts` directory there is `points.ecs`, which exercises the new functionality.
|
|
76
76
|
|
|
77
|
-
A plugin can act as a wrapper around any Python functionality that has a sensible API, thereby hiding its complexity. The only challenge is to devise an unambiguous syntax that doesn't clash with anything already existing in **_EasyCoder_
|
|
77
|
+
A plugin can act as a wrapper around any Python functionality that has a sensible API, thereby hiding its complexity. The only challenge is to devise an unambiguous syntax that doesn't clash with anything already existing in **_EasyCoder_**.
|
|
78
78
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
easycoder/__init__.py,sha256=
|
|
1
|
+
easycoder/__init__.py,sha256=k7jfdc4pthQcQKvNzXXUQGWfqAU8_YxU1NXjra0hOsE,289
|
|
2
2
|
easycoder/ec_classes.py,sha256=mRvIk2d-yc20u54oX8fauKeYy-z_g30Otbl-dn5O6T4,1486
|
|
3
3
|
easycoder/ec_compiler.py,sha256=s7M3Jl6z0X_tp-QW4p3v7ac2fhL_bf0uw1GHebqt1Ug,4638
|
|
4
4
|
easycoder/ec_condition.py,sha256=WSbONo4zs2sX1icOVpscZDFSCAEFmTsquoc2RGcLx_k,763
|
|
@@ -6,11 +6,11 @@ easycoder/ec_core.py,sha256=NfXNTyxmsU4_f3JTTFMUzgsfCRL9se8rdVfwqBC_1wM,76452
|
|
|
6
6
|
easycoder/ec_graphics.py,sha256=qHkZkpT5WM0Y-vHXXLoiqGGS_1qWiajKBYqS1MRSicA,12786
|
|
7
7
|
easycoder/ec_handler.py,sha256=WDDIz0awD3vSQZ149rgbUWsClt6zXqED8ByXQJ5p1Ds,2200
|
|
8
8
|
easycoder/ec_program.py,sha256=MHPHEYHoU5zUVsnkL30kyUxtFph-8naVlDGN2hHsKpw,8103
|
|
9
|
-
easycoder/ec_renderer.py,sha256=
|
|
9
|
+
easycoder/ec_renderer.py,sha256=w3qf-CZlnA-jKcflT8PPzX7NUDJkqrl8w692-rwU3Y8,12122
|
|
10
10
|
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
11
11
|
easycoder/ec_value.py,sha256=aOvSF6bM1iKpcLLm0zyGerxHixBkyjE3iYl1Bx6jmzU,2381
|
|
12
|
-
easycoder-
|
|
13
|
-
easycoder-
|
|
14
|
-
easycoder-
|
|
15
|
-
easycoder-
|
|
16
|
-
easycoder-
|
|
12
|
+
easycoder-241218.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
13
|
+
easycoder-241218.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
14
|
+
easycoder-241218.1.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
|
|
15
|
+
easycoder-241218.1.dist-info/METADATA,sha256=ooonquwbm7yneNnmOFldtcEYhHMxyXyUwCanVjXYRnE,4098
|
|
16
|
+
easycoder-241218.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|