Preview¶
preview ¶
Preview SVG designs on a physical Stream Deck device.
Examples:
::
python -m deux.tools.preview \
--card0 my_card.svg --key0 my_key.svg \
--background "#1a2b3c"
# Auto-reload when SVG files change:
python -m deux.tools.preview \
--card0 my_card.svg --key0 my_key.svg --watch
Only the specified slots are updated; unspecified keys and cards are
left blank (black unless --background is given). SVGs are scaled
edge-to-edge to the connected device's native key/panel size — the tool
does not impose any margins, padding, or gaps.
Use --touchstrip to push a single full-width SVG across the entire
touchstrip instead of specifying individual --cardN panels. The
--touchstrip flag is mutually exclusive with --cardN flags.
The tool auto-detects the first connected visual Stream Deck device and adapts key/card counts and dimensions to the hardware.
With --watch, the tool monitors all specified SVG files and
automatically re-renders and re-pushes images when any file changes.
The poll interval can be tuned with --poll-interval (default 0.5s).
PreviewDeckDevice ¶
Bases: Protocol
Protocol for the low-level Stream Deck device used by the preview tool.
Source code in src/deux/tools/preview.py
parse_hex_color ¶
Validate and normalise a hex colour string to #RRGGBB.
Accepts RRGGBB or #RRGGBB (case-insensitive). Raises
:class:argparse.ArgumentTypeError for invalid values so that
argparse can produce a user-friendly error message.
Source code in src/deux/tools/preview.py
load_svg ¶
Load an SVG file and return a PIL Image fitted to max_width x max_height.
The SVG is rasterised at a size that preserves its intrinsic aspect ratio. The result is guaranteed to be at most max_width wide and max_height tall.
Source code in src/deux/tools/preview.py
compose_key_image ¶
Place svg_img edge-to-edge on a key-sized canvas.
The image is centred only when its intrinsic aspect ratio differs from the key — there are no margins or padding around it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
svg_img
|
Image
|
Pre-rasterised SVG image to composite onto the key canvas. |
required |
key_size
|
tuple[int, int]
|
|
required |
background
|
str
|
Canvas fill colour (any PIL-compatible colour string). |
'black'
|
Returns:
| Type | Description |
|---|---|
bytes
|
JPEG-encoded image bytes ready for |
Source code in src/deux/tools/preview.py
compose_card_image ¶
compose_card_image(svg_img: Image, panel_size: tuple[int, int], background: str = 'black') -> Image.Image
Place svg_img edge-to-edge on a panel-sized card canvas.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
svg_img
|
Image
|
Pre-rasterised SVG image to composite onto the card canvas. |
required |
panel_size
|
tuple[int, int]
|
|
required |
background
|
str
|
Canvas fill colour (any PIL-compatible colour string). |
'black'
|
Returns:
| Type | Description |
|---|---|
Image
|
Composited card image at panel_size. |
Source code in src/deux/tools/preview.py
compose_touchstrip ¶
compose_touchstrip(card_images: list[Image | None], *, touchscreen_width: int, touchscreen_height: int, panel_count: int, panel_width: int, background: str = 'black') -> bytes
Compose card images into a single touchscreen JPEG.
Cards are tiled edge-to-edge starting at (i * panel_width, 0).
The background colour shows wherever a slot is None or a
card image leaves pixels uncovered.
Source code in src/deux/tools/preview.py
compose_full_touchstrip ¶
compose_full_touchstrip(svg_img: Image, touchscreen_size: tuple[int, int], background: str = 'black') -> bytes
Place svg_img edge-to-edge on a full touchstrip canvas.
Unlike :func:compose_touchstrip, which tiles individual card
images, this function composites a single SVG image covering the
entire touchstrip area.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
svg_img
|
Image
|
Pre-rasterised SVG image to composite onto the touchstrip canvas. |
required |
touchscreen_size
|
tuple[int, int]
|
|
required |
background
|
str
|
Canvas fill colour (any PIL-compatible colour string). |
"black"
|
Returns:
| Type | Description |
|---|---|
bytes
|
JPEG-encoded image bytes ready for |
Source code in src/deux/tools/preview.py
build_parser ¶
Build the argparse parser for the preview tool.
The parser declares --keyN / --cardN flags up to a generous
upper bound; flags that don't correspond to an actual slot on the
connected device are ignored at render time.
Source code in src/deux/tools/preview.py
parse_args ¶
Parse CLI arguments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
argv
|
list[str] | None
|
Argument list to parse. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
Namespace
|
Parsed arguments with key/card paths, brightness, background, etc. |
Source code in src/deux/tools/preview.py
push_to_device
async
¶
Open the deck, render images for args, and push them.
Sized to the connected device's capabilities — key images are
rendered at caps.key_size and the touchstrip at
caps.touchscreen_width × caps.touchscreen_height.
When args.watch is true the tool polls the referenced SVG files
and re-pushes on change. poll_interval controls how often files
are polled (in seconds).
Source code in src/deux/tools/preview.py
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | |
collect_svg_paths ¶
Return the list of SVG file paths specified in args.
Returns:
| Type | Description |
|---|---|
list[Path]
|
Ordered list of SVG paths (keys first, then cards). |
Source code in src/deux/tools/preview.py
get_mtimes ¶
Return a mapping of paths to their modification times.
Missing files are silently assigned mtime 0.0.
Source code in src/deux/tools/preview.py
render_preview ¶
Render all specified SVGs at caps sizes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
args
|
Namespace
|
Parsed CLI arguments. |
required |
caps
|
DeviceCapabilities
|
Capabilities of the connected device — drives key and panel sizing. |
required |
Returns:
| Type | Description |
|---|---|
tuple[dict[int, bytes], bytes]
|
|
Source code in src/deux/tools/preview.py
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | |
main ¶
Entry point for the preview tool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
argv
|
list[str] | None
|
Argument list to parse. Defaults to |
None
|