Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use bevy::{prelude::*, utils::HashMap};
use crate::{
children::KChildren,
context::WidgetName,
prelude::KayakWidgetContext,
styles::{ComputedStyles, KStyle, RenderCommand, Units},
widget::Widget,
};
#[derive(Component, Default, Debug, Clone, PartialEq, Eq)]
pub struct AccordionContext {
allow_one: bool,
accordions: HashMap<usize, bool>,
}
impl AccordionContext {
pub fn is_open(&self, index: usize) -> bool {
self.accordions.get(&index).copied().unwrap_or(false)
}
pub fn toggle_current(&mut self, index: usize) {
if self.allow_one {
self.accordions
.iter_mut()
.filter(|(e, _)| **e != index)
.for_each(|(_, v)| {
*v = false;
});
}
if let Some(open) = self.accordions.get_mut(&index) {
*open = !*open;
} else {
self.accordions.insert(index, true);
}
}
}
#[derive(Component, Default, Debug, Clone, PartialEq, Eq)]
pub struct AccordionContextProvider {
pub allow_only_one: bool,
pub default_open: Option<usize>,
}
impl Widget for AccordionContextProvider {}
#[derive(Bundle, Debug, Clone, PartialEq)]
pub struct AccordionContextBundle {
pub accordion: AccordionContextProvider,
pub computed_styles: ComputedStyles,
pub children: KChildren,
pub widget_name: WidgetName,
}
impl Default for AccordionContextBundle {
fn default() -> Self {
Self {
accordion: Default::default(),
children: Default::default(),
computed_styles: ComputedStyles(KStyle {
render_command: RenderCommand::Layout.into(),
height: Units::Auto.into(),
width: Units::Stretch(1.0).into(),
..KStyle::default()
}),
widget_name: AccordionContextProvider::default().get_name(),
}
}
}
pub fn render(
In(widget_entity): In<Entity>,
widget_context: Res<KayakWidgetContext>,
mut commands: Commands,
children_query: Query<(&AccordionContextProvider, &KChildren)>,
) -> bool {
if let Ok((accordion, children)) = children_query.get(widget_entity) {
let context_entity = if let Some(context_entity) =
widget_context.get_context_entity::<AccordionContext>(widget_entity)
{
context_entity
} else {
let mut accordion_context = AccordionContext {
allow_one: accordion.allow_only_one,
..AccordionContext::default()
};
if let Some(default_open) = accordion.default_open {
accordion_context.toggle_current(default_open);
}
commands.spawn(accordion_context).id()
};
widget_context.set_context_entity::<AccordionContext>(Some(widget_entity), context_entity);
children.process(&widget_context, &mut commands, Some(widget_entity));
}
true
}