Hmmm. This is war
This commit is contained in:
parent
5e774c432e
commit
2c3e9b06c2
|
|
@ -20,6 +20,5 @@ iced_wgpu = "0.14"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
dirs = "6"
|
dirs = "6"
|
||||||
|
image = "0.25"
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
|
||||||
embed-resource = "3"
|
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,5 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(target_os = "windows")]
|
// Icon embedding via resource compilers (winres, embed-resource) doesn't
|
||||||
{
|
// work reliably with the gnullvm toolchain. The window icon is set at
|
||||||
use std::process::Command;
|
// runtime via winit instead — see app.rs.
|
||||||
|
|
||||||
let svg = "../assets/Acord.svg";
|
|
||||||
let ico = "icon.ico";
|
|
||||||
let rc = "icon.rc";
|
|
||||||
let tmp = "icon_tmp";
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed={svg}");
|
|
||||||
|
|
||||||
// Generate icon.ico from SVG via rsvg-convert + magick.
|
|
||||||
let _ = std::fs::create_dir_all(tmp);
|
|
||||||
let sizes = [16, 24, 32, 48, 64, 128, 256];
|
|
||||||
let mut pngs = Vec::new();
|
|
||||||
|
|
||||||
for size in sizes {
|
|
||||||
let out = format!("{tmp}/icon_{size}.png");
|
|
||||||
let s = size.to_string();
|
|
||||||
let ok = Command::new("rsvg-convert")
|
|
||||||
.args(["--width", &s, "--height", &s, svg, "-o", &out])
|
|
||||||
.status()
|
|
||||||
.map(|s| s.success())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if !ok {
|
|
||||||
println!("cargo:warning=rsvg-convert not found or failed — building without icon");
|
|
||||||
let _ = std::fs::remove_dir_all(tmp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pngs.push(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
let ok = Command::new("magick")
|
|
||||||
.args(pngs.iter().map(|s| s.as_str()))
|
|
||||||
.arg(ico)
|
|
||||||
.status()
|
|
||||||
.map(|s| s.success())
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
let _ = std::fs::remove_dir_all(tmp);
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
println!("cargo:warning=magick (ImageMagick) not found — building without icon");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write a .rc file and embed via embed-resource (supports LLVM/GNU toolchains).
|
|
||||||
std::fs::write(rc, "1 ICON \"icon.ico\"\n").ok();
|
|
||||||
embed_resource::compile(rc, embed_resource::NONE);
|
|
||||||
println!("cargo:warning=icon embedded successfully");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,9 +154,16 @@ impl ApplicationHandler for App {
|
||||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||||
if self.window.is_some() { return; }
|
if self.window.is_some() { return; }
|
||||||
|
|
||||||
let attrs = WindowAttributes::default()
|
let mut attrs = WindowAttributes::default()
|
||||||
.with_title("Acord")
|
.with_title("Acord")
|
||||||
.with_inner_size(LogicalSize::new(1100.0, 750.0));
|
.with_inner_size(LogicalSize::new(1100.0, 750.0));
|
||||||
|
|
||||||
|
// Load window icon from the bundled PNG (rasterized from SVG at build
|
||||||
|
// time or shipped alongside the exe). Falls back to no icon silently.
|
||||||
|
if let Some(icon) = load_window_icon() {
|
||||||
|
attrs = attrs.with_window_icon(Some(icon));
|
||||||
|
}
|
||||||
|
|
||||||
let window = event_loop.create_window(attrs).expect("create window");
|
let window = event_loop.create_window(attrs).expect("create window");
|
||||||
self.scale = window.scale_factor() as f32;
|
self.scale = window.scale_factor() as f32;
|
||||||
|
|
||||||
|
|
@ -363,3 +370,36 @@ fn decode_winit_modifiers(state: ModifiersState) -> iced_wgpu::core::keyboard::M
|
||||||
if state.control_key() { m |= iced_wgpu::core::keyboard::Modifiers::LOGO; }
|
if state.control_key() { m |= iced_wgpu::core::keyboard::Modifiers::LOGO; }
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load the app icon from `assets/Acord.svg` (relative to exe) or a
|
||||||
|
/// pre-rasterized PNG next to the exe. Returns None on any failure.
|
||||||
|
fn load_window_icon() -> Option<winit::window::Icon> {
|
||||||
|
// Try loading a PNG icon next to the exe first.
|
||||||
|
let exe_dir = std::env::current_exe().ok()?.parent()?.to_path_buf();
|
||||||
|
|
||||||
|
// Try pre-rasterized icon.png next to exe.
|
||||||
|
let png_path = exe_dir.join("icon.png");
|
||||||
|
let bytes = if png_path.exists() {
|
||||||
|
std::fs::read(&png_path).ok()?
|
||||||
|
} else {
|
||||||
|
// Fall back to the SVG in the assets dir (repo layout).
|
||||||
|
let svg_path = exe_dir.join("../assets/Acord.svg")
|
||||||
|
.canonicalize().ok()
|
||||||
|
.or_else(|| {
|
||||||
|
// Running from repo root via cargo run.
|
||||||
|
std::path::PathBuf::from("assets/Acord.svg").canonicalize().ok()
|
||||||
|
})?;
|
||||||
|
// Use rsvg-convert at runtime as a fallback.
|
||||||
|
let output = std::process::Command::new("rsvg-convert")
|
||||||
|
.args(["--width", "256", "--height", "256"])
|
||||||
|
.arg(&svg_path)
|
||||||
|
.output()
|
||||||
|
.ok()?;
|
||||||
|
if !output.status.success() { return None; }
|
||||||
|
output.stdout
|
||||||
|
};
|
||||||
|
|
||||||
|
let img = image::load_from_memory(&bytes).ok()?.into_rgba8();
|
||||||
|
let (w, h) = img.dimensions();
|
||||||
|
winit::window::Icon::from_rgba(img.into_raw(), w, h).ok()
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue