use crate::ecs::components::{Pane, PaneState, Tab, TabOf, Viewer, Workspace};
use crate::ecs::messages::Effect;
use crate::ecs::support::{Effects, tab_area};
use bevy_ecs::prelude::*;
pub fn resolve_layout(
mut tabs: Query<(Entity, &mut Tab)>,
members: Query<&TabOf>,
mut viewers: Query<&mut Viewer>,
mut panes: Query<&mut Pane>,
workspaces: Query<&Workspace>,
mut effects: Effects,
) {
for (tab, mut component) in &mut tabs {
if !members
.get(tab)
.is_ok_and(|member| member.0 == component.workspace)
{
continue;
}
let showing = |viewer: &Viewer| viewer.selection.tab == Some(tab) && !viewer.detaching;
let smallest = viewers
.iter()
.filter(|viewer| showing(viewer))
.map(|viewer| (viewer.rows, viewer.cols))
.reduce(|a, b| (a.0.min(b.0), a.1.min(b.1)));
let area = smallest.map_or(component.area, |(rows, cols)| tab_area(rows, cols));
if !component.layout_changed && area == component.area {
continue;
}
component.area = area;
let geometry = component.layout.geometry(area).unwrap_or_default();
for (pane, rect) in &geometry {
let Ok(mut pane) = panes.get_mut(*pane) else {
continue;
};
let (rows, cols) = Pane::terminal_size(*rect);
if pane.rect == *rect && pane.terminal.size() == (rows, cols) {
continue;
}
pane.rect = *rect;
pane.terminal.resize(rows, cols);
pane.dirty = true;
if matches!(pane.state, PaneState::Live { .. }) {
effects.emit(Effect::ResizePty {
pane: pane.id,
rows,
cols,
});
}
}
if component.geometry != geometry
&& let Ok(workspace) = workspaces.get(component.workspace)
{
effects.event(
component.workspace,
&workspace.name,
crate::proto::control::Event::WorkspaceChanged { id: 0 },
);
}
component.geometry = geometry;
component.layout_changed = false;
for mut viewer in &mut viewers {
if showing(&viewer) {
viewer.dirty = true;
}
}
}
}