added runtime wiget data, container children setting & widget update function

This commit is contained in:
Surferlul 2022-07-31 01:13:00 +02:00
parent cf3d949369
commit 3502960731
9 changed files with 151 additions and 47 deletions

View File

@ -13,6 +13,9 @@ def main():
app = native.Application( app = native.Application(
window=native.Window( window=native.Window(
title="Example native-ui app",
width=350,
height=200,
child=native.Container( child=native.Container(
layout=abstract.Layout.VERTICAL, layout=abstract.Layout.VERTICAL,
) )
@ -20,19 +23,36 @@ def main():
) )
cont = app.window.child cont = app.window.child
def on_pressed(button, container): def window_update(self, container):
splt = self.title.split()
if self.title[-1].isdigit():
splt = splt[:-1]
else:
splt.append("Buttons:")
splt.append(str(len(container.children)))
self.title = " ".join(splt)
app.window.update = window_update
app.window.update_args = [cont]
def on_pressed(self, container, window):
print("Hello world") print("Hello world")
container.call("add_child", self.label = f"Clicked {self.runtime_data.get('clicked', 1)}"
self.runtime_data["clicked"] = self.runtime_data.get('clicked', 1) + 1
container.add_child(
native.Button( native.Button(
label="Hello", label="Hello",
pressed=on_pressed, pressed=on_pressed,
pressed_args=[container] pressed_args=[container, window]
)) ))
# test removing container children feature
container.children = container.children
window.update()
cont.add_child(native.Button( cont.add_child(native.Button(
label="Hello", label="Hello",
pressed=on_pressed, pressed=on_pressed,
pressed_args=[cont], pressed_args=[cont, app.window],
)) ))
app.build() app.build()

View File

@ -20,6 +20,14 @@ def abstract_property(function: Callable):
return property(fget, fset) return property(fget, fset)
def abstract_method(function: Callable):
def wrapper(self, *args, **kwargs):
res = function(self, *args, **kwargs)
self.called(function.__name__, res, *args, **kwargs)
return wrapper
class Abstract(object): class Abstract(object):
def __init__(self, platform: str = None): def __init__(self, platform: str = None):
self.is_builder = False self.is_builder = False
@ -28,6 +36,14 @@ class Abstract(object):
if platform is not None: if platform is not None:
self.supported_platforms.add(platform) self.supported_platforms.add(platform)
self.native = None self.native = None
if not hasattr(self, "runtime_data"):
self.runtime_data = {}
if not hasattr(self, "update"):
self._update = lambda *args, **kwargs: None
if not hasattr(self, "update_args"):
self.update_args = []
if not hasattr(self, "update_kwargs"):
self.update_kwargs = {}
def set(self, **kwargs): def set(self, **kwargs):
for prop in kwargs: for prop in kwargs:
@ -66,6 +82,17 @@ class Abstract(object):
return self.native return self.native
return self.native_call("build", *args, **kwargs) return self.native_call("build", *args, **kwargs)
@property
def update(self):
def f(*args, **kwargs):
self.call("_update", self, *args, *self.update_args, **kwargs, **self.update_kwargs)
return f
@update.setter
def update(self, value):
self._update = value
class __metaclass__(type): class __metaclass__(type):
__inheritors__ = defaultdict(list) __inheritors__ = defaultdict(list)

View File

@ -4,8 +4,8 @@ from typing import Callable
class Button(Abstract): class Button(Abstract):
def __init__(self, def __init__(self,
label: str = "", label: str = None,
pressed: Callable = lambda button: None, pressed: Callable = lambda *args, **kwargs: None,
pressed_args: list = None, pressed_args: list = None,
pressed_kwargs: dict = None, pressed_kwargs: dict = None,
platform: str = None): platform: str = None):
@ -16,8 +16,8 @@ class Button(Abstract):
pressed_args = [] pressed_args = []
if pressed_kwargs is None: if pressed_kwargs is None:
pressed_kwargs = {} pressed_kwargs = {}
self._pressed_args = pressed_args self.pressed_args = pressed_args
self._pressed_kwargs = pressed_kwargs self.pressed_kwargs = pressed_kwargs
@abstract_property @abstract_property
def label(self, value): def label(self, value):
@ -27,19 +27,5 @@ class Button(Abstract):
def pressed(self, value): def pressed(self, value):
self._pressed = value self._pressed = value
@abstract_property
def pressed_args(self, value):
self._pressed_args = value
def add_pressed_arg(self, value):
self._pressed_args.append(value)
@abstract_property
def pressed_kwargs(self, value):
self._pressed_kwargs = value
def set_pressed_kwarg(self, key, value):
self._pressed_kwargs[key] = value
def press(self, *args, **kwargs): def press(self, *args, **kwargs):
self.call("pressed", *args, *self._pressed_args, **kwargs, **self._pressed_kwargs) self.call("pressed", self, *args, *self.pressed_args, **kwargs, **self.pressed_kwargs)

View File

@ -1,8 +1,8 @@
from . import Abstract, Layout, abstract_property from . import Abstract, Layout, abstract_property, abstract_method
class Container(Abstract): class Container(Abstract):
def __init__(self, layout: Layout = Layout.HORIZONTAL, children: list = None, platform: str = None): def __init__(self, layout: Layout = None, children: list = None, platform: str = None):
super().__init__(platform=platform) super().__init__(platform=platform)
if children is None: if children is None:
children = [] children = []
@ -13,11 +13,18 @@ class Container(Abstract):
def layout(self, value): def layout(self, value):
self._layout = value self._layout = value
def get_children(self): @abstract_property
return self._children def children(self, value):
# in case for loop manipulates value through reference
value = [child for child in value]
for _ in range(len(self._children)):
self.pop_child(0)
self._children = value
@abstract_method
def add_child(self, child): def add_child(self, child):
self._children.append(child) self._children.append(child)
@abstract_method
def pop_child(self, index): def pop_child(self, index):
return self._children.pop(index) return self._children.pop(index)

View File

@ -2,10 +2,30 @@ from . import Abstract, abstract_property
class Window(Abstract): class Window(Abstract):
def __init__(self, child: Abstract = None, platform: str = None): def __init__(self,
child: Abstract = None,
title: str = None,
width: int = None,
height: int = None,
platform: str = None):
super().__init__(platform=platform) super().__init__(platform=platform)
self._child = child self._child = child
self._title = title
self._width = width
self._height = height
@abstract_property @abstract_property
def child(self, value): def child(self, value):
self._child = value self._child = value
@abstract_property
def title(self, value):
self._title = value
@abstract_property
def width(self, value):
self._width = value
@abstract_property
def height(self, value):
self._height = value

View File

@ -12,11 +12,16 @@ class Application(abstract.Application):
super().__init__(*args, **kwargs, platform=platform) super().__init__(*args, **kwargs, platform=platform)
def changed_gnome(self, property_name: str, index: int = None): def changed_gnome(self, property_name: str, index: int = None):
pass match property_name:
case "window": self.set_window_gnome()
def called_gnome(self, property_name: str, res: Any, *args, **kwargs): def called_gnome(self, property_name: str, res: Any, *args, **kwargs):
pass pass
def set_window_gnome(self):
if self.window is not None:
self.native.abstract_window = self.window
def build_gnome(self): def build_gnome(self):
class GnomeApp(Adw.Application): class GnomeApp(Adw.Application):
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -34,8 +39,7 @@ class Application(abstract.Application):
self.window.present() self.window.present()
self.native = GnomeApp(application_id=gnome.application_id) self.native = GnomeApp(application_id=gnome.application_id)
if self.window is not None: self.set_window_gnome()
self.native.abstract_window = self.window
return self.native return self.native
def run_gnome(self, *args, **kwargs): def run_gnome(self, *args, **kwargs):

View File

@ -11,15 +11,21 @@ class Button(abstract.Button):
super().__init__(*args, **kwargs, platform=platform) super().__init__(*args, **kwargs, platform=platform)
def changed_gnome(self, property_name: str, index: int = None): def changed_gnome(self, property_name: str, index: int = None):
pass match property_name:
case "label": self.set_label_gnome()
def called_gnome(self, property_name: str, res: Any, *args, **kwargs): def called_gnome(self, property_name: str, res: Any, *args, **kwargs):
pass pass
def set_label_gnome(self):
if self.label is not None:
self.native.set_label(self.label)
def clicked(self, _native_button): def clicked(self, _native_button):
self.call("press", self) self.call("press")
def build_gnome(self): def build_gnome(self):
self.native = Gtk.Button(label=self.label) self.native = Gtk.Button()
self.native.connect('clicked', self.clicked) self.native.connect('clicked', self.clicked)
self.set_label_gnome()
return self.native return self.native

View File

@ -11,17 +11,28 @@ class Container(abstract.Container):
super().__init__(*args, **kwargs, platform=platform) super().__init__(*args, **kwargs, platform=platform)
def changed_gnome(self, property_name: str, index: int = None): def changed_gnome(self, property_name: str, index: int = None):
pass match property_name:
case "layout": self.set_layout_gnome()
case "children": self.set_children_gnome()
def called_gnome(self, property_name: str, res: Any, *args, **kwargs): def called_gnome(self, property_name: str, res: Any, *args, **kwargs):
if property_name == "add_child": match property_name:
self.native.append(args[0].build()) case "add_child": self.native.append(args[0].build())
case "pop_child": self.native.remove(res.native)
def set_layout_gnome(self):
if self.layout is not None:
match self.layout:
case abstract.Layout.HORIZONTAL: self.native.set_orientation(Gtk.Orientation.HORIZONTAL)
case abstract.Layout.VERTICAL: self.native.set_orientation(Gtk.Orientation.VERTICAL)
def set_children_gnome(self):
for child in self.children:
self.native.append(child.build())
def build_gnome(self): def build_gnome(self):
orientation = Gtk.Orientation.VERTICAL self.native = Gtk.Box()
if self.layout == abstract.Layout.HORIZONTAL: self.set_layout_gnome()
orientation = Gtk.Orientation.HORIZONTAL self.set_children_gnome()
self.native = Gtk.Box(orientation=orientation)
for child in self.call("get_children"):
self.native.append(child.build())
return self.native return self.native

View File

@ -11,14 +11,37 @@ class Window(abstract.Window):
super().__init__(*args, **kwargs, platform=platform) super().__init__(*args, **kwargs, platform=platform)
def changed_gnome(self, property_name: str, index: int = None): def changed_gnome(self, property_name: str, index: int = None):
if "property_name" == "child": match property_name:
self.native.set_child(self.child.build()) case "child": self.set_child_gnome()
case "title": self.set_title_gnome()
case "width": self.set_width_gnome()
case "height": self.set_height_gnome()
def called_gnome(self, property_name: str, res: Any, *args, **kwargs): def called_gnome(self, property_name: str, res: Any, *args, **kwargs):
pass pass
def build_gnome(self, app: abstract.Application = None): def set_title_gnome(self):
self.native = Gtk.ApplicationWindow(application=app) if self.title is not None:
self.native.set_title(self.title)
def set_width_gnome(self):
if self.width is not None:
self.native.set_default_size(self.width,
self.native.get_default_size()[1])
def set_height_gnome(self):
if self.height is not None:
self.native.set_default_size(self.native.get_default_size()[0],
self.height)
def set_child_gnome(self):
if self.child is not None: if self.child is not None:
self.native.set_child(self.child.build()) self.native.set_child(self.child.build())
def build_gnome(self, app: abstract.Application = None):
self.native = Gtk.ApplicationWindow(application=app)
self.set_child_gnome()
self.set_title_gnome()
self.set_width_gnome()
self.set_height_gnome()
return self.native return self.native