From bda0c97c08f8b1f59172d92f9a964fd3b894d780 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 7 Feb 2022 18:57:38 -0600 Subject: [PATCH 1/4] scrolling label --- adafruit_display_text/scrolling_label.py | 149 +++++++++++++++++++++++ examples/display_text_scrolling_label.py | 17 +++ 2 files changed, 166 insertions(+) create mode 100644 adafruit_display_text/scrolling_label.py create mode 100644 examples/display_text_scrolling_label.py diff --git a/adafruit_display_text/scrolling_label.py b/adafruit_display_text/scrolling_label.py new file mode 100644 index 0000000..e472590 --- /dev/null +++ b/adafruit_display_text/scrolling_label.py @@ -0,0 +1,149 @@ +# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +`adafruit_display_text.scrolling_label` +==================================================== + +Displays text into a fixed-width label that scrolls leftward +if the full_text is large enough to need it. + +* Author(s): Tim Cocks + +Implementation Notes +-------------------- + +**Hardware:** + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://circuitpython.org/downloads + +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git" + +import time +from adafruit_display_text import bitmap_label + + +class ScrollingLabel(bitmap_label.Label): + + """ + ScrollingLabel - A fixed-width label that will scroll to the left + in order to show the full text if it's larger than the fixed-width. + + :param font: The font to use for the label. + :param max_characters: The number of characters that sets the fixed-width. Default is 10. + :param full_text: The full text to show in the label. If this is longer than + `max_characters` then the label will scroll to show everything. + :param animate_time: The number of seconds in between scrolling animation + frames. Default is 0.3 seconds. + :param current_index: The index of the first visible character in the label. + Default is 0, the first character. Will increase while scrolling. + """ + + # pylint: disable=too-many-arguments + def __init__( + self, + font, + max_characters=10, + full_text="", + animate_time=0.3, + current_index=0, + **kwargs + ): + + super().__init__(font, **kwargs) + self.animate_time = animate_time + self._current_index = current_index + self._last_animate_time = -1 + self.max_characters = max_characters + if "text" in kwargs: + raise ValueError( + "User code should not set the text argument on ScrollingText. " + "Use full_text instead." + ) + + if full_text[-1] != " ": + full_text = "{} ".format(full_text) + self._full_text = full_text + + self.update() + + def update(self, force=False): + """ + Attempt to update the display. If `animate_time` has elapsed since + previews animation frame then move the characters over by 1 index. + Must be called in the main loop of user code. + + :param force: whether to ignore `animation_time` and force the update. Default is False. + :return: None + """ + _now = time.monotonic() + if force or self._last_animate_time + self.animate_time <= _now: + + if len(self.full_text) <= self.max_characters: + self.text = self.full_text + self._last_animate_time = _now + return + + if self.current_index + self.max_characters <= len(self.full_text): + _showing_string = self.full_text[ + self.current_index : self.current_index + self.max_characters + ] + else: + _showing_string_start = self.full_text[self.current_index :] + _showing_string_end = "{}".format( + self.full_text[ + : (self.current_index + self.max_characters) + % len(self.full_text) + ] + ) + + _showing_string = "{}{}".format( + _showing_string_start, _showing_string_end + ) + self.text = _showing_string + + self.current_index += 1 + self._last_animate_time = _now + + return + + @property + def current_index(self): + """ + Index of the first visible character. + + :return int: the current index + """ + return self._current_index + + @current_index.setter + def current_index(self, new_index): + if new_index < len(self.full_text): + self._current_index = new_index + else: + self._current_index = new_index % len(self.full_text) + + @property + def full_text(self): + """ + The full text to be shown. If it's longer than `max_characters` then + scrolling will occur as needed. + + :return string: The full text of this label. + """ + return self._full_text + + @full_text.setter + def full_text(self, new_text): + if new_text[-1] != " ": + new_text = "{} ".format(new_text) + self._full_text = new_text + self.current_index = 0 + self.update() diff --git a/examples/display_text_scrolling_label.py b/examples/display_text_scrolling_label.py new file mode 100644 index 0000000..26a9f78 --- /dev/null +++ b/examples/display_text_scrolling_label.py @@ -0,0 +1,17 @@ +# SPDX-FileCopyrightText: 2022 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +import board +import terminalio +from adafruit_display_text.scrolling_label import ScrollingLabel + + +text = "Hello world CircuitPython scrolling label" +my_scrolling_label = ScrollingLabel( + terminalio.FONT, full_text=text, max_characters=20, animate_time=0.3 +) +my_scrolling_label.x = 10 +my_scrolling_label.y = 10 +board.DISPLAY.show(my_scrolling_label) +while True: + my_scrolling_label.update() From e0dba2752dad17465feda5516a34fec33d62425b Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 8 Feb 2022 19:39:27 -0600 Subject: [PATCH 2/4] argument name to text --- adafruit_display_text/scrolling_label.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/adafruit_display_text/scrolling_label.py b/adafruit_display_text/scrolling_label.py index e472590..baccd6a 100644 --- a/adafruit_display_text/scrolling_label.py +++ b/adafruit_display_text/scrolling_label.py @@ -51,7 +51,7 @@ def __init__( self, font, max_characters=10, - full_text="", + text="", animate_time=0.3, current_index=0, **kwargs @@ -62,15 +62,10 @@ def __init__( self._current_index = current_index self._last_animate_time = -1 self.max_characters = max_characters - if "text" in kwargs: - raise ValueError( - "User code should not set the text argument on ScrollingText. " - "Use full_text instead." - ) - - if full_text[-1] != " ": - full_text = "{} ".format(full_text) - self._full_text = full_text + + if text[-1] != " ": + text = "{} ".format(text) + self._full_text = text self.update() From 593211d052328118987ea46f808462c7fdcf6de9 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 8 Feb 2022 19:50:27 -0600 Subject: [PATCH 3/4] update docstring --- adafruit_display_text/scrolling_label.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_display_text/scrolling_label.py b/adafruit_display_text/scrolling_label.py index baccd6a..88ae61c 100644 --- a/adafruit_display_text/scrolling_label.py +++ b/adafruit_display_text/scrolling_label.py @@ -38,7 +38,7 @@ class ScrollingLabel(bitmap_label.Label): :param font: The font to use for the label. :param max_characters: The number of characters that sets the fixed-width. Default is 10. - :param full_text: The full text to show in the label. If this is longer than + :param text: The full text to show in the label. If this is longer than `max_characters` then the label will scroll to show everything. :param animate_time: The number of seconds in between scrolling animation frames. Default is 0.3 seconds. From 5437378d612634703a338e415c580d27526331e4 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Tue, 8 Feb 2022 20:04:15 -0600 Subject: [PATCH 4/4] update example --- examples/display_text_scrolling_label.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/display_text_scrolling_label.py b/examples/display_text_scrolling_label.py index 26a9f78..4bfdf43 100644 --- a/examples/display_text_scrolling_label.py +++ b/examples/display_text_scrolling_label.py @@ -8,7 +8,7 @@ text = "Hello world CircuitPython scrolling label" my_scrolling_label = ScrollingLabel( - terminalio.FONT, full_text=text, max_characters=20, animate_time=0.3 + terminalio.FONT, text=text, max_characters=20, animate_time=0.3 ) my_scrolling_label.x = 10 my_scrolling_label.y = 10