mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
## What The native app now draws its own window chrome, laid out like the Claude desktop app. - **Custom title bar** (40 px) replaces the native frame: - Left: the ArtCraft mark (goes Home) and the sidebar toggle. - Right: credits, the account menu or Sign in, then minimize, maximize/restore and close. - Dragging the empty space moves the window; a double-click maximizes. - On macOS the traffic lights stay, with room left for them. - **Sidebar** is flush with the window's left edge, on the darker chrome, with no floating card. - **Content panel** is inset 8 px from the window edges, with rounded corners and a hairline border. Its header holds the breadcrumbs and the select and grid/list toggles. - **Borderless window**: the edges and corners resize it, and a hairline outlines it (hidden when maximized). ## Notes - The window chrome helpers (`ui/window.rs`) are ported from the ArtCraft Launcher, which uses the same egui 0.36. - The mark is the in-repo `services/artcraft.svg`, tinted brand blue. The old wordmark loader is removed. - Toasts are moved down to sit below the new header. ## Testing - `cargo test -p artcraft_native`: 29 tests pass. - `cargo clippy -p artcraft_native --all-targets --no-deps` is clean. - Screenshot-verified against a live account. - Not tested by hand: dragging, resizing and the caption buttons. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
36 lines
1.4 KiB
Rust
36 lines
1.4 KiB
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
|
|
//! ArtCraft, natively: an egui desktop app over the ArtCraft API (no Tauri, no webview).
|
|
|
|
mod app;
|
|
mod backend;
|
|
mod feed;
|
|
mod models;
|
|
mod overlays;
|
|
mod pages;
|
|
mod prompt_box;
|
|
mod shell;
|
|
mod theme;
|
|
mod ui;
|
|
|
|
const APP_ID: &str = "ai.artcraft.native";
|
|
|
|
fn main() -> eframe::Result {
|
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
|
let mut viewport = egui::ViewportBuilder::default().with_title("ArtCraft").with_app_id(APP_ID).with_inner_size([1440.0, 900.0]).with_min_inner_size([960.0, 640.0]);
|
|
if let Some(icon) = app_icon() {
|
|
viewport = viewport.with_icon(icon);
|
|
}
|
|
// The app draws its own title bar; macOS keeps its traffic lights over it.
|
|
viewport = if cfg!(target_os = "macos") { viewport.with_fullsize_content_view(true).with_titlebar_shown(false).with_title_shown(false) } else { viewport.with_decorations(false) };
|
|
let options = eframe::NativeOptions { viewport, persist_window: true, ..Default::default() };
|
|
eframe::run_native("ArtCraft", options, Box::new(|cc| Ok(Box::new(app::ArtcraftApp::new(cc)))))
|
|
}
|
|
|
|
/// The window and taskbar icon.
|
|
fn app_icon() -> Option<egui::IconData> {
|
|
const ICON: &[u8] = include_bytes!("../../crates/desktop/artcraft/icons/icon.png");
|
|
let rgba = image::load_from_memory(ICON).ok()?.into_rgba8();
|
|
Some(egui::IconData { width: rgba.width(), height: rgba.height(), rgba: rgba.into_raw() })
|
|
}
|