Skip to content

Commit b1930c7

Browse files
authored
Merge pull request #6 from adafruit/move_editor
Moving editor into apps and more
2 parents a5e9c5a + b9f9f8e commit b1930c7

File tree

10 files changed

+765
-45
lines changed

10 files changed

+765
-45
lines changed

build.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"https://cdn-learn.adafruit.com/downloads/zip/3194658/Metro/Metro_RP2350_FlappyNyanCat.zip?timestamp={}",
1313
"https://cdn-learn.adafruit.com/downloads/zip/3196927/Metro/Metro_RP2350_Match3/match3_game.zip?timestamp={}",
1414
"https://cdn-learn.adafruit.com/downloads/zip/3194422/Metro/Metro_RP2350_Breakout.zip?timestamp={}",
15-
"https://cdn-learn.adafruit.com/downloads/zip/3196755/Metro/Metro_RP2350_Chips_Challenge.zip?timestamp=1746112286",
15+
"https://cdn-learn.adafruit.com/downloads/zip/3196755/Metro/Metro_RP2350_Chips_Challenge.zip?timestamp={}",
1616
]
1717

1818
def create_font_specific_zip(font_path: Path, src_dir: Path, learn_projects_dir: Path, output_dir: Path):
@@ -99,6 +99,9 @@ def create_font_specific_zip(font_path: Path, src_dir: Path, learn_projects_dir:
9999
# Write the file
100100
with open(target, 'wb') as f:
101101
f.write(source.read())
102+
103+
# copy builtin apps
104+
shutil.copytree("builtin_apps", apps_dir, dirs_exist_ok=True)
102105

103106
# Create the final zip file
104107
with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-FileCopyrightText: 2024 Tim Cocks
2+
#
3+
# SPDX-License-Identifier: MIT
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# SPDX-FileCopyrightText: 2023 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import select
6+
import sys
7+
# pylint: disable=no-self-use
8+
9+
try:
10+
import termios
11+
12+
_orig_attr = None # pylint: disable=invalid-name
13+
14+
def _nonblocking():
15+
global _orig_attr # pylint: disable=global-statement
16+
_orig_attr = termios.tcgetattr(sys.stdin)
17+
attr = termios.tcgetattr(sys.stdin)
18+
attr[3] &= ~(termios.ECHO | termios.ICANON)
19+
attr[6][termios.VMIN] = 1
20+
attr[6][termios.VTIME] = 0
21+
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, attr)
22+
23+
def _blocking():
24+
if _orig_attr is not None:
25+
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, _orig_attr)
26+
27+
except ImportError:
28+
29+
def _nonblocking():
30+
pass
31+
32+
def _blocking():
33+
pass
34+
35+
36+
# LINES = 24
37+
# COLS = 80
38+
39+
LINES = 33
40+
COLS = 120
41+
42+
special_keys = {
43+
"\x1b": ..., # all prefixes of special keys must be entered as Ellipsis
44+
"\x1b[": ...,
45+
"\x1b[3": ...,
46+
"\x1b[5": ...,
47+
"\x1b[6": ...,
48+
"\x1b[A": "KEY_UP",
49+
"\x1b[B": "KEY_DOWN",
50+
"\x1b[C": "KEY_RIGHT",
51+
"\x1b[D": "KEY_LEFT",
52+
"\x1b[H": "KEY_HOME",
53+
"\x1b[F": "KEY_END",
54+
"\x1b[5~": "KEY_PGUP",
55+
"\x1b[6~": "KEY_PGDN",
56+
"\x1b[3~": "KEY_DELETE",
57+
}
58+
59+
60+
class Screen:
61+
def __init__(self, terminal=None):
62+
self._poll = select.poll()
63+
self._poll.register(sys.stdin, select.POLLIN)
64+
self._pending = ""
65+
self._terminal = terminal
66+
67+
def _sys_stdin_readable(self):
68+
return hasattr(sys.stdin, "readable") and sys.stdin.readable()
69+
70+
def _sys_stdout_flush(self):
71+
if hasattr(sys.stdout, "flush"):
72+
sys.stdout.flush()
73+
74+
def _terminal_read_blocking(self):
75+
return sys.stdin.read(1)
76+
77+
def _terminal_read_timeout(self, timeout):
78+
if self._sys_stdin_readable() or self._poll.poll(timeout):
79+
r = sys.stdin.read(1)
80+
return r
81+
return None
82+
83+
def move(self, y, x):
84+
if self._terminal is not None:
85+
self._terminal.write(f"\033[{y+1};{x+1}H")
86+
else:
87+
print(end=f"\033[{y+1};{x+1}H")
88+
89+
def erase(self):
90+
if self._terminal is not None:
91+
self._terminal.write("\033H\033[2J")
92+
else:
93+
print(end="\033H\033[2J")
94+
95+
def addstr(self, y, x, text):
96+
self.move(y, x)
97+
if self._terminal is not None:
98+
self._terminal.write(text)
99+
else:
100+
print(end=text)
101+
102+
def getkey(self):
103+
self._sys_stdout_flush()
104+
pending = self._pending
105+
if pending and (code := special_keys.get(pending)) is None:
106+
self._pending = pending[1:]
107+
return pending[0]
108+
109+
while True:
110+
if pending:
111+
c = self._terminal_read_timeout(50)
112+
if c is None:
113+
self._pending = pending[1:]
114+
return pending[0]
115+
else:
116+
c = self._terminal_read_blocking()
117+
c = pending + c
118+
119+
code = special_keys.get(c)
120+
121+
if code is None:
122+
self._pending = c[1:]
123+
return c[0]
124+
if code is not Ellipsis:
125+
return code
126+
127+
pending = c
128+
129+
130+
def wrapper(func, *args, **kwds):
131+
stdscr = Screen()
132+
try:
133+
_nonblocking()
134+
return func(stdscr, *args, **kwds)
135+
finally:
136+
_blocking()
137+
stdscr.move(LINES - 1, 0)
138+
print("\n")
139+
140+
def custom_terminal_wrapper(terminal, func, *args, **kwds):
141+
stdscr = Screen(terminal)
142+
try:
143+
_nonblocking()
144+
return func(stdscr, *args, **kwds)
145+
finally:
146+
_blocking()
147+
stdscr.move(LINES - 1, 0)
148+
print("\n")

0 commit comments

Comments
 (0)