Skip to content

Commit

Permalink
Add undo/redo demo. (emilk#4811)
Browse files Browse the repository at this point in the history
* Closes emilk#1713 

I almost went to implement my own undo/redo system, and then found the
egui undoer.
Went to make a small demo to test for myself how it worked, and then
found the linked issue.
So here is a tweaked version of that :)

Co-authored-by: Wybe Westra <[email protected]>
  • Loading branch information
2 people authored and lucasmerlin committed Jul 30, 2024
1 parent 9227a87 commit 41ae7af
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/egui_demo_lib/src/demo/demo_app_windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl Default for Demos {
Box::<super::text_edit::TextEditDemo>::default(),
Box::<super::text_layout::TextLayoutDemo>::default(),
Box::<super::tooltips::Tooltips>::default(),
Box::<super::undo_redo::UndoRedoDemo>::default(),
Box::<super::widget_gallery::WidgetGallery>::default(),
Box::<super::window_options::WindowOptions>::default(),
])
Expand Down
1 change: 1 addition & 0 deletions crates/egui_demo_lib/src/demo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub mod text_edit;
pub mod text_layout;
pub mod toggle_switch;
pub mod tooltips;
pub mod undo_redo;
pub mod widget_gallery;
pub mod window_options;

Expand Down
78 changes: 78 additions & 0 deletions crates/egui_demo_lib/src/demo/undo_redo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use egui::{util::undoer::Undoer, Button};

#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct State {
pub toggle_value: bool,
pub text: String,
}

impl Default for State {
fn default() -> Self {
Self {
toggle_value: Default::default(),
text: "Text with undo/redo".to_owned(),
}
}
}

/// Showcase [`egui::util::undoer::Undoer`]
#[derive(Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct UndoRedoDemo {
pub state: State,
pub undoer: Undoer<State>,
}

impl crate::Demo for UndoRedoDemo {
fn name(&self) -> &'static str {
"⟲ Undo Redo"
}

fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
egui::Window::new(self.name())
.open(open)
.resizable(false)
.show(ctx, |ui| {
use crate::View as _;
self.ui(ui);
});
}
}

impl crate::View for UndoRedoDemo {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.vertical_centered(|ui| {
ui.add(crate::egui_github_link_file!());
});

ui.checkbox(&mut self.state.toggle_value, "Checkbox with undo/redo");
ui.text_edit_singleline(&mut self.state.text);

ui.separator();

let can_undo = self.undoer.has_undo(&self.state);
let can_redo = self.undoer.has_redo(&self.state);

ui.horizontal(|ui| {
let undo = ui.add_enabled(can_undo, Button::new("⟲ Undo")).clicked();
let redo = ui.add_enabled(can_redo, Button::new("⟳ Redo")).clicked();

if undo {
if let Some(undo_text) = self.undoer.undo(&self.state) {
self.state = undo_text.clone();
}
}
if redo {
if let Some(redo_text) = self.undoer.redo(&self.state) {
self.state = redo_text.clone();
}
}
});

self.undoer
.feed_state(ui.ctx().input(|input| input.time), &self.state);
}
}

0 comments on commit 41ae7af

Please sign in to comment.