use std::any::Any;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::task::Waker;
use smallvec::SmallVec;
use crate::draw::Primitive;
use crate::event::Event;
use crate::layout::*;
use crate::node::GenericNode;
use crate::style::*;
pub mod prelude {
pub use super::button::Button;
pub use super::column::Column;
pub use super::drag_drop::{Drag, Drop};
pub use super::dropdown::Dropdown;
pub use super::dummy::Dummy;
pub use super::frame::Frame;
pub use super::image::Image;
pub use super::input::Input;
pub use super::layers::Layers;
pub use super::menu::Menu;
pub use super::panel::Panel;
pub use super::progress::Progress;
pub use super::row::Row;
pub use super::scroll::Scroll;
pub use super::slider::Slider;
pub use super::spacer::Spacer;
pub use super::text::Text;
pub use super::toggle::Toggle;
pub use super::window::Window;
pub use super::{StateVec, Widget};
}
pub mod button;
pub mod column;
pub mod drag_drop;
pub mod dropdown;
pub mod dummy;
pub mod frame;
pub mod image;
pub mod input;
pub mod layers;
pub mod menu;
pub mod panel;
pub mod progress;
pub mod row;
pub mod scroll;
pub mod slider;
pub mod spacer;
pub mod text;
pub mod toggle;
pub mod window;
pub trait Widget<'a, Message>: Send {
type State: Any + Send + Sync;
fn key(&self) -> u64 {
let mut hasher = DefaultHasher::new();
std::any::type_name::<Self>().hash(&mut hasher);
hasher.finish()
}
fn mount(&self) -> Self::State;
fn widget(&self) -> &'static str;
fn state(&self, _state: &Self::State) -> StateVec {
StateVec::new()
}
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn visit_children(&mut self, visitor: &mut dyn FnMut(&mut dyn GenericNode<'a, Message>));
fn size(&self, state: &Self::State, style: &Stylesheet) -> (Size, Size);
fn hit(
&self,
_state: &Self::State,
layout: Rectangle,
clip: Rectangle,
_style: &Stylesheet,
x: f32,
y: f32,
) -> bool {
layout.point_inside(x, y) && clip.point_inside(x, y)
}
fn focused(&self, _state: &Self::State) -> bool {
false
}
fn event(
&mut self,
_state: &mut Self::State,
_layout: Rectangle,
_clip: Rectangle,
_style: &Stylesheet,
_event: Event,
_context: &mut Context<Message>,
) {
}
fn draw(
&mut self,
state: &mut Self::State,
layout: Rectangle,
clip: Rectangle,
style: &Stylesheet,
) -> Vec<Primitive<'a>>;
}
pub type StateVec = SmallVec<[StyleState<&'static str>; 3]>;
pub struct Context<Message> {
cursor: (f32, f32),
redraw: bool,
poll: bool,
messages: Vec<Message>,
waker: Waker,
}
impl<Message> Context<Message> {
pub(crate) fn new(redraw: bool, cursor: (f32, f32), waker: Waker) -> Self {
Context {
cursor,
redraw,
poll: false,
messages: Vec::new(),
waker,
}
}
pub(crate) fn sub_context<M>(&self) -> Context<M> {
Context {
cursor: self.cursor,
redraw: self.redraw,
poll: self.poll,
messages: Vec::new(),
waker: self.waker.clone(),
}
}
pub fn push(&mut self, message: Message) {
self.messages.push(message);
}
pub fn extend<I: IntoIterator<Item = Message>>(&mut self, iter: I) {
self.messages.extend(iter);
}
pub fn redraw(&mut self) {
self.redraw = true;
}
pub fn redraw_requested(&self) -> bool {
self.redraw
}
pub fn cursor(&self) -> (f32, f32) {
self.cursor
}
pub(crate) fn task_context(&self) -> std::task::Context<'_> {
std::task::Context::from_waker(&self.waker)
}
pub(crate) fn into_vec(self) -> Vec<Message> {
self.messages
}
}
impl<Message> IntoIterator for Context<Message> {
type Item = Message;
type IntoIter = std::vec::IntoIter<Message>;
fn into_iter(self) -> Self::IntoIter {
self.messages.into_iter()
}
}