A ui toolkit for building gpui apps
rust gpui

clean up gpuikit

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