From 0e0ffc3b92d9e98fe227c42b373736aac0eee78c Mon Sep 17 00:00:00 2001
From: FloVanGH <flovanpt@posteo.de>
Date: Fri, 23 Nov 2018 23:00:22 +0100
Subject: [PATCH] Port all widgets to new structure. Update readme example.

---
 README.md                   |  16 ++----
 examples/minimal.rs         |  24 ++++----
 src/application/window.rs   |  13 +----
 src/event/key.rs            |  26 +++++++--
 src/event/mouse.rs          |  35 ++++++++++--
 src/widget/button.rs        |  65 ++++++---------------
 src/widget/center.rs        |  35 +++---------
 src/widget/column.rs        |  33 +++--------
 src/widget/container.rs     |   5 +-
 src/widget/mod.rs           |  68 +++++++++++-----------
 src/widget/row.rs           |  35 +++---------
 src/widget/scroll_viewer.rs |  43 ++++----------
 src/widget/stack.rs         |  26 ++-------
 src/widget/text_block.rs    |   7 ++-
 src/widget/text_box.rs      | 110 +++++++++---------------------------
 15 files changed, 195 insertions(+), 346 deletions(-)

diff --git a/README.md b/README.md
index 5ad68b6..b33170b 100644
--- a/README.md
+++ b/README.md
@@ -52,19 +52,14 @@ crate](https://github.com/AngryLawyer/rust-sdl2#user-content-requirements).
 ```rust
 extern crate orbtk;
 use orbtk::*;
-use std::rc::Rc;
 
 struct MainView;
 
 impl Widget for MainView {
-    fn template(&self) -> Template {
-        Template::Single(Rc::new(Container {
-            child: Some(Rc::new(TextBlock {
-                label: Property::new(Label(String::from("OrbTk"))),
-                ..Default::default()
-            })),
-                ..Default::default()
-        }))
+    fn template() -> Template {
+        Container::template()
+            .as_parent_type(ParentType::Single)
+            .with_child(TextBlock::template())
     }
 }
 
@@ -74,7 +69,8 @@ fn main() {
         .create_window()
         .with_bounds(Rect::new(0, 0, 420, 730))
         .with_title("Orbtk")
-        .with_root(MainView)
+        .with_root(MainView::template())
+        .with_debug_flag(true)
         .build();
     application.run();
 }
diff --git a/examples/minimal.rs b/examples/minimal.rs
index 59db9fc..c64664d 100644
--- a/examples/minimal.rs
+++ b/examples/minimal.rs
@@ -1,20 +1,15 @@
 extern crate orbtk;
 use orbtk::*;
-use std::rc::Rc;
 
-// struct MainView;
+struct MainView;
 
-// impl Widget for MainView {
-//     fn template(&self) -> Template {
-//         Template::Single(Rc::new(Container {
-//             child: Some(Rc::new(TextBlock {
-//                 label: Property::new(Label(String::from("OrbTk"))),
-//                 ..Default::default()
-//             })),
-//                 ..Default::default()
-//         }))
-//     }
-// }
+impl Widget for MainView {
+    fn template() -> Template {
+        Container::template()
+            .as_parent_type(ParentType::Single)
+            .with_child(TextBlock::template())
+    }
+}
 
 fn main() {
     let mut application = Application::default();
@@ -22,7 +17,8 @@ fn main() {
         .create_window()
         .with_bounds(Rect::new(0, 0, 420, 730))
         .with_title("Orbtk")
-        // .with_root(MainView)
+        .with_root(MainView::template())
+        .with_debug_flag(true)
         .build();
     application.run();
 }
diff --git a/src/application/window.rs b/src/application/window.rs
index 81b3da1..539e796 100644
--- a/src/application/window.rs
+++ b/src/application/window.rs
@@ -17,18 +17,7 @@ use systems::{EventSystem, LayoutSystem, RenderSystem, StateSystem};
 use theme::Theme;
 use tree::Tree;
 use Global;
-
-pub struct Template {
-    children: Vec<Template>,
-    parent_type: ParentType,
-    state: Option<Rc<State>>,
-    event_handlers: Vec<Rc<EventHandler>>,
-    render_object: Option<Box<RenderObject>>,
-    layout_object: Box<LayoutObject>,
-
-    // todo: only one prop type per widget.
-    properties: Vec<ComponentBox>,
-}
+use widget::Template;
 
 impl Default for Template {
     fn default() -> Self {
diff --git a/src/event/key.rs b/src/event/key.rs
index fe20c4d..fac5444 100644
--- a/src/event/key.rs
+++ b/src/event/key.rs
@@ -299,20 +299,38 @@ pub type KeyHandler = Rc<Fn(Key, &mut WidgetContainer) -> bool + 'static>;
 
 #[derive(Default)]
 pub struct KeyEventHandler {
-    pub on_key_up: Option<KeyHandler>,
-    pub on_key_down: Option<KeyHandler>,
+    key_up: Option<KeyHandler>,
+    key_down: Option<KeyHandler>,
+}
+
+impl KeyEventHandler {
+    pub fn on_key_up(mut self, handler: KeyHandler) -> Self {
+        self.key_up = Some(handler);
+        self
+    } 
+
+    pub fn on_key_down(mut self, handler: KeyHandler) -> Self {
+        self.key_down = Some(handler);
+        self
+    } 
+}
+
+impl Into<Rc<EventHandler>> for KeyEventHandler {
+    fn into(self) -> Rc<EventHandler> {
+        Rc::new(self)
+    }
 }
 
 impl EventHandler for KeyEventHandler {
     fn handle_event(&self, event: &EventBox, widget: &mut WidgetContainer) -> bool {
         if let Ok(event) = event.downcast_ref::<KeyDownEvent>() {
-            if let Some(handler) = &self.on_key_down {
+            if let Some(handler) = &self.key_down {
                 return (handler)(event.key, widget);
             }
         }
 
         if let Ok(event) = event.downcast_ref::<KeyUpEvent>() {
-            if let Some(handler) = &self.on_key_up {
+            if let Some(handler) = &self.key_up {
                 return (handler)(event.key, widget);
             }
         }
diff --git a/src/event/mouse.rs b/src/event/mouse.rs
index 697977e..dd00806 100644
--- a/src/event/mouse.rs
+++ b/src/event/mouse.rs
@@ -66,27 +66,50 @@ pub type OnMouseUp = Rc<Fn() + 'static>;
 
 #[derive(Default)]
 pub struct MouseEventHandler {
-    pub on_mouse_up: Option<MouseHandler>,
-    pub on_mouse_down: Option<MouseHandler>,
-    pub on_click: Option<MouseHandler>,
+    mouse_up: Option<MouseHandler>,
+    mouse_down: Option<MouseHandler>,
+    click: Option<MouseHandler>,
+}
+
+impl MouseEventHandler {
+    pub fn on_mouse_up(mut self, handler: MouseHandler) -> Self {
+        self.mouse_up = Some(handler);
+        self
+    } 
+
+    pub fn on_mouse_down(mut self, handler: MouseHandler) -> Self {
+        self.mouse_down = Some(handler);
+        self
+    } 
+
+     pub fn on_click(mut self, handler: MouseHandler) -> Self {
+        self.click = Some(handler);
+        self
+    } 
+}
+
+impl Into<Rc<EventHandler>> for MouseEventHandler {
+    fn into(self) -> Rc<EventHandler> {
+        Rc::new(self)
+    }
 }
 
 impl EventHandler for MouseEventHandler {
     fn handle_event(&self, event: &EventBox, widget: &mut WidgetContainer) -> bool {
         if let Ok(event) = event.downcast_ref::<ClickEvent>() {
-            if let Some(handler) = &self.on_click {
+            if let Some(handler) = &self.click {
                 return (handler)(event.position, widget);
             }
         }
 
         if let Ok(event) = event.downcast_ref::<MouseDownEvent>() {
-            if let Some(handler) = &self.on_mouse_down {
+            if let Some(handler) = &self.mouse_down {
                 return (handler)(event.position, widget);
             }
         }
 
         if let Ok(event) = event.downcast_ref::<MouseUpEvent>() {
-            if let Some(handler) = &self.on_mouse_up {
+            if let Some(handler) = &self.mouse_up {
                 (handler)(event.position, widget);
                 return true;
             }
diff --git a/src/widget/button.rs b/src/widget/button.rs
index 7dc684d..d58fbd0 100644
--- a/src/widget/button.rs
+++ b/src/widget/button.rs
@@ -1,11 +1,11 @@
 use std::rc::Rc;
 
-use event::{EventHandler, Pressed, MouseOver};
+use event::Pressed;
 use state::State;
 use theme::Selector;
 use widget::{
-    add_selector_to_widget, remove_selector_from_widget, Center, Container, Label, Property,
-    PropertyResult, Template, TextBlock, Widget, WidgetContainer,
+    add_selector_to_widget, remove_selector_from_widget, Center, Container, Label, Template,
+    TextBlock, Widget, WidgetContainer,
 };
 
 /// The `ButtonState` handles the pressed state of the `Button` widget.
@@ -26,54 +26,25 @@ impl State for ButtonState {
     }
 }
 
-/// The `Button` struct represents a widget that can be clicked by user. It's used to peform an action.
-pub struct Button {
-    pub label: Property<Label>,
-    pub selector: Property<Selector>,
-    pub event_handlers: Vec<Rc<EventHandler>>,
-    pub state: Rc<ButtonState>,
-}
-
-impl Default for Button {
-    fn default() -> Button {
-        Button {
-            label: Property::new(Label(String::from("label"))),
-            selector: Property::new(Selector::new(Some(String::from("button")))),
-            event_handlers: vec![],
-            state: Rc::new(ButtonState::default()),
-        }
+impl Into<Rc<State>> for ButtonState {
+    fn into(self) -> Rc<State> {
+        Rc::new(self)
     }
 }
 
+/// The `Button` struct represents a widget that can be clicked by user. It's used to peform an action.
+pub struct Button;
+
 impl Widget for Button {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("Button -> ");
-        Template::Single(Rc::new(Container {
-            selector: self.selector.clone(),
-            child: Some(Rc::new(Center {
-                child: Some(Rc::new(TextBlock {
-                    label: self.label.clone(),
-                    selector: self.selector.clone(),
-                })),
-            })),
-            ..Default::default()
-        }))
-    }
-
-    fn properties(&self) -> Vec<PropertyResult> {
-        vec![
-            self.selector.build(),
-            self.label.build(),
-            Property::new(Pressed::default()).build(),
-            Property::new(MouseOver::default()).build(),
-        ]
-    }
-
-    fn state(&self) -> Option<Rc<State>> {
-        Some(self.state.clone())
-    }
-
-    fn event_handlers(&self) -> Vec<Rc<EventHandler>> {
-        self.event_handlers.to_vec()
+        Template::default()
+            .with_property(Label::from("Button"))
+            .with_property(Selector::new().with("button"))
+            .with_child(
+                Container::template()
+                    .with_child(Center::template().with_child(TextBlock::template())),
+            )
+            .with_state(ButtonState::default())
     }
 }
diff --git a/src/widget/center.rs b/src/widget/center.rs
index b51c9a3..e7643b7 100644
--- a/src/widget/center.rs
+++ b/src/widget/center.rs
@@ -1,36 +1,15 @@
-use std::rc::Rc;
-
-use layout_object::{CenterLayoutObject, LayoutObject};
+use layout_object::CenterLayoutObject;
 use widget::{Template, Widget};
+use enums::ParentType;
 
 /// This layout widget centers its children within itself.
-pub struct Center {
-    pub child: Option<Rc<Widget>>,
-}
-
-impl Default for Center {
-    fn default() -> Center {
-        Center {
-             child: None,
-        }
-    }
-}
+pub struct Center;
 
 impl Widget for Center {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("Center -> ");
-        if let Some(child) = &self.child {
-            Template::Single(child.clone())
-        } else {
-            Template::Empty
-        }
+        Template::default()
+            .as_parent_type(ParentType::Single)
+            .with_layout_object(CenterLayoutObject) 
     }
-
-    fn layout_object(&self) -> Box<LayoutObject> {
-        Box::new(CenterLayoutObject)
-    }
-}
-
-pub struct PbCenter {
-    
 }
diff --git a/src/widget/column.rs b/src/widget/column.rs
index e74ba59..dcefaeb 100644
--- a/src/widget/column.rs
+++ b/src/widget/column.rs
@@ -1,35 +1,16 @@
-use std::rc::Rc;
-
-use layout_object::{FlexLayoutObject, LayoutObject};
+use layout_object::FlexLayoutObject;
 use enums::Alignment;
 use widget::{Template, Widget};
+use enums::ParentType;
 
 /// This layout widget orders its children vertical.
-pub struct Column {
-    pub children: Vec<Rc<Widget>>,
-}
-
-impl Default for Column {
-    fn default() -> Column {
-        Column {
-            children: vec![],
-        }
-    }
-}
+pub struct Column;
 
 impl Widget for Column {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("Column -> ");
-        if self.children.is_empty() {
-            Template::Empty
-        } else if self.children.len() == 1 {
-            Template::Single(self.children[0].clone())
-        } else {
-            Template::Mutli(self.children.to_vec())
-        }
-    }
-
-    fn layout_object(&self) -> Box<LayoutObject> {
-        Box::new(FlexLayoutObject::new(Alignment::Vertical))
+        Template::default()
+            .as_parent_type(ParentType::Multi)
+            .with_layout_object(FlexLayoutObject::new(Alignment::Vertical)) 
     }
 }
diff --git a/src/widget/container.rs b/src/widget/container.rs
index c030485..5e9c38d 100644
--- a/src/widget/container.rs
+++ b/src/widget/container.rs
@@ -2,14 +2,15 @@
 use layout_object::PaddingLayoutObject;
 use render_object::{RectangleRenderObject};
 use theme::Selector;
-use widget::Widget;
+use widget::{Template, Widget};
 use enums::ParentType;
-use application::Template;
 
+/// The `Container` layout surrounds its child with a padding. Draws a box arround the child.
 pub struct Container;
 
 impl Widget for Container {
     fn template() -> Template {
+        print!("Container -> ");
         Template::default()
             .as_parent_type(ParentType::Single)
             .with_property(Selector::new().with("container"))
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index de46c3a..3a54228 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -1,39 +1,37 @@
 //! Contains concret implementations of OrbTk's default widgets. It contains also layout widgets.
 
-use std::any::{Any, TypeId};
-use std::cell::Cell;
+use std::any::TypeId;
 use std::rc::Rc;
 
 use dces::{Component, ComponentBox, Entity, EntityComponentManager, NotFound, SharedComponentBox};
 
+use enums::ParentType;
 use event::EventHandler;
-use layout_object::{DefaultLayoutObject, LayoutObject};
+use layout_object::LayoutObject;
 use render_object::RenderObject;
 use state::State;
 use theme::Selector;
 use tree::Tree;
-use application::Template;
 
-// pub use self::button::*;
-// pub use self::center::*;
-// pub use self::column::*;
+pub use self::button::*;
+pub use self::center::*;
+pub use self::column::*;
 pub use self::container::*;
-// pub use self::row::*;
-// pub use self::scroll_viewer::*;
-// pub use self::stack::*;
+pub use self::row::*;
+pub use self::scroll_viewer::*;
+pub use self::stack::*;
 pub use self::text_block::*;
-// pub use self::text_box::*;
+pub use self::text_box::*;
 
-// mod button;
-// mod center;
-// mod column;
+mod button;
+mod center;
+mod column;
 mod container;
-// mod macros;
-// mod row;
-// mod scroll_viewer;
-// mod stack;
+mod row;
+mod scroll_viewer;
+mod stack;
 mod text_block;
-//mod text_box;
+mod text_box;
 
 #[derive(Copy, Clone)]
 pub struct Drawable;
@@ -47,19 +45,17 @@ pub struct Offset(pub i32, pub i32);
 pub struct Label(pub String);
 
 impl From<&str> for Label {
-    fn from (s: &str) -> Label {
+    fn from(s: &str) -> Label {
         Label(s.to_string())
     }
 }
 
 impl From<String> for Label {
-    fn from (s: String) -> Label {
+    fn from(s: String) -> Label {
         Label(s)
     }
 }
 
-
-
 // pub struct Key(pub String);
 
 pub struct Padding {
@@ -69,6 +65,22 @@ pub struct Padding {
     pub bottom: u32,
 }
 
+pub struct Template {
+    pub children: Vec<Template>,
+    pub parent_type: ParentType,
+    pub state: Option<Rc<State>>,
+    pub event_handlers: Vec<Rc<EventHandler>>,
+    pub render_object: Option<Box<RenderObject>>,
+    pub layout_object: Box<LayoutObject>,
+
+    // todo: only one prop type per widget.
+    pub properties: Vec<ComponentBox>,
+}
+
+pub trait Widget {
+    fn template() -> Template;
+}
+
 pub struct WidgetContainer<'a> {
     tree: &'a Tree,
     ecm: &'a mut EntityComponentManager,
@@ -177,12 +189,4 @@ pub fn remove_selector_from_widget(pseudo_class: &str, widget: &mut WidgetContai
 //     }
 // }
 
-pub struct Property {
-
-}
-
-
-
-pub trait Widget {
-    fn template() -> Template;
-}
+pub struct Property {}
diff --git a/src/widget/row.rs b/src/widget/row.rs
index a48985b..c0b527b 100644
--- a/src/widget/row.rs
+++ b/src/widget/row.rs
@@ -1,35 +1,16 @@
-use std::rc::Rc;
-
-use layout_object::{FlexLayoutObject, LayoutObject};
+use layout_object::FlexLayoutObject;
 use enums::Alignment;
 use widget::{Template, Widget};
+use enums::ParentType;
 
 /// This layout widget orders its children horizontal.
-pub struct Row {
-    pub children: Vec<Rc<Widget>>,
-}
-
-impl Default for Row {
-    fn default() -> Row {
-        Row {
-            children: vec![],
-        }
-    }
-}
+pub struct Row;
 
 impl Widget for Row {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("Row -> ");
-        if self.children.is_empty() {
-            Template::Empty
-        } else if self.children.len() == 1 {
-            Template::Single(self.children[0].clone())
-        } else {
-            Template::Mutli(self.children.to_vec())
-        }
-    }
-
-    fn layout_object(&self) -> Box<LayoutObject> {
-        Box::new(FlexLayoutObject::new(Alignment::Horizontal))
+        Template::default()
+            .as_parent_type(ParentType::Multi)
+            .with_layout_object(FlexLayoutObject::new(Alignment::Horizontal)) 
     }
-}
+}
\ No newline at end of file
diff --git a/src/widget/scroll_viewer.rs b/src/widget/scroll_viewer.rs
index fed9ae1..5d63c78 100644
--- a/src/widget/scroll_viewer.rs
+++ b/src/widget/scroll_viewer.rs
@@ -1,39 +1,16 @@
-use std::rc::Rc;
+use enums::ParentType;
+use layout_object::ScrollLayoutObject;
+use widget::{Offset, Template, Widget};
 
-use widget::{Property, PropertyResult, Template, Widget};
-use layout_object::{LayoutObject, ScrollLayoutObject};
-
-
-/// This layout widget orders its children vertical.
-pub struct ScrollViewer {
-    pub child: Option<Rc<Widget>>,
-    pub offset: Property<Offset>,
-}
-
-impl Default for ScrollViewer {
-    fn default() -> ScrollViewer {
-        ScrollViewer {
-            child: None,
-            offset: Property::new(Offset::default()),
-        }
-    }
-}
+/// Use to scroll its content.
+pub struct ScrollViewer;
 
 impl Widget for ScrollViewer {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("ScrollViewer -> ");
-        if let Some(child) = &self.child {
-            Template::Single(child.clone())
-        } else {
-            Template::Empty
-        }
-    }
-
-    fn properties(&self) -> Vec<PropertyResult> {
-        vec![self.offset.build()]
-    }
-
-    fn layout_object(&self) -> Box<LayoutObject> {
-        Box::new(ScrollLayoutObject)
+        Template::default()
+            .as_parent_type(ParentType::Single)
+            .with_property(Offset::default())
+            .with_layout_object(ScrollLayoutObject)
     }
 }
diff --git a/src/widget/stack.rs b/src/widget/stack.rs
index 977b4b9..f7a9fe6 100644
--- a/src/widget/stack.rs
+++ b/src/widget/stack.rs
@@ -1,27 +1,13 @@
-use std::rc::Rc;
-
 use widget::{Template, Widget};
+use enums::ParentType;
 
 /// Use this layout widget to overlay its children (on z axis).
-pub struct Stack {
-    pub children: Vec<Rc<Widget>>,
-}
-
-impl Default for Stack {
-    fn default() -> Stack {
-        Stack { children: vec![] }
-    }
-}
+pub struct Stack;
 
 impl Widget for Stack {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("Stack -> ");
-        if self.children.is_empty() {
-            Template::Empty
-        } else if self.children.len() == 1 {
-            Template::Single(self.children[0].clone())
-        } else {
-            Template::Mutli(self.children.to_vec())
-        }
+        Template::default()
+            .as_parent_type(ParentType::Multi)
     }
-}
+}
\ No newline at end of file
diff --git a/src/widget/text_block.rs b/src/widget/text_block.rs
index 32df735..c5b1711 100644
--- a/src/widget/text_block.rs
+++ b/src/widget/text_block.rs
@@ -1,17 +1,18 @@
 use layout_object::TextSizeLayoutObject;
 use render_object::TextRenderObject;
 use theme::Selector;
-use widget::{Label, Widget};
-use application::Template;
+use widget::{Label, Template, Widget};
 
+/// The `TextBlock` widget is used to draw text.
 pub struct TextBlock;
 
 impl Widget for TextBlock {
     fn template() -> Template {
+        print!("TextBlock -> ");
         Template::default()
             .with_property(Label::from("TextBlock"))
             .with_property(Selector::new().with("textblock"))
             .with_layout_object(TextSizeLayoutObject)
             .with_render_object(TextRenderObject)
     }
-}
\ No newline at end of file
+}
diff --git a/src/widget/text_box.rs b/src/widget/text_box.rs
index 6b0a36d..5efb16d 100644
--- a/src/widget/text_box.rs
+++ b/src/widget/text_box.rs
@@ -1,13 +1,10 @@
+use event::{Focused, Key};
 use std::cell::{Cell, RefCell};
 use std::rc::Rc;
-
-use super::Property;
-use event::{EventHandler, KeyEventHandler};
-use event::{Focused, Key};
 use theme::Selector;
 use widget::{
-    add_selector_to_widget, remove_selector_from_widget, Container, Label, PropertyResult,
-    ScrollViewer, Stack, State, Template, TextBlock, Widget, WidgetContainer,
+    add_selector_to_widget, remove_selector_from_widget, Container, Label, ScrollViewer, Stack,
+    State, Template, TextBlock, Widget, WidgetContainer,
 };
 
 /// The `TextBoxState`handles the text processing of the `TextBox` widget.
@@ -18,6 +15,12 @@ pub struct TextBoxState {
     updated: Cell<bool>,
 }
 
+impl Into<Rc<State>> for TextBoxState {
+    fn into(self) -> Rc<State> {
+        Rc::new(self)
+    }
+}
+
 impl TextBoxState {
     fn update_text(&self, key: Key) -> bool {
         if !self.focused.get() {
@@ -27,13 +30,13 @@ impl TextBoxState {
         match <Option<u8>>::from(key) {
             Some(byte) => {
                 (*self.text.borrow_mut()).push(byte as char);
-            },
+            }
             None => match key {
                 Key::Backspace => {
                     (*self.text.borrow_mut()).pop();
                 }
                 _ => {}
-            }
+            },
         }
 
         self.updated.set(true);
@@ -70,82 +73,25 @@ impl State for TextBoxState {
     }
 }
 
-/// A single line text input widget.
-pub struct TextBox {
-    pub label: Property<Label>,
-    pub selector: Property<Selector>,
-    pub event_handlers: Vec<Rc<EventHandler>>,
-    pub state: Rc<TextBoxState>,
-}
-
-impl Default for TextBox {
-    fn default() -> TextBox {
-        TextBox {
-            label: Property::new(Label(String::from("TextBox"))),
-            selector: Property::new(Selector::new(Some(String::from("textbox")))),
-            event_handlers: vec![],
-            state: Rc::new(TextBoxState::default()),
-        }
-    }
-}
+/// The `TextBoxState`handles the text processing of the `TextBox` widget.
+pub struct TextBox;
 
 impl Widget for TextBox {
-    fn template(&self) -> Template {
+    fn template() -> Template {
         print!("TextBox -> ");
-
-        // Initial set state text to textbox label.
-        if let Some(text) = &self.label.property {
-            *self.state.text.borrow_mut() = text.0.clone();
-        }
-
-        Template::Single(Rc::new(Container {
-            selector: self.selector.clone(),
-            child: Some(Rc::new(Stack {
-                children: vec![
-                    Rc::new(ScrollViewer {
-                        child: Some(Rc::new(TextBlock {
-                            label: self.label.clone(),
-                            selector: self.selector.clone(),
-                        })),
-                        ..Default::default()
-                    }),
-                    // todo: Cursor as rectangle -> predifined bounds
-                    // scroll handling by cursor
-                    // Rc::new(TextBlock {
-                    //     ..Default::default()
-                    // }),
-                ],
-            })),
-            ..Default::default()
-        }))
-    }
-
-    fn properties(&self) -> Vec<PropertyResult> {
-        vec![
-            self.label.build(),
-            self.selector.build(),
-            Property::new(Focused(false)).build(),
-        ]
-    }
-
-    fn state(&self) -> Option<Rc<State>> {
-        Some(self.state.clone())
-    }
-
-    fn event_handlers(&self) -> Vec<Rc<EventHandler>> {
-        let state = self.state.clone();
-
-        let mut event_handlers: Vec<Rc<EventHandler>> = vec![Rc::new(KeyEventHandler {
-            on_key_down: Some(Rc::new(
-                move |key: Key, _widget: &mut WidgetContainer| -> bool { state.update_text(key) },
-            )),
-            ..Default::default()
-        })];
-
-        for handler in &self.event_handlers {
-            event_handlers.push(handler.clone());
-        }
-
-        event_handlers
+        Template::default()
+            .with_property(Label::from("TextBox"))
+            .with_property(Selector::new().with("textbox"))
+            .with_property(Focused(false))
+            .with_child(
+                Container::template().with_child(
+                    Stack::template()
+                        .with_child(ScrollViewer::template().with_child(TextBlock::template())),
+                ),
+            )
+            .with_state(TextBoxState::default())
+        // .with_event_handler(KeyEventHandler::default().on_key_down(Rc::new(
+        //     move |key: Key, _widget: &mut WidgetContainer| -> bool { state.update_text(key) },
+        // )))
     }
 }
-- 
GitLab