2019-11-21 13:47:20 +01:00
|
|
|
use crate::{Background, Bus, Element, Length, Widget};
|
2019-09-14 20:54:50 +02:00
|
|
|
|
2019-09-15 18:53:13 +02:00
|
|
|
use dodrio::bumpalo;
|
|
|
|
|
|
2019-11-21 13:47:20 +01:00
|
|
|
/// A generic widget that produces a message when clicked.
|
|
|
|
|
pub struct Button<'a, Message> {
|
|
|
|
|
content: Element<'a, Message>,
|
|
|
|
|
on_press: Option<Message>,
|
|
|
|
|
width: Length,
|
|
|
|
|
min_width: u32,
|
|
|
|
|
padding: u16,
|
|
|
|
|
background: Option<Background>,
|
|
|
|
|
border_radius: u16,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, Message> Button<'a, Message> {
|
|
|
|
|
/// Creates a new [`Button`] with some local [`State`] and the given
|
|
|
|
|
/// content.
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
/// [`State`]: struct.State.html
|
|
|
|
|
pub fn new<E>(_state: &'a mut State, content: E) -> Self
|
|
|
|
|
where
|
|
|
|
|
E: Into<Element<'a, Message>>,
|
|
|
|
|
{
|
|
|
|
|
Button {
|
|
|
|
|
content: content.into(),
|
|
|
|
|
on_press: None,
|
|
|
|
|
width: Length::Shrink,
|
|
|
|
|
min_width: 0,
|
|
|
|
|
padding: 0,
|
|
|
|
|
background: None,
|
|
|
|
|
border_radius: 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the width of the [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
pub fn width(mut self, width: Length) -> Self {
|
|
|
|
|
self.width = width;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the minimum width of the [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
pub fn min_width(mut self, min_width: u32) -> Self {
|
|
|
|
|
self.min_width = min_width;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the padding of the [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
pub fn padding(mut self, padding: u16) -> Self {
|
|
|
|
|
self.padding = padding;
|
|
|
|
|
self
|
|
|
|
|
}
|
2019-10-08 03:13:41 +02:00
|
|
|
|
2019-11-21 13:47:20 +01:00
|
|
|
/// Sets the [`Background`] of the [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
/// [`Background`]: ../../struct.Background.html
|
|
|
|
|
pub fn background(mut self, background: Background) -> Self {
|
|
|
|
|
self.background = Some(background);
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the border radius of the [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
pub fn border_radius(mut self, border_radius: u16) -> Self {
|
|
|
|
|
self.border_radius = border_radius;
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the message that will be produced when the [`Button`] is pressed.
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
pub fn on_press(mut self, msg: Message) -> Self {
|
|
|
|
|
self.on_press = Some(msg);
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The local state of a [`Button`].
|
|
|
|
|
///
|
|
|
|
|
/// [`Button`]: struct.Button.html
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
|
|
|
pub struct State;
|
|
|
|
|
|
|
|
|
|
impl State {
|
|
|
|
|
/// Creates a new [`State`].
|
|
|
|
|
///
|
|
|
|
|
/// [`State`]: struct.State.html
|
|
|
|
|
pub fn new() -> State {
|
|
|
|
|
State::default()
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-14 20:54:50 +02:00
|
|
|
|
2019-09-15 17:43:15 +02:00
|
|
|
impl<'a, Message> Widget<Message> for Button<'a, Message>
|
|
|
|
|
where
|
|
|
|
|
Message: 'static + Copy,
|
|
|
|
|
{
|
|
|
|
|
fn node<'b>(
|
|
|
|
|
&self,
|
|
|
|
|
bump: &'b bumpalo::Bump,
|
|
|
|
|
bus: &Bus<Message>,
|
|
|
|
|
) -> dodrio::Node<'b> {
|
|
|
|
|
use dodrio::builder::*;
|
|
|
|
|
|
2019-10-08 03:13:41 +02:00
|
|
|
let mut node =
|
|
|
|
|
button(bump).children(vec![self.content.node(bump, bus)]);
|
2019-09-15 17:43:15 +02:00
|
|
|
|
|
|
|
|
if let Some(on_press) = self.on_press {
|
|
|
|
|
let event_bus = bus.clone();
|
|
|
|
|
|
|
|
|
|
node = node.on("click", move |root, vdom, _event| {
|
|
|
|
|
event_bus.publish(on_press, root);
|
|
|
|
|
|
|
|
|
|
vdom.schedule_render();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-21 13:38:14 +02:00
|
|
|
// TODO: Complete styling
|
|
|
|
|
|
2019-09-15 17:43:15 +02:00
|
|
|
node.finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-14 20:54:50 +02:00
|
|
|
|
|
|
|
|
impl<'a, Message> From<Button<'a, Message>> for Element<'a, Message>
|
|
|
|
|
where
|
2019-09-15 17:43:15 +02:00
|
|
|
Message: 'static + Copy,
|
2019-09-14 20:54:50 +02:00
|
|
|
{
|
|
|
|
|
fn from(button: Button<'a, Message>) -> Element<'a, Message> {
|
|
|
|
|
Element::new(button)
|
|
|
|
|
}
|
|
|
|
|
}
|