Skip to content

Commit b55c3e3

Browse files
committed
working on tab_layout and simpletest example
1 parent 2b9aaa1 commit b55c3e3

File tree

8 files changed

+192
-134
lines changed

8 files changed

+192
-134
lines changed

adafruit_displayio_layout/layouts/page_layout.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ def __init__(
5353
self.x = x
5454
self.y = y
5555

56-
self._page_content_list = []
56+
self.page_content_list = []
5757
self._cur_showing_index = 0
5858

5959
def add_content(self, page_content, page_name=None):
60-
"""Add a child to the grid.
60+
"""Add a child to the page layout.
6161
6262
:param page_content: the content for the page typically a Group
6363
:param page_name: the name of this page
@@ -72,10 +72,10 @@ def add_content(self, page_content, page_name=None):
7272
"page_name": page_name,
7373
}
7474

75-
if len(self._page_content_list) > 0:
75+
if len(self.page_content_list) > 0:
7676
_page_group.hidden = True
7777

78-
self._page_content_list.append(sub_view_obj)
78+
self.page_content_list.append(sub_view_obj)
7979
self.append(_page_group)
8080

8181
def _check_args(self, page_name, page_index):
@@ -95,16 +95,16 @@ def _check_args(self, page_name, page_index):
9595
)
9696

9797
if page_index is not None:
98-
if page_index >= len(self._page_content_list):
98+
if page_index >= len(self.page_content_list):
9999
raise KeyError(
100100
"KeyError at index {} in list length {}".format(
101-
page_index, len(self._page_content_list)
101+
page_index, len(self.page_content_list)
102102
),
103103
)
104104

105105
if page_name is not None:
106106
_found = False
107-
for page in self._page_content_list:
107+
for page in self.page_content_list:
108108
if not _found:
109109
if page_name == page["page_name"]:
110110
_found = True
@@ -125,10 +125,10 @@ def get_page(self, page_name=None, page_index=None):
125125
self._check_args(page_name, page_index)
126126

127127
if page_index is not None:
128-
return self._page_content_list[page_index]
128+
return self.page_content_list[page_index]
129129

130130
if page_name is not None:
131-
for cell in self._page_content_list:
131+
for cell in self.page_content_list:
132132
if cell["page_name"] == page_name:
133133
return cell
134134

@@ -149,7 +149,7 @@ def show_page(self, page_name=None, page_index=None):
149149

150150
self._check_args(page_name, page_index)
151151

152-
for cur_index, page in enumerate(self._page_content_list):
152+
for cur_index, page in enumerate(self.page_content_list):
153153
if page_name is not None:
154154
if page["page_name"] == page_name:
155155
self._cur_showing_index = cur_index
@@ -182,7 +182,7 @@ def showing_page_name(self):
182182
Name of the currently showing page
183183
:return string: showing_page_name
184184
"""
185-
return self._page_content_list[self._cur_showing_index]["page_name"]
185+
return self.page_content_list[self._cur_showing_index]["page_name"]
186186

187187
@showing_page_name.setter
188188
def showing_page_name(self, new_name):
@@ -194,7 +194,7 @@ def showing_page_content(self):
194194
The content object for the currently showing page
195195
:return Displayable: showing_page_content
196196
"""
197-
return self._page_content_list[self._cur_showing_index]["content"][0]
197+
return self.page_content_list[self._cur_showing_index]["content"][0]
198198

199199
def next_page(self, loop=True):
200200
"""
@@ -203,7 +203,7 @@ def next_page(self, loop=True):
203203
:return: None
204204
"""
205205

206-
if self._cur_showing_index + 1 < len(self._page_content_list):
206+
if self._cur_showing_index + 1 < len(self.page_content_list):
207207
self.show_page(page_index=self._cur_showing_index + 1)
208208
else:
209209
if not loop:
@@ -223,4 +223,4 @@ def previous_page(self, loop=True):
223223
if not loop:
224224
print("No more pages")
225225
else:
226-
self.show_page(page_index=len(self._page_content_list) - 1)
226+
self.show_page(page_index=len(self.page_content_list) - 1)

adafruit_displayio_layout/layouts/tab_layout.py

Lines changed: 125 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,91 @@
1+
# SPDX-FileCopyrightText: 2022 Tim Cocks
2+
#
3+
# SPDX-License-Identifier: MIT
14

5+
"""
6+
`tab_layout`
7+
================================================================================
8+
9+
A layout that organizes pages into tabs.
10+
11+
12+
* Author(s): Tim Cocks
13+
14+
Implementation Notes
15+
--------------------
16+
17+
**Hardware:**
18+
19+
**Software and Dependencies:**
20+
21+
* Adafruit CircuitPython firmware for the supported boards:
22+
https://github.com/adafruit/circuitpython/releases
23+
24+
"""
225
try:
3-
from typing import Optional, Union
26+
from typing import Optional, Union, Tuple
427
from fontio import BuiltinFont
528
from adafruit_bitmap_font.bdf import BDF
629
from adafruit_bitmap_font.pcf import PCF
730
except ImportError:
831
pass
932

10-
import board
1133
import terminalio
1234
import displayio
1335
import adafruit_imageload
1436
from adafruit_display_text.bitmap_label import Label
1537
from adafruit_imageload.tilegrid_inflator import inflate_tilegrid
1638
from adafruit_displayio_layout.layouts.page_layout import PageLayout
1739

40+
1841
class TabLayout(displayio.Group):
19-
def __init__(self,
20-
x: int = 0, y: int = 0,
21-
display: displayio.Display = board.DISPLAY,
22-
tab_text_scale: int = 1,
23-
custom_font: Optional[Union[BuiltinFont, BDF, PCF]] = terminalio.FONT,
24-
inactive_tab_spritesheet: Optional[str] = None,
25-
active_tab_spritesheet: Optional[str] = None,
26-
active_tab_text_color: Optional[int, tuple[int, int, int]] = 0x999999,
27-
inactive_tab_text_color: Optional[int, tuple[int, int, int]] = 0xfffff,
28-
inactive_tab_transparent_indexes: Optional[Union[int, tuple[int, int]]] = None,
29-
active_tab_transparent_indexes: Optional[Union[int, tuple[int, int]]] = None,
30-
tab_count: int = None,
31-
):
42+
"""
43+
A layout that organizes children into a grid table structure.
44+
45+
:param int x: x location the layout should be placed. Pixel coordinates.
46+
:param int y: y location the layout should be placed. Pixel coordinates.
47+
:param displayio.Display display: The Display object to show the tab layout on.
48+
:param int tab_text_scale: Size of the text shown in the tabs.
49+
Whole numbers 1 and greater are valid
50+
:param Optional[Union[BuiltinFont, BDF, PCF]] custom_font: A pre-loaded font object to use
51+
for the tab labels
52+
:param str inactive_tab_spritesheet: Filepath of the spritesheet to show for inactive tabs.
53+
:param str active_tab_spritesheet: Filepath of the spritesheet to show for the active tab.
54+
:param Optional[int, tuple[int, int, int]] active_tab_text_color: Hex or tuple color to use
55+
for the active tab label
56+
:param Optional[int, tuple[int, int, int]] inactive_tab_text_color: Hex or tuple color to
57+
use for inactive tab labels
58+
:param Optional[Union[int, tuple[int, int]]] inactive_tab_transparent_indexes: single index
59+
or tuple of multiple indexes to be made transparent in the inactive tab sprite palette.
60+
:param Optional[Union[int, tuple[int, int]]] active_tab_transparent_indexes: single index
61+
or tuple of multiple indexes to be made transparent in the active tab sprite palette.
62+
:param int tab_count: How many tabs to draw in the layout. Positive whole numbers are valid.
63+
"""
64+
65+
# pylint: disable=too-many-instance-attributes, too-many-arguments, invalid-name, too-many-branches
3266

67+
def __init__(
68+
self,
69+
x: int = 0,
70+
y: int = 0,
71+
display: Optional[displayio.Display] = None,
72+
tab_text_scale: int = 1,
73+
custom_font: Optional[Union[BuiltinFont, BDF, PCF]] = terminalio.FONT,
74+
inactive_tab_spritesheet: Optional[str] = None,
75+
active_tab_spritesheet: Optional[str] = None,
76+
active_tab_text_color: Optional[Union[int, Tuple[int, int, int]]] = 0x999999,
77+
inactive_tab_text_color: Optional[Union[int, Tuple[int, int, int]]] = 0xFFFFF,
78+
inactive_tab_transparent_indexes: Optional[Union[int, Tuple[int, int]]] = None,
79+
active_tab_transparent_indexes: Optional[Union[int, Tuple[int, int]]] = None,
80+
tab_count: int = None,
81+
):
82+
83+
if display is None:
84+
# pylint: disable=import-outside-toplevel
85+
import board
86+
87+
if hasattr(board, "DISPLAY"):
88+
display = board.DISPLAY
3389
if inactive_tab_spritesheet is None:
3490
raise AttributeError("Must pass active_tab_spritesheet")
3591
if active_tab_spritesheet is None:
@@ -39,8 +95,12 @@ def __init__(self,
3995

4096
super().__init__(x=x, y=y)
4197
self.tab_count = tab_count
42-
self._active_bmp, self._active_palette = adafruit_imageload.load(active_tab_spritesheet)
43-
self._inactive_bmp, self._inactive_palette = adafruit_imageload.load(inactive_tab_spritesheet)
98+
self._active_bmp, self._active_palette = adafruit_imageload.load(
99+
active_tab_spritesheet
100+
)
101+
self._inactive_bmp, self._inactive_palette = adafruit_imageload.load(
102+
inactive_tab_spritesheet
103+
)
44104

45105
if isinstance(active_tab_transparent_indexes, int):
46106
self._active_palette.make_transparent(active_tab_transparent_indexes)
@@ -56,7 +116,9 @@ def __init__(self,
56116
for index in inactive_tab_transparent_indexes:
57117
self._inactive_palette.make_transparent(index)
58118
else:
59-
raise AttributeError("inactive_tab_transparent_indexes must be int or tuple")
119+
raise AttributeError(
120+
"inactive_tab_transparent_indexes must be int or tuple"
121+
)
60122

61123
self.tab_height = self._active_bmp.height
62124
self.display = display
@@ -72,25 +134,35 @@ def __init__(self,
72134
self.append(self.page_layout)
73135

74136
def _draw_tabs(self):
75-
for i, page_dict in enumerate(self.page_layout._page_content_list):
137+
for i, page_dict in enumerate(self.page_layout.page_content_list):
76138
if i not in self.tab_dict:
77139
print(f"creating tab {i}")
78140
_new_tab_group = displayio.Group()
79-
_tab_tilegrid = inflate_tilegrid(bmp_obj=self._inactive_bmp, bmp_palette=self._inactive_palette,
80-
target_size=((self.display.width // self.tab_count) // (
81-
self._active_bmp.width // 3), 3))
141+
_tab_tilegrid = inflate_tilegrid(
142+
bmp_obj=self._inactive_bmp,
143+
bmp_palette=self._inactive_palette,
144+
target_size=(
145+
(self.display.width // self.tab_count)
146+
// (self._active_bmp.width // 3),
147+
3,
148+
),
149+
)
82150

83151
_tab_tilegrid.x = (self.display.width // self.tab_count) * i
84152
_new_tab_group.append(_tab_tilegrid)
85153

86-
_tab_label = Label(self.custom_font, text=page_dict["page_name"],
87-
color=self.inactive_tab_text_color, scale=self.tab_text_scale)
154+
_tab_label = Label(
155+
self.custom_font,
156+
text=page_dict["page_name"],
157+
color=self.inactive_tab_text_color,
158+
scale=self.tab_text_scale,
159+
)
88160

89161
_tab_label.anchor_point = (0.5, 0.5)
90162
_tab_label.anchored_position = (
91-
_tab_tilegrid.x +
92-
((_tab_tilegrid.width * _tab_tilegrid.tile_width) // 2),
93-
(_tab_tilegrid.height * _tab_tilegrid.tile_height) // 2
163+
_tab_tilegrid.x
164+
+ ((_tab_tilegrid.width * _tab_tilegrid.tile_width) // 2),
165+
(_tab_tilegrid.height * _tab_tilegrid.tile_height) // 2,
94166
)
95167
_new_tab_group.append(_tab_label)
96168

@@ -113,10 +185,15 @@ def _update_active_tab(self):
113185
self.tab_group[i][1].color = self.inactive_tab_text_color
114186

115187
def add_content(self, tab_content, tab_name):
188+
"""Add a child to the tab layout.
189+
190+
:param tab_content: the content for the tab typically a Group
191+
:param tab_name: the name of this tab, will be shown inside the tab
192+
193+
:return: None"""
116194
self.page_layout.add_content(tab_content, tab_name)
117195
self._draw_tabs()
118196

119-
120197
def show_page(self, page_name=None, page_index=None):
121198
"""
122199
Show the specified page, and hide all other pages.
@@ -129,7 +206,6 @@ def show_page(self, page_name=None, page_index=None):
129206
self.page_layout.show_page(page_name=page_name, page_index=page_index)
130207
self._update_active_tab()
131208

132-
133209
@property
134210
def showing_page_index(self):
135211
"""
@@ -140,7 +216,8 @@ def showing_page_index(self):
140216

141217
@showing_page_index.setter
142218
def showing_page_index(self, new_index):
143-
self.show_page(page_index=new_index)
219+
if self.showing_page_index != new_index:
220+
self.show_page(page_index=new_index)
144221

145222
@property
146223
def showing_page_name(self):
@@ -180,3 +257,21 @@ def previous_page(self, loop=True):
180257
"""
181258
self.page_layout.previous_page(loop=loop)
182259
self._update_active_tab()
260+
261+
def handle_touch_events(self, touch_event):
262+
"""
263+
Check if the touch event is on the tabs and if so change to the touched tab.
264+
265+
:param tuple touch_event: tuple containing x and y coordinates of the
266+
touch event in indexes 0 and 1.
267+
:return: None
268+
"""
269+
270+
if touch_event:
271+
if 0 <= touch_event[1] <= self.tab_height:
272+
273+
touched_tab_index = touch_event[0] // (
274+
self.display.width // self.tab_count
275+
)
276+
print(f"{touch_event[0]} - {touched_tab_index}")
277+
self.showing_page_index = touched_tab_index

docs/api.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
77
.. automodule:: adafruit_displayio_layout.layouts.grid_layout
88
:members:
9+
:private-members:
10+
:member-order: bysource
11+
12+
.. automodule:: adafruit_displayio_layout.layouts.page_layout
13+
:members:
14+
:private-members:
15+
:member-order: bysource
16+
17+
.. automodule:: adafruit_displayio_layout.layouts.tab_layout
18+
:members:
19+
:private-members:
20+
:member-order: bysource
921

1022
.. automodule:: adafruit_displayio_layout.widgets.widget
1123
:members:
File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
2+
# SPDX-License-Identifier: MIT

0 commit comments

Comments
 (0)