Skip to content

Commit ea69caf

Browse files
authored
Merge pull request #36 from FoamyGuy/sprite_button
adding sprite_button and refactoring to package instead of single file
2 parents 73b36fc + ea1769a commit ea69caf

13 files changed

+416
-92
lines changed

adafruit_button/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
`adafruit_button`
7+
================================================================================
8+
9+
UI Buttons for displayio
10+
11+
12+
* Author(s): Limor Fried
13+
14+
Implementation Notes
15+
--------------------
16+
17+
**Software and Dependencies:**
18+
19+
* Adafruit CircuitPython firmware for the supported boards:
20+
https://github.com/adafruit/circuitpython/releases
21+
22+
"""
23+
from adafruit_button.button import Button

adafruit_button.py renamed to adafruit_button/button.py

Lines changed: 17 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# SPDX-License-Identifier: MIT
44

55
"""
6-
`adafruit_button`
6+
`adafruit_button.button`
77
================================================================================
88
99
UI Buttons for displayio
@@ -22,24 +22,15 @@
2222
"""
2323

2424
from micropython import const
25-
import displayio
26-
from adafruit_display_text.label import Label
2725
from adafruit_display_shapes.rect import Rect
2826
from adafruit_display_shapes.roundrect import RoundRect
27+
from adafruit_button.button_base import ButtonBase, _check_color
2928

3029
__version__ = "0.0.0+auto.0"
3130
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Button.git"
3231

3332

34-
def _check_color(color):
35-
# if a tuple is supplied, convert it to a RGB number
36-
if isinstance(color, tuple):
37-
r, g, b = color
38-
return int((r << 16) + (g << 8) + (b & 0xFF))
39-
return color
40-
41-
42-
class Button(displayio.Group):
33+
class Button(ButtonBase):
4334
# pylint: disable=too-many-instance-attributes, too-many-locals
4435
"""Helper class for creating UI buttons for ``displayio``.
4536
@@ -141,26 +132,27 @@ def __init__(
141132
selected_outline=None,
142133
selected_label=None
143134
):
144-
super().__init__(x=x, y=y)
145-
self.x = x
146-
self.y = y
147-
self._width = width
148-
self._height = height
149-
self._font = label_font
150-
self._selected = False
151-
self.name = name
152-
self._label = label
135+
super().__init__(
136+
x=x,
137+
y=y,
138+
width=width,
139+
height=height,
140+
name=name,
141+
label=label,
142+
label_font=label_font,
143+
label_color=label_color,
144+
selected_label=selected_label,
145+
)
146+
153147
self.body = self.fill = self.shadow = None
154148
self.style = style
155149

156150
self._fill_color = _check_color(fill_color)
157151
self._outline_color = _check_color(outline_color)
158-
self._label_color = label_color
159-
self._label_font = label_font
152+
160153
# Selecting inverts the button colors!
161154
self._selected_fill = _check_color(selected_fill)
162155
self._selected_outline = _check_color(selected_outline)
163-
self._selected_label = _check_color(selected_label)
164156

165157
if self.selected_fill is None and fill_color is not None:
166158
self.selected_fill = (~self._fill_color) & 0xFFFFFF
@@ -173,64 +165,17 @@ def __init__(
173165

174166
self.label = label
175167

176-
@property
177-
def label(self):
178-
"""The text label of the button"""
179-
return self._label.text
180-
181-
@label.setter
182-
def label(self, newtext):
183-
if self._label and self and (self[-1] == self._label):
184-
self.pop()
185-
186-
self._label = None
187-
if not newtext or (self._label_color is None): # no new text
188-
return # nothing to do!
189-
190-
if not self._label_font:
191-
raise RuntimeError("Please provide label font")
192-
self._label = Label(self._label_font, text=newtext)
193-
dims = self._label.bounding_box
194-
if dims[2] >= self.width or dims[3] >= self.height:
195-
while len(self._label.text) > 1 and (
196-
dims[2] >= self.width or dims[3] >= self.height
197-
):
198-
self._label.text = "{}.".format(self._label.text[:-2])
199-
dims = self._label.bounding_box
200-
if len(self._label.text) <= 1:
201-
raise RuntimeError("Button not large enough for label")
202-
self._label.x = (self.width - dims[2]) // 2
203-
self._label.y = self.height // 2
204-
self._label.color = self._label_color
205-
self.append(self._label)
206-
207-
if (self.selected_label is None) and (self._label_color is not None):
208-
self.selected_label = (~self._label_color) & 0xFFFFFF
209-
210-
@property
211-
def selected(self):
212-
"""Selected inverts the colors."""
213-
return self._selected
214-
215-
@selected.setter
216-
def selected(self, value):
217-
if value == self._selected:
218-
return # bail now, nothing more to do
219-
self._selected = value
168+
def _subclass_selected_behavior(self, value):
220169
if self._selected:
221170
new_fill = self.selected_fill
222171
new_out = self.selected_outline
223-
new_label = self.selected_label
224172
else:
225173
new_fill = self._fill_color
226174
new_out = self._outline_color
227-
new_label = self._label_color
228175
# update all relevant colors!
229176
if self.body is not None:
230177
self.body.fill = new_fill
231178
self.body.outline = new_out
232-
if self._label is not None:
233-
self._label.color = new_label
234179

235180
@property
236181
def group(self):
@@ -295,25 +240,6 @@ def selected_outline(self, new_color):
295240
if self.selected:
296241
self.body.outline = self._selected_outline
297242

298-
@property
299-
def selected_label(self):
300-
"""The font color of the button when selected"""
301-
return self._selected_label
302-
303-
@selected_label.setter
304-
def selected_label(self, new_color):
305-
self._selected_label = _check_color(new_color)
306-
307-
@property
308-
def label_color(self):
309-
"""The font color of the button"""
310-
return self._label_color
311-
312-
@label_color.setter
313-
def label_color(self, new_color):
314-
self._label_color = _check_color(new_color)
315-
self._label.color = self._label_color
316-
317243
@property
318244
def width(self):
319245
"""The width of the button"""

adafruit_button/button_base.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
`adafruit_button.button`
7+
================================================================================
8+
9+
UI Buttons for displayio
10+
11+
12+
* Author(s): Limor Fried
13+
14+
Implementation Notes
15+
--------------------
16+
17+
**Software and Dependencies:**
18+
19+
* Adafruit CircuitPython firmware for the supported boards:
20+
https://github.com/adafruit/circuitpython/releases
21+
22+
"""
23+
from adafruit_display_text.bitmap_label import Label
24+
from displayio import Group
25+
26+
27+
def _check_color(color):
28+
# if a tuple is supplied, convert it to a RGB number
29+
if isinstance(color, tuple):
30+
r, g, b = color
31+
return int((r << 16) + (g << 8) + (b & 0xFF))
32+
return color
33+
34+
35+
class ButtonBase(Group):
36+
# pylint: disable=too-many-instance-attributes
37+
"""Superclass for creating UI buttons for ``displayio``.
38+
39+
:param x: The x position of the button.
40+
:param y: The y position of the button.
41+
:param width: The width of the button in tiles.
42+
:param height: The height of the button in tiles.
43+
:param name: A name, or miscellaneous string that is stored on the button.
44+
:param label: The text that appears inside the button. Defaults to not displaying the label.
45+
:param label_font: The button label font.
46+
:param label_color: The color of the button label text. Defaults to 0x0.
47+
:param selected_label: Text that appears when selected
48+
"""
49+
50+
def __init__(
51+
self,
52+
*,
53+
x,
54+
y,
55+
width,
56+
height,
57+
name=None,
58+
label=None,
59+
label_font=None,
60+
label_color=0x0,
61+
selected_label=None
62+
):
63+
super().__init__(x=x, y=y)
64+
self.x = x
65+
self.y = y
66+
self._width = width
67+
self._height = height
68+
self._font = label_font
69+
self._selected = False
70+
self.name = name
71+
self._label = label
72+
self._label_color = label_color
73+
self._label_font = label_font
74+
self._selected_label = _check_color(selected_label)
75+
76+
@property
77+
def label(self):
78+
"""The text label of the button"""
79+
return self._label.text
80+
81+
@label.setter
82+
def label(self, newtext):
83+
if self._label and self and (self[-1] == self._label):
84+
self.pop()
85+
86+
self._label = None
87+
if not newtext or (self._label_color is None): # no new text
88+
return # nothing to do!
89+
90+
if not self._label_font:
91+
raise RuntimeError("Please provide label font")
92+
self._label = Label(self._label_font, text=newtext)
93+
dims = self._label.bounding_box
94+
if dims[2] >= self.width or dims[3] >= self.height:
95+
while len(self._label.text) > 1 and (
96+
dims[2] >= self.width or dims[3] >= self.height
97+
):
98+
self._label.text = "{}.".format(self._label.text[:-2])
99+
dims = self._label.bounding_box
100+
if len(self._label.text) <= 1:
101+
raise RuntimeError("Button not large enough for label")
102+
self._label.x = (self.width - dims[2]) // 2
103+
self._label.y = self.height // 2
104+
self._label.color = (
105+
self._label_color if not self.selected else self._selected_label
106+
)
107+
self.append(self._label)
108+
109+
if (self.selected_label is None) and (self._label_color is not None):
110+
self.selected_label = (~self._label_color) & 0xFFFFFF
111+
112+
def _subclass_selected_behavior(self, value):
113+
# Subclasses should overide this!
114+
pass
115+
116+
@property
117+
def selected(self):
118+
"""Selected inverts the colors."""
119+
return self._selected
120+
121+
@selected.setter
122+
def selected(self, value):
123+
if value == self._selected:
124+
return # bail now, nothing more to do
125+
self._selected = value
126+
127+
if self._selected:
128+
new_label = self.selected_label
129+
else:
130+
new_label = self._label_color
131+
if self._label is not None:
132+
self._label.color = new_label
133+
134+
self._subclass_selected_behavior(value)
135+
136+
@property
137+
def selected_label(self):
138+
"""The font color of the button when selected"""
139+
return self._selected_label
140+
141+
@selected_label.setter
142+
def selected_label(self, new_color):
143+
self._selected_label = _check_color(new_color)
144+
145+
@property
146+
def label_color(self):
147+
"""The font color of the button"""
148+
return self._label_color
149+
150+
@label_color.setter
151+
def label_color(self, new_color):
152+
self._label_color = _check_color(new_color)
153+
self._label.color = self._label_color

0 commit comments

Comments
 (0)