Skip to content

Commit c8b9d22

Browse files
authored
Merge pull request #1 from tekktrik/dev/use-enum-widget-types
Add colorwheel effect, refactor library
2 parents 199f434 + e22535e commit c8b9d22

6 files changed

+219
-18
lines changed

displayio_effects/__init__.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2+
# SPDX-FileCopyrightText: Copyright (c) 2022 Alec Delaney for CircuitPython Organization
3+
#
4+
# SPDX-License-Identifier: MIT
5+
# pylint: disable=protected-access
6+
"""
7+
`displayio_effects`
8+
================================================================================
9+
10+
Add the some flair to your widgets!
11+
12+
13+
* Author(s): Alec Delaney
14+
15+
Implementation Notes
16+
--------------------
17+
18+
**Software and Dependencies:**
19+
20+
* Adafruit CircuitPython firmware for the supported boards:
21+
https://circuitpython.org/downloads
22+
"""
23+
24+
25+
WIDGET_TYPE_ATTR = "_widget_type"
26+
27+
# pylint: disable=too-few-public-methods
28+
class WidgetType:
29+
"""Enum values for customizable widget types. Valid options are:
30+
31+
- ``WidgetType.DIAL`` - Dial widget
32+
- ``WidgetType.GAUGE`` - Gauge widget
33+
"""
34+
35+
DIAL = 0
36+
GAUGE = 1
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2+
# SPDX-FileCopyrightText: Copyright (c) 2022 Alec Delaney for CircuitPython Organization
3+
#
4+
# SPDX-License-Identifier: MIT
5+
# pylint: disable=protected-access
6+
"""
7+
`displayio_effects.fluctuation_effect`
8+
================================================================================
9+
10+
Add the colorwheel effect to your widgets
11+
12+
13+
* Author(s): Alec Delaney
14+
15+
Implementation Notes
16+
--------------------
17+
18+
**Software and Dependencies:**
19+
20+
* Adafruit CircuitPython firmware for the supported boards:
21+
https://circuitpython.org/downloads
22+
"""
23+
24+
from rainbowio import colorwheel
25+
from adafruit_itertools.adafruit_itertools import cycle
26+
from displayio_effects import WidgetType, WIDGET_TYPE_ATTR
27+
28+
__version__ = "0.0.0-auto.0"
29+
__repo__ = "https://github.com/tekktrik/CircuitPython_Org_DisplayIO_Effects.git"
30+
31+
32+
COLORWHEEL_WIDGET_VALUES = {
33+
WidgetType.DIAL: {
34+
"path": ["_needle", "pixel_shader"],
35+
"index": 0,
36+
},
37+
WidgetType.GAUGE: {
38+
"path": ["_palette"],
39+
"index": 2,
40+
},
41+
}
42+
43+
COLORWHEEL_COLORS = cycle([colorwheel(color_value) for color_value in range(256)])
44+
45+
46+
def _get_widget_value(instance):
47+
widget_type = getattr(instance, WIDGET_TYPE_ATTR)
48+
return COLORWHEEL_WIDGET_VALUES[widget_type]
49+
50+
51+
def hook_colorwheel_effect(widget_class, widget_type):
52+
"""Adds the colorwheel effect for the given class
53+
54+
:param widget_class: The widget class that should have this effect hooked
55+
into it
56+
:param int widget_type: The enum value of this widget type, must be a
57+
valid ~WidgetType
58+
59+
For example, to hook this into the ``Dial`` widget, you would use the
60+
following code:
61+
62+
.. code-block:: python
63+
64+
from displayio_dial import Dial
65+
from displayio_effects import WidgetType, colorwheel_effect
66+
67+
fluctuation_effect.hook_colorwheel_effect(Dial, WidgetType.DIAL)
68+
69+
"""
70+
71+
if not COLORWHEEL_WIDGET_VALUES.get(widget_type):
72+
raise ValueError(
73+
"The given widget does not have the ability to use this effect"
74+
)
75+
76+
setattr(widget_class, WIDGET_TYPE_ATTR, widget_type)
77+
78+
setattr(widget_class, "update_colorwheel", update_colorwheel)
79+
80+
81+
def update_colorwheel(self):
82+
"""Updates the widget value and propagates the fluctuation effect refresh"""
83+
84+
palette_map = _get_widget_value(self)
85+
palette_attr = self
86+
for attr_path in palette_map["path"]:
87+
palette_attr = getattr(palette_attr, attr_path)
88+
palette_attr[palette_map["index"]] = next(COLORWHEEL_COLORS)

displayio_effects/fluctuation_effect.py

+32-12
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,23 @@
2222
"""
2323

2424
import random
25+
from displayio_effects import WidgetType, WIDGET_TYPE_ATTR
2526

2627
__version__ = "0.0.0-auto.0"
2728
__repo__ = "https://github.com/tekktrik/CircuitPython_Org_DisplayIO_Effects.git"
2829

2930

31+
FLUCTUATION_WIDGET_VALUES = {
32+
WidgetType.DIAL: "value",
33+
WidgetType.GAUGE: "level",
34+
}
35+
36+
37+
def _get_value_name(instance):
38+
widget_type = getattr(instance, WIDGET_TYPE_ATTR)
39+
return FLUCTUATION_WIDGET_VALUES[widget_type]
40+
41+
3042
@property
3143
def fluctuation_amplitude(self):
3244
"""The furtherest the fluctuation effect can randomly set the widget value relative
@@ -37,10 +49,11 @@ def fluctuation_amplitude(self):
3749

3850
@fluctuation_amplitude.setter
3951
def fluctuation_amplitude(self, amplitude):
52+
value_name = _get_value_name(self)
4053
if amplitude < 0:
4154
raise ValueError("Fluctuation effect setting must be larger than 0")
4255
if amplitude:
43-
self._fluctuation_hold_value = getattr(self, self._value_name)
56+
self._fluctuation_hold_value = getattr(self, value_name)
4457
self._fluctuation_amplitude = amplitude
4558

4659

@@ -60,6 +73,8 @@ def fluctuation_move_rate(self, rate):
6073
def update_fluctuation(self):
6174
"""Updates the widget value and propagates the fluctuation effect refresh"""
6275

76+
value_name = _get_value_name(self)
77+
6378
if self._fluctuation_amplitude == 0:
6479
self._fluctuation_destination = None
6580
return
@@ -71,13 +86,13 @@ def update_fluctuation(self):
7186
+ self._fluctuation_hold_value
7287
)
7388

74-
value = getattr(self, self._value_name)
89+
value = getattr(self, value_name)
7590
value = (
7691
value + self._fluctuation_move_rate
7792
if self._fluctuation_destination > value
7893
else value - self._fluctuation_move_rate
7994
)
80-
setattr(self, self._value_name, value)
95+
setattr(self, value_name, value)
8196

8297
threshold_check = (
8398
value >= self._fluctuation_destination
@@ -88,34 +103,39 @@ def update_fluctuation(self):
88103
self._fluctuation_destination = self._fluctuation_hold_value
89104

90105

91-
def hook_fluctuation_effect(widget_class, value_name):
106+
def hook_fluctuation_effect(widget_class, widget_type):
92107
"""Adds the fluctuation effect for the given class
93108
94-
:param widget_classes: The widgets that should have this effect hooked
95-
into them.
96-
:param str value_name: The name of the attribute that sets the "value"
97-
for this widget
109+
:param widget_class: The widget class that should have this effect hooked
110+
into it
111+
:param int widget_type: The enum value of this widget type, must be a
112+
valid ~WidgetType
98113
99114
For example, to hook this into the ``Dial`` widget, you would use the
100115
following code:
101116
102117
.. code-block:: python
103118
104119
from displayio_dial import Dial
105-
from displayio_effects import fluctuation_effect
120+
from displayio_effects import WidgetType, fluctuation_effect
106121
107-
fluctuation_effect.hook_fluctuation_effect(Dial, "value")
122+
fluctuation_effect.hook_fluctuation_effect(Dial, WidgetType.DIAL)
108123
109124
"""
110125

111-
setattr(widget_class, "_value_name", value_name)
126+
if not FLUCTUATION_WIDGET_VALUES.get(widget_type):
127+
raise ValueError(
128+
"The given widget does not have the ability to use this effect"
129+
)
130+
131+
setattr(widget_class, WIDGET_TYPE_ATTR, widget_type)
112132

113133
setattr(widget_class, "_fluctuation_destination", None)
114134
setattr(widget_class, "_fluctuation_hold_value", 0)
115135

116136
setattr(widget_class, "fluctuation_amplitude", fluctuation_amplitude)
117137
setattr(widget_class, "_fluctuation_amplitude", 0)
118138
setattr(widget_class, "fluctuation_move_rate", fluctuation_move_rate)
119-
setattr(widget_class, "_fluctuation_move_rate", 0.1)
139+
setattr(widget_class, "_fluctuation_move_rate", 0.01)
120140

121141
setattr(widget_class, "update_fluctuation", update_fluctuation)
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# SPDX-FileCopyrightText: 2021 GaryZ, Alec Delaney
2+
# SPDX-FileCopyrightText: Copyright (c) 2022 Alec Delaney for CircuitPython Organization
3+
#
4+
# SPDX-License-Identifier: Unlicense
5+
#############################
6+
"""
7+
Use the random fluctuation effect for the Dial.
8+
"""
9+
10+
import time
11+
import board
12+
import displayio
13+
import terminalio
14+
from displayio_dial import Dial
15+
from displayio_effects import WidgetType, colorwheel_effect
16+
17+
# Fonts used for the Dial tick labels
18+
tick_font = terminalio.FONT
19+
20+
display = board.DISPLAY # create the display on the PyPortal or Clue (for example)
21+
# otherwise change this to setup the display
22+
# for display chip driver and pinout you have (e.g. ILI9341)
23+
24+
25+
# Define the minimum and maximum values for the dial
26+
minimum_value = 0
27+
maximum_value = 100
28+
29+
# Hook in the throttle effect for the Dial widget
30+
colorwheel_effect.hook_colorwheel_effect(Dial, WidgetType.DIAL)
31+
32+
# Create a Dial widget
33+
my_dial = Dial(
34+
x=20, # set x-position of the dial inside of my_group
35+
y=20, # set y-position of the dial inside of my_group
36+
width=180, # requested width of the dial
37+
height=180, # requested height of the dial
38+
padding=25, # add 25 pixels around the dial to make room for labels
39+
start_angle=-120, # left angle position at -120 degrees
40+
sweep_angle=240, # total sweep angle of 240 degrees
41+
min_value=minimum_value, # set the minimum value shown on the dial
42+
max_value=maximum_value, # set the maximum value shown on the dial
43+
tick_label_font=tick_font, # the font used for the tick labels
44+
tick_label_scale=2.0, # the scale factor for the tick label font
45+
)
46+
47+
my_group = displayio.Group()
48+
my_group.append(my_dial)
49+
50+
display.show(my_group) # add high level Group to the display
51+
52+
# Set the dial to the value before turning on the fluctuation effect
53+
my_dial.value = 50
54+
55+
while True:
56+
57+
my_dial.update_colorwheel()
58+
time.sleep(0.01)

examples/displayio_effects_gauge.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
# SPDX-License-Identifier: Unlicense
44

55
"""
6-
Create multiple gauge's and change their level.
7-
This works on any CircuitPython device with a built-in display.
6+
Use the random fluctuation effect for the Gauge.
87
"""
98

109

1110
import time
1211
import board
1312
import displayio
1413
from displayio_gauge import Gauge
15-
from displayio_effects import fluctuation_effect
14+
from displayio_effects import WidgetType, fluctuation_effect
1615

1716
display = board.DISPLAY
1817

@@ -27,7 +26,7 @@
2726
main_group.append(bg_sprite)
2827
display.show(main_group)
2928

30-
fluctuation_effect.hook_fluctuation_effect(Gauge, "level")
29+
fluctuation_effect.hook_fluctuation_effect(Gauge, WidgetType.GAUGE)
3130

3231
my_gauge = Gauge(
3332
x=90,

examples/displayio_effects_simpletest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import displayio
1212
import terminalio
1313
from displayio_dial import Dial
14-
from displayio_effects import fluctuation_effect
14+
from displayio_effects import WidgetType, fluctuation_effect
1515

1616
# Fonts used for the Dial tick labels
1717
tick_font = terminalio.FONT
@@ -26,7 +26,7 @@
2626
maximum_value = 100
2727

2828
# Hook in the throttle effect for the Dial widget
29-
fluctuation_effect.hook_fluctuation_effect(Dial, "value")
29+
fluctuation_effect.hook_fluctuation_effect(Dial, WidgetType.DIAL)
3030

3131
# Create a Dial widget
3232
my_dial = Dial(

0 commit comments

Comments
 (0)