use super::DockTabs;
use super::splitter::{
DEFAULT_SEPARATOR_SIZE, default_separator_color, default_separator_hover_color,
};
use super::tabs::{
DEFAULT_TAB_BAR_HEIGHT, default_active_tab_color, default_inactive_tab_color,
default_tab_bar_color, default_tab_hover_color, default_tab_text_color,
};
use crate::tree::{LayoutRect, NodeId, UiTree};
use astrelis_core::alloc::HashMap;
use astrelis_render::Color;
#[derive(Debug, Clone)]
pub struct DockingStyle {
pub separator_size: f32,
pub separator_color: Color,
pub separator_hover_color: Color,
pub tab_bar_height: f32,
pub tab_bar_color: Color,
pub active_tab_color: Color,
pub inactive_tab_color: Color,
pub tab_text_color: Color,
pub tab_hover_color: Color,
pub tab_font_size: f32,
pub closable: bool,
pub content_padding: f32,
pub separator_tolerance: f32,
}
impl Default for DockingStyle {
fn default() -> Self {
Self {
separator_size: DEFAULT_SEPARATOR_SIZE,
separator_color: default_separator_color(),
separator_hover_color: default_separator_hover_color(),
tab_bar_height: DEFAULT_TAB_BAR_HEIGHT,
tab_bar_color: default_tab_bar_color(),
active_tab_color: default_active_tab_color(),
inactive_tab_color: default_inactive_tab_color(),
tab_text_color: default_tab_text_color(),
tab_hover_color: default_tab_hover_color(),
tab_font_size: 11.0,
closable: false,
content_padding: 4.0,
separator_tolerance: 4.0,
}
}
}
impl DockingStyle {
pub fn separator_size(mut self, size: f32) -> Self {
self.separator_size = size;
self
}
pub fn separator_colors(mut self, normal: Color, hover: Color) -> Self {
self.separator_color = normal;
self.separator_hover_color = hover;
self
}
pub fn tab_bar_height(mut self, height: f32) -> Self {
self.tab_bar_height = height;
self
}
pub fn tab_bar_color(mut self, color: Color) -> Self {
self.tab_bar_color = color;
self
}
pub fn active_tab_color(mut self, color: Color) -> Self {
self.active_tab_color = color;
self
}
pub fn inactive_tab_color(mut self, color: Color) -> Self {
self.inactive_tab_color = color;
self
}
pub fn tab_text_color(mut self, color: Color) -> Self {
self.tab_text_color = color;
self
}
pub fn tab_hover_color(mut self, color: Color) -> Self {
self.tab_hover_color = color;
self
}
pub fn tab_font_size(mut self, size: f32) -> Self {
self.tab_font_size = size;
self
}
pub fn closable(mut self, closable: bool) -> Self {
self.closable = closable;
self
}
pub fn content_padding(mut self, padding: f32) -> Self {
self.content_padding = padding;
self
}
pub fn separator_tolerance(mut self, tolerance: f32) -> Self {
self.separator_tolerance = tolerance;
self
}
}
#[derive(Debug, Clone)]
pub struct CachedContainerInfo {
pub layout: LayoutRect,
pub tab_count: usize,
}
pub struct DockingContext {
tab_containers: HashMap<NodeId, CachedContainerInfo>,
cache_dirty: bool,
style: DockingStyle,
}
impl DockingContext {
pub fn new() -> Self {
Self {
tab_containers: HashMap::new(),
cache_dirty: true,
style: DockingStyle::default(),
}
}
pub fn style(&self) -> &DockingStyle {
&self.style
}
pub fn style_mut(&mut self) -> &mut DockingStyle {
&mut self.style
}
pub fn set_style(&mut self, style: DockingStyle) {
self.style = style;
}
pub fn invalidate(&mut self) {
self.cache_dirty = true;
}
pub fn rebuild_cache(&mut self, tree: &UiTree) {
self.tab_containers.clear();
let all_tabs = tree.find_widgets_with_layout::<DockTabs>();
for (node_id, layout) in all_tabs {
let tab_count = tree
.get_widget(node_id)
.and_then(|w| w.as_any().downcast_ref::<DockTabs>())
.map(|t| t.tab_count())
.unwrap_or(0);
self.tab_containers
.insert(node_id, CachedContainerInfo { layout, tab_count });
}
self.cache_dirty = false;
}
pub fn find_tab_containers(&mut self, tree: &UiTree) -> &HashMap<NodeId, CachedContainerInfo> {
if self.cache_dirty {
self.rebuild_cache(tree);
}
&self.tab_containers
}
pub fn is_dirty(&self) -> bool {
self.cache_dirty
}
pub fn container_count(&self) -> usize {
self.tab_containers.len()
}
}
impl Default for DockingContext {
fn default() -> Self {
Self::new()
}
}