Skip to content

Commit

Permalink
Release 0.14 (#252)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* Update crate version and add MSRV change to changelog

* Fix heading type in changelog

* Update duplicate to 2.0 (#248)

* Egui 0.29 (#251)

* Upgrade to egui 0.29.

* Update changelog and readme

* Update release date in changelog

---------

Co-authored-by: Ved_s <[email protected]>
Co-authored-by: Tau Gärtli <[email protected]>
  • Loading branch information
3 people authored Oct 2, 2024
1 parent e33130c commit 179832d
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 57 deletions.
27 changes: 22 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# egui_dock changelog

## 0.14.0 - 2024-09-02

### 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
implement `Clone`. ([#241](https://github.com/Adanos020/egui_dock/pull/241))

## 0.13.0 - 2024-07-03

### Breaking changes

- Upgraded to egui 0.28.
- Changed MSRV to 1.76.

## 0.12.0 - 2024-04-05

Expand Down Expand Up @@ -294,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

Expand Down Expand Up @@ -462,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)
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 = "1.0"
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",
] }
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down Expand Up @@ -32,8 +32,8 @@ Add `egui` and `egui_dock` to your project's dependencies.

```toml
[dependencies]
egui = "0.28"
egui_dock = "0.13"
egui = "0.29"
egui_dock = "0.14"
```

Then proceed by setting up `egui`, following its [quick start guide](https://github.com/emilk/egui#quick-start).
Expand Down
16 changes: 8 additions & 8 deletions src/dock_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,9 @@ impl<Tab> DockState<Tab> {
/// 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<F, NewTab>(&self, function: F) -> DockState<NewTab>
pub fn filter_map_tabs<F, NewTab>(&self, mut function: F) -> DockState<NewTab>
where
F: Clone + FnMut(&Tab) -> Option<NewTab>,
F: FnMut(&Tab) -> Option<NewTab>,
{
let DockState {
surfaces,
Expand All @@ -481,7 +481,7 @@ impl<Tab> DockState<Tab> {
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();
Expand All @@ -504,7 +504,7 @@ impl<Tab> DockState<Tab> {
/// ```
pub fn map_tabs<F, NewTab>(&self, mut function: F) -> DockState<NewTab>
where
F: Clone + FnMut(&Tab) -> NewTab,
F: FnMut(&Tab) -> NewTab,
{
self.filter_map_tabs(move |tab| Some(function(tab)))
}
Expand All @@ -522,7 +522,7 @@ impl<Tab> DockState<Tab> {
/// ```
pub fn filter_tabs<F>(&self, mut predicate: F) -> DockState<Tab>
where
F: Clone + FnMut(&Tab) -> bool,
F: FnMut(&Tab) -> bool,
Tab: Clone,
{
self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone()))
Expand All @@ -539,12 +539,12 @@ impl<Tab> DockState<Tab> {
/// 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<F>(&mut self, predicate: F)
pub fn retain_tabs<F>(&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()
});
}
Expand Down
12 changes: 7 additions & 5 deletions src/dock_state/surface.rs
Original file line number Diff line number Diff line change
@@ -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))]
Expand Down Expand Up @@ -81,7 +83,7 @@ impl<Tab> Surface<Tab> {
/// it'll change to [`Surface::Empty`].
pub fn filter_map_tabs<F, NewTab>(&self, function: F) -> Surface<NewTab>
where
F: Clone + FnMut(&Tab) -> Option<NewTab>,
F: FnMut(&Tab) -> Option<NewTab>,
{
match self {
Surface::Empty => Surface::Empty,
Expand All @@ -100,7 +102,7 @@ impl<Tab> Surface<Tab> {
/// Returns a new [`Surface`] while mapping the tab type.
pub fn map_tabs<F, NewTab>(&self, mut function: F) -> Surface<NewTab>
where
F: Clone + FnMut(&Tab) -> NewTab,
F: FnMut(&Tab) -> NewTab,
{
self.filter_map_tabs(move |tab| Some(function(tab)))
}
Expand All @@ -110,7 +112,7 @@ impl<Tab> Surface<Tab> {
/// it'll change to [`Surface::Empty`].
pub fn filter_tabs<F>(&self, mut predicate: F) -> Surface<Tab>
where
F: Clone + FnMut(&Tab) -> bool,
F: FnMut(&Tab) -> bool,
Tab: Clone,
{
self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone()))
Expand All @@ -121,7 +123,7 @@ impl<Tab> Surface<Tab> {
/// it'll change to [`Surface::Empty`].
pub fn retain_tabs<F>(&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);
Expand Down
16 changes: 8 additions & 8 deletions src/dock_state/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,9 +737,9 @@ impl<Tab> Tree<Tab> {

/// Returns a new [`Tree`] while mapping and filtering the tab type.
/// Any remaining empty [`Node`]s are removed.
pub fn filter_map_tabs<F, NewTab>(&self, function: F) -> Tree<NewTab>
pub fn filter_map_tabs<F, NewTab>(&self, mut function: F) -> Tree<NewTab>
where
F: Clone + FnMut(&Tab) -> Option<NewTab>,
F: FnMut(&Tab) -> Option<NewTab>,
{
let Tree {
focused_node,
Expand All @@ -750,7 +750,7 @@ impl<Tab> Tree<Tab> {
.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));
}
Expand All @@ -768,7 +768,7 @@ impl<Tab> Tree<Tab> {
/// Returns a new [`Tree`] while mapping the tab type.
pub fn map_tabs<F, NewTab>(&self, mut function: F) -> Tree<NewTab>
where
F: Clone + FnMut(&Tab) -> NewTab,
F: FnMut(&Tab) -> NewTab,
{
self.filter_map_tabs(move |tab| Some(function(tab)))
}
Expand All @@ -777,21 +777,21 @@ impl<Tab> Tree<Tab> {
/// Any remaining empty [`Node`]s are removed.
pub fn filter_tabs<F>(&self, mut predicate: F) -> Tree<Tab>
where
F: Clone + FnMut(&Tab) -> bool,
F: FnMut(&Tab) -> bool,
Tab: Clone,
{
self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone()))
}

/// Removes all tabs for which `predicate` returns `false`.
/// Any remaining empty [`Node`]s are also removed.
pub fn retain_tabs<F>(&mut self, predicate: F)
pub fn retain_tabs<F>(&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));
}
Expand Down
4 changes: 2 additions & 2 deletions src/dock_state/tree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl<Tab> Node<Tab> {
/// If this [`Node`] remains empty, it will change to [`Node::Empty`].
pub fn filter_tabs<F>(&self, mut predicate: F) -> Node<Tab>
where
F: Clone + FnMut(&Tab) -> bool,
F: FnMut(&Tab) -> bool,
Tab: Clone,
{
self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone()))
Expand All @@ -350,7 +350,7 @@ impl<Tab> Node<Tab> {
/// If this [`Node`] remains empty, it will change to [`Node::Empty`].
pub fn retain_tabs<F>(&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);
Expand Down
36 changes: 17 additions & 19 deletions src/widgets/dock_area/show/leaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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));

Expand Down
6 changes: 3 additions & 3 deletions src/widgets/dock_area/show/window_surface.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -133,7 +133,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
) -> Option<CollapsingResponse<()>> {
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));
Expand Down Expand Up @@ -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() {
Expand Down

0 comments on commit 179832d

Please sign in to comment.