Add focus and keyboard control to native/qt spinbox

This commit is contained in:
Lukas Jung 2022-03-02 10:28:42 +01:00 committed by Lukas Jung
parent 103b069dde
commit c15b0e1486
4 changed files with 54 additions and 9 deletions

View file

@ -1,7 +1,10 @@
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
use i_slint_core::input::FocusEventResult;
use i_slint_core::{
input::{FocusEventResult, KeyEventType},
items::{EventResult, KeyEventArg},
};
use super::*;
@ -21,10 +24,13 @@ pub struct NativeSpinBox {
pub width: Property<f32>,
pub height: Property<f32>,
pub enabled: Property<bool>,
pub has_focus: Property<bool>,
pub value: Property<i32>,
pub minimum: Property<i32>,
pub maximum: Property<i32>,
pub cached_rendering_data: CachedRenderingData,
pub key_pressed: Callback<KeyEventArg, EventResult>,
pub key_released: Callback<KeyEventArg, EventResult>,
data: Property<NativeSpinBoxData>,
}
@ -112,8 +118,8 @@ impl Item for NativeSpinBox {
fn input_event(
self: Pin<&Self>,
event: MouseEvent,
_window: &WindowRc,
_self_rc: &i_slint_core::items::ItemRc,
window: &WindowRc,
self_rc: &i_slint_core::items::ItemRc,
) -> InputEventResult {
let size: qttypes::QSize = get_size!(self);
let enabled = self.enabled();
@ -178,15 +184,40 @@ impl Item for NativeSpinBox {
if changed {
self.data.set(data);
}
if let MouseEvent::MousePressed { .. } = event {
if !self.has_focus() {
window.clone().set_focus_item(self_rc);
}
}
InputEventResult::EventAccepted
}
fn key_event(self: Pin<&Self>, _: &KeyEvent, _window: &WindowRc) -> KeyEventResult {
KeyEventResult::EventIgnored
fn key_event(self: Pin<&Self>, event: &KeyEvent, _window: &WindowRc) -> KeyEventResult {
let r = match event.event_type {
KeyEventType::KeyPressed => {
Self::FIELD_OFFSETS.key_pressed.apply_pin(self).call(&(event.clone(),))
}
KeyEventType::KeyReleased => {
Self::FIELD_OFFSETS.key_released.apply_pin(self).call(&(event.clone(),))
}
};
match r {
EventResult::accept => KeyEventResult::EventAccepted,
EventResult::reject => KeyEventResult::EventIgnored,
}
}
fn focus_event(self: Pin<&Self>, _: &FocusEvent, _window: &WindowRc) -> FocusEventResult {
FocusEventResult::FocusIgnored
fn focus_event(self: Pin<&Self>, event: &FocusEvent, _window: &WindowRc) -> FocusEventResult {
match event {
FocusEvent::FocusIn | FocusEvent::WindowReceivedFocus => {
self.has_focus.set(true);
}
FocusEvent::FocusOut | FocusEvent::WindowLostFocus => {
self.has_focus.set(false);
}
}
FocusEventResult::FocusAccepted
}
fn_render! { this dpr size painter widget initial_state =>

View file

@ -459,9 +459,12 @@ export NativeSpinBox := _ {
property <length> width;
property <length> height;
property <bool> enabled: true;
property <bool> has-focus: native_output;
property <int> value: native_output;
property <int> minimum;
property <int> maximum: 100;
callback key_pressed(KeyEvent) -> EventResult;
callback key_released(KeyEvent) -> EventResult;
//-is_internal
}

View file

@ -16,7 +16,18 @@ export StandardButton := NativeButton {
is-standard-button: true;
}
export CheckBox := NativeCheckBox { }
export SpinBox := NativeSpinBox { property<length> font-size; }
export SpinBox := NativeSpinBox {
property<length> font-size;
key-pressed(event) => {
if (enabled && event.text == Keys.UpArrow && value < maximum) {
value += 1;
} else if (enabled && event.text == Keys.DownArrow && value > minimum) {
value -= 1;
}
accept
}
}
export Slider := NativeSlider { }
export GroupBox := NativeGroupBox {
GridLayout {

View file

@ -52,7 +52,7 @@ type ItemRendererRef<'a> = &'a mut dyn crate::item_rendering::ItemRenderer;
/// Workarounds for cbindgen
pub type VoidArg = ();
type KeyEventArg = (KeyEvent,);
pub type KeyEventArg = (KeyEvent,);
type PointerEventArg = (PointerEvent,);
type PointArg = (Point,);