summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-17 19:09:26 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-17 19:09:26 +0700
commit9b23ea698e98f5731a1253410e23697329083c78 (patch)
tree9e02612d7a1afd9a07e5585523e3138027b0dc24
parentda45b6c1627935bff5334d213096c4e78972af46 (diff)
downloadiced-9b23ea698e98f5731a1253410e23697329083c78.tar.gz
iced-9b23ea698e98f5731a1253410e23697329083c78.tar.bz2
iced-9b23ea698e98f5731a1253410e23697329083c78.zip
Implement `pure` version of `component` example
-rw-r--r--Cargo.toml1
-rw-r--r--examples/pure/component/Cargo.toml11
-rw-r--r--examples/pure/component/src/main.rs168
3 files changed, 180 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e94a1652..aa4bbacd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -90,6 +90,7 @@ members = [
"examples/tooltip",
"examples/tour",
"examples/url_handler",
+ "examples/pure/component",
"examples/pure/counter",
"examples/pure/pick_list",
"examples/pure/todos",
diff --git a/examples/pure/component/Cargo.toml b/examples/pure/component/Cargo.toml
new file mode 100644
index 00000000..a15f134f
--- /dev/null
+++ b/examples/pure/component/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "pure_component"
+version = "0.1.0"
+authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
+edition = "2021"
+publish = false
+
+[dependencies]
+iced = { path = "../../..", features = ["debug", "pure"] }
+iced_native = { path = "../../../native" }
+iced_lazy = { path = "../../../lazy", features = ["pure"] }
diff --git a/examples/pure/component/src/main.rs b/examples/pure/component/src/main.rs
new file mode 100644
index 00000000..0de7bdd9
--- /dev/null
+++ b/examples/pure/component/src/main.rs
@@ -0,0 +1,168 @@
+use iced::pure::widget::container;
+use iced::pure::{Element, Sandbox};
+use iced::{Length, Settings};
+
+use numeric_input::numeric_input;
+
+pub fn main() -> iced::Result {
+ Component::run(Settings::default())
+}
+
+#[derive(Default)]
+struct Component {
+ 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(&self) -> Element<Message> {
+ container(numeric_input(self.value, Message::NumericInputChanged))
+ .padding(20)
+ .height(Length::Fill)
+ .center_y()
+ .into()
+ }
+}
+
+mod numeric_input {
+ use iced::pure::widget::Element;
+ use iced::pure::widget::{row, text, text_input};
+ use iced_lazy::pure::component::{self, Component};
+ use iced_native::alignment::{self, Alignment};
+ use iced_native::text;
+ use iced_native::Length;
+
+ pub struct NumericInput<Message> {
+ value: Option<u32>,
+ on_change: Box<dyn Fn(Option<u32>) -> Message>,
+ }
+
+ pub fn numeric_input<Message>(
+ value: Option<u32>,
+ on_change: impl Fn(Option<u32>) -> Message + 'static,
+ ) -> NumericInput<Message> {
+ NumericInput::new(value, on_change)
+ }
+
+ #[derive(Debug, Clone)]
+ pub enum Event {
+ InputChanged(String),
+ IncrementPressed,
+ DecrementPressed,
+ }
+
+ impl<Message> NumericInput<Message> {
+ pub fn new(
+ value: Option<u32>,
+ on_change: impl Fn(Option<u32>) -> Message + 'static,
+ ) -> Self {
+ Self {
+ value,
+ on_change: Box::new(on_change),
+ }
+ }
+ }
+
+ impl<Message, Renderer> Component<Message, Renderer> for NumericInput<Message>
+ where
+ Renderer: text::Renderer + 'static,
+ {
+ type State = ();
+ type Event = Event;
+
+ fn update(
+ &mut self,
+ _state: &mut Self::State,
+ 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(&self, _state: &Self::State) -> Element<Event, Renderer> {
+ let button = |label, on_press| {
+ use iced::pure::widget::button;
+
+ button(
+ text(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()
+ .push(button("-", Event::DecrementPressed))
+ .push(
+ text_input(
+ "Type a number",
+ self.value
+ .as_ref()
+ .map(u32::to_string)
+ .as_ref()
+ .map(String::as_str)
+ .unwrap_or(""),
+ Event::InputChanged,
+ )
+ .padding(10),
+ )
+ .push(button("+", Event::IncrementPressed))
+ .align_items(Alignment::Fill)
+ .spacing(10)
+ .into()
+ }
+ }
+
+ impl<'a, Message, Renderer> From<NumericInput<Message>>
+ for Element<'a, Message, Renderer>
+ where
+ Message: 'a,
+ Renderer: 'static + text::Renderer,
+ {
+ fn from(numeric_input: NumericInput<Message>) -> Self {
+ component::view(numeric_input)
+ }
+ }
+}