Change separator color on hover and drag (#68)

* Change separator color on hover and drag

* Document what Style::from_egui does

* Update changelog

* Replace glob `use` statements with specific imports
This commit is contained in:
Emil Ernerfeldt
2022-11-16 11:08:34 +00:00
committed by GitHub
parent 041e5f362c
commit 5f6a431841
6 changed files with 88 additions and 33 deletions
+2
View File
@@ -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`
+8 -2
View File
@@ -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| {
+17 -7
View File
@@ -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::{
@@ -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;
@@ -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),
);
}
@@ -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);
+57 -20
View File
@@ -22,7 +22,9 @@ pub struct Style {
pub separator_width: f32,
pub separator_extra: f32,
pub separator_color: Color32,
pub separator_color_idle: Color32,
pub separator_color_hovered: Color32,
pub separator_color_dragged: Color32,
pub tab_bar_background_color: Color32,
@@ -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,
@@ -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),
@@ -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,
border_color: style.visuals.widgets.active.bg_fill,
close_tab_background_color: style.visuals.widgets.active.bg_fill,
@@ -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;
@@ -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;
@@ -214,6 +236,7 @@ impl Style {
);
(
response,
rect.intersect(Rect::everything_above(separator.min.y)),
separator,
rect.intersect(Rect::everything_below(separator.max.y)),
@@ -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(mut self, separator_color: Color32) -> Self {
self.style.separator_color = separator_color;
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_dragged(mut self, separator_color_dragged: Color32) -> Self {
self.style.separator_color_dragged = separator_color_dragged;
self
}
+1 -1
View File
@@ -1,4 +1,4 @@
use egui::*;
use egui::Rect;
/// Identifies a tab within a [`Node`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
+3 -3
View File
@@ -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