Skip to content

Commit 40b1812

Browse files
committed
adding linear_layout
1 parent c544136 commit 40b1812

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2021 Tim Cocks
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
`grid_layout`
6+
================================================================================
7+
8+
A layout that organizes cells into a vertical or horizontal line.
9+
10+
11+
* Author(s): Tim Cocks
12+
13+
Implementation Notes
14+
--------------------
15+
16+
**Hardware:**
17+
18+
**Software and Dependencies:**
19+
20+
* Adafruit CircuitPython firmware for the supported boards:
21+
https://github.com/adafruit/circuitpython/releases
22+
23+
"""
24+
25+
from adafruit_displayio_layout.widgets.widget import Widget
26+
27+
28+
class LinearLayout(Widget):
29+
"""
30+
LinearLayout holds multiple content elements and arranges
31+
them in a line either horizontally or vertically.
32+
"""
33+
34+
VERTICAL_ORIENTATION = 1
35+
HORIZONTAL_ORIENTATION = 2
36+
37+
def __init__(
38+
self,
39+
x,
40+
y,
41+
orientation=VERTICAL_ORIENTATION,
42+
padding=0,
43+
):
44+
"""
45+
:param int x: The horizontal position of the layout
46+
:param int y: The vertical position of the layout
47+
:param int orientation: The orientation of the layout. Must be VERTICAL_ORIENTATION
48+
or HORIZONTAL_ORIENTATION
49+
:param int padding: The padding between items in the layout
50+
"""
51+
52+
super().__init__(x=x, y=y, width=1, height=1)
53+
54+
self.x = x
55+
self.y = y
56+
self.padding = padding
57+
if orientation not in [self.VERTICAL_ORIENTATION, self.HORIZONTAL_ORIENTATION]:
58+
raise ValueError(
59+
"Orientation must be either LinearLayout.VERTICAL_ORIENTATION"
60+
" or LinearLayout.HORIZONTAL_ORIENTATION"
61+
)
62+
63+
self.orientation = orientation
64+
self._content_list = []
65+
self._prev_content_end = 0
66+
67+
def add_content(self, content):
68+
"""Add a child to the linear layout.
69+
70+
:param content: the content to add to the linear layout e.g. label, button, etc...
71+
Group subclasses that have width and height properties can be used.
72+
73+
:return: None"""
74+
75+
self._content_list.append(content)
76+
self.append(content)
77+
self._layout()
78+
79+
def _layout(self):
80+
# pylint: disable=too-many-branches, protected-access
81+
self._prev_content_end = 0
82+
83+
for _, content in enumerate(self._content_list):
84+
if not hasattr(content, "anchor_point"):
85+
if self.orientation == self.VERTICAL_ORIENTATION:
86+
content.y = self._prev_content_end
87+
try:
88+
self._prev_content_end = (
89+
self._prev_content_end + content.height + self.padding
90+
)
91+
except AttributeError as error:
92+
print(error)
93+
try:
94+
self._prev_content_end = (
95+
self._prev_content_end + content._height + self.padding
96+
)
97+
except AttributeError as inner_error:
98+
print(inner_error)
99+
100+
else:
101+
content.x = self._prev_content_end
102+
if not hasattr(content, "tile_width"):
103+
self._prev_content_end = (
104+
content.x + content.width + (self.padding * 2)
105+
)
106+
else:
107+
self._prev_content_end = (
108+
content.x
109+
+ (content.width * content.tile_width)
110+
+ (self.padding * 2)
111+
)
112+
else: # use anchor point
113+
content.anchor_point = (
114+
0,
115+
content.anchor_point[1] if content.anchor_point is not None else 0,
116+
)
117+
if self.orientation == self.VERTICAL_ORIENTATION:
118+
content.anchored_position = (0, self._prev_content_end)
119+
# self._prev_content_end = content.y + content.height
120+
if not hasattr(content, "bounding_box"):
121+
self._prev_content_end = (
122+
self._prev_content_end + content.height + self.padding
123+
)
124+
else:
125+
self._prev_content_end = (
126+
self._prev_content_end
127+
+ (content.bounding_box[3] * content.scale)
128+
+ self.padding
129+
)
130+
131+
else:
132+
original_achored_pos_y = (
133+
content.anchored_position[1]
134+
if content.anchored_position is not None
135+
else 0
136+
)
137+
138+
content.anchored_position = (
139+
self._prev_content_end,
140+
original_achored_pos_y,
141+
)
142+
if not hasattr(content, "bounding_box"):
143+
self._prev_content_end = (
144+
self._prev_content_end + content.width + self.padding
145+
)
146+
else:
147+
self._prev_content_end = (
148+
self._prev_content_end
149+
+ (content.bounding_box[2] * content.scale)
150+
+ self.padding
151+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# SPDX-FileCopyrightText: 2024 Tim C, written for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
Illustrates usage of LinearLayout to display a text label to the right of
6+
an icon.
7+
"""
8+
import adafruit_imageload
9+
import board
10+
import displayio
11+
import terminalio
12+
from adafruit_display_text import label
13+
from adafruit_displayio_layout.layouts.linear_layout import LinearLayout
14+
15+
# use built in display (PyPortal, PyGamer, PyBadge, CLUE, etc.)
16+
# see guide for setting up external displays (TFT / OLED breakouts, RGB matrices, etc.)
17+
# https://learn.adafruit.com/circuitpython-display-support-using-displayio/display-and-display-bus
18+
display = board.DISPLAY
19+
20+
# Make the display context
21+
main_group = displayio.Group()
22+
display.root_group = main_group
23+
24+
layout = LinearLayout(
25+
x=10, y=10, padding=4, orientation=LinearLayout.HORIZONTAL_ORIENTATION
26+
)
27+
28+
lbl = label.Label(terminalio.FONT, scale=4, x=0, y=0, text="Hello")
29+
30+
icon, icon_palette = adafruit_imageload.load("icons/Play_48x48_small.bmp")
31+
icon_tile_grid = displayio.TileGrid(icon, pixel_shader=icon_palette)
32+
layout.add_content(icon_tile_grid)
33+
layout.add_content(lbl)
34+
35+
main_group.append(layout)
36+
while True:
37+
pass

0 commit comments

Comments
 (0)