Remove `SelectableLabel` (#7277)
* part of https://github.com/emilk/egui/issues/7264 * removes SelectableLabel (Use `Button::selectable` instead) * updates `Ui::selectable_value/label` with IntoAtoms support Had to make some changes to `Button` since the SelecatbleLabel had no frame unless selected.
This commit is contained in:
parent
2b62c68598
commit
47a2bb10b0
|
|
@ -27,7 +27,7 @@ use crate::{
|
|||
vec2, widgets,
|
||||
widgets::{
|
||||
Button, Checkbox, DragValue, Hyperlink, Image, ImageSource, Label, Link, RadioButton,
|
||||
SelectableLabel, Separator, Spinner, TextEdit, Widget, color_picker,
|
||||
Separator, Spinner, TextEdit, Widget, color_picker,
|
||||
},
|
||||
};
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -2077,13 +2077,13 @@ impl Ui {
|
|||
Checkbox::new(checked, atoms).ui(self)
|
||||
}
|
||||
|
||||
/// Acts like a checkbox, but looks like a [`SelectableLabel`].
|
||||
/// Acts like a checkbox, but looks like a [`Button::selectable`].
|
||||
///
|
||||
/// Click to toggle to bool.
|
||||
///
|
||||
/// See also [`Self::checkbox`].
|
||||
pub fn toggle_value(&mut self, selected: &mut bool, text: impl Into<WidgetText>) -> Response {
|
||||
let mut response = self.selectable_label(*selected, text);
|
||||
pub fn toggle_value<'a>(&mut self, selected: &mut bool, atoms: impl IntoAtoms<'a>) -> Response {
|
||||
let mut response = self.selectable_label(*selected, atoms);
|
||||
if response.clicked() {
|
||||
*selected = !*selected;
|
||||
response.mark_changed();
|
||||
|
|
@ -2134,10 +2134,10 @@ impl Ui {
|
|||
|
||||
/// Show a label which can be selected or not.
|
||||
///
|
||||
/// See also [`SelectableLabel`] and [`Self::toggle_value`].
|
||||
/// See also [`Button::selectable`] and [`Self::toggle_value`].
|
||||
#[must_use = "You should check if the user clicked this with `if ui.selectable_label(…).clicked() { … } "]
|
||||
pub fn selectable_label(&mut self, checked: bool, text: impl Into<WidgetText>) -> Response {
|
||||
SelectableLabel::new(checked, text).ui(self)
|
||||
pub fn selectable_label<'a>(&mut self, checked: bool, text: impl IntoAtoms<'a>) -> Response {
|
||||
Button::selectable(checked, text).ui(self)
|
||||
}
|
||||
|
||||
/// Show selectable text. It is selected if `*current_value == selected_value`.
|
||||
|
|
@ -2145,12 +2145,12 @@ impl Ui {
|
|||
///
|
||||
/// Example: `ui.selectable_value(&mut my_enum, Enum::Alternative, "Alternative")`.
|
||||
///
|
||||
/// See also [`SelectableLabel`] and [`Self::toggle_value`].
|
||||
pub fn selectable_value<Value: PartialEq>(
|
||||
/// See also [`Button::selectable`] and [`Self::toggle_value`].
|
||||
pub fn selectable_value<'a, Value: PartialEq>(
|
||||
&mut self,
|
||||
current_value: &mut Value,
|
||||
selected_value: Value,
|
||||
text: impl Into<WidgetText>,
|
||||
text: impl IntoAtoms<'a>,
|
||||
) -> Response {
|
||||
let mut response = self.selectable_label(*current_value == selected_value, text);
|
||||
if response.clicked() && *current_value != selected_value {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ pub struct Button<'a> {
|
|||
stroke: Option<Stroke>,
|
||||
small: bool,
|
||||
frame: Option<bool>,
|
||||
frame_when_inactive: bool,
|
||||
min_size: Vec2,
|
||||
corner_radius: Option<CornerRadius>,
|
||||
selected: bool,
|
||||
|
|
@ -44,6 +45,7 @@ impl<'a> Button<'a> {
|
|||
stroke: None,
|
||||
small: false,
|
||||
frame: None,
|
||||
frame_when_inactive: true,
|
||||
min_size: Vec2::ZERO,
|
||||
corner_radius: None,
|
||||
selected: false,
|
||||
|
|
@ -52,6 +54,27 @@ impl<'a> Button<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Show a selectable button.
|
||||
///
|
||||
/// Equivalent to:
|
||||
/// ```rust
|
||||
/// # use egui::{Button, IntoAtoms, __run_test_ui};
|
||||
/// # __run_test_ui(|ui| {
|
||||
/// let selected = true;
|
||||
/// ui.add(Button::new("toggle me").selected(selected).frame_when_inactive(!selected).frame(true));
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also:
|
||||
/// - [`Ui::selectable_value`]
|
||||
/// - [`Ui::selectable_label`]
|
||||
pub fn selectable(selected: bool, atoms: impl IntoAtoms<'a>) -> Self {
|
||||
Self::new(atoms)
|
||||
.selected(selected)
|
||||
.frame_when_inactive(selected)
|
||||
.frame(true)
|
||||
}
|
||||
|
||||
/// Creates a button with an image. The size of the image as displayed is defined by the provided size.
|
||||
///
|
||||
/// Note: In contrast to [`Button::new`], this limits the image size to the default font height
|
||||
|
|
@ -138,6 +161,18 @@ impl<'a> Button<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// If `false`, the button will not have a frame when inactive.
|
||||
///
|
||||
/// Default: `true`.
|
||||
///
|
||||
/// Note: When [`Self::frame`] (or `ui.visuals().button_frame`) is `false`, this setting
|
||||
/// has no effect.
|
||||
#[inline]
|
||||
pub fn frame_when_inactive(mut self, frame_when_inactive: bool) -> Self {
|
||||
self.frame_when_inactive = frame_when_inactive;
|
||||
self
|
||||
}
|
||||
|
||||
/// By default, buttons senses clicks.
|
||||
/// Change this to a drag-button with `Sense::drag()`.
|
||||
#[inline]
|
||||
|
|
@ -220,6 +255,7 @@ impl<'a> Button<'a> {
|
|||
stroke,
|
||||
small,
|
||||
frame,
|
||||
frame_when_inactive,
|
||||
mut min_size,
|
||||
corner_radius,
|
||||
selected,
|
||||
|
|
@ -243,9 +279,9 @@ impl<'a> Button<'a> {
|
|||
|
||||
let text = layout.text().map(String::from);
|
||||
|
||||
let has_frame = frame.unwrap_or_else(|| ui.visuals().button_frame);
|
||||
let has_frame_margin = frame.unwrap_or_else(|| ui.visuals().button_frame);
|
||||
|
||||
let mut button_padding = if has_frame {
|
||||
let mut button_padding = if has_frame_margin {
|
||||
ui.spacing().button_padding
|
||||
} else {
|
||||
Vec2::ZERO
|
||||
|
|
@ -262,13 +298,22 @@ impl<'a> Button<'a> {
|
|||
let response = if ui.is_rect_visible(prepared.response.rect) {
|
||||
let visuals = ui.style().interact_selectable(&prepared.response, selected);
|
||||
|
||||
let visible_frame = if frame_when_inactive {
|
||||
has_frame_margin
|
||||
} else {
|
||||
has_frame_margin
|
||||
&& (prepared.response.hovered()
|
||||
|| prepared.response.is_pointer_button_down_on()
|
||||
|| prepared.response.has_focus())
|
||||
};
|
||||
|
||||
if image_tint_follows_text_color {
|
||||
prepared.map_images(|image| image.tint(visuals.text_color()));
|
||||
}
|
||||
|
||||
prepared.fallback_text_color = visuals.text_color();
|
||||
|
||||
if has_frame {
|
||||
if visible_frame {
|
||||
let stroke = stroke.unwrap_or(visuals.bg_stroke);
|
||||
let fill = fill.unwrap_or(visuals.weak_bg_fill);
|
||||
prepared.frame = prepared
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ mod slider;
|
|||
mod spinner;
|
||||
pub mod text_edit;
|
||||
|
||||
#[expect(deprecated)]
|
||||
pub use self::selected_label::SelectableLabel;
|
||||
pub use self::{
|
||||
button::Button,
|
||||
checkbox::Checkbox,
|
||||
|
|
@ -35,7 +37,6 @@ pub use self::{
|
|||
label::Label,
|
||||
progress_bar::ProgressBar,
|
||||
radio_button::RadioButton,
|
||||
selected_label::SelectableLabel,
|
||||
separator::Separator,
|
||||
slider::{Slider, SliderClamping, SliderOrientation},
|
||||
spinner::Spinner,
|
||||
|
|
|
|||
|
|
@ -1,88 +1,2 @@
|
|||
use crate::{
|
||||
NumExt as _, Response, Sense, TextStyle, Ui, Widget, WidgetInfo, WidgetText, WidgetType,
|
||||
};
|
||||
|
||||
/// One out of several alternatives, either selected or not.
|
||||
/// Will mark selected items with a different background color.
|
||||
/// An alternative to [`crate::RadioButton`] and [`crate::Checkbox`].
|
||||
///
|
||||
/// Usually you'd use [`Ui::selectable_value`] or [`Ui::selectable_label`] instead.
|
||||
///
|
||||
/// ```
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// #[derive(PartialEq)]
|
||||
/// enum Enum { First, Second, Third }
|
||||
/// let mut my_enum = Enum::First;
|
||||
///
|
||||
/// ui.selectable_value(&mut my_enum, Enum::First, "First");
|
||||
///
|
||||
/// // is equivalent to:
|
||||
///
|
||||
/// if ui.add(egui::SelectableLabel::new(my_enum == Enum::First, "First")).clicked() {
|
||||
/// my_enum = Enum::First
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
|
||||
pub struct SelectableLabel {
|
||||
selected: bool,
|
||||
text: WidgetText,
|
||||
}
|
||||
|
||||
impl SelectableLabel {
|
||||
pub fn new(selected: bool, text: impl Into<WidgetText>) -> Self {
|
||||
Self {
|
||||
selected,
|
||||
text: text.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for SelectableLabel {
|
||||
fn ui(self, ui: &mut Ui) -> Response {
|
||||
let Self { selected, text } = self;
|
||||
|
||||
let button_padding = ui.spacing().button_padding;
|
||||
let total_extra = button_padding + button_padding;
|
||||
|
||||
let wrap_width = ui.available_width() - total_extra.x;
|
||||
let galley = text.into_galley(ui, None, wrap_width, TextStyle::Button);
|
||||
|
||||
let mut desired_size = total_extra + galley.size();
|
||||
desired_size.y = desired_size.y.at_least(ui.spacing().interact_size.y);
|
||||
let (rect, response) = ui.allocate_at_least(desired_size, Sense::click());
|
||||
response.widget_info(|| {
|
||||
WidgetInfo::selected(
|
||||
WidgetType::SelectableLabel,
|
||||
ui.is_enabled(),
|
||||
selected,
|
||||
galley.text(),
|
||||
)
|
||||
});
|
||||
|
||||
if ui.is_rect_visible(response.rect) {
|
||||
let text_pos = ui
|
||||
.layout()
|
||||
.align_size_within_rect(galley.size(), rect.shrink2(button_padding))
|
||||
.min;
|
||||
|
||||
let visuals = ui.style().interact_selectable(&response, selected);
|
||||
|
||||
if selected || response.hovered() || response.highlighted() || response.has_focus() {
|
||||
let rect = rect.expand(visuals.expansion);
|
||||
|
||||
ui.painter().rect(
|
||||
rect,
|
||||
visuals.corner_radius,
|
||||
visuals.weak_bg_fill,
|
||||
visuals.bg_stroke,
|
||||
epaint::StrokeKind::Inside,
|
||||
);
|
||||
}
|
||||
|
||||
ui.painter().galley(text_pos, galley, visuals.text_color());
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
#[deprecated = "SelectableLabel has been removed. Use Button::selectable() instead"]
|
||||
pub struct SelectableLabel {}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub fn password_ui(ui: &mut egui::Ui, password: &mut String) -> egui::Response {
|
|||
let result = ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
// Toggle the `show_plaintext` bool with a button:
|
||||
let response = ui
|
||||
.add(egui::SelectableLabel::new(show_plaintext, "👁"))
|
||||
.selectable_label(show_plaintext, "👁")
|
||||
.on_hover_text("Show/hide password");
|
||||
|
||||
if response.clicked() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue