Browse Source

Working filter callback

pull/149/head
Andrea Ciliberti 1 year ago
parent
commit
fa613c25cb
  1. 59
      ctru-rs/src/applets/swkbd.rs

59
ctru-rs/src/applets/swkbd.rs

@ -1,7 +1,6 @@
//! Software Keyboard applet. //! Software Keyboard applet.
//! //!
//! This applet opens a virtual keyboard on the console's bottom screen which lets the user write UTF-16 valid text. //! This applet opens a virtual keyboard on the console's bottom screen which lets the user write UTF-16 valid text.
// TODO: Implement remaining functionality (filter callbacks, etc.). Also improve "max text length" API.
#![doc(alias = "keyboard")] #![doc(alias = "keyboard")]
use crate::services::{apt::Apt, gfx::Gfx}; use crate::services::{apt::Apt, gfx::Gfx};
@ -9,6 +8,7 @@ use ctru_sys::{self, SwkbdState};
use bitflags::bitflags; use bitflags::bitflags;
use libc; use libc;
use std::ffi::CStr;
use std::fmt::Display; use std::fmt::Display;
use std::iter::once; use std::iter::once;
use std::str; use std::str;
@ -48,6 +48,21 @@ pub enum Kind {
Western = ctru_sys::SWKBD_TYPE_WESTERN, Western = ctru_sys::SWKBD_TYPE_WESTERN,
} }
/// The type of result returned by a custom filter callback.
///
/// The custom callback can be set using [`SoftwareKeyboard::set_filter_callback()`].
#[doc(alias = "SwkbdCallbackResult")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum CallbackResult {
/// The callback yields a positive result.
Ok = ctru_sys::SWKBD_CALLBACK_OK,
/// The callback finds the input invalid, but lets the user try again.
Retry = ctru_sys::SWKBD_CALLBACK_CONTINUE,
/// The callback finds the input invalid and closes the Software Keyboard view.
Close = ctru_sys::SWKBD_CALLBACK_CLOSE,
}
/// Represents which button the user pressed to close the [`SoftwareKeyboard`]. /// Represents which button the user pressed to close the [`SoftwareKeyboard`].
/// ///
/// Button text and behaviour can be customized with [`SoftwareKeyboard::configure_button()`]. /// Button text and behaviour can be customized with [`SoftwareKeyboard::configure_button()`].
@ -357,6 +372,45 @@ impl SoftwareKeyboard {
self.state.filter_flags = filters.bits(); self.state.filter_flags = filters.bits();
} }
/// Configure a custom filtering function to validate the input.
///
/// The callback function will return a callback result and the error message to display when the input is invalid.
///
/// # Notes
///
/// This function will overwrite any currently set filter configuration.
pub fn set_filter_callback<F>(&mut self, callback: F)
where
F: FnOnce(&str) -> CallbackResult,
{
unsafe extern "C" fn internal_callback<F>(
user: *mut libc::c_void,
_pp_message: *mut *const libc::c_char,
text: *const libc::c_char,
_text_size: libc::size_t,
) -> ctru_sys::SwkbdCallbackResult
where
F: FnOnce(&str) -> CallbackResult,
{
let closure = Box::from_raw(user as *mut Box<F>);
let text = CStr::from_ptr(text);
let text_slice: &str = text.to_str().unwrap();
closure(text_slice).into()
}
let boxed_callback = Box::new(Box::new(callback));
unsafe {
ctru_sys::swkbdSetFilterCallback(
self.state.as_mut(),
Some(internal_callback::<F>),
Box::into_raw(boxed_callback).cast(),
)
};
}
/// Configure the maximum number of digits that can be entered in the keyboard when the [`Filters::DIGITS`] flag is enabled. /// Configure the maximum number of digits that can be entered in the keyboard when the [`Filters::DIGITS`] flag is enabled.
/// ///
/// # Example /// # Example
@ -524,7 +578,7 @@ impl SoftwareKeyboard {
/// keyboard. By default the limit is `65000` code units. /// keyboard. By default the limit is `65000` code units.
/// ///
/// # Notes /// # Notes
/// ///
/// This action will overwrite any previously submitted [`ValidInput`] validation. /// This action will overwrite any previously submitted [`ValidInput`] validation.
/// ///
/// Keyboard input is converted from UTF-16 to UTF-8 before being handed to Rust, /// Keyboard input is converted from UTF-16 to UTF-8 before being handed to Rust,
@ -682,3 +736,4 @@ from_impl!(ValidInput, i32);
from_impl!(ValidInput, u32); from_impl!(ValidInput, u32);
from_impl!(ButtonConfig, i32); from_impl!(ButtonConfig, i32);
from_impl!(PasswordMode, u32); from_impl!(PasswordMode, u32);
from_impl!(CallbackResult, u32);

Loading…
Cancel
Save