GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: node-domain opacity for the graph (style.surface.graph.node.opacity)
Graph node bodies, wires, connectors, and toggles fade via a new
node_opacity, independent of network_opacity which fades only the pane
surface (grid cells/gaps).
Co-Authored-By: Claude Fable 5 <[email protected]>
src/color.rs | 18 ++++++++++++++++++
src/widget/display/graph.rs | 19 +++++++++++++------
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/src/color.rs b/src/color.rs
index 102631a..0b4a32d 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -128,6 +128,10 @@ static SCROLLBAR_THUMB_COLOR: RwLock<[f32; 4]> = RwLock::new([0.60, 0.60, 0.65,
static GRAPH_CELL_COLOR: RwLock<[f32; 3]> = RwLock::new([0.13, 0.13, 0.16]);
static GRAPH_GAP_COLOR: RwLock<[f32; 3]> = RwLock::new([0.07, 0.07, 0.09]);
static GRAPH_OPACITY: RwLock<f32> = RwLock::new(0.95);
+/// Opacity of the graph's NODE-domain content (node bodies, wires, connectors,
+/// node text) — `style.surface.graph.node.opacity`, deliberately independent of
+/// `GRAPH_OPACITY`, which fades only the pane surface (grid cells/gaps).
+static GRAPH_NODE_OPACITY: RwLock<f32> = RwLock::new(1.0);
static GRAPH_NODE_COLOR: RwLock<[f32; 4]> = RwLock::new(NODE_IDLE);
static GRAPH_NODE_SELECTED_COLOR: RwLock<[f32; 4]> = RwLock::new(NODE_SELECTED);
@@ -553,6 +557,9 @@ fn parse_and_set_colors(content: &str) {
if let Some(opacity) = val.pointer("/style/surface/graph/opacity").and_then(|v| v.as_f64()) {
if let Ok(mut lock) = GRAPH_OPACITY.write() { *lock = opacity as f32; }
}
+ if let Some(opacity) = val.pointer("/style/surface/graph/node/opacity").and_then(|v| v.as_f64()) {
+ if let Ok(mut lock) = GRAPH_NODE_OPACITY.write() { *lock = opacity as f32; }
+ }
if let Some(c) = get_color("/style/data/tree/background_color") {
if let Ok(mut lock) = TREE_BACKGROUND_COLOR.write() { *lock = c; }
@@ -795,6 +802,17 @@ pub fn graph_opacity() -> f32 {
*GRAPH_OPACITY.read().unwrap()
}
+pub fn graph_node_opacity() -> f32 {
+ load_colors_once();
+ *GRAPH_NODE_OPACITY.read().unwrap()
+}
+
+pub fn set_graph_node_opacity(opacity: f32) {
+ if let Ok(mut lock) = GRAPH_NODE_OPACITY.write() {
+ *lock = opacity;
+ }
+}
+
pub fn set_graph_opacity(opacity: f32) {
if let Ok(mut lock) = GRAPH_OPACITY.write() {
*lock = opacity;
diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index 07ec0b6..9931001 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -76,6 +76,9 @@ pub struct Graph {
uniform_background: bool,
network_opacity: f32,
+ /// Node-domain opacity (bodies, wires, connectors) — independent of
+ /// `network_opacity`, which fades the pane surface (grid cells/gaps).
+ node_opacity: f32,
cell_color: [f32; 3],
gap_color: [f32; 3],
@@ -120,6 +123,7 @@ impl Graph {
toggle_hovered_idx: None,
uniform_background: false,
network_opacity: crate::color::graph_opacity(),
+ node_opacity: crate::color::graph_node_opacity(),
cell_color: cell_col,
gap_color: gap_col,
connecting_from: None,
@@ -135,6 +139,9 @@ impl Graph {
pub fn set_network_opacity(&mut self, opacity: f32) {
self.network_opacity = opacity;
}
+ pub fn set_node_opacity(&mut self, opacity: f32) {
+ self.node_opacity = opacity;
+ }
pub fn grid_sizes(&self) -> (f32, f32) {
(self.grid_size_x, self.grid_size_y)
}
@@ -295,7 +302,7 @@ impl Graph {
// Connection wires: each node with an "input" parameter draws a wire from that source
// node's first output port to its own first input port.
- let wire_color = [0.0, 0.75, 1.0, 0.7 * self.network_opacity]; // Vibrant cyan glow
+ let wire_color = [0.0, 0.75, 1.0, 0.7 * self.node_opacity]; // Vibrant cyan glow
for i in 0..self.nodes.len() {
let node = &self.nodes[i];
if let Some((_, input_name, _)) = node.parameters.iter().find(|(name, _, _)| name.eq_ignore_ascii_case("input")) {
@@ -420,7 +427,7 @@ impl Graph {
} else {
colors::node_color()
};
- bg_color[3] *= self.network_opacity;
+ bg_color[3] *= self.node_opacity;
if nx + nw > min_x && nx < max_x && ny + nh > min_y && ny < max_y {
quads.push((nx, ny, nw, nh, bg_color));
}
@@ -431,13 +438,13 @@ impl Graph {
} else {
colors::TOGGLE_OFF
};
- btn_color[3] *= self.network_opacity;
+ btn_color[3] *= self.node_opacity;
push_clipped(tx, ty, tw, th, btn_color, &mut quads);
if self.nodes[i].geom_visible {
let inset = 3.0 * scale_f;
let mut toggle_on_color = colors::TOGGLE_ON;
- toggle_on_color[3] *= self.network_opacity;
+ toggle_on_color[3] *= self.node_opacity;
push_clipped(tx + inset, ty + inset, tw - inset * 2.0, th - inset * 2.0, toggle_on_color, &mut quads);
}
}
@@ -493,8 +500,8 @@ impl Graph {
let conn_size = crate::layout::graph_connector_size();
let mut conn_color = colors::graph_connector_color();
let mut conn_hl_color = colors::graph_connector_highlight_color();
- conn_color[3] *= self.network_opacity;
- conn_hl_color[3] *= self.network_opacity;
+ conn_color[3] *= self.node_opacity;
+ conn_hl_color[3] *= self.node_opacity;
for i in 0..self.nodes.len() {
if let Some((nx, ny, nw, nh)) = self.node_rect(i) {