Created
March 3, 2023 00:45
-
-
Save demodude4u/603f3bb63a8cad48e45186a64edd05c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sys import path as syspath # NOQA | |
syspath.insert(0, '/Games/FileExplore') # NOQA | |
from time import sleep_ms | |
from os import ilistdir | |
from thumbyGraphics import display | |
from thumbyButton import buttonA, buttonB, buttonU, buttonD, buttonL, buttonR | |
MASK_U = 0x1 | |
MASK_D = 0x2 | |
MASK_L = 0x4 | |
MASK_R = 0x8 | |
MASK_A = 0x10 | |
MASK_B = 0x20 | |
MASK_ALL = 0x3F | |
MASK_DPAD = 0xF | |
MASK_NONE = 0x0 | |
pollRate = 20 | |
repeatingDelay = 500 | |
repeatingRate = 100 | |
def waitInput(mask=MASK_ALL, repeating=MASK_NONE): | |
buttonA.latchedPress = False | |
buttonB.latchedPress = False | |
buttonU.latchedPress = False | |
buttonD.latchedPress = False | |
buttonL.latchedPress = False | |
buttonR.latchedPress = False | |
while True: | |
if mask & MASK_A and _waitInput_button(buttonA, repeating & MASK_A): | |
return | |
if mask & MASK_B and _waitInput_button(buttonB, repeating & MASK_B): | |
return | |
if mask & MASK_U and _waitInput_button(buttonU, repeating & MASK_U): | |
return | |
if mask & MASK_D and _waitInput_button(buttonD, repeating & MASK_D): | |
return | |
if mask & MASK_L and _waitInput_button(buttonL, repeating & MASK_L): | |
return | |
if mask & MASK_R and _waitInput_button(buttonR, repeating & MASK_R): | |
return | |
sleep_ms(pollRate) | |
def _waitInput_button(button, repeating): | |
button.update() | |
if button.latchedPress: | |
return True | |
if button.pressed() and repeating: | |
button.repeatDuration += pollRate | |
if button.repeatDuration - repeatingDelay > repeatingRate: | |
button.repeatDuration -= repeatingRate | |
button.latchedPress = True | |
return True | |
else: | |
button.repeatDuration = 0 | |
return False | |
class Console: | |
def __init__(self): | |
self.inverted = False | |
self.x = 0 | |
self.y = 0 | |
self.fontID = None | |
self.font5() | |
def _font(self, id, path, w, h, p): | |
if self.fontID == id: | |
return | |
display.setFont(path, w, h, p) | |
self.charWidth = w + 1 | |
self.charHeight = h + 1 | |
self.columns = 72 // self.charWidth | |
self.rows = 40 // self.charHeight | |
self.fontID = id | |
def font5(self): | |
self._font(5, "/lib/font3x5.bin", 3, 5, 1) | |
return self | |
def font7(self): | |
self._font(7, "/lib/font5x7.bin", 5, 7, 1) | |
return self | |
def font8(self): | |
self._font(8, "/lib/font8x8.bin", 8, 8, 1) | |
return self | |
def cls(self): | |
display.fill(0) | |
self.x = 0 | |
self.y = 0 | |
return self | |
def offsetX(self, dx): | |
self.x += dx | |
return self | |
def offsetY(self, dy): | |
self.y += dy | |
return self | |
def invert(self, set=None): | |
if set is None: | |
self.inverted = not self.inverted | |
else: | |
self.inverted = set | |
return self | |
def write(self, text): | |
if self.x < 72 and self.y < 40: | |
length = len(text) | |
if self.inverted: | |
display.drawFilledRectangle( | |
self.x, self.y, self.charWidth * length, self.charHeight, 1) | |
display.drawText(text, self.x, self.y, 0 if self.inverted else 1) | |
self.x += self.charWidth * length | |
return self | |
def nextLine(self): | |
if self.x < 72 and self.y < 40: | |
display.drawFilledRectangle( | |
self.x, self.y, 72 - self.x, self.charHeight, 1 if self.inverted else 0) | |
self.x = 0 | |
self.y += self.charHeight | |
return self | |
def show(self): | |
display.display.show() | |
console = Console() | |
def explore(folder): | |
if not folder.endswith("/"): | |
folder = folder + "/" | |
files = list(ilistdir(folder)) | |
scroll = 0 | |
highlight = 0 | |
while True: | |
console.cls().font5() | |
console.invert(True).write( | |
folder[-console.columns:]).nextLine().invert() | |
console.offsetY(1) | |
count = len(files) | |
highlight = max(0, min(count-1, highlight)) | |
scroll = max(highlight - console.rows + 2, min(highlight, scroll)) | |
i = scroll | |
end = min(i + console.rows - 1, count) | |
while i < end: | |
if i == highlight: | |
console.invert() | |
console.write(files[i][0]).invert(False).nextLine() | |
i += 1 | |
console.show() | |
waitInput(MASK_U | MASK_D | MASK_A | MASK_B, MASK_U | MASK_D) | |
if buttonU.justPressed(): | |
highlight -= 1 | |
if buttonD.justPressed(): | |
highlight += 1 | |
if buttonB.justPressed(): | |
return | |
if buttonA.justPressed(): | |
name, type, _, size = files[highlight] | |
path = folder + name | |
if type & 0x4000: # Folder | |
explore(path) | |
if type & 0x8000: # File | |
viewText(path) | |
files = list(ilistdir(folder)) | |
def viewText(file): | |
# TODO read in memory, do not copy | |
lines = open(file, "r").readlines() | |
scrollX, scrollY = 0, 0 | |
highlightX, highlightY = 0, 0 | |
while True: | |
console.cls().font5() | |
console.invert(True).write(file[-console.columns:]).nextLine().invert() | |
console.offsetY(1) | |
countY = len(lines) | |
y = scrollY | |
endY = min(y + console.rows - 1, countY) | |
while y < endY: | |
if y == highlightY and highlightX >= scrollX: | |
console.write(lines[y][scrollX:highlightX]) | |
console.invert().write( | |
lines[y][highlightX:highlightX+1]).invert() | |
console.write(lines[y][highlightX+1:]) | |
else: | |
console.write(lines[y][scrollX:]) | |
console.nextLine() | |
y += 1 | |
console.show() | |
waitInput(MASK_ALL, MASK_DPAD) | |
if buttonU.justPressed(): | |
highlightY -= 1 | |
highlightY = max(0, min(countY-1, highlightY)) | |
scrollY = max(highlightY - console.rows + | |
2, min(highlightY, scrollY)) | |
if buttonD.justPressed(): | |
highlightY += 1 | |
highlightY = max(0, min(countY-1, highlightY)) | |
scrollY = max(highlightY - console.rows + | |
2, min(highlightY, scrollY)) | |
if buttonL.justPressed(): | |
highlightX -= 1 | |
highlightX = max(0, min(len(lines[highlightY])-1, highlightX)) | |
scrollX = max(highlightX - console.columns + | |
1, min(highlightX, scrollX)) | |
if buttonR.justPressed(): | |
highlightX += 1 | |
highlightX = max(0, min(len(lines[highlightY])-1, highlightX)) | |
scrollX = max(highlightX - console.columns + | |
1, min(highlightX, scrollX)) | |
if buttonB.justPressed(): | |
return | |
if buttonA.justPressed(): | |
pass | |
explore("/") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment