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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use crate::*;
#[derive(Properties, PartialEq)]
pub(crate) struct AppDrawerProps {
pub class: String,
}
#[derive(Default, Copy, Clone, PartialEq, Debug)]
pub(crate) struct AppDrawerState {
pub is_open: bool,
pub content: usize,
}
pub(crate) struct AppDrawer {
app_drawer_agent: Box<dyn Bridge<AppDrawerAgent>>,
is_open: bool,
content: usize,
}
pub(crate) fn render_drawer_button(
button_info: Option<DrawerToggleInfo>,
onclick: yew::Callback<MouseEvent>,
) -> Html {
match button_info {
Some(drawer_info) => {
html! {
<button type="button" title={drawer_info.title} class="btn toggle elevation-1" onclick={onclick}>
{(drawer_info.display)()}
</button>
}
}
None => html! {},
}
}
impl AppDrawer {
fn toggle_state(&mut self, content_ref: usize) {
self.is_open = content_ref > 0 && !self.is_open;
if content_ref > 0 {
self.content = content_ref.clone();
}
}
}
impl Component for AppDrawer {
type Message = AppDrawerReceiverMessage;
type Properties = AppDrawerProps;
fn create(ctx: &yew::Context<Self>) -> Self {
Self {
app_drawer_agent: AppDrawerAgent::bridge(
ctx.link()
.callback(AppDrawerReceiverMessage::AppDrawerMessage),
),
is_open: false,
content: 0,
}
}
fn update(&mut self, ctx: &yew::Context<Self>, msg: Self::Message) -> bool {
let is_open = self.is_open.clone();
match msg {
AppDrawerReceiverMessage::AppDrawerMessage(message) => {
match message {
AppDrawerRequest::ToggleTopDrawer(fnval) => {
if ctx.props().class != "top" {
return false;
}
self.toggle_state(fnval);
}
AppDrawerRequest::ToggleRightDrawer(fnval) => {
if ctx.props().class != "right" {
return false;
}
self.toggle_state(fnval);
}
AppDrawerRequest::ToggleBottomDrawer(fnval) => {
if ctx.props().class != "bottom" {
return false;
}
self.toggle_state(fnval);
}
AppDrawerRequest::ToggleLeftDrawer(fnval) => {
if ctx.props().class != "left" {
return false;
}
self.toggle_state(fnval);
}
}
is_open != self.is_open
}
AppDrawerReceiverMessage::None => false,
}
}
fn view(&self, ctx: &yew::Context<Self>) -> Html {
let props = ctx.props();
let class = format!(
"app-drawer {} {}",
props.class,
if self.is_open { "open" } else { "closed" }
);
let content: fn() -> Html = if self.content > 0 {
let fnptr = self.content as *const ();
unsafe { std::mem::transmute(fnptr) }
} else {
|| html!("")
};
let class_direction_cover = ctx.props().class.to_owned();
let class_direction_placement = ctx.props().class.to_owned();
html! {
<aside class={class}>
<div class="page-cover" onclick={ctx.link().callback(move |_|
{
if class_direction_cover == "top" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleTopDrawer(0.to_owned()));
} else if class_direction_cover == "right" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleRightDrawer(0.to_owned()));
} else if class_direction_cover == "bottom" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleBottomDrawer(0.to_owned()));
}
AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleLeftDrawer(0.to_owned()))
}
)}>
</div>
<div class="drawer-placement" onclick={ctx.link().callback(move |_|
{
if class_direction_placement == "top" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleTopDrawer(0.to_owned()));
} else if class_direction_placement == "right" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleRightDrawer(0.to_owned()));
} else if class_direction_placement == "bottom" {
return AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleBottomDrawer(0.to_owned()));
}
AppDrawerReceiverMessage::AppDrawerMessage(AppDrawerRequest::ToggleLeftDrawer(0.to_owned()))
}
)}>
<div class="drawer-content">
{content()}
</div>
</div>
</aside>
}
}
}