summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-11-08 15:29:58 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-11-29 15:04:13 +0700
commit010b62b9ee20b03053ab538a5910795bc0618378 (patch)
tree6b75a4844239bd93e0a125e6f9d81a356f268f28 /examples
parentbffa7203dfd333b699bc29a22c74fb602eea4ea1 (diff)
downloadiced-010b62b9ee20b03053ab538a5910795bc0618378.tar.gz
iced-010b62b9ee20b03053ab538a5910795bc0618378.tar.bz2
iced-010b62b9ee20b03053ab538a5910795bc0618378.zip
Draft `component` example :tada:
Diffstat (limited to 'examples')
-rw-r--r--examples/component/Cargo.toml11
-rw-r--r--examples/component/src/main.rs180
2 files changed, 191 insertions, 0 deletions
diff --git a/examples/component/Cargo.toml b/examples/component/Cargo.toml
new file mode 100644
index 00000000..5761db9f
--- /dev/null
+++ b/examples/component/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "component"
+version = "0.1.0"
+authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
+edition = "2018"
+publish = false
+
+[dependencies]
+iced = { path = "../..", features = ["debug"] }
+iced_native = { path = "../../native" }
+iced_lazy = { path = "../../lazy" }
diff --git a/examples/component/src/main.rs b/examples/component/src/main.rs
new file mode 100644
index 00000000..58d3f354
--- /dev/null
+++ b/examples/component/src/main.rs
@@ -0,0 +1,180 @@
+use iced::{Container, Element, Length, Sandbox, Settings};
+use numeric_input::NumericInput;
+
+pub fn main() -> iced::Result {
+ Component::run(Settings::default())
+}
+
+#[derive(Default)]
+struct Component {
+ numeric_input: numeric_input::State,
+ value: Option<u32>,
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Message {
+ NumericInputChanged(Option<u32>),
+}
+
+impl Sandbox for Component {
+ type Message = Message;
+
+ fn new() -> Self {
+ Self::default()
+ }
+
+ fn title(&self) -> String {
+ String::from("Component - Iced")
+ }
+
+ fn update(&mut self, message: Message) {
+ match message {
+ Message::NumericInputChanged(value) => {
+ self.value = value;
+ }
+ }
+ }
+
+ fn view(&mut self) -> Element<Message> {
+ Container::new(NumericInput::new(
+ &mut self.numeric_input,
+ self.value,
+ Message::NumericInputChanged,
+ ))
+ .padding(20)
+ .height(Length::Fill)
+ .center_y()
+ .into()
+ }
+}
+
+mod numeric_input {
+ use iced_lazy::component::{self, Component};
+ use iced_native::alignment::{self, Alignment};
+ use iced_native::text;
+ use iced_native::widget::button::{self, Button};
+ use iced_native::widget::text_input::{self, TextInput};
+ use iced_native::widget::{Row, Text};
+ use iced_native::{Element, Length};
+
+ pub struct NumericInput<'a, Message> {
+ state: &'a mut State,
+ value: Option<u32>,
+ on_change: Box<dyn Fn(Option<u32>) -> Message>,
+ }
+
+ #[derive(Default)]
+ pub struct State {
+ input: text_input::State,
+ decrement_button: button::State,
+ increment_button: button::State,
+ }
+
+ #[derive(Debug, Clone)]
+ pub enum Event {
+ InputChanged(String),
+ IncrementPressed,
+ DecrementPressed,
+ }
+
+ impl<'a, Message> NumericInput<'a, Message> {
+ pub fn new(
+ state: &'a mut State,
+ value: Option<u32>,
+ on_change: impl Fn(Option<u32>) -> Message + 'static,
+ ) -> Self {
+ Self {
+ state,
+ value,
+ on_change: Box::new(on_change),
+ }
+ }
+ }
+
+ impl<'a, Message, Renderer> Component<Message, Renderer>
+ for NumericInput<'a, Message>
+ where
+ Renderer: 'a + text::Renderer,
+ {
+ type Event = Event;
+
+ fn update(&mut self, event: Event) -> Option<Message> {
+ match event {
+ Event::IncrementPressed => Some((self.on_change)(Some(
+ self.value.unwrap_or_default().saturating_add(1),
+ ))),
+ Event::DecrementPressed => Some((self.on_change)(Some(
+ self.value.unwrap_or_default().saturating_sub(1),
+ ))),
+ Event::InputChanged(value) => {
+ if value.is_empty() {
+ Some((self.on_change)(None))
+ } else {
+ value
+ .parse()
+ .ok()
+ .map(Some)
+ .map(self.on_change.as_ref())
+ }
+ }
+ }
+ }
+
+ fn view(&mut self) -> Element<Event, Renderer> {
+ let button = |state, label, on_press| {
+ Button::new(
+ state,
+ Text::new(label)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .horizontal_alignment(alignment::Horizontal::Center)
+ .vertical_alignment(alignment::Vertical::Center),
+ )
+ .width(Length::Units(50))
+ .on_press(on_press)
+ };
+
+ Row::with_children(vec![
+ button(
+ &mut self.state.decrement_button,
+ "-",
+ Event::DecrementPressed,
+ )
+ .into(),
+ TextInput::new(
+ &mut self.state.input,
+ "Type a number",
+ self.value
+ .as_ref()
+ .map(u32::to_string)
+ .as_ref()
+ .map(String::as_str)
+ .unwrap_or(""),
+ Event::InputChanged,
+ )
+ .padding(10)
+ .into(),
+ button(
+ &mut self.state.increment_button,
+ "+",
+ Event::IncrementPressed,
+ )
+ .into(),
+ ])
+ .align_items(Alignment::Fill)
+ .spacing(10)
+ .into()
+ }
+ }
+
+ impl<'a, Message, Renderer> From<NumericInput<'a, Message>>
+ for Element<'a, Message, Renderer>
+ where
+ Message: 'a,
+ Renderer: text::Renderer + 'a,
+ {
+ fn from(numeric_input: NumericInput<'a, Message>) -> Self {
+ component::view(Box::new(numeric_input))
+ }
+ }
+}