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
use bevy::{app::AppExit, prelude::*};
use kayak_ui::prelude::{widgets::*, *};
#[derive(Default, Clone, PartialEq, Component)]
pub struct MenuButton {
text: String,
}
impl Widget for MenuButton {}
#[derive(Bundle)]
pub struct MenuButtonBundle {
button: MenuButton,
styles: KStyle,
on_event: OnEvent,
widget_name: WidgetName,
}
impl Default for MenuButtonBundle {
fn default() -> Self {
Self {
button: Default::default(),
styles: KStyle {
bottom: Units::Pixels(20.0).into(),
cursor: KCursorIcon(CursorIcon::Hand).into(),
..Default::default()
},
on_event: OnEvent::default(),
widget_name: MenuButton::default().get_name(),
}
}
}
fn menu_button_render(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
asset_server: Res<AssetServer>,
menu_button_query: Query<&MenuButton>,
state_query: Query<&ButtonState>,
) -> bool {
let state_entity =
widget_context.use_state(&mut commands, entity, ButtonState { hovering: false });
let button_text = menu_button_query.get(entity).unwrap().text.clone();
let button_image = asset_server.load("main_menu/button.png");
let button_image_hover = asset_server.load("main_menu/button-hover.png");
let on_event = OnEvent::new(
move |In((event_dispatcher_context, _, mut event, _entity)): In<(
EventDispatcherContext,
WidgetState,
Event,
Entity,
)>,
mut query: Query<&mut ButtonState>| {
if let Ok(mut button) = query.get_mut(state_entity) {
match event.event_type {
EventType::MouseIn(..) => {
event.stop_propagation();
button.hovering = true;
}
EventType::MouseOut(..) => {
button.hovering = false;
}
_ => {}
}
}
(event_dispatcher_context, event)
},
);
if let Ok(button_state) = state_query.get(state_entity) {
let button_image_handle = if button_state.hovering {
button_image_hover
} else {
button_image
};
let parent_id = Some(entity);
rsx! {
<NinePatchBundle
nine_patch={NinePatch {
handle: button_image_handle,
border: Edge::all(10.0),
}}
styles={KStyle {
width: Units::Stretch(1.0).into(),
height: Units::Pixels(40.0).into(),
bottom: Units::Pixels(30.0).into(),
left: Units::Pixels(50.0).into(),
right: Units::Pixels(50.0).into(),
..KStyle::default()
}}
on_event={on_event}
>
<TextWidgetBundle
styles={KStyle {
top: Units::Stretch(1.0).into(),
bottom: Units::Stretch(1.0).into(),
..Default::default()
}}
text={TextProps {
alignment: Alignment::Middle,
content: button_text,
size: 28.0,
..Default::default()
}}
/>
</NinePatchBundle>
}
true
}
#[derive(Default, Resource)]
pub struct PreloadResource {
images: Vec<Handle<Image>>,
}
fn startup(
mut commands: Commands,
mut font_mapping: ResMut<FontMapping>,
asset_server: Res<AssetServer>,
mut preload_resource: ResMut<PreloadResource>,
) {
font_mapping.set_default(asset_server.load("lato-light.kttf"));
let mut widget_context = KayakRootContext::new();
widget_context.add_plugin(KayakWidgetsContextPlugin);
widget_context.add_widget_data::<MenuButton, ButtonState>();
widget_context.add_widget_system(
MenuButton::default().get_name(),
widget_update::<MenuButton, ButtonState>,
menu_button_render,
);
let panel1_image = asset_server.load("main_menu/panel1.png");
let logo_image = asset_server.load("main_menu/logo.png");
let kayak_image = asset_server.load("main_menu/kayak.png");
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
let button_image = asset_server.load("main_menu/button.png");
let button_image_hover = asset_server.load("main_menu/button-hover.png");
preload_resource.images.extend(vec![
panel1_image.clone(),
logo_image.clone(),
button_image.clone(),
button_image_hover.clone(),
]);
let handle_click_close = OnEvent::new(
move |In((event_dispatcher_context, _, event, _entity)): In<(
EventDispatcherContext,
WidgetState,
Event,
Entity,
)>,
mut exit: EventWriter<AppExit>| {
match event.event_type {
EventType::Click(..) => {
exit.send(AppExit);
}
_ => {}
}
(event_dispatcher_context, event)
},
);
let parent_id = None;
rsx! {
<KayakAppBundle>
<NinePatchBundle
nine_patch={NinePatch {
handle: panel1_image,
border: Edge::all(25.0),
}}
styles={KStyle {
width: Units::Pixels(350.0).into(),
height: Units::Pixels(512.0).into(),
left: Units::Stretch(1.0).into(),
right: Units::Stretch(1.0).into(),
top: Units::Stretch(1.0).into(),
bottom: Units::Stretch(1.0).into(),
padding: Edge::new(
Units::Pixels(20.0),
Units::Pixels(20.0),
Units::Pixels(50.0),
Units::Pixels(20.0),
).into(),
..KStyle::default()
}}
>
<KImageBundle
image={KImage(kayak_image)}
styles={KStyle {
width: Units::Pixels(310.0).into(),
height: Units::Pixels(104.0).into(),
top: Units::Pixels(25.0).into(),
bottom: Units::Pixels(25.0).into(),
..KStyle::default()
}}
/>
<KImageBundle
image={KImage(logo_image)}
styles={KStyle {
width: Units::Pixels(310.0).into(),
height: Units::Pixels(78.0).into(),
bottom: Units::Stretch(1.0).into(),
..KStyle::default()
}}
/>
<MenuButtonBundle button={MenuButton { text: "Play".into() }} />
<MenuButtonBundle button={MenuButton { text: "Options".into() }} />
<MenuButtonBundle
button={MenuButton { text: "Quit".into() }}
on_event={handle_click_close}
/>
</NinePatchBundle>
</KayakAppBundle>
commands.spawn(UICameraBundle::new(widget_context));
}
fn main() {
App::new()
.init_resource::<PreloadResource>()
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
.add_plugin(KayakContextPlugin)
.add_plugin(KayakWidgets)
.add_startup_system(startup)
.run()
}