Skip to content

Commit

Permalink
feat: Add selection field support to toast inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
AtifChy committed May 30, 2024
1 parent b53e2e8 commit d13cda8
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 9 deletions.
14 changes: 11 additions & 3 deletions examples/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use winrt_toast::content::image::{ImageHintCrop, ImagePlacement};
use winrt_toast::content::input::InputType;
use winrt_toast::content::text::TextPlacement;
use winrt_toast::{
Action, ActivatedAction, DismissalReason, Image, Input, Result, Text, Toast, ToastDuration,
ToastManager,
Action, ActivatedAction, DismissalReason, Image, Input, Result, Selection, Text, Toast,
ToastDuration, ToastManager,
};

fn main() -> Result<()> {
Expand All @@ -27,14 +27,22 @@ fn main() -> Result<()> {
.with_hint_crop(ImageHintCrop::Circle);

toast
.tag("example")
.text1("Title")
.text2(Text::new("Body"))
.text3(Text::new("Via SMS").with_placement(TextPlacement::Attribution))
.image(1, hero_image)
.image(2, icon_image)
.duration(ToastDuration::Long)
.audio(Audio::new(Sound::Looping(LoopingSound::Alarm5)).with_looping())
.input(Input::new("box", InputType::Text).with_placeholder("Type here..."))
.input(
Input::new("box", InputType::Selection)
.with_title("Select an option")
.with_default_input("breakfast"),
)
.selection(Selection::new("breakfast", "Breakfast"))
.selection(Selection::new("lunch", "Lunch"))
.selection(Selection::new("dinner", "Dinner"))
.action(Action::new("Send", "send", "").with_input_id("box"))
.action(Action::new("Dismiss", "dismiss", ""));

Expand Down
35 changes: 35 additions & 0 deletions src/content/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Input {
type_: InputType,
place_holder: Option<String>,
title: Option<String>,
default_input: Option<String>,
}

impl Input {
Expand All @@ -18,6 +19,7 @@ impl Input {
type_,
place_holder: None,
title: None,
default_input: None,
}
}

Expand All @@ -33,6 +35,12 @@ impl Input {
self
}

/// The default input of the input.
pub fn with_default_input(mut self, default_input: impl Into<String>) -> Self {
self.default_input = Some(default_input.into());
self
}

pub(crate) fn write_to_element(&self, el: &XmlElement) -> crate::Result<()> {
el.SetAttribute(&hs("id"), &hs(&self.id))?;
el.SetAttribute(&hs("type"), &hs(self.type_.as_str()))?;
Expand All @@ -42,6 +50,9 @@ impl Input {
if let Some(title) = &self.title {
el.SetAttribute(&hs("title"), &hs(title))?;
}
if let Some(default_input) = &self.default_input {
el.SetAttribute(&hs("defaultInput"), &hs(default_input))?;
}

Ok(())
}
Expand All @@ -64,3 +75,27 @@ impl InputType {
}
}
}

/// Represents a selection in a selection input field.
#[derive(Debug, Clone)]
pub struct Selection {
id: String,
content: String,
}

impl Selection {
/// Create a new selection.
pub fn new(id: impl Into<String>, content: impl Into<String>) -> Self {
Self {
id: id.into(),
content: content.into(),
}
}

pub(crate) fn write_to_element(&self, el: &XmlElement) -> crate::Result<()> {
el.SetAttribute(&hs("id"), &hs(&self.id))?;
el.SetAttribute(&hs("content"), &hs(&self.content))?;

Ok(())
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub use content::audio::Audio;
pub use content::header::Header;
pub use content::image::Image;
pub use content::input::Input;
pub use content::input::Selection;
pub use content::text::Text;

mod manager;
Expand Down
23 changes: 18 additions & 5 deletions src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl ToastManager {
where
F: FnMut(Option<ActivatedAction>) + Send + 'static,
{
let id: String = input_id.map_or_else(|| "".to_string(), |s| s.to_string());
let id = input_id.map_or("".to_string(), |s| s.to_string());
self.on_activated = Some(TypedEventHandler::new(
move |_, args: &Option<IInspectable>| {
f(Self::get_activated_action(args, id.clone()));
Expand Down Expand Up @@ -292,19 +292,32 @@ impl ToastManager {
}
// </audio>
// <actions>
if !toast.actions.is_empty() {
if toast.input.is_some() || !toast.actions.is_empty() {
let actions_el = toast_doc.CreateElement(&hs("actions"))?;
toast_el.AppendChild(&actions_el)?;
// <input>
if let Some(input) = &toast.input {
let el = toast_doc.CreateElement(&hs("input"))?;
actions_el.AppendChild(&el)?;
input.write_to_element(&el)?;
let input_el = toast_doc.CreateElement(&hs("input"))?;
actions_el.AppendChild(&input_el)?;
input.write_to_element(&input_el)?;
// <selection>
{
for selection in &toast.selections {
let el = toast_doc.CreateElement(&hs("selection"))?;
input_el.AppendChild(&el)?;
selection.write_to_element(&el)?;
}
}
// </selection>
}
// </input>
// <action>
for action in &toast.actions {
let el = toast_doc.CreateElement(&hs("action"))?;
actions_el.AppendChild(&el)?;
action.write_to_element(&el)?;
}
// </action>
}
// </actions>

Expand Down
9 changes: 8 additions & 1 deletion src/toast.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt::Debug;
use std::{collections::HashMap, time::Duration};

use crate::{Action, Audio, Header, Image, Input, Text};
use crate::{Action, Audio, Header, Image, Input, Selection, Text};

/// Represents a Windows toast.
///
Expand All @@ -22,6 +22,7 @@ pub struct Toast {
pub(crate) audio: Option<Audio>,
pub(crate) actions: Vec<Action>,
pub(crate) input: Option<Input>,
pub(crate) selections: Vec<Selection>,
pub(crate) use_button_style: Option<UseButtonStyle>,
}

Expand Down Expand Up @@ -86,6 +87,12 @@ impl Toast {
self
}

/// Add a selection field to the toast.
pub fn selection(&mut self, selection: Selection) -> &mut Toast {
self.selections.push(selection);
self
}

/// Add a new action to the toast.
pub fn action(&mut self, action: Action) -> &mut Toast {
self.actions.push(action);
Expand Down

0 comments on commit d13cda8

Please sign in to comment.