use eframe::egui;
use grimdock::{
AddTabEntry, HeaderVisibility, OpenBehavior, PanelContext, PanelStyle, PanelTree,
PersistedNode, Tab,
};
fn main() -> eframe::Result<()> {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_title("grimdock 3_header_features")
.with_inner_size([960.0, 540.0]),
..Default::default()
};
eframe::run_native(
"grimdock 3_header_features",
options,
Box::new(|_cc| Ok(Box::new(App::new()))),
)
}
#[derive(Clone, PartialEq, Eq, Debug)]
enum TabId {
Notes,
Search,
Problems,
Terminal,
Output,
}
struct App {
tree: PanelTree<TabId>,
style: PanelStyle,
hide_headers: bool,
}
impl App {
fn new() -> Self {
Self {
tree: PanelTree::new(vec![
Tab::new("notes", TabId::Notes)
.with_leading_visual(">")
.with_closable(true),
Tab::new("search", TabId::Search)
.with_leading_visual("?")
.with_closable(true),
Tab::new("problems", TabId::Problems)
.with_leading_visual("x")
.with_closable(true),
]),
style: PanelStyle::default(),
hide_headers: false,
}
}
fn sync_header_visibility(&mut self) {
let header_visibility = if self.hide_headers {
HeaderVisibility::Hidden
} else {
HeaderVisibility::Always
};
let pane_ids = self
.tree
.to_persisted()
.nodes
.into_iter()
.filter_map(|node| match node {
PersistedNode::Leaf { pane, .. } => Some(pane),
_ => None,
})
.collect::<Vec<_>>();
for pane_id in pane_ids {
if let Some(mut pane) = self.tree.pane_mut(pane_id) {
let mut options = pane.options();
options.header_visibility = header_visibility;
pane.set_options(options);
}
}
}
}
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
self.sync_header_visibility();
egui::CentralPanel::default()
.frame(egui::Frame::NONE)
.show(ctx, |ui| {
ui.checkbox(&mut self.hide_headers, "Hide pane headers");
ui.separator();
let output = PanelContext::new(ui, &mut self.tree, &self.style)
.with_add_tab_provider(&|pane_id, tree| {
let mut entries = vec![
AddTabEntry::new(
"Output",
Tab::new("output", TabId::Output)
.with_leading_visual("!")
.with_closable(true),
),
];
if tree.find_pane_containing(&TabId::Notes) == Some(pane_id) {
entries.push(
AddTabEntry::new(
"Terminal",
Tab::new("terminal", TabId::Terminal)
.with_leading_visual("$")
.with_closable(true),
)
.with_open_behavior(OpenBehavior::FocusExisting),
);
}
entries
})
.show(|ui, tab_id| match tab_id {
TabId::Notes => {
ui.heading("Notes");
ui.label("This pane gets both Output and Terminal in its + menu.");
ui.label("Right-click a tab for Close / Close others / Split actions.");
}
TabId::Search => {
ui.heading("Search");
ui.text_edit_singleline(&mut String::new());
}
TabId::Problems => {
ui.heading("Problems");
ui.label("No problems detected.");
}
TabId::Terminal => {
ui.heading("Terminal");
ui.label("$ cargo run");
}
TabId::Output => {
ui.heading("Output");
ui.label("[INFO] pane-specific add menus are enabled");
}
});
if !output.closed_tabs.is_empty() {
ui.separator();
ui.label(format!("Closed this frame: {:?}", output.closed_tabs));
}
});
}
}