Kaynağa Gözat

app: apply new theming + make a radial glow cos artman demand it

jkds 6 ay önce
ebeveyn
işleme
638d46ff64

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

@@ -276,6 +276,13 @@ pub async fn make(
         cc.compile("h + 1").unwrap(),
         sep_color,
     );
+    shape.add_gradient_box(
+        expr::const_f32(EMOJI_BG_W + 1.),
+        expr::const_f32(0.),
+        expr::load_var("w"),
+        expr::load_var("h"),
+        [[0., 1., 0.64, 0.3], [0., 1., 0.64, 0.3], [0., 0.88, 1., 0.], [0., 0.88, 1., 0.]],
+    );
 
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
     layer_node.link(node);
@@ -624,14 +631,6 @@ pub async fn make(
         expr::load_var("h"),
         bg_color,
     );
-    // Left hand darker box
-    shape.add_filled_box(
-        expr::const_f32(0.),
-        expr::const_f32(1.),
-        expr::const_f32(EMOJI_BG_W),
-        expr::load_var("h"),
-        lhs_bg_color,
-    );
     // Top line
     shape.add_filled_box(
         expr::const_f32(0.),
@@ -640,13 +639,20 @@ pub async fn make(
         expr::const_f32(1.),
         line_color,
     );
-    // Side line
-    shape.add_filled_box(
-        expr::const_f32(EMOJI_BG_W),
-        expr::const_f32(0.),
-        expr::const_f32(EMOJI_BG_W + 1.),
+    shape.add_radial_glow(
+        // Center
+        cc.compile("w / 2").unwrap(),
         expr::load_var("h"),
-        line_color,
+        // Size
+        expr::load_var("w"),
+        cc.compile("h / 4").unwrap(),
+        // Segments
+        8,
+        // Angles
+        std::f32::consts::PI,
+        2. * std::f32::consts::PI,
+        // Color
+        [0., 0.4, 0., 1.],
     );
     // Bottom line
     //shape.add_filled_box(

+ 20 - 35
bin/app/src/app/schema/mod.rs

@@ -219,23 +219,27 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
     window.link(node);
     */
 
-    if COLOR_SCHEME == ColorScheme::DarkMode {
-        // Bg layer
-        let layer_node = create_layer("bg_layer");
-        let prop = layer_node.get_property("rect").unwrap();
-        prop.set_f32(atom, Role::App, 0, 0.).unwrap();
-        prop.set_f32(atom, Role::App, 1, 0.).unwrap();
-        prop.set_expr(atom, Role::App, 2, expr::load_var("w")).unwrap();
-        prop.set_expr(atom, Role::App, 3, expr::load_var("h")).unwrap();
-        layer_node.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
-        layer_node.set_property_u32(atom, Role::App, "z_index", 0).unwrap();
-        let layer_node = layer_node.setup(|me| Layer::new(me, app.render_api.clone())).await;
-        window.link(layer_node.clone());
+    // Root content layer
+    let content = create_layer("content");
+    let prop = content.get_property("rect").unwrap();
+    prop.set_expr(atom, Role::App, 0, expr::load_var("insets_left")).unwrap();
+    prop.set_expr(atom, Role::App, 1, expr::load_var("insets_top")).unwrap();
+    let code = cc.compile("w - insets_left - insets_right").unwrap();
+    prop.set_expr(atom, Role::App, 2, code).unwrap();
+    let code = cc.compile("h - insets_top - insets_bottom").unwrap();
+    prop.set_expr(atom, Role::App, 3, code).unwrap();
+    let window_insets = window.get_property("insets").unwrap();
+    prop.add_depend(&window_insets, 0, "insets_left");
+    prop.add_depend(&window_insets, 1, "insets_top");
+    prop.add_depend(&window_insets, 2, "insets_right");
+    prop.add_depend(&window_insets, 3, "insets_bottom");
+    content.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
+    content.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
+    let content = content.setup(|me| Layer::new(me, app.render_api.clone())).await;
+    window.link(content.clone());
 
+    if COLOR_SCHEME == ColorScheme::DarkMode {
         let node = create_video("king");
-
-        // Create a bg image
-        //let node = create_image("bg_image");
         let prop = node.get_property("rect").unwrap();
         prop.set_f32(atom, Role::App, 0, 0.).unwrap();
         prop.set_f32(atom, Role::App, 1, 0.).unwrap();
@@ -293,7 +297,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         //let node = node.setup(|me| Image::new(me, app.render_api.clone())).await;
         //layer_node.link(node);
         let node = node.setup(|me| Video::new(me, app.render_api.clone(), app.ex.clone())).await;
-        layer_node.link(node);
+        content.link(node);
     } else if COLOR_SCHEME == ColorScheme::PaperLight {
         let node = create_vector_art("bg");
         let prop = node.get_property("rect").unwrap();
@@ -317,25 +321,6 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         window.link(node);
     }
 
-    // Root content layer
-    let content = create_layer("content");
-    let prop = content.get_property("rect").unwrap();
-    prop.set_expr(atom, Role::App, 0, expr::load_var("insets_left")).unwrap();
-    prop.set_expr(atom, Role::App, 1, expr::load_var("insets_top")).unwrap();
-    let code = cc.compile("w - insets_left - insets_right").unwrap();
-    prop.set_expr(atom, Role::App, 2, code).unwrap();
-    let code = cc.compile("h - insets_top - insets_bottom").unwrap();
-    prop.set_expr(atom, Role::App, 3, code).unwrap();
-    let window_insets = window.get_property("insets").unwrap();
-    prop.add_depend(&window_insets, 0, "insets_left");
-    prop.add_depend(&window_insets, 1, "insets_top");
-    prop.add_depend(&window_insets, 2, "insets_right");
-    prop.add_depend(&window_insets, 3, "insets_bottom");
-    content.set_property_bool(atom, Role::App, "is_visible", true).unwrap();
-    content.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
-    let content = content.setup(|me| Layer::new(me, app.render_api.clone())).await;
-    window.link(content.clone());
-
     let netlayer_node = create_layer("netstatus_layer");
     let prop = netlayer_node.get_property("rect").unwrap();
     let code = cc.compile("w - NETSTATUS_ICON_SIZE").unwrap();

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

@@ -112,6 +112,21 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
         1.,
         COLOR_PURPLE,
     );
+    shape.add_radial_glow(
+        // Center
+        cc.compile("w / 2").unwrap(),
+        cc.compile("h / 2").unwrap(),
+        // Size
+        expr::load_var("w"),
+        expr::load_var("h"),
+        // Segments
+        16,
+        // Angles
+        0.,
+        2. * std::f32::consts::PI,
+        // Color
+        [0., 1., 0., 1.],
+    );
     let node = node.setup(|me| VectorArt::new(me, shape, app.render_api.clone())).await;
     layer_node.link(node);
 

+ 3 - 1
bin/app/src/main.rs

@@ -23,7 +23,6 @@
 use clap::Parser;
 use darkfi::system::CondVar;
 use std::sync::{Arc, OnceLock};
-use url::Url;
 
 #[macro_use]
 extern crate tracing;
@@ -62,11 +61,14 @@ use net::ZeroMQAdapter;
 #[cfg(feature = "enable-plugins")]
 use {
     darkfi_serial::{deserialize, Decodable, Encodable},
+    // Local imports
     gfx::RenderApi,
     prop::{PropertyBool, PropertyStr, Role},
     scene::{SceneNodePtr, Slot},
     std::io::Cursor,
     ui::chatview,
+    // Global imports
+    url::Url,
 };
 
 // This is historical, but ideally we can fix the entire project and remove this import.

+ 2 - 2
bin/app/src/ui/edit/action.rs

@@ -20,10 +20,10 @@ use parking_lot::Mutex as SyncMutex;
 use rand::{rngs::OsRng, Rng};
 
 use crate::{
-    gfx::{gfxtag, DrawCall, DrawInstruction, Point, Rectangle},
+    gfx::{gfxtag, DrawCall, DrawInstruction, Point, Rectangle, RenderApi},
     mesh::{Color, MeshBuilder},
     prop::BatchGuardId,
-    text, RenderApi,
+    text,
 };
 
 macro_rules! d { ($($arg:tt)*) => { debug!(target: "ui::edit::action", $($arg)*); } }

+ 68 - 11
bin/app/src/ui/vector_art/shape.rs

@@ -50,6 +50,19 @@ impl ShapeVertex {
     }
 }
 
+// This is bullshit. We need something in expr to support joining exprs somehow. Subroutines.
+// Hacky temp workaround for now.
+// s-expr surgery
+fn sexpr_add(mut x: SExprCode, op: Op) -> Option<SExprCode> {
+    let eqn = x.pop()?;
+    x.push(Op::Add((Box::new(eqn), Box::new(op))));
+    Some(x)
+}
+fn sexpr_mul(mut x: SExprCode, op: Op) -> Option<Op> {
+    let eqn = x.pop()?;
+    Some(Op::Mul((Box::new(eqn), Box::new(op))))
+}
+
 #[derive(Debug)]
 pub struct VectorShape {
     pub verts: Vec<ShapeVertex>,
@@ -123,13 +136,6 @@ impl VectorShape {
         self.indices.append(&mut indices);
     }
 
-    // s-expr surgery
-    fn sexpr_add(mut x: SExprCode, border_px: f32) -> Option<SExprCode> {
-        let eqn = x.pop()?;
-        x.push(Op::Add((Box::new(eqn), Box::new(Op::ConstFloat32(border_px)))));
-        Some(x)
-    }
-
     pub fn add_outline(
         &mut self,
         x1: SExprCode,
@@ -143,7 +149,7 @@ impl VectorShape {
         self.add_filled_box(
             x1.clone(),
             y1.clone(),
-            Self::sexpr_add(x1.clone(), border_px).unwrap(),
+            sexpr_add(x1.clone(), Op::ConstFloat32(border_px)).unwrap(),
             y2.clone(),
             color.clone(),
         );
@@ -152,12 +158,12 @@ impl VectorShape {
             x1.clone(),
             y1.clone(),
             x2.clone(),
-            Self::sexpr_add(y1.clone(), border_px).unwrap(),
+            sexpr_add(y1.clone(), Op::ConstFloat32(border_px)).unwrap(),
             color.clone(),
         );
         // RHS
         self.add_filled_box(
-            Self::sexpr_add(x2.clone(), -border_px).unwrap(),
+            sexpr_add(x2.clone(), Op::ConstFloat32(-border_px)).unwrap(),
             y1.clone(),
             x2.clone(),
             y2.clone(),
@@ -166,13 +172,64 @@ impl VectorShape {
         // BHS
         self.add_filled_box(
             x1.clone(),
-            Self::sexpr_add(y2.clone(), -border_px).unwrap(),
+            sexpr_add(y2.clone(), Op::ConstFloat32(-border_px)).unwrap(),
             x2.clone(),
             y2.clone(),
             color.clone(),
         );
     }
 
+    pub fn add_radial_glow(
+        &mut self,
+        center_x: SExprCode,
+        center_y: SExprCode,
+        width: SExprCode,
+        height: SExprCode,
+        segments: usize,
+        start_angle: f32,
+        end_angle: f32,
+        mut color: Color,
+    ) {
+        // Helper to create an x coordinate on the ellipse: center_x + width * cos_angle
+        fn ellipse_x(center_x: &SExprCode, width: &SExprCode, cos_angle: f32) -> SExprCode {
+            let width_calc = sexpr_mul(width.clone(), Op::ConstFloat32(cos_angle)).unwrap();
+            sexpr_add(center_x.clone(), width_calc).unwrap()
+        }
+
+        // Helper to create a y coordinate on the ellipse: center_y + height * sin_angle
+        fn ellipse_y(center_y: &SExprCode, height: &SExprCode, sin_angle: f32) -> SExprCode {
+            let height_calc = sexpr_mul(height.clone(), Op::ConstFloat32(sin_angle)).unwrap();
+            sexpr_add(center_y.clone(), height_calc).unwrap()
+        }
+
+        let mut new_verts = vec![];
+        let mut new_indices = vec![];
+        let base_idx = self.verts.len() as u16;
+
+        // Create center vertex at index 0
+        new_verts.push(ShapeVertex::new(center_x.clone(), center_y.clone(), color.clone()));
+
+        color[3] = 0.;
+        // Generate vertices along the arc
+        for i in 0..=segments {
+            let t = i as f32 / segments as f32;
+            let angle = start_angle + t * (end_angle - start_angle);
+            let x = ellipse_x(&center_x, &width, angle.cos() * 0.5);
+            let y = ellipse_y(&center_y, &height, angle.sin() * 0.5);
+            new_verts.push(ShapeVertex::new(x, y, color.clone()));
+        }
+
+        // Create triangles: center vertex (0) with each pair of adjacent arc vertices
+        for i in 0..segments {
+            new_indices.push(base_idx); // center
+            new_indices.push(base_idx + 1 + i as u16); // current arc vertex
+            new_indices.push(base_idx + 2 + i as u16); // next arc vertex
+        }
+
+        self.verts.append(&mut new_verts);
+        self.indices.append(&mut new_indices);
+    }
+
     pub fn scaled(self, scale: f32) -> Self {
         Self {
             verts: self.verts.into_iter().map(|v| v.scale(scale)).collect(),