use std::any::Any;
use std::fmt;
use std::rc::Rc;
use teksilo_canvas::{Point, Rect, Size};
use crate::widget_id::WidgetId;
use crate::window::TeksiloWindowId;
pub trait PlatformTitleBarHost {
fn reserved_leading_inset(&self) -> Size;
fn reserved_trailing_inset(&self) -> Size;
fn renders_custom_controls(&self) -> bool;
fn needs_custom_resize_handles(&self) -> bool;
fn begin_drag(&self) -> Result<(), PlatformError>;
fn begin_resize(&self, edge: ResizeEdge) -> Result<(), PlatformError>;
fn show_window_menu(&self, at: Point) -> Result<(), PlatformError>;
fn has_window_menu(&self) -> bool {
true
}
fn update_hit_regions(&self, regions: &HitRegions);
fn title_bar_widget_id(&self, _target: ControlTarget) -> Option<WidgetId> {
None
}
fn set_button_hover(&self, _target: ControlTarget, _entered: bool) {}
fn register_hover_signal(&self, _target: ControlTarget, _signal: crate::signal::Signal<bool>) {}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ControlTarget {
Minimize,
Maximize,
Close,
}
#[derive(Debug, Clone, Copy)]
pub struct TitleBarSyntheticEvent {
pub teksilo_id: TeksiloWindowId,
pub target: ControlTarget,
}
#[derive(Debug, Clone, Copy)]
pub struct TitleBarHoverEvent {
pub teksilo_id: TeksiloWindowId,
pub target: ControlTarget,
pub entered: bool,
}
#[derive(Clone)]
pub struct TitleBarHostCallbacks {
pub request_close: Rc<dyn Fn()>,
pub post_external: Rc<dyn Fn(Box<dyn Any + Send>)>,
pub teksilo_id: TeksiloWindowId,
}
impl TitleBarHostCallbacks {
pub fn noop() -> Self {
Self {
request_close: Rc::new(|| {}),
post_external: Rc::new(|_| {}),
teksilo_id: TeksiloWindowId::new(0),
}
}
}
impl fmt::Debug for TitleBarHostCallbacks {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TitleBarHostCallbacks")
.finish_non_exhaustive()
}
}
#[derive(Debug, Default, Clone)]
pub struct HitRegions {
pub minimize: Option<Rect>,
pub maximize: Option<Rect>,
pub close: Option<Rect>,
pub minimize_id: Option<WidgetId>,
pub maximize_id: Option<WidgetId>,
pub close_id: Option<WidgetId>,
pub drag: Vec<Rect>,
pub no_drag: Vec<Rect>,
pub resize_borders: ResizeBorders,
}
impl HitRegions {
pub fn new() -> Self {
Self::default()
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct ResizeBorders {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}
impl ResizeBorders {
pub const fn uniform(thickness: f32) -> Self {
Self {
top: thickness,
right: thickness,
bottom: thickness,
left: thickness,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResizeEdge {
Top,
TopLeft,
TopRight,
Left,
Right,
Bottom,
BottomLeft,
BottomRight,
}
#[derive(Debug, thiserror::Error)]
pub enum PlatformError {
#[error("operation not supported on this platform")]
Unsupported,
#[error("platform error: {0}")]
Os(String),
}