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.12 #235

Merged
merged 17 commits into from
Apr 5, 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
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://github.com/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://github.com/Adanos020/egui_dock/pull/225):
### Fixed

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

## 0.11.0 - 2024-02-06

### Added

- `filter_map_tabs`, `filter_tabs`, and `retain_tabs` ([#217](https://github.com/Adanos020/egui_dock/pull/217))
- `filter_map_tabs`, `filter_tabs`, and `retain_tabs`. ([#217](https://github.com/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://github.com/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
Loading