Parcourir la source

wallet: add Roles to the property system. Useful for distinguishing between who modifies a property and later applying permissions too.

rsx il y a 2 ans
Parent
commit
cf2fe7d59e

+ 110 - 110
bin/darkwallet/src/app.rs

@@ -25,7 +25,7 @@ use crate::{
     error::Error,
     error::Error,
     expr::Op,
     expr::Op,
     gfx2::{GraphicsEventPublisherPtr, RenderApiPtr, Vertex},
     gfx2::{GraphicsEventPublisherPtr, RenderApiPtr, Vertex},
-    prop::{Property, PropertySubType, PropertyType},
+    prop::{Property, PropertySubType, PropertyType, Role},
     scene::{MethodResponseFn, Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, SceneNodeType},
     scene::{MethodResponseFn, Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, SceneNodeType},
     text2::TextShaperPtr,
     text2::TextShaperPtr,
     ui::{chatview, Button, ChatView, EditBox, Image, Mesh, RenderLayer, Stoppable, Text, Window},
     ui::{chatview, Button, ChatView, EditBox, Image, Mesh, RenderLayer, Stoppable, Text, Window},
@@ -144,8 +144,8 @@ impl App {
         let mut prop = Property::new("screen_size", PropertyType::Float32, PropertySubType::Pixel);
         let mut prop = Property::new("screen_size", PropertyType::Float32, PropertySubType::Pixel);
         prop.set_array_len(2);
         prop.set_array_len(2);
         // Window not yet initialized so we can't set these.
         // Window not yet initialized so we can't set these.
-        //prop.set_f32(0, screen_width);
-        //prop.set_f32(1, screen_height);
+        //prop.set_f32(Role::App, 0, screen_width);
+        //prop.set_f32(Role::App, 1, screen_height);
         window.add_property(prop).unwrap();
         window.add_property(prop).unwrap();
 
 
         let mut prop = Property::new("scale", PropertyType::Float32, PropertySubType::Pixel);
         let mut prop = Property::new("scale", PropertyType::Float32, PropertySubType::Pixel);
@@ -175,7 +175,7 @@ impl App {
 
 
         // Testing
         // Testing
         let node = sg.get_node(window_id).unwrap();
         let node = sg.get_node(window_id).unwrap();
-        node.set_property_f32("scale", 2.).unwrap();
+        node.set_property_f32(Role::App, "scale", 2.).unwrap();
 
 
         drop(sg);
         drop(sg);
 
 
@@ -214,13 +214,13 @@ impl App {
         // Customize our layer
         // Customize our layer
         let node = sg.get_node(layer_node_id).unwrap();
         let node = sg.get_node(layer_node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 0.).unwrap();
-        prop.set_f32(1, 0.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
+        prop.set_f32(Role::App, 1, 0.).unwrap();
         let code = vec![Op::LoadVar("w".to_string())];
         let code = vec![Op::LoadVar("w".to_string())];
-        prop.set_expr(2, code).unwrap();
+        prop.set_expr(Role::App, 2, code).unwrap();
         let code = vec![Op::LoadVar("h".to_string())];
         let code = vec![Op::LoadVar("h".to_string())];
-        prop.set_expr(3, code).unwrap();
-        node.set_property_bool("is_visible", true).unwrap();
+        prop.set_expr(Role::App, 3, code).unwrap();
+        node.set_property_bool(Role::App, "is_visible", true).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         let node_id = node.id;
         let node_id = node.id;
@@ -240,12 +240,12 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 0.).unwrap();
-        prop.set_f32(1, 0.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
+        prop.set_f32(Role::App, 1, 0.).unwrap();
         let code = vec![Op::LoadVar("w".to_string())];
         let code = vec![Op::LoadVar("w".to_string())];
-        prop.set_expr(2, code).unwrap();
+        prop.set_expr(Role::App, 2, code).unwrap();
         let code = vec![Op::LoadVar("h".to_string())];
         let code = vec![Op::LoadVar("h".to_string())];
-        prop.set_expr(3, code).unwrap();
+        prop.set_expr(Role::App, 3, code).unwrap();
 
 
         let c = if LIGHTMODE { 1. } else { 0. };
         let c = if LIGHTMODE { 1. } else { 0. };
         // Setup the pimpl
         // Setup the pimpl
@@ -288,10 +288,10 @@ impl App {
             Box::new(Op::LoadVar("w".to_string())),
             Box::new(Op::LoadVar("w".to_string())),
             Box::new(Op::ConstFloat32(220.)),
             Box::new(Op::ConstFloat32(220.)),
         ))];
         ))];
-        prop.set_expr(0, code).unwrap();
-        prop.set_f32(1, 10.).unwrap();
-        prop.set_f32(2, 200.).unwrap();
-        prop.set_f32(3, 60.).unwrap();
+        prop.set_expr(Role::App, 0, code).unwrap();
+        prop.set_f32(Role::App, 1, 10.).unwrap();
+        prop.set_f32(Role::App, 2, 200.).unwrap();
+        prop.set_f32(Role::App, 3, 60.).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         let (x1, y1) = (0., 0.);
         let (x1, y1) = (0., 0.);
@@ -340,16 +340,16 @@ impl App {
         let node_id = create_button(&mut sg, "btn");
         let node_id = create_button(&mut sg, "btn");
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
-        node.set_property_bool("is_active", true).unwrap();
+        node.set_property_bool(Role::App, "is_active", true).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
         let code = vec![Op::Sub((
         let code = vec![Op::Sub((
             Box::new(Op::LoadVar("w".to_string())),
             Box::new(Op::LoadVar("w".to_string())),
             Box::new(Op::ConstFloat32(220.)),
             Box::new(Op::ConstFloat32(220.)),
         ))];
         ))];
-        prop.set_expr(0, code).unwrap();
-        prop.set_f32(1, 10.).unwrap();
-        prop.set_f32(2, 200.).unwrap();
-        prop.set_f32(3, 60.).unwrap();
+        prop.set_expr(Role::App, 0, code).unwrap();
+        prop.set_f32(Role::App, 1, 10.).unwrap();
+        prop.set_f32(Role::App, 2, 200.).unwrap();
+        prop.set_f32(Role::App, 3, 60.).unwrap();
 
 
         drop(sg);
         drop(sg);
         let pimpl =
         let pimpl =
@@ -365,10 +365,10 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 10.).unwrap();
-        prop.set_f32(1, 10.).unwrap();
-        prop.set_f32(2, 60.).unwrap();
-        prop.set_f32(3, 60.).unwrap();
+        prop.set_f32(Role::App, 0, 10.).unwrap();
+        prop.set_f32(Role::App, 1, 10.).unwrap();
+        prop.set_f32(Role::App, 2, 60.).unwrap();
+        prop.set_f32(Role::App, 3, 60.).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         let (x1, y1) = (0., 0.);
         let (x1, y1) = (0., 0.);
@@ -418,15 +418,15 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 0.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
         let code =
         let code =
             vec![Op::Div((Box::new(Op::LoadVar("h".to_string())), Box::new(Op::ConstFloat32(2.))))];
             vec![Op::Div((Box::new(Op::LoadVar("h".to_string())), Box::new(Op::ConstFloat32(2.))))];
-        prop.set_expr(1, code).unwrap();
+        prop.set_expr(Role::App, 1, code).unwrap();
         let code = vec![Op::LoadVar("w".to_string())];
         let code = vec![Op::LoadVar("w".to_string())];
-        prop.set_expr(2, code).unwrap();
-        prop.set_f32(3, 5.).unwrap();
+        prop.set_expr(Role::App, 2, code).unwrap();
+        prop.set_f32(Role::App, 3, 5.).unwrap();
 
 
-        node.set_property_u32("z_index", 2).unwrap();
+        node.set_property_u32(Role::App, "z_index", 2).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         let (x1, y1) = (0., 0.);
         let (x1, y1) = (0., 0.);
@@ -463,17 +463,17 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 0.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
         let code = vec![Op::Sub((
         let code = vec![Op::Sub((
             Box::new(Op::LoadVar("h".to_string())),
             Box::new(Op::LoadVar("h".to_string())),
             Box::new(Op::ConstFloat32(200.)),
             Box::new(Op::ConstFloat32(200.)),
         ))];
         ))];
-        prop.set_expr(1, code).unwrap();
+        prop.set_expr(Role::App, 1, code).unwrap();
         let code = vec![Op::LoadVar("w".to_string())];
         let code = vec![Op::LoadVar("w".to_string())];
-        prop.set_expr(2, code).unwrap();
-        prop.set_f32(3, 5.).unwrap();
+        prop.set_expr(Role::App, 2, code).unwrap();
+        prop.set_f32(Role::App, 3, 5.).unwrap();
 
 
-        node.set_property_u32("z_index", 2).unwrap();
+        node.set_property_u32(Role::App, "z_index", 2).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         let (x1, y1) = (0., 0.);
         let (x1, y1) = (0., 0.);
@@ -510,12 +510,12 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 80.).unwrap();
-        prop.set_f32(1, 10.).unwrap();
-        prop.set_f32(2, 60.).unwrap();
-        prop.set_f32(3, 60.).unwrap();
+        prop.set_f32(Role::App, 0, 80.).unwrap();
+        prop.set_f32(Role::App, 1, 10.).unwrap();
+        prop.set_f32(Role::App, 2, 60.).unwrap();
+        prop.set_f32(Role::App, 3, 60.).unwrap();
 
 
-        node.set_property_str("path", KING_PATH).unwrap();
+        node.set_property_str(Role::App, "path", KING_PATH).unwrap();
 
 
         // Setup the pimpl
         // Setup the pimpl
         drop(sg);
         drop(sg);
@@ -532,19 +532,19 @@ impl App {
 
 
         let node = sg.get_node_mut(node_id).unwrap();
         let node = sg.get_node_mut(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 100.).unwrap();
-        prop.set_f32(1, 100.).unwrap();
-        prop.set_f32(2, 800.).unwrap();
-        prop.set_f32(3, 200.).unwrap();
-        node.set_property_f32("baseline", 40.).unwrap();
-        node.set_property_f32("font_size", 60.).unwrap();
-        node.set_property_str("text", "anon1🍆").unwrap();
-        //node.set_property_str("text", "anon1").unwrap();
+        prop.set_f32(Role::App, 0, 100.).unwrap();
+        prop.set_f32(Role::App, 1, 100.).unwrap();
+        prop.set_f32(Role::App, 2, 800.).unwrap();
+        prop.set_f32(Role::App, 3, 200.).unwrap();
+        node.set_property_f32(Role::App, "baseline", 40.).unwrap();
+        node.set_property_f32(Role::App, "font_size", 60.).unwrap();
+        node.set_property_str(Role::App, "text", "anon1🍆").unwrap();
+        //node.set_property_str(Role::App, "text", "anon1").unwrap();
         let prop = node.get_property("text_color").unwrap();
         let prop = node.get_property("text_color").unwrap();
-        prop.set_f32(0, 0.).unwrap();
-        prop.set_f32(1, 1.).unwrap();
-        prop.set_f32(2, 0.).unwrap();
-        prop.set_f32(3, 1.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
+        prop.set_f32(Role::App, 1, 1.).unwrap();
+        prop.set_f32(Role::App, 2, 0.).unwrap();
+        prop.set_f32(Role::App, 3, 1.).unwrap();
 
 
         drop(sg);
         drop(sg);
         let pimpl = Text::new(
         let pimpl = Text::new(
@@ -564,60 +564,60 @@ impl App {
         // Text edit
         // Text edit
         let node_id = create_editbox(&mut sg, "editz");
         let node_id = create_editbox(&mut sg, "editz");
         let node = sg.get_node(node_id).unwrap();
         let node = sg.get_node(node_id).unwrap();
-        node.set_property_bool("is_active", true).unwrap();
+        node.set_property_bool(Role::App, "is_active", true).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 150.).unwrap();
-        prop.set_f32(1, 150.).unwrap();
-        prop.set_f32(2, 380.).unwrap();
+        prop.set_f32(Role::App, 0, 150.).unwrap();
+        prop.set_f32(Role::App, 1, 150.).unwrap();
+        prop.set_f32(Role::App, 2, 380.).unwrap();
         //let code = vec![Op::Sub((
         //let code = vec![Op::Sub((
         //    Box::new(Op::LoadVar("h".to_string())),
         //    Box::new(Op::LoadVar("h".to_string())),
         //    Box::new(Op::ConstFloat32(60.)),
         //    Box::new(Op::ConstFloat32(60.)),
         //))];
         //))];
-        //prop.set_expr(1, code).unwrap();
+        //prop.set_expr(Role::App, 1, code).unwrap();
         //let code = vec![Op::Sub((
         //let code = vec![Op::Sub((
         //    Box::new(Op::LoadVar("w".to_string())),
         //    Box::new(Op::LoadVar("w".to_string())),
         //    Box::new(Op::ConstFloat32(120.)),
         //    Box::new(Op::ConstFloat32(120.)),
         //))];
         //))];
-        //prop.set_expr(2, code).unwrap();
-        prop.set_f32(3, 60.).unwrap();
-        node.set_property_f32("baseline", 40.).unwrap();
-        node.set_property_f32("font_size", 20.).unwrap();
-        node.set_property_f32("font_size", 40.).unwrap();
-        node.set_property_str("text", "hello king!😁🍆jelly 🍆1234").unwrap();
+        //prop.set_expr(Role::App, 2, code).unwrap();
+        prop.set_f32(Role::App, 3, 60.).unwrap();
+        node.set_property_f32(Role::App, "baseline", 40.).unwrap();
+        node.set_property_f32(Role::App, "font_size", 20.).unwrap();
+        node.set_property_f32(Role::App, "font_size", 40.).unwrap();
+        node.set_property_str(Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
         let prop = node.get_property("text_color").unwrap();
         let prop = node.get_property("text_color").unwrap();
         if LIGHTMODE {
         if LIGHTMODE {
-            prop.set_f32(0, 0.).unwrap();
-            prop.set_f32(1, 0.).unwrap();
-            prop.set_f32(2, 0.).unwrap();
-            prop.set_f32(3, 1.).unwrap();
+            prop.set_f32(Role::App, 0, 0.).unwrap();
+            prop.set_f32(Role::App, 1, 0.).unwrap();
+            prop.set_f32(Role::App, 2, 0.).unwrap();
+            prop.set_f32(Role::App, 3, 1.).unwrap();
         } else {
         } else {
-            prop.set_f32(0, 1.).unwrap();
-            prop.set_f32(1, 1.).unwrap();
-            prop.set_f32(2, 1.).unwrap();
-            prop.set_f32(3, 1.).unwrap();
+            prop.set_f32(Role::App, 0, 1.).unwrap();
+            prop.set_f32(Role::App, 1, 1.).unwrap();
+            prop.set_f32(Role::App, 2, 1.).unwrap();
+            prop.set_f32(Role::App, 3, 1.).unwrap();
         }
         }
         let prop = node.get_property("cursor_color").unwrap();
         let prop = node.get_property("cursor_color").unwrap();
-        prop.set_f32(0, 1.).unwrap();
-        prop.set_f32(1, 0.5).unwrap();
-        prop.set_f32(2, 0.5).unwrap();
-        prop.set_f32(3, 1.).unwrap();
+        prop.set_f32(Role::App, 0, 1.).unwrap();
+        prop.set_f32(Role::App, 1, 0.5).unwrap();
+        prop.set_f32(Role::App, 2, 0.5).unwrap();
+        prop.set_f32(Role::App, 3, 1.).unwrap();
         let prop = node.get_property("hi_bg_color").unwrap();
         let prop = node.get_property("hi_bg_color").unwrap();
         if LIGHTMODE {
         if LIGHTMODE {
-            prop.set_f32(0, 0.5).unwrap();
-            prop.set_f32(1, 0.5).unwrap();
-            prop.set_f32(2, 0.5).unwrap();
-            prop.set_f32(3, 1.).unwrap();
+            prop.set_f32(Role::App, 0, 0.5).unwrap();
+            prop.set_f32(Role::App, 1, 0.5).unwrap();
+            prop.set_f32(Role::App, 2, 0.5).unwrap();
+            prop.set_f32(Role::App, 3, 1.).unwrap();
         } else {
         } else {
-            prop.set_f32(0, 1.).unwrap();
-            prop.set_f32(1, 1.).unwrap();
-            prop.set_f32(2, 1.).unwrap();
-            prop.set_f32(3, 0.5).unwrap();
+            prop.set_f32(Role::App, 0, 1.).unwrap();
+            prop.set_f32(Role::App, 1, 1.).unwrap();
+            prop.set_f32(Role::App, 2, 1.).unwrap();
+            prop.set_f32(Role::App, 3, 0.5).unwrap();
         }
         }
         let prop = node.get_property("selected").unwrap();
         let prop = node.get_property("selected").unwrap();
-        prop.set_null(0).unwrap();
-        prop.set_null(1).unwrap();
-        node.set_property_u32("z_index", 1).unwrap();
-        //node.set_property_bool("debug", true).unwrap();
+        prop.set_null(Role::App, 0).unwrap();
+        prop.set_null(Role::App, 1).unwrap();
+        node.set_property_u32(Role::App, "z_index", 1).unwrap();
+        //node.set_property_bool(Role::App, "debug", true).unwrap();
 
 
         drop(sg);
         drop(sg);
         let pimpl = EditBox::new(
         let pimpl = EditBox::new(
@@ -639,12 +639,12 @@ impl App {
         let (node_id, recvr) = create_chatview(&mut sg, "chatty");
         let (node_id, recvr) = create_chatview(&mut sg, "chatty");
         let node = sg.get_node(node_id).unwrap();
         let node = sg.get_node(node_id).unwrap();
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
-        prop.set_f32(0, 0.).unwrap();
+        prop.set_f32(Role::App, 0, 0.).unwrap();
         let code =
         let code =
             vec![Op::Div((Box::new(Op::LoadVar("h".to_string())), Box::new(Op::ConstFloat32(2.))))];
             vec![Op::Div((Box::new(Op::LoadVar("h".to_string())), Box::new(Op::ConstFloat32(2.))))];
-        prop.set_expr(1, code).unwrap();
+        prop.set_expr(Role::App, 1, code).unwrap();
         let code = vec![Op::LoadVar("w".to_string())];
         let code = vec![Op::LoadVar("w".to_string())];
-        prop.set_expr(2, code).unwrap();
+        prop.set_expr(Role::App, 2, code).unwrap();
         let code = vec![Op::Sub((
         let code = vec![Op::Sub((
             Box::new(Op::Div((
             Box::new(Op::Div((
                 Box::new(Op::LoadVar("h".to_string())),
                 Box::new(Op::LoadVar("h".to_string())),
@@ -652,28 +652,28 @@ impl App {
             ))),
             ))),
             Box::new(Op::ConstFloat32(200.)),
             Box::new(Op::ConstFloat32(200.)),
         ))];
         ))];
-        prop.set_expr(3, code).unwrap();
-        node.set_property_f32("font_size", 20.).unwrap();
-        node.set_property_f32("line_height", 30.).unwrap();
-        node.set_property_f32("baseline", 20.).unwrap();
-        node.set_property_u32("z_index", 1).unwrap();
+        prop.set_expr(Role::App, 3, code).unwrap();
+        node.set_property_f32(Role::App, "font_size", 20.).unwrap();
+        node.set_property_f32(Role::App, "line_height", 30.).unwrap();
+        node.set_property_f32(Role::App, "baseline", 20.).unwrap();
+        node.set_property_u32(Role::App, "z_index", 1).unwrap();
 
 
         let prop = node.get_property("timestamp_color").unwrap();
         let prop = node.get_property("timestamp_color").unwrap();
-        prop.set_f32(0, 0.5).unwrap();
-        prop.set_f32(1, 0.5).unwrap();
-        prop.set_f32(2, 0.5).unwrap();
-        prop.set_f32(3, 0.5).unwrap();
+        prop.set_f32(Role::App, 0, 0.5).unwrap();
+        prop.set_f32(Role::App, 1, 0.5).unwrap();
+        prop.set_f32(Role::App, 2, 0.5).unwrap();
+        prop.set_f32(Role::App, 3, 0.5).unwrap();
         let prop = node.get_property("text_color").unwrap();
         let prop = node.get_property("text_color").unwrap();
         if LIGHTMODE {
         if LIGHTMODE {
-            prop.set_f32(0, 0.).unwrap();
-            prop.set_f32(1, 0.).unwrap();
-            prop.set_f32(2, 0.).unwrap();
-            prop.set_f32(3, 1.).unwrap();
+            prop.set_f32(Role::App, 0, 0.).unwrap();
+            prop.set_f32(Role::App, 1, 0.).unwrap();
+            prop.set_f32(Role::App, 2, 0.).unwrap();
+            prop.set_f32(Role::App, 3, 1.).unwrap();
         } else {
         } else {
-            prop.set_f32(0, 1.).unwrap();
-            prop.set_f32(1, 1.).unwrap();
-            prop.set_f32(2, 1.).unwrap();
-            prop.set_f32(3, 1.).unwrap();
+            prop.set_f32(Role::App, 0, 1.).unwrap();
+            prop.set_f32(Role::App, 1, 1.).unwrap();
+            prop.set_f32(Role::App, 2, 1.).unwrap();
+            prop.set_f32(Role::App, 3, 1.).unwrap();
         }
         }
 
 
         let prop = node.get_property("nick_colors").unwrap();
         let prop = node.get_property("nick_colors").unwrap();
@@ -691,7 +691,7 @@ impl App {
             1.00, 0.30, 0.00, 1.
             1.00, 0.30, 0.00, 1.
         ];
         ];
         for c in nick_colors {
         for c in nick_colors {
-            prop.push_f32(c).unwrap();
+            prop.push_f32(Role::App, c).unwrap();
         }
         }
 
 
         drop(sg);
         drop(sg);
@@ -723,7 +723,7 @@ impl App {
         // This also affects mouse/touch input since coords need to be accurately translated
         // This also affects mouse/touch input since coords need to be accurately translated
         // Also we need to think about nesting of layers.
         // Also we need to think about nesting of layers.
         //let window_node = sg.get_node_mut(window_id).unwrap();
         //let window_node = sg.get_node_mut(window_id).unwrap();
-        //win_node.set_property_f32("scale", 1.6).unwrap();
+        //win_node.set_property_f32(Role::App, "scale", 1.6).unwrap();
     }
     }
 
 
     async fn trigger_redraw(&self) {
     async fn trigger_redraw(&self) {

+ 10 - 10
bin/darkwallet/src/net.rs

@@ -27,7 +27,7 @@ use zeromq::{Socket, SocketRecv, SocketSend};
 use crate::{
 use crate::{
     error::{Error, Result},
     error::{Error, Result},
     expr::SExprCode,
     expr::SExprCode,
-    prop::{Property, PropertySubType, PropertyType, PropertyValue},
+    prop::{Property, PropertySubType, PropertyType, PropertyValue, Role},
     scene::{SceneGraphPtr2, SceneNodeId, SceneNodeType, Slot, SlotId},
     scene::{SceneGraphPtr2, SceneNodeId, SceneNodeType, Slot, SlotId},
 };
 };
 
 
@@ -381,40 +381,40 @@ impl ZeroMQAdapter {
 
 
                 match prop_type {
                 match prop_type {
                     PropertyType::Null => {
                     PropertyType::Null => {
-                        prop.set_null(prop_i)?;
+                        prop.set_null(Role::User, prop_i)?;
                     }
                     }
                     PropertyType::Bool => {
                     PropertyType::Bool => {
                         let val = bool::decode(&mut cur).unwrap();
                         let val = bool::decode(&mut cur).unwrap();
-                        prop.set_bool(prop_i, val)?;
+                        prop.set_bool(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::Uint32 => {
                     PropertyType::Uint32 => {
                         let val = u32::decode(&mut cur).unwrap();
                         let val = u32::decode(&mut cur).unwrap();
-                        prop.set_u32(prop_i, val)?;
+                        prop.set_u32(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::Float32 => {
                     PropertyType::Float32 => {
                         let val = f32::decode(&mut cur).unwrap();
                         let val = f32::decode(&mut cur).unwrap();
-                        prop.set_f32(prop_i, val)?;
+                        prop.set_f32(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::Str => {
                     PropertyType::Str => {
                         let val = String::decode(&mut cur).unwrap();
                         let val = String::decode(&mut cur).unwrap();
-                        prop.set_str(prop_i, val)?;
+                        prop.set_str(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::Enum => {
                     PropertyType::Enum => {
                         let val = String::decode(&mut cur).unwrap();
                         let val = String::decode(&mut cur).unwrap();
-                        prop.set_enum(prop_i, val)?;
+                        prop.set_enum(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::Buffer => {
                     PropertyType::Buffer => {
                         let val = Vec::<u8>::decode(&mut cur).unwrap();
                         let val = Vec::<u8>::decode(&mut cur).unwrap();
-                        prop.set_buf(prop_i, val)?;
+                        prop.set_buf(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::SceneNodeId => {
                     PropertyType::SceneNodeId => {
                         let val = SceneNodeId::decode(&mut cur).unwrap();
                         let val = SceneNodeId::decode(&mut cur).unwrap();
-                        prop.set_node_id(prop_i, val)?;
+                        prop.set_node_id(Role::User, prop_i, val)?;
                     }
                     }
                     PropertyType::SExpr => {
                     PropertyType::SExpr => {
                         let val = SExprCode::decode(&mut cur).unwrap();
                         let val = SExprCode::decode(&mut cur).unwrap();
                         debug!(target: "req", "  received code {:?}", val);
                         debug!(target: "req", "  received code {:?}", val);
-                        prop.set_expr(prop_i, val)?;
+                        prop.set_expr(Role::User, prop_i, val)?;
                     }
                     }
                 }
                 }
             }
             }

+ 63 - 58
bin/darkwallet/src/prop/mod.rs

@@ -74,6 +74,13 @@ pub enum PropertySubType {
     ResourceId = 3,
     ResourceId = 3,
 }
 }
 
 
+#[derive(Debug, Copy, Clone)]
+pub enum Role {
+    User = 0,
+    App = 1,
+    Internal = 2,
+}
+
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub enum PropertyValue {
 pub enum PropertyValue {
     Unset,
     Unset,
@@ -197,7 +204,7 @@ impl Encodable for PropertyValue {
 pub enum ModifyAction {
 pub enum ModifyAction {
     Clear,
     Clear,
     Set(usize),
     Set(usize),
-    Push,
+    Push(usize),
 }
 }
 
 
 pub type PropertyPtr = Arc<Property>;
 pub type PropertyPtr = Arc<Property>;
@@ -226,7 +233,7 @@ pub struct Property {
     // PropertyType must be Enum
     // PropertyType must be Enum
     pub enum_items: Option<Vec<String>>,
     pub enum_items: Option<Vec<String>>,
 
 
-    on_modify: PublisherPtr<ModifyAction>,
+    on_modify: PublisherPtr<(Role, ModifyAction)>,
 }
 }
 
 
 impl Property {
 impl Property {
@@ -327,14 +334,14 @@ impl Property {
     // Set
     // Set
 
 
     /// This will clear all values, resetting them to the default
     /// This will clear all values, resetting them to the default
-    pub fn clear_values(&self) {
+    pub fn clear_values(&self, role: Role) {
         let vals = &mut self.vals.lock().unwrap();
         let vals = &mut self.vals.lock().unwrap();
         vals.clear();
         vals.clear();
         vals.resize(self.array_len, PropertyValue::Unset);
         vals.resize(self.array_len, PropertyValue::Unset);
-        self.on_modify.notify(ModifyAction::Clear);
+        self.on_modify.notify((role, ModifyAction::Clear));
     }
     }
 
 
-    fn set_raw_value(&self, i: usize, val: PropertyValue) -> Result<()> {
+    fn set_raw_value(&self, role: Role, i: usize, val: PropertyValue) -> Result<()> {
         if self.typ != val.as_type() {
         if self.typ != val.as_type() {
             return Err(Error::PropertyWrongType)
             return Err(Error::PropertyWrongType)
         }
         }
@@ -344,37 +351,40 @@ impl Property {
             return Err(Error::PropertyWrongIndex)
             return Err(Error::PropertyWrongIndex)
         }
         }
         vals[i] = val;
         vals[i] = val;
-        self.on_modify.notify(ModifyAction::Set(i));
+        self.on_modify.notify((role, ModifyAction::Set(i)));
         Ok(())
         Ok(())
     }
     }
 
 
-    pub fn unset(&self, i: usize) -> Result<()> {
+    pub fn unset(&self, role: Role, i: usize) -> Result<()> {
         let vals = &mut self.vals.lock().unwrap();
         let vals = &mut self.vals.lock().unwrap();
         if i >= vals.len() {
         if i >= vals.len() {
             return Err(Error::PropertyWrongIndex)
             return Err(Error::PropertyWrongIndex)
         }
         }
         vals[i] = PropertyValue::Unset;
         vals[i] = PropertyValue::Unset;
-        self.on_modify.notify(ModifyAction::Set(i));
+        self.on_modify.notify((role, ModifyAction::Set(i)));
         Ok(())
         Ok(())
     }
     }
 
 
-    pub fn set_null(&self, i: usize) -> Result<()> {
+    pub fn set_null(&self, role: Role, i: usize) -> Result<()> {
         if !self.is_null_allowed {
         if !self.is_null_allowed {
             return Err(Error::PropertyNullNotAllowed)
             return Err(Error::PropertyNullNotAllowed)
         }
         }
+
         let vals = &mut self.vals.lock().unwrap();
         let vals = &mut self.vals.lock().unwrap();
         if i >= vals.len() {
         if i >= vals.len() {
             return Err(Error::PropertyWrongIndex)
             return Err(Error::PropertyWrongIndex)
         }
         }
         vals[i] = PropertyValue::Null;
         vals[i] = PropertyValue::Null;
-        self.on_modify.notify(ModifyAction::Set(i));
+        drop(vals);
+
+        self.on_modify.notify((role, ModifyAction::Set(i)));
         Ok(())
         Ok(())
     }
     }
 
 
-    pub fn set_bool(&self, i: usize, val: bool) -> Result<()> {
-        self.set_raw_value(i, PropertyValue::Bool(val))
+    pub fn set_bool(&self, role: Role, i: usize, val: bool) -> Result<()> {
+        self.set_raw_value(role, i, PropertyValue::Bool(val))
     }
     }
-    pub fn set_u32(&self, i: usize, val: u32) -> Result<()> {
+    pub fn set_u32(&self, role: Role, i: usize, val: u32) -> Result<()> {
         if self.min_val.is_some() {
         if self.min_val.is_some() {
             let min = self.min_val.as_ref().unwrap().as_u32()?;
             let min = self.min_val.as_ref().unwrap().as_u32()?;
             if val < min {
             if val < min {
@@ -387,9 +397,9 @@ impl Property {
                 return Err(Error::PropertyOutOfRange);
                 return Err(Error::PropertyOutOfRange);
             }
             }
         }
         }
-        self.set_raw_value(i, PropertyValue::Uint32(val))
+        self.set_raw_value(role, i, PropertyValue::Uint32(val))
     }
     }
-    pub fn set_f32(&self, i: usize, val: f32) -> Result<()> {
+    pub fn set_f32(&self, role: Role, i: usize, val: f32) -> Result<()> {
         if self.min_val.is_some() {
         if self.min_val.is_some() {
             let min = self.min_val.as_ref().unwrap().as_f32()?;
             let min = self.min_val.as_ref().unwrap().as_f32()?;
             if val < min {
             if val < min {
@@ -402,12 +412,12 @@ impl Property {
                 return Err(Error::PropertyOutOfRange);
                 return Err(Error::PropertyOutOfRange);
             }
             }
         }
         }
-        self.set_raw_value(i, PropertyValue::Float32(val))
+        self.set_raw_value(role, i, PropertyValue::Float32(val))
     }
     }
-    pub fn set_str<S: Into<String>>(&self, i: usize, val: S) -> Result<()> {
-        self.set_raw_value(i, PropertyValue::Str(val.into()))
+    pub fn set_str<S: Into<String>>(&self, role: Role, i: usize, val: S) -> Result<()> {
+        self.set_raw_value(role, i, PropertyValue::Str(val.into()))
     }
     }
-    pub fn set_enum<S: Into<String>>(&self, i: usize, val: S) -> Result<()> {
+    pub fn set_enum<S: Into<String>>(&self, role: Role, i: usize, val: S) -> Result<()> {
         if self.typ != PropertyType::Enum {
         if self.typ != PropertyType::Enum {
             return Err(Error::PropertyWrongType)
             return Err(Error::PropertyWrongType)
         }
         }
@@ -415,15 +425,15 @@ impl Property {
         if !self.enum_items.as_ref().unwrap().contains(&val) {
         if !self.enum_items.as_ref().unwrap().contains(&val) {
             return Err(Error::PropertyWrongEnumItem)
             return Err(Error::PropertyWrongEnumItem)
         }
         }
-        self.set_raw_value(i, PropertyValue::Enum(val.into()))
+        self.set_raw_value(role, i, PropertyValue::Enum(val.into()))
     }
     }
-    pub fn set_buf(&self, i: usize, val: Vec<u8>) -> Result<()> {
-        self.set_raw_value(i, PropertyValue::Buffer(Arc::new(val)))
+    pub fn set_buf(&self, role: Role, i: usize, val: Vec<u8>) -> Result<()> {
+        self.set_raw_value(role, i, PropertyValue::Buffer(Arc::new(val)))
     }
     }
-    pub fn set_node_id(&self, i: usize, val: SceneNodeId) -> Result<()> {
-        self.set_raw_value(i, PropertyValue::SceneNodeId(val))
+    pub fn set_node_id(&self, role: Role, i: usize, val: SceneNodeId) -> Result<()> {
+        self.set_raw_value(role, i, PropertyValue::SceneNodeId(val))
     }
     }
-    pub fn set_expr(&self, i: usize, val: SExprCode) -> Result<()> {
+    pub fn set_expr(&self, role: Role, i: usize, val: SExprCode) -> Result<()> {
         if !self.is_expr_allowed {
         if !self.is_expr_allowed {
             return Err(Error::PropertySExprNotAllowed)
             return Err(Error::PropertySExprNotAllowed)
         }
         }
@@ -432,7 +442,7 @@ impl Property {
             return Err(Error::PropertyWrongIndex)
             return Err(Error::PropertyWrongIndex)
         }
         }
         vals[i] = PropertyValue::SExpr(Arc::new(val));
         vals[i] = PropertyValue::SExpr(Arc::new(val));
-        self.on_modify.notify(ModifyAction::Set(i));
+        self.on_modify.notify((role, ModifyAction::Set(i)));
         Ok(())
         Ok(())
     }
     }
 
 
@@ -457,51 +467,46 @@ impl Property {
 
 
     // Push
     // Push
 
 
-    pub fn push_null(&self) -> Result<usize> {
+    fn push_value(&self, role: Role, value: PropertyValue) -> Result<usize> {
         if self.is_bounded() {
         if self.is_bounded() {
             return Err(Error::PropertyIsBounded)
             return Err(Error::PropertyIsBounded)
         }
         }
+
         let vals = &mut self.vals.lock().unwrap();
         let vals = &mut self.vals.lock().unwrap();
         let i = vals.len();
         let i = vals.len();
-        vals.push(PropertyValue::Null);
-        self.on_modify.notify(ModifyAction::Push);
+        vals.push(value);
+        drop(vals);
+
+        self.on_modify.notify((role, ModifyAction::Push(i)));
         Ok(i)
         Ok(i)
     }
     }
 
 
-    pub fn push_bool(&self, val: bool) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_bool(i, val)?;
-        Ok(i)
+    pub fn push_null(&self, role: Role) -> Result<usize> {
+        self.push_value(role, PropertyValue::Null)
     }
     }
-    pub fn push_u32(&self, val: u32) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_u32(i, val)?;
-        Ok(i)
+
+    pub fn push_bool(&self, role: Role, val: bool) -> Result<usize> {
+        self.push_value(role, PropertyValue::Bool(val))
     }
     }
-    pub fn push_f32(&self, val: f32) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_f32(i, val)?;
-        Ok(i)
+    pub fn push_u32(&self, role: Role, val: u32) -> Result<usize> {
+        // TODO: none of these push calls are enforcing constraints that are required
+        // see the set_XX calls.
+        self.push_value(role, PropertyValue::Uint32(val))
     }
     }
-    pub fn push_str<S: Into<String>>(&self, val: S) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_str(i, val)?;
-        Ok(i)
+    pub fn push_f32(&self, role: Role, val: f32) -> Result<usize> {
+        self.push_value(role, PropertyValue::Float32(val))
     }
     }
-    pub fn push_enum<S: Into<String>>(&self, val: S) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_enum(i, val)?;
-        Ok(i)
+    pub fn push_str<S: Into<String>>(&self, role: Role, val: S) -> Result<usize> {
+        self.push_value(role, PropertyValue::Str(val.into()))
     }
     }
-    pub fn push_buf(&self, val: Vec<u8>) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_buf(i, val)?;
-        Ok(i)
+    pub fn push_enum<S: Into<String>>(&self, role: Role, val: S) -> Result<usize> {
+        self.push_value(role, PropertyValue::Enum(val.into()))
     }
     }
-    pub fn push_node_id(&self, val: SceneNodeId) -> Result<usize> {
-        let i = self.push_null()?;
-        self.set_node_id(i, val)?;
-        Ok(i)
+    pub fn push_buf(&self, role: Role, val: Vec<u8>) -> Result<usize> {
+        self.push_value(role, PropertyValue::Buffer(Arc::new(val)))
+    }
+    pub fn push_node_id(&self, role: Role, val: SceneNodeId) -> Result<usize> {
+        self.push_value(role, PropertyValue::SceneNodeId(val))
     }
     }
 
 
     // Get
     // Get
@@ -643,7 +648,7 @@ impl Property {
 
 
     // Subs
     // Subs
 
 
-    pub fn subscribe_modify(&self) -> Subscription<ModifyAction> {
+    pub fn subscribe_modify(&self) -> Subscription<(Role, ModifyAction)> {
         self.on_modify.clone().subscribe()
         self.on_modify.clone().subscribe()
     }
     }
 }
 }

+ 26 - 21
bin/darkwallet/src/prop/wrap.rs

@@ -18,7 +18,7 @@
 
 
 use std::sync::Arc;
 use std::sync::Arc;
 
 
-use super::{Property, PropertyPtr};
+use super::{Property, PropertyPtr, Role};
 use crate::{
 use crate::{
     error::{Error, Result},
     error::{Error, Result},
     scene::SceneNode,
     scene::SceneNode,
@@ -26,17 +26,18 @@ use crate::{
 
 
 pub struct PropertyBool {
 pub struct PropertyBool {
     prop: PropertyPtr,
     prop: PropertyPtr,
+    role: Role,
     idx: usize,
     idx: usize,
 }
 }
 
 
 impl PropertyBool {
 impl PropertyBool {
-    pub fn wrap(node: &SceneNode, prop_name: &str, idx: usize) -> Result<Self> {
+    pub fn wrap(node: &SceneNode, role: Role, prop_name: &str, idx: usize) -> Result<Self> {
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
 
 
         // Test if it works
         // Test if it works
         let _ = prop.get_bool(idx)?;
         let _ = prop.get_bool(idx)?;
 
 
-        Ok(Self { prop, idx })
+        Ok(Self { prop, role, idx })
     }
     }
 
 
     pub fn get(&self) -> bool {
     pub fn get(&self) -> bool {
@@ -44,7 +45,7 @@ impl PropertyBool {
     }
     }
 
 
     pub fn set(&self, val: bool) {
     pub fn set(&self, val: bool) {
-        self.prop.set_bool(self.idx, val).unwrap()
+        self.prop.set_bool(self.role, self.idx, val).unwrap()
     }
     }
 
 
     pub fn prop(&self) -> PropertyPtr {
     pub fn prop(&self) -> PropertyPtr {
@@ -54,24 +55,25 @@ impl PropertyBool {
 
 
 pub struct PropertyUint32 {
 pub struct PropertyUint32 {
     prop: PropertyPtr,
     prop: PropertyPtr,
+    role: Role,
     idx: usize,
     idx: usize,
 }
 }
 
 
 impl PropertyUint32 {
 impl PropertyUint32 {
-    pub fn from(prop: PropertyPtr, idx: usize) -> Result<Self> {
+    pub fn from(prop: PropertyPtr, role: Role, idx: usize) -> Result<Self> {
         // Test if it works
         // Test if it works
         let _ = prop.get_u32(idx)?;
         let _ = prop.get_u32(idx)?;
 
 
-        Ok(Self { prop, idx })
+        Ok(Self { prop, role, idx })
     }
     }
 
 
-    pub fn wrap(node: &SceneNode, prop_name: &str, idx: usize) -> Result<Self> {
+    pub fn wrap(node: &SceneNode, role: Role, prop_name: &str, idx: usize) -> Result<Self> {
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
 
 
         // Test if it works
         // Test if it works
         let _ = prop.get_u32(idx)?;
         let _ = prop.get_u32(idx)?;
 
 
-        Ok(Self { prop, idx })
+        Ok(Self { prop, role, idx })
     }
     }
 
 
     pub fn get(&self) -> u32 {
     pub fn get(&self) -> u32 {
@@ -79,7 +81,7 @@ impl PropertyUint32 {
     }
     }
 
 
     pub fn set(&self, val: u32) {
     pub fn set(&self, val: u32) {
-        self.prop.set_u32(self.idx, val).unwrap()
+        self.prop.set_u32(self.role, self.idx, val).unwrap()
     }
     }
 
 
     pub fn prop(&self) -> PropertyPtr {
     pub fn prop(&self) -> PropertyPtr {
@@ -89,17 +91,18 @@ impl PropertyUint32 {
 
 
 pub struct PropertyFloat32 {
 pub struct PropertyFloat32 {
     prop: PropertyPtr,
     prop: PropertyPtr,
+    role: Role,
     idx: usize,
     idx: usize,
 }
 }
 
 
 impl PropertyFloat32 {
 impl PropertyFloat32 {
-    pub fn wrap(node: &SceneNode, prop_name: &str, idx: usize) -> Result<Self> {
+    pub fn wrap(node: &SceneNode, role: Role, prop_name: &str, idx: usize) -> Result<Self> {
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
 
 
         // Test if it works
         // Test if it works
         let _ = prop.get_f32(idx)?;
         let _ = prop.get_f32(idx)?;
 
 
-        Ok(Self { prop, idx })
+        Ok(Self { prop, role, idx })
     }
     }
 
 
     pub fn get(&self) -> f32 {
     pub fn get(&self) -> f32 {
@@ -107,7 +110,7 @@ impl PropertyFloat32 {
     }
     }
 
 
     pub fn set(&self, val: f32) {
     pub fn set(&self, val: f32) {
-        self.prop.set_f32(self.idx, val).unwrap()
+        self.prop.set_f32(self.role, self.idx, val).unwrap()
     }
     }
 
 
     pub fn prop(&self) -> PropertyPtr {
     pub fn prop(&self) -> PropertyPtr {
@@ -117,17 +120,18 @@ impl PropertyFloat32 {
 
 
 pub struct PropertyStr {
 pub struct PropertyStr {
     prop: PropertyPtr,
     prop: PropertyPtr,
+    role: Role,
     idx: usize,
     idx: usize,
 }
 }
 
 
 impl PropertyStr {
 impl PropertyStr {
-    pub fn wrap(node: &SceneNode, prop_name: &str, idx: usize) -> Result<Self> {
+    pub fn wrap(node: &SceneNode, role: Role, prop_name: &str, idx: usize) -> Result<Self> {
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
 
 
         // Test if it works
         // Test if it works
         let _ = prop.get_str(idx)?;
         let _ = prop.get_str(idx)?;
 
 
-        Ok(Self { prop, idx })
+        Ok(Self { prop, role, idx })
     }
     }
 
 
     pub fn get(&self) -> String {
     pub fn get(&self) -> String {
@@ -135,7 +139,7 @@ impl PropertyStr {
     }
     }
 
 
     pub fn set<S: Into<String>>(&self, val: S) {
     pub fn set<S: Into<String>>(&self, val: S) {
-        self.prop.set_str(self.idx, val.into()).unwrap()
+        self.prop.set_str(self.role, self.idx, val.into()).unwrap()
     }
     }
 
 
     pub fn prop(&self) -> PropertyPtr {
     pub fn prop(&self) -> PropertyPtr {
@@ -145,10 +149,11 @@ impl PropertyStr {
 
 
 pub struct PropertyColor {
 pub struct PropertyColor {
     prop: PropertyPtr,
     prop: PropertyPtr,
+    role: Role,
 }
 }
 
 
 impl PropertyColor {
 impl PropertyColor {
-    pub fn wrap(node: &SceneNode, prop_name: &str) -> Result<Self> {
+    pub fn wrap(node: &SceneNode, role: Role, prop_name: &str) -> Result<Self> {
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
         let prop = node.get_property(prop_name).ok_or(Error::PropertyNotFound)?;
 
 
         if !prop.is_bounded() || prop.get_len() != 4 {
         if !prop.is_bounded() || prop.get_len() != 4 {
@@ -158,7 +163,7 @@ impl PropertyColor {
         // Test if it works
         // Test if it works
         let _ = prop.get_f32(0)?;
         let _ = prop.get_f32(0)?;
 
 
-        Ok(Self { prop })
+        Ok(Self { prop, role })
     }
     }
 
 
     pub fn get(&self) -> [f32; 4] {
     pub fn get(&self) -> [f32; 4] {
@@ -171,10 +176,10 @@ impl PropertyColor {
     }
     }
 
 
     pub fn set(&self, val: [f32; 4]) {
     pub fn set(&self, val: [f32; 4]) {
-        self.prop.set_f32(0, val[0]).unwrap();
-        self.prop.set_f32(1, val[1]).unwrap();
-        self.prop.set_f32(2, val[2]).unwrap();
-        self.prop.set_f32(3, val[3]).unwrap();
+        self.prop.set_f32(self.role, 0, val[0]).unwrap();
+        self.prop.set_f32(self.role, 1, val[1]).unwrap();
+        self.prop.set_f32(self.role, 2, val[2]).unwrap();
+        self.prop.set_f32(self.role, 3, val[3]).unwrap();
     }
     }
 
 
     pub fn prop(&self) -> PropertyPtr {
     pub fn prop(&self) -> PropertyPtr {

+ 11 - 11
bin/darkwallet/src/scene.rs

@@ -24,7 +24,7 @@ use std::{fmt, str::FromStr, sync::Arc};
 
 
 use crate::{
 use crate::{
     error::{Error, Result},
     error::{Error, Result},
-    prop::{Property, PropertyPtr, PropertyType},
+    prop::{Property, PropertyPtr, PropertyType, Role},
     ui,
     ui,
 };
 };
 
 
@@ -459,20 +459,20 @@ impl SceneNode {
         self.get_property(name).ok_or(Error::PropertyNotFound)?.get_node_id(0)
         self.get_property(name).ok_or(Error::PropertyNotFound)?.get_node_id(0)
     }
     }
     // Setters
     // Setters
-    pub fn set_property_bool(&self, name: &str, val: bool) -> Result<()> {
-        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_bool(0, val)
+    pub fn set_property_bool(&self, role: Role, name: &str, val: bool) -> Result<()> {
+        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_bool(role, 0, val)
     }
     }
-    pub fn set_property_u32(&self, name: &str, val: u32) -> Result<()> {
-        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_u32(0, val)
+    pub fn set_property_u32(&self, role: Role, name: &str, val: u32) -> Result<()> {
+        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_u32(role, 0, val)
     }
     }
-    pub fn set_property_f32(&self, name: &str, val: f32) -> Result<()> {
-        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_f32(0, val)
+    pub fn set_property_f32(&self, role: Role, name: &str, val: f32) -> Result<()> {
+        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_f32(role, 0, val)
     }
     }
-    pub fn set_property_str<S: Into<String>>(&self, name: &str, val: S) -> Result<()> {
-        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_str(0, val)
+    pub fn set_property_str<S: Into<String>>(&self, role: Role, name: &str, val: S) -> Result<()> {
+        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_str(role, 0, val)
     }
     }
-    pub fn set_property_node_id(&self, name: &str, val: SceneNodeId) -> Result<()> {
-        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_node_id(0, val)
+    pub fn set_property_node_id(&self, role: Role, name: &str, val: SceneNodeId) -> Result<()> {
+        self.get_property(name).ok_or(Error::PropertyNotFound)?.set_node_id(role, 0, val)
     }
     }
 
 
     pub fn add_signal<S: Into<String>>(
     pub fn add_signal<S: Into<String>>(

+ 2 - 2
bin/darkwallet/src/ui/button.rs

@@ -28,7 +28,7 @@ use crate::{
         DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
         DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
         RenderApiPtr, Vertex,
         RenderApiPtr, Vertex,
     },
     },
-    prop::{PropertyBool, PropertyPtr, PropertyUint32},
+    prop::{PropertyBool, PropertyPtr, PropertyUint32, Role},
     pubsub::Subscription,
     pubsub::Subscription,
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, Signal},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, Signal},
 };
 };
@@ -58,7 +58,7 @@ impl Button {
         let scene_graph = sg.lock().await;
         let scene_graph = sg.lock().await;
         let node = scene_graph.get_node(node_id).unwrap();
         let node = scene_graph.get_node(node_id).unwrap();
         //let node_name = node.name.clone();
         //let node_name = node.name.clone();
-        let is_active = PropertyBool::wrap(node, "is_active", 0).unwrap();
+        let is_active = PropertyBool::wrap(node, Role::Internal, "is_active", 0).unwrap();
         let rect = node.get_property("rect").expect("Button::rect");
         let rect = node.get_property("rect").expect("Button::rect");
         //let sig = node.get_signal("click").expect("Button::click");
         //let sig = node.get_signal("click").expect("Button::click");
         drop(scene_graph);
         drop(scene_graph);

+ 16 - 10
bin/darkwallet/src/ui/chatview.rs

@@ -18,7 +18,7 @@
 
 
 use async_lock::Mutex as AsyncMutex;
 use async_lock::Mutex as AsyncMutex;
 use darkfi_serial::{deserialize, Decodable, Encodable, SerialDecodable, SerialEncodable};
 use darkfi_serial::{deserialize, Decodable, Encodable, SerialDecodable, SerialEncodable};
-use miniquad::{TouchPhase, KeyCode, KeyMods};
+use miniquad::{KeyCode, KeyMods, TouchPhase};
 use rand::{rngs::OsRng, Rng};
 use rand::{rngs::OsRng, Rng};
 use std::{
 use std::{
     collections::BTreeMap,
     collections::BTreeMap,
@@ -36,6 +36,7 @@ use crate::{
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_GREY, COLOR_WHITE},
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_GREY, COLOR_WHITE},
     prop::{
     prop::{
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
+        Role,
     },
     },
     pubsub::Subscription,
     pubsub::Subscription,
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
@@ -254,14 +255,14 @@ impl ChatView {
         let node_name = node.name.clone();
         let node_name = node.name.clone();
 
 
         let rect = node.get_property("rect").expect("ChatView::rect");
         let rect = node.get_property("rect").expect("ChatView::rect");
-        let scroll = PropertyFloat32::wrap(node, "scroll", 0).unwrap();
-        let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
-        let line_height = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
-        let baseline = PropertyFloat32::wrap(node, "baseline", 0).unwrap();
-        let timestamp_color = PropertyColor::wrap(node, "timestamp_color").unwrap();
-        let text_color = PropertyColor::wrap(node, "text_color").unwrap();
+        let scroll = PropertyFloat32::wrap(node, Role::Internal, "scroll", 0).unwrap();
+        let font_size = PropertyFloat32::wrap(node, Role::Internal, "font_size", 0).unwrap();
+        let line_height = PropertyFloat32::wrap(node, Role::Internal, "line_height", 0).unwrap();
+        let baseline = PropertyFloat32::wrap(node, Role::Internal, "baseline", 0).unwrap();
+        let timestamp_color = PropertyColor::wrap(node, Role::Internal, "timestamp_color").unwrap();
+        let text_color = PropertyColor::wrap(node, Role::Internal, "text_color").unwrap();
         let nick_colors = node.get_property("nick_colors").expect("ChatView::nick_colors");
         let nick_colors = node.get_property("nick_colors").expect("ChatView::nick_colors");
-        let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
+        let z_index = PropertyUint32::wrap(node, Role::Internal, "z_index", 0).unwrap();
 
 
         drop(scene_graph);
         drop(scene_graph);
 
 
@@ -301,8 +302,13 @@ impl ChatView {
             }
             }
             on_modify.when_change(rect.clone(), redraw);
             on_modify.when_change(rect.clone(), redraw);
 
 
-            let mut tasks =
-                vec![mouse_wheel_task, mouse_move_task, touch_task, key_down_task, insert_line_method_task];
+            let mut tasks = vec![
+                mouse_wheel_task,
+                mouse_move_task,
+                touch_task,
+                key_down_task,
+                insert_line_method_task,
+            ];
             tasks.append(&mut on_modify.tasks);
             tasks.append(&mut on_modify.tasks);
 
 
             Self {
             Self {

+ 36 - 35
bin/darkwallet/src/ui/editbox.rs

@@ -36,6 +36,7 @@ use crate::{
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     prop::{
     prop::{
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
+        Role,
     },
     },
     pubsub::Subscription,
     pubsub::Subscription,
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
@@ -177,20 +178,20 @@ impl EditBox {
         let node = scene_graph.get_node(node_id).unwrap();
         let node = scene_graph.get_node(node_id).unwrap();
         let node_name = node.name.clone();
         let node_name = node.name.clone();
 
 
-        let is_active = PropertyBool::wrap(node, "is_active", 0).unwrap();
-        let is_focused = PropertyBool::wrap(node, "is_focused", 0).unwrap();
+        let is_active = PropertyBool::wrap(node, Role::Internal, "is_active", 0).unwrap();
+        let is_focused = PropertyBool::wrap(node, Role::Internal, "is_focused", 0).unwrap();
         let rect = node.get_property("rect").expect("EditBox::rect");
         let rect = node.get_property("rect").expect("EditBox::rect");
-        let baseline = PropertyFloat32::wrap(node, "baseline", 0).unwrap();
-        let scroll = PropertyFloat32::wrap(node, "scroll", 0).unwrap();
-        let cursor_pos = PropertyUint32::wrap(node, "cursor_pos", 0).unwrap();
-        let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
-        let text = PropertyStr::wrap(node, "text", 0).unwrap();
-        let text_color = PropertyColor::wrap(node, "text_color").unwrap();
-        let cursor_color = PropertyColor::wrap(node, "cursor_color").unwrap();
-        let hi_bg_color = PropertyColor::wrap(node, "hi_bg_color").unwrap();
+        let baseline = PropertyFloat32::wrap(node, Role::Internal, "baseline", 0).unwrap();
+        let scroll = PropertyFloat32::wrap(node, Role::Internal, "scroll", 0).unwrap();
+        let cursor_pos = PropertyUint32::wrap(node, Role::Internal, "cursor_pos", 0).unwrap();
+        let font_size = PropertyFloat32::wrap(node, Role::Internal, "font_size", 0).unwrap();
+        let text = PropertyStr::wrap(node, Role::Internal, "text", 0).unwrap();
+        let text_color = PropertyColor::wrap(node, Role::Internal, "text_color").unwrap();
+        let cursor_color = PropertyColor::wrap(node, Role::Internal, "cursor_color").unwrap();
+        let hi_bg_color = PropertyColor::wrap(node, Role::Internal, "hi_bg_color").unwrap();
         let selected = node.get_property("selected").unwrap();
         let selected = node.get_property("selected").unwrap();
-        let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
-        let debug = PropertyBool::wrap(node, "debug", 0).unwrap();
+        let z_index = PropertyUint32::wrap(node, Role::Internal, "z_index", 0).unwrap();
+        let debug = PropertyBool::wrap(node, Role::Internal, "debug", 0).unwrap();
 
 
         drop(scene_graph);
         drop(scene_graph);
 
 
@@ -667,16 +668,16 @@ impl EditBox {
             self.apply_cursor_scrolling();
             self.apply_cursor_scrolling();
 
 
             // begin selection
             // begin selection
-            self.selected.set_u32(0, cpos).unwrap();
-            self.selected.set_u32(1, cpos).unwrap();
+            self.selected.set_u32(Role::Internal, 0, cpos).unwrap();
+            self.selected.set_u32(Role::Internal, 1, cpos).unwrap();
 
 
             self.mouse_btn_held.store(true, Ordering::Relaxed);
             self.mouse_btn_held.store(true, Ordering::Relaxed);
         // click outside the box will make it unfocused
         // click outside the box will make it unfocused
         } else if self.is_focused.get() {
         } else if self.is_focused.get() {
             debug!(target: "ui::editbox", "EditBox unfocused");
             debug!(target: "ui::editbox", "EditBox unfocused");
             self.is_focused.set(false);
             self.is_focused.set(false);
-            self.selected.set_null(0).unwrap();
-            self.selected.set_null(1).unwrap();
+            self.selected.set_null(Role::Internal, 0).unwrap();
+            self.selected.set_null(Role::Internal, 1).unwrap();
             focus_changed = true;
             focus_changed = true;
         } else {
         } else {
             // Do nothing. Click was outside editbox, and editbox wasn't focused
             // Do nothing. Click was outside editbox, and editbox wasn't focused
@@ -713,7 +714,7 @@ impl EditBox {
         let cpos = self.find_closest_glyph_idx(mouse_x, &rect);
         let cpos = self.find_closest_glyph_idx(mouse_x, &rect);
 
 
         self.cursor_pos.set(cpos);
         self.cursor_pos.set(cpos);
-        self.selected.set_u32(1, cpos).unwrap();
+        self.selected.set_u32(Role::Internal, 1, cpos).unwrap();
 
 
         self.apply_cursor_scrolling();
         self.apply_cursor_scrolling();
         self.redraw().await;
         self.redraw().await;
@@ -856,11 +857,11 @@ impl EditBox {
 
 
                 // Start selection if shift is held
                 // Start selection if shift is held
                 if !mods.shift {
                 if !mods.shift {
-                    self.selected.set_null(0).unwrap();
-                    self.selected.set_null(1).unwrap();
+                    self.selected.set_null(Role::Internal, 0).unwrap();
+                    self.selected.set_null(Role::Internal, 1).unwrap();
                 } else if self.selected.is_null(0).unwrap() {
                 } else if self.selected.is_null(0).unwrap() {
                     assert!(self.selected.is_null(1).unwrap());
                     assert!(self.selected.is_null(1).unwrap());
-                    self.selected.set_u32(0, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 0, cursor_pos).unwrap();
                 }
                 }
 
 
                 if cursor_pos > 0 {
                 if cursor_pos > 0 {
@@ -871,7 +872,7 @@ impl EditBox {
 
 
                 // Update selection
                 // Update selection
                 if mods.shift {
                 if mods.shift {
-                    self.selected.set_u32(1, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 1, cursor_pos).unwrap();
                 }
                 }
 
 
                 self.apply_cursor_scrolling();
                 self.apply_cursor_scrolling();
@@ -882,11 +883,11 @@ impl EditBox {
 
 
                 // Start selection if shift is held
                 // Start selection if shift is held
                 if !mods.shift {
                 if !mods.shift {
-                    self.selected.set_null(0).unwrap();
-                    self.selected.set_null(1).unwrap();
+                    self.selected.set_null(Role::Internal, 0).unwrap();
+                    self.selected.set_null(Role::Internal, 1).unwrap();
                 } else if self.selected.is_null(0).unwrap() {
                 } else if self.selected.is_null(0).unwrap() {
                     assert!(self.selected.is_null(1).unwrap());
                     assert!(self.selected.is_null(1).unwrap());
-                    self.selected.set_u32(0, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 0, cursor_pos).unwrap();
                 }
                 }
 
 
                 let glyphs_len = self.glyphs.lock().unwrap().len() as u32;
                 let glyphs_len = self.glyphs.lock().unwrap().len() as u32;
@@ -898,7 +899,7 @@ impl EditBox {
 
 
                 // Update selection
                 // Update selection
                 if mods.shift {
                 if mods.shift {
-                    self.selected.set_u32(1, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 1, cursor_pos).unwrap();
                 }
                 }
 
 
                 self.apply_cursor_scrolling();
                 self.apply_cursor_scrolling();
@@ -980,18 +981,18 @@ impl EditBox {
                 let cursor_pos = self.cursor_pos.get();
                 let cursor_pos = self.cursor_pos.get();
 
 
                 if !mods.shift {
                 if !mods.shift {
-                    self.selected.set_null(0).unwrap();
-                    self.selected.set_null(1).unwrap();
+                    self.selected.set_null(Role::Internal, 0).unwrap();
+                    self.selected.set_null(Role::Internal, 1).unwrap();
                 } else if self.selected.is_null(0).unwrap() {
                 } else if self.selected.is_null(0).unwrap() {
                     assert!(self.selected.is_null(1).unwrap());
                     assert!(self.selected.is_null(1).unwrap());
-                    self.selected.set_u32(0, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 0, cursor_pos).unwrap();
                 }
                 }
 
 
                 self.cursor_pos.set(0);
                 self.cursor_pos.set(0);
 
 
                 // Update selection
                 // Update selection
                 if mods.shift {
                 if mods.shift {
-                    self.selected.set_u32(1, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 1, cursor_pos).unwrap();
                 }
                 }
 
 
                 self.apply_cursor_scrolling();
                 self.apply_cursor_scrolling();
@@ -1001,11 +1002,11 @@ impl EditBox {
                 let cursor_pos = self.cursor_pos.get();
                 let cursor_pos = self.cursor_pos.get();
 
 
                 if !mods.shift {
                 if !mods.shift {
-                    self.selected.set_null(0).unwrap();
-                    self.selected.set_null(1).unwrap();
+                    self.selected.set_null(Role::Internal, 0).unwrap();
+                    self.selected.set_null(Role::Internal, 1).unwrap();
                 } else if self.selected.is_null(0).unwrap() {
                 } else if self.selected.is_null(0).unwrap() {
                     assert!(self.selected.is_null(1).unwrap());
                     assert!(self.selected.is_null(1).unwrap());
-                    self.selected.set_u32(0, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 0, cursor_pos).unwrap();
                 }
                 }
 
 
                 let glyphs_len = self.glyphs.lock().unwrap().len();
                 let glyphs_len = self.glyphs.lock().unwrap().len();
@@ -1013,7 +1014,7 @@ impl EditBox {
 
 
                 // Update selection
                 // Update selection
                 if mods.shift {
                 if mods.shift {
-                    self.selected.set_u32(1, cursor_pos).unwrap();
+                    self.selected.set_u32(Role::Internal, 1, cursor_pos).unwrap();
                 }
                 }
 
 
                 self.apply_cursor_scrolling();
                 self.apply_cursor_scrolling();
@@ -1051,8 +1052,8 @@ impl EditBox {
         );
         );
         self.text.set(text);
         self.text.set(text);
 
 
-        self.selected.set_null(0).unwrap();
-        self.selected.set_null(1).unwrap();
+        self.selected.set_null(Role::Internal, 0).unwrap();
+        self.selected.set_null(Role::Internal, 1).unwrap();
         self.cursor_pos.set(sel_start as u32);
         self.cursor_pos.set(sel_start as u32);
     }
     }
 
 

+ 3 - 2
bin/darkwallet/src/ui/image.rs

@@ -30,6 +30,7 @@ use crate::{
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     prop::{
     prop::{
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
+        Role,
     },
     },
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     text2::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
     text2::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
@@ -66,8 +67,8 @@ impl Image {
         let node = scene_graph.get_node(node_id).unwrap();
         let node = scene_graph.get_node(node_id).unwrap();
         let node_name = node.name.clone();
         let node_name = node.name.clone();
         let rect = node.get_property("rect").expect("Text::rect");
         let rect = node.get_property("rect").expect("Text::rect");
-        let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
-        let path = PropertyStr::wrap(node, "path", 0).unwrap();
+        let z_index = PropertyUint32::wrap(node, Role::Internal, "z_index", 0).unwrap();
+        let path = PropertyStr::wrap(node, Role::Internal, "path", 0).unwrap();
         drop(scene_graph);
         drop(scene_graph);
 
 
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {

+ 3 - 3
bin/darkwallet/src/ui/layer.rs

@@ -22,7 +22,7 @@ use std::sync::{Arc, Weak};
 
 
 use crate::{
 use crate::{
     gfx2::{DrawCall, DrawInstruction, Rectangle, RenderApiPtr},
     gfx2::{DrawCall, DrawInstruction, Rectangle, RenderApiPtr},
-    prop::{PropertyBool, PropertyPtr},
+    prop::{PropertyBool, PropertyPtr, Role},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
 };
 };
 
 
@@ -55,8 +55,8 @@ impl RenderLayer {
         let node = sg.get_node(node_id).unwrap();
         let node = sg.get_node(node_id).unwrap();
         let node_name = node.name.clone();
         let node_name = node.name.clone();
 
 
-        let is_visible =
-            PropertyBool::wrap(node, "is_visible", 0).expect("RenderLayer::is_visible");
+        let is_visible = PropertyBool::wrap(node, Role::Internal, "is_visible", 0)
+            .expect("RenderLayer::is_visible");
         let rect = node.get_property("rect").expect("RenderLayer::rect");
         let rect = node.get_property("rect").expect("RenderLayer::rect");
         drop(sg);
         drop(sg);
 
 

+ 3 - 4
bin/darkwallet/src/ui/mesh.rs

@@ -21,7 +21,7 @@ use std::sync::{Arc, Weak};
 
 
 use crate::{
 use crate::{
     gfx2::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApiPtr, Vertex},
     gfx2::{DrawCall, DrawInstruction, DrawMesh, Rectangle, RenderApiPtr, Vertex},
-    prop::{PropertyPtr, PropertyUint32},
+    prop::{PropertyPtr, PropertyUint32, Role},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
 };
 };
 
 
@@ -63,14 +63,13 @@ impl Mesh {
         let node = scene_graph.get_node(node_id).unwrap();
         let node = scene_graph.get_node(node_id).unwrap();
         let node_name = node.name.clone();
         let node_name = node.name.clone();
         let rect = node.get_property("rect").expect("Mesh::rect");
         let rect = node.get_property("rect").expect("Mesh::rect");
-        let z_index_prop = node.get_property("z_index").expect("Mesh::z_index");
-        let z_index = PropertyUint32::from(z_index_prop.clone(), 0).unwrap();
+        let z_index = PropertyUint32::wrap(node, Role::Internal, "z_index", 0).unwrap();
         drop(scene_graph);
         drop(scene_graph);
 
 
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
         let self_ = Arc::new_cyclic(|me: &Weak<Self>| {
             let mut on_modify = OnModify::new(ex, node_name, node_id, me.clone());
             let mut on_modify = OnModify::new(ex, node_name, node_id, me.clone());
             on_modify.when_change(rect.clone(), Self::redraw);
             on_modify.when_change(rect.clone(), Self::redraw);
-            on_modify.when_change(z_index_prop, Self::redraw);
+            on_modify.when_change(z_index.prop(), Self::redraw);
 
 
             Self {
             Self {
                 sg,
                 sg,

+ 7 - 6
bin/darkwallet/src/ui/text.rs

@@ -26,6 +26,7 @@ use crate::{
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
     prop::{
     prop::{
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
         PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
+        Role,
     },
     },
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     text2::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
     text2::{self, Glyph, GlyphPositionIter, SpritePtr, TextShaper, TextShaperPtr},
@@ -74,12 +75,12 @@ impl Text {
         let node = scene_graph.get_node(node_id).unwrap();
         let node = scene_graph.get_node(node_id).unwrap();
         let node_name = node.name.clone();
         let node_name = node.name.clone();
         let rect = node.get_property("rect").expect("Text::rect");
         let rect = node.get_property("rect").expect("Text::rect");
-        let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
-        let text = PropertyStr::wrap(node, "text", 0).unwrap();
-        let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
-        let text_color = PropertyColor::wrap(node, "text_color").unwrap();
-        let baseline = PropertyFloat32::wrap(node, "baseline", 0).unwrap();
-        let debug = PropertyBool::wrap(node, "debug", 0).unwrap();
+        let z_index = PropertyUint32::wrap(node, Role::Internal, "z_index", 0).unwrap();
+        let text = PropertyStr::wrap(node, Role::Internal, "text", 0).unwrap();
+        let font_size = PropertyFloat32::wrap(node, Role::Internal, "font_size", 0).unwrap();
+        let text_color = PropertyColor::wrap(node, Role::Internal, "text_color").unwrap();
+        let baseline = PropertyFloat32::wrap(node, Role::Internal, "baseline", 0).unwrap();
+        let debug = PropertyBool::wrap(node, Role::Internal, "debug", 0).unwrap();
         drop(scene_graph);
         drop(scene_graph);
 
 
         let render_info = Self::regen_mesh(
         let render_info = Self::regen_mesh(

+ 3 - 3
bin/darkwallet/src/ui/win.rs

@@ -20,7 +20,7 @@ use std::sync::{Arc, Weak};
 
 
 use crate::{
 use crate::{
     gfx2::{DrawCall, GraphicsEventPublisherPtr, Rectangle, RenderApiPtr},
     gfx2::{DrawCall, GraphicsEventPublisherPtr, Rectangle, RenderApiPtr},
-    prop::PropertyPtr,
+    prop::{PropertyPtr, Role},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
     scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId},
 };
 };
 
 
@@ -70,8 +70,8 @@ impl Window {
 
 
                     debug!(target: "ui::win", "Window resized ({w}, {h})");
                     debug!(target: "ui::win", "Window resized ({w}, {h})");
                     // Now update the properties
                     // Now update the properties
-                    screen_size_prop2.set_f32(0, w).unwrap();
-                    screen_size_prop2.set_f32(1, h).unwrap();
+                    screen_size_prop2.set_f32(Role::Internal, 0, w).unwrap();
+                    screen_size_prop2.set_f32(Role::Internal, 1, h).unwrap();
 
 
                     let Some(self_) = me2.upgrade() else {
                     let Some(self_) = me2.upgrade() else {
                         // Should not happen
                         // Should not happen