Skip to content

Commit

Permalink
Merge pull request #48 from ch4nsuk3/add-annotations
Browse files Browse the repository at this point in the history
Add annotations
  • Loading branch information
FoamyGuy authored Dec 4, 2024
2 parents c368494 + f6026b2 commit 09e3958
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 91 deletions.
96 changes: 56 additions & 40 deletions adafruit_button/button.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
# SPDX-FileCopyrightText: 2024 Channing Ramos
#
# SPDX-License-Identifier: MIT

Expand All @@ -9,7 +10,7 @@
UI Buttons for displayio
* Author(s): Limor Fried
* Author(s): Limor Fried, Channing Ramos
Implementation Notes
--------------------
Expand All @@ -27,7 +28,7 @@
from adafruit_button.button_base import ButtonBase, _check_color

try:
from typing import Optional, Union
from typing import Optional, Union, Tuple
from fontio import FontProtocol
from displayio import Group
except ImportError:
Expand All @@ -39,30 +40,45 @@

class Button(ButtonBase):
# pylint: disable=too-many-instance-attributes, too-many-locals
"""Helper class for creating UI buttons for ``displayio``.
:param x: The x position of the button.
:param y: The y position of the button.
:param width: The width of the button in pixels.
:param height: The height of the button in pixels.
:param name: The name of the button.
"""Helper class for creating UI buttons for ``displayio``. Provides the following
buttons:
RECT: A rectangular button. SHAWDOWRECT adds a drop shadow.
ROUNDRECT: A rectangular button with rounded corners. SHADOWROUNDRECT adds
a drop shadow.
:param int x: The x position of the button.
:param int y: The y position of the button.
:param int width: The width of the button in pixels.
:param int height: The height of the button in pixels.
:param Optional[str] name: The name of the button.
:param style: The style of the button. Can be RECT, ROUNDRECT, SHADOWRECT, SHADOWROUNDRECT.
Defaults to RECT.
:param fill_color: The color to fill the button. Defaults to 0xFFFFFF.
:param outline_color: The color of the outline of the button.
:param label: The text that appears inside the button. Defaults to not displaying the label.
:param label_font: The button label font.
:param label_color: The color of the button label text. Defaults to 0x0.
:param selected_fill: Inverts the fill color.
:param selected_outline: Inverts the outline color.
:param selected_label: Inverts the label color.
:param Optional[Union[int, Tuple[int, int, int]]] fill_color: The color to fill the button.
Accepts an int or a tuple of 3 integers representing RGB values. Defaults to 0xFFFFFF.
:param Optional[Union[int, Tuple[int, int, int]]] outline_color: The color of the outline of
the button. Accepts an int or a tuple of 3 integers representing RGB values. Defaults to 0x0.
:param Optional[str] label: The text that appears inside the button.
:param Optional[FontProtocol] label_font: The button label font. Defaults to
''terminalio.FONT''
:param Optional[Union[int, Tuple[int, int, int]]] label_color: The color of the button label
text. Accepts an int or a tuple of 3 integers representing RGB values. Defaults to 0x0.
:param Optional[Union[int, Tuple[int, int, int]]] selected_fill: The fill color when the
button is selected. Accepts an int or a tuple of 3 integers representing RGB values.
Defaults to the inverse of the fill_color.
:param Optional[Union[int, Tuple[int, int, int]]] selected_outline: The outline color when the
button is selected. Accepts an int or a tuple of 3 integers representing RGB values.
Defaults to the inverse of outline_color.
:param Optional[Union[int, Tuple[int, int, int]]] selected_label: The label color when the
button is selected. Accepts an int or a tuple of 3 integers representing RGB values.
Defaults to inverting the label_color.
:param Optional[int] label_scale: The scale factor used for the label. Defaults to 1.
"""

def _empty_self_group(self):
def _empty_self_group(self) -> None:
while len(self) > 0:
self.pop()

def _create_body(self):
def _create_body(self) -> None:
if (self.outline_color is not None) or (self.fill_color is not None):
if self.style == Button.RECT:
self.body = Rect(
Expand Down Expand Up @@ -129,17 +145,17 @@ def __init__(
width: int,
height: int,
name: Optional[str] = None,
style: int = RECT,
fill_color: Optional[Union[int, tuple[int, int, int]]] = 0xFFFFFF,
outline_color: Optional[Union[int, tuple[int, int, int]]] = 0x0,
style=RECT,
fill_color: Optional[Union[int, Tuple[int, int, int]]] = 0xFFFFFF,
outline_color: Optional[Union[int, Tuple[int, int, int]]] = 0x0,
label: Optional[str] = None,
label_font: Optional[FontProtocol] = None,
label_color: Optional[Union[int, tuple[int, int, int]]] = 0x0,
selected_fill: Optional[Union[int, tuple[int, int, int]]] = None,
selected_outline: Optional[Union[int, tuple[int, int, int]]] = None,
selected_label: Optional[Union[int, tuple[int, int, int]]] = None,
label_scale: Optional[int] = None
) -> None:
label_color: Optional[Union[int, Tuple[int, int, int]]] = 0x0,
selected_fill: Optional[Union[int, Tuple[int, int, int]]] = None,
selected_outline: Optional[Union[int, Tuple[int, int, int]]] = None,
selected_label: Optional[Union[int, Tuple[int, int, int]]] = None,
label_scale: Optional[int] = 1
):
super().__init__(
x=x,
y=y,
Expand All @@ -164,9 +180,9 @@ def __init__(
self._selected_outline = _check_color(selected_outline)

if self.selected_fill is None and fill_color is not None:
self.selected_fill = (~self._fill_color) & 0xFFFFFF
self.selected_fill = (~_check_color(self._fill_color)) & 0xFFFFFF
if self.selected_outline is None and outline_color is not None:
self.selected_outline = (~self._outline_color) & 0xFFFFFF
self.selected_outline = (~_check_color(self._outline_color)) & 0xFFFFFF

self._create_body()
if self.body:
Expand Down Expand Up @@ -206,45 +222,45 @@ def contains(self, point: tuple[int, int]) -> bool:
)

@property
def fill_color(self) -> int:
def fill_color(self) -> Optional[int]:
"""The fill color of the button body"""
return self._fill_color

@fill_color.setter
def fill_color(self, new_color: int) -> None:
def fill_color(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._fill_color = _check_color(new_color)
if not self.selected:
self.body.fill = self._fill_color

@property
def outline_color(self) -> int:
def outline_color(self) -> Optional[int]:
"""The outline color of the button body"""
return self._outline_color

@outline_color.setter
def outline_color(self, new_color: int) -> None:
def outline_color(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._outline_color = _check_color(new_color)
if not self.selected:
self.body.outline = self._outline_color

@property
def selected_fill(self) -> int:
def selected_fill(self) -> Optional[int]:
"""The fill color of the button body when selected"""
return self._selected_fill

@selected_fill.setter
def selected_fill(self, new_color: int) -> None:
def selected_fill(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._selected_fill = _check_color(new_color)
if self.selected:
self.body.fill = self._selected_fill

@property
def selected_outline(self) -> int:
def selected_outline(self) -> Optional[int]:
"""The outline color of the button body when selected"""
return self._selected_outline

@selected_outline.setter
def selected_outline(self, new_color: int) -> None:
def selected_outline(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._selected_outline = _check_color(new_color)
if self.selected:
self.body.outline = self._selected_outline
Expand Down Expand Up @@ -279,8 +295,8 @@ def height(self, new_height: int) -> None:

def resize(self, new_width: int, new_height: int) -> None:
"""Resize the button to the new width and height given
:param new_width int the desired width
:param new_height int the desired height
:param int new_width: The desired width in pixels.
:param int new_height: he desired height in pixels.
"""
self._width = new_width
self._height = new_height
Expand Down
62 changes: 35 additions & 27 deletions adafruit_button/button_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries
# SPDX-FileCopyrightText: 2024 Channing Ramos
#
# SPDX-License-Identifier: MIT

Expand All @@ -9,7 +10,7 @@
UI Buttons for displayio
* Author(s): Limor Fried
* Author(s): Limor Fried, Channing Ramos
Implementation Notes
--------------------
Expand All @@ -22,15 +23,16 @@
"""
from adafruit_display_text.bitmap_label import Label
from displayio import Group
import terminalio

try:
from typing import Optional, Union
from typing import Optional, Union, Tuple
from fontio import FontProtocol
except ImportError:
pass


def _check_color(color):
def _check_color(color: Optional[Union[int, tuple[int, int, int]]]) -> int:
# if a tuple is supplied, convert it to a RGB number
if isinstance(color, tuple):
r, g, b = color
Expand All @@ -42,15 +44,20 @@ class ButtonBase(Group):
# pylint: disable=too-many-instance-attributes
"""Superclass for creating UI buttons for ``displayio``.
:param x: The x position of the button.
:param y: The y position of the button.
:param width: The width of the button in tiles.
:param height: The height of the button in tiles.
:param name: A name, or miscellaneous string that is stored on the button.
:param label: The text that appears inside the button. Defaults to not displaying the label.
:param label_font: The button label font.
:param label_color: The color of the button label text. Defaults to 0x0.
:param selected_label: Text that appears when selected
:param int x: The x position of the button.
:param int y: The y position of the button.
:param int width: The width of the button in tiles.
:param int height: The height of the button in tiles.
:param Optional[str] name: A name, or miscellaneous string that is stored on the button.
:param Optional[str] label: The text that appears inside the button.
:param Optional[FontProtocol] label_font: The button label font.
Defaults to ''terminalio.FONT''
:param Optional[Union[int, Tuple[int, int, int]]] label_color: The color of the label text.
Defaults to 0x0. Accepts an int or a tuple of 3 integers representing RGB values.
:param Optional[Union[int, Tuple[int, int, int]]] selected_label: The color of the label text
when the button is selected. Accepts an int or a tuple of 3 integers representing RGB values.
Defaults to an inverse of label_color.
:param Optional[int] label_scale: The scale factor used for the label. Defaults to 1.
"""

def __init__(
Expand All @@ -63,10 +70,10 @@ def __init__(
name: Optional[str] = None,
label: Optional[str] = None,
label_font: Optional[FontProtocol] = None,
label_color: Optional[Union[int, tuple[int, int, int]]] = 0x0,
selected_label: Optional[Union[int, tuple[int, int, int]]] = None,
label_scale: Optional[int] = None
):
label_color: Optional[Union[int, Tuple[int, int, int]]] = 0x0,
selected_label: Optional[Union[int, Tuple[int, int, int]]] = None,
label_scale: Optional[int] = 1,
) -> None:
super().__init__(x=x, y=y)
self.x = x
self.y = y
Expand All @@ -76,13 +83,13 @@ def __init__(
self._selected = False
self.name = name
self._label = label
self._label_color = label_color
self._label_color = _check_color(label_color)
self._label_font = label_font
self._selected_label = _check_color(selected_label)
self._label_scale = label_scale or 1
self._label_scale = label_scale

@property
def label(self) -> str:
def label(self) -> Optional[str]:
"""The text label of the button"""
return getattr(self._label, "text", None)

Expand All @@ -96,7 +103,7 @@ def label(self, newtext: str) -> None:
return # nothing to do!

if not self._label_font:
raise RuntimeError("Please provide label font")
self._label_font = terminalio.FONT
self._label = Label(self._label_font, text=newtext, scale=self._label_scale)
dims = list(self._label.bounding_box)
dims[2] *= self._label.scale
Expand All @@ -119,15 +126,15 @@ def label(self, newtext: str) -> None:
self.append(self._label)

if (self.selected_label is None) and (self._label_color is not None):
self.selected_label = (~self._label_color) & 0xFFFFFF
self.selected_label = (~_check_color(self._label_color)) & 0xFFFFFF

def _subclass_selected_behavior(self, value):
# Subclasses should overide this!
def _subclass_selected_behavior(self, value: bool):
# Subclasses should override this!
pass

@property
def selected(self) -> bool:
"""Selected inverts the colors."""
"""Returns whether the button is selected."""
return self._selected

@selected.setter
Expand All @@ -147,11 +154,12 @@ def selected(self, value: bool) -> None:

@property
def selected_label(self) -> int:
"""The font color of the button when selected"""
"""The font color of the button when selected.
If no color is specified it defaults to the inverse of the label_color"""
return self._selected_label

@selected_label.setter
def selected_label(self, new_color: int) -> None:
def selected_label(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._selected_label = _check_color(new_color)

@property
Expand All @@ -160,6 +168,6 @@ def label_color(self) -> int:
return self._label_color

@label_color.setter
def label_color(self, new_color: int):
def label_color(self, new_color: Union[int, Tuple[int, int, int]]) -> None:
self._label_color = _check_color(new_color)
self._label.color = self._label_color
Loading

0 comments on commit 09e3958

Please sign in to comment.