diff --git a/README.md b/README.md index bad3888..339b05e 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,7 @@ Each button can take the following configuration | `text` | ✅ | The text to display on the button. If empty, no text is displayed. You might want to add `\n` characters to spread the text over several lines, or use the `\|` character in YAML to create a multi-line string. | | `str` | | `text_color` | ✅ | Color of the text. If empty, the color is `white`, unless an `entity_id` is specified, in which case the color is `amber` when the state is `on`, and `white` when it is `off`. | | `Optional[str]` | | `text_size` | ❌ | Integer size of the text. | `12` | `int` | +| `text_offset` | ❌ | The text's position can be moved up or down from the center of the button, and this movement is measured in pixels. The value can be positive (for upward movement) or negative (for downward movement). | | `int` | | `icon` | ✅ | The icon filename to display on the button. Make the path absolute (e.g., `/config/streamdeck/my_icon.png`) or relative to the `assets` directory (e.g., `my_icon.png`). If empty, a icon with `icon_background_color` and `text` is displayed. The icon can be a URL to an image, like `'url:https://www.nijho.lt/authors/admin/avatar.jpg'`, or a `spotify:` icon, like `'spotify:album/6gnYcXVaffdG0vwVM34cr8'`. If the icon is a `spotify:` icon, the icon will be downloaded and cached. The icon can also display a partially complete ring, like a progress bar, or sensor value, like `ring:25` for a 25% complete ring. | | `Optional[str]` | | `icon_mdi` | ✅ | The Material Design Icon to display on the button. If empty, no icon is displayed. See https://mdi.bessarabov.com/ for a list of icons. The SVG icon will be downloaded and cached. | | `Optional[str]` | | `icon_background_color` | ✅ | A color (in hex format, e.g., '#FF0000') for the background of the icon (if no `icon` is specified). | `#000000` | `str` | diff --git a/home_assistant_streamdeck_yaml.py b/home_assistant_streamdeck_yaml.py index d196175..42f14fc 100755 --- a/home_assistant_streamdeck_yaml.py +++ b/home_assistant_streamdeck_yaml.py @@ -99,6 +99,13 @@ class Button(BaseModel, extra="forbid"): # type: ignore[call-arg] allow_template=False, description="Integer size of the text.", ) + text_offset: int = Field( + default=0, + allow_template=False, + description="The text's position can be moved up or down from the center of" + " the button, and this movement is measured in pixels. The value can be" + " positive (for upward movement) or negative (for downward movement).", + ) icon: str | None = Field( default=None, allow_template=True, @@ -362,11 +369,12 @@ def render_icon( # noqa: PLR0912 PLR0915 image = _convert_to_grayscale(image) _add_text( - image, - font_filename, - self.text_size, - text, + image=image, + font_filename=font_filename, + text_size=self.text_size, + text=text, text_color=text_color if not key_pressed else "green", + text_offset=self.text_offset, ) return image @@ -1291,16 +1299,18 @@ def _init_icon( def _add_text( + *, image: Image.Image, font_filename: str, text_size: int, text: str, text_color: str, + text_offset: int = 0, ) -> None: draw = ImageDraw.Draw(image) font = ImageFont.truetype(str(ASSETS_PATH / font_filename), text_size) draw.text( - (image.width / 2, image.height / 2), + (image.width / 2, image.height / 2 + text_offset), text=text, font=font, anchor="ms", diff --git a/tests/test_app.py b/tests/test_app.py index a1d5aba..11de148 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -121,6 +121,7 @@ def button_dict() -> dict[str, dict[str, Any]]: "script_with_text_and_icon": { "service": "script.turn_off_everything", "text": "ALL OFF", + "text_offset": 4, "icon": "night_sky.png", }, "input_select_with_template": {