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.2"
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 50+ 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.jsonand are resolved through [MacTheme].
License
Dual-licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.