Skip to main content

brep_app/panels/
document_tabs.rs

1//! The DOCUMENT TABS seam — the outcome type the dock reports model-tab clicks
2//! through, plus the verifier global describing the open models.
3//!
4//! # There is no strip here any more
5//!
6//! The tabs are drawn by `egui_tiles` itself: every open model is a
7//! [`crate::panels::dock::PaneKind::Document`] pane, and they all live in one
8//! `Tabs` container whose tab bar IS the model switcher. An earlier version drew
9//! a hand-rolled strip INSIDE the single viewport pane, which left the pane
10//! wearing two stacked bars — the tiles tab bar saying "3D View" above our own
11//! row of file names. Making the pane's own bar the document bar is both what a
12//! docked editor should look like and less code.
13//!
14//! Exclusivity — the bar holds 3D views and nothing else — is enforced in
15//! `dock.rs` instead of by construction, because `egui_tiles` has no hook to
16//! refuse a drop into a container: see `evict_foreign_panes_from_document_group`
17//! (nothing else may land in the group) and `is_tile_draggable` (no document may
18//! leave it).
19
20use crate::automation::hit_keys::HitKeyDoc;
21use crate::document::Documents;
22use eframe::egui;
23
24/// What the user did in the document tab bar this frame. At most one of each —
25/// the shell acts on them after the dock's borrows are released.
26#[derive(Default)]
27pub struct TabsOutcome {
28    /// Activate this document (a tab click, seen as egui_tiles' active tab
29    /// disagreeing with [`Documents`]).
30    pub activate: Option<usize>,
31    /// Close this document (its `✕`). Routed through the file dialog so a dirty
32    /// model is confirmed first.
33    pub close: Option<usize>,
34    /// Per-tab screen rects for the headed verifier, keyed `doctab:<index>`,
35    /// collected in `DockBehavior::on_tab_button`.
36    pub hits: Vec<(String, egui::Rect)>,
37}
38
39/// The `__brepDocuments` verifier global: the open tabs (title, raw name, dirty)
40/// and which one is active.
41#[cfg_attr(not(target_arch = "wasm32"), allow(dead_code))]
42pub fn state_json(docs: &Documents) -> String {
43    let tabs: Vec<serde_json::Value> = docs
44        .iter()
45        .map(|doc| {
46            serde_json::json!({
47                "title": doc.title(),
48                "name": doc.name(),
49                "dirty": doc.dirty_marker(),
50            })
51        })
52        .collect();
53    serde_json::json!({ "active": docs.active_index(), "tabs": tabs }).to_string()
54}
55
56/// The hit keys this panel publishes (see `automation::hit_keys`).
57pub static HIT_KEYS: &[HitKeyDoc] = &[
58    HitKeyDoc { panel: "documents", prefix: "doctab:", meaning: "activate a document tab (doctab:i) or close it (doctab:i:close)", command: None },
59];