Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • flow3r/flow3r-firmware
  • Vespasian/flow3r-firmware
  • alxndr42/flow3r-firmware
  • pl/flow3r-firmware
  • Kari/flow3r-firmware
  • raimue/flow3r-firmware
  • grandchild/flow3r-firmware
  • mu5tach3/flow3r-firmware
  • Nervengift/flow3r-firmware
  • arachnist/flow3r-firmware
  • TheNewCivilian/flow3r-firmware
  • alibi/flow3r-firmware
  • manuel_v/flow3r-firmware
  • xeniter/flow3r-firmware
  • maxbachmann/flow3r-firmware
  • yGifoom/flow3r-firmware
  • istobic/flow3r-firmware
  • EiNSTeiN_/flow3r-firmware
  • gnudalf/flow3r-firmware
  • 999eagle/flow3r-firmware
  • toerb/flow3r-firmware
  • pandark/flow3r-firmware
  • teal/flow3r-firmware
  • x42/flow3r-firmware
  • alufers/flow3r-firmware
  • dos/flow3r-firmware
  • yrlf/flow3r-firmware
  • LuKaRo/flow3r-firmware
  • ThomasElRubio/flow3r-firmware
  • ai/flow3r-firmware
  • T_X/flow3r-firmware
  • highTower/flow3r-firmware
  • beanieboi/flow3r-firmware
  • Woazboat/flow3r-firmware
  • gooniesbro/flow3r-firmware
  • marvino/flow3r-firmware
  • kressnerd/flow3r-firmware
  • quazgar/flow3r-firmware
  • aoid/flow3r-firmware
  • jkj/flow3r-firmware
  • naomi/flow3r-firmware
41 results
Show changes
Commits on Source (6)
from st3m.application import Application, ApplicationContext
from st3m.input import InputController, InputState
from st3m.ui import colours
from st3m.ui.view import ViewManager
from ctx import Context
from .applist import AppList
from .background import Flow3rView
from .record import RecordView
from .manual import ManualInputView
class Gr33nhouseApp(Application):
items = ["Browse apps", "Record App Seed", "Enter App Seed"]
selection = 0
input: InputController
background: Flow3rView
def __init__(self, app_ctx: ApplicationContext) -> None:
super().__init__(app_ctx=app_ctx)
self.input = InputController()
self.background = Flow3rView()
def on_enter(self, vm: ViewManager | None) -> None:
super().on_enter(vm)
if self.vm is None:
raise RuntimeError("vm is None")
def draw(self, ctx: Context) -> None:
self.background.draw(ctx)
ctx.save()
ctx.gray(1.0)
ctx.rectangle(
-120.0,
-15.0,
240.0,
30.0,
).fill()
ctx.translate(0, -30 * self.selection)
offset = 0
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
for idx, item in enumerate(self.items):
if idx == self.selection:
ctx.gray(0.0)
else:
ctx.gray(1.0)
ctx.move_to(0, offset)
ctx.text(item)
offset += 30
ctx.restore()
def think(self, ins: InputState, delta_ms: int) -> None:
self.background.think(ins, delta_ms)
self.input.think(ins, delta_ms)
if self.input.buttons.app.left.pressed:
if self.selection > 0:
self.selection -= 1
elif self.input.buttons.app.right.pressed:
if self.selection < len(self.items) - 1:
self.selection += 1
elif self.input.buttons.app.middle.pressed:
if self.selection == 0:
self.vm.push(AppList())
elif self.selection == 1:
self.vm.push(RecordView())
elif self.selection == 2:
self.vm.push(ManualInputView())
from st3m.goose import Optional, Enum
from st3m.input import InputController, InputState
from st3m.ui import colours
from st3m.ui.view import BaseView, ViewManager
from ctx import Context
import urequests
import time
from .background import Flow3rView
from .confirmation import ConfirmationView
class ViewState(Enum):
INITIAL = 1
LOADING = 2
ERROR = 3
LOADED = 4
class AppList(BaseView):
initial_ticks: int = 0
_state: ViewState = ViewState.INITIAL
apps: list[any] = []
selection: int = 0
input: InputController
background: Flow3rView
def __init__(self) -> None:
self.input = InputController()
self.vm = None
self.background = Flow3rView()
def on_enter(self, vm: Optional[ViewManager]) -> None:
self.vm = vm
self.initial_ticks = time.ticks_ms()
def draw(self, ctx: Context) -> None:
ctx.move_to(0, 0)
if self._state == ViewState.INITIAL or self._state == ViewState.LOADING:
ctx.rgb(*colours.BLACK)
ctx.rectangle(
-120.0,
-120.0,
240.0,
240.0,
).fill()
ctx.save()
ctx.rgb(*colours.WHITE)
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.text("Collecting seeds...")
ctx.restore()
return
elif self._state == ViewState.ERROR:
ctx.rgb(*colours.BLACK)
ctx.rectangle(
-120.0,
-120.0,
240.0,
240.0,
).fill()
ctx.save()
ctx.rgb(*colours.WHITE)
ctx.gray(1.0)
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.text("Something went wrong")
ctx.restore()
return
elif self._state == ViewState.LOADED:
self.background.draw(ctx)
ctx.save()
ctx.gray(1.0)
ctx.rectangle(
-120.0,
-15.0,
240.0,
30.0,
).fill()
ctx.translate(0, -30 * self.selection)
offset = 0
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.move_to(0, 0)
for idx, app in enumerate(self.apps):
if idx == self.selection:
ctx.gray(0.0)
else:
ctx.gray(1.0)
ctx.move_to(0, offset)
ctx.text(app["name"])
offset += 30
ctx.restore()
else:
raise RuntimeError(f"Invalid view state {self._state}")
def think(self, ins: InputState, delta_ms: int) -> None:
if self.initial_ticks == 0 or time.ticks_ms() < self.initial_ticks + 300:
return
self.input.think(ins, delta_ms)
if self._state == ViewState.INITIAL:
try:
self._state = ViewState.LOADING
print("Loading app list...")
res = urequests.get("https://flow3r.garden/api/apps.json")
self.apps = res.json()["apps"]
if self.apps == None:
print(f"Invalid JSON or no apps: {res.json()}")
self._state = ViewState.ERROR
return
self._state = ViewState.LOADED
print("App list loaded")
except Exception as e:
print(f"Load failed: {e}")
self._state = ViewState.ERROR
return
elif self._state == ViewState.LOADING:
raise RuntimeError(f"Invalid view state {self._state}")
elif self._state == ViewState.ERROR:
return
self.background.think(ins, delta_ms)
if self.input.buttons.app.left.pressed:
if self.selection > 0:
self.selection -= 1
elif self.input.buttons.app.right.pressed:
if self.selection < len(self.apps) - 1:
self.selection += 1
elif self.input.buttons.app.middle.pressed:
print(f"state {self._state}")
print(f">> {self.apps[self.selection]}")
app = self.apps[self.selection]
url = app["tarDownloadUrl"]
name = app["name"]
author = app["author"]
# self.vm.push(DownloadView(url))
self.vm.push(
ConfirmationView(
url=url,
name=name,
author=author,
)
)
import random
from st3m.input import InputController, InputState
from st3m.ui.view import BaseView
from ctx import Context
class Flow3rView(BaseView):
input: InputController
def __init__(self) -> None:
self.vm = None
self.input = InputController()
self.flowers = []
for i in range(8):
self.flowers.append(
Flower(
((random.getrandbits(16) - 32767) / 32767.0) * 200,
((random.getrandbits(16)) / 65535.0) * 240 - 120,
((random.getrandbits(16)) / 65535.0) * 400 + 25,
)
)
def think(self, ins: InputState, delta_ms: int) -> None:
super().think(ins, delta_ms)
for c in self.flowers:
c.y += (10 * delta_ms / 1000.0) * 200 / c.z
if c.y > 300:
c.y = -300
c.rot += delta_ms * c.rot_speed
self.flowers = sorted(self.flowers, key=lambda c: -c.z)
def draw(self, ctx: Context) -> None:
ctx.save()
ctx.rectangle(-120, -120, 240, 240)
ctx.rgb(0.1, 0.4, 0.3)
ctx.fill()
for f in self.flowers:
f.draw(ctx)
ctx.restore()
class Flower:
def __init__(self, x: float, y: float, z: float) -> None:
self.x = x
self.y = y
self.z = z
self.rot = 0
self.rot_speed = (((random.getrandbits(16) - 32767) / 32767.0) - 0.5) / 800
def draw(self, ctx: Context):
ctx.save()
ctx.translate(-78 + self.x, -70 + self.y)
ctx.translate(50, 40)
ctx.rotate(self.rot)
ctx.translate(-50, -40)
ctx.scale(100 / self.z, 100.0 / self.z)
ctx.move_to(76.221727, 3.9788409).curve_to(
94.027758, 31.627675, 91.038918, 37.561293, 94.653428, 48.340473
).rel_curve_to(
25.783102, -3.90214, 30.783332, -1.52811, 47.230192, 4.252451
).rel_curve_to(
-11.30184, 19.609496, -21.35729, 20.701768, -35.31018, 32.087063
).rel_curve_to(
5.56219, 12.080061, 12.91196, 25.953973, 9.98735, 45.917643
).rel_curve_to(
-19.768963, -4.59388, -22.879866, -10.12216, -40.896842, -23.93099
).rel_curve_to(
-11.463256, 10.23025, -17.377386, 18.2378, -41.515124, 25.03533
).rel_curve_to(
0.05756, -29.49286, 4.71903, -31.931936, 10.342734, -46.700913
).curve_to(
33.174997, 77.048676, 19.482194, 71.413009, 8.8631648, 52.420793
).curve_to(
27.471602, 45.126773, 38.877997, 45.9184, 56.349456, 48.518302
).curve_to(
59.03275, 31.351935, 64.893201, 16.103886, 76.221727, 3.9788409
).close_path().rgba(
1.0, 0.6, 0.4, 0.4
).fill()
ctx.restore()
return
ctx.move_to(116.89842, 17.221179).rel_curve_to(
6.77406, 15.003357, 9.99904, 35.088466, 0.27033, 47.639569
).curve_to(
108.38621, 76.191194, 87.783414, 86.487988, 75.460015, 75.348373
).curve_to(
64.051094, 64.686361, 61.318767, 54.582827, 67.499384, 36.894251
).curve_to(
79.03955, 16.606134, 103.60918, 15.612261, 116.89842, 17.221179
).close_path().rgb(
0.5, 0.3, 0.4
).fill()
ctx.move_to(75.608612, 4.2453713).curve_to(
85.516707, 17.987709, 93.630911, 33.119248, 94.486497, 49.201225
).curve_to(
95.068862, 60.147617, 85.880014, 75.820834, 74.919761, 75.632395
).curve_to(
63.886159, 75.442695, 57.545631, 61.257211, 57.434286, 50.22254
).curve_to(
57.257291, 32.681814, 65.992688, 16.610811, 75.608612, 4.2453713
).close_path().rgb(
0.2, 0.5, 0.8
).fill()
ctx.restore()
from st3m.input import InputController, InputState
from st3m.ui import colours
from st3m.ui.view import BaseView, ViewManager
from ctx import Context
from .background import Flow3rView
class ConfirmationView(BaseView):
background: Flow3rView
input: InputController
url: str
name: str
author: str
def __init__(self, url: str, name: str, author: str) -> None:
self.input = InputController()
self.vm = None
self.background = Flow3rView()
self.url = url
self.name = name
self.author = author
def on_enter(self, vm: ViewManager | None) -> None:
super().on_enter(vm)
if self.vm is None:
raise RuntimeError("vm is None")
def draw(self, ctx: Context) -> None:
ctx.move_to(0, 0)
self.background.draw(ctx)
ctx.save()
ctx.rgb(*colours.WHITE)
ctx.rectangle(
-120.0,
-80.0,
240.0,
160.0,
).fill()
ctx.rgb(*colours.BLACK)
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.move_to(0, -60)
ctx.text("Install")
ctx.move_to(0, -30)
ctx.text(self.name)
ctx.move_to(0, 0)
ctx.text("by")
ctx.move_to(0, 30)
ctx.text(self.author)
ctx.move_to(0, 60)
ctx.text("?")
ctx.restore()
def think(self, ins: InputState, delta_ms: int) -> None:
self.input.think(ins, delta_ms)
self.background.think(ins, delta_ms)
import network
from st3m.input import InputState
import urequests
import gzip
import utarfile
import io
import os
from st3m.ui.view import BaseView
from ctx import Context
class DownloadView(BaseView):
def __init__(self, url: str) -> None:
super().__init__()
self._state = 1
self._try = 1
self._url = url
def draw(self, ctx: Context) -> None:
ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill()
if self._state == 1 or self._state == 2:
# Fetching
ctx.rgb(255, 0, 0).rectangle(-20, -20, 40, 40).fill()
self._state = 2
elif self._state == 3 or self._state == 4:
# Extracting
ctx.rgb(0, 0, 255).rectangle(-20, -20, 40, 40).fill()
self._state = 4
elif self._state == 5:
# Done
ctx.rgb(0, 255, 0).rectangle(-20, -20, 40, 40).fill()
def think(self, ins: InputState, delta_ms: int) -> None:
super().think(ins, delta_ms) # Let BaseView do its thing
if self._state == 2:
try:
print("Getting it")
self.response = urequests.get(self._url)
if self.response.content is not None:
print("Got something")
self._state = 3
return
print("no content...")
except:
print("Exception")
print("Next try")
self._try += 1
elif self._state == 4:
tar = gzip.decompress(self.response.content)
self.response = None
t = utarfile.TarFile(fileobj=io.BytesIO(tar))
for i in t:
print(i.name)
if i.type == utarfile.DIRTYPE:
print("dirtype")
dirname = "/flash/sys/apps/" + i.name
if not os.path.exists(dirname):
print("making", dirname)
os.mkdir(dirname)
else:
print("dir", dirname, "exists")
else:
filename = "/flash/sys/apps/" + i.name
print("writing to", filename)
f = t.extractfile(i)
with open(filename, "wb") as of:
of.write(f.read())
self._state = 5
self.vm.pop()
[app]
name = "Get Apps"
menu = "Hidden"
[entry]
class = "Gr33nhouseApp"
[metadata]
author = "Flow3r Badge Authors"
license = "LGPL-3.0-only"
url = "https://git.flow3r.garden/flow3r/flow3r-firmware"
from st3m.input import InputController, InputState
from st3m.ui import colours
from st3m.ui.view import BaseView, ViewManager
from ctx import Context
from .background import Flow3rView
class ManualInputView(BaseView):
input: InputController
def __init__(self) -> None:
self.input = InputController()
self.vm = None
self.background = Flow3rView()
def on_enter(self, vm: ViewManager | None) -> None:
super().on_enter(vm)
if self.vm is None:
raise RuntimeError("vm is None")
def draw(self, ctx: Context) -> None:
ctx.move_to(0, 0)
ctx.save()
ctx.rgb(*colours.BLACK)
ctx.rectangle(
-120.0,
-120.0,
240.0,
240.0,
).fill()
ctx.rgb(*colours.WHITE)
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.text("Coming soon")
ctx.restore()
def think(self, ins: InputState, delta_ms: int) -> None:
self.input.think(ins, delta_ms)
from st3m.input import InputController, InputState
from st3m.ui import colours
from st3m.ui.view import BaseView, ViewManager
from ctx import Context
from .background import Flow3rView
class RecordView(BaseView):
input: InputController
def __init__(self) -> None:
self.input = InputController()
self.vm = None
self.background = Flow3rView()
def on_enter(self, vm: ViewManager | None) -> None:
super().on_enter(vm)
if self.vm is None:
raise RuntimeError("vm is None")
def draw(self, ctx: Context) -> None:
ctx.move_to(0, 0)
ctx.save()
ctx.rgb(*colours.BLACK)
ctx.rectangle(
-120.0,
-120.0,
240.0,
240.0,
).fill()
ctx.rgb(*colours.WHITE)
ctx.font = "Camp Font 3"
ctx.font_size = 24
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.text("Coming soon")
ctx.restore()
def think(self, ins: InputState, delta_ms: int) -> None:
self.input.think(ins, delta_ms)
from st3m.run import run_main
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("Camp2023-open")
run_main()
......@@ -121,7 +121,7 @@ class BundleMetadata:
if "menu" not in app or type(app["menu"]) != str:
raise BundleMetadataBroken("missing app.menu key")
self.menu = app["menu"]
if self.menu not in ["Apps", "Music", "Badge"]:
if self.menu not in ["Apps", "Music", "Badge", "Hidden"]:
raise BundleMetadataBroken("app.menu must be either Apps, Music or Badge")
self._t = t
......
......@@ -11,7 +11,7 @@ from st3m.ui.menu import (
from st3m.ui.elements import overlays
from st3m.ui.view import View, ViewManager, ViewTransitionBlend
from st3m.ui.elements.menus import SimpleMenu, SunMenu
from st3m.application import discover_bundles, BundleMetadata
from st3m.application import discover_bundles, BundleMetadata, MenuItemAppLaunch
from st3m.about import About
from st3m import settings, logging, processors, wifi
......@@ -135,6 +135,7 @@ def run_main() -> None:
[
MenuItemBack(),
MenuItemForeground("Settings", menu_settings),
MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/gr33nhouse")),
MenuItemAction("Disk Mode (Flash)", machine.disk_mode_flash),
MenuItemAction("Disk Mode (SD)", machine.disk_mode_sd),
MenuItemLaunchPersistentView("About", About),
......