Commit f529b60e authored by Florian Blasius's avatar Florian Blasius 🤘

[api update] implement tree build with new api.

parent 7ad2ccb2
......@@ -127,17 +127,17 @@ impl Widget for MainView {
}
fn main() {
let mut world = World::from_container(Tree::default());
let mut context = WipBuildContext::new(&mut world);
let _wip_button = WipButton::create()
.background("green")
.foreground("blue")
.text("Click me")
.on_click(|_| {
println!("Clicked");
false
})
.build(&mut context);
// let mut world = World::from_container(Tree::default());
// let mut context = WipBuildContext::new(&mut world);
// let _wip_button = WipButton::create()
// .background("green")
// .foreground("blue")
// .text("Click me")
// .on_click(|_| {
// println!("Clicked");
// false
// })
// .build(&mut context);
let mut application = Application::default();
......@@ -145,8 +145,8 @@ fn main() {
.create_window()
.bounds((100.0, 100.0, 420.0, 730.0))
.title("OrbTk - widgets example")
.root(MainView::create())
// .root(MainView::create())
.debug_flag(false)
.build();
.wip_build(WipButton::create());
application.run();
}
......@@ -18,7 +18,7 @@ use crate::{
EventSystem, InitSystem, LayoutSystem, PostLayoutStateSystem, RenderSystem, StateSystem,
},
theme::Theme,
widget::{PropertyResult, State, Template},
widget::{PropertyResult, State, Template, WipBuildContext, WipTemplateBuilder, WipWidget},
Global,
};
......@@ -79,6 +79,10 @@ impl<'a> WindowBuilder<'a> {
self
}
// pub fn wip_root(mut self, root: WipTemplateBuilder) -> Self {
// self
// }
/// Sets whether the window is resizable or not.
pub fn resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
......@@ -86,12 +90,135 @@ impl<'a> WindowBuilder<'a> {
}
/// Used to set the `debug` flag of the window.
/// If the flag is set to `ture` debug informations will be printed to the console.
/// If the flag is set to `true` debug information will be printed to the console.
pub fn debug_flag(mut self, debug: bool) -> Self {
self.debug_flag = debug;
self
}
/// Creates the window with the given properties and builds its widget tree.
pub fn wip_build<W>(self, root: W)
where
W: WipWidget,
{
let (mut runner, backend) =
target_backend(&self.title, self.bounds, self.resizable, self.theme);
let mut world = World::from_container(Tree::default());
let render_objects = Rc::new(RefCell::new(BTreeMap::new()));
let layouts = Rc::new(RefCell::new(BTreeMap::new()));
let handlers = Rc::new(RefCell::new(BTreeMap::new()));
let states = Rc::new(RefCell::new(BTreeMap::new()));
let update = Rc::new(Cell::new(true));
let running = Rc::new(Cell::new(true));
let debug_flag = Rc::new(Cell::new(self.debug_flag));
if debug_flag.get() {
println!("------ Start build tree ------\n");
}
// register window as entity with global properties
let window = world
.create_entity()
.with(Global::default())
.with(Bounds::new(
0.0,
0.0,
self.bounds.width(),
self.bounds.height(),
))
.with(Constraint::default())
.build();
if debug_flag.get() {
println!("Window (id = {}, children_len = 1)", window,);
}
let mut world = World::from_container(Tree::default());
let mut context = WipBuildContext::new(
window,
&mut world,
render_objects.clone(),
layouts.clone(),
handlers.clone(),
states.clone(),
);
// Register root widget as child of window
let root = root.build(&mut context);
world.entity_container().append_child(window, root).unwrap();
world.register_init_system(InitSystem {
backend: backend.clone(),
});
world
.create_system(EventSystem {
backend: backend.clone(),
handlers: handlers.clone(),
update: update.clone(),
running: running.clone(),
})
.with_priority(0)
.build();
world
.create_system(StateSystem {
backend: backend.clone(),
states: states.clone(),
update: update.clone(),
running: running.clone(),
})
.with_priority(1)
.build();
world
.create_system(LayoutSystem {
backend: backend.clone(),
layouts: layouts.clone(),
update: update.clone(),
debug_flag: debug_flag.clone(),
running: running.clone(),
})
.with_priority(2)
.build();
world
.create_system(PostLayoutStateSystem {
backend: backend.clone(),
states: states.clone(),
update: update.clone(),
running: running.clone(),
})
.with_priority(3)
.build();
world
.create_system(RenderSystem {
backend: backend.clone(),
render_objects: render_objects.clone(),
update: update.clone(),
debug_flag: debug_flag.clone(),
running: running.clone(),
})
.with_priority(4)
.build();
runner.world(world);
self.application.windows.push(Window {
backend_runner: runner,
render_objects,
layouts,
handlers,
states,
update,
running,
resizable: self.resizable,
debug_flag,
})
}
/// Creates the window with the given properties and builds its widget tree.
pub fn build(self) {
let (mut runner, backend) =
......
......@@ -95,7 +95,7 @@ pub trait ClickHandler: Sized + From<Template> + Into<Template> {
}
}
pub trait WipClickHandler<'a>: Sized + WipWidget<'a> {
pub trait WipClickHandler: Sized + WipWidget {
/// Inserts a handler.
fn on_click<H: Fn(Point) -> bool + 'static>(self, handler: H) -> Self {
self.insert_handler(ClickEventHandler {
......
......@@ -157,6 +157,7 @@ macro_rules! wip_widget {
$(
$property: PropertySource<$property_type>,
)*
children: Vec<Entity>,
}
impl $widget {
......@@ -183,11 +184,11 @@ macro_rules! wip_widget {
$(
$(
impl<'a> $handler<'a> for $widget {}
impl $handler for $widget {}
)*
)*
impl<'a> WipWidget<'a> for $widget {
impl WipWidget for $widget {
fn create() -> Self {
$widget {
attached_properties: HashMap::new(),
......@@ -196,6 +197,7 @@ macro_rules! wip_widget {
$(
$property: PropertySource::Value($property_type::default()),
)*
children: vec![],
}
}
......@@ -204,7 +206,12 @@ macro_rules! wip_widget {
self
}
fn build(self, context: &mut WipBuildContext<'a>) -> WipTemplate {
fn child(mut self, child: Entity) -> Self {
self.children.push(child);
self
}
fn build(self, context: &mut WipBuildContext) -> Entity {
let entity = context.create_entity();
for (_, property) in self.attached_properties {
......@@ -226,7 +233,12 @@ macro_rules! wip_widget {
}
)*
$widget::template(context.create_entity(), context)
for child in self.children {
context.append_child(entity, child);
}
entity
// $widget::template(context.create_entity(), context)
}
}
};
......
......@@ -4,13 +4,15 @@ use crate::{
event::{ClickHandler, WipClickHandler},
properties::*,
styling::{colors, fonts},
widget::{Container, FontIconBlock, Property, Stack, Template, TextBlock, Widget, WipTextBlock, WipContainer, WipTemplateBuilder, WipBuildContext, WipTemplate },
widget::{
Container, FontIconBlock, Property, Stack, Template, TextBlock, Widget, WipBuildContext,
WipContainer, WipTemplate, WipTemplateBuilder, WipTextBlock,
},
};
widget!(
/// The `Button` widget can be clicked by user. It's used to perform an action.
Button
(
Button(
BackgroundProperty,
BorderRadiusProperty,
BorderThicknessProperty,
......@@ -117,15 +119,18 @@ wip_widget!(
}
);
impl<'a> WipTemplateBuilder<'a> for WipButton {
fn template(id: Entity, context: &mut WipBuildContext<'a>) -> WipTemplate {
WipTemplate::new(id).child(
WipContainer::create().background(id).build(context).child(
WipTextBlock::create()
.foreground(id)
.text(id)
.build(context),
),
)
impl WipTemplateBuilder for WipButton {
fn template(self, id: Entity, context: &mut WipBuildContext) {
self.child(
WipContainer::create()
.background(id)
.child(
WipTextBlock::create()
.foreground(id)
.text(id)
.build(context),
)
.build(context),
);
}
}
\ No newline at end of file
}
......@@ -41,8 +41,8 @@ WipContainer {
background: WipBackground
});
impl<'a> WipTemplateBuilder<'a> for WipContainer {
fn template(id: Entity, context: &mut WipBuildContext<'a>) -> WipTemplate {
WipTemplate::new(id)
impl WipTemplateBuilder for WipContainer {
fn template(self, id: Entity, context: &mut WipBuildContext) {
// WipTemplate::new(id)
}
}
use std::rc::Rc;
use dces::prelude::{World, Entity, Component, ComponentBox, SharedComponentBox};
use std::{cell::RefCell, collections::BTreeMap, rc::Rc};
use dces::prelude::{Component, ComponentBox, Entity, SharedComponentBox, World};
use crate::application::Tree;
......@@ -9,9 +8,13 @@ use crate::theme::Selector;
use crate::event::EventHandler;
use crate::{Layout, RenderObject};
pub use self::context::Context;
pub use self::message::{MessageBox, StringMessage};
pub use self::property::{get_property, PropertyResult, Property, WipProperty, WipPropertyBuilder, PropertySource};
pub use self::property::{
get_property, Property, PropertyResult, PropertySource, WipProperty, WipPropertyBuilder,
};
pub use self::state::State;
pub use self::template::{Template, TemplateBase};
pub use self::widget_container::WidgetContainer;
......@@ -58,44 +61,57 @@ impl WipTemplate {
children: vec![],
}
}
pub fn child(mut self, template: WipTemplate) -> Self {
self.children.push(template);
self
}
}
/// The `TemplateBuilder` trait provides the method for the widget template creation.
pub trait WipTemplateBuilder<'a> {
pub trait WipTemplateBuilder: Sized {
/// Creates the template of the widget and returns it.
fn template(id: Entity, context: &mut WipBuildContext<'a>) -> WipTemplate;
fn template(self, _id: Entity, _context: &mut WipBuildContext) {}
}
/// The `Widget` trait is used to define a new widget.
pub trait WipWidget<'a>: Sized + WipTemplateBuilder<'a> {
pub trait WipWidget: WipTemplateBuilder {
/// Creates a new widget.
fn create() -> Self;
/// Builds the widget and returns the template of the widget.
fn build(self, context: &mut WipBuildContext<'a>) -> WipTemplate;
fn build(self, context: &mut WipBuildContext) -> Entity;
/// Inerts a new event handler.
fn insert_handler(mut self, handler: impl Into<Rc<dyn EventHandler>>) -> Self;
fn insert_handler(self, handler: impl Into<Rc<dyn EventHandler>>) -> Self;
fn child(self, child: Entity) -> Self;
}
pub struct WipBuildContext<'a> {
root: Entity,
world: &'a mut World<Tree>,
render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<dyn EventHandler>>>>>,
states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
}
impl<'a> WipBuildContext<'a> {
pub fn new(world: &'a mut World<Tree>) -> Self {
WipBuildContext { world }
pub fn new(
root: Entity,
world: &'a mut World<Tree>,
render_objects: Rc<RefCell<BTreeMap<Entity, Box<dyn RenderObject>>>>,
layouts: Rc<RefCell<BTreeMap<Entity, Box<dyn Layout>>>>,
handlers: Rc<RefCell<BTreeMap<Entity, Vec<Rc<dyn EventHandler>>>>>,
states: Rc<RefCell<BTreeMap<Entity, Rc<dyn State>>>>,
) -> Self {
WipBuildContext { root, world, render_objects, layouts, handlers, states }
}
pub fn create_entity(&mut self) -> Entity {
self.world.create_entity().build()
}
pub fn append_child(&mut self, parent: Entity, child: Entity) {
self.world.entity_container().append_child(parent, child).unwrap();
}
pub fn register_property<P: Component>(&mut self, entity: Entity, property: P) {
self.world
.entity_component_manager()
......@@ -108,7 +124,7 @@ impl<'a> WipBuildContext<'a> {
.register_component_box(entity, property);
}
pub fn register_property_shared_box(&mut self, entity: Entity, property: SharedComponentBox) {
pub fn register_property_shared_box(&mut self, entity: Entity, property: SharedComponentBox) {
self.world
.entity_component_manager()
.register_shared_component_box(entity, property);
......@@ -119,4 +135,4 @@ impl<'a> WipBuildContext<'a> {
.entity_component_manager()
.register_shared_component::<P>(target, source);
}
}
\ No newline at end of file
}
......@@ -40,8 +40,8 @@ WipTextBlock {
text: WipText
});
impl<'a> WipTemplateBuilder<'a> for WipTextBlock {
fn template(id: Entity, context: &mut WipBuildContext<'a>) -> WipTemplate {
WipTemplate::new(id)
impl WipTemplateBuilder for WipTextBlock {
fn template(self, id: Entity, context: &mut WipBuildContext) {
self.text("");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment