diff options
author | 2019-12-08 06:53:54 +0100 | |
---|---|---|
committer | 2019-12-08 06:53:54 +0100 | |
commit | 9b84b6e40336543380312aa1b2b1091791ec25cd (patch) | |
tree | c14ed67cfc38e1a22617716c361e4684a64e7fac /examples | |
parent | 48145ba51e045f8b0b4788f3a75d20b9d9b7e6ad (diff) | |
parent | f942fc3b68ecbbe136c54922109c7e2e4732735b (diff) | |
download | iced-9b84b6e40336543380312aa1b2b1091791ec25cd.tar.gz iced-9b84b6e40336543380312aa1b2b1091791ec25cd.tar.bz2 iced-9b84b6e40336543380312aa1b2b1091791ec25cd.zip |
Merge branch 'master' into feature/event-subscriptions
Diffstat (limited to 'examples')
-rw-r--r-- | examples/custom_widget.rs | 145 | ||||
-rw-r--r-- | examples/tour.rs | 43 |
2 files changed, 177 insertions, 11 deletions
diff --git a/examples/custom_widget.rs b/examples/custom_widget.rs new file mode 100644 index 00000000..cf2f7792 --- /dev/null +++ b/examples/custom_widget.rs @@ -0,0 +1,145 @@ +//! This example showcases a simple native custom widget that draws a circle. +mod circle { + // For now, to implement a custom native widget you will need to add + // `iced_native` and `iced_wgpu` to your dependencies. + // + // Then, you simply need to define your widget type and implement the + // `iced_native::Widget` trait with the `iced_wgpu::Renderer`. + // + // Of course, you can choose to make the implementation renderer-agnostic, + // if you wish to, by creating your own `Renderer` trait, which could be + // implemented by `iced_wgpu` and other renderers. + use iced_native::{ + layout, Background, Color, Element, Hasher, Layout, Length, + MouseCursor, Point, Size, Widget, + }; + use iced_wgpu::{Primitive, Renderer}; + + pub struct Circle { + radius: u16, + } + + impl Circle { + pub fn new(radius: u16) -> Self { + Self { radius } + } + } + + impl<Message> Widget<Message, Renderer> for Circle { + fn width(&self) -> Length { + Length::Shrink + } + + fn height(&self) -> Length { + Length::Shrink + } + + fn layout( + &self, + _renderer: &Renderer, + _limits: &layout::Limits, + ) -> layout::Node { + layout::Node::new(Size::new( + f32::from(self.radius) * 2.0, + f32::from(self.radius) * 2.0, + )) + } + + fn hash_layout(&self, state: &mut Hasher) { + use std::hash::Hash; + + self.radius.hash(state); + } + + fn draw( + &self, + _renderer: &mut Renderer, + layout: Layout<'_>, + _cursor_position: Point, + ) -> (Primitive, MouseCursor) { + ( + Primitive::Quad { + bounds: layout.bounds(), + background: Background::Color(Color::BLACK), + border_radius: self.radius, + }, + MouseCursor::OutOfBounds, + ) + } + } + + impl<'a, Message> Into<Element<'a, Message, Renderer>> for Circle { + fn into(self) -> Element<'a, Message, Renderer> { + Element::new(self) + } + } +} + +use circle::Circle; +use iced::{ + slider, Align, Column, Container, Element, Length, Sandbox, Settings, + Slider, Text, +}; + +pub fn main() { + Example::run(Settings::default()) +} + +struct Example { + radius: u16, + slider: slider::State, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + RadiusChanged(f32), +} + +impl Sandbox for Example { + type Message = Message; + + fn new() -> Self { + Example { + radius: 50, + slider: slider::State::new(), + } + } + + fn title(&self) -> String { + String::from("Custom widget - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::RadiusChanged(radius) => { + self.radius = radius.round() as u16; + } + } + } + + fn view(&mut self) -> Element<Message> { + let content = Column::new() + .padding(20) + .spacing(20) + .max_width(500) + .align_items(Align::Center) + .push(Circle::new(self.radius)) + .push( + Text::new(format!("Radius: {}", self.radius.to_string())) + .width(Length::Shrink), + ) + .push(Slider::new( + &mut self.slider, + 1.0..=100.0, + f32::from(self.radius), + Message::RadiusChanged, + )); + + Container::new(content) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} diff --git a/examples/tour.rs b/examples/tour.rs index b06fbc37..da05b396 100644 --- a/examples/tour.rs +++ b/examples/tour.rs @@ -140,6 +140,7 @@ impl Steps { Step::Scrollable, Step::TextInput { value: String::new(), + is_secure: false, state: text_input::State::new(), }, Step::Debugger, @@ -210,6 +211,7 @@ enum Step { Scrollable, TextInput { value: String, + is_secure: bool, state: text_input::State, }, Debugger, @@ -226,6 +228,7 @@ pub enum StepMessage { LanguageSelected(Language), ImageWidthChanged(f32), InputChanged(String), + ToggleSecureInput(bool), DebugToggled(bool), } @@ -277,6 +280,11 @@ impl<'a> Step { *value = new_value; } } + StepMessage::ToggleSecureInput(toggle) => { + if let Step::TextInput { is_secure, .. } = self { + *is_secure = toggle; + } + } }; } @@ -328,7 +336,11 @@ impl<'a> Step { spacing, } => Self::rows_and_columns(*layout, spacing_slider, *spacing), Step::Scrollable => Self::scrollable(), - Step::TextInput { value, state } => Self::text_input(value, state), + Step::TextInput { + value, + is_secure, + state, + } => Self::text_input(value, *is_secure, state), Step::Debugger => Self::debugger(debug), Step::End => Self::end(), } @@ -582,22 +594,31 @@ impl<'a> Step { fn text_input( value: &str, + is_secure: bool, state: &'a mut text_input::State, ) -> Column<'a, StepMessage> { + let text_input = TextInput::new( + state, + "Type something to continue...", + value, + StepMessage::InputChanged, + ) + .padding(10) + .size(30); Self::container("Text input") .push(Text::new( "Use a text input to ask for different kinds of information.", )) - .push( - TextInput::new( - state, - "Type something to continue...", - value, - StepMessage::InputChanged, - ) - .padding(10) - .size(30), - ) + .push(if is_secure { + text_input.password() + } else { + text_input + }) + .push(Checkbox::new( + is_secure, + "Enable password mode", + StepMessage::ToggleSecureInput, + )) .push(Text::new( "A text input produces a message every time it changes. It is \ very easy to keep track of its contents:", |