Add Ui::set_visible as a way to hide widgets

Closes https://github.com/emilk/egui/issues/460
This commit is contained in:
Emil Ernerfeldt 2021-06-07 22:12:49 +02:00
parent 3c603c55b8
commit ece25ee7f3
4 changed files with 79 additions and 21 deletions

View file

@ -13,6 +13,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
* Add resizable panels.
* Add an option to overwrite frame of a `Panel`.
* Add `ScrollArea::show_rows` for efficient scrolling of huge UI:s.
* Add `Ui::set_visible` as a way to hide widgets.
* Add `Style::override_text_style` to easily change the text style of everything in a `Ui` (or globally).
* You can now change `TextStyle` on checkboxes, radio buttons and `SelectableLabel`.
* Add support for [cint](https://crates.io/crates/cint) under `cint` feature.

View file

@ -66,6 +66,15 @@ impl Painter {
self.fade_to_color = fade_to_color;
}
pub(crate) fn visible(&self) -> bool {
self.fade_to_color != Some(Color32::TRANSPARENT)
}
/// If `false`, nothing added to the painter will be visible
pub(crate) fn set_invisible(&mut self) {
self.fade_to_color = Some(Color32::TRANSPARENT)
}
/// Create a painter for a sub-region of this `Painter`.
///
/// The clip-rect of the returned `Painter` will be the intersection
@ -145,14 +154,21 @@ impl Painter {
/// Can be used for free painting.
/// NOTE: all coordinates are screen coordinates!
pub fn add(&self, mut shape: Shape) -> ShapeIdx {
self.transform_shape(&mut shape);
self.paint_list.lock().add(self.clip_rect, shape)
if self.fade_to_color == Some(Color32::TRANSPARENT) {
self.paint_list.lock().add(self.clip_rect, Shape::Noop)
} else {
self.transform_shape(&mut shape);
self.paint_list.lock().add(self.clip_rect, shape)
}
}
/// Add many shapes at once.
///
/// Calling this once is generally faster than calling [`Self::add`] multiple times.
pub fn extend(&self, mut shapes: Vec<Shape>) {
if self.fade_to_color == Some(Color32::TRANSPARENT) {
return;
}
if !shapes.is_empty() {
if self.fade_to_color.is_some() {
for shape in &mut shapes {
@ -166,6 +182,9 @@ impl Painter {
/// Modify an existing [`Shape`].
pub fn set(&self, idx: ShapeIdx, mut shape: Shape) {
if self.fade_to_color == Some(Color32::TRANSPARENT) {
return;
}
self.transform_shape(&mut shape);
self.paint_list.lock().set(idx, self.clip_rect, shape)
}

View file

@ -215,14 +215,44 @@ impl Ui {
/// ```
pub fn set_enabled(&mut self, enabled: bool) {
self.enabled &= enabled;
if self.enabled {
self.painter.set_fade_to_color(None);
} else {
if !self.enabled && self.visible() {
self.painter
.set_fade_to_color(Some(self.visuals().window_fill()));
}
}
/// If `false`, any widgets added to the `Ui` will be invisible and non-interactive.
#[inline(always)]
pub fn visible(&self) -> bool {
self.painter.visible()
}
/// Calling `set_visible(false)` will cause all further widgets to be invisible,
/// yet still allocate space.
///
/// The widgets will not be interactive (`set_visible(false)` implies `set_enabled(false)`).
///
/// Calling `set_visible(true)` has no effect.
///
/// ### Example
/// ```
/// # let ui = &mut egui::Ui::__test();
/// # let mut visible = true;
/// ui.group(|ui|{
/// ui.checkbox(&mut visible, "Show subsection");
/// ui.set_visible(visible);
/// if ui.button("Button that is not always shown").clicked() {
/// /* … */
/// }
/// });
/// ```
pub fn set_visible(&mut self, visible: bool) {
self.set_enabled(visible);
if !visible {
self.painter.set_invisible();
}
}
#[inline(always)]
pub fn layout(&self) -> &Layout {
self.placer.layout()
@ -1226,6 +1256,8 @@ impl Ui {
/// ui.label("Within a frame");
/// });
/// ```
///
/// Se also [`Self::scope`].
pub fn group<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
crate::Frame::group(self.style()).show(self, add_contents)
}

View file

@ -9,6 +9,7 @@ enum Enum {
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
pub struct WidgetGallery {
enabled: bool,
visible: bool,
boolean: bool,
radio: Enum,
scalar: f32,
@ -20,6 +21,7 @@ impl Default for WidgetGallery {
fn default() -> Self {
Self {
enabled: true,
visible: true,
boolean: false,
radio: Enum::First,
scalar: 42.0,
@ -47,13 +49,27 @@ impl super::Demo for WidgetGallery {
impl super::View for WidgetGallery {
fn ui(&mut self, ui: &mut egui::Ui) {
self.gallery(ui);
ui.scope(|ui| {
ui.set_visible(self.visible);
ui.set_enabled(self.enabled);
egui::Grid::new("my_grid")
.striped(true)
.spacing([40.0, 4.0])
.show(ui, |ui| {
self.gallery_grid_contents(ui);
});
});
ui.separator();
ui.vertical_centered(|ui| {
ui.checkbox(&mut self.enabled, "Interactive")
.on_hover_text("Convenient way to inspect how the widgets look when disabled.");
ui.horizontal(|ui| {
ui.checkbox(&mut self.visible, "Visible")
.on_hover_text("Uncheck to hide all the widgets.");
if self.visible {
ui.checkbox(&mut self.enabled, "Interactive")
.on_hover_text("Uncheck to inspect how the widgets look when disabled.");
}
});
ui.separator();
@ -69,18 +85,10 @@ impl super::View for WidgetGallery {
}
impl WidgetGallery {
fn gallery(&mut self, ui: &mut egui::Ui) {
egui::Grid::new("my_grid")
.striped(true)
.spacing([40.0, 4.0])
.show(ui, |ui| {
self.gallery_grid_contents(ui);
});
}
fn gallery_grid_contents(&mut self, ui: &mut egui::Ui) {
let Self {
enabled,
enabled: _,
visible: _,
boolean,
radio,
scalar,
@ -88,8 +96,6 @@ impl WidgetGallery {
color,
} = self;
ui.set_enabled(*enabled);
ui.add(doc_link_label("Label", "label,heading"));
ui.label("Welcome to the widget gallery!");
ui.end_row();