1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use crate::{vec2, Response, Sense, Ui, Vec2, Widget};
/// A visual separator. A horizontal or vertical line (depending on [`crate::Layout`]).
///
/// Usually you'd use the shorter version [`Ui::separator`].
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// // These are equivalent:
/// ui.separator();
/// ui.add(egui::Separator::default());
/// # });
/// ```
#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
pub struct Separator {
spacing: f32,
grow: f32,
is_horizontal_line: Option<bool>,
}
impl Default for Separator {
fn default() -> Self {
Self {
spacing: 6.0,
grow: 0.0,
is_horizontal_line: None,
}
}
}
impl Separator {
/// How much space we take up. The line is painted in the middle of this.
///
/// In a vertical layout, with a horizontal Separator,
/// this is the height of the separator widget.
///
/// In a horizontal layout, with a vertical Separator,
/// this is the width of the separator widget.
#[inline]
pub fn spacing(mut self, spacing: f32) -> Self {
self.spacing = spacing;
self
}
/// Explicitly ask for a horizontal line.
///
/// By default you will get a horizontal line in vertical layouts,
/// and a vertical line in horizontal layouts.
#[inline]
pub fn horizontal(mut self) -> Self {
self.is_horizontal_line = Some(true);
self
}
/// Explicitly ask for a vertical line.
///
/// By default you will get a horizontal line in vertical layouts,
/// and a vertical line in horizontal layouts.
#[inline]
pub fn vertical(mut self) -> Self {
self.is_horizontal_line = Some(false);
self
}
/// Extend each end of the separator line by this much.
///
/// The default is to take up the available width/height of the parent.
///
/// This will make the line extend outside the parent ui.
#[inline]
pub fn grow(mut self, extra: f32) -> Self {
self.grow += extra;
self
}
/// Contract each end of the separator line by this much.
///
/// The default is to take up the available width/height of the parent.
///
/// This effectively adds margins to the line.
#[inline]
pub fn shrink(mut self, shrink: f32) -> Self {
self.grow -= shrink;
self
}
}
impl Widget for Separator {
fn ui(self, ui: &mut Ui) -> Response {
let Self {
spacing,
grow,
is_horizontal_line,
} = self;
let is_horizontal_line = is_horizontal_line
.unwrap_or_else(|| ui.is_grid() || !ui.layout().main_dir().is_horizontal());
let available_space = if ui.is_sizing_pass() {
Vec2::ZERO
} else {
ui.available_size_before_wrap()
};
let size = if is_horizontal_line {
vec2(available_space.x, spacing)
} else {
vec2(spacing, available_space.y)
};
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
if ui.is_rect_visible(response.rect) {
let stroke = ui.visuals().widgets.noninteractive.bg_stroke;
let painter = ui.painter();
if is_horizontal_line {
painter.hline(
(rect.left() - grow)..=(rect.right() + grow),
painter.round_to_pixel_center(rect.center().y),
stroke,
);
} else {
painter.vline(
painter.round_to_pixel_center(rect.center().x),
(rect.top() - grow)..=(rect.bottom() + grow),
stroke,
);
}
}
response
}
}