@@ -8,7 +8,7 @@ use ctru_sys::{self, SwkbdState};
8
8
9
9
use bitflags:: bitflags;
10
10
use libc;
11
- use std:: ffi:: CStr ;
11
+ use std:: ffi:: { CStr , CString } ;
12
12
use std:: fmt:: Display ;
13
13
use std:: iter:: once;
14
14
use std:: str;
@@ -199,10 +199,6 @@ bitflags! {
199
199
const BACKSLASH = ctru_sys:: SWKBD_FILTER_BACKSLASH ;
200
200
/// Disallow the use of profanity via Nintendo's profanity filter.
201
201
const PROFANITY = ctru_sys:: SWKBD_FILTER_PROFANITY ;
202
- /// Use a custom callback in order to filter the input.
203
- ///
204
- /// TODO: It's currently impossible to setup a custom filter callback.
205
- const CALLBACK = ctru_sys:: SWKBD_FILTER_CALLBACK ;
206
202
}
207
203
}
208
204
@@ -378,26 +374,52 @@ impl SoftwareKeyboard {
378
374
///
379
375
/// # Notes
380
376
///
381
- /// This function will overwrite any currently set filter configuration.
377
+ /// The filter callback will work only for the next time the keyboard is used. After using it once, it must be set again.
378
+ ///
379
+ /// # Example
380
+ ///
381
+ /// ```
382
+ /// # let _runner = test_runner::GdbRunner::default();
383
+ /// # fn main() {
384
+ /// #
385
+ /// use ctru::applets::swkbd::{SoftwareKeyboard, CallbackInput};
386
+ /// let mut keyboard = SoftwareKeyboard::default();
387
+ ///
388
+ /// keyboard.set_filter_callback(|text| {
389
+ /// if text.contains("boo") {
390
+ /// println!("Ah, you scared me!");
391
+ /// }
392
+ ///
393
+ /// (CallbackResult::Ok, None)
394
+ /// });
395
+ /// #
396
+ /// # }
382
397
pub fn set_filter_callback < F > ( & mut self , callback : F )
383
398
where
384
- F : FnOnce ( & str ) -> CallbackResult ,
399
+ F : FnOnce ( & str ) -> ( CallbackResult , Option < CString > ) ,
385
400
{
386
401
unsafe extern "C" fn internal_callback < F > (
387
402
user : * mut libc:: c_void ,
388
- _pp_message : * mut * const libc:: c_char ,
403
+ pp_message : * mut * const libc:: c_char ,
389
404
text : * const libc:: c_char ,
390
405
_text_size : libc:: size_t ,
391
406
) -> ctru_sys:: SwkbdCallbackResult
392
407
where
393
- F : FnOnce ( & str ) -> CallbackResult ,
408
+ F : FnOnce ( & str ) -> ( CallbackResult , Option < CString > ) ,
394
409
{
395
410
let closure = Box :: from_raw ( user as * mut Box < F > ) ;
396
411
397
412
let text = CStr :: from_ptr ( text) ;
398
413
let text_slice: & str = text. to_str ( ) . unwrap ( ) ;
399
414
400
- closure ( text_slice) . into ( )
415
+ let result = closure ( text_slice) ;
416
+
417
+ if let Some ( cstr) = result. 1 {
418
+ * pp_message = cstr. as_ptr ( ) ;
419
+ Box :: leak ( Box :: new ( cstr) ) ; // Definitely SHOULD NOT do this, but as far as design goes, it's clean.
420
+ }
421
+
422
+ result. 0 . into ( )
401
423
}
402
424
403
425
let boxed_callback = Box :: new ( Box :: new ( callback) ) ;
@@ -511,10 +533,10 @@ impl SoftwareKeyboard {
511
533
/// Set the 2 custom characters to add to the keyboard while using [`Kind::Numpad`].
512
534
///
513
535
/// These characters will appear in their own buttons right next to the `0` key.
514
- ///
536
+ ///
515
537
/// # Notes
516
- ///
517
- /// You can set one or both of these keys to `NUL` (value 0) to avoid showing the additional buttons to the user.
538
+ ///
539
+ /// If `None` is passed as either key, that button will not be shown to the user.
518
540
///
519
541
/// # Example
520
542
///
@@ -525,13 +547,26 @@ impl SoftwareKeyboard {
525
547
/// use ctru::applets::swkbd::{SoftwareKeyboard, Kind, ButtonConfig};
526
548
/// let mut keyboard = SoftwareKeyboard::new(Kind::Numpad, ButtonConfig::LeftRight);
527
549
///
528
- /// keyboard.set_numpad_keys(('#', '.'));
550
+ /// keyboard.set_numpad_keys(Some('#'), Some('.'));
551
+ ///
552
+ /// // The right numpad key will not be shown.
553
+ /// keyboard.set_numpad_keys(Some('!'), None);
529
554
/// #
530
555
/// # }
531
556
#[ doc( alias = "swkbdSetNumpadKeys" ) ]
532
- pub fn set_numpad_keys ( & mut self , keys : ( char , char ) ) {
557
+ pub fn set_numpad_keys ( & mut self , left_key : Option < char > , right_key : Option < char > ) {
558
+ let mut keys = ( 0 , 0 ) ;
559
+
560
+ if let Some ( k) = left_key {
561
+ keys. 0 = k as i32 ;
562
+ }
563
+
564
+ if let Some ( k) = right_key {
565
+ keys. 1 = k as i32 ;
566
+ }
567
+
533
568
unsafe {
534
- ctru_sys:: swkbdSetNumpadKeys ( self . state . as_mut ( ) , keys. 0 as i32 , keys. 1 as i32 ) ;
569
+ ctru_sys:: swkbdSetNumpadKeys ( self . state . as_mut ( ) , keys. 0 , keys. 1 ) ;
535
570
}
536
571
}
537
572
0 commit comments