composeui 0.1.0__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.
- composeui/__init__.py +11 -0
- composeui/core/__init__.py +0 -0
- composeui/core/application.py +368 -0
- composeui/core/chartcolors.py +23 -0
- composeui/core/chartimage.py +336 -0
- composeui/core/dataframesource.py +307 -0
- composeui/core/jobs.py +426 -0
- composeui/core/model.py +66 -0
- composeui/core/registry.py +66 -0
- composeui/core/reload.py +476 -0
- composeui/core/renderer.py +193 -0
- composeui/core/signal.py +358 -0
- composeui/core/sqlitemodel.py +1183 -0
- composeui/core/study.py +121 -0
- composeui/core/translation.py +221 -0
- composeui/core/translationcheck.py +254 -0
- composeui/core/view.py +5508 -0
- composeui/images/composeui.svg +15 -0
- composeui/locales/fr.json +73 -0
- composeui/mypy.py +46 -0
- composeui/py.typed +0 -0
- composeui/qtcore/__init__.py +0 -0
- composeui/qtcore/maprenderer.py +115 -0
- composeui/qtcore/qtapplication.py +222 -0
- composeui/qtcore/qtrenderer.py +2862 -0
- composeui/qtcore/widgets/__init__.py +0 -0
- composeui/qtcore/widgets/map.qml +123 -0
- composeui/qtcore/widgets/qchart.py +393 -0
- composeui/qtcore/widgets/qdatefield.py +101 -0
- composeui/qtcore/widgets/qexpander.py +60 -0
- composeui/qtcore/widgets/qfilepathfield.py +34 -0
- composeui/qtcore/widgets/qfiltertable.py +394 -0
- composeui/qtcore/widgets/qformdialog.py +64 -0
- composeui/qtcore/widgets/qformlabel.py +53 -0
- composeui/qtcore/widgets/qmap.py +68 -0
- composeui/qtcore/widgets/qmarkicon.py +37 -0
- composeui/qtcore/widgets/qmetric.py +44 -0
- composeui/qtcore/widgets/qplaintext.py +29 -0
- composeui/qtcore/widgets/qradiogroup.py +57 -0
- composeui/qtcore/widgets/qsidebar.py +116 -0
- composeui/qtcore/widgets/qsourcetable.py +216 -0
- composeui/qtcore/widgets/qsplitter.py +69 -0
- composeui/qtcore/widgets/qtexttable.py +703 -0
- composeui/qtcore/widgets/qvaluecombobox.py +41 -0
- composeui/qtcore/widgets/qvalueslider.py +64 -0
- composeui/qtcore/widgets/qwindowrelease.py +32 -0
- composeui/textualcore/__init__.py +0 -0
- composeui/textualcore/textualapplication.py +121 -0
- composeui/textualcore/textualrenderer.py +2893 -0
- composeui/textualcore/widgets/__init__.py +0 -0
- composeui/textualcore/widgets/composebutton.py +17 -0
- composeui/textualcore/widgets/composechart.py +212 -0
- composeui/textualcore/widgets/composecheckbox.py +35 -0
- composeui/textualcore/widgets/composecollapsible.py +41 -0
- composeui/textualcore/widgets/composecombobox.py +54 -0
- composeui/textualcore/widgets/composedateinput.py +325 -0
- composeui/textualcore/widgets/composedialog.py +90 -0
- composeui/textualcore/widgets/composefilepathinput.py +85 -0
- composeui/textualcore/widgets/composefiltertable.py +367 -0
- composeui/textualcore/widgets/composeformdialog.py +86 -0
- composeui/textualcore/widgets/composeinput.py +50 -0
- composeui/textualcore/widgets/composelist.py +20 -0
- composeui/textualcore/widgets/composemarkdown.py +17 -0
- composeui/textualcore/widgets/composemetric.py +60 -0
- composeui/textualcore/widgets/composeradioset.py +54 -0
- composeui/textualcore/widgets/composesidebar.py +111 -0
- composeui/textualcore/widgets/composeslider.py +144 -0
- composeui/textualcore/widgets/composesourcetable.py +288 -0
- composeui/textualcore/widgets/composesplitter.py +211 -0
- composeui/textualcore/widgets/composetabbedcontent.py +35 -0
- composeui/textualcore/widgets/composetable.py +476 -0
- composeui/textualcore/widgets/composetoolbar.py +62 -0
- composeui/textualcore/widgets/composetree.py +139 -0
- composeui/webcore/__init__.py +0 -0
- composeui/webcore/headers.py +57 -0
- composeui/webcore/icons.py +58 -0
- composeui/webcore/limits.py +55 -0
- composeui/webcore/origin.py +63 -0
- composeui/webcore/page.py +146 -0
- composeui/webcore/routes.py +303 -0
- composeui/webcore/session.py +436 -0
- composeui/webcore/static/app.css +2 -0
- composeui/webcore/static/cally.js +1312 -0
- composeui/webcore/static/daisyui.LICENSE +21 -0
- composeui/webcore/static/deckgl.LICENSE +19 -0
- composeui/webcore/static/deckgl.min.js +6423 -0
- composeui/webcore/static/htmx.min.js +1 -0
- composeui/webcore/static/page.js +1175 -0
- composeui/webcore/static/uPlot.LICENSE +21 -0
- composeui/webcore/static/uPlot.iife.min.js +2 -0
- composeui/webcore/webapplication.py +495 -0
- composeui/webcore/webrenderer.py +5113 -0
- composeui-0.1.0.dist-info/METADATA +222 -0
- composeui-0.1.0.dist-info/RECORD +97 -0
- composeui-0.1.0.dist-info/WHEEL +5 -0
- composeui-0.1.0.dist-info/licenses/LICENSE +9 -0
- composeui-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: composeui
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A framework-agnostic MVVM layer for Python UIs: one app for Qt, Textual and the web
|
|
5
|
+
Author-email: El Hadi Moussi <50993404+ehmoussi@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ehmoussi/composeui
|
|
8
|
+
Project-URL: Documentation, https://ehmoussi.github.io/composeui/
|
|
9
|
+
Project-URL: Source, https://github.com/ehmoussi/composeui
|
|
10
|
+
Project-URL: Issues, https://github.com/ehmoussi/composeui/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/ehmoussi/composeui/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: mvvm,gui,qt,pyside6,textual,tui,web,htmx,attrs,cattrs,reactive
|
|
13
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Environment :: Console
|
|
24
|
+
Classifier: Environment :: Web Environment
|
|
25
|
+
Classifier: Environment :: X11 Applications :: Qt
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
27
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
28
|
+
Classifier: Typing :: Typed
|
|
29
|
+
Requires-Python: >=3.9
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Requires-Dist: attrs>=26.1.0
|
|
33
|
+
Requires-Dist: cattrs>=25.3.0
|
|
34
|
+
Requires-Dist: typing-extensions>=4.15.0
|
|
35
|
+
Provides-Extra: pyside6
|
|
36
|
+
Requires-Dist: pyqtgraph>=0.13.7; extra == "pyside6"
|
|
37
|
+
Requires-Dist: pyside6>=6.10.3; extra == "pyside6"
|
|
38
|
+
Requires-Dist: qtpy>=2.4.3; extra == "pyside6"
|
|
39
|
+
Provides-Extra: tui
|
|
40
|
+
Requires-Dist: textual>=8.2.8; extra == "tui"
|
|
41
|
+
Requires-Dist: textual-fspicker>=0.6.0; extra == "tui"
|
|
42
|
+
Requires-Dist: textual-plotext>=1.0.1; extra == "tui"
|
|
43
|
+
Provides-Extra: web
|
|
44
|
+
Requires-Dist: itsdangerous>=2.2.0; extra == "web"
|
|
45
|
+
Requires-Dist: markdown-it-py>=3.0.0; extra == "web"
|
|
46
|
+
Requires-Dist: markupsafe>=3.0.2; extra == "web"
|
|
47
|
+
Requires-Dist: python-multipart>=0.0.20; extra == "web"
|
|
48
|
+
Requires-Dist: starlette>=0.49.3; extra == "web"
|
|
49
|
+
Requires-Dist: uvicorn>=0.39.0; extra == "web"
|
|
50
|
+
Provides-Extra: report
|
|
51
|
+
Requires-Dist: matplotlib>=3.9; extra == "report"
|
|
52
|
+
Provides-Extra: reload
|
|
53
|
+
Requires-Dist: watchfiles>=1.1.1; extra == "reload"
|
|
54
|
+
Provides-Extra: dataframe
|
|
55
|
+
Requires-Dist: narwhals>=2.21.0; extra == "dataframe"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
<h1>
|
|
59
|
+
<picture>
|
|
60
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ehmoussi/composeui/main/docs/_static/composeui-logo-dark.svg">
|
|
61
|
+
<img alt="ComposeUI" src="https://raw.githubusercontent.com/ehmoussi/composeui/main/docs/_static/composeui-logo-light.svg" width="268" height="64">
|
|
62
|
+
</picture>
|
|
63
|
+
</h1>
|
|
64
|
+
|
|
65
|
+
A small, framework-agnostic MVVM layer for building UIs in Python. You declare views as typed
|
|
66
|
+
[`attrs`](https://www.attrs.org/) classes. They hold the state of the UI, but no toolkit code: in
|
|
67
|
+
MVVM terms, they are the view-models
|
|
68
|
+
([how ComposeUI maps to MVVM](https://ehmoussi.github.io/composeui/user-guide/core-concepts.html#how-composeui-maps-to-mvvm)).
|
|
69
|
+
A `Renderer` binds each view to a toolkit widget, which plays the View role of MVVM:
|
|
70
|
+
|
|
71
|
+
- a desktop window with [Qt](https://pypi.org/project/QtPy/), through `qtpy`;
|
|
72
|
+
- a terminal with [Textual](https://textual.textualize.io/);
|
|
73
|
+
- a web page served with [Starlette](https://www.starlette.io/) and [htmx](https://htmx.org/).
|
|
74
|
+
|
|
75
|
+
`Signal` objects carry events between view, model, and application code.
|
|
76
|
+
|
|
77
|
+
> **Status:** early-stage / pre-alpha. The API is small and still moving.
|
|
78
|
+
|
|
79
|
+
## Why
|
|
80
|
+
|
|
81
|
+
- **Declarative views.** A view is an `attrs` class with typed fields. You don't build
|
|
82
|
+
widgets or wire their signals by hand.
|
|
83
|
+
- **Reactive by construction.** When you set an attribute of a view (`view.text = "..."`),
|
|
84
|
+
the view pushes the change to its renderer. Normal state changes need no `update()` or
|
|
85
|
+
`refresh()` calls.
|
|
86
|
+
- **Toolkit-agnostic core.** `composeui.core` doesn't import Qt, Textual, or Starlette
|
|
87
|
+
when Python imports it. Each backend is imported only when a view renders with it.
|
|
88
|
+
- **Typed callback injection.** `Signal.connect` and `Application.connect` read the
|
|
89
|
+
parameter names of a callback. They inject `view`, `main_view`, or `model` when the
|
|
90
|
+
callback asks for them. So callbacks stay short, without manual lookups.
|
|
91
|
+
|
|
92
|
+
## When to use it
|
|
93
|
+
|
|
94
|
+
- **Choose ComposeUI** when one app must show as a desktop window, in a terminal, and in a
|
|
95
|
+
browser, or may move from one to another later. It also suits an app whose state must be
|
|
96
|
+
typed, saved as a file, and tested without a UI
|
|
97
|
+
([Testing your app](https://ehmoussi.github.io/composeui/user-guide/testing.html)).
|
|
98
|
+
- **Compared with Streamlit,** the views are explicit classes that keep their state, and
|
|
99
|
+
nothing runs the script again on each change. The same app also runs as a desktop
|
|
100
|
+
window or in a terminal.
|
|
101
|
+
- **Compared with Qt, Textual, or a web framework alone,** the app gives up the widgets
|
|
102
|
+
that only one toolkit has, and keeps one code base for the three.
|
|
103
|
+
- **Not yet** for an app that needs a stable API, or a widget that is still missing, such
|
|
104
|
+
as a context menu or a wizard (see
|
|
105
|
+
[`ROADMAP.md`](https://github.com/ehmoussi/composeui/blob/main/ROADMAP.md)).
|
|
106
|
+
|
|
107
|
+
## Installation
|
|
108
|
+
|
|
109
|
+
Requires Python >= 3.9. Install ComposeUI from PyPI with the extras of the backends that you
|
|
110
|
+
want, for example the web and Qt backends:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
uv add "composeui[web,pyside6]" # or: pip install "composeui[web,pyside6]"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Each extra adds a backend or a feature:
|
|
117
|
+
|
|
118
|
+
| Extra | Installs | For |
|
|
119
|
+
| --- | --- | --- |
|
|
120
|
+
| `web` | Starlette, uvicorn | The web backend, the default |
|
|
121
|
+
| `pyside6` | PySide6 | The Qt backend, a desktop window |
|
|
122
|
+
| `tui` | Textual | The Textual backend, a terminal |
|
|
123
|
+
| `report` | matplotlib | The report images of charts |
|
|
124
|
+
| `dataframe` | narwhals | A large table of a pandas, Polars, or PyArrow frame |
|
|
125
|
+
| `reload` | watchfiles | A faster `--reload` in development |
|
|
126
|
+
|
|
127
|
+
To try ComposeUI and its example apps, clone the repository and install every extra:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
git clone https://github.com/ehmoussi/composeui
|
|
131
|
+
cd composeui
|
|
132
|
+
uv sync --all-extras
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To choose extras, give them all in one command, for example
|
|
136
|
+
`uv sync --extra web --extra pyside6`. Each `uv sync` removes the extras that it does not
|
|
137
|
+
name, so a second `uv sync --extra tui` would remove the web and Qt backends.
|
|
138
|
+
|
|
139
|
+
## Quickstart
|
|
140
|
+
|
|
141
|
+
A minimal window with a text input. As you type your name, the status bar greets you:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from attrs import Factory
|
|
145
|
+
|
|
146
|
+
from composeui.core.application import run
|
|
147
|
+
from composeui.core.view import InputView, MainView, define_view
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@define_view
|
|
151
|
+
class GreetingInputView(InputView):
|
|
152
|
+
def __attrs_post_init__(self) -> None:
|
|
153
|
+
super().__attrs_post_init__()
|
|
154
|
+
self.placeholder = "Type your name..."
|
|
155
|
+
self.text_edited.connect(self._on_name_changed)
|
|
156
|
+
|
|
157
|
+
# `main_view` is injected automatically because it's a requested parameter.
|
|
158
|
+
def _on_name_changed(self, text: str, *, main_view: MainView) -> None:
|
|
159
|
+
main_view.status_bar.show_message(f"Hello, {text}!" if text else "")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@define_view
|
|
163
|
+
class HelloMainView(MainView):
|
|
164
|
+
app_title = "Hello ComposeUI"
|
|
165
|
+
extension = ".hello" # the file type of its studies, which the File menu saves
|
|
166
|
+
|
|
167
|
+
greeting: GreetingInputView = Factory(GreetingInputView)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
run(HelloMainView)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Run it with one of the backends. Each backend needs its extra:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv run python hello.py --backend qt # a window: the pyside6 extra
|
|
178
|
+
uv run python hello.py --backend textual # a terminal: the tui extra
|
|
179
|
+
uv run python hello.py # a web page, the default: the web extra
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The web backend serves the page at http://127.0.0.1:8000. `run` imports only the backend
|
|
183
|
+
that you choose, and leaves the rest of the command line to the app (`--help` lists it).
|
|
184
|
+
|
|
185
|
+
<img alt="The quickstart on the web: a text field holds Ada, and the status bar says Hello, Ada!" src="https://raw.githubusercontent.com/ehmoussi/composeui/main/docs/images/quickstart-web.png" width="600">
|
|
186
|
+
|
|
187
|
+
### Next steps
|
|
188
|
+
|
|
189
|
+
1. Read the [core concepts](https://ehmoussi.github.io/composeui/user-guide/core-concepts.html)
|
|
190
|
+
of the user guide: views, signals, the model, and studies.
|
|
191
|
+
2. Build a form with its layout and its checks, in
|
|
192
|
+
[Building views](https://ehmoussi.github.io/composeui/user-guide/building-views.html).
|
|
193
|
+
3. Run the example apps, in the order of the
|
|
194
|
+
[examples guide](https://ehmoussi.github.io/composeui/examples-guide.html#where-to-start).
|
|
195
|
+
The first,
|
|
196
|
+
[`src/examples/pipeform.py`](https://github.com/ehmoussi/composeui/blob/main/src/examples/pipeform.py),
|
|
197
|
+
has forms, radio groups, a check box, a read-only table, checks, and a File menu that
|
|
198
|
+
saves and opens:
|
|
199
|
+
`uv run python -m examples.pipeform --backend qt`, or `textual`, or `web`.
|
|
200
|
+
|
|
201
|
+
## Documentation
|
|
202
|
+
|
|
203
|
+
The documentation site, at https://ehmoussi.github.io/composeui/, has the guides below, a
|
|
204
|
+
widget catalog, and the API reference.
|
|
205
|
+
|
|
206
|
+
- The [user guide](https://ehmoussi.github.io/composeui/user-guide.html) explains how to build an app: the
|
|
207
|
+
views, their layout, forms and their checks, the widgets, pages, tabs, dialogs, tables,
|
|
208
|
+
charts, [maps](https://ehmoussi.github.io/composeui/user-guide/maps.html), threads, SQLite models, CSV
|
|
209
|
+
imports, translations, the differences between the backends, testing an app, and a skill
|
|
210
|
+
for coding agents.
|
|
211
|
+
- The [examples guide](https://ehmoussi.github.io/composeui/examples-guide.html) says what each example app
|
|
212
|
+
shows, and how to run it.
|
|
213
|
+
- The [technical guide](https://ehmoussi.github.io/composeui/technical-guide.html) explains how ComposeUI
|
|
214
|
+
works inside, and how to develop it: the architecture, how to add a widget or a backend,
|
|
215
|
+
the tests, and the checks.
|
|
216
|
+
- [`CHANGELOG.md`](https://github.com/ehmoussi/composeui/blob/main/CHANGELOG.md) lists the changes of each
|
|
217
|
+
release.
|
|
218
|
+
- [`ROADMAP.md`](https://github.com/ehmoussi/composeui/blob/main/ROADMAP.md) lists the work that is left.
|
|
219
|
+
|
|
220
|
+
## License
|
|
221
|
+
|
|
222
|
+
MIT, see [`LICENSE`](https://github.com/ehmoussi/composeui/blob/main/LICENSE).
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
composeui/__init__.py,sha256=UB8dn-CJ-nSFXzpWnfRwqFaE4F7RNlUTSrS99LFZXIg,341
|
|
2
|
+
composeui/mypy.py,sha256=ZrBCifwxkeWGX9px9y3_QT9fryuME0zk0y16teuLn5s,1883
|
|
3
|
+
composeui/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
composeui/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
composeui/core/application.py,sha256=kYP2rjCTwDSymvYsANUAJQgpPo0s7qX9f5Wzamzkbh8,14191
|
|
6
|
+
composeui/core/chartcolors.py,sha256=onjsKYpWJHgCZi6OtyX5_-uHzHVUP2mIha6Bgyz8fWA,916
|
|
7
|
+
composeui/core/chartimage.py,sha256=HE0B26iSu9CWqiZsdNEDbiglxolugufln6nYSuQ2_us,11884
|
|
8
|
+
composeui/core/dataframesource.py,sha256=q42uJ3acPenDJeNW3ruhlXKmMt2f-VB7SUi1nyJzHys,11576
|
|
9
|
+
composeui/core/jobs.py,sha256=Xdf3YvHKnqw4CHPrZk2gy7PklTv5Ej73M37E4fBJd3Q,17492
|
|
10
|
+
composeui/core/model.py,sha256=0AswlNgdL6UqiT2cUvgLhwABbzBl_GrdaXkxtXvAWK0,2355
|
|
11
|
+
composeui/core/registry.py,sha256=fqYIUm0rP7mSj6ewr-l2Zj_2myvQiPvJ9e4qfydAaV8,2245
|
|
12
|
+
composeui/core/reload.py,sha256=X9GAjmquxVvgDtqVCRsWVc4HNJ39TUqqI5C51KtM8uc,19257
|
|
13
|
+
composeui/core/renderer.py,sha256=7p8kMMEu3Gd88ScQakNK3wvabsi9jWFfp8OpSdjNzkg,7111
|
|
14
|
+
composeui/core/signal.py,sha256=N6Wpkh05F7VQweq22nxwJrELEGeInldnoSoBqfF3OiA,14105
|
|
15
|
+
composeui/core/sqlitemodel.py,sha256=-S2kNPuDhSwAX53KkODY9evgzTiHKaKDoG2mIMKXXG4,50152
|
|
16
|
+
composeui/core/study.py,sha256=LiP3BAaKpM9hPxj-ZNlqoKeIy_5QrZKy6WmpGpT2hLQ,5466
|
|
17
|
+
composeui/core/translation.py,sha256=GXyyBA5ER9otESrELgQ2y5P1yGtUhlpDeOkt3hM2W-Y,8158
|
|
18
|
+
composeui/core/translationcheck.py,sha256=wc3rPSs64WycQBKOEA8zVj_IQsxlf2wEx-NRDKwLS_k,9539
|
|
19
|
+
composeui/core/view.py,sha256=YBQfs5xZVkF31PAj5_nAsbwWyy_nO0DkVpO7zwD9XLA,226161
|
|
20
|
+
composeui/images/composeui.svg,sha256=jKQ_2oK59xCnI-wIlm7fST5og3v6yoCsVdb2Yv-_eQY,820
|
|
21
|
+
composeui/locales/fr.json,sha256=Ujww7htQlGbGoVmmEQujmwPRhv7WOrwLuRJASezi8PQ,2724
|
|
22
|
+
composeui/qtcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
composeui/qtcore/maprenderer.py,sha256=ZUk5LK6mtjwKGg_2awUsrCUzsGL8s3G_K2ZEfRJ7MnY,4303
|
|
24
|
+
composeui/qtcore/qtapplication.py,sha256=d3Q0nxfEmur5QVIruZyJ7w9qd4SuDJrb57EEJPyzvIg,7803
|
|
25
|
+
composeui/qtcore/qtrenderer.py,sha256=zel2Xr0mRojbHYIprNHXcwcgezPzN4ltagxasxrftEk,114176
|
|
26
|
+
composeui/qtcore/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
composeui/qtcore/widgets/map.qml,sha256=eCqqoh2vm6xNvjqN9xVTPEIAcuR7hlacJ9sgMOAeJaw,4569
|
|
28
|
+
composeui/qtcore/widgets/qchart.py,sha256=3-TspCjwtELvLol0DQamtmaxh4b5P4-sdAarU-0gBjM,17750
|
|
29
|
+
composeui/qtcore/widgets/qdatefield.py,sha256=s_EAj40VF6o2w_YYVpTYHclDzFcTpvVkl7Byo4TRM7M,4140
|
|
30
|
+
composeui/qtcore/widgets/qexpander.py,sha256=6v7zdxPDv-FdAUmJdnJ8CkK3cJN4T8wzjoQvmO5bMng,2618
|
|
31
|
+
composeui/qtcore/widgets/qfilepathfield.py,sha256=hmmloSznorj3CTcs-_QkJQz05ta6YJ7OPoa7EQZMyq4,1364
|
|
32
|
+
composeui/qtcore/widgets/qfiltertable.py,sha256=kWqxoRGRnGMl0oVmj86b1EvYP2idqAvq2VZl6Gxan8k,16120
|
|
33
|
+
composeui/qtcore/widgets/qformdialog.py,sha256=_frY4nh-M8sL46zVIgAUQGYrGMc307xlcv8o8tjx-1M,2142
|
|
34
|
+
composeui/qtcore/widgets/qformlabel.py,sha256=TVudhzpZryvBOXlAzigj0hI91j58P2-hBxhU2i5OxHY,1951
|
|
35
|
+
composeui/qtcore/widgets/qmap.py,sha256=UXghRtSpFfZECsnK1VvorbyzmamiZRrLSdpny-X3S64,2498
|
|
36
|
+
composeui/qtcore/widgets/qmarkicon.py,sha256=p_hEFZ3XDj5uozoUji1i2C_28ZdXrtl5LJj5YjnJvSA,1316
|
|
37
|
+
composeui/qtcore/widgets/qmetric.py,sha256=pi29U1kaOevvwYkQGsC22vxEVWNHODtqddrbepXOLuw,1781
|
|
38
|
+
composeui/qtcore/widgets/qplaintext.py,sha256=UkGzKXTy_ANfnwLQcP9N1OU9bAQ63f6t5NramncDukI,870
|
|
39
|
+
composeui/qtcore/widgets/qradiogroup.py,sha256=_SmfoEC4auHA0JmVE5tARWghysc1IdFdqyFxMb5E0pc,2192
|
|
40
|
+
composeui/qtcore/widgets/qsidebar.py,sha256=wW-BMJ2Lwd8V8ZNJdhRgWmZwrkl38E0jRwEVckVrfyc,5058
|
|
41
|
+
composeui/qtcore/widgets/qsourcetable.py,sha256=W3M8fvtV0Hs8PCeJ_3b7wnU2gy4fvmw5mBiwh5ZMZI8,9359
|
|
42
|
+
composeui/qtcore/widgets/qsplitter.py,sha256=l4GJdk9c-oDkcT9tm5xcnyv35TKM5Lvx_OoBa1WzTlw,2568
|
|
43
|
+
composeui/qtcore/widgets/qtexttable.py,sha256=6p1GcJ3CNTzE5lT_SaHYW3ROizZwzyvnE65OtcxcIHU,30194
|
|
44
|
+
composeui/qtcore/widgets/qvaluecombobox.py,sha256=3ErfHV9_4oVtWLWPX_phUG1MuFRkDccFJ_UcdHHuyOA,1539
|
|
45
|
+
composeui/qtcore/widgets/qvalueslider.py,sha256=C99kn_aJEPvhv_LxS2iyJzrsgzaFTl2On8wPmv8NJwo,2669
|
|
46
|
+
composeui/qtcore/widgets/qwindowrelease.py,sha256=joxvMJfQgw6RwhB8W95wToFhYedbhdBDvZjYcjY26dY,1342
|
|
47
|
+
composeui/textualcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
+
composeui/textualcore/textualapplication.py,sha256=7hGPBzvufKBqc0il0aJrDeNmleoMVYmN2lHRDfKbOns,3859
|
|
49
|
+
composeui/textualcore/textualrenderer.py,sha256=0XI7viMgLzIM9FE24q3c3t_vA3N6MMBE6UtV_zHOBUw,114360
|
|
50
|
+
composeui/textualcore/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
+
composeui/textualcore/widgets/composebutton.py,sha256=Ch3oHoXeuQLwLTcievg95kKSR8TVYLmhbt5Mn7ZSJHY,438
|
|
52
|
+
composeui/textualcore/widgets/composechart.py,sha256=E7oRYGKZ0a2hjG6UbgupKoSZ3B0AA0qLagOhNHPfz1Q,8361
|
|
53
|
+
composeui/textualcore/widgets/composecheckbox.py,sha256=uwZYQWcCksXbq_bOhS5Gw_iJqqn_nbHKe3rBgnpA3CY,1068
|
|
54
|
+
composeui/textualcore/widgets/composecollapsible.py,sha256=nIJen27SXCC0umT6rX9-UwfUpC90w2V9yF2KjghFX7Q,1520
|
|
55
|
+
composeui/textualcore/widgets/composecombobox.py,sha256=WxMrLwOL_hODoPUQueiU6amfYpnh2rljSzAvQ999e-E,1812
|
|
56
|
+
composeui/textualcore/widgets/composedateinput.py,sha256=Vq_9iishEGTVW53ml29QvOHEBY2jUQUHQBM6dZeJRbo,11393
|
|
57
|
+
composeui/textualcore/widgets/composedialog.py,sha256=UtdX6I0bSdChEMLQIAiaUq6tUoYlOjJi0aKPrrGmG-g,2791
|
|
58
|
+
composeui/textualcore/widgets/composefilepathinput.py,sha256=p5fCqLXS9Mou7p_6LJLtqxg00LUDi8ijjvcs_fHCerg,2988
|
|
59
|
+
composeui/textualcore/widgets/composefiltertable.py,sha256=UsH_ZZEMU1slBZa3NIrJUQ8k9xdktDU_8G4kF0Q1Los,13379
|
|
60
|
+
composeui/textualcore/widgets/composeformdialog.py,sha256=by4bQrjssnajplR3Eeh9nfkLpojfvqgheLeIslBPcfc,2844
|
|
61
|
+
composeui/textualcore/widgets/composeinput.py,sha256=NFWCOrESvK4x81ewOxrkaPPL66NnvGyXOcZwiaWuir8,1728
|
|
62
|
+
composeui/textualcore/widgets/composelist.py,sha256=xdz7RvmVbn5C5yj4V1lQFCEACoC5iCwC3KRCo3pa_IU,511
|
|
63
|
+
composeui/textualcore/widgets/composemarkdown.py,sha256=qyBOplO0wpjtMpH0ROZqD845BkVhURdLp_nTA5P5JAs,533
|
|
64
|
+
composeui/textualcore/widgets/composemetric.py,sha256=METhAPxbiFaYLRn3vW6_m3K_5Y0w7y0IrfOdV7xhAe8,1666
|
|
65
|
+
composeui/textualcore/widgets/composeradioset.py,sha256=AExRKZNVmsFIKj1E23W92yetdkzEtRZJm1kykvrE1sY,2035
|
|
66
|
+
composeui/textualcore/widgets/composesidebar.py,sha256=3Lvn8VTi2zSWaCkdLzeRgLDntkixLwJS9oTd6FiV7n4,3455
|
|
67
|
+
composeui/textualcore/widgets/composeslider.py,sha256=Gzy7MdiVBrqO3_GMxyfJeVGT3k4dyk8GT6ugTsOxfG0,5183
|
|
68
|
+
composeui/textualcore/widgets/composesourcetable.py,sha256=9DXqY6E5nqoW69ofG6EQj51FWhhoWSkYuKjEV2wSTWg,11556
|
|
69
|
+
composeui/textualcore/widgets/composesplitter.py,sha256=49v51kaEhFVgfL_wf-wQDGcgw4f2bpZMajKB9xaQihc,8225
|
|
70
|
+
composeui/textualcore/widgets/composetabbedcontent.py,sha256=8xy_BmB7rukR_EwSJoTX-aAbEjZWziAh03dCqtiVuQU,1494
|
|
71
|
+
composeui/textualcore/widgets/composetable.py,sha256=_0Uda7ibYWruBJ1HmXZCozv2dpjnmLVfyX0EJadx1BM,19903
|
|
72
|
+
composeui/textualcore/widgets/composetoolbar.py,sha256=aiQ137RmbFUX7ZvQv4hTGCsPhD3U94HSmulxPyWR0x8,1472
|
|
73
|
+
composeui/textualcore/widgets/composetree.py,sha256=2ZSxfpqVwRbJIl6BbBTqnUmhxCUn5wIPudXDaZ-vHfE,5349
|
|
74
|
+
composeui/webcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
75
|
+
composeui/webcore/headers.py,sha256=Fod-rj4eG3VW2xE9bWznGh5pXFebW3IRcxtyTzowKeQ,2579
|
|
76
|
+
composeui/webcore/icons.py,sha256=1pwHPPr3nSEn7ZgiubUy2saqJwI8mcKIIS678hIuCwY,2053
|
|
77
|
+
composeui/webcore/limits.py,sha256=Vh3tpLU0KyxgwFsCuqZRHoEugEw1ifIZSf1wXr73ibA,2295
|
|
78
|
+
composeui/webcore/origin.py,sha256=7RyCvs-uiZrhJaCpX0ygtei6I1h9FbihqUVHUxHtjjU,2328
|
|
79
|
+
composeui/webcore/page.py,sha256=uMRENCDO09GTgfctqKtEMQShgdoaSxTrMVC6zDRTikg,5532
|
|
80
|
+
composeui/webcore/routes.py,sha256=ql_tCIfnLa2yoAZfepf3DyhcDxfNVz0NW0Wl-RPHKcE,12489
|
|
81
|
+
composeui/webcore/session.py,sha256=LZLyZy1fWxazonj6c-4PO7pLnRKByMUo_yLBKNB1e6I,19035
|
|
82
|
+
composeui/webcore/webapplication.py,sha256=k-jlMOstBSwplTxNdX7zxGZXZprzy7pJ97Ciglg59cQ,21060
|
|
83
|
+
composeui/webcore/webrenderer.py,sha256=-TuppI9DZh5wE35GlrLXk8mDQkTSzbLioK1DzxKGm10,217744
|
|
84
|
+
composeui/webcore/static/app.css,sha256=721zkPu7Yv2ksycAMy-biEwGR0z3JHJY4q04tATcDnA,147685
|
|
85
|
+
composeui/webcore/static/cally.js,sha256=2unIU0C1mxkbYSMXaCMMs8EEOj55AFU4sj1iZM9AHTo,39533
|
|
86
|
+
composeui/webcore/static/daisyui.LICENSE,sha256=hwnjrGXIRjfEItyAgriT2Zl_zgk3Ucd7LxmDvynb-eo,1071
|
|
87
|
+
composeui/webcore/static/deckgl.LICENSE,sha256=5Jmiwro7n6q-kf3930PjKUOSYyZLcUjlVI0OxgXM6fI,1055
|
|
88
|
+
composeui/webcore/static/deckgl.min.js,sha256=I04K-XppG45a6mxsqecDp7pSBv0fU9qp9nDkHbCJ3i0,1701208
|
|
89
|
+
composeui/webcore/static/htmx.min.js,sha256=cepnGFv6jJjDnTFxfG_OXYUjcPzf0SnbRUN3TTFFwN4,51238
|
|
90
|
+
composeui/webcore/static/page.js,sha256=oa5PTfk2uzqQJfutU-1R1A6lmtemqA9H-iTMEuAF7hI,51934
|
|
91
|
+
composeui/webcore/static/uPlot.LICENSE,sha256=j5iSKWmbT-LxoEMtDp7cM4qKkR4lDi0bAezXcKX1sb0,1078
|
|
92
|
+
composeui/webcore/static/uPlot.iife.min.js,sha256=GcjUxq2Ikpp59K5J1vcWFWbf0Lo9FcxJXpdPeH63jx8,51081
|
|
93
|
+
composeui-0.1.0.dist-info/licenses/LICENSE,sha256=fq_-yLY-RBFbGOKX1GUAGrd97hKh8qHpkrqzh6vHtaA,1080
|
|
94
|
+
composeui-0.1.0.dist-info/METADATA,sha256=lP_3NfrCH5Osedncfgzpa07SE4BJxHiQX-AWSueSzzo,10191
|
|
95
|
+
composeui-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
96
|
+
composeui-0.1.0.dist-info/top_level.txt,sha256=ohPTnCpCKa1CeDEmGab38AN2WcE3aLJP9ajuiYSwnh8,10
|
|
97
|
+
composeui-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 El Hadi Moussi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
composeui
|