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
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
use bevy::{prelude::*, window::PrimaryWindow};
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 camera's width and height.
/// It will auto update if bevy's camera changes.
#[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.get_name(),
}
}
}
pub fn app_update(
In((entity, previous_props_entity)): In<(Entity, Entity)>,
widget_context: Res<KayakWidgetContext>,
widget_param: WidgetParam<KayakApp, EmptyState>,
camera: Query<&Camera, With<CameraUIKayak>>,
windows: Query<&Window, With<PrimaryWindow>>,
) -> 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.single();
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(entity): In<Entity>,
widget_context: Res<KayakWidgetContext>,
mut commands: Commands,
mut query: Query<(&KStyle, &mut ComputedStyles, &KChildren)>,
camera: Query<&Camera, With<CameraUIKayak>>,
) -> 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.viewport {
width = viewport.physical_size.x as f32;
height = viewport.physical_size.y as f32;
}
}
}
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
}