ferroui_base/styling/
style_children.rs1use super::{IStyle, StyleBase};
2use crate::WeakRef;
3use std::cell::RefCell;
4use std::rc::Rc;
5
6#[derive(Clone)]
11pub struct StyleChildren(Rc<StyleChildrenData>);
12
13struct StyleChildrenData {
14 owner: WeakRef<StyleBase>,
15 items: RefCell<Rc<Vec<Rc<dyn IStyle>>>>,
16}
17
18fn as_style_base(item: &Rc<dyn IStyle>) -> Option<&StyleBase> {
19 item.as_object().and_then(|o| o.downcast_ref::<StyleBase>())
20}
21
22impl PartialEq for StyleChildren {
23 fn eq(&self, other: &Self) -> bool {
24 Rc::ptr_eq(&self.0, &other.0)
25 }
26}
27
28impl std::fmt::Debug for StyleChildren {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 write!(f, "StyleChildren({})", self.count())
31 }
32}
33
34impl StyleChildren {
35 pub(crate) fn new(owner: WeakRef<StyleBase>) -> Self {
36 Self(Rc::new(StyleChildrenData { owner, items: RefCell::new(Rc::new(Vec::new())) }))
37 }
38
39 #[inline]
41 pub fn count(&self) -> usize {
42 self.0.items.borrow().len()
43 }
44
45 #[inline]
46 pub fn is_empty(&self) -> bool {
47 self.0.items.borrow().is_empty()
48 }
49
50 pub fn get(&self, index: usize) -> Rc<dyn IStyle> {
52 self.0.items.borrow()[index].clone()
53 }
54
55 #[inline]
57 pub fn snapshot(&self) -> Rc<Vec<Rc<dyn IStyle>>> {
58 self.0.items.borrow().clone()
59 }
60
61 pub fn add(&self, item: impl Into<Rc<dyn IStyle>>) {
63 self.insert(self.count(), item)
64 }
65
66 pub fn insert(&self, index: usize, item: impl Into<Rc<dyn IStyle>>) {
68 let item = item.into();
69 let owner = self.0.owner.upgrade();
70 if let Some(style) = as_style_base(&item) {
71 style.set_parent(owner.as_ref());
72 }
73 Rc::make_mut(&mut *self.0.items.borrow_mut()).insert(index, item);
74 }
75
76 pub fn remove_at(&self, index: usize) {
78 let item = self.get(index);
79 if let Some(style) = as_style_base(&item) {
80 style.set_parent(None);
81 }
82 if let Some(host) = self.0.owner.upgrade().and_then(|o| o.owner()) {
83 if let Some(provider) = item.as_resource_provider() {
84 provider.remove_owner(&host);
85 }
86 }
87 Rc::make_mut(&mut *self.0.items.borrow_mut()).remove(index);
88 }
89
90 pub fn remove(&self, item: impl Into<Rc<dyn IStyle>>) -> bool {
92 let item = item.into();
93 let index = self.0.items.borrow().iter().position(|i| super::style_ptr_eq(i, &item));
94 match index {
95 Some(index) => {
96 self.remove_at(index);
97 true
98 }
99 None => false,
100 }
101 }
102
103 pub fn set(&self, index: usize, item: impl Into<Rc<dyn IStyle>>) {
105 let item = item.into();
106 let owner = self.0.owner.upgrade();
107 if let Some(style) = as_style_base(&item) {
108 style.set_parent(owner.as_ref());
109 }
110 Rc::make_mut(&mut *self.0.items.borrow_mut())[index] = item.clone();
111 if let Some(host) = owner.and_then(|o| o.owner()) {
112 if let Some(provider) = item.as_resource_provider() {
113 provider.add_owner(&host);
114 }
115 }
116 }
117
118 pub fn clear(&self) {
120 *self.0.items.borrow_mut() = Rc::new(Vec::new());
121 }
122}