first draft
This commit is contained in:
parent
61760f8e4e
commit
d9c34f7fe5
3 changed files with 207 additions and 0 deletions
|
|
@ -349,3 +349,7 @@ pub mod tooltip {
|
||||||
pub mod warning;
|
pub mod warning;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use warning::*;
|
pub use warning::*;
|
||||||
|
|
||||||
|
mod toaster;
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use toaster::toaster;
|
||||||
106
src/widget/toaster/mod.rs
Normal file
106
src/widget/toaster/mod.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
// Copyright 2024 wiiznokes
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use iced::{Command, Length};
|
||||||
|
use iced_core::{Element};
|
||||||
|
use crate::widget::container;
|
||||||
|
use crate::widget::Column;
|
||||||
|
use widget::Toaster;
|
||||||
|
|
||||||
|
use crate::ext::CollectionWidget;
|
||||||
|
|
||||||
|
use super::{button, row, text};
|
||||||
|
|
||||||
|
|
||||||
|
mod widget;
|
||||||
|
|
||||||
|
pub fn toaster<'a, Message: Clone + 'a, Theme, Renderer>(
|
||||||
|
toasts: &'a Toasts<Message>,
|
||||||
|
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
|
) -> Element<'a, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: iced_core::Renderer,
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
let make_toast = |toast: &Toast<Message>| {
|
||||||
|
|
||||||
|
let row = row()
|
||||||
|
.push(text(toast.message))
|
||||||
|
.push_maybe(toast.action.map(|t| button(text(t.0)).on_press(t.1)));
|
||||||
|
|
||||||
|
container(row)
|
||||||
|
.into()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let col = Column::with_children(toasts.toasts.iter().map(|t| {
|
||||||
|
make_toast(t)
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Toaster::new(col.into(), content.into()).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum ToastDuration {
|
||||||
|
Short,
|
||||||
|
Medium,
|
||||||
|
Long,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToastDuration {
|
||||||
|
fn duration(&self) -> Duration {
|
||||||
|
match self {
|
||||||
|
ToastDuration::Short => Duration::from_millis(200),
|
||||||
|
ToastDuration::Medium => Duration::from_millis(1000),
|
||||||
|
ToastDuration::Long => Duration::from_millis(5000),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Toast<Message> {
|
||||||
|
message: String,
|
||||||
|
/// (Description, message)
|
||||||
|
action: Option<(String, Message)>,
|
||||||
|
|
||||||
|
duration: ToastDuration,
|
||||||
|
|
||||||
|
id: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Toasts<Message> {
|
||||||
|
id_count: u32,
|
||||||
|
toasts: Vec<Toast<Message>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ToastMessage(u32);
|
||||||
|
|
||||||
|
impl<Message> Toasts<Message> {
|
||||||
|
pub fn push(&mut self, mut toast: Toast<Message>) -> Command<ToastMessage> {
|
||||||
|
toast.id = self.id_count;
|
||||||
|
self.id_count += 1;
|
||||||
|
|
||||||
|
let message = ToastMessage(toast.id);
|
||||||
|
let duration = toast.duration.duration();
|
||||||
|
|
||||||
|
self.toasts.push(toast);
|
||||||
|
|
||||||
|
Command::perform(
|
||||||
|
async move {
|
||||||
|
tokio::time::sleep(duration).await;
|
||||||
|
},
|
||||||
|
|_| message,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_message(&mut self, message: ToastMessage) {
|
||||||
|
self.toasts
|
||||||
|
.iter()
|
||||||
|
.position(|e| e.id == message.0)
|
||||||
|
.map(|index| self.toasts.remove(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
97
src/widget/toaster/widget.rs
Normal file
97
src/widget/toaster/widget.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2024 wiiznokes
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
use iced::Size;
|
||||||
|
use iced_runtime::core::widget::Id;
|
||||||
|
use iced_runtime::{keyboard, Command};
|
||||||
|
|
||||||
|
use iced_core::event::{self, Event};
|
||||||
|
use iced_core::renderer::{self, Quad, Renderer};
|
||||||
|
use iced_core::touch;
|
||||||
|
use iced_core::widget::tree::{self, Tree};
|
||||||
|
use iced_core::widget::Operation;
|
||||||
|
use iced_core::Element;
|
||||||
|
use iced_core::{layout, svg};
|
||||||
|
use iced_core::{mouse, Border};
|
||||||
|
use iced_core::{overlay, Shadow};
|
||||||
|
use iced_core::{
|
||||||
|
Background, Clipboard, Color, Layout, Length, Padding, Point, Rectangle, Shell, Vector, Widget,
|
||||||
|
};
|
||||||
|
use iced_renderer::core::widget::{operation, OperationOutputWrapper};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use super::Toasts;
|
||||||
|
|
||||||
|
pub struct Toaster<'a, Message, Theme, Renderer> {
|
||||||
|
toasts: Element<'a, Message, Theme, Renderer>,
|
||||||
|
content: Element<'a, Message, Theme, Renderer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Theme, Renderer> Toaster<'a, Message, Theme, Renderer> {
|
||||||
|
pub fn new(
|
||||||
|
toasts: Element<'a, Message, Theme, Renderer>,
|
||||||
|
content: Element<'a, Message, Theme, Renderer>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
toasts,
|
||||||
|
content,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
|
||||||
|
for Toaster<'a, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: iced_core::Renderer,
|
||||||
|
{
|
||||||
|
fn size(&self) -> Size<Length> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(
|
||||||
|
&self,
|
||||||
|
tree: &mut Tree,
|
||||||
|
renderer: &Renderer,
|
||||||
|
limits: &layout::Limits,
|
||||||
|
) -> layout::Node {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_interaction(
|
||||||
|
&self,
|
||||||
|
_state: &Tree,
|
||||||
|
_layout: Layout<'_>,
|
||||||
|
_cursor: mouse::Cursor,
|
||||||
|
_viewport: &Rectangle,
|
||||||
|
_renderer: &Renderer,
|
||||||
|
) -> mouse::Interaction {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(
|
||||||
|
&self,
|
||||||
|
tree: &Tree,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
theme: &Theme,
|
||||||
|
style: &renderer::Style,
|
||||||
|
layout: Layout<'_>,
|
||||||
|
cursor: mouse::Cursor,
|
||||||
|
viewport: &Rectangle,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message, Theme, Renderer> From<Toaster<'a, Message, Theme, Renderer>>
|
||||||
|
for Element<'a, Message, Theme, Renderer>
|
||||||
|
where
|
||||||
|
Renderer: renderer::Renderer + 'a,
|
||||||
|
Theme: 'a,
|
||||||
|
Message: 'a
|
||||||
|
{
|
||||||
|
fn from(
|
||||||
|
toggler: Toaster<'a, Message, Theme, Renderer>,
|
||||||
|
) -> Element<'a, Message, Theme, Renderer> {
|
||||||
|
Element::new(toggler)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue