tangled
alpha
login
or
join now
nate.rip
/
gpuikit
A ui toolkit for building gpui apps
rust
gpui
0
fork
atom
overview
issues
pulls
pipelines
clean up gpuikit
iamnbutler
3 months ago
7948dcd1
e9af1cfd
+52
-266
3 changed files
expand all
collapse all
unified
split
crates
gpuikit
src
error.rs
layout.rs
lib.rs
+30
crates/gpuikit/src/error.rs
···
1
1
+
use std::fmt;
2
2
+
3
3
+
/// General GPUIKit error type
4
4
+
#[derive(Debug)]
5
5
+
pub enum Error {
6
6
+
/// Theme not found
7
7
+
ThemeNotFound(String),
8
8
+
/// Asset not found
9
9
+
AssetNotFound(String),
10
10
+
/// Invalid configuration
11
11
+
InvalidConfig(String),
12
12
+
/// Other error with message
13
13
+
Other(String),
14
14
+
}
15
15
+
16
16
+
impl fmt::Display for Error {
17
17
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18
18
+
match self {
19
19
+
Error::ThemeNotFound(name) => write!(f, "Theme not found: {}", name),
20
20
+
Error::AssetNotFound(path) => write!(f, "Asset not found: {}", path),
21
21
+
Error::InvalidConfig(msg) => write!(f, "Invalid configuration: {}", msg),
22
22
+
Error::Other(msg) => write!(f, "Error: {}", msg),
23
23
+
}
24
24
+
}
25
25
+
}
26
26
+
27
27
+
impl std::error::Error for Error {}
28
28
+
29
29
+
/// Result type alias for GPUIKit operations
30
30
+
pub type Result<T> = std::result::Result<T, Error>;
+13
crates/gpuikit/src/layout.rs
···
1
1
+
use gpui::*;
2
2
+
3
3
+
pub fn h_stack() -> Div {
4
4
+
div().flex()
5
5
+
}
6
6
+
7
7
+
pub fn v_stack() -> Div {
8
8
+
div().flex().flex_col()
9
9
+
}
10
10
+
11
11
+
pub fn centered(child: impl IntoElement) -> Div {
12
12
+
div().flex().items_center().justify_center().child(child)
13
13
+
}
+9
-266
crates/gpuikit/src/lib.rs
···
4
4
pub use gpuikit_theme as theme;
5
5
pub use gpuikit_utils as utils;
6
6
7
7
-
// Re-export commonly used types from theme
8
8
-
pub use theme::{
9
9
-
BorderStyle, Shadow, Spacing, Theme, ThemeAppearance, ThemeColors, ThemeManager, ThemeMetadata,
10
10
-
Typography,
11
11
-
};
12
12
-
13
13
-
// Re-export commonly used types from assets
14
14
-
pub use assets::{AssetManager, EmbeddedAssetSource, EmbeddedAssets};
15
15
-
16
16
-
// Re-export commonly used utilities
17
17
-
pub use utils::{
18
18
-
geometry::{center_rect, expand_bounds, point_in_bounds},
19
19
-
string::{truncate_string, wrap_text},
20
20
-
task::{debounce, throttle},
21
21
-
};
7
7
+
pub mod error;
8
8
+
pub mod layout;
22
9
23
23
-
/// Prelude module for convenient imports
24
24
-
pub mod prelude {
25
25
-
pub use crate::assets::{AssetManager, EmbeddedAssets};
26
26
-
pub use crate::theme::{Theme, ThemeAppearance, ThemeManager};
27
27
-
pub use crate::utils::{center_rect, point_in_bounds};
28
28
-
29
29
-
// Re-export gpui for convenience
30
30
-
pub use gpui;
31
31
-
}
32
32
-
33
33
-
/// UI Components module
34
34
-
pub mod components {
35
35
-
//! Pre-built UI components for GPUI applications
36
36
-
//!
37
37
-
//! This module will contain reusable UI components like buttons,
38
38
-
//! inputs, panels, etc. Currently being developed.
39
39
-
40
40
-
use crate::theme::Theme;
41
41
-
use gpui::*;
42
42
-
43
43
-
/// Button component (placeholder for future implementation)
44
44
-
#[allow(dead_code)]
45
45
-
pub struct Button {
46
46
-
label: SharedString,
47
47
-
theme: Theme,
48
48
-
}
49
49
-
50
50
-
/// Input field component (placeholder for future implementation)
51
51
-
#[allow(dead_code)]
52
52
-
pub struct Input {
53
53
-
placeholder: Option<SharedString>,
54
54
-
theme: Theme,
55
55
-
}
56
56
-
57
57
-
/// Panel component (placeholder for future implementation)
58
58
-
#[allow(dead_code)]
59
59
-
pub struct Panel {
60
60
-
theme: Theme,
61
61
-
}
62
62
-
}
63
63
-
64
64
-
/// Styling utilities and helpers
65
10
pub mod style {
66
66
-
//! Styling utilities for consistent component appearance
67
67
-
68
11
use crate::theme::Theme;
69
69
-
use gpui::*;
70
12
71
71
-
/// Apply theme colors to an element
72
13
pub trait Themed {
73
73
-
/// Apply theme styling
74
14
fn themed(self, theme: &Theme) -> Self;
75
15
}
76
16
77
77
-
/// Get the appropriate text color for a background
78
78
-
pub fn contrast_color(background: Hsla) -> Hsla {
79
79
-
if background.l > 0.5 {
80
80
-
// Light background, use dark text
81
81
-
hsla(0.0, 0.0, 0.13, 1.0)
82
82
-
} else {
83
83
-
// Dark background, use light text
84
84
-
hsla(0.0, 0.0, 0.91, 1.0)
85
85
-
}
86
86
-
}
87
87
-
88
88
-
/// Create a focus ring style
89
89
-
pub fn focus_ring(theme: &Theme) -> BoxStyle {
90
90
-
BoxStyle {
91
91
-
border_color: Some(theme.colors.primary.shade_500),
92
92
-
border_width: Some(px(2.0)),
93
93
-
..Default::default()
94
94
-
}
95
95
-
}
96
96
-
97
97
-
/// Box styling helper
98
98
-
#[derive(Debug, Clone, Default)]
99
99
-
pub struct BoxStyle {
100
100
-
/// Background color
101
101
-
pub background: Option<Hsla>,
102
102
-
/// Border color
103
103
-
pub border_color: Option<Hsla>,
104
104
-
/// Border width
105
105
-
pub border_width: Option<Pixels>,
106
106
-
/// Border radius
107
107
-
pub border_radius: Option<Pixels>,
108
108
-
/// Padding
109
109
-
pub padding: Option<Pixels>,
110
110
-
}
111
111
-
}
112
112
-
113
113
-
/// Layout utilities and helpers
114
114
-
pub mod layout {
115
115
-
//! Layout utilities for positioning and sizing elements
116
116
-
117
117
-
use gpui::*;
118
118
-
119
119
-
/// Stack layout direction
120
120
-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
121
121
-
pub enum StackDirection {
122
122
-
/// Horizontal (row) layout
123
123
-
Horizontal,
124
124
-
/// Vertical (column) layout
125
125
-
Vertical,
126
126
-
}
127
127
-
128
128
-
/// Alignment options
129
129
-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
130
130
-
pub enum Alignment {
131
131
-
/// Start alignment
132
132
-
Start,
133
133
-
/// Center alignment
134
134
-
Center,
135
135
-
/// End alignment
136
136
-
End,
137
137
-
/// Stretch to fill
138
138
-
Stretch,
139
139
-
/// Space between items
140
140
-
SpaceBetween,
141
141
-
/// Space around items
142
142
-
SpaceAround,
143
143
-
/// Space evenly
144
144
-
SpaceEvenly,
145
145
-
}
146
146
-
147
147
-
/// Create a flex container with common settings
148
148
-
pub fn flex_container(direction: StackDirection, gap: Pixels) -> Div {
149
149
-
let mut container = div();
150
150
-
151
151
-
match direction {
152
152
-
StackDirection::Horizontal => {
153
153
-
container = container.flex_row();
154
154
-
}
155
155
-
StackDirection::Vertical => {
156
156
-
container = container.flex_col();
157
157
-
}
158
158
-
}
159
159
-
160
160
-
container.gap(gap)
161
161
-
}
162
162
-
163
163
-
/// Center an element within its container
164
164
-
pub fn center(child: impl IntoElement) -> Div {
165
165
-
div().flex().items_center().justify_center().child(child)
166
166
-
}
167
167
-
}
168
168
-
169
169
-
/// Animation utilities
170
170
-
pub mod animation {
171
171
-
//! Animation and transition utilities
172
172
-
173
173
-
use std::time::Duration;
174
174
-
175
175
-
/// Standard animation durations
176
176
-
pub struct Durations;
177
177
-
178
178
-
impl Durations {
179
179
-
/// Fast animation (150ms)
180
180
-
pub const FAST: Duration = Duration::from_millis(150);
181
181
-
/// Normal animation (250ms)
182
182
-
pub const NORMAL: Duration = Duration::from_millis(250);
183
183
-
/// Slow animation (350ms)
184
184
-
pub const SLOW: Duration = Duration::from_millis(350);
185
185
-
}
186
186
-
187
187
-
/// Easing functions for animations
188
188
-
pub mod easing {
189
189
-
/// Linear easing
190
190
-
pub fn linear(t: f32) -> f32 {
191
191
-
t
192
192
-
}
193
193
-
194
194
-
/// Ease in (accelerate)
195
195
-
pub fn ease_in(t: f32) -> f32 {
196
196
-
t * t
197
197
-
}
198
198
-
199
199
-
/// Ease out (decelerate)
200
200
-
pub fn ease_out(t: f32) -> f32 {
201
201
-
t * (2.0 - t)
202
202
-
}
203
203
-
204
204
-
/// Ease in-out (accelerate then decelerate)
205
205
-
pub fn ease_in_out(t: f32) -> f32 {
206
206
-
if t < 0.5 {
207
207
-
2.0 * t * t
208
208
-
} else {
209
209
-
-1.0 + (4.0 - 2.0 * t) * t
210
210
-
}
211
211
-
}
212
212
-
}
213
213
-
}
214
214
-
215
215
-
/// Error types for GPUIKit
216
216
-
pub mod error {
217
217
-
//! Error types used throughout GPUIKit
218
218
-
219
219
-
use std::fmt;
220
220
-
221
221
-
/// General GPUIKit error type
222
222
-
#[derive(Debug)]
223
223
-
pub enum Error {
224
224
-
/// Theme not found
225
225
-
ThemeNotFound(String),
226
226
-
/// Asset not found
227
227
-
AssetNotFound(String),
228
228
-
/// Invalid configuration
229
229
-
InvalidConfig(String),
230
230
-
/// Other error with message
231
231
-
Other(String),
232
232
-
}
233
233
-
234
234
-
impl fmt::Display for Error {
235
235
-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236
236
-
match self {
237
237
-
Error::ThemeNotFound(name) => write!(f, "Theme not found: {}", name),
238
238
-
Error::AssetNotFound(path) => write!(f, "Asset not found: {}", path),
239
239
-
Error::InvalidConfig(msg) => write!(f, "Invalid configuration: {}", msg),
240
240
-
Error::Other(msg) => write!(f, "Error: {}", msg),
241
241
-
}
242
242
-
}
243
243
-
}
244
244
-
245
245
-
impl std::error::Error for Error {}
246
246
-
247
247
-
/// Result type alias for GPUIKit operations
248
248
-
pub type Result<T> = std::result::Result<T, Error>;
249
249
-
}
250
250
-
251
251
-
// Version information
252
252
-
/// Current version of GPUIKit
253
253
-
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
254
254
-
255
255
-
/// Get version information
256
256
-
pub fn version() -> &'static str {
257
257
-
VERSION
258
258
-
}
259
259
-
260
260
-
#[cfg(test)]
261
261
-
mod tests {
262
262
-
use super::*;
263
263
-
264
264
-
#[test]
265
265
-
fn test_version() {
266
266
-
assert!(!version().is_empty());
267
267
-
}
268
268
-
269
269
-
#[test]
270
270
-
fn test_contrast_color() {
271
271
-
use gpui::hsla;
272
272
-
273
273
-
let light_bg = hsla(0.0, 0.0, 0.9, 1.0);
274
274
-
let dark_bg = hsla(0.0, 0.0, 0.1, 1.0);
275
275
-
276
276
-
let light_text = style::contrast_color(dark_bg);
277
277
-
let dark_text = style::contrast_color(light_bg);
278
278
-
279
279
-
assert!(light_text.l > dark_text.l);
280
280
-
}
17
17
+
// todo: is Themed useful?
18
18
+
//
19
19
+
// I could see most gpuikit components being something like:
20
20
+
//
21
21
+
// pub trait Component: IntoElement + Themed {}
22
22
+
//
23
23
+
// where Themed eventually gets more style helpers...
281
24
}