use slint::{ PlatformError, platform::{Platform, WindowAdapter}, }; use std::cell::{Cell, RefCell}; use std::rc::{Rc, Weak}; use crate::rendering::femtovg::main_window::FemtoVGWindow; use crate::rendering::femtovg::popup_window::PopupWindow; type PopupCreator = dyn Fn() -> Result, PlatformError>; thread_local! { static CURRENT_PLATFORM: RefCell>> = const { RefCell::new(None) }; } pub fn close_current_popup() { CURRENT_PLATFORM.with(|platform| { if let Some(weak_platform) = platform.borrow().as_ref() { if let Some(strong_platform) = weak_platform.upgrade() { strong_platform.close_current_popup(); } } }); } pub fn set_popup_position_override(x: f32, y: f32) { CURRENT_PLATFORM.with(|platform| { if let Some(weak_platform) = platform.borrow().as_ref() { if let Some(strong_platform) = weak_platform.upgrade() { strong_platform.set_popup_position(x, y); } } }); } #[must_use] pub fn get_popup_position_override() -> Option<(f32, f32)> { CURRENT_PLATFORM.with(|platform| { platform.borrow().as_ref() .and_then(Weak::upgrade) .and_then(|strong| strong.get_popup_position()) }) } pub fn clear_popup_position_override() { CURRENT_PLATFORM.with(|platform| { if let Some(weak_platform) = platform.borrow().as_ref() { if let Some(strong_platform) = weak_platform.upgrade() { strong_platform.clear_popup_position(); } } }); } pub struct CustomSlintPlatform { main_window: Weak, popup_creator: RefCell>>, first_call: Cell, last_popup: RefCell>>, popup_position: RefCell>, } impl CustomSlintPlatform { #[must_use] pub fn new(window: &Rc) -> Rc { let platform = Rc::new(Self { main_window: Rc::downgrade(window), popup_creator: RefCell::new(None), first_call: Cell::new(true), last_popup: RefCell::new(None), popup_position: RefCell::new(None), }); CURRENT_PLATFORM.with(|current| { *current.borrow_mut() = Some(Rc::downgrade(&platform)); }); platform } #[allow(dead_code)] pub fn set_popup_creator(&self, creator: F) where F: Fn() -> Result, PlatformError> + 'static, { *self.popup_creator.borrow_mut() = Some(Rc::new(creator)); } pub fn set_last_popup(&self, popup: &Rc) { *self.last_popup.borrow_mut() = Some(Rc::downgrade(popup)); } pub fn close_current_popup(&self) { if let Some(weak_popup) = self.last_popup.borrow().as_ref() { if let Some(popup) = weak_popup.upgrade() { popup.close_popup(); } } *self.last_popup.borrow_mut() = None; } pub fn set_popup_position(&self, x: f32, y: f32) { *self.popup_position.borrow_mut() = Some((x, y)); } #[must_use] pub fn get_popup_position(&self) -> Option<(f32, f32)> { *self.popup_position.borrow() } pub fn clear_popup_position(&self) { *self.popup_position.borrow_mut() = None; } } impl Platform for CustomSlintPlatform { fn create_window_adapter(&self) -> Result, PlatformError> { if self.first_call.get() { self.first_call.set(false); self.main_window .upgrade() .ok_or(PlatformError::NoPlatform) .map(|w| w as Rc) } else if let Some(creator) = self.popup_creator.borrow().as_ref() { creator() } else { Err(PlatformError::NoPlatform) } } }