Skip to content

Commit

Permalink
Modifiers support
Browse files Browse the repository at this point in the history
Closes #162
  • Loading branch information
ecton committed Sep 9, 2024
1 parent 1cb93e2 commit 8d653c2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
additional parameter controlling whether to position the window with the
initial value of the dynamic or whether to let the operating system perform
the initial positioning.
- Keyboard modifiers have been added to two event structures: `ButtonClick` and
`KeyboardEvent`. Because of this change, `KeyboardEvent` no longer implements
`From<winit::event::KeyEvent>`. Instead, a new api `KeyEvent::from_winit`
allows constructing from both the modifiers and key event.

### Changed

Expand Down Expand Up @@ -85,6 +89,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Window::inner_position`
- `Window::maximized`
- `Window::minimized`
- `Window::modifiers`
- `Window::outer_position`
- `Window::outer_size`
- `Window::resize_increments`
Expand Down
12 changes: 10 additions & 2 deletions src/widgets/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Duration;

use figures::units::{Lp, Px, UPx};
use figures::{IntoSigned, Point, Rect, Round, ScreenScale, Size};
use kludgine::app::winit::event::MouseButton;
use kludgine::app::winit::event::{Modifiers, MouseButton};
use kludgine::app::winit::window::CursorIcon;
use kludgine::shapes::{Shape, StrokeOptions};
use kludgine::Color;
Expand Down Expand Up @@ -40,6 +40,7 @@ pub struct Button {
#[derive(Debug, Default)]
struct PerWindow {
buttons_pressed: usize,
modifiers: Modifiers,
cached_state: CacheState,
active_colors: Option<Dynamic<ButtonColors>>,
color_animation: AnimationHandle,
Expand Down Expand Up @@ -432,7 +433,9 @@ impl Widget for Button {
_button: MouseButton,
context: &mut EventContext<'_>,
) -> EventHandling {
self.per_window.entry(context).or_default().buttons_pressed += 1;
let per_window = self.per_window.entry(context).or_default();
per_window.buttons_pressed += 1;
per_window.modifiers = context.modifiers();
context.activate();
HANDLED
}
Expand Down Expand Up @@ -475,11 +478,13 @@ impl Widget for Button {
if Rect::from(last_layout.size).contains(location) {
context.focus();

let modifiers = window_local.modifiers;
self.invoke_on_click(
Some(ButtonClick {
mouse_button: button,
location,
window_location: location + last_layout.origin,
modifiers,
}),
context,
);
Expand Down Expand Up @@ -598,4 +603,7 @@ pub struct ButtonClick {
pub location: Point<Px>,
/// The location relative to the window of the click.
pub window_location: Point<Px>,

/// The keyboard modifiers state when this click began.
pub modifiers: Modifiers,
}
46 changes: 35 additions & 11 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ where
outer_position: Option<Dynamic<Point<Px>>>,
close_requested: Option<Callback<(), bool>>,
icon: Option<Value<Option<RgbaImage>>>,
modifiers: Option<Dynamic<Modifiers>>,
}

impl<Behavior> Default for Window<Behavior>
Expand Down Expand Up @@ -642,6 +643,7 @@ where
inner_position: None,
outer_position: None,
icon: None,
modifiers: None,
}
}

Expand Down Expand Up @@ -982,6 +984,13 @@ where
self.icon = Some(icon.into_value());
self
}

/// Sets `modifiers` to contain the state of the keyboard modifiers when
/// this window has keyboard focus.
pub fn modifiers(mut self, modifiers: impl IntoDynamic<Modifiers>) -> Self {
self.modifiers = Some(modifiers.into_dynamic());
self
}
}

impl<Behavior> Run for Window<Behavior>
Expand Down Expand Up @@ -1050,6 +1059,7 @@ where
outer_position: this.outer_position.unwrap_or_default(),
outer_size: this.outer_size.unwrap_or_default(),
window_icon: this.icon.unwrap_or_default(),
modifiers: this.modifiers.unwrap_or_default(),
}),
pending: this.pending,
},
Expand Down Expand Up @@ -1207,6 +1217,7 @@ struct OpenWindow<T> {
outer_position: Tracked<Dynamic<Point<Px>>>,
inner_position: Dynamic<Point<Px>>,
window_icon: Tracked<Value<Option<RgbaImage>>>,
modifiers: Dynamic<Modifiers>,
}

impl<T> OpenWindow<T>
Expand Down Expand Up @@ -1643,6 +1654,7 @@ where
inner_position: settings.inner_position,
outer_position: Tracked::from(settings.outer_position).ignoring_first(),
window_icon: Tracked::from(settings.window_icon),
modifiers: settings.modifiers,
};

this.synchronize_platform_window(&mut window);
Expand Down Expand Up @@ -2469,13 +2481,8 @@ where
input: winit::event::KeyEvent,
is_synthetic: bool,
) {
self.keyboard_input(
window,
kludgine,
device_id.into(),
input.into(),
is_synthetic,
);
let event = KeyEvent::from_winit(input, window.modifiers());
self.keyboard_input(window, kludgine, device_id.into(), event, is_synthetic);
}

fn mouse_wheel(
Expand All @@ -2489,7 +2496,13 @@ where
self.mouse_wheel(window, kludgine, device_id.into(), delta, phase);
}

// fn modifiers_changed(&mut self, window: kludgine::app::Window<'_, ()>) {}
fn modifiers_changed(
&mut self,
window: kludgine::app::Window<'_, WindowCommand>,
_kludgine: &mut Kludgine,
) {
self.modifiers.set(window.modifiers());
}

fn ime(
&mut self,
Expand Down Expand Up @@ -2673,6 +2686,7 @@ pub(crate) mod sealed {
use figures::units::{Px, UPx};
use figures::{Fraction, Point, Size};
use image::{DynamicImage, RgbaImage};
use kludgine::app::winit::event::Modifiers;
use kludgine::app::winit::window::{UserAttentionType, WindowLevel};
use kludgine::Color;
use parking_lot::Mutex;
Expand Down Expand Up @@ -2731,6 +2745,7 @@ pub(crate) mod sealed {
pub outer_position: Dynamic<Point<Px>>,
pub outer_size: Dynamic<Size<UPx>>,
pub window_icon: Value<Option<RgbaImage>>,
pub modifiers: Dynamic<Modifiers>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -3343,6 +3358,7 @@ impl StandaloneWindowBuilder {
outer_position: Dynamic::default(),
outer_size: Dynamic::default(),
window_icon: Value::Constant(None),
modifiers: Dynamic::default(),
},
);

Expand Down Expand Up @@ -4348,6 +4364,7 @@ where
state: ElementState::Pressed,
repeat: false,
location: KeyLocation::Standard,
modifiers: Modifiers::default(),
};
self.recorder
.window
Expand Down Expand Up @@ -4379,6 +4396,7 @@ where
location: KeyLocation::Standard,
state: ElementState::Pressed,
repeat: false,
modifiers: Modifiers::default(),
};
let _handled =
self.recorder
Expand Down Expand Up @@ -4661,7 +4679,7 @@ impl FrameAssembler {
}

/// Describes a keyboard input targeting a window.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct KeyEvent {
/// The logical key that is interpretted from the `physical_key`.
///
Expand Down Expand Up @@ -4697,17 +4715,23 @@ pub struct KeyEvent {
/// See [`KeyEvent::logical_key`](winit::event::KeyEvent::logical_key) for
/// more information.
pub repeat: bool,

/// The modifiers state active for this event.
pub modifiers: Modifiers,
}

impl From<winit::event::KeyEvent> for KeyEvent {
fn from(event: winit::event::KeyEvent) -> Self {
impl KeyEvent {
/// Returns a new key event from a winit key event and modifiers.
#[must_use]
pub fn from_winit(event: winit::event::KeyEvent, modifiers: Modifiers) -> Self {
Self {
physical_key: event.physical_key,
logical_key: event.logical_key,
text: event.text,
location: event.location,
state: event.state,
repeat: event.repeat,
modifiers,
}
}
}

0 comments on commit 8d653c2

Please sign in to comment.