From 53b190e3f836516250dc5e1e33cda01a45efa181 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 16 Dec 2023 11:47:03 -0600 Subject: [PATCH 1/5] GridLayout cell contains --- .../layouts/grid_layout.py | 49 +++++++++++++++++++ docs/conf.py | 1 + 2 files changed, 50 insertions(+) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index df87eae..eee392d 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -406,9 +406,21 @@ def get_cell(self, cell_coordinates: Tuple[int, int]) -> displayio.Group: :return: the displayio content object at those coordinates """ for index, cell in enumerate(self._cell_content_list): + # exact location 1x1 cell if cell["grid_position"] == cell_coordinates: return self._cell_content_list[index]["content"] + # multi-spanning cell, any size bigger than 1x1 + if ( + cell["grid_position"][0] + <= cell_coordinates[0] + < cell["grid_position"][0] + cell["cell_size"][0] + and cell["grid_position"][1] + <= cell_coordinates[1] + < cell["grid_position"][1] + cell["cell_size"][1] + ): + return self._cell_content_list[index]["content"] + raise KeyError( "GridLayout does not contain cell at coordinates {}".format( cell_coordinates @@ -425,3 +437,40 @@ def cell_size_pixels(self) -> Tuple[int, int]: pixels of a 1x1 cell in the GridLayout """ return (self._width // self.grid_size[0], self._height // self.grid_size[1]) + + @property + def width(self) -> int: + """ + The width in pixels of the GridLayout. + """ + return self._width + + @property + def height(self) -> int: + """ + The width in pixels of the GridLayout. + """ + return self._height + + def which_cell_contains( + self, pixel_location: Union[Tuple[int, int], List[int]] + ) -> Optional[tuple]: + """ + Given a pixel x,y coordinate returns the location of the cell + that contains the coordinate. + + :param pixel_location: x,y pixel coordinate as a tuple or list + :returns: cell coordinates x,y tuple or None if the pixel coordinates are + outside the bounds of the GridLayout + """ + cell_size = self.cell_size_pixels + if ( + not self.x <= pixel_location[0] < self.x + self.width + or not self.y <= pixel_location[1] < self.y + self.height + ): + return None + + cell_x_coord = (pixel_location[0] - self.x) // cell_size[0] + cell_y_coord = (pixel_location[1] - self.y) // cell_size[1] + + return cell_x_coord, cell_y_coord diff --git a/docs/conf.py b/docs/conf.py index 964e471..3d12838 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,6 +32,7 @@ # autodoc module docs will fail to generate with a warning. autodoc_mock_imports = [ "vectorio", + "terminalio", "bitmaptools", ] From 4b0f993ff57eb0c04e67ae49e8fb6d7efe595696 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sat, 16 Dec 2023 11:51:22 -0600 Subject: [PATCH 2/5] fix docstring --- adafruit_displayio_layout/layouts/grid_layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index eee392d..b57ad24 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -448,7 +448,7 @@ def width(self) -> int: @property def height(self) -> int: """ - The width in pixels of the GridLayout. + The height in pixels of the GridLayout. """ return self._height From 873672f83bcb1e60ab7cbf8ac1b8d9f149bc9a28 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 26 Dec 2023 15:07:16 -0600 Subject: [PATCH 3/5] public layout_content. Don't add and remove lines many times unecessarily. --- .../layouts/grid_layout.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index b57ad24..d43608a 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -111,8 +111,13 @@ def __init__( ): self.cell_padding = 1 + def layout_cells(self): + self._layout_cells() + def _layout_cells(self) -> None: # pylint: disable=too-many-locals, too-many-branches, too-many-statements + for line_obj in self._divider_lines: + self.remove(line_obj["rect"]) for cell in self._cell_content_list: if cell["content"] not in self: grid_size_x = self.grid_size[0] @@ -359,15 +364,16 @@ def _layout_cells(self) -> None: } ) - for line_obj in self._divider_lines: - self.append(line_obj["rect"]) + for line_obj in self._divider_lines: + self.append(line_obj["rect"]) def add_content( - self, - cell_content: displayio.Group, - grid_position: Tuple[int, int], - cell_size: Tuple[int, int], - cell_anchor_point: Optional[Tuple[float, ...]] = None, + self, + cell_content: displayio.Group, + grid_position: Tuple[int, int], + cell_size: Tuple[int, int], + cell_anchor_point: Optional[Tuple[float, ...]] = None, + layout_cells=True ) -> None: """Add a child to the grid. @@ -395,7 +401,8 @@ def add_content( "cell_size": cell_size, } self._cell_content_list.append(sub_view_obj) - self._layout_cells() + if layout_cells: + self._layout_cells() def get_cell(self, cell_coordinates: Tuple[int, int]) -> displayio.Group: """ From 67f8bc959090076bc53b427745b5426bc452d6fd Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 26 Dec 2023 17:48:35 -0600 Subject: [PATCH 4/5] public layout_content. Don't add and remove lines many times unecessarily. --- adafruit_displayio_layout/layouts/grid_layout.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index b57ad24..27dc5db 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -111,8 +111,14 @@ def __init__( ): self.cell_padding = 1 + def layout_cells(self): + """render the grid with all cell content and dividers""" + self._layout_cells() + def _layout_cells(self) -> None: # pylint: disable=too-many-locals, too-many-branches, too-many-statements + for line_obj in self._divider_lines: + self.remove(line_obj["rect"]) for cell in self._cell_content_list: if cell["content"] not in self: grid_size_x = self.grid_size[0] @@ -359,8 +365,8 @@ def _layout_cells(self) -> None: } ) - for line_obj in self._divider_lines: - self.append(line_obj["rect"]) + for line_obj in self._divider_lines: + self.append(line_obj["rect"]) def add_content( self, @@ -368,6 +374,7 @@ def add_content( grid_position: Tuple[int, int], cell_size: Tuple[int, int], cell_anchor_point: Optional[Tuple[float, ...]] = None, + layout_cells=True, ) -> None: """Add a child to the grid. @@ -395,7 +402,8 @@ def add_content( "cell_size": cell_size, } self._cell_content_list.append(sub_view_obj) - self._layout_cells() + if layout_cells: + self._layout_cells() def get_cell(self, cell_coordinates: Tuple[int, int]) -> displayio.Group: """ From baeccd1eed05556d690d5e5eed5a346ee8346c30 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 16 Jan 2024 15:46:40 -0600 Subject: [PATCH 5/5] fix extra divider line removal --- adafruit_displayio_layout/layouts/grid_layout.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/adafruit_displayio_layout/layouts/grid_layout.py b/adafruit_displayio_layout/layouts/grid_layout.py index 27dc5db..fd06895 100644 --- a/adafruit_displayio_layout/layouts/grid_layout.py +++ b/adafruit_displayio_layout/layouts/grid_layout.py @@ -303,9 +303,6 @@ def _layout_cells(self) -> None: x=_right_line_loc_x, ) - for line_obj in self._divider_lines: - self.remove(line_obj["rect"]) - """ Only use bottom divider lines on the bottom row. All other rows rely on top divder lines of the row beneath them.