easycoder 241215.1__tar.gz → 241218.1__tar.gz

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.

Files changed (72) hide show
  1. {easycoder-241215.1 → easycoder-241218.1}/PKG-INFO +3 -3
  2. {easycoder-241215.1 → easycoder-241218.1}/README.md +2 -2
  3. {easycoder-241215.1 → easycoder-241218.1}/easycoder/__init__.py +1 -1
  4. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_renderer.py +65 -60
  5. easycoder-241218.1/images/Semoigo Dawn.jpg +0 -0
  6. {easycoder-241215.1/scripts → easycoder-241218.1/json}/graphics-demo.json +27 -3
  7. {easycoder-241215.1 → easycoder-241218.1}/scripts/graphics-demo.ecs +4 -3
  8. {easycoder-241215.1 → easycoder-241218.1}/LICENSE +0 -0
  9. {easycoder-241215.1 → easycoder-241218.1}/doc/README.md +0 -0
  10. {easycoder-241215.1 → easycoder-241218.1}/doc/core/add.md +0 -0
  11. {easycoder-241215.1 → easycoder-241218.1}/doc/core/append.md +0 -0
  12. {easycoder-241215.1 → easycoder-241218.1}/doc/core/assert.md +0 -0
  13. {easycoder-241215.1 → easycoder-241218.1}/doc/core/begin.md +0 -0
  14. {easycoder-241215.1 → easycoder-241218.1}/doc/core/clear.md +0 -0
  15. {easycoder-241215.1 → easycoder-241218.1}/doc/core/close.md +0 -0
  16. {easycoder-241215.1 → easycoder-241218.1}/doc/core/create.md +0 -0
  17. {easycoder-241215.1 → easycoder-241218.1}/doc/core/debug.md +0 -0
  18. {easycoder-241215.1 → easycoder-241218.1}/doc/core/decrement.md +0 -0
  19. {easycoder-241215.1 → easycoder-241218.1}/doc/core/delete.md +0 -0
  20. {easycoder-241215.1 → easycoder-241218.1}/doc/core/divide.md +0 -0
  21. {easycoder-241215.1 → easycoder-241218.1}/doc/core/exit.md +0 -0
  22. {easycoder-241215.1 → easycoder-241218.1}/doc/core/file.md +0 -0
  23. {easycoder-241215.1 → easycoder-241218.1}/doc/core/fork.md +0 -0
  24. {easycoder-241215.1 → easycoder-241218.1}/doc/core/get.md +0 -0
  25. {easycoder-241215.1 → easycoder-241218.1}/doc/core/go.md +0 -0
  26. {easycoder-241215.1 → easycoder-241218.1}/doc/core/gosub.md +0 -0
  27. {easycoder-241215.1 → easycoder-241218.1}/doc/core/if.md +0 -0
  28. {easycoder-241215.1 → easycoder-241218.1}/doc/core/import.md +0 -0
  29. {easycoder-241215.1 → easycoder-241218.1}/doc/core/increment.md +0 -0
  30. {easycoder-241215.1 → easycoder-241218.1}/doc/core/index.md +0 -0
  31. {easycoder-241215.1 → easycoder-241218.1}/doc/core/init.md +0 -0
  32. {easycoder-241215.1 → easycoder-241218.1}/doc/core/input.md +0 -0
  33. {easycoder-241215.1 → easycoder-241218.1}/doc/core/multiply.md +0 -0
  34. {easycoder-241215.1 → easycoder-241218.1}/doc/core/open.md +0 -0
  35. {easycoder-241215.1 → easycoder-241218.1}/doc/core/pop.md +0 -0
  36. {easycoder-241215.1 → easycoder-241218.1}/doc/core/post.md +0 -0
  37. {easycoder-241215.1 → easycoder-241218.1}/doc/core/print.md +0 -0
  38. {easycoder-241215.1 → easycoder-241218.1}/doc/core/push.md +0 -0
  39. {easycoder-241215.1 → easycoder-241218.1}/doc/core/put.md +0 -0
  40. {easycoder-241215.1 → easycoder-241218.1}/doc/core/read.md +0 -0
  41. {easycoder-241215.1 → easycoder-241218.1}/doc/core/replace.md +0 -0
  42. {easycoder-241215.1 → easycoder-241218.1}/doc/core/return.md +0 -0
  43. {easycoder-241215.1 → easycoder-241218.1}/doc/core/script.md +0 -0
  44. {easycoder-241215.1 → easycoder-241218.1}/doc/core/set.md +0 -0
  45. {easycoder-241215.1 → easycoder-241218.1}/doc/core/split.md +0 -0
  46. {easycoder-241215.1 → easycoder-241218.1}/doc/core/stack.md +0 -0
  47. {easycoder-241215.1 → easycoder-241218.1}/doc/core/stop.md +0 -0
  48. {easycoder-241215.1 → easycoder-241218.1}/doc/core/system.md +0 -0
  49. {easycoder-241215.1 → easycoder-241218.1}/doc/core/take.md +0 -0
  50. {easycoder-241215.1 → easycoder-241218.1}/doc/core/toggle.md +0 -0
  51. {easycoder-241215.1 → easycoder-241218.1}/doc/core/truncate.md +0 -0
  52. {easycoder-241215.1 → easycoder-241218.1}/doc/core/variable.md +0 -0
  53. {easycoder-241215.1 → easycoder-241218.1}/doc/core/wait.md +0 -0
  54. {easycoder-241215.1 → easycoder-241218.1}/doc/core/while.md +0 -0
  55. {easycoder-241215.1 → easycoder-241218.1}/doc/core/write.md +0 -0
  56. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_classes.py +0 -0
  57. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_compiler.py +0 -0
  58. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_condition.py +0 -0
  59. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_core.py +0 -0
  60. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_graphics.py +0 -0
  61. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_handler.py +0 -0
  62. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_program.py +0 -0
  63. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_timestamp.py +0 -0
  64. {easycoder-241215.1 → easycoder-241218.1}/easycoder/ec_value.py +0 -0
  65. {easycoder-241215.1 → easycoder-241218.1}/plugins/ec_p100.py +0 -0
  66. {easycoder-241215.1 → easycoder-241218.1}/plugins/example.py +0 -0
  67. {easycoder-241215.1 → easycoder-241218.1}/pyproject.toml +0 -0
  68. {easycoder-241215.1 → easycoder-241218.1}/scripts/benchmark.ecs +0 -0
  69. {easycoder-241215.1 → easycoder-241218.1}/scripts/fizzbuzz.ecs +0 -0
  70. {easycoder-241215.1 → easycoder-241218.1}/scripts/hello.ecs +0 -0
  71. {easycoder-241215.1 → easycoder-241218.1}/scripts/points.ecs +0 -0
  72. {easycoder-241215.1 → easycoder-241218.1}/scripts/tests.ecs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 241215.1
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 **EasyCoder_** environment, in other Python programs.
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
 
@@ -51,7 +51,7 @@ Here in the repository is a folder called `scripts` containing some sample scrip
51
51
  ## Graphical programmming
52
52
  **_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`.
53
53
 
54
- 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.
54
+ 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.
55
55
 
56
56
  ## EasyCoder programming reference
57
57
 
@@ -63,4 +63,4 @@ The language comprises a general-purpose core package, which can be enhanced by
63
63
 
64
64
  **_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.
65
65
 
66
- 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_**
66
+ 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_**.
@@ -10,4 +10,4 @@ from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
  from .ec_graphics import *
12
12
 
13
- __version__ = "241215.1"
13
+ __version__ = "241218.1"
@@ -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, offset, args):
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
- left = offset['dx'] + left
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 = left + width
122
- bottom = top + height
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(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
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(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
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, {'dx': left, 'dy': top}, args)
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, {'dx': left, 'dy': top}, args)
162
+ childSpec = renderWidget(child, widgetSpec, args)
162
163
  widgetSpec['children'].append(childSpec['name'])
163
164
  return widgetSpec
164
165
 
165
- def renderText(values, offset, args):
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
- left = offset['dx'] + left
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
- fontSize = round(height*2/5) if shape == 'ellipse' else round(height*3/5)
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 = top + round(fontSize * 5 / 4)
187
- adjust = round(fontSize/5) if shape == 'ellipse' else 0
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
- if shape == 'ellipse':
201
- containerId = getCanvas().create_oval(left, top, right, bottom, fill=fill, outline=outline, width=outlineWidth)
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, offset, args):
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
- left = offset['dx'] + left
228
- top = offset['dy'] + top
224
+ screenTop = top + getScreenTop(parent)
229
225
  width = getValue(args, values['width']) if 'width' in values else 100
230
- height = getValue(args, values['height']) if 'height' in values else 100
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, offset, args):
254
+ def renderWidget(widget, parent, args):
261
255
  widgetType = widget['type']
262
256
  if widgetType in ['rectangle', 'ellipse']:
263
- return renderIntoRectangle(widgetType, widget, offset, args)
257
+ return renderIntoRectangle(widgetType, widget, parent, args)
264
258
  elif widgetType == 'text':
265
- return renderText(widget, offset, args)
259
+ return renderText(widget, parent, args)
266
260
  elif widgetType == 'image':
267
- return renderImage(widget, offset, args)
261
+ return renderImage(widget, parent, args)
268
262
 
269
263
  # Render a complete specification
270
- def renderSpec(spec, offset, args):
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], offset, args)
269
+ renderWidget(spec[widget], parent, args)
276
270
  # Otherwise, process the single widget
277
271
  else:
278
- renderWidget(spec[widgets], offset, args)
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), offset, {})
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, offset, args)
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,7 +1,8 @@
1
1
  {
2
2
  "#": [
3
3
  "BlueRect",
4
- "RedEllipse"
4
+ "RedEllipse",
5
+ "Photo"
5
6
  ],
6
7
  "BlueRect": {
7
8
  "type": "rectangle",
@@ -27,10 +28,33 @@
27
28
  "RedEllipse": {
28
29
  "type": "ellipse",
29
30
  "left": 300,
30
- "top": 200,
31
+ "top": 100,
31
32
  "width": 200,
32
33
  "height": 100,
33
34
  "fill": "red",
34
- "name": "redellipse"
35
+ "name": "redellipse",
36
+ "#": [
37
+ "WhiteText"
38
+ ],
39
+ "WhiteText": {
40
+ "type": "text",
41
+ "left": 25,
42
+ "top": 40,
43
+ "width": 160,
44
+ "height": 32,
45
+ "color": "white",
46
+ "text": "Graphics demo",
47
+ "fontSize": 20,
48
+ "name": "mytext"
49
+ }
50
+ },
51
+
52
+ "Photo": {
53
+ "type": "image",
54
+ "left": 150,
55
+ "top": 250,
56
+ "width": 300,
57
+ "source": "images/Semoigo Dawn.jpg",
58
+ "name": "dawn"
35
59
  }
36
60
  }
@@ -5,6 +5,7 @@
5
5
  rectangle BlueRect
6
6
  ellipse RedEllipse
7
7
  ellipse GreenCircle
8
+ text WhiteText
8
9
  file File
9
10
  variable Spec
10
11
  variable UpDown
@@ -16,7 +17,7 @@
16
17
 
17
18
  create screen at 300 300 size 640 480 fill color yellow
18
19
 
19
- open File `scripts/graphics-demo.json` for reading
20
+ open File `json/graphics-demo.json` for reading
20
21
  read Spec from File
21
22
  close File
22
23
 
@@ -48,7 +49,7 @@
48
49
  clear UpDown
49
50
  end
50
51
  move RedEllipse to Left Top
51
- take 5 from Left
52
+ add 5 to Left
52
53
  end
53
54
  else
54
55
  begin
@@ -62,7 +63,7 @@
62
63
  set UpDown
63
64
  end
64
65
  move RedEllipse to Left Top
65
- add 5 to Left
66
+ take 5 from Left
66
67
  end
67
68
  increment N
68
69
  end
File without changes
File without changes