egui-macview
Native-style macOS AppKit controls, layouts, and smooth spring animations for egui on Windows, macOS, Linux, and Web.
Why egui-macview?
Standard egui is great for quick tools and game overlays, but building a desktop application that feels like a native macOS app (such as Xcode, Final Cut Pro, Finder, or System Settings) requires predictable widget dimensions, crisp 1px borders, keyboard navigation, and smooth animations.
egui-macview gives you a ready-to-use library of 35+ macOS AppKit and AVKit controls built directly on egui 0.37:
- Measured on real macOS hardware: Control heights, padding insets, corner radii, and colors are measured directly from macOS Sonoma (
AppKitandAVKit) so your UI looks right out of the box. - Light, Dark, and Anthracite themes: Switch seamlessly between
MacAppearance::Aqua(Light),MacAppearance::DarkAqua(Dark), andMacAppearance::Anthracite, with automatic WCAG contrast handling for custom accent colors. - Battery-friendly by design: Zero background repaints when idle, automatic animation pausing when the window is unfocused or minimized, and 2D viewport culling for large tables and grids.
- Cross-platform vector icons: Includes an embedded
CupertinoIconsTrueType font so symbols look identical on Windows, macOS, Linux, and Web without relying on OS emojis.
Installation
Add egui-macview to your Cargo.toml:
[]
= "0.37.0"
= "0.6.3"
To run the interactive showcase gallery included in this repository:
Your First App in 60 Seconds (eframe)
Here is a complete, runnable desktop application (src/main.rs) with a macOS window toolbar, a resizable sidebar split view, and a two-column settings form:
use egui;
use ;
Quick Start & Copy-Paste Examples
Every control in egui-macview works with standard egui::Ui and optionally accepts a [MacTheme]. If you call theme.apply_to_egui(ctx) once when your app starts (or when the theme changes), widgets will automatically pick up your active theme even if you omit .theme(&theme).
1. Theme Setup, Buttons, Toggles & Segmented Controls
use ;
# let ctx = default;
// Call once at startup to register the monochrome Cupertino vector icon font:
let mut fonts = default;
setup_symbols_font;
ctx.set_fonts;
// Create a macOS theme (Aqua for Light mode, DarkAqua for Dark mode)
let theme = new;
theme.apply_to_egui;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
2. Forms, Text Inputs, Search Fields, Sliders & Steppers
Use [MacForm] for clean two-column macOS preference panes with right-aligned labels and left-aligned controls:
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
3. Dropdowns & Searchable Combo Boxes (MacComboBox & MacPopUpButton)
Use [MacPopUpButton] when the user picks from a fixed list, or [MacComboBox] when they can both type to filter and pick from a dropdown list:
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
4. Date & Time Picker (MacDatePicker)
[MacDatePicker] supports both a compact text field with an integrated stepper (TextFieldAndStepper, where users can click year/month/day segments and use arrow keys) and a visual month calendar grid with an analog clock (ClockAndCalendar):
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
5. Layout Containers: Tabs, Collapsible Disclosure Groups, Boxes & Split Views
Organize complex inspector panels and multi-pane windows with [MacTabView], [MacDisclosureGroup], [MacBox], and [MacSplitView]:
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
6. Data Views: Multi-Column Tables, 2D Grids, Breadcrumb Path Bars & Rule Editors
Render large datasets smoothly with [MacTableView] and [MacCollectionView] (both use viewport culling so off-screen rows/tiles cost zero CPU time):
use BTreeSet;
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
7. Media Player Overlay, Timeline Scrubber, Audio Meters & Rotary Dials
Build audio/video players and studio interfaces with [MacPlayerView], [MacTrimScrubber], [MacLevelIndicator], [MacCircularSlider], and [MacRatingIndicator]:
use ;
# let ctx = default;
# let mut output = ctx.run_ui;
# output.textures_delta.clear;
Component Reference
Layout Containers (src/layout/ & src/controls/)
| Component | macOS AppKit Equivalent | What It Does |
|---|---|---|
[MacSplitView] |
NSSplitView |
Resizable two-pane split container with min/max size constraints. |
[MacStackView] |
NSStackView |
Horizontal or vertical linear stack with consistent spacing and optional dividers. |
[MacScrollView] |
NSScrollView |
Scroll container with overlay scrollbars that fade out when idle. |
[MacForm] |
NSGridView / Form |
Two-column form layout with right-aligned labels and left-aligned controls. |
[MacRow] |
Auto-Layout Row | Single-line horizontal row that distributes width cleanly across child cells. |
[MacFixedView] |
Retained Frame | Fixed-size coordinate container that prevents child widgets from overflowing. |
[MacBox] |
NSBox |
Grouped border box with an optional title and standard horizontal separator. |
[MacTabView] |
NSTabView |
Tabbed container supporting top segmented tabs (TopTabsBezelBorder) or borderless pages. |
[MacDisclosureGroup] |
NSButton Disclosure |
Collapsible section with an animated rotating disclosure triangle (CASpring). |
Controls & Data Views (src/controls/)
| Component | macOS AppKit Equivalent | What It Does |
|---|---|---|
[MacButton] / [MacButtonCell] |
NSButton |
Push buttons, default action blue buttons, checkboxes, radio buttons, and icon buttons. |
[MacToggle] |
NSSwitch |
Animated pill switch with system green active fill. |
[MacSegmentedControl] |
NSSegmentedControl |
Multi-segment pill switcher with a sliding selection thumb. |
[MacInputCell] |
NSTextField |
Single-line text and numeric input with focus ring, Tab cycling, Enter commit, and Escape cancel. |
[MacSearchField] |
NSSearchField |
Search input with leading magnifying glass icon and trailing clear (×) button. |
[MacComboBox] |
NSComboBox |
Editable text field combined with a filterable dropdown list (Alt+Down, arrow keys, Enter). |
[MacPopUpButton] |
NSPopUpButton |
Dropdown menu button with double-chevron indicator and screen-clamped popover. |
[MacSlider] |
NSSlider (Linear) |
Horizontal slider with optional tick marks and keyboard arrow stepping. |
[MacCircularSlider] |
NSSlider (Circular) |
Rotary dial knob with drag tracking, angle indicator, and spring feedback. |
[MacStepper] |
NSStepper |
Up/down numeric increment buttons with range clamping. |
[MacDatePicker] |
NSDatePicker |
Date and time selector supporting both inline stepper fields and a month calendar + analog clock. |
[MacColorWell] |
NSColorWell |
Color swatch button with alpha checkerboard preview and popover color picker. |
[MacProgressIndicator] |
NSProgressIndicator |
Determinate/indeterminate progress bars and 12-spoke spinning activity indicators. |
[MacLevelIndicator] |
NSLevelIndicator |
Continuous or discrete audio/capacity meter with green/yellow/red thresholds and peak hold. |
[MacRatingIndicator] |
NSLevelIndicator (Rating) |
Interactive 5-star rating widget with optional half-star precision. |
[MacTokenField] |
NSTokenField |
Tag input that turns comma- or Enter-separated words into removable capsule pills. |
[MacPathControl] |
NSPathControl |
Interactive folder/file breadcrumb bar with clickable segments. |
[MacOutlineView] |
NSOutlineView |
Collapsible tree view for sidebars and hierarchical lists. |
[MacTableView] |
NSTableView |
Multi-column sortable table with alternating row fills, multi-selection, and viewport culling. |
[MacCollectionView] |
NSCollectionView |
2D grid view with flow layout, rubber-band marquee selection, arrow-key navigation, and viewport culling. |
[MacRuleEditor] |
NSRuleEditor |
Multi-row predicate filter builder with criterion pills and [+] / [-] row buttons. |
[MacPlayerView] |
AVPlayerView |
Media player transport overlay supporting Floating HUD pod, Inline bar, and Minimal styles. |
[MacTrimScrubber] |
AVPlayerView Trim Bar |
QuickTime-style timeline scrubber with waveform preview, yellow In/Out trim handles, and timecode badge. |
Navigation, Surfaces & State (src/navigation/, src/surfaces/, src/state/)
| Component | macOS AppKit Equivalent | What It Does |
|---|---|---|
[MacToolbar] |
NSToolbar |
Window titlebar with traffic light buttons (or Windows caption buttons), drag-to-move, and double-click maximize. |
[MacMenuBar] |
NSMenu |
Top menu bar with cascading submenus and keyboard shortcut handling. |
[MacCommandPalette] |
Spotlight Overlay | ⌘K / Ctrl+K modal command search bar with fuzzy matching. |
[MacCanvasFooter] |
Status Bar | 24 pt bottom status bar with breadcrumbs, cursor coordinates, and zoom presets. |
[MacContextMenu] |
Context Menu | Right-click popup menu clamped to the window bounds. |
[MacToastManager] |
HUD Notification | Non-blocking toast banners with spring entry/exit animations. |
[MacPanel] / [MacPopover] |
NSPanel / NSPopover |
Floating translucent utility panels, inspector cards ([MacCard]), and compact HUD boxes ([MacFloatingInfoBox]). |
[NSUndoManager] |
NSUndoManager |
Bounded undo/redo history stack with duplicate-state filtering. |
When to Use Which Control (Decision Guide)
Not sure which widget fits your screen best? Use these guidelines modeled after Apple's macOS Human Interface Guidelines:
1. Choosing a Selection Control
| Control | Best For | Avoid When |
|---|---|---|
[MacSegmentedControl] |
Switching between 2 to 5 closely related views or modes (e.g., Grid | List | Columns) where all options should be visible at a glance. |
You have more than 5 options, or the labels are long phrases. Use [MacPopUpButton] instead. |
[MacPopUpButton] |
Picking one option from a fixed list of 5 to 20 items (e.g., file export format or color profile) where the user does not need to type custom values. | The list has dozens of items that need text filtering, or the user can enter a custom value. Use [MacComboBox] instead. |
[MacComboBox] |
Picking from a searchable list OR typing a custom value (e.g., choosing a font family or entering a custom zoom preset). | The user must only pick from a small, strictly fixed set of options. Use [MacPopUpButton] instead. |
2. Choosing a Data View
| Control | Best For | Avoid When |
|---|---|---|
[MacTableView] |
Displaying structured records with multiple attributes (e.g., Name, Date Modified, Size) that users sort by column header or navigate row-by-row. | Items are primarily visual (thumbnails, icons, color swatches). Use [MacCollectionView] instead. |
[MacOutlineView] |
Navigating hierarchical trees (e.g., folder trees, document outlines, scene graphs, or sidebar navigation) with collapsible parent nodes. | Your data is flat and has no parent-child hierarchy. Use [MacTableView] instead. |
[MacCollectionView] |
Browsing visual 2D grids of tiles (e.g., photo galleries, icon pickers, asset browsers) with rubber-band marquee selection and 2D arrow-key navigation. | Users need to compare text or numbers across multiple columns. Use [MacTableView] instead. |
3. Choosing a Layout Container
| Container | Best For | Avoid When |
|---|---|---|
[MacSplitView] |
Dividing a window into resizable workspace panes (e.g., a left navigation sidebar, a center canvas, and a right inspector). | Grouping small related controls inside a single pane. Use [MacBox] or [MacForm] instead. |
[MacTabView] |
Switching an entire pane between peer pages (e.g., General, Shortcuts, Export preference tabs) where only one page is visible at a time. |
Hiding optional advanced settings on the same page. Use [MacDisclosureGroup] instead. |
[MacDisclosureGroup] |
Toggling optional or advanced details inline so the user can expand multiple sections simultaneously. | Top-level window navigation. Use [MacTabView] or [MacSplitView] instead. |
[MacBox] |
Visually grouping a cluster of related fields under a subtle border and title label. | Aligning two-column Label: Control pairs. Put a [MacForm] inside the [MacBox] for alignment. |
4. Choosing a Numeric Input
| Control | Best For |
|---|---|
[MacSlider] |
Adjusting a continuous value within a bounded range (e.g., Opacity 0%–100% or Volume) where visual proportion matters more than exact digits. |
[MacStepper] |
Nudging an exact numeric value up or down by fixed increments (e.g., ±1 px border width or ±25% zoom) next to a readout or text field. |
[MacCircularSlider] |
Compact rotary dials in audio mixers, pan pots, or angle/rotation inspectors where vertical space is tight. |
[MacInputCell::numeric] |
Typing an exact number with keyboard arrow stepping (Up/Down for ±1×, Shift for ±10×, Cmd/Ctrl for ±100×) and Escape rollback. |
Troubleshooting & FAQ
1. Why do icons or symbols show up as empty boxes (□)?
egui-macview uses an embedded monochrome vector icon font (CupertinoIcons.ttf) so symbols render identically on Windows, macOS, Linux, and Web. You must register this font once on your egui::Context at startup:
use setup_symbols_font;
# let ctx = default;
let mut fonts = default;
setup_symbols_font;
ctx.set_fonts;
2. How do I switch dynamically between Light (Aqua), Dark (DarkAqua), and Anthracite themes?
Create a [MacTheme] with your chosen [MacAppearance] and call theme.apply_to_egui(ctx). Calling apply_to_egui updates egui's background visuals and stores the theme inside egui::Context so every egui-macview widget automatically uses it:
use ;
# let ctx = default;
let theme = new;
theme.apply_to_egui;
# let mut out = ctx.run_ui;
# out.textures_delta.clear;
3. How do I avoid widget ID collisions when rendering controls in a for loop?
Just like standard egui, stateful controls (MacComboBox, MacTableView, MacDisclosureGroup, MacInputCell, MacRuleEditor) use an ID salt to store popup or focus state across frames. When rendering multiple instances in a loop, either pass a unique tuple (name, index) as the ID salt or wrap each iteration in ui.push_id:
use MacComboBox;
# let ctx = default;
# let mut out = ctx.run_ui;
# out.textures_delta.clear;
4. How does battery-saving idle repaint work?
Immediate-mode GUIs often burn CPU and laptop battery by repainting at 60–120 FPS even when nothing is moving. egui-macview avoids this automatically:
- Spring animations (
CASpring) request repaints only while a transition is in flight. As soon as a toggle switch, segmented pill, or disclosure chevron settles at its target position, it stops requesting repaints (0% CPUat rest). - Floating media HUD (
MacPlayerView) schedules a single wakeup timer (request_repaint_after_secs) for its 3.0-second auto-hide instead of polling every frame. - Unfocused & minimized windows: Continuous animations (such as indeterminate progress spinners) check
is_window_active(ctx)andui.is_rect_visible(rect)and pause automatically when your app window is in the background or minimized.
Quality & Testing
Run the full test suite and linter with:
- 23 integration test suites and 60+ documentation tests verify widget layout, keyboard navigation, undo/redo roundtrips, WCAG contrast ratios, and zero idle CPU usage.
- Design token architecture: All dimensions, spacing, corner radii, and semantic colors live in
tokens/design_tokens.json([MacDesignTokens]) and are resolved through [MacTheme].
License
Dual-licensed under either of:
- Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (https://opensource.org/licenses/MIT)
at your option.