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

Release 0.14 #252

Merged
merged 6 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading