From 5d089bc557813a5624e6d3e6bac6c9e9777bd0ff Mon Sep 17 00:00:00 2001 From: Shubham Patel <165564832+shubham0x13@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:49:05 +0530 Subject: [PATCH 1/4] Add anchor method --- adafruit_displayio_layout/layouts/__init__.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/adafruit_displayio_layout/layouts/__init__.py b/adafruit_displayio_layout/layouts/__init__.py index e69de29..7d9f684 100644 --- a/adafruit_displayio_layout/layouts/__init__.py +++ b/adafruit_displayio_layout/layouts/__init__.py @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: 2025 Shubham Patel +# +# SPDX-License-Identifier: MIT + +from micropython import const + +try: + from typing import Tuple +except ImportError: + pass + +# Anchor point constants for anchor method. +ANCHOR_TOP_LEFT = const((0.0, 0.0)) +ANCHOR_TOP_CENTER = const((0.5, 0.0)) +ANCHOR_TOP_RIGHT = const((1.0, 0.0)) +ANCHOR_CENTER_LEFT = const((0.0, 0.5)) +ANCHOR_CENTER = const((0.5, 0.5)) +ANCHOR_CENTER_RIGHT = const((1.0, 0.5)) +ANCHOR_BOTTOM_LEFT = const((0.0, 1.0)) +ANCHOR_BOTTOM_CENTER = const((0.5, 1.0)) +ANCHOR_BOTTOM_RIGHT = const((1.0, 1.0)) + + +def anchor(obj, anchor: Tuple[float, float], width: int, height: int) -> None: + """Helper to position a display object on screen using a defined anchor point. + + Sets `anchor_point` and `anchored_position` for display elements such as `Label`, + `Widget`, `AnchoredTileGrid`, or `AnchoredGroup`. + + :param obj: The object to be positioned. Must support `anchor_point` and `anchored_position`. + :param anchor: One of the predefined anchor constants (e.g. ANCHOR_TOP_LEFT, ANCHOR_CENTER) + :param width: Width of the display in pixels + :param height: Height of the display in pixels + """ + if not hasattr(obj, "anchor_point") or not hasattr(obj, "anchored_position"): + raise AttributeError( + "Object must have both `anchor_point` and `anchored_position` attributes." + ) + + if anchor not in { + ANCHOR_TOP_LEFT, + ANCHOR_TOP_CENTER, + ANCHOR_TOP_RIGHT, + ANCHOR_CENTER_LEFT, + ANCHOR_CENTER, + ANCHOR_CENTER_RIGHT, + ANCHOR_BOTTOM_LEFT, + ANCHOR_BOTTOM_CENTER, + ANCHOR_BOTTOM_RIGHT, + }: + raise ValueError( + "Anchor must be one of: ANCHOR_TOP_LEFT, ANCHOR_TOP_CENTER, ANCHOR_TOP_RIGHT,\n" + "ANCHOR_CENTER_LEFT, ANCHOR_CENTER, ANCHOR_CENTER_RIGHT,\n" + "ANCHOR_BOTTOM_LEFT, ANCHOR_BOTTOM_CENTER, ANCHOR_BOTTOM_RIGHT." + ) + + obj.anchor_point = anchor + obj.anchored_position = ( + int(anchor[0] * width), + int(anchor[1] * height), + ) From cfb3f13e9fffb3e2c28a04eb633f2f53608750f3 Mon Sep 17 00:00:00 2001 From: Shubham Patel <165564832+shubham0x13@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:16:35 +0530 Subject: [PATCH 2/4] Add bounds check in add_content --- adafruit_displayio_layout/layouts/grid_layout.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index 957cb91..15cfd09 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -378,6 +378,15 @@ def add_content( then the cell_anchor_point from the GridLayout will be used. :return: None""" + grid_x = grid_position[0] + grid_y = grid_position[1] + max_grid_x = self.grid_size[0] + max_grid_y = self.grid_size[1] + if grid_x >= max_grid_x or grid_y >= max_grid_y: + raise ValueError( + f"Grid position {grid_position} is out of bounds for grid size {self.grid_size}" + ) + if cell_anchor_point: _this_cell_anchor_point = cell_anchor_point else: From 74411706db2f863ced498925409b4060a99492c2 Mon Sep 17 00:00:00 2001 From: Shubham Patel <165564832+shubham0x13@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:23:46 +0530 Subject: [PATCH 3/4] Simplify grid bounds unpacking --- adafruit_displayio_layout/layouts/grid_layout.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index 15cfd09..b57bd16 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -378,10 +378,8 @@ def add_content( then the cell_anchor_point from the GridLayout will be used. :return: None""" - grid_x = grid_position[0] - grid_y = grid_position[1] - max_grid_x = self.grid_size[0] - max_grid_y = self.grid_size[1] + grid_x, grid_y = grid_position + max_grid_x, max_grid_y = self.grid_size if grid_x >= max_grid_x or grid_y >= max_grid_y: raise ValueError( f"Grid position {grid_position} is out of bounds for grid size {self.grid_size}" From 7eac6b8038cae2a7252b1e78539f6b0a674773d4 Mon Sep 17 00:00:00 2001 From: Shubham Patel <165564832+shubham0x13@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:53:57 +0530 Subject: [PATCH 4/4] Update example --- .../displayio_layout_grid_layout_get_cell_test.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/displayio_layout_grid_layout_get_cell_test.py b/examples/displayio_layout_grid_layout_get_cell_test.py index 06ccfd0..66d856a 100644 --- a/examples/displayio_layout_grid_layout_get_cell_test.py +++ b/examples/displayio_layout_grid_layout_get_cell_test.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MIT """ Make green and purple rectangles and then update the color -and text values of the labels using the get_cell() function. +and text values of the labels using the get_content() function. """ import board @@ -47,14 +47,14 @@ main_group.append(layout) -layout.get_cell((0, 0)).text = "Happy" -layout.get_cell((1, 0)).text = "Circuit" +layout.get_content((0, 0)).text = "Happy" +layout.get_content((1, 0)).text = "Circuit" -layout.get_cell((0, 1)).text = "Python" -layout.get_cell((1, 1)).text = "Day" +layout.get_content((0, 1)).text = "Python" +layout.get_content((1, 1)).text = "Day" -layout.get_cell((0, 1)).background_color = 0x007700 -layout.get_cell((1, 1)).background_color = 0x770077 +layout.get_content((0, 1)).background_color = 0x007700 +layout.get_content((1, 1)).background_color = 0x770077 while True: pass