diff --git a/README.md b/README.md
index 524f831..610dcb8 100644
--- a/README.md
+++ b/README.md
@@ -8,156 +8,39 @@ or suddenly realize the script has stopped for a long while.
It'll be reassuring that the script can stop with a friendly gesture.
-
-## Usage
+## Features
+
+winsdk_toast can pop up Windows Toast Notifications that contain
+
+- [x] Text
+- [x] Image
+- [x] Input
+ - [x] Text
+ - [x] Selection
+- [x] Audio
+ - [x] Buit-in
+ - [ ] Custom
+- [x] Progress
+ - [x] Still
+ - [ ] Live
+- [x] Group
+- [x] Event
+
+## Minimal Example
```python
-from os.path import abspath
from winsdk_toast import Notifier, Toast
-path_pic = abspath('./example/resource/python.ico')
notifier = Notifier('程序名 applicationId')
-
-# %% minimal example
toast = Toast()
toast.add_text('第一行 1st line')
notifier.show(toast)
-# %% which is equivalent to
-xml = """
-
-
-
- 第一行 1st line
-
-
-
-"""
-toast = Toast(xml)
-notifier.show(toast)
-
-
-# %% simple example
-toast = Toast()
-toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
-toast.add_text('第二行 2nd line')
-toast.add_text('第三行 3rd line', placement='attribution')
-toast.add_image(path_pic, placement='appLogoOverride')
-toast.add_action('关闭 Close')
-toast.set_audio(silent='true')
-notifier.show(toast)
-# %% which is equivalent to
-xml = f"""
-
-
-
- 第一行 1st line
- 第二行 2nd line
- 第三行 3rd line
-
-
-
-
-
-
-
-"""
-toast = Toast(xml)
-notifier.show(toast)
-
-# %% example for control freak
-toast = Toast()
-element_toast = toast.set_toast(
- launch='blah', duration='long', displayTimeStamp='2022-04-01T12:00:00Z', scenario='default',
- useButtonStyle='false', activationType='background'
-)
-element_visual = toast.set_visual(
- version='1', lang='zh-CN', baseUri='ms-appx:///', branding='none', addImageQuery='false'
-)
-element_binding = toast.set_binding(
- template='ToastGeneric', fallback='2ndtemplate', lang='zh-CN', addImageQuery='false',
- baseUri='ms-appx:///', branding='none'
-)
-element_text = toast.add_text(
- text='第一行 1st line for control freak', id_='1', lang='zh-CN', placement=None,
- hint_maxLines='1', hint_style='title', hint_align='center', hint_wrap='false',
- element_parent=element_binding
-)
-element_group = toast.add_group()
-element_subgroup_left = toast.add_subgroup(element_parent=element_group)
-element_text = toast.add_text(
- text='第二行 2nd line for control freak', id_='2', lang='zh-CN', placement=None,
- hint_maxLines='1', hint_style='captionSubtle ', hint_align='left', hint_wrap='false',
- element_parent=element_subgroup_left
-)
-element_subgroup_right = toast.add_subgroup(element_parent=element_group)
-element_text = toast.add_text(
- text='第三行 3rd line for control freak', id_='3', lang='zh-CN', placement='attribution',
- hint_maxLines='1', hint_style='captionSubtle', hint_align='left', hint_wrap='false',
- element_parent=element_subgroup_right
-)
-toast.add_image(
- path_pic, id_=None, alt='', addImageQuery='false',
- placement='appLogoOverride', hint_crop='circle'
-)
-toast.set_actions()
-toast.add_action(
- '关闭 Close', arguments='dismiss', activationType='system', placement=None,
- imageUri=None, hint_inputId=None, hint_buttonStyle=None, hint_toolTip='tip close'
-)
-notifier.show(toast)
-# %% which is equivalent to
-xml = f"""
-
-
-
- 第一行 1st line for control freak
-
-
- 第二行 2nd line for control freak
-
-
- 第三行 3rd line for control freak
-
-
-
-
-
-
-
-
-
-"""
-toast = Toast(xml)
-notifier.show(toast)
```
-The corresponding effects are like:
-
-![minimal_example.gif](doc/pic/minimal_example.gif)
-
-![simple_example.gif](doc/pic/simple_example.gif)
-
-![example_for_control_freak.gif](doc/pic/example_for_control_freak.gif)
-
-
-## Todo
-
-- Events and callbacks.
-- Documentation.
-- Costume audio. According to [Microsoft Docs], this might be tricky.
-- ...
-
-[Microsoft Docs]: https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/custom-audio-on-toasts
-## else
+![minimal_example.gif](docs/source/Examples/pics/minimal.gif)
-When I almost make it work, I found another package [windows_toast]
-which has the same dependency and more features.
-Luckily our 'styles' are quite different, and I'm on vacation,
-so I decide to finish it any way.
+More examples and documents are on the way.
-If you need more features now, please use [windows_toast] instead,
-maybe give this one a try later.
[winsdk]: https://pypi.org/project/winsdk
-[windows_toast]: https://github.com/DatGuy1/Windows-Toasts
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..d0c3cbf
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..dc1312a
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/source/Examples/events.md b/docs/source/Examples/events.md
new file mode 100644
index 0000000..ccf041b
--- /dev/null
+++ b/docs/source/Examples/events.md
@@ -0,0 +1,94 @@
+# Events
+
+A Toast Notification ends up with an event among `Activated`, `Dissmissed` and `Failed`.
+
+By default, `Notifier` handles `Activated` by printing the argument of the Action(button) and the inputs of Inputs, handes `Dissmissed` by printing the reason of `Dissmissed`, handles `Failed` by raising error_code.
+
+```python
+from winsdk_toast import Notifier, Toast
+
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_input(type_='text', id_='input_name')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true') # Mute
+
+# Step3. Show the Toast
+notifier.show(toast)
+```
+
+If click the `X` at the top-right, `Dissmissed` event happens and prints
+
+```
+Dismissed reason: UserCanceled
+```
+
+If wait till it disappears, `Dissmissed` event happens and prints
+
+```
+Dismissed reason: TimeOut
+```
+
+If click the `关闭 Close` button, `Activated` event happens and prints
+
+```
+Activated with
+ argument: dismiss
+ inputs: {'input_name': ''}
+```
+
+If type `test input` in the input box and click on `关闭 Close` button, `Activated` event happens and prints
+
+```
+Activated with
+ argument: dismiss
+ inputs: {'input_name': 'test input'}
+```
+
+I haven't figured out how the `activationType` and `arguments` of `action` work, so just leave them to dismiss the Toast Notification.
+
+## Custom `handle`
+
+Just define the functions that handle the `EventArgsActivated`, `EventArgsDismissed`, `EventArgsFailed` respectively, and pass them to `notifier.show`.
+
+```python
+from winsdk_toast import Notifier, Toast
+from winsdk_toast.event import EventArgsActivated, EventArgsDismissed, EventArgsFailed
+
+
+def handle_activated(event_args_activated: EventArgsActivated):
+ print('activated')
+ print('inputs:', event_args_activated.inputs)
+ print('argument:', event_args_activated.argument)
+
+
+def handle_dismissed(event_args_dismissed: EventArgsDismissed):
+ print('dismissed')
+ print('reason:', event_args_dismissed.reason)
+
+
+def handle_failed(event_args_failed: EventArgsFailed):
+ print('failed')
+ print('error_code:', event_args_failed.error_code)
+
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_input(type_='text', id_='input_name')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true') # Mute
+
+# Step3. Show the Toast
+notifier.show(
+ toast, handle_activated=handle_activated, handle_dismissed=handle_dismissed, handle_failed=handle_failed
+)
+```
\ No newline at end of file
diff --git a/docs/source/Examples/index.rst b/docs/source/Examples/index.rst
new file mode 100644
index 0000000..7c01504
--- /dev/null
+++ b/docs/source/Examples/index.rst
@@ -0,0 +1,9 @@
+Examples
+========================================
+
+.. toctree::
+ :maxdepth: 2
+
+ minimal.md
+ pic_and_button.md
+ events.md
diff --git a/docs/source/Examples/minimal.md b/docs/source/Examples/minimal.md
new file mode 100644
index 0000000..41b90d4
--- /dev/null
+++ b/docs/source/Examples/minimal.md
@@ -0,0 +1,43 @@
+# Minimal
+
+```python
+from winsdk_toast import Notifier, Toast
+
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+toast = Toast()
+toast.add_text('第一行 1st line')
+
+# Step3. Show the Toast
+notifier.show(toast)
+```
+
+![minimal.gif](pics/minimal.gif)
+
+Which can also be achieved by
+
+```python
+from winsdk_toast import Notifier, Toast
+
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+xml = """
+
+
+
+ 第一行 1st line
+
+
+
+"""
+toast = Toast(xml)
+
+# Step3. Show the Toast
+notifier.show(toast)
+```
diff --git a/docs/source/Examples/pic_and_button.md b/docs/source/Examples/pic_and_button.md
new file mode 100644
index 0000000..0b3d7a5
--- /dev/null
+++ b/docs/source/Examples/pic_and_button.md
@@ -0,0 +1,66 @@
+# pic and button
+
+```python
+from os.path import abspath
+
+from winsdk_toast import Notifier, Toast
+
+
+# absolute path of the picture to be shown
+path_pic = abspath('./resource/python.ico')
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_text('第二行 2nd line')
+toast.add_text('第三行 3rd line', placement='attribution')
+toast.add_image(path_pic, placement='appLogoOverride')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true') # Mute
+
+# Step3. Show the Toast
+notifier.show(toast)
+```
+
+![simple.gif](pics/simple.gif)
+
+Which can also be achieved by
+
+```python
+from os.path import abspath
+
+from winsdk_toast import Notifier, Toast
+
+
+# absolute path of the picture to be shown
+path_pic = abspath('./resource/python.ico')
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+xml = f"""
+
+
+
+ 第一行 1st line
+ 第二行 2nd line
+ 第三行 3rd line
+
+
+
+
+
+
+
+"""
+toast = Toast(xml)
+
+# Step3. Show the Toast
+notifier.show(toast)
+```
+
+
diff --git a/doc/pic/example_for_control_freak.gif b/docs/source/Examples/pics/example_for_control_freak.gif
similarity index 100%
rename from doc/pic/example_for_control_freak.gif
rename to docs/source/Examples/pics/example_for_control_freak.gif
diff --git a/doc/pic/minimal_example.gif b/docs/source/Examples/pics/minimal.gif
similarity index 100%
rename from doc/pic/minimal_example.gif
rename to docs/source/Examples/pics/minimal.gif
diff --git a/doc/pic/simple_example.gif b/docs/source/Examples/pics/simple.gif
similarity index 100%
rename from doc/pic/simple_example.gif
rename to docs/source/Examples/pics/simple.gif
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..04d622e
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,56 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'winsdk_toast'
+copyright = '2022, modabao'
+author = 'modabao'
+
+# The full version, including alpha/beta/rc tags
+release = '0.1.0'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'myst_parser'
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme' # 'alabaster'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 0000000..463ab2f
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,21 @@
+.. winsdk_toast documentation master file, created by
+ sphinx-quickstart on Sat May 14 17:43:29 2022.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to winsdk_toast's documentation!
+========================================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ Examples/index
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/example/custom_handle.py b/example/custom_handle.py
new file mode 100644
index 0000000..b725403
--- /dev/null
+++ b/example/custom_handle.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+"""
+simple example
+
+@Author: modabao
+@Time: 2022/5/3 10:33
+"""
+
+from winsdk_toast import Notifier, Toast
+from winsdk_toast.event import EventArgsActivated, EventArgsDismissed, EventArgsFailed
+
+
+def handle_activated(event_args_activated: EventArgsActivated):
+ print('activated')
+ print('inputs:', event_args_activated.inputs)
+ print('argument:', event_args_activated.argument)
+
+
+def handle_dismissed(event_args_dismissed: EventArgsDismissed):
+ print('dismissed')
+ print('reason:', event_args_dismissed.reason)
+
+
+def handle_failed(event_args_failed: EventArgsFailed):
+ print('failed')
+ print('error_code:', event_args_failed.error_code)
+
+
+# Step1. Create Notifier with applicationId
+notifier = Notifier('程序名 applicationId')
+
+# Step2. Create Toast which contains the message to be shown
+toast = Toast()
+toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
+toast.add_input(type_='text', id_='input_name')
+toast.add_action('关闭 Close')
+toast.set_audio(silent='true') # Mute
+
+# Step3. Show the Toast
+notifier.show(
+ toast, handle_activated=handle_activated, handle_dismissed=handle_dismissed, handle_failed=handle_failed
+)
diff --git a/example/minimal.py b/example/minimal.py
index da593ce..b2ca7e4 100644
--- a/example/minimal.py
+++ b/example/minimal.py
@@ -9,22 +9,25 @@
from winsdk_toast import Notifier, Toast
+# Step1. Create Notifier with applicationId
notifier = Notifier('程序名 applicationId')
-# %% minimal example
+# Step2. Create Toast which contains the message to be shown
toast = Toast()
toast.add_text('第一行 1st line')
+
+# Step3. Show the Toast
notifier.show(toast)
# %% which is equivalent to
-xml = """
-
-
-
- 第一行 1st line
-
-
-
-"""
-toast = Toast(xml)
-notifier.show(toast)
+# xml = """
+#
+#
+#
+# 第一行 1st line
+#
+#
+#
+# """
+# toast = Toast(xml)
+# notifier.show(toast)
diff --git a/example/simple.py b/example/simple.py
index a997feb..313fe76 100644
--- a/example/simple.py
+++ b/example/simple.py
@@ -10,35 +10,54 @@
from winsdk_toast import Notifier, Toast
+
+# absolute path of the picture to be shown
path_pic = abspath('./resource/python.ico')
+# Step1. Create Notifier with applicationId
notifier = Notifier('程序名 applicationId')
-# %% simple example
+# Step2. Create Toast which contains the message to be shown
toast = Toast()
toast.add_text('第一行 1st line', hint_align='center', hint_style='caption')
toast.add_text('第二行 2nd line')
toast.add_text('第三行 3rd line', placement='attribution')
toast.add_image(path_pic, placement='appLogoOverride')
toast.add_action('关闭 Close')
-toast.set_audio(silent='true')
+toast.set_audio(silent='true') # Mute
+
+# Step3. Show the Toast
notifier.show(toast)
+
# %% which is equivalent to
-xml = f"""
-
-
-
- 第一行 1st line
- 第二行 2nd line
- 第三行 3rd line
-
-
-
-
-
-
-
-"""
-toast = Toast(xml)
-notifier.show(toast)
+#
+# from os.path import abspath
+#
+# from winsdk_toast import Notifier, Toast
+#
+# path_pic = abspath('./resource/python.ico')
+#
+# # Step1. Create Notifier with applicationId
+# notifier = Notifier('程序名 applicationId')
+#
+# # Step2. Create Toast which contains the message to be shown
+# xml = f"""
+#
+#
+#
+# 第一行 1st line
+# 第二行 2nd line
+# 第三行 3rd line
+#
+#
+#
+#
+#
+#
+#
+# """
+# toast = Toast(xml)
+#
+# # Step3. Show the Toast
+# notifier.show(toast)
diff --git a/src/winsdk_toast/__init__.py b/src/winsdk_toast/__init__.py
index 666f8b0..30aba7f 100644
--- a/src/winsdk_toast/__init__.py
+++ b/src/winsdk_toast/__init__.py
@@ -9,4 +9,4 @@
from winsdk_toast.notifier import Notifier
__all__ = ['Toast', 'Notifier']
-__version__ = '0.0.2'
+__version__ = '0.1.0'
diff --git a/src/winsdk_toast/event.py b/src/winsdk_toast/event.py
new file mode 100644
index 0000000..585f492
--- /dev/null
+++ b/src/winsdk_toast/event.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+"""
+
+@Author: modabao
+@Time: 2022/5/8 14:57
+"""
+
+from winsdk.windows.foundation import IPropertyValue
+from winsdk.windows.ui.notifications import ToastActivatedEventArgs, ToastDismissedEventArgs, ToastFailedEventArgs
+
+
+class EventArgsActivated(object):
+ """
+ https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastactivatedeventargs?view=winrt-22000
+ """
+ def __init__(self, sender, event_args, input_ids):
+ self.sender = sender
+ event_args = ToastActivatedEventArgs._from(event_args)
+ self.argument = event_args.arguments
+ self.inputs = {
+ input_id: IPropertyValue._from(event_args.user_input.lookup(input_id)).get_string()
+ for input_id in input_ids
+ }
+
+
+class EventArgsDismissed(object):
+ """
+ https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastdismissedeventargs?view=winrt-22000
+ """
+ def __init__(self, sender, event_args):
+ self.sender = sender
+ event_args = ToastDismissedEventArgs._from(event_args)
+ self.reason = ['UserCanceled', 'ApplicationHidden', 'TimeOut'][event_args.reason]
+
+
+class EventArgsFailed(object):
+ """
+ https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastdismissedeventargs?view=winrt-22000
+ """
+ def __init__(self, sender, event_args):
+ self.sender = sender
+ event_args = ToastFailedEventArgs._from(event_args)
+ self.error_code = event_args.error_code
+
+
+def handle_activated(event_args_activated: EventArgsActivated):
+ print(f'Activated with')
+ print(f'\targument: {event_args_activated.argument}')
+ print(f'\tinputs: {event_args_activated.inputs}')
+
+
+def handle_dismissed(event_args_dismissed: EventArgsDismissed):
+ print(f'Dismissed reason: {event_args_dismissed.reason}')
+
+
+def handle_failed(event_args_failed: EventArgsFailed):
+ raise RuntimeError(event_args_failed.error_code)
diff --git a/src/winsdk_toast/notifier.py b/src/winsdk_toast/notifier.py
index 72e8d8a..334b1ca 100644
--- a/src/winsdk_toast/notifier.py
+++ b/src/winsdk_toast/notifier.py
@@ -5,9 +5,63 @@
@Time: 2022/5/1 11:52
"""
+import asyncio
+
from winsdk.windows.ui.notifications import ToastNotificationManager
from winsdk_toast.toast import Toast
+from winsdk_toast.event import (
+ EventArgsActivated, EventArgsDismissed, EventArgsFailed,
+ handle_activated, handle_dismissed, handle_failed
+)
+
+
+async def show(
+ toast_notifier, toast: Toast,
+ handle_activated=handle_activated, handle_dismissed=handle_dismissed, handle_failed=handle_failed
+):
+ toast_notification = toast.suit_up()
+ event_loop = asyncio.get_running_loop()
+ aws = []
+ tokens = {}
+
+ future_activated = event_loop.create_future()
+ token_activated = toast_notification.add_activated(
+ lambda sender, event_args: event_loop.call_soon_threadsafe(
+ future_activated.set_result, handle_activated(EventArgsActivated(sender, event_args, toast.input_ids))
+ )
+ )
+ aws.append(future_activated)
+ tokens['activated'] = token_activated
+
+ future_dismissed = event_loop.create_future()
+ token_dismissed = toast_notification.add_dismissed(
+ lambda sender, event_args: event_loop.call_soon_threadsafe(
+ future_dismissed.set_result, handle_dismissed(EventArgsDismissed(sender, event_args)))
+ )
+ aws.append(future_dismissed)
+ tokens['dismissed'] = token_dismissed
+
+ future_failed = event_loop.create_future()
+ token_failed = toast_notification.add_failed(
+ lambda sender, event_args: event_loop.call_soon_threadsafe(
+ future_failed.set_result, handle_failed(EventArgsFailed(sender, event_args)))
+ )
+ aws.append(future_failed)
+ tokens['failed'] = token_failed
+
+ toast_notifier.show(toast_notification)
+ try:
+ [done], pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
+ for p in pending:
+ p.cancel()
+ finally:
+ if (token_activated := tokens['activated']) is not None:
+ toast_notification.remove_activated(token_activated)
+ if (token_dismissed := tokens['dismissed']) is not None:
+ toast_notification.remove_dismissed(token_dismissed)
+ if (token_failed := tokens['failed']) is not None:
+ toast_notification.remove_failed(token_failed)
class Notifier(object):
@@ -19,5 +73,7 @@ def __init__(self, applicationId):
"""
self.toast_notifier = ToastNotificationManager.create_toast_notifier(applicationId)
- def show(self, toast: Toast):
- self.toast_notifier.show(toast.suit_up())
+ def show(self, toast: Toast,
+ handle_activated=handle_activated, handle_dismissed=handle_dismissed, handle_failed=handle_failed):
+ asyncio.run(show(self.toast_notifier, toast, handle_activated, handle_dismissed, handle_failed))
+
diff --git a/src/winsdk_toast/toast.py b/src/winsdk_toast/toast.py
index b8809b9..9d2cba2 100644
--- a/src/winsdk_toast/toast.py
+++ b/src/winsdk_toast/toast.py
@@ -22,6 +22,7 @@ def __init__(self, xml=None):
self.xml_document = XmlDocument()
if xml is not None:
self.xml_document.load_xml(xml)
+ self.input_ids = []
def suit_up(self):
"""Suit up to face notifier
@@ -314,6 +315,7 @@ def add_input(self, type_, id_=None, placeHolderContent=None, element_parent=Non
'placeHolderContent': placeHolderContent
}
set_attributes(element_input, attributes)
+ self.input_ids.append(id_)
return element_input
def add_selection(self, id_=None, content=None, element_parent=None):