Change film editing to use a modal library
This commit is contained in:
parent
6ea1fca14d
commit
a49744a79d
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -760,6 +760,15 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui-modal"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "868331421dda06e5dc8e96b2be78fd01c33a8e5c99ca452369cebecbef7b6639"
|
||||
dependencies = [
|
||||
"egui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui-winit"
|
||||
version = "0.22.0"
|
||||
@ -820,6 +829,18 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum_dispatch"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11f36e95862220b211a6e2aa5eca09b4fa391b13cd52ceb8035a24bf65a79de2"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.7"
|
||||
@ -945,7 +966,9 @@ dependencies = [
|
||||
"chrono",
|
||||
"eframe",
|
||||
"egui-datepicker",
|
||||
"egui-modal",
|
||||
"egui_extras",
|
||||
"enum_dispatch",
|
||||
"env_logger",
|
||||
"itertools",
|
||||
"serde",
|
||||
|
@ -9,7 +9,9 @@ edition = "2021"
|
||||
chrono = { version = "0.4.26", features = ["serde"] }
|
||||
eframe = { version = "0.22.0", features = ["ron", "persistence"] }
|
||||
egui-datepicker = { version = "0.3.0", path = "egui-datepicker" }
|
||||
egui-modal = "0.2.4"
|
||||
egui_extras = { version = "0.22.0", features = ["datepicker"] }
|
||||
enum_dispatch = "0.3.11"
|
||||
env_logger = "0.10.0"
|
||||
itertools = "0.10.5"
|
||||
serde = { version = "1.0.163", features = ["derive"] }
|
||||
|
@ -1,8 +1,9 @@
|
||||
use eframe::{
|
||||
egui::{self, DragValue, Window},
|
||||
emath::Align2,
|
||||
egui::{self, DragValue},
|
||||
epaint::Color32,
|
||||
};
|
||||
use egui_modal::Modal;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use stash::Stash;
|
||||
|
||||
use crate::{
|
||||
@ -10,73 +11,51 @@ use crate::{
|
||||
AppState,
|
||||
};
|
||||
|
||||
enum OperationWindow {
|
||||
Add(AddFilmWindow),
|
||||
Edit(EditFilmWindow),
|
||||
Delete(DeleteFilmWindow),
|
||||
#[enum_dispatch(OperationWindow)]
|
||||
enum OperationWindowEnum {
|
||||
AddFilmWindow,
|
||||
EditFilmWindow,
|
||||
DeleteFilmWindow,
|
||||
}
|
||||
|
||||
impl OperationWindow {
|
||||
fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool {
|
||||
match self {
|
||||
OperationWindow::Add(win) => win.draw(ctx, app_state),
|
||||
OperationWindow::Edit(win) => win.draw(ctx, app_state),
|
||||
OperationWindow::Delete(win) => win.draw(ctx, app_state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DeleteFilmWindow> for OperationWindow {
|
||||
fn from(v: DeleteFilmWindow) -> Self {
|
||||
Self::Delete(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EditFilmWindow> for OperationWindow {
|
||||
fn from(v: EditFilmWindow) -> Self {
|
||||
Self::Edit(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AddFilmWindow> for OperationWindow {
|
||||
fn from(v: AddFilmWindow) -> Self {
|
||||
Self::Add(v)
|
||||
}
|
||||
#[enum_dispatch]
|
||||
trait OperationWindow {
|
||||
fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool;
|
||||
}
|
||||
|
||||
pub struct EditFilmsWindow {
|
||||
operation_win: Option<OperationWindow>,
|
||||
operation_win: Option<OperationWindowEnum>,
|
||||
}
|
||||
|
||||
impl EditFilmsWindow {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(ctx: &egui::Context) -> Self {
|
||||
Modal::new(ctx, "edit_films_modal").open();
|
||||
Self {
|
||||
operation_win: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool {
|
||||
let mut close_unclicked = true;
|
||||
Window::new("Edit Films")
|
||||
.open(&mut close_unclicked)
|
||||
.interactable(self.operation_win.is_none())
|
||||
.resizable(false)
|
||||
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
|
||||
.show(ctx, |ui| {
|
||||
ui.set_enabled(self.operation_win.is_none());
|
||||
let modal = Modal::new(ctx, "edit_films_modal");
|
||||
modal.show(|ui| {
|
||||
ui.set_enabled(self.operation_win.is_none());
|
||||
modal.title(ui, "Edit films");
|
||||
// modal.frame(ui, |ui| {
|
||||
for (i, film) in app_state.films.iter() {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(film.to_string());
|
||||
if ui.button("Edit").clicked() {
|
||||
self.operation_win =
|
||||
Some(EditFilmWindow::new(i, &app_state.films).into());
|
||||
Some(EditFilmWindow::new(i, &app_state.films, &ctx).into());
|
||||
modal.close();
|
||||
}
|
||||
let film_used = app_state.rolls.iter().any(|roll| roll.film == i);
|
||||
if ui
|
||||
.add_enabled(!film_used, egui::Button::new("Delete"))
|
||||
.clicked()
|
||||
{
|
||||
self.operation_win = Some(DeleteFilmWindow::new(i).into());
|
||||
self.operation_win = Some(DeleteFilmWindow::new(i, &ctx).into());
|
||||
modal.close();
|
||||
}
|
||||
if film_used {
|
||||
ui.label("(Used by one or more rolls, cannot delete)");
|
||||
@ -84,15 +63,21 @@ impl EditFilmsWindow {
|
||||
});
|
||||
}
|
||||
if ui.button("Add").clicked() {
|
||||
self.operation_win = Some(AddFilmWindow::new().into());
|
||||
self.operation_win = Some(AddFilmWindow::new(&ctx).into());
|
||||
modal.close();
|
||||
}
|
||||
// });
|
||||
modal.buttons(ui, |ui| {
|
||||
modal.button(ui, "Close");
|
||||
});
|
||||
});
|
||||
if let Some(operation_win) = self.operation_win.as_mut() {
|
||||
if operation_win.draw(ctx, app_state) {
|
||||
self.operation_win = None;
|
||||
modal.open();
|
||||
}
|
||||
}
|
||||
!close_unclicked
|
||||
!modal.is_open() && self.operation_win.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,22 +88,25 @@ struct AddFilmWindow {
|
||||
}
|
||||
|
||||
impl AddFilmWindow {
|
||||
fn new() -> Self {
|
||||
fn new(ctx: &egui::Context) -> Self {
|
||||
Modal::new(ctx, "add_film_modal").open();
|
||||
Self {
|
||||
name: String::new(),
|
||||
iso: 400,
|
||||
show_name_req_err: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationWindow for AddFilmWindow {
|
||||
fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool {
|
||||
let mut close_unclicked = true;
|
||||
let mut close_window = false;
|
||||
Window::new("Add Film")
|
||||
.resizable(false)
|
||||
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
|
||||
.open(&mut close_unclicked)
|
||||
.show(ctx, |ui| {
|
||||
let modal = Modal::new(ctx, "add_film_modal");
|
||||
modal.show(|ui| {
|
||||
modal.title(ui, "Add film");
|
||||
modal.frame(ui, |ui| {
|
||||
if self.show_name_req_err {
|
||||
ui.colored_label(Color32::DARK_RED, "Error: Name required");
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
let label = ui.label("Name:");
|
||||
ui.text_edit_singleline(&mut self.name)
|
||||
@ -129,20 +117,19 @@ impl AddFilmWindow {
|
||||
ui.add(DragValue::new(&mut self.iso).clamp_range(1..=u32::MAX))
|
||||
.labelled_by(label.id);
|
||||
});
|
||||
if ui.button("Submit").clicked() {
|
||||
});
|
||||
modal.buttons(ui, |ui| {
|
||||
if modal.button(ui, "Submit").clicked() {
|
||||
if self.name.is_empty() {
|
||||
self.show_name_req_err = true;
|
||||
return;
|
||||
}
|
||||
app_state.films.put(Film::new(&self.name, self.iso));
|
||||
close_window = true;
|
||||
}
|
||||
|
||||
if self.show_name_req_err {
|
||||
ui.colored_label(Color32::DARK_RED, "Error: Name required");
|
||||
}
|
||||
modal.caution_button(ui, "Cancel");
|
||||
});
|
||||
!close_unclicked || close_window
|
||||
});
|
||||
!modal.is_open()
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +141,9 @@ struct EditFilmWindow {
|
||||
}
|
||||
|
||||
impl EditFilmWindow {
|
||||
fn new(film: FilmKey, films: &Stash<Film, FilmKey>) -> Self {
|
||||
#[must_use]
|
||||
fn new(film: FilmKey, films: &Stash<Film, FilmKey>, ctx: &egui::Context) -> Self {
|
||||
Modal::new(ctx, "edit_film_modal").open();
|
||||
let name = films[film].name.clone();
|
||||
let iso = films[film].iso;
|
||||
Self {
|
||||
@ -164,15 +153,17 @@ impl EditFilmWindow {
|
||||
show_name_req_err: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationWindow for EditFilmWindow {
|
||||
fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool {
|
||||
let mut close_unclicked = true;
|
||||
let mut close_window = false;
|
||||
Window::new("Edit Film")
|
||||
.resizable(false)
|
||||
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
|
||||
.open(&mut close_unclicked)
|
||||
.show(ctx, |ui| {
|
||||
let modal = Modal::new(ctx, "edit_film_modal");
|
||||
modal.show(|ui| {
|
||||
modal.title(ui, "Edit film");
|
||||
modal.frame(ui, |ui| {
|
||||
if self.show_name_req_err {
|
||||
ui.colored_label(Color32::DARK_RED, "Error: Name required");
|
||||
}
|
||||
ui.horizontal(|ui| {
|
||||
let label = ui.label("Name:");
|
||||
ui.text_edit_singleline(&mut self.name)
|
||||
@ -183,20 +174,20 @@ impl EditFilmWindow {
|
||||
ui.add(DragValue::new(&mut self.iso).clamp_range(1..=u32::MAX))
|
||||
.labelled_by(label.id);
|
||||
});
|
||||
if ui.button("Submit").clicked() {
|
||||
});
|
||||
modal.buttons(ui, |ui| {
|
||||
if modal.button(ui, "Submit").clicked() {
|
||||
if self.name.is_empty() {
|
||||
self.show_name_req_err = true;
|
||||
return;
|
||||
}
|
||||
app_state.films[self.film] = Film::new(&self.name, self.iso);
|
||||
app_state.resort_roll_list = true;
|
||||
close_window = true;
|
||||
}
|
||||
if self.show_name_req_err {
|
||||
ui.colored_label(Color32::DARK_RED, "Error: Name required");
|
||||
}
|
||||
modal.caution_button(ui, "Cancel");
|
||||
});
|
||||
!close_unclicked || close_window
|
||||
});
|
||||
!modal.is_open()
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,32 +196,31 @@ struct DeleteFilmWindow {
|
||||
}
|
||||
|
||||
impl DeleteFilmWindow {
|
||||
fn new(film: FilmKey) -> Self {
|
||||
#[must_use]
|
||||
fn new(film: FilmKey, ctx: &egui::Context) -> Self {
|
||||
Modal::new(ctx, "delete_film_modal").open();
|
||||
Self { film }
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationWindow for DeleteFilmWindow {
|
||||
fn draw(&mut self, ctx: &egui::Context, app_state: &mut AppState) -> bool {
|
||||
let mut close_unclicked = true;
|
||||
let mut close_window = false;
|
||||
Window::new("Confirm delete")
|
||||
.resizable(false)
|
||||
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
|
||||
.open(&mut close_unclicked)
|
||||
.show(ctx, |ui| {
|
||||
ui.heading(format!(
|
||||
let modal = Modal::new(ctx, "delete_film_modal");
|
||||
modal.show(|ui| {
|
||||
modal.title(ui, "Confirm delete");
|
||||
modal.frame(ui, |ui| {
|
||||
modal.body(ui, format!(
|
||||
"Really delete {}?",
|
||||
&app_state.films[self.film].name
|
||||
));
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Yes").clicked() {
|
||||
app_state.films.take(self.film);
|
||||
close_window = true;
|
||||
}
|
||||
if ui.button("No").clicked() {
|
||||
close_window = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
!close_unclicked || close_window
|
||||
modal.buttons(ui, |ui| {
|
||||
if modal.caution_button(ui, "Yes").clicked() {
|
||||
app_state.films.take(self.film);
|
||||
};
|
||||
modal.button(ui, "No");
|
||||
})
|
||||
});
|
||||
!modal.is_open()
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ impl eframe::App for MyApp {
|
||||
.add_enabled(self.edit_films_window.is_none(), Button::new("Edit films"))
|
||||
.clicked()
|
||||
{
|
||||
self.edit_films_window = Some(EditFilmsWindow::new());
|
||||
self.edit_films_window = Some(EditFilmsWindow::new(&ctx));
|
||||
}
|
||||
ui.checkbox(&mut self.show_debug_info, "Show debug info");
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user