Explorar el Código

wallet: begin reorganzing py code into a submodule

rsx hace 2 años
padre
commit
c475c198e7

+ 111 - 228
bin/darkwallet/client.py

@@ -1,100 +1,9 @@
 #!/usr/bin/python
 # Ping a peer
 from pydrk import Api, exc, ErrorCode, HostApi, SceneNodeType, PropertyType, vertex, face, serial
+import gui
 import sys, zmq
 
-def join(parent_path, child_name):
-    if parent_path == "/":
-        return f"/{child_name}"
-    return f"{parent_path}/{child_name}"
-
-def print_tree():
-    root_id = api.lookup_node_id("/")
-    print_node_info(root_id)
-
-def print_node_info(parent_id, indent=0):
-    ws = " "*4*indent
-    for (child_name, child_id, child_type) in api.get_children(parent_id):
-        match child_type:
-            case SceneNodeType.ROOT:
-                child_type = "root"
-            case SceneNodeType.WINDOW:
-                child_type = "window"
-            case SceneNodeType.WINDOW_INPUT:
-                child_type = "window_input"
-            case SceneNodeType.KEYBOARD:
-                child_type = "keyboard"
-            case SceneNodeType.MOUSE:
-                child_type = "mouse"
-            case SceneNodeType.RENDER_LAYER:
-                child_type = "render_layer"
-            case SceneNodeType.RENDER_OBJECT:
-                child_type = "render_object"
-            case SceneNodeType.RENDER_MESH:
-                child_type = "render_mesh"
-            case SceneNodeType.RENDER_TEXT:
-                child_type = "render_text"
-            case SceneNodeType.RENDER_TEXTURE:
-                child_type = "render_texture"
-            case SceneNodeType.FONTS:
-                child_type = "fonts"
-            case SceneNodeType.FONT:
-                child_type = "font"
-            case SceneNodeType.LINE_POSITION:
-                child_type = "line_position"
-
-        desc = f"{ws}{child_name}:{child_id}/"
-        desc += " "*(50 - len(desc))
-        desc += f"[{child_type}]"
-        print(desc)
-
-        print_node_info(child_id, indent+1)
-
-    for prop_name, prop_type in api.get_properties(parent_id):
-        if prop_type == PropertyType.STR:
-            prop_val = api.get_property(parent_id, prop_name)
-            prop_val = f" = \"{prop_val}\""
-        elif prop_type != PropertyType.BUFFER:
-            prop_val = api.get_property(parent_id, prop_name)
-            prop_val = f" = {prop_val}"
-        else:
-            prop_val = ""
-
-        prop_type = PropertyType.to_str(prop_type)
-
-        print(f"{ws}{prop_name}: {prop_type}{prop_val}")
-
-    for sig in api.get_signals(parent_id):
-        print(f"{ws}~{sig}")
-        for slot_id, slot in api.get_slots(parent_id, sig):
-            print(f"{ws}- '{slot}' ({slot_id})")
-
-    for method_name in api.get_methods(parent_id):
-        args, results = api.get_method(parent_id, method_name)
-
-        args = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in args]
-        results = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in results]
-
-        method_str = f"{method_name}(" + ", ".join(args) + ") -> (" + ", ".join(results) + ")"
-        print(f"{ws}{method_str}")
-
-def make_sub_socket():
-    context = zmq.Context()
-    socket = context.socket(zmq.SUB)
-    socket.setsockopt(zmq.SUBSCRIBE, b'')
-    socket.connect("tcp://localhost:9485")
-    return socket
-
-def remove_node_recursive(node_id):
-    for (_, child_id, _) in api.get_children(node_id):
-        # Unlink the child
-        api.unlink_node(child_id, node_id)
-        # Remove the node
-        remove_node_recursive(child_id)
-    # Garbage collection
-    if not api.get_parents(node_id):
-        api.remove_node(node_id)
-
 def clear_layer(layer_path):
     layer_id = api.lookup_node_id("/window/layer2")
     if layer_id is None:
@@ -110,29 +19,6 @@ def clear_layer(layer_path):
 
     api.remove_node(layer_id)
 
-def remove_all_slots(node_path, sig):
-    node_id = api.lookup_node_id(node_path)
-    for slot_id, slot in api.get_slots(node_id, sig):
-        print(f"{node_path}:{sig}(): Unregistering slot '{slot}':{slot_id}")
-        api.unregister_slot(node_id, sig, slot_id)
-
-def register_slot(node_path, sig, tag):
-    remove_all_slots(node_path, sig)
-    node_id = api.lookup_node_id(node_path)
-    api.register_slot(node_id, sig, "", tag)
-
-def get_property(node_path, prop):
-    node_id = api.lookup_node_id(node_path)
-    return api.get_property(node_id, prop)
-
-def set_property(node_path, prop, val):
-    node_id = api.lookup_node_id(node_path)
-    match val:
-        case float():
-            api.set_property_f32(node_id, prop, val)
-        case int():
-            api.set_property_u32(node_id, prop, val)
-
 def recalc_areas():
     print("recalc areas")
     w = get_property("/window", "width")
@@ -140,116 +26,113 @@ def recalc_areas():
     set_property("/window/layer2", "rect_w", int(w))
     set_property("/window/layer2", "rect_h", int(h))
 
-    print_tree()
-
-def garbage_collect():
-    for node_id in api.scan_dangling():
-        remove_node_recursive(node_id)
-
-api = Api()
-host = HostApi(api)
-print(api.hello())
-
-garbage_collect()
-clear_layer("/window/layer2")
-
-print("Generating scene...")
-subsock = make_sub_socket()
-
-register_slot("/window",                "resize",        b"resize")
-register_slot("/window/input/mouse",    "button_down",   b"click")
-register_slot("/window/input/mouse",    "wheel",         b"wheel")
-#register_slot("/window/input/mouse",    "move",          b"mouse")
-
-layer_id = api.add_node("layer2", SceneNodeType.RENDER_LAYER)
-api.add_property(layer_id, "rect_x", PropertyType.UINT32)
-api.add_property(layer_id, "rect_y", PropertyType.UINT32)
-api.add_property(layer_id, "rect_w", PropertyType.UINT32)
-api.add_property(layer_id, "rect_h", PropertyType.UINT32)
-api.add_property(layer_id, "is_visible", PropertyType.BOOL)
-api.set_property_bool(layer_id, "is_visible", True)
-win_id = api.lookup_node_id("/window")
-api.link_node(layer_id, win_id)
-
-if True:
-    layer_id = api.lookup_node_id("/window/layer2")
-
-    obj_id = api.add_node("obj1", SceneNodeType.RENDER_OBJECT)
-    api.add_property(obj_id, "x", PropertyType.FLOAT32)
-    api.add_property(obj_id, "y", PropertyType.FLOAT32)
-    api.add_property(obj_id, "scale", PropertyType.FLOAT32)
-    api.set_property_f32(obj_id, "scale", 1.0)
-
-    mesh_id = api.add_node("mesh", SceneNodeType.RENDER_MESH)
-    api.add_property(mesh_id, "verts", PropertyType.BUFFER)
-    api.add_property(mesh_id, "faces", PropertyType.BUFFER)
-
-    texture_id = host.load_texture("da_king", "king.png")
-    api.link_node(texture_id, obj_id)
-    # To preserve the ratio, we should do this when resize happens too
-    texture_w = api.get_property(texture_id, "width")
-    texture_h = api.get_property(texture_id, "width")
-    texture_ratio = texture_w / texture_h
-    screen_w = get_property("/window", "width")
-    screen_h = get_property("/window", "height")
-    screen_ratio = screen_w / screen_h
-    aspect_ratio = texture_ratio / screen_ratio
-
-    #api.set_property_bool("/window/layer2", "is_visible", False)
-    # Lets add a poly - must be counterclockwise
-    x, y = 0.25, 0.25
-    w, h = 0.5 * aspect_ratio, 0.5
-    vert1 = vertex(x,     y,     1, 1, 1, 1, 0, 0)
-    vert2 = vertex(x + w, y,     1, 1, 1, 1, 1, 0)
-    vert3 = vertex(x,     y + h, 1, 1, 1, 1, 0, 1)
-    vert4 = vertex(x + w, y + h, 1, 1, 1, 1, 1, 1)
-    api.set_property_buffer(mesh_id, "verts", vert1 + vert2 + vert3 + vert4)
-    api.set_property_buffer(mesh_id, "faces", face(0, 2, 1) + face(1, 2, 3))
-
-    api.link_node(mesh_id, obj_id)
-    api.link_node(obj_id, layer_id)
-
-if True:
-    layer_id = api.lookup_node_id("/window/layer2")
-    obj_id = api.add_node("obj", SceneNodeType.RENDER_OBJECT)
-    api.add_property(obj_id, "x", PropertyType.FLOAT32)
-    api.add_property(obj_id, "y", PropertyType.FLOAT32)
-    api.add_property(obj_id, "scale", PropertyType.FLOAT32)
-    api.set_property_f32(obj_id, "scale", 1.0)
-
-    # Call method
-    text_id = host.create_text(
-        "/font/inter-regular", "mytxt2", "hello world", 34
-    )
-    if text_id is None:
-        sys.exit(-1)
-    print("create text node id:", text_id)
-
-    api.set_property_f32(obj_id, "x", 0.5)
-    api.set_property_f32(text_id, "r", 1.0)
-    api.set_property_f32(text_id, "g", 1.0)
-    api.set_property_f32(text_id, "b", 1.0)
-    api.set_property_f32(text_id, "a", 1.0)
-
-    api.link_node(text_id, obj_id)
-    api.link_node(obj_id, layer_id)
-
-# Screen init
-recalc_areas()
-
-print_tree()
-print()
-print("Scene created.")
-
-while True:
-    data = subsock.recv()
-    match data:
-        case b"resize":
-            recalc_areas()
-        case b"click":
-            x = get_property("/window/input/mouse", "x")
-            y = get_property("/window/input/mouse", "y")
-            print(f"mouse clicked ({x}, {y})")
-        case b"wheel":
-            print("mouse wheely")
-
+    gui.print_tree()
+
+#api = Api()
+#host = HostApi(api)
+#print(api.hello())
+#
+#garbage_collect()
+#clear_layer("/window/layer2")
+#
+#print("Generating scene...")
+#subsock = make_sub_socket()
+#
+#register_slot("/window",                "resize",        b"resize")
+#register_slot("/window/input/mouse",    "button_down",   b"click")
+#register_slot("/window/input/mouse",    "wheel",         b"wheel")
+##register_slot("/window/input/mouse",    "move",          b"mouse")
+#
+#layer_id = api.add_node("layer2", SceneNodeType.RENDER_LAYER)
+#api.add_property(layer_id, "rect_x", PropertyType.UINT32)
+#api.add_property(layer_id, "rect_y", PropertyType.UINT32)
+#api.add_property(layer_id, "rect_w", PropertyType.UINT32)
+#api.add_property(layer_id, "rect_h", PropertyType.UINT32)
+#api.add_property(layer_id, "is_visible", PropertyType.BOOL)
+#api.set_property_bool(layer_id, "is_visible", True)
+#win_id = api.lookup_node_id("/window")
+#api.link_node(layer_id, win_id)
+#
+#if True:
+#    layer_id = api.lookup_node_id("/window/layer2")
+#
+#    obj_id = api.add_node("obj1", SceneNodeType.RENDER_OBJECT)
+#    api.add_property(obj_id, "x", PropertyType.FLOAT32)
+#    api.add_property(obj_id, "y", PropertyType.FLOAT32)
+#    api.add_property(obj_id, "scale", PropertyType.FLOAT32)
+#    api.set_property_f32(obj_id, "scale", 1.0)
+#
+#    mesh_id = api.add_node("mesh", SceneNodeType.RENDER_MESH)
+#    api.add_property(mesh_id, "verts", PropertyType.BUFFER)
+#    api.add_property(mesh_id, "faces", PropertyType.BUFFER)
+#
+#    texture_id = host.load_texture("da_king", "king.png")
+#    api.link_node(texture_id, obj_id)
+#    # To preserve the ratio, we should do this when resize happens too
+#    texture_w = api.get_property(texture_id, "width")
+#    texture_h = api.get_property(texture_id, "width")
+#    texture_ratio = texture_w / texture_h
+#    screen_w = get_property("/window", "width")
+#    screen_h = get_property("/window", "height")
+#    screen_ratio = screen_w / screen_h
+#    aspect_ratio = texture_ratio / screen_ratio
+#
+#    #api.set_property_bool("/window/layer2", "is_visible", False)
+#    # Lets add a poly - must be counterclockwise
+#    x, y = 0.25, 0.25
+#    w, h = 0.5 * aspect_ratio, 0.5
+#    vert1 = vertex(x,     y,     1, 1, 1, 1, 0, 0)
+#    vert2 = vertex(x + w, y,     1, 1, 1, 1, 1, 0)
+#    vert3 = vertex(x,     y + h, 1, 1, 1, 1, 0, 1)
+#    vert4 = vertex(x + w, y + h, 1, 1, 1, 1, 1, 1)
+#    api.set_property_buffer(mesh_id, "verts", vert1 + vert2 + vert3 + vert4)
+#    api.set_property_buffer(mesh_id, "faces", face(0, 2, 1) + face(1, 2, 3))
+#
+#    api.link_node(mesh_id, obj_id)
+#    api.link_node(obj_id, layer_id)
+#
+#if True:
+#    layer_id = api.lookup_node_id("/window/layer2")
+#    obj_id = api.add_node("obj", SceneNodeType.RENDER_OBJECT)
+#    api.add_property(obj_id, "x", PropertyType.FLOAT32)
+#    api.add_property(obj_id, "y", PropertyType.FLOAT32)
+#    api.add_property(obj_id, "scale", PropertyType.FLOAT32)
+#    api.set_property_f32(obj_id, "scale", 1.0)
+#
+#    # Call method
+#    text_id = host.create_text(
+#        "/font/inter-regular", "mytxt2", "hello world", 34
+#    )
+#    if text_id is None:
+#        sys.exit(-1)
+#    print("create text node id:", text_id)
+#
+#    api.set_property_f32(obj_id, "x", 0.5)
+#    api.set_property_f32(text_id, "r", 1.0)
+#    api.set_property_f32(text_id, "g", 1.0)
+#    api.set_property_f32(text_id, "b", 1.0)
+#    api.set_property_f32(text_id, "a", 1.0)
+#
+#    api.link_node(text_id, obj_id)
+#    api.link_node(obj_id, layer_id)
+#
+## Screen init
+#recalc_areas()
+#
+#gui.print_tree()
+#print()
+#print("Scene created.")
+#
+#while True:
+#    data = subsock.recv()
+#    match data:
+#        case b"resize":
+#            recalc_areas()
+#        case b"click":
+#            x = get_property("/window/input/mouse", "x")
+#            y = get_property("/window/input/mouse", "y")
+#            print(f"mouse clicked ({x}, {y})")
+#        case b"wheel":
+#            print("mouse wheely")
+#
+gui.main()

+ 45 - 0
bin/darkwallet/gui/__init__.py

@@ -0,0 +1,45 @@
+from .print_tree import print_tree
+from .api import *
+from .gfx import Layer
+from . import settings
+
+class App(EventLoop):
+
+    def __init__(self):
+        super().__init__()
+
+        w = get_property("/window", "width")
+        h = get_property("/window", "height")
+
+        self.chatbox_layer = Layer("chatbox_layer")
+        self.chatbox_layer.resize(w, h)
+
+        self.chatbox_layer.add_obj("outline")
+
+    def resize_event(self, w, h):
+        print(f"resize ({w}, {h})")
+        self.chatbox_layer.resize(w, h)
+
+    def mouse_click(self, x, y):
+        print(f"mouse click ({x}, {y})")
+
+    def mouse_wheel(self, y):
+        settings.ui_scale *= 1 + y/100
+        print(settings.ui_scale)
+
+    def key_down(self, keycode, keymods, repeat):
+        #print(f"key_down: '{keycode}'")
+        if keymods.ctrl and keycode == "=":
+            settings.ui_scale *= 1.01
+            print(settings.ui_scale)
+        elif keymods.ctrl and keycode == "-":
+            settings.ui_scale *= 0.99
+            print(settings.ui_scale)
+
+def main():
+    garbage_collect()
+
+    app = App()
+    print_tree()
+    app.run()
+

+ 143 - 0
bin/darkwallet/gui/api.py

@@ -0,0 +1,143 @@
+from collections import namedtuple
+from pydrk import Api, HostApi, PropertyType
+import zmq
+
+api = Api()
+host = HostApi(api)
+print("Node status:", api.hello())
+
+def make_sub_socket():
+    context = zmq.Context()
+    socket = context.socket(zmq.SUB)
+    socket.setsockopt(zmq.SUBSCRIBE, b'')
+    socket.connect("tcp://localhost:9485")
+    return socket
+
+def remove_all_slots(node_path, sig):
+    node_id = api.lookup_node_id(node_path)
+    for slot_id, slot in api.get_slots(node_id, sig):
+        print(f"{node_path}:{sig}(): Unregistering slot '{slot}':{slot_id}")
+        api.unregister_slot(node_id, sig, slot_id)
+
+def register_slot(node_path, sig, tag):
+    remove_all_slots(node_path, sig)
+    node_id = api.lookup_node_id(node_path)
+    api.register_slot(node_id, sig, "", tag)
+
+def get_property(node_path, prop):
+    node_id = api.lookup_node_id(node_path)
+    return api.get_property(node_id, prop)
+
+def set_property(node_id, prop, val):
+    node_id = _lookup_node(node_id)
+    match val:
+        case float():
+            api.set_property_f32(node_id, prop, val)
+        case int():
+            api.set_property_u32(node_id, prop, val)
+def set_property_f32(node_id, prop, val):
+    node_id = _lookup_node(node_id)
+    api.set_property_f32(node_id, prop, float(val))
+def set_property_u32(node_id, prop, val):
+    node_id = _lookup_node(node_id)
+    api.set_property_u32(node_id, prop, int(val))
+
+def add_property_bool(node_id, prop, val=None):
+    api.add_property(node_id, prop, PropertyType.BOOL)
+    if val is not None:
+        api.set_property_bool(node_id, prop, val)
+def add_property_f32(node_id, prop, val=None):
+    api.add_property(node_id, prop, PropertyType.FLOAT32)
+    if val is not None:
+        api.set_property_f32(node_id, prop, val)
+def add_property_u32(node_id, prop, val=None):
+    api.add_property(node_id, prop, PropertyType.UINT32)
+    if val is not None:
+        api.set_property_u32(node_id, prop, val)
+
+def _lookup_node(node_id):
+    if isinstance(node_id, str):
+        node_id = api.lookup_node_id(node_id)
+    return node_id
+
+def link_node(child_id, parent_id):
+    child_id = _lookup_node(child_id)
+    parent_id = _lookup_node(parent_id)
+    api.link_node(child_id, parent_id)
+def unlink_node(child_id, parent_id):
+    child_id = _lookup_node(child_id)
+    parent_id = _lookup_node(parent_id)
+    api.unlink_node(child_id, parent_id)
+
+def remove_node_recursive(node_id):
+    for (_, child_id, _) in api.get_children(node_id):
+        # Unlink the child
+        api.unlink_node(child_id, node_id)
+        # Remove the node
+        remove_node_recursive(child_id)
+    # Garbage collection
+    if not api.get_parents(node_id):
+        api.remove_node(node_id)
+
+def garbage_collect():
+    dangling = api.scan_dangling()
+    for node_id in dangling:
+        remove_node_recursive(node_id)
+    print(f"Garbage collect: removed {len(dangling)} nodes")
+
+KeyMods = namedtuple("KeyMods", ["shift", "ctrl", "alt", "logo"])
+
+class EventLoop:
+
+    def __init__(self):
+        self.subsock = make_sub_socket()
+        register_slot("/window",                "resize",        b"rs")
+        register_slot("/window/input/mouse",    "button_down",   b"ck")
+        register_slot("/window/input/mouse",    "wheel",         b"wh")
+        register_slot("/window/input/mouse",    "move",          b"mm")
+        register_slot("/window/input/keyboard", "key_down",      b"kd")
+
+    def run(self):
+        while True:
+            data = self.subsock.recv()
+            match data:
+                case b"rs":
+                    w = get_property("/window", "width")
+                    h = get_property("/window", "height")
+                    self.resize_event(w, h)
+                case b"ck":
+                    x = get_property("/window/input/mouse", "click_x")
+                    y = get_property("/window/input/mouse", "click_y")
+                    self.mouse_click(x, y)
+                case b"wh":
+                    y = get_property("/window/input/mouse", "wheel_y")
+                    self.mouse_wheel(y)
+                case b"mm":
+                    pass
+                case b"kd":
+                    shift =   get_property("/window/input/keyboard", "shift")
+                    ctrl =    get_property("/window/input/keyboard", "ctrl")
+                    alt =     get_property("/window/input/keyboard", "alt")
+                    logo =    get_property("/window/input/keyboard", "logo")
+                    keycode = get_property("/window/input/keyboard", "keycode")
+                    repeat =  get_property("/window/input/keyboard", "repeat")
+
+                    keymods = KeyMods(shift, ctrl, alt, logo)
+                    # Sometimes these get stuck when exiting the window.
+                    # We don't need these anyway
+                    if keycode in ("LeftShift", "LeftSuper"):
+                        continue
+                    self.key_down(keycode, keymods, repeat)
+
+    def resize_event(self, w, h):
+        pass
+
+    def mouse_click(self, x, y):
+        pass
+
+    def mouse_wheel(self, y):
+        pass
+
+    def key_down(self, keycode, keymods, repeat):
+        pass
+

+ 45 - 0
bin/darkwallet/gui/gfx.py

@@ -0,0 +1,45 @@
+from pydrk import SceneNodeType, PropertyType, vertex, face
+from .api import *
+
+def clear_layer(layer_name):
+    layer_id = api.lookup_node_id(f"/window/{layer_name}")
+    if layer_id is None:
+        return
+
+    unlink_node(layer_id, "/window")
+
+    for (_, child_id, child_type) in api.get_children(layer_id):
+        api.unlink_node(child_id, layer_id)
+        if child_type == SceneNodeType.RENDER_OBJECT:
+            remove_node_recursive(child_id)
+
+    api.remove_node(layer_id)
+
+def add_layer(layer_name):
+    layer_id = api.add_node(layer_name, SceneNodeType.RENDER_LAYER)
+    add_property_u32(layer_id, "rect_x")
+    add_property_u32(layer_id, "rect_y")
+    add_property_u32(layer_id, "rect_w")
+    add_property_u32(layer_id, "rect_h")
+    add_property_bool(layer_id, "is_visible", True)
+    link_node(layer_id, "/window")
+    return layer_id
+
+class Layer:
+
+    def __init__(self, name):
+        self.name = name
+        clear_layer(name)
+        self.id = add_layer(name)
+
+    def resize(self, w, h):
+        set_property_u32(self.id, "rect_w", w)
+        set_property_u32(self.id, "rect_h", h)
+
+    def add_obj(self, name):
+        obj_id = api.add_node(name, SceneNodeType.RENDER_OBJECT)
+        add_property_f32(obj_id, "x")
+        add_property_f32(obj_id, "y")
+        add_property_f32(obj_id, "scale", 1.0)
+        link_node(obj_id, self.id)
+

+ 78 - 0
bin/darkwallet/gui/print_tree.py

@@ -0,0 +1,78 @@
+from pydrk import SceneNodeType, PropertyType
+from .api import api
+
+def join(parent_path, child_name):
+    if parent_path == "/":
+        return f"/{child_name}"
+    return f"{parent_path}/{child_name}"
+
+def print_tree():
+    root_id = api.lookup_node_id("/")
+    print_node_info(root_id)
+
+def print_node_info(parent_id, indent=0):
+    ws = " "*4*indent
+    for (child_name, child_id, child_type) in api.get_children(parent_id):
+        match child_type:
+            case SceneNodeType.ROOT:
+                child_type = "root"
+            case SceneNodeType.WINDOW:
+                child_type = "window"
+            case SceneNodeType.WINDOW_INPUT:
+                child_type = "window_input"
+            case SceneNodeType.KEYBOARD:
+                child_type = "keyboard"
+            case SceneNodeType.MOUSE:
+                child_type = "mouse"
+            case SceneNodeType.RENDER_LAYER:
+                child_type = "render_layer"
+            case SceneNodeType.RENDER_OBJECT:
+                child_type = "render_object"
+            case SceneNodeType.RENDER_MESH:
+                child_type = "render_mesh"
+            case SceneNodeType.RENDER_TEXT:
+                child_type = "render_text"
+            case SceneNodeType.RENDER_TEXTURE:
+                child_type = "render_texture"
+            case SceneNodeType.FONTS:
+                child_type = "fonts"
+            case SceneNodeType.FONT:
+                child_type = "font"
+            case SceneNodeType.LINE_POSITION:
+                child_type = "line_position"
+
+        desc = f"{ws}{child_name}:{child_id}/"
+        desc += " "*(50 - len(desc))
+        desc += f"[{child_type}]"
+        print(desc)
+
+        print_node_info(child_id, indent+1)
+
+    for prop_name, prop_type in api.get_properties(parent_id):
+        if prop_type == PropertyType.STR:
+            prop_val = api.get_property(parent_id, prop_name)
+            prop_val = f" = \"{prop_val}\""
+        elif prop_type != PropertyType.BUFFER:
+            prop_val = api.get_property(parent_id, prop_name)
+            prop_val = f" = {prop_val}"
+        else:
+            prop_val = ""
+
+        prop_type = PropertyType.to_str(prop_type)
+
+        print(f"{ws}{prop_name}: {prop_type}{prop_val}")
+
+    for sig in api.get_signals(parent_id):
+        print(f"{ws}~{sig}")
+        for slot_id, slot in api.get_slots(parent_id, sig):
+            print(f"{ws}- '{slot}' ({slot_id})")
+
+    for method_name in api.get_methods(parent_id):
+        args, results = api.get_method(parent_id, method_name)
+
+        args = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in args]
+        results = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in results]
+
+        method_str = f"{method_name}(" + ", ".join(args) + ") -> (" + ", ".join(results) + ")"
+        print(f"{ws}{method_str}")
+

+ 2 - 0
bin/darkwallet/gui/settings.py

@@ -0,0 +1,2 @@
+ui_scale = 1.0
+

+ 34 - 31
bin/darkwallet/src/gfx.rs

@@ -211,8 +211,11 @@ impl Stage {
 
         let mouse = scene_graph.add_node("mouse", SceneNodeType::Mouse);
         mouse.add_property("button", PropertyType::Uint32).unwrap();
-        mouse.add_property("x", PropertyType::Float32).unwrap();
-        mouse.add_property("y", PropertyType::Float32).unwrap();
+        mouse.add_property("motion_x", PropertyType::Float32).unwrap();
+        mouse.add_property("motion_y", PropertyType::Float32).unwrap();
+        mouse.add_property("wheel_y", PropertyType::Float32).unwrap();
+        mouse.add_property("click_x", PropertyType::Float32).unwrap();
+        mouse.add_property("click_y", PropertyType::Float32).unwrap();
         mouse.add_signal("button_up").unwrap();
         mouse.add_signal("button_down").unwrap();
         mouse.add_signal("wheel").unwrap();
@@ -676,24 +679,24 @@ impl EventHandler for Stage {
         };
 
         match keycode {
-            KeyCode::Space => send_key_down("Space"),
-            KeyCode::Apostrophe => send_key_down("Apostrophe"),
-            KeyCode::Comma => send_key_down("Comma"),
-            KeyCode::Minus => send_key_down("Minus"),
-            KeyCode::Period => send_key_down("Period"),
-            KeyCode::Slash => send_key_down("Slash"),
-            KeyCode::Key0 => send_key_down("Key0"),
-            KeyCode::Key1 => send_key_down("Key1"),
-            KeyCode::Key2 => send_key_down("Key2"),
-            KeyCode::Key3 => send_key_down("Key3"),
-            KeyCode::Key4 => send_key_down("Key4"),
-            KeyCode::Key5 => send_key_down("Key5"),
-            KeyCode::Key6 => send_key_down("Key6"),
-            KeyCode::Key7 => send_key_down("Key7"),
-            KeyCode::Key8 => send_key_down("Key8"),
-            KeyCode::Key9 => send_key_down("Key9"),
-            KeyCode::Semicolon => send_key_down("Semicolon"),
-            KeyCode::Equal => send_key_down("Equal"),
+            KeyCode::Space => send_key_down(" "),
+            KeyCode::Apostrophe => send_key_down("'"),
+            KeyCode::Comma => send_key_down(","),
+            KeyCode::Minus => send_key_down("-"),
+            KeyCode::Period => send_key_down("."),
+            KeyCode::Slash => send_key_down("/"),
+            KeyCode::Key0 => send_key_down("0"),
+            KeyCode::Key1 => send_key_down("1"),
+            KeyCode::Key2 => send_key_down("2"),
+            KeyCode::Key3 => send_key_down("3"),
+            KeyCode::Key4 => send_key_down("4"),
+            KeyCode::Key5 => send_key_down("5"),
+            KeyCode::Key6 => send_key_down("6"),
+            KeyCode::Key7 => send_key_down("7"),
+            KeyCode::Key8 => send_key_down("8"),
+            KeyCode::Key9 => send_key_down("9"),
+            KeyCode::Semicolon => send_key_down(":"),
+            KeyCode::Equal => send_key_down("="),
             KeyCode::A => send_key_down("A"),
             KeyCode::B => send_key_down("B"),
             KeyCode::C => send_key_down("C"),
@@ -720,9 +723,9 @@ impl EventHandler for Stage {
             KeyCode::X => send_key_down("X"),
             KeyCode::Y => send_key_down("Y"),
             KeyCode::Z => send_key_down("Z"),
-            KeyCode::LeftBracket => send_key_down("LeftBracket"),
-            KeyCode::Backslash => send_key_down("Backslash"),
-            KeyCode::RightBracket => send_key_down("RightBracket"),
+            KeyCode::LeftBracket => send_key_down("("),
+            KeyCode::Backslash => send_key_down("\\"),
+            KeyCode::RightBracket => send_key_down(")"),
             KeyCode::GraveAccent => send_key_down("GraveAccent"),
             KeyCode::World1 => send_key_down("World1"),
             KeyCode::World2 => send_key_down("World2"),
@@ -802,31 +805,31 @@ impl EventHandler for Stage {
     fn mouse_motion_event(&mut self, x: f32, y: f32) {
         let mut scene_graph = self.scene_graph.lock().unwrap();
         let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
-        mouse.set_property_f32("x", x).unwrap();
-        mouse.set_property_f32("y", y).unwrap();
+        mouse.set_property_f32("motion_x", x).unwrap();
+        mouse.set_property_f32("motion_y", y).unwrap();
         mouse.trigger("move").unwrap();
     }
     fn mouse_wheel_event(&mut self, x: f32, y: f32) {
         let mut scene_graph = self.scene_graph.lock().unwrap();
         let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
-        mouse.set_property_f32("x", x).unwrap();
-        mouse.set_property_f32("y", y).unwrap();
+        //mouse.set_property_f32("x", x).unwrap();
+        mouse.set_property_f32("wheel_y", y).unwrap();
         mouse.trigger("wheel").unwrap();
     }
     fn mouse_button_down_event(&mut self, button: MouseButton, x: f32, y: f32) {
         let mut scene_graph = self.scene_graph.lock().unwrap();
         let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
         mouse.set_property_u32("button", button.to_u8() as u32).unwrap();
-        mouse.set_property_f32("x", x).unwrap();
-        mouse.set_property_f32("y", y).unwrap();
+        mouse.set_property_f32("click_x", x).unwrap();
+        mouse.set_property_f32("click_y", y).unwrap();
         mouse.trigger("button_down").unwrap();
     }
     fn mouse_button_up_event(&mut self, button: MouseButton, x: f32, y: f32) {
         let mut scene_graph = self.scene_graph.lock().unwrap();
         let mouse = scene_graph.lookup_node_mut("/window/input/mouse").unwrap();
         mouse.set_property_u32("button", button.to_u8() as u32).unwrap();
-        mouse.set_property_f32("x", x).unwrap();
-        mouse.set_property_f32("y", y).unwrap();
+        mouse.set_property_f32("click_x", x).unwrap();
+        mouse.set_property_f32("click_y", y).unwrap();
         mouse.trigger("button_up").unwrap();
     }