Skip to content

Commit

Permalink
Release 0.12 (#235)
Browse files Browse the repository at this point in the history
* Bump crate version number

* Added #[derive(Serialize, Deserialize)] to the Style structs under the serde feature (#227)

* Fix docking on empty main surface. (#222)

* Fix docking on empty main surface.

* Update changelog and bump patch number.

* Bugfixes (#225)

* Fix visual bug happening while a tab is being dragged.

* Fix crash on retaining tabs.

* Fix `filter_map_tabs` leaving leaf nodes empty.

* Update changelog

* Revert simple.rs

* Bump patch version number.

* added the derives

---------

Co-authored-by: Adam Gąsior <[email protected]>

* Upgrade egui and fix clippy

* Fix close buttons

* Fix drag-n-drop (todo: fix overlays).

* Fix overlay

* Fix dragging tabs

* Fix visual bug while dragging and hovering one tab over another

* Fix close buttons again

* Fix more visual glitches while dragging tabs

* Fixed the mysterious resizing of the area occupied by `DockArea` caused by overlays.

* Fix clippy and revert test changes to `simple` example.

* Fix clippy

* Update changelog

* Fix splits in the buttons overlay.

* Add border rounding to style editor in `hello` example

* Update changelog

---------

Co-authored-by: Quinntyx <[email protected]>
  • Loading branch information
Adanos020 and Quinntyx authored Apr 5, 2024
1 parent 45a68a7 commit d637fd1
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 117 deletions.
22 changes: 19 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# egui_dock changelog

## 0.12.0 - 2024-04-03

### Breaking changes

- Upgraded to egui 0.27.

### Changed

- All `Style` structs are now serializable with `serde`. ([#227](https:/Adanos020/egui_dock/pull/227))

### Fixed

- Dragging tabs around should no longer cause the `DockArea` to resize a tiny bit on every frame.
- Dragged tabs should now always follow the mouse exactly.
- Button overlay now correctly renders split buttons when allowed splits are either `LeftRightOnly` or `TopBottomOnly`.

## 0.11.4 - 2024-03-11

### Fixed
Expand Down Expand Up @@ -29,17 +45,17 @@ From [#225](https:/Adanos020/egui_dock/pull/225):
### Fixed

- Bug where tabs couldn't be re-docked onto the main surface if it's
empty ([#222](https:/Adanos020/egui_dock/pull/222))
empty. ([#222](https:/Adanos020/egui_dock/pull/222))

## 0.11.0 - 2024-02-06

### Added

- `filter_map_tabs`, `filter_tabs`, and `retain_tabs` ([#217](https:/Adanos020/egui_dock/pull/217))
- `filter_map_tabs`, `filter_tabs`, and `retain_tabs`. ([#217](https:/Adanos020/egui_dock/pull/217))

### Breaking changes

- Upgraded to egui 0.26
- Upgraded to egui 0.26.

## 0.10.0 - 2024-01-09

Expand Down
6 changes: 3 additions & 3 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.11.4"
version = "0.12.0"
edition = "2021"
rust-version = "1.72"
license = "MIT"
Expand All @@ -18,14 +18,14 @@ default = []
serde = ["dep:serde", "egui/serde"]

[dependencies]
egui = { version = "0.26", default-features = false }
egui = { version = "0.27", default-features = false }
serde = { version = "1", optional = true, features = ["derive"] }

duplicate = "1.0"
paste = "1.0"

[dev-dependencies]
eframe = { version = "0.26", default-features = false, features = [
eframe = { version = "0.27", default-features = false, features = [
"default_fonts",
"glow",
] }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Add `egui` and `egui_dock` to your project's dependencies.
```toml
[dependencies]
egui = "0.26"
egui_dock = "0.11"
egui_dock = "0.12"
```

Then proceed by setting up `egui`, following its [quick start guide](https:/emilk/egui#quick-start).
Expand Down
6 changes: 5 additions & 1 deletion examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::collections::HashSet;

use eframe::{egui, NativeOptions};
use eframe::NativeOptions;
use egui::{
color_picker::{color_edit_button_srgba, Alpha},
vec2, CentralPanel, ComboBox, Frame, Rounding, Slider, TopBottomPanel, Ui, ViewportBuilder,
Expand Down Expand Up @@ -197,6 +197,10 @@ impl MyContext {
Alpha::OnlyBlend,
);
ui.end_row();

ui.label("Rounding:");
rounding_ui(ui, &mut style.main_surface_border_rounding);
ui.end_row();
});
});

Expand Down
13 changes: 12 additions & 1 deletion src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub enum TabAddAlign {
/// #
/// ```
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[allow(missing_docs)]
pub struct Style {
/// Sets padding to indent from the edges of the window. By `Default` it's `None`.
Expand All @@ -63,6 +64,7 @@ pub struct Style {

/// Specifies the look and feel of buttons.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ButtonsStyle {
/// Color of the close tab button.
pub close_tab_color: Color32,
Expand Down Expand Up @@ -91,6 +93,7 @@ pub struct ButtonsStyle {

/// Specifies the look and feel of node separators.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct SeparatorStyle {
/// Width of the rectangle separator between nodes. By `Default` it's `1.0`.
pub width: f32,
Expand All @@ -115,6 +118,7 @@ pub struct SeparatorStyle {

/// Specifies the look and feel of tab bars.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TabBarStyle {
/// Background color of tab bar. By `Default` it's [`Color32::WHITE`].
pub bg_fill: Color32,
Expand All @@ -138,6 +142,7 @@ pub struct TabBarStyle {

/// Specifies the look and feel of an individual tab.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TabStyle {
/// Style of the tab when it is active.
pub active: TabInteractionStyle,
Expand Down Expand Up @@ -177,6 +182,7 @@ pub struct TabStyle {

/// Specifies the look and feel of individual tabs while they are being interacted with.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TabInteractionStyle {
/// Color of the outline around tabs. By `Default` it's [`Color32::BLACK`].
pub outline_color: Color32,
Expand All @@ -193,6 +199,7 @@ pub struct TabInteractionStyle {

/// Specifies the look and feel of the tab body.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct TabBodyStyle {
/// Inner margin of tab body. By `Default` it's `Margin::same(4.0)`.
pub inner_margin: Margin,
Expand All @@ -209,6 +216,7 @@ pub struct TabBodyStyle {

/// Specifies the look and feel of the tab drop overlay.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct OverlayStyle {
/// Sets selection color for the placing area of the tab where this tab targeted on it.
/// By `Default` it's `(0, 191, 255)` (light blue) with `0.5` capacity.
Expand Down Expand Up @@ -246,6 +254,7 @@ pub struct OverlayStyle {

/// Specifies the feel of the tab drop overlay, i.e anything non visual about the overlay.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct OverlayFeel {
/// range is `0.0..=1.0`.
pub window_drop_coverage: f32,
Expand All @@ -264,7 +273,8 @@ pub struct OverlayFeel {
}

/// Specifies the type of overlay used.
#[derive(Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum OverlayType {
/// Shows highlighted areas predicting where a dropped tab would land were it to be dropped this frame.
///
Expand All @@ -279,6 +289,7 @@ pub enum OverlayType {

/// Highlighting on the currently hovered leaf.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct LeafHighlighting {
/// Fill color.
pub color: Color32,
Expand Down
48 changes: 26 additions & 22 deletions src/widgets/dock_area/drag_and_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::{
AllowedSplits, NodeIndex, Split, Style, SurfaceIndex, TabDestination, TabIndex, TabInsert,
};
use egui::{
emath::inverse_lerp, vec2, Context, Id, LayerId, NumExt, Order, Pos2, Rect, Stroke, Ui, Vec2,
emath::inverse_lerp, vec2, Context, Id, LayerId, NumExt, Order, Painter, Pos2, Rect, Stroke,
Ui, Vec2,
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -67,8 +68,15 @@ impl TreeComponent {
}
}

fn make_overlay_painter(ui: &Ui) -> Painter {
let id = Id::new("overlay");
let layer_id = LayerId::new(Order::Foreground, id);
ui.ctx().layer_painter(layer_id)
}

fn draw_highlight_rect(rect: Rect, ui: &Ui, style: &Style) {
ui.painter().rect(
let painter = make_overlay_painter(ui);
painter.rect(
rect.expand(style.overlay.hovered_leaf_highlight.expansion),
style.overlay.hovered_leaf_highlight.rounding,
style.overlay.hovered_leaf_highlight.color,
Expand All @@ -87,7 +95,7 @@ fn button_ui(
) -> bool {
let visuals = &style.overlay;
let button_stroke = Stroke::new(1.0, visuals.button_color);
let painter = ui.painter();
let painter = make_overlay_painter(ui);
painter.rect_stroke(rect, 0.0, visuals.button_border_stroke);
let rect = rect.shrink(rect.width() * 0.1);
painter.rect_stroke(rect, 0.0, button_stroke);
Expand Down Expand Up @@ -175,15 +183,9 @@ impl DragDropState {
let shortest_side = ((rect.width() - total_button_spacing) / 3.0)
.min((rect.height() - total_button_spacing) / 3.0)
.min(style.overlay.max_button_size);
let mut offset_vector = vec2(0.0, shortest_side + style.overlay.button_spacing);

let mut destination: Option<TabDestination> = match windows_allowed {
true => Some(TabDestination::Window(Rect::from_min_size(
pointer,
self.drag.rect.size(),
))),
false => None,
};

let mut destination: Option<TabDestination> = windows_allowed
.then(|| TabDestination::Window(Rect::from_min_size(pointer, self.drag.rect.size())));

let center = rect.center();
let rect = Rect::from_center_size(center, Vec2::splat(shortest_side));
Expand All @@ -202,10 +204,17 @@ impl DragDropState {

for split in [Split::Below, Split::Right, Split::Above, Split::Left] {
match allowed_splits {
AllowedSplits::TopBottomOnly if split.is_top_bottom() => continue,
AllowedSplits::LeftRightOnly if split.is_left_right() => continue,
AllowedSplits::TopBottomOnly if !split.is_top_bottom() => continue,
AllowedSplits::LeftRightOnly if !split.is_left_right() => continue,
AllowedSplits::None => continue,
_ => {
let offset_value = shortest_side + style.overlay.button_spacing;
let offset_vector = match split {
Split::Above => vec2(0.0, -offset_value),
Split::Below => vec2(0.0, offset_value),
Split::Left => vec2(-offset_value, 0.0),
Split::Right => vec2(offset_value, 0.0),
};
if button_ui(
Rect::from_center_size(center + offset_vector, Vec2::splat(shortest_side)),
ui,
Expand All @@ -219,7 +228,6 @@ impl DragDropState {
Some(TabDestination::Node(surface, node, TabInsert::Split(split)))
}
}
offset_vector = offset_vector.rot90();
}
}
}
Expand Down Expand Up @@ -384,7 +392,7 @@ impl DragDropState {
pub(super) fn is_locked(&self, style: &Style, ctx: &Context) -> bool {
match self.locked.as_ref() {
Some(lock_time) => {
let elapsed = (ctx.input(|i| i.time) - lock_time) as f32;
let elapsed = ctx.input(|i| (i.time - lock_time) as f32);
ctx.request_repaint();
elapsed < style.overlay.feel.max_preference_time
}
Expand Down Expand Up @@ -413,18 +421,14 @@ const fn lerp_vec(split: Split, alpha: f32) -> Vec2 {
// Draws a filled rect describing where a tab will be dropped.
#[inline(always)]
fn draw_drop_rect(rect: Rect, ui: &Ui, style: &Style) {
let id = Id::new("overlay");
let layer_id = LayerId::new(Order::Foreground, id);
let painter = ui.ctx().layer_painter(layer_id);
let painter = make_overlay_painter(ui);
painter.rect_filled(rect, 0.0, style.overlay.selection_color);
}

// Draws a stroked rect describing where a tab will be dropped.
#[inline(always)]
fn draw_window_rect(rect: Rect, ui: &Ui, style: &Style) {
let id = Id::new("overlay");
let layer_id = LayerId::new(Order::Foreground, id);
let painter = ui.ctx().layer_painter(layer_id);
let painter = make_overlay_painter(ui);
painter.rect_stroke(
rect,
0.0,
Expand Down
5 changes: 0 additions & 5 deletions src/widgets/dock_area/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ mod tab_removal;

use crate::{dock_state::DockState, NodeIndex, Style, SurfaceIndex, TabIndex};
pub use allowed_splits::AllowedSplits;
use drag_and_drop::{DragData, HoverData};
use tab_removal::TabRemoval;

use egui::{emath::*, Id};
Expand All @@ -32,8 +31,6 @@ pub struct DockArea<'tree, Tab> {
allowed_splits: AllowedSplits,
window_bounds: Option<Rect>,

drag_data: Option<DragData>,
hover_data: Option<HoverData>,
to_remove: Vec<TabRemoval>,
to_detach: Vec<(SurfaceIndex, NodeIndex, TabIndex)>,
new_focused: Option<(SurfaceIndex, NodeIndex)>,
Expand All @@ -56,8 +53,6 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
draggable_tabs: true,
show_tab_name_on_hover: false,
allowed_splits: AllowedSplits::default(),
drag_data: None,
hover_data: None,
to_remove: Vec::new(),
to_detach: Vec::new(),
new_focused: None,
Expand Down
Loading

0 comments on commit d637fd1

Please sign in to comment.