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.
- core_10x/__init__.py +42 -0
- core_10x/backbone/__init__.py +0 -0
- core_10x/backbone/backbone_store.py +59 -0
- core_10x/backbone/backbone_traitable.py +30 -0
- core_10x/backbone/backbone_user.py +66 -0
- core_10x/backbone/bound_data_domain.py +49 -0
- core_10x/backbone/namespace.py +101 -0
- core_10x/backbone/vault.py +38 -0
- core_10x/code_samples/__init__.py +0 -0
- core_10x/code_samples/_package_manifest.py +3 -0
- core_10x/code_samples/directories.py +181 -0
- core_10x/code_samples/person.py +76 -0
- core_10x/concrete_traits.py +356 -0
- core_10x/conftest.py +12 -0
- core_10x/curve.py +321 -0
- core_10x/data_domain.py +48 -0
- core_10x/data_domain_binder.py +45 -0
- core_10x/directory.py +250 -0
- core_10x/entity.py +8 -0
- core_10x/entity_filter.py +5 -0
- core_10x/environment_variables.py +147 -0
- core_10x/exec_control.py +84 -0
- core_10x/experimental/__init__.py +0 -0
- core_10x/experimental/data_protocol_ex.py +34 -0
- core_10x/global_cache.py +121 -0
- core_10x/manual_tests/__init__.py +0 -0
- core_10x/manual_tests/calendar_test.py +35 -0
- core_10x/manual_tests/ctor_update_bug.py +58 -0
- core_10x/manual_tests/debug_graph_on.py +17 -0
- core_10x/manual_tests/debug_graphoff_inside_graph_on.py +28 -0
- core_10x/manual_tests/enum_bits_test.py +17 -0
- core_10x/manual_tests/env_vars_trivial_test.py +12 -0
- core_10x/manual_tests/existing_traitable.py +33 -0
- core_10x/manual_tests/k10x_test1.py +13 -0
- core_10x/manual_tests/named_constant_test.py +121 -0
- core_10x/manual_tests/nucleus_trivial_test.py +42 -0
- core_10x/manual_tests/polars_test.py +14 -0
- core_10x/manual_tests/py_class_test.py +4 -0
- core_10x/manual_tests/rc_test.py +42 -0
- core_10x/manual_tests/rdate_test.py +12 -0
- core_10x/manual_tests/reference_serialization_bug.py +19 -0
- core_10x/manual_tests/resource_trivial_test.py +10 -0
- core_10x/manual_tests/store_uri_test.py +6 -0
- core_10x/manual_tests/trait_definition_test.py +19 -0
- core_10x/manual_tests/trait_filter_test.py +15 -0
- core_10x/manual_tests/trait_flag_modification_test.py +42 -0
- core_10x/manual_tests/trait_modification_bug.py +26 -0
- core_10x/manual_tests/traitable_as_of_test.py +82 -0
- core_10x/manual_tests/traitable_heir_test.py +39 -0
- core_10x/manual_tests/traitable_history_test.py +41 -0
- core_10x/manual_tests/traitable_serialization_test.py +54 -0
- core_10x/manual_tests/traitable_trivial_test.py +71 -0
- core_10x/manual_tests/trivial_graph_test.py +16 -0
- core_10x/manual_tests/ts_class_association_test.py +64 -0
- core_10x/manual_tests/ts_trivial_test.py +35 -0
- core_10x/named_constant.py +425 -0
- core_10x/nucleus.py +81 -0
- core_10x/package_manifest.py +85 -0
- core_10x/package_refactoring.py +153 -0
- core_10x/py_class.py +431 -0
- core_10x/rc.py +155 -0
- core_10x/rdate.py +339 -0
- core_10x/resource.py +189 -0
- core_10x/roman_number.py +67 -0
- core_10x/testlib/__init__.py +0 -0
- core_10x/testlib/test_store.py +240 -0
- core_10x/testlib/traitable_history_tests.py +787 -0
- core_10x/testlib/ts_tests.py +280 -0
- core_10x/trait.py +377 -0
- core_10x/trait_definition.py +176 -0
- core_10x/trait_filter.py +205 -0
- core_10x/trait_method_error.py +36 -0
- core_10x/traitable.py +1082 -0
- core_10x/traitable_cli.py +153 -0
- core_10x/traitable_heir.py +33 -0
- core_10x/traitable_id.py +31 -0
- core_10x/ts_store.py +172 -0
- core_10x/ts_store_type.py +26 -0
- core_10x/ts_union.py +147 -0
- core_10x/ui_hint.py +153 -0
- core_10x/unit_tests/test_concrete_traits.py +156 -0
- core_10x/unit_tests/test_converters.py +51 -0
- core_10x/unit_tests/test_curve.py +157 -0
- core_10x/unit_tests/test_directory.py +54 -0
- core_10x/unit_tests/test_documentation.py +172 -0
- core_10x/unit_tests/test_environment_variables.py +15 -0
- core_10x/unit_tests/test_filters.py +239 -0
- core_10x/unit_tests/test_graph.py +348 -0
- core_10x/unit_tests/test_named_constant.py +98 -0
- core_10x/unit_tests/test_rc.py +11 -0
- core_10x/unit_tests/test_rdate.py +484 -0
- core_10x/unit_tests/test_trait_method_error.py +80 -0
- core_10x/unit_tests/test_trait_modification.py +19 -0
- core_10x/unit_tests/test_traitable.py +959 -0
- core_10x/unit_tests/test_traitable_history.py +1 -0
- core_10x/unit_tests/test_ts_store.py +1 -0
- core_10x/unit_tests/test_ts_union.py +369 -0
- core_10x/unit_tests/test_ui_nodes.py +81 -0
- core_10x/unit_tests/test_xxcalendar.py +471 -0
- core_10x/vault/__init__.py +0 -0
- core_10x/vault/sec_keys.py +133 -0
- core_10x/vault/security_keys_old.py +168 -0
- core_10x/vault/vault.py +56 -0
- core_10x/vault/vault_traitable.py +56 -0
- core_10x/vault/vault_user.py +70 -0
- core_10x/xdate_time.py +136 -0
- core_10x/xnone.py +71 -0
- core_10x/xxcalendar.py +228 -0
- infra_10x/__init__.py +0 -0
- infra_10x/manual_tests/__init__.py +0 -0
- infra_10x/manual_tests/test_misc.py +16 -0
- infra_10x/manual_tests/test_prepare_filter_and_pipeline.py +25 -0
- infra_10x/mongodb_admin.py +111 -0
- infra_10x/mongodb_store.py +346 -0
- infra_10x/mongodb_utils.py +129 -0
- infra_10x/unit_tests/conftest.py +13 -0
- infra_10x/unit_tests/test_mongo_db.py +36 -0
- infra_10x/unit_tests/test_mongo_history.py +1 -0
- py10x_universe-0.1.3.dist-info/METADATA +406 -0
- py10x_universe-0.1.3.dist-info/RECORD +214 -0
- py10x_universe-0.1.3.dist-info/WHEEL +4 -0
- py10x_universe-0.1.3.dist-info/licenses/LICENSE +21 -0
- ui_10x/__init__.py +0 -0
- ui_10x/apps/__init__.py +0 -0
- ui_10x/apps/collection_editor_app.py +100 -0
- ui_10x/choice.py +212 -0
- ui_10x/collection_editor.py +135 -0
- ui_10x/concrete_trait_widgets.py +220 -0
- ui_10x/conftest.py +8 -0
- ui_10x/entity_stocker.py +173 -0
- ui_10x/examples/__init__.py +0 -0
- ui_10x/examples/_guess_word_data.py +14076 -0
- ui_10x/examples/collection_editor.py +17 -0
- ui_10x/examples/date_selector.py +14 -0
- ui_10x/examples/entity_stocker.py +18 -0
- ui_10x/examples/guess_word.py +392 -0
- ui_10x/examples/message_box.py +20 -0
- ui_10x/examples/multi_choice.py +17 -0
- ui_10x/examples/py_data_browser.py +66 -0
- ui_10x/examples/radiobox.py +29 -0
- ui_10x/examples/single_choice.py +31 -0
- ui_10x/examples/style_sheet.py +47 -0
- ui_10x/examples/trivial_entity_editor.py +18 -0
- ui_10x/platform.py +20 -0
- ui_10x/platform_interface.py +517 -0
- ui_10x/py_data_browser.py +249 -0
- ui_10x/qt6/__init__.py +0 -0
- ui_10x/qt6/conftest.py +8 -0
- ui_10x/qt6/manual_tests/__init__.py +0 -0
- ui_10x/qt6/manual_tests/basic_test.py +35 -0
- ui_10x/qt6/platform_implementation.py +275 -0
- ui_10x/qt6/utils.py +665 -0
- ui_10x/rio/__init__.py +0 -0
- ui_10x/rio/apps/examples/examples/__init__.py +22 -0
- ui_10x/rio/apps/examples/examples/components/__init__.py +3 -0
- ui_10x/rio/apps/examples/examples/components/collection_editor.py +15 -0
- ui_10x/rio/apps/examples/examples/pages/collection_editor.py +21 -0
- ui_10x/rio/apps/examples/examples/pages/login_page.py +88 -0
- ui_10x/rio/apps/examples/examples/pages/style_sheet.py +21 -0
- ui_10x/rio/apps/examples/rio.toml +14 -0
- ui_10x/rio/component_builder.py +497 -0
- ui_10x/rio/components/__init__.py +9 -0
- ui_10x/rio/components/group_box.py +31 -0
- ui_10x/rio/components/labeled_checkbox.py +18 -0
- ui_10x/rio/components/line_edit.py +37 -0
- ui_10x/rio/components/radio_button.py +32 -0
- ui_10x/rio/components/separator.py +24 -0
- ui_10x/rio/components/splitter.py +121 -0
- ui_10x/rio/components/tree_view.py +75 -0
- ui_10x/rio/conftest.py +35 -0
- ui_10x/rio/internals/__init__.py +0 -0
- ui_10x/rio/internals/app.py +192 -0
- ui_10x/rio/manual_tests/__init__.py +0 -0
- ui_10x/rio/manual_tests/basic_test.py +24 -0
- ui_10x/rio/manual_tests/splitter.py +27 -0
- ui_10x/rio/platform_implementation.py +91 -0
- ui_10x/rio/style_sheet.py +53 -0
- ui_10x/rio/unit_tests/test_collection_editor.py +68 -0
- ui_10x/rio/unit_tests/test_internals.py +630 -0
- ui_10x/rio/unit_tests/test_style_sheet.py +37 -0
- ui_10x/rio/widgets/__init__.py +46 -0
- ui_10x/rio/widgets/application.py +109 -0
- ui_10x/rio/widgets/button.py +48 -0
- ui_10x/rio/widgets/button_group.py +60 -0
- ui_10x/rio/widgets/calendar.py +23 -0
- ui_10x/rio/widgets/checkbox.py +24 -0
- ui_10x/rio/widgets/dialog.py +137 -0
- ui_10x/rio/widgets/group_box.py +27 -0
- ui_10x/rio/widgets/layout.py +34 -0
- ui_10x/rio/widgets/line_edit.py +37 -0
- ui_10x/rio/widgets/list.py +105 -0
- ui_10x/rio/widgets/message_box.py +70 -0
- ui_10x/rio/widgets/scroll_area.py +31 -0
- ui_10x/rio/widgets/spacer.py +6 -0
- ui_10x/rio/widgets/splitter.py +45 -0
- ui_10x/rio/widgets/text_edit.py +28 -0
- ui_10x/rio/widgets/tree.py +89 -0
- ui_10x/rio/widgets/unit_tests/test_button.py +101 -0
- ui_10x/rio/widgets/unit_tests/test_button_group.py +33 -0
- ui_10x/rio/widgets/unit_tests/test_calendar.py +114 -0
- ui_10x/rio/widgets/unit_tests/test_checkbox.py +109 -0
- ui_10x/rio/widgets/unit_tests/test_group_box.py +158 -0
- ui_10x/rio/widgets/unit_tests/test_label.py +43 -0
- ui_10x/rio/widgets/unit_tests/test_line_edit.py +140 -0
- ui_10x/rio/widgets/unit_tests/test_list.py +146 -0
- ui_10x/table_header_view.py +305 -0
- ui_10x/table_view.py +174 -0
- ui_10x/trait_editor.py +189 -0
- ui_10x/trait_widget.py +131 -0
- ui_10x/traitable_editor.py +200 -0
- ui_10x/traitable_view.py +131 -0
- ui_10x/unit_tests/conftest.py +8 -0
- ui_10x/unit_tests/test_platform.py +9 -0
- 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']
|