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

wallet: chatview which is scrollable via scroll property

darkfi 2 éve
szülő
commit
bdc3f99f22
2 módosított fájl, 56 hozzáadás és 15 törlés
  1. 11 2
      bin/darkwallet/src/app.rs
  2. 45 13
      bin/darkwallet/src/ui/chatview.rs

+ 11 - 2
bin/darkwallet/src/app.rs

@@ -402,16 +402,22 @@ impl App {
         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(0, 0.).unwrap();
-        prop.set_f32(1, 200.).unwrap();
+        let code =
+            vec![Op::Div((Box::new(Op::LoadVar("h".to_string())), Box::new(Op::ConstFloat32(2.))))];
+        prop.set_expr(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(2, code).unwrap();
         let code = vec![Op::Sub((
         let code = vec![Op::Sub((
-            Box::new(Op::LoadVar("h".to_string())),
+            Box::new(Op::Div((
+                Box::new(Op::LoadVar("h".to_string())),
+                Box::new(Op::ConstFloat32(2.)),
+            ))),
             Box::new(Op::ConstFloat32(200.)),
             Box::new(Op::ConstFloat32(200.)),
         ))];
         ))];
         prop.set_expr(3, code).unwrap();
         prop.set_expr(3, code).unwrap();
         node.set_property_f32("font_size", 20.).unwrap();
         node.set_property_f32("font_size", 20.).unwrap();
         node.set_property_f32("line_height", 30.).unwrap();
         node.set_property_f32("line_height", 30.).unwrap();
+        node.set_property_f32("baseline", 10.).unwrap();
         node.set_property_u32("z_index", 1).unwrap();
         node.set_property_u32("z_index", 1).unwrap();
 
 
         drop(sg);
         drop(sg);
@@ -608,6 +614,9 @@ fn create_chatview(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
     let prop = Property::new("line_height", PropertyType::Float32, PropertySubType::Pixel);
     let prop = Property::new("line_height", PropertyType::Float32, PropertySubType::Pixel);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 
+    let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
+    node.add_property(prop).unwrap();
+
     let mut prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
     let mut prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
     node.add_property(prop).unwrap();
     node.add_property(prop).unwrap();
 
 

+ 45 - 13
bin/darkwallet/src/ui/chatview.rs

@@ -41,6 +41,8 @@ use crate::{
 
 
 use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
 use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppable};
 
 
+const DEBUG_RENDER: bool = false;
+
 #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
 #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
 pub struct ChatMsg {
 pub struct ChatMsg {
     pub nick: String,
     pub nick: String,
@@ -80,6 +82,7 @@ pub struct ChatView {
     scroll: PropertyFloat32,
     scroll: PropertyFloat32,
     font_size: PropertyFloat32,
     font_size: PropertyFloat32,
     line_height: PropertyFloat32,
     line_height: PropertyFloat32,
+    baseline: PropertyFloat32,
     z_index: PropertyUint32,
     z_index: PropertyUint32,
 }
 }
 
 
@@ -98,6 +101,7 @@ impl ChatView {
         let scroll = PropertyFloat32::wrap(node, "scroll", 0).unwrap();
         let scroll = PropertyFloat32::wrap(node, "scroll", 0).unwrap();
         let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
         let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
         let line_height = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
         let line_height = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
+        let baseline = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
         let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
         let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
 
 
         drop(scene_graph);
         drop(scene_graph);
@@ -115,6 +119,7 @@ impl ChatView {
             scroll,
             scroll,
             font_size,
             font_size,
             line_height,
             line_height,
+            baseline,
             z_index,
             z_index,
         });
         });
 
 
@@ -170,6 +175,7 @@ impl ChatView {
     async fn regen_mesh(&self, mut clip: Rectangle) -> Vec<DrawInstruction> {
     async fn regen_mesh(&self, mut clip: Rectangle) -> Vec<DrawInstruction> {
         let font_size = self.font_size.get();
         let font_size = self.font_size.get();
         let line_height = self.line_height.get();
         let line_height = self.line_height.get();
+        let baseline = self.baseline.get();
         // Draw time and nick, then go over each word. If word crosses end of line
         // Draw time and nick, then go over each word. If word crosses end of line
         // then apply a line break before the word and continue.
         // then apply a line break before the word and continue.
         let pages = self.pages.lock().unwrap().clone();
         let pages = self.pages.lock().unwrap().clone();
@@ -177,8 +183,12 @@ impl ChatView {
         let mut draws = vec![];
         let mut draws = vec![];
         let color = COLOR_WHITE;
         let color = COLOR_WHITE;
 
 
+        // This is a little hack to nudge the bottom line up slightly, otherwise
+        // chars like p will cross the bottom.
+        let descent = line_height / 2.;
+
         // Pages start at the bottom.
         // Pages start at the bottom.
-        let mut height = 0;
+        let mut current_idx = 1;
         'pageloop: for page in pages {
         'pageloop: for page in pages {
             let mut mesh = MeshBuilder::new();
             let mut mesh = MeshBuilder::new();
 
 
@@ -189,22 +199,22 @@ impl ChatView {
                 // We are drawing bottom up but line wrap gives us lines in normal order
                 // We are drawing bottom up but line wrap gives us lines in normal order
                 lines.reverse();
                 lines.reverse();
                 for line in lines {
                 for line in lines {
-                    let px_height = height as f32 * line_height;
+                    let off_y = descent + current_idx as f32 * line_height;
 
 
-                    if px_height > clip.h {
-                        break 'pageloop;
-                    }
+                    //if px_height > clip.h {
+                    //    break 'pageloop;
+                    //}
 
 
                     // Render line
                     // Render line
-                    let mut glyph_pos_iter =
-                        GlyphPositionIter::new(font_size, &line, clip.h - px_height);
+                    let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &line, baseline);
                     for (mut glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
                     for (mut glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
                         let uv_rect =
                         let uv_rect =
                             page.atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
                             page.atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
+                        glyph_rect.y -= off_y;
                         mesh.draw_box(&glyph_rect, color, uv_rect);
                         mesh.draw_box(&glyph_rect, color, uv_rect);
                     }
                     }
 
 
-                    height += 1;
+                    current_idx += 1;
                 }
                 }
             }
             }
 
 
@@ -218,6 +228,22 @@ impl ChatView {
             }));
             }));
         }
         }
 
 
+        if DEBUG_RENDER {
+            let mut debug_mesh = MeshBuilder::new();
+            debug_mesh.draw_outline(
+                &Rectangle { x: 0., y: -clip.h, w: clip.w, h: clip.h },
+                COLOR_BLUE,
+                2.,
+            );
+            let mesh = debug_mesh.alloc(&self.render_api).await.unwrap();
+            draws.push(DrawInstruction::Draw(DrawMesh {
+                vertex_buffer: mesh.vertex_buffer,
+                index_buffer: mesh.index_buffer,
+                texture: None,
+                num_elements: mesh.num_elements,
+            }));
+        }
+
         draws
         draws
     }
     }
 
 
@@ -239,19 +265,25 @@ impl ChatView {
 
 
         let mut drawcalls = self.regen_mesh(rect.clone()).await;
         let mut drawcalls = self.regen_mesh(rect.clone()).await;
         // TODO: delete old buffers
         // TODO: delete old buffers
+        // we need to save the buffers for that
         let mut freed_textures = vec![];
         let mut freed_textures = vec![];
         let mut freed_buffers = vec![];
         let mut freed_buffers = vec![];
 
 
+        debug!(target: "ui::chatview", "chatview rect = {:?}", rect);
+
         // Apply scroll and scissor
         // Apply scroll and scissor
         // We use the scissor for scrolling
         // We use the scissor for scrolling
-        let off_x = rect.x / parent_rect.w;
-        let off_y = rect.y / parent_rect.h;
-        let scale_x = 1. / parent_rect.w;
-        let scale_y = 1. / parent_rect.h;
+        // Because we use the scissor, our actual rect is now rect instead of parent_rect
+        let off_x = 0.;
+        let off_y = self.scroll.get() + rect.h / rect.h;
+        let scale_x = 1. / rect.w;
+        let scale_y = 1. / rect.h;
         let model = glam::Mat4::from_translation(glam::Vec3::new(off_x, off_y, 0.)) *
         let model = glam::Mat4::from_translation(glam::Vec3::new(off_x, off_y, 0.)) *
             glam::Mat4::from_scale(glam::Vec3::new(scale_x, scale_y, 1.));
             glam::Mat4::from_scale(glam::Vec3::new(scale_x, scale_y, 1.));
 
 
-        let mut instrs = vec![DrawInstruction::ApplyMatrix(model)];
+        let mut instrs =
+            vec![DrawInstruction::ApplyViewport(rect), DrawInstruction::ApplyMatrix(model)];
+        //let mut instrs = vec![DrawInstruction::ApplyMatrix(model)];
         instrs.append(&mut drawcalls);
         instrs.append(&mut drawcalls);
 
 
         Some(DrawUpdate {
         Some(DrawUpdate {