Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programmatically open / closing windows #3517

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
41 changes: 37 additions & 4 deletions crates/egui/src/containers/collapsing_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ use epaint::Shape;
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub(crate) struct InnerState {
open: bool, // Expand / collapse
hidden: bool, // Show / Hide
/// Expand / collapse
open: bool,
/// Show / Hide (only on windows)
Norlock marked this conversation as resolved.
Show resolved Hide resolved
hidden: bool,

/// Height of the region when open. Used for animations
#[cfg_attr(feature = "serde", serde(default))]
Expand Down Expand Up @@ -66,14 +68,17 @@ impl CollapsingState {
ui.ctx().request_repaint();
}

/// Only on windows
pub fn is_hidden(&self) -> bool {
self.state.hidden
}

/// Only on windows
pub fn toggle_hidden(&mut self) {
self.state.hidden = !self.state.hidden;
}

/// Only on windows
pub fn set_hidden(&mut self, hidden: bool) {
self.state.hidden = hidden;
}
Expand Down Expand Up @@ -345,6 +350,16 @@ pub fn paint_default_icon(ui: &mut Ui, openness: f32, response: &Response) {
));
}

/// A event to expand / collapse the widget automatically
#[derive(PartialEq, Default, Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum CollapsingHeaderEvent {
#[default]
Expand,
Collapse,
ToggleCollapse,
}

/// A function that paints an icon indicating if the region is open or not
pub type IconPainter = Box<dyn FnOnce(&mut Ui, f32, &Response)>;

Expand All @@ -368,6 +383,7 @@ pub struct CollapsingHeader {
text: WidgetText,
default_open: bool,
open: Option<bool>,
display_event: Option<CollapsingHeaderEvent>,
id_source: Id,
enabled: bool,
selectable: bool,
Expand Down Expand Up @@ -396,6 +412,7 @@ impl CollapsingHeader {
selected: false,
show_background: false,
icon: None,
display_event: None,
}
}

Expand All @@ -416,6 +433,11 @@ impl CollapsingHeader {
self
}

pub fn display(mut self, new_event: &mut Option<CollapsingHeaderEvent>) -> Self {
self.display_event = new_event.take();
self
}

/// Explicitly set the source of the [`Id`] of this widget, instead of using title label.
/// This is useful if the title label is dynamic or not unique.
pub fn id_source(mut self, id_source: impl Hash) -> Self {
Expand Down Expand Up @@ -517,8 +539,8 @@ impl CollapsingHeader {
selectable,
selected,
show_background,
display_event,
} = self;

// TODO(emilk): horizontal layout, with icon and text as labels. Insert background behind using Frame.

let id = ui.make_persistent_id(id_source);
Expand Down Expand Up @@ -548,7 +570,18 @@ impl CollapsingHeader {

let mut state = CollapsingState::load(ui.ctx(), id, default_open);

if let Some(open) = open {
let request_repaint = display_event.is_some();

match display_event {
Some(CollapsingHeaderEvent::Expand) => state.set_open(true),
Some(CollapsingHeaderEvent::Collapse) => state.set_open(false),
Some(CollapsingHeaderEvent::ToggleCollapse) => state.set_open(!state.is_open()),
None => {}
}

if request_repaint {
ui.ctx().request_repaint();
} else if let Some(open) = open {
if open != state.is_open() {
state.toggle_open(ui);
header_response.mark_changed();
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/containers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ pub use {
popup::*,
resize::Resize,
scroll_area::ScrollArea,
window::{DisplayEvent, SetEvent, Window},
window::{SetEvent, Window, WindowEvent},
};
24 changes: 12 additions & 12 deletions crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ pub struct Window<'open> {
default_open: bool,
with_title_bar: bool,
with_closing_btn: bool,
display_event: Option<DisplayEvent>,
display_event: Option<WindowEvent>,
open: Option<&'open mut bool>,
}

#[derive(PartialEq, Default, Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum DisplayEvent {
pub enum WindowEvent {
#[default]
Expand,
Collapse,
Expand All @@ -52,12 +52,12 @@ pub enum DisplayEvent {

// Helper function for user space
pub trait SetEvent {
fn set(&mut self, display_event: DisplayEvent);
fn set(&mut self, display_event: WindowEvent);
}

impl SetEvent for Option<DisplayEvent> {
fn set(&mut self, display_event: DisplayEvent) {
let _ = self.insert(display_event);
impl SetEvent for Option<WindowEvent> {
fn set(&mut self, display_event: WindowEvent) {
*self = Some(display_event);
}
}

Expand Down Expand Up @@ -239,7 +239,7 @@ impl<'open> Window<'open> {
self
}

pub fn display_event(mut self, new_event: &mut Option<DisplayEvent>) -> Self {
pub fn display_event(mut self, new_event: &mut Option<WindowEvent>) -> Self {
self.display_event = new_event.take();
self
}
Expand Down Expand Up @@ -385,11 +385,11 @@ impl<'open> Window<'open> {
}

match display_event {
Some(DisplayEvent::Hide) => collapsing.set_hidden(true),
Some(DisplayEvent::Expand) => collapsing.set_open(true),
Some(DisplayEvent::Collapse) => collapsing.set_open(false),
Some(DisplayEvent::ToggleHidden) => collapsing.toggle_hidden(),
Some(DisplayEvent::ToggleCollapse) => collapsing.set_open(!collapsing.is_open()),
Some(WindowEvent::Hide) => collapsing.set_hidden(true),
Some(WindowEvent::Expand) => collapsing.set_open(true),
Some(WindowEvent::Collapse) => collapsing.set_open(false),
Some(WindowEvent::ToggleHidden) => collapsing.toggle_hidden(),
Some(WindowEvent::ToggleCollapse) => collapsing.set_open(!collapsing.is_open()),
None => collapsing.set_hidden(matches!(open, Some(false))),
}

Expand Down
8 changes: 4 additions & 4 deletions crates/egui_demo_lib/src/demo/about.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use egui::DisplayEvent;
use egui::{SetEvent, WindowEvent};

#[derive(Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct About {
display_event: Option<DisplayEvent>,
display_event: Option<WindowEvent>,
}

impl super::Demo for About {
Expand All @@ -27,11 +27,11 @@ impl super::Demo for About {

impl About {
pub fn toggle_collapse(&mut self) {
self.display_event = Some(DisplayEvent::ToggleCollapse);
self.display_event.set(WindowEvent::ToggleCollapse);
}

pub fn toggle_hidden(&mut self) {
self.display_event = Some(DisplayEvent::ToggleHidden);
self.display_event.set(WindowEvent::ToggleHidden);
}
}

Expand Down