Skip to content

Instantly share code, notes, and snippets.

@demodude4u
Created March 3, 2023 00:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demodude4u/603f3bb63a8cad48e45186a64edd05c4 to your computer and use it in GitHub Desktop.
Save demodude4u/603f3bb63a8cad48e45186a64edd05c4 to your computer and use it in GitHub Desktop.
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