145 lines
3.4 KiB
Python
145 lines
3.4 KiB
Python
import importlib
|
|
import json
|
|
import os
|
|
import re
|
|
|
|
import pygame
|
|
|
|
|
|
class Panel(object):
|
|
def __init__(self, surf, position=None, anchor=None, pivot=None, children=None, args=None):
|
|
if isinstance(surf, tuple) or not surf:
|
|
self.__surf = pygame.Surface(surf or (0, 0), flags=pygame.SRCALPHA)
|
|
else:
|
|
self.__surf = surf
|
|
|
|
self.position = position or (0, 0)
|
|
self.anchor = anchor or (0, 0)
|
|
self.pivot = pivot or self.anchor
|
|
self.children = children or []
|
|
self.args = args or {}
|
|
|
|
@property
|
|
def size(self):
|
|
surf = self.__surf
|
|
|
|
if callable(surf):
|
|
surf = surf(**self.args)
|
|
if isinstance(surf, Panel):
|
|
return surf.size
|
|
|
|
return surf.get_width(), surf.get_height()
|
|
|
|
@property
|
|
def surf(self):
|
|
surf = self.__surf
|
|
|
|
if callable(surf):
|
|
surf = surf(**self.args)
|
|
elif isinstance(surf, Panel):
|
|
surf = surf.surf
|
|
else:
|
|
surf = surf.copy()
|
|
|
|
for child in self.children:
|
|
c_surf = child
|
|
position = (0, 0)
|
|
|
|
if isinstance(child, Panel):
|
|
c_surf = child.surf
|
|
|
|
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))
|
|
|
|
surf.blit(c_surf, position)
|
|
|
|
return surf
|
|
|
|
|
|
old_modules = {}
|
|
|
|
|
|
def load(file):
|
|
loaded_modules = {}
|
|
|
|
fp = file
|
|
directory, file = os.path.split(file)
|
|
|
|
def ordered_pair(s, dtype=float):
|
|
if not s:
|
|
return None
|
|
|
|
try:
|
|
op = tuple(dtype(c) for c in (re.split(r'\s*[,x\s]\s*', s)))
|
|
except ValueError:
|
|
return None
|
|
|
|
if len(op) != 2:
|
|
return None
|
|
|
|
return op
|
|
|
|
def script(s):
|
|
if not s:
|
|
return None
|
|
|
|
pair = re.split(r'::', s)
|
|
|
|
if len(pair) != 2:
|
|
return None
|
|
|
|
mod, func = pair
|
|
|
|
mname = directory.replace('/', '.') + '.' + mod
|
|
|
|
if mod not in loaded_modules:
|
|
if mod in old_modules:
|
|
importlib.reload(old_modules[mod])
|
|
|
|
try:
|
|
loaded_modules[mod] = importlib.import_module(mname)
|
|
except ModuleNotFoundError:
|
|
return None
|
|
|
|
mod = loaded_modules[mod]
|
|
|
|
try:
|
|
func = getattr(mod, func)
|
|
except AttributeError:
|
|
return None
|
|
|
|
return func
|
|
|
|
def from_dict(d: dict):
|
|
surf = d.get('surf', None)
|
|
position = d.get('position', None)
|
|
anchor = d.get('anchor', None)
|
|
pivot = d.get('pivot', None)
|
|
children = d.get('children', [])
|
|
args = d.get('args', {})
|
|
|
|
surf = ordered_pair(surf, int) or script(surf)
|
|
position = ordered_pair(position, int)
|
|
anchor = ordered_pair(anchor)
|
|
pivot = ordered_pair(pivot)
|
|
children = [from_dict(d) for d in children]
|
|
|
|
return Panel(surf, position, anchor, pivot, children, args)
|
|
|
|
with open(fp) as f:
|
|
j = json.load(f)
|
|
if isinstance(j, list):
|
|
ls = [from_dict(d) for d in j]
|
|
else:
|
|
ls = [from_dict(j)]
|
|
|
|
old_modules.clear()
|
|
for k, v in loaded_modules.items():
|
|
old_modules[k] = v
|
|
|
|
return ls
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print(load('clock.json'))
|