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

Highlight the header of the topmost Window #3515

Merged
merged 18 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
7 changes: 7 additions & 0 deletions crates/egui/src/containers/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub struct Frame {

pub fill: Color32,

pub selected_header_color: Color32,
emilk marked this conversation as resolved.
Show resolved Hide resolved

pub stroke: Stroke,
}

Expand Down Expand Up @@ -69,6 +71,7 @@ impl Frame {
rounding: style.visuals.window_rounding,
shadow: style.visuals.window_shadow,
fill: style.visuals.window_fill(),
selected_header_color: style.visuals.window_selected_header_color(),
stroke: style.visuals.window_stroke(),
..Default::default()
}
Expand All @@ -80,6 +83,7 @@ impl Frame {
rounding: style.visuals.menu_rounding,
shadow: style.visuals.popup_shadow,
fill: style.visuals.window_fill(),
selected_header_color: style.visuals.window_selected_header_color(),
stroke: style.visuals.window_stroke(),
..Default::default()
}
Expand All @@ -91,6 +95,7 @@ impl Frame {
rounding: style.visuals.menu_rounding,
shadow: style.visuals.popup_shadow,
fill: style.visuals.window_fill(),
selected_header_color: style.visuals.window_selected_header_color(),
stroke: style.visuals.window_stroke(),
..Default::default()
}
Expand All @@ -105,6 +110,7 @@ impl Frame {
inner_margin: Margin::same(2.0),
rounding: style.visuals.widgets.noninteractive.rounding,
fill: style.visuals.extreme_bg_color,
selected_header_color: style.visuals.window_selected_header_color(),
stroke: style.visuals.window_stroke(),
..Default::default()
}
Expand Down Expand Up @@ -232,6 +238,7 @@ impl Frame {
rounding,
shadow,
fill,
selected_header_color: _,
stroke,
} = *self;

Expand Down
39 changes: 32 additions & 7 deletions crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,19 @@ impl<'open> Window<'open> {
let resize = resize.resizable(false); // We move it manually
let mut resize = resize.id(resize_id);

let on_top = Some(area_layer_id) == ctx.get_top_layer_id();
let mut area = area.begin(ctx);

let title_content_spacing = 2.0 * ctx.style().spacing.item_spacing.y;

// Calculate roughly how much larger the window size is compared to the inner rect
let title_bar_height = if with_title_bar {
let style = ctx.style();
ctx.fonts(|f| title.font_height(f, &style)) + title_content_spacing * 2.0
Copy link

@margual56 margual56 Feb 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (the * 2.0) is the culprit. When set to 1.0, the result is the expected one:

image

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why only your window is broken, and no other one on egui.rs

Maybe you can make a PR to fix it?

} else {
0.0
};

// First interact (move etc) to avoid frame delay:
let last_frame_outer_rect = area.state().rect();
let interaction = if possible.movable || possible.resizable() {
Expand All @@ -365,13 +374,6 @@ impl<'open> Window<'open> {
last_frame_outer_rect,
)
.and_then(|window_interaction| {
// Calculate roughly how much larger the window size is compared to the inner rect
let title_bar_height = if with_title_bar {
let style = ctx.style();
ctx.fonts(|f| title.font_height(f, &style)) + title_content_spacing
} else {
0.0
};
let margins = frame.outer_margin.sum()
+ frame.inner_margin.sum()
+ vec2(0.0, title_bar_height);
Expand Down Expand Up @@ -434,6 +436,29 @@ impl<'open> Window<'open> {
// END FRAME --------------------------------

if let Some(title_bar) = title_bar {
if on_top {
let rect = Rect::from_min_size(
outer_rect.min,
Vec2 {
x: outer_rect.size().x,
y: title_bar_height,
},
);
let mut round = area_content_ui.visuals().window_rounding;
if !is_collapsed {
round.se = 0.0;
round.sw = 0.0;
}
let (r, g, b, _) = area_content_ui
.visuals()
.window_selected_header_color()
.to_tuple();
let selected_color = Color32::from_rgba_unmultiplied(r, g, b, 128);

area_content_ui
.painter()
.rect_filled(rect, round, selected_color);
};
title_bar.ui(
&mut area_content_ui,
outer_rect,
Expand Down
5 changes: 5 additions & 0 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,11 @@ impl Context {
self.memory_mut(|mem| mem.areas.move_to_top(layer_id));
}

/// Retrieve the `LayerId` of the top level windows.
pub fn get_top_layer_id(&self) -> Option<LayerId> {
GuillaumeSchmid marked this conversation as resolved.
Show resolved Hide resolved
self.memory(|mem| mem.areas.get_top_layer_id(Order::Middle))
}

pub(crate) fn rect_contains_pointer(&self, layer_id: LayerId, rect: Rect) -> bool {
rect.is_positive() && {
let pointer_pos = self.input(|i| i.pointer.interact_pos());
Expand Down
10 changes: 9 additions & 1 deletion crates/egui/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use epaint::{emath::Rangef, vec2, Vec2};

use crate::{area, window, EventFilter, Id, IdMap, InputState, LayerId, Pos2, Rect, Style};
use crate::{area, window, EventFilter, Id, IdMap, InputState, LayerId, Order, Pos2, Rect, Style};

// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -819,6 +819,14 @@ impl Areas {
}
}

pub fn get_top_layer_id(&self, order: Order) -> Option<LayerId> {
GuillaumeSchmid marked this conversation as resolved.
Show resolved Hide resolved
self.order
.iter()
.filter(|layer| layer.order == order)
.last()
.copied()
}

pub(crate) fn end_frame(&mut self) {
let Self {
visible_last_frame,
Expand Down
11 changes: 11 additions & 0 deletions crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ pub struct Visuals {

pub window_rounding: Rounding,
pub window_shadow: Shadow,
pub window_selected_header_color: Color32,
pub window_fill: Color32,
pub window_stroke: Stroke,

Expand Down Expand Up @@ -587,6 +588,12 @@ impl Visuals {
self.window_fill
}

/// Window selected header color.
#[inline(always)]
pub fn window_selected_header_color(&self) -> Color32 {
self.window_selected_header_color
}

#[inline(always)]
pub fn window_stroke(&self) -> Stroke {
self.window_stroke
Expand Down Expand Up @@ -845,6 +852,7 @@ impl Visuals {
window_rounding: Rounding::same(6.0),
window_shadow: Shadow::big_dark(),
window_fill: Color32::from_gray(27),
window_selected_header_color: Color32::from_gray(64),
window_stroke: Stroke::new(1.0, Color32::from_gray(60)),

menu_rounding: Rounding::same(6.0),
Expand Down Expand Up @@ -885,6 +893,7 @@ impl Visuals {

window_shadow: Shadow::big_light(),
window_fill: Color32::from_gray(248),
window_selected_header_color: Color32::from_rgb(32, 64, 255),
emilk marked this conversation as resolved.
Show resolved Hide resolved
window_stroke: Stroke::new(1.0, Color32::from_gray(190)),

panel_fill: Color32::from_gray(248),
Expand Down Expand Up @@ -1421,6 +1430,7 @@ impl Visuals {
window_rounding,
window_shadow,
window_fill,
window_selected_header_color,
window_stroke,

menu_rounding,
Expand Down Expand Up @@ -1448,6 +1458,7 @@ impl Visuals {
ui.collapsing("Background Colors", |ui| {
ui_color(ui, &mut widgets.inactive.weak_bg_fill, "Buttons");
ui_color(ui, window_fill, "Windows");
ui_color(ui, window_selected_header_color, "Selected window");
ui_color(ui, panel_fill, "Panels");
ui_color(ui, faint_bg_color, "Faint accent").on_hover_text(
"Used for faint accentuation of interactive things, like striped grids.",
Expand Down
11 changes: 3 additions & 8 deletions crates/egui_demo_lib/src/demo/window_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub struct WindowOptions {
closable: bool,
collapsible: bool,
resizable: bool,
constrain: bool,
emilk marked this conversation as resolved.
Show resolved Hide resolved
scroll2: [bool; 2],
disabled_time: f64,

Expand All @@ -23,7 +22,6 @@ impl Default for WindowOptions {
closable: true,
collapsible: true,
resizable: true,
constrain: true,
scroll2: [true; 2],
disabled_time: f64::NEG_INFINITY,
anchored: false,
Expand All @@ -45,7 +43,6 @@ impl super::Demo for WindowOptions {
closable,
collapsible,
resizable,
constrain,
scroll2,
disabled_time,
anchored,
Expand All @@ -62,7 +59,6 @@ impl super::Demo for WindowOptions {
let mut window = egui::Window::new(title)
.id(egui::Id::new("demo_window_options")) // required since we change the title
.resizable(resizable)
.constrain(constrain)
.collapsible(collapsible)
.title_bar(title_bar)
.scroll2(scroll2)
Expand All @@ -85,7 +81,6 @@ impl super::View for WindowOptions {
closable,
collapsible,
resizable,
constrain,
scroll2,
disabled_time: _,
anchored,
Expand All @@ -104,8 +99,6 @@ impl super::View for WindowOptions {
ui.checkbox(closable, "closable");
ui.checkbox(collapsible, "collapsible");
ui.checkbox(resizable, "resizable");
ui.checkbox(constrain, "constrain")
.on_hover_text("Constrain window to the screen");
ui.checkbox(&mut scroll2[0], "hscroll");
ui.checkbox(&mut scroll2[1], "vscroll");
});
Expand Down Expand Up @@ -136,7 +129,9 @@ impl super::View for WindowOptions {
});

ui.separator();

let pipo = Some(ui.layer_id()) == ui.ctx().get_top_layer_id();
ui.label(format!("This window has focus: {pipo}."));
ui.separator();
ui.horizontal(|ui| {
if ui.button("Disable for 2 seconds").clicked() {
self.disabled_time = ui.input(|i| i.time);
Expand Down
Loading