velto-core 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- velto_core-0.1.0/LICENSE +21 -0
- velto_core-0.1.0/PKG-INFO +343 -0
- velto_core-0.1.0/README.md +302 -0
- velto_core-0.1.0/psx/__init__.py +120 -0
- velto_core-0.1.0/psx/app.py +118 -0
- velto_core-0.1.0/psx/core/__init__.py +1 -0
- velto_core-0.1.0/psx/core/component.py +48 -0
- velto_core-0.1.0/psx/core/contracts.py +238 -0
- velto_core-0.1.0/psx/core/defaults.py +143 -0
- velto_core-0.1.0/psx/core/errors.py +51 -0
- velto_core-0.1.0/psx/core/events.py +27 -0
- velto_core-0.1.0/psx/core/grid_contract.py +159 -0
- velto_core-0.1.0/psx/core/hooks.py +209 -0
- velto_core-0.1.0/psx/core/instance.py +46 -0
- velto_core-0.1.0/psx/core/layout_item.py +88 -0
- velto_core-0.1.0/psx/core/layout_tree.py +190 -0
- velto_core-0.1.0/psx/core/native.py +502 -0
- velto_core-0.1.0/psx/core/native_materialization.py +398 -0
- velto_core-0.1.0/psx/core/props.py +110 -0
- velto_core-0.1.0/psx/core/reconcile.py +888 -0
- velto_core-0.1.0/psx/core/registry.py +180 -0
- velto_core-0.1.0/psx/core/scheduler.py +77 -0
- velto_core-0.1.0/psx/core/structural_binding.py +181 -0
- velto_core-0.1.0/psx/core/validators.py +725 -0
- velto_core-0.1.0/psx/core/vnode.py +746 -0
- velto_core-0.1.0/psx/css/__init__.py +11 -0
- velto_core-0.1.0/psx/css/cache.py +85 -0
- velto_core-0.1.0/psx/css/cascade.py +72 -0
- velto_core-0.1.0/psx/css/catalog.py +66 -0
- velto_core-0.1.0/psx/css/context.py +44 -0
- velto_core-0.1.0/psx/css/cursor.py +41 -0
- velto_core-0.1.0/psx/css/effects.py +40 -0
- velto_core-0.1.0/psx/css/geometry.py +54 -0
- velto_core-0.1.0/psx/css/inheritance.py +43 -0
- velto_core-0.1.0/psx/css/markup.py +133 -0
- velto_core-0.1.0/psx/css/native_paint.py +389 -0
- velto_core-0.1.0/psx/css/parser.py +158 -0
- velto_core-0.1.0/psx/css/properties.py +202 -0
- velto_core-0.1.0/psx/css/sources.py +83 -0
- velto_core-0.1.0/psx/css/tree.py +159 -0
- velto_core-0.1.0/psx/css/visual_values.py +103 -0
- velto_core-0.1.0/psx/devtools/__init__.py +22 -0
- velto_core-0.1.0/psx/devtools/__main__.py +26 -0
- velto_core-0.1.0/psx/devtools/classifier.py +52 -0
- velto_core-0.1.0/psx/devtools/config.py +54 -0
- velto_core-0.1.0/psx/devtools/coordinated_refresh.py +124 -0
- velto_core-0.1.0/psx/devtools/qyro_reload.py +474 -0
- velto_core-0.1.0/psx/devtools/runtime.py +48 -0
- velto_core-0.1.0/psx/devtools/state.py +58 -0
- velto_core-0.1.0/psx/devtools/supervisor.py +169 -0
- velto_core-0.1.0/psx/devtools/watcher.py +96 -0
- velto_core-0.1.0/psx/extensions/__init__.py +5 -0
- velto_core-0.1.0/psx/extensions/qt_webengine.py +230 -0
- velto_core-0.1.0/psx/integrations/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/__init__.py +54 -0
- velto_core-0.1.0/psx/layout/adapters/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/adapters/external_native_geometry_ports.py +122 -0
- velto_core-0.1.0/psx/layout/adapters/grid_native_commit.py +302 -0
- velto_core-0.1.0/psx/layout/adapters/grid_viewport_workset.py +263 -0
- velto_core-0.1.0/psx/layout/adapters/headless_block_bridge.py +153 -0
- velto_core-0.1.0/psx/layout/adapters/headless_grid_bridge.py +153 -0
- velto_core-0.1.0/psx/layout/adapters/headless_layout_bridge.py +330 -0
- velto_core-0.1.0/psx/layout/adapters/headless_measurement.py +46 -0
- velto_core-0.1.0/psx/layout/adapters/native_flow_viewport.py +229 -0
- velto_core-0.1.0/psx/layout/adapters/native_geometry.py +287 -0
- velto_core-0.1.0/psx/layout/adapters/native_grid_bridge.py +520 -0
- velto_core-0.1.0/psx/layout/adapters/native_pixel_space.py +101 -0
- velto_core-0.1.0/psx/layout/adapters/native_readback_reuse.py +94 -0
- velto_core-0.1.0/psx/layout/adapters/native_scroll_hosts.py +67 -0
- velto_core-0.1.0/psx/layout/adapters/viewport_resize_priority.py +190 -0
- velto_core-0.1.0/psx/layout/adapters/viewport_scroll_reentry.py +63 -0
- velto_core-0.1.0/psx/layout/compat/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/compat/native_component_matrix.py +6 -0
- velto_core-0.1.0/psx/layout/compat/native_external_ownership_cases.py +6 -0
- velto_core-0.1.0/psx/layout/compat/native_external_ownership_receipts.py +10 -0
- velto_core-0.1.0/psx/layout/compat/native_operation_contracts.py +6 -0
- velto_core-0.1.0/psx/layout/compat/native_operation_evidence.py +6 -0
- velto_core-0.1.0/psx/layout/compat/native_operation_oracles.py +6 -0
- velto_core-0.1.0/psx/layout/compat/native_operation_receipts.py +10 -0
- velto_core-0.1.0/psx/layout/contracts/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/contracts/capabilities.py +125 -0
- velto_core-0.1.0/psx/layout/contracts/engine.py +74 -0
- velto_core-0.1.0/psx/layout/contracts/errors.py +35 -0
- velto_core-0.1.0/psx/layout/contracts/fixed_point.py +103 -0
- velto_core-0.1.0/psx/layout/contracts/flow.py +25 -0
- velto_core-0.1.0/psx/layout/contracts/lengths.py +133 -0
- velto_core-0.1.0/psx/layout/contracts/model.py +286 -0
- velto_core-0.1.0/psx/layout/contracts/native_wire.py +116 -0
- velto_core-0.1.0/psx/layout/contracts/recursive_tree.py +333 -0
- velto_core-0.1.0/psx/layout/contracts/tree_identity.py +16 -0
- velto_core-0.1.0/psx/layout/contracts/used_size.py +14 -0
- velto_core-0.1.0/psx/layout/contracts/wire.py +325 -0
- velto_core-0.1.0/psx/layout/engine/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/engine/backend.py +417 -0
- velto_core-0.1.0/psx/layout/fallback/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/fallback/align_content.py +107 -0
- velto_core-0.1.0/psx/layout/fallback/auto_cross_tree.py +126 -0
- velto_core-0.1.0/psx/layout/fallback/baseline.py +57 -0
- velto_core-0.1.0/psx/layout/fallback/box_geometry.py +49 -0
- velto_core-0.1.0/psx/layout/fallback/compute_alpha.py +1441 -0
- velto_core-0.1.0/psx/layout/fallback/constraint_propagation.py +2 -0
- velto_core-0.1.0/psx/layout/fallback/convergence.py +64 -0
- velto_core-0.1.0/psx/layout/fallback/cross_alignment.py +66 -0
- velto_core-0.1.0/psx/layout/fallback/cross_margins.py +80 -0
- velto_core-0.1.0/psx/layout/fallback/cross_stretch.py +48 -0
- velto_core-0.1.0/psx/layout/fallback/edge_pipeline.py +151 -0
- velto_core-0.1.0/psx/layout/fallback/edge_tree.py +121 -0
- velto_core-0.1.0/psx/layout/fallback/engine.py +128 -0
- velto_core-0.1.0/psx/layout/fallback/flex_math.py +149 -0
- velto_core-0.1.0/psx/layout/fallback/flow_layout.py +94 -0
- velto_core-0.1.0/psx/layout/fallback/grid_math.py +290 -0
- velto_core-0.1.0/psx/layout/fallback/intrinsic.py +119 -0
- velto_core-0.1.0/psx/layout/fallback/intrinsic_dependencies.py +102 -0
- velto_core-0.1.0/psx/layout/fallback/intrinsic_tree.py +22 -0
- velto_core-0.1.0/psx/layout/fallback/line_layout.py +200 -0
- velto_core-0.1.0/psx/layout/fallback/main_alignment.py +95 -0
- velto_core-0.1.0/psx/layout/fallback/main_margins.py +148 -0
- velto_core-0.1.0/psx/layout/fallback/margin_flex_pipeline.py +278 -0
- velto_core-0.1.0/psx/layout/fallback/margin_tree.py +138 -0
- velto_core-0.1.0/psx/layout/fallback/measured_block_snapshot.py +570 -0
- velto_core-0.1.0/psx/layout/fallback/measurement_coordinator.py +40 -0
- velto_core-0.1.0/psx/layout/fallback/measurement_plan.py +2 -0
- velto_core-0.1.0/psx/layout/fallback/measurement_round.py +2 -0
- velto_core-0.1.0/psx/layout/fallback/percentage_box_sizing.py +44 -0
- velto_core-0.1.0/psx/layout/fallback/percentage_constraints.py +143 -0
- velto_core-0.1.0/psx/layout/fallback/percentage_flex_basis.py +48 -0
- velto_core-0.1.0/psx/layout/fallback/remeasurement.py +2 -0
- velto_core-0.1.0/psx/layout/fallback/resolved_pipeline.py +116 -0
- velto_core-0.1.0/psx/layout/fallback/resolved_tree.py +95 -0
- velto_core-0.1.0/psx/layout/fallback/semantic_inline_text.py +128 -0
- velto_core-0.1.0/psx/layout/fallback/sizing.py +6 -0
- velto_core-0.1.0/psx/layout/fallback/used_size.py +2 -0
- velto_core-0.1.0/psx/layout/fallback/used_size_tree.py +3 -0
- velto_core-0.1.0/psx/layout/flow/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/flow/solver.py +93 -0
- velto_core-0.1.0/psx/layout/grid/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/grid/contracts.py +83 -0
- velto_core-0.1.0/psx/layout/grid/grid_early_viewport.py +336 -0
- velto_core-0.1.0/psx/layout/grid/grid_flex_composition.py +231 -0
- velto_core-0.1.0/psx/layout/grid/grid_geometry_reuse.py +386 -0
- velto_core-0.1.0/psx/layout/grid/grid_intrinsic_reuse.py +128 -0
- velto_core-0.1.0/psx/layout/grid/grid_native_composition.py +1060 -0
- velto_core-0.1.0/psx/layout/grid/grid_native_measurement.py +295 -0
- velto_core-0.1.0/psx/layout/grid/grid_native_plan.py +87 -0
- velto_core-0.1.0/psx/layout/grid/grid_solved_reuse.py +161 -0
- velto_core-0.1.0/psx/layout/grid/grid_tree_measurement.py +139 -0
- velto_core-0.1.0/psx/layout/grid/grid_uniform_projection.py +292 -0
- velto_core-0.1.0/psx/layout/grid/mixed_grid_native.py +832 -0
- velto_core-0.1.0/psx/layout/grid/solver.py +139 -0
- velto_core-0.1.0/psx/layout/inline/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/inline/semantic_inline_native_layout.py +225 -0
- velto_core-0.1.0/psx/layout/inline/semantic_inline_native_measurement.py +20 -0
- velto_core-0.1.0/psx/layout/inline/semantic_inline_native_paint.py +66 -0
- velto_core-0.1.0/psx/layout/inline/semantic_inline_text.py +138 -0
- velto_core-0.1.0/psx/layout/projection/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/projection/box_sizing.py +104 -0
- velto_core-0.1.0/psx/layout/projection/canonical_box_style.py +123 -0
- velto_core-0.1.0/psx/layout/projection/display_context.py +95 -0
- velto_core-0.1.0/psx/layout/projection/inline_baselines.py +63 -0
- velto_core-0.1.0/psx/layout/projection/mounted_layout_index.py +42 -0
- velto_core-0.1.0/psx/layout/projection/native_component_capabilities.py +113 -0
- velto_core-0.1.0/psx/layout/projection/native_layout_snapshot.py +667 -0
- velto_core-0.1.0/psx/layout/projection/native_structural_snapshot_reuse.py +153 -0
- velto_core-0.1.0/psx/layout/projection/replaced_image_sizing.py +60 -0
- velto_core-0.1.0/psx/layout/projection/size_resolution.py +161 -0
- velto_core-0.1.0/psx/layout/projection/used_size.py +62 -0
- velto_core-0.1.0/psx/layout/projection/used_size_tree.py +80 -0
- velto_core-0.1.0/psx/layout/runtime/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/runtime/adapter_contract.py +253 -0
- velto_core-0.1.0/psx/layout/runtime/calibration.py +63 -0
- velto_core-0.1.0/psx/layout/runtime/constraint_propagation.py +163 -0
- velto_core-0.1.0/psx/layout/runtime/context_invalidation_plan.py +67 -0
- velto_core-0.1.0/psx/layout/runtime/dependency_cycle.py +98 -0
- velto_core-0.1.0/psx/layout/runtime/incremental_layout.py +78 -0
- velto_core-0.1.0/psx/layout/runtime/incremental_result_reuse.py +56 -0
- velto_core-0.1.0/psx/layout/runtime/layout_change_effects.py +207 -0
- velto_core-0.1.0/psx/layout/runtime/live_lifecycle.py +87 -0
- velto_core-0.1.0/psx/layout/runtime/measurement_plan.py +110 -0
- velto_core-0.1.0/psx/layout/runtime/measurement_round.py +100 -0
- velto_core-0.1.0/psx/layout/runtime/native_intrinsic_cache.py +101 -0
- velto_core-0.1.0/psx/layout/runtime/native_lifecycle.py +85 -0
- velto_core-0.1.0/psx/layout/runtime/native_measurement.py +50 -0
- velto_core-0.1.0/psx/layout/runtime/native_measurement_dependencies.py +56 -0
- velto_core-0.1.0/psx/layout/runtime/native_measurement_invalidation.py +66 -0
- velto_core-0.1.0/psx/layout/runtime/native_resource_watch.py +92 -0
- velto_core-0.1.0/psx/layout/runtime/native_scroll_transaction.py +96 -0
- velto_core-0.1.0/psx/layout/runtime/recursive_geometry.py +35 -0
- velto_core-0.1.0/psx/layout/runtime/recursive_measurement.py +82 -0
- velto_core-0.1.0/psx/layout/runtime/recursive_pipeline.py +118 -0
- velto_core-0.1.0/psx/layout/runtime/recursive_preparation.py +114 -0
- velto_core-0.1.0/psx/layout/runtime/remeasure_session.py +120 -0
- velto_core-0.1.0/psx/layout/runtime/remeasurement.py +66 -0
- velto_core-0.1.0/psx/layout/runtime/structural_text_probe.py +169 -0
- velto_core-0.1.0/psx/layout/runtime/toolkit_worker.py +182 -0
- velto_core-0.1.0/psx/layout/runtime/width_dependent_intrinsic_measurement.py +172 -0
- velto_core-0.1.0/psx/layout/runtime/worker_lifecycle.py +243 -0
- velto_core-0.1.0/psx/layout/scroll/__init__.py +1 -0
- velto_core-0.1.0/psx/layout/scroll/native_scroll_viewport.py +72 -0
- velto_core-0.1.0/psx/layout/scroll/scroll_events.py +78 -0
- velto_core-0.1.0/psx/layout/scroll/scroll_offsets.py +81 -0
- velto_core-0.1.0/psx/markup/__init__.py +14 -0
- velto_core-0.1.0/psx/markup/ast.py +68 -0
- velto_core-0.1.0/psx/markup/compile.py +484 -0
- velto_core-0.1.0/psx/markup/component_compiler.py +144 -0
- velto_core-0.1.0/psx/markup/expressive_ast.py +565 -0
- velto_core-0.1.0/psx/markup/expressive_lower.py +224 -0
- velto_core-0.1.0/psx/markup/expressive_runtime.py +244 -0
- velto_core-0.1.0/psx/markup/expressive_syntax.py +113 -0
- velto_core-0.1.0/psx/markup/html_aliases.py +416 -0
- velto_core-0.1.0/psx/markup/html_form_groups.py +119 -0
- velto_core-0.1.0/psx/markup/image_sources.py +40 -0
- velto_core-0.1.0/psx/markup/lexer.py +157 -0
- velto_core-0.1.0/psx/markup/parser.py +157 -0
- velto_core-0.1.0/psx/markup/transform.py +370 -0
- velto_core-0.1.0/psx/plugins.py +144 -0
- velto_core-0.1.0/psx/renderers/__init__.py +6 -0
- velto_core-0.1.0/psx/renderers/adapters.py +110 -0
- velto_core-0.1.0/psx/renderers/components/badge.py +68 -0
- velto_core-0.1.0/psx/renderers/components/button.py +62 -0
- velto_core-0.1.0/psx/renderers/components/checkbox.py +45 -0
- velto_core-0.1.0/psx/renderers/components/divider.py +31 -0
- velto_core-0.1.0/psx/renderers/components/image.py +103 -0
- velto_core-0.1.0/psx/renderers/components/input.py +127 -0
- velto_core-0.1.0/psx/renderers/components/link.py +38 -0
- velto_core-0.1.0/psx/renderers/components/progressbar.py +107 -0
- velto_core-0.1.0/psx/renderers/components/radio.py +55 -0
- velto_core-0.1.0/psx/renderers/components/scroll.py +54 -0
- velto_core-0.1.0/psx/renderers/components/select.py +84 -0
- velto_core-0.1.0/psx/renderers/components/slider.py +108 -0
- velto_core-0.1.0/psx/renderers/components/spacer.py +41 -0
- velto_core-0.1.0/psx/renderers/components/spinbox.py +71 -0
- velto_core-0.1.0/psx/renderers/components/switch.py +42 -0
- velto_core-0.1.0/psx/renderers/components/text.py +103 -0
- velto_core-0.1.0/psx/renderers/components/textarea.py +80 -0
- velto_core-0.1.0/psx/renderers/headless.py +461 -0
- velto_core-0.1.0/psx/renderers/kivy/__init__.py +5 -0
- velto_core-0.1.0/psx/renderers/kivy/badge.py +120 -0
- velto_core-0.1.0/psx/renderers/kivy/box.py +63 -0
- velto_core-0.1.0/psx/renderers/kivy/cinnamon_kivy_display_scale.py +86 -0
- velto_core-0.1.0/psx/renderers/kivy/cinnamon_kivy_layout_bridge.py +704 -0
- velto_core-0.1.0/psx/renderers/kivy/cinnamon_kivy_measurement.py +405 -0
- velto_core-0.1.0/psx/renderers/kivy/css_cursor.py +118 -0
- velto_core-0.1.0/psx/renderers/kivy/divider.py +320 -0
- velto_core-0.1.0/psx/renderers/kivy/flex.py +96 -0
- velto_core-0.1.0/psx/renderers/kivy/image.py +159 -0
- velto_core-0.1.0/psx/renderers/kivy/inline_measurement.py +31 -0
- velto_core-0.1.0/psx/renderers/kivy/inline_paint.py +77 -0
- velto_core-0.1.0/psx/renderers/kivy/kivy.py +1994 -0
- velto_core-0.1.0/psx/renderers/kivy/link.py +70 -0
- velto_core-0.1.0/psx/renderers/kivy/progressbar.py +89 -0
- velto_core-0.1.0/psx/renderers/kivy/radio.py +230 -0
- velto_core-0.1.0/psx/renderers/kivy/scroll.py +220 -0
- velto_core-0.1.0/psx/renderers/kivy/scroll_host.py +33 -0
- velto_core-0.1.0/psx/renderers/kivy/spinbox.py +141 -0
- velto_core-0.1.0/psx/renderers/kivy/switch.py +145 -0
- velto_core-0.1.0/psx/renderers/protocol.py +22 -0
- velto_core-0.1.0/psx/renderers/qt/__init__.py +6 -0
- velto_core-0.1.0/psx/renderers/qt/badge.py +125 -0
- velto_core-0.1.0/psx/renderers/qt/box.py +91 -0
- velto_core-0.1.0/psx/renderers/qt/cinnamon_qt_layout_bridge.py +621 -0
- velto_core-0.1.0/psx/renderers/qt/cinnamon_qt_measurement.py +234 -0
- velto_core-0.1.0/psx/renderers/qt/cinnamon_qt_worker_dispatch.py +130 -0
- velto_core-0.1.0/psx/renderers/qt/divider.py +258 -0
- velto_core-0.1.0/psx/renderers/qt/flex.py +94 -0
- velto_core-0.1.0/psx/renderers/qt/image.py +167 -0
- velto_core-0.1.0/psx/renderers/qt/inline_measurement.py +15 -0
- velto_core-0.1.0/psx/renderers/qt/inline_paint.py +54 -0
- velto_core-0.1.0/psx/renderers/qt/link.py +69 -0
- velto_core-0.1.0/psx/renderers/qt/pyqt.py +1623 -0
- velto_core-0.1.0/psx/renderers/qt/pyside.py +19 -0
- velto_core-0.1.0/psx/renderers/qt/radiogroup.py +183 -0
- velto_core-0.1.0/psx/renderers/qt/scroll.py +337 -0
- velto_core-0.1.0/psx/renderers/qt/scroll_host.py +28 -0
- velto_core-0.1.0/psx/renderers/qt/spinbox.py +150 -0
- velto_core-0.1.0/psx/renderers/qt/switch.py +183 -0
- velto_core-0.1.0/psx/renderers/tkinter/__init__.py +5 -0
- velto_core-0.1.0/psx/renderers/tkinter/badge.py +152 -0
- velto_core-0.1.0/psx/renderers/tkinter/box.py +55 -0
- velto_core-0.1.0/psx/renderers/tkinter/cinnamon_tk_measurement.py +343 -0
- velto_core-0.1.0/psx/renderers/tkinter/cinnamon_tkinter_layout_bridge.py +673 -0
- velto_core-0.1.0/psx/renderers/tkinter/divider.py +301 -0
- velto_core-0.1.0/psx/renderers/tkinter/flex.py +76 -0
- velto_core-0.1.0/psx/renderers/tkinter/image.py +188 -0
- velto_core-0.1.0/psx/renderers/tkinter/inline_measurement.py +28 -0
- velto_core-0.1.0/psx/renderers/tkinter/inline_paint.py +53 -0
- velto_core-0.1.0/psx/renderers/tkinter/link.py +71 -0
- velto_core-0.1.0/psx/renderers/tkinter/radiogroup.py +165 -0
- velto_core-0.1.0/psx/renderers/tkinter/rounded_surface.py +262 -0
- velto_core-0.1.0/psx/renderers/tkinter/scroll.py +332 -0
- velto_core-0.1.0/psx/renderers/tkinter/scroll_host.py +56 -0
- velto_core-0.1.0/psx/renderers/tkinter/select.py +81 -0
- velto_core-0.1.0/psx/renderers/tkinter/spinbox.py +128 -0
- velto_core-0.1.0/psx/renderers/tkinter/switch.py +150 -0
- velto_core-0.1.0/psx/renderers/tkinter/tkinter.py +2936 -0
- velto_core-0.1.0/pyproject.toml +72 -0
velto_core-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PSX contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: velto-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Velto is a declarative, reactive Python UI framework with native rendering, expressive PSX markup, and cross-platform layout powered by Cinnamon.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: velto,ui,declarative,reactive,native,psx,rust,pyside6,pyqt6,pyqt5,pyside2,kivy,tkinter
|
|
8
|
+
Author: runesc
|
|
9
|
+
Author-email: luisalfredoreyes98@gmail.com
|
|
10
|
+
Requires-Python: >=3.10,<3.14.20
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Provides-Extra: kivy
|
|
19
|
+
Provides-Extra: pyqt5
|
|
20
|
+
Provides-Extra: pyqt6
|
|
21
|
+
Provides-Extra: pyside2
|
|
22
|
+
Provides-Extra: pyside6
|
|
23
|
+
Requires-Dist: Kivy (>=2.3) ; extra == "kivy"
|
|
24
|
+
Requires-Dist: Pillow (>=10.0)
|
|
25
|
+
Requires-Dist: PyQt5 (>=5.15) ; (python_version < "3.14.20") and (extra == "pyqt5")
|
|
26
|
+
Requires-Dist: PyQt6 (>=6.8) ; (python_version < "3.14.20") and (extra == "pyqt6")
|
|
27
|
+
Requires-Dist: PySide2 (>=5.15,<6) ; (python_version < "3.11") and (extra == "pyside2")
|
|
28
|
+
Requires-Dist: PySide6 (>=6.11) ; (python_version < "3.14.20") and (extra == "pyside6")
|
|
29
|
+
Requires-Dist: build (>=1.2) ; extra == "dev"
|
|
30
|
+
Requires-Dist: maturin (>=1.16.0,<2.0.0) ; extra == "dev"
|
|
31
|
+
Requires-Dist: playwright (>=1.64.1,<2.0.0) ; extra == "dev"
|
|
32
|
+
Requires-Dist: psutil (>=5.9) ; extra == "dev"
|
|
33
|
+
Requires-Dist: pyqtgraph (>=0.14.0,<0.15.0) ; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest (>=8.0) ; extra == "dev"
|
|
35
|
+
Requires-Dist: resvg_py (>=0.5,<0.6)
|
|
36
|
+
Requires-Dist: ruff ; extra == "dev"
|
|
37
|
+
Requires-Dist: tomli (>=2) ; (python_version < "3.11") and (extra == "dev")
|
|
38
|
+
Requires-Dist: velto-cinnamon-core (==0.1.0)
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# PSX
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
Build native Python interfaces using **PSX Markup**, CSS-like styling, reusable components, and a unified cross-platform rendering system.
|
|
45
|
+
|
|
46
|
+
PSX is the UI foundation of **Velto**. It provides a unified interface authoring language with familiar HTML-like syntax, reactive components, and native widget integration, rendering actual native widgets through **Qt, Tkinter, and Kivy**.
|
|
47
|
+
|
|
48
|
+
**No browser. No embedded web engine. Native interfaces powered by Python.**
|
|
49
|
+
|
|
50
|
+
> **Project status:** PSX is currently in alpha development. Features and APIs may change as the project evolves.
|
|
51
|
+
|
|
52
|
+
[](https://python.org)
|
|
53
|
+

|
|
54
|
+

|
|
55
|
+

|
|
56
|
+
[](https://github.com/Neuri-AI/PSX/actions/workflows/publish-to-pypi.yml)
|
|
57
|
+

|
|
58
|
+

|
|
59
|
+
[](LICENSE)
|
|
60
|
+
[](https://buymeacoffee.com/neuri)
|
|
61
|
+
|
|
62
|
+
## Why PSX?
|
|
63
|
+
|
|
64
|
+
Python already has excellent native UI frameworks. PSX doesn't replace them—it provides a common interface-building layer on top of their rendering capabilities.
|
|
65
|
+
|
|
66
|
+
- **PSX Markup** — Define interfaces using elements, attributes, expressions, conditionals, loops, and reusable components.
|
|
67
|
+
- **Native rendering** — Render actual widgets using PySide6, PyQt6, PyQt5, PySide2, Tkinter, or Kivy where supported.
|
|
68
|
+
- **CSS-like styling** — Apply styles using selectors, classes, inheritance, and a supported subset of CSS properties.
|
|
69
|
+
- **Unified layout** — Use Cinnamon, PSX's integrated layout engine, for consistent geometry calculations.
|
|
70
|
+
- **Reactive components** — Manage local state, effects, and references through hooks.
|
|
71
|
+
- **Efficient updates** — Reconcile virtual nodes, preserve compatible widget identities, and update affected interface regions.
|
|
72
|
+
- **Native interoperability** — Integrate framework-specific widgets and third-party libraries.
|
|
73
|
+
- **Extensible architecture** — Register components, native adapters, and plugins.
|
|
74
|
+
|
|
75
|
+
## Getting Started
|
|
76
|
+
|
|
77
|
+
### Requirements
|
|
78
|
+
|
|
79
|
+
- Python 3.10–3.13
|
|
80
|
+
- A supported native UI toolkit
|
|
81
|
+
- Windows, macOS, or Linux, subject to backend compatibility
|
|
82
|
+
|
|
83
|
+
### Installation
|
|
84
|
+
|
|
85
|
+
Install PSX from a local checkout with your preferred backend:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/Neuri-AI/PSX.git
|
|
89
|
+
cd PSX
|
|
90
|
+
|
|
91
|
+
# PySide6
|
|
92
|
+
python -m pip install -e ".[pyside6]"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Other available backend extras include `pyqt6`, `pyqt5`, `pyside2`, and `kivy`.
|
|
96
|
+
|
|
97
|
+
PySide2 has additional Python version restrictions, and Tkinter is normally provided by the Python installation.
|
|
98
|
+
|
|
99
|
+
See the [compatibility documentation](docs/compatibility.md) for supported combinations.
|
|
100
|
+
|
|
101
|
+
### Hello World
|
|
102
|
+
|
|
103
|
+
PSX interfaces are defined using **PSX Markup**:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from psx import psx
|
|
107
|
+
|
|
108
|
+
view = psx("""
|
|
109
|
+
<div>
|
|
110
|
+
<h1>Hello, World!</h1>
|
|
111
|
+
<p>Welcome to PSX.</p>
|
|
112
|
+
<button>Get started</button>
|
|
113
|
+
</div>
|
|
114
|
+
""")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The markup is compiled into a tree of virtual nodes (VNodes), which PSX reconciles and sends to a native renderer.
|
|
118
|
+
|
|
119
|
+
This snippet illustrates markup construction. A complete application also requires an application lifecycle and a compatible renderer.
|
|
120
|
+
|
|
121
|
+
### Reactive Components
|
|
122
|
+
|
|
123
|
+
PSX components can use hooks to manage state and update their interfaces.
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from psx import component, psx, use_state
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@component
|
|
130
|
+
def Counter():
|
|
131
|
+
count, set_count = use_state(0)
|
|
132
|
+
|
|
133
|
+
def increment():
|
|
134
|
+
set_count(lambda current: current + 1)
|
|
135
|
+
|
|
136
|
+
return psx("""
|
|
137
|
+
<div>
|
|
138
|
+
<h2>Counter</h2>
|
|
139
|
+
<p>Count: {count}</p>
|
|
140
|
+
<button on_click={increment}>
|
|
141
|
+
Increment
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
""")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
When state changes, PSX reconciles the updated interface instead of recreating the entire native widget tree.
|
|
148
|
+
|
|
149
|
+
PSX resolves references to local variables and callbacks through its lexical source transformation system.
|
|
150
|
+
|
|
151
|
+
## PSX Markup
|
|
152
|
+
|
|
153
|
+
**PSX Markup is the interface authoring language of PSX.**
|
|
154
|
+
|
|
155
|
+
All interfaces are defined through PSX Markup, which provides a unified syntax for HTML-like elements, built-in components, native widgets, and custom components.
|
|
156
|
+
|
|
157
|
+
It supports expressions, conditional rendering, iterations, component composition, and reactive state integration.
|
|
158
|
+
|
|
159
|
+
### HTML-like Elements
|
|
160
|
+
|
|
161
|
+
HTML-like elements provide familiar syntax for building native interfaces.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from psx import psx
|
|
165
|
+
|
|
166
|
+
view = psx("""
|
|
167
|
+
<div class="profile">
|
|
168
|
+
<h2>Profile</h2>
|
|
169
|
+
<p>Manage your account.</p>
|
|
170
|
+
<input placeholder="Your name" />
|
|
171
|
+
<button>Save changes</button>
|
|
172
|
+
</div>
|
|
173
|
+
""")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
These elements participate in PSX's component, styling, layout, reconciliation, and native rendering systems.
|
|
177
|
+
|
|
178
|
+
### Built-in Components
|
|
179
|
+
|
|
180
|
+
PSX provides built-in components such as `Flex`, `Grid`, `GridItem`, `Scroll`, and `Native` for organizing layouts, managing scrollable content, and integrating native widgets.
|
|
181
|
+
|
|
182
|
+
These components are used directly within PSX Markup:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from psx import psx
|
|
186
|
+
|
|
187
|
+
view = psx("""
|
|
188
|
+
<Flex direction="column" gap="16">
|
|
189
|
+
<h2>Dashboard</h2>
|
|
190
|
+
|
|
191
|
+
<Grid columns="2" gap="12">
|
|
192
|
+
<GridItem>
|
|
193
|
+
<p>Overview</p>
|
|
194
|
+
</GridItem>
|
|
195
|
+
|
|
196
|
+
<GridItem>
|
|
197
|
+
<p>Statistics</p>
|
|
198
|
+
</GridItem>
|
|
199
|
+
</Grid>
|
|
200
|
+
</Flex>
|
|
201
|
+
""")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Built-in components and HTML-like elements are part of the same markup system, sharing PSX's reconciliation, styling, layout, and native rendering infrastructure.
|
|
205
|
+
|
|
206
|
+
### Third-party Native Widgets
|
|
207
|
+
|
|
208
|
+
The `Native` component enables the integration of toolkit-specific widgets and third-party libraries directly into PSX Markup.
|
|
209
|
+
|
|
210
|
+
For example, a PyQtGraph chart can be embedded in a Qt-based interface:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
import numpy as np
|
|
214
|
+
import pyqtgraph as pg
|
|
215
|
+
|
|
216
|
+
from psx import psx
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class SineChart(pg.PlotWidget):
|
|
220
|
+
def __init__(self):
|
|
221
|
+
super().__init__()
|
|
222
|
+
|
|
223
|
+
x = np.linspace(0, 10, 1000)
|
|
224
|
+
|
|
225
|
+
self.setBackground("#151515")
|
|
226
|
+
self.setTitle("Sine Wave")
|
|
227
|
+
self.showGrid(x=True, y=True)
|
|
228
|
+
self.plot(
|
|
229
|
+
x,
|
|
230
|
+
np.sin(x),
|
|
231
|
+
pen=pg.mkPen("#8B5CF6", width=2),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
view = psx("""
|
|
236
|
+
<Flex direction="column" gap="16">
|
|
237
|
+
<h2>Signal Visualization</h2>
|
|
238
|
+
<Native widget={SineChart} />
|
|
239
|
+
</Flex>
|
|
240
|
+
""")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The example illustrates third-party widget integration using the Qt backend. The exact `Native` widget-binding attribute should be checked against the installed PSX version.
|
|
244
|
+
|
|
245
|
+
Native widgets retain their toolkit-specific functionality and compatibility requirements.
|
|
246
|
+
|
|
247
|
+
## CSS and Layout
|
|
248
|
+
|
|
249
|
+
PSX includes a CSS-like styling system connected to its universal box model and Cinnamon layout engine.
|
|
250
|
+
|
|
251
|
+
Its supported styling capabilities include:
|
|
252
|
+
|
|
253
|
+
- Stylesheets, selectors, classes, IDs, specificity, cascade, and inheritance.
|
|
254
|
+
- Dimensions, spacing, borders, and supported sizing constraints.
|
|
255
|
+
- Foreground colors, semantic backgrounds, and native typography.
|
|
256
|
+
- Supported Flex, Grid, Block, and Inline layout behavior.
|
|
257
|
+
- Incremental layout and measurement invalidation.
|
|
258
|
+
|
|
259
|
+
Native visual support varies by property, component, and renderer.
|
|
260
|
+
|
|
261
|
+
PSX does not claim complete browser CSS compatibility.
|
|
262
|
+
|
|
263
|
+
## Architecture Overview
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
PSX Markup
|
|
267
|
+
|
|
|
268
|
+
v
|
|
269
|
+
Markup Compiler
|
|
270
|
+
|
|
|
271
|
+
v
|
|
272
|
+
Virtual Nodes
|
|
273
|
+
|
|
|
274
|
+
v
|
|
275
|
+
Reconciler
|
|
276
|
+
|
|
|
277
|
+
+---------+---------+
|
|
278
|
+
| |
|
|
279
|
+
v v
|
|
280
|
+
CSS & Styles Hooks & State
|
|
281
|
+
| |
|
|
282
|
+
+---------+---------+
|
|
283
|
+
|
|
|
284
|
+
v
|
|
285
|
+
Cinnamon Layout
|
|
286
|
+
|
|
|
287
|
+
v
|
|
288
|
+
Native Renderers
|
|
289
|
+
|
|
|
290
|
+
+-----------+-----------+
|
|
291
|
+
| | |
|
|
292
|
+
v v v
|
|
293
|
+
Qt Tkinter Kivy
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
PSX manages the interface representation, reconciliation, supported style resolution, and layout coordination.
|
|
297
|
+
|
|
298
|
+
Native renderers translate the resulting operations into real toolkit widgets, while Cinnamon remains the shared layout authority for the geometry it manages.
|
|
299
|
+
|
|
300
|
+
The diagram is a conceptual overview; actual rendering and update operations interact through the reconciler and renderer lifecycle.
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
## 🤝 Contributing
|
|
304
|
+
|
|
305
|
+
Contributions to `PSX` are welcome.
|
|
306
|
+
|
|
307
|
+
1. Fork the repository on GitHub.
|
|
308
|
+
2. Create a feature branch:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
git checkout -b feature/amazing-feature
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
3. Run the test suite:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
poetry run pytest
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
4. Commit your changes:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
git commit -m "feat: add amazing feature"
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
5. Push your branch:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
git push origin feature/amazing-feature
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
6. Open a pull request.
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
PSX is released under the MIT License.
|
|
337
|
+
|
|
338
|
+
See [LICENSE](LICENSE) for details.
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
For the new explicit `props` mapping, use `update_props(props, changed)` on your
|
|
342
|
+
widget or register `@native_adapter`. See [Native reactive props](docs/native-reactive-props.md).
|
|
343
|
+
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# PSX
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Build native Python interfaces using **PSX Markup**, CSS-like styling, reusable components, and a unified cross-platform rendering system.
|
|
5
|
+
|
|
6
|
+
PSX is the UI foundation of **Velto**. It provides a unified interface authoring language with familiar HTML-like syntax, reactive components, and native widget integration, rendering actual native widgets through **Qt, Tkinter, and Kivy**.
|
|
7
|
+
|
|
8
|
+
**No browser. No embedded web engine. Native interfaces powered by Python.**
|
|
9
|
+
|
|
10
|
+
> **Project status:** PSX is currently in alpha development. Features and APIs may change as the project evolves.
|
|
11
|
+
|
|
12
|
+
[](https://python.org)
|
|
13
|
+

|
|
14
|
+

|
|
15
|
+

|
|
16
|
+
[](https://github.com/Neuri-AI/PSX/actions/workflows/publish-to-pypi.yml)
|
|
17
|
+

|
|
18
|
+

|
|
19
|
+
[](LICENSE)
|
|
20
|
+
[](https://buymeacoffee.com/neuri)
|
|
21
|
+
|
|
22
|
+
## Why PSX?
|
|
23
|
+
|
|
24
|
+
Python already has excellent native UI frameworks. PSX doesn't replace them—it provides a common interface-building layer on top of their rendering capabilities.
|
|
25
|
+
|
|
26
|
+
- **PSX Markup** — Define interfaces using elements, attributes, expressions, conditionals, loops, and reusable components.
|
|
27
|
+
- **Native rendering** — Render actual widgets using PySide6, PyQt6, PyQt5, PySide2, Tkinter, or Kivy where supported.
|
|
28
|
+
- **CSS-like styling** — Apply styles using selectors, classes, inheritance, and a supported subset of CSS properties.
|
|
29
|
+
- **Unified layout** — Use Cinnamon, PSX's integrated layout engine, for consistent geometry calculations.
|
|
30
|
+
- **Reactive components** — Manage local state, effects, and references through hooks.
|
|
31
|
+
- **Efficient updates** — Reconcile virtual nodes, preserve compatible widget identities, and update affected interface regions.
|
|
32
|
+
- **Native interoperability** — Integrate framework-specific widgets and third-party libraries.
|
|
33
|
+
- **Extensible architecture** — Register components, native adapters, and plugins.
|
|
34
|
+
|
|
35
|
+
## Getting Started
|
|
36
|
+
|
|
37
|
+
### Requirements
|
|
38
|
+
|
|
39
|
+
- Python 3.10–3.13
|
|
40
|
+
- A supported native UI toolkit
|
|
41
|
+
- Windows, macOS, or Linux, subject to backend compatibility
|
|
42
|
+
|
|
43
|
+
### Installation
|
|
44
|
+
|
|
45
|
+
Install PSX from a local checkout with your preferred backend:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/Neuri-AI/PSX.git
|
|
49
|
+
cd PSX
|
|
50
|
+
|
|
51
|
+
# PySide6
|
|
52
|
+
python -m pip install -e ".[pyside6]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Other available backend extras include `pyqt6`, `pyqt5`, `pyside2`, and `kivy`.
|
|
56
|
+
|
|
57
|
+
PySide2 has additional Python version restrictions, and Tkinter is normally provided by the Python installation.
|
|
58
|
+
|
|
59
|
+
See the [compatibility documentation](docs/compatibility.md) for supported combinations.
|
|
60
|
+
|
|
61
|
+
### Hello World
|
|
62
|
+
|
|
63
|
+
PSX interfaces are defined using **PSX Markup**:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from psx import psx
|
|
67
|
+
|
|
68
|
+
view = psx("""
|
|
69
|
+
<div>
|
|
70
|
+
<h1>Hello, World!</h1>
|
|
71
|
+
<p>Welcome to PSX.</p>
|
|
72
|
+
<button>Get started</button>
|
|
73
|
+
</div>
|
|
74
|
+
""")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The markup is compiled into a tree of virtual nodes (VNodes), which PSX reconciles and sends to a native renderer.
|
|
78
|
+
|
|
79
|
+
This snippet illustrates markup construction. A complete application also requires an application lifecycle and a compatible renderer.
|
|
80
|
+
|
|
81
|
+
### Reactive Components
|
|
82
|
+
|
|
83
|
+
PSX components can use hooks to manage state and update their interfaces.
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from psx import component, psx, use_state
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@component
|
|
90
|
+
def Counter():
|
|
91
|
+
count, set_count = use_state(0)
|
|
92
|
+
|
|
93
|
+
def increment():
|
|
94
|
+
set_count(lambda current: current + 1)
|
|
95
|
+
|
|
96
|
+
return psx("""
|
|
97
|
+
<div>
|
|
98
|
+
<h2>Counter</h2>
|
|
99
|
+
<p>Count: {count}</p>
|
|
100
|
+
<button on_click={increment}>
|
|
101
|
+
Increment
|
|
102
|
+
</button>
|
|
103
|
+
</div>
|
|
104
|
+
""")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When state changes, PSX reconciles the updated interface instead of recreating the entire native widget tree.
|
|
108
|
+
|
|
109
|
+
PSX resolves references to local variables and callbacks through its lexical source transformation system.
|
|
110
|
+
|
|
111
|
+
## PSX Markup
|
|
112
|
+
|
|
113
|
+
**PSX Markup is the interface authoring language of PSX.**
|
|
114
|
+
|
|
115
|
+
All interfaces are defined through PSX Markup, which provides a unified syntax for HTML-like elements, built-in components, native widgets, and custom components.
|
|
116
|
+
|
|
117
|
+
It supports expressions, conditional rendering, iterations, component composition, and reactive state integration.
|
|
118
|
+
|
|
119
|
+
### HTML-like Elements
|
|
120
|
+
|
|
121
|
+
HTML-like elements provide familiar syntax for building native interfaces.
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from psx import psx
|
|
125
|
+
|
|
126
|
+
view = psx("""
|
|
127
|
+
<div class="profile">
|
|
128
|
+
<h2>Profile</h2>
|
|
129
|
+
<p>Manage your account.</p>
|
|
130
|
+
<input placeholder="Your name" />
|
|
131
|
+
<button>Save changes</button>
|
|
132
|
+
</div>
|
|
133
|
+
""")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
These elements participate in PSX's component, styling, layout, reconciliation, and native rendering systems.
|
|
137
|
+
|
|
138
|
+
### Built-in Components
|
|
139
|
+
|
|
140
|
+
PSX provides built-in components such as `Flex`, `Grid`, `GridItem`, `Scroll`, and `Native` for organizing layouts, managing scrollable content, and integrating native widgets.
|
|
141
|
+
|
|
142
|
+
These components are used directly within PSX Markup:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from psx import psx
|
|
146
|
+
|
|
147
|
+
view = psx("""
|
|
148
|
+
<Flex direction="column" gap="16">
|
|
149
|
+
<h2>Dashboard</h2>
|
|
150
|
+
|
|
151
|
+
<Grid columns="2" gap="12">
|
|
152
|
+
<GridItem>
|
|
153
|
+
<p>Overview</p>
|
|
154
|
+
</GridItem>
|
|
155
|
+
|
|
156
|
+
<GridItem>
|
|
157
|
+
<p>Statistics</p>
|
|
158
|
+
</GridItem>
|
|
159
|
+
</Grid>
|
|
160
|
+
</Flex>
|
|
161
|
+
""")
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Built-in components and HTML-like elements are part of the same markup system, sharing PSX's reconciliation, styling, layout, and native rendering infrastructure.
|
|
165
|
+
|
|
166
|
+
### Third-party Native Widgets
|
|
167
|
+
|
|
168
|
+
The `Native` component enables the integration of toolkit-specific widgets and third-party libraries directly into PSX Markup.
|
|
169
|
+
|
|
170
|
+
For example, a PyQtGraph chart can be embedded in a Qt-based interface:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
import numpy as np
|
|
174
|
+
import pyqtgraph as pg
|
|
175
|
+
|
|
176
|
+
from psx import psx
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class SineChart(pg.PlotWidget):
|
|
180
|
+
def __init__(self):
|
|
181
|
+
super().__init__()
|
|
182
|
+
|
|
183
|
+
x = np.linspace(0, 10, 1000)
|
|
184
|
+
|
|
185
|
+
self.setBackground("#151515")
|
|
186
|
+
self.setTitle("Sine Wave")
|
|
187
|
+
self.showGrid(x=True, y=True)
|
|
188
|
+
self.plot(
|
|
189
|
+
x,
|
|
190
|
+
np.sin(x),
|
|
191
|
+
pen=pg.mkPen("#8B5CF6", width=2),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
view = psx("""
|
|
196
|
+
<Flex direction="column" gap="16">
|
|
197
|
+
<h2>Signal Visualization</h2>
|
|
198
|
+
<Native widget={SineChart} />
|
|
199
|
+
</Flex>
|
|
200
|
+
""")
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The example illustrates third-party widget integration using the Qt backend. The exact `Native` widget-binding attribute should be checked against the installed PSX version.
|
|
204
|
+
|
|
205
|
+
Native widgets retain their toolkit-specific functionality and compatibility requirements.
|
|
206
|
+
|
|
207
|
+
## CSS and Layout
|
|
208
|
+
|
|
209
|
+
PSX includes a CSS-like styling system connected to its universal box model and Cinnamon layout engine.
|
|
210
|
+
|
|
211
|
+
Its supported styling capabilities include:
|
|
212
|
+
|
|
213
|
+
- Stylesheets, selectors, classes, IDs, specificity, cascade, and inheritance.
|
|
214
|
+
- Dimensions, spacing, borders, and supported sizing constraints.
|
|
215
|
+
- Foreground colors, semantic backgrounds, and native typography.
|
|
216
|
+
- Supported Flex, Grid, Block, and Inline layout behavior.
|
|
217
|
+
- Incremental layout and measurement invalidation.
|
|
218
|
+
|
|
219
|
+
Native visual support varies by property, component, and renderer.
|
|
220
|
+
|
|
221
|
+
PSX does not claim complete browser CSS compatibility.
|
|
222
|
+
|
|
223
|
+
## Architecture Overview
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
PSX Markup
|
|
227
|
+
|
|
|
228
|
+
v
|
|
229
|
+
Markup Compiler
|
|
230
|
+
|
|
|
231
|
+
v
|
|
232
|
+
Virtual Nodes
|
|
233
|
+
|
|
|
234
|
+
v
|
|
235
|
+
Reconciler
|
|
236
|
+
|
|
|
237
|
+
+---------+---------+
|
|
238
|
+
| |
|
|
239
|
+
v v
|
|
240
|
+
CSS & Styles Hooks & State
|
|
241
|
+
| |
|
|
242
|
+
+---------+---------+
|
|
243
|
+
|
|
|
244
|
+
v
|
|
245
|
+
Cinnamon Layout
|
|
246
|
+
|
|
|
247
|
+
v
|
|
248
|
+
Native Renderers
|
|
249
|
+
|
|
|
250
|
+
+-----------+-----------+
|
|
251
|
+
| | |
|
|
252
|
+
v v v
|
|
253
|
+
Qt Tkinter Kivy
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
PSX manages the interface representation, reconciliation, supported style resolution, and layout coordination.
|
|
257
|
+
|
|
258
|
+
Native renderers translate the resulting operations into real toolkit widgets, while Cinnamon remains the shared layout authority for the geometry it manages.
|
|
259
|
+
|
|
260
|
+
The diagram is a conceptual overview; actual rendering and update operations interact through the reconciler and renderer lifecycle.
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
## 🤝 Contributing
|
|
264
|
+
|
|
265
|
+
Contributions to `PSX` are welcome.
|
|
266
|
+
|
|
267
|
+
1. Fork the repository on GitHub.
|
|
268
|
+
2. Create a feature branch:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
git checkout -b feature/amazing-feature
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
3. Run the test suite:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
poetry run pytest
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
4. Commit your changes:
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
git commit -m "feat: add amazing feature"
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
5. Push your branch:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
git push origin feature/amazing-feature
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
6. Open a pull request.
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
PSX is released under the MIT License.
|
|
297
|
+
|
|
298
|
+
See [LICENSE](LICENSE) for details.
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
For the new explicit `props` mapping, use `update_props(props, changed)` on your
|
|
302
|
+
widget or register `@native_adapter`. See [Native reactive props](docs/native-reactive-props.md).
|