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

Change separator color on hover and drag #68

Merged
merged 4 commits into from
Nov 16, 2022
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
- `Tree::tabs`: an iterator over the tabs in a tree. ([#53](https://github.com/Adanos020/egui_dock/pull/53))
- `Style` now includes an option to show the hoverd tab's name. ([#56](https://github.com/Adanos020/egui_dock/pull/56))
- `Style` now includes an option to change default inner_margin. ([#67](https://github.com/Adanos020/egui_dock/pull/67))
- The split separator now highlights on hover ([#68](https://github.com/Adanos020/egui_dock/pull/68))

### Breaking changes
- 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))

### Deprecated (will be deleted in the next release)
- `dynamic_tab::TabContent`
Expand Down
10 changes: 8 additions & 2 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,14 @@ impl MyContext {

ui.separator();

ui.label("Color");
color_picker_color32(ui, &mut style.separator_color, Alpha::OnlyBlend);
ui.label("Idle color");
color_picker_color32(ui, &mut style.separator_color_idle, Alpha::OnlyBlend);

ui.label("Hovered color");
color_picker_color32(ui, &mut style.separator_color_hovered, Alpha::OnlyBlend);

ui.label("Dragged color");
color_picker_color32(ui, &mut style.separator_color_dragged, Alpha::OnlyBlend);
});

ui.collapsing("Tabs", |ui| {
Expand Down
24 changes: 17 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@
//! # });
//! ```

use egui::style::Margin;
use egui::*;
use egui::{
pos2, style::Margin, vec2, Context, CursorIcon, Frame, Id, LayerId, Order, Pos2, Rect,
Rounding, ScrollArea, Sense, Stroke, Ui, WidgetText,
};

#[allow(deprecated)]
pub use crate::{
Expand All @@ -69,7 +71,8 @@ pub use crate::{
tree::{Node, NodeIndex, Split, TabIndex, Tree},
};
pub use egui;
use utils::*;

use utils::expand_to_pixel;

mod dynamic_tab;
mod popup;
Expand Down Expand Up @@ -257,7 +260,7 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
ui.painter().rect(
rect,
margin.top,
style.separator_color,
style.separator_color_idle,
Stroke::new(margin.top, style.border_color),
);
}
Expand Down Expand Up @@ -289,14 +292,21 @@ impl<'tree, Tab> DockArea<'tree, Tab> {
{
let rect = expand_to_pixel(*rect, pixels_per_point);

let (left, separator, right) = if is_horizontal {
let (response, left, separator, right) = if is_horizontal {
style.hsplit(ui, fraction, rect)
} else {
style.vsplit(ui, fraction, rect)
};

ui.painter()
.rect_filled(separator, Rounding::none(), style.separator_color);
let color = if response.dragged() {
style.separator_color_dragged
} else if response.hovered() {
style.separator_color_hovered
} else {
style.separator_color_idle
};

ui.painter().rect_filled(separator, Rounding::none(), color);

self.tree[node_index.left()].set_rect(left);
self.tree[node_index.right()].set_rect(right);
Expand Down
77 changes: 57 additions & 20 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ pub struct Style {

pub separator_width: f32,
pub separator_extra: f32,
pub separator_color: Color32,
pub separator_color_idle: Color32,
emilk marked this conversation as resolved.
Show resolved Hide resolved
pub separator_color_hovered: Color32,
pub separator_color_dragged: Color32,

pub tab_bar_background_color: Color32,

Expand Down Expand Up @@ -65,7 +67,9 @@ impl Default for Style {
selection_color: Color32::from_rgb(0, 191, 255).linear_multiply(0.5),
separator_width: 1.0,
separator_extra: 175.0,
separator_color: Color32::BLACK,
separator_color_idle: Color32::BLACK,
separator_color_hovered: Color32::GRAY,
separator_color_dragged: Color32::WHITE,

tab_bar_background_color: Color32::WHITE,

Expand Down Expand Up @@ -101,18 +105,22 @@ impl Style {
/// Derives relevant fields from `egui::Style` and sets the remaining fields to their default values.
///
/// Fields overwritten by [`egui::Style`] are:
/// - `selection_color`
/// - `tab_bar_background_color`
/// - `tab_outline_color`
/// - `tab_background_color`
/// - `separator_color`
/// - `border_color`
/// - `close_tab_background_color`
/// - `close_tab_color`
/// - `close_tab_active_color`
/// - `add_tab_background_color`
/// - `add_tab_color`
/// - `add_tab_active_color`
/// - [`Self::selection_color`]
/// - [`Self::tab_bar_background_color`]
/// - [`Self::tab_outline_color`]
/// - [`Self::tab_background_color`]
/// - [`Self::tab_text_color_unfocused`]
/// - [`Self::tab_text_color_focused`]
/// - [`Self::separator_color_idle`]
/// - [`Self::separator_color_hovered`]
/// - [`Self::separator_color_dragged`]
/// - [`Self::border_color`]
/// - [`Self::close_tab_background_color`]
/// - [`Self::close_tab_color`]
/// - [`Self::close_tab_active_color`]
/// - [`Self::add_tab_background_color`]
/// - [`Self::add_tab_color`]
/// - [`Self::add_tab_active_color`]
pub fn from_egui(style: &egui::Style) -> Self {
Self {
selection_color: style.visuals.selection.bg_fill.linear_multiply(0.5),
Expand All @@ -124,7 +132,10 @@ impl Style {
tab_text_color_unfocused: style.visuals.text_color(),
tab_text_color_focused: style.visuals.strong_text_color(),

separator_color: style.visuals.widgets.active.bg_fill,
separator_color_idle: style.visuals.widgets.noninteractive.bg_stroke.color,
separator_color_hovered: style.visuals.widgets.hovered.bg_stroke.color,
separator_color_dragged: style.visuals.widgets.active.bg_stroke.color,
emilk marked this conversation as resolved.
Show resolved Hide resolved

border_color: style.visuals.widgets.active.bg_fill,

close_tab_background_color: style.visuals.widgets.active.bg_fill,
Expand All @@ -138,7 +149,12 @@ impl Style {
}
}

pub(crate) fn hsplit(&self, ui: &mut Ui, fraction: &mut f32, rect: Rect) -> (Rect, Rect, Rect) {
pub(crate) fn hsplit(
&self,
ui: &mut Ui,
fraction: &mut f32,
rect: Rect,
) -> (Response, Rect, Rect, Rect) {
let pixels_per_point = ui.ctx().pixels_per_point();

let mut separator = rect;
Expand Down Expand Up @@ -173,13 +189,19 @@ impl Style {
);

(
response,
rect.intersect(Rect::everything_right_of(separator.max.x)),
separator,
rect.intersect(Rect::everything_left_of(separator.min.x)),
)
}

pub(crate) fn vsplit(&self, ui: &mut Ui, fraction: &mut f32, rect: Rect) -> (Rect, Rect, Rect) {
pub(crate) fn vsplit(
&self,
ui: &mut Ui,
fraction: &mut f32,
rect: Rect,
) -> (Response, Rect, Rect, Rect) {
let pixels_per_point = ui.ctx().pixels_per_point();

let mut separator = rect;
Expand Down Expand Up @@ -214,6 +236,7 @@ impl Style {
);

(
response,
rect.intersect(Rect::everything_above(separator.min.y)),
separator,
rect.intersect(Rect::everything_below(separator.max.y)),
Expand Down Expand Up @@ -451,10 +474,24 @@ impl StyleBuilder {
self
}

/// Sets `separator_color`for the rectangle separator. By `Default` it's [`Color32::BLACK`].
/// Sets the idle color for the rectangle separator. By `Default` it's [`Color32::BLACK`].
#[inline(always)]
pub fn with_separator_color_idle(mut self, separator_color_idle: Color32) -> Self {
self.style.separator_color_idle = separator_color_idle;
self
}

/// Sets the hovered color for the rectangle separator. By `Default` it's [`Color32::GRAY`].
#[inline(always)]
pub fn with_separator_color_hovered(mut self, separator_color_hovered: Color32) -> Self {
self.style.separator_color_hovered = separator_color_hovered;
self
}

/// Sets the dragged color for the rectangle separator. By `Default` it's [`Color32::WHITE`].
#[inline(always)]
pub fn with_separator_color(mut self, separator_color: Color32) -> Self {
self.style.separator_color = separator_color;
pub fn with_separator_color_dragged(mut self, separator_color_dragged: Color32) -> Self {
emilk marked this conversation as resolved.
Show resolved Hide resolved
self.style.separator_color_dragged = separator_color_dragged;
self
}

Expand Down
2 changes: 1 addition & 1 deletion src/tree.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use egui::*;
use egui::Rect;

/// Identifies a tab within a [`Node`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
Expand Down
6 changes: 3 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use egui::*;
use egui::{Pos2, Rect};

#[inline(always)]
pub fn expand_to_pixel(mut rect: Rect, ppi: f32) -> egui::Rect {
pub fn expand_to_pixel(mut rect: Rect, ppi: f32) -> Rect {
rect.min = map_to_pixel_pos(rect.min, ppi, f32::floor);
rect.max = map_to_pixel_pos(rect.max, ppi, f32::ceil);
rect
}

#[inline(always)]
pub fn map_to_pixel_pos(mut pos: Pos2, ppi: f32, map: fn(f32) -> f32) -> egui::Pos2 {
pub fn map_to_pixel_pos(mut pos: Pos2, ppi: f32, map: fn(f32) -> f32) -> Pos2 {
pos.x = map_to_pixel(pos.x, ppi, map);
pos.y = map_to_pixel(pos.y, ppi, map);
pos
Expand Down