diff options
author | 2019-11-21 13:47:20 +0100 | |
---|---|---|
committer | 2019-11-21 13:47:20 +0100 | |
commit | 65eb218d3d7ba52b2869a586a1480eeb3c8f84e4 (patch) | |
tree | 644f27f40f2f4b8ee1abe7743aac426297503eea /native/src/widget/button.rs | |
parent | d3553adf278e5b616fbd885f321faa83a4d24b56 (diff) | |
download | iced-65eb218d3d7ba52b2869a586a1480eeb3c8f84e4.tar.gz iced-65eb218d3d7ba52b2869a586a1480eeb3c8f84e4.tar.bz2 iced-65eb218d3d7ba52b2869a586a1480eeb3c8f84e4.zip |
Move widgets from `core` to `native` and `web`
Also made fields private and improved `Renderer` traits.
Diffstat (limited to 'native/src/widget/button.rs')
-rw-r--r-- | native/src/widget/button.rs | 166 |
1 files changed, 142 insertions, 24 deletions
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 15beaeba..f2cce3d2 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -1,32 +1,144 @@ //! Allow your users to perform actions by pressing a button. //! -//! A [`Button`] has some local [`State`] and a [`Class`]. +//! A [`Button`] has some local [`State`]. //! //! [`Button`]: struct.Button.html //! [`State`]: struct.State.html -//! [`Class`]: enum.Class.html -use crate::input::{mouse, ButtonState}; -use crate::{layout, Element, Event, Hasher, Layout, Point, Widget}; +use crate::{ + input::{mouse, ButtonState}, + layout, Background, Element, Event, Hasher, Layout, Length, Point, + Rectangle, Widget, +}; use std::hash::Hash; -pub use iced_core::button::State; +/// A generic widget that produces a message when clicked. +pub struct Button<'a, Message, Renderer> { + state: &'a mut State, + content: Element<'a, Message, Renderer>, + on_press: Option<Message>, + width: Length, + min_width: u32, + padding: u16, + background: Option<Background>, + border_radius: u16, +} + +impl<'a, Message, Renderer> Button<'a, Message, Renderer> { + /// 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, Renderer>>, + { + Button { + state, + 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 + } + + /// 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 + } -pub type Button<'a, Message, Renderer> = - iced_core::Button<'a, Message, Element<'a, Message, Renderer>>; + /// 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 { + is_pressed: bool, +} + +impl State { + /// Creates a new [`State`]. + /// + /// [`State`]: struct.State.html + pub fn new() -> State { + State::default() + } +} impl<'a, Message, Renderer> Widget<Message, Renderer> for Button<'a, Message, Renderer> where Renderer: self::Renderer, - Message: Clone + std::fmt::Debug, + Message: Clone, { fn layout( &self, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - renderer.layout(&self, limits) + let padding = f32::from(self.padding); + let limits = limits + .min_width(self.min_width) + .width(self.width) + .height(Length::Shrink) + .pad(padding); + + let mut content = self.content.layout(renderer, &limits); + + content.bounds.x = padding; + content.bounds.y = padding; + + let size = limits.resolve(content.size()).pad(padding); + + layout::Node::with_children(size, vec![content]) } fn on_event( @@ -73,7 +185,20 @@ where layout: Layout<'_>, cursor_position: Point, ) -> Renderer::Output { - renderer.draw(&self, layout, cursor_position) + let content = self.content.draw( + renderer, + layout.children().next().unwrap(), + cursor_position, + ); + + renderer.draw( + layout.bounds(), + cursor_position, + self.state.is_pressed, + self.background, + self.border_radius, + content, + ) } fn hash_layout(&self, state: &mut Hasher) { @@ -90,24 +215,17 @@ where /// [`Button`]: struct.Button.html /// [renderer]: ../../renderer/index.html pub trait Renderer: crate::Renderer + Sized { - /// Creates a [`Node`] for the provided [`Button`]. - /// - /// [`Node`]: ../../struct.Node.html - /// [`Button`]: struct.Button.html - fn layout<Message>( - &self, - button: &Button<'_, Message, Self>, - limits: &layout::Limits, - ) -> layout::Node; - /// Draws a [`Button`]. /// /// [`Button`]: struct.Button.html - fn draw<Message>( + fn draw( &mut self, - button: &Button<'_, Message, Self>, - layout: Layout<'_>, + bounds: Rectangle, cursor_position: Point, + is_pressed: bool, + background: Option<Background>, + border_radius: u16, + content: Self::Output, ) -> Self::Output; } @@ -115,7 +233,7 @@ impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>> for Element<'a, Message, Renderer> where Renderer: 'static + self::Renderer, - Message: 'static + Clone + std::fmt::Debug, + Message: 'static + Clone, { fn from( button: Button<'a, Message, Renderer>, |