diff --git a/src/ui.rs b/src/ui.rs index ea8dbb2fd3ac5a4c9c74de336cf88039d953c413..46926d541a2c15600212afe5fcb2dcb86bda982a 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -2,5 +2,6 @@ mod composable_view; mod layout_manager; mod panes; mod shortcuts; +mod utils; pub use composable_view::ComposableView; diff --git a/src/ui/composable_view.rs b/src/ui/composable_view.rs index b2a0c5d8ce5f398c43e0c27081f9e71d063ba49b..16774e910a1651a03a32088e68aac41aef7a0264 100644 --- a/src/ui/composable_view.rs +++ b/src/ui/composable_view.rs @@ -1,7 +1,8 @@ use super::{ layout_manager::LayoutManager, - panes::{Pane, PaneBehavior}, + panes::{Pane, PaneBehavior, PaneKind}, shortcuts, + utils::maximized_pane_ui, }; use std::{ fs, @@ -19,6 +20,7 @@ pub struct ComposableView { pub layout_manager: LayoutManager, behavior: ComposableBehavior, + maximized_pane: Option<TileId>, } // An app must implement the `App` trait to define how the ui is built @@ -44,6 +46,7 @@ impl eframe::App for ComposableView { ((Modifiers::NONE, Key::V), PaneAction::SplitV), ((Modifiers::NONE, Key::H), PaneAction::SplitH), ((Modifiers::NONE, Key::C), PaneAction::Close), + ((Modifiers::SHIFT, Key::Escape), PaneAction::Maximize), ]; pane_action = pane_action.or(shortcuts::map_to_action(ctx, &key_action_pairs[..]) .map(|action| (action, hovered_pane))); @@ -87,6 +90,27 @@ impl eframe::App for ComposableView { PaneAction::Replace(new_pane) => { panes_tree.tiles.insert(hovered_tile, Tile::Pane(*new_pane)); } + PaneAction::Maximize => { + // This is a toggle: if there is not currently a maximized pane, + // maximize the hovered pane, otherwize remove the maximized pane. + if self.maximized_pane.is_some() { + self.maximized_pane = None; + } else { + let hovered_pane_is_default = panes_tree + .tiles + .get(hovered_tile) + .map(|hovered_pane| match hovered_pane { + Tile::Pane(Pane { + pane: PaneKind::Default(_), + }) => true, + _ => false, + }) + .unwrap_or(false); + if !hovered_pane_is_default { + self.maximized_pane = Some(hovered_tile); + } + } + } } } @@ -103,7 +127,15 @@ impl eframe::App for ComposableView { // A central panel covers the remainder of the screen, i.e. whatever area is left after adding other panels. egui::CentralPanel::default().show(ctx, |ui| { - panes_tree.ui(&mut self.behavior, ui); + if let Some(maximized_pane) = self.maximized_pane { + if let Some(Tile::Pane(pane)) = panes_tree.tiles.get_mut(maximized_pane) { + maximized_pane_ui(ui, pane); + } else { + panic!("Maximized pane not found in tree!"); + } + } else { + panes_tree.ui(&mut self.behavior, ui); + } }); LayoutManager::show(self, ctx); @@ -246,4 +278,5 @@ pub enum PaneAction { SplitV, Close, Replace(Box<Pane>), + Maximize, } diff --git a/src/ui/utils.rs b/src/ui/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..e9121eedef63af0d73069a8befb728255e042fa2 --- /dev/null +++ b/src/ui/utils.rs @@ -0,0 +1,13 @@ +use egui::containers::Frame; +use egui::{Shadow, Style, Ui}; + +use super::panes::{Pane, PaneBehavior}; + +/// This function wraps a ui into a popup frame intended for the pane that needs +/// to be maximized on screen. +pub fn maximized_pane_ui(ui: &mut Ui, pane: &mut Pane) { + Frame::popup(&Style::default()) + .fill(egui::Color32::TRANSPARENT) + .shadow(Shadow::NONE) + .show(ui, |ui| pane.ui(ui)); +}