summaryrefslogtreecommitdiff
path: root/src/dialogs.rs
diff options
context:
space:
mode:
authorpml68 <contact@pml68.dev>2025-06-08 02:04:09 +0200
committerpml68 <contact@pml68.dev>2025-06-08 02:04:09 +0200
commitc1f50e1efa78ef7f35ed6f44828976fb7328d85b (patch)
treea33930e87597b02aafa22e8f209e114eaef79912 /src/dialogs.rs
parentfix: animated theme change on startup when config theme != "Dark" (diff)
downloadiced-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 '')
-rw-r--r--src/dialogs.rs118
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)
+ }
}