add window icon

This commit is contained in:
Chance 2025-04-03 01:37:53 -04:00 committed by BitSyndicate
parent d8e6baebf1
commit 841ff739dd
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 443E4198D6BBA6DE
13 changed files with 659 additions and 113 deletions

View file

@ -1,21 +1,26 @@
use std::env;
use std::fs;
use std::io::Cursor;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
use ctx::{Renderer, Vertex};
use winit::dpi::LogicalSize;
use winit::dpi::Size;
use std::env;
use std::fs;
use std::path::PathBuf;
use image::ImageDecoder;
use image::ImageFormat;
use tobj::Mesh;
use tobj::{LoadOptions, Model};
use tracing::{debug, error, info, trace, warn};
use wgpu::rwh::HasWindowHandle;
use winit::application::ApplicationHandler;
use winit::dpi::LogicalSize;
use winit::dpi::Size;
use winit::event::{KeyEvent, WindowEvent};
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
use winit::monitor::MonitorHandle;
use winit::platform::windows::WindowAttributesExtWindows;
use winit::window::Fullscreen;
use winit::window::Icon;
use winit::window::Window;
use winit::window::WindowId;
@ -90,7 +95,14 @@ f 6/11/6 5/10/6 1/1/6 2/13/6
impl App<'_> {
fn create_main_window(&mut self, event_loop: &ActiveEventLoop) {
let win_attr = Window::default_attributes().with_title("Zenyx").with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)));
let icon = self.load_icon_from_bytes(Self::ICON).unwrap();
let win_attr = Window::default_attributes()
.with_title("Zenyx")
.with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)))
.with_window_icon(icon.clone())
.with_taskbar_icon(icon);
match event_loop.create_window(win_attr) {
Ok(window) => {
let window = Arc::new(window);
@ -160,7 +172,7 @@ impl App<'_> {
) {
if !key_event.state.is_pressed() || key_event.repeat {
return;
}
}
match key_event.physical_key {
winit::keyboard::PhysicalKey::Code(code) => match code {
winit::keyboard::KeyCode::Space => {
@ -199,6 +211,7 @@ impl App<'_> {
warn!("No window context for toggling background: {:?}", window_id);
}
}
fn toggle_fullscreen(&mut self, window_id: WindowId) {
if let Some(ctx) = self.windows.get_mut(&window_id) {
let is_fullscreen = ctx.window.fullscreen().is_some();
@ -216,13 +229,43 @@ impl App<'_> {
warn!("No window found for fullscreen toggle: {:?}", window_id);
}
}
fn load_icon_from_bytes(&self, bytes: &[u8]) -> Result<Option<Icon>, String> {
const IMAGE_DIR: &str = env!("CARGO_MANIFEST_DIR");
let cursor = Cursor::new(bytes);
let format = image::guess_format(bytes).map_err(|_| "Failed to guess image format")?;
let decoder = match format {
ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor).map_err(|e| format!("Failed to decode PNG: {}", e))?,
_ => {
let img = image::load_from_memory(bytes).map_err(|e| format!("Failed to load image: {}", e))?.into_rgba8();
let (width, height) = img.dimensions();
return Icon::from_rgba(img.into_raw(), width, height)
.map(Some)
.map_err(|e| format!("Failed to create icon from bytes: {}", e));
}
};
let (width, height) = decoder.dimensions();
let mut image_data = vec![0; decoder.total_bytes() as usize];
decoder.read_image(&mut image_data).map_err(|e| format!("Failed to read image data: {}", e))?;
Icon::from_rgba(image_data, width, height)
.map(Some)
.map_err(|e| format!("Failed to create icon from bytes: {}", e))
}
const ICON: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png"));
fn spawn_child_window(&mut self, event_loop: &ActiveEventLoop) {
if let Some(main_ctx) = self.windows.values().find(|ctx| ctx.is_main_window()) {
let title = format!("Zenyx - New Window {}", self.windows.len());
// TODO: Verify that this is safe instead of matching on it
let icon = self.load_icon_from_bytes(Self::ICON).unwrap();
let win_attr = unsafe {
let base = Window::default_attributes().with_title(title).with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)));
let base = Window::default_attributes()
.with_title(title)
.with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0)))
.with_window_icon(icon.clone())
.with_taskbar_icon(icon);
match main_ctx.window_handle() {
Ok(handle) => {
if !cfg!(target_os = "windows") {
@ -230,11 +273,11 @@ impl App<'_> {
} else {
base
}
},
}
Err(e) => {
error!("{e}");
base
},
}
}
};
match event_loop.create_window(win_attr) {