Forráskód Böngészése

app: restore back the main app schema

darkfi 1 éve
szülő
commit
e79ccad144

+ 1 - 1
bin/app/Makefile

@@ -19,7 +19,7 @@ DEBUG_FEATURES = --features=enable-filelog,enable-plugins
 
 
 #DEV_FEATURES = --features=enable-filelog,enable-netdebug,emulate-android
 #DEV_FEATURES = --features=enable-filelog,enable-netdebug,emulate-android
 #DEV_FEATURES = --features=enable-filelog,enable-netdebug,enable-plugins
 #DEV_FEATURES = --features=enable-filelog,enable-netdebug,enable-plugins
-DEV_FEATURES =
+DEV_FEATURES = --features=enable-netdebug
 
 
 default: build-release
 default: build-release
 	./darkfi-app
 	./darkfi-app

+ 2 - 0
bin/app/gui/print_tree.py

@@ -72,6 +72,8 @@ def print_node_info(parent_path, depth, indent):
 
 
             if prop.type == PropertyType.STR:
             if prop.type == PropertyType.STR:
                 prop_val = [f"\"{pv}\"" for pv in prop_val]
                 prop_val = [f"\"{pv}\"" for pv in prop_val]
+            elif prop.type == PropertyType.FLOAT32:
+                prop_val = "[" + ", ".join(f"{pv:.2f}" for pv in prop_val) + "]"
 
 
             if len(prop_val) == 1:
             if len(prop_val) == 1:
                 prop_val = prop_val[0]
                 prop_val = prop_val[0]

+ 1 - 1
bin/app/src/app/mod.rs

@@ -205,7 +205,7 @@ impl App {
         self.sg_root.clone().link(window.clone());
         self.sg_root.clone().link(window.clone());
         self.sg_root.clone().link(setting_root.clone());
         self.sg_root.clone().link(setting_root.clone());
 
 
-        schema::test::make(&self, window.clone()).await;
+        schema::make(&self, window.clone()).await;
 
 
         d!("Schema loaded");
         d!("Schema loaded");
 
 

+ 6 - 8
bin/app/src/app/node.rs

@@ -167,6 +167,12 @@ pub fn create_text(name: &str) -> SceneNode {
     let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
     let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
+    let mut prop = Property::new("lineheight", PropertyType::Float32, PropertySubType::Pixel);
+    prop.set_ui_text("Line Height", "Line height/lead (em)");
+    prop.set_defaults_f32(vec![1.2]).unwrap();
+    prop.set_range_f32(0., f32::MAX);
+    node.add_property(prop).unwrap();
+
     let prop = Property::new("font_size", PropertyType::Float32, PropertySubType::Pixel);
     let prop = Property::new("font_size", PropertyType::Float32, PropertySubType::Pixel);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
@@ -329,17 +335,9 @@ pub fn create_chatedit(name: &str) -> SceneNode {
     prop.allow_exprs();
     prop.allow_exprs();
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
-    // DEPRECATED ------------
     let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
     let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
-    let prop = Property::new("linespacing", PropertyType::Float32, PropertySubType::Pixel);
-    node.add_property(prop).unwrap();
-
-    let prop = Property::new("descent", PropertyType::Float32, PropertySubType::Pixel);
-    node.add_property(prop).unwrap();
-    //------------------------
-
     let mut prop = Property::new("lineheight", PropertyType::Float32, PropertySubType::Pixel);
     let mut prop = Property::new("lineheight", PropertyType::Float32, PropertySubType::Pixel);
     prop.set_ui_text("Line Height", "Line height/lead (em)");
     prop.set_ui_text("Line Height", "Line height/lead (em)");
     prop.set_defaults_f32(vec![1.2]).unwrap();
     prop.set_defaults_f32(vec![1.2]).unwrap();

+ 4 - 20
bin/app/src/app/schema/chat.rs

@@ -68,11 +68,9 @@ mod android_ui_consts {
     pub const CHATEDIT_SELECT_ASCENT: f32 = 50.;
     pub const CHATEDIT_SELECT_ASCENT: f32 = 50.;
     pub const CHATEDIT_SELECT_DESCENT: f32 = 20.;
     pub const CHATEDIT_SELECT_DESCENT: f32 = 20.;
     pub const CHATEDIT_HANDLE_DESCENT: f32 = 10.;
     pub const CHATEDIT_HANDLE_DESCENT: f32 = 10.;
-    pub const CHATEDIT_LINESPACING: f32 = 70.;
     pub const CHATEDIT_NEG_W: f32 = 300.;
     pub const CHATEDIT_NEG_W: f32 = 300.;
     pub const CHATEDIT_LHS_PAD: f32 = 150.;
     pub const CHATEDIT_LHS_PAD: f32 = 150.;
     pub const TEXTBAR_BASELINE: f32 = 60.;
     pub const TEXTBAR_BASELINE: f32 = 60.;
-    pub const TEXT_DESCENT: f32 = 20.;
     pub const EMOJI_BTN_X: f32 = 60.;
     pub const EMOJI_BTN_X: f32 = 60.;
     pub const EMOJI_BG_W: f32 = 120.;
     pub const EMOJI_BG_W: f32 = 120.;
     pub const EMOJI_SCALE: f32 = 40.;
     pub const EMOJI_SCALE: f32 = 40.;
@@ -137,11 +135,9 @@ mod ui_consts {
     pub const CHATEDIT_SELECT_ASCENT: f32 = 30.;
     pub const CHATEDIT_SELECT_ASCENT: f32 = 30.;
     pub const CHATEDIT_SELECT_DESCENT: f32 = 10.;
     pub const CHATEDIT_SELECT_DESCENT: f32 = 10.;
     pub const CHATEDIT_HANDLE_DESCENT: f32 = 35.;
     pub const CHATEDIT_HANDLE_DESCENT: f32 = 35.;
-    pub const CHATEDIT_LINESPACING: f32 = 35.;
     pub const CHATEDIT_NEG_W: f32 = 190.;
     pub const CHATEDIT_NEG_W: f32 = 190.;
     pub const CHATEDIT_LHS_PAD: f32 = 100.;
     pub const CHATEDIT_LHS_PAD: f32 = 100.;
     pub const TEXTBAR_BASELINE: f32 = 34.;
     pub const TEXTBAR_BASELINE: f32 = 34.;
-    pub const TEXT_DESCENT: f32 = 10.;
     pub const EMOJI_BTN_X: f32 = 38.;
     pub const EMOJI_BTN_X: f32 = 38.;
     pub const EMOJI_BG_W: f32 = 80.;
     pub const EMOJI_BG_W: f32 = 80.;
     pub const EMOJI_SCALE: f32 = 20.;
     pub const EMOJI_SCALE: f32 = 20.;
@@ -699,8 +695,9 @@ pub async fn make(
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     node.set_property_bool(atom, Role::App, "is_active", true).unwrap();
     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
     node.set_property_bool(atom, Role::App, "is_focused", true).unwrap();
 
 
-    node.set_property_f32(atom, Role::App, "min_height", CHATEDIT_MIN_HEIGHT).unwrap();
-    node.set_property_f32(atom, Role::App, "max_height", CHATEDIT_MAX_HEIGHT).unwrap();
+    let prop = node.get_property("height_range").unwrap();
+    prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_MIN_HEIGHT).unwrap();
+    prop.clone().set_f32(atom, Role::App, 1, CHATEDIT_MAX_HEIGHT).unwrap();
 
 
     let prop = node.get_property("rect").unwrap();
     let prop = node.get_property("rect").unwrap();
     prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
     prop.clone().set_f32(atom, Role::App, 0, CHATEDIT_LHS_PAD).unwrap();
@@ -714,12 +711,10 @@ pub async fn make(
     editbox_bg_rect_prop.add_depend(&prop, 3, "editz_h");
     editbox_bg_rect_prop.add_depend(&prop, 3, "editz_h");
 
 
     let prop = node.get_property("padding").unwrap();
     let prop = node.get_property("padding").unwrap();
-    prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
+    prop.clone().set_f32(atom, Role::App, 0, TEXTBAR_BASELINE / 2.).unwrap();
     prop.clone().set_f32(atom, Role::App, 1, TEXTBAR_BASELINE / 2.).unwrap();
     prop.clone().set_f32(atom, Role::App, 1, TEXTBAR_BASELINE / 2.).unwrap();
 
 
     node.set_property_f32(atom, Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
-    node.set_property_f32(atom, Role::App, "linespacing", CHATEDIT_LINESPACING).unwrap();
-    node.set_property_f32(atom, Role::App, "descent", TEXT_DESCENT).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", FONTSIZE).unwrap();
     //node.set_property_str(atom, Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
     //node.set_property_str(atom, Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
     let prop = node.get_property("text_color").unwrap();
     let prop = node.get_property("text_color").unwrap();
@@ -784,7 +779,6 @@ pub async fn make(
 
 
     let editz_text = PropertyStr::wrap(&node, Role::App, "text", 0).unwrap();
     let editz_text = PropertyStr::wrap(&node, Role::App, "text", 0).unwrap();
     let editz_select_text = node.get_property("select_text").unwrap();
     let editz_select_text = node.get_property("select_text").unwrap();
-    let editz_cursor_pos = node.get_property("cursor_pos").unwrap();
 
 
     //let editbox_focus = PropertyBool::wrap(node, Role::App, "is_focused", 0).unwrap();
     //let editbox_focus = PropertyBool::wrap(node, Role::App, "is_focused", 0).unwrap();
     //let darkirc_backend = app.darkirc_backend.clone();
     //let darkirc_backend = app.darkirc_backend.clone();
@@ -1581,16 +1575,6 @@ pub async fn make(
     });
     });
     app.tasks.lock().unwrap().push(listen_click);
     app.tasks.lock().unwrap().push(listen_click);
 
 
-    let editz_cpos_sub = editz_cursor_pos.subscribe_modify();
-    let pasta_is_visible2 = pasta_is_visible.clone();
-    let editz_cpos_task = app.ex.spawn(async move {
-        while let Ok(_) = editz_cpos_sub.receive().await {
-            let atom = &mut PropertyAtomicGuard::new();
-            pasta_is_visible2.set(atom, false);
-        }
-    });
-    app.tasks.lock().unwrap().push(editz_cpos_task);
-
     let editz_select_sub = editz_select_text.subscribe_modify();
     let editz_select_sub = editz_select_text.subscribe_modify();
     let pasta_is_visible2 = pasta_is_visible.clone();
     let pasta_is_visible2 = pasta_is_visible.clone();
     let editz_select_task = app.ex.spawn(async move {
     let editz_select_task = app.ex.spawn(async move {

+ 9 - 8
bin/app/src/app/schema/menu.rs

@@ -48,8 +48,9 @@ use super::{ColorScheme, CHANNELS, COLOR_SCHEME};
 
 
 mod android_ui_consts {
 mod android_ui_consts {
     pub const CHANNEL_LABEL_X: f32 = 40.;
     pub const CHANNEL_LABEL_X: f32 = 40.;
+    pub const CHANNEL_LABEL_Y: f32 = 28.;
     pub const CHANNEL_LABEL_LINESPACE: f32 = 140.;
     pub const CHANNEL_LABEL_LINESPACE: f32 = 140.;
-    pub const CHANNEL_LABEL_FONTSIZE: f32 = 40.;
+    pub const CHANNEL_LABEL_FONTSIZE: f32 = 44.;
     pub const CHANNEL_LABEL_BASELINE: f32 = 82.;
     pub const CHANNEL_LABEL_BASELINE: f32 = 82.;
 }
 }
 
 
@@ -69,8 +70,9 @@ mod ui_consts {
 ))]
 ))]
 mod ui_consts {
 mod ui_consts {
     pub const CHANNEL_LABEL_X: f32 = 20.;
     pub const CHANNEL_LABEL_X: f32 = 20.;
+    pub const CHANNEL_LABEL_Y: f32 = 14.;
     pub const CHANNEL_LABEL_LINESPACE: f32 = 60.;
     pub const CHANNEL_LABEL_LINESPACE: f32 = 60.;
-    pub const CHANNEL_LABEL_FONTSIZE: f32 = 20.;
+    pub const CHANNEL_LABEL_FONTSIZE: f32 = 22.;
     pub const CHANNEL_LABEL_BASELINE: f32 = 37.;
     pub const CHANNEL_LABEL_BASELINE: f32 = 37.;
 }
 }
 
 
@@ -101,13 +103,11 @@ pub async fn make(app: &App, window: SceneNodePtr) {
         layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
         layer_node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
     window.link(layer_node.clone());
     window.link(layer_node.clone());
 
 
-    let mut channel_y = 0.;
-
     // Channels label bg
     // Channels label bg
     let node = create_vector_art("channels_label_bg");
     let node = create_vector_art("channels_label_bg");
     let prop = node.get_property("rect").unwrap();
     let prop = node.get_property("rect").unwrap();
     prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
     prop.clone().set_f32(atom, Role::App, 0, 0.).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, channel_y).unwrap();
+    prop.clone().set_f32(atom, Role::App, 1, 0.).unwrap();
     prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     prop.clone().set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
     prop.clone().set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
     prop.clone().set_f32(atom, Role::App, 3, CHANNEL_LABEL_LINESPACE).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
@@ -148,7 +148,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     let node = create_text("channels_label");
     let node = create_text("channels_label");
     let prop = node.get_property("rect").unwrap();
     let prop = node.get_property("rect").unwrap();
     prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
     prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
-    prop.clone().set_f32(atom, Role::App, 1, channel_y).unwrap();
+    prop.clone().set_f32(atom, Role::App, 1, CHANNEL_LABEL_Y).unwrap();
     prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
     prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
     prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
     prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
     node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
@@ -156,6 +156,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     node.set_property_f32(atom, Role::App, "font_size", CHANNEL_LABEL_FONTSIZE).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", CHANNEL_LABEL_FONTSIZE).unwrap();
     node.set_property_str(atom, Role::App, "text", "CHANNELS").unwrap();
     node.set_property_str(atom, Role::App, "text", "CHANNELS").unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
     //node.set_property_str(atom, Role::App, "text", "anon1").unwrap();
+    //node.set_property_bool(atom, Role::App, "debug", true).unwrap();
     let prop = node.get_property("text_color").unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::DarkMode {
     if COLOR_SCHEME == ColorScheme::DarkMode {
         prop.clone().set_f32(atom, Role::App, 0, 0.65).unwrap();
         prop.clone().set_f32(atom, Role::App, 0, 0.65).unwrap();
@@ -183,7 +184,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
         .await;
         .await;
     layer_node.clone().link(node);
     layer_node.clone().link(node);
 
 
-    channel_y += CHANNEL_LABEL_LINESPACE;
+    let mut channel_y = CHANNEL_LABEL_LINESPACE;
 
 
     for (i, channel) in CHANNELS.iter().enumerate() {
     for (i, channel) in CHANNELS.iter().enumerate() {
         let node = create_vector_art(&(channel.to_string() + "_channel_label_bg"));
         let node = create_vector_art(&(channel.to_string() + "_channel_label_bg"));
@@ -234,7 +235,7 @@ pub async fn make(app: &App, window: SceneNodePtr) {
         let node = create_text(&(channel.to_string() + "_channel_label"));
         let node = create_text(&(channel.to_string() + "_channel_label"));
         let prop = node.get_property("rect").unwrap();
         let prop = node.get_property("rect").unwrap();
         prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
         prop.clone().set_f32(atom, Role::App, 0, CHANNEL_LABEL_X).unwrap();
-        prop.clone().set_f32(atom, Role::App, 1, channel_y).unwrap();
+        prop.clone().set_f32(atom, Role::App, 1, channel_y + CHANNEL_LABEL_Y).unwrap();
         prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
         prop.clone().set_f32(atom, Role::App, 2, 1000.).unwrap();
         prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
         prop.clone().set_f32(atom, Role::App, 3, 200.).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
         node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();

+ 0 - 2
bin/app/src/app/schema/test.rs

@@ -503,8 +503,6 @@ pub async fn make(app: &App, window: SceneNodePtr) {
     prop.clone().set_f32(atom, Role::App, 1, 20.).unwrap();
     prop.clone().set_f32(atom, Role::App, 1, 20.).unwrap();
 
 
     node.set_property_f32(atom, Role::App, "baseline", 34.).unwrap();
     node.set_property_f32(atom, Role::App, "baseline", 34.).unwrap();
-    node.set_property_f32(atom, Role::App, "linespacing", 50.).unwrap();
-    node.set_property_f32(atom, Role::App, "descent", 10.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 40.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", 40.).unwrap();
 
 
     #[cfg(target_os = "android")]
     #[cfg(target_os = "android")]

+ 1 - 1
bin/app/src/text2/mod.rs

@@ -31,7 +31,7 @@ pub mod atlas;
 mod editor;
 mod editor;
 pub use editor::Editor;
 pub use editor::Editor;
 mod render;
 mod render;
-pub use render::{render_layout, DebugRenderOptions};
+pub use render::{render_layout, render_layout_with_opts, DebugRenderOptions};
 
 
 use darkfi::system::CondVar;
 use darkfi::system::CondVar;
 
 

+ 5 - 0
bin/app/src/text2/render.rs

@@ -43,6 +43,11 @@ impl std::ops::BitOr for DebugRenderOptions {
         Self(self.0 | rhs.0)
         Self(self.0 | rhs.0)
     }
     }
 }
 }
+impl std::ops::BitOrAssign for DebugRenderOptions {
+    fn bitor_assign(&mut self, rhs: Self) {
+        self.0 |= rhs.0;
+    }
+}
 
 
 pub fn render_layout(
 pub fn render_layout(
     layout: &parley::Layout<Color>,
     layout: &parley::Layout<Color>,

+ 0 - 8
bin/app/src/ui/chatedit.rs

@@ -231,8 +231,6 @@ pub struct ChatEdit {
     content_height: PropertyFloat32,
     content_height: PropertyFloat32,
     rect: PropertyRect,
     rect: PropertyRect,
     baseline: PropertyFloat32,
     baseline: PropertyFloat32,
-    linespacing: PropertyFloat32,
-    descent: PropertyFloat32,
     lineheight: PropertyFloat32,
     lineheight: PropertyFloat32,
     scroll: PropertyFloat32,
     scroll: PropertyFloat32,
     scroll_speed: PropertyFloat32,
     scroll_speed: PropertyFloat32,
@@ -296,9 +294,6 @@ impl ChatEdit {
             PropertyFloat32::wrap(node_ref, Role::Internal, "content_height", 0).unwrap();
             PropertyFloat32::wrap(node_ref, Role::Internal, "content_height", 0).unwrap();
         let rect = PropertyRect::wrap(node_ref, Role::Internal, "rect").unwrap();
         let rect = PropertyRect::wrap(node_ref, Role::Internal, "rect").unwrap();
         let baseline = PropertyFloat32::wrap(node_ref, Role::Internal, "baseline", 0).unwrap();
         let baseline = PropertyFloat32::wrap(node_ref, Role::Internal, "baseline", 0).unwrap();
-        let linespacing =
-            PropertyFloat32::wrap(node_ref, Role::Internal, "linespacing", 0).unwrap();
-        let descent = PropertyFloat32::wrap(node_ref, Role::Internal, "descent", 0).unwrap();
         let lineheight = PropertyFloat32::wrap(node_ref, Role::Internal, "lineheight", 0).unwrap();
         let lineheight = PropertyFloat32::wrap(node_ref, Role::Internal, "lineheight", 0).unwrap();
         let scroll = PropertyFloat32::wrap(node_ref, Role::Internal, "scroll", 0).unwrap();
         let scroll = PropertyFloat32::wrap(node_ref, Role::Internal, "scroll", 0).unwrap();
         let scroll_speed =
         let scroll_speed =
@@ -362,8 +357,6 @@ impl ChatEdit {
             content_height,
             content_height,
             rect,
             rect,
             baseline,
             baseline,
-            linespacing,
-            descent,
             lineheight: lineheight.clone(),
             lineheight: lineheight.clone(),
             scroll: scroll.clone(),
             scroll: scroll.clone(),
             scroll_speed,
             scroll_speed,
@@ -1383,7 +1376,6 @@ impl UIObject for ChatEdit {
 
 
         on_modify.when_change(self.rect.prop(), redraw);
         on_modify.when_change(self.rect.prop(), redraw);
         on_modify.when_change(self.baseline.prop(), redraw);
         on_modify.when_change(self.baseline.prop(), redraw);
-        on_modify.when_change(self.linespacing.prop(), redraw);
         on_modify.when_change(self.lineheight.prop(), redraw);
         on_modify.when_change(self.lineheight.prop(), redraw);
         on_modify.when_change(self.select_ascent.prop(), redraw);
         on_modify.when_change(self.select_ascent.prop(), redraw);
         on_modify.when_change(self.select_descent.prop(), redraw);
         on_modify.when_change(self.select_descent.prop(), redraw);

+ 13 - 5
bin/app/src/ui/text.rs

@@ -22,8 +22,8 @@ use std::sync::{Arc, Mutex as SyncMutex, OnceLock, Weak};
 
 
 use crate::{
 use crate::{
     gfx::{
     gfx::{
-        GfxDrawCall, GfxDrawInstruction, GfxDrawMesh, GfxTextureId, ManagedTexturePtr, Rectangle,
-        RenderApi,
+        GfxDrawCall, GfxDrawInstruction, GfxDrawMesh, GfxTextureId, ManagedTexturePtr, Point,
+        Rectangle, RenderApi,
     },
     },
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_RED, COLOR_WHITE},
     mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_RED, COLOR_WHITE},
     prop::{
     prop::{
@@ -65,6 +65,7 @@ pub struct Text {
     font_size: PropertyFloat32,
     font_size: PropertyFloat32,
     text_color: PropertyColor,
     text_color: PropertyColor,
     baseline: PropertyFloat32,
     baseline: PropertyFloat32,
+    lineheight: PropertyFloat32,
     debug: PropertyBool,
     debug: PropertyBool,
 
 
     window_scale: PropertyFloat32,
     window_scale: PropertyFloat32,
@@ -89,6 +90,7 @@ impl Text {
         let font_size = PropertyFloat32::wrap(node_ref, Role::Internal, "font_size", 0).unwrap();
         let font_size = PropertyFloat32::wrap(node_ref, Role::Internal, "font_size", 0).unwrap();
         let text_color = PropertyColor::wrap(node_ref, Role::Internal, "text_color").unwrap();
         let text_color = PropertyColor::wrap(node_ref, Role::Internal, "text_color").unwrap();
         let baseline = PropertyFloat32::wrap(node_ref, Role::Internal, "baseline", 0).unwrap();
         let baseline = PropertyFloat32::wrap(node_ref, Role::Internal, "baseline", 0).unwrap();
+        let lineheight = PropertyFloat32::wrap(node_ref, Role::Internal, "lineheight", 0).unwrap();
         let debug = PropertyBool::wrap(node_ref, Role::Internal, "debug", 0).unwrap();
         let debug = PropertyBool::wrap(node_ref, Role::Internal, "debug", 0).unwrap();
 
 
         let node_name = node_ref.name.clone();
         let node_name = node_ref.name.clone();
@@ -108,6 +110,7 @@ impl Text {
             font_size,
             font_size,
             text_color,
             text_color,
             baseline,
             baseline,
+            lineheight,
             debug,
             debug,
 
 
             window_scale,
             window_scale,
@@ -120,15 +123,21 @@ impl Text {
     async fn regen_mesh(&self) -> Vec<GfxDrawInstruction> {
     async fn regen_mesh(&self) -> Vec<GfxDrawInstruction> {
         let text = self.text.get();
         let text = self.text.get();
         let font_size = self.font_size.get();
         let font_size = self.font_size.get();
+        let lineheight = self.lineheight.get();
         let text_color = self.text_color.get();
         let text_color = self.text_color.get();
         let window_scale = self.window_scale.get();
         let window_scale = self.window_scale.get();
 
 
         let layout = {
         let layout = {
             let mut txt_ctx = TEXT_CTX.get().await;
             let mut txt_ctx = TEXT_CTX.get().await;
-            txt_ctx.make_layout(&text, text_color, font_size, 0., window_scale, None, &[])
+            txt_ctx.make_layout(&text, text_color, font_size, lineheight, window_scale, None, &[])
         };
         };
 
 
-        text2::render_layout(&layout, &self.render_api)
+        let mut debug_opts = text2::DebugRenderOptions::Off;
+        if self.debug.get() {
+            debug_opts |= text2::DebugRenderOptions::Baseline;
+        }
+
+        text2::render_layout_with_opts(&layout, debug_opts, &self.render_api)
     }
     }
 
 
     async fn redraw(self: Arc<Self>) {
     async fn redraw(self: Arc<Self>) {
@@ -178,7 +187,6 @@ impl UIObject for Text {
         on_modify.when_change(self.font_size.prop(), Self::redraw);
         on_modify.when_change(self.font_size.prop(), Self::redraw);
         on_modify.when_change(self.text_color.prop(), Self::redraw);
         on_modify.when_change(self.text_color.prop(), Self::redraw);
         on_modify.when_change(self.debug.prop(), Self::redraw);
         on_modify.when_change(self.debug.prop(), Self::redraw);
-        on_modify.when_change(self.baseline.prop(), Self::redraw);
 
 
         self.tasks.set(on_modify.tasks);
         self.tasks.set(on_modify.tasks);
     }
     }