From f3a709f36705ab1898d79989b14f3504606b007e Mon Sep 17 00:00:00 2001 From: Ved_s Date: Thu, 4 Jul 2024 06:44:32 +1100 Subject: [PATCH 1/6] Remove `Clone` bound on `map_tabs` and `filter_map_tabs` (#241) * remove Clone bound on map_tabs and filter_map_tabs * remove Clone bound from all functions with Clone + FnMut bounds * Update changelog * Add missing period in changelog --------- Co-authored-by: Adanos020 --- CHANGELOG.md | 7 +++++++ src/dock_state/mod.rs | 16 ++++++++-------- src/dock_state/surface.rs | 8 ++++---- src/dock_state/tree/mod.rs | 16 ++++++++-------- src/dock_state/tree/node.rs | 4 ++-- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1653f307..be3e4446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # egui_dock changelog +## 0.14.0 - Unreleased + +## Changed + +- `{DockState,Surface,Tree,Node}::{filter_map_tabs,map_tabs,filter_tabs,retain_tabs}` no longer require the predicate to + implement `Clone`. ([#241](https://github.com/Adanos020/egui_dock/pull/241)) + ## 0.13.0 - 2024-07-03 ### Breaking changes diff --git a/src/dock_state/mod.rs b/src/dock_state/mod.rs index 404526d8..c603a92f 100644 --- a/src/dock_state/mod.rs +++ b/src/dock_state/mod.rs @@ -469,9 +469,9 @@ impl DockState { /// let tabs: Vec<_> = mapped_dock_state.iter_all_tabs().map(|(_, tab)| tab.to_owned()).collect(); /// assert_eq!(tabs, vec!["1".to_string(), "3".to_string()]); /// ``` - pub fn filter_map_tabs(&self, function: F) -> DockState + pub fn filter_map_tabs(&self, mut function: F) -> DockState where - F: Clone + FnMut(&Tab) -> Option, + F: FnMut(&Tab) -> Option, { let DockState { surfaces, @@ -481,7 +481,7 @@ impl DockState { let surfaces = surfaces .iter() .filter_map(|surface| { - let surface = surface.filter_map_tabs(function.clone()); + let surface = surface.filter_map_tabs(&mut function); (!surface.is_empty()).then_some(surface) }) .collect(); @@ -504,7 +504,7 @@ impl DockState { /// ``` pub fn map_tabs(&self, mut function: F) -> DockState where - F: Clone + FnMut(&Tab) -> NewTab, + F: FnMut(&Tab) -> NewTab, { self.filter_map_tabs(move |tab| Some(function(tab))) } @@ -522,7 +522,7 @@ impl DockState { /// ``` pub fn filter_tabs(&self, mut predicate: F) -> DockState where - F: Clone + FnMut(&Tab) -> bool, + F: FnMut(&Tab) -> bool, Tab: Clone, { self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone())) @@ -539,12 +539,12 @@ impl DockState { /// let tabs: Vec<_> = dock_state.iter_all_tabs().map(|(_, tab)| tab.to_owned()).collect(); /// assert_eq!(tabs, vec!["tab1".to_string(), "tab2".to_string()]); /// ``` - pub fn retain_tabs(&mut self, predicate: F) + pub fn retain_tabs(&mut self, mut predicate: F) where - F: Clone + FnMut(&mut Tab) -> bool, + F: FnMut(&mut Tab) -> bool, { self.surfaces.retain_mut(|surface| { - surface.retain_tabs(predicate.clone()); + surface.retain_tabs(&mut predicate); !surface.is_empty() }); } diff --git a/src/dock_state/surface.rs b/src/dock_state/surface.rs index 476a7a7f..66da3b97 100644 --- a/src/dock_state/surface.rs +++ b/src/dock_state/surface.rs @@ -81,7 +81,7 @@ impl Surface { /// it'll change to [`Surface::Empty`]. pub fn filter_map_tabs(&self, function: F) -> Surface where - F: Clone + FnMut(&Tab) -> Option, + F: FnMut(&Tab) -> Option, { match self { Surface::Empty => Surface::Empty, @@ -100,7 +100,7 @@ impl Surface { /// Returns a new [`Surface`] while mapping the tab type. pub fn map_tabs(&self, mut function: F) -> Surface where - F: Clone + FnMut(&Tab) -> NewTab, + F: FnMut(&Tab) -> NewTab, { self.filter_map_tabs(move |tab| Some(function(tab))) } @@ -110,7 +110,7 @@ impl Surface { /// it'll change to [`Surface::Empty`]. pub fn filter_tabs(&self, mut predicate: F) -> Surface where - F: Clone + FnMut(&Tab) -> bool, + F: FnMut(&Tab) -> bool, Tab: Clone, { self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone())) @@ -121,7 +121,7 @@ impl Surface { /// it'll change to [`Surface::Empty`]. pub fn retain_tabs(&mut self, predicate: F) where - F: Clone + FnMut(&mut Tab) -> bool, + F: FnMut(&mut Tab) -> bool, { if let Surface::Main(tree) | Surface::Window(tree, _) = self { tree.retain_tabs(predicate); diff --git a/src/dock_state/tree/mod.rs b/src/dock_state/tree/mod.rs index cdb6f3e5..648bc52c 100644 --- a/src/dock_state/tree/mod.rs +++ b/src/dock_state/tree/mod.rs @@ -737,9 +737,9 @@ impl Tree { /// Returns a new [`Tree`] while mapping and filtering the tab type. /// Any remaining empty [`Node`]s are removed. - pub fn filter_map_tabs(&self, function: F) -> Tree + pub fn filter_map_tabs(&self, mut function: F) -> Tree where - F: Clone + FnMut(&Tab) -> Option, + F: FnMut(&Tab) -> Option, { let Tree { focused_node, @@ -750,7 +750,7 @@ impl Tree { .iter() .enumerate() .map(|(index, node)| { - let filtered_node = node.filter_map_tabs(function.clone()); + let filtered_node = node.filter_map_tabs(&mut function); if filtered_node.is_empty() && !node.is_empty() { emptied_nodes.insert(NodeIndex(index)); } @@ -768,7 +768,7 @@ impl Tree { /// Returns a new [`Tree`] while mapping the tab type. pub fn map_tabs(&self, mut function: F) -> Tree where - F: Clone + FnMut(&Tab) -> NewTab, + F: FnMut(&Tab) -> NewTab, { self.filter_map_tabs(move |tab| Some(function(tab))) } @@ -777,7 +777,7 @@ impl Tree { /// Any remaining empty [`Node`]s are removed. pub fn filter_tabs(&self, mut predicate: F) -> Tree where - F: Clone + FnMut(&Tab) -> bool, + F: FnMut(&Tab) -> bool, Tab: Clone, { self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone())) @@ -785,13 +785,13 @@ impl Tree { /// Removes all tabs for which `predicate` returns `false`. /// Any remaining empty [`Node`]s are also removed. - pub fn retain_tabs(&mut self, predicate: F) + pub fn retain_tabs(&mut self, mut predicate: F) where - F: Clone + FnMut(&mut Tab) -> bool, + F: FnMut(&mut Tab) -> bool, { let mut emptied_nodes = HashSet::default(); for (index, node) in self.nodes.iter_mut().enumerate() { - node.retain_tabs(predicate.clone()); + node.retain_tabs(&mut predicate); if node.is_empty() { emptied_nodes.insert(NodeIndex(index)); } diff --git a/src/dock_state/tree/node.rs b/src/dock_state/tree/node.rs index 26958e89..113a9032 100644 --- a/src/dock_state/tree/node.rs +++ b/src/dock_state/tree/node.rs @@ -340,7 +340,7 @@ impl Node { /// If this [`Node`] remains empty, it will change to [`Node::Empty`]. pub fn filter_tabs(&self, mut predicate: F) -> Node where - F: Clone + FnMut(&Tab) -> bool, + F: FnMut(&Tab) -> bool, Tab: Clone, { self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone())) @@ -350,7 +350,7 @@ impl Node { /// If this [`Node`] remains empty, it will change to [`Node::Empty`]. pub fn retain_tabs(&mut self, predicate: F) where - F: Clone + FnMut(&mut Tab) -> bool, + F: FnMut(&mut Tab) -> bool, { if let Node::Leaf { tabs, .. } = self { tabs.retain_mut(predicate); From bb9ee3e59309da5b72847afc75dc631b9d59381e Mon Sep 17 00:00:00 2001 From: Adanos020 Date: Wed, 3 Jul 2024 20:48:23 +0100 Subject: [PATCH 2/6] Update crate version and add MSRV change to changelog --- CHANGELOG.md | 1 + Cargo.toml | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be3e4446..f1b1b47e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Breaking changes - Upgraded to egui 0.28. +- Changed MSRV to 1.76. ## 0.12.0 - 2024-04-05 diff --git a/Cargo.toml b/Cargo.toml index 9d23e368..564cd3cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "egui_dock" description = "Docking system for egui - an immediate-mode GUI library for Rust" authors = ["lain-dono", "Adam Gąsior (Adanos020)"] -version = "0.13.0" +version = "0.14.0" edition = "2021" rust-version = "1.76" license = "MIT" diff --git a/README.md b/README.md index 87470595..eca933f5 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Add `egui` and `egui_dock` to your project's dependencies. ```toml [dependencies] egui = "0.28" -egui_dock = "0.13" +egui_dock = "0.14" ``` Then proceed by setting up `egui`, following its [quick start guide](https://github.com/emilk/egui#quick-start). From 47def04357664eedc40bce5913b8d0bcbdf1826d Mon Sep 17 00:00:00 2001 From: Adanos020 Date: Wed, 3 Jul 2024 20:52:53 +0100 Subject: [PATCH 3/6] Fix heading type in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1b1b47e..4b8ac301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.14.0 - Unreleased -## Changed +### Changed - `{DockState,Surface,Tree,Node}::{filter_map_tabs,map_tabs,filter_tabs,retain_tabs}` no longer require the predicate to implement `Clone`. ([#241](https://github.com/Adanos020/egui_dock/pull/241)) From 332b2bd62eae285e6624b1b164699fab73760575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tau=20G=C3=A4rtli?= Date: Thu, 26 Sep 2024 16:00:08 +0200 Subject: [PATCH 4/6] Update duplicate to 2.0 (#248) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 564cd3cd..0986d984 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ serde = ["dep:serde", "egui/serde"] egui = { version = "0.28", default-features = false } serde = { version = "1", optional = true, features = ["derive"] } -duplicate = "1.0" +duplicate = "2.0" paste = "1.0" [dev-dependencies] From 901f22bce336f09084839e84bc731639045e516e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20G=C4=85sior?= Date: Wed, 2 Oct 2024 14:03:04 +0100 Subject: [PATCH 5/6] Egui 0.29 (#251) * Upgrade to egui 0.29. * Update changelog and readme --- CHANGELOG.md | 19 ++++++++--- Cargo.toml | 4 +-- README.md | 4 +-- src/dock_state/surface.rs | 4 ++- src/widgets/dock_area/show/leaf.rs | 36 +++++++++----------- src/widgets/dock_area/show/window_surface.rs | 6 ++-- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8ac301..1f1e5034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.14.0 - Unreleased +### Breaking changes + +- Upgraded to egui 0.29. + ### Changed - `{DockState,Surface,Tree,Node}::{filter_map_tabs,map_tabs,filter_tabs,retain_tabs}` no longer require the predicate to @@ -302,14 +306,18 @@ provide a guide of how to use the library. to `TabStyle` ([89f3248](https://github.com/Adanos020/egui_dock/commit/89f32487a9e1fe8dee92f1fbdc296a2d460c0909)) - -Removed `StyleBuilder` ([9a9b275](https://github.com/Adanos020/egui_dock/commit/9a9b2750cd290bebcc4088761249e02102cb0ce7)) +Removed +`StyleBuilder` ([9a9b275](https://github.com/Adanos020/egui_dock/commit/9a9b2750cd290bebcc4088761249e02102cb0ce7)) - Removed `TabViewer::inner_margin_override` – no deprecation as it's in direct conflict - with `TabViewer::tab_style_override` ([99333b0](https://github.com/Adanos020/egui_dock/commit/99333b093d307181c288b3e134379cfe47647a7c)) + with + `TabViewer::tab_style_override` ([99333b0](https://github.com/Adanos020/egui_dock/commit/99333b093d307181c288b3e134379cfe47647a7c)) - Moved `Style::default_inner_margin` - to `TabsStyle::inner_margin` ([78ecf3a](https://github.com/Adanos020/egui_dock/commit/78ecf3a175ffb960724f328274682dfded800e0f)) + to + `TabsStyle::inner_margin` ([78ecf3a](https://github.com/Adanos020/egui_dock/commit/78ecf3a175ffb960724f328274682dfded800e0f)) - Moved `TabStyle::hline_color` - to `TabBarStyle::hline_color` ([99333b0](https://github.com/Adanos020/egui_dock/commit/99333b093d307181c288b3e134379cfe47647a7c)) + to + `TabBarStyle::hline_color` ([99333b0](https://github.com/Adanos020/egui_dock/commit/99333b093d307181c288b3e134379cfe47647a7c)) ## 0.5.2 - 2023-06-04 @@ -470,7 +478,8 @@ Removed `StyleBuilder` ([9a9b275](https://github.com/Adanos020/egui_dock/commit/ - Renamed `TabViewer::inner_margin` to `TabViewer::inner_margin_override`. ([#67](https://github.com/Adanos020/egui_dock/pull/67)) - `Style::with_separator_color` has been split - into `separator_color_idle`, `separator_color_hovered`, `separator_color_dragged` ([#68](https://github.com/Adanos020/egui_dock/pull/68)) + into `separator_color_idle`, `separator_color_hovered`, + `separator_color_dragged` ([#68](https://github.com/Adanos020/egui_dock/pull/68)) - Updated `egui` to 0.20.0 [#77](https://github.com/Adanos020/egui_dock/pull/77) ### Deprecated (will be deleted in the next release) diff --git a/Cargo.toml b/Cargo.toml index 0986d984..c79a6b47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,14 +18,14 @@ default = [] serde = ["dep:serde", "egui/serde"] [dependencies] -egui = { version = "0.28", default-features = false } +egui = { version = "0.29", default-features = false } serde = { version = "1", optional = true, features = ["derive"] } duplicate = "2.0" paste = "1.0" [dev-dependencies] -eframe = { version = "0.28", default-features = false, features = [ +eframe = { version = "0.29", default-features = false, features = [ "default_fonts", "glow", ] } diff --git a/README.md b/README.md index eca933f5..c70eb12a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![github](https://img.shields.io/badge/github-Adanos020/egui_dock-8da0cb?logo=github)](https://github.com/Adanos020/egui_dock) [![Crates.io](https://img.shields.io/crates/v/egui_dock)](https://crates.io/crates/egui_dock) [![docs.rs](https://img.shields.io/docsrs/egui_dock)](https://docs.rs/egui_dock/) -[![egui_version](https://img.shields.io/badge/egui-0.28-blue)](https://github.com/emilk/egui) +[![egui_version](https://img.shields.io/badge/egui-0.29-blue)](https://github.com/emilk/egui) Originally created by [@lain-dono](https://github.com/lain-dono), this library provides a docking system for `egui`. @@ -32,7 +32,7 @@ Add `egui` and `egui_dock` to your project's dependencies. ```toml [dependencies] -egui = "0.28" +egui = "0.29" egui_dock = "0.14" ``` diff --git a/src/dock_state/surface.rs b/src/dock_state/surface.rs index 66da3b97..169145f6 100644 --- a/src/dock_state/surface.rs +++ b/src/dock_state/surface.rs @@ -1,7 +1,9 @@ use crate::{Node, NodeIndex, Tree, WindowState}; /// A [`Surface`] is the highest level component in a [`DockState`](crate::DockState). [`Surface`]s represent an area -/// in which nodes are placed. Typically, you're only using one surface, which is the main surface. However, if you drag +/// in which nodes are placed. +/// +/// Typically, you're only using one surface, which is the main surface. However, if you drag /// a tab out in a way which creates a window, you also create a new surface in which nodes can appear. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] diff --git a/src/widgets/dock_area/show/leaf.rs b/src/widgets/dock_area/show/leaf.rs index 05982608..7cf02486 100644 --- a/src/widgets/dock_area/show/leaf.rs +++ b/src/widgets/dock_area/show/leaf.rs @@ -4,7 +4,7 @@ use egui::emath::TSTransform; use egui::{ epaint::TextShape, lerp, pos2, vec2, Align, Align2, Button, CursorIcon, Frame, Id, Key, LayerId, Layout, NumExt, Order, Rect, Response, Rounding, ScrollArea, Sense, Stroke, TextStyle, - Ui, UiStackInfo, Vec2, WidgetText, + Ui, UiBuilder, Vec2, WidgetText, }; use crate::{ @@ -32,11 +32,11 @@ impl<'tree, Tab> DockArea<'tree, Tab> { let rect = self.dock_state[surface_index][node_index] .rect() .expect("This node must be a leaf"); - let ui = &mut ui.child_ui_with_id_source( - rect, - Layout::top_down_justified(Align::Min), - (node_index, "node"), - None, + let ui = &mut ui.new_child( + UiBuilder::new() + .max_rect(rect) + .layout(Layout::top_down_justified(Align::Min)) + .id_salt((node_index, "node")), ); let spacing = ui.spacing().item_spacing; ui.spacing_mut().item_spacing = Vec2::ZERO; @@ -112,11 +112,11 @@ impl<'tree, Tab> DockArea<'tree, Tab> { vec2(tabbar_outer_rect.width(), tabbar_outer_rect.height()), ); - let tabs_ui = &mut ui.child_ui_with_id_source( - tabbar_inner_rect, - Layout::left_to_right(Align::Center), - "tabs", - None, + let tabs_ui = &mut ui.new_child( + UiBuilder::new() + .max_rect(tabbar_inner_rect) + .layout(Layout::left_to_right(Align::Center)) + .id_salt("tabs"), ); let mut clip_rect = tabbar_outer_rect; @@ -432,11 +432,11 @@ impl<'tree, Tab> DockArea<'tree, Tab> { tabbar_outer_rect.right_bottom() - vec2(offset, 2.0), ); - let ui = &mut ui.child_ui_with_id_source( - rect, - Layout::left_to_right(Align::Center), - (node_index, "tab_add"), - None, + let ui = &mut ui.new_child( + UiBuilder::new() + .max_rect(rect) + .layout(Layout::left_to_right(Align::Center)) + .id_salt((node_index, "tab_add")), ); let (rect, mut response) = ui.allocate_exact_size(ui.available_size(), Sense::click()); @@ -772,9 +772,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> { ui.ctx().clone(), ui.layer_id(), id, - body_rect, - ui.clip_rect(), - UiStackInfo::default(), + UiBuilder::new().max_rect(body_rect), ); ui.set_clip_rect(Rect::from_min_max(ui.cursor().min, ui.clip_rect().max)); diff --git a/src/widgets/dock_area/show/window_surface.rs b/src/widgets/dock_area/show/window_surface.rs index 84cc6558..64290741 100644 --- a/src/widgets/dock_area/show/window_surface.rs +++ b/src/widgets/dock_area/show/window_surface.rs @@ -1,6 +1,6 @@ use egui::{ CollapsingHeader, CollapsingResponse, Frame, Galley, Id, Layout, Rect, Response, Sense, - TextStyle, TextWrapMode, Ui, Vec2, Widget, + TextStyle, TextWrapMode, Ui, UiBuilder, Vec2, Widget, }; use std::convert::identity; use std::sync::Arc; @@ -133,7 +133,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> { ) -> Option> { if self.show_window_collapse_buttons { let ch_response = CollapsingHeader::new("") - .id_source(id) + .id_salt(id) .open(open) .show_unindented(ui, |ui| { ui.set_min_size(Vec2::splat(100.0)); @@ -198,7 +198,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> { .as_str(), ), ); - ui.allocate_ui_at_rect(rect, |ui| { + ui.allocate_new_ui(UiBuilder::new().max_rect(rect), |ui| { ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| { ui.set_height(rect.height()); if ui.add(close_button).clicked() { From 7c56c671fe99ec25cbac2a395733a1ca1b132151 Mon Sep 17 00:00:00 2001 From: Adanos020 Date: Wed, 2 Oct 2024 14:04:51 +0100 Subject: [PATCH 6/6] Update release date in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f1e5034..c8c7eca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # egui_dock changelog -## 0.14.0 - Unreleased +## 0.14.0 - 2024-09-02 ### Breaking changes