diff options
| author | pml68 <contact@pml68.dev> | 2025-06-08 02:04:09 +0200 |
|---|---|---|
| committer | pml68 <contact@pml68.dev> | 2025-06-08 02:04:09 +0200 |
| commit | c1f50e1efa78ef7f35ed6f44828976fb7328d85b (patch) | |
| tree | a33930e87597b02aafa22e8f209e114eaef79912 /src/dialogs.rs | |
| parent | fix: animated theme change on startup when config theme != "Dark" (diff) | |
| download | iced-builder-c1f50e1efa78ef7f35ed6f44828976fb7328d85b.tar.gz | |
feat: dialog improvements
- "Unsaved changes" dialogs ask about saving the project
- Trying to close the window also triggers an "unsaved changes" dialog
when the editor is dirty.
- Nicer API for dialogs (similar to what I do in `foghorn-rs/foghorn`)
Diffstat (limited to 'src/dialogs.rs')
| -rw-r--r-- | src/dialogs.rs | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/src/dialogs.rs b/src/dialogs.rs index c1933ec..68bbd6e 100644 --- a/src/dialogs.rs +++ b/src/dialogs.rs @@ -1,47 +1,103 @@ -use iced::Task; +use std::borrow::Cow; + +use iced::widget::text; use iced_dialog::button; use crate::Message; -use crate::types::{DialogAction, DialogButtons, Element}; +use crate::types::Element; -pub const UNSAVED_CHANGES_TITLE: &str = "Unsaved changes"; +pub const UNSAVED_CHANGES_TITLE: &str = "Hold on for a sec!"; pub const WARNING_TITLE: &str = "Heads up!"; pub const ERROR_TITLE: &str = "Oops! Something went wrong."; -pub fn ok_button<'a>() -> Element<'a, Message> { - button("Ok", Message::DialogOk).into() +#[derive(Debug, Clone, Copy, Default)] +pub enum Action { + #[default] + None, + Close, + UnsavedChanges(UnsavedChanges), } -pub fn cancel_button<'a>() -> Element<'a, Message> { - button("Cancel", Message::DialogCancel).into() +#[derive(Debug, Clone, Copy)] +pub enum UnsavedChanges { + New, + Open, + Exit, } -pub fn error_dialog(description: impl Into<String>) -> Task<Message> { - Task::done(Message::OpenDialog( - ERROR_TITLE, - description.into(), - DialogButtons::Ok, - DialogAction::None, - )) +impl From<Action> for Vec<Element<'_, Message>> { + fn from(action: Action) -> Self { + match action { + Action::None => vec![], + Action::Close => vec![button("Close", Message::DialogYes).into()], + Action::UnsavedChanges(_) => vec![ + button("Don't Save", Message::DialogNo).into(), + button("Save", Message::DialogYes).into(), + button("Cancel", Message::DialogCancel).into(), + ], + } + } } -pub fn warning_dialog(description: impl Into<String>) -> Task<Message> { - Task::done(Message::OpenDialog( - WARNING_TITLE, - description.into(), - DialogButtons::Ok, - DialogAction::None, - )) +#[derive(Debug, Default)] +pub struct Dialog { + is_open: bool, + title: Cow<'static, str>, + content: Cow<'static, str>, + action: Action, } -pub fn unsaved_changes_dialog( - description: impl Into<String>, - action: DialogAction, -) -> Task<Message> { - Task::done(Message::OpenDialog( - UNSAVED_CHANGES_TITLE, - description.into(), - DialogButtons::OkCancel, - action, - )) +impl Dialog { + pub fn new( + title: impl Into<Cow<'static, str>>, + content: impl Into<Cow<'static, str>>, + action: Action, + ) -> Self { + Self { + is_open: true, + title: title.into(), + content: content.into(), + action, + } + } + + pub fn error(content: impl Into<Cow<'static, str>>) -> Self { + Self::new(ERROR_TITLE, content, Action::Close) + } + + pub fn warning(content: impl Into<Cow<'static, str>>) -> Self { + Self::new(WARNING_TITLE, content, Action::Close) + } + + pub fn unsaved_changes( + content: impl Into<Cow<'static, str>>, + unsaved_changes: UnsavedChanges, + ) -> Self { + Self::new( + UNSAVED_CHANGES_TITLE, + content, + Action::UnsavedChanges(unsaved_changes), + ) + } + + pub fn close(&mut self) { + self.is_open = false; + } + + pub fn action(&self) -> Action { + self.action + } + + pub fn as_iced_dialog<'a>( + &'a self, + base: impl Into<Element<'a, Message>>, + ) -> iced_dialog::Dialog<'a, Message, material_theme::Theme> { + iced_dialog::Dialog::with_buttons( + self.is_open, + base, + text(&*self.content), + self.action.into(), + ) + .title(&*self.title) + } } |
