easycoder 250118.2__py2.py3-none-any.whl → 250123.2__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_core.py +33 -25
- easycoder/ec_graphics.py +360 -29
- easycoder/ec_gutils.py +102 -42
- {easycoder-250118.2.dist-info → easycoder-250123.2.dist-info}/METADATA +1 -1
- {easycoder-250118.2.dist-info → easycoder-250123.2.dist-info}/RECORD +9 -9
- {easycoder-250118.2.dist-info → easycoder-250123.2.dist-info}/LICENSE +0 -0
- {easycoder-250118.2.dist-info → easycoder-250123.2.dist-info}/WHEEL +0 -0
- {easycoder-250118.2.dist-info → easycoder-250123.2.dist-info}/entry_points.txt +0 -0
easycoder/__init__.py
CHANGED
easycoder/ec_core.py
CHANGED
|
@@ -2,7 +2,7 @@ import json, math, hashlib, threading, os, subprocess, sys, requests, time, numb
|
|
|
2
2
|
from psutil import Process
|
|
3
3
|
from datetime import datetime, timezone
|
|
4
4
|
from random import randrange
|
|
5
|
-
from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, Condition
|
|
5
|
+
from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, Condition, Object
|
|
6
6
|
from .ec_handler import Handler
|
|
7
7
|
from .ec_timestamp import getTimestamp
|
|
8
8
|
|
|
@@ -729,6 +729,12 @@ class Core(Handler):
|
|
|
729
729
|
target['locked'] = True
|
|
730
730
|
return self.nextPC()
|
|
731
731
|
|
|
732
|
+
# Log a message
|
|
733
|
+
def k_log(self, command):
|
|
734
|
+
command['log'] = True
|
|
735
|
+
command['keyword'] = 'print'
|
|
736
|
+
return self.k_print(command)
|
|
737
|
+
|
|
732
738
|
# Declare a module variable
|
|
733
739
|
def k_module(self, command):
|
|
734
740
|
return self.compileVariable(command)
|
|
@@ -995,11 +1001,11 @@ class Core(Handler):
|
|
|
995
1001
|
value = self.getRuntimeValue(command['value'])
|
|
996
1002
|
program = command['program']
|
|
997
1003
|
code = program.code[program.pc]
|
|
998
|
-
lino = code['lino'] + 1
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1004
|
+
lino = str(code['lino'] + 1)
|
|
1005
|
+
while len(lino) < 4: lino = f' {lino}'
|
|
1006
|
+
if value == None: value = '<empty>'
|
|
1007
|
+
if 'log' in command: print(f'{datetime.now().time()}: {lino}-> {value}')
|
|
1008
|
+
else: print(value)
|
|
1003
1009
|
return self.nextPC()
|
|
1004
1010
|
|
|
1005
1011
|
# Push a value onto a stack
|
|
@@ -1147,6 +1153,7 @@ class Core(Handler):
|
|
|
1147
1153
|
return self.stack.pop()
|
|
1148
1154
|
|
|
1149
1155
|
# Compile and run a script
|
|
1156
|
+
# run {path} [as {module}] [with {variable} [and {variable}...]]
|
|
1150
1157
|
def k_run(self, command):
|
|
1151
1158
|
try:
|
|
1152
1159
|
command['path'] = self.nextValue()
|
|
@@ -1157,20 +1164,24 @@ class Core(Handler):
|
|
|
1157
1164
|
if self.nextIsSymbol():
|
|
1158
1165
|
record = self.getSymbolRecord()
|
|
1159
1166
|
if record['keyword'] == 'module':
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1167
|
+
name = record['name']
|
|
1168
|
+
command['module'] = name
|
|
1169
|
+
else: RuntimeError(self.program, f'Symbol \'name\' is not a module')
|
|
1170
|
+
else: RuntimeError(self.program, 'Module name expected after \'as\'')
|
|
1171
|
+
else: RuntimeError(self.program, '\'as {module name}\' expected')
|
|
1172
|
+
exports = []
|
|
1173
|
+
if self.peek() == 'with':
|
|
1174
|
+
self.nextToken()
|
|
1175
|
+
while True:
|
|
1176
|
+
name = self.nextToken()
|
|
1177
|
+
record = self.getSymbolRecord()
|
|
1178
|
+
exports.append(name)
|
|
1179
|
+
if self.peek() != 'and':
|
|
1180
|
+
break
|
|
1181
|
+
self.nextToken()
|
|
1182
|
+
command['exports'] = json.dumps(exports)
|
|
1183
|
+
self.add(command)
|
|
1184
|
+
return True
|
|
1174
1185
|
|
|
1175
1186
|
def r_run(self, command):
|
|
1176
1187
|
module = self.getVariable(command['module'])
|
|
@@ -1734,10 +1745,7 @@ class Core(Handler):
|
|
|
1734
1745
|
if symbolRecord['valueHolder']:
|
|
1735
1746
|
value['target'] = symbolRecord['name']
|
|
1736
1747
|
return value
|
|
1737
|
-
|
|
1738
|
-
value['value'] = self.getValue()
|
|
1739
|
-
return value
|
|
1740
|
-
self.warning(f'Core.compileValue: Token \'{self.getToken()}\' does not hold a value')
|
|
1748
|
+
FatalError(self.program.compiler, 'Variable does not hold a value')
|
|
1741
1749
|
return None
|
|
1742
1750
|
|
|
1743
1751
|
if token == 'arg':
|
|
@@ -2503,7 +2511,7 @@ class Core(Handler):
|
|
|
2503
2511
|
return not comparison if condition.negate else comparison
|
|
2504
2512
|
|
|
2505
2513
|
def c_not(self, condition):
|
|
2506
|
-
return not self.getRuntimeValue(condition.
|
|
2514
|
+
return not self.getRuntimeValue(condition.value)
|
|
2507
2515
|
|
|
2508
2516
|
def c_object(self, condition):
|
|
2509
2517
|
comparison = type(self.getRuntimeValue(condition.value1)) is dict
|
easycoder/ec_graphics.py
CHANGED
|
@@ -57,7 +57,10 @@ class Graphics(Handler):
|
|
|
57
57
|
layout = json.loads(self.getRuntimeValue(json.loads(args)))
|
|
58
58
|
default = self.utils.getDefaultArgs(type)
|
|
59
59
|
for n in range(0, len(layout)):
|
|
60
|
-
|
|
60
|
+
try:
|
|
61
|
+
args = self.utils.decode(self, default, layout[n])
|
|
62
|
+
except Exception as e:
|
|
63
|
+
RuntimeError(self.program, e)
|
|
61
64
|
item = self.utils.createElement(type, param, args)
|
|
62
65
|
target['layout'].append(item)
|
|
63
66
|
else:
|
|
@@ -125,7 +128,8 @@ class Graphics(Handler):
|
|
|
125
128
|
if type == 'window':
|
|
126
129
|
layout = self.getVariable(command['layout'])
|
|
127
130
|
title = self.getRuntimeValue(command['title'])
|
|
128
|
-
|
|
131
|
+
window = psg.Window(title, layout['layout'], finalize=True)
|
|
132
|
+
record['window'] = window
|
|
129
133
|
record['eventHandlers'] = {}
|
|
130
134
|
self.program.windowRecord = record
|
|
131
135
|
self.program.run(self.nextPC())
|
|
@@ -202,38 +206,327 @@ class Graphics(Handler):
|
|
|
202
206
|
psg.popup(self.getRuntimeValue(command['message']))
|
|
203
207
|
return self.nextPC()
|
|
204
208
|
|
|
209
|
+
# set property {property} of {key} in {window} to {value}
|
|
205
210
|
def k_set(self, command):
|
|
206
|
-
if self.
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
if self.nextIs('property'):
|
|
212
|
+
command['property'] = self.nextValue()
|
|
213
|
+
if self.nextIs('of'):
|
|
214
|
+
command['key'] = self.nextValue()
|
|
215
|
+
if self.nextIs('in'):
|
|
216
|
+
if self.nextIsSymbol():
|
|
217
|
+
record = self.getSymbolRecord()
|
|
218
|
+
if record['keyword'] == 'window':
|
|
219
|
+
name = record['name']
|
|
220
|
+
command['window'] = name
|
|
221
|
+
if self.nextIs('to'):
|
|
222
|
+
command['value'] = self.nextValue()
|
|
223
|
+
self.add(command)
|
|
224
|
+
return True
|
|
225
|
+
else: RuntimeError(self.program, f'\'{name}\' is not a window variable')
|
|
226
|
+
else: RuntimeError(self.program, 'No window variable given')
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
def r_set(self, command):
|
|
230
|
+
property = self.getRuntimeValue(command['property'])
|
|
231
|
+
key = self.getRuntimeValue(command['key'])
|
|
232
|
+
window = self.program.windowRecord['window']
|
|
233
|
+
value = self.getRuntimeValue(command['value'])
|
|
234
|
+
self.utils.updateProperty(window[key], property, value)
|
|
235
|
+
return self.nextPC()
|
|
236
|
+
|
|
237
|
+
def k_window(self, command):
|
|
238
|
+
return self.compileVariable(command)
|
|
239
|
+
|
|
240
|
+
def r_window(self, command):
|
|
241
|
+
return self.nextPC()
|
|
242
|
+
|
|
243
|
+
#############################################################################
|
|
244
|
+
# Compile a value in this domain
|
|
245
|
+
def compileValue(self):
|
|
246
|
+
value = {}
|
|
247
|
+
value['domain'] = self.getName()
|
|
248
|
+
token = self.getToken()
|
|
249
|
+
if self.isSymbol():
|
|
250
|
+
value['name'] = token
|
|
251
|
+
symbolRecord = self.getSymbolRecord()
|
|
252
|
+
keyword = symbolRecord['keyword']
|
|
253
|
+
if keyword == 'event':
|
|
254
|
+
value['type'] = 'symbol'
|
|
255
|
+
return value
|
|
256
|
+
return None
|
|
257
|
+
|
|
258
|
+
if self.getToken() == 'the':
|
|
259
|
+
self.nextToken()
|
|
260
|
+
|
|
261
|
+
token = self.getToken()
|
|
262
|
+
value['type'] = token
|
|
263
|
+
|
|
264
|
+
if token == 'event':
|
|
265
|
+
return value
|
|
266
|
+
|
|
267
|
+
return None
|
|
268
|
+
|
|
269
|
+
#############################################################################
|
|
270
|
+
# Modify a value or leave it unchanged.
|
|
271
|
+
def modifyValue(self, value):
|
|
272
|
+
return value
|
|
273
|
+
|
|
274
|
+
#############################################################################
|
|
275
|
+
# Value handlers
|
|
276
|
+
|
|
277
|
+
# This is used by the expression evaluator to get the value of a symbol
|
|
278
|
+
def v_symbol(self, symbolRecord):
|
|
279
|
+
if symbolRecord['keyword'] == 'event':
|
|
280
|
+
return self.getSymbolValue(symbolRecord)
|
|
281
|
+
else:
|
|
282
|
+
return None
|
|
283
|
+
|
|
284
|
+
def v_event(self, v):
|
|
285
|
+
v['type'] = 'text'
|
|
286
|
+
v['content'] = self.eventValues
|
|
287
|
+
return v
|
|
288
|
+
|
|
289
|
+
#############################################################################
|
|
290
|
+
# Compile a condition
|
|
291
|
+
def compileCondition(self):
|
|
292
|
+
condition = {}
|
|
293
|
+
return condition
|
|
294
|
+
|
|
295
|
+
#############################################################################
|
|
296
|
+
# Condition handlers
|
|
297
|
+
|
|
298
|
+
#############################################################################
|
|
299
|
+
# The main loop
|
|
300
|
+
def mainLoop(self):
|
|
301
|
+
windowRecord = self.program.windowRecord
|
|
302
|
+
window = windowRecord['window']
|
|
303
|
+
eventHandlers = windowRecord['eventHandlers']
|
|
304
|
+
while True:
|
|
305
|
+
event, values = window.Read(timeout=100)
|
|
306
|
+
if event == psg.WIN_CLOSED or event == "EXIT":
|
|
307
|
+
del window
|
|
308
|
+
break
|
|
309
|
+
if event == '__TIMEOUT__': self.program.flushCB()
|
|
310
|
+
else:
|
|
311
|
+
if event in eventHandlers:
|
|
312
|
+
self.eventValues = values
|
|
313
|
+
eventHandlers[event]()
|
|
314
|
+
class Graphics(Handler):
|
|
315
|
+
|
|
316
|
+
def __init__(self, compiler):
|
|
317
|
+
Handler.__init__(self, compiler)
|
|
318
|
+
self.utils = GUtils()
|
|
319
|
+
|
|
320
|
+
def getName(self):
|
|
321
|
+
return 'graphics'
|
|
322
|
+
|
|
323
|
+
#############################################################################
|
|
324
|
+
# Keyword handlers
|
|
325
|
+
|
|
326
|
+
def k_add(self, command):
|
|
327
|
+
token = self.nextToken()
|
|
328
|
+
if self.isSymbol():
|
|
329
|
+
symbolRecord = self.getSymbolRecord()
|
|
330
|
+
name = symbolRecord['name']
|
|
331
|
+
keyword = symbolRecord['keyword']
|
|
209
332
|
if keyword == 'layout':
|
|
210
|
-
command['
|
|
333
|
+
command['args'] = name
|
|
334
|
+
elif keyword in ['column', 'frame', 'tab']:
|
|
335
|
+
command['name'] = name
|
|
336
|
+
command['type'] = token
|
|
211
337
|
if self.peek() == 'to':
|
|
212
|
-
|
|
213
|
-
|
|
338
|
+
command['args'] = []
|
|
339
|
+
else:
|
|
214
340
|
command['args'] = self.utils.getArgs(self)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
341
|
+
else:
|
|
342
|
+
command['type'] = token
|
|
343
|
+
command['args'] = self.utils.getArgs(self)
|
|
344
|
+
if self.nextIs('to'):
|
|
345
|
+
if self.nextIsSymbol():
|
|
346
|
+
symbolRecord = self.getSymbolRecord()
|
|
347
|
+
if symbolRecord['keyword'] in ['column', 'frame', 'layout', 'tab']:
|
|
348
|
+
command['target'] = symbolRecord['name']
|
|
349
|
+
self.addCommand(command)
|
|
350
|
+
return True
|
|
351
|
+
return False
|
|
221
352
|
|
|
222
|
-
def
|
|
353
|
+
def r_add(self, command):
|
|
223
354
|
target = self.getVariable(command['target'])
|
|
224
|
-
target['layout'] = []
|
|
225
355
|
type = command['type']
|
|
226
356
|
args = command['args']
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
357
|
+
param= None
|
|
358
|
+
if not 'layout' in target:
|
|
359
|
+
target['layout'] = []
|
|
360
|
+
if args[0] == '{':
|
|
361
|
+
if type in ['Column', 'Frame', 'Tab']:
|
|
362
|
+
record = self.getVariable(command['name'])
|
|
363
|
+
param = record['layout']
|
|
364
|
+
layout = json.loads(self.getRuntimeValue(json.loads(args)))
|
|
365
|
+
default = self.utils.getDefaultArgs(type)
|
|
366
|
+
for n in range(0, len(layout)):
|
|
367
|
+
try:
|
|
368
|
+
args = self.utils.decode(self, default, layout[n])
|
|
369
|
+
except Exception as e:
|
|
370
|
+
RuntimeError(self.program, e)
|
|
371
|
+
item = self.utils.createElement(type, param, args)
|
|
372
|
+
target['layout'].append(item)
|
|
373
|
+
else:
|
|
374
|
+
v = self.getVariable(args)
|
|
375
|
+
target['layout'].append(v['layout'])
|
|
376
|
+
return self.nextPC()
|
|
377
|
+
|
|
378
|
+
def k_close(self, command):
|
|
379
|
+
if self.nextIsSymbol():
|
|
380
|
+
symbolRecord = self.getSymbolRecord()
|
|
381
|
+
if symbolRecord['keyword'] == 'window':
|
|
382
|
+
command['target'] = symbolRecord['name']
|
|
383
|
+
self.add(command)
|
|
384
|
+
return True
|
|
385
|
+
return False
|
|
386
|
+
|
|
387
|
+
def r_close(self, command):
|
|
388
|
+
target = self.getVariable(command['target'])
|
|
389
|
+
target['window'].close()
|
|
390
|
+
return self.nextPC()
|
|
391
|
+
|
|
392
|
+
def k_column(self, command):
|
|
393
|
+
return self.compileVariable(command)
|
|
394
|
+
|
|
395
|
+
def r_column(self, command):
|
|
396
|
+
return self.nextPC()
|
|
397
|
+
|
|
398
|
+
# create {window} layout {layout}
|
|
399
|
+
# create {element} {args...}
|
|
400
|
+
def k_create(self, command):
|
|
401
|
+
if self.nextIsSymbol():
|
|
402
|
+
symbolRecord = self.getSymbolRecord()
|
|
403
|
+
type = symbolRecord['keyword']
|
|
404
|
+
command['type'] = type
|
|
405
|
+
command['name'] = symbolRecord['name']
|
|
406
|
+
if type == 'window':
|
|
407
|
+
command['title'] = self.nextValue()
|
|
408
|
+
if self.nextIs('layout'):
|
|
409
|
+
if self.nextIsSymbol():
|
|
410
|
+
symbolRecord = self.getSymbolRecord()
|
|
411
|
+
if symbolRecord['keyword'] == 'layout':
|
|
412
|
+
command['layout'] = symbolRecord['name']
|
|
413
|
+
self.addCommand(command)
|
|
414
|
+
return True
|
|
415
|
+
return False
|
|
416
|
+
|
|
417
|
+
def r_create(self, command):
|
|
418
|
+
type = command['type']
|
|
419
|
+
record = self.getVariable(command['name'])
|
|
420
|
+
if type == 'window':
|
|
421
|
+
title = self.getRuntimeValue(command['title'])
|
|
422
|
+
layout = self.getVariable(command['layout'])['layout']
|
|
423
|
+
# keys = {}
|
|
424
|
+
# self.utils.tagKeys(keys, layout)
|
|
425
|
+
window = psg.Window(title, layout, finalize=True)
|
|
426
|
+
# window.keys = keys
|
|
427
|
+
record['window'] = window
|
|
428
|
+
record['eventHandlers'] = {}
|
|
429
|
+
self.program.windowRecord = record
|
|
430
|
+
self.program.run(self.nextPC())
|
|
431
|
+
self.mainLoop()
|
|
432
|
+
# self.program.kill()
|
|
433
|
+
return 0
|
|
434
|
+
else:
|
|
435
|
+
RuntimeError(self.program, 'Variable is not a window or an element')
|
|
436
|
+
|
|
437
|
+
def k_init(self, command):
|
|
438
|
+
if self.nextIsSymbol():
|
|
439
|
+
symbolRecord = self.getSymbolRecord()
|
|
440
|
+
if symbolRecord['keyword'] in ['column', 'frame', 'layout', 'tab']:
|
|
441
|
+
command['target'] = symbolRecord['name']
|
|
442
|
+
self.add(command)
|
|
443
|
+
return True
|
|
444
|
+
return False
|
|
445
|
+
|
|
446
|
+
def r_init(self, command):
|
|
447
|
+
target = self.getVariable(command['target'])
|
|
448
|
+
target['layout'] = []
|
|
449
|
+
return self.nextPC()
|
|
450
|
+
|
|
451
|
+
def k_layout(self, command):
|
|
452
|
+
return self.compileVariable(command)
|
|
453
|
+
|
|
454
|
+
def r_layout(self, command):
|
|
455
|
+
return self.nextPC()
|
|
456
|
+
|
|
457
|
+
def k_on(self, command):
|
|
458
|
+
token = self.nextToken()
|
|
459
|
+
if token == 'event':
|
|
460
|
+
command['key'] = self.nextValue()
|
|
461
|
+
if self.nextIs('in'):
|
|
462
|
+
if self.nextIsSymbol():
|
|
463
|
+
record = self.getSymbolRecord()
|
|
464
|
+
if record['keyword'] == 'window':
|
|
465
|
+
command['window'] = record['name']
|
|
466
|
+
command['goto'] = self.getPC() + 2
|
|
467
|
+
self.add(command)
|
|
468
|
+
self.nextToken()
|
|
469
|
+
pcNext = self.getPC()
|
|
470
|
+
cmd = {}
|
|
471
|
+
cmd['domain'] = 'core'
|
|
472
|
+
cmd['lino'] = command['lino']
|
|
473
|
+
cmd['keyword'] = 'gotoPC'
|
|
474
|
+
cmd['goto'] = 0
|
|
475
|
+
cmd['debug'] = False
|
|
476
|
+
self.addCommand(cmd)
|
|
477
|
+
self.compileOne()
|
|
478
|
+
cmd = {}
|
|
479
|
+
cmd['domain'] = 'core'
|
|
480
|
+
cmd['lino'] = command['lino']
|
|
481
|
+
cmd['keyword'] = 'stop'
|
|
482
|
+
cmd['debug'] = False
|
|
483
|
+
self.addCommand(cmd)
|
|
484
|
+
# Fixup the link
|
|
485
|
+
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
486
|
+
return True
|
|
487
|
+
return False
|
|
488
|
+
|
|
489
|
+
def r_on(self, command):
|
|
490
|
+
key = self.getRuntimeValue(command['key'])
|
|
491
|
+
window = self.getVariable(command['window'])
|
|
492
|
+
window['eventHandlers'][key] = lambda: self.run(command['goto'])
|
|
493
|
+
return self.nextPC()
|
|
494
|
+
|
|
495
|
+
def k_popup(self, command):
|
|
496
|
+
command['message'] = self.nextValue()
|
|
497
|
+
self.addCommand(command)
|
|
498
|
+
return True
|
|
499
|
+
|
|
500
|
+
def r_popup(self, command):
|
|
501
|
+
psg.popup(self.getRuntimeValue(command['message']))
|
|
502
|
+
return self.nextPC()
|
|
503
|
+
|
|
504
|
+
# set property {property} of {key} in {window} to {value}
|
|
505
|
+
def k_set(self, command):
|
|
506
|
+
if self.nextIs('property'):
|
|
507
|
+
command['property'] = self.nextValue()
|
|
508
|
+
if self.nextIs('of'):
|
|
509
|
+
command['key'] = self.nextValue()
|
|
510
|
+
if self.nextIs('in'):
|
|
511
|
+
if self.nextIsSymbol():
|
|
512
|
+
record = self.getSymbolRecord()
|
|
513
|
+
if record['keyword'] == 'window':
|
|
514
|
+
name = record['name']
|
|
515
|
+
command['window'] = name
|
|
516
|
+
if self.nextIs('to'):
|
|
517
|
+
command['value'] = self.nextValue()
|
|
518
|
+
self.add(command)
|
|
519
|
+
return True
|
|
520
|
+
else: RuntimeError(self.program, f'\'{name}\' is not a window variable')
|
|
521
|
+
else: RuntimeError(self.program, 'No window variable given')
|
|
522
|
+
return False
|
|
523
|
+
|
|
524
|
+
def r_set(self, command):
|
|
525
|
+
property = self.getRuntimeValue(command['property'])
|
|
526
|
+
key = self.getRuntimeValue(command['key'])
|
|
527
|
+
window = self.program.windowRecord['window']
|
|
528
|
+
value = self.getRuntimeValue(command['value'])
|
|
529
|
+
self.utils.updateProperty(window[key], property, value)
|
|
237
530
|
return self.nextPC()
|
|
238
531
|
|
|
239
532
|
def k_window(self, command):
|
|
@@ -266,6 +559,21 @@ class Graphics(Handler):
|
|
|
266
559
|
if token == 'event':
|
|
267
560
|
return value
|
|
268
561
|
|
|
562
|
+
if token == 'property':
|
|
563
|
+
value['key'] = self.nextValue()
|
|
564
|
+
if self.nextIs('of'):
|
|
565
|
+
if self.nextToken() == 'the':
|
|
566
|
+
if self.nextIs('event'):
|
|
567
|
+
value['source'] = '_event_'
|
|
568
|
+
return value
|
|
569
|
+
else:
|
|
570
|
+
value['key'] = self.getValue()
|
|
571
|
+
if self.nextIs('in'):
|
|
572
|
+
if self.nextIsSymbol():
|
|
573
|
+
record = self.getSymbolRecord()
|
|
574
|
+
if record['keyword'] == 'window':
|
|
575
|
+
value['source'] = record['name']
|
|
576
|
+
return value
|
|
269
577
|
return None
|
|
270
578
|
|
|
271
579
|
#############################################################################
|
|
@@ -284,10 +592,30 @@ class Graphics(Handler):
|
|
|
284
592
|
return None
|
|
285
593
|
|
|
286
594
|
def v_event(self, v):
|
|
595
|
+
window = self.eventValues['window']
|
|
596
|
+
values = self.eventValues['values']
|
|
597
|
+
self.utils.getEventProperties(window, values)
|
|
287
598
|
v['type'] = 'text'
|
|
288
|
-
v['content'] =
|
|
599
|
+
v['content'] = values
|
|
289
600
|
return v
|
|
290
601
|
|
|
602
|
+
def v_property(self, v):
|
|
603
|
+
key = self.getRuntimeValue(v['key'])
|
|
604
|
+
source = v['source']
|
|
605
|
+
if source == '_event_':
|
|
606
|
+
window = self.eventValues['window']
|
|
607
|
+
values = self.eventValues['values']
|
|
608
|
+
self.utils.getEventProperties(window, values)
|
|
609
|
+
v['type'] = 'text'
|
|
610
|
+
v['content'] = values[key]
|
|
611
|
+
return v
|
|
612
|
+
else:
|
|
613
|
+
window = self.getVariable(source)
|
|
614
|
+
widget = window['window'].key_dict[key]
|
|
615
|
+
v['type'] = 'text'
|
|
616
|
+
v['content'] = widget.get()
|
|
617
|
+
return v
|
|
618
|
+
|
|
291
619
|
#############################################################################
|
|
292
620
|
# Compile a condition
|
|
293
621
|
def compileCondition(self):
|
|
@@ -305,10 +633,13 @@ class Graphics(Handler):
|
|
|
305
633
|
eventHandlers = windowRecord['eventHandlers']
|
|
306
634
|
while True:
|
|
307
635
|
event, values = window.Read(timeout=100)
|
|
308
|
-
if event == psg.
|
|
636
|
+
if event == psg.WIN_CLOSED or event == "EXIT":
|
|
637
|
+
del window
|
|
309
638
|
break
|
|
310
639
|
if event == '__TIMEOUT__': self.program.flushCB()
|
|
311
640
|
else:
|
|
312
641
|
if event in eventHandlers:
|
|
313
|
-
self.eventValues =
|
|
642
|
+
self.eventValues = {}
|
|
643
|
+
self.eventValues['values'] = values
|
|
644
|
+
self.eventValues['window'] = window
|
|
314
645
|
eventHandlers[event]()
|
easycoder/ec_gutils.py
CHANGED
|
@@ -8,7 +8,8 @@ class GUtils:
|
|
|
8
8
|
args = []
|
|
9
9
|
while True:
|
|
10
10
|
key = handler.nextToken()
|
|
11
|
-
value =
|
|
11
|
+
value = handler.nextValue()
|
|
12
|
+
value = json.dumps(value)
|
|
12
13
|
args.append(f'{key}={value}')
|
|
13
14
|
if handler.peek() == 'and':
|
|
14
15
|
handler.nextToken()
|
|
@@ -21,64 +22,123 @@ class GUtils:
|
|
|
21
22
|
# Get the default args for a graphic element
|
|
22
23
|
def getDefaultArgs(self, type):
|
|
23
24
|
args = {}
|
|
24
|
-
if type == 'Button':
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
args['expand_x'] = False
|
|
32
|
-
elif type == 'Column':
|
|
33
|
-
args['expand_x'] = False
|
|
34
|
-
args['pad'] = (0, 0)
|
|
35
|
-
elif type == 'Input':
|
|
36
|
-
args['key'] = None
|
|
37
|
-
args['size'] = (None, None)
|
|
38
|
-
elif type == 'Multiline':
|
|
39
|
-
args['default_text'] = ''
|
|
40
|
-
args['key'] = None
|
|
41
|
-
args['size'] = (None, None)
|
|
42
|
-
elif type == 'Text':
|
|
43
|
-
args['text'] = '(empty)'
|
|
44
|
-
args['size'] = (None, None)
|
|
45
|
-
args['expand_x'] = False
|
|
25
|
+
if type == 'Button': self.getDefaultButton(args)
|
|
26
|
+
elif type == 'Checkbox': self.getDefaultCheckbox(args)
|
|
27
|
+
elif type == 'Column': self.getDefaultColumn(args)
|
|
28
|
+
elif type == 'Input': self.getDefaultInput(args)
|
|
29
|
+
elif type == 'Listbox': self.getDefaultListbox(args)
|
|
30
|
+
elif type == 'Multiline': self.getDefaultMultiline(args)
|
|
31
|
+
elif type == 'Text': self.getDefaultText(args)
|
|
46
32
|
return args
|
|
47
33
|
|
|
48
34
|
# Decode an argument at runtime
|
|
49
|
-
def decode(self, args, text):
|
|
35
|
+
def decode(self, handler, args, text):
|
|
50
36
|
p = text.find('=')
|
|
51
37
|
if p > 0:
|
|
52
38
|
key = text[0:p]
|
|
53
|
-
value =
|
|
39
|
+
value = text[p+1:]
|
|
40
|
+
value = json.loads(value)
|
|
41
|
+
if value['type'] == 'symbol':
|
|
42
|
+
record = handler.program.getSymbolRecord(value['name'])
|
|
43
|
+
value = handler.getSymbolValue(record)
|
|
44
|
+
if value != None: value = value['content']
|
|
45
|
+
else: raise Exception('Variable has no value')
|
|
54
46
|
args[key] = value
|
|
55
47
|
return args
|
|
56
48
|
return None
|
|
57
49
|
|
|
50
|
+
# Reduce the event properties to a list of strings
|
|
51
|
+
def getEventProperties(self, window, values):
|
|
52
|
+
keys = values.keys()
|
|
53
|
+
for key in keys:
|
|
54
|
+
v = values[key]
|
|
55
|
+
element = window.key_dict[key]
|
|
56
|
+
if type(element) is psg.Listbox:
|
|
57
|
+
# Only pick one from those selected
|
|
58
|
+
v = v[0]
|
|
59
|
+
values[key] = v
|
|
60
|
+
|
|
58
61
|
# Create an element
|
|
59
62
|
def createElement(self, type, param, args):
|
|
60
|
-
if type == 'Button':
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return psg.Column(param, expand_x=args['expand_x'], pad=args['pad'])
|
|
68
|
-
elif type == 'Input':
|
|
69
|
-
size = self.getSize(args)
|
|
70
|
-
return psg.Input(key=args['key'], size=size)
|
|
71
|
-
elif type == 'Multiline':
|
|
72
|
-
size = self.getSize(args)
|
|
73
|
-
return psg.Multiline(default_text=args['default_text'], key=args['key'], size=size)
|
|
74
|
-
elif type == 'Text':
|
|
75
|
-
size = self.getSize(args)
|
|
76
|
-
return psg.Text(text=args['text'], size=size, expand_x=args['expand_x'])
|
|
63
|
+
if type == 'Button': return self.createButton(param, args)
|
|
64
|
+
elif type == 'Checkbox': return self.createCheckbox(param, args)
|
|
65
|
+
elif type == 'Column': return self.createColumn(param, args)
|
|
66
|
+
elif type == 'Input': return self.createInput(param, args)
|
|
67
|
+
elif type == 'Listbox': return self.createListbox(param, args)
|
|
68
|
+
elif type == 'Multiline': return self.createMultiline(param, args)
|
|
69
|
+
elif type == 'Text': return self.createText(param, args)
|
|
77
70
|
else: return None
|
|
78
71
|
|
|
72
|
+
# Update a property
|
|
73
|
+
def updateProperty(self, element, property, value):
|
|
74
|
+
if property == 'disabled':
|
|
75
|
+
element.update(disabled=value)
|
|
76
|
+
elif property == 'value':
|
|
77
|
+
element.update(value=value)
|
|
78
|
+
elif property == 'values':
|
|
79
|
+
element.update(values=value)
|
|
80
|
+
|
|
79
81
|
def getSize(self, args):
|
|
80
82
|
size = args['size']
|
|
81
83
|
if size == (None, None):
|
|
82
84
|
return size
|
|
83
85
|
size = size.split()
|
|
84
86
|
return (size[0], size[1])
|
|
87
|
+
|
|
88
|
+
def getDefaultButton(self, args):
|
|
89
|
+
args['button_text'] = '(empty)'
|
|
90
|
+
args['disabled'] = False
|
|
91
|
+
args['size'] = (None, None)
|
|
92
|
+
|
|
93
|
+
def createButton(self, param, args):
|
|
94
|
+
return psg.Button(button_text=args['button_text'], disabled=args['disabled'], size=self.getSize(args))
|
|
95
|
+
|
|
96
|
+
def getDefaultCheckbox(self, args):
|
|
97
|
+
args['text'] = ''
|
|
98
|
+
args['key'] = None
|
|
99
|
+
args['size'] = (None, None)
|
|
100
|
+
args['expand_x'] = False
|
|
101
|
+
|
|
102
|
+
def createCheckbox(self, param, args):
|
|
103
|
+
return psg.Checkbox(args['text'], key=args['key'], expand_x=args['expand_x'], size=self.getSize(args))
|
|
104
|
+
|
|
105
|
+
def getDefaultColumn(self, args):
|
|
106
|
+
args['expand_x'] = False
|
|
107
|
+
args['pad'] = (0, 0)
|
|
108
|
+
|
|
109
|
+
def createColumn(self, param, args):
|
|
110
|
+
return psg.Column(param, expand_x=args['expand_x'], pad=args['pad'])
|
|
111
|
+
|
|
112
|
+
def getDefaultInput(self, args):
|
|
113
|
+
args['default_text'] = ''
|
|
114
|
+
args['key'] = None
|
|
115
|
+
args['size'] = (None, None)
|
|
116
|
+
|
|
117
|
+
def createInput(self, param, args):
|
|
118
|
+
return psg.Input(default_text=args['default_text'], key=args['key'], size=self.getSize(args))
|
|
119
|
+
|
|
120
|
+
def getDefaultListbox(self, args):
|
|
121
|
+
args['list'] = []
|
|
122
|
+
args['key'] = [None]
|
|
123
|
+
args['size'] = '10 2'
|
|
124
|
+
args['select_mode'] = None
|
|
125
|
+
|
|
126
|
+
def createListbox(self, param, args):
|
|
127
|
+
return psg.Listbox([], key=args['key'], size=self.getSize(args))
|
|
128
|
+
|
|
129
|
+
def getDefaultMultiline(self, args):
|
|
130
|
+
args['default_text'] = ''
|
|
131
|
+
args['key'] = None
|
|
132
|
+
args['size'] = (None, None)
|
|
133
|
+
|
|
134
|
+
def createMultiline(self, param, args):
|
|
135
|
+
return psg.Multiline(default_text=args['default_text'], key=args['key'], size=self.getSize(args))
|
|
136
|
+
|
|
137
|
+
def getDefaultText(self, args):
|
|
138
|
+
args['text'] = '(empty)'
|
|
139
|
+
args['size'] = (None, None)
|
|
140
|
+
args['expand_x'] = False
|
|
141
|
+
|
|
142
|
+
def createText(self, param, args):
|
|
143
|
+
return psg.Text(text=args['text'], expand_x=args['expand_x'], size=self.getSize(args))
|
|
144
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 250123.2
|
|
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>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
easycoder/README.md,sha256=PYqOc_SkIGiFbyCNs90y7JqoqWe4aO1xYIW-6bOnFKU,573
|
|
2
|
-
easycoder/__init__.py,sha256=
|
|
2
|
+
easycoder/__init__.py,sha256=v90K-BoaxHQG44wkLTa8lNRPz8R1nU2QCQKSuIOpjao,262
|
|
3
3
|
easycoder/ec_classes.py,sha256=xnWBNak8oKydkFoxHLlq9wo3lIsB3aMnTDrqbtCfoWo,1512
|
|
4
4
|
easycoder/ec_compiler.py,sha256=dFJEA_uOhD-HeSiAdBzmmA6q3LHThUVoJpSETanmSHs,4800
|
|
5
5
|
easycoder/ec_condition.py,sha256=WSbONo4zs2sX1icOVpscZDFSCAEFmTsquoc2RGcLx_k,763
|
|
6
|
-
easycoder/ec_core.py,sha256=
|
|
7
|
-
easycoder/ec_graphics.py,sha256=
|
|
8
|
-
easycoder/ec_gutils.py,sha256=
|
|
6
|
+
easycoder/ec_core.py,sha256=kbThzsgjgkk3j29XprZ904Uuh_vF6qXHcPecuCYZvuU,87061
|
|
7
|
+
easycoder/ec_graphics.py,sha256=KbLbhNDr-DjKKy8RbkzpBogvz30FXFOsmQUJxFcBg4E,23718
|
|
8
|
+
easycoder/ec_gutils.py,sha256=cREktnAoHd_1t_fDgrnQ1F60n_TzFTGvoXJeWc_LJo4,5068
|
|
9
9
|
easycoder/ec_handler.py,sha256=IJvxcrJJSR53d6DS_8H5qPHKhp9y5-GV4WXAjhZxu_o,2250
|
|
10
10
|
easycoder/ec_program.py,sha256=R8zMukA-pfRsOpcy9WqTw7fE_190dQfrMt2la23Yrs4,9904
|
|
11
11
|
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
12
12
|
easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
|
|
13
|
-
easycoder-
|
|
14
|
-
easycoder-
|
|
15
|
-
easycoder-
|
|
16
|
-
easycoder-
|
|
17
|
-
easycoder-
|
|
13
|
+
easycoder-250123.2.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
14
|
+
easycoder-250123.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
15
|
+
easycoder-250123.2.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
|
|
16
|
+
easycoder-250123.2.dist-info/METADATA,sha256=d48Jr5Dj08j1a112uEuw9OvPoEsiYNYqfiAq9dfvtS4,6162
|
|
17
|
+
easycoder-250123.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|