easycoder 250527.1__tar.gz → 250602.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 (166) hide show
  1. {easycoder-250527.1 → easycoder-250602.1}/PKG-INFO +1 -1
  2. {easycoder-250527.1 → easycoder-250602.1}/easycoder/__init__.py +1 -1
  3. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_program.py +6 -9
  4. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_pyside.py +56 -16
  5. easycoder-250527.1/easycoder/ec_graphics.py +0 -429
  6. easycoder-250527.1/easycoder/ec_gutils.py +0 -175
  7. {easycoder-250527.1 → easycoder-250602.1}/.gitignore +0 -0
  8. {easycoder-250527.1 → easycoder-250602.1}/LICENSE +0 -0
  9. {easycoder-250527.1 → easycoder-250602.1}/README.md +0 -0
  10. {easycoder-250527.1 → easycoder-250602.1}/backdrop.jpg +0 -0
  11. {easycoder-250527.1 → easycoder-250602.1}/doc/README.md +0 -0
  12. {easycoder-250527.1 → easycoder-250602.1}/doc/core/README.md +0 -0
  13. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/boolean.md +0 -0
  14. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/empty.md +0 -0
  15. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/ends.md +0 -0
  16. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/even.md +0 -0
  17. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/exists.md +0 -0
  18. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/greater.md +0 -0
  19. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/hasProperty.md +0 -0
  20. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/includes.md +0 -0
  21. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/is.md +0 -0
  22. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/less.md +0 -0
  23. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/list.md +0 -0
  24. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/none.md +0 -0
  25. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/not.md +0 -0
  26. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/numeric.md +0 -0
  27. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/object.md +0 -0
  28. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/odd.md +0 -0
  29. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/starts.md +0 -0
  30. {easycoder-250527.1 → easycoder-250602.1}/doc/core/conditions/string.md +0 -0
  31. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/add.md +0 -0
  32. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/append.md +0 -0
  33. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/assert.md +0 -0
  34. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/begin.md +0 -0
  35. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/clear.md +0 -0
  36. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/close.md +0 -0
  37. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/create.md +0 -0
  38. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/debug.md +0 -0
  39. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/decrement.md +0 -0
  40. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/delete.md +0 -0
  41. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/divide.md +0 -0
  42. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/exit.md +0 -0
  43. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/file.md +0 -0
  44. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/fork.md +0 -0
  45. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/get.md +0 -0
  46. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/go.md +0 -0
  47. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/gosub.md +0 -0
  48. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/if.md +0 -0
  49. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/import.md +0 -0
  50. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/increment.md +0 -0
  51. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/index.md +0 -0
  52. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/init.md +0 -0
  53. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/input.md +0 -0
  54. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/load.md +0 -0
  55. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/lock.md +0 -0
  56. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/log.md +0 -0
  57. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/module.md +0 -0
  58. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/multiply.md +0 -0
  59. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/negate.md +0 -0
  60. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/open.md +0 -0
  61. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/pop.md +0 -0
  62. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/post.md +0 -0
  63. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/print.md +0 -0
  64. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/push.md +0 -0
  65. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/put.md +0 -0
  66. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/read.md +0 -0
  67. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/release.md +0 -0
  68. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/replace.md +0 -0
  69. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/return.md +0 -0
  70. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/run.md +0 -0
  71. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/save.md +0 -0
  72. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/script.md +0 -0
  73. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/set.md +0 -0
  74. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/split.md +0 -0
  75. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/stack.md +0 -0
  76. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/stop.md +0 -0
  77. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/system.md +0 -0
  78. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/take.md +0 -0
  79. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/toggle.md +0 -0
  80. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/truncate.md +0 -0
  81. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/unlock.md +0 -0
  82. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/variable.md +0 -0
  83. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/wait.md +0 -0
  84. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/while.md +0 -0
  85. {easycoder-250527.1 → easycoder-250602.1}/doc/core/keywords/write.md +0 -0
  86. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/arg.md +0 -0
  87. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/args.md +0 -0
  88. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/cos.md +0 -0
  89. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/datime.md +0 -0
  90. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/decode.md +0 -0
  91. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/element.md +0 -0
  92. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/elements.md +0 -0
  93. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/empty.md +0 -0
  94. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/encode.md +0 -0
  95. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/error.md +0 -0
  96. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/files.md +0 -0
  97. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/float.md +0 -0
  98. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/from.md +0 -0
  99. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/hash.md +0 -0
  100. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/index.md +0 -0
  101. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/integer.md +0 -0
  102. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/json.md +0 -0
  103. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/keys.md +0 -0
  104. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/left.md +0 -0
  105. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/length.md +0 -0
  106. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/lowercase.md +0 -0
  107. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/memory.md +0 -0
  108. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/modification.md +0 -0
  109. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/modulo.md +0 -0
  110. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/newline.md +0 -0
  111. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/now.md +0 -0
  112. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/position.md +0 -0
  113. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/property.md +0 -0
  114. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/random.md +0 -0
  115. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/right.md +0 -0
  116. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/sin.md +0 -0
  117. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/stringify.md +0 -0
  118. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/tab.md +0 -0
  119. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/tan.md +0 -0
  120. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/timestamp.md +0 -0
  121. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/today.md +0 -0
  122. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/trim.md +0 -0
  123. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/type.md +0 -0
  124. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/uppercase.md +0 -0
  125. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/value.md +0 -0
  126. {easycoder-250527.1 → easycoder-250602.1}/doc/core/values/weekday.md +0 -0
  127. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/README.md +0 -0
  128. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/attach.md +0 -0
  129. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/close.md +0 -0
  130. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/create.md +0 -0
  131. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/ellipse.md +0 -0
  132. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/image.md +0 -0
  133. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/move.md +0 -0
  134. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/on.md +0 -0
  135. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/rectangle.md +0 -0
  136. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/render.md +0 -0
  137. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/run.md +0 -0
  138. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/set.md +0 -0
  139. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/keywords/text.md +0 -0
  140. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/values/attribute.md +0 -0
  141. {easycoder-250527.1 → easycoder-250602.1}/doc/graphics/values/window.md +0 -0
  142. {easycoder-250527.1 → easycoder-250602.1}/easycoder/README.md +0 -0
  143. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_classes.py +0 -0
  144. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_compiler.py +0 -0
  145. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_condition.py +0 -0
  146. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_core.py +0 -0
  147. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_handler.py +0 -0
  148. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_timestamp.py +0 -0
  149. {easycoder-250527.1 → easycoder-250602.1}/easycoder/ec_value.py +0 -0
  150. {easycoder-250527.1 → easycoder-250602.1}/images/Semoigo Dawn.jpg +0 -0
  151. {easycoder-250527.1 → easycoder-250602.1}/json/graphics-demo.json +0 -0
  152. {easycoder-250527.1 → easycoder-250602.1}/plugins/ec_keyboard.py +0 -0
  153. {easycoder-250527.1 → easycoder-250602.1}/plugins/ec_p100.py +0 -0
  154. {easycoder-250527.1 → easycoder-250602.1}/plugins/ec_pyside6.py +0 -0
  155. {easycoder-250527.1 → easycoder-250602.1}/plugins/points.py +0 -0
  156. {easycoder-250527.1 → easycoder-250602.1}/pyproject.toml +0 -0
  157. {easycoder-250527.1 → easycoder-250602.1}/scripts/benchmark.ecs +0 -0
  158. {easycoder-250527.1 → easycoder-250602.1}/scripts/config.ecg +0 -0
  159. {easycoder-250527.1 → easycoder-250602.1}/scripts/ec_keyboard.py +0 -0
  160. {easycoder-250527.1 → easycoder-250602.1}/scripts/findxr.ecs +0 -0
  161. {easycoder-250527.1 → easycoder-250602.1}/scripts/fizzbuzz.ecs +0 -0
  162. {easycoder-250527.1 → easycoder-250602.1}/scripts/hello.ecs +0 -0
  163. {easycoder-250527.1 → easycoder-250602.1}/scripts/points.ecs +0 -0
  164. {easycoder-250527.1 → easycoder-250602.1}/scripts/test.ecs +0 -0
  165. {easycoder-250527.1 → easycoder-250602.1}/scripts/tests.ecs +0 -0
  166. {easycoder-250527.1 → easycoder-250602.1}/testrc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 250527.1
3
+ Version: 250602.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>
@@ -9,4 +9,4 @@ from .ec_program import *
9
9
  from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
 
12
- __version__ = "250527.1"
12
+ __version__ = "250602.1"
@@ -24,9 +24,6 @@ class Program:
24
24
  exit()
25
25
  self.classes=[Core]
26
26
  scriptName = argv
27
- if scriptName.endswith('.ecg'):
28
- from .ec_graphics import Graphics
29
- self.classes.append(Graphics)
30
27
 
31
28
  f = open(scriptName, 'r')
32
29
  source = f.read()
@@ -52,6 +49,11 @@ class Program:
52
49
  self.ticker = 0
53
50
  self.running = True
54
51
 
52
+ # This is called at 10msec intervals by the GUI code
53
+ def flushCB(self):
54
+ self.ticker += 1
55
+ flush()
56
+
55
57
  def start(self, parent=None, module = None, exports=[]):
56
58
  self.parent = parent
57
59
  self.exports = exports
@@ -289,11 +291,6 @@ class Program:
289
291
  self.parent.waiting = False
290
292
  self.parent.program.run(self.parent.pc)
291
293
 
292
- # This is called at 10msec intervals by the GUI code
293
- def flushCB(self):
294
- self.ticker += 1
295
- flush()
296
-
297
294
  # Flush the queue
298
295
  def flush(self, pc):
299
296
  global queue
@@ -326,7 +323,7 @@ class Program:
326
323
  elif self.pc == None or self.pc == 0 or self.pc >= len(self.code):
327
324
  break
328
325
 
329
- # Run the script
326
+ # Run the script at a given PC value
330
327
  def run(self, pc):
331
328
  global queue
332
329
  item = Object()
@@ -40,12 +40,16 @@ class Graphics(Handler):
40
40
  def __init__(self, compiler):
41
41
  Handler.__init__(self, compiler)
42
42
  self.blocked = False
43
+ self.runOnTick = 0
43
44
 
44
45
  def getName(self):
45
46
  return 'graphics'
46
47
 
47
48
  def closeEvent(self):
48
49
  print('window closed')
50
+
51
+ def isWidget(self, keyword):
52
+ return keyword in ['layout', 'groupbox', 'label', 'pushbutton', 'checkbox', 'lineinput', 'listbox', 'combobox']
49
53
 
50
54
  #############################################################################
51
55
  # Keyword handlers
@@ -84,7 +88,7 @@ class Graphics(Handler):
84
88
  elif self.isSymbol():
85
89
  record = self.getSymbolRecord()
86
90
  if record['extra'] == 'gui':
87
- if record['keyword'] in ['layout', 'groupbox', 'label', 'pushbutton', 'checkbox', 'lineinput', 'listbox', 'combobox']:
91
+ if self.isWidget(record['keyword']):
88
92
  if self.peek() == 'to':
89
93
  # (2)
90
94
  record = self.getSymbolRecord()
@@ -170,9 +174,11 @@ class Graphics(Handler):
170
174
  # clear {widget}
171
175
  def k_clear(self, command):
172
176
  if self.nextIsSymbol():
173
- command['name'] = self.getSymbolRecord()['name']
174
- self.add(command)
175
- return True
177
+ record = self.getSymbolRecord()
178
+ if self.isWidget(record['keyword']):
179
+ command['name'] = record['name']
180
+ self.add(command)
181
+ return True
176
182
  return False
177
183
 
178
184
  def r_clear(self, command):
@@ -583,9 +589,9 @@ class Graphics(Handler):
583
589
 
584
590
  # on click {pushbutton}
585
591
  # on select {combobox}/{listbox}
592
+ # on tick
586
593
  def k_on(self, command):
587
594
  def setupOn():
588
- command['name'] = record['name']
589
595
  command['goto'] = self.getPC() + 2
590
596
  self.add(command)
591
597
  self.nextToken()
@@ -606,34 +612,65 @@ class Graphics(Handler):
606
612
  cmd['keyword'] = 'stop'
607
613
  cmd['debug'] = False
608
614
  self.addCommand(cmd)
609
- # Fixup the link
615
+ # Fixup the goto
610
616
  self.getCommandAt(pcNext)['goto'] = self.getPC()
611
617
 
612
618
  token = self.nextToken()
619
+ command['type'] = token
613
620
  if token == 'click':
614
621
  if self.nextIsSymbol():
615
622
  record = self.getSymbolRecord()
616
623
  if record['keyword'] == 'pushbutton':
624
+ command['name'] = record['name']
617
625
  setupOn()
618
626
  return True
619
627
  elif token == 'select':
620
628
  if self.nextIsSymbol():
621
629
  record = self.getSymbolRecord()
622
630
  if record['keyword'] in ['combobox', 'listbox']:
631
+ command['name'] = record['name']
623
632
  setupOn()
624
633
  return True
634
+ elif token == 'tick':
635
+ command['tick'] = True
636
+ command['runOnTick'] = self.getPC() + 2
637
+ self.addCommand(command)
638
+ self.nextToken()
639
+ # Step over the on tick action
640
+ pcNext = self.getPC()
641
+ cmd = {}
642
+ cmd['domain'] = 'core'
643
+ cmd['lino'] = command['lino']
644
+ cmd['keyword'] = 'gotoPC'
645
+ cmd['goto'] = 0
646
+ cmd['debug'] = False
647
+ self.addCommand(cmd)
648
+ # This is the on tick handler
649
+ self.compileOne()
650
+ cmd = {}
651
+ cmd['domain'] = 'core'
652
+ cmd['lino'] = command['lino']
653
+ cmd['keyword'] = 'stop'
654
+ cmd['debug'] = False
655
+ self.addCommand(cmd)
656
+ # Fixup the goto
657
+ self.getCommandAt(pcNext)['goto'] = self.getPC()
658
+ return True
625
659
  return False
626
660
 
627
661
  def r_on(self, command):
628
- record = self.getVariable(command['name'])
629
- widget = record['widget']
630
- keyword = record['keyword']
631
- if keyword == 'pushbutton':
632
- widget.clicked.connect(lambda: self.run(command['goto']))
633
- elif keyword == 'combobox':
634
- widget.currentIndexChanged.connect(lambda: self.run(command['goto']))
635
- elif keyword == 'listbox':
636
- widget.itemClicked.connect(lambda: self.run(command['goto']))
662
+ if command['type'] == 'tick':
663
+ self.runOnTick = command['runOnTick']
664
+ else:
665
+ record = self.getVariable(command['name'])
666
+ widget = record['widget']
667
+ keyword = record['keyword']
668
+ if keyword == 'pushbutton':
669
+ widget.clicked.connect(lambda: self.run(command['goto']))
670
+ elif keyword == 'combobox':
671
+ widget.currentIndexChanged.connect(lambda: self.run(command['goto']))
672
+ elif keyword == 'listbox':
673
+ widget.itemClicked.connect(lambda: self.run(command['goto']))
637
674
  return self.nextPC()
638
675
 
639
676
  # Declare a pushbutton variable
@@ -915,7 +952,10 @@ class Graphics(Handler):
915
952
  def init():
916
953
  self.program.flush(self.nextPC())
917
954
  def flush():
918
- if not self.blocked: self.program.flushCB()
955
+ if not self.blocked:
956
+ if self.runOnTick != 0:
957
+ self.program.run(self.runOnTick)
958
+ self.program.flushCB()
919
959
  timer = QTimer()
920
960
  timer.timeout.connect(flush)
921
961
  timer.start(10)
@@ -1,429 +0,0 @@
1
- from .ec_classes import FatalError, RuntimeError
2
- from .ec_handler import Handler
3
- from .ec_gutils import GUtils
4
- import PySimpleGUI as psg
5
- import json
6
- from copy import deepcopy
7
-
8
- class Graphics(Handler):
9
-
10
- def __init__(self, compiler):
11
- Handler.__init__(self, compiler)
12
- self.utils = GUtils()
13
-
14
- def getName(self):
15
- return 'graphics'
16
-
17
- #############################################################################
18
- # Keyword handlers
19
-
20
- def k_add(self, command):
21
- token = self.nextToken()
22
- if self.isSymbol():
23
- symbolRecord = self.getSymbolRecord()
24
- name = symbolRecord['name']
25
- keyword = symbolRecord['keyword']
26
- if keyword == 'layout':
27
- command['args'] = name
28
- elif keyword in ['column', 'frame', 'tab']:
29
- command['name'] = name
30
- command['type'] = token
31
- if self.peek() == 'to':
32
- command['args'] = name
33
- else:
34
- command['args'] = self.utils.getArgs(self)
35
- else:
36
- command['type'] = token
37
- command['args'] = self.utils.getArgs(self)
38
- if self.nextIs('to'):
39
- if self.nextIsSymbol():
40
- symbolRecord = self.getSymbolRecord()
41
- if symbolRecord['keyword'] in ['column', 'frame', 'layout', 'tab']:
42
- command['target'] = symbolRecord['name']
43
- self.addCommand(command)
44
- return True
45
- return False
46
-
47
- def r_add(self, command):
48
- def create(type, layout, args2, target):
49
- args = self.utils.getDefaultArgs(type)
50
- for n in range(0, len(args2)):
51
- try:
52
- self.utils.decode(self, args, args2[n])
53
- except Exception as e:
54
- RuntimeError(self.program, e)
55
- item = self.utils.createWidget(type, layout, args)
56
- target['layout'].append(item)
57
-
58
- target = self.getVariable(command['target'])
59
- type = command['type']
60
- args = command['args']
61
- if not 'layout' in target:
62
- target['layout'] = []
63
- if len(args) > 0 and args[0] == '{':
64
- args = json.loads(self.getRuntimeValue(json.loads(args)))
65
- if type in ['Column', 'Frame', 'Tab']:
66
- record = self.getVariable(command['name'])
67
- layout = record['layout']
68
- create(type, layout, args, target)
69
- else:
70
- create(type, None, args, target)
71
- else:
72
- if type in ['Column', 'Frame', 'Tab']:
73
- record = self.getVariable(command['name'])
74
- layout = record['layout']
75
- create(type, layout, args, target)
76
- else:
77
- v = self.getVariable(args)
78
- target['layout'].append(v['layout'])
79
- return self.nextPC()
80
-
81
- def k_close(self, command):
82
- if self.nextIsSymbol():
83
- symbolRecord = self.getSymbolRecord()
84
- if symbolRecord['keyword'] == 'window':
85
- command['target'] = symbolRecord['name']
86
- self.add(command)
87
- return True
88
- return False
89
-
90
- def r_close(self, command):
91
- target = self.getVariable(command['target'])
92
- target['window'].close()
93
- return self.nextPC()
94
-
95
- def k_column(self, command):
96
- return self.compileVariable(command)
97
-
98
- def r_column(self, command):
99
- return self.nextPC()
100
-
101
- # create layout {name} from {spec}
102
- # create {window} layout {layout}
103
- def k_create(self, command):
104
- token = self.nextToken()
105
- if token == 'layout':
106
- if self.nextIsSymbol():
107
- record = self.getSymbolRecord()
108
- if record['keyword'] == 'layout':
109
- command['layout'] = record['name']
110
- if self.nextIs('from'):
111
- command['spec'] = self.nextValue()
112
- self.addCommand(command)
113
- return True
114
- elif self.isSymbol():
115
- symbolRecord = self.getSymbolRecord()
116
- command['name'] = symbolRecord['name']
117
- command['title'] = self.nextValue()
118
- if self.nextIs('layout'):
119
- if self.nextIsSymbol():
120
- symbolRecord = self.getSymbolRecord()
121
- if symbolRecord['keyword'] == 'layout':
122
- command['layout'] = symbolRecord['name']
123
- self.addCommand(command)
124
- return True
125
- return False
126
-
127
- def r_create(self, command):
128
- def processItem(name, item):
129
- print(name, item['type'])
130
- children = item['#']
131
- if isinstance(children, list):
132
- print("List")
133
- for child in children:
134
- print(child)
135
- else:
136
- print("Single:", children)
137
-
138
- if 'spec' in command:
139
- spec = self.getRuntimeValue(command['spec'])
140
- layout = self.getVariable(command['layout'])
141
- for key in spec.keys():
142
- item = spec[key]
143
- print(key, item['type'])
144
- if item['type'] == 'column':
145
- for child in item['#']: processItem(child, item[child])
146
- return self.nextPC()
147
- else:
148
- record = self.getVariable(command['name'])
149
- title = self.getRuntimeValue(command['title'])
150
- layout = self.getVariable(command['layout'])['layout']
151
- window = psg.Window(title, layout, finalize=True)
152
- record['window'] = window
153
- record['eventHandlers'] = {}
154
- self.program.run(self.nextPC())
155
- self.mainLoop(record)
156
- return 0
157
-
158
- def k_frame(self, command):
159
- return self.compileVariable(command)
160
-
161
- def r_frame(self, command):
162
- return self.nextPC()
163
-
164
- # get {variable} from popup {type} {message} {title}
165
- def k_get(self, command):
166
- if self.nextIsSymbol():
167
- symbolRecord = self.getSymbolRecord()
168
- if symbolRecord['hasValue']:
169
- command['target'] = self.getToken()
170
- else:
171
- FatalError(self.compiler, f'Variable "{symbolRecord["name"]}" does not hold a value')
172
- if symbolRecord['hasValue']:
173
- if self.nextIs('from'):
174
- if self.nextIs('popup'):
175
- command['ptype'] = self.nextToken()
176
- command['message'] = self.nextValue()
177
- command['title'] = self.nextValue()
178
- self.addCommand(command)
179
- return True
180
- return False
181
-
182
- def r_get(self, command):
183
- target = self.getVariable(command['target'])
184
- ptype = command['ptype']
185
- if ptype == 'text':
186
- text = psg.popup_get_text(self.getRuntimeValue(command['message']), title=self.getRuntimeValue(command['title']))
187
- elif ptype == 'ok-cancel':
188
- text = psg.popup_ok_cancel(self.getRuntimeValue(command['message']), title=self.getRuntimeValue(command['title']))
189
- elif ptype == 'yes-no':
190
- text = psg.popup_yes_no(self.getRuntimeValue(command['message']), title=self.getRuntimeValue(command['title']))
191
- else:
192
- return None
193
- v = {}
194
- v['type'] = 'text'
195
- v['content'] = text
196
- self.program.putSymbolValue(target, v)
197
- return self.nextPC()
198
-
199
- def k_init(self, command):
200
- if self.nextIsSymbol():
201
- symbolRecord = self.getSymbolRecord()
202
- if symbolRecord['keyword'] in ['column', 'frame', 'layout', 'tab']:
203
- command['target'] = symbolRecord['name']
204
- self.add(command)
205
- return True
206
- return False
207
-
208
- def r_init(self, command):
209
- target = self.getVariable(command['target'])
210
- target['layout'] = []
211
- return self.nextPC()
212
-
213
- def k_layout(self, command):
214
- return self.compileVariable(command)
215
-
216
- def r_layout(self, command):
217
- return self.nextPC()
218
-
219
- def k_on(self, command):
220
- token = self.nextToken()
221
- if token == 'event':
222
- command['key'] = self.nextValue()
223
- if self.nextIs('in'):
224
- if self.nextIsSymbol():
225
- record = self.getSymbolRecord()
226
- if record['keyword'] == 'window':
227
- command['window'] = record['name']
228
- command['goto'] = self.getPC() + 2
229
- self.add(command)
230
- self.nextToken()
231
- pcNext = self.getPC()
232
- cmd = {}
233
- cmd['domain'] = 'core'
234
- cmd['lino'] = command['lino']
235
- cmd['keyword'] = 'gotoPC'
236
- cmd['goto'] = 0
237
- cmd['debug'] = False
238
- self.addCommand(cmd)
239
- self.compileOne()
240
- cmd = {}
241
- cmd['domain'] = 'core'
242
- cmd['lino'] = command['lino']
243
- cmd['keyword'] = 'stop'
244
- cmd['debug'] = False
245
- self.addCommand(cmd)
246
- # Fixup the link
247
- self.getCommandAt(pcNext)['goto'] = self.getPC()
248
- return True
249
- return False
250
-
251
- def r_on(self, command):
252
- key = self.getRuntimeValue(command['key'])
253
- window = self.getVariable(command['window'])
254
- window['eventHandlers'][key] = lambda: self.run(command['goto'])
255
- return self.nextPC()
256
-
257
- # popup {message} {title}
258
- def k_popup(self, command):
259
- command['message'] = self.nextValue()
260
- command['title'] = self.nextValue()
261
- self.addCommand(command)
262
- return True
263
-
264
- def r_popup(self, command):
265
- psg.popup(self.getRuntimeValue(command['message']), title=self.getRuntimeValue(command['title']))
266
- return self.nextPC()
267
-
268
- def k_refresh(self, command):
269
- if self.nextIsSymbol():
270
- symbolRecord = self.getSymbolRecord()
271
- if symbolRecord['keyword'] == 'window':
272
- command['target'] = symbolRecord['name']
273
- self.add(command)
274
- return True
275
- return False
276
-
277
- def r_refresh(self, command):
278
- target = self.getVariable(command['target'])
279
- target['window'].refresh()
280
- return self.nextPC()
281
-
282
- # set property {property} of {key} in {window} to {value}
283
- def k_set(self, command):
284
- if self.nextIs('property'):
285
- command['property'] = self.nextValue()
286
- if self.nextIs('of'):
287
- command['key'] = self.nextValue()
288
- if self.nextIs('in'):
289
- if self.nextIsSymbol():
290
- record = self.getSymbolRecord()
291
- if record['keyword'] == 'window':
292
- name = record['name']
293
- command['window'] = name
294
- if self.nextIs('to'):
295
- command['value'] = self.nextValue()
296
- self.add(command)
297
- return True
298
- else: RuntimeError(self.program, f'\'{name}\' is not a window variable')
299
- else: RuntimeError(self.program, 'No window variable given')
300
- return False
301
-
302
- def r_set(self, command):
303
- property = self.getRuntimeValue(command['property'])
304
- key = self.getRuntimeValue(command['key'])
305
- windowRecord = self.getVariable(command['window'])
306
- window = windowRecord['window']
307
- value = self.getRuntimeValue(command['value'])
308
- self.utils.updateProperty(window[key], property, value)
309
- return self.nextPC()
310
-
311
- def k_window(self, command):
312
- return self.compileVariable(command)
313
-
314
- def r_window(self, command):
315
- return self.nextPC()
316
-
317
- #############################################################################
318
- # Compile a value in this domain
319
- def compileValue(self):
320
- value = {}
321
- value['domain'] = self.getName()
322
- token = self.getToken()
323
- if self.isSymbol():
324
- value['name'] = token
325
- symbolRecord = self.getSymbolRecord()
326
- keyword = symbolRecord['keyword']
327
- if keyword == 'event':
328
- value['type'] = 'symbol'
329
- return value
330
- return None
331
-
332
- if self.getToken() == 'the':
333
- self.nextToken()
334
-
335
- token = self.getToken()
336
- value['type'] = token
337
-
338
- if token == 'event':
339
- return value
340
-
341
- if token == 'property':
342
- value['property'] = self.nextValue()
343
- if self.nextIs('of'):
344
- if self.nextToken() == 'the':
345
- if self.nextIs('event'):
346
- return value
347
- return None
348
-
349
- if token == 'value':
350
- if self.nextIs('of'):
351
- if self.nextIs('key'):
352
- value['key'] = self.nextValue()
353
- if self.nextIs('in'):
354
- if self.nextIsSymbol():
355
- record = self.getSymbolRecord()
356
- if record['keyword'] == 'window':
357
- value['window'] = record['name']
358
- return value
359
- return None
360
-
361
- #############################################################################
362
- # Modify a value or leave it unchanged.
363
- def modifyValue(self, value):
364
- return value
365
-
366
- #############################################################################
367
- # Value handlers
368
-
369
- # This is used by the expression evaluator to get the value of a symbol
370
- def v_symbol(self, symbolRecord):
371
- if symbolRecord['keyword'] == 'event':
372
- return self.getSymbolValue(symbolRecord)
373
- else:
374
- return None
375
-
376
- def v_event(self, v):
377
- window = self.eventValues['window']
378
- values = self.eventValues['values']
379
- self.utils.getEventProperties(window, values)
380
- v['type'] = 'text'
381
- v['content'] = values
382
- return v
383
-
384
- def v_property(self, v):
385
- property = self.getRuntimeValue(v['property'])
386
- window = self.eventValues['window']
387
- values = self.eventValues['values']
388
- self.utils.getEventProperties(window, values)
389
- v['type'] = 'text'
390
- v['content'] = values[property]
391
- return v
392
-
393
- def v_value(self, v):
394
- key = self.getRuntimeValue(v['key'])
395
- window = self.getVariable(v['window'])
396
- value = self.utils.getWidgetValue(window, key)
397
- if value == None: RuntimeError(self.program, 'getWidgetValue: unimplemented widget type')
398
- v = deepcopy(v)
399
- v['type'] = 'text'
400
- v['content'] = value
401
- return v
402
-
403
- #############################################################################
404
- # Compile a condition
405
- def compileCondition(self):
406
- condition = {}
407
- return condition
408
-
409
- #############################################################################
410
- # Condition handlers
411
-
412
- #############################################################################
413
- # The main loop
414
- def mainLoop(self, windowRecord):
415
- window = windowRecord['window']
416
- eventHandlers = windowRecord['eventHandlers']
417
- while True:
418
- event, values = window.Read(timeout=100)
419
- if event == psg.WIN_CLOSED or event == "EXIT":
420
- del window
421
- break
422
- if event == '__TIMEOUT__': self.program.flushCB()
423
- else:
424
- if event in eventHandlers:
425
- self.eventValues = {}
426
- self.eventValues['values'] = values
427
- self.eventValues['window'] = window
428
- eventHandlers[event]()
429
- pass