use flatland_client_lib::{ClientConfig, GfxWindowPrefs};
use macroquad::prelude::Conf;
const DEFAULT_WIDTH: i32 = 1400;
const DEFAULT_HEIGHT: i32 = 900;
const MIN_WIDTH: u32 = 640;
const MIN_HEIGHT: u32 = 480;
pub fn window_conf() -> Conf {
let prefs = ClientConfig::load().gfx_window;
let (width, height) = prefs
.width
.zip(prefs.height)
.map(|(w, h)| (w as i32, h as i32))
.unwrap_or((DEFAULT_WIDTH, DEFAULT_HEIGHT));
Conf {
window_title: format!("Flatland3 gfx v{}", env!("CARGO_PKG_VERSION")),
window_width: width.max(MIN_WIDTH as i32),
window_height: height.max(MIN_HEIGHT as i32),
window_resizable: true,
high_dpi: false,
..Default::default()
}
}
pub fn apply_saved_position() {
let prefs = ClientConfig::load().gfx_window;
let (Some(x), Some(y)) = (prefs.x, prefs.y) else {
return;
};
set_window_position(x, y);
}
pub fn capture_window_geometry() -> GfxWindowPrefs {
let width = macroquad::window::screen_width().round().max(MIN_WIDTH as f32) as u32;
let height = macroquad::window::screen_height().round().max(MIN_HEIGHT as f32) as u32;
let (x, y) = window_position();
GfxWindowPrefs {
width: Some(width),
height: Some(height),
x,
y,
}
}
pub fn save_window_geometry(prefs: GfxWindowPrefs) {
if prefs.is_empty() {
return;
}
let mut cfg = ClientConfig::load();
if cfg.save_gfx_window(prefs).is_err() {
tracing::warn!("failed to save gfx window geometry");
}
}
fn set_window_position(x: u32, y: u32) {
#[cfg(target_os = "macos")]
macos::set_frame_origin(x, y);
#[cfg(any(target_os = "windows", target_os = "linux"))]
miniquad::window::set_window_position(x, y);
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
let _ = (x, y);
}
fn window_position() -> (Option<u32>, Option<u32>) {
#[cfg(target_os = "macos")]
{
return macos::frame_origin();
}
#[cfg(any(target_os = "windows", target_os = "linux"))]
{
let (x, y) = miniquad::window::get_window_position();
return (Some(x), Some(y));
}
#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))]
{
(None, None)
}
}
#[cfg(target_os = "macos")]
#[allow(deprecated)]
mod macos {
use cocoa::appkit::NSApp;
use cocoa::base::{id, nil};
use cocoa::foundation::NSRect;
use objc::{msg_send, sel};
pub fn frame_origin() -> (Option<u32>, Option<u32>) {
unsafe {
let Some(window) = main_window() else {
return (None, None);
};
let frame: NSRect = msg_send![window, frame];
(
Some(frame.origin.x.max(0.0) as u32),
Some(frame.origin.y.max(0.0) as u32),
)
}
}
pub fn set_frame_origin(x: u32, y: u32) {
unsafe {
let Some(window) = main_window() else {
return;
};
let mut frame: NSRect = msg_send![window, frame];
frame.origin.x = x as f64;
frame.origin.y = y as f64;
let _: () = msg_send![window, setFrameOrigin: frame.origin];
}
}
unsafe fn main_window() -> Option<id> {
let app: id = NSApp();
if app == nil {
return None;
}
let window: id = msg_send![app, mainWindow];
if window == nil {
return None;
}
Some(window)
}
}