egui/widgets/
selected_label.rs1use crate::{NumExt, Response, Sense, TextStyle, Ui, Widget, WidgetInfo, WidgetText, WidgetType};
2
3#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
25pub struct SelectableLabel {
26 selected: bool,
27 text: WidgetText,
28}
29
30impl SelectableLabel {
31 pub fn new(selected: bool, text: impl Into<WidgetText>) -> Self {
32 Self {
33 selected,
34 text: text.into(),
35 }
36 }
37}
38
39impl Widget for SelectableLabel {
40 fn ui(self, ui: &mut Ui) -> Response {
41 let Self { selected, text } = self;
42
43 let button_padding = ui.spacing().button_padding;
44 let total_extra = button_padding + button_padding;
45
46 let wrap_width = ui.available_width() - total_extra.x;
47 let galley = text.into_galley(ui, None, wrap_width, TextStyle::Button);
48
49 let mut desired_size = total_extra + galley.size();
50 desired_size.y = desired_size.y.at_least(ui.spacing().interact_size.y);
51 let (rect, response) = ui.allocate_at_least(desired_size, Sense::click());
52 response.widget_info(|| {
53 WidgetInfo::selected(
54 WidgetType::SelectableLabel,
55 ui.is_enabled(),
56 selected,
57 galley.text(),
58 )
59 });
60
61 if ui.is_rect_visible(response.rect) {
62 let text_pos = ui
63 .layout()
64 .align_size_within_rect(galley.size(), rect.shrink2(button_padding))
65 .min;
66
67 let visuals = ui.style().interact_selectable(&response, selected);
68
69 if selected || response.hovered() || response.highlighted() || response.has_focus() {
70 let rect = rect.expand(visuals.expansion);
71
72 ui.painter().rect(
73 rect,
74 visuals.corner_radius,
75 visuals.weak_bg_fill,
76 visuals.bg_stroke,
77 epaint::StrokeKind::Inside,
78 );
79 }
80
81 ui.painter().galley(text_pos, galley, visuals.text_color());
82 }
83
84 response
85 }
86}