summaryrefslogtreecommitdiffstats
path: root/native/src/widget/button.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-21 13:47:20 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-21 13:47:20 +0100
commit65eb218d3d7ba52b2869a586a1480eeb3c8f84e4 (patch)
tree644f27f40f2f4b8ee1abe7743aac426297503eea /native/src/widget/button.rs
parentd3553adf278e5b616fbd885f321faa83a4d24b56 (diff)
downloadiced-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.rs166
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>,