first draft

This commit is contained in:
wiiznokes 2024-06-27 01:25:30 +02:00
parent 61760f8e4e
commit d9c34f7fe5
3 changed files with 207 additions and 0 deletions

View file

@ -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
View 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));
}
}

View 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)
}
}