🧑💻 Redefine typed and generic component lists
This commit is contained in:
parent
f208da1b7b
commit
905b4b1cba
12 changed files with 176 additions and 186 deletions
|
|
@ -10,14 +10,14 @@ pub enum FormMethod {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Form {
|
pub struct Form {
|
||||||
|
id : OptionId,
|
||||||
weight : Weight,
|
weight : Weight,
|
||||||
renderable: Renderable,
|
renderable: Renderable,
|
||||||
id : OptionId,
|
|
||||||
classes : OptionClasses,
|
classes : OptionClasses,
|
||||||
action : OptionString,
|
action : OptionString,
|
||||||
charset : OptionString,
|
charset : OptionString,
|
||||||
method : FormMethod,
|
method : FormMethod,
|
||||||
stuff : ArcComponents,
|
stuff : AnyComponents,
|
||||||
template : String,
|
template : String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,6 +64,12 @@ impl ComponentTrait for Form {
|
||||||
impl Form {
|
impl Form {
|
||||||
// Form BUILDER.
|
// Form BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||||
self.weight = value;
|
self.weight = value;
|
||||||
|
|
@ -76,12 +82,6 @@ impl Form {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
|
||||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
pub fn alter_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
||||||
self.classes.alter_value(op, classes);
|
self.classes.alter_value(op, classes);
|
||||||
|
|
@ -106,14 +106,15 @@ impl Form {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
pub fn with_element(mut self, element: impl ComponentTrait) -> Self {
|
pub fn with_element(mut self, element: impl ComponentTrait) -> Self {
|
||||||
self.stuff.alter(ArcOp::Add(ArcComponent::with(element)));
|
self.stuff.alter_value(ArcAnyOp::Add(ArcAnyComponent::new(element)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_elements(&mut self, op: ArcOp) -> &mut Self {
|
pub fn alter_elements(&mut self, op: ArcAnyOp) -> &mut Self {
|
||||||
self.stuff.alter(op);
|
self.stuff.alter_value(op);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +142,7 @@ impl Form {
|
||||||
&self.method
|
&self.method
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elements(&self) -> &ArcComponents {
|
pub fn elements(&self) -> &AnyComponents {
|
||||||
&self.stuff
|
&self.stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use super::Submenu;
|
use super::Submenu;
|
||||||
|
|
||||||
type Content = TypedComponent<Html>;
|
type Content = ArcTypedComponent<Html>;
|
||||||
type SubmenuItems = TypedComponent<Submenu>;
|
type SubmenuItems = ArcTypedComponent<Submenu>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub enum ElementType {
|
pub enum ElementType {
|
||||||
|
|
@ -54,14 +54,14 @@ impl ComponentTrait for Element {
|
||||||
impl Element {
|
impl Element {
|
||||||
pub fn html(content: Html) -> Self {
|
pub fn html(content: Html) -> Self {
|
||||||
Element {
|
Element {
|
||||||
element_type: ElementType::Html(Content::with(content)),
|
element_type: ElementType::Html(Content::new(content)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submenu(submenu: Submenu) -> Self {
|
pub fn submenu(submenu: Submenu) -> Self {
|
||||||
Element {
|
Element {
|
||||||
element_type: ElementType::Submenu(SubmenuItems::with(submenu)),
|
element_type: ElementType::Submenu(SubmenuItems::new(submenu)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,13 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use super::Element;
|
use super::Element;
|
||||||
|
|
||||||
type Elements = TypedComponents<Element>;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Group {
|
pub struct Group {
|
||||||
|
id : OptionId,
|
||||||
weight : Weight,
|
weight : Weight,
|
||||||
renderable: Renderable,
|
renderable: Renderable,
|
||||||
id : OptionId,
|
elements : TypedComponents<Element>,
|
||||||
elements : Elements,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_handle!(COMPONENT_BASE_MENU_GROUP for Group);
|
impl_handle!(COMPONENT_BASE_MENU_GROUP for Group);
|
||||||
|
|
@ -44,6 +42,12 @@ impl ComponentTrait for Group {
|
||||||
impl Group {
|
impl Group {
|
||||||
// Group BUILDER.
|
// Group BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||||
self.weight = value;
|
self.weight = value;
|
||||||
|
|
@ -56,27 +60,21 @@ impl Group {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[rustfmt::skip]
|
||||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_element(mut self, element: Element) -> Self {
|
pub fn add_element(mut self, element: Element) -> Self {
|
||||||
self.elements
|
self.elements.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(element)));
|
||||||
.alter(TypedOp::Add(TypedComponent::with(element)));
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_elements(&mut self, op: TypedOp<Element>) -> &mut Self {
|
pub fn alter_elements(&mut self, op: ArcTypedOp<Element>) -> &mut Self {
|
||||||
self.elements.alter(op);
|
self.elements.alter_value(op);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group GETTERS.
|
// Group GETTERS.
|
||||||
|
|
||||||
pub fn elements(&self) -> &Elements {
|
pub fn elements(&self) -> &TypedComponents<Element> {
|
||||||
&self.elements
|
&self.elements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ use crate::prelude::*;
|
||||||
use super::{Megamenu, Submenu};
|
use super::{Megamenu, Submenu};
|
||||||
|
|
||||||
type Label = L10n;
|
type Label = L10n;
|
||||||
type Content = TypedComponent<Html>;
|
type Content = ArcTypedComponent<Html>;
|
||||||
type SubmenuItems = TypedComponent<Submenu>;
|
type SubmenuItems = ArcTypedComponent<Submenu>;
|
||||||
type MegamenuGroups = TypedComponent<Megamenu>;
|
type MegamenuGroups = ArcTypedComponent<Megamenu>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub enum ItemType {
|
pub enum ItemType {
|
||||||
|
|
@ -123,21 +123,21 @@ impl Item {
|
||||||
|
|
||||||
pub fn html(content: Html) -> Self {
|
pub fn html(content: Html) -> Self {
|
||||||
Item {
|
Item {
|
||||||
item_type: ItemType::Html(Content::with(content)),
|
item_type: ItemType::Html(Content::new(content)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submenu(label: L10n, submenu: Submenu) -> Self {
|
pub fn submenu(label: L10n, submenu: Submenu) -> Self {
|
||||||
Item {
|
Item {
|
||||||
item_type: ItemType::Submenu(label, SubmenuItems::with(submenu)),
|
item_type: ItemType::Submenu(label, SubmenuItems::new(submenu)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn megamenu(label: L10n, megamenu: Megamenu) -> Self {
|
pub fn megamenu(label: L10n, megamenu: Megamenu) -> Self {
|
||||||
Item {
|
Item {
|
||||||
item_type: ItemType::Megamenu(label, MegamenuGroups::with(megamenu)),
|
item_type: ItemType::Megamenu(label, MegamenuGroups::new(megamenu)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,13 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use super::Group;
|
use super::Group;
|
||||||
|
|
||||||
type Groups = TypedComponents<Group>;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Megamenu {
|
pub struct Megamenu {
|
||||||
|
id : OptionId,
|
||||||
weight : Weight,
|
weight : Weight,
|
||||||
renderable: Renderable,
|
renderable: Renderable,
|
||||||
id : OptionId,
|
groups : TypedComponents<Group>,
|
||||||
groups : Groups,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_handle!(COMPONENT_BASE_MENU_MEGAMENU for Megamenu);
|
impl_handle!(COMPONENT_BASE_MENU_MEGAMENU for Megamenu);
|
||||||
|
|
@ -44,6 +42,12 @@ impl ComponentTrait for Megamenu {
|
||||||
impl Megamenu {
|
impl Megamenu {
|
||||||
// Megamenu BUILDER.
|
// Megamenu BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||||
self.weight = value;
|
self.weight = value;
|
||||||
|
|
@ -56,26 +60,21 @@ impl Megamenu {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[rustfmt::skip]
|
||||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_group(mut self, group: Group) -> Self {
|
pub fn add_group(mut self, group: Group) -> Self {
|
||||||
self.groups.alter(TypedOp::Add(TypedComponent::with(group)));
|
self.groups.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(group)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_groups(&mut self, op: TypedOp<Group>) -> &mut Self {
|
pub fn alter_groups(&mut self, op: ArcTypedOp<Group>) -> &mut Self {
|
||||||
self.groups.alter(op);
|
self.groups.alter_value(op);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Megamenu GETTERS.
|
// Megamenu GETTERS.
|
||||||
|
|
||||||
pub fn groups(&self) -> &Groups {
|
pub fn groups(&self) -> &TypedComponents<Group> {
|
||||||
&self.groups
|
&self.groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ use super::Item;
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Menu {
|
pub struct Menu {
|
||||||
|
id : OptionId,
|
||||||
weight : Weight,
|
weight : Weight,
|
||||||
renderable: Renderable,
|
renderable: Renderable,
|
||||||
id : OptionId,
|
|
||||||
items : TypedComponents<Item>,
|
items : TypedComponents<Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +70,12 @@ impl ComponentTrait for Menu {
|
||||||
impl Menu {
|
impl Menu {
|
||||||
// Menu BUILDER.
|
// Menu BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||||
self.weight = value;
|
self.weight = value;
|
||||||
|
|
@ -82,20 +88,15 @@ impl Menu {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[rustfmt::skip]
|
||||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_item(mut self, item: Item) -> Self {
|
pub fn add_item(mut self, item: Item) -> Self {
|
||||||
self.items.alter(TypedOp::Add(TypedComponent::with(item)));
|
self.items.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(item)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_items(&mut self, op: TypedOp<Item>) -> &mut Self {
|
pub fn alter_items(&mut self, op: ArcTypedOp<Item>) -> &mut Self {
|
||||||
self.items.alter(op);
|
self.items.alter_value(op);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,14 @@ use crate::prelude::*;
|
||||||
|
|
||||||
use super::Item;
|
use super::Item;
|
||||||
|
|
||||||
type Items = TypedComponents<Item>;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Submenu {
|
pub struct Submenu {
|
||||||
|
id : OptionId,
|
||||||
weight : Weight,
|
weight : Weight,
|
||||||
renderable: Renderable,
|
renderable: Renderable,
|
||||||
id : OptionId,
|
|
||||||
title : OptionTranslated,
|
title : OptionTranslated,
|
||||||
items : Items,
|
items : TypedComponents<Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_handle!(COMPONENT_BASE_MENU_SUBMENU for Submenu);
|
impl_handle!(COMPONENT_BASE_MENU_SUBMENU for Submenu);
|
||||||
|
|
@ -50,6 +48,12 @@ impl ComponentTrait for Submenu {
|
||||||
impl Submenu {
|
impl Submenu {
|
||||||
// Submenu BUILDER.
|
// Submenu BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||||
self.weight = value;
|
self.weight = value;
|
||||||
|
|
@ -62,26 +66,21 @@ impl Submenu {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
|
||||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_title(&mut self, title: L10n) -> &mut Self {
|
pub fn alter_title(&mut self, title: L10n) -> &mut Self {
|
||||||
self.title.alter_value(title);
|
self.title.alter_value(title);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
pub fn add_item(mut self, item: Item) -> Self {
|
pub fn add_item(mut self, item: Item) -> Self {
|
||||||
self.items.alter(TypedOp::Add(TypedComponent::with(item)));
|
self.items.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(item)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_items(&mut self, op: TypedOp<Item>) -> &mut Self {
|
pub fn alter_items(&mut self, op: ArcTypedOp<Item>) -> &mut Self {
|
||||||
self.items.alter(op);
|
self.items.alter_value(op);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +90,7 @@ impl Submenu {
|
||||||
&self.title
|
&self.title
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn items(&self) -> &Items {
|
pub fn items(&self) -> &TypedComponents<Item> {
|
||||||
&self.items
|
&self.items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@ pub use renderable::{FnIsRenderable, Renderable};
|
||||||
mod definition;
|
mod definition;
|
||||||
pub use definition::{component_as_mut, component_as_ref, ComponentBase, ComponentTrait};
|
pub use definition::{component_as_mut, component_as_ref, ComponentBase, ComponentTrait};
|
||||||
|
|
||||||
mod arc;
|
mod arc_any;
|
||||||
pub use arc::{ArcComponent, ArcComponents, ArcOp};
|
pub use arc_any::AnyComponents;
|
||||||
|
pub use arc_any::{ArcAnyComponent, ArcAnyOp};
|
||||||
|
|
||||||
mod typed;
|
mod arc_typed;
|
||||||
pub use typed::{TypedComponent, TypedComponents, TypedOp};
|
pub use arc_typed::TypedComponents;
|
||||||
|
pub use arc_typed::{ArcTypedComponent, ArcTypedOp};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::core::component::{ComponentTrait, Context};
|
use crate::core::component::{ComponentTrait, Context};
|
||||||
use crate::html::{html, Markup};
|
use crate::html::{html, Markup};
|
||||||
use crate::{impl_handle, Handle, Weight};
|
use crate::{fn_builder, impl_handle, Handle, Weight};
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
|
|
@ -16,30 +16,26 @@ impl ComponentTrait for ComponentNull {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ArcComponent(Arc<RwLock<dyn ComponentTrait>>);
|
pub struct ArcAnyComponent(Arc<RwLock<dyn ComponentTrait>>);
|
||||||
|
|
||||||
impl Default for ArcComponent {
|
impl Default for ArcAnyComponent {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ArcComponent(Arc::new(RwLock::new(ComponentNull)))
|
ArcAnyComponent(Arc::new(RwLock::new(ComponentNull)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArcComponent {
|
impl ArcAnyComponent {
|
||||||
pub fn new() -> Self {
|
pub fn new(component: impl ComponentTrait) -> Self {
|
||||||
ArcComponent::default()
|
ArcAnyComponent(Arc::new(RwLock::new(component)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with(component: impl ComponentTrait) -> Self {
|
// ArcAnyComponent BUILDER.
|
||||||
ArcComponent(Arc::new(RwLock::new(component)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ArcComponent BUILDER.
|
|
||||||
|
|
||||||
pub fn set(&mut self, component: impl ComponentTrait) {
|
pub fn set(&mut self, component: impl ComponentTrait) {
|
||||||
self.0 = Arc::new(RwLock::new(component));
|
self.0 = Arc::new(RwLock::new(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArcComponent GETTERS.
|
// ArcAnyComponent GETTERS.
|
||||||
|
|
||||||
pub fn get(&self) -> RwLockReadGuard<'_, dyn ComponentTrait> {
|
pub fn get(&self) -> RwLockReadGuard<'_, dyn ComponentTrait> {
|
||||||
self.0.read().unwrap()
|
self.0.read().unwrap()
|
||||||
|
|
@ -57,69 +53,66 @@ impl ArcComponent {
|
||||||
self.0.read().unwrap().weight()
|
self.0.read().unwrap().weight()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArcComponent RENDER.
|
// ArcAnyComponent RENDER.
|
||||||
|
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
self.0.write().unwrap().render(cx)
|
self.0.write().unwrap().render(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ArcOp {
|
// *************************************************************************************************
|
||||||
Add(ArcComponent),
|
|
||||||
AddAfterId(&'static str, ArcComponent),
|
pub enum ArcAnyOp {
|
||||||
AddBeforeId(&'static str, ArcComponent),
|
Add(ArcAnyComponent),
|
||||||
AddFirst(ArcComponent),
|
AddAfterId(&'static str, ArcAnyComponent),
|
||||||
|
AddBeforeId(&'static str, ArcAnyComponent),
|
||||||
|
AddFirst(ArcAnyComponent),
|
||||||
RemoveById(&'static str),
|
RemoveById(&'static str),
|
||||||
ReplaceById(&'static str, ArcComponent),
|
ReplaceById(&'static str, ArcAnyComponent),
|
||||||
Reset,
|
Reset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ArcComponents(Vec<ArcComponent>);
|
pub struct AnyComponents(Vec<ArcAnyComponent>);
|
||||||
|
|
||||||
impl ArcComponents {
|
impl AnyComponents {
|
||||||
pub fn new() -> Self {
|
pub fn new(arc: ArcAnyComponent) -> Self {
|
||||||
ArcComponents::default()
|
AnyComponents::default().with_value(ArcAnyOp::Add(arc))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with(arc: ArcComponent) -> Self {
|
pub(crate) fn merge(mixes: &[Option<&AnyComponents>]) -> Self {
|
||||||
let mut components = ArcComponents::new();
|
let mut opt = AnyComponents::default();
|
||||||
components.alter(ArcOp::Add(arc));
|
|
||||||
components
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn merge(mixes: &[Option<&ArcComponents>]) -> Self {
|
|
||||||
let mut components = ArcComponents::default();
|
|
||||||
for m in mixes.iter().flatten() {
|
for m in mixes.iter().flatten() {
|
||||||
components.0.append(&mut m.0.clone());
|
opt.0.append(&mut m.0.clone());
|
||||||
}
|
}
|
||||||
components
|
opt
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArcComponents BUILDER.
|
// AnyComponents BUILDER.
|
||||||
|
|
||||||
pub fn alter(&mut self, op: ArcOp) -> &mut Self {
|
#[fn_builder]
|
||||||
|
pub fn alter_value(&mut self, op: ArcAnyOp) -> &mut Self {
|
||||||
match op {
|
match op {
|
||||||
ArcOp::Add(arc) => self.0.push(arc),
|
ArcAnyOp::Add(arc) => self.0.push(arc),
|
||||||
ArcOp::AddAfterId(id, arc) => {
|
ArcAnyOp::AddAfterId(id, arc) => {
|
||||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
Some(index) => self.0.insert(index + 1, arc),
|
Some(index) => self.0.insert(index + 1, arc),
|
||||||
_ => self.0.push(arc),
|
_ => self.0.push(arc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArcOp::AddBeforeId(id, arc) => {
|
ArcAnyOp::AddBeforeId(id, arc) => {
|
||||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
Some(index) => self.0.insert(index, arc),
|
Some(index) => self.0.insert(index, arc),
|
||||||
_ => self.0.insert(0, arc),
|
_ => self.0.insert(0, arc),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArcOp::AddFirst(arc) => self.0.insert(0, arc),
|
ArcAnyOp::AddFirst(arc) => self.0.insert(0, arc),
|
||||||
ArcOp::RemoveById(id) => {
|
ArcAnyOp::RemoveById(id) => {
|
||||||
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
self.0.remove(index);
|
self.0.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArcOp::ReplaceById(id, arc) => {
|
ArcAnyOp::ReplaceById(id, arc) => {
|
||||||
for c in self.0.iter_mut() {
|
for c in self.0.iter_mut() {
|
||||||
if c.id().as_deref() == Some(id) {
|
if c.id().as_deref() == Some(id) {
|
||||||
*c = arc;
|
*c = arc;
|
||||||
|
|
@ -127,26 +120,30 @@ impl ArcComponents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArcOp::Reset => self.0.clear(),
|
ArcAnyOp::Reset => self.0.clear(),
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArcComponents GETTERS.
|
// AnyComponents GETTERS.
|
||||||
|
|
||||||
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcComponent> {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcAnyComponent> {
|
||||||
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcComponent> {
|
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcAnyComponent> {
|
||||||
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcComponent> {
|
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcAnyComponent> {
|
||||||
self.0.iter().filter(move |&c| c.handle() == handle)
|
self.0.iter().filter(move |&c| c.handle() == handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArcComponents RENDER.
|
// AnyComponents RENDER.
|
||||||
|
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
let mut components = self.0.clone();
|
let mut components = self.0.clone();
|
||||||
|
|
@ -1,34 +1,30 @@
|
||||||
use crate::core::component::{ComponentTrait, Context};
|
use crate::core::component::{ComponentTrait, Context};
|
||||||
use crate::html::{html, Markup};
|
use crate::html::{html, Markup};
|
||||||
use crate::{Handle, Weight};
|
use crate::{fn_builder, Handle, Weight};
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TypedComponent<T: ComponentTrait + Default>(Arc<RwLock<T>>);
|
pub struct ArcTypedComponent<T: ComponentTrait>(Arc<RwLock<T>>);
|
||||||
|
|
||||||
impl<T: ComponentTrait + Default> Clone for TypedComponent<T> {
|
impl<T: ComponentTrait> Clone for ArcTypedComponent<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.clone())
|
Self(self.0.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ComponentTrait + Default> TypedComponent<T> {
|
impl<T: ComponentTrait> ArcTypedComponent<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new(component: T) -> Self {
|
||||||
TypedComponent::<T>::default()
|
ArcTypedComponent(Arc::new(RwLock::new(component)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with(component: T) -> Self {
|
// ArcTypedComponent BUILDER.
|
||||||
TypedComponent(Arc::new(RwLock::new(component)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypedComponent BUILDER.
|
|
||||||
|
|
||||||
pub fn set(&mut self, component: T) {
|
pub fn set(&mut self, component: T) {
|
||||||
self.0 = Arc::new(RwLock::new(component));
|
self.0 = Arc::new(RwLock::new(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypedComponent GETTERS.
|
// ArcTypedComponent GETTERS.
|
||||||
|
|
||||||
pub fn get(&self) -> RwLockReadGuard<'_, T> {
|
pub fn get(&self) -> RwLockReadGuard<'_, T> {
|
||||||
self.0.read().unwrap()
|
self.0.read().unwrap()
|
||||||
|
|
@ -46,61 +42,58 @@ impl<T: ComponentTrait + Default> TypedComponent<T> {
|
||||||
self.0.read().unwrap().weight()
|
self.0.read().unwrap().weight()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypedComponent RENDER.
|
// ArcTypedComponent RENDER.
|
||||||
|
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
self.0.write().unwrap().render(cx)
|
self.0.write().unwrap().render(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TypedOp<T: ComponentTrait + Default> {
|
// *************************************************************************************************
|
||||||
Add(TypedComponent<T>),
|
|
||||||
AddAfterId(&'static str, TypedComponent<T>),
|
pub enum ArcTypedOp<T: ComponentTrait + Default> {
|
||||||
AddBeforeId(&'static str, TypedComponent<T>),
|
Add(ArcTypedComponent<T>),
|
||||||
AddFirst(TypedComponent<T>),
|
AddAfterId(&'static str, ArcTypedComponent<T>),
|
||||||
|
AddBeforeId(&'static str, ArcTypedComponent<T>),
|
||||||
|
AddFirst(ArcTypedComponent<T>),
|
||||||
RemoveById(&'static str),
|
RemoveById(&'static str),
|
||||||
ReplaceById(&'static str, TypedComponent<T>),
|
ReplaceById(&'static str, ArcTypedComponent<T>),
|
||||||
Reset,
|
Reset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct TypedComponents<T: ComponentTrait + Default>(Vec<TypedComponent<T>>);
|
pub struct TypedComponents<T: ComponentTrait + Default>(Vec<ArcTypedComponent<T>>);
|
||||||
|
|
||||||
impl<T: ComponentTrait + Default> TypedComponents<T> {
|
impl<T: ComponentTrait + Default> TypedComponents<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new(arc: ArcTypedComponent<T>) -> Self {
|
||||||
TypedComponents::<T>::default()
|
TypedComponents::default().with_value(ArcTypedOp::Add(arc))
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with(one: TypedComponent<T>) -> Self {
|
|
||||||
let mut components = TypedComponents::new();
|
|
||||||
components.alter(TypedOp::Add(one));
|
|
||||||
components
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypedComponents BUILDER.
|
// TypedComponents BUILDER.
|
||||||
|
|
||||||
pub fn alter(&mut self, op: TypedOp<T>) -> &mut Self {
|
#[fn_builder]
|
||||||
|
pub fn alter_value(&mut self, op: ArcTypedOp<T>) -> &mut Self {
|
||||||
match op {
|
match op {
|
||||||
TypedOp::Add(one) => self.0.push(one),
|
ArcTypedOp::Add(one) => self.0.push(one),
|
||||||
TypedOp::AddAfterId(id, one) => {
|
ArcTypedOp::AddAfterId(id, one) => {
|
||||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
Some(index) => self.0.insert(index + 1, one),
|
Some(index) => self.0.insert(index + 1, one),
|
||||||
_ => self.0.push(one),
|
_ => self.0.push(one),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedOp::AddBeforeId(id, one) => {
|
ArcTypedOp::AddBeforeId(id, one) => {
|
||||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
Some(index) => self.0.insert(index, one),
|
Some(index) => self.0.insert(index, one),
|
||||||
_ => self.0.insert(0, one),
|
_ => self.0.insert(0, one),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedOp::AddFirst(one) => self.0.insert(0, one),
|
ArcTypedOp::AddFirst(one) => self.0.insert(0, one),
|
||||||
TypedOp::RemoveById(id) => {
|
ArcTypedOp::RemoveById(id) => {
|
||||||
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||||
self.0.remove(index);
|
self.0.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedOp::ReplaceById(id, one) => {
|
ArcTypedOp::ReplaceById(id, one) => {
|
||||||
for c in self.0.iter_mut() {
|
for c in self.0.iter_mut() {
|
||||||
if c.id().as_deref() == Some(id) {
|
if c.id().as_deref() == Some(id) {
|
||||||
*c = one;
|
*c = one;
|
||||||
|
|
@ -108,22 +101,26 @@ impl<T: ComponentTrait + Default> TypedComponents<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypedOp::Reset => self.0.clear(),
|
ArcTypedOp::Reset => self.0.clear(),
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// TypedComponents GETTERS.
|
// TypedComponents GETTERS.
|
||||||
|
|
||||||
pub fn get_by_id(&self, id: &'static str) -> Option<&TypedComponent<T>> {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcTypedComponent<T>> {
|
||||||
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &TypedComponent<T>> {
|
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcTypedComponent<T>> {
|
||||||
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &TypedComponent<T>> {
|
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcTypedComponent<T>> {
|
||||||
self.0.iter().filter(move |&c| c.handle() == handle)
|
self.0.iter().filter(move |&c| c.handle() == handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::core::component::{ArcComponent, ArcComponents, ArcOp};
|
use crate::core::component::{AnyComponents, ArcAnyComponent, ArcAnyOp};
|
||||||
use crate::core::theme::ThemeRef;
|
use crate::core::theme::ThemeRef;
|
||||||
use crate::{Handle, LazyStatic};
|
use crate::{Handle, LazyStatic};
|
||||||
|
|
||||||
|
|
@ -9,36 +9,32 @@ static THEME_REGIONS: LazyStatic<RwLock<HashMap<Handle, ComponentsRegions>>> =
|
||||||
LazyStatic::new(|| RwLock::new(HashMap::new()));
|
LazyStatic::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
static COMMON_REGIONS: LazyStatic<RwLock<ComponentsRegions>> =
|
static COMMON_REGIONS: LazyStatic<RwLock<ComponentsRegions>> =
|
||||||
LazyStatic::new(|| RwLock::new(ComponentsRegions::new()));
|
LazyStatic::new(|| RwLock::new(ComponentsRegions::default()));
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ComponentsRegions(HashMap<&'static str, ArcComponents>);
|
pub struct ComponentsRegions(HashMap<&'static str, AnyComponents>);
|
||||||
|
|
||||||
impl ComponentsRegions {
|
impl ComponentsRegions {
|
||||||
pub fn new() -> Self {
|
pub fn new(region: &'static str, arc: ArcAnyComponent) -> Self {
|
||||||
ComponentsRegions::default()
|
let mut regions = ComponentsRegions::default();
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with(region: &'static str, arc: ArcComponent) -> Self {
|
|
||||||
let mut regions = ComponentsRegions::new();
|
|
||||||
regions.add_in(region, arc);
|
regions.add_in(region, arc);
|
||||||
regions
|
regions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_in(&mut self, region: &'static str, arc: ArcComponent) {
|
pub fn add_in(&mut self, region: &'static str, arc: ArcAnyComponent) {
|
||||||
if let Some(region) = self.0.get_mut(region) {
|
if let Some(region) = self.0.get_mut(region) {
|
||||||
region.alter(ArcOp::Add(arc));
|
region.alter_value(ArcAnyOp::Add(arc));
|
||||||
} else {
|
} else {
|
||||||
self.0.insert(region, ArcComponents::with(arc));
|
self.0.insert(region, AnyComponents::new(arc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_components(&self, theme: ThemeRef, region: &str) -> ArcComponents {
|
pub fn get_components(&self, theme: ThemeRef, region: &str) -> AnyComponents {
|
||||||
let common = COMMON_REGIONS.read().unwrap();
|
let common = COMMON_REGIONS.read().unwrap();
|
||||||
if let Some(hm) = THEME_REGIONS.read().unwrap().get(&theme.handle()) {
|
if let Some(hm) = THEME_REGIONS.read().unwrap().get(&theme.handle()) {
|
||||||
ArcComponents::merge(&[common.0.get(region), self.0.get(region), hm.0.get(region)])
|
AnyComponents::merge(&[common.0.get(region), self.0.get(region), hm.0.get(region)])
|
||||||
} else {
|
} else {
|
||||||
ArcComponents::merge(&[common.0.get(region), self.0.get(region)])
|
AnyComponents::merge(&[common.0.get(region), self.0.get(region)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +44,7 @@ pub enum Region {
|
||||||
OfTheme(ThemeRef, &'static str),
|
OfTheme(ThemeRef, &'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_component_in(region: Region, arc: ArcComponent) {
|
pub fn add_component_in(region: Region, arc: ArcAnyComponent) {
|
||||||
match region {
|
match region {
|
||||||
Region::Named(name) => {
|
Region::Named(name) => {
|
||||||
COMMON_REGIONS.write().unwrap().add_in(name, arc);
|
COMMON_REGIONS.write().unwrap().add_in(name, arc);
|
||||||
|
|
@ -58,7 +54,7 @@ pub fn add_component_in(region: Region, arc: ArcComponent) {
|
||||||
if let Some(hm) = regions.get_mut(&theme.handle()) {
|
if let Some(hm) = regions.get_mut(&theme.handle()) {
|
||||||
hm.add_in(region, arc);
|
hm.add_in(region, arc);
|
||||||
} else {
|
} else {
|
||||||
regions.insert(theme.handle(), ComponentsRegions::with(region, arc));
|
regions.insert(theme.handle(), ComponentsRegions::new(region, arc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::base::action;
|
use crate::base::action;
|
||||||
use crate::core::component::{ArcComponent, ArcComponents as RegionComponents, ComponentTrait};
|
use crate::core::component::{AnyComponents, ArcAnyComponent, ComponentTrait};
|
||||||
use crate::core::component::{Context, ContextOp};
|
use crate::core::component::{Context, ContextOp};
|
||||||
use crate::core::theme::ComponentsRegions;
|
use crate::core::theme::ComponentsRegions;
|
||||||
use crate::html::{html, Markup, DOCTYPE};
|
use crate::html::{html, Markup, DOCTYPE};
|
||||||
|
|
@ -95,7 +95,7 @@ impl Page {
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self {
|
pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self {
|
||||||
self.regions.add_in(region, ArcComponent::with(component));
|
self.regions.add_in(region, ArcAnyComponent::new(component));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ impl Page {
|
||||||
&self.skip_to
|
&self.skip_to
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn components_in(&self, region: &str) -> RegionComponents {
|
pub fn components_in(&self, region: &str) -> AnyComponents {
|
||||||
self.regions.get_components(self.context.theme(), region)
|
self.regions.get_components(self.context.theme(), region)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue