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

[api update] render object, layout, states

parent f529b60e
......@@ -136,7 +136,6 @@ impl<'a> WindowBuilder<'a> {
let mut world = World::from_container(Tree::default());
let mut context = WipBuildContext::new(
window,
&mut world,
render_objects.clone(),
layouts.clone(),
......
use std::{cell::RefCell, collections::BTreeMap, rc::Rc};
use std::{cell::RefCell, collections::BTreeMap, rc::Rc, any::Any };
use dces::prelude::{Entity, EntityComponentManager};
......@@ -23,7 +23,7 @@ mod stack;
mod text_selection;
/// A layout is used to dynamic order the children of a widget.
pub trait Layout {
pub trait Layout: Any {
// Measure all children before the arrangement.
fn measure(
&self,
......
......@@ -142,7 +142,7 @@ macro_rules! wip_property {
/// Used to define a widget, with properties and event handlers.
macro_rules! wip_widget {
( $(#[$widget_doc:meta])* $widget:ident $(: $( $handler:ident ),*)* { $($(#[$prop_doc:meta])* $property:ident: $property_type:tt ),* } ) => {
( $(#[$widget_doc:meta])* $widget:ident $(<$state:ident>)* $(: $( $handler:ident ),*)* { $($(#[$prop_doc:meta])* $property:ident: $property_type:tt ),* } ) => {
use std::{ any::TypeId, rc::Rc, collections::HashMap};
use dces::prelude::{Component, ComponentBox, SharedComponentBox };
......@@ -211,6 +211,12 @@ macro_rules! wip_widget {
self
}
$(
fn state(self) -> Option<Rc<State>> {
Rc::new($state::new())
}
)*
fn build(self, context: &mut WipBuildContext) -> Entity {
let entity = context.create_entity();
......@@ -232,13 +238,13 @@ macro_rules! wip_widget {
}
}
)*
for child in self.children {
context.append_child(entity, child);
}
entity
// $widget::template(context.create_entity(), context)
}
}
};
......
//! This module contains all render objects used in OrbTk. Render objects are used to define how to draw parts of a widget.
use std::any::Any;
use orbgl_api::Canvas;
use crate::backend::Renderer;
......@@ -16,7 +18,7 @@ mod image;
mod rectangle;
mod text;
pub trait RenderObject {
pub trait RenderObject: Any {
fn render(
&self,
canvas: &mut Canvas,
......
......@@ -8,7 +8,7 @@ use crate::theme::Selector;
use crate::event::EventHandler;
use crate::{Layout, RenderObject};
use crate::{Layout, PaddingLayout, RenderObject};
pub use self::context::Context;
pub use self::message::{MessageBox, StringMessage};
......@@ -80,11 +80,85 @@ pub trait WipWidget: WipTemplateBuilder {
/// Inerts a new event handler.
fn insert_handler(self, handler: impl Into<Rc<dyn EventHandler>>) -> Self;
fn render_object(self) -> Option<Box<dyn RenderObject>> {
None
}
fn layout(self) -> Box<dyn Layout> {
Box::new(PaddingLayout::new())
}
fn state(self) -> Option<Rc<State>> {
None
}
fn child(self, child: Entity) -> Self;
}
use std::any::TypeId;
use std::collections::HashMap;
#[derive(Default)]
pub struct LayoutStorage {
layouts: HashMap<TypeId, Box<dyn Layout>>,
map: HashMap<Entity, TypeId>,
}
impl LayoutStorage {
pub fn new() -> Self {
LayoutStorage::default()
}
pub fn register_layout<L: Layout + Default>(&mut self, widget: Entity) {
let type_id = TypeId::of::<L>();
if !self.layouts.contains_key(&type_id) {
self.layouts.insert(type_id, Box::new(L::default()));
}
self.map.insert(widget, type_id);
}
pub fn layout(&self, widget: Entity) -> Option<&Box<Layout>> {
if let Some(type_id) = self.map.get(&widget) {
return self.layouts.get(type_id);
}
None
}
}
#[derive(Default)]
pub struct RenderObjectStorage {
render_objects: HashMap<TypeId, Box<dyn RenderObject>>,
map: HashMap<Entity, TypeId>,
}
impl RenderObjectStorage {
pub fn new() -> Self {
RenderObjectStorage::default()
}
pub fn register_render_object<R: RenderObject + Default>(&mut self, widget: Entity) {
let type_id = TypeId::of::<R>();
if !self.render_objects.contains_key(&type_id) {
self.render_objects.insert(type_id, Box::new(R::default()));
}
self.map.insert(widget, type_id);
}
pub fn render_object(&self, widget: Entity) -> Option<&Box<RenderObject>> {
if let Some(type_id) = self.map.get(&widget) {
return self.render_objects.get(type_id);
}
None
}
}
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>>>>,
......@@ -94,14 +168,19 @@ pub struct WipBuildContext<'a> {
impl<'a> WipBuildContext<'a> {
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 }
WipBuildContext {
world,
render_objects,
layouts,
handlers,
states,
}
}
pub fn create_entity(&mut self) -> Entity {
......@@ -109,25 +188,28 @@ impl<'a> WipBuildContext<'a> {
}
pub fn append_child(&mut self, parent: Entity, child: Entity) {
self.world.entity_container().append_child(parent, child).unwrap();
self.world
.entity_container()
.append_child(parent, child)
.unwrap();
}
pub fn register_property<P: Component>(&mut self, entity: Entity, property: P) {
pub fn register_property<P: Component>(&mut self, widget: Entity, property: P) {
self.world
.entity_component_manager()
.register_component(entity, property);
.register_component(widget, property);
}
pub fn register_property_box(&mut self, entity: Entity, property: ComponentBox) {
pub fn register_property_box(&mut self, widget: Entity, property: ComponentBox) {
self.world
.entity_component_manager()
.register_component_box(entity, property);
.register_component_box(widget, property);
}
pub fn register_property_shared_box(&mut self, entity: Entity, property: SharedComponentBox) {
pub fn register_property_shared_box(&mut self, widget: Entity, property: SharedComponentBox) {
self.world
.entity_component_manager()
.register_shared_component_box(entity, property);
.register_shared_component_box(widget, property);
}
pub fn register_shared_property<P: Component>(&mut self, target: Entity, source: Entity) {
......@@ -135,4 +217,20 @@ impl<'a> WipBuildContext<'a> {
.entity_component_manager()
.register_shared_component::<P>(target, source);
}
pub fn register_state(&self, widget: Entity, state: Rc<State>) {
self.states.borrow_mut().insert(widget, state);
}
pub fn register_render_object(&self, widget: Entity, render_object: Box<dyn RenderObject>) {
self.render_objects
.borrow_mut()
.insert(widget, render_object);
}
pub fn register_layout(&self, widget: Entity, layout: Box<dyn Layout>) {
self.layouts.borrow_mut().insert(widget, layout);
}
}
// todo: improvement use only one layout and one render object of the same type.
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