use crate::layout::docking::DockPanel;
use crate::layout::LayoutManager;
use crate::input::core::event_processor::PlatformEvent;
use super::builder::RgbaIcon;
use super::multi_window::{WindowCtx, WindowKey, WindowSpec};
use crate::platform::types::CornerStyle;
#[derive(Clone, Debug, Default)]
pub struct NoPanel;
impl DockPanel for NoPanel {
fn title(&self) -> &str { "" }
fn type_id(&self) -> &'static str { "no_panel" }
fn min_size(&self) -> (f32, f32) { (0.0, 0.0) }
fn closable(&self) -> bool { false }
}
pub trait App<P: DockPanel = NoPanel>: Sized + 'static {
fn init(&mut self, _key: &WindowKey, _layout: &mut LayoutManager<P>) {}
fn ui(&mut self, win: &mut WindowCtx<'_, P>);
fn regions(&mut self) -> Vec<crate::render::RenderRegion> {
Vec::new()
}
fn draw_region(&mut self, _region_id: &str, win: &mut WindowCtx<'_, P>) {
self.ui(win);
}
fn take_pending_spawn(&mut self) -> Option<WindowSpec> { None }
fn take_window_to_close(&mut self) -> Option<WindowKey> { None }
fn on_chrome_new_window(&mut self, _source_window: &WindowKey) -> Option<WindowSpec> {
None
}
fn on_event(&mut self, _event: &PlatformEvent) -> bool { false }
fn shutdown(&mut self) {}
fn on_dismiss(&mut self,
_layout: &mut LayoutManager<P>,
_overlay: crate::layout::OverlayHandle,
) {}
fn on_modal_close(&mut self,
_layout: &mut LayoutManager<P>,
_modal: crate::layout::ModalHandle,
) {}
fn on_modal_tab(&mut self,
_layout: &mut LayoutManager<P>,
_modal: crate::layout::ModalHandle,
_index: usize,
) {}
fn on_dropdown_item(&mut self,
_layout: &mut LayoutManager<P>,
_dropdown: crate::layout::DropdownHandle,
_item_id: &str,
) {}
fn on_toolbar_item(&mut self,
_layout: &mut LayoutManager<P>,
_toolbar: crate::layout::ToolbarHandle,
_item_id: &str,
) {}
fn on_context_menu_item(&mut self,
_layout: &mut LayoutManager<P>,
_menu: crate::layout::ContextMenuHandle,
_index: usize,
) {}
fn on_chrome_tab(&mut self,
_layout: &mut LayoutManager<P>,
_tab_index: usize,
) {}
fn on_chrome_control(&mut self,
_layout: &mut LayoutManager<P>,
_control: crate::layout::ChromeWindowControl,
) {}
fn on_dispatch(&mut self,
_layout: &mut LayoutManager<P>,
_event: crate::layout::DispatchEvent,
) {}
fn on_unhandled_click(&mut self,
_layout: &mut LayoutManager<P>,
_widget_id: &crate::types::WidgetId,
) {}
fn route_click(&mut self,
layout: &mut LayoutManager<P>,
x: f64,
y: f64,
) -> bool {
use crate::layout::{ClickOutcome, DispatchEvent};
match layout.handle_click((x, y)) {
ClickOutcome::DismissOverlay(handle) => {
self.on_dismiss(layout, handle);
true
}
ClickOutcome::DispatchEvent(ev) => {
match ev {
DispatchEvent::ModalCloseRequested(h) => {
self.on_modal_close(layout, h);
}
DispatchEvent::ModalTabClicked { modal, index } => {
self.on_modal_tab(layout, modal, index);
}
DispatchEvent::DropdownItemClicked { dropdown, ref item_id } => {
self.on_dropdown_item(layout, dropdown.clone(), item_id);
}
DispatchEvent::ToolbarItemClicked { toolbar, ref item_id } => {
self.on_toolbar_item(layout, toolbar.clone(), item_id);
}
DispatchEvent::ContextMenuItemClicked { menu, item_index } => {
self.on_context_menu_item(layout, menu, item_index);
}
DispatchEvent::ChromeTabClicked { tab_index } => {
self.on_chrome_tab(layout, tab_index);
}
DispatchEvent::ChromeWindowControl { control } => {
self.on_chrome_control(layout, control);
}
DispatchEvent::Unhandled(ref id) => {
self.on_unhandled_click(layout, id);
}
other => {
self.on_dispatch(layout, other);
}
}
true
}
ClickOutcome::Unhandled { .. } => false,
}
}
}
#[derive(Clone, Debug)]
pub struct AppConfig {
pub title: String,
pub initial_size: (u32, u32),
pub min_size: Option<(u32, u32)>,
pub decorations: bool,
pub vsync: bool,
pub background: u32,
pub multi_window: bool,
pub fps_limit: u32,
pub msaa_samples: u8,
pub single_instance: Option<String>,
pub border_color: Option<u32>,
pub corner_style: CornerStyle,
pub shadow: Option<bool>,
pub start_visible: bool,
pub icon: Option<RgbaIcon>,
pub agent_api_port: Option<u16>,
pub default_tick_rate: crate::render::TickRate,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
title: "uzor app".to_string(),
initial_size: (1280, 720),
min_size: Some((400, 300)),
decorations: false,
vsync: true,
background: 0xFF181820,
multi_window: false,
fps_limit: 0,
msaa_samples: 1,
single_instance: None,
border_color: None,
corner_style: CornerStyle::Default,
shadow: None,
start_visible: false,
icon: None,
agent_api_port: None,
default_tick_rate: crate::render::TickRate::Capped(60),
}
}
}
pub struct ClosureApp<P, F>
where
P: DockPanel,
F: FnMut(&mut LayoutManager<P>, &mut dyn crate::render::RenderContext) + 'static,
{
ui_fn: F,
_phantom: std::marker::PhantomData<P>,
}
impl<P, F> ClosureApp<P, F>
where
P: DockPanel + Default,
F: FnMut(&mut LayoutManager<P>, &mut dyn crate::render::RenderContext) + 'static,
{
pub fn new(ui_fn: F) -> Self {
Self { ui_fn, _phantom: std::marker::PhantomData }
}
}
impl<P, F> App<P> for ClosureApp<P, F>
where
P: DockPanel + Default + 'static,
F: FnMut(&mut LayoutManager<P>, &mut dyn crate::render::RenderContext) + 'static,
{
fn ui(&mut self, win: &mut WindowCtx<'_, P>) {
(self.ui_fn)(win.layout, win.render);
}
}