Settings app
parent
f7fefaa331
commit
0f3c2c0e7c
|
@ -6,22 +6,22 @@ To publish apps use https://badge.emfcamp.org"""
|
|||
|
||||
___license___ = "MIT"
|
||||
___title___ = "Badge Store"
|
||||
___dependencies___ = ["badge_store", "dialogs", "ugfx_helper", "app"]
|
||||
___dependencies___ = ["badge_store", "dialogs", "ugfx_helper", "app", "database"]
|
||||
___categories___ = ["System"]
|
||||
___bootstrapped___ = True
|
||||
|
||||
import ugfx_helper
|
||||
import os
|
||||
import wifi
|
||||
import ugfx_helper, os, database, wifi, app
|
||||
from dialogs import *
|
||||
import app
|
||||
from lib.badge_store import BadgeStore
|
||||
|
||||
### VIEWS ###
|
||||
|
||||
ugfx_helper.init()
|
||||
|
||||
store = BadgeStore()
|
||||
url = database.get("badge_store.url", "http://badgeserver.emfcamp.org/2018")
|
||||
repo = database.get("badge_store.repo", "emfcamp/Mk4-Apps")
|
||||
ref = database.get("badge_store.ref", "master")
|
||||
store = BadgeStore(url=url, repo=repo, ref=ref)
|
||||
title = "TiLDA Badge Store"
|
||||
|
||||
def clear():
|
||||
|
|
|
@ -66,7 +66,7 @@ def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width
|
|||
if button_no: button_no.destroy()
|
||||
label.destroy()
|
||||
|
||||
def prompt_text(description, init_text = "", true_text="OK", false_text="Back", font=FONT_MEDIUM_BOLD, style=default_style_badge):
|
||||
def prompt_text(description, init_text="", true_text="OK", false_text="Back", font=FONT_MEDIUM_BOLD, style=default_style_badge):
|
||||
"""Shows a dialog and keyboard that allows the user to input/change a string
|
||||
|
||||
Returns None if user aborts with button B
|
||||
|
@ -119,7 +119,7 @@ def prompt_text(description, init_text = "", true_text="OK", false_text="Back",
|
|||
edit.destroy();
|
||||
return
|
||||
|
||||
def prompt_option(options, index=0, text = "Please select one of the following:", title=None, select_text="OK", none_text=None):
|
||||
def prompt_option(options, index=0, text = None, title=None, select_text="OK", none_text=None):
|
||||
"""Shows a dialog prompting for one of multiple options
|
||||
|
||||
If none_text is specified the user can use the B or Menu button to skip the selection
|
||||
|
@ -133,12 +133,15 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
|||
if title:
|
||||
window.text(5, 10, title, TILDA_COLOR)
|
||||
window.line(0, 25, ugfx.width() - 10, 25, ugfx.BLACK)
|
||||
window.text(5, 30, text, ugfx.BLACK)
|
||||
list_y = 50
|
||||
list_y = 30
|
||||
if text:
|
||||
list_y += 20
|
||||
window.text(5, 30, text, ugfx.BLACK)
|
||||
|
||||
else:
|
||||
window.text(5, 10, text, ugfx.BLACK)
|
||||
|
||||
options_list = ugfx.List(5, list_y, ugfx.width() - 25, 180 - list_y, parent = window)
|
||||
options_list = ugfx.List(5, list_y, ugfx.width() - 25, 260 - list_y, parent = window)
|
||||
|
||||
for option in options:
|
||||
if isinstance(option, dict) and option["title"]:
|
||||
|
@ -151,8 +154,8 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
|||
if none_text:
|
||||
none_text = "B: " + none_text
|
||||
|
||||
button_select = ugfx.Button(5, ugfx.height() - 50, 140 if none_text else ugfx.width() - 25, 30 , select_text, parent=window)
|
||||
button_none = ugfx.Button(ugfx.width() - 160, ugfx.height() - 50, 140, 30 , none_text, parent=window) if none_text else None
|
||||
button_select = ugfx.Button(5, ugfx.height() - 50, 105 if none_text else 200, 30 , select_text, parent=window)
|
||||
button_none = ugfx.Button(117, ugfx.height() - 50, 105, 30 , none_text, parent=window) if none_text else None
|
||||
|
||||
try:
|
||||
while True:
|
||||
|
@ -180,7 +183,7 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
|||
|
||||
class WaitingMessage:
|
||||
"""Shows a dialog with a certain message that can not be dismissed by the user"""
|
||||
def __init__(self, text = "Please Wait...", title="TiLDA"):
|
||||
def __init__(self, text="Please Wait...", title="TiLDA"):
|
||||
self.window = ugfx.Container(30, 30, ugfx.width() - 60, ugfx.height() - 60)
|
||||
self.window.show()
|
||||
self.window.text(5, 10, title, TILDA_COLOR)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Library for sleep related functions"""
|
||||
|
||||
___license___ = "MIT"
|
||||
|
||||
import time
|
||||
|
||||
def sleep_ms(duration):
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
"""A stack-based naviation system.
|
||||
|
||||
Maintains a stack of states through which a user can navigate.
|
||||
Think Android's back button model.
|
||||
|
||||
Every screen is modeled as a function that takes one argument "state".
|
||||
It can modify state and should either return
|
||||
* None (which means go back one level)
|
||||
* A new function (which adds to the stack)
|
||||
* A keyword like NEXT_EXIT (exit nav) or NEXT_TOP (go to top of stack)
|
||||
|
||||
Children get a a shallow clone of the current state, going back will
|
||||
lead to a screen with the original state.
|
||||
"""
|
||||
|
||||
___dependencies___ = ["dialogs", "database"]
|
||||
___license___ = "MIT"
|
||||
|
||||
import dialogs, database
|
||||
|
||||
NEXT_EXIT = "exit" # Leave navigation
|
||||
NEXT_TOP = "init" # Go to top of stack
|
||||
def nav(init_fn, init_state={}):
|
||||
stack = [(init_fn, init_state)]
|
||||
while stack:
|
||||
(fn, state) = stack[-1] # peek
|
||||
next_state = state.copy()
|
||||
result = fn(next_state)
|
||||
if callable(result):
|
||||
stack.append((result, next_state))
|
||||
elif result == NEXT_TOP:
|
||||
stack = [(init_fn, init_state)]
|
||||
elif result == NEXT_EXIT:
|
||||
break
|
||||
else:
|
||||
stack.pop()
|
||||
|
||||
# A simple menu. Format of items is [{"foo":fn}, ...]
|
||||
def selection(items, title="Settings", none_text="Back"):
|
||||
items = [{"title": t, "function": fn} for (t, fn) in items.items()]
|
||||
selection = dialogs.prompt_option(items, none_text=none_text, title=title)
|
||||
if selection:
|
||||
return selection["function"]
|
||||
else:
|
||||
return None
|
||||
|
||||
# A wrapper for a simple string menu
|
||||
def change_string(title, getter_setter_function):
|
||||
def inner(state):
|
||||
value = getter_setter_function()
|
||||
value = dialogs.prompt_text(title, init_text=value, true_text="Change", false_text="Back")
|
||||
if value:
|
||||
getter_setter_function(value)
|
||||
return inner
|
||||
|
||||
# A wrapper for a database key
|
||||
def change_database_string(title, key, default=""):
|
||||
def inner(state):
|
||||
value = database.get(key, default)
|
||||
value = dialogs.prompt_text(title, init_text=value, true_text="Change", false_text="Back")
|
||||
if value:
|
||||
database.set(key, value)
|
||||
return inner
|
|
@ -0,0 +1,9 @@
|
|||
from stack_nav import *
|
||||
from database import *
|
||||
|
||||
def settings_badge_store(state):
|
||||
return selection({
|
||||
("API: %s" % get("badge_store.url", "http://badgeserver.emfcamp.org/2018")): change_database_string("Set API", "badge_store.url", "http://badgeserver.emfcamp.org/2018"),
|
||||
("Repo: %s" % get("badge_store.repo", "emfcamp/Mk4-Apps")): change_database_string("Git repository", "badge_store.repo", "emfcamp/Mk4-Apps"),
|
||||
("Ref: %s" % get("badge_store.ref", "master")): change_database_string("Set branch, tag or commit", "badge_store.ref", "master")
|
||||
}, "Badge store settings")
|
|
@ -6,71 +6,41 @@ Currently supports
|
|||
* Pick default app
|
||||
* Change badgestore repo/branch
|
||||
|
||||
Todo:
|
||||
* timezone
|
||||
|
||||
"""
|
||||
|
||||
___name___ = "Settings"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["dialogs", "ugfx_helper", "database"]
|
||||
___dependencies___ = ["dialogs", "ugfx_helper", "database", "app", "stack_nav", "wifi"]
|
||||
___categories___ = ["System"]
|
||||
___bootstrapped___ = True
|
||||
|
||||
import ugfx_helper, os, wifi, app, database
|
||||
from settings.badge_store_settings import settings_badge_store
|
||||
from dialogs import *
|
||||
from stack_nav import *
|
||||
|
||||
### VIEWS ###
|
||||
|
||||
ugfx_helper.init()
|
||||
|
||||
title = "Settings"
|
||||
|
||||
def clear():
|
||||
ugfx.clear(ugfx.html_color(ugfx.WHITE))
|
||||
|
||||
def settings_name(state):
|
||||
pass
|
||||
|
||||
### SCREENS ###
|
||||
def settings_startup_app(state):
|
||||
pass
|
||||
apps = app.get_apps()
|
||||
print(apps)
|
||||
selection = prompt_option([{"title": a.title, "app": a} for a in apps], text="Select App:", none_text="Back", title="Set startup app")
|
||||
if selection:
|
||||
app.write_launch_file(app.name, "default_app.txt")
|
||||
|
||||
def settings_wifi(state):
|
||||
pass
|
||||
|
||||
def settings_badge_store(state):
|
||||
pass
|
||||
wifi.choose_wifi()
|
||||
|
||||
def settings_main(state):
|
||||
menu_items = [
|
||||
{"title": "Change Name", "function": settings_name},
|
||||
{"title": "Wifi", "function": settings_wifi},
|
||||
{"title": "Set startup app", "function": settings_startup_app},
|
||||
{"title": "Change Badge Store", "function": settings_badge_store}
|
||||
]
|
||||
return selection({
|
||||
"Homescreeen Name": change_database_string("Set your name", "name"),
|
||||
"Wifi": settings_wifi,
|
||||
"Startup app": settings_startup_app,
|
||||
"Badge Store": settings_badge_store
|
||||
}, none_text="Exit")
|
||||
|
||||
return prompt_option(menu_items, none_text="Exit", text="What do you want to do?", title=title)
|
||||
|
||||
# Todo: this might be useful in a lib
|
||||
|
||||
# A stack-based naviation system.
|
||||
NEXT_EXIT = "exit" # Leave navigation
|
||||
NEXT_INIT = "init" # Go to top of stack
|
||||
def nav(init_fn, init_state={}):
|
||||
stack = [(init_fn, init_state)]
|
||||
|
||||
while len(stack):
|
||||
(fn, state) = stack[-1] # peek
|
||||
next_state = state.clone()
|
||||
print(next_state)
|
||||
result = fn(next_state)
|
||||
if callable(result):
|
||||
stack.append((result, next_state))
|
||||
elif result == NEXT_INIT:
|
||||
stack = [(init_fn, init_state)]
|
||||
elif result == NEXT_EXIT:
|
||||
break
|
||||
else:
|
||||
stack.pop()
|
||||
|
||||
print("bye")
|
||||
|
||||
# Entry point
|
||||
### ENTRY POINT ###
|
||||
ugfx_helper.init()
|
||||
nav(settings_main)
|
||||
#show_app("launcher")
|
||||
|
|
Loading…
Reference in New Issue