egui/widgets/
separator.rs1use crate::{
2 Response, Sense, Ui, Vec2, Widget, vec2,
3 widget_style::{Classes, HasClasses, SeparatorStyle},
4};
5
6#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
18pub struct Separator {
19 spacing: Option<f32>,
20 grow: f32,
21 is_horizontal_line: Option<bool>,
22 classes: Classes,
23}
24
25impl Default for Separator {
26 fn default() -> Self {
27 Self {
28 spacing: None,
29 grow: 0.0,
30 is_horizontal_line: None,
31 classes: Classes::default(),
32 }
33 }
34}
35
36impl Separator {
37 #[inline]
45 pub fn spacing(mut self, spacing: f32) -> Self {
46 self.spacing = Some(spacing);
47 self
48 }
49
50 #[inline]
55 pub fn horizontal(mut self) -> Self {
56 self.is_horizontal_line = Some(true);
57 self
58 }
59
60 #[inline]
65 pub fn vertical(mut self) -> Self {
66 self.is_horizontal_line = Some(false);
67 self
68 }
69
70 #[inline]
76 pub fn grow(mut self, extra: f32) -> Self {
77 self.grow += extra;
78 self
79 }
80
81 #[inline]
87 pub fn shrink(mut self, shrink: f32) -> Self {
88 self.grow -= shrink;
89 self
90 }
91}
92
93impl Widget for Separator {
94 fn ui(self, ui: &mut Ui) -> Response {
95 let Self {
96 spacing,
97 grow,
98 is_horizontal_line,
99 classes,
100 } = self;
101
102 let id = ui.next_auto_id();
104 let response: Option<Response> = ui.ctx().read_response(id);
105 let state = response.map(|r| r.widget_state()).unwrap_or_default();
106 let SeparatorStyle {
107 spacing: spacing_style,
108 stroke,
109 } = ui.style().separator_style(&classes, state);
110
111 let spacing = spacing.unwrap_or(spacing_style);
113
114 let is_horizontal_line = is_horizontal_line
115 .unwrap_or_else(|| ui.is_grid() || !ui.layout().main_dir().is_horizontal());
116
117 let available_space = if ui.is_sizing_pass() {
118 Vec2::ZERO
119 } else {
120 ui.available_size_before_wrap()
121 };
122
123 let size = if is_horizontal_line {
124 vec2(available_space.x, spacing)
125 } else {
126 vec2(spacing, available_space.y)
127 };
128
129 let (rect, response) = ui.allocate_at_least(size, Sense::hover());
130
131 if ui.is_rect_visible(response.rect) {
132 let painter = ui.painter();
133 if is_horizontal_line {
134 painter.hline(
135 (rect.left() - grow)..=(rect.right() + grow),
136 rect.center().y,
137 stroke,
138 );
139 } else {
140 painter.vline(
141 rect.center().x,
142 (rect.top() - grow)..=(rect.bottom() + grow),
143 stroke,
144 );
145 }
146 }
147
148 response
149 }
150}
151
152impl HasClasses for Separator {
153 fn classes(&self) -> &Classes {
154 &self.classes
155 }
156
157 fn classes_mut(&mut self) -> &mut Classes {
158 &mut self.classes
159 }
160}