Add ui.add_enabled and ui.add_enabled_ui, and remove Button::enabled

This commit is contained in:
Emil Ernerfeldt 2021-10-17 22:17:50 +02:00
parent 8a47019c1a
commit 2af2e8bad5
7 changed files with 79 additions and 37 deletions

View file

@ -11,6 +11,8 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Add horizontal scrolling support to `ScrollArea` and `Window` (opt-in).
* `TextEdit::layouter`: Add custom text layout for e.g. syntax highlighting or WYSIWYG.
* `Fonts::layout_job`: New text layout engine allowing mixing fonts, colors and styles, with underlining and strikethrough.
* Add `ui.add_enabled(bool, widget)` to easily add a possibly disabled widget.
* Add `ui.add_enabled_ui(bool, |ui| …)` to create a possibly disabled UI section.
* Add feature `"serialize"` separatedly from `"persistence"`.
* Add `egui::widgets::global_dark_light_mode_buttons` to easily add buttons for switching the egui theme.
* `TextEdit` can now be used to show text which can be selectedd and copied, but not edited.
@ -35,6 +37,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Show tooltips above widgets on touch screens.
* Fix popups sometimes getting clipped by panels.
### Removed 🔥
* Replace `Button::enabled` with `ui.add_enabled`.
## 0.14.2 - 2021-08-28 - Window resize fix

View file

@ -207,6 +207,11 @@ impl Ui {
/// If `false`, the `Ui` does not allow any interaction and
/// the widgets in it will draw with a gray look.
#[inline(always)]
pub fn is_enabled(&self) -> bool {
self.enabled
}
#[deprecated = "Renamed to is_enabled"]
pub fn enabled(&self) -> bool {
self.enabled
}
@ -214,6 +219,8 @@ impl Ui {
/// Calling `set_enabled(false)` will cause the `Ui` to deny all future interaction
/// and all the widgets will draw with a gray look.
///
/// Usually it is more convenient to use [`Self::add_enabled_ui`] or [`Self::add_enabled`].
///
/// Calling `set_enabled(true)` has no effect - it will NOT re-enable the `Ui` once disabled.
///
/// ### Example
@ -926,6 +933,59 @@ impl Ui {
.inner
}
/// Add a single[`Widget`] that is possibly disabled, i.e. greyed out and non-interactive.
///
/// If you call `add_enabled` from within an already disabled UI,
/// the widget will always be disabled, even if the `enabled` argument is true.
///
/// See also [`Self::add_enabled_ui`] and [`Self::is_enabled`].
///
/// ```
/// # let ui = &mut egui::Ui::__test();
/// ui.add_enabled(false, egui::Button::new("Can't click this"));
/// ```
pub fn add_enabled(&mut self, enabled: bool, widget: impl Widget) -> Response {
if enabled || !self.is_enabled() {
self.add(widget)
} else {
let old_painter = self.painter.clone();
self.set_enabled(false);
let response = self.add(widget);
self.enabled = true;
self.painter = old_painter;
response
}
}
/// Add a section that is possibly disabled, i.e. greyed out and non-interactive.
///
/// If you call `add_enabled_ui` from within an already disabled UI,
/// the result will always be disabled, even if the `enabled` argument is true.
///
/// See also [`Self::add_enabled`] and [`Self::is_enabled`].
///
/// ### Example
/// ```
/// # let ui = &mut egui::Ui::__test();
/// # let mut enabled = true;
/// ui.checkbox(&mut enabled, "Enable subsection");
/// ui.add_enabled_ui(enabled, |ui| {
/// if ui.button("Button that is not always clickable").clicked() {
/// /* … */
/// }
/// });
/// ```
pub fn add_enabled_ui<R>(
&mut self,
enabled: bool,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.scope(|ui| {
ui.set_enabled(enabled);
add_contents(ui)
})
}
/// Add extra space before the next widget.
///
/// The direction is dependent on the layout.

View file

@ -15,10 +15,16 @@ fn select<T>(b: bool, if_true: T, if_false: T) -> T {
///
/// ```
/// # let ui = &mut egui::Ui::__test();
/// # fn do_stuff() {}
///
/// if ui.add(egui::Button::new("Click mew")).clicked() {
/// do_stuff();
/// }
/// # fn do_stuff() {}
///
/// // A greyed-out and non-interactive button:
/// if ui.add_enabled(false, egui::Button::new("Can't click this")).clicked() {
/// unreachable!();
/// }
/// ```
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Button {
@ -103,17 +109,6 @@ impl Button {
self
}
/// If you set this to `false`, the button will be grayed out and un-clickable.
/// `enabled(false)` has the same effect as calling `sense(Sense::hover())`.
///
/// This is a convenience for [`Ui::set_enabled`].
pub fn enabled(mut self, enabled: bool) -> Self {
if !enabled {
self.sense = Sense::hover();
}
self
}
/// If `true`, the text will wrap at the `max_width`.
/// By default [`Self::wrap`] will be true in vertical layouts
/// and horizontal layouts with wrapping,
@ -131,8 +126,8 @@ impl Button {
}
}
impl Button {
fn enabled_ui(self, ui: &mut Ui) -> Response {
impl Widget for Button {
fn ui(self, ui: &mut Ui) -> Response {
let Button {
text,
text_color,
@ -201,22 +196,6 @@ impl Button {
}
}
impl Widget for Button {
fn ui(self, ui: &mut Ui) -> Response {
let button_enabled = self.sense != Sense::hover();
if button_enabled || !ui.enabled() {
self.enabled_ui(ui)
} else {
// We need get a temporary disabled `Ui` to get that grayed out look:
ui.scope(|ui| {
ui.set_enabled(false);
self.enabled_ui(ui)
})
.inner
}
}
}
// ----------------------------------------------------------------------------
// TODO: allow checkbox without a text label

View file

@ -91,7 +91,7 @@ pub fn reset_button<T: Default + PartialEq>(ui: &mut Ui, value: &mut T) {
/// The button is only enabled if the value does not already have its original value.
pub fn reset_button_with<T: PartialEq>(ui: &mut Ui, value: &mut T, reset_value: T) {
if ui
.add(Button::new("Reset").enabled(*value != reset_value))
.add_enabled(*value != reset_value, Button::new("Reset"))
.clicked()
{
*value = reset_value;

View file

@ -53,9 +53,8 @@ impl super::Demo for WidgetGallery {
impl super::View for WidgetGallery {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.scope(|ui| {
ui.add_enabled_ui(self.enabled, |ui| {
ui.set_visible(self.visible);
ui.set_enabled(self.enabled);
egui::Grid::new("my_grid")
.num_columns(2)

View file

@ -240,10 +240,9 @@ impl BackendPanel {
)
.on_hover_text("Physical pixels per point.");
if let Some(native_pixels_per_point) = info.native_pixels_per_point {
let button = egui::Button::new("Reset")
.enabled(*pixels_per_point != native_pixels_per_point);
let enabled = *pixels_per_point != native_pixels_per_point;
if ui
.add(button)
.add_enabled(enabled, egui::Button::new("Reset"))
.on_hover_text(format!(
"Reset scale to native value ({:.1})",
native_pixels_per_point

View file

@ -262,7 +262,7 @@ impl CodeTheme {
};
if ui
.add(egui::Button::new("Reset theme").enabled(*self != reset_value))
.add_enabled(*self != reset_value, egui::Button::new("Reset theme"))
.clicked()
{
*self = reset_value;