Add overline option for Table rows (#5637)

* Closes no issue, I just needed this for an app and figured it could be
useful.
* [x] I have followed the instructions in the PR template

This PR adds an `overline` option for `egui_extras::TableRow`, which is
useful for visually grouping rows. The overline consumes no layout
space.

A screenshot of the demo app, showing every 7th row getting an overline.

<img width="704" alt="Screenshot 2025-01-25 at 14 40 08"
src="https://github.com/user-attachments/assets/9ccbee3d-296d-4afd-9290-c669e4ede1c0"
/>

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
Aarni Koskela 2025-04-08 12:36:43 +03:00 committed by GitHub
parent 565966b3c9
commit 36e007bd8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 31 additions and 2 deletions

View File

@ -13,6 +13,7 @@ enum DemoType {
pub struct TableDemo {
demo: DemoType,
striped: bool,
overline: bool,
resizable: bool,
clickable: bool,
num_rows: usize,
@ -28,6 +29,7 @@ impl Default for TableDemo {
Self {
demo: DemoType::Manual,
striped: true,
overline: true,
resizable: true,
clickable: true,
num_rows: 10_000,
@ -65,6 +67,7 @@ impl crate::View for TableDemo {
ui.vertical(|ui| {
ui.horizontal(|ui| {
ui.checkbox(&mut self.striped, "Striped");
ui.checkbox(&mut self.overline, "Overline some rows");
ui.checkbox(&mut self.resizable, "Resizable columns");
ui.checkbox(&mut self.clickable, "Clickable rows");
});
@ -212,6 +215,7 @@ impl TableDemo {
let row_height = if is_thick { 30.0 } else { 18.0 };
body.row(row_height, |mut row| {
row.set_selected(self.selection.contains(&row_index));
row.set_overline(self.overline && row_index % 7 == 3);
row.col(|ui| {
ui.label(row_index.to_string());
@ -247,6 +251,7 @@ impl TableDemo {
};
row.set_selected(self.selection.contains(&row_index));
row.set_overline(self.overline && row_index % 7 == 3);
row.col(|ui| {
ui.label(row_index.to_string());
@ -280,6 +285,7 @@ impl TableDemo {
};
row.set_selected(self.selection.contains(&row_index));
row.set_overline(self.overline && row_index % 7 == 3);
row.col(|ui| {
ui.label(row_index.to_string());

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:13115759157beb57febcff4be6f1710340736108b520e9ad3efb04be3cedcf7b
size 68767
oid sha256:9446da28768cae0b489e0f6243410a8b3acf0ca2a0b70690d65d2a6221bc25b9
size 30517

View File

@ -33,6 +33,7 @@ pub(crate) struct StripLayoutFlags {
pub(crate) striped: bool,
pub(crate) hovered: bool,
pub(crate) selected: bool,
pub(crate) overline: bool,
/// Used when we want to accruately measure the size of this cell.
pub(crate) sizing_pass: bool,
@ -232,6 +233,14 @@ impl<'l> StripLayout<'l> {
child_ui.style_mut().visuals.override_text_color = Some(stroke_color);
}
if flags.overline {
child_ui.painter().hline(
max_rect.x_range(),
max_rect.top(),
child_ui.visuals().widgets.noninteractive.bg_stroke,
);
}
add_cell_contents(&mut child_ui);
child_ui

View File

@ -507,6 +507,7 @@ impl<'a> TableBuilder<'a> {
striped: false,
hovered: false,
selected: false,
overline: false,
response: &mut response,
});
layout.allocate_rect();
@ -990,6 +991,7 @@ impl<'a> TableBody<'a> {
striped: self.striped && self.row_index % 2 == 0,
hovered: self.hovered_row_index == Some(self.row_index),
selected: false,
overline: false,
response: &mut response,
});
self.capture_hover_state(&response, self.row_index);
@ -1071,6 +1073,7 @@ impl<'a> TableBody<'a> {
striped: self.striped && (row_index + self.row_index) % 2 == 0,
hovered: self.hovered_row_index == Some(row_index),
selected: false,
overline: false,
response: &mut response,
});
self.capture_hover_state(&response, row_index);
@ -1152,6 +1155,7 @@ impl<'a> TableBody<'a> {
striped: self.striped && (row_index + self.row_index) % 2 == 0,
hovered: self.hovered_row_index == Some(row_index),
selected: false,
overline: false,
response: &mut response,
});
self.capture_hover_state(&response, row_index);
@ -1173,6 +1177,7 @@ impl<'a> TableBody<'a> {
height: row_height,
striped: self.striped && (row_index + self.row_index) % 2 == 0,
hovered: self.hovered_row_index == Some(row_index),
overline: false,
selected: false,
response: &mut response,
});
@ -1260,6 +1265,7 @@ pub struct TableRow<'a, 'b> {
striped: bool,
hovered: bool,
selected: bool,
overline: bool,
response: &'b mut Option<Response>,
}
@ -1297,6 +1303,7 @@ impl TableRow<'_, '_> {
striped: self.striped,
hovered: self.hovered,
selected: self.selected,
overline: self.overline,
sizing_pass: auto_size_this_frame || self.layout.ui.is_sizing_pass(),
};
@ -1333,6 +1340,13 @@ impl TableRow<'_, '_> {
self.hovered = hovered;
}
/// Set the overline state for this row. The overline is a line above the row,
/// usable for e.g. visually grouping rows.
#[inline]
pub fn set_overline(&mut self, overline: bool) {
self.overline = overline;
}
/// Returns a union of the [`Response`]s of the cells added to the row up to this point.
///
/// You need to add at least one row to the table before calling this function.