11use crate :: application:: Editor ;
2+ use crate :: consts:: DOUBLE_CLICK_MILLISECONDS ;
23use crate :: messages:: input_mapper:: utility_types:: input_keyboard:: { Key , KeyStates , ModifierKeys } ;
34use crate :: messages:: input_mapper:: utility_types:: input_mouse:: { MouseButton , MouseKeys , MouseState } ;
45use crate :: messages:: input_mapper:: utility_types:: misc:: FrameTimeInfo ;
@@ -16,6 +17,7 @@ pub struct InputPreprocessorMessageHandler {
1617 pub time : u64 ,
1718 pub keyboard : KeyStates ,
1819 pub mouse : MouseState ,
20+ pub last_key_down : Option < ( Key , u64 ) > , // (Key, timestamp)
1921}
2022
2123#[ message_handler_data]
@@ -44,7 +46,18 @@ impl<'a> MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContex
4446 InputPreprocessorMessage :: KeyDown { key, key_repeat, modifier_keys } => {
4547 self . update_states_of_modifier_keys ( modifier_keys, responses) ;
4648 self . keyboard . set ( key as usize ) ;
49+
4750 if !key_repeat {
51+ if let Some ( ( last_key, last_time) ) = self . last_key_down {
52+ if last_key == key && self . time . saturating_sub ( last_time) < DOUBLE_CLICK_MILLISECONDS {
53+ responses. add ( InputMapperMessage :: DoubleTap ( key) ) ;
54+ self . last_key_down = None ;
55+ } else {
56+ self . last_key_down = Some ( ( key, self . time ) ) ;
57+ }
58+ } else {
59+ self . last_key_down = Some ( ( key, self . time ) ) ;
60+ }
4861 responses. add ( InputMapperMessage :: KeyDownNoRepeat ( key) ) ;
4962 }
5063 responses. add ( InputMapperMessage :: KeyDown ( key) ) ;
@@ -185,6 +198,7 @@ impl InputPreprocessorMessageHandler {
185198
186199#[ cfg( test) ]
187200mod test {
201+ use crate :: consts:: DOUBLE_CLICK_MILLISECONDS ;
188202 use crate :: messages:: input_mapper:: utility_types:: input_keyboard:: { Key , ModifierKeys } ;
189203 use crate :: messages:: input_mapper:: utility_types:: input_mouse:: { EditorMouseState , MouseKeys , ScrollDelta } ;
190204 use crate :: messages:: prelude:: * ;
@@ -292,4 +306,52 @@ mod test {
292306 assert ! ( responses. contains( & InputMapperMessage :: KeyDown ( Key :: Control ) . into( ) ) ) ;
293307 assert ! ( responses. contains( & InputMapperMessage :: KeyDown ( Key :: Control ) . into( ) ) ) ;
294308 }
309+
310+ fn key_down ( input_preprocessor : & mut InputPreprocessorMessageHandler , key : Key , responses : & mut VecDeque < Message > ) {
311+ input_preprocessor. process_message (
312+ InputPreprocessorMessage :: KeyDown {
313+ key,
314+ key_repeat : false ,
315+ modifier_keys : ModifierKeys :: empty ( ) ,
316+ } ,
317+ responses,
318+ InputPreprocessorMessageContext {
319+ viewport : & ViewportMessageHandler :: default ( ) ,
320+ } ,
321+ ) ;
322+ }
323+
324+ #[ test]
325+ fn process_double_tap_within_threshold ( ) {
326+ let mut input_preprocessor = InputPreprocessorMessageHandler :: default ( ) ;
327+ let mut responses = VecDeque :: new ( ) ;
328+
329+ // First tap at time 0
330+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
331+ responses. clear ( ) ;
332+
333+ // Second tap within threshold
334+ input_preprocessor. time = 50 ;
335+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
336+
337+ assert ! ( responses. contains( & InputMapperMessage :: DoubleTap ( Key :: Space ) . into( ) ) ) ;
338+ assert ! ( input_preprocessor. last_key_down. is_none( ) ) ;
339+ }
340+
341+ #[ test]
342+ fn process_double_tap_outside_threshold ( ) {
343+ let mut input_preprocessor = InputPreprocessorMessageHandler :: default ( ) ;
344+ let mut responses = VecDeque :: new ( ) ;
345+
346+ // First tap at time 0
347+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
348+ responses. clear ( ) ;
349+
350+ // Second tap outside threshold
351+ input_preprocessor. time = DOUBLE_CLICK_MILLISECONDS + 1 ;
352+ key_down ( & mut input_preprocessor, Key :: Space , & mut responses) ;
353+
354+ assert ! ( !responses. contains( & InputMapperMessage :: DoubleTap ( Key :: Space ) . into( ) ) ) ;
355+ assert_eq ! ( input_preprocessor. last_key_down, Some ( ( Key :: Space , DOUBLE_CLICK_MILLISECONDS + 1 ) ) ) ;
356+ }
295357}
0 commit comments