Added keyboard_input

This commit is contained in:
Jonathan Johnson 2023-10-18 08:51:11 -07:00
parent fc707835f5
commit e04b1b14ad
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
4 changed files with 73 additions and 12 deletions

View file

@ -1,6 +1,6 @@
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use kludgine::app::winit::event::{DeviceId, MouseButton}; use kludgine::app::winit::event::{DeviceId, KeyEvent, MouseButton};
use kludgine::figures::units::{Px, UPx}; use kludgine::figures::units::{Px, UPx};
use kludgine::figures::{IntoSigned, Point, Rect, Size}; use kludgine::figures::{IntoSigned, Point, Rect, Size};
@ -108,6 +108,17 @@ impl<'context, 'window> Context<'context, 'window> {
.mouse_up(location, device_id, button, self); .mouse_up(location, device_id, button, self);
} }
pub fn keyboard_input(
&mut self,
device_id: DeviceId,
input: KeyEvent,
is_synthetic: bool,
) -> EventHandling {
self.current_node
.lock()
.keyboard_input(device_id, input, is_synthetic, self)
}
#[must_use] #[must_use]
pub fn push_child(&self, child: BoxedWidget) -> ManagedWidget { pub fn push_child(&self, child: BoxedWidget) -> ManagedWidget {
self.current_node self.current_node

View file

@ -5,7 +5,7 @@ use std::panic::UnwindSafe;
use std::sync::{Arc, Mutex, MutexGuard, PoisonError}; use std::sync::{Arc, Mutex, MutexGuard, PoisonError};
use kludgine::app::winit::error::EventLoopError; use kludgine::app::winit::error::EventLoopError;
use kludgine::app::winit::event::{DeviceId, MouseButton}; use kludgine::app::winit::event::{DeviceId, KeyEvent, MouseButton};
use kludgine::figures::units::{Px, UPx}; use kludgine::figures::units::{Px, UPx};
use kludgine::figures::{Point, Size}; use kludgine::figures::{Point, Size};
@ -85,6 +85,17 @@ pub trait Widget: Send + UnwindSafe + Debug + 'static {
context: &mut Context<'_, '_>, context: &mut Context<'_, '_>,
) { ) {
} }
#[allow(unused_variables)]
fn keyboard_input(
&mut self,
device_id: DeviceId,
input: KeyEvent,
is_synthetic: bool,
context: &mut Context<'_, '_>,
) -> EventHandling {
UNHANDLED
}
} }
pub type EventHandling = ControlFlow<EventHandled, EventIgnored>; pub type EventHandling = ControlFlow<EventHandled, EventIgnored>;

View file

@ -1,6 +1,7 @@
use std::panic::UnwindSafe; use std::panic::UnwindSafe;
use kludgine::app::winit::event::{DeviceId, MouseButton}; use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton};
use kludgine::app::winit::keyboard::KeyCode;
use kludgine::figures::units::{Px, UPx}; use kludgine::figures::units::{Px, UPx};
use kludgine::figures::{Point, Rect, Size}; use kludgine::figures::{Point, Rect, Size};
use kludgine::shapes::{Shape, StrokeOptions}; use kludgine::shapes::{Shape, StrokeOptions};
@ -8,7 +9,7 @@ use kludgine::Color;
use crate::context::Context; use crate::context::Context;
use crate::graphics::Graphics; use crate::graphics::Graphics;
use crate::widget::{Callback, EventHandling, IntoValue, Value, Widget, HANDLED}; use crate::widget::{Callback, EventHandling, IntoValue, Value, Widget, HANDLED, UNHANDLED};
#[derive(Debug)] #[derive(Debug)]
pub struct Button { pub struct Button {
@ -34,6 +35,12 @@ impl Button {
self.on_click = Some(Callback::new(callback)); self.on_click = Some(Callback::new(callback));
self self
} }
fn invoke_on_click(&mut self) {
if let Some(on_click) = self.on_click.as_mut() {
on_click.invoke(());
}
}
} }
impl Widget for Button { impl Widget for Button {
@ -138,9 +145,7 @@ impl Widget for Button {
{ {
context.focus(); context.focus();
if let Some(on_click) = self.on_click.as_mut() { self.invoke_on_click();
on_click.invoke(());
}
} }
} }
} }
@ -162,6 +167,30 @@ impl Widget for Button {
}) })
} }
fn keyboard_input(
&mut self,
_device_id: DeviceId,
input: KeyEvent,
_is_synthetic: bool,
context: &mut Context<'_, '_>,
) -> EventHandling {
if input.physical_key == KeyCode::Space {
let changed = match input.state {
ElementState::Pressed => context.activate(),
ElementState::Released => {
self.invoke_on_click();
context.deactivate()
}
};
if changed {
context.set_needs_redraw();
}
HANDLED
} else {
UNHANDLED
}
}
fn unhover(&mut self, context: &mut Context<'_, '_>) { fn unhover(&mut self, context: &mut Context<'_, '_>) {
context.set_needs_redraw(); context.set_needs_redraw();
} }

View file

@ -4,7 +4,7 @@ use std::panic::{AssertUnwindSafe, UnwindSafe};
use kludgine::app::winit::dpi::PhysicalPosition; use kludgine::app::winit::dpi::PhysicalPosition;
use kludgine::app::winit::error::EventLoopError; use kludgine::app::winit::error::EventLoopError;
use kludgine::app::winit::event::{DeviceId, ElementState, MouseButton}; use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseButton};
use kludgine::app::winit::keyboard::KeyCode; use kludgine::app::winit::keyboard::KeyCode;
use kludgine::app::WindowBehavior as _; use kludgine::app::WindowBehavior as _;
use kludgine::figures::units::Px; use kludgine::figures::units::Px;
@ -197,11 +197,21 @@ where
fn keyboard_input( fn keyboard_input(
&mut self, &mut self,
mut window: RunningWindow<'_>, mut window: RunningWindow<'_>,
_device_id: DeviceId, device_id: DeviceId,
input: kludgine::app::winit::event::KeyEvent, input: KeyEvent,
_is_synthetic: bool, is_synthetic: bool,
) { ) {
if !input.state.is_pressed() { let handled = if let Some(focus) = self.root.tree.focused_widget() {
let focus = self.root.tree.widget(focus);
let mut focus = Context::new(&focus, &mut window);
recursively_handle_event(&mut focus, |widget| {
widget.keyboard_input(device_id, input.clone(), is_synthetic)
})
.is_some()
} else {
false
};
if !handled && !input.state.is_pressed() {
match input.physical_key { match input.physical_key {
KeyCode::KeyW if window.modifiers().state().primary() => { KeyCode::KeyW if window.modifiers().state().primary() => {
if self.request_close(&mut window) { if self.request_close(&mut window) {