Settings app
parent
f7fefaa331
commit
0f3c2c0e7c
|
@ -6,22 +6,22 @@ To publish apps use https://badge.emfcamp.org"""
|
||||||
|
|
||||||
___license___ = "MIT"
|
___license___ = "MIT"
|
||||||
___title___ = "Badge Store"
|
___title___ = "Badge Store"
|
||||||
___dependencies___ = ["badge_store", "dialogs", "ugfx_helper", "app"]
|
___dependencies___ = ["badge_store", "dialogs", "ugfx_helper", "app", "database"]
|
||||||
___categories___ = ["System"]
|
___categories___ = ["System"]
|
||||||
___bootstrapped___ = True
|
___bootstrapped___ = True
|
||||||
|
|
||||||
import ugfx_helper
|
import ugfx_helper, os, database, wifi, app
|
||||||
import os
|
|
||||||
import wifi
|
|
||||||
from dialogs import *
|
from dialogs import *
|
||||||
import app
|
|
||||||
from lib.badge_store import BadgeStore
|
from lib.badge_store import BadgeStore
|
||||||
|
|
||||||
### VIEWS ###
|
### VIEWS ###
|
||||||
|
|
||||||
ugfx_helper.init()
|
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"
|
title = "TiLDA Badge Store"
|
||||||
|
|
||||||
def clear():
|
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()
|
if button_no: button_no.destroy()
|
||||||
label.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
|
"""Shows a dialog and keyboard that allows the user to input/change a string
|
||||||
|
|
||||||
Returns None if user aborts with button B
|
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();
|
edit.destroy();
|
||||||
return
|
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
|
"""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
|
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:
|
if title:
|
||||||
window.text(5, 10, title, TILDA_COLOR)
|
window.text(5, 10, title, TILDA_COLOR)
|
||||||
window.line(0, 25, ugfx.width() - 10, 25, ugfx.BLACK)
|
window.line(0, 25, ugfx.width() - 10, 25, ugfx.BLACK)
|
||||||
window.text(5, 30, text, ugfx.BLACK)
|
list_y = 30
|
||||||
list_y = 50
|
if text:
|
||||||
|
list_y += 20
|
||||||
|
window.text(5, 30, text, ugfx.BLACK)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
window.text(5, 10, text, ugfx.BLACK)
|
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:
|
for option in options:
|
||||||
if isinstance(option, dict) and option["title"]:
|
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:
|
if none_text:
|
||||||
none_text = "B: " + 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_select = ugfx.Button(5, ugfx.height() - 50, 105 if none_text else 200, 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_none = ugfx.Button(117, ugfx.height() - 50, 105, 30 , none_text, parent=window) if none_text else None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
@ -180,7 +183,7 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
||||||
|
|
||||||
class WaitingMessage:
|
class WaitingMessage:
|
||||||
"""Shows a dialog with a certain message that can not be dismissed by the user"""
|
"""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 = ugfx.Container(30, 30, ugfx.width() - 60, ugfx.height() - 60)
|
||||||
self.window.show()
|
self.window.show()
|
||||||
self.window.text(5, 10, title, TILDA_COLOR)
|
self.window.text(5, 10, title, TILDA_COLOR)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
"""Library for sleep related functions"""
|
"""Library for sleep related functions"""
|
||||||
|
|
||||||
|
___license___ = "MIT"
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
def sleep_ms(duration):
|
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
|
* Pick default app
|
||||||
* Change badgestore repo/branch
|
* Change badgestore repo/branch
|
||||||
|
|
||||||
|
Todo:
|
||||||
|
* timezone
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
___name___ = "Settings"
|
___name___ = "Settings"
|
||||||
___license___ = "MIT"
|
___license___ = "MIT"
|
||||||
___dependencies___ = ["dialogs", "ugfx_helper", "database"]
|
___dependencies___ = ["dialogs", "ugfx_helper", "database", "app", "stack_nav", "wifi"]
|
||||||
___categories___ = ["System"]
|
___categories___ = ["System"]
|
||||||
___bootstrapped___ = True
|
___bootstrapped___ = True
|
||||||
|
|
||||||
import ugfx_helper, os, wifi, app, database
|
import ugfx_helper, os, wifi, app, database
|
||||||
|
from settings.badge_store_settings import settings_badge_store
|
||||||
|
from dialogs import *
|
||||||
|
from stack_nav import *
|
||||||
|
|
||||||
### VIEWS ###
|
### SCREENS ###
|
||||||
|
|
||||||
ugfx_helper.init()
|
|
||||||
|
|
||||||
title = "Settings"
|
|
||||||
|
|
||||||
def clear():
|
|
||||||
ugfx.clear(ugfx.html_color(ugfx.WHITE))
|
|
||||||
|
|
||||||
def settings_name(state):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def settings_startup_app(state):
|
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):
|
def settings_wifi(state):
|
||||||
pass
|
wifi.choose_wifi()
|
||||||
|
|
||||||
def settings_badge_store(state):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def settings_main(state):
|
def settings_main(state):
|
||||||
menu_items = [
|
return selection({
|
||||||
{"title": "Change Name", "function": settings_name},
|
"Homescreeen Name": change_database_string("Set your name", "name"),
|
||||||
{"title": "Wifi", "function": settings_wifi},
|
"Wifi": settings_wifi,
|
||||||
{"title": "Set startup app", "function": settings_startup_app},
|
"Startup app": settings_startup_app,
|
||||||
{"title": "Change Badge Store", "function": settings_badge_store}
|
"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)
|
### ENTRY POINT ###
|
||||||
|
ugfx_helper.init()
|
||||||
# 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
|
|
||||||
nav(settings_main)
|
nav(settings_main)
|
||||||
#show_app("launcher")
|
|
||||||
|
|
Loading…
Reference in New Issue