more flexible functions, allow passing arguments to functions

This commit is contained in:
2017-04-19 02:16:50 -04:00
parent 64c094d3d0
commit e093cac35b
6 changed files with 94 additions and 41 deletions

5
.gitignore vendored
View File

@@ -65,7 +65,7 @@ lib/
lib64/ lib64/
parts/ parts/
sdist/ sdist/
var/ update_files.txt/
wheels/ wheels/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
@@ -140,3 +140,6 @@ ENV/
.ropeproject .ropeproject
.idea/ .idea/
/run.sh /run.sh
/reupload.sh
/update.sh
/update_files.txt

View File

@@ -1,26 +1,40 @@
[ [
{ {
"surf": "panel_script::time", "surf": "panel_script::time",
"anchor": "0.5,0.5" "anchor": "0.5,0.4",
"args": {
"size": 360
}
}, },
{ {
"surf": "500 500", "surf": "1280 500",
"anchor": "0.5,0.5", "anchor": "0.5,0.4",
"position": "0 250", "position": "0 250",
"children": [ "children": [
{ {
"surf": "panel_script::date", "surf": "panel_script::time",
"args": {
"fmt": "%A, %B %d",
"size": 60
},
"position": "0 -60", "position": "0 -60",
"anchor": ".5 .5" "anchor": ".5 .5"
}, },
{ {
"surf": "panel_script::icon", "surf": "panel_script::image",
"args": {
"path": "'res/png/'+str(get_weather().current_conditions.icon)+'.png'",
"do_eval": true
},
"position": "0 80", "position": "0 80",
"anchor": ".5 .5", "anchor": ".5 .5",
"pivot": "1 .5" "pivot": "1 .5"
}, },
{ {
"surf": "panel_script::temperature", "surf": "panel_script::weather",
"args": {
"fmt": "{current_conditions.temperature}\u00b0{units.temperature}"
},
"position": "0 80", "position": "0 80",
"anchor": ".5 .5", "anchor": ".5 .5",
"pivot": "0 .5" "pivot": "0 .5"

View File

@@ -14,7 +14,7 @@ pygame.init()
pygame.mouse.set_visible(False) pygame.mouse.set_visible(False)
SIZE = (1280, 1024) SIZE = (1280, 1024)
mode = pygame.display.set_mode(SIZE, 1) screen = pygame.display.set_mode(SIZE, pygame.HWSURFACE | pygame.DOUBLEBUF)
pygame.display.set_caption("weather clock") pygame.display.set_caption("weather clock")
clock = pygame.time.Clock() clock = pygame.time.Clock()
@@ -24,6 +24,8 @@ def game_loop():
parent = None parent = None
while True: while True:
clock.tick(1)
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.KEYDOWN: if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q: if event.key == pygame.K_q:
@@ -35,13 +37,13 @@ def game_loop():
panel_time = os.stat(CONFIG_PATH).st_mtime_ns panel_time = os.stat(CONFIG_PATH).st_mtime_ns
if panel_time != panel_load: if panel_time != panel_load:
parent = panel.Panel(SIZE, children=panel.load(CONFIG_PATH)) parent = panel.Panel(lambda: pygame.Surface(SIZE), children=panel.load(CONFIG_PATH))
panel_load = panel_time panel_load = panel_time
mode.blit(parent.surf, (0, 0)) screen.fill((0, 0, 0))
screen.blit(parent.surf, (0, 0))
pygame.display.update() pygame.display.flip()
clock.tick(8)
game_loop() game_loop()

View File

@@ -6,7 +6,7 @@ import pygame
class Panel(object): class Panel(object):
def __init__(self, surf, position=None, anchor=None, pivot=None, children=None): def __init__(self, surf, position=None, anchor=None, pivot=None, children=None, args=None):
if isinstance(surf, tuple) or not surf: if isinstance(surf, tuple) or not surf:
self.__surf = pygame.Surface(surf or (0, 0), flags=pygame.SRCALPHA) self.__surf = pygame.Surface(surf or (0, 0), flags=pygame.SRCALPHA)
else: else:
@@ -16,13 +16,14 @@ class Panel(object):
self.anchor = anchor or (0, 0) self.anchor = anchor or (0, 0)
self.pivot = pivot or self.anchor self.pivot = pivot or self.anchor
self.children = children or [] self.children = children or []
self.args = args or {}
@property @property
def size(self): def size(self):
surf = self.__surf surf = self.__surf
if callable(surf): if callable(surf):
surf = surf() surf = surf(**self.args)
if isinstance(surf, Panel): if isinstance(surf, Panel):
return surf.size return surf.size
@@ -33,7 +34,7 @@ class Panel(object):
surf = self.__surf surf = self.__surf
if callable(surf): if callable(surf):
surf = surf() surf = surf(**self.args)
elif isinstance(surf, Panel): elif isinstance(surf, Panel):
surf = surf.surf surf = surf.surf
else: else:
@@ -49,11 +50,6 @@ class Panel(object):
position = tuple(int(a * s - v * c + p) for a, v, s, c, p in position = tuple(int(a * s - v * c + p) for a, v, s, c, p in
zip(child.anchor, child.pivot, self.size, child.size, child.position)) zip(child.anchor, child.pivot, self.size, child.size, child.position))
if callable(c_surf):
c_surf = c_surf()
if isinstance(c_surf, Panel):
c_surf=c_surf.surf
surf.blit(c_surf, position) surf.blit(c_surf, position)
return surf return surf
@@ -114,6 +110,7 @@ def load(file):
anchor = d.get('anchor', None) anchor = d.get('anchor', None)
pivot = d.get('pivot', None) pivot = d.get('pivot', None)
children = d.get('children', []) children = d.get('children', [])
args = d.get('args', {})
surf = ordered_pair(surf, int) or script(surf) surf = ordered_pair(surf, int) or script(surf)
position = ordered_pair(position, int) position = ordered_pair(position, int)
@@ -121,7 +118,7 @@ def load(file):
pivot = ordered_pair(pivot) pivot = ordered_pair(pivot)
children = [from_dict(d) for d in children] children = [from_dict(d) for d in children]
return Panel(surf, position, anchor, pivot, children) return Panel(surf, position, anchor, pivot, children, args)
with open(file) as f: with open(file) as f:
j = json.load(f) j = json.load(f)

View File

@@ -12,39 +12,56 @@ WHITE = (255, 255, 255)
GRAY = (175, 175, 175) GRAY = (175, 175, 175)
BLACK = (0, 0, 0) BLACK = (0, 0, 0)
font = {
'RobotoSlab': { class Font(object):
30: pygame.font.Font("res/RobotoSlab-Regular.ttf", 30), def __init__(self, name):
45: pygame.font.Font("res/RobotoSlab-Regular.ttf", 45), self.file = name
60: pygame.font.Font("res/RobotoSlab-Regular.ttf", 60), self.fonts = {}
90: pygame.font.Font("res/RobotoSlab-Regular.ttf", 90),
360: pygame.font.Font("res/RobotoSlab-Regular.ttf", 360), def __getitem__(self, size):
} if size not in self.fonts:
} self.fonts[size] = pygame.font.Font(self.file, size)
return self.fonts[size]
def time(): roboto = Font('res/RobotoSlab-Regular.ttf')
return font['RobotoSlab'][360].render(format(datetime.now(), '%I:%H').lstrip('0'), True, WHITE)
def date(): def __do_eval(text):
return font['RobotoSlab'][60].render(format(datetime.now(), '%A, %B %d'), True, GRAY) try:
return eval(text)
except:
return text
def temperature(): def text(size=60, t="", do_eval=False):
f = font['RobotoSlab'][90] if do_eval:
return f.render('{0[current_conditions][temperature]}\u00b0'.format(get_weather()), True, WHITE) t = __do_eval(t)
return roboto[size].render(t, True, WHITE)
def icon(): def time(size=60, fmt='%I:%H', strip='0'):
return pygame.image.load('res/png/12.png') return roboto[size].render(format(datetime.now(), fmt).lstrip(strip), True, WHITE)
def weather(size=60, fmt='{current_conditions.temperature}\u00b0'):
return roboto[size].render(fmt.format(**get_weather()), True, WHITE)
def image(path="", do_eval=False):
if do_eval:
path = __do_eval(path)
try:
return pygame.image.load(path)
except:
return text(size=15, t=path)
def header(): def header():
es = get_events() es = get_events()
def item(i): def item(i):
f = font['RobotoSlab'][30] f = roboto[30]
e = es[i] e = es[i]
l = e.label l = e.label
t = '{days}d {hours}h {minutes}m'.format(**e.time) t = '{days}d {hours}h {minutes}m'.format(**e.time)

View File

@@ -12,6 +12,25 @@ UPDATE_INTERVAL = 60 * 20
__weather = {} __weather = {}
class AttrDict(dict):
""" Dictionary subclass whose entries can be accessed by attributes
(as well as normally).
"""
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self
@staticmethod
def from_nested_dict(data):
""" Construct nested AttrDicts from nested dictionaries. """
if not isinstance(data, dict):
return data
else:
return AttrDict({key: AttrDict.from_nested_dict(data[key])
for key in data})
def update_weather(force=False): def update_weather(force=False):
global __weather global __weather
now = datetime.now() now = datetime.now()
@@ -22,6 +41,7 @@ def update_weather(force=False):
if force or interval <= 0 or interval > UPDATE_INTERVAL: if force or interval <= 0 or interval > UPDATE_INTERVAL:
__weather = pywapi.get_weather_from_weather_com(LOCATION, UNITS) __weather = pywapi.get_weather_from_weather_com(LOCATION, UNITS)
__weather.setdefault('current_conditions', {}).setdefault('last_checked', str(now)) __weather.setdefault('current_conditions', {}).setdefault('last_checked', str(now))
__weather = AttrDict.from_nested_dict(__weather)
print('updated weather at', now) print('updated weather at', now)
@@ -33,4 +53,4 @@ def get_weather(force_update=False):
if __name__ == '__main__': if __name__ == '__main__':
while True: while True:
print('{0[current_conditions][temperature]}\u00b0{0[units][temperature]}'.format(get_weather())) print('{current_conditions.temperature}\u00b0{units.temperature}'.format(**get_weather()))