-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
183 lines (145 loc) · 6.01 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import time
import badger2040
import badger_os
# Global Constants
WIDTH = badger2040.WIDTH
HEIGHT = badger2040.HEIGHT
IMAGE_WIDTH = 104
COMPANY_HEIGHT = 30
DETAILS_HEIGHT = 20
NAME_HEIGHT = HEIGHT - COMPANY_HEIGHT - (DETAILS_HEIGHT * 2) - 2
TEXT_WIDTH = WIDTH - IMAGE_WIDTH - 1
COMPANY_TEXT_SIZE = 0.6
DETAILS_TEXT_SIZE = 0.5
LEFT_PADDING = 5
NAME_PADDING = 20
DETAIL_SPACING = 10
DEFAULT_TEXT = """mustelid inc
H. Badger
RP2040
2MB Flash
E ink
296x128px"""
BADGE_IMAGE = bytearray(int(IMAGE_WIDTH * HEIGHT / 8))
try:
open("badge-image.bin", "rb").readinto(BADGE_IMAGE)
except OSError:
try:
import badge_image
BADGE_IMAGE = bytearray(badge_image.data())
del badge_image
except ImportError:
pass
# ------------------------------
# Utility functions
# ------------------------------
# Reduce the size of a string until it fits within a given width
def truncatestring(text, text_size, width):
while True:
length = display.measure_text(text, text_size)
if length > 0 and length > width:
text = text[:-1]
else:
text += ""
return text
# ------------------------------
# Drawing functions
# ------------------------------
# Draw the badge, including user text
def draw_badge():
display.pen(0)
display.clear()
# Draw badge image
display.image(BADGE_IMAGE, IMAGE_WIDTH, HEIGHT, WIDTH - IMAGE_WIDTH, 0)
# Draw a border around the image
display.pen(0)
display.thickness(1)
display.line(WIDTH - IMAGE_WIDTH, 0, WIDTH - 1, 0)
display.line(WIDTH - IMAGE_WIDTH, 0, WIDTH - IMAGE_WIDTH, HEIGHT - 1)
display.line(WIDTH - IMAGE_WIDTH, HEIGHT - 1, WIDTH - 1, HEIGHT - 1)
display.line(WIDTH - 1, 0, WIDTH - 1, HEIGHT - 1)
# Uncomment this if a white background is wanted behind the company
# display.pen(15)
# display.rectangle(1, 1, TEXT_WIDTH, COMPANY_HEIGHT - 1)
# Draw the company
display.pen(15) # Change this to 0 if a white background is used
display.font("sans")
display.thickness(1)
display.text(company, LEFT_PADDING, (COMPANY_HEIGHT // 2) + 1, COMPANY_TEXT_SIZE)
# Draw a white background behind the name
display.pen(15)
display.thickness(1)
display.rectangle(1, COMPANY_HEIGHT + 1, TEXT_WIDTH, NAME_HEIGHT)
# Draw the name, scaling it based on the available width
display.pen(0)
display.font("sans")
display.thickness(4)
name_size = 2.0 # A sensible starting scale
while True:
name_length = display.measure_text(name, name_size)
if name_length >= (TEXT_WIDTH - NAME_PADDING) and name_size >= 0.1:
name_size -= 0.01
else:
display.text(name, (TEXT_WIDTH - name_length) // 2, (NAME_HEIGHT // 2) + COMPANY_HEIGHT + 1, name_size)
break
# Draw a white backgrounds behind the details
display.pen(15)
display.thickness(1)
display.rectangle(1, HEIGHT - DETAILS_HEIGHT * 2, TEXT_WIDTH, DETAILS_HEIGHT - 1)
display.rectangle(1, HEIGHT - DETAILS_HEIGHT, TEXT_WIDTH, DETAILS_HEIGHT - 1)
# Draw the first detail's title and text
display.pen(0)
display.font("sans")
display.thickness(1)
name_length = display.measure_text(detail1_title, DETAILS_TEXT_SIZE)
display.text(detail1_title, LEFT_PADDING, HEIGHT - ((DETAILS_HEIGHT * 3) // 2), DETAILS_TEXT_SIZE)
display.thickness(1)
display.text(detail1_text, 5 + name_length + DETAIL_SPACING, HEIGHT - ((DETAILS_HEIGHT * 3) // 2), DETAILS_TEXT_SIZE)
# Draw the second detail's title and text
display.thickness(1)
name_length = display.measure_text(detail2_title, DETAILS_TEXT_SIZE)
display.text(detail2_title, LEFT_PADDING, HEIGHT - (DETAILS_HEIGHT // 2), DETAILS_TEXT_SIZE)
display.thickness(2)
display.text(detail2_text, LEFT_PADDING + name_length + DETAIL_SPACING, HEIGHT - (DETAILS_HEIGHT // 2), DETAILS_TEXT_SIZE)
# ------------------------------
# Program setup
# ------------------------------
# Create a new Badger and set it to update NORMAL
display = badger2040.Badger2040()
display.led(128)
display.update_speed(badger2040.UPDATE_NORMAL)
# Open the badge file
try:
badge = open("badge.txt", "r")
except OSError:
with open("badge.txt", "w") as f:
f.write(DEFAULT_TEXT)
f.flush()
badge = open("badge.txt", "r")
# Read in the next 6 lines
company = badge.readline() # "mustelid inc"
name = badge.readline() # "H. Badger"
detail1_title = badge.readline() # "RP2040"
detail1_text = badge.readline() # "2MB Flash"
detail2_title = badge.readline() # "E ink"
detail2_text = badge.readline() # "296x128px"
# Truncate all of the text (except for the name as that is scaled)
company = truncatestring(company, COMPANY_TEXT_SIZE, TEXT_WIDTH)
detail1_title = truncatestring(detail1_title, DETAILS_TEXT_SIZE, TEXT_WIDTH)
detail1_text = truncatestring(detail1_text, DETAILS_TEXT_SIZE,
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail1_title, DETAILS_TEXT_SIZE))
detail2_title = truncatestring(detail2_title, DETAILS_TEXT_SIZE, TEXT_WIDTH)
detail2_text = truncatestring(detail2_text, DETAILS_TEXT_SIZE,
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail2_title, DETAILS_TEXT_SIZE))
# ------------------------------
# Main program
# ------------------------------
draw_badge()
while True:
if display.pressed(badger2040.BUTTON_A) or display.pressed(badger2040.BUTTON_B) or display.pressed(badger2040.BUTTON_C) or display.pressed(badger2040.BUTTON_UP) or display.pressed(badger2040.BUTTON_DOWN):
badger_os.warning(display, "To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt")
time.sleep(4)
draw_badge()
display.update()
# If on battery, halt the Badger to save power, it will wake up if any of the front buttons are pressed
display.halt()