-
Notifications
You must be signed in to change notification settings - Fork 50
/
app.rs
132 lines (118 loc) · 4.24 KB
/
app.rs
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
use bevy::prelude::*;
use kayak_ui_macros::rsx;
use crate::{
children::KChildren,
context::WidgetName,
prelude::KayakWidgetContext,
styles::{ComputedStyles, KStyle, RenderCommand, StyleProp, Units},
widget::{EmptyState, Widget, WidgetParam},
CameraUIKayak,
};
use super::ClipBundle;
#[derive(Component, Default, Clone, PartialEq, Eq)]
pub struct KayakApp;
impl Widget for KayakApp {}
/// Kayak's default root widget
/// This widget provides a width/height that matches the screen size in bevy
/// It will auto update if bevy's window changes as well.
#[derive(Bundle)]
pub struct KayakAppBundle {
pub app: KayakApp,
pub styles: KStyle,
pub computed_styles: ComputedStyles,
pub children: KChildren,
pub widget_name: WidgetName,
}
impl Default for KayakAppBundle {
fn default() -> Self {
Self {
app: Default::default(),
styles: Default::default(),
computed_styles: ComputedStyles::default(),
children: Default::default(),
widget_name: KayakApp::default().get_name(),
}
}
}
pub fn app_update(
In((widget_context, entity, previous_props_entity)): In<(KayakWidgetContext, Entity, Entity)>,
widget_param: WidgetParam<KayakApp, EmptyState>,
camera: Query<&Camera, With<CameraUIKayak>>,
windows: Res<Windows>,
) -> bool {
let mut window_change = false;
if let Ok(app_style) = widget_param.computed_style_query.get(entity) {
if let Some(camera_entity) = widget_context.camera_entity {
if let Ok(camera) = camera.get(camera_entity) {
if let Some(size) = camera.logical_viewport_size() {
if app_style.0.width != StyleProp::Value(Units::Pixels(size.x)) {
window_change = true;
}
if app_style.0.height != StyleProp::Value(Units::Pixels(size.y)) {
window_change = true;
}
} else {
let primary_window = windows.get_primary().unwrap();
if app_style.0.width != StyleProp::Value(Units::Pixels(primary_window.width()))
{
window_change = true;
}
if app_style.0.height
!= StyleProp::Value(Units::Pixels(primary_window.height()))
{
window_change = true;
}
}
}
}
}
widget_param.has_changed(&widget_context, entity, previous_props_entity) || window_change
}
/// TODO: USE CAMERA INSTEAD OF WINDOW!!
pub fn app_render(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
mut query: Query<(&KStyle, &mut ComputedStyles, &KChildren)>,
camera: Query<&Camera, With<CameraUIKayak>>,
windows: Res<Windows>,
images: Res<Assets<Image>>,
) -> bool {
let (mut width, mut height) = (0.0, 0.0);
if let Some(camera_entity) = widget_context.camera_entity {
if let Ok(camera) = camera.get(camera_entity) {
if let Some(size) = camera.logical_viewport_size() {
width = size.x;
height = size.y;
} else if let Some(viewport) = camera
.target
.get_render_target_info(&windows, &images)
.as_ref()
.map(|target_info| {
let scale = target_info.scale_factor;
(target_info.physical_size.as_dvec2() / scale).as_vec2()
})
{
width = viewport.x;
height = viewport.y;
}
}
}
if let Ok((app_style, mut computed_styles, children)) = query.get_mut(entity) {
*computed_styles = KStyle::default()
.with_style(KStyle {
render_command: RenderCommand::Layout.into(),
width: Units::Pixels(width).into(),
height: Units::Pixels(height).into(),
..Default::default()
})
.with_style(app_style)
.into();
let parent_id = Some(entity);
rsx! {
<ClipBundle
children={children.clone()}
/>
};
}
true
}