Center window titles

This commit is contained in:
Emil Ernerfeldt 2021-01-10 10:41:04 +01:00
parent 430fcd9e91
commit e079ac5b46
4 changed files with 55 additions and 20 deletions

View File

@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed 🔧
* Center window titles.
* Tweak size and alignment of some emojis to match other text.
### Fixed 🐛

View File

@ -1,6 +1,6 @@
//! One- and two-dimensional alignment ([`Align::Center`], [`LEFT_TOP`] etc).
use crate::math::{pos2, Rect};
use crate::math::*;
/// left/center/right or top/center/bottom alignment for e.g. anchors and `Layout`s.
#[derive(Clone, Copy, Debug, PartialEq)]
@ -77,3 +77,23 @@ pub(crate) fn anchor_rect(rect: Rect, anchor: (Align, Align)) -> Rect {
};
Rect::from_min_size(pos2(x, y), rect.size())
}
/// e.g. center a size within a given frame
pub fn align_size_within_rect(align: (Align, Align), size: Vec2, frame: Rect) -> Rect {
let x = match align.0 {
Align::Min => frame.left(),
Align::Center => frame.center().x - size.x / 2.0,
Align::Max => frame.right() - size.x,
};
let y = match align.1 {
Align::Min => frame.top(),
Align::Center => frame.center().y - size.y / 2.0,
Align::Max => frame.bottom() - size.y,
};
Rect::from_min_size(Pos2::new(x, y), size)
}
pub fn center_size_in_rect(size: Vec2, frame: Rect) -> Rect {
align_size_within_rect(CENTER_CENTER, size, frame)
}

View File

@ -632,7 +632,7 @@ struct TitleBar {
id: Id,
title_label: Label,
title_galley: Galley,
title_rect: Rect,
min_rect: Rect,
rect: Rect,
}
@ -645,7 +645,8 @@ fn show_title_bar(
collapsible: bool,
) -> TitleBar {
let (title_bar, response) = ui.horizontal(|ui| {
ui.set_min_height(title_label.font_height(ui.fonts(), ui.style()));
let height = title_label.font_height(ui.fonts(), ui.style());
ui.set_min_height(height);
let item_spacing = ui.style().spacing.item_spacing;
let button_size = ui.style().spacing.icon_width;
@ -663,27 +664,22 @@ fn show_title_bar(
}
let title_galley = title_label.layout(ui);
let (id, title_rect) = ui.allocate_space(title_galley.size);
if show_close_button {
// Reserve space for close button which will be added later (once we know our full width):
let close_max_x = title_rect.right() + item_spacing.x + button_size + item_spacing.x;
let close_max_x = close_max_x.max(ui.max_rect_finite().right());
let close_rect = Rect::from_min_size(
pos2(
close_max_x - button_size,
title_rect.center().y - 0.5 * button_size,
),
Vec2::splat(button_size),
);
ui.expand_to_include_rect(close_rect);
}
let minimum_width = if collapsible || show_close_button {
// If at least one button is shown we make room for both buttons (since title is centered)
let space_x = item_spacing.x;
space_x + button_size + space_x + title_galley.size.x + space_x + button_size + space_x
} else {
item_spacing.x + title_galley.size.x + item_spacing.x
};
let min_rect = Rect::from_min_size(ui.min_rect().min, vec2(minimum_width, height));
let id = ui.advance_cursor_after_rect(min_rect);
TitleBar {
id,
title_label,
title_galley,
title_rect,
min_rect,
rect: Rect::invalid(), // Will be filled in later
}
});
@ -716,9 +712,18 @@ impl TitleBar {
}
}
// TODO: pick style for title based on move interaction
let style = if ui.ui_contains_mouse() {
ui.style().visuals.widgets.hovered
} else {
ui.style().visuals.widgets.inactive
};
self.title_label = self.title_label.text_color(style.fg_stroke.color);
let full_top_rect = Rect::from_x_y_ranges(self.rect.x_range(), self.min_rect.y_range());
let text_pos = align::center_size_in_rect(self.title_galley.size, full_top_rect);
let text_pos = text_pos.left_top() - 2.0 * Vec2::Y; // HACK: center on x-height of text (looks better)
self.title_label
.paint_galley(ui, self.title_rect.min, self.title_galley);
.paint_galley(ui, text_pos, self.title_galley);
if let Some(content_response) = &content_response {
// paint separator between title and content:
@ -760,6 +765,8 @@ fn close_button(ui: &mut Ui, rect: Rect) -> Response {
let response = ui.interact(rect, close_id, Sense::click());
ui.expand_to_include_rect(response.rect);
let rect = rect.shrink(2.0);
let stroke = ui.style().interact(&response).fg_stroke;
ui.painter()
.line_segment([rect.left_top(), rect.right_bottom()], stroke);

View File

@ -56,6 +56,13 @@ impl Rect {
}
}
pub fn from_x_y_ranges(x_range: RangeInclusive<f32>, y_range: RangeInclusive<f32>) -> Self {
Rect {
min: pos2(*x_range.start(), *y_range.start()),
max: pos2(*x_range.end(), *y_range.end()),
}
}
/// Expand by this much in each direction, keeping the center
#[must_use]
pub fn expand(self, amnt: f32) -> Self {