use std::{collections::HashMap, sync::Arc};
use gpui::{App, Global, WeakEntity, Window};
use super::{DockArea, PanelInfo, PanelState, PanelView};
pub struct PanelBuildContext<'a> {
dock_area: WeakEntity<DockArea>,
state: &'a PanelState,
info: &'a PanelInfo,
}
impl<'a> PanelBuildContext<'a> {
pub fn new(
dock_area: WeakEntity<DockArea>,
state: &'a PanelState,
info: &'a PanelInfo,
) -> Self {
Self {
dock_area,
state,
info,
}
}
pub fn dock_area(&self) -> WeakEntity<DockArea> {
self.dock_area.clone()
}
pub fn state(&self) -> &PanelState {
self.state
}
pub fn info(&self) -> &PanelInfo {
self.info
}
}
pub struct PanelRegistry {
items: HashMap<
String,
Arc<dyn Fn(PanelBuildContext, &mut Window, &mut App) -> Arc<dyn PanelView>>,
>,
}
impl PanelRegistry {
pub(crate) fn init(cx: &mut App) {
if cx.try_global::<PanelRegistry>().is_none() {
cx.set_global(PanelRegistry::new());
}
}
pub fn new() -> Self {
Self {
items: HashMap::new(),
}
}
pub fn global(cx: &App) -> &Self {
cx.global::<PanelRegistry>()
}
pub fn global_mut(cx: &mut App) -> &mut Self {
cx.global_mut::<PanelRegistry>()
}
pub fn build_panel(
panel_name: &str,
context: PanelBuildContext,
window: &mut Window,
cx: &mut App,
) -> Option<Arc<dyn PanelView>> {
let build = Self::global(cx).items.get(panel_name).cloned()?;
Some(build(context, window, cx))
}
}
impl Default for PanelRegistry {
fn default() -> Self {
Self::new()
}
}
impl Global for PanelRegistry {}
pub fn register_panel<F>(cx: &mut App, panel_name: &str, deserialize: F)
where
F: Fn(PanelBuildContext, &mut Window, &mut App) -> Arc<dyn PanelView> + 'static,
{
PanelRegistry::init(cx);
PanelRegistry::global_mut(cx)
.items
.insert(panel_name.to_string(), Arc::new(deserialize));
}