Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions library/lcd/lcd_comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,150 @@ def DisplayProgressBar(self, x: int, y: int, width: int, height: int, min_value:
draw.rectangle([0, 0, width - 1, height - 1], fill=None, outline=bar_color)

self.DisplayPILImage(bar_image, x, y)

def DisplayRadialProgressBar(self, xc: int, yc: int, radius: int, bar_width: int,
min_value: int = 0,
max_value: int = 100,
angle_start: int = 0,
angle_end: int = 360,
angle_sep: int = 5,
angle_steps: int = 10,
clockwise: bool = True,
value: int = 50,
text: str = None,
with_text: bool = True,
font: str = "roboto/Roboto-Black.ttf",
font_size: int = 20,
font_color: Tuple[int, int, int] = (0, 0, 0),
bar_color: Tuple[int, int, int] = (0, 0, 0),
background_color: Tuple[int, int, int] = (255, 255, 255),
background_image: str = None):
# Generate a radial progress bar and display it
# Provide the background image path to display progress bar with transparent background

if isinstance(bar_color, str):
bar_color = tuple(map(int, bar_color.split(', ')))

if isinstance(background_color, str):
background_color = tuple(map(int, background_color.split(', ')))

if isinstance(font_color, str):
font_color = tuple(map(int, font_color.split(', ')))

assert xc - radius >= 0 and xc + radius <= self.get_width(), 'Progress bar width exceeds display width'
assert yc - radius >= 0 and yc + radius <= self.get_height(), 'Progress bar height exceeds display height'
assert 0 < bar_width <= radius, 'Progress bar linewidth must be > 0 and <= radius'
assert angle_end % 361 != angle_start % 361, 'Change your angles values'
assert isinstance(angle_steps, int), 'angle_steps value must be an integer'
assert angle_sep >= 0, 'Provide an angle_sep value >= 0'
assert angle_steps > 0, 'Provide an angle_step value > 0'
assert angle_sep * angle_steps < 360, 'Given angle_sep and angle_steps values are not correctly set'

# Don't let the set value exceed our min or max value, this is bad :)
if value < min_value:
value = min_value
elif max_value < value:
value = max_value

assert min_value <= value <= max_value, 'Progress bar value shall be between min and max'

diameter = 2 * radius
bbox = (xc - radius, yc - radius, xc + radius, yc + radius)
#
if background_image is None:
# A bitmap is created with solid background
bar_image = Image.new('RGB', (diameter, diameter), background_color)
else:
# A bitmap is created from provided background image
bar_image = Image.open(background_image)

# Crop bitmap to keep only the progress bar background
bar_image = bar_image.crop(box=bbox)

# Draw progress bar
pct = (value - min_value)/(max_value - min_value)
draw = ImageDraw.Draw(bar_image)

# PIL arc method uses angles with
# . 3 o'clock for 0
# . clockwise from angle start to angle end
angle_start %= 361
angle_end %= 361
#
if clockwise:
if angle_end < angle_start:
ecart = 360 - angle_start + angle_end
else:
ecart = angle_end - angle_start
#
# solid bar case
if angle_sep == 0:
if angle_end < angle_start:
angleE = angle_start + pct * ecart
angleS = angle_start
else:
angleS = angle_start
angleE = angle_start + pct * ecart
draw.arc([0, 0, diameter - 1, diameter - 1], angleS, angleE,
fill=bar_color, width=bar_width)
# discontinued bar case
else:
angleE = angle_start + pct * ecart
angle_complet = ecart / angle_steps
etapes = int((angleE - angle_start) / angle_complet)
for i in range(etapes):
draw.arc([0, 0, diameter - 1, diameter - 1],
angle_start + i * angle_complet,
angle_start + (i + 1) * angle_complet - angle_sep,
fill=bar_color,
width=bar_width)

draw.arc([0, 0, diameter - 1, diameter - 1],
angle_start + etapes * angle_complet,
angleE,
fill=bar_color,
width=bar_width)
else:
if angle_end < angle_start:
ecart = angle_start - angle_end
else:
ecart = 360 - angle_end + angle_start
# solid bar case
if angle_sep == 0:
if angle_end < angle_start:
angleE = angle_start
angleS = angle_start - pct * ecart
else:
angleS = angle_start - pct * ecart
angleE = angle_start
draw.arc([0, 0, diameter - 1, diameter - 1], angleS, angleE,
fill=bar_color, width=bar_width)
# discontinued bar case
else:
angleS = angle_start - pct * ecart
angle_complet = ecart / angle_steps
etapes = int((angle_start - angleS) / angle_complet)
for i in range(etapes):
draw.arc([0, 0, diameter - 1, diameter - 1],
angle_start - (i + 1) * angle_complet + angle_sep,
angle_start - i * angle_complet,
fill=bar_color,
width=bar_width)

draw.arc([0, 0, diameter - 1, diameter - 1],
angleS,
angle_start - etapes * angle_complet,
fill=bar_color,
width=bar_width)

# Draw text
if with_text:
if text is None:
text = f"{int(pct * 100 + .5)}%"
font = ImageFont.truetype("./res/fonts/" + font, font_size)
left, top, right, bottom = font.getbbox(text)
w, h = right - left, bottom - top
draw.text((radius - w / 2, radius - top - h / 2), text,
font=font, fill=font_color)

self.DisplayPILImage(bar_image, xc - radius, yc - radius)
Binary file modified res/themes/3.5inchTheme2/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/BigClock/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/Cyberpunk-net/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/Cyberpunk/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/LandscapeEarth/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/LandscapeMagicBlue/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/Terminal/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/bash-dark-green-gpu/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified res/themes/bash-dark-green/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions simple-program.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ def sighandler(signum, frame):
bar_color=(0, 255, 0), bar_outline=False,
background_image=background)

lcd_comm.DisplayRadialProgressBar(98, 320, 25, 4,
min_value=0,
max_value=100,
value=bar_value,
angle_sep=0,
bar_color=(0, 255, 0),
font_color=(255, 255, 255),
background_image=background)

lcd_comm.DisplayRadialProgressBar(222, 320, 40, 13,
min_value=0,
max_value=100,
angle_start=405,
angle_end=135,
angle_steps=10,
angle_sep=5,
clockwise=False,
value=bar_value,
bar_color=(255, 255, 0),
text=f"{10 * int(bar_value / 10)}°C",
font="geforce/GeForce-Bold.ttf",
font_size=20,
font_color=(255, 255, 0),
background_image=background)

bar_value = (bar_value + 2) % 101

# Close serial connection at exit
Expand Down