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
use bevy::prelude::*;
use kayak_ui::prelude::{widgets::*, *};
mod input;
mod items;
use crate::input::*;
use items::*;
// A bit of state management.
// Consider this like "global" state.
#[derive(Resource)]
pub struct TodoList {
pub new_item: String,
pub items: Vec<String>,
}
impl Default for TodoList {
fn default() -> Self {
Self::new()
}
}
impl TodoList {
pub fn new() -> Self {
Self {
new_item: "".into(),
items: vec![
"Buy milk".into(),
"Paint Shed".into(),
"Eat Dinner".into(),
"Write new Bevy UI library".into(),
],
}
}
}
// Our own version of widget_update that handles resource change events.
pub fn widget_update_with_resource<
Props: PartialEq + Component + Clone,
State: PartialEq + Component + Clone,
>(
In((entity, previous_entity)): In<(Entity, Entity)>,
widget_context: Res<KayakWidgetContext>,
todo_list: Res<TodoList>,
widget_param: WidgetParam<Props, State>,
) -> bool {
widget_param.has_changed(&widget_context, entity, previous_entity) || todo_list.is_changed()
}
fn startup(
mut commands: Commands,
mut font_mapping: ResMut<FontMapping>,
asset_server: Res<AssetServer>,
) {
let camera_entity = commands
.spawn((Camera2dBundle::default(), CameraUIKayak))
.id();
font_mapping.set_default(asset_server.load("roboto.kayak_font"));
let mut widget_context = KayakRootContext::new(camera_entity);
widget_context.add_plugin(KayakWidgetsContextPlugin);
widget_context.add_widget_data::<TodoItemsProps, EmptyState>();
widget_context.add_widget_data::<TodoInputProps, EmptyState>();
widget_context.add_widget_system(
TodoItemsProps.get_name(),
widget_update_with_resource::<TodoItemsProps, EmptyState>,
render_todo_items,
);
widget_context.add_widget_system(
TodoInputProps.get_name(),
widget_update_with_resource::<TodoInputProps, EmptyState>,
render_todo_input,
);
let parent_id = None;
rsx! {
<KayakAppBundle>
<WindowBundle
window={KWindow {
title: "Todo App".into(),
draggable: true,
initial_position: Vec2::new(
(1280.0 / 2.0) - (350.0 / 2.0),
(720.0 / 2.0) - (600.0 / 2.0)
),
size: Vec2::new(400.0, 600.0),
..Default::default()
}}
>
<TodoInputBundle />
<ScrollContextProviderBundle>
<ScrollBoxBundle>
<TodoItemsBundle />
</ScrollBoxBundle>
</ScrollContextProviderBundle>
</WindowBundle>
</KayakAppBundle>
};
commands.spawn((widget_context, EventDispatcher::default()));
}
fn main() {
App::new()
.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
.add_plugins(DefaultPlugins)
.add_plugins((
KayakContextPlugin,
KayakWidgets,
bevy_inspector_egui::quick::WorldInspectorPlugin::new(),
))
.insert_resource(TodoList::new())
.add_systems(Startup, startup)
.run()
}