easycoder 250123.2__tar.gz → 250204.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 (175) hide show
  1. {easycoder-250123.2 → easycoder-250204.1}/PKG-INFO +1 -1
  2. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/lock.md +2 -2
  3. easycoder-250204.1/doc/core/keywords/log.md +21 -0
  4. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/module.md +1 -1
  5. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/print.md +1 -2
  6. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/README.md +4 -2
  7. {easycoder-250123.2 → easycoder-250204.1}/easycoder/__init__.py +1 -1
  8. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_core.py +19 -10
  9. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_graphics.py +34 -325
  10. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_gutils.py +25 -5
  11. {easycoder-250123.2 → easycoder-250204.1}/LICENSE +0 -0
  12. {easycoder-250123.2 → easycoder-250204.1}/README.md +0 -0
  13. {easycoder-250123.2 → easycoder-250204.1}/doc/README.md +0 -0
  14. {easycoder-250123.2 → easycoder-250204.1}/doc/core/README.md +0 -0
  15. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/boolean.md +0 -0
  16. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/empty.md +0 -0
  17. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/ends.md +0 -0
  18. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/even.md +0 -0
  19. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/exists.md +0 -0
  20. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/greater.md +0 -0
  21. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/hasProperty.md +0 -0
  22. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/includes.md +0 -0
  23. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/is.md +0 -0
  24. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/less.md +0 -0
  25. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/list.md +0 -0
  26. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/none.md +0 -0
  27. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/not.md +0 -0
  28. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/numeric.md +0 -0
  29. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/object.md +0 -0
  30. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/odd.md +0 -0
  31. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/starts.md +0 -0
  32. {easycoder-250123.2 → easycoder-250204.1}/doc/core/conditions/string.md +0 -0
  33. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/add.md +0 -0
  34. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/append.md +0 -0
  35. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/assert.md +0 -0
  36. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/begin.md +0 -0
  37. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/clear.md +0 -0
  38. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/close.md +0 -0
  39. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/create.md +0 -0
  40. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/debug.md +0 -0
  41. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/decrement.md +0 -0
  42. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/delete.md +0 -0
  43. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/divide.md +0 -0
  44. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/exit.md +0 -0
  45. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/file.md +0 -0
  46. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/fork.md +0 -0
  47. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/get.md +0 -0
  48. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/go.md +0 -0
  49. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/gosub.md +0 -0
  50. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/if.md +0 -0
  51. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/import.md +0 -0
  52. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/increment.md +0 -0
  53. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/index.md +0 -0
  54. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/init.md +0 -0
  55. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/input.md +0 -0
  56. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/load.md +0 -0
  57. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/multiply.md +0 -0
  58. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/negate.md +0 -0
  59. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/open.md +0 -0
  60. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/pop.md +0 -0
  61. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/post.md +0 -0
  62. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/push.md +0 -0
  63. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/put.md +0 -0
  64. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/read.md +0 -0
  65. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/release.md +0 -0
  66. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/replace.md +0 -0
  67. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/return.md +0 -0
  68. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/run.md +0 -0
  69. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/save.md +0 -0
  70. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/script.md +0 -0
  71. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/set.md +0 -0
  72. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/split.md +0 -0
  73. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/stack.md +0 -0
  74. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/stop.md +0 -0
  75. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/system.md +0 -0
  76. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/take.md +0 -0
  77. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/toggle.md +0 -0
  78. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/truncate.md +0 -0
  79. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/unlock.md +0 -0
  80. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/variable.md +0 -0
  81. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/wait.md +0 -0
  82. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/while.md +0 -0
  83. {easycoder-250123.2 → easycoder-250204.1}/doc/core/keywords/write.md +0 -0
  84. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/arg.md +0 -0
  85. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/args.md +0 -0
  86. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/cos.md +0 -0
  87. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/datime.md +0 -0
  88. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/decode.md +0 -0
  89. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/element.md +0 -0
  90. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/elements.md +0 -0
  91. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/empty.md +0 -0
  92. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/encode.md +0 -0
  93. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/error.md +0 -0
  94. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/files.md +0 -0
  95. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/float.md +0 -0
  96. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/from.md +0 -0
  97. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/hash.md +0 -0
  98. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/index.md +0 -0
  99. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/integer.md +0 -0
  100. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/json.md +0 -0
  101. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/keys.md +0 -0
  102. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/left.md +0 -0
  103. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/length.md +0 -0
  104. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/lowercase.md +0 -0
  105. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/memory.md +0 -0
  106. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/modification.md +0 -0
  107. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/modulo.md +0 -0
  108. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/newline.md +0 -0
  109. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/now.md +0 -0
  110. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/position.md +0 -0
  111. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/property.md +0 -0
  112. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/random.md +0 -0
  113. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/right.md +0 -0
  114. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/sin.md +0 -0
  115. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/stringify.md +0 -0
  116. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/tab.md +0 -0
  117. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/tan.md +0 -0
  118. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/timestamp.md +0 -0
  119. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/today.md +0 -0
  120. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/trim.md +0 -0
  121. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/type.md +0 -0
  122. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/uppercase.md +0 -0
  123. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/value.md +0 -0
  124. {easycoder-250123.2 → easycoder-250204.1}/doc/core/values/weekday.md +0 -0
  125. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/attach.md +0 -0
  126. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/close.md +0 -0
  127. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/create.md +0 -0
  128. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/ellipse.md +0 -0
  129. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/image.md +0 -0
  130. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/move.md +0 -0
  131. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/on.md +0 -0
  132. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/rectangle.md +0 -0
  133. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/render.md +0 -0
  134. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/run.md +0 -0
  135. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/set.md +0 -0
  136. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/keywords/text.md +0 -0
  137. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/values/attribute.md +0 -0
  138. {easycoder-250123.2 → easycoder-250204.1}/doc/graphics/values/window.md +0 -0
  139. {easycoder-250123.2 → easycoder-250204.1}/easycoder/README.md +0 -0
  140. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_classes.py +0 -0
  141. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_compiler.py +0 -0
  142. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_condition.py +0 -0
  143. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_handler.py +0 -0
  144. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_program.py +0 -0
  145. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_timestamp.py +0 -0
  146. {easycoder-250123.2 → easycoder-250204.1}/easycoder/ec_value.py +0 -0
  147. {easycoder-250123.2 → easycoder-250204.1}/images/Semoigo Dawn.jpg +0 -0
  148. {easycoder-250123.2 → easycoder-250204.1}/json/graphics-demo.json +0 -0
  149. {easycoder-250123.2 → easycoder-250204.1}/plugins/ec_keyboard.py +0 -0
  150. {easycoder-250123.2 → easycoder-250204.1}/plugins/ec_p100.py +0 -0
  151. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/4-function.json +0 -0
  152. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/4-function.png +0 -0
  153. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-0.json +0 -0
  154. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-0.png +0 -0
  155. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-1.json +0 -0
  156. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-1.png +0 -0
  157. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-2.json +0 -0
  158. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-2.png +0 -0
  159. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-3.json +0 -0
  160. {easycoder-250123.2 → easycoder-250204.1}/plugins/keyboards/qwerty-3.png +0 -0
  161. {easycoder-250123.2 → easycoder-250204.1}/plugins/points.py +0 -0
  162. {easycoder-250123.2 → easycoder-250204.1}/pyproject.toml +0 -0
  163. {easycoder-250123.2 → easycoder-250204.1}/scripts/README.md +0 -0
  164. {easycoder-250123.2 → easycoder-250204.1}/scripts/benchmark.ecs +0 -0
  165. {easycoder-250123.2 → easycoder-250204.1}/scripts/config.ecg +0 -0
  166. {easycoder-250123.2 → easycoder-250204.1}/scripts/connect.ecg +0 -0
  167. {easycoder-250123.2 → easycoder-250204.1}/scripts/ec_keyboard.py +0 -0
  168. {easycoder-250123.2 → easycoder-250204.1}/scripts/findxr.ecs +0 -0
  169. {easycoder-250123.2 → easycoder-250204.1}/scripts/fizzbuzz.ecs +0 -0
  170. {easycoder-250123.2 → easycoder-250204.1}/scripts/hello.ecs +0 -0
  171. {easycoder-250123.2 → easycoder-250204.1}/scripts/points.ecs +0 -0
  172. {easycoder-250123.2 → easycoder-250204.1}/scripts/test.ecs +0 -0
  173. {easycoder-250123.2 → easycoder-250204.1}/scripts/testg.ecg +0 -0
  174. {easycoder-250123.2 → easycoder-250204.1}/scripts/tests.ecs +0 -0
  175. {easycoder-250123.2 → easycoder-250204.1}/test.ecs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: easycoder
3
- Version: 250123.2
3
+ Version: 250204.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,7 +9,7 @@
9
9
  ## Description:
10
10
  Locks a variable to prevent it being modified. See also [unlock](unlock.md).
11
11
 
12
- Next: [lock](lock.md)
13
- Prev: [init](init.md)
12
+ Next: [log](log.md)
13
+ Prev: [load](load.md)
14
14
 
15
15
  [Back](../../README.md)
@@ -0,0 +1,21 @@
1
+ # log
2
+
3
+ ## Syntax:
4
+ `log {message}`
5
+
6
+ ## Examples:
7
+ ``log `ProcessResponses` ``
8
+
9
+ ## Description:
10
+ Prints a log message to the console.
11
+
12
+ The output is prefixed by the current time and the script line number of the print command. This is very useful in large scripts when trying to find a log command that is outputting some unwanted messages. For example, the above example produces the output
13
+
14
+ `14:46:59.048918: 1056-> ProcessResponses`
15
+
16
+ See also [print](print.md).
17
+
18
+ Next: [module](module.md)
19
+ Prev: [lock](lock.md)
20
+
21
+ [Back](../../README.md)
@@ -12,6 +12,6 @@ Declare a module variable, which enables you to run another script as a child of
12
12
  Module variables can be assigned any number of elements - see [set the elements](set.md).
13
13
 
14
14
  Next: [multiply](multiply.md)
15
- Prev: [lock](lock.md)
15
+ Prev: [log](log.md)
16
16
 
17
17
  [Back](../../README.md)
@@ -7,8 +7,7 @@
7
7
  `print Data cat newline`
8
8
 
9
9
  ## Description:
10
- Print something to the terminal. The second example shows the use of string catenation, which is also covered in [values](../core.md).
11
- The output is prefixed by the script line number of the print command. This is very useful in large scripts when trying to figure where print output is coming from.
10
+ Print something to the terminal. The second example shows the use of string catenation, which is also covered in [values](../core.md). See also [log](log.md)
12
11
 
13
12
  Next: [push](push.md)
14
13
  Prev: [post](post.md)
@@ -1,5 +1,7 @@
1
1
  # The 'graphics' package
2
2
 
3
+ **Documentation yet to be written**
4
+
3
5
  The graphics package contains keywords values and conditionals needed for programming graphical applications.
4
6
 
5
7
  There are three primary components to the language:
@@ -10,11 +12,11 @@ There are three primary components to the language:
10
12
 
11
13
  The core keywords are:
12
14
 
13
- [attach](attach.md) [close](close.md) [create](create.md) [ellipse](ellipse.md) [image](image.md) [move](move.md) [on](on.md) [rectangle](rectangle.md) [render](render.md) [run](run.md) [set](set.md) [text](text.md)
15
+
14
16
 
15
17
  The core values are:
16
18
 
17
- [attribute](attribute.md) [window](window.md)
19
+
18
20
 
19
21
  The core conditions are:
20
22
 
@@ -9,4 +9,4 @@ from .ec_program import *
9
9
  from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
 
12
- __version__ = "250123.2"
12
+ __version__ = "250204.1"
@@ -1,4 +1,4 @@
1
- import json, math, hashlib, threading, os, subprocess, sys, requests, time, numbers, base64
1
+ import json, math, hashlib, threading, os, subprocess, sys, requests, time, numbers, base64, binascii
2
2
  from psutil import Process
3
3
  from datetime import datetime, timezone
4
4
  from random import randrange
@@ -484,7 +484,6 @@ class Core(Handler):
484
484
  except:
485
485
  pass
486
486
  RuntimeError(self.program, f'There is no label "{label}"')
487
- return None
488
487
 
489
488
  def r_gotoPC(self, command):
490
489
  return command['goto']
@@ -499,12 +498,14 @@ class Core(Handler):
499
498
 
500
499
  def r_gosub(self, command):
501
500
  label = command['gosub'] + ':'
502
- address = self.symbols[label]
503
- if address != None:
504
- self.stack.append(self.nextPC())
505
- return address
506
- RuntimeError(self.program, f'There is no label "{label + ":"}"')
507
- return None
501
+ try:
502
+ address = self.symbols[label]
503
+ if address != None:
504
+ self.stack.append(self.nextPC())
505
+ return address
506
+ except:
507
+ pass
508
+ RuntimeError(self.program, f'There is no label "{label}"')
508
509
 
509
510
  # if <condition> <action> [else <action>]
510
511
  def k_if(self, command):
@@ -1002,9 +1003,9 @@ class Core(Handler):
1002
1003
  program = command['program']
1003
1004
  code = program.code[program.pc]
1004
1005
  lino = str(code['lino'] + 1)
1005
- while len(lino) < 4: lino = f' {lino}'
1006
+ while len(lino) < 5: lino = f' {lino}'
1006
1007
  if value == None: value = '<empty>'
1007
- if 'log' in command: print(f'{datetime.now().time()}: {lino}-> {value}')
1008
+ if 'log' in command: print(f'{datetime.now().time()}:{lino}-> {value}')
1008
1009
  else: print(value)
1009
1010
  return self.nextPC()
1010
1011
 
@@ -1988,6 +1989,10 @@ class Core(Handler):
1988
1989
  value['type'] = 'text'
1989
1990
  if self.encoding == 'utf-8':
1990
1991
  value['content'] = content.decode('utf-8')
1992
+ elif self.encoding == 'hex':
1993
+ b = content.encode('utf-8')
1994
+ mb = binascii.unhexlify(b)
1995
+ value['content'] = mb.decode('utf-8')
1991
1996
  elif self.encoding == 'base64':
1992
1997
  base64_bytes = content.encode('ascii')
1993
1998
  message_bytes = base64.b64decode(base64_bytes)
@@ -2031,6 +2036,10 @@ class Core(Handler):
2031
2036
  value['type'] = 'text'
2032
2037
  if self.encoding == 'utf-8':
2033
2038
  value['content'] = content.encode('utf-8')
2039
+ elif self.encoding == 'hex':
2040
+ b = content.encode('utf-8')
2041
+ mb = binascii.hexlify(b)
2042
+ value['content'] = mb.decode('utf-8')
2034
2043
  elif self.encoding == 'base64':
2035
2044
  data_bytes = content.encode('ascii')
2036
2045
  base64_bytes = base64.b64encode(data_bytes)
@@ -1,8 +1,8 @@
1
- from .ec_classes import FatalError, RuntimeError, Object
2
- from .ec_handler import Handler
1
+ from .ec_classes import FatalError, RuntimeError, Handler
3
2
  from .ec_gutils import GUtils
4
3
  import PySimpleGUI as psg
5
4
  import json
5
+ from copy import deepcopy
6
6
 
7
7
  class Graphics(Handler):
8
8
 
@@ -61,28 +61,13 @@ class Graphics(Handler):
61
61
  args = self.utils.decode(self, default, layout[n])
62
62
  except Exception as e:
63
63
  RuntimeError(self.program, e)
64
- item = self.utils.createElement(type, param, args)
64
+ item = self.utils.createWidget(type, param, args)
65
65
  target['layout'].append(item)
66
66
  else:
67
67
  v = self.getVariable(args)
68
68
  target['layout'].append(v['layout'])
69
69
  return self.nextPC()
70
70
 
71
- def k_capture(self, command):
72
- if self.nextIs('event'):
73
- if self.nextIs('as'):
74
- if self.nextIsSymbol():
75
- record = self.getSymbolRecord()
76
- command['target'] = record['name']
77
- self.addCommand(command)
78
- return True
79
- return False
80
-
81
- def r_capture(self, command):
82
- target = self.getVariable(command['target'])
83
- self.putSymbolValue(target, self.getConstant(self.eventValues))
84
- return self.nextPC()
85
-
86
71
  def k_close(self, command):
87
72
  if self.nextIsSymbol():
88
73
  symbolRecord = self.getSymbolRecord()
@@ -126,15 +111,14 @@ class Graphics(Handler):
126
111
  type = command['type']
127
112
  record = self.getVariable(command['name'])
128
113
  if type == 'window':
129
- layout = self.getVariable(command['layout'])
130
114
  title = self.getRuntimeValue(command['title'])
131
- window = psg.Window(title, layout['layout'], finalize=True)
115
+ layout = self.getVariable(command['layout'])['layout']
116
+ window = psg.Window(title, layout, finalize=True)
132
117
  record['window'] = window
133
118
  record['eventHandlers'] = {}
134
119
  self.program.windowRecord = record
135
120
  self.program.run(self.nextPC())
136
121
  self.mainLoop()
137
- # self.program.kill()
138
122
  return 0
139
123
  else:
140
124
  RuntimeError(self.program, 'Variable is not a window or an element')
@@ -206,176 +190,7 @@ class Graphics(Handler):
206
190
  psg.popup(self.getRuntimeValue(command['message']))
207
191
  return self.nextPC()
208
192
 
209
- # set property {property} of {key} in {window} to {value}
210
- def k_set(self, command):
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']
332
- if keyword == 'layout':
333
- command['args'] = name
334
- elif keyword in ['column', 'frame', 'tab']:
335
- command['name'] = name
336
- command['type'] = token
337
- if self.peek() == 'to':
338
- command['args'] = []
339
- else:
340
- command['args'] = self.utils.getArgs(self)
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
352
-
353
- def r_add(self, command):
354
- target = self.getVariable(command['target'])
355
- type = command['type']
356
- args = command['args']
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):
193
+ def k_refresh(self, command):
379
194
  if self.nextIsSymbol():
380
195
  symbolRecord = self.getSymbolRecord()
381
196
  if symbolRecord['keyword'] == 'window':
@@ -384,121 +199,9 @@ class Graphics(Handler):
384
199
  return True
385
200
  return False
386
201
 
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):
202
+ def r_refresh(self, command):
447
203
  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']))
204
+ target['window'].refresh()
502
205
  return self.nextPC()
503
206
 
504
207
  # set property {property} of {key} in {window} to {value}
@@ -560,21 +263,24 @@ class Graphics(Handler):
560
263
  return value
561
264
 
562
265
  if token == 'property':
563
- value['key'] = self.nextValue()
266
+ value['property'] = self.nextValue()
564
267
  if self.nextIs('of'):
565
268
  if self.nextToken() == 'the':
566
269
  if self.nextIs('event'):
567
- value['source'] = '_event_'
568
270
  return value
569
- else:
570
- value['key'] = self.getValue()
271
+ return None
272
+
273
+ if token == 'value':
274
+ if self.nextIs('of'):
275
+ if self.nextIs('key'):
276
+ value['key'] = self.nextValue()
571
277
  if self.nextIs('in'):
572
278
  if self.nextIsSymbol():
573
279
  record = self.getSymbolRecord()
574
280
  if record['keyword'] == 'window':
575
- value['source'] = record['name']
281
+ value['window'] = record['name']
576
282
  return value
577
- return None
283
+ return None
578
284
 
579
285
  #############################################################################
580
286
  # Modify a value or leave it unchanged.
@@ -600,21 +306,23 @@ class Graphics(Handler):
600
306
  return v
601
307
 
602
308
  def v_property(self, v):
309
+ property = self.getRuntimeValue(v['property'])
310
+ window = self.eventValues['window']
311
+ values = self.eventValues['values']
312
+ self.utils.getEventProperties(window, values)
313
+ v['type'] = 'text'
314
+ v['content'] = values[property]
315
+ return v
316
+
317
+ def v_value(self, v):
603
318
  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
319
+ window = self.getVariable(v['window'])
320
+ value = self.utils.getWidgetValue(window, key)
321
+ if value == None: RuntimeError(self.program, 'getWidgetValue: unimplemented widget type')
322
+ v = deepcopy(v)
323
+ v['type'] = 'text'
324
+ v['content'] = value
325
+ return v
618
326
 
619
327
  #############################################################################
620
328
  # Compile a condition
@@ -643,3 +351,4 @@ class Graphics(Handler):
643
351
  self.eventValues['values'] = values
644
352
  self.eventValues['window'] = window
645
353
  eventHandlers[event]()
354
+ pass
@@ -52,14 +52,14 @@ class GUtils:
52
52
  keys = values.keys()
53
53
  for key in keys:
54
54
  v = values[key]
55
- element = window.key_dict[key]
56
- if type(element) is psg.Listbox:
55
+ widget = window.key_dict[key]
56
+ if type(widget) is psg.Listbox:
57
57
  # Only pick one from those selected
58
58
  v = v[0]
59
59
  values[key] = v
60
60
 
61
- # Create an element
62
- def createElement(self, type, param, args):
61
+ # Create a widget
62
+ def createWidget(self, type, param, args):
63
63
  if type == 'Button': return self.createButton(param, args)
64
64
  elif type == 'Checkbox': return self.createCheckbox(param, args)
65
65
  elif type == 'Column': return self.createColumn(param, args)
@@ -69,10 +69,29 @@ class GUtils:
69
69
  elif type == 'Text': return self.createText(param, args)
70
70
  else: return None
71
71
 
72
+ # Get the current value of a widget
73
+ def getWidgetValue(self, window, key):
74
+ key_dict = window['window'].key_dict
75
+ widget = key_dict[key]
76
+ if type(widget) is psg.Button: return widget.get()
77
+ elif type(widget) is psg.Checkbox: return widget.get()
78
+ elif type(widget) is psg.Column: return widget.get()
79
+ elif type(widget) is psg.Input: return widget.get()
80
+ elif type(widget) is psg.Listbox:
81
+ items = widget.get()
82
+ if len(items) > 0:
83
+ return items[0]
84
+ return ''
85
+ elif type(widget) is psg.Multiline: return widget.get()
86
+ elif type(widget) is psg.Text: return widget.get()
87
+ return None
88
+
72
89
  # Update a property
73
90
  def updateProperty(self, element, property, value):
74
91
  if property == 'disabled':
75
92
  element.update(disabled=value)
93
+ elif property == 'text':
94
+ element.update(text=value)
76
95
  elif property == 'value':
77
96
  element.update(value=value)
78
97
  elif property == 'values':
@@ -136,9 +155,10 @@ class GUtils:
136
155
 
137
156
  def getDefaultText(self, args):
138
157
  args['text'] = '(empty)'
158
+ args['key'] = None
139
159
  args['size'] = (None, None)
140
160
  args['expand_x'] = False
141
161
 
142
162
  def createText(self, param, args):
143
- return psg.Text(text=args['text'], expand_x=args['expand_x'], size=self.getSize(args))
163
+ return psg.Text(text=args['text'], expand_x=args['expand_x'], key=args['key'], size=self.getSize(args))
144
164
 
File without changes
File without changes
File without changes