r2
Free open-source Cloudflare R2 desktop client and S3 GUI for macOS, Windows, and Linux. Manage Cloudflare R2, AWS S3, M…
rust webgpu ui
git clone https://github.com/shi-yan/AssortedWidgets.gitshi-yan/AssortedWidgets
A cross-platform GUI framework for Rust with first-class support for custom graphics and WebGPU rendering.
Add to your Cargo.toml:
[dependencies] assorted_widgets = "0.1"
use assorted_widgets::{Application, Widget};
use assorted_widgets::paint::{Color, ShapeStyle};
use assorted_widgets::text::TextStyle;
use assorted_widgets::types::{Point, Rect, Size, WidgetId};
struct MyWidget {
id: WidgetId,
bounds: Rect,
}
impl Widget for MyWidget {
// Use the macro to implement boilerplate methods
assorted_widgets::impl_widget_essentials!();
fn paint(&self, ctx: &mut assorted_widgets::paint::PaintContext) {
// Draw a rectangle
ctx.draw_styled_rect(
self.bounds,
ShapeStyle::solid(Color::rgb(0.2, 0.4, 0.8)),
);
// Draw some text
let text_style = TextStyle::new()
.size(16.0)
.color(Color::WHITE);
ctx.draw_text(
"Hello, AssortedWidgets!",
&text_style,
Point::new(20.0, 20.0),
None,
);
}
}
fn main() {
// ✨ Clean ergonomic API - no pollster, no window ID juggling!
Application::launch(|app| {
app.spawn_window("Hello Widget", 800.0, 600.0, |window| {
let widget = MyWidget {
id: WidgetId::new(1),
bounds: Rect::new(Point::ZERO, Size::new(800.0, 600.0)),
};
window.set_main_widget(widget);
});
});
}
graph TB
subgraph "Application Layer"
A[Your App]
end
subgraph "Framework Layer"
B[Widget Manager<br/>Flat Hash Table]
C[Widget Tree<br/>Tree Structure]
D[Layout Manager<br/>Taffy]
E[Application<br/>Event Queue]
end
subgraph "Rendering Layer"
F[Paint Context<br/>Multi-Tiered]
G[Primitive Batcher<br/>Themed UI]
H[Text Renderer<br/>Glyph Atlas]
I[Raw WebGPU<br/>Custom Graphics]
end
subgraph "Platform Layer"
J[Window<br/>macOS/Linux/Win]
K[Input<br/>Mouse/Keyboard]
L[WebGPU Surface]
end
A --> B
A --> C
B --> D
C --> D
D --> E
E --> F
F --> G
F --> H
F --> I
G --> L
H --> L
I --> L
J --> E
K --> E
Loading
AssortedWidgets supports high-level themed UI primitives:
impl Widget for MyWidget {
fn paint(&self, ctx: &mut PaintContext) {
// Solid and styled rectangles
ctx.draw_styled_rect(
self.bounds,
ShapeStyle::solid(Color::rgb(0.2, 0.2, 0.25))
.with_corner_radius(8.0)
.with_border(2.0, Color::rgb(0.4, 0.4, 0.5)),
);
// Text rendering
ctx.draw_text(pos, "Hello", Color::WHITE, 16.0);
// Vector paths
ctx.draw_line(start, end, Stroke::new(Color::RED, 2.0));
ctx.fill_path(path, Color::BLUE);
}
}
AssortedWidgets uses a three-system architecture internally:
All three systems are hidden behind a clean Window API:
// Qt-style implicit root container (recommended)
window.set_root_layout(taffy::Style {
display: Display::Flex,
flex_direction: FlexDirection::Column,
gap: taffy::Size {
width: taffy::LengthPercentage::length(10.0),
height: taffy::LengthPercentage::length(10.0),
},
..Default::default()
});
// Add widgets as children of the root container
let widget_id = window.add_to_root(widget, style)?;
// Or add as child of another widget
let child_id = window.add_child(widget, style, parent_id)?;
// Floating widgets (tooltips, modals) skip layout
let tooltip_id = window.add_floating(parent_id, tooltip_widget)?;
Layout is handled by Taffy, supporting Flexbox and CSS Grid:
// Parent determines child size (split view)
let parent_style = Style {
display: Display::Flex,
size: Size { width: 800px, height: 600px },
..Default::default()
};
let child_style = Style {
flex_grow: 1.0,
flex_basis: Dimension::Points(0.0),
..Default::default()
};
// Child determines parent size (auto-sizing text)
let text_style = Style {
size: Size { width: Auto, height: Auto },
..Default::default()
};
// Measure function provides intrinsic text size
AssortedWidgets uses a smart resource sharing model to optimize memory and performance:
// Shared across all windows (Arc<RenderContext>)
pub struct RenderContext {
// GPU Resources
device: Arc<wgpu::Device>,
queue: Arc<wgpu::Queue>,
// Shared Pipelines (Created Once, Reused by All Windows)
rect_pipeline: RectPipeline,
text_pipeline: TextPipeline,
surface_format: wgpu::TextureFormat,
// Shared Rendering Resources
glyph_atlas: Arc<Mutex<GlyphAtlas>>, // Single atlas for all windows
font_system: Arc<Mutex<FontSystemWrapper>>, // Font loading
text_engine: Arc<Mutex<TextEngine>>, // Text shaping cache
}
// Per-window resources reference shared pipelines
pub struct WindowRenderer {
surface: wgpu::Surface<'static>,
rect_uniform_buffer: wgpu::Buffer, // Screen size (per-window)
text_uniform_buffer: wgpu::Buffer, // Screen size (per-window)
render_context: Arc<RenderContext>, // Shared pipelines + atlas + fonts
// ...
}
// GlyphKey includes scale_factor for multi-DPI support
pub struct GlyphKey {
font_id: usize,
size_bits: u32,
character: char,
scale_factor: u8, // 100 = 1.0x, 200 = 2.0x (Retina)
}
// Benefits:
// - Pipelines created once, not duplicated per window (5 windows = 1× creation)
// - Single atlas (~16MB) instead of per-window duplication (~80MB for 5 windows)
// - Window moves between displays? Both 1x and 2x glyphs cached simultaneously
// - Font system initialized once, shared across all windows
Themes are read-only configuration structs uploaded to GPU:
pub struct Theme {
pub background: Color,
pub foreground: Color,
pub primary: Color,
pub text: Color,
pub font_size: f32,
pub padding: f32,
// ...
}
// Toggle theme = single uniform buffer update
// All shaders + UI elements update automatically
See the examples/ directory:
cube_3d_demo.rs - 3D rotating cube with low-level WebGPU RenderPass access ⭐ NEW!phase4_paths_test.rs - Vector graphics with lines, curves, and pathsicons_and_images.rs - Icon and image rendering demoicon_visual_demo.rs - Visual icon demonstrationime_demo.rs - Input Method Editor and focus testingRun an example:
cargo run --example cube_3d_demo
| Platform | Status | Notes |
|---|---|---|
| macOS | ✅ Implemented | 10.15+, Metal backend |
| Linux | 🚧 Planned | Wayland + X11 |
| Windows | 🚧 Planned | Win32 API |
| Web | 🔮 Future | WASM + WebGPU |
Tier 2 Rendering - Low-Level WebGPU Access:
register_custom_render()Phase 4 Complete - Vector Graphics:
Phase 3 Complete - Rendering Infrastructure:
Contributions welcome! See CONTRIBUTING.md for guidelines.
MIT OR Apache-2.0
more like this
Free open-source Cloudflare R2 desktop client and S3 GUI for macOS, Windows, and Linux. Manage Cloudflare R2, AWS S3, M…
search projects, people, and tags