GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Support window_manager.light_source_position configuration and evaluate dynamic bevel shading in push_plate_bevel_vertices
src/backend/window_runner.rs | 86 ++++++++++++++++++++++----------------------
src/layout.rs | 5 +++
2 files changed, 48 insertions(+), 43 deletions(-)
diff --git a/src/backend/window_runner.rs b/src/backend/window_runner.rs
index d4cc7bc..e15590c 100644
--- a/src/backend/window_runner.rs
+++ b/src/backend/window_runner.rs
@@ -637,55 +637,55 @@ pub fn push_plate_bevel_vertices(
out: &mut Vec<Vertex>,
) {
let r = r.min(ww * 0.5).min(h * 0.5);
- let highlight_color = [1.0, 1.0, 1.0, 0.15];
- let shadow_color = [0.0, 0.0, 0.0, 0.25];
- out.extend_from_slice(&quad_vertices_with_clip(x + r, y, ww - 2.0 * r, t, sw, sh, highlight_color, clip_circle));
- out.extend_from_slice(&quad_vertices_with_clip(x, y + r, t, h - 2.0 * r, sw, sh, highlight_color, clip_circle));
- out.extend_from_slice(&quad_vertices_with_clip(x + r, y + h - t, ww - 2.0 * r, t, sw, sh, shadow_color, clip_circle));
- out.extend_from_slice(&quad_vertices_with_clip(x + ww - t, y + r, t, h - 2.0 * r, sw, sh, shadow_color, clip_circle));
+ let light_angle = crate::layout::light_source_position();
+ let rad = light_angle.to_radians();
+ let lx = rad.cos();
+ let ly = -rad.sin();
- let segments = 16;
+ let edge_color = |factor: f32| -> [f32; 4] {
+ if factor >= 0.0 {
+ [1.0, 1.0, 1.0, 0.15 * factor]
+ } else {
+ [0.0, 0.0, 0.0, 0.25 * (-factor)]
+ }
+ };
- push_arc_background_vertices(
- x + r, y + r, r, t,
- std::f32::consts::PI, 1.5 * std::f32::consts::PI,
- sw, sh, highlight_color, segments, clip_circle,
- out,
- );
+ let top_color = edge_color(-ly);
+ let left_color = edge_color(-lx);
+ let bottom_color = edge_color(ly);
+ let right_color = edge_color(lx);
- push_arc_background_vertices(
- x + ww - r, y + r, r, t,
- 1.5 * std::f32::consts::PI, 1.75 * std::f32::consts::PI,
- sw, sh, highlight_color, segments / 2, clip_circle,
- out,
- );
- push_arc_background_vertices(
- x + ww - r, y + r, r, t,
- 1.75 * std::f32::consts::PI, 2.0 * std::f32::consts::PI,
- sw, sh, shadow_color, segments / 2, clip_circle,
- out,
- );
+ out.extend_from_slice(&quad_vertices_with_clip(x + r, y, ww - 2.0 * r, t, sw, sh, top_color, clip_circle));
+ out.extend_from_slice(&quad_vertices_with_clip(x, y + r, t, h - 2.0 * r, sw, sh, left_color, clip_circle));
+ out.extend_from_slice(&quad_vertices_with_clip(x + r, y + h - t, ww - 2.0 * r, t, sw, sh, bottom_color, clip_circle));
+ out.extend_from_slice(&quad_vertices_with_clip(x + ww - t, y + r, t, h - 2.0 * r, sw, sh, right_color, clip_circle));
- push_arc_background_vertices(
- x + ww - r, y + h - r, r, t,
- 0.0, 0.5 * std::f32::consts::PI,
- sw, sh, shadow_color, segments, clip_circle,
- out,
- );
+ let segments = 16;
+ let corners = [
+ (x + r, y + r, std::f32::consts::PI, 1.5 * std::f32::consts::PI), // Top-Left
+ (x + ww - r, y + r, 1.5 * std::f32::consts::PI, 2.0 * std::f32::consts::PI), // Top-Right
+ (x + ww - r, y + h - r, 0.0, 0.5 * std::f32::consts::PI), // Bottom-Right
+ (x + r, y + h - r, 0.5 * std::f32::consts::PI, std::f32::consts::PI), // Bottom-Left
+ ];
- push_arc_background_vertices(
- x + r, y + h - r, r, t,
- 0.5 * std::f32::consts::PI, 0.75 * std::f32::consts::PI,
- sw, sh, shadow_color, segments / 2, clip_circle,
- out,
- );
- push_arc_background_vertices(
- x + r, y + h - r, r, t,
- 0.75 * std::f32::consts::PI, std::f32::consts::PI,
- sw, sh, highlight_color, segments / 2, clip_circle,
- out,
- );
+ for &(cx, cy, start_angle, end_angle) in &corners {
+ for j in 0..segments {
+ let theta1 = start_angle + (j as f32) * (end_angle - start_angle) / (segments as f32);
+ let theta2 = start_angle + ((j + 1) as f32) * (end_angle - start_angle) / (segments as f32);
+ let theta_mid = 0.5 * (theta1 + theta2);
+
+ let factor = (theta_mid.cos() * lx + theta_mid.sin() * ly).clamp(-1.0, 1.0);
+ let segment_color = edge_color(factor);
+
+ push_arc_background_vertices(
+ cx, cy, r, t,
+ theta1, theta2,
+ sw, sh, segment_color, 1, clip_circle,
+ out,
+ );
+ }
+ }
}
pub fn push_plate_solid_border_vertices(
diff --git a/src/layout.rs b/src/layout.rs
index e60403d..63c9893 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -105,6 +105,7 @@ fn flatten_json_to_flat_props(val: &serde_json::Value, prefix: &str, flat_props:
"style.control.toggle.disabled_color" => "toggle_disabled_color",
"style.control.toggle.border_color" => "toggle_border_color",
"style.control.toggle.corner_radius" => "toggle_corner_radius",
+ "window_manager.light_source_position" => "light_source_position",
"style.control.ramp.height" => "ramp_height",
"style.status.normal_color" => "status_normal_color",
"style.status.background_color" => "status_background_color",
@@ -1412,6 +1413,10 @@ pub fn set_toggle_height(height: f32) {
}
}
+pub fn light_source_position() -> f32 {
+ get_style_registry().read().unwrap().get_float("light_source_position").unwrap_or(135.0)
+}
+
pub fn toggle_corner_radius() -> f32 {
lazy_init_style_registry();
get_style_registry().read().unwrap().get_float("toggle_corner_radius").unwrap_or(4.0)