Newer
Older
input::{
keyboard::KeyboardInput,
mouse::{MouseButtonInput, MouseScrollUnit, MouseWheel},
prelude::{EventReader, IntoExclusiveSystem, MouseButton, Plugin, Res, World},
window::{CursorMoved, ReceivedCharacter, WindowCreated, WindowResized, Windows},
use kayak_core::{bind, Binding, InputEvent, MutableBound};
pub use render::font::FontMapping;
pub use render::image::ImageManager;
#[derive(Default)]
pub struct BevyKayakUIPlugin;
impl Plugin for BevyKayakUIPlugin {
fn build(&self, app: &mut bevy::prelude::App) {
app.insert_resource(bind(WindowSize::default()))
.add_plugin(bevy_kayak_renderer::BevyKayakRendererPlugin)
.add_plugin(render::BevyKayakUIExtractPlugin)
.add_system(update_window_size)
.add_system(update.exclusive_system());
}
}
pub(crate) fn to_bevy_color(color: &kayak_core::color::Color) -> Color {
Color::rgba(color.r, color.g, color.b, color.a)
}
if let Some(bevy_context) = world.remove_resource::<BevyContext>() {
if let Ok(mut context) = bevy_context.kayak_context.write() {
if let Some(ref mut windows) = world.get_resource_mut::<Windows>() {
if let Some(window) = windows.get_primary_mut() {
window.set_cursor_icon(convert_cursor_icon(context.cursor_icon()));
}
}
pub fn process_events(world: &mut World) {
let window_size = if let Some(windows) = world.get_resource::<Windows>() {
if let Some(window) = windows.get_primary() {
Vec2::new(window.width(), window.height())
} else {
log::warn!("Couldn't find primiary window!");
return;
log::warn!("Couldn't find primiary window!");
return;
if let Some(bevy_context) = world.remove_resource::<BevyContext>() {
if let Ok(mut context) = bevy_context.kayak_context.write() {
let mut input_events = Vec::new();
context.query_world::<(
EventReader<CursorMoved>,
EventReader<MouseButtonInput>,
EventReader<ReceivedCharacter>,
EventReader<KeyboardInput>,
), _, _>(
|(
mut cursor_moved_events,
mut mouse_button_input_events,
mut mouse_wheel_events,
mut char_input_events,
mut keyboard_input_events,
)| {
if let Some(event) = cursor_moved_events.iter().last() {
// Currently, we can only handle a single MouseMoved event at a time so everything but the last needs to be skipped
input_events.push(InputEvent::MouseMoved((
event.position.x as f32,
window_size.y - event.position.y as f32,
)));
}
for event in mouse_button_input_events.iter() {
match event.button {
MouseButton::Left => {
input_events.push(InputEvent::MouseLeftRelease);
}
}
_ => {}
for MouseWheel { x, y, unit } in mouse_wheel_events.iter() {
input_events.push(InputEvent::Scroll {
dx: *x,
dy: *y,
is_line: matches!(unit, MouseScrollUnit::Line),
})
}
for event in char_input_events.iter() {
input_events.push(InputEvent::CharEvent { c: event.char });
}
for event in keyboard_input_events.iter() {
if let Some(key_code) = event.key_code {
let kayak_key_code = key::convert_virtual_key_code(key_code);
input_events.push(InputEvent::Keyboard {
key: kayak_key_code,
is_pressed: matches!(event.state, ButtonState::Pressed),
context.process_events(input_events);
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
/// Tracks the bevy window size.
#[derive(Default, Debug, Clone, Copy, PartialEq)]
pub struct WindowSize(pub f32, pub f32);
fn update_window_size(
mut window_resized_events: EventReader<WindowResized>,
mut window_created_events: EventReader<WindowCreated>,
windows: Res<Windows>,
window_size: Res<Binding<WindowSize>>,
) {
let mut changed_window_ids = Vec::new();
// handle resize events. latest events are handled first because we only want to resize each
// window once
for event in window_resized_events.iter().rev() {
if changed_window_ids.contains(&event.id) {
continue;
}
changed_window_ids.push(event.id);
}
// handle resize events. latest events are handled first because we only want to resize each
// window once
for event in window_created_events.iter().rev() {
if changed_window_ids.contains(&event.id) {
continue;
}
changed_window_ids.push(event.id);
}
for window_id in changed_window_ids {
if let Some(window) = windows.get(window_id) {
let width = window.width();
let height = window.height();
window_size.set(WindowSize(width, height));
}
}
}