83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
|
import native_ui
|
||
|
from typing import Callable, Any
|
||
|
from collections import defaultdict
|
||
|
from enum import Enum
|
||
|
|
||
|
|
||
|
class Layout(Enum):
|
||
|
HORIZONTAL = 0
|
||
|
VERTICAL = 1
|
||
|
|
||
|
|
||
|
def abstract_property(function: Callable):
|
||
|
def fget(self):
|
||
|
return getattr(self, f"_{function.__name__}")
|
||
|
|
||
|
def fset(self, value):
|
||
|
function(self, value)
|
||
|
self.changed(function.__name__)
|
||
|
|
||
|
return property(fget, fset)
|
||
|
|
||
|
|
||
|
class Abstract(object):
|
||
|
def __init__(self, platform: str = None):
|
||
|
self.is_builder = False
|
||
|
if not hasattr(self, "supported_platforms"):
|
||
|
self.supported_platforms = set()
|
||
|
if platform is not None:
|
||
|
self.supported_platforms.add(platform)
|
||
|
self.native = None
|
||
|
|
||
|
def set(self, **kwargs):
|
||
|
for prop in kwargs:
|
||
|
self.set_property(prop, kwargs[prop])
|
||
|
|
||
|
def set_property(self, property_name: str, value: Any, index: int = None):
|
||
|
if index is None:
|
||
|
setattr(self, property_name, value)
|
||
|
else:
|
||
|
getattr(self, property_name)[index] = value
|
||
|
self.changed(property_name, index=index)
|
||
|
|
||
|
def call(self, property_name: str, *args, **kwargs):
|
||
|
res = getattr(self, property_name)(*args, **kwargs)
|
||
|
self.called(property_name, res, *args, **kwargs)
|
||
|
return res
|
||
|
|
||
|
def native_call(self, property_name: str, *args, **kwargs):
|
||
|
if native_ui.runtime_platform is None:
|
||
|
print("No runtime platform set")
|
||
|
if native_ui.runtime_platform not in self.supported_platforms:
|
||
|
print(f"Platform {native_ui.runtime_platform} not supported by {type(self).__name__}")
|
||
|
else:
|
||
|
return getattr(self, f"{property_name}_{native_ui.runtime_platform}")(*args, **kwargs)
|
||
|
|
||
|
def changed(self, property_name: str, index: int = None):
|
||
|
if self.native is not None:
|
||
|
self.native_call("changed", property_name, index)
|
||
|
|
||
|
def called(self, property_name: str, res: Any, *args, **kwargs):
|
||
|
if self.native is not None:
|
||
|
self.native_call("called", property_name, res, *args, **kwargs)
|
||
|
|
||
|
def build(self, *args, **kwargs):
|
||
|
if self.native is not None:
|
||
|
return self.native
|
||
|
return self.native_call("build", *args, **kwargs)
|
||
|
|
||
|
class __metaclass__(type):
|
||
|
__inheritors__ = defaultdict(list)
|
||
|
|
||
|
def __new__(meta, name, bases, dct):
|
||
|
klass = type.__new__(meta, name, bases, dct)
|
||
|
for base in klass.mro()[1:-1]:
|
||
|
meta.__inheritors__[base].append(klass)
|
||
|
return klass
|
||
|
|
||
|
|
||
|
from .button import Button
|
||
|
from .container import Container
|
||
|
from .window import Window
|
||
|
from .application import Application
|