Collaping header and indent: add a closing horizontal line

This commit is contained in:
Emil Ernerfeldt 2021-02-03 00:55:53 +01:00
parent 829455b347
commit c536e1b0da
4 changed files with 56 additions and 10 deletions

View file

@ -254,7 +254,14 @@ impl CollapsingHeader {
header_response,
mut state,
} = self.begin(ui);
let ret_response = state.add_contents(ui, id, |ui| ui.indent(id, add_contents).0);
let ret_response = state.add_contents(ui, id, |ui| {
ui.indent(id, |ui| {
// make as wide as the header:
ui.expand_to_include_x(header_response.rect.right());
add_contents(ui)
})
.0
});
ui.memory().collapsing_headers.insert(id, state);
if let Some((ret, response)) = ret_response {

View file

@ -60,6 +60,16 @@ impl Region {
self.min_rect = self.min_rect.union(rect);
self.max_rect = self.max_rect.union(rect);
}
/// Ensure we are big enough to contain the given x-coordinate.
/// This is sometimes useful to expand an ui to stretch to a certain place.
pub fn expand_to_include_x(&mut self, x: f32) {
self.min_rect.min.x = self.min_rect.min.x.min(x);
self.min_rect.max.x = self.min_rect.max.x.max(x);
self.max_rect.min.x = self.max_rect.min.x.min(x);
self.max_rect.max.x = self.max_rect.max.x.max(x);
}
}
// ----------------------------------------------------------------------------

View file

@ -118,12 +118,16 @@ impl Placer {
}
/// Advance the cursor by this many points.
/// [`Self::min_rect`] will expand to contain the cursor.
pub(crate) fn advance_cursor(&mut self, amount: f32) {
debug_assert!(
self.grid.is_none(),
"You cannot advance the cursor when in a grid layout"
);
self.layout.advance_cursor(&mut self.region.cursor, amount)
self.layout.advance_cursor(&mut self.region.cursor, amount);
self.region
.expand_to_include_rect(Rect::from_min_size(self.cursor(), Vec2::zero()));
}
/// Advance cursor after a widget was added to a specific rectangle
@ -167,6 +171,11 @@ impl Placer {
self.region.expand_to_include_rect(rect);
}
/// Expand the `min_rect` and `max_rect` of this ui to include a child at the given x-coordinate.
pub(crate) fn expand_to_include_x(&mut self, x: f32) {
self.region.expand_to_include_x(x);
}
/// Set the maximum width of the ui.
/// You won't be able to shrink it below the current minimum size.
pub(crate) fn set_max_width(&mut self, width: f32) {

View file

@ -311,6 +311,12 @@ impl Ui {
self.set_max_width(width);
}
/// Ensure we are big enough to contain the given x-coordinate.
/// This is sometimes useful to expand an ui to stretch to a certain place.
pub fn expand_to_include_x(&mut self, x: f32) {
self.placer.expand_to_include_x(x);
}
// ------------------------------------------------------------------------
// Layout related measures:
@ -426,8 +432,11 @@ impl Ui {
// Stuff that moves the cursor, i.e. allocates space in this ui!
/// Advance the cursor (where the next widget is put) by this many points.
///
/// The direction is dependent on the layout.
/// This is useful for creating some extra space between widgets.
///
/// [`Self::min_rect`] will expand to contain the cursor.
pub fn advance_cursor(&mut self, amount: f32) {
self.placer.advance_cursor(amount);
}
@ -965,16 +974,27 @@ impl Ui {
..self.child_ui(child_rect, *self.layout())
};
let ret = add_contents(&mut child_ui);
let end_with_horizontal_line = true;
if end_with_horizontal_line {
child_ui.advance_cursor(4.0);
}
let size = child_ui.min_size();
// draw a grey line on the left to mark the indented section
let line_start = child_rect.min - indent * 0.5;
let line_start = self.painter().round_pos_to_pixels(line_start);
let line_end = pos2(line_start.x, line_start.y + size.y - 2.0);
self.painter.line_segment(
[line_start, line_end],
self.visuals().widgets.noninteractive.bg_stroke,
);
// draw a faint line on the left to mark the indented section
let stroke = self.visuals().widgets.noninteractive.bg_stroke;
let left_top = child_rect.min - indent * 0.5;
let left_top = self.painter().round_pos_to_pixels(left_top);
let left_bottom = pos2(left_top.x, left_top.y + size.y - 2.0);
let left_bottom = self.painter().round_pos_to_pixels(left_bottom);
self.painter.line_segment([left_top, left_bottom], stroke);
if end_with_horizontal_line {
let fudge = 2.0; // looks nicer with button rounding in collapsing headers
let right_bottom = pos2(child_ui.min_rect().right() - fudge, left_bottom.y);
self.painter
.line_segment([left_bottom, right_bottom], stroke);
}
let response = self.allocate_response(indent + size, Sense::hover());
(ret, response)