1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! Workflow canvas theme
use crate::theme::Theme;
use gpui::Rgba;
/// Theme for the workflow canvas
#[derive(Debug, Clone)]
pub struct WorkflowTheme {
// Canvas
/// Canvas background color
pub canvas_background: Rgba,
/// Grid line color
pub grid_color: Rgba,
/// Grid line spacing in pixels
pub grid_spacing: f32,
// Nodes
/// Node background color
pub node_background: Rgba,
/// Node border color
pub node_border: Rgba,
/// Node border color when selected
pub node_border_selected: Rgba,
/// Node header background
pub node_header: Rgba,
/// Node text color
pub node_text: Rgba,
/// Node border radius
pub node_border_radius: f32,
/// Node header height in pixels (used for port positioning)
pub node_header_height: f32,
/// Node content padding in pixels (py_2 = 8px)
pub node_content_padding: f32,
// Ports
/// Input port color
pub port_input: Rgba,
/// Output port color
pub port_output: Rgba,
/// Port color when hovered
pub port_hover: Rgba,
/// Port color when connection is valid
pub port_valid: Rgba,
/// Port color when connection is invalid
pub port_invalid: Rgba,
/// Port radius
pub port_radius: f32,
// Connections
/// Connection line color
pub connection_color: Rgba,
/// Connection line color when selected
pub connection_selected: Rgba,
/// Connection line width for fat links (all channels)
pub connection_width: f32,
/// Connection line width for thin links (single channel)
pub connection_width_thin: f32,
/// Connection preview color (while dragging)
pub connection_preview: Rgba,
// Selection
/// Selection box fill color
pub selection_fill: Rgba,
/// Selection box border color
pub selection_border: Rgba,
}
impl WorkflowTheme {
/// Create theme from the global theme
pub fn from_theme(theme: &Theme) -> Self {
Self {
// Canvas
canvas_background: theme.background,
grid_color: Rgba {
r: theme.border.r,
g: theme.border.g,
b: theme.border.b,
a: 0.3,
},
grid_spacing: 20.0,
// Nodes
node_background: theme.surface,
node_border: theme.border,
node_border_selected: theme.accent,
node_header: Rgba {
r: theme.surface.r * 0.8,
g: theme.surface.g * 0.8,
b: theme.surface.b * 0.8,
a: theme.surface.a,
},
node_text: theme.text_primary,
node_border_radius: 8.0,
// Header height: py_1 (4px) + text_sm (~20px line height) + py_1 (4px) = 28px
node_header_height: 28.0,
// Content padding: py_2 = 8px
node_content_padding: 8.0,
// Ports
port_input: theme.info,
port_output: theme.success,
port_hover: theme.accent_hover,
port_valid: theme.success,
port_invalid: theme.error,
port_radius: 6.0,
// Connections
connection_color: theme.text_secondary,
connection_selected: theme.accent,
connection_width: 4.0, // Fat links (all channels)
connection_width_thin: 1.5, // Thin links (single channel)
connection_preview: Rgba {
r: theme.accent.r,
g: theme.accent.g,
b: theme.accent.b,
a: 0.6,
},
// Selection
selection_fill: Rgba {
r: theme.accent.r,
g: theme.accent.g,
b: theme.accent.b,
a: 0.1,
},
selection_border: theme.accent,
}
}
/// Create default dark theme
pub fn dark() -> Self {
Self::from_theme(&Theme::dark())
}
/// Scale the theme dimensions by a factor
pub fn scale(&self, factor: f32) -> Self {
let mut scaled = self.clone();
scaled.grid_spacing *= factor;
scaled.node_border_radius *= factor;
scaled.node_header_height *= factor;
scaled.node_content_padding *= factor;
scaled.port_radius *= factor;
scaled.connection_width *= factor;
scaled.connection_width_thin *= factor;
scaled
}
}
impl Default for WorkflowTheme {
fn default() -> Self {
Self::dark()
}
}