Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different design: more compact windows and collapsing/closing control on each tab bar #237

Merged
merged 36 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1d61ecd
Correct comment typos
micfong-z May 8, 2024
c48c758
Add two buttons on tab bars
micfong-z May 8, 2024
4a1fd3f
Add some utility for recursive node collapse checking
micfong-z May 10, 2024
74ff62a
Preliminary implementation of collapsing windows
micfong-z May 10, 2024
41a9e1a
Handle tab collapsing layout
micfong-z May 13, 2024
689cdea
Resize windows when subnodes collapsed
micfong-z May 13, 2024
e9017ad
Implements leaf close all button
micfong-z May 13, 2024
a041b9d
Update changelog
micfong-z May 13, 2024
3876bba
Allow dragging to a collapsed leaf
micfong-z May 18, 2024
e260c8c
Fix collapsed state checking after dnd splits
micfong-z May 18, 2024
e05c1c8
Update examples
micfong-z May 18, 2024
037ae29
Update changelog
micfong-z May 23, 2024
417f665
Fix up changelog after rebase
Adanos020 Jul 3, 2024
681619c
Fix failing test and rename `Translations::window` to `Translations::…
Adanos020 Jul 3, 2024
f3a709f
Remove `Clone` bound on `map_tabs` and `filter_map_tabs` (#241)
Ved-s Jul 3, 2024
bb9ee3e
Update crate version and add MSRV change to changelog
Adanos020 Jul 3, 2024
47def04
Fix heading type in changelog
Adanos020 Jul 3, 2024
70da8a9
Merge branch 'release-0.14' into compact_tab_bar
Adanos020 Jul 3, 2024
c26d38e
Fix tab bar scroll bar width on window surfaces
micfong-z Jul 4, 2024
3b3f647
Add close window button in context menu
micfong-z Jul 4, 2024
803fd0d
Add minimize window button
micfong-z Jul 9, 2024
a98266f
Update CHANGELOG.md
micfong-z Jul 9, 2024
e73fd52
Fix cargo test
micfong-z Jul 10, 2024
ee5ee60
Add tooltips to right-clickable tab bar buttons
micfong-z Jul 10, 2024
d7303ba
Add minimization activation with modifiers
micfong-z Jul 13, 2024
755a430
Add close window with modifiers
micfong-z Jul 14, 2024
5db05c1
Correct tooltip display conditions
micfong-z Jul 14, 2024
3c04e71
Merge remote-tracking branch 'upstream/main' into compact_tab_bar
micfong-z Oct 13, 2024
b331f82
Upgrade to egui 0.29
micfong-z Oct 13, 2024
d32f4db
Add secondary button feature toggle
micfong-z Oct 14, 2024
d2fa131
Cleanup code
micfong-z Oct 17, 2024
d6fc75a
Update examples
micfong-z Oct 17, 2024
848aa51
Fix cursor icon logic
micfong-z Oct 17, 2024
803b762
Update examples
micfong-z Oct 17, 2024
e11a7ca
Update changelog
micfong-z Oct 17, 2024
b5baa15
Make Japanese translations in the example more consistent with each o…
Adanos020 Oct 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/Cargo.lock
/.idea
/.vscode
64 changes: 64 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
# egui_dock changelog

## 0.15.0 - Unreleased

### Changed

- From ([#237](https://github.com/Adanos020/egui_dock/pull/237)):
- Each leaf can now be collapsed / closed individually. They are introduced as additional tab bar controls.
- Undocked windows are now more compact. The original undocked window controls are now accessible as "secondary buttons" from the tab bar.
- By default, the secondary buttons are activated from primary buttons either by holding the <kbd>Shift</kbd> key while clicking on them, or from a context menu by right-clicking them.
- A number of tooltip hints are on by default as guides to the new behavior, but they can be disabled.
- There has been an overhaul to the internal codebase to support the new features.

### Added

- From ([#237](https://github.com/Adanos020/egui_dock/pull/237)):
- `DockArea::show_leaf_close_all_buttons` – shows a close all button which closes all open tabs in a leaf.
- `DockArea::show_leaf_collapse_buttons` – shows a collapsing button which collapses a leaf (no longer collapsing a window).
- `DockArea::show_secondary_button_hint` – sets whether tooltip hints are shown for secondary buttons on tab bars.
- `DockArea::show_leaf_collapse_buttons` – shows a collapsing button which collapses a leaf (no longer collapsing a window).
- `DockArea::secondary_button_on_modifier` – sets whether the secondary buttons on tab bars are activated by the modifier key.
- `DockArea::secondary_button_context_menu` – sets whether the secondary buttons on tab bars are activated from a context value by right-clicking primary buttons.
- Added the following translations:
- `LeafTranslations::close_all_button`
- `LeafTranslations::close_all_button_menu_hint`
- `LeafTranslations::close_all_button_modifier_hint`
- `LeafTranslations::close_all_button_modifier_menu_hint`
- `LeafTranslations::close_all_button_disabled_tooltip`
- `LeafTranslations::minimize_button`
- `LeafTranslations::minimize_button_menu_hint`
- `LeafTranslations::minimize_button_modifier_hint`
- `LeafTranslations::minimize_button_modifier_menu_hint`
- `Node::is_collapsed` – returns whether the `Node` is collapsed.
- `Node::collapsed_leaf_count` – returns the number of collapsed layers of leaf subnodes.
- `Node::set_collapsed` – set the collapsing state of the `Node`.
- `Node::set_collapsed_leaf_count` – sets the number of collapsed layers of leaf subnodes.
- `WindowState::minimized` field – records whether a window is minimized.
- `WindowState::expanded_height` field – records the height of the window before it was fully collapsed.
- Added style configuration for the two buttons:
- `ButtonsStyle::{close_all_tabs, collapse_tabs, minimize_window}_color`
- `ButtonsStyle::{close_all_tabs, collapse_tabs, minimize_window}_active_color`
- `ButtonsStyle::{close_all_tabs, collapse_tabs, minimize_window}_bg_fill`
- `ButtonsStyle::{close_all_tabs, collapse_tabs, minimize_window}_border_color`
- `ButtonsStyle::close_all_tabs_disabled_color`
- `Style::TAB_CLOSE_ALL_BUTTON_SIZE`
- `Style::TAB_CLOSE_ALL_SIZE`
- `Style::TAB_COLLAPSE_BUTTON_SIZE`
- `Style::TAB_COLLAPSE_ARROW_SIZE`
- `Style::TAB_EXPAND_BUTTON_SIZE`
- `Style::TAB_EXPAND_ARROW_SIZE`

### Breaking changes

- From ([#237](https://github.com/Adanos020/egui_dock/pull/237)):
- Renamed `Translations::WindowTranslations` to `Translations::LeafTranslations`.
- Renamed `WindowTranslations::close_button_tooltip` to `LeafTranslations::close_button_disabled_tooltip`.
- `Translations::LeafTranslations` now requires more fields to be constructed (see **Added** section).

### Deprecated

- From ([#237](https://github.com/Adanos020/egui_dock/pull/237)):
- `DockArea::show_window_close_buttons` – no longer has any effect; consider using `DockArea::show_leaf_close_all_buttons`
instead.
- `DockArea::show_window_collapse_buttons` – no longer has any effect; consider using `DockArea::show_leaf_collapse_buttons`
instead.

## 0.14.0 - 2024-09-02

### Breaking changes
Expand Down
42 changes: 33 additions & 9 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ struct MyContext {
draggable_tabs: bool,
show_tab_name_on_hover: bool,
allowed_splits: AllowedSplits,
show_window_close: bool,
show_window_collapse: bool,
show_leaf_close_all: bool,
show_leaf_collapse: bool,
show_secondary_button_hint: bool,
secondary_button_on_modifier: bool,
secondary_button_context_menu: bool,
}

struct MyApp {
Expand Down Expand Up @@ -156,10 +159,25 @@ impl MyContext {
ui.checkbox(&mut self.show_add_buttons, "Show add buttons");
ui.checkbox(&mut self.draggable_tabs, "Draggable tabs");
ui.checkbox(&mut self.show_tab_name_on_hover, "Show tab name on hover");
ui.checkbox(&mut self.show_window_close, "Show close button on windows");
ui.checkbox(
&mut self.show_window_collapse,
"Show collaspse button on windows",
&mut self.show_leaf_close_all,
"Show close all button on tab bars",
);
ui.checkbox(
&mut self.show_leaf_collapse,
"Show collaspse button on tab bars",
);
ui.checkbox(
&mut self.secondary_button_on_modifier,
"Enable secondary buttons when modifiers (Shift by default) are pressed",
);
ui.checkbox(
&mut self.secondary_button_context_menu,
"Enable secondary buttons in right-click context menus",
);
ui.checkbox(
&mut self.show_secondary_button_hint,
"Show tooltip hints for secondary buttons",
);
ComboBox::new("cbox:allowed_splits", "Split direction(s)")
.selected_text(format!("{:?}", self.allowed_splits))
Expand Down Expand Up @@ -540,8 +558,11 @@ impl Default for MyApp {
style: None,
open_tabs,

show_window_close: true,
show_window_collapse: true,
show_leaf_close_all: true,
show_leaf_collapse: true,
show_secondary_button_hint: true,
secondary_button_on_modifier: true,
secondary_button_context_menu: true,
show_close_buttons: true,
show_add_buttons: false,
draggable_tabs: true,
Expand Down Expand Up @@ -599,8 +620,11 @@ impl eframe::App for MyApp {
.draggable_tabs(self.context.draggable_tabs)
.show_tab_name_on_hover(self.context.show_tab_name_on_hover)
.allowed_splits(self.context.allowed_splits)
.show_window_close_buttons(self.context.show_window_close)
.show_window_collapse_buttons(self.context.show_window_collapse)
.show_leaf_close_all_buttons(self.context.show_leaf_close_all)
.show_leaf_collapse_buttons(self.context.show_leaf_collapse)
.show_secondary_button_hint(self.context.show_secondary_button_hint)
.secondary_button_on_modifier(self.context.secondary_button_on_modifier)
.secondary_button_context_menu(self.context.secondary_button_context_menu)
.show_inside(ui, &mut self.context);
});
}
Expand Down
60 changes: 52 additions & 8 deletions src/dock_state/translations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub struct Translations {
/// Text overrides for buttons in tab context menus.
pub tab_context_menu: TabContextMenuTranslations,
/// Text overrides for buttons in windows.
pub window: WindowTranslations,
pub leaf: LeafTranslations,
}

/// Specifies text in buttons displayed in the context menu displayed upon right-clicking on a tab.
Expand All @@ -18,21 +18,46 @@ pub struct TabContextMenuTranslations {
pub eject_button: String,
}

/// Specifies text in buttons displayed in the context menu displayed upon right-clicking on a tab.
/// Specifies text displayed in the primary buttons on a tab bar.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct WindowTranslations {
/// Message in the tooltip shown while hovering over a grayed out X button of a window
pub struct LeafTranslations {
/// Message in the tooltip shown while hovering over a grayed out X button of a leaf
/// containing non-closable tabs.
pub close_button_disabled_tooltip: String,
/// Button that closes the entire window.
pub close_all_button: String,
/// Message in the tooltip shown while hovering over an X button of a window.
/// Used when the secondary buttons are accessible from the context menu.
pub close_all_button_menu_hint: String,
/// Message in the tooltip shown while hovering over an X button of a window.
/// Used when the secondary buttons are accessible using modifiers.
pub close_all_button_modifier_hint: String,
/// Message in the tooltip shown while hovering over an X button of a window.
/// Used when the secondary buttons are accessible using modifiers and from the context menu.
pub close_all_button_modifier_menu_hint: String,
/// Message in the tooltip shown while hovering over a grayed out close window button of a window
/// containing non-closable tabs.
pub close_button_tooltip: String,
pub close_all_button_disabled_tooltip: String,
/// Button that minimizes the window.
pub minimize_button: String,
/// Message in the tooltip shown while hovering over a collapse button of a leaf.
/// Used when the secondary buttons are accessible from the context menu.
pub minimize_button_menu_hint: String,
/// Message in the tooltip shown while hovering over a collapse button of a leaf.
/// Used when the secondary buttons are accessible using modifiers.
pub minimize_button_modifier_hint: String,
/// Message in the tooltip shown while hovering over a collapse button of a leaf.
/// Used when the secondary buttons are accessible using modifiers and from the context menu.
pub minimize_button_modifier_menu_hint: String,
}

impl Translations {
/// Default English translations.
pub fn english() -> Self {
Self {
tab_context_menu: TabContextMenuTranslations::english(),
window: WindowTranslations::english(),
leaf: LeafTranslations::english(),
}
}
}
Expand All @@ -47,11 +72,30 @@ impl TabContextMenuTranslations {
}
}

impl WindowTranslations {
impl LeafTranslations {
/// Default English translations.
pub fn english() -> Self {
Self {
close_button_tooltip: String::from("This window contains non-closable tabs."),
close_button_disabled_tooltip: String::from("This leaf contains non-closable tabs."),
close_all_button: String::from("Close window"),
close_all_button_menu_hint: String::from("Right click to close this window."),
close_all_button_modifier_hint: String::from(
"Press modifier keys (Shift by default) to close this window.",
),
close_all_button_modifier_menu_hint: String::from(
"Press modifier keys (Shift by default) or right click to close this window.",
),
close_all_button_disabled_tooltip: String::from(
"This window contains non-closable tabs.",
),
minimize_button: String::from("Minimize window"),
minimize_button_menu_hint: String::from("Right click to minimize this window."),
minimize_button_modifier_hint: String::from(
"Press modifier keys (Shift by default) to minimize this window.",
),
minimize_button_modifier_menu_hint: String::from(
"Press modifier keys (Shift by default) or right click to minimize this window.",
),
}
}
}
86 changes: 86 additions & 0 deletions src/dock_state/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub use tab_iter::TabIter;
use egui::ahash::HashSet;
use egui::Rect;
use std::{
cmp::max,
fmt,
ops::{Index, IndexMut},
slice::{Iter, IterMut},
Expand Down Expand Up @@ -125,6 +126,9 @@ pub struct Tree<Tab> {
// Binary tree vector
pub(super) nodes: Vec<Node<Tab>>,
focused_node: Option<NodeIndex>,
// Whether all subnodes of the tree is collapsed
collapsed: bool,
collapsed_leaf_count: i32,
}

impl<Tab> fmt::Debug for Tree<Tab> {
Expand All @@ -138,6 +142,8 @@ impl<Tab> Default for Tree<Tab> {
Self {
nodes: Vec::new(),
focused_node: None,
collapsed: false,
collapsed_leaf_count: 0,
}
}
}
Expand Down Expand Up @@ -166,6 +172,8 @@ impl<Tab> Tree<Tab> {
Self {
nodes: vec![root],
focused_node: None,
collapsed: false,
collapsed_leaf_count: 0,
}
}

Expand Down Expand Up @@ -520,6 +528,7 @@ impl<Tab> Tree<Tab> {
self[index[1]] = new;

self.focused_node = Some(index[1]);
self.node_update_collapsed(index[1]);

index
}
Expand Down Expand Up @@ -744,6 +753,8 @@ impl<Tab> Tree<Tab> {
let Tree {
focused_node,
nodes,
collapsed,
collapsed_leaf_count,
} = self;
let mut emptied_nodes = HashSet::default();
let nodes = nodes
Expand All @@ -760,6 +771,8 @@ impl<Tab> Tree<Tab> {
let mut new_tree = Tree {
nodes,
focused_node: *focused_node,
collapsed: *collapsed,
collapsed_leaf_count: *collapsed_leaf_count,
};
new_tree.balance(emptied_nodes);
new_tree
Expand Down Expand Up @@ -799,6 +812,26 @@ impl<Tab> Tree<Tab> {
self.balance(emptied_nodes);
}

/// Sets the collapsing state of the [`Tree`].
pub(crate) fn set_collapsed(&mut self, collapsed: bool) {
self.collapsed = collapsed;
}

/// Returns whether the [`Tree`] is collapsed.
pub(crate) fn is_collapsed(&self) -> bool {
self.collapsed
}

/// Sets the number of collapsed layers of leaf subnodes in the [`Tree`].
pub(crate) fn set_collapsed_leaf_count(&mut self, collapsed_leaf_count: i32) {
self.collapsed_leaf_count = collapsed_leaf_count;
}

/// Returns the number of collapsed layers of leaf subnodes in the [`Tree`].
pub(crate) fn collapsed_leaf_count(&self) -> i32 {
self.collapsed_leaf_count
}

fn balance(&mut self, emptied_nodes: HashSet<NodeIndex>) {
let mut emptied_parents = HashSet::default();
for parent_index in emptied_nodes.into_iter().filter_map(|ni| ni.parent()) {
Expand All @@ -817,6 +850,59 @@ impl<Tab> Tree<Tab> {
self.balance(emptied_parents);
}
}

/// Updates the collapsed state of the node and its parents.
pub(crate) fn node_update_collapsed(&mut self, node_index: NodeIndex) {
let collapsed = self[node_index].is_collapsed();
if !collapsed {
// Recursively notify parent nodes that the leaf has expanded
let mut parent_index_option = node_index.parent();
while let Some(parent_index) = parent_index_option {
parent_index_option = parent_index.parent();

// Update collapsed leaf count and collapse status
let left_count = self[parent_index.left()].collapsed_leaf_count();
let right_count = self[parent_index.right()].collapsed_leaf_count();
self[parent_index].set_collapsed(false);

if self[parent_index].is_horizontal() {
self[parent_index].set_collapsed_leaf_count(max(left_count, right_count));
} else {
self[parent_index].set_collapsed_leaf_count(left_count + right_count);
}
}
self.set_collapsed(false);
let root_index = NodeIndex::root();
self.set_collapsed_leaf_count(self[root_index].collapsed_leaf_count());
} else {
// Recursively notify parent nodes that the leaf has collapsed
let mut parent_index_option = node_index.parent();
while let Some(parent_index) = parent_index_option {
parent_index_option = parent_index.parent();

// Update collapsed leaf count and collapse status
let left_count = self[parent_index.left()].collapsed_leaf_count();
let right_count = self[parent_index.right()].collapsed_leaf_count();

if self[parent_index].is_horizontal() {
self[parent_index].set_collapsed_leaf_count(max(left_count, right_count));
} else {
self[parent_index].set_collapsed_leaf_count(left_count + right_count);
}

if self[parent_index.left()].is_collapsed()
&& self[parent_index.right()].is_collapsed()
{
self[parent_index].set_collapsed(true);
}
}
if self.root_node().is_some_and(|root| root.is_collapsed()) {
self.set_collapsed(true);
let root_index = NodeIndex::root();
self.set_collapsed_leaf_count(self[root_index].collapsed_leaf_count());
}
}
}
}

impl<Tab> Tree<Tab>
Expand Down
Loading
Loading