From 65eb218d3d7ba52b2869a586a1480eeb3c8f84e4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 Nov 2019 13:47:20 +0100 Subject: Move widgets from `core` to `native` and `web` Also made fields private and improved `Renderer` traits. --- native/src/widget/button.rs | 166 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 142 insertions(+), 24 deletions(-) (limited to 'native/src/widget/button.rs') 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, + width: Length, + min_width: u32, + padding: u16, + background: Option, + 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(state: &'a mut State, content: E) -> Self + where + E: Into>, + { + 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 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( - &self, - button: &Button<'_, Message, Self>, - limits: &layout::Limits, - ) -> layout::Node; - /// Draws a [`Button`]. /// /// [`Button`]: struct.Button.html - fn draw( + fn draw( &mut self, - button: &Button<'_, Message, Self>, - layout: Layout<'_>, + bounds: Rectangle, cursor_position: Point, + is_pressed: bool, + background: Option, + border_radius: u16, + content: Self::Output, ) -> Self::Output; } @@ -115,7 +233,7 @@ impl<'a, Message, Renderer> From> 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>, -- cgit From d136b7ce648cde0dcdcc5388d8cb82b3e7e0fc58 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 Nov 2019 21:16:40 +0100 Subject: Uncomment missing debug implementations rule --- native/src/widget/button.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'native/src/widget/button.rs') diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 81cb9310..159cd07e 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -12,7 +12,20 @@ use crate::{ }; use std::hash::Hash; -/// A generic widget that produces a message when clicked. +/// A generic widget that produces a message when pressed. +/// +/// ``` +/// # use iced_native::{button, Button}; +/// +/// enum Message { +/// ButtonPressed, +/// } +/// +/// let mut state = button::State::new(); +/// let button = Button::new(&mut state, Text::new("Press me!")) +/// .on_press(Message::ButtonPressed); +/// ``` +#[allow(missing_debug_implementations)] pub struct Button<'a, Message, Renderer> { state: &'a mut State, content: Element<'a, Message, Renderer>, -- cgit From 048909b45dfecef73bfacf3b5aa67462470ccca2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 Nov 2019 22:13:54 +0100 Subject: Fix `Button` example in `iced_native` --- native/src/widget/button.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'native/src/widget/button.rs') diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs index 159cd07e..023c4ee8 100644 --- a/native/src/widget/button.rs +++ b/native/src/widget/button.rs @@ -4,7 +4,6 @@ //! //! [`Button`]: struct.Button.html //! [`State`]: struct.State.html - use crate::{ input::{mouse, ButtonState}, layout, Background, Element, Event, Hasher, Layout, Length, Point, @@ -15,8 +14,11 @@ use std::hash::Hash; /// A generic widget that produces a message when pressed. /// /// ``` -/// # use iced_native::{button, Button}; -/// +/// # use iced_native::{button, Text}; +/// # +/// # type Button<'a, Message> = +/// # iced_native::Button<'a, Message, iced_native::renderer::Null>; +/// # /// enum Message { /// ButtonPressed, /// } -- cgit