py10x-universe 0.1.3__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.
Files changed (214) hide show
  1. core_10x/__init__.py +42 -0
  2. core_10x/backbone/__init__.py +0 -0
  3. core_10x/backbone/backbone_store.py +59 -0
  4. core_10x/backbone/backbone_traitable.py +30 -0
  5. core_10x/backbone/backbone_user.py +66 -0
  6. core_10x/backbone/bound_data_domain.py +49 -0
  7. core_10x/backbone/namespace.py +101 -0
  8. core_10x/backbone/vault.py +38 -0
  9. core_10x/code_samples/__init__.py +0 -0
  10. core_10x/code_samples/_package_manifest.py +3 -0
  11. core_10x/code_samples/directories.py +181 -0
  12. core_10x/code_samples/person.py +76 -0
  13. core_10x/concrete_traits.py +356 -0
  14. core_10x/conftest.py +12 -0
  15. core_10x/curve.py +321 -0
  16. core_10x/data_domain.py +48 -0
  17. core_10x/data_domain_binder.py +45 -0
  18. core_10x/directory.py +250 -0
  19. core_10x/entity.py +8 -0
  20. core_10x/entity_filter.py +5 -0
  21. core_10x/environment_variables.py +147 -0
  22. core_10x/exec_control.py +84 -0
  23. core_10x/experimental/__init__.py +0 -0
  24. core_10x/experimental/data_protocol_ex.py +34 -0
  25. core_10x/global_cache.py +121 -0
  26. core_10x/manual_tests/__init__.py +0 -0
  27. core_10x/manual_tests/calendar_test.py +35 -0
  28. core_10x/manual_tests/ctor_update_bug.py +58 -0
  29. core_10x/manual_tests/debug_graph_on.py +17 -0
  30. core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
  31. core_10x/manual_tests/enum_bits_test.py +17 -0
  32. core_10x/manual_tests/env_vars_trivial_test.py +12 -0
  33. core_10x/manual_tests/existing_traitable.py +33 -0
  34. core_10x/manual_tests/k10x_test1.py +13 -0
  35. core_10x/manual_tests/named_constant_test.py +121 -0
  36. core_10x/manual_tests/nucleus_trivial_test.py +42 -0
  37. core_10x/manual_tests/polars_test.py +14 -0
  38. core_10x/manual_tests/py_class_test.py +4 -0
  39. core_10x/manual_tests/rc_test.py +42 -0
  40. core_10x/manual_tests/rdate_test.py +12 -0
  41. core_10x/manual_tests/reference_serialization_bug.py +19 -0
  42. core_10x/manual_tests/resource_trivial_test.py +10 -0
  43. core_10x/manual_tests/store_uri_test.py +6 -0
  44. core_10x/manual_tests/trait_definition_test.py +19 -0
  45. core_10x/manual_tests/trait_filter_test.py +15 -0
  46. core_10x/manual_tests/trait_flag_modification_test.py +42 -0
  47. core_10x/manual_tests/trait_modification_bug.py +26 -0
  48. core_10x/manual_tests/traitable_as_of_test.py +82 -0
  49. core_10x/manual_tests/traitable_heir_test.py +39 -0
  50. core_10x/manual_tests/traitable_history_test.py +41 -0
  51. core_10x/manual_tests/traitable_serialization_test.py +54 -0
  52. core_10x/manual_tests/traitable_trivial_test.py +71 -0
  53. core_10x/manual_tests/trivial_graph_test.py +16 -0
  54. core_10x/manual_tests/ts_class_association_test.py +64 -0
  55. core_10x/manual_tests/ts_trivial_test.py +35 -0
  56. core_10x/named_constant.py +425 -0
  57. core_10x/nucleus.py +81 -0
  58. core_10x/package_manifest.py +85 -0
  59. core_10x/package_refactoring.py +153 -0
  60. core_10x/py_class.py +431 -0
  61. core_10x/rc.py +155 -0
  62. core_10x/rdate.py +339 -0
  63. core_10x/resource.py +189 -0
  64. core_10x/roman_number.py +67 -0
  65. core_10x/testlib/__init__.py +0 -0
  66. core_10x/testlib/test_store.py +240 -0
  67. core_10x/testlib/traitable_history_tests.py +787 -0
  68. core_10x/testlib/ts_tests.py +280 -0
  69. core_10x/trait.py +377 -0
  70. core_10x/trait_definition.py +176 -0
  71. core_10x/trait_filter.py +205 -0
  72. core_10x/trait_method_error.py +36 -0
  73. core_10x/traitable.py +1082 -0
  74. core_10x/traitable_cli.py +153 -0
  75. core_10x/traitable_heir.py +33 -0
  76. core_10x/traitable_id.py +31 -0
  77. core_10x/ts_store.py +172 -0
  78. core_10x/ts_store_type.py +26 -0
  79. core_10x/ts_union.py +147 -0
  80. core_10x/ui_hint.py +153 -0
  81. core_10x/unit_tests/test_concrete_traits.py +156 -0
  82. core_10x/unit_tests/test_converters.py +51 -0
  83. core_10x/unit_tests/test_curve.py +157 -0
  84. core_10x/unit_tests/test_directory.py +54 -0
  85. core_10x/unit_tests/test_documentation.py +172 -0
  86. core_10x/unit_tests/test_environment_variables.py +15 -0
  87. core_10x/unit_tests/test_filters.py +239 -0
  88. core_10x/unit_tests/test_graph.py +348 -0
  89. core_10x/unit_tests/test_named_constant.py +98 -0
  90. core_10x/unit_tests/test_rc.py +11 -0
  91. core_10x/unit_tests/test_rdate.py +484 -0
  92. core_10x/unit_tests/test_trait_method_error.py +80 -0
  93. core_10x/unit_tests/test_trait_modification.py +19 -0
  94. core_10x/unit_tests/test_traitable.py +959 -0
  95. core_10x/unit_tests/test_traitable_history.py +1 -0
  96. core_10x/unit_tests/test_ts_store.py +1 -0
  97. core_10x/unit_tests/test_ts_union.py +369 -0
  98. core_10x/unit_tests/test_ui_nodes.py +81 -0
  99. core_10x/unit_tests/test_xxcalendar.py +471 -0
  100. core_10x/vault/__init__.py +0 -0
  101. core_10x/vault/sec_keys.py +133 -0
  102. core_10x/vault/security_keys_old.py +168 -0
  103. core_10x/vault/vault.py +56 -0
  104. core_10x/vault/vault_traitable.py +56 -0
  105. core_10x/vault/vault_user.py +70 -0
  106. core_10x/xdate_time.py +136 -0
  107. core_10x/xnone.py +71 -0
  108. core_10x/xxcalendar.py +228 -0
  109. infra_10x/__init__.py +0 -0
  110. infra_10x/manual_tests/__init__.py +0 -0
  111. infra_10x/manual_tests/test_misc.py +16 -0
  112. infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
  113. infra_10x/mongodb_admin.py +111 -0
  114. infra_10x/mongodb_store.py +346 -0
  115. infra_10x/mongodb_utils.py +129 -0
  116. infra_10x/unit_tests/conftest.py +13 -0
  117. infra_10x/unit_tests/test_mongo_db.py +36 -0
  118. infra_10x/unit_tests/test_mongo_history.py +1 -0
  119. py10x_universe-0.1.3.dist-info/METADATA +406 -0
  120. py10x_universe-0.1.3.dist-info/RECORD +214 -0
  121. py10x_universe-0.1.3.dist-info/WHEEL +4 -0
  122. py10x_universe-0.1.3.dist-info/licenses/LICENSE +21 -0
  123. ui_10x/__init__.py +0 -0
  124. ui_10x/apps/__init__.py +0 -0
  125. ui_10x/apps/collection_editor_app.py +100 -0
  126. ui_10x/choice.py +212 -0
  127. ui_10x/collection_editor.py +135 -0
  128. ui_10x/concrete_trait_widgets.py +220 -0
  129. ui_10x/conftest.py +8 -0
  130. ui_10x/entity_stocker.py +173 -0
  131. ui_10x/examples/__init__.py +0 -0
  132. ui_10x/examples/_guess_word_data.py +14076 -0
  133. ui_10x/examples/collection_editor.py +17 -0
  134. ui_10x/examples/date_selector.py +14 -0
  135. ui_10x/examples/entity_stocker.py +18 -0
  136. ui_10x/examples/guess_word.py +392 -0
  137. ui_10x/examples/message_box.py +20 -0
  138. ui_10x/examples/multi_choice.py +17 -0
  139. ui_10x/examples/py_data_browser.py +66 -0
  140. ui_10x/examples/radiobox.py +29 -0
  141. ui_10x/examples/single_choice.py +31 -0
  142. ui_10x/examples/style_sheet.py +47 -0
  143. ui_10x/examples/trivial_entity_editor.py +18 -0
  144. ui_10x/platform.py +20 -0
  145. ui_10x/platform_interface.py +517 -0
  146. ui_10x/py_data_browser.py +249 -0
  147. ui_10x/qt6/__init__.py +0 -0
  148. ui_10x/qt6/conftest.py +8 -0
  149. ui_10x/qt6/manual_tests/__init__.py +0 -0
  150. ui_10x/qt6/manual_tests/basic_test.py +35 -0
  151. ui_10x/qt6/platform_implementation.py +275 -0
  152. ui_10x/qt6/utils.py +665 -0
  153. ui_10x/rio/__init__.py +0 -0
  154. ui_10x/rio/apps/examples/examples/__init__.py +22 -0
  155. ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
  156. ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
  157. ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
  158. ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
  159. ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
  160. ui_10x/rio/apps/examples/rio.toml +14 -0
  161. ui_10x/rio/component_builder.py +497 -0
  162. ui_10x/rio/components/__init__.py +9 -0
  163. ui_10x/rio/components/group_box.py +31 -0
  164. ui_10x/rio/components/labeled_checkbox.py +18 -0
  165. ui_10x/rio/components/line_edit.py +37 -0
  166. ui_10x/rio/components/radio_button.py +32 -0
  167. ui_10x/rio/components/separator.py +24 -0
  168. ui_10x/rio/components/splitter.py +121 -0
  169. ui_10x/rio/components/tree_view.py +75 -0
  170. ui_10x/rio/conftest.py +35 -0
  171. ui_10x/rio/internals/__init__.py +0 -0
  172. ui_10x/rio/internals/app.py +192 -0
  173. ui_10x/rio/manual_tests/__init__.py +0 -0
  174. ui_10x/rio/manual_tests/basic_test.py +24 -0
  175. ui_10x/rio/manual_tests/splitter.py +27 -0
  176. ui_10x/rio/platform_implementation.py +91 -0
  177. ui_10x/rio/style_sheet.py +53 -0
  178. ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
  179. ui_10x/rio/unit_tests/test_internals.py +630 -0
  180. ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
  181. ui_10x/rio/widgets/__init__.py +46 -0
  182. ui_10x/rio/widgets/application.py +109 -0
  183. ui_10x/rio/widgets/button.py +48 -0
  184. ui_10x/rio/widgets/button_group.py +60 -0
  185. ui_10x/rio/widgets/calendar.py +23 -0
  186. ui_10x/rio/widgets/checkbox.py +24 -0
  187. ui_10x/rio/widgets/dialog.py +137 -0
  188. ui_10x/rio/widgets/group_box.py +27 -0
  189. ui_10x/rio/widgets/layout.py +34 -0
  190. ui_10x/rio/widgets/line_edit.py +37 -0
  191. ui_10x/rio/widgets/list.py +105 -0
  192. ui_10x/rio/widgets/message_box.py +70 -0
  193. ui_10x/rio/widgets/scroll_area.py +31 -0
  194. ui_10x/rio/widgets/spacer.py +6 -0
  195. ui_10x/rio/widgets/splitter.py +45 -0
  196. ui_10x/rio/widgets/text_edit.py +28 -0
  197. ui_10x/rio/widgets/tree.py +89 -0
  198. ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
  199. ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
  200. ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
  201. ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
  202. ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
  203. ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
  204. ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
  205. ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
  206. ui_10x/table_header_view.py +305 -0
  207. ui_10x/table_view.py +174 -0
  208. ui_10x/trait_editor.py +189 -0
  209. ui_10x/trait_widget.py +131 -0
  210. ui_10x/traitable_editor.py +200 -0
  211. ui_10x/traitable_view.py +131 -0
  212. ui_10x/unit_tests/conftest.py +8 -0
  213. ui_10x/unit_tests/test_platform.py +9 -0
  214. ui_10x/utils.py +661 -0
@@ -0,0 +1,17 @@
1
+ if __name__ == '__main__':
2
+ from core_10x.code_samples.person import Person
3
+ from core_10x.exec_control import INTERACTIVE
4
+ from infra_10x.mongodb_store import MongoStore
5
+
6
+ from ui_10x.collection_editor import Collection, CollectionEditor
7
+ from ui_10x.utils import UxDialog, ux
8
+
9
+ ux.init()
10
+
11
+ with MongoStore.instance(hostname = 'localhost', dbname = 'test', username = '', password = ''):
12
+ with INTERACTIVE():
13
+ coll = Collection(cls = Person)
14
+ ce = CollectionEditor(coll = coll)
15
+ w = ce.main_widget()
16
+ d = UxDialog(w)
17
+ d.exec()
@@ -0,0 +1,14 @@
1
+ from core_10x.rc import RC
2
+
3
+ if __name__ == '__main__':
4
+ #import os;assert os.environ.setdefault('UI_PLATFORM', 'Rio') == os.getenv('UI_PLATFORM')
5
+
6
+ from ui_10x.utils import ux, ux_pick_date
7
+
8
+
9
+ app = ux.init()
10
+
11
+ ux_pick_date(on_accept=lambda value: print(value) or RC(True))
12
+
13
+ print(ux_pick_date())
14
+
@@ -0,0 +1,18 @@
1
+ if __name__ == '__main__':
2
+ from core_10x.code_samples.person import Person
3
+ from core_10x.exec_control import INTERACTIVE
4
+ from infra_10x.mongodb_store import MongoStore
5
+
6
+ from ui_10x.entity_stocker import EntityStocker, StockerPlug
7
+ from ui_10x.utils import UxDialog, ux
8
+
9
+ ux.init()
10
+
11
+ with MongoStore.instance(hostname = 'localhost', dbname = 'test', username = '', password = ''):
12
+ plug = StockerPlug(current_class = Person)
13
+ se = EntityStocker(plug = plug)
14
+
15
+ with INTERACTIVE() as graph:
16
+ w = se.main_widget()
17
+ d = UxDialog(w)
18
+ rc = d.exec()
@@ -0,0 +1,392 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import random
5
+ from typing import TYPE_CHECKING
6
+
7
+ import core_10x.trait_definition as trait_definition
8
+ from core_10x.global_cache import cache
9
+ from core_10x.traitable import RC, RC_TRUE, RT, T, Traitable, Ui
10
+
11
+ from ui_10x.platform_interface import HBoxLayout, PushButton, VBoxLayout, Widget
12
+ from ui_10x.utils import ux
13
+
14
+ # from ui_10x.table_view import TableView
15
+ # from ui_10x.traitable_editor import TraitableEditor
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Generator
19
+
20
+
21
+ class CHAR_STATE:
22
+ # fmt: off
23
+ NONE = ( 'lightgray', 'black' )
24
+ WRONG_POS = ( 'white', 'black' )
25
+ BINGO = ( 'darkgreen', 'white' )
26
+ # fmt: on
27
+
28
+
29
+ class GuessResult(Traitable):
30
+ # fmt: off
31
+ the_word: str = RT()
32
+ guess: str = RT()
33
+ num_chars: int = RT()
34
+
35
+ demo_class: type = RT()
36
+
37
+ char_state: list = RT()
38
+
39
+ guessed_chars: list = RT()
40
+ current_char: int = RT(0)
41
+ # fmt: on
42
+
43
+ def guessed_chars_get(self) -> list:
44
+ return list(self.num_chars * ' ')
45
+
46
+ def set_current_char(self, c: str):
47
+ i = self.current_char
48
+ guessed_chars = self.guessed_chars
49
+ guessed_chars[i] = c
50
+ self.current_char = i + 1
51
+
52
+ def delete_char(self):
53
+ i = self.current_char
54
+ if i:
55
+ i -= 1
56
+ guessed_chars = self.guessed_chars
57
+ guessed_chars[i] = ' '
58
+ self.current_char = i
59
+
60
+ def accept_guess(self):
61
+ self.guess = ''.join(self.guessed_chars)
62
+
63
+ def num_chars_get(self) -> int:
64
+ return len(self.the_word)
65
+
66
+ def char_state_get(self) -> list:
67
+ num_chars = self.num_chars
68
+ res = [CHAR_STATE.NONE] * num_chars
69
+ word = list(self.the_word)
70
+ for i, c in enumerate(self.guess):
71
+ try:
72
+ pos = word.index(c)
73
+ res[i] = CHAR_STATE.BINGO if pos == i else CHAR_STATE.WRONG_POS
74
+ word[pos] = ''
75
+ except ValueError:
76
+ pass
77
+
78
+ return res
79
+
80
+ def guess_get(self) -> str:
81
+ return self.num_chars * ' '
82
+
83
+ @classmethod
84
+ def _create_char_trait(cls, i: int):
85
+ name = f'char_{i}'
86
+ getter_name = f'{name}_get'
87
+ sh_name = f'{name}_style_sheet'
88
+ getter = lambda self: self.guess[i]
89
+ getter.__name__ = getter_name
90
+ sh_getter = lambda self: T.colors(*self.char_state[i])
91
+ sh_getter.__name__ = sh_name
92
+ setattr(cls, getter_name, getter)
93
+ setattr(cls, sh_name, sh_getter)
94
+ # return ( name, T( str, f'{i+1}' ) )
95
+ # fmt: off
96
+ return (
97
+ name,
98
+ trait_definition.TraitDefinition(
99
+ **{
100
+ trait_definition.NAME_TAG: name,
101
+ trait_definition.DATATYPE_TAG: str,
102
+ trait_definition.FLAGS_TAG: T.RUNTIME,
103
+ }
104
+ )
105
+ )
106
+ # fmt: on
107
+
108
+ def keyboard(self):
109
+ w = Widget()
110
+ lay = VBoxLayout()
111
+ w.set_layout(lay)
112
+
113
+ for i, keys in enumerate(self.s_keys):
114
+ hlay = HBoxLayout()
115
+ for j, c in enumerate(keys):
116
+ b = PushButton(c)
117
+ styles = self.s_style.get(i)
118
+ if styles:
119
+ sh = styles.get(j)
120
+ if sh:
121
+ b.set_style_sheet(sh)
122
+
123
+ avg_char_width = w.font_metrics().average_char_width()
124
+ b.setMaximumWidth(3 * avg_char_width)
125
+
126
+ hlay.add_widget(b)
127
+ lay.add_layout(hlay)
128
+
129
+ return w
130
+
131
+
132
+ class Key:
133
+ def __init__(self, guess: GuessResult, c: str, stylesheet: str, callback):
134
+ self.guess = guess
135
+ self.c = c
136
+ self.stylesheet = stylesheet
137
+ self.callback = callback
138
+ self.w: PushButton = None
139
+
140
+ def widget(self, parent_w: Widget) -> PushButton:
141
+ if not self.w:
142
+ self.w = b = PushButton(self.c)
143
+ b.clicked_connect(lambda w: self.callback(w))
144
+ b.set_style_sheet(self.stylesheet)
145
+ avg_char_width = parent_w.font_metrics().average_char_width()
146
+ b.setMaximumWidth(3 * avg_char_width)
147
+
148
+ return self.w
149
+
150
+
151
+ class Keyboard:
152
+ # fmt: off
153
+ s_keys = [
154
+ 'qwertyuiop',
155
+ 'asdfghjkl',
156
+ '*zxcvbnm<',
157
+ ]
158
+ s_special_chars = {
159
+ 2: {
160
+ 0: ( 'background-color: green; color: white', GuessResult.accept_guess ),
161
+ len(s_keys[2]) - 1: ( 'background-color: red; color: white', GuessResult.delete_char ),
162
+ }
163
+ }
164
+ # fmt: on
165
+
166
+ def __init__(self, guess: GuessResult):
167
+ self.guess = guess
168
+ special_chars = self.s_special_chars
169
+ num_rows = len(self.s_keys)
170
+ self.keys = keys = [[]] * num_rows
171
+ for i, symbols in enumerate(self.s_keys):
172
+ for j, c in enumerate(symbols):
173
+ sh = ''
174
+ cb = GuessResult.set_current_char
175
+ exc = special_chars.get(i)
176
+ if exc:
177
+ spec = exc.get(j)
178
+ if spec:
179
+ sh, cb = spec
180
+
181
+ key = Key(guess, c, sh, cb)
182
+ keys[i].append(key)
183
+
184
+ def widget(self) -> Widget: ...
185
+
186
+
187
+ class Game(Traitable):
188
+ # fmt: off
189
+ num_chars: int = RT(5)
190
+
191
+ the_word: str = RT()
192
+ guess: str = RT( ui_hint = Ui('>'))
193
+ push: bool = RT( ui_hint = Ui('*', widget_type = Ui.WIDGET_TYPE.PUSH, right_label = True, max_width = 3))
194
+
195
+ count: int = RT(6)
196
+ current: int = RT(0)
197
+
198
+ guess_res_class: type = RT()
199
+ attempts: list = RT()
200
+ #table: TableView = RT()
201
+ # fmt: on
202
+
203
+ def the_word_get(self) -> str:
204
+ return _GuessWordData.new_word(self.num_chars).upper()
205
+
206
+ def guess_set(self, trait, value: str) -> RC:
207
+ self.raw_set_value(trait, value.upper())
208
+ return RC_TRUE
209
+
210
+ def guess_res_class_get(self):
211
+ num_chars = self.num_chars
212
+
213
+ class Demo(GuessResult):
214
+ @classmethod
215
+ def own_trait_definitions(cls) -> Generator[tuple[str, trait_definition.TraitDefinition]]:
216
+ yield from (tri for i in range(num_chars) if (tri := GuessResult._create_char_trait(i)))
217
+
218
+ Demo.traits()
219
+ return Demo
220
+
221
+ def guess_result(self, guess: str):
222
+ demo_class = self.guess_res_class
223
+ return demo_class(the_word=self.the_word, guess=guess)
224
+
225
+ def push_get(self) -> bool:
226
+ return self.current < self.count
227
+
228
+ def attempts_get(self) -> list:
229
+ num_chars = self.num_chars
230
+ return [self.guess_result(num_chars * ' ') for _ in range(self.count)]
231
+
232
+ def push_action(self, editor):
233
+ current = self.current()
234
+ guess = self.guess()
235
+ if len(guess) != self.num_chars():
236
+ ux.warning(f'The word is {self.num_chars()} characters long.')
237
+ return
238
+
239
+ gr = self.guess_result(self.guess())
240
+ attempts = self.attempts()
241
+ attempts[current] = gr
242
+ self.table().renderEntity(current, None)
243
+
244
+ if all(s == CHAR_STATE.BINGO for s in gr.char_state()):
245
+ ux.success('Great job - you got it!')
246
+
247
+ current += 1
248
+ if current >= self.count():
249
+ ux.warning('Unfortunately you have failed this time')
250
+
251
+ self.current = current
252
+
253
+
254
+ # def table_get( self ) -> TableView:
255
+ # table = TableView( self.attempts() )
256
+ # hv = table.horizontalHeader()
257
+ # hv.setStretchLastSection( False )
258
+ #
259
+ # return table
260
+
261
+ # fmt: off
262
+ s_keys = [
263
+ 'qwertyuiop',
264
+ 'asdfghjkl',
265
+ '*zxcvbnm<'
266
+ ]
267
+ s_style = {
268
+ 2: {
269
+ 0: 'background-color: green; color: white',
270
+ len( s_keys[ 2 ] ) - 1: 'background-color: red; color: white'
271
+ }
272
+ }
273
+ # fmt: on
274
+
275
+ def keyboard(self):
276
+ w = Widget()
277
+ lay = VBoxLayout()
278
+ w.set_layout(lay)
279
+
280
+ for i, keys in enumerate(self.s_keys):
281
+ hlay = HBoxLayout()
282
+ for j, c in enumerate(keys):
283
+ b = PushButton(c)
284
+ styles = self.s_style.get(i)
285
+ if styles:
286
+ sh = styles.get(j)
287
+ if sh:
288
+ b.set_style_sheet(sh)
289
+
290
+ avg_char_width = w.font_metrics().average_char_width()
291
+ b.setMaximumWidth(3 * avg_char_width)
292
+
293
+ hlay.add_widget(b)
294
+ lay.add_layout(hlay)
295
+
296
+ return w
297
+
298
+ def widget(self):
299
+ ux.init()
300
+ w = Widget()
301
+ lay = VBoxLayout()
302
+ w.set_layout(lay)
303
+
304
+ self.m_top_editor = top_editor = self
305
+ top = top_editor.row()
306
+ lay.add_layout(top)
307
+ lay.add_widget(ux.separator())
308
+
309
+ table = self.table()
310
+ lay.add_widget(table)
311
+
312
+ lay.add_widget(ux.separator())
313
+ lay.add_widget(self.keyboard())
314
+
315
+ return w
316
+
317
+
318
+ class _GuessWordData:
319
+ # fmt: off
320
+ MODULE_NAME = '_guess_word_data'
321
+ NUM_CHARS = (5, 6)
322
+ # fmt: on
323
+
324
+ @classmethod
325
+ def download_nouns(cls, filename: str):
326
+ import nltk
327
+ from nltk.corpus import wordnet as wn
328
+
329
+ if os.path.exists(filename):
330
+ return
331
+
332
+ nltk.download('wordnet')
333
+ noun_pool = [
334
+ w.name() for s in wn.all_synsets('n') for w in s.lemmas() if len(w.name()) in cls.NUM_CHARS and w.name().isalpha() and w.name().islower()
335
+ ]
336
+
337
+ with open(filename, 'w') as f:
338
+ print('noun_pool = {', file=f)
339
+ for n in cls.NUM_CHARS:
340
+ print(f'\t{n}: [', file=f)
341
+ pool = [w for w in noun_pool if len(w) == n]
342
+ for w in pool:
343
+ print(f'\t\t{w!r},', file=f)
344
+ print('\t],', file=f)
345
+ print('}', file=f)
346
+
347
+ @classmethod
348
+ @cache
349
+ def noun_pool(cls) -> dict:
350
+ import importlib
351
+ import importlib.util
352
+ from pathlib import Path
353
+
354
+ package_name = cls.__module__.rsplit('.', 1)[0]
355
+ spec = importlib.util.find_spec(package_name)
356
+ assert spec.submodule_search_locations
357
+ package_dir = Path(spec.submodule_search_locations[0])
358
+ file_name = package_dir / f'{cls.MODULE_NAME}.py'
359
+ cls.download_nouns(file_name)
360
+
361
+ module_name = f'{package_name}.{cls.MODULE_NAME}'
362
+ m = importlib.import_module(module_name)
363
+ noun_pool = getattr(m, 'noun_pool', None)
364
+ assert noun_pool and type(noun_pool) is dict, 'noun_pool must be a non-empty dict by num chars'
365
+ return noun_pool
366
+
367
+ @classmethod
368
+ def word_exists(cls, w: str) -> bool:
369
+ noun_pool = cls.noun_pool()
370
+ n = len(w)
371
+ words = noun_pool.get(n)
372
+ return words and w in words
373
+
374
+ @classmethod
375
+ def new_word(cls, n: int) -> str:
376
+ noun_pool = cls.noun_pool()
377
+ words = noun_pool.get(n)
378
+ if words is None:
379
+ raise AssertionError(f'There are no {n}-letter words available')
380
+ return random.choice(words)
381
+
382
+
383
+ if __name__ == '__main__':
384
+ from ui_10x.examples.guess_word import Game, _GuessWordData
385
+
386
+ game = Game()
387
+ # w = game.widget()
388
+
389
+ w = game.the_word
390
+
391
+ # d = UxDialog( w, title = f'You have {game.count()} attempts to guess a word' )
392
+ # d.exec()
@@ -0,0 +1,20 @@
1
+
2
+
3
+ if __name__ == '__main__':
4
+ #import os;assert os.environ.setdefault('UI_PLATFORM', 'Rio') == os.getenv('UI_PLATFORM')
5
+
6
+ from ui_10x.utils import ux, ux_answer, ux_success, ux_warning
7
+
8
+ app = ux.init()
9
+
10
+ ret = ux_answer('This is a message box. '*50+'Ok?', title='Message Box Title')
11
+
12
+ print(ret)
13
+
14
+
15
+ ret = ux_success('This is a success message box. '*50+'Ok?', title='Success Message Box Title')
16
+ print(ret)
17
+
18
+ ret = ux_warning('This is a warning message box. '*50+'Ok?', title='Warning Message Box Title')
19
+ print(ret)
20
+
@@ -0,0 +1,17 @@
1
+ if __name__ == '__main__':
2
+ from core_10x.code_samples.directories import ANIMALS
3
+
4
+ from ui_10x.choice import MultiChoice
5
+ from ui_10x.utils import UxDialog, ux
6
+
7
+ ux.init()
8
+
9
+ choice1 = MultiChoice(choices = ANIMALS)
10
+
11
+ d = UxDialog(choice1.widget())
12
+ d.exec()
13
+
14
+ choice2 = MultiChoice(choices = ANIMALS.choices())
15
+
16
+ d = UxDialog(choice2.widget())
17
+ d.exec()
@@ -0,0 +1,66 @@
1
+ from datetime import date
2
+
3
+ from core_10x.py_class import PyClass
4
+
5
+ from ui_10x.py_data_browser import PyDataBrowser
6
+ from ui_10x.utils import ux
7
+
8
+
9
+ class A:
10
+ pass
11
+
12
+
13
+ class B:
14
+ def __repr__(self):
15
+ return f'class {self.__class__.__name__} stub'
16
+
17
+ data = {
18
+ 'Plain int': 33,
19
+ 'Boolean': True,
20
+ 'All': (False, True),
21
+ 'Just None': None,
22
+ 'Now': date.today(),
23
+ 'A simple list': [ 100, 'abracadabra', 375.89 ],
24
+ 'A simple dict': dict(_a = 10, _b = None, _c = 'Atlantic Ocean'),
25
+ 'Unknown': A(),
26
+ 'Unknown, but': B(),
27
+
28
+ 'Nested Dict': dict(
29
+ person = dict(
30
+ first_name = 'Mike',
31
+ last_name = 'Fellows',
32
+ age = 50,
33
+ countries = ('USA', 'Japan', 'Korea'),
34
+ ),
35
+ regions = [
36
+ 'Europe',
37
+ dict(
38
+ North = [ 'Canada', 'USA', 'Mexico' ],
39
+ Central = [ 'Nicaragua', 'Costa Rica', 'Equador' ],
40
+ South = [ 'Brasil', 'Argentina' ],
41
+ ),
42
+ 'Asia',
43
+ ],
44
+ ),
45
+ # 'People': Person.generateList( _cache_only = True )
46
+ }
47
+
48
+ def on_select(browser: PyDataBrowser, path: list, value, delims = ('/', '/')):
49
+ path_text = PyDataBrowser.path_to_str(path, delims)
50
+ return print(f"'{path_text}' -> {value}")
51
+
52
+
53
+ if __name__ == '__main__':
54
+ ux.init()
55
+
56
+ PyDataBrowser.show([10, 'a'], on_select = on_select)
57
+
58
+ PyDataBrowser.edit(
59
+ data,
60
+ on_select = lambda browser, path, value: on_select(browser, path, value, delims = ('[]', '[]'))
61
+ )
62
+
63
+ PyDataBrowser.show(
64
+ PyClass.class_names_by_module('core_10x'),
65
+ on_select = lambda browser, path, value: on_select(browser, path, value, delims = ('.', ''))
66
+ )
@@ -0,0 +1,29 @@
1
+ from core_10x.rc import RC_TRUE
2
+
3
+ if __name__ == '__main__':
4
+ #import os;assert os.environ.setdefault('UI_PLATFORM', 'Rio') == os.getenv('UI_PLATFORM')
5
+
6
+ from core_10x.named_constant import NamedConstant
7
+
8
+ from ui_10x.utils import UxDialog, UxRadioBox, ux
9
+
10
+ class COLOR(NamedConstant, lowercase_values = True):
11
+ BLACK = ()
12
+ WHITE = ()
13
+ GREEN = ()
14
+ RED = ()
15
+ BROWN = ()
16
+
17
+ app = ux.init()
18
+
19
+ w = UxRadioBox(COLOR, 'Choose a Color', default_value = COLOR.GREEN)
20
+ def cb():
21
+ print('accept:', w.choice() )
22
+ return RC_TRUE
23
+ d = UxDialog(w, accept_callback=cb)
24
+
25
+ rc = d.exec()
26
+
27
+ print(w.choice(),rc)
28
+
29
+
@@ -0,0 +1,31 @@
1
+ if __name__ == '__main__':
2
+ #import os;assert os.environ.setdefault('UI_PLATFORM', 'Rio') == os.getenv('UI_PLATFORM')
3
+
4
+ from core_10x.code_samples.directories import ANIMALS, FISH
5
+
6
+ from ui_10x.choice import Choice
7
+ from ui_10x.utils import UxDialog, ux
8
+
9
+ ux.init()
10
+
11
+ choice1 = Choice(choices = ANIMALS)
12
+ d = UxDialog(choice1.widget())
13
+ d.exec()
14
+
15
+ print(choice1.values_selected)
16
+
17
+ choice2 = Choice(choices = FISH)
18
+ d = UxDialog(choice2.widget())
19
+ d.exec()
20
+
21
+ print(choice2.values_selected)
22
+
23
+ choice3 = Choice(choices = FISH.choices())
24
+
25
+ d = UxDialog(choice3.widget())
26
+ d.exec()
27
+
28
+ print(choice3.values_selected)
29
+
30
+ choice3.popup()
31
+ print(choice3.values_selected)
@@ -0,0 +1,47 @@
1
+ from core_10x.exec_control import CACHE_ONLY
2
+ from core_10x.traitable import T, Traitable, Ui
3
+
4
+ COLORS = ('black', 'white', 'green', 'lightgreen', 'red', 'blue', 'grey')
5
+
6
+ class StyleSheet(Traitable):
7
+ foreground: str = T('black', ui_hint = Ui(widget_type = Ui.WIDGET_TYPE.CHOICE))
8
+ background: str = T('white', ui_hint = Ui(widget_type = Ui.WIDGET_TYPE.CHOICE, flags = Ui.SEPARATOR))
9
+
10
+ font: str = T('Helvetica', ui_hint = Ui(widget_type = Ui.WIDGET_TYPE.CHOICE))
11
+ font_style: bool = T(False, ui_hint = Ui('italic', right_label = True))
12
+ font_weight: bool = T(False, ui_hint = Ui('bold', flags = Ui.SEPARATOR, right_label = True))
13
+
14
+ border_style: bool = T(False)
15
+ border_color: str = T('blue', ui_hint = Ui(widget_type = Ui.WIDGET_TYPE.CHOICE))
16
+ border_width: int = T(2, ui_hint = Ui(flags = Ui.SEPARATOR))
17
+
18
+ show_me: str = T('This is how it will look...', ui_hint = Ui('WYSIWYG', min_width = 50))
19
+
20
+ def foreground_choices(self, t): return COLORS
21
+ def background_choices(self, t): return COLORS
22
+ def border_color_choices(self, t): return COLORS
23
+ def font_choices(self, t): return ('Times New Roman', 'Helvetica', 'Courier New')
24
+
25
+ def show_me_style_sheet(self) -> dict:
26
+ ss = {
27
+ Ui.FG_COLOR: self.foreground,
28
+ Ui.BG_COLOR: self.background,
29
+ Ui.FONT: self.font,
30
+ Ui.FONT_STYLE: 'italic' if self.font_style else 'normal',
31
+ Ui.FONT_WEIGHT: 'bold' if self.font_weight else 'normal',
32
+ Ui.BORDER_WIDTH: f'{self.border_width}px',
33
+ Ui.BORDER_STYLE: 'solid' if self.border_style else '',
34
+ Ui.BORDER_COLOR: self.border_color,
35
+ }
36
+ print(ss)
37
+ return ss
38
+
39
+ if __name__ == '__main__':
40
+ from ui_10x.traitable_editor import TraitableEditor
41
+
42
+ with CACHE_ONLY():
43
+ sheet = StyleSheet()
44
+ e = TraitableEditor(sheet, _confirm = True)
45
+ e.dialog().exec()
46
+
47
+
@@ -0,0 +1,18 @@
1
+ from core_10x.code_samples.person import Person
2
+ from infra_10x.mongodb_store import MongoStore
3
+
4
+ from ui_10x.traitable_editor import TraitableEditor, TraitableView
5
+
6
+ if __name__ == '__main__':
7
+ db = MongoStore.instance(hostname='localhost', dbname='test')
8
+ db.begin_using()
9
+
10
+ p = Person(first_name = 'Sasha', last_name = 'Davidovich')
11
+ view = TraitableView.modify(Person,
12
+ #weight_qu = UiMod(flags = Ui.HIDDEN),
13
+ )
14
+ e = TraitableEditor.editor(p, view = view)
15
+ rc = e.dialog(save=True).exec()
16
+
17
+
18
+
ui_10x/platform.py ADDED
@@ -0,0 +1,20 @@
1
+ import os
2
+ import sys
3
+ import typing
4
+
5
+ if typing.TYPE_CHECKING:
6
+ import platform_interface as ux
7
+ else:
8
+ pname = os.getenv('UI_PLATFORM')
9
+ if pname is None:
10
+ pname = 'Qt6' if 'rio' not in sys.modules else 'Rio'
11
+
12
+ if pname == 'Qt6':
13
+ import ui_10x.qt6.platform_implementation as ux
14
+ elif pname == 'Rio':
15
+ import ui_10x.rio.platform_implementation as ux
16
+ else:
17
+ raise ImportError(f'UI implementation for `{pname}` is not available')
18
+
19
+
20
+ __all__ = ['ux']